diff --git a/.gitignore b/.gitignore index 9a6a0f0..d8db69f 100644 --- a/.gitignore +++ b/.gitignore @@ -6,15 +6,7 @@ .vscode/ -**/storage-secret.yaml - -**/backend-secret.yaml - -**/frontend-secret.yaml - -**/postgres-secret.yaml - -**/redis-secret.yaml +**/*.json **/cert-manager-certificate.yaml diff --git a/setup.py b/setup.py index 5e0fc16..b332109 100644 --- a/setup.py +++ b/setup.py @@ -3,40 +3,17 @@ from dotenv import load_dotenv from envsubst import envsubst from pathlib import Path, PosixPath import argparse +import warnings +import json import os -ENV_VARIABLES = [ - "FRONTEND_PATH", - "BACKEND_URL", - "BACKEND_OAUTH_URL", - "TOKEN_SECRET", - "ACCESS_TOKEN_DURATION", - "REFRESH_TOKEN_DURATION", - "DEFAULT_USER_FULLNAME", - "DEFAULT_USER_EMAIL", - "DEFAULT_USER_USERNAME", - "DEFAULT_USER_PASSWORD", - "GOOGLE_CLIENT_ID", - "GOOGLE_CLIENT_SECRET", - "GOOGLE_REDIRECT_URL", - "OAUTH_GITHUB_CLIENT_ID", - "OAUTH_GITHUB_CLIENT_SECRET", - "OAUTH_GITHUB_REDIRECT_URL", - "POSTGRES_USER", - "POSTGRES_PASSWORD", - "POSTGRES_DB", - "REDIS_PASSWORD", - "STORAGE_TYPE", - "AWS_ACCESS_KEY_ID", - "AWS_SECRET_ACCESS_KEY", - "AWS_REGION_NAME", - "AWS_BUCKET_NAME", - "VIRUS_CHECKER_TYPE", - "VIRUS_CHECKER_API_KEY", -] +def write_template(template: str, output: str): + with open(template, 'r') as template,\ + open(output, 'w') as output: + output.write(envsubst(template.read())) -def setting_environment(environment: str): +def configure_templates(environment: str): if not environment in ("prod", "staging", "local", "dev"): raise ValueError("Invalid Environment Selected") @@ -54,48 +31,146 @@ def setting_environment(environment: str): os.environ["DOMAIN"] = DOMAIN os.environ["API_DOMAIN"] = API_DOMAIN + write_template( + "template/cert-manager/cert-manager-certificate.template.yaml", + "deployment/cert-manager/cert-manager-certificate.yaml" + ) -def load_secret_file(file: str): - secret_file_path = Path(file) - if not secret_file_path.exists(): - raise FileNotFoundError("Secret File Doesn't Exists") + write_template( + "template/nginx-ingress/nginx-ingress-api.yaml", + "deployment/nginx-ingress/nginx-ingress-api.yaml" + ) - load_dotenv(dotenv_path=secret_file_path) + write_template( + "template/nginx-ingress/nginx-ingress-root.yaml", + "deployment/nginx-ingress/nginx-ingress-root.yaml" + ) -def fetch_env_variables(): - for env in ENV_VARIABLES: - value = os.environ[env] - value = value.encode("utf-8") - os.environ[env] = b64encode(value).decode() +def validate_backend_secret(secret: str): + required_keys = [ + 'tokenSecret', + 'accessTokenDuration', + 'refreshTokenDuration', + 'defaultUserFullName', + 'defaultUserEmail', + 'defaultUserUsername', + 'defaultUserPassword', + 'googleClientId', + 'googleClientSecret', + 'googleRedirectUrl', + 'githubClientId', + 'githubClientSecret', + 'githubRedirectUrl' + ] + + for key in required_keys: + if key not in secret: + raise ValueError(f"Key {key} not found in backendSecret") -def envsubst_file(file: PosixPath): - with open(file) as f: - formated_file = envsubst(f.read()) +def validate_frontend_secret(secret: str): + required_keys = [ + 'frontendPath', + 'backendUrl', + 'backendOAuthUrl', + ] - new_file = Path("deployment") \ - .joinpath(*[part.split('.')[0] for part in file.parts if part != "template"]) \ - .with_suffix(".yaml") - - with open(new_file, 'w') as f: - f.write(formated_file) + for key in required_keys: + if key not in secret: + raise ValueError(f"Key {key} not found in frontendSecret") -def substitute_secrets_from_templates(): - for subdir in Path("template").glob("*"): - for file in subdir.glob("*.yaml"): - envsubst_file(file) +def validate_postgres_secret(secret: str): + required_keys = [ + 'postgresUser', + 'postgresPassword', + 'postgresDatabase' + ] + + for key in required_keys: + if key not in secret: + raise ValueError(f"Key {key} not found in postgresSecret") + + + +def validate_redis_secret(secret: str): + required_keys = [ + 'redisPassword', + ] + + for key in required_keys: + if key not in secret: + raise ValueError(f"Key {key} not found in redisSecret") + + +def validate_storage_secret(secret: str): + required_keys = [ + 'storageType', + 'awsAccessKeyId', + 'awsSecretAccessKey', + 'awsRegion', + 'awsBucket', + 'virusCheckerType', + 'virusCheckerApiKey', + ] + + for key in required_keys: + if key not in secret: + raise ValueError(f"Key {key} not found in storageSecret") + + + + +def validate_env(env: dict): + required_secrets = [ + 'backendSecret', + 'frontendSecret', + 'postgresSecret', + 'redisSecret', + 'storageSecret', + ] + + for secret in required_secrets: + if secret not in env: + raise ValueError(f"Secret {secret} not found in env.json") + + if secret == 'backendSecret': + validate_backend_secret(env[secret]) + + if secret == 'frontendSecret': + validate_frontend_secret(env[secret]) + + if secret == 'postgresSecret': + validate_postgres_secret(env[secret]) + + if secret == 'redisSecret': + validate_redis_secret(env[secret]) + + if secret == 'storageSecret': + validate_storage_secret(env[secret]) + +def write_secrets_to_file(env: dict): + for key, secret in env.items(): + dir = Path("deployment", "secrets") + + with open(dir.joinpath(f"{key}.json"), "w") as f: + json.dump(secret, f, indent=4) + + +def read_env_json(file: str) -> dict: + with open(file, "r") as f: + return json.load(f) def main(file, environment): - setting_environment(environment) + env = read_env_json(file) - load_secret_file(file) + validate_env(env) - fetch_env_variables() + write_secrets_to_file(env) - substitute_secrets_from_templates() + configure_templates(environment) if __name__ == "__main__": diff --git a/template/backend/backend-secret.template.yaml b/template/backend/backend-secret.template.yaml deleted file mode 100644 index 5791e76..0000000 --- a/template/backend/backend-secret.template.yaml +++ /dev/null @@ -1,20 +0,0 @@ -apiVersion: v1 -kind: Secret -metadata: - namespace: portfolio - name: backend-secret -type: Opaque -data: - token_secret: $TOKEN_SECRET - access_token_duration: $ACCESS_TOKEN_DURATION - refresh_token_duration: $REFRESH_TOKEN_DURATION - default_user_fullname: $DEFAULT_USER_FULLNAME - default_user_email: $DEFAULT_USER_EMAIL - default_user_username: $DEFAULT_USER_USERNAME - default_user_password: $DEFAULT_USER_PASSWORD - google_client_id: $GOOGLE_CLIENT_ID - google_client_secret: $GOOGLE_CLIENT_SECRET - google_redirect_url: $GOOGLE_REDIRECT_URL - github_client_id: $OAUTH_GITHUB_CLIENT_ID - github_client_secret: $OAUTH_GITHUB_CLIENT_SECRET - github_redirect_url: $OAUTH_GITHUB_REDIRECT_URL diff --git a/template/frontend/frontend-secret.template.yaml b/template/frontend/frontend-secret.template.yaml deleted file mode 100644 index 51e27b0..0000000 --- a/template/frontend/frontend-secret.template.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: v1 -kind: Secret -metadata: - namespace: portfolio - name: frontend-secret -type: Opaque -data: - frontend_path: $FRONTEND_PATH - backend_url: $BACKEND_URL - backend_oauth_url: $BACKEND_OAUTH_URL \ No newline at end of file diff --git a/template/postgres/postgres-secret.template.yaml b/template/postgres/postgres-secret.template.yaml deleted file mode 100644 index d410139..0000000 --- a/template/postgres/postgres-secret.template.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: v1 -kind: Secret -metadata: - namespace: portfolio - name: postgres-secret -type: Opaque -data: - POSTGRES_USER: $POSTGRES_USER - POSTGRES_PASSWORD: $POSTGRES_PASSWORD - POSTGRES_DB: $POSTGRES_DB \ No newline at end of file diff --git a/template/redis/redis-secret.template.yaml b/template/redis/redis-secret.template.yaml deleted file mode 100644 index 4d91d9e..0000000 --- a/template/redis/redis-secret.template.yaml +++ /dev/null @@ -1,8 +0,0 @@ -apiVersion: v1 -kind: Secret -metadata: - namespace: portfolio - name: redis-secret -type: Opaque -data: - redis-password: $REDIS_PASSWORD \ No newline at end of file diff --git a/template/storage/storage-secret.template.yaml b/template/storage/storage-secret.template.yaml deleted file mode 100644 index 959a281..0000000 --- a/template/storage/storage-secret.template.yaml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: v1 -kind: Secret -metadata: - namespace: portfolio - name: storage-secret -type: Opaque -data: - storage_type: $STORAGE_TYPE - aws_access_key_id: $AWS_ACCESS_KEY_ID - aws_access_access_key: $AWS_SECRET_ACCESS_KEY - aws_region_name: $AWS_REGION_NAME - aws_bucket_name: $AWS_BUCKET_NAME - virus_checker_type: $VIRUS_CHECKER_TYPE - virus_checher_api_key: $VIRUS_CHECKER_API_KEY \ No newline at end of file