From 4d1773374fe78fac9987a267691bcbc79d942fb9 Mon Sep 17 00:00:00 2001 From: Pavel Kirilin <win10@list.ru> Date: Thu, 2 Sep 2021 21:54:22 +0400 Subject: [PATCH] Updated kubernetes config. Signed-off-by: Pavel Kirilin <win10@list.ru> --- fastapi_template/cli.py | 1 + fastapi_template/input_model.py | 1 + fastapi_template/template/cookiecutter.json | 5 +- .../template/hooks/pre_gen_project.py | 5 -- .../.dockerignore | 1 + .../.gitlab-ci.yml | 3 +- .../conditional_files.json | 6 ++ .../deploy/docker-compose.yml | 7 +-- .../deploy/kube/app.yml | 45 ++++++++++----- .../deploy/kube/db.yml | 56 +++++++++++++++++-- .../deploy/kube/redis.yml | 14 +++-- .../db/migrations/env.py | 2 +- 12 files changed, 107 insertions(+), 39 deletions(-) diff --git a/fastapi_template/cli.py b/fastapi_template/cli.py index a5d3b46..b715f39 100644 --- a/fastapi_template/cli.py +++ b/fastapi_template/cli.py @@ -145,6 +145,7 @@ def read_user_input(current_context: BuilderContext) -> BuilderContext: current_context.project_name = prompt( "Project name: ", validator=SnakeCaseValidator() ) + current_context.kube_name = current_context.project_name.replace('_', '-') if current_context.project_description is None: current_context.project_description = prompt("Project description: ") if current_context.db is None: diff --git a/fastapi_template/input_model.py b/fastapi_template/input_model.py index 1c7f3bb..5cbaf1f 100644 --- a/fastapi_template/input_model.py +++ b/fastapi_template/input_model.py @@ -30,6 +30,7 @@ class BuilderContext(BaseModel): """Options for project generation.""" project_name: Optional[str] + kube_name: Optional[str] project_description: Optional[str] db: Optional[DatabaseType] db_info: Optional[Database] diff --git a/fastapi_template/template/cookiecutter.json b/fastapi_template/template/cookiecutter.json index e974c3d..1b3d564 100644 --- a/fastapi_template/template/cookiecutter.json +++ b/fastapi_template/template/cookiecutter.json @@ -20,7 +20,10 @@ "enable_kube": { "type": "bool" }, + "kube_name": { + "type": "string" + }, "_extensions": [ "cookiecutter.extensions.RandomStringExtension" ] -} +} \ No newline at end of file diff --git a/fastapi_template/template/hooks/pre_gen_project.py b/fastapi_template/template/hooks/pre_gen_project.py index b86829b..0ddf1f0 100644 --- a/fastapi_template/template/hooks/pre_gen_project.py +++ b/fastapi_template/template/hooks/pre_gen_project.py @@ -1,8 +1,3 @@ """ Pre generation hooks -Currently only synchronizes passwords - - -{{ cookiecutter.update({"postgres_password": random_ascii_string(20) }) }} -{{ cookiecutter.update({"redis_password": random_ascii_string(20) }) }} """ \ No newline at end of file diff --git a/fastapi_template/template/{{cookiecutter.project_name}}/.dockerignore b/fastapi_template/template/{{cookiecutter.project_name}}/.dockerignore index 741c3d3..00ce79b 100644 --- a/fastapi_template/template/{{cookiecutter.project_name}}/.dockerignore +++ b/fastapi_template/template/{{cookiecutter.project_name}}/.dockerignore @@ -3,6 +3,7 @@ deploy/ .idea/ .vscode/ +.git/ # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] diff --git a/fastapi_template/template/{{cookiecutter.project_name}}/.gitlab-ci.yml b/fastapi_template/template/{{cookiecutter.project_name}}/.gitlab-ci.yml index 5d18f16..b568e79 100644 --- a/fastapi_template/template/{{cookiecutter.project_name}}/.gitlab-ci.yml +++ b/fastapi_template/template/{{cookiecutter.project_name}}/.gitlab-ci.yml @@ -39,7 +39,6 @@ pytest: {%- if cookiecutter.db_info.name != "sqlite" %} services: - name: {{ cookiecutter.db_info.image }} - alias: {{ cookiecutter.project_name }}-db {%- endif %} variables: {%- if cookiecutter.db_info.name == "postgresql" %} @@ -61,7 +60,7 @@ pytest: {%- if cookiecutter.db_info.name != "sqlite" %} - apt update - apt install -y wait-for-it - - wait-for-it -t 180 {{ cookiecutter.project_name }}-db:{{cookiecutter.db_info.port}} + - wait-for-it -t 180 ${{ cookiecutter.project_name | upper }}_DB_HOST:{{cookiecutter.db_info.port}} {%- endif %} {%- endif %} - pytest -vv --cov="{{cookiecutter.project_name}}" . {% if cookiecutter.enable_alembic %}--test-alembic{%- endif %} diff --git a/fastapi_template/template/{{cookiecutter.project_name}}/conditional_files.json b/fastapi_template/template/{{cookiecutter.project_name}}/conditional_files.json index eac8acc..0ce5340 100644 --- a/fastapi_template/template/{{cookiecutter.project_name}}/conditional_files.json +++ b/fastapi_template/template/{{cookiecutter.project_name}}/conditional_files.json @@ -23,6 +23,12 @@ "alembic.ini" ] }, + "Postgres and MySQL support": { + "enabled": "{{cookiecutter.db_info.name != 'sqlite'}}", + "resources": [ + "deploy/kube/db.yml" + ] + }, "Alembic": { "enabled": "{{cookiecutter.enable_alembic}}", "resources": [ diff --git a/fastapi_template/template/{{cookiecutter.project_name}}/deploy/docker-compose.yml b/fastapi_template/template/{{cookiecutter.project_name}}/deploy/docker-compose.yml index 5f465cb..318833b 100644 --- a/fastapi_template/template/{{cookiecutter.project_name}}/deploy/docker-compose.yml +++ b/fastapi_template/template/{{cookiecutter.project_name}}/deploy/docker-compose.yml @@ -5,7 +5,7 @@ services: build: context: . dockerfile: ./deploy/Dockerfile - image: {{cookiecutter.project_name}}:latest + image: {{cookiecutter.project_name}}:{{"${" }}{{cookiecutter.project_name | upper }}_VERSION:-latest{{"}"}} env_file: - .env environment: @@ -45,10 +45,7 @@ services: {% if cookiecutter.enable_alembic == 'True' %} migrator: - build: - context: . - dockerfile: ./deploy/Dockerfile - image: {{cookiecutter.project_name}}:latest + image: {{cookiecutter.project_name}}:{{"${" }}{{cookiecutter.project_name | upper }}_VERSION:-latest{{"}"}} {%- if cookiecutter.db_info.name == "sqlite" %} command: alembic upgrade head environment: diff --git a/fastapi_template/template/{{cookiecutter.project_name}}/deploy/kube/app.yml b/fastapi_template/template/{{cookiecutter.project_name}}/deploy/kube/app.yml index 8d9330c..8a29dc3 100644 --- a/fastapi_template/template/{{cookiecutter.project_name}}/deploy/kube/app.yml +++ b/fastapi_template/template/{{cookiecutter.project_name}}/deploy/kube/app.yml @@ -2,23 +2,40 @@ apiVersion: apps/v1 kind: Deployment metadata: - name: {{cookiecutter.project_name}} + name: {{cookiecutter.kube_name}}-app spec: selector: matchLabels: - app: {{cookiecutter.project_name}} + app: {{cookiecutter.kube_name}}-app template: metadata: labels: - app: {{cookiecutter.project_name}} + app: {{cookiecutter.kube_name}}-app spec: containers: - - name: {{cookiecutter.project_name}} + - name: app image: {{cookiecutter.project_name}}:latest - imagePullPolicy: Always - envFrom: - - configMapRef: - name: {{cookiecutter.project_name}}-env + {%- if cookiecutter.db_info.name == "sqlite" %} + command: ["/bin/sh"] + args: + - -c + - >- + alembic upgrade head && + python -m {{cookiecutter.project_name }} + {%- endif %} + env: + - name: {{cookiecutter.project_name | upper }}_HOST + value: 0.0.0.0 + {%- if cookiecutter.db_info.name != "none" %} + {%- if cookiecutter.db_info.name != "sqlite" %} + - name: {{cookiecutter.project_name | upper }}_DB_HOST + value: {{cookiecutter.kube_name}}-db-service + {%- endif %} + {%- endif %} + {%- if cookiecutter.enable_redis %} + - name: {{cookiecutter.project_name | upper }}_REDIS_HOST + value: {{cookiecutter.kube_name}}-redis-service + {%- endif %} resources: limits: memory: "300Mi" @@ -29,10 +46,10 @@ spec: apiVersion: v1 kind: Service metadata: - name: {{cookiecutter.project_name}} + name: {{cookiecutter.kube_name}}-app-service spec: selector: - app: {{cookiecutter.project_name}} + app: {{cookiecutter.kube_name}}-app ports: - port: 80 targetPort: 8000 @@ -40,18 +57,18 @@ spec: apiVersion: networking.k8s.io/v1 kind: Ingress metadata: - name: {{cookiecutter.project_name}} + name: {{cookiecutter.kube_name}}-app labels: - name: {{cookiecutter.project_name}} + name: {{cookiecutter.kube_name}}-app spec: rules: - - host: {{cookiecutter.project_name}}.local + - host: {{ cookiecutter.kube_name }}.local http: paths: - pathType: Prefix path: "/" backend: service: - name: {{cookiecutter.project_name}} + name: {{cookiecutter.kube_name}}-app-service port: number: 80 diff --git a/fastapi_template/template/{{cookiecutter.project_name}}/deploy/kube/db.yml b/fastapi_template/template/{{cookiecutter.project_name}}/deploy/kube/db.yml index 5fe6ed1..cd337fb 100644 --- a/fastapi_template/template/{{cookiecutter.project_name}}/deploy/kube/db.yml +++ b/fastapi_template/template/{{cookiecutter.project_name}}/deploy/kube/db.yml @@ -1,15 +1,16 @@ +--- apiVersion: apps/v1 kind: Deployment metadata: - name: {{cookiecutter.project_name}}-db + name: {{cookiecutter.kube_name}}-db spec: selector: matchLabels: - app: {{cookiecutter.project_name}}-db + app: {{cookiecutter.kube_name}}-db template: metadata: labels: - app: {{cookiecutter.project_name}}-db + app: {{cookiecutter.kube_name}}-db spec: containers: - name: database @@ -18,16 +19,59 @@ spec: limits: memory: "300Mi" cpu: "200m" + env: + {%- if cookiecutter.db_info.name == 'postgresql' %} + - name: POSTGRES_PASSWORD + value: {{cookiecutter.project_name}} + - name: POSTGRES_USER + value: {{cookiecutter.project_name}} + - name: POSTGRES_DB + value: {{cookiecutter.project_name}} + {%- elif cookiecutter.db_info.name == 'mysql' %} + - name: MYSQL_PASSWORD + value: {{cookiecutter.project_name}} + - name: MYSQL_USER + value: {{cookiecutter.project_name}} + - name: MYSQL_DATABASE + value: {{cookiecutter.project_name}} + - name: ALLOW_EMPTY_PASSWORD + value: "yes" + {%- endif %} ports: - - containerPort: 5432 + - containerPort: {{cookiecutter.db_info.port}} --- apiVersion: v1 kind: Service metadata: - name: "{{cookiecutter.project_name}}-db" + name: "{{cookiecutter.kube_name}}-db-service" spec: selector: - app: {{cookiecutter.project_name}}-db + app: {{cookiecutter.kube_name}}-db ports: - port: {{cookiecutter.db_info.port}} targetPort: {{cookiecutter.db_info.port}} +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: {{cookiecutter.kube_name}}-migrator +spec: + ttlSecondsAfterFinished: 100 + template: + spec: + containers: + - name: migrator + image: {{cookiecutter.project_name}}:latest + command: + - "wait-for-it" + - "-t" + - "180" + - "{{cookiecutter.kube_name}}-db-service:{{cookiecutter.db_info.port}}" + - "--" + - "alembic" + - "upgrade" + - "head" + env: + - name: {{cookiecutter.project_name | upper }}_DB_HOST + value: {{cookiecutter.kube_name}}-db-service + restartPolicy: Never diff --git a/fastapi_template/template/{{cookiecutter.project_name}}/deploy/kube/redis.yml b/fastapi_template/template/{{cookiecutter.project_name}}/deploy/kube/redis.yml index 4e1e304..6ad232f 100644 --- a/fastapi_template/template/{{cookiecutter.project_name}}/deploy/kube/redis.yml +++ b/fastapi_template/template/{{cookiecutter.project_name}}/deploy/kube/redis.yml @@ -1,19 +1,23 @@ +--- apiVersion: apps/v1 kind: Deployment metadata: - name: {{cookiecutter.project_name}}-redis + name: {{cookiecutter.kube_name}}-redis spec: selector: matchLabels: - app: {{cookiecutter.project_name}}-redis + app: {{cookiecutter.kube_name}}-redis template: metadata: labels: - app: {{cookiecutter.project_name}}-redis + app: {{cookiecutter.kube_name}}-redis spec: containers: - name: redis image: bitnami/redis:6.2.5 + env: + - name: ALLOW_EMPTY_PASSWORD + value: "yes" resources: limits: memory: "300Mi" @@ -24,10 +28,10 @@ spec: apiVersion: v1 kind: Service metadata: - name: "{{cookiecutter.project_name}}-redis" + name: "{{cookiecutter.kube_name}}-redis-service" spec: selector: - app: {{cookiecutter.project_name}}-redis + app: {{cookiecutter.kube_name}}-redis ports: - port: 6379 targetPort: 6379 diff --git a/fastapi_template/template/{{cookiecutter.project_name}}/{{cookiecutter.project_name}}/db/migrations/env.py b/fastapi_template/template/{{cookiecutter.project_name}}/{{cookiecutter.project_name}}/db/migrations/env.py index 7ab3146..4e58cd7 100644 --- a/fastapi_template/template/{{cookiecutter.project_name}}/{{cookiecutter.project_name}}/db/migrations/env.py +++ b/fastapi_template/template/{{cookiecutter.project_name}}/{{cookiecutter.project_name}}/db/migrations/env.py @@ -11,7 +11,7 @@ from {{cookiecutter.project_name}}.settings import settings # this is the Alembic Config object, which provides # access to the values within the .ini file in use. -config = context.config +config = context.config # type: ignore load_all_models() -- GitLab