dbt-platform-helper 12.2.4__tar.gz → 12.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of dbt-platform-helper might be problematic. Click here for more details.
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/PKG-INFO +1 -1
- dbt_platform_helper-12.3.0/dbt_platform_helper/commands/codebase.py +75 -0
- dbt_platform_helper-12.3.0/dbt_platform_helper/commands/conduit.py +58 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/commands/secrets.py +1 -1
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/domain/codebase.py +60 -60
- dbt_platform_helper-12.3.0/dbt_platform_helper/domain/conduit.py +127 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/domain/database_copy.py +42 -37
- dbt_platform_helper-12.3.0/dbt_platform_helper/exceptions.py +147 -0
- dbt_platform_helper-12.3.0/dbt_platform_helper/providers/cloudformation.py +127 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/providers/copilot.py +32 -12
- dbt_platform_helper-12.3.0/dbt_platform_helper/providers/ecs.py +87 -0
- dbt_platform_helper-12.3.0/dbt_platform_helper/providers/secrets.py +85 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/utils/application.py +1 -1
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/utils/aws.py +29 -6
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/utils/validation.py +39 -14
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/pyproject.toml +1 -1
- dbt_platform_helper-12.2.4/dbt_platform_helper/commands/codebase.py +0 -146
- dbt_platform_helper-12.2.4/dbt_platform_helper/commands/conduit.py +0 -78
- dbt_platform_helper-12.2.4/dbt_platform_helper/domain/conduit.py +0 -172
- dbt_platform_helper-12.2.4/dbt_platform_helper/exceptions.py +0 -81
- dbt_platform_helper-12.2.4/dbt_platform_helper/providers/cloudformation.py +0 -105
- dbt_platform_helper-12.2.4/dbt_platform_helper/providers/ecs.py +0 -79
- dbt_platform_helper-12.2.4/dbt_platform_helper/providers/secrets.py +0 -85
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/LICENSE +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/COMMANDS.md +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/README.md +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/__init__.py +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/addon-plans.yml +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/addons-template-map.yml +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/commands/__init__.py +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/commands/application.py +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/commands/config.py +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/commands/copilot.py +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/commands/database.py +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/commands/environment.py +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/commands/generate.py +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/commands/notify.py +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/commands/pipeline.py +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/commands/version.py +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/constants.py +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/default-extensions.yml +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/domain/__init__.py +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/domain/maintenance_page.py +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/jinja2_tags.py +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/providers/__init__.py +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/providers/load_balancers.py +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/templates/.copilot/config.yml +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/templates/.copilot/image_build_run.sh +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/templates/.copilot/phases/build.sh +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/templates/.copilot/phases/install.sh +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/templates/.copilot/phases/post_build.sh +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/templates/.copilot/phases/pre_build.sh +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/templates/COMMANDS.md.jinja +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/templates/addon-instructions.txt +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/templates/addons/README.md +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/templates/addons/svc/appconfig-ipfilter.yml +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/templates/addons/svc/prometheus-policy.yml +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/templates/addons/svc/s3-policy.yml +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/templates/addons/svc/subscription-filter.yml +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/templates/ci-codebuild-role-policy.json +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/templates/create-codebuild-role.json +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/templates/custom-codebuild-role-policy.json +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/templates/env/manifest.yml +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/templates/env/terraform-overrides/cfn.patches.yml +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/templates/environment-pipelines/main.tf +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/templates/environments/main.tf +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/templates/pipelines/codebase/manifest.yml +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/templates/pipelines/codebase/overrides/.gitignore +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/templates/pipelines/codebase/overrides/bin/override.ts +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/templates/pipelines/codebase/overrides/buildspec.deploy.yml +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/templates/pipelines/codebase/overrides/buildspec.image.yml +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/templates/pipelines/codebase/overrides/cdk.json +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/templates/pipelines/codebase/overrides/package-lock.json +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/templates/pipelines/codebase/overrides/package.json +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/templates/pipelines/codebase/overrides/stack.ts +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/templates/pipelines/codebase/overrides/tsconfig.json +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/templates/pipelines/codebase/overrides/types.ts +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/templates/pipelines/environments/buildspec.yml +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/templates/pipelines/environments/manifest.yml +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/templates/pipelines/environments/overrides/cfn.patches.yml +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/templates/svc/maintenance_pages/default.html +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/templates/svc/maintenance_pages/dmas-migration.html +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/templates/svc/maintenance_pages/migration.html +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/templates/svc/manifest-backend.yml +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/templates/svc/manifest-public.yml +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/templates/svc/overrides/cfn.patches.yml +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/utils/__init__.py +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/utils/arn_parser.py +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/utils/click.py +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/utils/cloudfoundry.py +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/utils/files.py +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/utils/git.py +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/utils/manifests.py +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/utils/messages.py +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/utils/platform_config.py +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/utils/template.py +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/utils/versioning.py +0 -0
- {dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/platform_helper.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: dbt-platform-helper
|
|
3
|
-
Version: 12.
|
|
3
|
+
Version: 12.3.0
|
|
4
4
|
Summary: Set of tools to help transfer applications/services from GOV.UK PaaS to DBT PaaS augmenting AWS Copilot.
|
|
5
5
|
License: MIT
|
|
6
6
|
Author: Department for Business and Trade Platform Team
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import click
|
|
2
|
+
|
|
3
|
+
from dbt_platform_helper.domain.codebase import Codebase
|
|
4
|
+
from dbt_platform_helper.exceptions import PlatformException
|
|
5
|
+
from dbt_platform_helper.utils.click import ClickDocOptGroup
|
|
6
|
+
from dbt_platform_helper.utils.versioning import (
|
|
7
|
+
check_platform_helper_version_needs_update,
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@click.group(chain=True, cls=ClickDocOptGroup)
|
|
12
|
+
def codebase():
|
|
13
|
+
"""Codebase commands."""
|
|
14
|
+
check_platform_helper_version_needs_update()
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@codebase.command()
|
|
18
|
+
def prepare():
|
|
19
|
+
"""Sets up an application codebase for use within a DBT platform project."""
|
|
20
|
+
try:
|
|
21
|
+
Codebase().prepare()
|
|
22
|
+
except PlatformException as err:
|
|
23
|
+
click.secho(str(err), fg="red")
|
|
24
|
+
raise click.Abort
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@codebase.command()
|
|
28
|
+
@click.option("--app", help="AWS application name", required=True)
|
|
29
|
+
@click.option(
|
|
30
|
+
"--with-images",
|
|
31
|
+
help="List up to the last 10 images tagged for this codebase",
|
|
32
|
+
default=False,
|
|
33
|
+
is_flag=True,
|
|
34
|
+
)
|
|
35
|
+
def list(app, with_images):
|
|
36
|
+
"""List available codebases for the application."""
|
|
37
|
+
try:
|
|
38
|
+
Codebase().list(app, with_images)
|
|
39
|
+
except PlatformException as err:
|
|
40
|
+
click.secho(str(err), fg="red")
|
|
41
|
+
raise click.Abort
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
@codebase.command()
|
|
45
|
+
@click.option("--app", help="AWS application name", required=True)
|
|
46
|
+
@click.option(
|
|
47
|
+
"--codebase",
|
|
48
|
+
help="The codebase name as specified in the platform-config.yml file",
|
|
49
|
+
required=True,
|
|
50
|
+
)
|
|
51
|
+
@click.option("--commit", help="GitHub commit hash", required=True)
|
|
52
|
+
def build(app, codebase, commit):
|
|
53
|
+
"""Trigger a CodePipeline pipeline based build."""
|
|
54
|
+
try:
|
|
55
|
+
Codebase().build(app, codebase, commit)
|
|
56
|
+
except PlatformException as err:
|
|
57
|
+
click.secho(str(err), fg="red")
|
|
58
|
+
raise click.Abort
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
@codebase.command()
|
|
62
|
+
@click.option("--app", help="AWS application name", required=True)
|
|
63
|
+
@click.option("--env", help="AWS Copilot environment", required=True)
|
|
64
|
+
@click.option(
|
|
65
|
+
"--codebase",
|
|
66
|
+
help="The codebase name as specified in the platform-config.yml file",
|
|
67
|
+
required=True,
|
|
68
|
+
)
|
|
69
|
+
@click.option("--commit", help="GitHub commit hash", required=True)
|
|
70
|
+
def deploy(app, env, codebase, commit):
|
|
71
|
+
try:
|
|
72
|
+
Codebase().deploy(app, env, codebase, commit)
|
|
73
|
+
except PlatformException as err:
|
|
74
|
+
click.secho(str(err), fg="red")
|
|
75
|
+
raise click.Abort
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import click
|
|
2
|
+
|
|
3
|
+
from dbt_platform_helper.domain.conduit import Conduit
|
|
4
|
+
from dbt_platform_helper.exceptions import AWSException
|
|
5
|
+
from dbt_platform_helper.providers.cloudformation import CloudFormation
|
|
6
|
+
from dbt_platform_helper.providers.ecs import ECS
|
|
7
|
+
from dbt_platform_helper.providers.secrets import Secrets
|
|
8
|
+
from dbt_platform_helper.utils.application import load_application
|
|
9
|
+
from dbt_platform_helper.utils.click import ClickDocOptCommand
|
|
10
|
+
from dbt_platform_helper.utils.versioning import (
|
|
11
|
+
check_platform_helper_version_needs_update,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
CONDUIT_ACCESS_OPTIONS = ["read", "write", "admin"]
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@click.command(cls=ClickDocOptCommand)
|
|
18
|
+
@click.argument("addon_name", type=str, required=True)
|
|
19
|
+
@click.option("--app", help="Application name", required=True)
|
|
20
|
+
@click.option("--env", help="Environment name", required=True)
|
|
21
|
+
@click.option(
|
|
22
|
+
"--access",
|
|
23
|
+
default="read",
|
|
24
|
+
type=click.Choice(CONDUIT_ACCESS_OPTIONS),
|
|
25
|
+
help="Allow read, write or admin access to the database addons.",
|
|
26
|
+
)
|
|
27
|
+
def conduit(addon_name: str, app: str, env: str, access: str):
|
|
28
|
+
"""Opens a shell for a given addon_name create a conduit connection to
|
|
29
|
+
interact with postgres, opensearch or redis."""
|
|
30
|
+
check_platform_helper_version_needs_update()
|
|
31
|
+
application = load_application(app)
|
|
32
|
+
|
|
33
|
+
try:
|
|
34
|
+
secrets_provider: Secrets = Secrets(
|
|
35
|
+
application.environments[env].session.client("ssm"),
|
|
36
|
+
application.environments[env].session.client("secretsmanager"),
|
|
37
|
+
application.name,
|
|
38
|
+
env,
|
|
39
|
+
)
|
|
40
|
+
cloudformation_provider: CloudFormation = CloudFormation(
|
|
41
|
+
application.environments[env].session.client("cloudformation"),
|
|
42
|
+
application.environments[env].session.client("iam"),
|
|
43
|
+
application.environments[env].session.client("ssm"),
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
ecs_provider: ECS = ECS(
|
|
47
|
+
application.environments[env].session.client("ecs"),
|
|
48
|
+
application.environments[env].session.client("ssm"),
|
|
49
|
+
application.name,
|
|
50
|
+
env,
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
Conduit(application, secrets_provider, cloudformation_provider, ecs_provider).start(
|
|
54
|
+
env, addon_name, access
|
|
55
|
+
)
|
|
56
|
+
except AWSException as err:
|
|
57
|
+
click.secho(str(err), fg="red")
|
|
58
|
+
raise click.Abort
|
{dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/commands/secrets.py
RENAMED
|
@@ -102,7 +102,6 @@ def list(app, env):
|
|
|
102
102
|
params = dict(Path=path, Recursive=False, WithDecryption=True, MaxResults=10)
|
|
103
103
|
secrets = []
|
|
104
104
|
|
|
105
|
-
# TODO: refactor shared code with get_ssm_secret_names - Check if this is still valid
|
|
106
105
|
while True:
|
|
107
106
|
response = client.get_parameters_by_path(**params)
|
|
108
107
|
|
|
@@ -114,6 +113,7 @@ def list(app, env):
|
|
|
114
113
|
else:
|
|
115
114
|
break
|
|
116
115
|
|
|
116
|
+
# Todo: When we refactor this, the above could probably just use dbt_platform_helper.utils.aws.get_ssm_secret_names so we would end up with print("\n".join(get_ssm_secret_names(app, env)))
|
|
117
117
|
print("\n".join(sorted(secrets)))
|
|
118
118
|
|
|
119
119
|
|
{dbt_platform_helper-12.2.4 → dbt_platform_helper-12.3.0}/dbt_platform_helper/domain/codebase.py
RENAMED
|
@@ -11,7 +11,6 @@ from boto3 import Session
|
|
|
11
11
|
|
|
12
12
|
from dbt_platform_helper.exceptions import ApplicationDeploymentNotTriggered
|
|
13
13
|
from dbt_platform_helper.exceptions import ApplicationEnvironmentNotFoundError
|
|
14
|
-
from dbt_platform_helper.exceptions import NoCopilotCodebasesFoundError
|
|
15
14
|
from dbt_platform_helper.exceptions import NotInCodeBaseRepositoryError
|
|
16
15
|
from dbt_platform_helper.utils.application import Application
|
|
17
16
|
from dbt_platform_helper.utils.application import load_application
|
|
@@ -29,31 +28,31 @@ from dbt_platform_helper.utils.template import setup_templates
|
|
|
29
28
|
class Codebase:
|
|
30
29
|
def __init__(
|
|
31
30
|
self,
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
31
|
+
input: Callable[[str], str] = click.prompt,
|
|
32
|
+
echo: Callable[[str], str] = click.secho,
|
|
33
|
+
confirm: Callable[[str], bool] = click.confirm,
|
|
34
|
+
load_application: Callable[[str], Application] = load_application,
|
|
35
|
+
get_aws_session_or_abort: Callable[[str], Session] = get_aws_session_or_abort,
|
|
36
|
+
check_codebase_exists: Callable[[str], str] = check_codebase_exists,
|
|
37
|
+
check_image_exists: Callable[[str], str] = check_image_exists,
|
|
38
|
+
get_build_url_from_arn: Callable[[str], str] = get_build_url_from_arn,
|
|
39
|
+
list_latest_images: Callable[[str], str] = list_latest_images,
|
|
40
|
+
start_build_extraction: Callable[[str], str] = start_build_extraction,
|
|
41
|
+
check_if_commit_exists: Callable[[str], str] = check_if_commit_exists,
|
|
42
|
+
run_subprocess: Callable[[str], str] = subprocess.run,
|
|
44
43
|
):
|
|
45
|
-
self.
|
|
46
|
-
self.
|
|
47
|
-
self.
|
|
48
|
-
self.
|
|
49
|
-
self.
|
|
50
|
-
self.
|
|
51
|
-
self.
|
|
52
|
-
self.
|
|
53
|
-
self.
|
|
54
|
-
self.
|
|
55
|
-
self.
|
|
56
|
-
self.
|
|
44
|
+
self.input = input
|
|
45
|
+
self.echo = echo
|
|
46
|
+
self.confirm = confirm
|
|
47
|
+
self.load_application = load_application
|
|
48
|
+
self.get_aws_session_or_abort = get_aws_session_or_abort
|
|
49
|
+
self.check_codebase_exists = check_codebase_exists
|
|
50
|
+
self.check_image_exists = check_image_exists
|
|
51
|
+
self.get_build_url_from_arn = get_build_url_from_arn
|
|
52
|
+
self.list_latest_images = list_latest_images
|
|
53
|
+
self.start_build_extraction = start_build_extraction
|
|
54
|
+
self.check_if_commit_exists = check_if_commit_exists
|
|
55
|
+
self.run_subprocess = run_subprocess
|
|
57
56
|
|
|
58
57
|
def prepare(self):
|
|
59
58
|
"""Sets up an application codebase for use within a DBT platform
|
|
@@ -61,13 +60,15 @@ class Codebase:
|
|
|
61
60
|
templates = setup_templates()
|
|
62
61
|
|
|
63
62
|
repository = (
|
|
64
|
-
self.
|
|
63
|
+
self.run_subprocess(
|
|
64
|
+
["git", "remote", "get-url", "origin"], capture_output=True, text=True
|
|
65
|
+
)
|
|
65
66
|
.stdout.split("/")[-1]
|
|
66
67
|
.strip()
|
|
67
68
|
.removesuffix(".git")
|
|
68
69
|
)
|
|
69
70
|
if repository.endswith("-deploy") or Path("./copilot").exists():
|
|
70
|
-
raise NotInCodeBaseRepositoryError
|
|
71
|
+
raise NotInCodeBaseRepositoryError()
|
|
71
72
|
|
|
72
73
|
builder_configuration_url = "https://raw.githubusercontent.com/uktrade/ci-image-builder/main/image_builder/configuration/builder_configuration.yml"
|
|
73
74
|
builder_configuration_response = requests.get(builder_configuration_url)
|
|
@@ -91,7 +92,7 @@ class Codebase:
|
|
|
91
92
|
config_contents = templates.get_template(f".copilot/config.yml").render(
|
|
92
93
|
repository=repository, builder_version=builder_version
|
|
93
94
|
)
|
|
94
|
-
self.
|
|
95
|
+
self.echo(
|
|
95
96
|
mkfile(
|
|
96
97
|
Path("."), ".copilot/image_build_run.sh", image_build_run_contents, overwrite=True
|
|
97
98
|
)
|
|
@@ -100,27 +101,27 @@ class Codebase:
|
|
|
100
101
|
image_build_run_file = Path(".copilot/image_build_run.sh")
|
|
101
102
|
image_build_run_file.chmod(image_build_run_file.stat().st_mode | stat.S_IEXEC)
|
|
102
103
|
|
|
103
|
-
self.
|
|
104
|
+
self.echo(mkfile(Path("."), ".copilot/config.yml", config_contents, overwrite=True))
|
|
104
105
|
|
|
105
106
|
for phase in ["build", "install", "post_build", "pre_build"]:
|
|
106
107
|
phase_contents = templates.get_template(f".copilot/phases/{phase}.sh").render()
|
|
107
108
|
|
|
108
|
-
self.
|
|
109
|
+
self.echo(
|
|
109
110
|
mkfile(Path("./.copilot"), f"phases/{phase}.sh", phase_contents, overwrite=True)
|
|
110
111
|
)
|
|
111
112
|
|
|
112
113
|
def build(self, app: str, codebase: str, commit: str):
|
|
113
114
|
"""Trigger a CodePipeline pipeline based build."""
|
|
114
|
-
session = self.
|
|
115
|
-
self.
|
|
115
|
+
session = self.get_aws_session_or_abort()
|
|
116
|
+
self.load_application(app, default_session=session)
|
|
116
117
|
|
|
117
|
-
self.
|
|
118
|
+
self.check_if_commit_exists(commit)
|
|
118
119
|
|
|
119
120
|
codebuild_client = session.client("codebuild")
|
|
120
121
|
build_url = self.__start_build_with_confirmation(
|
|
121
|
-
self.
|
|
122
|
+
self.confirm,
|
|
122
123
|
codebuild_client,
|
|
123
|
-
self.
|
|
124
|
+
self.get_build_url_from_arn,
|
|
124
125
|
f'You are about to build "{app}" for "{codebase}" with commit "{commit}". Do you want to continue?',
|
|
125
126
|
{
|
|
126
127
|
"projectName": f"codebuild-{app}-{codebase}",
|
|
@@ -130,29 +131,29 @@ class Codebase:
|
|
|
130
131
|
)
|
|
131
132
|
|
|
132
133
|
if build_url:
|
|
133
|
-
return self.
|
|
134
|
+
return self.echo(
|
|
134
135
|
f"Your build has been triggered. Check your build progress in the AWS Console: {build_url}"
|
|
135
136
|
)
|
|
136
137
|
|
|
137
|
-
raise ApplicationDeploymentNotTriggered()
|
|
138
|
+
raise ApplicationDeploymentNotTriggered(codebase)
|
|
138
139
|
|
|
139
140
|
def deploy(self, app, env, codebase, commit):
|
|
140
141
|
"""Trigger a CodePipeline pipeline based deployment."""
|
|
141
|
-
session = self.
|
|
142
|
+
session = self.get_aws_session_or_abort()
|
|
142
143
|
|
|
143
|
-
application = self.
|
|
144
|
+
application = self.load_application(app, default_session=session)
|
|
144
145
|
if not application.environments.get(env):
|
|
145
|
-
raise ApplicationEnvironmentNotFoundError()
|
|
146
|
+
raise ApplicationEnvironmentNotFoundError(env)
|
|
146
147
|
|
|
147
|
-
self.
|
|
148
|
+
self.check_codebase_exists(session, application, codebase)
|
|
148
149
|
|
|
149
|
-
self.
|
|
150
|
+
self.check_image_exists(session, application, codebase, commit)
|
|
150
151
|
|
|
151
152
|
codebuild_client = session.client("codebuild")
|
|
152
153
|
build_url = self.__start_build_with_confirmation(
|
|
153
|
-
self.
|
|
154
|
+
self.confirm,
|
|
154
155
|
codebuild_client,
|
|
155
|
-
self.
|
|
156
|
+
self.get_build_url_from_arn,
|
|
156
157
|
f'You are about to deploy "{app}" for "{codebase}" with commit "{commit}" to the "{env}" environment. Do you want to continue?',
|
|
157
158
|
{
|
|
158
159
|
"projectName": f"pipeline-{application.name}-{codebase}-BuildProject",
|
|
@@ -166,34 +167,34 @@ class Codebase:
|
|
|
166
167
|
)
|
|
167
168
|
|
|
168
169
|
if build_url:
|
|
169
|
-
return self.
|
|
170
|
+
return self.echo(
|
|
170
171
|
"Your deployment has been triggered. Check your build progress in the AWS Console: "
|
|
171
172
|
f"{build_url}",
|
|
172
173
|
)
|
|
173
174
|
|
|
174
|
-
raise ApplicationDeploymentNotTriggered()
|
|
175
|
+
raise ApplicationDeploymentNotTriggered(codebase)
|
|
175
176
|
|
|
176
177
|
def list(self, app: str, with_images: bool):
|
|
177
178
|
"""List available codebases for the application."""
|
|
178
|
-
session = self.
|
|
179
|
-
application = self.
|
|
179
|
+
session = self.get_aws_session_or_abort()
|
|
180
|
+
application = self.load_application(app, session)
|
|
180
181
|
ssm_client = session.client("ssm")
|
|
181
182
|
ecr_client = session.client("ecr")
|
|
182
183
|
codebases = self.__get_codebases(application, ssm_client)
|
|
183
184
|
|
|
184
|
-
self.
|
|
185
|
+
self.echo("The following codebases are available:")
|
|
185
186
|
|
|
186
187
|
for codebase in codebases:
|
|
187
|
-
self.
|
|
188
|
+
self.echo(f"- {codebase['name']} (https://github.com/{codebase['repository']})")
|
|
188
189
|
if with_images:
|
|
189
|
-
self.
|
|
190
|
+
self.list_latest_images(
|
|
190
191
|
ecr_client,
|
|
191
192
|
f"{application.name}/{codebase['name']}",
|
|
192
193
|
codebase["repository"],
|
|
193
|
-
self.
|
|
194
|
+
self.echo,
|
|
194
195
|
)
|
|
195
196
|
|
|
196
|
-
self.
|
|
197
|
+
self.echo("")
|
|
197
198
|
|
|
198
199
|
def __get_codebases(self, application, ssm_client):
|
|
199
200
|
parameters = ssm_client.get_parameters_by_path(
|
|
@@ -204,19 +205,18 @@ class Codebase:
|
|
|
204
205
|
codebases = [json.loads(p["Value"]) for p in parameters]
|
|
205
206
|
|
|
206
207
|
if not codebases:
|
|
207
|
-
|
|
208
|
-
raise NoCopilotCodebasesFoundError
|
|
208
|
+
return []
|
|
209
209
|
return codebases
|
|
210
210
|
|
|
211
211
|
def __start_build_with_confirmation(
|
|
212
212
|
self,
|
|
213
|
-
|
|
213
|
+
confirm,
|
|
214
214
|
codebuild_client,
|
|
215
|
-
|
|
215
|
+
get_build_url_from_arn,
|
|
216
216
|
confirmation_message,
|
|
217
217
|
build_options,
|
|
218
218
|
):
|
|
219
|
-
if
|
|
220
|
-
build_arn = self.
|
|
221
|
-
return
|
|
219
|
+
if confirm(confirmation_message):
|
|
220
|
+
build_arn = self.start_build_extraction(codebuild_client, build_options)
|
|
221
|
+
return get_build_url_from_arn(build_arn)
|
|
222
222
|
return None
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import subprocess
|
|
2
|
+
from collections.abc import Callable
|
|
3
|
+
|
|
4
|
+
import click
|
|
5
|
+
|
|
6
|
+
from dbt_platform_helper.providers.cloudformation import CloudFormation
|
|
7
|
+
from dbt_platform_helper.providers.copilot import connect_to_addon_client_task
|
|
8
|
+
from dbt_platform_helper.providers.copilot import create_addon_client_task
|
|
9
|
+
from dbt_platform_helper.providers.copilot import create_postgres_admin_task
|
|
10
|
+
from dbt_platform_helper.providers.ecs import ECS
|
|
11
|
+
from dbt_platform_helper.providers.secrets import Secrets
|
|
12
|
+
from dbt_platform_helper.utils.application import Application
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class Conduit:
|
|
16
|
+
def __init__(
|
|
17
|
+
self,
|
|
18
|
+
application: Application,
|
|
19
|
+
secrets_provider: Secrets,
|
|
20
|
+
cloudformation_provider: CloudFormation,
|
|
21
|
+
ecs_provider: ECS,
|
|
22
|
+
echo: Callable[[str], str] = click.secho,
|
|
23
|
+
subprocess: subprocess = subprocess,
|
|
24
|
+
connect_to_addon_client_task=connect_to_addon_client_task,
|
|
25
|
+
create_addon_client_task=create_addon_client_task,
|
|
26
|
+
create_postgres_admin_task=create_postgres_admin_task,
|
|
27
|
+
):
|
|
28
|
+
|
|
29
|
+
self.application = application
|
|
30
|
+
self.secrets_provider = secrets_provider
|
|
31
|
+
self.cloudformation_provider = cloudformation_provider
|
|
32
|
+
self.ecs_provider = ecs_provider
|
|
33
|
+
self.subprocess = subprocess
|
|
34
|
+
self.echo = echo
|
|
35
|
+
self.connect_to_addon_client_task = connect_to_addon_client_task
|
|
36
|
+
self.create_addon_client_task = create_addon_client_task
|
|
37
|
+
self.create_postgres_admin_task = create_postgres_admin_task
|
|
38
|
+
|
|
39
|
+
def start(self, env: str, addon_name: str, access: str = "read"):
|
|
40
|
+
clients = self._initialise_clients(env)
|
|
41
|
+
addon_type, cluster_arn, parameter_name, task_name = self._get_addon_details(
|
|
42
|
+
addon_name, access
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
self.echo(f"Checking if a conduit task is already running for {addon_type}")
|
|
46
|
+
task_arns = self.ecs_provider.get_ecs_task_arns(cluster_arn, task_name)
|
|
47
|
+
if not task_arns:
|
|
48
|
+
self.echo("Creating conduit task")
|
|
49
|
+
self.create_addon_client_task(
|
|
50
|
+
clients["iam"],
|
|
51
|
+
clients["ssm"],
|
|
52
|
+
clients["secrets_manager"],
|
|
53
|
+
self.subprocess,
|
|
54
|
+
self.application,
|
|
55
|
+
env,
|
|
56
|
+
addon_type,
|
|
57
|
+
addon_name,
|
|
58
|
+
task_name,
|
|
59
|
+
access,
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
self.echo("Updating conduit task")
|
|
63
|
+
self._update_stack_resources(
|
|
64
|
+
self.application.name,
|
|
65
|
+
env,
|
|
66
|
+
addon_type,
|
|
67
|
+
addon_name,
|
|
68
|
+
task_name,
|
|
69
|
+
parameter_name,
|
|
70
|
+
access,
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
task_arns = self.ecs_provider.get_ecs_task_arns(cluster_arn, task_name)
|
|
74
|
+
|
|
75
|
+
else:
|
|
76
|
+
self.echo("Conduit task already running")
|
|
77
|
+
|
|
78
|
+
self.echo(f"Checking if exec is available for conduit task...")
|
|
79
|
+
|
|
80
|
+
self.ecs_provider.ecs_exec_is_available(cluster_arn, task_arns)
|
|
81
|
+
|
|
82
|
+
self.echo("Connecting to conduit task")
|
|
83
|
+
self.connect_to_addon_client_task(
|
|
84
|
+
clients["ecs"], self.subprocess, self.application.name, env, cluster_arn, task_name
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
def _initialise_clients(self, env):
|
|
88
|
+
return {
|
|
89
|
+
"ecs": self.application.environments[env].session.client("ecs"),
|
|
90
|
+
"iam": self.application.environments[env].session.client("iam"),
|
|
91
|
+
"ssm": self.application.environments[env].session.client("ssm"),
|
|
92
|
+
"cloudformation": self.application.environments[env].session.client("cloudformation"),
|
|
93
|
+
"secrets_manager": self.application.environments[env].session.client("secretsmanager"),
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
def _get_addon_details(self, addon_name, access):
|
|
97
|
+
addon_type = self.secrets_provider.get_addon_type(addon_name)
|
|
98
|
+
cluster_arn = self.ecs_provider.get_cluster_arn()
|
|
99
|
+
parameter_name = self.secrets_provider.get_parameter_name(addon_type, addon_name, access)
|
|
100
|
+
task_name = self.ecs_provider.get_or_create_task_name(addon_name, parameter_name)
|
|
101
|
+
|
|
102
|
+
return addon_type, cluster_arn, parameter_name, task_name
|
|
103
|
+
|
|
104
|
+
def _update_stack_resources(
|
|
105
|
+
self,
|
|
106
|
+
app_name,
|
|
107
|
+
env,
|
|
108
|
+
addon_type,
|
|
109
|
+
addon_name,
|
|
110
|
+
task_name,
|
|
111
|
+
parameter_name,
|
|
112
|
+
access,
|
|
113
|
+
):
|
|
114
|
+
self.cloudformation_provider.add_stack_delete_policy_to_task_role(task_name)
|
|
115
|
+
stack_name = self.cloudformation_provider.update_conduit_stack_resources(
|
|
116
|
+
app_name,
|
|
117
|
+
env,
|
|
118
|
+
addon_type,
|
|
119
|
+
addon_name,
|
|
120
|
+
task_name,
|
|
121
|
+
parameter_name,
|
|
122
|
+
access,
|
|
123
|
+
)
|
|
124
|
+
self.echo("Waiting for conduit task update to complete...")
|
|
125
|
+
self.cloudformation_provider.wait_for_cloudformation_to_reach_status(
|
|
126
|
+
"stack_update_complete", stack_name
|
|
127
|
+
)
|