Skip to content

Commit

Permalink
Refactor Vault resources (#210)
Browse files Browse the repository at this point in the history
* Refactor Vault resources

Co-authored-by: Daniele Pompa <[email protected]>
  • Loading branch information
filippo-20tab and daniele-20tab authored Dec 7, 2022
1 parent 3491df7 commit 12901ae
Show file tree
Hide file tree
Showing 15 changed files with 419 additions and 536 deletions.
105 changes: 49 additions & 56 deletions bootstrap/collector.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ def collect(
deployment_type = clean_deployment_type(deployment_type)
# The "digitalocean-k8s" deployment type includes Postgres by default
if digitalocean_enabled := ("digitalocean" in deployment_type):
digitalocean_token = validate_or_prompt_password(
digitalocean_token = validate_or_prompt_secret(
"DigitalOcean token", digitalocean_token
)
(
Expand Down Expand Up @@ -236,9 +236,9 @@ def collect(
sentry_org,
sentry_url,
sentry_auth_token,
backend_type,
backend_service_slug,
backend_sentry_dsn,
frontend_type,
frontend_service_slug,
frontend_sentry_dsn,
)
(
Expand Down Expand Up @@ -394,8 +394,8 @@ def validate_or_prompt_email(message, value=None, default=None, required=True):
return validate_or_prompt_email(message, None, default, required)


def validate_or_prompt_password(message, value=None, default=None, required=True):
"""Validate the given password or prompt until a valid value is provided."""
def validate_or_prompt_secret(message, value=None, default=None, required=True):
"""Validate the given secret or prompt until a valid value is provided."""
if value is None:
value = click.prompt(message, default=default, hide_input=True)
try:
Expand All @@ -404,7 +404,7 @@ def validate_or_prompt_password(message, value=None, default=None, required=True
except validators.ValidationFailure:
pass
click.echo(error("Please type at least 8 chars!"))
return validate_or_prompt_password(message, None, default, required)
return validate_or_prompt_secret(message, None, default, required)


def validate_or_prompt_path(message, value=None, default=None, required=True):
Expand Down Expand Up @@ -543,7 +543,7 @@ def clean_terraform_backend(
terraform_cloud_hostname,
default="app.terraform.io",
)
terraform_cloud_token = validate_or_prompt_password(
terraform_cloud_token = validate_or_prompt_secret(
"Terraform Cloud User token",
terraform_cloud_token,
)
Expand Down Expand Up @@ -583,16 +583,21 @@ def clean_terraform_backend(

def clean_vault_data(vault_token, vault_url, quiet=False):
"""Return the Vault data, if applicable."""
if vault_token or (
vault_token is None
if vault_url or (
vault_url is None
and click.confirm(
"Do you want to use Vault for secrets management?",
)
):
vault_token = validate_or_prompt_password("Vault token", vault_token)
vault_token = validate_or_prompt_secret(
"Vault token (leave blank to perform a browser-based OIDC authentication)",
vault_token,
default="",
required=False,
)
quiet or click.confirm(
warning(
"Make sure the Vault token has enough permissions to enable the "
"Make sure your Vault permissions allow to enable the "
"project secrets backends and manage the project secrets. Continue?"
),
abort=True,
Expand Down Expand Up @@ -635,7 +640,7 @@ def clean_kubernetes_credentials(
kubernetes_host = kubernetes_host or validate_or_prompt_url(
"Kubernetes host", kubernetes_host
)
kubernetes_token = kubernetes_token or validate_or_prompt_password(
kubernetes_token = kubernetes_token or validate_or_prompt_secret(
"Kubernetes token", kubernetes_token
)
return kubernetes_cluster_ca_certificate, kubernetes_host, kubernetes_token
Expand Down Expand Up @@ -710,30 +715,49 @@ def clean_letsencrypt_certificate_email(letsencrypt_certificate_email):
)


def clean_sentry_org(sentry_org):
"""Return the Sentry organization."""
return sentry_org if sentry_org is not None else click.prompt("Sentry organization")


def clean_sentry_dsn(service_slug, sentry_dsn):
"""Return the backend Sentry DSN."""
if service_slug:
return validate_or_prompt_url(
f"Sentry DSN of the {service_slug} service (leave blank if unused)",
sentry_dsn,
default="",
required=False,
)


def clean_sentry_data(
sentry_org,
sentry_url,
sentry_auth_token,
backend_type,
backend_service_slug,
backend_sentry_dsn,
frontend_type,
frontend_service_slug,
frontend_sentry_dsn,
):
"""Return the Sentry configuration data."""
if sentry_org or (
sentry_org is None
and click.confirm(warning("Do you want to use Sentry?"), default=False)
if any((backend_service_slug, frontend_service_slug)) and (
sentry_org
or (
sentry_org is None
and click.confirm(warning("Do you want to use Sentry?"), default=False)
)
):
sentry_org = clean_sentry_org(sentry_org)
sentry_url = validate_or_prompt_url(
"Sentry URL", sentry_url, default="https://sentry.io/"
)
sentry_auth_token = validate_or_prompt_password(
sentry_auth_token = validate_or_prompt_secret(
"Sentry auth token", sentry_auth_token
)
backend_sentry_dsn = clean_backend_sentry_dsn(backend_type, backend_sentry_dsn)
frontend_sentry_dsn = clean_frontend_sentry_dsn(
frontend_type, frontend_sentry_dsn
backend_sentry_dsn = clean_sentry_dsn(backend_service_slug, backend_sentry_dsn)
frontend_sentry_dsn = clean_sentry_dsn(
frontend_service_slug, frontend_sentry_dsn
)
else:
sentry_org = None
Expand All @@ -750,37 +774,6 @@ def clean_sentry_data(
)


def clean_sentry_org(sentry_org):
"""Return the Sentry organization."""
return sentry_org if sentry_org is not None else click.prompt("Sentry organization")


def clean_backend_sentry_dsn(backend_type, backend_sentry_dsn):
"""Return the backend Sentry DSN."""
if backend_type:
return (
backend_sentry_dsn
if backend_sentry_dsn is not None
else click.prompt(
"Backend Sentry DSN (leave blank if unused)",
default="",
)
)


def clean_frontend_sentry_dsn(frontend_type, frontend_sentry_dsn):
"""Return the frontend Sentry DSN."""
if frontend_type:
return (
frontend_sentry_dsn
if frontend_sentry_dsn is not None
else click.prompt(
"Frontend Sentry DSN (leave blank if unused)",
default="",
)
)


def clean_digitalocean_options(
digitalocean_domain_create,
digitalocean_dns_records_create,
Expand Down Expand Up @@ -899,7 +892,7 @@ def clean_pact_broker_data(pact_broker_url, pact_broker_username, pact_broker_pa
pact_broker_username = pact_broker_username or click.prompt(
"Pact broker username",
)
pact_broker_password = validate_or_prompt_password(
pact_broker_password = validate_or_prompt_secret(
"Pact broker password", pact_broker_password
)
else:
Expand Down Expand Up @@ -1008,7 +1001,7 @@ def clean_s3_media_storage_data(
):
"""Return S3 media storage data."""
if media_storage == MEDIA_STORAGE_DIGITALOCEAN_S3:
digitalocean_token = validate_or_prompt_password(
digitalocean_token = validate_or_prompt_secret(
"DigitalOcean token", digitalocean_token
)
s3_region = s3_region or click.prompt(
Expand All @@ -1027,8 +1020,8 @@ def clean_s3_media_storage_data(
s3_bucket_name = s3_bucket_name or click.prompt(
"AWS S3 bucket name",
)
s3_access_id = validate_or_prompt_password("S3 Access Key ID", s3_access_id)
s3_secret_key = validate_or_prompt_password("S3 Secret Access Key", s3_secret_key)
s3_access_id = validate_or_prompt_secret("S3 Access Key ID", s3_access_id)
s3_secret_key = validate_or_prompt_secret("S3 Secret Access Key", s3_secret_key)
return (
digitalocean_token,
s3_region,
Expand Down
37 changes: 37 additions & 0 deletions bootstrap/constants.py
Original file line number Diff line number Diff line change
@@ -1,35 +1,72 @@
"""Web project initialization CLI constants."""

from pathlib import Path
from typing import Dict

DUMPS_DIR = Path(__file__).parent.parent / ".dumps"

# Stacks

# BEWARE: stack names must be suitable for inclusion in Vault paths

DEV_STACK_NAME = "development"

DEV_STACK_SLUG = "dev"

STAGE_STACK_NAME = "staging"

STAGE_STACK_SLUG = "stage"

MAIN_STACK_NAME = "main"

MAIN_STACK_SLUG = "main"

STACKS_CHOICES = {
"1": [{"name": MAIN_STACK_NAME, "slug": MAIN_STACK_SLUG}],
"2": [
{"name": DEV_STACK_NAME, "slug": DEV_STACK_SLUG},
{"name": MAIN_STACK_NAME, "slug": MAIN_STACK_SLUG},
],
"3": [
{"name": DEV_STACK_NAME, "slug": DEV_STACK_SLUG},
{"name": STAGE_STACK_NAME, "slug": STAGE_STACK_SLUG},
{"name": MAIN_STACK_NAME, "slug": MAIN_STACK_SLUG},
],
}

# Environments

# BEWARE: environment names must be suitable for inclusion in Vault paths

DEV_ENV_NAME = "development"

DEV_ENV_SLUG = "dev"

DEV_ENV_STACK_CHOICES: Dict[str, str] = {
"1": MAIN_STACK_SLUG,
}

STAGE_ENV_NAME = "staging"

STAGE_ENV_SLUG = "stage"

STAGE_ENV_STACK_CHOICES: Dict[str, str] = {
"1": MAIN_STACK_SLUG,
"2": DEV_STACK_SLUG,
}

PROD_ENV_NAME = "production"

PROD_ENV_SLUG = "prod"

PROD_ENV_STACK_CHOICES: Dict[str, str] = {}

# Env vars

GITLAB_TOKEN_ENV_VAR = "GITLAB_PRIVATE_TOKEN"

VAULT_TOKEN_ENV_VAR = "VAULT_TOKEN"

# Subrepos

BACKEND_TEMPLATE_URLS = {
Expand Down
Loading

0 comments on commit 12901ae

Please sign in to comment.