Repository: GoogleCloudPlatform/django-cloud-deploy

Issue:
Unable to deploy to GKE when the Django project name has uppercase letters
## Issue running command
django-cloud-deploy cloudify

## Please describe what is wrong




## Environment information

Django Cloud Deploy: [0.2.1]

Platform: [Linux-4.19.20-1rodete1-amd64-x86_64-with-Debian-rodete-rodete]

Gcloud Version: [238.0.0]

Cloud SQL Proxy Version: [Cloud SQL Proxy: version 1.13; sha ac834ce67862b7c4ed8bdbe86e664572f820c245 built Tue Oct  9 23:39:16 UTC 2018]

Python Version: [3.6.5 (default, Mar 31 2018, 05:34:57)  [GCC 7.3.0]]

Docker Version: [Docker version 18.09.2, build 6247962]

## Traceback
```.pytb
Traceback (most recent call last):
  File "/usr/local/google/home/wangxf/Desktop/django-cloud-deploy/django_cloud_deploy/django_cloud_deploy.py", line 46, in _cloudify
    cloudify.main(args)
  File "/usr/local/google/home/wangxf/Desktop/django-cloud-deploy/django_cloud_deploy/cli/cloudify.py", line 159, in main
    deploy_existing_django_project=True)
  File "/usr/local/google/home/wangxf/Desktop/django-cloud-deploy/django_cloud_deploy/workflow/__init__.py", line 269, in create_and_deploy_new_project
    django_project_name, image_name, secrets)
  File "/usr/local/google/home/wangxf/Desktop/django-cloud-deploy/django_cloud_deploy/workflow/deploy_workflow.py", line 83, in deploy_gke_app
    secrets, region, zone)
  File "/usr/local/google/home/wangxf/Desktop/django-cloud-deploy/django_cloud_deploy/workflow/_deploygke.py", line 105, in deploy_new_app_sync
    self._container_client.create_deployment(deployment_data, kube_config)
  File "/usr/local/google/home/wangxf/Desktop/django-cloud-deploy/django_cloud_deploy/cloudlib/container.py", line 293, in create_deployment
    namespace=namespace, body=deployment_data)
  File "/usr/local/google/home/wangxf/Desktop/django-cloud-deploy/venv/lib/python3.6/site-packages/kubernetes/client/apis/extensions_v1beta1_api.py", line 175, in create_namespaced_deployment
    (data) = self.create_namespaced_deployment_with_http_info(namespace, body, **kwargs)
  File "/usr/local/google/home/wangxf/Desktop/django-cloud-deploy/venv/lib/python3.6/site-packages/kubernetes/client/apis/extensions_v1beta1_api.py", line 266, in create_namespaced_deployment_with_http_info
    collection_formats=collection_formats)
  File "/usr/local/google/home/wangxf/Desktop/django-cloud-deploy/venv/lib/python3.6/site-packages/kubernetes/client/api_client.py", line 321, in call_api
    _return_http_data_only, collection_formats, _preload_content, _request_timeout)
  File "/usr/local/google/home/wangxf/Desktop/django-cloud-deploy/venv/lib/python3.6/site-packages/kubernetes/client/api_client.py", line 155, in __call_api
    _request_timeout=_request_timeout)
  File "/usr/local/google/home/wangxf/Desktop/django-cloud-deploy/venv/lib/python3.6/site-packages/kubernetes/client/api_client.py", line 364, in request
    body=body)
  File "/usr/local/google/home/wangxf/Desktop/django-cloud-deploy/venv/lib/python3.6/site-packages/kubernetes/client/rest.py", line 266, in POST
    body=body)
  File "/usr/local/google/home/wangxf/Desktop/django-cloud-deploy/venv/lib/python3.6/site-packages/kubernetes/client/rest.py", line 222, in request
    raise ApiException(http_resp=r)
kubernetes.client.rest.ApiException: (422)
Reason: Unprocessable Entity
HTTP response headers: HTTPHeaderDict({'Audit-Id': 'a62276db-9066-48b5-a879-e6978b94abbc', 'Content-Type': 'application/json', 'Date': 'Sat, 30 Mar 2019 00:26:44 GMT', 'Content-Length': '1541'})
HTTP response body: {"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"Deployment.apps \"DjangoBlog\" is invalid: [metadata.name: Invalid value: \"DjangoBlog\": a DNS-1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*'), spec.template.spec.containers[0].name: Invalid value: \"DjangoBlog-app\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name',  or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?')]","reason":"Invalid","details":{"name":"DjangoBlog","group":"apps","kind":"Deployment","causes":[{"reason":"FieldValueInvalid","message":"Invalid value: \"DjangoBlog\": a DNS-1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')","field":"metadata.name"},{"reason":"FieldValueInvalid","message":"Invalid value: \"DjangoBlog-app\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name',  or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?')","field":"spec.template.spec.containers[0].name"}]},"code":422}



```

Discussion:

Patch:
diff --git a/django_cloud_deploy/skeleton/source_generator.py b/django_cloud_deploy/skeleton/source_generator.py
index d74be49..70ea8cb 100644
--- a/django_cloud_deploy/skeleton/source_generator.py
+++ b/django_cloud_deploy/skeleton/source_generator.py
@@ -647,7 +647,7 @@ class _YAMLFileGenerator(_Jinja2FileGenerator):
         django_secrets = django_secrets or []
 
         options = {
-            'project_name': project_name,
+            'project_name': project_name.lower(),
             'project_id': project_id,
             'cloud_sql_connection_string': cloud_sql_connection_string,
             'image_tag': image_tag,


Test patch:
diff --git a/django_cloud_deploy/tests/unit/skeleton/source_generator_test.py b/django_cloud_deploy/tests/unit/skeleton/source_generator_test.py
index 75b786e..7945a03 100644
--- a/django_cloud_deploy/tests/unit/skeleton/source_generator_test.py
+++ b/django_cloud_deploy/tests/unit/skeleton/source_generator_test.py
@@ -577,6 +577,17 @@ class YAMLFileGeneratorTest(FileGeneratorTest):
             # Assert cloudsql secret is used as default
             self.assertIn('name: cloudsql-oauth-credentials', yaml_file_content)
 
+    def test_lowercase_project_name(self):
+        project_id = 'fake_projectid'
+        project_name = 'DjangoBlog'
+        self._generator.generate_new(self._project_dir, project_name,
+                                     project_id)
+
+        yaml_file_path = os.path.join(self._project_dir, project_name + '.yaml')
+        with open(yaml_file_path) as yaml_file:
+            yaml_file_content = yaml_file.read()
+            self.assertIn(project_name.lower(), yaml_file_content)
+
     def test_customized_yaml_file_content(self):
         project_id = project_name = 'test_customized_yaml_file_content'
         instance_name = 'fake_instance_name'