dbt-platform-helper 12.2.4__py3-none-any.whl → 12.4.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 (33) hide show
  1. dbt_platform_helper/COMMANDS.md +6 -1
  2. dbt_platform_helper/commands/codebase.py +9 -80
  3. dbt_platform_helper/commands/conduit.py +25 -45
  4. dbt_platform_helper/commands/config.py +4 -4
  5. dbt_platform_helper/commands/copilot.py +13 -15
  6. dbt_platform_helper/commands/database.py +17 -4
  7. dbt_platform_helper/commands/environment.py +3 -2
  8. dbt_platform_helper/commands/secrets.py +1 -1
  9. dbt_platform_helper/domain/codebase.py +81 -63
  10. dbt_platform_helper/domain/conduit.py +42 -93
  11. dbt_platform_helper/domain/database_copy.py +48 -42
  12. dbt_platform_helper/domain/maintenance_page.py +8 -8
  13. dbt_platform_helper/platform_exception.py +5 -0
  14. dbt_platform_helper/providers/aws.py +32 -0
  15. dbt_platform_helper/providers/cloudformation.py +129 -100
  16. dbt_platform_helper/providers/copilot.py +33 -16
  17. dbt_platform_helper/providers/ecs.py +97 -74
  18. dbt_platform_helper/providers/load_balancers.py +11 -5
  19. dbt_platform_helper/providers/secrets.py +100 -59
  20. dbt_platform_helper/providers/validation.py +19 -0
  21. dbt_platform_helper/utils/application.py +14 -2
  22. dbt_platform_helper/utils/arn_parser.py +1 -1
  23. dbt_platform_helper/utils/aws.py +38 -12
  24. dbt_platform_helper/utils/git.py +2 -2
  25. dbt_platform_helper/utils/validation.py +57 -18
  26. dbt_platform_helper/utils/versioning.py +8 -8
  27. {dbt_platform_helper-12.2.4.dist-info → dbt_platform_helper-12.4.0.dist-info}/METADATA +1 -1
  28. {dbt_platform_helper-12.2.4.dist-info → dbt_platform_helper-12.4.0.dist-info}/RECORD +31 -30
  29. dbt_platform_helper/addons-template-map.yml +0 -29
  30. dbt_platform_helper/exceptions.py +0 -81
  31. {dbt_platform_helper-12.2.4.dist-info → dbt_platform_helper-12.4.0.dist-info}/LICENSE +0 -0
  32. {dbt_platform_helper-12.2.4.dist-info → dbt_platform_helper-12.4.0.dist-info}/WHEEL +0 -0
  33. {dbt_platform_helper-12.2.4.dist-info → dbt_platform_helper-12.4.0.dist-info}/entry_points.txt +0 -0
@@ -9,11 +9,9 @@ import requests
9
9
  import yaml
10
10
  from boto3 import Session
11
11
 
12
- from dbt_platform_helper.exceptions import ApplicationDeploymentNotTriggered
13
- from dbt_platform_helper.exceptions import ApplicationEnvironmentNotFoundError
14
- from dbt_platform_helper.exceptions import NoCopilotCodebasesFoundError
15
- from dbt_platform_helper.exceptions import NotInCodeBaseRepositoryError
12
+ from dbt_platform_helper.platform_exception import PlatformException
16
13
  from dbt_platform_helper.utils.application import Application
14
+ from dbt_platform_helper.utils.application import ApplicationException
17
15
  from dbt_platform_helper.utils.application import load_application
18
16
  from dbt_platform_helper.utils.aws import check_codebase_exists
19
17
  from dbt_platform_helper.utils.aws import check_image_exists
@@ -29,31 +27,31 @@ from dbt_platform_helper.utils.template import setup_templates
29
27
  class Codebase:
30
28
  def __init__(
31
29
  self,
32
- input_fn: Callable[[str], str] = click.prompt,
33
- echo_fn: Callable[[str], str] = click.secho,
34
- confirm_fn: Callable[[str], bool] = click.confirm,
35
- load_application_fn: Callable[[str], Application] = load_application,
36
- get_aws_session_or_abort_fn: Callable[[str], Session] = get_aws_session_or_abort,
37
- check_codebase_exists_fn: Callable[[str], str] = check_codebase_exists,
38
- check_image_exists_fn: Callable[[str], str] = check_image_exists,
39
- get_build_url_from_arn_fn: Callable[[str], str] = get_build_url_from_arn,
40
- list_latest_images_fn: Callable[[str], str] = list_latest_images,
41
- start_build_extraction_fn: Callable[[str], str] = start_build_extraction,
42
- check_if_commit_exists_fn: Callable[[str], str] = check_if_commit_exists,
43
- subprocess: Callable[[str], str] = subprocess.run,
30
+ input: Callable[[str], str] = click.prompt,
31
+ echo: Callable[[str], str] = click.secho,
32
+ confirm: Callable[[str], bool] = click.confirm,
33
+ load_application: Callable[[str], Application] = load_application,
34
+ get_aws_session_or_abort: Callable[[str], Session] = get_aws_session_or_abort,
35
+ check_codebase_exists: Callable[[str], str] = check_codebase_exists,
36
+ check_image_exists: Callable[[str], str] = check_image_exists,
37
+ get_build_url_from_arn: Callable[[str], str] = get_build_url_from_arn,
38
+ list_latest_images: Callable[[str], str] = list_latest_images,
39
+ start_build_extraction: Callable[[str], str] = start_build_extraction,
40
+ check_if_commit_exists: Callable[[str], str] = check_if_commit_exists,
41
+ run_subprocess: Callable[[str], str] = subprocess.run,
44
42
  ):
45
- self.input_fn = input_fn
46
- self.echo_fn = echo_fn
47
- self.confirm_fn = confirm_fn
48
- self.load_application_fn = load_application_fn
49
- self.get_aws_session_or_abort_fn = get_aws_session_or_abort_fn
50
- self.check_codebase_exists_fn = check_codebase_exists_fn
51
- self.check_image_exists_fn = check_image_exists_fn
52
- self.get_build_url_from_arn_fn = get_build_url_from_arn_fn
53
- self.list_latest_images_fn = list_latest_images_fn
54
- self.start_build_extraction_fn = start_build_extraction_fn
55
- self.check_if_commit_exists_fn = check_if_commit_exists_fn
56
- self.subprocess = subprocess
43
+ self.input = input
44
+ self.echo = echo
45
+ self.confirm = confirm
46
+ self.load_application = load_application
47
+ self.get_aws_session_or_abort = get_aws_session_or_abort
48
+ self.check_codebase_exists = check_codebase_exists
49
+ self.check_image_exists = check_image_exists
50
+ self.get_build_url_from_arn = get_build_url_from_arn
51
+ self.list_latest_images = list_latest_images
52
+ self.start_build_extraction = start_build_extraction
53
+ self.check_if_commit_exists = check_if_commit_exists
54
+ self.run_subprocess = run_subprocess
57
55
 
58
56
  def prepare(self):
59
57
  """Sets up an application codebase for use within a DBT platform
@@ -61,13 +59,15 @@ class Codebase:
61
59
  templates = setup_templates()
62
60
 
63
61
  repository = (
64
- self.subprocess(["git", "remote", "get-url", "origin"], capture_output=True, text=True)
62
+ self.run_subprocess(
63
+ ["git", "remote", "get-url", "origin"], capture_output=True, text=True
64
+ )
65
65
  .stdout.split("/")[-1]
66
66
  .strip()
67
67
  .removesuffix(".git")
68
68
  )
69
69
  if repository.endswith("-deploy") or Path("./copilot").exists():
70
- raise NotInCodeBaseRepositoryError
70
+ raise NotInCodeBaseRepositoryException()
71
71
 
72
72
  builder_configuration_url = "https://raw.githubusercontent.com/uktrade/ci-image-builder/main/image_builder/configuration/builder_configuration.yml"
73
73
  builder_configuration_response = requests.get(builder_configuration_url)
@@ -91,7 +91,7 @@ class Codebase:
91
91
  config_contents = templates.get_template(f".copilot/config.yml").render(
92
92
  repository=repository, builder_version=builder_version
93
93
  )
94
- self.echo_fn(
94
+ self.echo(
95
95
  mkfile(
96
96
  Path("."), ".copilot/image_build_run.sh", image_build_run_contents, overwrite=True
97
97
  )
@@ -100,27 +100,27 @@ 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_fn(mkfile(Path("."), ".copilot/config.yml", config_contents, overwrite=True))
103
+ self.echo(mkfile(Path("."), ".copilot/config.yml", config_contents, overwrite=True))
104
104
 
105
105
  for phase in ["build", "install", "post_build", "pre_build"]:
106
106
  phase_contents = templates.get_template(f".copilot/phases/{phase}.sh").render()
107
107
 
108
- self.echo_fn(
108
+ self.echo(
109
109
  mkfile(Path("./.copilot"), f"phases/{phase}.sh", phase_contents, overwrite=True)
110
110
  )
111
111
 
112
112
  def build(self, app: str, codebase: str, commit: str):
113
113
  """Trigger a CodePipeline pipeline based build."""
114
- session = self.get_aws_session_or_abort_fn()
115
- self.load_application_fn(app, default_session=session)
114
+ session = self.get_aws_session_or_abort()
115
+ self.load_application(app, default_session=session)
116
116
 
117
- self.check_if_commit_exists_fn(commit)
117
+ self.check_if_commit_exists(commit)
118
118
 
119
119
  codebuild_client = session.client("codebuild")
120
120
  build_url = self.__start_build_with_confirmation(
121
- self.confirm_fn,
121
+ self.confirm,
122
122
  codebuild_client,
123
- self.get_build_url_from_arn_fn,
123
+ self.get_build_url_from_arn,
124
124
  f'You are about to build "{app}" for "{codebase}" with commit "{commit}". Do you want to continue?',
125
125
  {
126
126
  "projectName": f"codebuild-{app}-{codebase}",
@@ -130,29 +130,29 @@ class Codebase:
130
130
  )
131
131
 
132
132
  if build_url:
133
- return self.echo_fn(
133
+ return self.echo(
134
134
  f"Your build has been triggered. Check your build progress in the AWS Console: {build_url}"
135
135
  )
136
136
 
137
- raise ApplicationDeploymentNotTriggered()
137
+ raise ApplicationDeploymentNotTriggered(codebase)
138
138
 
139
139
  def deploy(self, app, env, codebase, commit):
140
140
  """Trigger a CodePipeline pipeline based deployment."""
141
- session = self.get_aws_session_or_abort_fn()
141
+ session = self.get_aws_session_or_abort()
142
142
 
143
- application = self.load_application_fn(app, default_session=session)
143
+ application = self.load_application(app, default_session=session)
144
144
  if not application.environments.get(env):
145
- raise ApplicationEnvironmentNotFoundError()
145
+ raise ApplicationEnvironmentNotFoundException(env)
146
146
 
147
- self.check_codebase_exists_fn(session, application, codebase)
147
+ self.check_codebase_exists(session, application, codebase)
148
148
 
149
- self.check_image_exists_fn(session, application, codebase, commit)
149
+ self.check_image_exists(session, application, codebase, commit)
150
150
 
151
151
  codebuild_client = session.client("codebuild")
152
152
  build_url = self.__start_build_with_confirmation(
153
- self.confirm_fn,
153
+ self.confirm,
154
154
  codebuild_client,
155
- self.get_build_url_from_arn_fn,
155
+ self.get_build_url_from_arn,
156
156
  f'You are about to deploy "{app}" for "{codebase}" with commit "{commit}" to the "{env}" environment. Do you want to continue?',
157
157
  {
158
158
  "projectName": f"pipeline-{application.name}-{codebase}-BuildProject",
@@ -166,34 +166,34 @@ class Codebase:
166
166
  )
167
167
 
168
168
  if build_url:
169
- return self.echo_fn(
169
+ return self.echo(
170
170
  "Your deployment has been triggered. Check your build progress in the AWS Console: "
171
171
  f"{build_url}",
172
172
  )
173
173
 
174
- raise ApplicationDeploymentNotTriggered()
174
+ raise ApplicationDeploymentNotTriggered(codebase)
175
175
 
176
176
  def list(self, app: str, with_images: bool):
177
177
  """List available codebases for the application."""
178
- session = self.get_aws_session_or_abort_fn()
179
- application = self.load_application_fn(app, session)
178
+ session = self.get_aws_session_or_abort()
179
+ application = self.load_application(app, session)
180
180
  ssm_client = session.client("ssm")
181
181
  ecr_client = session.client("ecr")
182
182
  codebases = self.__get_codebases(application, ssm_client)
183
183
 
184
- self.echo_fn("The following codebases are available:")
184
+ self.echo("The following codebases are available:")
185
185
 
186
186
  for codebase in codebases:
187
- self.echo_fn(f"- {codebase['name']} (https://github.com/{codebase['repository']})")
187
+ self.echo(f"- {codebase['name']} (https://github.com/{codebase['repository']})")
188
188
  if with_images:
189
- self.list_latest_images_fn(
189
+ self.list_latest_images(
190
190
  ecr_client,
191
191
  f"{application.name}/{codebase['name']}",
192
192
  codebase["repository"],
193
- self.echo_fn,
193
+ self.echo,
194
194
  )
195
195
 
196
- self.echo_fn("")
196
+ self.echo("")
197
197
 
198
198
  def __get_codebases(self, application, ssm_client):
199
199
  parameters = ssm_client.get_parameters_by_path(
@@ -204,19 +204,37 @@ class Codebase:
204
204
  codebases = [json.loads(p["Value"]) for p in parameters]
205
205
 
206
206
  if not codebases:
207
- # TODO Is this really an error? Or just no codebases so we could return an empty list?
208
- raise NoCopilotCodebasesFoundError
207
+ return []
209
208
  return codebases
210
209
 
211
210
  def __start_build_with_confirmation(
212
211
  self,
213
- confirm_fn,
212
+ confirm,
214
213
  codebuild_client,
215
- get_build_url_from_arn_fn,
214
+ get_build_url_from_arn,
216
215
  confirmation_message,
217
216
  build_options,
218
217
  ):
219
- if confirm_fn(confirmation_message):
220
- build_arn = self.start_build_extraction_fn(codebuild_client, build_options)
221
- return get_build_url_from_arn_fn(build_arn)
218
+ if confirm(confirmation_message):
219
+ build_arn = self.start_build_extraction(codebuild_client, build_options)
220
+ return get_build_url_from_arn(build_arn)
222
221
  return None
222
+
223
+
224
+ class ApplicationDeploymentNotTriggered(PlatformException):
225
+ def __init__(self, codebase: str):
226
+ super().__init__(f"""Your deployment for {codebase} was not triggered.""")
227
+
228
+
229
+ class ApplicationEnvironmentNotFoundException(ApplicationException):
230
+ def __init__(self, environment: str):
231
+ super().__init__(
232
+ f"""The environment "{environment}" either does not exist or has not been deployed."""
233
+ )
234
+
235
+
236
+ class NotInCodeBaseRepositoryException(PlatformException):
237
+ def __init__(self):
238
+ super().__init__(
239
+ "You are in the deploy repository; make sure you are in the application codebase repository.",
240
+ )
@@ -3,80 +3,50 @@ from collections.abc import Callable
3
3
 
4
4
  import click
5
5
 
6
- from dbt_platform_helper.exceptions import ECSAgentNotRunning
7
- from dbt_platform_helper.providers.cloudformation import (
8
- add_stack_delete_policy_to_task_role,
9
- )
10
- from dbt_platform_helper.providers.cloudformation import update_conduit_stack_resources
11
- from dbt_platform_helper.providers.cloudformation import (
12
- wait_for_cloudformation_to_reach_status,
13
- )
6
+ from dbt_platform_helper.providers.cloudformation import CloudFormation
14
7
  from dbt_platform_helper.providers.copilot import connect_to_addon_client_task
15
8
  from dbt_platform_helper.providers.copilot import create_addon_client_task
16
- from dbt_platform_helper.providers.copilot import create_postgres_admin_task
17
- from dbt_platform_helper.providers.ecs import ecs_exec_is_available
18
- from dbt_platform_helper.providers.ecs import get_cluster_arn
19
- from dbt_platform_helper.providers.ecs import get_ecs_task_arns
20
- from dbt_platform_helper.providers.ecs import get_or_create_task_name
21
- from dbt_platform_helper.providers.secrets import get_addon_type
22
- from dbt_platform_helper.providers.secrets import get_parameter_name
9
+ from dbt_platform_helper.providers.ecs import ECS
10
+ from dbt_platform_helper.providers.secrets import Secrets
23
11
  from dbt_platform_helper.utils.application import Application
24
- from dbt_platform_helper.utils.messages import abort_with_error
25
12
 
26
13
 
27
14
  class Conduit:
28
15
  def __init__(
29
16
  self,
30
17
  application: Application,
31
- echo_fn: Callable[[str], str] = click.secho,
32
- subprocess_fn: subprocess = subprocess,
33
- get_ecs_task_arns_fn=get_ecs_task_arns,
34
- connect_to_addon_client_task_fn=connect_to_addon_client_task,
35
- create_addon_client_task_fn=create_addon_client_task,
36
- create_postgres_admin_task_fn=create_postgres_admin_task,
37
- get_addon_type_fn=get_addon_type,
38
- ecs_exec_is_available_fn=ecs_exec_is_available,
39
- get_cluster_arn_fn=get_cluster_arn,
40
- get_parameter_name_fn=get_parameter_name,
41
- get_or_create_task_name_fn=get_or_create_task_name,
42
- add_stack_delete_policy_to_task_role_fn=add_stack_delete_policy_to_task_role,
43
- update_conduit_stack_resources_fn=update_conduit_stack_resources,
44
- wait_for_cloudformation_to_reach_status_fn=wait_for_cloudformation_to_reach_status,
45
- abort_fn=abort_with_error,
18
+ secrets_provider: Secrets,
19
+ cloudformation_provider: CloudFormation,
20
+ ecs_provider: ECS,
21
+ echo: Callable[[str], str] = click.secho,
22
+ subprocess: subprocess = subprocess,
23
+ connect_to_addon_client_task=connect_to_addon_client_task,
24
+ create_addon_client_task=create_addon_client_task,
46
25
  ):
47
26
 
48
27
  self.application = application
49
- self.subprocess_fn = subprocess_fn
50
- self.echo_fn = echo_fn
51
- self.get_ecs_task_arns_fn = get_ecs_task_arns_fn
52
- self.connect_to_addon_client_task_fn = connect_to_addon_client_task_fn
53
- self.create_addon_client_task_fn = create_addon_client_task_fn
54
- self.create_postgres_admin_task = create_postgres_admin_task_fn
55
- self.get_addon_type_fn = get_addon_type_fn
56
- self.ecs_exec_is_available_fn = ecs_exec_is_available_fn
57
- self.get_cluster_arn_fn = get_cluster_arn_fn
58
- self.get_parameter_name_fn = get_parameter_name_fn
59
- self.get_or_create_task_name_fn = get_or_create_task_name_fn
60
- self.add_stack_delete_policy_to_task_role_fn = add_stack_delete_policy_to_task_role_fn
61
- self.update_conduit_stack_resources_fn = update_conduit_stack_resources_fn
62
- self.wait_for_cloudformation_to_reach_status_fn = wait_for_cloudformation_to_reach_status_fn
63
- self.abort_fn = abort_fn
28
+ self.secrets_provider = secrets_provider
29
+ self.cloudformation_provider = cloudformation_provider
30
+ self.ecs_provider = ecs_provider
31
+ self.subprocess = subprocess
32
+ self.echo = echo
33
+ self.connect_to_addon_client_task = connect_to_addon_client_task
34
+ self.create_addon_client_task = create_addon_client_task
64
35
 
65
36
  def start(self, env: str, addon_name: str, access: str = "read"):
66
37
  clients = self._initialise_clients(env)
67
38
  addon_type, cluster_arn, parameter_name, task_name = self._get_addon_details(
68
- env, addon_name, access
39
+ addon_name, access
69
40
  )
70
41
 
71
- self.echo_fn(f"Checking if a conduit task is already running for {addon_type}")
72
- task_arn = self.get_ecs_task_arns_fn(clients["ecs"], cluster_arn, task_name)
73
- if not task_arn:
74
- self.echo_fn("Creating conduit task")
75
- self.create_addon_client_task_fn(
42
+ self.echo(f"Checking if a conduit task is already running for {addon_type}")
43
+ task_arns = self.ecs_provider.get_ecs_task_arns(cluster_arn, task_name)
44
+ if not task_arns:
45
+ self.echo("Creating conduit task")
46
+ self.create_addon_client_task(
76
47
  clients["iam"],
77
48
  clients["ssm"],
78
- clients["secrets_manager"],
79
- self.subprocess_fn,
49
+ self.subprocess,
80
50
  self.application,
81
51
  env,
82
52
  addon_type,
@@ -85,11 +55,8 @@ class Conduit:
85
55
  access,
86
56
  )
87
57
 
88
- self.echo_fn("Updating conduit task")
58
+ self.echo("Updating conduit task")
89
59
  self._update_stack_resources(
90
- clients["cloudformation"],
91
- clients["iam"],
92
- clients["ssm"],
93
60
  self.application.name,
94
61
  env,
95
62
  addon_type,
@@ -99,21 +66,18 @@ class Conduit:
99
66
  access,
100
67
  )
101
68
 
102
- task_arn = self.get_ecs_task_arns_fn(clients["ecs"], cluster_arn, task_name)
69
+ task_arns = self.ecs_provider.get_ecs_task_arns(cluster_arn, task_name)
103
70
 
104
71
  else:
105
- self.echo_fn("Conduit task already running")
72
+ self.echo("Conduit task already running")
106
73
 
107
- self.echo_fn(f"Checking if exec is available for conduit task...")
74
+ self.echo(f"Checking if exec is available for conduit task...")
108
75
 
109
- try:
110
- self.ecs_exec_is_available_fn(clients["ecs"], cluster_arn, task_arn)
111
- except ECSAgentNotRunning:
112
- self.abort_fn('ECS exec agent never reached "RUNNING" status')
76
+ self.ecs_provider.ecs_exec_is_available(cluster_arn, task_arns)
113
77
 
114
- self.echo_fn("Connecting to conduit task")
115
- self.connect_to_addon_client_task_fn(
116
- clients["ecs"], self.subprocess_fn, self.application.name, env, cluster_arn, task_name
78
+ self.echo("Connecting to conduit task")
79
+ self.connect_to_addon_client_task(
80
+ clients["ecs"], self.subprocess, self.application.name, env, cluster_arn, task_name
117
81
  )
118
82
 
119
83
  def _initialise_clients(self, env):
@@ -121,30 +85,18 @@ class Conduit:
121
85
  "ecs": self.application.environments[env].session.client("ecs"),
122
86
  "iam": self.application.environments[env].session.client("iam"),
123
87
  "ssm": self.application.environments[env].session.client("ssm"),
124
- "cloudformation": self.application.environments[env].session.client("cloudformation"),
125
- "secrets_manager": self.application.environments[env].session.client("secretsmanager"),
126
88
  }
127
89
 
128
- def _get_addon_details(self, env, addon_name, access):
129
- ssm_client = self.application.environments[env].session.client("ssm")
130
- ecs_client = self.application.environments[env].session.client("ecs")
131
-
132
- addon_type = self.get_addon_type_fn(ssm_client, self.application.name, env, addon_name)
133
- cluster_arn = self.get_cluster_arn_fn(ecs_client, self.application.name, env)
134
- parameter_name = self.get_parameter_name_fn(
135
- self.application.name, env, addon_type, addon_name, access
136
- )
137
- task_name = self.get_or_create_task_name_fn(
138
- ssm_client, self.application.name, env, addon_name, parameter_name
139
- )
90
+ def _get_addon_details(self, addon_name, access):
91
+ addon_type = self.secrets_provider.get_addon_type(addon_name)
92
+ cluster_arn = self.ecs_provider.get_cluster_arn()
93
+ parameter_name = self.secrets_provider.get_parameter_name(addon_type, addon_name, access)
94
+ task_name = self.ecs_provider.get_or_create_task_name(addon_name, parameter_name)
140
95
 
141
96
  return addon_type, cluster_arn, parameter_name, task_name
142
97
 
143
98
  def _update_stack_resources(
144
99
  self,
145
- cloudformation_client,
146
- iam_client,
147
- ssm_client,
148
100
  app_name,
149
101
  env,
150
102
  addon_type,
@@ -153,11 +105,8 @@ class Conduit:
153
105
  parameter_name,
154
106
  access,
155
107
  ):
156
- self.add_stack_delete_policy_to_task_role_fn(cloudformation_client, iam_client, task_name)
157
- stack_name = self.update_conduit_stack_resources_fn(
158
- cloudformation_client,
159
- iam_client,
160
- ssm_client,
108
+ self.cloudformation_provider.add_stack_delete_policy_to_task_role(task_name)
109
+ stack_name = self.cloudformation_provider.update_conduit_stack_resources(
161
110
  app_name,
162
111
  env,
163
112
  addon_type,
@@ -166,7 +115,7 @@ class Conduit:
166
115
  parameter_name,
167
116
  access,
168
117
  )
169
- self.echo_fn("Waiting for conduit task update to complete...")
170
- self.wait_for_cloudformation_to_reach_status_fn(
171
- cloudformation_client, "stack_update_complete", stack_name
118
+ self.echo("Waiting for conduit task update to complete...")
119
+ self.cloudformation_provider.wait_for_cloudformation_to_reach_status(
120
+ "stack_update_complete", stack_name
172
121
  )