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
reconcile/acs_rbac.py
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
import logging
|
2
2
|
from collections import defaultdict
|
3
3
|
from collections.abc import Callable
|
4
|
+
from itertools import starmap
|
4
5
|
from typing import (
|
5
6
|
Self,
|
6
7
|
)
|
@@ -151,10 +152,7 @@ class AcsRbacIntegration(QontractReconcileIntegration[NoParams]):
|
|
151
152
|
permission_usernames[
|
152
153
|
Permission(**permission.dict(by_alias=True))
|
153
154
|
].append(user.org_username)
|
154
|
-
return
|
155
|
-
AcsRole.build(permission, usernames)
|
156
|
-
for permission, usernames in permission_usernames.items()
|
157
|
-
]
|
155
|
+
return list(starmap(AcsRole.build, permission_usernames.items()))
|
158
156
|
|
159
157
|
def get_current_state(
|
160
158
|
self, auth_provider_id: str, rbac_api_resources: RbacResources
|
reconcile/aus/base.py
CHANGED
@@ -585,20 +585,20 @@ def fetch_current_state(
|
|
585
585
|
addon_upgrade_policies = addon_service.get_addon_upgrade_policies(
|
586
586
|
ocm_api, spec.cluster.id, addon_id=addon_spec.addon.addon.id
|
587
587
|
)
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
addon_service=addon_service,
|
600
|
-
)
|
588
|
+
current_state.extend(
|
589
|
+
AddonUpgradePolicy(
|
590
|
+
id=addon_upgrade_policy.id,
|
591
|
+
addon_id=addon_spec.addon.addon.id,
|
592
|
+
cluster=spec.cluster,
|
593
|
+
next_run=addon_upgrade_policy.next_run,
|
594
|
+
schedule=addon_upgrade_policy.schedule,
|
595
|
+
schedule_type=addon_upgrade_policy.schedule_type,
|
596
|
+
version=addon_upgrade_policy.version,
|
597
|
+
state=addon_upgrade_policy.state,
|
598
|
+
addon_service=addon_service,
|
601
599
|
)
|
600
|
+
for addon_upgrade_policy in addon_upgrade_policies
|
601
|
+
)
|
602
602
|
elif spec.cluster.is_rosa_hypershift():
|
603
603
|
upgrade_policies = get_control_plane_upgrade_policies(
|
604
604
|
ocm_api, spec.cluster.id
|
reconcile/aws_ami_share.py
CHANGED
@@ -19,8 +19,7 @@ def filter_accounts(accounts: Iterable[dict[str, Any]]) -> list[dict[str, Any]]:
|
|
19
19
|
sharing = a.get("sharing")
|
20
20
|
if sharing:
|
21
21
|
sharing_account_names.add(a["name"])
|
22
|
-
for s in sharing
|
23
|
-
sharing_account_names.add(s["account"]["name"])
|
22
|
+
sharing_account_names.update(s["account"]["name"] for s in sharing)
|
24
23
|
|
25
24
|
return [a for a in accounts if a["name"] in sharing_account_names]
|
26
25
|
|
@@ -35,7 +35,7 @@ class AWSCloudwatchCleanupOption(BaseModel):
|
|
35
35
|
|
36
36
|
|
37
37
|
DEFAULT_AWS_CLOUDWATCH_CLEANUP_OPTION = AWSCloudwatchCleanupOption(
|
38
|
-
regex=re.compile(".*"),
|
38
|
+
regex=re.compile(r".*"),
|
39
39
|
retention_in_days=DEFAULT_RETENTION_IN_DAYS,
|
40
40
|
delete_empty_log_group=False,
|
41
41
|
)
|
@@ -177,7 +177,7 @@ class AwsSamlIdpIntegration(QontractReconcileIntegration[AwsSamlIdpIntegrationPa
|
|
177
177
|
integration_version=QONTRACT_INTEGRATION_VERSION,
|
178
178
|
dry_run=dry_run,
|
179
179
|
cache_source=ts.terraform_configurations(),
|
180
|
-
shard=self.params.account_name
|
180
|
+
shard=self.params.account_name or "",
|
181
181
|
ttl_seconds=self.params.extended_early_exit_cache_ttl_seconds,
|
182
182
|
logger=logging.getLogger(),
|
183
183
|
runner=runner,
|
@@ -295,7 +295,7 @@ class AwsSamlRolesIntegration(
|
|
295
295
|
integration_version=QONTRACT_INTEGRATION_VERSION,
|
296
296
|
dry_run=dry_run,
|
297
297
|
cache_source=ts.terraform_configurations(),
|
298
|
-
shard=self.params.account_name
|
298
|
+
shard=self.params.account_name or "",
|
299
299
|
ttl_seconds=self.params.extended_early_exit_cache_ttl_seconds,
|
300
300
|
logger=logging.getLogger(),
|
301
301
|
runner=runner,
|
@@ -273,7 +273,7 @@ class AVSIntegration(QontractReconcileIntegration[AVSIntegrationParams]):
|
|
273
273
|
supported_providers: Iterable[str],
|
274
274
|
) -> list[ExternalResource]:
|
275
275
|
external_resources: list[ExternalResource] = []
|
276
|
-
|
276
|
+
defaults_cache: dict[str, Any] = {}
|
277
277
|
for ns in namespaces:
|
278
278
|
for external_resource in ns.external_resources or []:
|
279
279
|
if not isinstance(
|
@@ -297,12 +297,12 @@ class AVSIntegration(QontractReconcileIntegration[AVSIntegrationParams]):
|
|
297
297
|
values = {}
|
298
298
|
# get/set the defaults file values from/to cache
|
299
299
|
if resource.defaults:
|
300
|
-
if not (values :=
|
300
|
+
if not (values := defaults_cache.get(resource.defaults, {})):
|
301
301
|
# retrieve the external resource spec values
|
302
302
|
values = get_values(
|
303
303
|
gql_get_resource_func, resource.defaults
|
304
304
|
)
|
305
|
-
|
305
|
+
defaults_cache[resource.defaults] = values
|
306
306
|
values = override_values(values, resource.overrides)
|
307
307
|
if resource.provider.lower() == "elasticache" and str(
|
308
308
|
values["engine_version"]
|
@@ -215,8 +215,8 @@ def write_coverage_report_to_stdout(change_decisions: list[ChangeDecision]) -> N
|
|
215
215
|
"disabled": False,
|
216
216
|
})
|
217
217
|
if d.coverage:
|
218
|
-
|
219
|
-
|
218
|
+
results.extend(
|
219
|
+
{
|
220
220
|
"file": d.file.path,
|
221
221
|
"schema": d.file.schema,
|
222
222
|
"changed path": d.diff.path,
|
@@ -228,7 +228,9 @@ def write_coverage_report_to_stdout(change_decisions: list[ChangeDecision]) -> N
|
|
228
228
|
for ar in ctx.approver_reachability or []
|
229
229
|
]),
|
230
230
|
"disabled": str(ctx.disabled),
|
231
|
-
}
|
231
|
+
}
|
232
|
+
for ctx in d.coverage
|
233
|
+
)
|
232
234
|
else:
|
233
235
|
results.append({
|
234
236
|
"file": d.file.path,
|
@@ -453,8 +455,9 @@ def run(
|
|
453
455
|
if not co_label.startswith("change-owner/")
|
454
456
|
}
|
455
457
|
for bc in changes:
|
456
|
-
|
457
|
-
|
458
|
+
labels.update(
|
459
|
+
change_owner_label(label) for label in bc.change_owner_labels
|
460
|
+
)
|
458
461
|
|
459
462
|
if mr_management_enabled:
|
460
463
|
gl.set_labels_on_merge_request(merge_request, labels)
|
@@ -578,15 +578,15 @@ class ChangeTypeProcessor:
|
|
578
578
|
|
579
579
|
# expand context based on change-type composition
|
580
580
|
for ce in self._context_expansions:
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
change_type=ec.change_type,
|
588
|
-
)
|
581
|
+
# add expanded contexts (derived owned files)
|
582
|
+
contexts.extend(
|
583
|
+
ResolvedContext(
|
584
|
+
owned_file_ref=ec.owned_file_ref,
|
585
|
+
context_file_ref=change.file_ref,
|
586
|
+
change_type=ec.change_type,
|
589
587
|
)
|
588
|
+
for ec in ce.expand(change, expansion_trail_copy)
|
589
|
+
)
|
590
590
|
|
591
591
|
# context detection
|
592
592
|
# the context for approver extraction can be found within the changed
|
@@ -603,17 +603,17 @@ class ChangeTypeProcessor:
|
|
603
603
|
)
|
604
604
|
)
|
605
605
|
for ce in self._context_expansions:
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
)
|
606
|
+
# add expanded contexts (derived owned files)
|
607
|
+
contexts.extend(
|
608
|
+
ResolvedContext(
|
609
|
+
owned_file_ref=ec.owned_file_ref,
|
610
|
+
context_file_ref=ctx_file_ref,
|
611
|
+
change_type=ec.change_type,
|
612
|
+
)
|
613
|
+
for ec in ce.expand_from_file_ref(
|
614
|
+
ctx_file_ref, expansion_trail_copy
|
616
615
|
)
|
616
|
+
)
|
617
617
|
|
618
618
|
return contexts
|
619
619
|
|
@@ -211,11 +211,11 @@ class BundleFileChange:
|
|
211
211
|
returns all the change-types that are involved in the coverage
|
212
212
|
of all changes
|
213
213
|
"""
|
214
|
-
|
215
|
-
|
216
|
-
for
|
217
|
-
|
218
|
-
|
214
|
+
return [
|
215
|
+
ctx.change_type_processor
|
216
|
+
for dc in self.diff_coverage
|
217
|
+
for ctx in dc.coverage
|
218
|
+
]
|
219
219
|
|
220
220
|
|
221
221
|
def parse_resource_file_content(content: Any | None) -> tuple[Any, str | None]:
|
@@ -308,10 +308,9 @@ def get_priority_for_changes(
|
|
308
308
|
"""
|
309
309
|
Finds the lowest priority of all change types involved in the provided bundle file changes.
|
310
310
|
"""
|
311
|
-
priorities
|
312
|
-
|
313
|
-
|
314
|
-
priorities.add(ct.priority)
|
311
|
+
priorities = {
|
312
|
+
ct.priority for bfc in bundle_file_changes for ct in bfc.involved_change_types()
|
313
|
+
}
|
315
314
|
# get the lowest priority
|
316
315
|
for p in reversed(ChangeTypePriority):
|
317
316
|
if p in priorities:
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import operator
|
1
2
|
from collections import defaultdict
|
2
3
|
from collections.abc import (
|
3
4
|
Iterable,
|
@@ -35,7 +36,7 @@ def get_approver_decisions_from_mr_comments(
|
|
35
36
|
comments: Iterable[Mapping[str, Any]],
|
36
37
|
) -> list[Decision]:
|
37
38
|
decisions: list[Decision] = []
|
38
|
-
for c in sorted(comments, key=
|
39
|
+
for c in sorted(comments, key=operator.itemgetter("created_at")):
|
39
40
|
commenter = c["username"]
|
40
41
|
comment_body = c.get("body")
|
41
42
|
for line in comment_body.split("\n") if comment_body else []:
|
@@ -146,20 +147,16 @@ def apply_decisions_to_changes(
|
|
146
147
|
to generate the coverage report and to reason about the approval
|
147
148
|
state of the MR.
|
148
149
|
"""
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
)
|
160
|
-
)
|
161
|
-
|
162
|
-
return diff_decisions
|
150
|
+
return [
|
151
|
+
_apply_decision_to_diff(
|
152
|
+
c,
|
153
|
+
d,
|
154
|
+
approver_decisions,
|
155
|
+
auto_approver_usernames,
|
156
|
+
)
|
157
|
+
for c in changes
|
158
|
+
for d in c.diff_coverage
|
159
|
+
]
|
163
160
|
|
164
161
|
|
165
162
|
def _apply_decision_to_diff(
|
@@ -139,7 +139,7 @@ def change_type_contexts_for_self_service_roles(
|
|
139
139
|
resolved_approvers = resolve_role_members([r for r in roles if r.self_service])
|
140
140
|
|
141
141
|
# match every BundleChange with every relevant ChangeTypeV1
|
142
|
-
change_type_contexts = []
|
142
|
+
change_type_contexts: list[tuple[BundleFileChange, ChangeTypeContext]] = []
|
143
143
|
for bc in bundle_changes:
|
144
144
|
for ctp in change_type_processors:
|
145
145
|
for ownership in ctp.find_context_file_refs(
|
@@ -177,8 +177,8 @@ def change_type_contexts_for_self_service_roles(
|
|
177
177
|
else []
|
178
178
|
)
|
179
179
|
})
|
180
|
-
|
181
|
-
|
180
|
+
change_type_contexts.extend(
|
181
|
+
(
|
182
182
|
bc,
|
183
183
|
ChangeTypeContext(
|
184
184
|
change_type_processor=ctp,
|
@@ -193,7 +193,9 @@ def change_type_contexts_for_self_service_roles(
|
|
193
193
|
change_owner_labels=change_type_labels_from_role(role),
|
194
194
|
context_file=ownership.context_file_ref,
|
195
195
|
),
|
196
|
-
)
|
196
|
+
)
|
197
|
+
for role in owning_roles.values()
|
198
|
+
)
|
197
199
|
return change_type_contexts
|
198
200
|
|
199
201
|
|
@@ -130,16 +130,14 @@ class AppInterfaceRepo:
|
|
130
130
|
elif c.change_schema is None or c.change_schema == ctp.context_schema:
|
131
131
|
# the change happens in the self_service related files
|
132
132
|
for ssc in role.self_service or []:
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
)
|
142
|
-
)
|
133
|
+
bundle_files.extend(
|
134
|
+
self.bundle_file_for_path(BundleFileType.DATAFILE, df.path)
|
135
|
+
for df in ssc.datafiles or []
|
136
|
+
)
|
137
|
+
bundle_files.extend(
|
138
|
+
self.bundle_file_for_path(BundleFileType.RESOURCEFILE, rf_path)
|
139
|
+
for rf_path in ssc.resources or []
|
140
|
+
)
|
143
141
|
return bundle_files
|
144
142
|
|
145
143
|
def bundle_files_with_schemas(self, schema: str) -> list[BundleFileChange]:
|
reconcile/cli.py
CHANGED
@@ -256,7 +256,7 @@ def print_to_file(function):
|
|
256
256
|
def config_name(function):
|
257
257
|
function = click.option(
|
258
258
|
"--config-name",
|
259
|
-
help="jenkins config name to print out.
|
259
|
+
help="jenkins config name to print out.must works with --print-only mode",
|
260
260
|
default=None,
|
261
261
|
)(function)
|
262
262
|
|
@@ -308,7 +308,7 @@ def vault_output_path(function):
|
|
308
308
|
def vault_throughput_path(function):
|
309
309
|
function = click.option(
|
310
310
|
"--vault-throughput-path",
|
311
|
-
help="path in Vault to find input resources
|
311
|
+
help="path in Vault to find input resources and store output resources.",
|
312
312
|
default="",
|
313
313
|
)(function)
|
314
314
|
|
@@ -888,7 +888,7 @@ def openshift_users(ctx, thread_pool_size, internal, use_jump_host):
|
|
888
888
|
|
889
889
|
|
890
890
|
@integration.command(
|
891
|
-
short_help="Use OpenShift ServiceAccount tokens
|
891
|
+
short_help="Use OpenShift ServiceAccount tokens across namespaces/clusters."
|
892
892
|
)
|
893
893
|
@threaded()
|
894
894
|
@binary(["oc", "ssh"])
|
@@ -1601,8 +1601,7 @@ def openshift_tekton_resources(
|
|
1601
1601
|
|
1602
1602
|
|
1603
1603
|
@integration.command(
|
1604
|
-
short_help="Guesses and adds labels to merge requests "
|
1605
|
-
"according to changed paths."
|
1604
|
+
short_help="Guesses and adds labels to merge requests according to changed paths."
|
1606
1605
|
)
|
1607
1606
|
@click.argument("gitlab-project-id")
|
1608
1607
|
@click.argument("gitlab-merge-request-id")
|
@@ -2801,7 +2800,7 @@ def ocm_addons_upgrade_scheduler_org(
|
|
2801
2800
|
@click.option(
|
2802
2801
|
"--ignore-sts-clusters",
|
2803
2802
|
is_flag=True,
|
2804
|
-
default=os.environ.get("IGNORE_STS_CLUSTERS"
|
2803
|
+
default=bool(os.environ.get("IGNORE_STS_CLUSTERS")),
|
2805
2804
|
help="Ignore STS clusters",
|
2806
2805
|
)
|
2807
2806
|
@click.pass_context
|
@@ -2938,7 +2937,7 @@ def ocm_addons(ctx, thread_pool_size):
|
|
2938
2937
|
|
2939
2938
|
|
2940
2939
|
@integration.command(
|
2941
|
-
short_help="Grants AWS infrastructure access
|
2940
|
+
short_help="Grants AWS infrastructure access to members in AWS groups via OCM."
|
2942
2941
|
)
|
2943
2942
|
@click.pass_context
|
2944
2943
|
def ocm_aws_infrastructure_access(ctx):
|
@@ -3129,7 +3128,7 @@ def email_sender(ctx):
|
|
3129
3128
|
|
3130
3129
|
|
3131
3130
|
@integration.command(
|
3132
|
-
short_help="Send emails to users based on
|
3131
|
+
short_help="Send emails to users based on requests submitted to app-interface."
|
3133
3132
|
)
|
3134
3133
|
@click.pass_context
|
3135
3134
|
def requests_sender(ctx):
|
@@ -3156,8 +3155,7 @@ def sql_query(ctx, enable_deletion):
|
|
3156
3155
|
|
3157
3156
|
|
3158
3157
|
@integration.command(
|
3159
|
-
short_help="Manages labels on gitlab merge requests "
|
3160
|
-
"based on OWNERS files schema."
|
3158
|
+
short_help="Manages labels on gitlab merge requests based on OWNERS files schema."
|
3161
3159
|
)
|
3162
3160
|
@threaded()
|
3163
3161
|
@click.pass_context
|
@@ -3525,7 +3523,7 @@ def integrations_manager(
|
|
3525
3523
|
@click.option(
|
3526
3524
|
"--mr-management",
|
3527
3525
|
is_flag=True,
|
3528
|
-
default=os.environ.get("MR_MANAGEMENT"
|
3526
|
+
default=bool(os.environ.get("MR_MANAGEMENT")),
|
3529
3527
|
help="Manage MR labels and comments (default to false)",
|
3530
3528
|
)
|
3531
3529
|
@click.pass_context
|
@@ -84,7 +84,7 @@ def parse_prober_url(url: str) -> dict[str, str]:
|
|
84
84
|
parsed_url = urlparse(url)
|
85
85
|
if parsed_url.scheme not in {"http", "https"}:
|
86
86
|
raise ValueError(
|
87
|
-
"the prober URL needs to be an http:// or https:// one
|
87
|
+
f"the prober URL needs to be an http:// or https:// one but is {url}"
|
88
88
|
)
|
89
89
|
data = {"url": parsed_url.netloc, "scheme": parsed_url.scheme}
|
90
90
|
if parsed_url.path:
|
reconcile/cna/integration.py
CHANGED
@@ -49,8 +49,8 @@ class CNAIntegration:
|
|
49
49
|
):
|
50
50
|
self._cna_clients = cna_clients
|
51
51
|
self._namespaces = namespaces
|
52
|
-
self._desired_states = desired_states
|
53
|
-
self._current_states = current_states
|
52
|
+
self._desired_states = desired_states or defaultdict(State)
|
53
|
+
self._current_states = current_states or defaultdict(State)
|
54
54
|
|
55
55
|
def assemble_desired_states(self):
|
56
56
|
self._desired_states = defaultdict(State)
|
reconcile/dashdotdb_base.py
CHANGED
@@ -57,7 +57,7 @@ class DashdotdbBase:
|
|
57
57
|
return None
|
58
58
|
|
59
59
|
params = {"scope": self.scope}
|
60
|
-
endpoint = f"{self.dashdotdb_url}/api/v1/
|
60
|
+
endpoint = f"{self.dashdotdb_url}/api/v1/token"
|
61
61
|
response = requests.get(
|
62
62
|
url=endpoint,
|
63
63
|
params=params,
|
@@ -81,7 +81,7 @@ class DashdotdbBase:
|
|
81
81
|
return None
|
82
82
|
|
83
83
|
params = {"scope": self.scope}
|
84
|
-
endpoint = f"{self.dashdotdb_url}/api/v1/
|
84
|
+
endpoint = f"{self.dashdotdb_url}/api/v1/token/{self.dashdotdb_token}"
|
85
85
|
response = requests.delete(
|
86
86
|
url=endpoint,
|
87
87
|
params=params,
|
reconcile/dashdotdb_cso.py
CHANGED
@@ -56,7 +56,7 @@ class DashdotdbCSO(DashdotdbBase):
|
|
56
56
|
return response
|
57
57
|
|
58
58
|
for item in imagemanifestvuln["items"]:
|
59
|
-
endpoint = f"{self.dashdotdb_url}/api/v1/
|
59
|
+
endpoint = f"{self.dashdotdb_url}/api/v1/imagemanifestvuln/{cluster}"
|
60
60
|
response = self._do_post(endpoint, item)
|
61
61
|
try:
|
62
62
|
response.raise_for_status()
|
reconcile/dashdotdb_dora.py
CHANGED
@@ -110,7 +110,7 @@ class DeploymentDB:
|
|
110
110
|
trigger_reason_pattern: str,
|
111
111
|
app_env_since_list: Iterable[tuple[AppEnv, datetime]],
|
112
112
|
) -> list[tuple[AppEnv, Deployment]]:
|
113
|
-
deployments = []
|
113
|
+
deployments: list[tuple[AppEnv, Deployment]] = []
|
114
114
|
with self.conn.cursor() as cur:
|
115
115
|
subq = [
|
116
116
|
sql.SQL(
|
@@ -137,11 +137,13 @@ class DeploymentDB:
|
|
137
137
|
|
138
138
|
cur.execute(query)
|
139
139
|
|
140
|
-
|
141
|
-
|
140
|
+
deployments.extend(
|
141
|
+
(
|
142
142
|
AppEnv(record[0], record[1]),
|
143
143
|
Deployment(record[2], record[3]),
|
144
|
-
)
|
144
|
+
)
|
145
|
+
for record in cur
|
146
|
+
)
|
145
147
|
|
146
148
|
if not deployments:
|
147
149
|
LOG.info("No deployments found")
|
reconcile/dashdotdb_slo.py
CHANGED
@@ -78,7 +78,7 @@ class DashdotdbSLO(DashdotdbBase):
|
|
78
78
|
|
79
79
|
for item in service_slos:
|
80
80
|
slo_name = item.name
|
81
|
-
endpoint = f"{self.dashdotdb_url}/api/v1/
|
81
|
+
endpoint = f"{self.dashdotdb_url}/api/v1/serviceslometrics/{slo_name}"
|
82
82
|
payload = item.dashdot_payload()
|
83
83
|
if self.dry_run:
|
84
84
|
continue
|
@@ -127,7 +127,7 @@ DROP ROLE IF EXISTS "{self._get_user()}";\\gexec"""
|
|
127
127
|
|
128
128
|
def _generate_db_access(self) -> str:
|
129
129
|
statements = [
|
130
|
-
f
|
130
|
+
f'GRANT {",".join(access.grants)} ON ALL TABLES IN SCHEMA "{access.target.dbschema}" TO "{self._get_user()}";'
|
131
131
|
for access in self.db_access.access or []
|
132
132
|
]
|
133
133
|
return "\n".join(statements)
|
@@ -149,10 +149,10 @@ DROP ROLE IF EXISTS "{self._get_user()}";\\gexec"""
|
|
149
149
|
f'REVOKE ALL PRIVILEGES ON ALL TABLES IN SCHEMA "{schema}" FROM "{self._get_user()}";'
|
150
150
|
)
|
151
151
|
else:
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
152
|
+
statements.extend(
|
153
|
+
f'REVOKE {grant} ON ALL TABLES IN SCHEMA "{schema}" FROM "{self._get_user()}";'
|
154
|
+
for grant in set(grants) - set(desired_grants[schema])
|
155
|
+
)
|
156
156
|
return "".join(statements)
|
157
157
|
|
158
158
|
def _provision_script(self) -> str:
|
@@ -445,22 +445,20 @@ def _populate_resources(
|
|
445
445
|
engine=engine,
|
446
446
|
)
|
447
447
|
script_secret_name = f"{resource_prefix}-script"
|
448
|
-
managed_resources.
|
448
|
+
managed_resources.extend([
|
449
449
|
DBAMResource(
|
450
450
|
resource=generate_script_secret_spec(
|
451
451
|
script_secret_name,
|
452
452
|
generator.generate_script(),
|
453
453
|
),
|
454
454
|
clean_up=True,
|
455
|
-
)
|
456
|
-
|
457
|
-
# create user secret
|
458
|
-
managed_resources.append(
|
455
|
+
),
|
456
|
+
# create user secret
|
459
457
|
DBAMResource(
|
460
458
|
resource=generate_user_secret_spec(resource_prefix, user_connection),
|
461
459
|
clean_up=False,
|
462
|
-
)
|
463
|
-
)
|
460
|
+
),
|
461
|
+
])
|
464
462
|
# create pull secret
|
465
463
|
labels = pull_secret["labels"] or {}
|
466
464
|
pull_secret_resources = orb.fetch_provider_vault_secret(
|
@@ -474,11 +472,9 @@ def _populate_resources(
|
|
474
472
|
integration_version=QONTRACT_INTEGRATION_VERSION,
|
475
473
|
settings=settings,
|
476
474
|
)
|
477
|
-
managed_resources.
|
478
|
-
DBAMResource(resource=pull_secret_resources, clean_up=True)
|
479
|
-
|
480
|
-
# create job
|
481
|
-
managed_resources.append(
|
475
|
+
managed_resources.extend([
|
476
|
+
DBAMResource(resource=pull_secret_resources, clean_up=True),
|
477
|
+
# create job
|
482
478
|
DBAMResource(
|
483
479
|
resource=get_job_spec(
|
484
480
|
JobData(
|
@@ -493,8 +489,8 @@ def _populate_resources(
|
|
493
489
|
)
|
494
490
|
),
|
495
491
|
clean_up=True,
|
496
|
-
)
|
497
|
-
)
|
492
|
+
),
|
493
|
+
])
|
498
494
|
|
499
495
|
return managed_resources
|
500
496
|
|
reconcile/email_sender.py
CHANGED
@@ -53,8 +53,7 @@ def collect_to(to):
|
|
53
53
|
if not service_owners:
|
54
54
|
continue
|
55
55
|
|
56
|
-
for service_owner in service_owners
|
57
|
-
audience.add(service_owner["email"])
|
56
|
+
audience.update(service_owner["email"] for service_owner in service_owners)
|
58
57
|
|
59
58
|
# TODO: implement clusters and namespaces
|
60
59
|
|
@@ -65,8 +64,7 @@ def collect_to(to):
|
|
65
64
|
if not account_owners:
|
66
65
|
continue
|
67
66
|
|
68
|
-
for account_owner in account_owners
|
69
|
-
audience.add(account_owner["email"])
|
67
|
+
audience.update(account_owner["email"] for account_owner in account_owners)
|
70
68
|
|
71
69
|
roles = to.get("roles")
|
72
70
|
if roles:
|
@@ -75,13 +73,11 @@ def collect_to(to):
|
|
75
73
|
if not users:
|
76
74
|
continue
|
77
75
|
|
78
|
-
for user in users
|
79
|
-
audience.add(user["org_username"])
|
76
|
+
audience.update(user["org_username"] for user in users)
|
80
77
|
|
81
78
|
users = to.get("users")
|
82
79
|
if users:
|
83
|
-
for user in users
|
84
|
-
audience.add(user["org_username"])
|
80
|
+
audience.update(user["org_username"] for user in users)
|
85
81
|
|
86
82
|
return audience
|
87
83
|
|
@@ -120,8 +120,8 @@ class OutputSecretsFormatter:
|
|
120
120
|
def _format_value(self, value: str) -> str:
|
121
121
|
decoded_value = base64.b64decode(value).decode("utf-8")
|
122
122
|
if decoded_value.startswith("__vault__:"):
|
123
|
-
|
124
|
-
secret_ref = VaultSecret(**
|
123
|
+
secret_ref_ = json.loads(decoded_value.replace("__vault__:", ""))
|
124
|
+
secret_ref = VaultSecret(**secret_ref_)
|
125
125
|
return self.secret_reader.read_secret(secret_ref)
|
126
126
|
else:
|
127
127
|
return decoded_value
|