qontract-reconcile 0.10.1rc975__py3-none-any.whl → 0.10.1rc977__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 (110) hide show
  1. {qontract_reconcile-0.10.1rc975.dist-info → qontract_reconcile-0.10.1rc977.dist-info}/METADATA +1 -1
  2. {qontract_reconcile-0.10.1rc975.dist-info → qontract_reconcile-0.10.1rc977.dist-info}/RECORD +110 -110
  3. reconcile/aus/healthchecks.py +1 -1
  4. reconcile/aws_account_manager/integration.py +23 -21
  5. reconcile/aws_account_manager/reconciler.py +1 -1
  6. reconcile/aws_saml_idp/integration.py +5 -5
  7. reconcile/aws_saml_roles/integration.py +5 -5
  8. reconcile/aws_version_sync/utils.py +3 -3
  9. reconcile/cna/state.py +2 -2
  10. reconcile/database_access_manager.py +2 -5
  11. reconcile/external_resources/manager.py +3 -3
  12. reconcile/external_resources/model.py +1 -1
  13. reconcile/external_resources/secrets_sync.py +2 -2
  14. reconcile/external_resources/state.py +1 -1
  15. reconcile/gcr_mirror.py +2 -6
  16. reconcile/jira_permissions_validator.py +4 -4
  17. reconcile/ldap_groups/integration.py +4 -7
  18. reconcile/ocm_internal_notifications/integration.py +2 -2
  19. reconcile/openshift_base.py +14 -14
  20. reconcile/openshift_cluster_bots.py +1 -1
  21. reconcile/openshift_clusterrolebindings.py +9 -10
  22. reconcile/openshift_namespace_labels.py +2 -2
  23. reconcile/openshift_namespaces.py +1 -1
  24. reconcile/openshift_resources_base.py +9 -9
  25. reconcile/openshift_rolebindings.py +8 -11
  26. reconcile/openshift_saas_deploy_trigger_base.py +8 -5
  27. reconcile/oum/base.py +1 -1
  28. reconcile/quay_mirror.py +3 -10
  29. reconcile/queries.py +1 -1
  30. reconcile/saas_auto_promotions_manager/merge_request_manager/mr_parser.py +2 -2
  31. reconcile/saas_auto_promotions_manager/merge_request_manager/renderer.py +1 -1
  32. reconcile/saas_auto_promotions_manager/utils/saas_files_inventory.py +0 -1
  33. reconcile/skupper_network/integration.py +3 -1
  34. reconcile/skupper_network/site_controller.py +8 -8
  35. reconcile/slack_usergroups.py +10 -10
  36. reconcile/status_board.py +1 -1
  37. reconcile/statuspage/status.py +1 -3
  38. reconcile/terraform_cloudflare_dns.py +2 -3
  39. reconcile/terraform_cloudflare_users.py +2 -3
  40. reconcile/terraform_repo.py +5 -3
  41. reconcile/terraform_resources.py +16 -16
  42. reconcile/terraform_tgw_attachments.py +6 -6
  43. reconcile/terraform_vpc_peerings.py +8 -8
  44. reconcile/terraform_vpc_resources/integration.py +1 -1
  45. reconcile/test/test_aws_cloudwatch_log_retention.py +2 -5
  46. reconcile/test/test_github_org.py +18 -16
  47. reconcile/test/test_github_repo_invites.py +10 -10
  48. reconcile/test/test_integrations_manager.py +11 -11
  49. reconcile/test/test_ocm_additional_routers.py +6 -6
  50. reconcile/test/test_ocm_clusters.py +1 -0
  51. reconcile/test/test_ocm_update_recommended_version.py +2 -2
  52. reconcile/test/test_openshift_serviceaccount_tokens.py +5 -5
  53. reconcile/test/test_openshift_tekton_resources.py +3 -3
  54. reconcile/test/test_saasherder.py +48 -48
  55. reconcile/test/test_sql_query.py +1 -1
  56. reconcile/test/test_terraform_cloudflare_resources.py +14 -14
  57. reconcile/test/test_terraform_cloudflare_users.py +4 -4
  58. reconcile/test/test_terraform_resources.py +32 -32
  59. reconcile/test/test_terraform_tgw_attachments.py +5 -5
  60. reconcile/typed_queries/saas_files.py +1 -1
  61. reconcile/unleash_feature_toggles/integration.py +2 -2
  62. reconcile/utils/aggregated_list.py +1 -1
  63. reconcile/utils/aws_api.py +1 -1
  64. reconcile/utils/aws_api_typed/iam.py +4 -2
  65. reconcile/utils/aws_api_typed/service_quotas.py +2 -2
  66. reconcile/utils/binary.py +1 -1
  67. reconcile/utils/clusterhealth/telemeter.py +5 -3
  68. reconcile/utils/config.py +4 -2
  69. reconcile/utils/expiration.py +1 -1
  70. reconcile/utils/external_resources.py +4 -7
  71. reconcile/utils/git.py +1 -3
  72. reconcile/utils/gitlab_api.py +1 -4
  73. reconcile/utils/glitchtip/client.py +7 -2
  74. reconcile/utils/gql.py +9 -8
  75. reconcile/utils/helm.py +1 -1
  76. reconcile/utils/imap_client.py +3 -1
  77. reconcile/utils/internal_groups/client.py +1 -1
  78. reconcile/utils/jinja2/utils.py +4 -4
  79. reconcile/utils/jobcontroller/models.py +2 -2
  80. reconcile/utils/jump_host.py +1 -1
  81. reconcile/utils/ldap_client.py +1 -1
  82. reconcile/utils/merge_request_manager/merge_request_manager.py +1 -4
  83. reconcile/utils/models.py +2 -5
  84. reconcile/utils/oc.py +18 -28
  85. reconcile/utils/ocm/ocm.py +3 -1
  86. reconcile/utils/ocm/products.py +2 -2
  87. reconcile/utils/ocm/search_filters.py +4 -11
  88. reconcile/utils/ocm_base_client.py +1 -4
  89. reconcile/utils/openshift_resource.py +12 -19
  90. reconcile/utils/quay_api.py +1 -3
  91. reconcile/utils/repo_owners.py +2 -8
  92. reconcile/utils/runtime/runner.py +1 -1
  93. reconcile/utils/saasherder/saasherder.py +4 -4
  94. reconcile/utils/secret_reader.py +2 -2
  95. reconcile/utils/slack_api.py +1 -1
  96. reconcile/utils/sqs_gateway.py +1 -1
  97. reconcile/utils/state.py +4 -4
  98. reconcile/utils/terraform/config_client.py +1 -1
  99. reconcile/utils/terraform_client.py +2 -2
  100. reconcile/utils/terrascript_aws_client.py +13 -23
  101. reconcile/utils/three_way_diff_strategy.py +3 -9
  102. reconcile/utils/unleash/client.py +2 -2
  103. reconcile/utils/vault.py +11 -14
  104. reconcile/utils/vcs.py +1 -1
  105. reconcile/vault_replication.py +1 -1
  106. tools/app_interface_reporter.py +2 -3
  107. tools/qontract_cli.py +1 -1
  108. {qontract_reconcile-0.10.1rc975.dist-info → qontract_reconcile-0.10.1rc977.dist-info}/WHEEL +0 -0
  109. {qontract_reconcile-0.10.1rc975.dist-info → qontract_reconcile-0.10.1rc977.dist-info}/entry_points.txt +0 -0
  110. {qontract_reconcile-0.10.1rc975.dist-info → qontract_reconcile-0.10.1rc977.dist-info}/top_level.txt +0 -0
@@ -1058,7 +1058,7 @@ class TerrascriptClient: # pylint: disable=too-many-public-methods
1058
1058
  except KeyError:
1059
1059
  msg = f"Key '{rec['key']}' was not found in the contents of secret '{rec['path']}'"
1060
1060
  logging.error(msg)
1061
- raise KeyError(msg)
1061
+ raise KeyError(msg) from None
1062
1062
  vault_values.append(value)
1063
1063
  record["records"] = vault_values
1064
1064
 
@@ -1918,10 +1918,7 @@ class TerrascriptClient: # pylint: disable=too-many-public-methods
1918
1918
  if name not in self.configs:
1919
1919
  return False
1920
1920
 
1921
- if self.configs[name]["supportedDeploymentRegions"] is not None:
1922
- return True
1923
-
1924
- return False
1921
+ return self.configs[name]["supportedDeploymentRegions"] is not None
1925
1922
 
1926
1923
  def _find_resource_spec(
1927
1924
  self, account: str, source: str, provider: str
@@ -1949,12 +1946,10 @@ class TerrascriptClient: # pylint: disable=too-many-public-methods
1949
1946
 
1950
1947
  @staticmethod
1951
1948
  def _db_needs_auth(config):
1952
- if (
1949
+ return bool(
1953
1950
  "replicate_source_db" not in config
1954
1951
  and config.get("replica_source", None) is None
1955
- ):
1956
- return True
1957
- return False
1952
+ )
1958
1953
 
1959
1954
  @staticmethod
1960
1955
  def validate_db_name(name):
@@ -2808,10 +2803,8 @@ class TerrascriptClient: # pylint: disable=too-many-public-methods
2808
2803
  )
2809
2804
 
2810
2805
  # iam policy for queue
2811
- policy_index = 0
2812
- for all_queues in all_queues_per_spec:
2806
+ for policy_index, all_queues in enumerate(all_queues_per_spec):
2813
2807
  policy_identifier = f"{identifier}-{policy_index}"
2814
- policy_index += 1
2815
2808
  if len(all_queues_per_spec) == 1:
2816
2809
  policy_identifier = identifier
2817
2810
  values = {}
@@ -2864,10 +2857,7 @@ class TerrascriptClient: # pylint: disable=too-many-public-methods
2864
2857
 
2865
2858
  values = {}
2866
2859
  fifo_topic = common_values.get("fifo_topic", False)
2867
- if fifo_topic:
2868
- topic_name = identifier + (".fifo")
2869
- else:
2870
- topic_name = identifier
2860
+ topic_name = identifier + ".fifo" if fifo_topic else identifier
2871
2861
 
2872
2862
  values["name"] = topic_name
2873
2863
  values["policy"] = policy
@@ -2878,7 +2868,7 @@ class TerrascriptClient: # pylint: disable=too-many-public-methods
2878
2868
  tf_resource = aws_sns_topic(identifier, **values)
2879
2869
  tf_resources.append(tf_resource)
2880
2870
 
2881
- if "subscriptions" in common_values.keys():
2871
+ if "subscriptions" in common_values:
2882
2872
  subscriptions = common_values.get("subscriptions")
2883
2873
  for index, sub in enumerate(subscriptions):
2884
2874
  sub_values = {}
@@ -3151,7 +3141,7 @@ class TerrascriptClient: # pylint: disable=too-many-public-methods
3151
3141
 
3152
3142
  values = common_values.get("distribution_config", {})
3153
3143
  # aws_s3_bucket_acl
3154
- if "logging_config" in values.keys():
3144
+ if "logging_config" in values:
3155
3145
  # we could set this at a global level with a standard name like "cloudfront"
3156
3146
  # but we need all aws accounts upgraded to aws provider >3.60 first
3157
3147
  tf_resources.append(
@@ -4242,7 +4232,7 @@ class TerrascriptClient: # pylint: disable=too-many-public-methods
4242
4232
  try:
4243
4233
  raw_values = gqlapi.get_resource(path)
4244
4234
  except gql.GqlGetResourceError as e:
4245
- raise FetchResourceError(str(e))
4235
+ raise FetchResourceError(str(e)) from e
4246
4236
  return raw_values
4247
4237
 
4248
4238
  def get_values(self, path: str) -> dict[str, Any]:
@@ -4252,7 +4242,7 @@ class TerrascriptClient: # pylint: disable=too-many-public-methods
4252
4242
  values.pop("$schema", None)
4253
4243
  except anymarkup.AnyMarkupError:
4254
4244
  e_msg = "Could not parse data. Skipping resource: {}"
4255
- raise FetchResourceError(e_msg.format(path))
4245
+ raise FetchResourceError(e_msg.format(path)) from None
4256
4246
  return values
4257
4247
 
4258
4248
  @staticmethod
@@ -4734,7 +4724,7 @@ class TerrascriptClient: # pylint: disable=too-many-public-methods
4734
4724
  )
4735
4725
  tf_resources.append(Output(output_name, value=output_value))
4736
4726
  # add master user creds to output and secretsmanager if internal_user_database_enabled
4737
- security_options = es_values.get("advanced_security_options", None)
4727
+ security_options = es_values.get("advanced_security_options")
4738
4728
  if security_options and security_options.get(
4739
4729
  "internal_user_database_enabled", False
4740
4730
  ):
@@ -4985,7 +4975,7 @@ class TerrascriptClient: # pylint: disable=too-many-public-methods
4985
4975
  def _get_alb_rule_condition_value(condition):
4986
4976
  condition_type = condition["type"]
4987
4977
  condition_type_key = SUPPORTED_ALB_LISTENER_RULE_CONDITION_TYPE_MAPPING.get(
4988
- condition_type, None
4978
+ condition_type
4989
4979
  )
4990
4980
  if condition_type_key is None:
4991
4981
  raise KeyError(f"unknown alb rule condition type {condition_type}")
@@ -5713,7 +5703,7 @@ class TerrascriptClient: # pylint: disable=too-many-public-methods
5713
5703
  except ClientError as details:
5714
5704
  raise StateInaccessibleException(
5715
5705
  f"Bucket {bucket_name} is not accessible - {str(details)}"
5716
- )
5706
+ ) from None
5717
5707
 
5718
5708
  # todo: probably remove 'RedHat' from the object/variable/filepath
5719
5709
  # names to keep the code RedHat-agnostic?
@@ -95,14 +95,11 @@ def is_empty_env_value(current: OR, desired: OR, patch: Mapping[str, Any]) -> bo
95
95
  :return: True if the change is not needed, False otherwise
96
96
  """
97
97
  pointer = patch["path"]
98
- if (
98
+ return bool(
99
99
  patch["op"] == "add"
100
100
  and not patch["value"]
101
101
  and re.match(EMPTY_ENV_VALUE, pointer)
102
- ):
103
- return True
104
-
105
- return False
102
+ )
106
103
 
107
104
 
108
105
  def is_valid_change(current: OR, desired: OR, patch: Mapping[str, Any]) -> bool:
@@ -116,10 +113,7 @@ def is_valid_change(current: OR, desired: OR, patch: Mapping[str, Any]) -> bool:
116
113
  return False
117
114
 
118
115
  # Other cases
119
- if is_empty_env_value(current, desired, patch):
120
- return False
121
-
122
- return True
116
+ return not is_empty_env_value(current, desired, patch)
123
117
 
124
118
 
125
119
  def three_way_diff_using_hash(c_item: OR, d_item: OR) -> bool:
@@ -43,7 +43,7 @@ class DisableClusterStrategy(ClusterStrategy):
43
43
  def apply(self, context: dict | None = None) -> bool:
44
44
  enable = True
45
45
 
46
- if context and "cluster_name" in context.keys():
46
+ if context and "cluster_name" in context:
47
47
  # if cluster in context is in clusters sent from server, disable
48
48
  enable = context["cluster_name"] not in self.parsed_provisioning
49
49
 
@@ -54,7 +54,7 @@ class EnableClusterStrategy(ClusterStrategy):
54
54
  def apply(self, context: dict | None = None) -> bool:
55
55
  enable = False
56
56
 
57
- if context and "cluster_name" in context.keys():
57
+ if context and "cluster_name" in context:
58
58
  # if cluster in context is in clusters sent from server, enable
59
59
  enable = context["cluster_name"] in self.parsed_provisioning
60
60
 
reconcile/utils/vault.py CHANGED
@@ -234,10 +234,10 @@ class _VaultClient:
234
234
  )
235
235
  except InvalidPath:
236
236
  msg = f"version '{version}' not found " f"for secret with path '{path}'."
237
- raise SecretVersionNotFound(msg)
237
+ raise SecretVersionNotFound(msg) from None
238
238
  except hvac.exceptions.Forbidden:
239
239
  msg = f"permission denied accessing secret '{path}'"
240
- raise SecretAccessForbidden(msg)
240
+ raise SecretAccessForbidden(msg) from None
241
241
  if secret is None or "data" not in secret or "data" not in secret["data"]:
242
242
  raise SecretNotFound(path)
243
243
 
@@ -250,7 +250,7 @@ class _VaultClient:
250
250
  secret = self._client.read(path)
251
251
  except hvac.exceptions.Forbidden:
252
252
  msg = f"permission denied accessing secret '{path}'"
253
- raise SecretAccessForbidden(msg)
253
+ raise SecretAccessForbidden(msg) from None
254
254
 
255
255
  if secret is None or "data" not in secret:
256
256
  raise SecretNotFound(path)
@@ -295,7 +295,7 @@ class _VaultClient:
295
295
  try:
296
296
  secret_field = data[field]
297
297
  except KeyError:
298
- raise SecretFieldNotFound(f"{path}/{field} ({version})")
298
+ raise SecretFieldNotFound(f"{path}/{field} ({version})") from None
299
299
  return secret_field
300
300
 
301
301
  def _read_v1(self, path, field):
@@ -303,7 +303,7 @@ class _VaultClient:
303
303
  try:
304
304
  secret_field = data[field]
305
305
  except KeyError:
306
- raise SecretFieldNotFound(f"{path}/{field}")
306
+ raise SecretFieldNotFound(f"{path}/{field}") from None
307
307
  return secret_field
308
308
 
309
309
  @retry()
@@ -355,14 +355,14 @@ class _VaultClient:
355
355
  self._read_all_v2.cache_clear()
356
356
  except hvac.exceptions.Forbidden:
357
357
  msg = f"permission denied accessing secret '{path}'"
358
- raise SecretAccessForbidden(msg)
358
+ raise SecretAccessForbidden(msg) from None
359
359
 
360
360
  def _write_v1(self, path, data):
361
361
  try:
362
362
  self._client.write(path, **data)
363
363
  except hvac.exceptions.Forbidden:
364
364
  msg = f"permission denied accessing secret '{path}'"
365
- raise SecretAccessForbidden(msg)
365
+ raise SecretAccessForbidden(msg) from None
366
366
 
367
367
  def _list_kv2(self, path: str) -> dict:
368
368
  try:
@@ -373,22 +373,19 @@ class _VaultClient:
373
373
  return response
374
374
  except hvac.exceptions.Forbidden:
375
375
  msg = f"permission denied accessing path '{path}'"
376
- raise PathAccessForbidden(msg)
376
+ raise PathAccessForbidden(msg) from None
377
377
 
378
378
  def _list(self, path: str) -> dict:
379
379
  try:
380
380
  return self._client.list(path)
381
381
  except hvac.exceptions.Forbidden:
382
382
  msg = f"permission denied accessing path '{path}'"
383
- raise PathAccessForbidden(msg)
383
+ raise PathAccessForbidden(msg) from None
384
384
 
385
385
  def list(self, path: str) -> list[str]:
386
386
  """Returns a list of secrets in a given path."""
387
387
  kv_version = self._get_mount_version_by_secret_path(path)
388
- if kv_version == 2:
389
- path_list = self._list_kv2(path)
390
- else:
391
- path_list = self._list(path)
388
+ path_list = self._list_kv2(path) if kv_version == 2 else self._list(path)
392
389
 
393
390
  if not path_list:
394
391
  # path list can be None if the path does not exist
@@ -420,7 +417,7 @@ class _VaultClient:
420
417
  self._client.delete(path)
421
418
  except hvac.exceptions.Forbidden:
422
419
  msg = f"permission denied accessing secret '{path}'"
423
- raise SecretAccessForbidden(msg)
420
+ raise SecretAccessForbidden(msg) from None
424
421
 
425
422
 
426
423
  class VaultClient:
reconcile/utils/vcs.py CHANGED
@@ -70,7 +70,7 @@ class VCS:
70
70
  self._allow_opening_mrs = allow_opening_mrs
71
71
  self._secret_reader = secret_reader
72
72
  self._gh_per_repo_url: dict[str, GithubRepositoryApi] = (
73
- {} if not github_api_per_repo_url else github_api_per_repo_url
73
+ github_api_per_repo_url if github_api_per_repo_url else {}
74
74
  )
75
75
  self._default_gh_token = (
76
76
  default_gh_token
@@ -121,7 +121,7 @@ def copy_vault_secret(
121
121
  except SecretAccessForbidden:
122
122
  # Raise exception if we can't read the secret from the source vault.
123
123
  # This is likely to be related to the approle permissions.
124
- raise SecretAccessForbidden("Cannot read secret from source vault")
124
+ raise SecretAccessForbidden("Cannot read secret from source vault") from None
125
125
  except SecretNotFound:
126
126
  # If the secret is present in vault, but there are no versions of it
127
127
  # we want to be aware of it, but not cause a failure of the complete
@@ -1,3 +1,4 @@
1
+ import contextlib
1
2
  import logging
2
3
  import os
3
4
  import textwrap
@@ -438,10 +439,8 @@ def main(
438
439
  if reports_path:
439
440
  report_file = os.path.join(reports_path, report["file_path"])
440
441
 
441
- try:
442
+ with contextlib.suppress(FileExistsError):
442
443
  os.makedirs(os.path.dirname(report_file))
443
- except FileExistsError:
444
- pass
445
444
 
446
445
  with open(report_file, "w", encoding="locale") as f:
447
446
  f.write(report["content"])
tools/qontract_cli.py CHANGED
@@ -2799,7 +2799,7 @@ def jenkins_jobs(ctx):
2799
2799
 
2800
2800
  for pj in project["jobs"]:
2801
2801
  for job in pj.values():
2802
- node = job["node"] if "node" in job else root_node
2802
+ node = job.get("node", root_node)
2803
2803
  if node in {"rhel8", "rhel8-app-interface"}:
2804
2804
  apps[app_name]["rhel8"] += 1
2805
2805
  totals["rhel8"] += 1