qontract-reconcile 0.10.2.dev256__py3-none-any.whl → 0.10.2.dev257__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.
Files changed (94) hide show
  1. {qontract_reconcile-0.10.2.dev256.dist-info → qontract_reconcile-0.10.2.dev257.dist-info}/METADATA +1 -1
  2. {qontract_reconcile-0.10.2.dev256.dist-info → qontract_reconcile-0.10.2.dev257.dist-info}/RECORD +94 -94
  3. reconcile/aus/advanced_upgrade_service.py +1 -1
  4. reconcile/aus/base.py +2 -2
  5. reconcile/aus/version_gates/sts_version_gate_handler.py +2 -2
  6. reconcile/aws_account_manager/reconciler.py +22 -20
  7. reconcile/aws_iam_keys.py +5 -5
  8. reconcile/aws_iam_password_reset.py +5 -5
  9. reconcile/aws_saml_roles/integration.py +5 -5
  10. reconcile/aws_version_sync/integration.py +4 -3
  11. reconcile/cli.py +5 -5
  12. reconcile/closedbox_endpoint_monitoring_base.py +1 -0
  13. reconcile/database_access_manager.py +4 -4
  14. reconcile/dynatrace_token_provider/integration.py +2 -2
  15. reconcile/external_resources/manager.py +2 -2
  16. reconcile/external_resources/model.py +1 -1
  17. reconcile/external_resources/secrets_sync.py +2 -2
  18. reconcile/gabi_authorized_users.py +3 -3
  19. reconcile/github_org.py +2 -2
  20. reconcile/gitlab_housekeeping.py +1 -1
  21. reconcile/gitlab_mr_sqs_consumer.py +1 -1
  22. reconcile/glitchtip/integration.py +2 -2
  23. reconcile/jenkins_worker_fleets.py +5 -5
  24. reconcile/ldap_groups/integration.py +3 -3
  25. reconcile/ocm_clusters.py +2 -2
  26. reconcile/ocm_internal_notifications/integration.py +2 -2
  27. reconcile/ocm_labels/integration.py +3 -2
  28. reconcile/openshift_base.py +12 -11
  29. reconcile/openshift_cluster_bots.py +2 -2
  30. reconcile/openshift_resources_base.py +3 -3
  31. reconcile/openshift_rhcs_certs.py +2 -2
  32. reconcile/openshift_saas_deploy.py +1 -1
  33. reconcile/quay_membership.py +4 -4
  34. reconcile/rhidp/common.py +3 -2
  35. reconcile/run_integration.py +7 -4
  36. reconcile/skupper_network/integration.py +3 -3
  37. reconcile/slack_usergroups.py +4 -4
  38. reconcile/status_board.py +3 -3
  39. reconcile/terraform_cloudflare_dns.py +5 -5
  40. reconcile/terraform_cloudflare_users.py +15 -17
  41. reconcile/terraform_resources.py +6 -6
  42. reconcile/terraform_vpc_peerings.py +9 -9
  43. reconcile/unleash_feature_toggles/integration.py +1 -1
  44. reconcile/utils/aggregated_list.py +2 -2
  45. reconcile/utils/aws_api_typed/iam.py +2 -2
  46. reconcile/utils/aws_api_typed/organization.py +4 -4
  47. reconcile/utils/aws_api_typed/service_quotas.py +4 -4
  48. reconcile/utils/aws_api_typed/support.py +9 -9
  49. reconcile/utils/aws_helper.py +1 -1
  50. reconcile/utils/config.py +8 -4
  51. reconcile/utils/deadmanssnitch_api.py +2 -4
  52. reconcile/utils/glitchtip/models.py +18 -12
  53. reconcile/utils/gql.py +4 -4
  54. reconcile/utils/internal_groups/client.py +2 -2
  55. reconcile/utils/jinja2/utils.py +7 -3
  56. reconcile/utils/jjb_client.py +2 -2
  57. reconcile/utils/models.py +2 -1
  58. reconcile/utils/mr/__init__.py +3 -3
  59. reconcile/utils/mr/app_interface_reporter.py +2 -2
  60. reconcile/utils/mr/aws_access.py +5 -2
  61. reconcile/utils/mr/base.py +3 -3
  62. reconcile/utils/mr/user_maintenance.py +1 -1
  63. reconcile/utils/oc.py +11 -11
  64. reconcile/utils/oc_connection_parameters.py +4 -4
  65. reconcile/utils/ocm/base.py +3 -3
  66. reconcile/utils/ocm/products.py +8 -8
  67. reconcile/utils/ocm/search_filters.py +2 -2
  68. reconcile/utils/openshift_resource.py +21 -18
  69. reconcile/utils/pagerduty_api.py +5 -5
  70. reconcile/utils/quay_api.py +2 -2
  71. reconcile/utils/rosa/rosa_cli.py +1 -1
  72. reconcile/utils/rosa/session.py +2 -2
  73. reconcile/utils/runtime/desired_state_diff.py +7 -7
  74. reconcile/utils/saasherder/interfaces.py +1 -0
  75. reconcile/utils/saasherder/models.py +1 -1
  76. reconcile/utils/saasherder/saasherder.py +1 -1
  77. reconcile/utils/secret_reader.py +20 -20
  78. reconcile/utils/slack_api.py +5 -5
  79. reconcile/utils/slo_document_manager.py +6 -6
  80. reconcile/utils/state.py +8 -8
  81. reconcile/utils/terraform_client.py +3 -3
  82. reconcile/utils/terrascript/cloudflare_client.py +2 -2
  83. reconcile/utils/terrascript/cloudflare_resources.py +1 -0
  84. reconcile/utils/terrascript_aws_client.py +12 -11
  85. reconcile/utils/vault.py +22 -22
  86. reconcile/vault_replication.py +15 -15
  87. tools/cli_commands/erv2.py +3 -2
  88. tools/cli_commands/gpg_encrypt.py +9 -9
  89. tools/cli_commands/systems_and_tools.py +1 -1
  90. tools/qontract_cli.py +13 -14
  91. tools/saas_promotion_state/saas_promotion_state.py +4 -4
  92. tools/template_validation.py +5 -5
  93. {qontract_reconcile-0.10.2.dev256.dist-info → qontract_reconcile-0.10.2.dev257.dist-info}/WHEEL +0 -0
  94. {qontract_reconcile-0.10.2.dev256.dist-info → qontract_reconcile-0.10.2.dev257.dist-info}/entry_points.txt +0 -0
reconcile/utils/vault.py CHANGED
@@ -18,27 +18,27 @@ LOG = logging.getLogger(__name__)
18
18
  VAULT_AUTO_REFRESH_INTERVAL = int(os.getenv("VAULT_AUTO_REFRESH_INTERVAL") or 600)
19
19
 
20
20
 
21
- class PathAccessForbidden(Exception):
21
+ class PathAccessForbiddenError(Exception):
22
22
  pass
23
23
 
24
24
 
25
- class SecretNotFound(Exception):
25
+ class SecretNotFoundError(Exception):
26
26
  pass
27
27
 
28
28
 
29
- class SecretAccessForbidden(Exception):
29
+ class SecretAccessForbiddenError(Exception):
30
30
  pass
31
31
 
32
32
 
33
- class SecretVersionIsNone(Exception):
33
+ class SecretVersionIsNoneError(Exception):
34
34
  pass
35
35
 
36
36
 
37
- class SecretVersionNotFound(Exception):
37
+ class SecretVersionNotFoundError(Exception):
38
38
  pass
39
39
 
40
40
 
41
- class SecretFieldNotFound(Exception):
41
+ class SecretFieldNotFoundError(Exception):
42
42
  pass
43
43
 
44
44
 
@@ -189,7 +189,7 @@ class _VaultClient:
189
189
  data = secret_data
190
190
 
191
191
  if data is None:
192
- raise SecretNotFound
192
+ raise SecretNotFoundError
193
193
 
194
194
  return data, version
195
195
 
@@ -223,7 +223,7 @@ class _VaultClient:
223
223
  read_path = "/".join(path_split[1:])
224
224
  if version is None:
225
225
  msg = f"version can not be null for secret with path '{path}'."
226
- raise SecretVersionIsNone(msg)
226
+ raise SecretVersionIsNoneError(msg)
227
227
  if version == SECRET_VERSION_LATEST:
228
228
  # https://github.com/hvac/hvac/blob/
229
229
  # ec048ded30d21c13c21cfa950d148c8bfc1467b0/
@@ -237,12 +237,12 @@ class _VaultClient:
237
237
  )
238
238
  except InvalidPath:
239
239
  msg = f"version '{version}' not found for secret with path '{path}'."
240
- raise SecretVersionNotFound(msg) from None
240
+ raise SecretVersionNotFoundError(msg) from None
241
241
  except hvac.exceptions.Forbidden:
242
242
  msg = f"permission denied accessing secret '{path}'"
243
- raise SecretAccessForbidden(msg) from None
243
+ raise SecretAccessForbiddenError(msg) from None
244
244
  if secret is None or "data" not in secret or "data" not in secret["data"]:
245
- raise SecretNotFound(path)
245
+ raise SecretNotFoundError(path)
246
246
 
247
247
  data = secret["data"]["data"]
248
248
  secret_version = secret["data"]["metadata"]["version"]
@@ -253,10 +253,10 @@ class _VaultClient:
253
253
  secret = self._client.read(path)
254
254
  except hvac.exceptions.Forbidden:
255
255
  msg = f"permission denied accessing secret '{path}'"
256
- raise SecretAccessForbidden(msg) from None
256
+ raise SecretAccessForbiddenError(msg) from None
257
257
 
258
258
  if secret is None or "data" not in secret:
259
- raise SecretNotFound(path)
259
+ raise SecretNotFoundError(path)
260
260
 
261
261
  return secret["data"]
262
262
 
@@ -285,7 +285,7 @@ class _VaultClient:
285
285
  data = self._read_v1(secret_path, secret_field)
286
286
 
287
287
  if data is None:
288
- raise SecretNotFound
288
+ raise SecretNotFoundError
289
289
 
290
290
  return (
291
291
  base64.b64decode(data).decode("utf-8")
@@ -298,7 +298,7 @@ class _VaultClient:
298
298
  try:
299
299
  secret_field = data[field]
300
300
  except KeyError:
301
- raise SecretFieldNotFound(f"{path}/{field} ({version})") from None
301
+ raise SecretFieldNotFoundError(f"{path}/{field} ({version})") from None
302
302
  return secret_field
303
303
 
304
304
  def _read_v1(self, path, field):
@@ -306,7 +306,7 @@ class _VaultClient:
306
306
  try:
307
307
  secret_field = data[field]
308
308
  except KeyError:
309
- raise SecretFieldNotFound(f"{path}/{field}") from None
309
+ raise SecretFieldNotFoundError(f"{path}/{field}") from None
310
310
  return secret_field
311
311
 
312
312
  @retry()
@@ -345,7 +345,7 @@ class _VaultClient:
345
345
  if current_data == data and not force:
346
346
  logging.debug(f"current data is up-to-date, skipping {path}")
347
347
  return
348
- except SecretVersionNotFound:
348
+ except SecretVersionNotFoundError:
349
349
  # if the secret is not found we need to write it
350
350
  logging.debug(f"secret not found in {path}, will create it")
351
351
 
@@ -358,14 +358,14 @@ class _VaultClient:
358
358
  self._read_all_v2.cache_clear()
359
359
  except hvac.exceptions.Forbidden:
360
360
  msg = f"permission denied accessing secret '{path}'"
361
- raise SecretAccessForbidden(msg) from None
361
+ raise SecretAccessForbiddenError(msg) from None
362
362
 
363
363
  def _write_v1(self, path, data):
364
364
  try:
365
365
  self._client.write(path, **data)
366
366
  except hvac.exceptions.Forbidden:
367
367
  msg = f"permission denied accessing secret '{path}'"
368
- raise SecretAccessForbidden(msg) from None
368
+ raise SecretAccessForbiddenError(msg) from None
369
369
 
370
370
  def _list_kv2(self, path: str) -> dict:
371
371
  try:
@@ -376,14 +376,14 @@ class _VaultClient:
376
376
  return response
377
377
  except hvac.exceptions.Forbidden:
378
378
  msg = f"permission denied accessing path '{path}'"
379
- raise PathAccessForbidden(msg) from None
379
+ raise PathAccessForbiddenError(msg) from None
380
380
 
381
381
  def _list(self, path: str) -> dict:
382
382
  try:
383
383
  return self._client.list(path)
384
384
  except hvac.exceptions.Forbidden:
385
385
  msg = f"permission denied accessing path '{path}'"
386
- raise PathAccessForbidden(msg) from None
386
+ raise PathAccessForbiddenError(msg) from None
387
387
 
388
388
  def list(self, path: str) -> list[str]:
389
389
  """Returns a list of secrets in a given path."""
@@ -420,7 +420,7 @@ class _VaultClient:
420
420
  self._client.delete(path)
421
421
  except hvac.exceptions.Forbidden:
422
422
  msg = f"permission denied accessing secret '{path}'"
423
- raise SecretAccessForbidden(msg) from None
423
+ raise SecretAccessForbiddenError(msg) from None
424
424
 
425
425
 
426
426
  class VaultClient:
@@ -26,9 +26,9 @@ from reconcile.gql_definitions.vault_policies.vault_policies import (
26
26
  )
27
27
  from reconcile.utils import gql
28
28
  from reconcile.utils.vault import (
29
- SecretAccessForbidden,
30
- SecretNotFound,
31
- SecretVersionNotFound,
29
+ SecretAccessForbiddenError,
30
+ SecretNotFoundError,
31
+ SecretVersionNotFoundError,
32
32
  VaultClient,
33
33
  _VaultClient,
34
34
  )
@@ -37,15 +37,15 @@ QONTRACT_INTEGRATION = "vault-replication"
37
37
  SECRET_PATH_PATTERN = re.compile(r"^[\w/-]+?(?P<folder>/\*?)?$")
38
38
 
39
39
 
40
- class VaultInvalidPaths(Exception):
40
+ class VaultInvalidPathsError(Exception):
41
41
  pass
42
42
 
43
43
 
44
- class VaultInvalidAuthMethod(Exception):
44
+ class VaultInvalidAuthMethodError(Exception):
45
45
  pass
46
46
 
47
47
 
48
- class VaultInvalidPolicy(Exception):
48
+ class VaultInvalidPolicyError(Exception):
49
49
  pass
50
50
 
51
51
 
@@ -64,7 +64,7 @@ def deep_copy_versions(
64
64
 
65
65
  try:
66
66
  secret, src_version = source_vault.read_all_with_version(secret_dict)
67
- except (SecretNotFound, SecretVersionNotFound):
67
+ except (SecretNotFoundError, SecretVersionNotFoundError):
68
68
  # Handle the case where the difference between the source and destination
69
69
  # versions is greater than the number of versions in the source vault.
70
70
  # By default the secret engines store up to 10 versions of a secret.
@@ -119,7 +119,7 @@ def copy_vault_secret(
119
119
 
120
120
  try:
121
121
  source_data, version = source_vault.read_all_with_version(secret_dict)
122
- except SecretAccessForbidden:
122
+ except SecretAccessForbiddenError:
123
123
  # Raise exception if we can't read the secret from the source vault.
124
124
  # This is likely to be related to the approle permissions.
125
125
  logging.error([
@@ -128,7 +128,7 @@ def copy_vault_secret(
128
128
  path,
129
129
  ])
130
130
  raise
131
- except SecretNotFound:
131
+ except SecretNotFoundError:
132
132
  # If the secret is present in vault, but there are no versions of it
133
133
  # we want to be aware of it, but not cause a failure of the complete
134
134
  # integration
@@ -161,7 +161,7 @@ def copy_vault_secret(
161
161
  current_source_version=version,
162
162
  path=path,
163
163
  )
164
- except (SecretVersionNotFound, SecretNotFound):
164
+ except (SecretVersionNotFoundError, SecretNotFoundError):
165
165
  logging.info(["replicate_vault_secret", "Secret not found", path])
166
166
  # Handle v1 secrets where version is None and we don't need to deep sync.
167
167
  if version is None:
@@ -194,7 +194,7 @@ def check_invalid_paths(
194
194
  # Exit if we have paths not present in the policy that needs to be replicated
195
195
  # this is to prevent to replicate secrets that are not allowed.
196
196
  logging.error(["replicate_vault_secret", "Invalid paths", invalid_paths])
197
- raise VaultInvalidPaths
197
+ raise VaultInvalidPathsError
198
198
 
199
199
 
200
200
  def list_invalid_paths(
@@ -236,7 +236,7 @@ def get_policy_secret_list(
236
236
  match = SECRET_PATH_PATTERN.match(path)
237
237
  if not match:
238
238
  logging.error(["get_policy_secret_list", "Invalid path to replicate", path])
239
- raise VaultInvalidPaths
239
+ raise VaultInvalidPathsError
240
240
 
241
241
  if match.group("folder"):
242
242
  # Remove the * at the end of the path because list method expects
@@ -304,7 +304,7 @@ def get_vault_credentials(
304
304
  VaultInstanceV1_VaultReplicationConfigV1_VaultInstanceAuthV1_VaultInstanceAuthApproleV1,
305
305
  ):
306
306
  # Exit if the auth method is not approle as is the only one supported
307
- raise VaultInvalidAuthMethod
307
+ raise VaultInvalidAuthMethodError
308
308
 
309
309
  role_id = {
310
310
  "path": vault_auth.role_id.path,
@@ -359,7 +359,7 @@ def replicate_paths(
359
359
  if path.policy is None:
360
360
  # Exit if the replication config is empty, this should never happen
361
361
  # as policy is a required field in the schema but makes mypy happy.
362
- raise VaultInvalidPolicy(
362
+ raise VaultInvalidPolicyError(
363
363
  "Policy is required when using policy provider"
364
364
  )
365
365
  policy_paths = get_policy_paths(
@@ -402,7 +402,7 @@ def get_secrets_from_templated_path(path: str, vault_list: Iterable[str]) -> lis
402
402
  suffix = cap_groups.group(3)
403
403
  else:
404
404
  # Exit if the path is not a valid formatted template on the secret path
405
- raise VaultInvalidPaths
405
+ raise VaultInvalidPathsError
406
406
 
407
407
  secret_start, secret_end = _get_start_end_secret(path)
408
408
 
@@ -39,6 +39,9 @@ from reconcile.utils import gql
39
39
  from reconcile.utils.exceptions import FetchResourceError
40
40
  from reconcile.utils.secret_reader import SecretReaderBase
41
41
 
42
+ UP = "\x1b[1A"
43
+ CLEAR = "\x1b[2K"
44
+
42
45
 
43
46
  def progress_spinner() -> Progress:
44
47
  """Display shiny progress spinner."""
@@ -56,8 +59,6 @@ def pause_progress_spinner(progress: Progress | None) -> Iterator:
56
59
  """Pause the progress spinner."""
57
60
  if progress:
58
61
  progress.stop()
59
- UP = "\x1b[1A"
60
- CLEAR = "\x1b[2K"
61
62
  for task in progress.tasks:
62
63
  if task.finished:
63
64
  continue
@@ -23,15 +23,15 @@ class GPGEncryptCommandData:
23
23
  target_user: str = ""
24
24
 
25
25
 
26
- class UserException(Exception):
26
+ class UserError(Exception):
27
27
  pass
28
28
 
29
29
 
30
- class ArgumentException(Exception):
30
+ class ArgumentError(Exception):
31
31
  pass
32
32
 
33
33
 
34
- class OpenshiftException(Exception):
34
+ class OpenshiftError(Exception):
35
35
  pass
36
36
 
37
37
 
@@ -51,7 +51,7 @@ class GPGEncryptCommand:
51
51
  def _fetch_oc_secret(self) -> str:
52
52
  parts = self._command_data.openshift_path.split("/")
53
53
  if len(parts) != 3:
54
- raise ArgumentException(
54
+ raise ArgumentError(
55
55
  f"Wrong format! --openshift-path must be of format {{cluster}}/{{namespace}}/{{secret}}. Got {self._command_data.openshift_path}"
56
56
  )
57
57
  cluster_name, namespace, secret = parts
@@ -62,7 +62,7 @@ class GPGEncryptCommand:
62
62
  )
63
63
 
64
64
  if not clusters:
65
- raise ArgumentException(f"No cluster found with name '{cluster_name}'")
65
+ raise ArgumentError(f"No cluster found with name '{cluster_name}'")
66
66
 
67
67
  settings = queries.get_app_interface_settings()
68
68
  data = {}
@@ -81,7 +81,7 @@ class GPGEncryptCommand:
81
81
  "data"
82
82
  ]
83
83
  except Exception as e:
84
- raise OpenshiftException(
84
+ raise OpenshiftError(
85
85
  f"Could not fetch secret from Openshift cluster {cluster_name}"
86
86
  ) from e
87
87
 
@@ -107,7 +107,7 @@ class GPGEncryptCommand:
107
107
  return self._fetch_local_file_secret()
108
108
  if self._command_data.openshift_path:
109
109
  return self._fetch_oc_secret()
110
- raise ArgumentException(
110
+ raise ArgumentError(
111
111
  f"No argument given which defines how to fetch the secret {self._command_data}"
112
112
  )
113
113
 
@@ -120,13 +120,13 @@ class GPGEncryptCommand:
120
120
  ),
121
121
  )
122
122
  if len(users) != 1:
123
- raise UserException(
123
+ raise UserError(
124
124
  f"Expected to find exactly one user for '{target_user}', but found {len(users)}."
125
125
  )
126
126
  user = users[0]
127
127
 
128
128
  if "public_gpg_key" not in user:
129
- raise UserException(
129
+ raise UserError(
130
130
  f"User '{target_user}' does not have an associated GPG key."
131
131
  )
132
132
 
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env python3
2
- # ruff: noqa: PLC0415 - `import` should be at the top-level of a file
2
+
3
3
 
4
4
  from typing import (
5
5
  Any,
tools/qontract_cli.py CHANGED
@@ -1066,14 +1066,14 @@ def network_reservations(ctx: click.Context) -> None:
1066
1066
  return url
1067
1067
 
1068
1068
  for network in get_networks():
1069
- parentAddress = "none"
1069
+ parent_address = "none"
1070
1070
  if network.parent_network:
1071
- parentAddress = network.parent_network.network_address
1071
+ parent_address = network.parent_network.network_address
1072
1072
  if network.in_use_by and network.in_use_by.vpc:
1073
1073
  network_table.append({
1074
1074
  "name": network.name,
1075
1075
  "network Address": network.network_address,
1076
- "parent Network": parentAddress,
1076
+ "parent Network": parent_address,
1077
1077
  "Account Name": network.in_use_by.vpc.account.name,
1078
1078
  "Account UID": network.in_use_by.vpc.account.uid,
1079
1079
  "Console Login URL": md_link(network.in_use_by.vpc.account.console_url),
@@ -1082,7 +1082,7 @@ def network_reservations(ctx: click.Context) -> None:
1082
1082
  network_table.append({
1083
1083
  "name": network.name,
1084
1084
  "network Address": network.network_address,
1085
- "parent Network": parentAddress,
1085
+ "parent Network": parent_address,
1086
1086
  "Account Name": "Unclaimed network",
1087
1087
  "Account UID": "Unclaimed network",
1088
1088
  "Console Login URL": "Unclaimed network",
@@ -1857,8 +1857,8 @@ You can view the source of this Markdown to extract the JSON data.
1857
1857
  @get.command
1858
1858
  @click.pass_context
1859
1859
  def rds_recommendations(ctx: click.Context) -> None:
1860
- IGNORED_STATUSES = ("resolved",)
1861
- IGNORED_SEVERITIES = ("informational",)
1860
+ ignored_statuses = ("resolved",)
1861
+ ignored_severities = ("informational",)
1862
1862
 
1863
1863
  settings = queries.get_app_interface_settings()
1864
1864
 
@@ -1919,8 +1919,8 @@ def rds_recommendations(ctx: click.Context) -> None:
1919
1919
  "Description": rec["Description"].replace("\n", " "),
1920
1920
  }
1921
1921
  for rec in db_recommendations
1922
- if rec.get("Status") not in IGNORED_STATUSES
1923
- and rec.get("Severity") not in IGNORED_SEVERITIES
1922
+ if rec.get("Status") not in ignored_statuses
1923
+ and rec.get("Severity") not in ignored_severities
1924
1924
  ]
1925
1925
  # If we have no recommendations to show, skip
1926
1926
  if not recommendations:
@@ -2678,7 +2678,6 @@ def ec2_jenkins_workers(
2678
2678
  ec2 = boto3.resource("ec2")
2679
2679
  results = []
2680
2680
  now = datetime.now(UTC)
2681
- DATE_FORMAT = "%Y-%m-%d %H:%M:%S"
2682
2681
  columns = [
2683
2682
  "type",
2684
2683
  "id",
@@ -2723,7 +2722,7 @@ def ec2_jenkins_workers(
2723
2722
  "id": f"[{instance.id}]({url})",
2724
2723
  "IP": instance.private_ip_address,
2725
2724
  "instance type": instance.instance_type,
2726
- "launch time (utc)": f"{instance.launch_time.strftime(DATE_FORMAT)} {launch_emoji}",
2725
+ "launch time (utc)": f"{instance.launch_time.strftime('%Y-%m-%d %H:%M:%S')} {launch_emoji}",
2727
2726
  "OS": os,
2728
2727
  "AMI": f"[{image.name}]({commit_url})",
2729
2728
  }
@@ -2801,12 +2800,12 @@ def slo_document_services(ctx: click.Context, status_board_instance: str) -> Non
2801
2800
  @click.argument("file_path")
2802
2801
  @click.pass_context
2803
2802
  def alerts(ctx: click.Context, file_path: str) -> None:
2804
- BIG_NUMBER = 10
2803
+ big_number = 10
2805
2804
 
2806
2805
  def sort_by_threshold(item: dict[str, str]) -> int:
2807
2806
  threshold = item["threshold"]
2808
2807
  if not threshold:
2809
- return BIG_NUMBER * 60 * 24
2808
+ return big_number * 60 * 24
2810
2809
  value = int(threshold[:-1])
2811
2810
  unit = threshold[-1]
2812
2811
  match unit:
@@ -2817,7 +2816,7 @@ def alerts(ctx: click.Context, file_path: str) -> None:
2817
2816
  case "d":
2818
2817
  return value * 60 * 24
2819
2818
  case _:
2820
- return BIG_NUMBER * 60 * 24
2819
+ return big_number * 60 * 24
2821
2820
 
2822
2821
  def sort_by_severity(item: dict[str, str]) -> int:
2823
2822
  match item["severity"].lower():
@@ -2828,7 +2827,7 @@ def alerts(ctx: click.Context, file_path: str) -> None:
2828
2827
  case "info":
2829
2828
  return 2
2830
2829
  case _:
2831
- return BIG_NUMBER
2830
+ return big_number
2832
2831
 
2833
2832
  with open(file_path, encoding="locale") as f:
2834
2833
  content = json.loads(f.read())
@@ -14,11 +14,11 @@ from reconcile.utils.secret_reader import create_secret_reader
14
14
  from reconcile.utils.state import init_state
15
15
 
16
16
 
17
- class SaasPromotionStateException(Exception):
17
+ class SaasPromotionStateError(Exception):
18
18
  pass
19
19
 
20
20
 
21
- class SaasPromotionStateMissingException(Exception):
21
+ class SaasPromotionStateMissingError(Exception):
22
22
  pass
23
23
 
24
24
 
@@ -72,12 +72,12 @@ class SaasPromotionState:
72
72
  )
73
73
 
74
74
  if not current_data:
75
- raise SaasPromotionStateMissingException(
75
+ raise SaasPromotionStateMissingError(
76
76
  f"No promotion state in S3 for given {publisher_uid=} {sha=} {channel=}"
77
77
  )
78
78
 
79
79
  if current_data.success:
80
- raise SaasPromotionStateException(
80
+ raise SaasPromotionStateError(
81
81
  f"The current promotion state is already marked successful for given {publisher_uid=} {sha=} {channel=}",
82
82
  current_data,
83
83
  )
@@ -57,17 +57,17 @@ def print_test_diffs(diffs: list[TemplateDiff]) -> None:
57
57
  def main(templates: tuple[str]) -> None:
58
58
  for template_path in templates:
59
59
  okay = True
60
- templateRaw = load_clean_yaml(template_path)
60
+ template_raw = load_clean_yaml(template_path)
61
61
 
62
62
  tests = []
63
- for testRaw in templateRaw["templateTest"]:
64
- test_yaml = load_clean_yaml(testRaw["$ref"])
63
+ for test_raw in template_raw["templateTest"]:
64
+ test_yaml = load_clean_yaml(test_raw["$ref"])
65
65
  variables = json.dumps(test_yaml["variables"])
66
66
  test_yaml["variables"] = variables
67
67
  tests.append(test_yaml)
68
68
 
69
- templateRaw["templateTest"] = tests
70
- template: TemplateV1 = TemplateV1(**data_default_none(TemplateV1, templateRaw))
69
+ template_raw["templateTest"] = tests
70
+ template: TemplateV1 = TemplateV1(**data_default_none(TemplateV1, template_raw))
71
71
 
72
72
  # templates_to_validate = {}
73
73
  for test in template.template_test: