qontract-reconcile 0.10.1rc976__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.
- {qontract_reconcile-0.10.1rc976.dist-info → qontract_reconcile-0.10.1rc977.dist-info}/METADATA +1 -1
- {qontract_reconcile-0.10.1rc976.dist-info → qontract_reconcile-0.10.1rc977.dist-info}/RECORD +109 -109
- reconcile/aus/healthchecks.py +1 -1
- reconcile/aws_account_manager/integration.py +23 -21
- reconcile/aws_account_manager/reconciler.py +1 -1
- reconcile/aws_saml_idp/integration.py +5 -5
- reconcile/aws_saml_roles/integration.py +5 -5
- reconcile/aws_version_sync/utils.py +3 -3
- reconcile/cna/state.py +2 -2
- reconcile/database_access_manager.py +2 -5
- reconcile/external_resources/manager.py +3 -3
- reconcile/external_resources/model.py +1 -1
- reconcile/external_resources/secrets_sync.py +2 -2
- reconcile/external_resources/state.py +1 -1
- reconcile/gcr_mirror.py +2 -6
- reconcile/jira_permissions_validator.py +4 -4
- reconcile/ldap_groups/integration.py +4 -7
- reconcile/ocm_internal_notifications/integration.py +2 -2
- reconcile/openshift_base.py +14 -14
- reconcile/openshift_cluster_bots.py +1 -1
- reconcile/openshift_clusterrolebindings.py +9 -10
- reconcile/openshift_namespace_labels.py +2 -2
- reconcile/openshift_namespaces.py +1 -1
- reconcile/openshift_resources_base.py +9 -9
- reconcile/openshift_rolebindings.py +8 -11
- reconcile/openshift_saas_deploy_trigger_base.py +8 -5
- reconcile/oum/base.py +1 -1
- reconcile/quay_mirror.py +3 -10
- reconcile/queries.py +1 -1
- reconcile/saas_auto_promotions_manager/merge_request_manager/mr_parser.py +2 -2
- reconcile/saas_auto_promotions_manager/merge_request_manager/renderer.py +1 -1
- reconcile/saas_auto_promotions_manager/utils/saas_files_inventory.py +0 -1
- reconcile/skupper_network/integration.py +3 -1
- reconcile/skupper_network/site_controller.py +8 -8
- reconcile/slack_usergroups.py +10 -10
- reconcile/status_board.py +1 -1
- reconcile/statuspage/status.py +1 -3
- reconcile/terraform_cloudflare_dns.py +2 -3
- reconcile/terraform_cloudflare_users.py +2 -3
- reconcile/terraform_repo.py +5 -3
- reconcile/terraform_resources.py +16 -16
- reconcile/terraform_tgw_attachments.py +6 -6
- reconcile/terraform_vpc_peerings.py +8 -8
- reconcile/terraform_vpc_resources/integration.py +1 -1
- reconcile/test/test_aws_cloudwatch_log_retention.py +2 -5
- reconcile/test/test_github_org.py +18 -16
- reconcile/test/test_github_repo_invites.py +10 -10
- reconcile/test/test_integrations_manager.py +11 -11
- reconcile/test/test_ocm_additional_routers.py +6 -6
- reconcile/test/test_ocm_clusters.py +1 -0
- reconcile/test/test_ocm_update_recommended_version.py +2 -2
- reconcile/test/test_openshift_serviceaccount_tokens.py +5 -5
- reconcile/test/test_openshift_tekton_resources.py +3 -3
- reconcile/test/test_saasherder.py +48 -48
- reconcile/test/test_sql_query.py +1 -1
- reconcile/test/test_terraform_cloudflare_resources.py +14 -14
- reconcile/test/test_terraform_cloudflare_users.py +4 -4
- reconcile/test/test_terraform_resources.py +32 -32
- reconcile/test/test_terraform_tgw_attachments.py +5 -5
- reconcile/typed_queries/saas_files.py +1 -1
- reconcile/unleash_feature_toggles/integration.py +2 -2
- reconcile/utils/aggregated_list.py +1 -1
- reconcile/utils/aws_api.py +1 -1
- reconcile/utils/aws_api_typed/iam.py +4 -2
- reconcile/utils/aws_api_typed/service_quotas.py +2 -2
- reconcile/utils/binary.py +1 -1
- reconcile/utils/clusterhealth/telemeter.py +5 -3
- reconcile/utils/config.py +4 -2
- reconcile/utils/expiration.py +1 -1
- reconcile/utils/external_resources.py +4 -7
- reconcile/utils/git.py +1 -3
- reconcile/utils/gitlab_api.py +1 -4
- reconcile/utils/gql.py +9 -8
- reconcile/utils/helm.py +1 -1
- reconcile/utils/imap_client.py +3 -1
- reconcile/utils/internal_groups/client.py +1 -1
- reconcile/utils/jinja2/utils.py +4 -4
- reconcile/utils/jobcontroller/models.py +2 -2
- reconcile/utils/jump_host.py +1 -1
- reconcile/utils/ldap_client.py +1 -1
- reconcile/utils/merge_request_manager/merge_request_manager.py +1 -4
- reconcile/utils/models.py +2 -5
- reconcile/utils/oc.py +18 -28
- reconcile/utils/ocm/ocm.py +3 -1
- reconcile/utils/ocm/products.py +2 -2
- reconcile/utils/ocm/search_filters.py +4 -11
- reconcile/utils/ocm_base_client.py +1 -4
- reconcile/utils/openshift_resource.py +12 -19
- reconcile/utils/quay_api.py +1 -3
- reconcile/utils/repo_owners.py +2 -8
- reconcile/utils/runtime/runner.py +1 -1
- reconcile/utils/saasherder/saasherder.py +4 -4
- reconcile/utils/secret_reader.py +2 -2
- reconcile/utils/slack_api.py +1 -1
- reconcile/utils/sqs_gateway.py +1 -1
- reconcile/utils/state.py +4 -4
- reconcile/utils/terraform/config_client.py +1 -1
- reconcile/utils/terraform_client.py +2 -2
- reconcile/utils/terrascript_aws_client.py +13 -23
- reconcile/utils/three_way_diff_strategy.py +3 -9
- reconcile/utils/unleash/client.py +2 -2
- reconcile/utils/vault.py +11 -14
- reconcile/utils/vcs.py +1 -1
- reconcile/vault_replication.py +1 -1
- tools/app_interface_reporter.py +2 -3
- tools/qontract_cli.py +1 -1
- {qontract_reconcile-0.10.1rc976.dist-info → qontract_reconcile-0.10.1rc977.dist-info}/WHEEL +0 -0
- {qontract_reconcile-0.10.1rc976.dist-info → qontract_reconcile-0.10.1rc977.dist-info}/entry_points.txt +0 -0
- {qontract_reconcile-0.10.1rc976.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
|
-
|
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
|
-
|
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
|
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
|
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
|
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"
|
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
|
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
|
-
|
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
|
-
|
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
|
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
|
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
|
-
|
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
|
reconcile/vault_replication.py
CHANGED
@@ -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
|
tools/app_interface_reporter.py
CHANGED
@@ -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
|
-
|
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
|
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
|
File without changes
|
File without changes
|
{qontract_reconcile-0.10.1rc976.dist-info → qontract_reconcile-0.10.1rc977.dist-info}/top_level.txt
RENAMED
File without changes
|