From ddd76b02ca16a170e66b70252cae232ce1eac6bf Mon Sep 17 00:00:00 2001 From: Ricardo Carrillo Cruz Date: Mon, 20 Mar 2023 11:46:36 +0100 Subject: [PATCH] Add extra_settings logic for EDA server --- config/crd/bases/eda.ansible.com_edas.yaml | 10 + ...server-operator.clusterserviceversion.yaml | 5 + .../eda/templates/eda-api.deployment.yaml.j2 | 12 + roles/eda/templates/eda.configmap.yaml.j2 | 234 ++++++++++++++++++ 4 files changed, 261 insertions(+) diff --git a/config/crd/bases/eda.ansible.com_edas.yaml b/config/crd/bases/eda.ansible.com_edas.yaml index f2339823..207a56df 100644 --- a/config/crd/bases/eda.ansible.com_edas.yaml +++ b/config/crd/bases/eda.ansible.com_edas.yaml @@ -189,6 +189,16 @@ spec: nodeport_port: description: Port to use for the nodeport type: integer + extra_settings: + description: Extra settings to specify for the API + items: + properties: + setting: + type: string + value: + x-kubernetes-preserve-unknown-fields: true + type: object + type: array status: description: Status defines the observed state of EDA type: object diff --git a/config/manifests/bases/eda-server-operator.clusterserviceversion.yaml b/config/manifests/bases/eda-server-operator.clusterserviceversion.yaml index 2338131a..478c65a7 100644 --- a/config/manifests/bases/eda-server-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/eda-server-operator.clusterserviceversion.yaml @@ -36,6 +36,11 @@ spec: x-descriptors: - urn:alm:descriptor:com.tectonic.ui:advanced - urn:alm:descriptor:io.kubernetes:Secret + - displayName: API Extra Settings + path: extra_settings + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:advanced + - urn:alm:descriptor:com.tectonic.ui:hidden - displayName: No Log Configuration path: no_log x-descriptors: diff --git a/roles/eda/templates/eda-api.deployment.yaml.j2 b/roles/eda/templates/eda-api.deployment.yaml.j2 index 72b441d0..f1cd4386 100644 --- a/roles/eda/templates/eda-api.deployment.yaml.j2 +++ b/roles/eda/templates/eda-api.deployment.yaml.j2 @@ -63,4 +63,16 @@ spec: ports: - containerPort: 8000 resources: {{ api.resource_requirements }} + volumeMounts: + - name: {{ ansible_operator_meta.name }}-settings + mountPath: /app/src/src/aap_eda/settings/default.py + subPath: default.py + readOnly: true restartPolicy: Always + volumes: + - name: {{ ansible_operator_meta.name }}-settings + configMap: + name: '{{ ansible_operator_meta.name }}-{{ deployment_type }}-configmap' + items: + - key: settings + path: default.py diff --git a/roles/eda/templates/eda.configmap.yaml.j2 b/roles/eda/templates/eda.configmap.yaml.j2 index f3b744c7..c834ddfc 100644 --- a/roles/eda/templates/eda.configmap.yaml.j2 +++ b/roles/eda/templates/eda.configmap.yaml.j2 @@ -8,6 +8,240 @@ metadata: labels: {{ lookup("template", "../common/templates/labels/common.yaml.j2") | indent(width=4) | trim }} data: + settings: | + import dynaconf + + settings = dynaconf.Dynaconf(envvar_prefix="EDA") + + # --------------------------------------------------------- + # DJANGO SETTINGS + # --------------------------------------------------------- + + SECRET_KEY = settings.get("SECRET_KEY") + + DEBUG = settings.get("DEBUG", False) + + ALLOWED_HOSTS = settings.get("ALLOWED_HOSTS", []) + ALLOWED_HOSTS = ( + ALLOWED_HOSTS.split(",") + if isinstance(ALLOWED_HOSTS, str) + else ALLOWED_HOSTS + ) + + + # Application definition + INSTALLED_APPS = [ + "daphne", + # Django apps + "django.contrib.auth", + "django.contrib.contenttypes", + "django.contrib.sessions", + "django.contrib.staticfiles", + # Third party apps + "rest_framework", + "drf_spectacular", + "django_rq", + "django_filters", + # Local apps + "aap_eda.api", + "aap_eda.core", + ] + + MIDDLEWARE = [ + "django.middleware.security.SecurityMiddleware", + "django.contrib.sessions.middleware.SessionMiddleware", + "django.middleware.common.CommonMiddleware", + "django.middleware.csrf.CsrfViewMiddleware", + "django.contrib.auth.middleware.AuthenticationMiddleware", + "django.middleware.clickjacking.XFrameOptionsMiddleware", + ] + + ROOT_URLCONF = "aap_eda.urls" + + TEMPLATES = [ + { + "BACKEND": "django.template.backends.django.DjangoTemplates", + "DIRS": [], + "APP_DIRS": True, + "OPTIONS": { + "context_processors": [ + "django.template.context_processors.debug", + "django.template.context_processors.request", + "django.contrib.auth.context_processors.auth", + ], + }, + }, + ] + + WSGI_APPLICATION = "aap_eda.wsgi.application" + + ASGI_APPLICATION = "aap_eda.asgi.application" + + + # Database + # https://docs.djangoproject.com/en/4.1/ref/settings/#databases + + DATABASES = { + "default": { + "ENGINE": "django.db.backends.postgresql", + "HOST": settings.get("DB_HOST", "127.0.0.1"), + "PORT": settings.get("DB_PORT", 5432), + "USER": settings.get("DB_USER", "postgres"), + "PASSWORD": settings.get("DB_PASSWORD"), + "NAME": settings.get("DB_NAME", "eda"), + } + } + + + # Password validation + # https://docs.djangoproject.com/en/4.1/ref/settings/#auth-password-validators + + AUTH_PASSWORD_VALIDATORS = [ + { + "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator", # noqa: E501 + }, + { + "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", # noqa: E501 + }, + { + "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator", # noqa: E501 + }, + { + "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator", # noqa: E501 + }, + ] + + + # Internationalization + # https://docs.djangoproject.com/en/4.1/topics/i18n/ + + LANGUAGE_CODE = "en-us" + + TIME_ZONE = "UTC" + + USE_I18N = True + + USE_TZ = True + + + # Static files (CSS, JavaScript, Images) + # https://docs.djangoproject.com/en/4.1/howto/static-files/ + + STATIC_URL = "static/" + + MEDIA_ROOT = settings.get("MEDIA_ROOT", "/var/lib/eda/files") + + # Default primary key field type + # https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field + + DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" + + AUTH_USER_MODEL = "core.User" + + REST_FRAMEWORK = { + "DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema", + "DEFAULT_PAGINATION_CLASS": "aap_eda.api.pagination.DefaultPagination", # noqa: E501 + "PAGE_SIZE": 20, + "DEFAULT_AUTHENTICATION_CLASSES": [ + "rest_framework.authentication.SessionAuthentication", + "rest_framework.authentication.BasicAuthentication", + ], + "DEFAULT_PERMISSION_CLASSES": [ + "rest_framework.permissions.IsAuthenticated", + ], + "TEST_REQUEST_DEFAULT_FORMAT": "json", + } + + # --------------------------------------------------------- + # TASKING SETTINGS + # --------------------------------------------------------- + RQ = { + "QUEUE_CLASS": "aap_eda.core.tasking.Queue", + "JOB_CLASS": "aap_eda.core.tasking.Job", + } + + RQ_UNIX_SOCKET_PATH = settings.get("MQ_UNIX_SOCKET_PATH", None) + + if RQ_UNIX_SOCKET_PATH: + RQ_QUEUES = { + "default": { + "UNIX_SOCKET_PATH": RQ_UNIX_SOCKET_PATH, + }, + } + else: + RQ_QUEUES = { + "default": { + "HOST": settings.get("MQ_HOST", "localhost"), + "PORT": settings.get("MQ_PORT", 6379), + } + } + RQ_QUEUES["default"]["DB"] = settings.get("MQ_DB", 0) + + # --------------------------------------------------------- + # APPLICATION SETTINGS + # --------------------------------------------------------- + + API_PREFIX = settings.get("API_PREFIX", "api/eda").strip("/") + + SPECTACULAR_SETTINGS = { + "TITLE": "Event Driven Ansible API", + "VERSION": "1.0.0", + "SERVE_INCLUDE_SCHEMA": False, + "SCHEMA_PATH_PREFIX": f"/{API_PREFIX}/v[0-9]", + "SCHEMA_PATH_PREFIX_TRIM": True, + "SERVERS": [{"url": f"/{API_PREFIX}/v1"}], + "PREPROCESSING_HOOKS": [ + "aap_eda.api.openapi.preprocess_filter_api_routes" + ], + } + + # --------------------------------------------------------- + # LOGGING SETTINGS + # --------------------------------------------------------- + + APP_LOG_LEVEL = settings.get("APP_LOG_LEVEL", "INFO") + + LOGGING = { + "version": 1, + "disable_existing_loggers": False, + "formatters": { + "simple": { + "format": "{asctime} {levelname:<8} {message}", + "style": "{", + }, + }, + "handlers": { + "console": {"class": "logging.StreamHandler", "formatter": "simple"}, + }, + "root": {"handlers": ["console"], "level": "WARNING"}, + "loggers": { + "django": { + "handlers": ["console"], + "level": "WARNING", + "propagate": False, + }, + "django.request": { + "handlers": ["console"], + "level": "INFO", + "propagate": False, + }, + "django.channels.server": { + "handlers": ["console"], + "level": "INFO", + "propagate": False, + }, + "aap_eda": { + "handlers": ["console"], + "level": APP_LOG_LEVEL, + "propagate": False, + }, + }, + } + + {% for item in extra_settings | default([]) %} + {{ item.setting }} = {{ item.value }} + {% endfor %} + nginx_conf: | events { worker_connections 1024;