dbt-platform-helper 15.9.0__py3-none-any.whl → 15.11.0__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.

Files changed (26) hide show
  1. dbt_platform_helper/COMMANDS.md +1 -51
  2. dbt_platform_helper/commands/internal.py +134 -0
  3. dbt_platform_helper/constants.py +14 -0
  4. dbt_platform_helper/domain/conduit.py +1 -1
  5. dbt_platform_helper/domain/config.py +30 -1
  6. dbt_platform_helper/domain/maintenance_page.py +10 -8
  7. dbt_platform_helper/domain/service.py +317 -53
  8. dbt_platform_helper/domain/update_alb_rules.py +346 -0
  9. dbt_platform_helper/entities/platform_config_schema.py +4 -5
  10. dbt_platform_helper/entities/service.py +139 -13
  11. dbt_platform_helper/providers/aws/exceptions.py +5 -0
  12. dbt_platform_helper/providers/aws/sso_auth.py +14 -0
  13. dbt_platform_helper/providers/config.py +0 -11
  14. dbt_platform_helper/providers/ecs.py +104 -11
  15. dbt_platform_helper/providers/load_balancers.py +86 -8
  16. dbt_platform_helper/providers/logs.py +57 -0
  17. dbt_platform_helper/providers/s3.py +21 -0
  18. dbt_platform_helper/providers/terraform_manifest.py +3 -5
  19. dbt_platform_helper/providers/yaml_file.py +13 -5
  20. {dbt_platform_helper-15.9.0.dist-info → dbt_platform_helper-15.11.0.dist-info}/METADATA +5 -3
  21. {dbt_platform_helper-15.9.0.dist-info → dbt_platform_helper-15.11.0.dist-info}/RECORD +25 -22
  22. {dbt_platform_helper-15.9.0.dist-info → dbt_platform_helper-15.11.0.dist-info}/WHEEL +1 -1
  23. platform_helper.py +2 -2
  24. dbt_platform_helper/commands/service.py +0 -53
  25. {dbt_platform_helper-15.9.0.dist-info → dbt_platform_helper-15.11.0.dist-info}/entry_points.txt +0 -0
  26. {dbt_platform_helper-15.9.0.dist-info → dbt_platform_helper-15.11.0.dist-info/licenses}/LICENSE +0 -0
@@ -27,8 +27,6 @@
27
27
  - [platform-helper secrets](#platform-helper-secrets)
28
28
  - [platform-helper secrets copy](#platform-helper-secrets-copy)
29
29
  - [platform-helper secrets list](#platform-helper-secrets-list)
30
- - [platform-helper service](#platform-helper-service)
31
- - [platform-helper service generate](#platform-helper-service-generate)
32
30
  - [platform-helper notify](#platform-helper-notify)
33
31
  - [platform-helper notify environment-progress](#platform-helper-notify-environment-progress)
34
32
  - [platform-helper notify post-message](#platform-helper-notify-post-message)
@@ -65,10 +63,10 @@ platform-helper <command> [--version]
65
63
  - [`database` ↪](#platform-helper-database)
66
64
  - [`environment` ↪](#platform-helper-environment)
67
65
  - [`generate` ↪](#platform-helper-generate)
66
+ - [`internal` ↪](#platform-helper-internal)
68
67
  - [`notify` ↪](#platform-helper-notify)
69
68
  - [`pipeline` ↪](#platform-helper-pipeline)
70
69
  - [`secrets` ↪](#platform-helper-secrets)
71
- - [`service` ↪](#platform-helper-service)
72
70
  - [`version` ↪](#platform-helper-version)
73
71
 
74
72
  # platform-helper application
@@ -663,54 +661,6 @@ platform-helper secrets list <application> <environment>
663
661
  - `--help <boolean>` _Defaults to False._
664
662
  - Show this message and exit.
665
663
 
666
- # platform-helper service
667
-
668
- [↩ Parent](#platform-helper)
669
-
670
- Commands affecting services.
671
-
672
- ## Usage
673
-
674
- ```
675
- platform-helper service generate
676
- ```
677
-
678
- ## Options
679
-
680
- - `--help <boolean>` _Defaults to False._
681
- - Show this message and exit.
682
-
683
- ## Commands
684
-
685
- - [`generate` ↪](#platform-helper-service-generate)
686
-
687
- # platform-helper service generate
688
-
689
- [↩ Parent](#platform-helper-service)
690
-
691
- Generate terraform manifest for the specified service(s).
692
-
693
- ## Usage
694
-
695
- ```
696
- platform-helper service generate [--name <name>] [--environment <environment>]
697
- [--image-tag <image_tag>]
698
- ```
699
-
700
- ## Options
701
-
702
- - `--name
703
- -n <text>`
704
- - The name of the service to generate a manifest for. Multiple values accepted.
705
- - `--environment
706
- -e <text>`
707
- - The name of the environment to generate service manifests for. Multiple values accepted.
708
- - `--image-tag
709
- -i <text>`
710
- - Docker image tag to deploy for the service. Overrides the $IMAGE_TAG environment variable.
711
- - `--help <boolean>` _Defaults to False._
712
- - Show this message and exit.
713
-
714
664
  # platform-helper notify
715
665
 
716
666
  [↩ Parent](#platform-helper)
@@ -0,0 +1,134 @@
1
+ import click
2
+
3
+ from dbt_platform_helper.domain.service import ServiceManager
4
+ from dbt_platform_helper.domain.update_alb_rules import UpdateALBRules
5
+ from dbt_platform_helper.domain.versioning import PlatformHelperVersioning
6
+ from dbt_platform_helper.platform_exception import PlatformException
7
+ from dbt_platform_helper.providers.config import ConfigProvider
8
+ from dbt_platform_helper.providers.config_validator import ConfigValidator
9
+ from dbt_platform_helper.providers.ecs import ECS
10
+ from dbt_platform_helper.providers.io import ClickIOProvider
11
+ from dbt_platform_helper.providers.logs import LogsProvider
12
+ from dbt_platform_helper.providers.s3 import S3Provider
13
+ from dbt_platform_helper.utils.application import load_application
14
+ from dbt_platform_helper.utils.aws import get_aws_session_or_abort
15
+ from dbt_platform_helper.utils.click import ClickDocOptGroup
16
+
17
+
18
+ @click.group(cls=ClickDocOptGroup)
19
+ def internal():
20
+ """Internal commands for use within pipelines or by Platform Team."""
21
+
22
+
23
+ @internal.command()
24
+ def migrate_service_manifests():
25
+ """Migrate copilot manifests to service manifests."""
26
+ click_io = ClickIOProvider()
27
+
28
+ try:
29
+ service_manager = ServiceManager()
30
+ service_manager.migrate_copilot_manifests()
31
+ except PlatformException as error:
32
+ click_io.abort_with_error(str(error))
33
+
34
+
35
+ @internal.group(cls=ClickDocOptGroup)
36
+ def service():
37
+ """Subgroup for 'internal service' commands."""
38
+
39
+
40
+ @service.command(help="Trigger an ECS deployment.")
41
+ @click.option("--name", required=True, help="The name of the ECS service to create or update.")
42
+ @click.option(
43
+ "--env",
44
+ required=True,
45
+ help="The name of the environment where the ECS service will be created or updated.",
46
+ )
47
+ @click.option(
48
+ "--image-tag",
49
+ required=True,
50
+ help="Image tag to deploy for the service(s). Takes precedence over the $IMAGE_TAG environment variable.",
51
+ )
52
+ def deploy(name, env, image_tag):
53
+ """Register a new ECS task definition from an S3 JSON template, update the
54
+ ECS service, and tail CloudWatch logs until the ECS rollout is complete."""
55
+ click_io = ClickIOProvider()
56
+
57
+ try:
58
+
59
+ config = ConfigProvider(ConfigValidator()).get_enriched_config()
60
+ application_name = config.get("application", "")
61
+ application = load_application(app=application_name, env=env)
62
+
63
+ ecs_client = application.environments[env].session.client("ecs")
64
+ ssm_client = application.environments[env].session.client("ssm")
65
+ s3_client = application.environments[env].session.client("s3")
66
+ logs_client = application.environments[env].session.client("logs")
67
+
68
+ ecs_provider = ECS(
69
+ ecs_client=ecs_client,
70
+ ssm_client=ssm_client,
71
+ application_name=application.name,
72
+ env=env,
73
+ )
74
+ s3_provider = S3Provider(client=s3_client)
75
+ logs_provider = LogsProvider(client=logs_client)
76
+
77
+ service_manager = ServiceManager(
78
+ ecs_provider=ecs_provider, s3_provider=s3_provider, logs_provider=logs_provider
79
+ )
80
+ service_manager.deploy(
81
+ service=name,
82
+ environment=env,
83
+ application=application.name,
84
+ image_tag=image_tag,
85
+ )
86
+ except PlatformException as error:
87
+ click_io.abort_with_error(str(error))
88
+
89
+
90
+ @service.command(help="Generate Terraform manifest for the specified service(s).")
91
+ @click.option(
92
+ "--name",
93
+ required=False,
94
+ help="The name of the service(s) to generate service manifest(s) for.",
95
+ multiple=True,
96
+ )
97
+ @click.option(
98
+ "--env",
99
+ required=True,
100
+ help="The name of the environment to generate service manifests for.",
101
+ )
102
+ def generate(name, env):
103
+ """Validates the service-config.yml format, applies the environment-specific
104
+ overrides, and generates a Terraform manifest at
105
+ /terraform/services/<environment>/<service>/main.tf.json."""
106
+
107
+ services = list(name)
108
+ click_io = ClickIOProvider()
109
+
110
+ try:
111
+ service_manager = ServiceManager()
112
+ service_manager.generate(environment=env, services=services)
113
+
114
+ except PlatformException as err:
115
+ click_io.abort_with_error(str(err))
116
+
117
+
118
+ @internal.group(cls=ClickDocOptGroup)
119
+ def alb():
120
+ """Load Balancer related commands."""
121
+ PlatformHelperVersioning().check_if_needs_update()
122
+
123
+
124
+ @alb.command()
125
+ @click.option("--env", type=str, required=True)
126
+ def update_rules(env: str):
127
+ """Update alb rules based on service-deployment-mode for a given
128
+ environment."""
129
+ try:
130
+ session = get_aws_session_or_abort()
131
+ update_aws = UpdateALBRules(session)
132
+ update_aws.update_alb_rules(environment=env)
133
+ except PlatformException as err:
134
+ ClickIOProvider().abort_with_error(str(err))
@@ -45,3 +45,17 @@ SERVICE_NAME_SUFFIX = f"Service-{COPILOT_IDENTIFIER}"
45
45
  REFRESH_TOKEN_MESSAGE = (
46
46
  "To refresh this SSO session run `aws sso login` with the corresponding profile"
47
47
  )
48
+ COPILOT_RULE_PRIORITY = 48000
49
+ PLATFORM_RULE_STARTING_PRIORITY = 10000
50
+ RULE_PRIORITY_INCREMENT = 100
51
+ DUMMY_RULE_REASON = "DummyRule"
52
+ MAINTENANCE_PAGE_TAGS = ["MaintenancePage", "AllowedIps", "BypassIpFilter", "AllowedSourceIps"]
53
+ MAINTENANCE_PAGE_REASON = "MaintenancePage"
54
+ MANAGED_BY_PLATFORM = "DBT Platform"
55
+ MANAGED_BY_SERVICE_TERRAFORM = "DBT Platform - Service Terraform"
56
+ MANAGED_BY_PLATFORM_TERRAFORM = "DBT Platform - Terraform"
57
+ STANDARD_PLATFORM_SSO_ROLES = [
58
+ "AdministratorAccess",
59
+ "DBTPlatformDeveloperWrite",
60
+ "DBTPlatformDeveloperRead",
61
+ ]
@@ -326,7 +326,7 @@ class Conduit:
326
326
  data_context = strategy.get_data()
327
327
 
328
328
  data_context["task_arns"] = self.ecs_provider.get_ecs_task_arns(
329
- data_context["cluster_arn"], data_context["task_def_family"]
329
+ cluster=data_context["cluster_arn"], task_def_family=data_context["task_def_family"]
330
330
  )
331
331
 
332
332
  info_log = (
@@ -7,6 +7,7 @@ from typing import Dict
7
7
  from prettytable import PrettyTable
8
8
 
9
9
  from dbt_platform_helper.constants import PLATFORM_CONFIG_FILE
10
+ from dbt_platform_helper.constants import STANDARD_PLATFORM_SSO_ROLES
10
11
  from dbt_platform_helper.domain.versioning import AWSVersioning
11
12
  from dbt_platform_helper.domain.versioning import CopilotVersioning
12
13
  from dbt_platform_helper.domain.versioning import PlatformHelperVersioning
@@ -140,6 +141,10 @@ class Config:
140
141
  if self.io.confirm(
141
142
  f"This command is destructive and will overwrite file contents at {file_path}. Are you sure you want to continue?"
142
143
  ):
144
+ self.io.info(
145
+ "Fetching credentials... this may take longer if you have access to many accounts."
146
+ )
147
+
143
148
  with open(aws_config_path, "w") as config_file:
144
149
  config_file.write(AWS_CONFIG)
145
150
 
@@ -147,7 +152,9 @@ class Config:
147
152
  config_file.write(f"[profile {account['accountName']}]\n")
148
153
  config_file.write("sso_session = uktrade\n")
149
154
  config_file.write(f"sso_account_id = {account['accountId']}\n")
150
- config_file.write("sso_role_name = AdministratorAccess\n")
155
+ config_file.write(
156
+ f"sso_role_name = {self._retrieve_role_for_aws_account(aws_sso_token=access_token, account_id=account['accountId'])}\n"
157
+ )
151
158
  config_file.write("region = eu-west-2\n")
152
159
  config_file.write("output = json\n")
153
160
  config_file.write("\n")
@@ -177,6 +184,28 @@ class Config:
177
184
  )
178
185
  return accounts_list
179
186
 
187
+ def _retrieve_role_for_aws_account(self, aws_sso_token, account_id):
188
+ """
189
+ Selects the most appropriate IAM role for a given AWS account.
190
+
191
+ Roles listed in STANDARD_PLATFORM_SSO_ROLES are preferred if available.
192
+ If none are found, the first available role returned by
193
+ sso.list_account_roles is used.
194
+ """
195
+
196
+ role_list = self.sso.list_account_roles(
197
+ access_token=aws_sso_token,
198
+ account_id=account_id,
199
+ max_results=100,
200
+ )
201
+
202
+ roles_retrieved = [r["roleName"] for r in role_list]
203
+
204
+ for role in STANDARD_PLATFORM_SSO_ROLES:
205
+ if role in roles_retrieved:
206
+ return role
207
+ return role_list[0]["roleName"]
208
+
180
209
  def _add_version_status_row(
181
210
  self, table: PrettyTable, header: str, version_status: VersionStatus
182
211
  ):
@@ -10,6 +10,8 @@ from typing import Union
10
10
 
11
11
  import click
12
12
 
13
+ from dbt_platform_helper.constants import MAINTENANCE_PAGE_REASON
14
+ from dbt_platform_helper.constants import MANAGED_BY_PLATFORM
13
15
  from dbt_platform_helper.platform_exception import PlatformException
14
16
  from dbt_platform_helper.providers.io import ClickIOProvider
15
17
  from dbt_platform_helper.providers.load_balancers import ListenerRuleNotFoundException
@@ -202,8 +204,8 @@ class MaintenancePage:
202
204
  [
203
205
  {"Key": "application", "Value": app},
204
206
  {"Key": "environment", "Value": env},
205
- {"Key": "reason", "Value": "MaintenancePage"},
206
- {"Key": "managed-by", "Value": "DBT Platform"},
207
+ {"Key": "reason", "Value": MAINTENANCE_PAGE_REASON},
208
+ {"Key": "managed-by", "Value": MANAGED_BY_PLATFORM},
207
209
  {"Key": "service", "Value": svc.name},
208
210
  ],
209
211
  )
@@ -217,8 +219,8 @@ class MaintenancePage:
217
219
  [
218
220
  {"Key": "application", "Value": app},
219
221
  {"Key": "environment", "Value": env},
220
- {"Key": "reason", "Value": "MaintenancePage"},
221
- {"Key": "managed-by", "Value": "DBT Platform"},
222
+ {"Key": "reason", "Value": MAINTENANCE_PAGE_REASON},
223
+ {"Key": "managed-by", "Value": MANAGED_BY_PLATFORM},
222
224
  {"Key": "service", "Value": svc.name},
223
225
  ],
224
226
  )
@@ -234,8 +236,8 @@ class MaintenancePage:
234
236
  [
235
237
  {"Key": "application", "Value": app},
236
238
  {"Key": "environment", "Value": env},
237
- {"Key": "reason", "Value": "MaintenancePage"},
238
- {"Key": "managed-by", "Value": "DBT Platform"},
239
+ {"Key": "reason", "Value": MAINTENANCE_PAGE_REASON},
240
+ {"Key": "managed-by", "Value": MANAGED_BY_PLATFORM},
239
241
  {"Key": "service", "Value": svc.name},
240
242
  ],
241
243
  )
@@ -287,10 +289,10 @@ class MaintenancePage:
287
289
  tags=[
288
290
  {"Key": "application", "Value": app},
289
291
  {"Key": "environment", "Value": env},
290
- {"Key": "reason", "Value": "MaintenancePage"},
292
+ {"Key": "reason", "Value": MAINTENANCE_PAGE_REASON},
291
293
  {"Key": "name", "Value": "MaintenancePage"},
292
294
  {"Key": "type", "Value": template},
293
- {"Key": "managed-by", "Value": "DBT Platform"},
295
+ {"Key": "managed-by", "Value": MANAGED_BY_PLATFORM},
294
296
  ],
295
297
  )
296
298
  except Exception as e: