dbt-platform-helper 13.3.0__py3-none-any.whl → 13.4.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.

@@ -236,7 +236,8 @@ platform-helper codebase build --app <application> --codebase <codebase>
236
236
 
237
237
  ```
238
238
  platform-helper codebase deploy --app <application> --env <environment> --codebase <codebase>
239
- --commit <commit>
239
+ [--tag <tag>] [--branch <branch>]
240
+ [--commit <commit>]
240
241
  ```
241
242
 
242
243
  ## Options
@@ -247,8 +248,12 @@ platform-helper codebase deploy --app <application> --env <environment> --codeba
247
248
  - AWS Copilot environment
248
249
  - `--codebase <text>`
249
250
  - The codebase name as specified in the platform-config.yml file. This can be run from any directory.
251
+ - `--tag <text>`
252
+ - Git tag that has been built into an image. Typically a semantic version of the form 1.2.3 or v1.2.3.
253
+ - `--branch <text>`
254
+ - Git branch that has been built into an image.
250
255
  - `--commit <text>`
251
- - GitHub commit hash
256
+ - Git sha hash that has been built into an image.
252
257
  - `--help <boolean>` _Defaults to False._
253
258
  - Show this message and exit.
254
259
 
@@ -66,11 +66,28 @@ def build(app, codebase, commit):
66
66
  help="The codebase name as specified in the platform-config.yml file. This can be run from any directory.",
67
67
  required=True,
68
68
  )
69
- @click.option("--commit", help="GitHub commit hash", required=True)
70
- def deploy(app, env, codebase, commit):
69
+ @click.option(
70
+ "--tag",
71
+ help="Git tag that has been built into an image. Typically a semantic version of the form 1.2.3 or v1.2.3.",
72
+ required=False,
73
+ )
74
+ @click.option(
75
+ "--branch",
76
+ help="Git branch that has been built into an image.",
77
+ required=False,
78
+ )
79
+ @click.option(
80
+ "--commit",
81
+ help="Git sha hash that has been built into an image.",
82
+ required=False,
83
+ )
84
+ def deploy(
85
+ app: str, env: str, codebase: str, commit: str = None, tag: str = None, branch: str = None
86
+ ):
87
+
71
88
  try:
72
89
  Codebase(ParameterStore(get_aws_session_or_abort().client("ssm"))).deploy(
73
- app, env, codebase, commit
90
+ app, env, codebase, commit, tag, branch
74
91
  )
75
92
  except PlatformException as err:
76
93
  ClickIOProvider().abort_with_error(str(err))
@@ -3,12 +3,14 @@ import stat
3
3
  import subprocess
4
4
  from collections.abc import Callable
5
5
  from pathlib import Path
6
+ from typing import Tuple
6
7
 
7
8
  import requests
8
9
  import yaml
9
10
  from boto3 import Session
10
11
 
11
12
  from dbt_platform_helper.platform_exception import PlatformException
13
+ from dbt_platform_helper.providers.ecr import ECRProvider
12
14
  from dbt_platform_helper.providers.files import FileProvider
13
15
  from dbt_platform_helper.providers.io import ClickIOProvider
14
16
  from dbt_platform_helper.providers.parameter_store import ParameterStore
@@ -17,7 +19,6 @@ from dbt_platform_helper.utils.application import (
17
19
  ApplicationEnvironmentNotFoundException,
18
20
  )
19
21
  from dbt_platform_helper.utils.application import load_application
20
- from dbt_platform_helper.utils.aws import check_image_exists
21
22
  from dbt_platform_helper.utils.aws import get_aws_session_or_abort
22
23
  from dbt_platform_helper.utils.aws import get_build_url_from_arn
23
24
  from dbt_platform_helper.utils.aws import get_build_url_from_pipeline_execution_id
@@ -37,7 +38,7 @@ class Codebase:
37
38
  io: ClickIOProvider = ClickIOProvider(),
38
39
  load_application: Callable[[str], Application] = load_application,
39
40
  get_aws_session_or_abort: Callable[[str], Session] = get_aws_session_or_abort,
40
- check_image_exists: Callable[[str], str] = check_image_exists,
41
+ ecr_provider: ECRProvider = ECRProvider(),
41
42
  get_image_build_project: Callable[[str], str] = get_image_build_project,
42
43
  get_manual_release_pipeline: Callable[[str], str] = get_manual_release_pipeline,
43
44
  get_build_url_from_arn: Callable[[str], str] = get_build_url_from_arn,
@@ -56,7 +57,7 @@ class Codebase:
56
57
  self.io = io
57
58
  self.load_application = load_application
58
59
  self.get_aws_session_or_abort = get_aws_session_or_abort
59
- self.check_image_exists = check_image_exists
60
+ self.ecr_provider = ecr_provider
60
61
  self.get_image_build_project = get_image_build_project
61
62
  self.get_manual_release_pipeline = get_manual_release_pipeline
62
63
  self.get_build_url_from_arn = get_build_url_from_arn
@@ -154,31 +155,54 @@ class Codebase:
154
155
 
155
156
  raise ApplicationDeploymentNotTriggered(codebase)
156
157
 
157
- def deploy(self, app, env, codebase, commit):
158
+ def deploy(
159
+ self,
160
+ app: str,
161
+ env: str,
162
+ codebase: str,
163
+ commit: str = None,
164
+ tag: str = None,
165
+ branch: str = None,
166
+ ):
158
167
  """Trigger a CodePipeline pipeline based deployment."""
159
- session = self.get_aws_session_or_abort()
160
168
 
161
- application = self.load_application(app, default_session=session)
162
- if not application.environments.get(env):
163
- raise ApplicationEnvironmentNotFoundException(application.name, env)
169
+ self._validate_reference_flags(commit, tag, branch)
164
170
 
165
- self.check_image_exists(session, application, codebase, commit)
171
+ application, session = self._populate_application_values(app, env)
166
172
 
167
- codepipeline_client = session.client("codepipeline")
173
+ image_ref = None
174
+ if commit:
175
+ image_ref = f"commit-{commit[0:7]}"
176
+ elif tag:
177
+ image_ref = f"tag-{tag}"
178
+ elif branch:
179
+ image_ref = f"branch-{branch}"
180
+ image_details = self.ecr_provider.get_image_details(application, codebase, image_ref)
181
+ image_ref = self.ecr_provider.find_commit_tag(image_details, image_ref)
168
182
 
183
+ codepipeline_client = session.client("codepipeline")
169
184
  pipeline_name = self.get_manual_release_pipeline(codepipeline_client, app, codebase)
170
185
 
186
+ corresponding_to = ""
187
+ if tag:
188
+ corresponding_to = f"(corresponding to tag {tag}) "
189
+ elif branch:
190
+ corresponding_to = f"(corresponding to branch {branch}) "
191
+
192
+ confirmation_message = f'\nYou are about to deploy "{app}" for "{codebase}" with image reference "{image_ref}" {corresponding_to}to the "{env}" environment using the "{pipeline_name}" deployment pipeline. Do you want to continue?'
193
+ build_options = {
194
+ "name": pipeline_name,
195
+ "variables": [
196
+ {"name": "ENVIRONMENT", "value": env},
197
+ {"name": "IMAGE_TAG", "value": image_ref},
198
+ ],
199
+ }
200
+
171
201
  build_url = self.__start_pipeline_execution_with_confirmation(
172
202
  codepipeline_client,
173
203
  self.get_build_url_from_pipeline_execution_id,
174
- f'You are about to deploy "{app}" for "{codebase}" with commit "{commit}" to the "{env}" environment using the "{pipeline_name}" deployment pipeline. Do you want to continue?',
175
- {
176
- "name": pipeline_name,
177
- "variables": [
178
- {"name": "ENVIRONMENT", "value": env},
179
- {"name": "IMAGE_TAG", "value": f"commit-{commit}"},
180
- ],
181
- },
204
+ confirmation_message,
205
+ build_options,
182
206
  )
183
207
 
184
208
  if build_url:
@@ -189,6 +213,25 @@ class Codebase:
189
213
 
190
214
  raise ApplicationDeploymentNotTriggered(codebase)
191
215
 
216
+ def _validate_reference_flags(self, commit: str, tag: str, branch: str):
217
+ provided = [ref for ref in [commit, tag, branch] if ref]
218
+
219
+ if len(provided) == 0:
220
+ self.io.abort_with_error(
221
+ "To deploy, you must provide one of the options --commit, --tag or --branch."
222
+ )
223
+ elif len(provided) > 1:
224
+ self.io.abort_with_error(
225
+ "You have provided more than one of the --tag, --branch and --commit options but these are mutually exclusive. Please provide only one of these options."
226
+ )
227
+
228
+ def _populate_application_values(self, app: str, env: str) -> Tuple[Application, Session]:
229
+ session = self.get_aws_session_or_abort()
230
+ application = self.load_application(app, default_session=session)
231
+ if not application.environments.get(env):
232
+ raise ApplicationEnvironmentNotFoundException(application.name, env)
233
+ return application, session
234
+
192
235
  def list(self, app: str, with_images: bool):
193
236
  """List available codebases for the application."""
194
237
  session = self.get_aws_session_or_abort()
@@ -229,44 +229,48 @@ class MaintenancePage:
229
229
  f"\nUse a browser plugin to add `Bypass-Key` header with value {bypass_value} to your requests. For more detail, visit https://platform.readme.trade.gov.uk/next-steps/put-a-service-under-maintenance/",
230
230
  )
231
231
 
232
- self.load_balancer.create_rule(
233
- listener_arn=listener_arn,
234
- priority=next(rule_priority),
235
- conditions=[
232
+ unique_sorted_host_headers = sorted(
233
+ list(
236
234
  {
237
- "Field": "path-pattern",
238
- "PathPatternConfig": {"Values": ["/*"]},
239
- },
240
- {
241
- "Field": "host-header",
242
- "HostHeaderConfig": {
243
- "Values": sorted(
244
- list(
245
- {
246
- value
247
- for condition in maintenance_page_host_header_conditions
248
- for value in condition["HostHeaderConfig"]["Values"]
249
- }
250
- )
251
- )
252
- },
253
- },
254
- ],
255
- actions=[
256
- {
257
- "Type": "fixed-response",
258
- "FixedResponseConfig": {
259
- "StatusCode": "503",
260
- "ContentType": "text/html",
261
- "MessageBody": maintenance_page_content,
262
- },
235
+ value
236
+ for condition in maintenance_page_host_header_conditions
237
+ for value in condition["HostHeaderConfig"]["Values"]
263
238
  }
264
- ],
265
- tags=[
266
- {"Key": "name", "Value": "MaintenancePage"},
267
- {"Key": "type", "Value": template},
268
- ],
239
+ )
269
240
  )
241
+
242
+ # Can only set 4 host headers per rule as listener rules have a max conditions of 5
243
+ for i in range(0, len(unique_sorted_host_headers), 4):
244
+ self.load_balancer.create_rule(
245
+ listener_arn=listener_arn,
246
+ priority=next(rule_priority),
247
+ conditions=[
248
+ {
249
+ "Field": "path-pattern",
250
+ "PathPatternConfig": {"Values": ["/*"]},
251
+ },
252
+ {
253
+ "Field": "host-header",
254
+ "HostHeaderConfig": {
255
+ "Values": unique_sorted_host_headers[i : i + 4],
256
+ },
257
+ },
258
+ ],
259
+ actions=[
260
+ {
261
+ "Type": "fixed-response",
262
+ "FixedResponseConfig": {
263
+ "StatusCode": "503",
264
+ "ContentType": "text/html",
265
+ "MessageBody": maintenance_page_content,
266
+ },
267
+ }
268
+ ],
269
+ tags=[
270
+ {"Key": "name", "Value": "MaintenancePage"},
271
+ {"Key": "type", "Value": template},
272
+ ],
273
+ )
270
274
  except Exception as e:
271
275
  self.__clean_up_maintenance_page_rules(listener_arn)
272
276
  raise FailedToActivateMaintenancePageException(
@@ -13,9 +13,9 @@ class CreateTaskTimeoutException(AWSException):
13
13
 
14
14
 
15
15
  class ImageNotFoundException(AWSException):
16
- def __init__(self, commit: str):
16
+ def __init__(self, image_ref: str):
17
17
  super().__init__(
18
- f"""The commit hash "{commit}" has not been built into an image, try the `platform-helper codebase build` command first."""
18
+ f"""An image labelled "{image_ref}" could not be found in your image repository. Try the `platform-helper codebase build` command first."""
19
19
  )
20
20
 
21
21
 
@@ -1,20 +1,77 @@
1
+ import botocore
1
2
  from boto3 import Session
2
3
 
4
+ from dbt_platform_helper.providers.aws.exceptions import ImageNotFoundException
5
+ from dbt_platform_helper.providers.aws.exceptions import RepositoryNotFoundException
6
+ from dbt_platform_helper.providers.io import ClickIOProvider
7
+ from dbt_platform_helper.utils.application import Application
3
8
  from dbt_platform_helper.utils.aws import get_aws_session_or_abort
4
9
 
5
10
 
6
11
  class ECRProvider:
7
- def __init__(self, session: Session = None):
12
+ def __init__(self, session: Session = None, click_io: ClickIOProvider = ClickIOProvider()):
8
13
  self.session = session
9
- self.client = None
10
-
11
- def _get_client(self):
12
- if not self.session:
13
- self.session = get_aws_session_or_abort()
14
- return self.session.client("ecr")
14
+ self.click_io = click_io
15
15
 
16
16
  def get_ecr_repo_names(self) -> list[str]:
17
17
  out = []
18
18
  for page in self._get_client().get_paginator("describe_repositories").paginate():
19
19
  out.extend([repo["repositoryName"] for repo in page.get("repositories", {})])
20
20
  return out
21
+
22
+ def get_image_details(
23
+ self, application: Application, codebase: str, image_ref: str
24
+ ) -> list[dict]:
25
+ """Check if image exists in AWS ECR, and return a list of dictionaries
26
+ containing image metadata."""
27
+
28
+ repository = f"{application.name}/{codebase}"
29
+
30
+ try:
31
+ image_info = self._get_client().describe_images(
32
+ repositoryName=repository,
33
+ imageIds=[{"imageTag": image_ref}],
34
+ )
35
+
36
+ self._check_image_details_exists(image_info, image_ref)
37
+
38
+ return image_info.get("imageDetails")
39
+ except botocore.exceptions.ClientError as e:
40
+ if e.response["Error"]["Code"] == "ImageNotFoundException":
41
+ raise ImageNotFoundException(image_ref)
42
+ if e.response["Error"]["Code"] == "RepositoryNotFoundException":
43
+ raise RepositoryNotFoundException(repository)
44
+
45
+ def find_commit_tag(self, image_details: list[dict], image_ref: str) -> str:
46
+ """Loop through imageTags list to query for an image tag starting with
47
+ 'commit-', and return that value if found."""
48
+
49
+ if image_ref.startswith("commit-"):
50
+ return image_ref
51
+
52
+ if image_details:
53
+ for image in image_details:
54
+ image_tags = image.get("imageTags", {})
55
+ for tag in image_tags:
56
+ if tag.startswith("commit-"):
57
+ self.click_io.info(
58
+ f'INFO: The tag "{image_ref}" is not a unique, commit-specific tag. Deploying the corresponding commit tag "{tag}" instead.'
59
+ )
60
+ return tag
61
+ self.click_io.warn(
62
+ f'WARNING: The AWS ECR image "{image_ref}" has no associated commit tag so deploying "{image_ref}". Note this could result in images with unintended or incompatible changes being deployed if new ECS Tasks for your service.'
63
+ )
64
+ return image_ref
65
+
66
+ @staticmethod
67
+ def _check_image_details_exists(image_info: dict, image_ref: str):
68
+ """Error handling for any unexpected scenario where AWS ECR returns a
69
+ malformed response."""
70
+
71
+ if "imageDetails" not in image_info:
72
+ raise ImageNotFoundException(image_ref)
73
+
74
+ def _get_client(self):
75
+ if not self.session:
76
+ self.session = get_aws_session_or_abort()
77
+ return self.session.client("ecr")
@@ -14,9 +14,10 @@ from botocore.exceptions import ClientError
14
14
 
15
15
  from dbt_platform_helper.constants import REFRESH_TOKEN_MESSAGE
16
16
  from dbt_platform_helper.platform_exception import PlatformException
17
- from dbt_platform_helper.providers.aws.exceptions import ImageNotFoundException
17
+ from dbt_platform_helper.providers.aws.exceptions import (
18
+ CopilotCodebaseNotFoundException,
19
+ )
18
20
  from dbt_platform_helper.providers.aws.exceptions import LogGroupNotFoundException
19
- from dbt_platform_helper.providers.aws.exceptions import RepositoryNotFoundException
20
21
  from dbt_platform_helper.providers.validation import ValidationException
21
22
 
22
23
  SSM_BASE_PATH = "/copilot/{app}/{env}/secrets/"
@@ -268,18 +269,23 @@ def start_pipeline_and_return_execution_id(codepipeline_client, build_options):
268
269
  return response["pipelineExecutionId"]
269
270
 
270
271
 
271
- def check_image_exists(session, application, codebase, commit):
272
- ecr_client = session.client("ecr")
273
- repository = f"{application.name}/{codebase}"
272
+ # Todo: This should probably be in the AWS Copilot provider
273
+ def check_codebase_exists(session: Session, application, codebase: str):
274
274
  try:
275
- ecr_client.describe_images(
276
- repositoryName=repository,
277
- imageIds=[{"imageTag": f"commit-{commit}"}],
275
+ # Todo: Can this leverage dbt_platform_helper.providers.secrets.Secrets.get_connection_secret_arn?
276
+ ssm_client = session.client("ssm")
277
+ json.loads(
278
+ ssm_client.get_parameter(
279
+ Name=f"/copilot/applications/{application.name}/codebases/{codebase}"
280
+ )["Parameter"]["Value"]
278
281
  )
279
- except ecr_client.exceptions.ImageNotFoundException:
280
- raise ImageNotFoundException(commit)
281
- except ecr_client.exceptions.RepositoryNotFoundException:
282
- raise RepositoryNotFoundException(repository)
282
+ except (
283
+ KeyError,
284
+ ValueError,
285
+ ssm_client.exceptions.ParameterNotFound,
286
+ json.JSONDecodeError,
287
+ ):
288
+ raise CopilotCodebaseNotFoundException(codebase)
283
289
 
284
290
 
285
291
  def get_build_url_from_arn(build_arn: str) -> str:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: dbt-platform-helper
3
- Version: 13.3.0
3
+ Version: 13.4.1
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
@@ -1,10 +1,10 @@
1
- dbt_platform_helper/COMMANDS.md,sha256=tBGjnVDw5sXQfCNyHJfFWWu_40LqxbmfIE_SRVhg97g,22644
1
+ dbt_platform_helper/COMMANDS.md,sha256=mjqrylK4O07danqv_D5TD-ecu1B-7g9SuBHxe9L16Xc,22934
2
2
  dbt_platform_helper/README.md,sha256=B0qN2_u_ASqqgkGDWY2iwNGZt_9tUgMb9XqtaTuzYjw,1530
3
3
  dbt_platform_helper/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  dbt_platform_helper/addon-plans.yml,sha256=O46a_ODsGG9KXmQY_1XbSGqrpSaHSLDe-SdROzHx8Go,4545
5
5
  dbt_platform_helper/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
6
  dbt_platform_helper/commands/application.py,sha256=OUQsahXXHSEKxmXAmK8fSy_bTLNwM_TdLuv6CvffRPk,10126
7
- dbt_platform_helper/commands/codebase.py,sha256=lwkZ9PZ7Zp1jQ2NaZ5-10gOMy85rYsHBa1-w8fU52k8,2763
7
+ dbt_platform_helper/commands/codebase.py,sha256=oNlZcP2w3XE5YP-JVl0rdqoJuXUrfe1ELZ5xAdgPvBk,3166
8
8
  dbt_platform_helper/commands/conduit.py,sha256=v5geTJzRHkOnbFfOqmjO6b57HXhs4YxTo_zJgDEYB0A,2300
9
9
  dbt_platform_helper/commands/config.py,sha256=7XRFgLHUg1n-k6DReEouVm9NzOm0zFtnBwDLyDLSBLw,1225
10
10
  dbt_platform_helper/commands/copilot.py,sha256=L9UUuqD62q0aFrTTEUla3A1WJBz-vFBfVi6p455TTgQ,1458
@@ -18,13 +18,13 @@ dbt_platform_helper/commands/version.py,sha256=gRQkmcFTz90SbYhO1L-j727AuZ_gnjQfc
18
18
  dbt_platform_helper/constants.py,sha256=DpHGG54lwjw3XGp2TKCEGNmzaz083lAWMGkEabujDrw,1050
19
19
  dbt_platform_helper/default-extensions.yml,sha256=SU1ZitskbuEBpvE7efc3s56eAUF11j70brhj_XrNMMo,493
20
20
  dbt_platform_helper/domain/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
21
- dbt_platform_helper/domain/codebase.py,sha256=2rSVCwGsnbFZbs9JvAFwjq2yPKfTqCPiBegYLvmCgIQ,10914
21
+ dbt_platform_helper/domain/codebase.py,sha256=8L1MntK26CX8ZW-Nb3MdM5oMa8LdXgiV3t8IDMszIgg,12478
22
22
  dbt_platform_helper/domain/conduit.py,sha256=5C5GnF5jssJ1rFFCY6qaKgvLjYUkyytRJE4tHlanYa0,4370
23
23
  dbt_platform_helper/domain/config.py,sha256=au45EnEAjv0RZUEDJ_0IQnsRV7wM0hHi-ZJ6LOnavYc,13361
24
24
  dbt_platform_helper/domain/copilot.py,sha256=9L4h-WFwgRU8AMjf14PlDqwLqOpIRinkuPvhe-8Uk3c,15034
25
25
  dbt_platform_helper/domain/copilot_environment.py,sha256=yPt6ZarOvFPo06XwY1sU5MOQsoV7TEsKSQHyM-G8aGc,9058
26
26
  dbt_platform_helper/domain/database_copy.py,sha256=CKvI9LsHyowg0bPT9jImk07w4TyQLPoInQoU2TUDiJQ,9485
27
- dbt_platform_helper/domain/maintenance_page.py,sha256=h7uYlUi4rlaDV9DvdElb2yD4H6Nz7dHMx3RIQfjHFZw,14258
27
+ dbt_platform_helper/domain/maintenance_page.py,sha256=CfSJJYXOaBC0S4tKsMl0Pz-_6r0DR5J8BUkBQUTx2nM,14494
28
28
  dbt_platform_helper/domain/pipelines.py,sha256=mUvGaNMtBAUemsb-fHDcpWV-9LfqGoSogI2LwDnvt0I,6503
29
29
  dbt_platform_helper/domain/terraform_environment.py,sha256=7ZKLZ8Zk6-V_IPaCDUP8eYTRudqDjHxvFnbG6LIlLO4,1759
30
30
  dbt_platform_helper/domain/versioning.py,sha256=9AdQ_pW20RUwdvdSgY_OzqlDkFaevLNAeh5WZ-w0Xww,7865
@@ -32,7 +32,7 @@ dbt_platform_helper/jinja2_tags.py,sha256=hKG6RS3zlxJHQ-Op9r2U2-MhWp4s3lZir4Ihe2
32
32
  dbt_platform_helper/platform_exception.py,sha256=bheZV9lqGvrCVTNT92349dVntNDEDWTEwciZgC83WzE,187
33
33
  dbt_platform_helper/providers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
34
  dbt_platform_helper/providers/aws/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
35
- dbt_platform_helper/providers/aws/exceptions.py,sha256=LcTRdjnABDx44BEC4kd4Qb9HNrEcyyCY4yzG16kV3eE,1712
35
+ dbt_platform_helper/providers/aws/exceptions.py,sha256=I6PQZjTWhJh9tgoKd9bkYwVFDRSgrri-0YhobLVERFo,1731
36
36
  dbt_platform_helper/providers/aws/interfaces.py,sha256=0JFggcUTJ8zERdxNVVpIiKvaaZeT2c-VECDG--MOi8E,285
37
37
  dbt_platform_helper/providers/aws/opensearch.py,sha256=Qne2SoPllmacVSc7AxtjBlEbSBsRMbR_ySEkEymSF9k,581
38
38
  dbt_platform_helper/providers/aws/redis.py,sha256=i3Kb00_BdqssjQg1wgZ-8GRXcEWQiORWnIEq6qkAXjQ,551
@@ -42,7 +42,7 @@ dbt_platform_helper/providers/cloudformation.py,sha256=SvCZgEVqxdpKfQMRAG3KzFQ43
42
42
  dbt_platform_helper/providers/config.py,sha256=X84xQxTVWDcuLAeGBM4A5uVhEiXIzjiVfCB9nAjqVf8,4249
43
43
  dbt_platform_helper/providers/config_validator.py,sha256=-n9KjfTQhk2NPK5Vw1Bbz9z-uTSQfWPWUbtRLp1EbTs,11088
44
44
  dbt_platform_helper/providers/copilot.py,sha256=Pgdh1JS-so2thT7Jqipol5aVkA_CgU6doUmy3YjYSXs,5328
45
- dbt_platform_helper/providers/ecr.py,sha256=lmLKGR5OQT8EyGsX-9M7oO0DHIyoMqgchBAVQBeoBZs,639
45
+ dbt_platform_helper/providers/ecr.py,sha256=siCGTEXR8Jd_pemPfKI3_U5P3Ix6dPrhWsg94EQiZzA,3266
46
46
  dbt_platform_helper/providers/ecs.py,sha256=XlQHYhZiLGrqR-1ZWMagGH2R2Hy7mCP6676eZL3YbNQ,3842
47
47
  dbt_platform_helper/providers/files.py,sha256=cJdOV6Eupi-COmGUMxZMF10BZnMi3MCCipTVUnE_NPA,857
48
48
  dbt_platform_helper/providers/io.py,sha256=FrVwWZqm8TFxp4Ph2AqbgsePpt6tryNdaPzc4wyGJmA,1364
@@ -85,7 +85,7 @@ dbt_platform_helper/templates/svc/overrides/cfn.patches.yml,sha256=W7-d017akuUq9
85
85
  dbt_platform_helper/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
86
86
  dbt_platform_helper/utils/application.py,sha256=_O2ywJRYYdWfBVz4LzD07PLO9hSPJf7FylE6toH19KM,5448
87
87
  dbt_platform_helper/utils/arn_parser.py,sha256=BaXzIxSOLdFmP_IfAxRq-0j-0Re1iCN7L4j2Zi5-CRQ,1304
88
- dbt_platform_helper/utils/aws.py,sha256=trdBgq1HqbW9rczog1LTZ1XLTwn2L1liUFrl9QSTDNA,12589
88
+ dbt_platform_helper/utils/aws.py,sha256=eqgRvilfgmmJ5UC54Uc0OzJD4ef3XZpkZ8gwXKOqPn4,12677
89
89
  dbt_platform_helper/utils/click.py,sha256=Fx4y4bbve1zypvog_sgK7tJtCocmzheoEFLBRv1lfdM,2943
90
90
  dbt_platform_helper/utils/git.py,sha256=pVa6K9LFscAHFpVEOZFoUwj-uHZP-52MFH7_C-uPQGs,782
91
91
  dbt_platform_helper/utils/messages.py,sha256=nWA7BWLb7ND0WH5TejDN4OQUJSKYBxU4tyCzteCrfT0,142
@@ -93,8 +93,8 @@ dbt_platform_helper/utils/template.py,sha256=g-Db-0I6a6diOHkgK1nYA0IxJSO4TRrjqOv
93
93
  dbt_platform_helper/utils/tool_versioning.py,sha256=UXrICUnnWCSpOdIIJaVnZcN2U3pgCUbpjvL4exevDbw,510
94
94
  dbt_platform_helper/utils/validation.py,sha256=coN7WsKW_nPGW9EU23AInBkAuvUl1NfQvc2bjVtgs14,1188
95
95
  platform_helper.py,sha256=_YNNGtMkH5BcpC_mQQYJrmlf2mt7lkxTYeH7ZgflPoA,1925
96
- dbt_platform_helper-13.3.0.dist-info/LICENSE,sha256=dP79lN73--7LMApnankTGLqDbImXg8iYFqWgnExGkGk,1090
97
- dbt_platform_helper-13.3.0.dist-info/METADATA,sha256=ebTgbrOTabzJ8qyfYiXRv_sPazEI02tdhbhu7v3XUbg,3243
98
- dbt_platform_helper-13.3.0.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
99
- dbt_platform_helper-13.3.0.dist-info/entry_points.txt,sha256=QhbY8F434A-onsg0-FsdMd2U6HKh6Q7yCFFZrGUh5-M,67
100
- dbt_platform_helper-13.3.0.dist-info/RECORD,,
96
+ dbt_platform_helper-13.4.1.dist-info/LICENSE,sha256=dP79lN73--7LMApnankTGLqDbImXg8iYFqWgnExGkGk,1090
97
+ dbt_platform_helper-13.4.1.dist-info/METADATA,sha256=oR-YiD_AFk8sL-CZ6CnbMziVA9mZG1SpXOnpTy3hTJw,3243
98
+ dbt_platform_helper-13.4.1.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
99
+ dbt_platform_helper-13.4.1.dist-info/entry_points.txt,sha256=QhbY8F434A-onsg0-FsdMd2U6HKh6Q7yCFFZrGUh5-M,67
100
+ dbt_platform_helper-13.4.1.dist-info/RECORD,,