dbt-platform-helper 12.5.0__py3-none-any.whl → 12.5.1__py3-none-any.whl
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/COMMANDS.md +1 -3
- dbt_platform_helper/commands/copilot.py +4 -2
- dbt_platform_helper/commands/environment.py +15 -13
- dbt_platform_helper/commands/pipeline.py +8 -170
- dbt_platform_helper/constants.py +1 -0
- dbt_platform_helper/domain/codebase.py +8 -4
- dbt_platform_helper/domain/copilot_environment.py +3 -3
- dbt_platform_helper/domain/database_copy.py +9 -7
- dbt_platform_helper/domain/maintenance_page.py +44 -20
- dbt_platform_helper/domain/pipelines.py +213 -0
- dbt_platform_helper/domain/terraform_environment.py +68 -35
- dbt_platform_helper/domain/test_platform_terraform_manifest_generator.py +100 -0
- dbt_platform_helper/providers/cache.py +1 -2
- dbt_platform_helper/providers/config.py +12 -2
- dbt_platform_helper/providers/copilot.py +2 -0
- dbt_platform_helper/providers/files.py +26 -0
- dbt_platform_helper/providers/vpc.py +57 -0
- dbt_platform_helper/providers/yaml_file.py +3 -14
- dbt_platform_helper/utils/application.py +32 -34
- dbt_platform_helper/utils/aws.py +0 -50
- dbt_platform_helper/utils/files.py +8 -23
- dbt_platform_helper/utils/platform_config.py +0 -7
- dbt_platform_helper/utils/versioning.py +12 -0
- {dbt_platform_helper-12.5.0.dist-info → dbt_platform_helper-12.5.1.dist-info}/METADATA +1 -1
- {dbt_platform_helper-12.5.0.dist-info → dbt_platform_helper-12.5.1.dist-info}/RECORD +28 -24
- {dbt_platform_helper-12.5.0.dist-info → dbt_platform_helper-12.5.1.dist-info}/WHEEL +1 -1
- {dbt_platform_helper-12.5.0.dist-info → dbt_platform_helper-12.5.1.dist-info}/LICENSE +0 -0
- {dbt_platform_helper-12.5.0.dist-info → dbt_platform_helper-12.5.1.dist-info}/entry_points.txt +0 -0
dbt_platform_helper/COMMANDS.md
CHANGED
|
@@ -460,13 +460,11 @@ platform-helper environment online --app <application> --env <environment>
|
|
|
460
460
|
## Usage
|
|
461
461
|
|
|
462
462
|
```
|
|
463
|
-
platform-helper environment generate --name <name>
|
|
463
|
+
platform-helper environment generate --name <name>
|
|
464
464
|
```
|
|
465
465
|
|
|
466
466
|
## Options
|
|
467
467
|
|
|
468
|
-
- `--vpc-name <text>`
|
|
469
|
-
|
|
470
468
|
- `--name
|
|
471
469
|
-n <text>`
|
|
472
470
|
|
|
@@ -13,12 +13,12 @@ from dbt_platform_helper.constants import PLATFORM_CONFIG_FILE
|
|
|
13
13
|
from dbt_platform_helper.domain.config_validator import ConfigValidator
|
|
14
14
|
from dbt_platform_helper.domain.copilot_environment import CopilotTemplating
|
|
15
15
|
from dbt_platform_helper.providers.config import ConfigProvider
|
|
16
|
+
from dbt_platform_helper.providers.files import FileProvider
|
|
16
17
|
from dbt_platform_helper.utils.application import get_application_name
|
|
17
18
|
from dbt_platform_helper.utils.application import load_application
|
|
18
19
|
from dbt_platform_helper.utils.aws import get_aws_session_or_abort
|
|
19
20
|
from dbt_platform_helper.utils.click import ClickDocOptGroup
|
|
20
21
|
from dbt_platform_helper.utils.files import generate_override_files
|
|
21
|
-
from dbt_platform_helper.utils.files import mkfile
|
|
22
22
|
from dbt_platform_helper.utils.messages import abort_with_error
|
|
23
23
|
from dbt_platform_helper.utils.template import ADDON_TEMPLATE_MAP
|
|
24
24
|
from dbt_platform_helper.utils.template import camel_case
|
|
@@ -379,7 +379,9 @@ def _generate_service_addons(
|
|
|
379
379
|
|
|
380
380
|
(output_dir / service_path).mkdir(parents=True, exist_ok=True)
|
|
381
381
|
click.echo(
|
|
382
|
-
mkfile(
|
|
382
|
+
FileProvider.mkfile(
|
|
383
|
+
output_dir, service_path / f"{addon_name}.yml", contents, overwrite=True
|
|
384
|
+
)
|
|
383
385
|
)
|
|
384
386
|
|
|
385
387
|
|
|
@@ -5,7 +5,7 @@ from dbt_platform_helper.constants import DEFAULT_TERRAFORM_PLATFORM_MODULES_VER
|
|
|
5
5
|
from dbt_platform_helper.constants import PLATFORM_CONFIG_FILE
|
|
6
6
|
from dbt_platform_helper.domain.config_validator import ConfigValidator
|
|
7
7
|
from dbt_platform_helper.domain.copilot_environment import CopilotEnvironment
|
|
8
|
-
from dbt_platform_helper.domain.maintenance_page import
|
|
8
|
+
from dbt_platform_helper.domain.maintenance_page import MaintenancePage
|
|
9
9
|
from dbt_platform_helper.domain.terraform_environment import TerraformEnvironment
|
|
10
10
|
from dbt_platform_helper.platform_exception import PlatformException
|
|
11
11
|
from dbt_platform_helper.providers.config import ConfigProvider
|
|
@@ -37,7 +37,7 @@ def environment():
|
|
|
37
37
|
def offline(app, env, svc, template, vpc):
|
|
38
38
|
"""Take load-balanced web services offline with a maintenance page."""
|
|
39
39
|
try:
|
|
40
|
-
|
|
40
|
+
MaintenancePage().activate(app, env, svc, template, vpc)
|
|
41
41
|
except PlatformException as err:
|
|
42
42
|
click.secho(str(err), fg="red")
|
|
43
43
|
raise click.Abort
|
|
@@ -49,28 +49,25 @@ def offline(app, env, svc, template, vpc):
|
|
|
49
49
|
def online(app, env):
|
|
50
50
|
"""Remove a maintenance page from an environment."""
|
|
51
51
|
try:
|
|
52
|
-
|
|
52
|
+
MaintenancePage().deactivate(app, env)
|
|
53
53
|
except PlatformException as err:
|
|
54
54
|
click.secho(str(err), fg="red")
|
|
55
55
|
raise click.Abort
|
|
56
56
|
|
|
57
57
|
|
|
58
58
|
@environment.command()
|
|
59
|
-
@click.option("--vpc-name", hidden=True)
|
|
60
59
|
@click.option("--name", "-n", required=True)
|
|
61
|
-
def generate(name
|
|
62
|
-
if vpc_name:
|
|
63
|
-
click.secho(
|
|
64
|
-
f"This option is deprecated. Please add the VPC name for your envs to {PLATFORM_CONFIG_FILE}",
|
|
65
|
-
fg="red",
|
|
66
|
-
)
|
|
67
|
-
raise click.Abort
|
|
60
|
+
def generate(name):
|
|
68
61
|
try:
|
|
69
62
|
config_provider = ConfigProvider(ConfigValidator())
|
|
70
63
|
CopilotEnvironment(config_provider).generate(name)
|
|
64
|
+
# TODO this exception will never be caught as the config provider catches schema errors and aborts
|
|
71
65
|
except SchemaError as ex:
|
|
72
66
|
click.secho(f"Invalid `{PLATFORM_CONFIG_FILE}` file: {str(ex)}", fg="red")
|
|
73
67
|
raise click.Abort
|
|
68
|
+
except PlatformException as err:
|
|
69
|
+
click.secho(str(err), fg="red")
|
|
70
|
+
raise click.Abort
|
|
74
71
|
|
|
75
72
|
|
|
76
73
|
@environment.command(help="Generate terraform manifest for the specified environment.")
|
|
@@ -82,5 +79,10 @@ def generate(name, vpc_name):
|
|
|
82
79
|
help=f"Override the default version of terraform-platform-modules. (Default version is '{DEFAULT_TERRAFORM_PLATFORM_MODULES_VERSION}').",
|
|
83
80
|
)
|
|
84
81
|
def generate_terraform(name, terraform_platform_modules_version):
|
|
85
|
-
|
|
86
|
-
|
|
82
|
+
|
|
83
|
+
try:
|
|
84
|
+
config_provider = ConfigProvider(ConfigValidator())
|
|
85
|
+
TerraformEnvironment(config_provider).generate(name, terraform_platform_modules_version)
|
|
86
|
+
except PlatformException as err:
|
|
87
|
+
click.secho(str(err), fg="red")
|
|
88
|
+
raise click.Abort
|
|
@@ -1,31 +1,19 @@
|
|
|
1
1
|
#!/usr/bin/env python
|
|
2
|
-
from os import makedirs
|
|
3
|
-
from pathlib import Path
|
|
4
|
-
from shutil import rmtree
|
|
5
2
|
|
|
6
3
|
import click
|
|
7
4
|
|
|
8
5
|
from dbt_platform_helper.constants import DEFAULT_TERRAFORM_PLATFORM_MODULES_VERSION
|
|
9
6
|
from dbt_platform_helper.domain.config_validator import ConfigValidator
|
|
7
|
+
from dbt_platform_helper.domain.pipelines import Pipelines
|
|
10
8
|
from dbt_platform_helper.providers.config import ConfigProvider
|
|
11
|
-
from dbt_platform_helper.utils.application import get_application_name
|
|
12
|
-
from dbt_platform_helper.utils.aws import get_account_details
|
|
13
9
|
from dbt_platform_helper.utils.aws import get_codestar_connection_arn
|
|
14
|
-
from dbt_platform_helper.utils.aws import get_public_repository_arn
|
|
15
10
|
from dbt_platform_helper.utils.click import ClickDocOptGroup
|
|
16
|
-
from dbt_platform_helper.utils.files import generate_override_files_from_template
|
|
17
|
-
from dbt_platform_helper.utils.files import mkfile
|
|
18
11
|
from dbt_platform_helper.utils.git import git_remote
|
|
19
12
|
from dbt_platform_helper.utils.messages import abort_with_error
|
|
20
|
-
from dbt_platform_helper.utils.template import setup_templates
|
|
21
13
|
from dbt_platform_helper.utils.versioning import (
|
|
22
14
|
check_platform_helper_version_needs_update,
|
|
23
15
|
)
|
|
24
16
|
|
|
25
|
-
CODEBASE_PIPELINES_KEY = "codebase_pipelines"
|
|
26
|
-
ENVIRONMENTS_KEY = "environments"
|
|
27
|
-
ENVIRONMENT_PIPELINES_KEY = "environment_pipelines"
|
|
28
|
-
|
|
29
17
|
|
|
30
18
|
@click.group(chain=True, cls=ClickDocOptGroup)
|
|
31
19
|
def pipeline():
|
|
@@ -62,161 +50,11 @@ def generate(terraform_platform_modules_version, deploy_branch):
|
|
|
62
50
|
This command does the following in relation to the codebase pipelines:
|
|
63
51
|
- Generates the copilot pipeline manifest.yml for copilot/pipelines/<codebase_pipeline_name>
|
|
64
52
|
"""
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
if not (has_codebase_pipelines or has_environment_pipelines):
|
|
72
|
-
click.secho("No pipelines defined: nothing to do.", err=True, fg="yellow")
|
|
73
|
-
return
|
|
74
|
-
|
|
75
|
-
platform_config_terraform_modules_default_version = pipeline_config.get(
|
|
76
|
-
"default_versions", {}
|
|
77
|
-
).get("terraform-platform-modules", "")
|
|
78
|
-
|
|
79
|
-
templates = setup_templates()
|
|
80
|
-
app_name = get_application_name()
|
|
81
|
-
|
|
82
|
-
git_repo = git_remote()
|
|
83
|
-
if not git_repo:
|
|
84
|
-
abort_with_error("The current directory is not a git repository")
|
|
85
|
-
|
|
86
|
-
codestar_connection_arn = get_codestar_connection_arn(app_name)
|
|
87
|
-
if codestar_connection_arn is None:
|
|
88
|
-
abort_with_error(f'There is no CodeStar Connection named "{app_name}" to use')
|
|
89
|
-
|
|
90
|
-
base_path = Path(".")
|
|
91
|
-
copilot_pipelines_dir = base_path / f"copilot/pipelines"
|
|
92
|
-
|
|
93
|
-
_clean_pipeline_config(copilot_pipelines_dir)
|
|
94
|
-
|
|
95
|
-
if has_environment_pipelines:
|
|
96
|
-
environment_pipelines = pipeline_config[ENVIRONMENT_PIPELINES_KEY]
|
|
97
|
-
|
|
98
|
-
for config in environment_pipelines.values():
|
|
99
|
-
aws_account = config.get("account")
|
|
100
|
-
_generate_terraform_environment_pipeline_manifest(
|
|
101
|
-
pipeline_config["application"],
|
|
102
|
-
aws_account,
|
|
103
|
-
terraform_platform_modules_version,
|
|
104
|
-
platform_config_terraform_modules_default_version,
|
|
105
|
-
deploy_branch,
|
|
106
|
-
)
|
|
107
|
-
|
|
108
|
-
if has_codebase_pipelines:
|
|
109
|
-
account_id, _ = get_account_details()
|
|
110
|
-
|
|
111
|
-
for codebase in pipeline_config[CODEBASE_PIPELINES_KEY]:
|
|
112
|
-
_generate_codebase_pipeline(
|
|
113
|
-
account_id,
|
|
114
|
-
app_name,
|
|
115
|
-
codestar_connection_arn,
|
|
116
|
-
git_repo,
|
|
117
|
-
codebase,
|
|
118
|
-
base_path,
|
|
119
|
-
copilot_pipelines_dir,
|
|
120
|
-
templates,
|
|
121
|
-
)
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
def _clean_pipeline_config(pipelines_dir):
|
|
125
|
-
if pipelines_dir.exists():
|
|
126
|
-
click.echo("Deleting copilot/pipelines directory.")
|
|
127
|
-
rmtree(pipelines_dir)
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
def _generate_codebase_pipeline(
|
|
131
|
-
account_id,
|
|
132
|
-
app_name,
|
|
133
|
-
codestar_connection_arn,
|
|
134
|
-
git_repo,
|
|
135
|
-
codebase,
|
|
136
|
-
base_path,
|
|
137
|
-
pipelines_dir,
|
|
138
|
-
templates,
|
|
139
|
-
):
|
|
140
|
-
makedirs(pipelines_dir / codebase["name"] / "overrides", exist_ok=True)
|
|
141
|
-
environments = []
|
|
142
|
-
for pipelines in codebase["pipelines"]:
|
|
143
|
-
environments += pipelines[ENVIRONMENTS_KEY]
|
|
144
|
-
|
|
145
|
-
additional_ecr = codebase.get("additional_ecr_repository", None)
|
|
146
|
-
add_public_perms = additional_ecr and additional_ecr.startswith("public.ecr.aws")
|
|
147
|
-
additional_ecr_arn = get_public_repository_arn(additional_ecr) if add_public_perms else None
|
|
148
|
-
|
|
149
|
-
template_data = {
|
|
150
|
-
"account_id": account_id,
|
|
151
|
-
"app_name": app_name,
|
|
152
|
-
"deploy_repo": git_repo,
|
|
153
|
-
"codebase": codebase,
|
|
154
|
-
ENVIRONMENTS_KEY: environments,
|
|
155
|
-
"codestar_connection_arn": codestar_connection_arn,
|
|
156
|
-
"codestar_connection_id": codestar_connection_arn.split("/")[-1],
|
|
157
|
-
"additional_ecr_arn": additional_ecr_arn,
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
_create_file_from_template(
|
|
161
|
-
base_path,
|
|
162
|
-
f"{codebase['name']}/manifest.yml",
|
|
163
|
-
pipelines_dir,
|
|
164
|
-
template_data,
|
|
165
|
-
templates,
|
|
166
|
-
"codebase/manifest.yml",
|
|
53
|
+
pipelines = Pipelines(
|
|
54
|
+
ConfigProvider(ConfigValidator()),
|
|
55
|
+
click.secho,
|
|
56
|
+
abort_with_error,
|
|
57
|
+
git_remote,
|
|
58
|
+
get_codestar_connection_arn,
|
|
167
59
|
)
|
|
168
|
-
|
|
169
|
-
overrides_path = Path(__file__).parent.parent.joinpath("templates/pipelines/codebase/overrides")
|
|
170
|
-
generate_override_files_from_template(
|
|
171
|
-
base_path, overrides_path, pipelines_dir / codebase["name"] / "overrides", template_data
|
|
172
|
-
)
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
def _create_file_from_template(
|
|
176
|
-
base_path, file_name, pipelines_dir, template_data, templates, template_name=None
|
|
177
|
-
):
|
|
178
|
-
contents = templates.get_template(
|
|
179
|
-
f"pipelines/{file_name if template_name is None else template_name}"
|
|
180
|
-
).render(template_data)
|
|
181
|
-
message = mkfile(base_path, pipelines_dir / file_name, contents, overwrite=True)
|
|
182
|
-
click.echo(message)
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
def _generate_terraform_environment_pipeline_manifest(
|
|
186
|
-
application,
|
|
187
|
-
aws_account,
|
|
188
|
-
cli_terraform_platform_modules_version,
|
|
189
|
-
platform_config_terraform_modules_default_version,
|
|
190
|
-
deploy_branch,
|
|
191
|
-
):
|
|
192
|
-
env_pipeline_template = setup_templates().get_template("environment-pipelines/main.tf")
|
|
193
|
-
|
|
194
|
-
terraform_platform_modules_version = _determine_terraform_platform_modules_version(
|
|
195
|
-
cli_terraform_platform_modules_version, platform_config_terraform_modules_default_version
|
|
196
|
-
)
|
|
197
|
-
|
|
198
|
-
contents = env_pipeline_template.render(
|
|
199
|
-
{
|
|
200
|
-
"application": application,
|
|
201
|
-
"aws_account": aws_account,
|
|
202
|
-
"terraform_platform_modules_version": terraform_platform_modules_version,
|
|
203
|
-
"deploy_branch": deploy_branch,
|
|
204
|
-
}
|
|
205
|
-
)
|
|
206
|
-
|
|
207
|
-
dir_path = f"terraform/environment-pipelines/{aws_account}"
|
|
208
|
-
makedirs(dir_path, exist_ok=True)
|
|
209
|
-
|
|
210
|
-
click.echo(mkfile(".", f"{dir_path}/main.tf", contents, overwrite=True))
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
def _determine_terraform_platform_modules_version(
|
|
214
|
-
cli_terraform_platform_modules_version, platform_config_terraform_modules_default_version
|
|
215
|
-
):
|
|
216
|
-
|
|
217
|
-
version_preference_order = [
|
|
218
|
-
cli_terraform_platform_modules_version,
|
|
219
|
-
platform_config_terraform_modules_default_version,
|
|
220
|
-
DEFAULT_TERRAFORM_PLATFORM_MODULES_VERSION,
|
|
221
|
-
]
|
|
222
|
-
return [version for version in version_preference_order if version][0]
|
|
60
|
+
pipelines.generate(terraform_platform_modules_version, deploy_branch)
|
dbt_platform_helper/constants.py
CHANGED
|
@@ -10,6 +10,7 @@ import yaml
|
|
|
10
10
|
from boto3 import Session
|
|
11
11
|
|
|
12
12
|
from dbt_platform_helper.platform_exception import PlatformException
|
|
13
|
+
from dbt_platform_helper.providers.files import FileProvider
|
|
13
14
|
from dbt_platform_helper.utils.application import Application
|
|
14
15
|
from dbt_platform_helper.utils.application import ApplicationException
|
|
15
16
|
from dbt_platform_helper.utils.application import load_application
|
|
@@ -19,7 +20,6 @@ from dbt_platform_helper.utils.aws import get_aws_session_or_abort
|
|
|
19
20
|
from dbt_platform_helper.utils.aws import get_build_url_from_arn
|
|
20
21
|
from dbt_platform_helper.utils.aws import list_latest_images
|
|
21
22
|
from dbt_platform_helper.utils.aws import start_build_extraction
|
|
22
|
-
from dbt_platform_helper.utils.files import mkfile
|
|
23
23
|
from dbt_platform_helper.utils.git import check_if_commit_exists
|
|
24
24
|
from dbt_platform_helper.utils.template import setup_templates
|
|
25
25
|
|
|
@@ -92,7 +92,7 @@ class Codebase:
|
|
|
92
92
|
repository=repository, builder_version=builder_version
|
|
93
93
|
)
|
|
94
94
|
self.echo(
|
|
95
|
-
mkfile(
|
|
95
|
+
FileProvider.mkfile(
|
|
96
96
|
Path("."), ".copilot/image_build_run.sh", image_build_run_contents, overwrite=True
|
|
97
97
|
)
|
|
98
98
|
)
|
|
@@ -100,13 +100,17 @@ class Codebase:
|
|
|
100
100
|
image_build_run_file = Path(".copilot/image_build_run.sh")
|
|
101
101
|
image_build_run_file.chmod(image_build_run_file.stat().st_mode | stat.S_IEXEC)
|
|
102
102
|
|
|
103
|
-
self.echo(
|
|
103
|
+
self.echo(
|
|
104
|
+
FileProvider.mkfile(Path("."), ".copilot/config.yml", config_contents, overwrite=True)
|
|
105
|
+
)
|
|
104
106
|
|
|
105
107
|
for phase in ["build", "install", "post_build", "pre_build"]:
|
|
106
108
|
phase_contents = templates.get_template(f".copilot/phases/{phase}.sh").render()
|
|
107
109
|
|
|
108
110
|
self.echo(
|
|
109
|
-
mkfile(
|
|
111
|
+
FileProvider.mkfile(
|
|
112
|
+
Path("./.copilot"), f"phases/{phase}.sh", phase_contents, overwrite=True
|
|
113
|
+
)
|
|
110
114
|
)
|
|
111
115
|
|
|
112
116
|
def build(self, app: str, codebase: str, commit: str):
|
|
@@ -5,9 +5,9 @@ import boto3
|
|
|
5
5
|
import click
|
|
6
6
|
|
|
7
7
|
from dbt_platform_helper.platform_exception import PlatformException
|
|
8
|
+
from dbt_platform_helper.providers.files import FileProvider
|
|
8
9
|
from dbt_platform_helper.providers.load_balancers import find_https_listener
|
|
9
10
|
from dbt_platform_helper.utils.aws import get_aws_session_or_abort
|
|
10
|
-
from dbt_platform_helper.utils.files import mkfile
|
|
11
11
|
from dbt_platform_helper.utils.template import S3_CROSS_ACCOUNT_POLICY
|
|
12
12
|
from dbt_platform_helper.utils.template import camel_case
|
|
13
13
|
from dbt_platform_helper.utils.template import setup_templates
|
|
@@ -111,7 +111,7 @@ def _generate_copilot_environment_manifests(
|
|
|
111
111
|
}
|
|
112
112
|
)
|
|
113
113
|
click.echo(
|
|
114
|
-
mkfile(
|
|
114
|
+
FileProvider.mkfile(
|
|
115
115
|
".", f"copilot/environments/{environment_name}/manifest.yml", contents, overwrite=True
|
|
116
116
|
)
|
|
117
117
|
)
|
|
@@ -155,7 +155,7 @@ class CopilotEnvironment:
|
|
|
155
155
|
|
|
156
156
|
|
|
157
157
|
class CopilotTemplating:
|
|
158
|
-
def __init__(self, mkfile_fn=mkfile):
|
|
158
|
+
def __init__(self, mkfile_fn=FileProvider.mkfile):
|
|
159
159
|
self.mkfile_fn = mkfile_fn
|
|
160
160
|
|
|
161
161
|
def generate_cross_account_s3_policies(self, environments: dict, extensions):
|
|
@@ -8,15 +8,15 @@ from boto3 import Session
|
|
|
8
8
|
|
|
9
9
|
from dbt_platform_helper.constants import PLATFORM_CONFIG_FILE
|
|
10
10
|
from dbt_platform_helper.domain.config_validator import ConfigValidator
|
|
11
|
-
from dbt_platform_helper.domain.maintenance_page import
|
|
11
|
+
from dbt_platform_helper.domain.maintenance_page import MaintenancePage
|
|
12
12
|
from dbt_platform_helper.providers.aws import AWSException
|
|
13
13
|
from dbt_platform_helper.providers.config import ConfigProvider
|
|
14
|
+
from dbt_platform_helper.providers.vpc import Vpc
|
|
15
|
+
from dbt_platform_helper.providers.vpc import VpcProvider
|
|
14
16
|
from dbt_platform_helper.utils.application import Application
|
|
15
17
|
from dbt_platform_helper.utils.application import ApplicationNotFoundException
|
|
16
18
|
from dbt_platform_helper.utils.application import load_application
|
|
17
|
-
from dbt_platform_helper.utils.aws import Vpc
|
|
18
19
|
from dbt_platform_helper.utils.aws import get_connection_string
|
|
19
|
-
from dbt_platform_helper.utils.aws import get_vpc_info_by_name
|
|
20
20
|
from dbt_platform_helper.utils.aws import wait_for_log_group_to_exist
|
|
21
21
|
from dbt_platform_helper.utils.messages import abort_with_error
|
|
22
22
|
|
|
@@ -28,13 +28,14 @@ class DatabaseCopy:
|
|
|
28
28
|
database: str,
|
|
29
29
|
auto_approve: bool = False,
|
|
30
30
|
load_application: Callable[[str], Application] = load_application,
|
|
31
|
-
|
|
31
|
+
# TODO We inject VpcProvider as a callable here so that it can be instantiated within the method. To be improved
|
|
32
|
+
vpc_provider: Callable[[Session], VpcProvider] = VpcProvider,
|
|
32
33
|
db_connection_string: Callable[
|
|
33
34
|
[Session, str, str, str, Callable], str
|
|
34
35
|
] = get_connection_string,
|
|
35
36
|
maintenance_page_provider: Callable[
|
|
36
37
|
[str, str, list[str], str, str], None
|
|
37
|
-
] =
|
|
38
|
+
] = MaintenancePage(),
|
|
38
39
|
input: Callable[[str], str] = click.prompt,
|
|
39
40
|
echo: Callable[[str], str] = click.secho,
|
|
40
41
|
abort: Callable[[str], None] = abort_with_error,
|
|
@@ -43,7 +44,7 @@ class DatabaseCopy:
|
|
|
43
44
|
self.app = app
|
|
44
45
|
self.database = database
|
|
45
46
|
self.auto_approve = auto_approve
|
|
46
|
-
self.
|
|
47
|
+
self.vpc_provider = vpc_provider
|
|
47
48
|
self.db_connection_string = db_connection_string
|
|
48
49
|
self.maintenance_page_provider = maintenance_page_provider
|
|
49
50
|
self.input = input
|
|
@@ -76,7 +77,8 @@ class DatabaseCopy:
|
|
|
76
77
|
env_session = environment.session
|
|
77
78
|
|
|
78
79
|
try:
|
|
79
|
-
|
|
80
|
+
vpc_provider = self.vpc_provider(env_session)
|
|
81
|
+
vpc_config = vpc_provider.get_vpc_info_by_name(self.app, env, vpc_name)
|
|
80
82
|
except AWSException as ex:
|
|
81
83
|
self.abort(str(ex))
|
|
82
84
|
|
|
@@ -3,38 +3,62 @@ import random
|
|
|
3
3
|
import re
|
|
4
4
|
import string
|
|
5
5
|
from pathlib import Path
|
|
6
|
+
from typing import Callable
|
|
6
7
|
from typing import List
|
|
7
8
|
from typing import Union
|
|
8
9
|
|
|
9
10
|
import boto3
|
|
10
11
|
import click
|
|
11
12
|
|
|
13
|
+
from dbt_platform_helper.platform_exception import PlatformException
|
|
12
14
|
from dbt_platform_helper.providers.load_balancers import ListenerNotFoundException
|
|
13
15
|
from dbt_platform_helper.providers.load_balancers import ListenerRuleNotFoundException
|
|
14
16
|
from dbt_platform_helper.providers.load_balancers import LoadBalancerNotFoundException
|
|
15
17
|
from dbt_platform_helper.providers.load_balancers import find_https_listener
|
|
18
|
+
from dbt_platform_helper.utils.application import Application
|
|
16
19
|
from dbt_platform_helper.utils.application import Environment
|
|
17
20
|
from dbt_platform_helper.utils.application import Service
|
|
18
21
|
from dbt_platform_helper.utils.application import load_application
|
|
19
22
|
|
|
20
23
|
|
|
21
|
-
class
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
24
|
+
class MaintenancePageException(PlatformException):
|
|
25
|
+
pass
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class LoadBalancedWebServiceNotFoundException(MaintenancePageException):
|
|
29
|
+
pass
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class MaintenancePage:
|
|
33
|
+
def __init__(
|
|
34
|
+
self,
|
|
35
|
+
user_prompt_callback: Callable[[str], bool] = click.confirm,
|
|
36
|
+
echo: Callable[[str], str] = click.secho,
|
|
37
|
+
):
|
|
38
|
+
self.user_prompt_callback = user_prompt_callback
|
|
39
|
+
self.echo = echo
|
|
25
40
|
|
|
41
|
+
def _get_deployed_load_balanced_web_services(self, app: Application, svc: str):
|
|
26
42
|
if "*" in svc:
|
|
27
|
-
services = [
|
|
28
|
-
s for s in application.services.values() if s.kind == "Load Balanced Web Service"
|
|
29
|
-
]
|
|
43
|
+
services = [s for s in app.services.values() if s.kind == "Load Balanced Web Service"]
|
|
30
44
|
else:
|
|
31
|
-
all_services = [get_app_service(app, s) for s in list(svc)]
|
|
45
|
+
all_services = [get_app_service(app.name, s) for s in list(svc)]
|
|
32
46
|
services = [s for s in all_services if s.kind == "Load Balanced Web Service"]
|
|
33
|
-
|
|
34
47
|
if not services:
|
|
35
|
-
|
|
48
|
+
raise LoadBalancedWebServiceNotFoundException
|
|
49
|
+
return services
|
|
50
|
+
|
|
51
|
+
def activate(self, app, env, svc, template, vpc):
|
|
52
|
+
try:
|
|
53
|
+
services = self._get_deployed_load_balanced_web_services(load_application(app), svc)
|
|
54
|
+
except LoadBalancedWebServiceNotFoundException:
|
|
55
|
+
# TODO DBTP-1643 - this bit of logic does not depend on env, so env shouldn't really be in the exception
|
|
56
|
+
# message
|
|
57
|
+
# Exception should be propagated to command and caught there.
|
|
58
|
+
self.echo(f"No services deployed yet to {app} environment {env}", fg="red")
|
|
36
59
|
raise click.Abort
|
|
37
60
|
|
|
61
|
+
application_environment = get_app_environment(app, env)
|
|
38
62
|
try:
|
|
39
63
|
https_listener = find_https_listener(application_environment.session, app, env)
|
|
40
64
|
current_maintenance_page = get_maintenance_page(
|
|
@@ -42,7 +66,7 @@ class MaintenancePageProvider:
|
|
|
42
66
|
)
|
|
43
67
|
remove_current_maintenance_page = False
|
|
44
68
|
if current_maintenance_page:
|
|
45
|
-
remove_current_maintenance_page =
|
|
69
|
+
remove_current_maintenance_page = self.user_prompt_callback(
|
|
46
70
|
f"There is currently a '{current_maintenance_page}' maintenance page for the {env} "
|
|
47
71
|
f"environment in {app}.\nWould you like to replace it with a '{template}' "
|
|
48
72
|
f"maintenance page?"
|
|
@@ -50,7 +74,7 @@ class MaintenancePageProvider:
|
|
|
50
74
|
if not remove_current_maintenance_page:
|
|
51
75
|
raise click.Abort
|
|
52
76
|
|
|
53
|
-
if remove_current_maintenance_page or
|
|
77
|
+
if remove_current_maintenance_page or self.user_prompt_callback(
|
|
54
78
|
f"You are about to enable the '{template}' maintenance page for the {env} "
|
|
55
79
|
f"environment in {app}.\nWould you like to continue?"
|
|
56
80
|
):
|
|
@@ -68,7 +92,7 @@ class MaintenancePageProvider:
|
|
|
68
92
|
allowed_ips,
|
|
69
93
|
template,
|
|
70
94
|
)
|
|
71
|
-
|
|
95
|
+
self.echo(
|
|
72
96
|
f"Maintenance page '{template}' added for environment {env} in application {app}",
|
|
73
97
|
fg="green",
|
|
74
98
|
)
|
|
@@ -76,13 +100,13 @@ class MaintenancePageProvider:
|
|
|
76
100
|
raise click.Abort
|
|
77
101
|
|
|
78
102
|
except LoadBalancerNotFoundException:
|
|
79
|
-
|
|
103
|
+
self.echo(
|
|
80
104
|
f"No load balancer found for environment {env} in the application {app}.", fg="red"
|
|
81
105
|
)
|
|
82
106
|
raise click.Abort
|
|
83
107
|
|
|
84
108
|
except ListenerNotFoundException:
|
|
85
|
-
|
|
109
|
+
self.echo(
|
|
86
110
|
f"No HTTPS listener found for environment {env} in the application {app}.", fg="red"
|
|
87
111
|
)
|
|
88
112
|
raise click.Abort
|
|
@@ -96,28 +120,28 @@ class MaintenancePageProvider:
|
|
|
96
120
|
application_environment.session, https_listener
|
|
97
121
|
)
|
|
98
122
|
if not current_maintenance_page:
|
|
99
|
-
|
|
123
|
+
self.echo("There is no current maintenance page to remove", fg="red")
|
|
100
124
|
raise click.Abort
|
|
101
125
|
|
|
102
|
-
if not
|
|
126
|
+
if not self.user_prompt_callback(
|
|
103
127
|
f"There is currently a '{current_maintenance_page}' maintenance page, "
|
|
104
128
|
f"would you like to remove it?"
|
|
105
129
|
):
|
|
106
130
|
raise click.Abort
|
|
107
131
|
|
|
108
132
|
remove_maintenance_page(application_environment.session, https_listener)
|
|
109
|
-
|
|
133
|
+
self.echo(
|
|
110
134
|
f"Maintenance page removed from environment {env} in application {app}", fg="green"
|
|
111
135
|
)
|
|
112
136
|
|
|
113
137
|
except LoadBalancerNotFoundException:
|
|
114
|
-
|
|
138
|
+
self.echo(
|
|
115
139
|
f"No load balancer found for environment {env} in the application {app}.", fg="red"
|
|
116
140
|
)
|
|
117
141
|
raise click.Abort
|
|
118
142
|
|
|
119
143
|
except ListenerNotFoundException:
|
|
120
|
-
|
|
144
|
+
self.echo(
|
|
121
145
|
f"No HTTPS listener found for environment {env} in the application {app}.", fg="red"
|
|
122
146
|
)
|
|
123
147
|
raise click.Abort
|