dbt-platform-helper 12.5.1__py3-none-any.whl → 13.0.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 (47) hide show
  1. dbt_platform_helper/COMMANDS.md +45 -42
  2. dbt_platform_helper/commands/codebase.py +7 -10
  3. dbt_platform_helper/commands/conduit.py +2 -2
  4. dbt_platform_helper/commands/config.py +1 -1
  5. dbt_platform_helper/commands/environment.py +32 -18
  6. dbt_platform_helper/commands/notify.py +5 -3
  7. dbt_platform_helper/commands/pipeline.py +17 -11
  8. dbt_platform_helper/constants.py +3 -1
  9. dbt_platform_helper/domain/codebase.py +48 -36
  10. dbt_platform_helper/domain/conduit.py +10 -12
  11. dbt_platform_helper/domain/config_validator.py +42 -31
  12. dbt_platform_helper/domain/copilot_environment.py +133 -129
  13. dbt_platform_helper/domain/database_copy.py +38 -37
  14. dbt_platform_helper/domain/maintenance_page.py +243 -193
  15. dbt_platform_helper/domain/pipelines.py +60 -135
  16. dbt_platform_helper/domain/terraform_environment.py +7 -3
  17. dbt_platform_helper/providers/aws.py +5 -0
  18. dbt_platform_helper/providers/cloudformation.py +12 -1
  19. dbt_platform_helper/providers/config.py +12 -14
  20. dbt_platform_helper/providers/ecr.py +20 -0
  21. dbt_platform_helper/providers/files.py +1 -1
  22. dbt_platform_helper/providers/io.py +31 -0
  23. dbt_platform_helper/providers/load_balancers.py +29 -3
  24. dbt_platform_helper/providers/platform_config_schema.py +24 -22
  25. dbt_platform_helper/providers/terraform_manifest.py +120 -0
  26. dbt_platform_helper/providers/vpc.py +81 -32
  27. dbt_platform_helper/templates/COMMANDS.md.jinja +5 -3
  28. dbt_platform_helper/templates/environment-pipelines/main.tf +2 -2
  29. dbt_platform_helper/templates/environments/main.tf +3 -4
  30. dbt_platform_helper/utils/aws.py +16 -5
  31. dbt_platform_helper/utils/messages.py +2 -3
  32. {dbt_platform_helper-12.5.1.dist-info → dbt_platform_helper-13.0.0.dist-info}/METADATA +2 -2
  33. {dbt_platform_helper-12.5.1.dist-info → dbt_platform_helper-13.0.0.dist-info}/RECORD +36 -44
  34. dbt_platform_helper/templates/pipelines/codebase/manifest.yml +0 -56
  35. dbt_platform_helper/templates/pipelines/codebase/overrides/.gitignore +0 -12
  36. dbt_platform_helper/templates/pipelines/codebase/overrides/bin/override.ts +0 -8
  37. dbt_platform_helper/templates/pipelines/codebase/overrides/buildspec.deploy.yml +0 -29
  38. dbt_platform_helper/templates/pipelines/codebase/overrides/buildspec.image.yml +0 -48
  39. dbt_platform_helper/templates/pipelines/codebase/overrides/cdk.json +0 -20
  40. dbt_platform_helper/templates/pipelines/codebase/overrides/package-lock.json +0 -4232
  41. dbt_platform_helper/templates/pipelines/codebase/overrides/package.json +0 -27
  42. dbt_platform_helper/templates/pipelines/codebase/overrides/stack.ts +0 -521
  43. dbt_platform_helper/templates/pipelines/codebase/overrides/tsconfig.json +0 -30
  44. dbt_platform_helper/templates/pipelines/codebase/overrides/types.ts +0 -52
  45. {dbt_platform_helper-12.5.1.dist-info → dbt_platform_helper-13.0.0.dist-info}/LICENSE +0 -0
  46. {dbt_platform_helper-12.5.1.dist-info → dbt_platform_helper-13.0.0.dist-info}/WHEEL +0 -0
  47. {dbt_platform_helper-12.5.1.dist-info → dbt_platform_helper-13.0.0.dist-info}/entry_points.txt +0 -0
@@ -2,6 +2,7 @@ import itertools
2
2
  import random
3
3
  import re
4
4
  import string
5
+ import traceback
5
6
  from pathlib import Path
6
7
  from typing import Callable
7
8
  from typing import List
@@ -11,14 +12,16 @@ import boto3
11
12
  import click
12
13
 
13
14
  from dbt_platform_helper.platform_exception import PlatformException
15
+ from dbt_platform_helper.providers.io import ClickIOProvider
14
16
  from dbt_platform_helper.providers.load_balancers import ListenerNotFoundException
15
17
  from dbt_platform_helper.providers.load_balancers import ListenerRuleNotFoundException
16
18
  from dbt_platform_helper.providers.load_balancers import LoadBalancerNotFoundException
17
- from dbt_platform_helper.providers.load_balancers import find_https_listener
19
+ from dbt_platform_helper.providers.load_balancers import (
20
+ get_https_listener_for_application,
21
+ )
18
22
  from dbt_platform_helper.utils.application import Application
19
23
  from dbt_platform_helper.utils.application import Environment
20
24
  from dbt_platform_helper.utils.application import Service
21
- from dbt_platform_helper.utils.application import load_application
22
25
 
23
26
 
24
27
  class MaintenancePageException(PlatformException):
@@ -26,134 +29,308 @@ class MaintenancePageException(PlatformException):
26
29
 
27
30
 
28
31
  class LoadBalancedWebServiceNotFoundException(MaintenancePageException):
29
- pass
32
+ def __init__(self, application_name: str):
33
+ super().__init__(f"No services deployed yet to {application_name} ")
30
34
 
31
35
 
32
- class MaintenancePage:
36
+ class FailedToActivateMaintenancePageException(MaintenancePageException):
33
37
  def __init__(
34
38
  self,
35
- user_prompt_callback: Callable[[str], bool] = click.confirm,
36
- echo: Callable[[str], str] = click.secho,
39
+ application_name: str,
40
+ env: str,
41
+ original_exception: Exception,
42
+ rolled_back_rules: dict[str, bool] = {},
37
43
  ):
38
- self.user_prompt_callback = user_prompt_callback
39
- self.echo = echo
44
+ super().__init__(
45
+ f"Maintenance page failed to activate for the {application_name} application in environment {env}."
46
+ )
47
+ self.orginal_exception = original_exception
48
+ self.rolled_back_rules = rolled_back_rules
49
+
50
+ def __str__(self):
51
+ return (
52
+ f"{super().__str__()}\n"
53
+ f"Rolled-back rules: {self.rolled_back_rules }\n"
54
+ f"Original exception: {self.orginal_exception}"
55
+ )
56
+
57
+
58
+ def get_maintenance_page_type(session: boto3.Session, listener_arn: str) -> Union[str, None]:
59
+ lb_client = session.client("elbv2")
60
+
61
+ rules = lb_client.describe_rules(ListenerArn=listener_arn)["Rules"]
62
+ tag_descriptions = get_rules_tag_descriptions(rules, lb_client)
40
63
 
41
- def _get_deployed_load_balanced_web_services(self, app: Application, svc: str):
64
+ maintenance_page_type = None
65
+ for description in tag_descriptions:
66
+ tags = {t["Key"]: t["Value"] for t in description["Tags"]}
67
+ if tags.get("name") == "MaintenancePage":
68
+ maintenance_page_type = tags.get("type")
69
+
70
+ return maintenance_page_type
71
+
72
+
73
+ def get_env_ips(vpc: str, application_environment: Environment) -> List[str]:
74
+ account_name = f"{application_environment.session.profile_name}-vpc"
75
+ vpc_name = vpc if vpc else account_name
76
+ ssm_client = application_environment.session.client("ssm")
77
+
78
+ try:
79
+ param_value = ssm_client.get_parameter(Name=f"/{vpc_name}/EGRESS_IPS")["Parameter"]["Value"]
80
+ except ssm_client.exceptions.ParameterNotFound:
81
+ click.secho(f"No parameter found with name: /{vpc_name}/EGRESS_IPS")
82
+ raise click.Abort
83
+
84
+ return [ip.strip() for ip in param_value.split(",")]
85
+
86
+
87
+ def add_maintenance_page(
88
+ session: boto3.Session,
89
+ listener_arn: str,
90
+ app: str,
91
+ env: str,
92
+ services: List[Service],
93
+ allowed_ips: tuple,
94
+ template: str = "default",
95
+ ):
96
+ lb_client = session.client("elbv2")
97
+ maintenance_page_content = get_maintenance_page_template(template)
98
+ bypass_value = "".join(random.choices(string.ascii_lowercase + string.digits, k=12))
99
+
100
+ rule_priority = itertools.count(start=1)
101
+ try:
102
+ for svc in services:
103
+ target_group_arn = find_target_group(app, env, svc.name, session)
104
+
105
+ # not all of an application's services are guaranteed to have been deployed to an environment
106
+ if not target_group_arn:
107
+ continue
108
+
109
+ for ip in allowed_ips:
110
+ create_header_rule(
111
+ lb_client,
112
+ listener_arn,
113
+ target_group_arn,
114
+ "X-Forwarded-For",
115
+ [ip],
116
+ "AllowedIps",
117
+ next(rule_priority),
118
+ )
119
+ create_source_ip_rule(
120
+ lb_client,
121
+ listener_arn,
122
+ target_group_arn,
123
+ [ip],
124
+ "AllowedSourceIps",
125
+ next(rule_priority),
126
+ )
127
+
128
+ create_header_rule(
129
+ lb_client,
130
+ listener_arn,
131
+ target_group_arn,
132
+ "Bypass-Key",
133
+ [bypass_value],
134
+ "BypassIpFilter",
135
+ next(rule_priority),
136
+ )
137
+
138
+ click.secho(
139
+ 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/",
140
+ )
141
+
142
+ lb_client.create_rule(
143
+ ListenerArn=listener_arn,
144
+ Priority=next(rule_priority),
145
+ Conditions=[
146
+ {
147
+ "Field": "path-pattern",
148
+ "PathPatternConfig": {"Values": ["/*"]},
149
+ }
150
+ ],
151
+ Actions=[
152
+ {
153
+ "Type": "fixed-response",
154
+ "FixedResponseConfig": {
155
+ "StatusCode": "503",
156
+ "ContentType": "text/html",
157
+ "MessageBody": maintenance_page_content,
158
+ },
159
+ }
160
+ ],
161
+ Tags=[
162
+ {"Key": "name", "Value": "MaintenancePage"},
163
+ {"Key": "type", "Value": template},
164
+ ],
165
+ )
166
+ except Exception as e:
167
+ deleted_rules = clean_up_maintenance_page_rules(session, listener_arn)
168
+ raise FailedToActivateMaintenancePageException(
169
+ app, env, f"{e}:\n {traceback.format_exc()}", deleted_rules
170
+ )
171
+
172
+
173
+ def clean_up_maintenance_page_rules(
174
+ session: boto3.Session, listener_arn: str, fail_when_not_deleted: bool = False
175
+ ) -> dict[str, bool]:
176
+ lb_client = session.client("elbv2")
177
+
178
+ rules = lb_client.describe_rules(ListenerArn=listener_arn)["Rules"]
179
+ tag_descriptions = get_rules_tag_descriptions(rules, lb_client)
180
+
181
+ deletes = {}
182
+ for name in ["MaintenancePage", "AllowedIps", "BypassIpFilter", "AllowedSourceIps"]:
183
+ deleted = delete_listener_rule(tag_descriptions, name, lb_client)
184
+ deletes[name] = bool(deleted)
185
+ if fail_when_not_deleted and name == "MaintenancePage" and not deleted:
186
+ raise ListenerRuleNotFoundException()
187
+
188
+ return deletes
189
+
190
+
191
+ def remove_maintenance_page(session: boto3.Session, listener_arn: str):
192
+ clean_up_maintenance_page_rules(session, listener_arn, True)
193
+
194
+
195
+ class MaintenancePage:
196
+ def __init__(
197
+ self,
198
+ application: Application,
199
+ io: ClickIOProvider = ClickIOProvider(),
200
+ get_https_listener_for_application: Callable[
201
+ [boto3.Session, str, str], str
202
+ ] = get_https_listener_for_application,
203
+ # TODO refactor get_maintenance_page_type, add_maintenance_page, remove_maintenance_page into MaintenancePage class with LoadBalancerProvider as the dependency
204
+ get_maintenance_page_type: Callable[
205
+ [boto3.Session, str], Union[str, None]
206
+ ] = get_maintenance_page_type,
207
+ get_env_ips: Callable[[str, Environment], List[str]] = get_env_ips,
208
+ add_maintenance_page: Callable[
209
+ [boto3.Session, str, str, str, List[Service], tuple, str], None
210
+ ] = add_maintenance_page,
211
+ remove_maintenance_page: Callable[[boto3.Session, str], None] = remove_maintenance_page,
212
+ ):
213
+ self.application = application
214
+ self.get_https_listener_for_application = get_https_listener_for_application
215
+ self.io = io
216
+ self.get_maintenance_page_type = get_maintenance_page_type
217
+ self.get_env_ips = get_env_ips
218
+ self.add_maintenance_page = add_maintenance_page
219
+ self.remove_maintenance_page = remove_maintenance_page
220
+
221
+ def _get_deployed_load_balanced_web_services(self, app: Application, svc: List[str]):
42
222
  if "*" in svc:
43
223
  services = [s for s in app.services.values() if s.kind == "Load Balanced Web Service"]
44
224
  else:
45
- all_services = [get_app_service(app.name, s) for s in list(svc)]
225
+ all_services = [get_app_service(app, s) for s in list(svc)]
46
226
  services = [s for s in all_services if s.kind == "Load Balanced Web Service"]
47
227
  if not services:
48
- raise LoadBalancedWebServiceNotFoundException
228
+ raise LoadBalancedWebServiceNotFoundException(app.name)
49
229
  return services
50
230
 
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")
59
- raise click.Abort
60
-
61
- application_environment = get_app_environment(app, env)
231
+ def activate(self, env: str, services: List[str], template: str, vpc: Union[str, None]):
232
+
233
+ services = self._get_deployed_load_balanced_web_services(self.application, services)
234
+ application_environment = get_app_environment(self.application, env)
235
+
62
236
  try:
63
- https_listener = find_https_listener(application_environment.session, app, env)
64
- current_maintenance_page = get_maintenance_page(
237
+ https_listener = self.get_https_listener_for_application(
238
+ application_environment.session, self.application.name, env
239
+ )
240
+ current_maintenance_page = self.get_maintenance_page_type(
65
241
  application_environment.session, https_listener
66
242
  )
67
243
  remove_current_maintenance_page = False
68
244
  if current_maintenance_page:
69
- remove_current_maintenance_page = self.user_prompt_callback(
245
+ remove_current_maintenance_page = self.io.confirm(
70
246
  f"There is currently a '{current_maintenance_page}' maintenance page for the {env} "
71
- f"environment in {app}.\nWould you like to replace it with a '{template}' "
247
+ f"environment in {self.application.name}.\nWould you like to replace it with a '{template}' "
72
248
  f"maintenance page?"
73
249
  )
74
250
  if not remove_current_maintenance_page:
75
- raise click.Abort
251
+ return
76
252
 
77
- if remove_current_maintenance_page or self.user_prompt_callback(
253
+ if remove_current_maintenance_page or self.io.confirm(
78
254
  f"You are about to enable the '{template}' maintenance page for the {env} "
79
- f"environment in {app}.\nWould you like to continue?"
255
+ f"environment in {self.application.name}.\nWould you like to continue?"
80
256
  ):
81
257
  if current_maintenance_page and remove_current_maintenance_page:
82
- remove_maintenance_page(application_environment.session, https_listener)
258
+ self.remove_maintenance_page(application_environment.session, https_listener)
83
259
 
84
- allowed_ips = get_env_ips(vpc, application_environment)
260
+ allowed_ips = self.get_env_ips(vpc, application_environment)
85
261
 
86
- add_maintenance_page(
262
+ self.add_maintenance_page(
87
263
  application_environment.session,
88
264
  https_listener,
89
- app,
265
+ self.application.name,
90
266
  env,
91
267
  services,
92
268
  allowed_ips,
93
269
  template,
94
270
  )
95
- self.echo(
96
- f"Maintenance page '{template}' added for environment {env} in application {app}",
97
- fg="green",
271
+ self.io.info(
272
+ f"Maintenance page '{template}' added for environment {env} in application {self.application.name}",
98
273
  )
99
- else:
100
- raise click.Abort
101
274
 
102
275
  except LoadBalancerNotFoundException:
103
- self.echo(
104
- f"No load balancer found for environment {env} in the application {app}.", fg="red"
276
+ # TODO push exception to command layer
277
+ self.io.abort_with_error(
278
+ f"No load balancer found for environment {env} in the application {self.application.name}.",
105
279
  )
106
- raise click.Abort
107
280
 
108
281
  except ListenerNotFoundException:
109
- self.echo(
110
- f"No HTTPS listener found for environment {env} in the application {app}.", fg="red"
282
+ # TODO push exception to command layer
283
+ self.io.abort_with_error(
284
+ f"No HTTPS listener found for environment {env} in the application {self.application.name}.",
111
285
  )
112
- raise click.Abort
113
286
 
114
- def deactivate(self, app, env):
115
- application_environment = get_app_environment(app, env)
287
+ def deactivate(self, env: str):
288
+ application_environment = get_app_environment(self.application, env)
116
289
 
117
290
  try:
118
- https_listener = find_https_listener(application_environment.session, app, env)
119
- current_maintenance_page = get_maintenance_page(
291
+ https_listener = self.get_https_listener_for_application(
292
+ application_environment.session, self.application.name, env
293
+ )
294
+ current_maintenance_page = self.get_maintenance_page_type(
120
295
  application_environment.session, https_listener
121
296
  )
297
+
298
+ # TODO discuss, reduce number of return statements but more nested if statements
122
299
  if not current_maintenance_page:
123
- self.echo("There is no current maintenance page to remove", fg="red")
124
- raise click.Abort
300
+ self.io.warn("There is no current maintenance page to remove")
301
+ return
125
302
 
126
- if not self.user_prompt_callback(
303
+ if not self.io.confirm(
127
304
  f"There is currently a '{current_maintenance_page}' maintenance page, "
128
305
  f"would you like to remove it?"
129
306
  ):
130
- raise click.Abort
307
+ return
131
308
 
132
- remove_maintenance_page(application_environment.session, https_listener)
133
- self.echo(
134
- f"Maintenance page removed from environment {env} in application {app}", fg="green"
309
+ self.remove_maintenance_page(application_environment.session, https_listener)
310
+ self.io.info(
311
+ f"Maintenance page removed from environment {env} in application {self.application.name}",
135
312
  )
136
313
 
137
314
  except LoadBalancerNotFoundException:
138
- self.echo(
139
- f"No load balancer found for environment {env} in the application {app}.", fg="red"
315
+ # TODO push exception to command layer
316
+ self.io.abort_with_error(
317
+ f"No load balancer found for environment {env} in the application {self.application.name}.",
140
318
  )
141
- raise click.Abort
142
319
 
143
320
  except ListenerNotFoundException:
144
- self.echo(
145
- f"No HTTPS listener found for environment {env} in the application {app}.", fg="red"
321
+ # TODO push exception to command layer
322
+ self.io.abort_with_error(
323
+ f"No HTTPS listener found for environment {env} in the application {self.application.name}.",
146
324
  )
147
- raise click.Abort
148
325
 
149
326
 
150
- def get_app_service(app_name: str, svc_name: str) -> Service:
151
- application = load_application(app_name)
327
+ def get_app_service(application: Application, svc_name: str) -> Service:
152
328
  application_service = application.services.get(svc_name)
153
329
 
154
330
  if not application_service:
331
+ # TODO raise exception instead of abort
155
332
  click.secho(
156
- f"The service {svc_name} was not found in the application {app_name}. "
333
+ f"The service {svc_name} was not found in the application {application.name}. "
157
334
  f"It either does not exist, or has not been deployed.",
158
335
  fg="red",
159
336
  )
@@ -162,13 +339,12 @@ def get_app_service(app_name: str, svc_name: str) -> Service:
162
339
  return application_service
163
340
 
164
341
 
165
- def get_app_environment(app_name: str, env_name: str) -> Environment:
166
- application = load_application(app_name)
342
+ def get_app_environment(application: Application, env_name: str) -> Environment:
167
343
  application_environment = application.environments.get(env_name)
168
344
 
169
345
  if not application_environment:
170
346
  click.secho(
171
- f"The environment {env_name} was not found in the application {app_name}. "
347
+ f"The environment {env_name} was not found in the application {application.name}. "
172
348
  f"It either does not exist, or has not been deployed.",
173
349
  fg="red",
174
350
  )
@@ -177,36 +353,6 @@ def get_app_environment(app_name: str, env_name: str) -> Environment:
177
353
  return application_environment
178
354
 
179
355
 
180
- def get_maintenance_page(session: boto3.Session, listener_arn: str) -> Union[str, None]:
181
- lb_client = session.client("elbv2")
182
-
183
- rules = lb_client.describe_rules(ListenerArn=listener_arn)["Rules"]
184
- tag_descriptions = get_rules_tag_descriptions(rules, lb_client)
185
-
186
- maintenance_page_type = None
187
- for description in tag_descriptions:
188
- tags = {t["Key"]: t["Value"] for t in description["Tags"]}
189
- if tags.get("name") == "MaintenancePage":
190
- maintenance_page_type = tags.get("type")
191
-
192
- return maintenance_page_type
193
-
194
-
195
- def remove_maintenance_page(session: boto3.Session, listener_arn: str):
196
- lb_client = session.client("elbv2")
197
-
198
- rules = lb_client.describe_rules(ListenerArn=listener_arn)["Rules"]
199
- tag_descriptions = lb_client.describe_tags(ResourceArns=[r["RuleArn"] for r in rules])[
200
- "TagDescriptions"
201
- ]
202
-
203
- for name in ["MaintenancePage", "AllowedIps", "BypassIpFilter", "AllowedSourceIps"]:
204
- deleted = delete_listener_rule(tag_descriptions, name, lb_client)
205
-
206
- if name == "MaintenancePage" and not deleted:
207
- raise ListenerRuleNotFoundException()
208
-
209
-
210
356
  def get_rules_tag_descriptions(rules: list, lb_client):
211
357
  tag_descriptions = []
212
358
  chunk_size = 20
@@ -233,88 +379,6 @@ def delete_listener_rule(tag_descriptions: list, tag_name: str, lb_client: boto3
233
379
  return current_rule_arn
234
380
 
235
381
 
236
- def add_maintenance_page(
237
- session: boto3.Session,
238
- listener_arn: str,
239
- app: str,
240
- env: str,
241
- services: List[Service],
242
- allowed_ips: tuple,
243
- template: str = "default",
244
- ):
245
- lb_client = session.client("elbv2")
246
- maintenance_page_content = get_maintenance_page_template(template)
247
- bypass_value = "".join(random.choices(string.ascii_lowercase + string.digits, k=12))
248
-
249
- rule_priority = itertools.count(start=1)
250
-
251
- for svc in services:
252
- target_group_arn = find_target_group(app, env, svc.name, session)
253
-
254
- # not all of an application's services are guaranteed to have been deployed to an environment
255
- if not target_group_arn:
256
- continue
257
-
258
- for ip in allowed_ips:
259
- create_header_rule(
260
- lb_client,
261
- listener_arn,
262
- target_group_arn,
263
- "X-Forwarded-For",
264
- [ip],
265
- "AllowedIps",
266
- next(rule_priority),
267
- )
268
- create_source_ip_rule(
269
- lb_client,
270
- listener_arn,
271
- target_group_arn,
272
- [ip],
273
- "AllowedSourceIps",
274
- next(rule_priority),
275
- )
276
-
277
- create_header_rule(
278
- lb_client,
279
- listener_arn,
280
- target_group_arn,
281
- "Bypass-Key",
282
- [bypass_value],
283
- "BypassIpFilter",
284
- next(rule_priority),
285
- )
286
-
287
- click.secho(
288
- 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/",
289
- fg="green",
290
- )
291
-
292
- lb_client.create_rule(
293
- ListenerArn=listener_arn,
294
- Priority=next(rule_priority),
295
- Conditions=[
296
- {
297
- "Field": "path-pattern",
298
- "PathPatternConfig": {"Values": ["/*"]},
299
- }
300
- ],
301
- Actions=[
302
- {
303
- "Type": "fixed-response",
304
- "FixedResponseConfig": {
305
- "StatusCode": "503",
306
- "ContentType": "text/html",
307
- "MessageBody": maintenance_page_content,
308
- },
309
- }
310
- ],
311
- Tags=[
312
- {"Key": "name", "Value": "MaintenancePage"},
313
- {"Key": "type", "Value": template},
314
- ],
315
- )
316
-
317
-
318
382
  def get_maintenance_page_template(template) -> str:
319
383
  template_contents = (
320
384
  Path(__file__)
@@ -472,17 +536,3 @@ def get_host_conditions(lb_client: boto3.client, listener_arn: str, target_group
472
536
  ]
473
537
 
474
538
  return conditions
475
-
476
-
477
- def get_env_ips(vpc: str, application_environment: Environment) -> List[str]:
478
- account_name = f"{application_environment.session.profile_name}-vpc"
479
- vpc_name = vpc if vpc else account_name
480
- ssm_client = application_environment.session.client("ssm")
481
-
482
- try:
483
- param_value = ssm_client.get_parameter(Name=f"/{vpc_name}/EGRESS_IPS")["Parameter"]["Value"]
484
- except ssm_client.exceptions.ParameterNotFound:
485
- click.secho(f"No parameter found with name: /{vpc_name}/EGRESS_IPS")
486
- raise click.Abort
487
-
488
- return [ip.strip() for ip in param_value.split(",")]