diff --git a/cookiecutter.json b/cookiecutter.json index b5dda0c7..eabf7d14 100644 --- a/cookiecutter.json +++ b/cookiecutter.json @@ -32,6 +32,10 @@ "None", "Gulp" ], + "cloud_provider": [ + "AWS", + "GCE" + ], "custom_bootstrap_compilation": "n", "use_compressor": "n", "use_celery": "n", diff --git a/tests/test_cookiecutter_generation.py b/tests/test_cookiecutter_generation.py index 36395627..17375b1c 100755 --- a/tests/test_cookiecutter_generation.py +++ b/tests/test_cookiecutter_generation.py @@ -11,6 +11,7 @@ PATTERN = "{{(\s?cookiecutter)[.](.*?)}}" RE_OBJ = re.compile(PATTERN) YN_CHOICES = ["y", "n"] +CLOUD_CHOICES = ["AWS", "GCE"] @pytest.fixture @@ -35,6 +36,7 @@ def context(): @pytest.mark.parametrize("use_sentry", YN_CHOICES, ids=lambda yn: f"sentry:{yn}") @pytest.mark.parametrize("use_compressor", YN_CHOICES, ids=lambda yn: f"cmpr:{yn}") @pytest.mark.parametrize("use_whitenoise", YN_CHOICES, ids=lambda yn: f"wnoise:{yn}") +@pytest.mark.parametrize("cloud_provider", CLOUD_CHOICES, ids=lambda yn: f"cloud:{yn}") def context_combination( windows, use_docker, @@ -43,6 +45,7 @@ def context_combination( use_sentry, use_compressor, use_whitenoise, + cloud_provider, ): """Fixture that parametrize the function where it's used.""" return { @@ -53,6 +56,7 @@ def context_combination( "use_mailhog": use_mailhog, "use_sentry": use_sentry, "use_whitenoise": use_whitenoise, + "cloud_provider": cloud_provider, } diff --git a/{{cookiecutter.project_slug}}/.envs/.production/.django b/{{cookiecutter.project_slug}}/.envs/.production/.django index 4175f894..a938ada6 100644 --- a/{{cookiecutter.project_slug}}/.envs/.production/.django +++ b/{{cookiecutter.project_slug}}/.envs/.production/.django @@ -16,13 +16,18 @@ DJANGO_SECURE_SSL_REDIRECT=False MAILGUN_API_KEY= DJANGO_SERVER_EMAIL= MAILGUN_DOMAIN= - +{% if cookiecutter.cloud_provider == 'AWS' %} # AWS # ------------------------------------------------------------------------------ DJANGO_AWS_ACCESS_KEY_ID= DJANGO_AWS_SECRET_ACCESS_KEY= DJANGO_AWS_STORAGE_BUCKET_NAME= - +{% elif cookiecutter.cloud_provider == 'GCE' %} +# GCE +# ------------------------------------------------------------------------------ +GOOGLE_APPLICATION_CREDENTIALS= +DJANGO_GCE_STORAGE_BUCKET_NAME= +{% endif %} # django-allauth # ------------------------------------------------------------------------------ DJANGO_ACCOUNT_ALLOW_REGISTRATION=True diff --git a/{{cookiecutter.project_slug}}/config/settings/production.py b/{{cookiecutter.project_slug}}/config/settings/production.py index 236c6c9f..4adbdb9c 100644 --- a/{{cookiecutter.project_slug}}/config/settings/production.py +++ b/{{cookiecutter.project_slug}}/config/settings/production.py @@ -70,6 +70,7 @@ SECURE_CONTENT_TYPE_NOSNIFF = env.bool( # ------------------------------------------------------------------------------ # https://django-storages.readthedocs.io/en/latest/#installation INSTALLED_APPS += ["storages"] # noqa F405 +{% if cookiecutter.cloud_provider == 'AWS' %} # https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html#settings AWS_ACCESS_KEY_ID = env("DJANGO_AWS_ACCESS_KEY_ID") # https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html#settings @@ -88,22 +89,27 @@ AWS_S3_OBJECT_PARAMETERS = { AWS_DEFAULT_ACL = None # https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html#settings AWS_S3_REGION_NAME = env("DJANGO_AWS_S3_REGION_NAME", default=None) +{% elif cookiecutter.cloud_provider == 'GCE' %} +DEFAULT_FILE_STORAGE = "storages.backends.gcloud.GoogleCloudStorage" +GS_BUCKET_NAME = env("DJANGO_GCE_STORAGE_BUCKET_NAME") +GS_DEFAULT_ACL = "publicRead" +{% endif %} # STATIC # ------------------------ {% if cookiecutter.use_whitenoise == 'y' -%} STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage" -{%- else %} +{%- endif -%} +{%- if cookiecutter.cloud_provider == 'AWS' %} STATICFILES_STORAGE = "config.settings.production.StaticRootS3Boto3Storage" STATIC_URL = f"https://{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com/static/" +{%- elif cookiecutter.cloud_provider == 'GCE' %} +STATIC_URL = "https://storage.googleapis.com/{}/static".format(GS_BUCKET_NAME) {%- endif %} # MEDIA # ------------------------------------------------------------------------------ -{% if cookiecutter.use_whitenoise == 'y' -%} -DEFAULT_FILE_STORAGE = "storages.backends.s3boto3.S3Boto3Storage" -MEDIA_URL = f"https://{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com/" -{%- else %} +{%- if cookiecutter.cloud_provider == 'AWS' %} # region http://stackoverflow.com/questions/10390244/ # Full-fledge class: https://stackoverflow.com/a/18046120/104731 from storages.backends.s3boto3 import S3Boto3Storage # noqa E402 @@ -121,6 +127,9 @@ class MediaRootS3Boto3Storage(S3Boto3Storage): # endregion DEFAULT_FILE_STORAGE = "config.settings.production.MediaRootS3Boto3Storage" MEDIA_URL = f"https://{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com/media/" +{%- elif cookiecutter.cloud_provider == 'GCE' %} +MEDIA_URL = "https://storage.googleapis.com/{}/media".format(GS_BUCKET_NAME) +MEDIA_ROOT = "https://storage.googleapis.com/{}/media".format(GS_BUCKET_NAME) {%- endif %} # TEMPLATES diff --git a/{{cookiecutter.project_slug}}/requirements/production.txt b/{{cookiecutter.project_slug}}/requirements/production.txt index 5a40f07a..b1758194 100644 --- a/{{cookiecutter.project_slug}}/requirements/production.txt +++ b/{{cookiecutter.project_slug}}/requirements/production.txt @@ -13,5 +13,9 @@ sentry-sdk==0.7.9 # https://github.com/getsentry/sentry-python # Django # ------------------------------------------------------------------------------ +{%- if cookiecutter.cloud_provider == 'AWS' %} django-storages[boto3]==1.7.1 # https://github.com/jschneier/django-storages +{%- elif cookiecutter.cloud_provider == 'GCE' %} +django-storages[google]==1.7.1 # https://github.com/jschneier/django-storages +{%- endif %} django-anymail[mailgun]==6.0 # https://github.com/anymail/django-anymail