qontract-reconcile 0.10.2.dev14__py3-none-any.whl → 0.10.2.dev15__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.2.dev14.dist-info → qontract_reconcile-0.10.2.dev15.dist-info}/METADATA +1 -1
- {qontract_reconcile-0.10.2.dev14.dist-info → qontract_reconcile-0.10.2.dev15.dist-info}/RECORD +133 -133
- reconcile/acs_rbac.py +2 -4
- reconcile/aus/base.py +13 -13
- reconcile/aws_ami_share.py +1 -2
- reconcile/aws_cloudwatch_log_retention/integration.py +1 -1
- reconcile/aws_saml_idp/integration.py +1 -1
- reconcile/aws_saml_roles/integration.py +1 -1
- reconcile/aws_version_sync/integration.py +3 -3
- reconcile/change_owners/change_owners.py +8 -5
- reconcile/change_owners/change_types.py +18 -18
- reconcile/change_owners/changes.py +8 -9
- reconcile/change_owners/decision.py +12 -15
- reconcile/change_owners/self_service_roles.py +6 -4
- reconcile/change_owners/tester.py +8 -10
- reconcile/cli.py +9 -11
- reconcile/closedbox_endpoint_monitoring_base.py +1 -1
- reconcile/cna/integration.py +2 -2
- reconcile/dashdotdb_base.py +2 -2
- reconcile/dashdotdb_cso.py +1 -1
- reconcile/dashdotdb_dora.py +6 -4
- reconcile/dashdotdb_slo.py +1 -1
- reconcile/database_access_manager.py +15 -19
- reconcile/email_sender.py +4 -8
- reconcile/external_resources/secrets_sync.py +2 -2
- reconcile/external_resources/state.py +17 -17
- reconcile/gabi_authorized_users.py +3 -3
- reconcile/gcr_mirror.py +2 -2
- reconcile/github_org.py +9 -13
- reconcile/gitlab_housekeeping.py +1 -1
- reconcile/gitlab_owners.py +10 -12
- reconcile/gitlab_permissions.py +5 -4
- reconcile/glitchtip/integration.py +14 -14
- reconcile/glitchtip_project_alerts/integration.py +3 -4
- reconcile/integrations_manager.py +1 -2
- reconcile/jenkins_job_builds_cleaner.py +7 -5
- reconcile/jenkins_roles.py +10 -6
- reconcile/jenkins_worker_fleets.py +5 -4
- reconcile/jira_permissions_validator.py +2 -6
- reconcile/ldap_groups/integration.py +3 -2
- reconcile/ocm_groups.py +5 -5
- reconcile/ocm_update_recommended_version.py +2 -2
- reconcile/openshift_base.py +15 -20
- reconcile/openshift_groups.py +9 -8
- reconcile/openshift_namespace_labels.py +3 -4
- reconcile/openshift_namespaces.py +1 -1
- reconcile/openshift_network_policies.py +1 -1
- reconcile/openshift_resources_base.py +4 -4
- reconcile/openshift_serviceaccount_tokens.py +1 -1
- reconcile/openshift_tekton_resources.py +1 -2
- reconcile/openshift_users.py +5 -4
- reconcile/prometheus_rules_tester/integration.py +8 -8
- reconcile/quay_mirror.py +3 -4
- reconcile/quay_mirror_org.py +1 -1
- reconcile/rhidp/ocm_oidc_idp/base.py +10 -15
- reconcile/run_integration.py +7 -7
- reconcile/saas_auto_promotions_manager/publisher.py +1 -1
- reconcile/saas_auto_promotions_manager/utils/saas_files_inventory.py +3 -9
- reconcile/service_dependencies.py +2 -7
- reconcile/skupper_network/reconciler.py +5 -5
- reconcile/skupper_network/site_controller.py +3 -3
- reconcile/sql_query.py +5 -5
- reconcile/status_board.py +24 -24
- reconcile/terraform_cloudflare_users.py +2 -2
- reconcile/terraform_repo.py +6 -6
- reconcile/terraform_users.py +8 -5
- reconcile/terraform_vpc_peerings.py +1 -1
- reconcile/terraform_vpc_resources/integration.py +1 -1
- reconcile/typed_queries/app_interface_deadmanssnitch_settings.py +1 -1
- reconcile/typed_queries/app_quay_repos_escalation_policies.py +1 -1
- reconcile/typed_queries/aws_vpc_requests.py +1 -1
- reconcile/typed_queries/aws_vpcs.py +1 -1
- reconcile/typed_queries/clusters.py +1 -1
- reconcile/typed_queries/clusters_minimal.py +1 -1
- reconcile/typed_queries/clusters_with_dms.py +1 -1
- reconcile/typed_queries/dynatrace_environments.py +1 -1
- reconcile/typed_queries/dynatrace_token_provider_token_specs.py +1 -1
- reconcile/typed_queries/reserved_networks.py +1 -1
- reconcile/typed_queries/saas_files.py +1 -1
- reconcile/typed_queries/slo_documents.py +1 -1
- reconcile/typed_queries/status_board.py +1 -2
- reconcile/utils/amtool.py +2 -2
- reconcile/utils/aws_api.py +10 -10
- reconcile/utils/aws_helper.py +1 -1
- reconcile/utils/binary.py +1 -2
- reconcile/utils/differ.py +4 -7
- reconcile/utils/dnsutils.py +4 -12
- reconcile/utils/external_resources.py +1 -2
- reconcile/utils/gitlab_api.py +2 -4
- reconcile/utils/glitchtip/models.py +1 -1
- reconcile/utils/helm.py +1 -1
- reconcile/utils/instrumented_wrappers.py +2 -2
- reconcile/utils/jjb_client.py +1 -1
- reconcile/utils/jump_host.py +1 -1
- reconcile/utils/metrics.py +6 -11
- reconcile/utils/mr/aws_access.py +1 -1
- reconcile/utils/mr/base.py +2 -4
- reconcile/utils/mr/notificator.py +1 -1
- reconcile/utils/mr/ocm_upgrade_scheduler_org_updates.py +1 -1
- reconcile/utils/oc.py +17 -31
- reconcile/utils/oc_map.py +1 -1
- reconcile/utils/ocm/base.py +4 -2
- reconcile/utils/ocm/search_filters.py +4 -3
- reconcile/utils/ocm/status_board.py +2 -2
- reconcile/utils/ocm/upgrades.py +4 -7
- reconcile/utils/ocm_base_client.py +1 -1
- reconcile/utils/openshift_resource.py +1 -1
- reconcile/utils/promtool.py +1 -1
- reconcile/utils/quay_api.py +1 -3
- reconcile/utils/raw_github_api.py +3 -10
- reconcile/utils/repo_owners.py +5 -5
- reconcile/utils/rest_api_base.py +1 -2
- reconcile/utils/rosa/rosa_cli.py +3 -3
- reconcile/utils/saasherder/saasherder.py +9 -15
- reconcile/utils/secret_reader.py +2 -2
- reconcile/utils/sharding.py +2 -2
- reconcile/utils/state.py +5 -5
- reconcile/utils/terraform_client.py +2 -2
- reconcile/utils/terrascript/cloudflare_resources.py +4 -6
- reconcile/utils/terrascript_aws_client.py +16 -28
- reconcile/utils/vault.py +2 -2
- reconcile/utils/vcs.py +8 -16
- reconcile/vault_replication.py +1 -8
- tools/app_interface_reporter.py +1 -1
- tools/cli_commands/container_images_report.py +1 -1
- tools/cli_commands/cost_report/view.py +4 -2
- tools/cli_commands/gpg_encrypt.py +1 -5
- tools/qontract_cli.py +14 -13
- tools/saas_metrics_exporter/commit_distance/channel.py +1 -1
- tools/saas_promotion_state/saas_promotion_state.py +1 -1
- tools/sd_app_sre_alert_report.py +3 -3
- {qontract_reconcile-0.10.2.dev14.dist-info → qontract_reconcile-0.10.2.dev15.dist-info}/WHEEL +0 -0
- {qontract_reconcile-0.10.2.dev14.dist-info → qontract_reconcile-0.10.2.dev15.dist-info}/entry_points.txt +0 -0
@@ -192,7 +192,7 @@ class LabelInventory:
|
|
192
192
|
changed[k] = v
|
193
193
|
|
194
194
|
# remove old labels
|
195
|
-
for k
|
195
|
+
for k in current:
|
196
196
|
if k in managed and k not in desired:
|
197
197
|
changed[k] = None
|
198
198
|
|
@@ -261,7 +261,7 @@ def get_desired(
|
|
261
261
|
# A dedicated integration or PR check will be done to ensure this
|
262
262
|
# case does not occur (anymore)
|
263
263
|
_LOG.debug(
|
264
|
-
f"Found several namespace definitions for
|
264
|
+
f"Found several namespace definitions for {cluster}/{ns_name}. Ignoring"
|
265
265
|
)
|
266
266
|
inventory.delete(cluster=cluster, namespace=ns_name)
|
267
267
|
|
@@ -310,8 +310,7 @@ def lookup_namespaces(cluster: str, oc_map: OCMap) -> tuple[str, dict[str, Any]
|
|
310
310
|
_LOG.error(msg)
|
311
311
|
except ApiException as e:
|
312
312
|
_LOG.error(
|
313
|
-
f"Cluster {cluster} skipped: "
|
314
|
-
f"APIException [{e.status}:{e.reason}] {e.body}"
|
313
|
+
f"Cluster {cluster} skipped: APIException [{e.status}:{e.reason}] {e.body}"
|
315
314
|
)
|
316
315
|
|
317
316
|
return cluster, None
|
@@ -131,7 +131,7 @@ def check_results(
|
|
131
131
|
if isinstance(e, Exception):
|
132
132
|
err = True
|
133
133
|
msg = (
|
134
|
-
f
|
134
|
+
f"cluster: {s['cluster']}, namespace: {s['namespace']}, "
|
135
135
|
f"exception: {e!s}"
|
136
136
|
)
|
137
137
|
logging.error(msg)
|
@@ -120,7 +120,7 @@ def run(dry_run, thread_pool_size=10, internal=None, use_jump_host=True, defer=N
|
|
120
120
|
if ob.is_namespace_deleted(namespace_info):
|
121
121
|
continue
|
122
122
|
|
123
|
-
shard_key = f"{namespace_info['cluster']['name']}/
|
123
|
+
shard_key = f"{namespace_info['cluster']['name']}/{namespace_info['name']}"
|
124
124
|
|
125
125
|
if not is_in_shard(shard_key):
|
126
126
|
continue
|
@@ -864,10 +864,10 @@ def get_namespaces(
|
|
864
864
|
)
|
865
865
|
)
|
866
866
|
]
|
867
|
-
|
867
|
+
namespaces_ = filter_namespaces_by_cluster_and_namespace(
|
868
868
|
namespaces, cluster_names, exclude_clusters, namespace_name
|
869
869
|
)
|
870
|
-
return canonicalize_namespaces(
|
870
|
+
return canonicalize_namespaces(namespaces_, providers, resource_schema_filter)
|
871
871
|
|
872
872
|
|
873
873
|
@defer
|
@@ -1029,10 +1029,10 @@ class CheckClusterScopedResourceDuplicates:
|
|
1029
1029
|
duplicates: list[tuple[str, str, str, list[str]]] = []
|
1030
1030
|
|
1031
1031
|
for cluster, cluster_resources in cluster_cs_resources.items():
|
1032
|
-
|
1032
|
+
kind_name: dict[str, dict[str, list[str]]] = {}
|
1033
1033
|
for ns, resources in cluster_resources.items():
|
1034
1034
|
for kind, names in resources.items():
|
1035
|
-
k_ref =
|
1035
|
+
k_ref = kind_name.setdefault(kind, {})
|
1036
1036
|
for name in names:
|
1037
1037
|
n_ref = k_ref.setdefault(name, [])
|
1038
1038
|
n_ref.append(ns)
|
@@ -108,8 +108,7 @@ def fetch_tkn_providers(saas_file_name: str | None) -> dict[str, Any]:
|
|
108
108
|
|
109
109
|
if duplicates:
|
110
110
|
raise OpenshiftTektonResourcesBadConfigError(
|
111
|
-
"There are duplicates in tekton providers names: "
|
112
|
-
f'{", ".join(duplicates)}'
|
111
|
+
f"There are duplicates in tekton providers names: {', '.join(duplicates)}"
|
113
112
|
)
|
114
113
|
|
115
114
|
# Only get the providers that are used by the saas files
|
reconcile/openshift_users.py
CHANGED
@@ -47,10 +47,11 @@ def get_cluster_users(
|
|
47
47
|
|
48
48
|
# backwarts compatibiltiy for clusters w/o auth
|
49
49
|
identity_prefixes = ["github"]
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
50
|
+
identity_prefixes.extend(
|
51
|
+
auth.name
|
52
|
+
for auth in cluster_info.auth
|
53
|
+
if isinstance(auth, ClusterAuthOIDCV1 | ClusterAuthRHIDPV1)
|
54
|
+
)
|
54
55
|
|
55
56
|
for u in oc.get_users():
|
56
57
|
if u["metadata"].get("labels", {}).get("admin", ""):
|
@@ -124,22 +124,22 @@ def get_rules_and_tests(
|
|
124
124
|
"""Iterates through all namespaces and returns a list of tests to run"""
|
125
125
|
namespace_with_prom_rules, _ = orb.get_namespaces(
|
126
126
|
PROVIDERS,
|
127
|
-
cluster_names=cluster_names
|
127
|
+
cluster_names=cluster_names or [],
|
128
128
|
namespace_name=NAMESPACE_NAME,
|
129
129
|
)
|
130
130
|
|
131
|
-
iterable = []
|
131
|
+
iterable: list[RuleToFetch] = []
|
132
132
|
for namespace in namespace_with_prom_rules:
|
133
133
|
prom_rules = [
|
134
134
|
r for r in namespace["openshiftResources"] if r["provider"] in PROVIDERS
|
135
135
|
]
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
resource=resource,
|
141
|
-
)
|
136
|
+
iterable.extend(
|
137
|
+
RuleToFetch(
|
138
|
+
namespace=namespace,
|
139
|
+
resource=resource,
|
142
140
|
)
|
141
|
+
for resource in prom_rules
|
142
|
+
)
|
143
143
|
|
144
144
|
return threaded.run(
|
145
145
|
func=fetch_rule_and_tests,
|
reconcile/quay_mirror.py
CHANGED
@@ -190,8 +190,7 @@ class QuayMirror:
|
|
190
190
|
)
|
191
191
|
if mirror_image.registry == "docker.io" and item["public"]:
|
192
192
|
_LOG.error(
|
193
|
-
"Image %s can't be mirrored to a public "
|
194
|
-
"quay repository.",
|
193
|
+
"Image %s can't be mirrored to a public quay repository.",
|
195
194
|
mirror_image,
|
196
195
|
)
|
197
196
|
sys.exit(ExitCodes.ERROR)
|
@@ -250,7 +249,7 @@ class QuayMirror:
|
|
250
249
|
for item in data:
|
251
250
|
push_creds = self.push_creds[org_key].split(":")
|
252
251
|
image = Image(
|
253
|
-
f
|
252
|
+
f"{item['server_url']}/{org}/{item['name']}",
|
254
253
|
username=push_creds[0],
|
255
254
|
password=push_creds[1],
|
256
255
|
response_cache=self.response_cache,
|
@@ -409,7 +408,7 @@ class QuayMirror:
|
|
409
408
|
org = org_data["name"]
|
410
409
|
instance = org_data["instance"]["name"]
|
411
410
|
org_key = OrgKey(instance, org)
|
412
|
-
creds[org_key] = f
|
411
|
+
creds[org_key] = f"{raw_data['user']}:{raw_data['token']}"
|
413
412
|
|
414
413
|
return creds
|
415
414
|
|
reconcile/quay_mirror_org.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
import logging
|
2
|
+
import operator
|
2
3
|
from collections.abc import (
|
3
4
|
Iterable,
|
4
5
|
Sequence,
|
@@ -38,10 +39,10 @@ class IDPState(BaseModel):
|
|
38
39
|
cluster: Cluster
|
39
40
|
idp: OCMOIdentityProvider | OCMOIdentityProviderOidc | OCMOIdentityProviderGithub
|
40
41
|
|
41
|
-
def __eq__(self,
|
42
|
-
if not isinstance(
|
42
|
+
def __eq__(self, value: object) -> bool:
|
43
|
+
if not isinstance(value, IDPState):
|
43
44
|
raise NotImplementedError("Cannot compare to non IDPState objects.")
|
44
|
-
return self.idp ==
|
45
|
+
return self.idp == value.idp
|
45
46
|
|
46
47
|
|
47
48
|
def run(
|
@@ -91,19 +92,13 @@ def fetch_current_state(
|
|
91
92
|
ocm_api: OCMBaseClient, clusters: Iterable[Cluster]
|
92
93
|
) -> list[IDPState]:
|
93
94
|
"""Fetch all current configured OIDC identity providers."""
|
94
|
-
|
95
|
-
|
95
|
+
return [
|
96
|
+
IDPState(cluster=cluster, idp=idp)
|
97
|
+
for cluster in clusters
|
96
98
|
for idp in get_identity_providers(
|
97
99
|
ocm_api=ocm_api, ocm_cluster=cluster.ocm_cluster
|
98
|
-
)
|
99
|
-
|
100
|
-
IDPState(
|
101
|
-
cluster=cluster,
|
102
|
-
idp=idp,
|
103
|
-
),
|
104
|
-
)
|
105
|
-
|
106
|
-
return current_state
|
100
|
+
)
|
101
|
+
]
|
107
102
|
|
108
103
|
|
109
104
|
def fetch_desired_state(
|
@@ -175,7 +170,7 @@ def act(
|
|
175
170
|
idp_state.idp.type,
|
176
171
|
idp_state.idp.name,
|
177
172
|
)),
|
178
|
-
equal=
|
173
|
+
equal=operator.eq,
|
179
174
|
)
|
180
175
|
|
181
176
|
for idp_state in diff_result.delete.values():
|
reconcile/run_integration.py
CHANGED
@@ -28,8 +28,8 @@ from reconcile.utils.runtime.environment import (
|
|
28
28
|
log_fmt,
|
29
29
|
)
|
30
30
|
|
31
|
-
SHARDS = int(os.environ.get("SHARDS", 1))
|
32
|
-
SHARD_ID = int(os.environ.get("SHARD_ID", 0))
|
31
|
+
SHARDS = int(os.environ.get("SHARDS", "1"))
|
32
|
+
SHARD_ID = int(os.environ.get("SHARD_ID", "0"))
|
33
33
|
SHARD_ID_LABEL = os.environ.get("SHARD_KEY", f"{SHARD_ID}-{SHARDS}")
|
34
34
|
PREFIX_LOG_LEVEL = os.environ.get("PREFIX_LOG_LEVEL", "false")
|
35
35
|
|
@@ -44,14 +44,14 @@ DRY_RUN = (
|
|
44
44
|
)
|
45
45
|
INTEGRATION_EXTRA_ARGS = os.environ.get("INTEGRATION_EXTRA_ARGS")
|
46
46
|
CONFIG = os.environ.get("CONFIG", "/config/config.toml")
|
47
|
-
PROMETHEUS_PORT = os.environ.get("PROMETHEUS_PORT", 9090)
|
47
|
+
PROMETHEUS_PORT = int(os.environ.get("PROMETHEUS_PORT", "9090"))
|
48
48
|
|
49
49
|
LOG_FILE = os.environ.get("LOG_FILE")
|
50
50
|
LOG_LEVEL = os.environ.get("LOG_LEVEL", "INFO")
|
51
|
-
SLEEP_DURATION_SECS = os.environ.get("SLEEP_DURATION_SECS", 600)
|
52
|
-
SLEEP_ON_ERROR = os.environ.get("SLEEP_ON_ERROR", 10)
|
51
|
+
SLEEP_DURATION_SECS = int(os.environ.get("SLEEP_DURATION_SECS", "600"))
|
52
|
+
SLEEP_ON_ERROR = int(os.environ.get("SLEEP_ON_ERROR", "10"))
|
53
53
|
|
54
|
-
PUSHGATEWAY_ENABLED = os.environ.get("PUSHGATEWAY_ENABLED"
|
54
|
+
PUSHGATEWAY_ENABLED = bool(os.environ.get("PUSHGATEWAY_ENABLED"))
|
55
55
|
|
56
56
|
LOG = logging.getLogger(__name__)
|
57
57
|
|
@@ -88,7 +88,7 @@ def _parse_dry_run_flag(dry_run: str | None) -> str | None:
|
|
88
88
|
)
|
89
89
|
logging.error(msg)
|
90
90
|
raise ValueError(msg)
|
91
|
-
return dry_run
|
91
|
+
return dry_run or None
|
92
92
|
|
93
93
|
|
94
94
|
def build_entry_point_args(
|
@@ -54,7 +54,7 @@ class Publisher:
|
|
54
54
|
self.app_name = app_name
|
55
55
|
self.namespace_name = namespace_name
|
56
56
|
self.resource_template_name = resource_template_name
|
57
|
-
self.target_name = target_name
|
57
|
+
self.target_name = target_name or "None"
|
58
58
|
self.cluster_name = cluster_name
|
59
59
|
self.redeploy_on_config_change = bool(redeploy_on_config_change)
|
60
60
|
self.has_subscriber = has_subscriber
|
@@ -92,21 +92,15 @@ class SaasFilesInventory:
|
|
92
92
|
blocked_versions.setdefault(code_component.url, set()).add(version)
|
93
93
|
for resource_template in saas_file.resource_templates:
|
94
94
|
for target in resource_template.targets:
|
95
|
-
file_path = target.path
|
95
|
+
file_path = target.path or saas_file.path
|
96
96
|
if target.disable or target.delete:
|
97
97
|
continue
|
98
98
|
if not target.promotion:
|
99
99
|
continue
|
100
100
|
if not target.promotion.auto:
|
101
101
|
continue
|
102
|
-
soak_days =
|
103
|
-
|
104
|
-
)
|
105
|
-
schedule = (
|
106
|
-
target.promotion.schedule
|
107
|
-
if target.promotion.schedule
|
108
|
-
else "* * * * *"
|
109
|
-
)
|
102
|
+
soak_days = target.promotion.soak_days or 0
|
103
|
+
schedule = target.promotion.schedule or "* * * * *"
|
110
104
|
subscriber = Subscriber(
|
111
105
|
uid=target.uid(
|
112
106
|
parent_saas_file_name=saas_file.name,
|
@@ -21,13 +21,8 @@ QONTRACT_INTEGRATION = "service-dependencies"
|
|
21
21
|
|
22
22
|
|
23
23
|
def get_dependency_names(dependency_map: Mapping[Any, Any], dep_type: str) -> list[str]:
|
24
|
-
|
25
|
-
for
|
26
|
-
if dm["type"] != dep_type:
|
27
|
-
continue
|
28
|
-
for service in dm["services"]:
|
29
|
-
dep_names.append(service["name"])
|
30
|
-
return dep_names
|
24
|
+
dependency_maps = (dm for dm in dependency_map if dm["type"] == dep_type)
|
25
|
+
return [service["name"] for service in dependency_maps]
|
31
26
|
|
32
27
|
|
33
28
|
def get_desired_dependency_names(
|
@@ -31,7 +31,7 @@ def delete_skupper_site(
|
|
31
31
|
for kind in integration_managed_kinds:
|
32
32
|
# delete everything labeled by us
|
33
33
|
to_delete.update({
|
34
|
-
f
|
34
|
+
f"{item['kind']}-{item['metadata']['name']}": item
|
35
35
|
for item in oc.get_items(
|
36
36
|
kind=kind,
|
37
37
|
namespace=site.namespace.name,
|
@@ -40,7 +40,7 @@ def delete_skupper_site(
|
|
40
40
|
})
|
41
41
|
# delete everything else that starts with 'skupper-'
|
42
42
|
to_delete.update({
|
43
|
-
f
|
43
|
+
f"{item['kind']}-{item['metadata']['name']}": item
|
44
44
|
for item in oc.get_items(kind=kind, namespace=site.namespace.name)
|
45
45
|
if item["metadata"]["name"].startswith("skupper-")
|
46
46
|
})
|
@@ -84,12 +84,12 @@ def _create_token(
|
|
84
84
|
logging.info(f"{connected_site}: Creating new connection token for {site}")
|
85
85
|
sc = get_site_controller(connected_site)
|
86
86
|
if not dry_run:
|
87
|
-
|
88
|
-
|
87
|
+
labels_ = copy.deepcopy(site.token_labels)
|
88
|
+
labels_.update(labels)
|
89
89
|
oc.apply(
|
90
90
|
connected_site.namespace.name,
|
91
91
|
resource=OR(
|
92
|
-
body=sc.site_token(connected_site.unique_token_name(site),
|
92
|
+
body=sc.site_token(connected_site.unique_token_name(site), labels_),
|
93
93
|
integration=integration,
|
94
94
|
integration_version=integration_version,
|
95
95
|
),
|
@@ -28,14 +28,14 @@ class SiteController:
|
|
28
28
|
|
29
29
|
def site_token(self, name: str, labels: MutableMapping[str, str]) -> dict[str, Any]:
|
30
30
|
"""Skupper site token secret."""
|
31
|
-
|
32
|
-
|
31
|
+
labels_ = copy.deepcopy(labels)
|
32
|
+
labels_["skupper.io/type"] = "connection-token-request"
|
33
33
|
return {
|
34
34
|
"apiVersion": "v1",
|
35
35
|
"kind": "Secret",
|
36
36
|
"metadata": {
|
37
37
|
"name": name,
|
38
|
-
"labels":
|
38
|
+
"labels": labels_,
|
39
39
|
},
|
40
40
|
}
|
41
41
|
|
reconcile/sql_query.py
CHANGED
@@ -277,17 +277,17 @@ def collect_queries(
|
|
277
277
|
tf_resource_info = get_tf_resource_info(terrascript, namespace, identifier)
|
278
278
|
if tf_resource_info is None:
|
279
279
|
logging.error(
|
280
|
-
f
|
280
|
+
f"[sql-query:{name} (path: {sql_query['path']})] Could not find rds identifier {identifier} in namespace {namespace['name']}. "
|
281
281
|
"If this is a removed read only instance, consider updating the identifier to the source replica or remove this file."
|
282
282
|
)
|
283
283
|
sys.exit(ExitCodes.ERROR)
|
284
284
|
|
285
|
-
|
285
|
+
queries_ = []
|
286
286
|
if sql_query["query"] is not None:
|
287
|
-
|
287
|
+
queries_.append(sql_query["query"])
|
288
288
|
|
289
289
|
if sql_query["queries"] is not None:
|
290
|
-
|
290
|
+
queries_.extend(sql_query["queries"])
|
291
291
|
|
292
292
|
# building up the final query dictionary
|
293
293
|
item = {
|
@@ -296,7 +296,7 @@ def collect_queries(
|
|
296
296
|
"identifier": sql_query["identifier"],
|
297
297
|
"db_conn": db_conn,
|
298
298
|
"output": output,
|
299
|
-
"queries":
|
299
|
+
"queries": queries_,
|
300
300
|
**tf_resource_info,
|
301
301
|
}
|
302
302
|
|
reconcile/status_board.py
CHANGED
@@ -194,40 +194,40 @@ class StatusBoardExporterIntegration(QontractReconcileIntegration):
|
|
194
194
|
)
|
195
195
|
)
|
196
196
|
# new product, so it misses also the applications
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
status_board_object=create_app(app_name, product),
|
202
|
-
)
|
197
|
+
return_list.extend(
|
198
|
+
StatusBoardHandler(
|
199
|
+
action="create",
|
200
|
+
status_board_object=create_app(app_name, product),
|
203
201
|
)
|
202
|
+
for app_name in desired_product_apps[product_name]
|
203
|
+
)
|
204
204
|
|
205
205
|
# existing product, only add/remove applications
|
206
206
|
for product_name, apps in diff_result.change.items():
|
207
207
|
product = current_products[product_name]
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
status_board_object=create_app(app_name, product),
|
213
|
-
)
|
208
|
+
return_list.extend(
|
209
|
+
StatusBoardHandler(
|
210
|
+
action="create",
|
211
|
+
status_board_object=create_app(app_name, product),
|
214
212
|
)
|
213
|
+
for app_name in apps.desired - apps.current
|
214
|
+
)
|
215
215
|
to_delete = apps.current - apps.desired
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
216
|
+
return_list.extend(
|
217
|
+
StatusBoardHandler(
|
218
|
+
action="delete",
|
219
|
+
status_board_object=application,
|
220
|
+
)
|
221
|
+
for application in product.applications or []
|
222
|
+
if application.name in to_delete
|
223
|
+
)
|
224
224
|
|
225
225
|
# product is deleted entirely
|
226
226
|
for product_name in diff_result.delete:
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
227
|
+
return_list.extend(
|
228
|
+
StatusBoardHandler(action="delete", status_board_object=application)
|
229
|
+
for application in current_products[product_name].applications or []
|
230
|
+
)
|
231
231
|
return_list.append(
|
232
232
|
StatusBoardHandler(
|
233
233
|
action="delete", status_board_object=current_products[product_name]
|
@@ -331,8 +331,8 @@ def build_external_resource_spec_from_cloudflare_users(
|
|
331
331
|
"""
|
332
332
|
specs: list[ExternalResourceSpec] = []
|
333
333
|
|
334
|
-
for
|
335
|
-
for
|
334
|
+
for v in cloudflare_users.values():
|
335
|
+
for cf_user in v.values():
|
336
336
|
data_source_cloudflare_account_roles = {
|
337
337
|
"identifier": safe_resource_id(cf_user.account_name),
|
338
338
|
"account_id": "${var.account_id}",
|
reconcile/terraform_repo.py
CHANGED
@@ -382,12 +382,12 @@ class TerraformRepoIntegration(
|
|
382
382
|
|
383
383
|
# construct diff urls
|
384
384
|
diff_urls: list[str] = []
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
385
|
+
# gitlab specific syntax
|
386
|
+
diff_urls.extend(
|
387
|
+
f"{pair.current.repository}/compare/{pair.current.ref}...{pair.desired.ref}"
|
388
|
+
for pair in diff_result.change.values()
|
389
|
+
if pair.current.ref != pair.desired.ref
|
390
|
+
)
|
391
391
|
|
392
392
|
if len(diff_urls) > 0:
|
393
393
|
comment_body = "tf-repo diffs:\n" + "\n".join([
|
reconcile/terraform_users.py
CHANGED
@@ -95,12 +95,15 @@ def _filter_participating_aws_accounts(
|
|
95
95
|
accounts: list,
|
96
96
|
roles: list[dict[str, Any]],
|
97
97
|
) -> list:
|
98
|
-
participating_aws_account_names = set()
|
98
|
+
participating_aws_account_names: set[str] = set()
|
99
99
|
for role in roles:
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
100
|
+
participating_aws_account_names.update(
|
101
|
+
aws_group["account"]["name"] for aws_group in role["aws_groups"] or []
|
102
|
+
)
|
103
|
+
participating_aws_account_names.update(
|
104
|
+
user_policy["account"]["name"]
|
105
|
+
for user_policy in role["user_policies"] or []
|
106
|
+
)
|
104
107
|
return [a for a in accounts if a["name"] in participating_aws_account_names]
|
105
108
|
|
106
109
|
|
@@ -702,7 +702,7 @@ def run(
|
|
702
702
|
integration_version=QONTRACT_INTEGRATION_VERSION,
|
703
703
|
dry_run=dry_run,
|
704
704
|
cache_source=cache_source,
|
705
|
-
shard=account_name
|
705
|
+
shard=account_name or "",
|
706
706
|
ttl_seconds=extended_early_exit_cache_ttl_seconds,
|
707
707
|
logger=logging.getLogger(),
|
708
708
|
runner=runner,
|
@@ -196,7 +196,7 @@ class TerraformVpcResources(QontractReconcileIntegration[TerraformVpcResourcesPa
|
|
196
196
|
mr_manager._fetch_managed_open_merge_requests()
|
197
197
|
|
198
198
|
# Create a MR for each vpc request if the MR don't exist yet
|
199
|
-
for
|
199
|
+
for outputs in handled_output.values():
|
200
200
|
template = gql_api.get_template(
|
201
201
|
path="/templating/templates/terraform-vpc-resources/vpc.yml"
|
202
202
|
)["template"]
|
@@ -10,7 +10,7 @@ from reconcile.utils.gql import GqlApi
|
|
10
10
|
def get_deadmanssnitch_settings(
|
11
11
|
gql_api: GqlApi | None = None,
|
12
12
|
) -> DeadMansSnitchSettingsV1:
|
13
|
-
api = gql_api
|
13
|
+
api = gql_api or gql.get_api()
|
14
14
|
data = query(query_func=api.query)
|
15
15
|
if data.settings and data.settings[0].dead_mans_snitch_settings is not None:
|
16
16
|
return data.settings[0].dead_mans_snitch_settings
|
@@ -9,6 +9,6 @@ from reconcile.utils.gql import GqlApi
|
|
9
9
|
def get_apps_quay_repos_escalation_policies(
|
10
10
|
gql_api: GqlApi | None = None,
|
11
11
|
) -> list[AppV1]:
|
12
|
-
api = gql_api
|
12
|
+
api = gql_api or gql.get_api()
|
13
13
|
data = query(query_func=api.query)
|
14
14
|
return list(data.apps or [])
|
@@ -4,6 +4,6 @@ from reconcile.utils.gql import GqlApi
|
|
4
4
|
|
5
5
|
|
6
6
|
def get_aws_vpc_requests(gql_api: GqlApi | None = None) -> list[VPCRequest]:
|
7
|
-
api = gql_api
|
7
|
+
api = gql_api or gql.get_api()
|
8
8
|
data = query(query_func=api.query)
|
9
9
|
return list(data.vpc_requests or [])
|
@@ -11,6 +11,6 @@ def get_clusters_with_dms(
|
|
11
11
|
) -> list[ClusterV1]:
|
12
12
|
# get the clusters containing the filed enableDeadMansSnitch
|
13
13
|
variable = {"filter": {"enableDeadMansSnitch": {"ne": None}}}
|
14
|
-
api = gql_api
|
14
|
+
api = gql_api or gql.get_api()
|
15
15
|
data = query(query_func=api.query, variables=variable)
|
16
16
|
return data.clusters or []
|
@@ -9,6 +9,6 @@ from reconcile.utils.gql import GqlApi
|
|
9
9
|
def get_dynatrace_environments(
|
10
10
|
api: GqlApi | None = None,
|
11
11
|
) -> list[DynatraceEnvironmentV1]:
|
12
|
-
api = api
|
12
|
+
api = api or gql.get_api()
|
13
13
|
data = query(api.query)
|
14
14
|
return list(data.environments or [])
|
@@ -9,6 +9,6 @@ from reconcile.utils.gql import GqlApi
|
|
9
9
|
def get_dynatrace_token_provider_token_specs(
|
10
10
|
api: GqlApi | None = None,
|
11
11
|
) -> list[DynatraceTokenProviderTokenSpecV1]:
|
12
|
-
api = api
|
12
|
+
api = api or gql.get_api()
|
13
13
|
data = query(api.query)
|
14
14
|
return list(data.token_specs or [])
|