Merge pull request #1234 from dod-ccpo/kv-flask-config
Use Key Vault for Flask application config
This commit is contained in:
commit
d9c79b9b58
@ -3,7 +3,7 @@
|
||||
"files": "^.secrets.baseline$|^.*pgsslrootcert.yml$",
|
||||
"lines": null
|
||||
},
|
||||
"generated_at": "2019-12-03T19:44:47Z",
|
||||
"generated_at": "2019-12-05T17:54:05Z",
|
||||
"plugins_used": [
|
||||
{
|
||||
"base64_limit": 4.5,
|
||||
@ -98,7 +98,7 @@
|
||||
"hashed_secret": "afc848c316af1a89d49826c5ae9d00ed769415f3",
|
||||
"is_secret": false,
|
||||
"is_verified": false,
|
||||
"line_number": 21,
|
||||
"line_number": 29,
|
||||
"type": "Secret Keyword"
|
||||
}
|
||||
],
|
||||
|
17
README.md
17
README.md
@ -168,12 +168,7 @@ Testing file uploads and downloads locally requires a few configuration options.
|
||||
In the flask config (`config/base.ini`, perhaps):
|
||||
|
||||
```
|
||||
CSP=<aws | azure | mock>
|
||||
|
||||
AWS_REGION_NAME=""
|
||||
AWS_ACCESS_KEY=""
|
||||
AWS_SECRET_KEY=""
|
||||
AWS_BUCKET_NAME=""
|
||||
CSP=< azure | mock>
|
||||
|
||||
AZURE_STORAGE_KEY=""
|
||||
AZURE_ACCOUNT_NAME=""
|
||||
@ -183,7 +178,7 @@ AZURE_TO_BUCKET_NAME=""
|
||||
There are also some build-time configuration that are used by parcel. Add these to `.env.local`, and run `rm -r .cache/` before running `yarn build`:
|
||||
|
||||
```
|
||||
CLOUD_PROVIDER=<aws | azure | mock>
|
||||
CLOUD_PROVIDER=<azure | mock>
|
||||
AZURE_ACCOUNT_NAME=""
|
||||
AZURE_CONTAINER_NAME=""
|
||||
```
|
||||
@ -223,6 +218,9 @@ To generate coverage reports for the Javascript tests:
|
||||
## Configuration
|
||||
|
||||
- `ASSETS_URL`: URL to host which serves static assets (such as a CDN).
|
||||
- `AZURE_ACCOUNT_NAME`: The name for the Azure blob storage account
|
||||
- `AZURE_STORAGE_KEY`: A valid secret key for the Azure blob storage account
|
||||
- `AZURE_TO_BUCKET_NAME`: The Azure blob storage container name for task order uploads
|
||||
- `BLOB_STORAGE_URL`: URL to Azure blob storage container.
|
||||
- `CAC_URL`: URL for the CAC authentication route.
|
||||
- `CA_CHAIN`: Path to the CA chain file.
|
||||
@ -238,6 +236,11 @@ To generate coverage reports for the Javascript tests:
|
||||
- `ENVIRONMENT`: String specifying the current environment. Acceptable values: "dev", "prod".
|
||||
- `LIMIT_CONCURRENT_SESSIONS`: Boolean specifying if users should be allowed only one active session at a time.
|
||||
- `LOG_JSON`: Boolean specifying whether app should log in a json format.
|
||||
- `MAIL_PASSWORD`: String. Password for the SMTP server.
|
||||
- `MAIL_PORT`: Integer. Port to use on the SMTP server.
|
||||
- `MAIL_SENDER`: String. Email address to send outgoing mail from.
|
||||
- `MAIL_SERVER`: The SMTP host
|
||||
- `MAIL_TLS`: Boolean. Use TLS to connect to the SMTP server.
|
||||
- `PERMANENT_SESSION_LIFETIME`: Integer specifying how many seconds a user's session can stay valid for. https://flask.palletsprojects.com/en/1.1.x/config/#PERMANENT_SESSION_LIFETIME
|
||||
- `PGDATABASE`: String specifying the name of the postgres database.
|
||||
- `PGHOST`: String specifying the hostname of the postgres database.
|
||||
|
42
atst/app.py
42
atst/app.py
@ -200,23 +200,21 @@ def make_config(direct_config=None):
|
||||
ENV_CONFIG_FILENAME = os.path.join(
|
||||
os.path.dirname(__file__), "../config/", "{}.ini".format(ENV.lower())
|
||||
)
|
||||
OVERRIDE_CONFIG_FILENAME = os.getenv("OVERRIDE_CONFIG_FULLPATH")
|
||||
OVERRIDE_CONFIG_DIRECTORY = os.getenv("OVERRIDE_CONFIG_DIRECTORY")
|
||||
|
||||
config = ConfigParser(allow_no_value=True)
|
||||
config.optionxform = str
|
||||
|
||||
config_files = [BASE_CONFIG_FILENAME, ENV_CONFIG_FILENAME]
|
||||
if OVERRIDE_CONFIG_FILENAME:
|
||||
config_files.append(OVERRIDE_CONFIG_FILENAME)
|
||||
|
||||
# ENV_CONFIG will override values in BASE_CONFIG.
|
||||
config.read(config_files)
|
||||
|
||||
if OVERRIDE_CONFIG_DIRECTORY:
|
||||
apply_config_from_directory(OVERRIDE_CONFIG_DIRECTORY, config)
|
||||
|
||||
# Check for ENV variables as a final source of overrides
|
||||
for confsetting in config.options("default"):
|
||||
env_override = os.getenv(confsetting.upper())
|
||||
if env_override:
|
||||
config.set("default", confsetting, env_override)
|
||||
apply_config_from_environment(config)
|
||||
|
||||
# override if a dictionary of options has been given
|
||||
if direct_config:
|
||||
@ -244,6 +242,36 @@ def make_config(direct_config=None):
|
||||
return map_config(config)
|
||||
|
||||
|
||||
def apply_config_from_directory(config_dir, config, section="default"):
|
||||
"""
|
||||
Loop files in a directory, check if the names correspond to
|
||||
known config values, and apply the file contents as the value
|
||||
for that setting if they do.
|
||||
"""
|
||||
for confsetting in os.listdir(config_dir):
|
||||
if confsetting in config.options(section):
|
||||
full_path = os.path.join(config_dir, confsetting)
|
||||
with open(full_path, "r") as conf_file:
|
||||
config.set(section, confsetting, conf_file.read().strip())
|
||||
|
||||
return config
|
||||
|
||||
|
||||
def apply_config_from_environment(config, section="default"):
|
||||
"""
|
||||
Loops all the configuration settins in a given section of a
|
||||
config object and checks whether those settings also exist as
|
||||
environment variables. If so, it applies the environment
|
||||
variables value as the new configuration setting value.
|
||||
"""
|
||||
for confsetting in config.options(section):
|
||||
env_override = os.getenv(confsetting.upper())
|
||||
if env_override:
|
||||
config.set(section, confsetting, env_override)
|
||||
|
||||
return config
|
||||
|
||||
|
||||
def make_redis(app, config):
|
||||
r = redis.Redis.from_url(config["REDIS_URI"])
|
||||
app.redis = r
|
||||
|
@ -1,5 +1,8 @@
|
||||
[default]
|
||||
ASSETS_URL
|
||||
AZURE_ACCOUNT_NAME
|
||||
AZURE_STORAGE_KEY
|
||||
AZURE_TO_BUCKET_NAME
|
||||
BLOB_STORAGE_URL=http://localhost:8000/
|
||||
CAC_URL = http://localhost:8000/login-redirect
|
||||
CA_CHAIN = ssl/server-certs/ca-chain.pem
|
||||
@ -15,6 +18,11 @@ DISABLE_CRL_CHECK = false
|
||||
ENVIRONMENT = dev
|
||||
LIMIT_CONCURRENT_SESSIONS = false
|
||||
LOG_JSON = false
|
||||
MAIL_PASSWORD
|
||||
MAIL_PORT
|
||||
MAIL_SENDER
|
||||
MAIL_SERVER
|
||||
MAIL_TLS
|
||||
PERMANENT_SESSION_LIFETIME = 1800
|
||||
PGDATABASE = atat
|
||||
PGHOST = localhost
|
||||
|
@ -37,35 +37,6 @@ If you are satisfied with the output from the diff, you can apply the new config
|
||||
|
||||
## Secrets and Configuration
|
||||
|
||||
### atst-overrides.ini
|
||||
|
||||
Production configuration values are provided to the ATAT Flask app by writing an `atst-overrides.ini` file to the running Docker container. This file is stored as a Kubernetes secret. It contains configuration information for the database connection, mailer, etc.
|
||||
|
||||
To update the configuration, you can do the following:
|
||||
|
||||
```
|
||||
kubectl -n atat get secret atst-config-ini -o=jsonpath='{.data.override\.ini}' | base64 --decode > override.ini
|
||||
```
|
||||
|
||||
This base64 decodes the secret and writes it to a local file called `override.ini`. Make any necessary config changes to that file.
|
||||
|
||||
To apply the new config, first delete the existing copy of the secret:
|
||||
|
||||
```
|
||||
kubectl -n atat delete secret atst-config-ini
|
||||
```
|
||||
|
||||
Then create a new copy of the secret from your updated copy:
|
||||
|
||||
```
|
||||
kubectl -n atat create secret generic atst-config-ini --from-file=./override.ini
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
||||
- Be careful not to check the override.ini file into source control.
|
||||
- Be careful not to overwrite one CSP cluster's config with the other's. This will break everything.
|
||||
|
||||
### nginx-htpasswd
|
||||
|
||||
If the site is running in dev mode, the `/login-dev` endpoint is available. This endpoint is protected by basic HTTP auth. To create a new password file, run:
|
||||
@ -178,11 +149,32 @@ az keyvault secret set --vault-name <VAULT NAME> --name <NAME OF PARAM> --value
|
||||
```
|
||||
---
|
||||
|
||||
# Secrets Management
|
||||
|
||||
Secrets, keys, and certificates are managed from Azure Key Vault. These items are mounted into the containers at runtime using the FlexVol implementation described below.
|
||||
|
||||
The following are mounted into the NGINX container in the atst pod:
|
||||
|
||||
- The TLS certs for the site
|
||||
- The DH parameter for TLS connections
|
||||
|
||||
These are mounted into every instance of the Flask application container (the atst container, the celery worker, etc.):
|
||||
|
||||
- The Azure storage key used to access blob storage (AZURE_STORAGE_KEY)
|
||||
- The password for the SMTP server used to send mail (MAIL_PASSWORD)
|
||||
- The Postgres database user password (PGPASSWORD)
|
||||
- The Redis user password (REDIS_PASSWORD)
|
||||
- The Flask secret key used for session signing and generating CSRF tokens (SECRET_KEY)
|
||||
|
||||
Secrets should be added to Key Vault with the following naming pattern: [branch/environment]-[all-caps config setting name]. Note that Key Vault does not support underscores. Substitute hyphens. For example, the config setting for the SMTP server password is MAIL_SERVER. The corresponding secret name in Key Vault is "master-MAIL-SERVER" for the credential used in the primary environment.These secrets are mounted into the containers via FlexVol.
|
||||
|
||||
To add or manage secrets, keys, and certificates in Key Vault, see the [documentation](https://docs.microsoft.com/en-us/azure/key-vault/quick-create-cli).
|
||||
|
||||
# Setting Up FlexVol for Secrets
|
||||
|
||||
## Preparing Azure Environment
|
||||
|
||||
A Key Vault will need to be created. Save it's full id (the full path) for use later.
|
||||
A Key Vault will need to be created. Save its full id (the full path) for use later.
|
||||
|
||||
## Preparing Cluster
|
||||
|
||||
|
@ -6,15 +6,28 @@ metadata:
|
||||
namespace: atat
|
||||
data:
|
||||
ASSETS_URL: https://atat-cdn.azureedge.net/
|
||||
AZURE_ACCOUNT_NAME: atat
|
||||
AZURE_TO_BUCKET_NAME: task-order-pdfs
|
||||
BLOB_STORAGE_URL: https://atat.blob.core.windows.net/
|
||||
CAC_URL: https://auth-staging.atat.code.mil/login-redirect
|
||||
CDN_ORIGIN: https://azure.atat.code.mil
|
||||
CELERY_DEFAULT_QUEUE: celery-master
|
||||
CSP: azure
|
||||
DEBUG: 0
|
||||
FLASK_ENV: master
|
||||
LOG_JSON: "true"
|
||||
OVERRIDE_CONFIG_FULLPATH: /opt/atat/atst/atst-overrides.ini
|
||||
MAIL_PORT: 587
|
||||
MAIL_SENDER: postmaster@atat.code.mil
|
||||
MAIL_SERVER: smtp.mailgun.org
|
||||
MAIL_TLS: "true"
|
||||
OVERRIDE_CONFIG_DIRECTORY: /config
|
||||
PGAPPNAME: atst
|
||||
PGDATABASE: staging
|
||||
PGHOST: atat-db.postgres.database.azure.com
|
||||
PGPORT: 5432
|
||||
PGSSLMODE: verify-full
|
||||
PGSSLROOTCERT: /opt/atat/atst/ssl/pgsslrootcert.crt
|
||||
PGUSER: atat_master@atat-db
|
||||
REDIS_HOST: atat.redis.cache.windows.net:6380
|
||||
REDIS_TLS: "true"
|
||||
STATIC_URL: https://atat-cdn.azureedge.net/static/
|
||||
|
@ -5,9 +5,25 @@ metadata:
|
||||
name: atst-worker-envvars
|
||||
namespace: atat
|
||||
data:
|
||||
AZURE_ACCOUNT_NAME: atat
|
||||
AZURE_TO_BUCKET_NAME: task-order-pdfs
|
||||
CAC_URL: https://auth-staging.atat.code.mil/login-redirect
|
||||
CELERY_DEFAULT_QUEUE: celery-master
|
||||
DISABLE_CRL_CHECK: "True"
|
||||
DEBUG: 0
|
||||
DISABLE_CRL_CHECK: "true"
|
||||
MAIL_PORT: 587
|
||||
MAIL_SENDER: postmaster@atat.code.mil
|
||||
MAIL_SERVER: smtp.mailgun.org
|
||||
MAIL_TLS: "true"
|
||||
OVERRIDE_CONFIG_DIRECTORY: /config
|
||||
PGAPPNAME: atst
|
||||
PGDATABASE: staging
|
||||
PGHOST: atat-db.postgres.database.azure.com
|
||||
PGPORT: 5432
|
||||
PGSSLMODE: verify-full
|
||||
PGSSLROOTCERT: /opt/atat/atst/ssl/pgsslrootcert.crt
|
||||
PGUSER: atat_master@atat-db
|
||||
REDIS_HOST: atat.redis.cache.windows.net:6380
|
||||
REDIS_TLS: "true"
|
||||
SERVER_NAME: azure.atat.code.mil
|
||||
TZ: UTC
|
||||
|
@ -34,9 +34,6 @@ spec:
|
||||
- configMapRef:
|
||||
name: atst-envvars
|
||||
volumeMounts:
|
||||
- name: atst-config
|
||||
mountPath: "/opt/atat/atst/atst-overrides.ini"
|
||||
subPath: atst-overrides.ini
|
||||
- name: nginx-client-ca-bundle
|
||||
mountPath: "/opt/atat/atst/ssl/server-certs/ca-chain.pem"
|
||||
subPath: client-ca-bundle.pem
|
||||
@ -50,6 +47,8 @@ spec:
|
||||
- name: uwsgi-config
|
||||
mountPath: "/opt/atat/atst/uwsgi.ini"
|
||||
subPath: uwsgi.ini
|
||||
- name: flask-secret
|
||||
mountPath: "/config"
|
||||
- name: nginx
|
||||
image: nginx:alpine
|
||||
ports:
|
||||
@ -79,13 +78,6 @@ spec:
|
||||
- name: nginx-secret
|
||||
mountPath: "/etc/ssl/"
|
||||
volumes:
|
||||
- name: atst-config
|
||||
secret:
|
||||
secretName: atst-config-ini
|
||||
items:
|
||||
- key: override.ini
|
||||
path: atst-overrides.ini
|
||||
mode: 0644
|
||||
- name: nginx-client-ca-bundle
|
||||
configMap:
|
||||
name: nginx-client-ca-bundle
|
||||
@ -141,6 +133,16 @@ spec:
|
||||
keyvaultobjectaliases: "dhparam.pem;atat.key;atat.crt"
|
||||
keyvaultobjecttypes: "secret;secret;secret"
|
||||
tenantid: $TENANT_ID
|
||||
- name: flask-secret
|
||||
flexVolume:
|
||||
driver: "azure/kv"
|
||||
options:
|
||||
usepodidentity: "true"
|
||||
keyvaultname: "atat-vault-test"
|
||||
keyvaultobjectnames: "master-AZURE-STORAGE-KEY;master-MAIL-PASSWORD;master-PGPASSWORD;master-REDIS-PASSWORD;master-SECRET-KEY"
|
||||
keyvaultobjectaliases: "AZURE_STORAGE_KEY;MAIL_PASSWORD;PGPASSWORD;REDIS_PASSWORD;SECRET_KEY"
|
||||
keyvaultobjecttypes: "secret;secret;secret;secret;key"
|
||||
tenantid: $TENANT_ID
|
||||
---
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
@ -161,6 +163,7 @@ spec:
|
||||
labels:
|
||||
app: atst
|
||||
role: worker
|
||||
aadpodidbinding: atat-kv-id-binding
|
||||
spec:
|
||||
securityContext:
|
||||
fsGroup: 101
|
||||
@ -182,20 +185,12 @@ spec:
|
||||
- configMapRef:
|
||||
name: atst-worker-envvars
|
||||
volumeMounts:
|
||||
- name: atst-config
|
||||
mountPath: "/opt/atat/atst/atst-overrides.ini"
|
||||
subPath: atst-overrides.ini
|
||||
- name: pgsslrootcert
|
||||
mountPath: "/opt/atat/atst/ssl/pgsslrootcert.crt"
|
||||
subPath: pgsslrootcert.crt
|
||||
- name: flask-secret
|
||||
mountPath: "/config"
|
||||
volumes:
|
||||
- name: atst-config
|
||||
secret:
|
||||
secretName: atst-config-ini
|
||||
items:
|
||||
- key: override.ini
|
||||
path: atst-overrides.ini
|
||||
mode: 0644
|
||||
- name: pgsslrootcert
|
||||
configMap:
|
||||
name: pgsslrootcert
|
||||
@ -203,6 +198,16 @@ spec:
|
||||
- key: cert
|
||||
path: pgsslrootcert.crt
|
||||
mode: 0666
|
||||
- name: flask-secret
|
||||
flexVolume:
|
||||
driver: "azure/kv"
|
||||
options:
|
||||
usepodidentity: "true"
|
||||
keyvaultname: "atat-vault-test"
|
||||
keyvaultobjectnames: "master-AZURE-STORAGE-KEY;master-MAIL-PASSWORD;master-PGPASSWORD;master-REDIS-PASSWORD;master-SECRET-KEY"
|
||||
keyvaultobjectaliases: "AZURE_STORAGE_KEY;MAIL_PASSWORD;PGPASSWORD;REDIS_PASSWORD;SECRET_KEY"
|
||||
keyvaultobjecttypes: "secret;secret;secret;secret;key"
|
||||
tenantid: $TENANT_ID
|
||||
---
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
@ -223,6 +228,7 @@ spec:
|
||||
labels:
|
||||
app: atst
|
||||
role: beat
|
||||
aadpodidbinding: atat-kv-id-binding
|
||||
spec:
|
||||
securityContext:
|
||||
fsGroup: 101
|
||||
@ -244,20 +250,12 @@ spec:
|
||||
- configMapRef:
|
||||
name: atst-worker-envvars
|
||||
volumeMounts:
|
||||
- name: atst-config
|
||||
mountPath: "/opt/atat/atst/atst-overrides.ini"
|
||||
subPath: atst-overrides.ini
|
||||
- name: pgsslrootcert
|
||||
mountPath: "/opt/atat/atst/ssl/pgsslrootcert.crt"
|
||||
subPath: pgsslrootcert.crt
|
||||
- name: flask-secret
|
||||
mountPath: "/config"
|
||||
volumes:
|
||||
- name: atst-config
|
||||
secret:
|
||||
secretName: atst-config-ini
|
||||
items:
|
||||
- key: override.ini
|
||||
path: atst-overrides.ini
|
||||
mode: 0644
|
||||
- name: pgsslrootcert
|
||||
configMap:
|
||||
name: pgsslrootcert
|
||||
@ -265,6 +263,16 @@ spec:
|
||||
- key: cert
|
||||
path: pgsslrootcert.crt
|
||||
mode: 0666
|
||||
- name: flask-secret
|
||||
flexVolume:
|
||||
driver: "azure/kv"
|
||||
options:
|
||||
usepodidentity: "true"
|
||||
keyvaultname: "atat-vault-test"
|
||||
keyvaultobjectnames: "master-AZURE-STORAGE-KEY;master-MAIL-PASSWORD;master-PGPASSWORD;master-REDIS-PASSWORD;master-SECRET-KEY"
|
||||
keyvaultobjectaliases: "AZURE_STORAGE_KEY;MAIL_PASSWORD;PGPASSWORD;REDIS_PASSWORD;SECRET_KEY"
|
||||
keyvaultobjecttypes: "secret;secret;secret;secret;key"
|
||||
tenantid: $TENANT_ID
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
|
@ -10,6 +10,11 @@ spec:
|
||||
jobTemplate:
|
||||
spec:
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: atst
|
||||
role: crl-sync
|
||||
aadpodidbinding: atat-kv-id-binding
|
||||
spec:
|
||||
restartPolicy: OnFailure
|
||||
containers:
|
||||
@ -27,19 +32,21 @@ spec:
|
||||
- configMapRef:
|
||||
name: atst-worker-envvars
|
||||
volumeMounts:
|
||||
- name: atst-config
|
||||
mountPath: "/opt/atat/atst/atst-overrides.ini"
|
||||
subPath: atst-overrides.ini
|
||||
- name: crls-vol
|
||||
mountPath: "/opt/atat/atst/crls"
|
||||
- name: flask-secret
|
||||
mountPath: "/config"
|
||||
volumes:
|
||||
- name: atst-config
|
||||
secret:
|
||||
secretName: atst-config-ini
|
||||
items:
|
||||
- key: override.ini
|
||||
path: atst-overrides.ini
|
||||
mode: 0644
|
||||
- name: crls-vol
|
||||
persistentVolumeClaim:
|
||||
claimName: crls-vol-claim
|
||||
- name: flask-secret
|
||||
flexVolume:
|
||||
driver: "azure/kv"
|
||||
options:
|
||||
usepodidentity: "true"
|
||||
keyvaultname: "atat-vault-test"
|
||||
keyvaultobjectnames: "master-AZURE-STORAGE-KEY;master-MAIL-PASSWORD;master-PGPASSWORD;master-REDIS-PASSWORD;master-SECRET-KEY"
|
||||
keyvaultobjectaliases: "AZURE_STORAGE_KEY;MAIL_PASSWORD;PGPASSWORD;REDIS_PASSWORD;SECRET_KEY"
|
||||
keyvaultobjecttypes: "secret;secret;secret;secret;key"
|
||||
tenantid: $TENANT_ID
|
||||
|
@ -11,3 +11,52 @@ spec:
|
||||
options:
|
||||
keyvaultname: "atat-vault-test"
|
||||
keyvaultobjectnames: "dhparam4096;staging-cert;staging-cert"
|
||||
- name: flask-secret
|
||||
flexVolume:
|
||||
options:
|
||||
keyvaultname: "atat-vault-test"
|
||||
keyvaultobjectnames: "staging-AZURE-STORAGE-KEY;staging-MAIL-PASSWORD;staging-PGPASSWORD;staging-REDIS-PASSWORD;staging-SECRET-KEY"
|
||||
---
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: atst-worker
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
volumes:
|
||||
- name: flask-secret
|
||||
flexVolume:
|
||||
options:
|
||||
keyvaultname: "atat-vault-test"
|
||||
keyvaultobjectnames: "staging-AZURE-STORAGE-KEY;staging-MAIL-PASSWORD;staging-PGPASSWORD;staging-REDIS-PASSWORD;staging-SECRET-KEY"
|
||||
---
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: atst-beat
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
volumes:
|
||||
- name: flask-secret
|
||||
flexVolume:
|
||||
options:
|
||||
keyvaultname: "atat-vault-test"
|
||||
keyvaultobjectnames: "staging-AZURE-STORAGE-KEY;staging-MAIL-PASSWORD;staging-PGPASSWORD;staging-REDIS-PASSWORD;staging-SECRET-KEY"
|
||||
---
|
||||
apiVersion: batch/v1beta1
|
||||
kind: CronJob
|
||||
metadata:
|
||||
name: crls
|
||||
spec:
|
||||
jobTemplate:
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
volumes:
|
||||
- name: flask-secret
|
||||
flexVolume:
|
||||
options:
|
||||
keyvaultname: "atat-vault-test"
|
||||
keyvaultobjectnames: "staging-AZURE-STORAGE-KEY;staging-MAIL-PASSWORD;staging-PGPASSWORD;staging-REDIS-PASSWORD;staging-SECRET-KEY"
|
||||
|
@ -7,6 +7,11 @@ spec:
|
||||
ttlSecondsAfterFinished: 100
|
||||
backoffLimit: 2
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: atst
|
||||
role: migration
|
||||
aadpodidbinding: atat-kv-id-binding
|
||||
spec:
|
||||
containers:
|
||||
- name: migration
|
||||
@ -28,20 +33,12 @@ spec:
|
||||
- configMapRef:
|
||||
name: atst-worker-envvars
|
||||
volumeMounts:
|
||||
- name: atst-config
|
||||
mountPath: "/opt/atat/atst/atst-overrides.ini"
|
||||
subPath: atst-overrides.ini
|
||||
- name: pgsslrootcert
|
||||
mountPath: "/opt/atat/atst/ssl/pgsslrootcert.crt"
|
||||
subPath: pgsslrootcert.crt
|
||||
- name: flask-secret
|
||||
mountPath: "/config"
|
||||
volumes:
|
||||
- name: atst-config
|
||||
secret:
|
||||
secretName: atst-config-ini
|
||||
items:
|
||||
- key: override.ini
|
||||
path: atst-overrides.ini
|
||||
mode: 0644
|
||||
- name: pgsslrootcert
|
||||
configMap:
|
||||
name: pgsslrootcert
|
||||
@ -49,4 +46,14 @@ spec:
|
||||
- key: cert
|
||||
path: pgsslrootcert.crt
|
||||
mode: 0666
|
||||
- name: flask-secret
|
||||
flexVolume:
|
||||
driver: "azure/kv"
|
||||
options:
|
||||
usepodidentity: "true"
|
||||
keyvaultname: "atat-vault-test"
|
||||
keyvaultobjectnames: "master-AZURE-STORAGE-KEY;master-MAIL-PASSWORD;master-PGPASSWORD;master-REDIS-PASSWORD;master-SECRET-KEY"
|
||||
keyvaultobjectaliases: "AZURE_STORAGE_KEY;MAIL_PASSWORD;PGPASSWORD;REDIS_PASSWORD;SECRET_KEY"
|
||||
keyvaultobjecttypes: "secret;secret;secret;secret;key"
|
||||
tenantid: $TENANT_ID
|
||||
restartPolicy: Never
|
||||
|
@ -1,8 +1,13 @@
|
||||
import os
|
||||
|
||||
from configparser import ConfigParser
|
||||
import pytest
|
||||
|
||||
from atst.app import make_crl_validator
|
||||
from atst.app import (
|
||||
make_crl_validator,
|
||||
apply_config_from_directory,
|
||||
apply_config_from_environment,
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@ -22,3 +27,43 @@ def test_make_crl_validator_creates_crl_dir(app, tmpdir, replace_crl_dir_config)
|
||||
replace_crl_dir_config(crl_dir)
|
||||
make_crl_validator(app)
|
||||
assert os.path.isdir(crl_dir)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def config_object():
|
||||
config = ConfigParser()
|
||||
config.optionxform = str
|
||||
config.read_string("[default]\nFOO=BALONEY")
|
||||
return config
|
||||
|
||||
|
||||
def test_apply_config_from_directory(tmpdir, config_object):
|
||||
config_setting = tmpdir.join("FOO")
|
||||
with open(config_setting, "w") as conf_file:
|
||||
conf_file.write("MAYO")
|
||||
|
||||
apply_config_from_directory(tmpdir, config_object)
|
||||
assert config_object.get("default", "FOO") == "MAYO"
|
||||
|
||||
|
||||
def test_apply_config_from_directory_skips_unknown_settings(tmpdir, config_object):
|
||||
config_setting = tmpdir.join("FLARF")
|
||||
with open(config_setting, "w") as conf_file:
|
||||
conf_file.write("MAYO")
|
||||
|
||||
apply_config_from_directory(tmpdir, config_object)
|
||||
assert "FLARF" not in config_object.options("default")
|
||||
|
||||
|
||||
def test_apply_config_from_environment(monkeypatch, config_object):
|
||||
monkeypatch.setenv("FOO", "MAYO")
|
||||
apply_config_from_environment(config_object)
|
||||
assert config_object.get("default", "FOO") == "MAYO"
|
||||
|
||||
|
||||
def test_apply_config_from_environment_skips_unknown_settings(
|
||||
monkeypatch, config_object
|
||||
):
|
||||
monkeypatch.setenv("FLARF", "MAYO")
|
||||
apply_config_from_environment(config_object)
|
||||
assert "FLARF" not in config_object.options("default")
|
||||
|
Loading…
x
Reference in New Issue
Block a user