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
@@ -78,7 +78,7 @@ class MRParser:
|
|
78
78
|
attrs = mr.attributes
|
79
79
|
desc = str(attrs.get("description", ""))
|
80
80
|
parts = desc.split(PROMOTION_DATA_SEPARATOR)
|
81
|
-
if
|
81
|
+
if len(parts) != 2:
|
82
82
|
logging.info(
|
83
83
|
"Bad data separator format. Closing %s",
|
84
84
|
mr.attributes.get("web_url", "NO_WEBURL"),
|
@@ -202,7 +202,7 @@ class MRParser:
|
|
202
202
|
is_batchable_str = self._apply_regex(
|
203
203
|
pattern=self._is_batchable_regex, promotion_data=promotion_data
|
204
204
|
)
|
205
|
-
if is_batchable_str not in
|
205
|
+
if is_batchable_str not in {"True", "False"}:
|
206
206
|
logging.info(
|
207
207
|
"Bad %s format. Closing %s",
|
208
208
|
IS_BATCHABLE,
|
@@ -163,7 +163,7 @@ def _parse_expression(expression: str) -> Any:
|
|
163
163
|
except JsonPathParserError as e:
|
164
164
|
raise RuntimeError(
|
165
165
|
f"Invalid jsonpath expression in namespaceSelector '{expression}' :{e}"
|
166
|
-
)
|
166
|
+
) from None
|
167
167
|
|
168
168
|
|
169
169
|
def is_namespace_addressed_by_selector(
|
@@ -55,7 +55,9 @@ def load_site_controller_template(
|
|
55
55
|
resource["content"], undefined=jinja2.StrictUndefined
|
56
56
|
).render(variables)
|
57
57
|
except jinja2.exceptions.UndefinedError as e:
|
58
|
-
raise SkupperNetworkExcpetion(
|
58
|
+
raise SkupperNetworkExcpetion(
|
59
|
+
f"Failed to render template {path}: {e.message}"
|
60
|
+
) from None
|
59
61
|
return yaml.safe_load(body)
|
60
62
|
|
61
63
|
|
@@ -30,14 +30,14 @@ class SiteController:
|
|
30
30
|
"""Skupper site token secret."""
|
31
31
|
_labels = copy.deepcopy(labels)
|
32
32
|
_labels["skupper.io/type"] = "connection-token-request"
|
33
|
-
return
|
34
|
-
apiVersion
|
35
|
-
kind
|
36
|
-
metadata
|
37
|
-
name
|
38
|
-
labels
|
39
|
-
|
40
|
-
|
33
|
+
return {
|
34
|
+
"apiVersion": "v1",
|
35
|
+
"kind": "Secret",
|
36
|
+
"metadata": {
|
37
|
+
"name": name,
|
38
|
+
"labels": _labels,
|
39
|
+
},
|
40
|
+
}
|
41
41
|
|
42
42
|
|
43
43
|
def get_site_controller(site: SkupperSite) -> SiteController:
|
reconcile/slack_usergroups.py
CHANGED
@@ -560,7 +560,7 @@ def _update_usergroup_users_from_state(
|
|
560
560
|
desired_ug_state.user_names
|
561
561
|
).items()
|
562
562
|
]
|
563
|
-
active_user_names =
|
563
|
+
active_user_names = {s.name for s in slack_user_objects}
|
564
564
|
|
565
565
|
if len(active_user_names) != len(desired_ug_state.user_names):
|
566
566
|
logging.info(
|
@@ -768,7 +768,7 @@ def run(
|
|
768
768
|
|
769
769
|
gqlapi = gql.get_api()
|
770
770
|
secret_reader = SecretReader(queries.get_secret_reader_settings())
|
771
|
-
init_users =
|
771
|
+
init_users = not usergroup_name
|
772
772
|
|
773
773
|
# queries
|
774
774
|
permissions = get_permissions(query_func=gqlapi.query)
|
@@ -804,14 +804,14 @@ def run(
|
|
804
804
|
# merge the two desired states recursively
|
805
805
|
desired_state = deep_update(desired_state, desired_state_cluster_usergroups)
|
806
806
|
|
807
|
-
runner_params: RunnerParams =
|
808
|
-
dry_run
|
809
|
-
slack_map
|
810
|
-
desired_state
|
811
|
-
clusters
|
812
|
-
workspace_name
|
813
|
-
usergroup_name
|
814
|
-
|
807
|
+
runner_params: RunnerParams = {
|
808
|
+
"dry_run": dry_run,
|
809
|
+
"slack_map": slack_map,
|
810
|
+
"desired_state": desired_state,
|
811
|
+
"clusters": clusters,
|
812
|
+
"workspace_name": workspace_name,
|
813
|
+
"usergroup_name": usergroup_name,
|
814
|
+
}
|
815
815
|
|
816
816
|
if enable_extended_early_exit:
|
817
817
|
extended_early_exit_run(
|
reconcile/status_board.py
CHANGED
@@ -223,7 +223,7 @@ class StatusBoardExporterIntegration(QontractReconcileIntegration):
|
|
223
223
|
)
|
224
224
|
|
225
225
|
# product is deleted entirely
|
226
|
-
for product_name in diff_result.delete
|
226
|
+
for product_name in diff_result.delete:
|
227
227
|
for application in current_products[product_name].applications or []:
|
228
228
|
return_list.append(
|
229
229
|
StatusBoardHandler(action="delete", status_board_object=application)
|
reconcile/statuspage/status.py
CHANGED
@@ -73,9 +73,7 @@ class ManualStatusProvider(StatusProvider, BaseModel):
|
|
73
73
|
now = datetime.now(UTC)
|
74
74
|
if self.start and now < self.start:
|
75
75
|
return False
|
76
|
-
|
77
|
-
return False
|
78
|
-
return True
|
76
|
+
return not (self.end and self.end < now)
|
79
77
|
|
80
78
|
|
81
79
|
def build_status_provider_config(
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import contextlib
|
1
2
|
import logging
|
2
3
|
import sys
|
3
4
|
from collections.abc import (
|
@@ -344,10 +345,8 @@ def build_cloudflare_terraform_config_collection(
|
|
344
345
|
rps,
|
345
346
|
)
|
346
347
|
|
347
|
-
|
348
|
+
with contextlib.suppress(ClientAlreadyRegisteredError):
|
348
349
|
cf_clients.register_client(f"{cf_account.name}-{zone.identifier}", client)
|
349
|
-
except ClientAlreadyRegisteredError:
|
350
|
-
pass
|
351
350
|
|
352
351
|
return cf_clients
|
353
352
|
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import contextlib
|
1
2
|
from collections.abc import (
|
2
3
|
Iterable,
|
3
4
|
Mapping,
|
@@ -264,10 +265,8 @@ class TerraformCloudflareUsers(
|
|
264
265
|
False,
|
265
266
|
)
|
266
267
|
|
267
|
-
|
268
|
+
with contextlib.suppress(ClientAlreadyRegisteredError):
|
268
269
|
cf_clients.register_client(cf_account.name, client)
|
269
|
-
except ClientAlreadyRegisteredError:
|
270
|
-
pass
|
271
270
|
|
272
271
|
return cf_clients
|
273
272
|
|
reconcile/terraform_repo.py
CHANGED
@@ -175,7 +175,9 @@ class TerraformRepoIntegration(
|
|
175
175
|
explicit_start=True,
|
176
176
|
)
|
177
177
|
except FileNotFoundError:
|
178
|
-
raise ParameterError(
|
178
|
+
raise ParameterError(
|
179
|
+
f"Unable to write to '{self.params.output_file}'"
|
180
|
+
) from None
|
179
181
|
else:
|
180
182
|
print(yaml.safe_dump(data=output.dict(), explicit_start=True))
|
181
183
|
|
@@ -231,7 +233,7 @@ class TerraformRepoIntegration(
|
|
231
233
|
except (KeyError, AttributeError):
|
232
234
|
raise ParameterError(
|
233
235
|
f'Invalid ref: "{ref}" on repo: "{repo_url}". Or the project repo is not reachable'
|
234
|
-
)
|
236
|
+
) from None
|
235
237
|
|
236
238
|
def merge_results(
|
237
239
|
self,
|
@@ -284,7 +286,7 @@ class TerraformRepoIntegration(
|
|
284
286
|
# state.add already performs a json.dumps(key) so we export the
|
285
287
|
# pydantic model as a dict to avoid a double json dump with extra quotes
|
286
288
|
state.add(add_key, add_val.dict(by_alias=True), force=True)
|
287
|
-
for delete_key in diff_result.delete
|
289
|
+
for delete_key in diff_result.delete:
|
288
290
|
state.rm(delete_key)
|
289
291
|
for change_key, change_val in diff_result.change.items():
|
290
292
|
if change_val.desired.delete:
|
reconcile/terraform_resources.py
CHANGED
@@ -399,22 +399,22 @@ def run(
|
|
399
399
|
if print_to_file:
|
400
400
|
return
|
401
401
|
|
402
|
-
runner_params: RunnerParams =
|
403
|
-
accounts
|
404
|
-
account_names
|
405
|
-
tf_namespaces
|
406
|
-
tf
|
407
|
-
ts
|
408
|
-
secret_reader
|
409
|
-
dry_run
|
410
|
-
enable_deletion
|
411
|
-
thread_pool_size
|
412
|
-
internal
|
413
|
-
use_jump_host
|
414
|
-
light
|
415
|
-
vault_output_path
|
416
|
-
defer
|
417
|
-
|
402
|
+
runner_params: RunnerParams = {
|
403
|
+
"accounts": accounts,
|
404
|
+
"account_names": account_names,
|
405
|
+
"tf_namespaces": tf_namespaces,
|
406
|
+
"tf": tf,
|
407
|
+
"ts": ts,
|
408
|
+
"secret_reader": secret_reader,
|
409
|
+
"dry_run": dry_run,
|
410
|
+
"enable_deletion": enable_deletion,
|
411
|
+
"thread_pool_size": thread_pool_size,
|
412
|
+
"internal": internal,
|
413
|
+
"use_jump_host": use_jump_host,
|
414
|
+
"light": light,
|
415
|
+
"vault_output_path": vault_output_path,
|
416
|
+
"defer": defer,
|
417
|
+
}
|
418
418
|
|
419
419
|
if enable_extended_early_exit and get_feature_toggle_state(
|
420
420
|
"terraform-resources-extended-early-exit",
|
@@ -528,12 +528,12 @@ def run(
|
|
528
528
|
defer(tf.cleanup)
|
529
529
|
if print_to_file:
|
530
530
|
return
|
531
|
-
runner_params: RunnerParams =
|
532
|
-
terraform_client
|
533
|
-
terrascript_client
|
534
|
-
enable_deletion
|
535
|
-
dry_run
|
536
|
-
|
531
|
+
runner_params: RunnerParams = {
|
532
|
+
"terraform_client": tf,
|
533
|
+
"terrascript_client": ts,
|
534
|
+
"enable_deletion": enable_deletion,
|
535
|
+
"dry_run": dry_run,
|
536
|
+
}
|
537
537
|
if enable_extended_early_exit and get_feature_toggle_state(
|
538
538
|
"terraform-tgw-attachments-extended-early-exit",
|
539
539
|
default=False,
|
@@ -44,7 +44,7 @@ def find_matching_peering(
|
|
44
44
|
peering_info = to_cluster["peering"]
|
45
45
|
peer_connections = peering_info["connections"]
|
46
46
|
for peer_connection in peer_connections:
|
47
|
-
if
|
47
|
+
if peer_connection["provider"] != desired_provider:
|
48
48
|
continue
|
49
49
|
if not peer_connection["cluster"]:
|
50
50
|
continue
|
@@ -318,7 +318,7 @@ def build_desired_state_vpc_mesh_single_cluster(
|
|
318
318
|
for peer_connection in peer_connections:
|
319
319
|
# We only care about account-vpc-mesh peering providers
|
320
320
|
peer_connection_provider = peer_connection["provider"]
|
321
|
-
if
|
321
|
+
if peer_connection_provider != "account-vpc-mesh":
|
322
322
|
continue
|
323
323
|
# filter on account
|
324
324
|
account = peer_connection["account"]
|
@@ -443,7 +443,7 @@ def build_desired_state_vpc_single_cluster(
|
|
443
443
|
for peer_connection in peer_connections:
|
444
444
|
# We only care about account-vpc peering providers
|
445
445
|
peer_connection_provider = peer_connection["provider"]
|
446
|
-
if
|
446
|
+
if peer_connection_provider != "account-vpc":
|
447
447
|
continue
|
448
448
|
# requester is the cluster's AWS account
|
449
449
|
requester = {
|
@@ -686,11 +686,11 @@ def run(
|
|
686
686
|
if defer:
|
687
687
|
defer(tf.cleanup)
|
688
688
|
|
689
|
-
runner_params: RunnerParams =
|
690
|
-
tf
|
691
|
-
dry_run
|
692
|
-
enable_deletion
|
693
|
-
|
689
|
+
runner_params: RunnerParams = {
|
690
|
+
"tf": tf,
|
691
|
+
"dry_run": dry_run,
|
692
|
+
"enable_deletion": enable_deletion,
|
693
|
+
}
|
694
694
|
|
695
695
|
if enable_extended_early_exit and get_feature_toggle_state(
|
696
696
|
"terraform-vpc-peerings-extended-early-exit",
|
@@ -74,7 +74,7 @@ class TerraformVpcResources(QontractReconcileIntegration[TerraformVpcResourcesPa
|
|
74
74
|
# this happens because we are not filtering the requests
|
75
75
|
# when running the integration for a single account with --account-name.
|
76
76
|
# We also don't want to create outputs for deleted requets.
|
77
|
-
if request.account.name not in outputs
|
77
|
+
if request.account.name not in outputs or request.delete:
|
78
78
|
continue
|
79
79
|
|
80
80
|
outputs_per_request[request.identifier] = []
|
@@ -1,8 +1,5 @@
|
|
1
1
|
from collections.abc import Generator
|
2
|
-
from datetime import
|
3
|
-
datetime,
|
4
|
-
timedelta,
|
5
|
-
)
|
2
|
+
from datetime import UTC, datetime, timedelta
|
6
3
|
from typing import (
|
7
4
|
TYPE_CHECKING,
|
8
5
|
Any,
|
@@ -97,7 +94,7 @@ def setup_mocks(
|
|
97
94
|
aws_accounts: list[dict],
|
98
95
|
log_groups: list[dict],
|
99
96
|
tags: dict[str, Any],
|
100
|
-
utcnow: datetime = datetime.
|
97
|
+
utcnow: datetime = datetime.now(UTC), # noqa: B008
|
101
98
|
) -> MagicMock:
|
102
99
|
mocker.patch(
|
103
100
|
"reconcile.aws_cloudwatch_log_retention.integration.get_aws_accounts",
|
@@ -85,22 +85,24 @@ class TestGithubOrg:
|
|
85
85
|
def do_current_state_test(path):
|
86
86
|
fixture = fxt.get_anymarkup(path)
|
87
87
|
|
88
|
-
with
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
88
|
+
with (
|
89
|
+
patch("reconcile.github_org.RawGithubApi") as m_rga,
|
90
|
+
patch("reconcile.github_org.Github") as m_gh,
|
91
|
+
):
|
92
|
+
m_gh.return_value = GithubMock(fixture["gh_api"])
|
93
|
+
m_rga.return_value = RawGithubApiMock()
|
94
|
+
|
95
|
+
gh_api_store = github_org.GHApiStore(config.get_config())
|
96
|
+
current_state = github_org.fetch_current_state(gh_api_store)
|
97
|
+
current_state = current_state.dump()
|
98
|
+
|
99
|
+
expected_current_state = fixture["state"]
|
100
|
+
|
101
|
+
assert len(current_state) == len(expected_current_state)
|
102
|
+
for group in current_state:
|
103
|
+
params = group["params"]
|
104
|
+
items = sorted(group["items"])
|
105
|
+
assert items == get_items_by_params(expected_current_state, params)
|
104
106
|
|
105
107
|
@staticmethod
|
106
108
|
def do_desired_state_test(path):
|
@@ -47,15 +47,15 @@ def test_parse_valid_code_components():
|
|
47
47
|
},
|
48
48
|
]
|
49
49
|
expected = github_repo_invites.CodeComponents(
|
50
|
-
urls=
|
50
|
+
urls={
|
51
51
|
"https://github.com/org1/project1",
|
52
52
|
"https://github.com/org2/project1",
|
53
53
|
"https://github.com/org2/project2",
|
54
|
-
|
55
|
-
known_orgs=
|
54
|
+
},
|
55
|
+
known_orgs={
|
56
56
|
"https://github.com/org1",
|
57
57
|
"https://github.com/org2",
|
58
|
-
|
58
|
+
},
|
59
59
|
)
|
60
60
|
assert github_repo_invites._parse_code_components(raw_code_components) == expected
|
61
61
|
|
@@ -84,8 +84,8 @@ def test_accept_invitations_no_dry_run(github):
|
|
84
84
|
]
|
85
85
|
]
|
86
86
|
code_components = github_repo_invites.CodeComponents(
|
87
|
-
urls=
|
88
|
-
known_orgs=
|
87
|
+
urls={f"{expected_org}/project1"},
|
88
|
+
known_orgs={expected_org},
|
89
89
|
)
|
90
90
|
dry_run = False
|
91
91
|
accepted_invitations = github_repo_invites._accept_invitations(
|
@@ -93,7 +93,7 @@ def test_accept_invitations_no_dry_run(github):
|
|
93
93
|
)
|
94
94
|
|
95
95
|
github.accept_repo_invitation.assert_called_once_with(expected_id)
|
96
|
-
assert accepted_invitations ==
|
96
|
+
assert accepted_invitations == {expected_org}
|
97
97
|
|
98
98
|
|
99
99
|
def test_accept_invitations_dry_run(github):
|
@@ -107,8 +107,8 @@ def test_accept_invitations_dry_run(github):
|
|
107
107
|
],
|
108
108
|
]
|
109
109
|
code_components = github_repo_invites.CodeComponents(
|
110
|
-
urls=
|
111
|
-
known_orgs=
|
110
|
+
urls={f"{expected_org}/project1"},
|
111
|
+
known_orgs={expected_org},
|
112
112
|
)
|
113
113
|
dry_run = True
|
114
114
|
accepted_invitations = github_repo_invites._accept_invitations(
|
@@ -116,4 +116,4 @@ def test_accept_invitations_dry_run(github):
|
|
116
116
|
)
|
117
117
|
|
118
118
|
github.accept_repo_invitation.assert_not_called()
|
119
|
-
assert accepted_invitations ==
|
119
|
+
assert accepted_invitations == {expected_org}
|
@@ -71,18 +71,18 @@ def test_collect_parameters() -> None:
|
|
71
71
|
template = {
|
72
72
|
"parameters": [
|
73
73
|
{
|
74
|
-
"name": "
|
74
|
+
"name": "TPLT_PARAM",
|
75
75
|
"value": "default",
|
76
76
|
}
|
77
77
|
]
|
78
78
|
}
|
79
|
-
os.environ["
|
79
|
+
os.environ["TPLT_PARAM"] = "override"
|
80
80
|
environment = EnvironmentV1(name="e", parameters='{"env_param": "test"}')
|
81
81
|
|
82
82
|
parameters = intop.collect_parameters(template, environment, "", "", None)
|
83
83
|
expected = {
|
84
84
|
"env_param": "test",
|
85
|
-
"
|
85
|
+
"TPLT_PARAM": "override",
|
86
86
|
}
|
87
87
|
assert parameters == expected
|
88
88
|
|
@@ -108,16 +108,16 @@ def test_collect_parameters_os_env_strongest() -> None:
|
|
108
108
|
template = {
|
109
109
|
"parameters": [
|
110
110
|
{
|
111
|
-
"name": "
|
111
|
+
"name": "ENV_PARAM",
|
112
112
|
"value": "default",
|
113
113
|
}
|
114
114
|
]
|
115
115
|
}
|
116
|
-
os.environ["
|
117
|
-
environment = EnvironmentV1(name="env", parameters='{"
|
116
|
+
os.environ["ENV_PARAM"] = "strongest"
|
117
|
+
environment = EnvironmentV1(name="env", parameters='{"ENV_PARAM": "override"}')
|
118
118
|
parameters = intop.collect_parameters(template, environment, "", "", None)
|
119
119
|
expected = {
|
120
|
-
"
|
120
|
+
"ENV_PARAM": "strongest",
|
121
121
|
}
|
122
122
|
assert parameters == expected
|
123
123
|
|
@@ -487,19 +487,19 @@ def shard_manager(
|
|
487
487
|
def test_shard_manager_aws_account_filtering(
|
488
488
|
aws_account_sharding_strategy: AWSAccountShardingStrategy,
|
489
489
|
) -> None:
|
490
|
-
assert [
|
490
|
+
assert [
|
491
491
|
a.name
|
492
492
|
for a in aws_account_sharding_strategy.filter_objects("another-integration")
|
493
|
-
]
|
493
|
+
] == ["acc-1", "acc-2", "acc-3", "acc-4"]
|
494
494
|
|
495
495
|
|
496
496
|
def test_shard_manager_aws_account_filtering_disabled(
|
497
497
|
aws_account_sharding_strategy: AWSAccountShardingStrategy,
|
498
498
|
) -> None:
|
499
499
|
# acc-4 is disabled for AWS_INTEGRATION
|
500
|
-
assert [
|
500
|
+
assert [
|
501
501
|
a.name for a in aws_account_sharding_strategy.filter_objects(AWS_INTEGRATION)
|
502
|
-
]
|
502
|
+
] == ["acc-1", "acc-2", "acc-3"]
|
503
503
|
|
504
504
|
|
505
505
|
#
|
@@ -50,14 +50,14 @@ class TestOCMAdditionalRouters(TestCase):
|
|
50
50
|
|
51
51
|
router_create = ocm_act["create"]
|
52
52
|
expected = []
|
53
|
-
for c in router_create
|
53
|
+
for c in router_create:
|
54
54
|
expected.append(call(c, router_create[c]))
|
55
55
|
calls = ocm.create_additional_router.call_args_list
|
56
56
|
self.assertEqual(calls, expected)
|
57
57
|
|
58
58
|
router_delete = ocm_act["delete"]
|
59
59
|
expected = []
|
60
|
-
for c in router_delete
|
60
|
+
for c in router_delete:
|
61
61
|
expected.append(call(c, router_delete[c]))
|
62
62
|
calls = ocm.delete_additional_router.call_args_list
|
63
63
|
self.assertEqual(calls, expected)
|
@@ -73,7 +73,7 @@ class TestOCMAdditionalRouters(TestCase):
|
|
73
73
|
|
74
74
|
ocm_api = fixture["ocm_api"]
|
75
75
|
clusters = []
|
76
|
-
for c in ocm_api
|
76
|
+
for c in ocm_api:
|
77
77
|
clusters.append({"name": c})
|
78
78
|
ocm = get.return_value
|
79
79
|
ocm.get_additional_routers.side_effect = lambda x: fixture["ocm_api"][x]
|
@@ -108,7 +108,7 @@ class TestOCMAdditionalRouters(TestCase):
|
|
108
108
|
|
109
109
|
ocm_api = fixture["ocm_api"]
|
110
110
|
clusters = []
|
111
|
-
for c in ocm_api
|
111
|
+
for c in ocm_api:
|
112
112
|
clusters.append({"name": c})
|
113
113
|
ocm = get.return_value
|
114
114
|
|
@@ -120,14 +120,14 @@ class TestOCMAdditionalRouters(TestCase):
|
|
120
120
|
|
121
121
|
router_create = ocm_act["create"]
|
122
122
|
expected = []
|
123
|
-
for c in router_create
|
123
|
+
for c in router_create:
|
124
124
|
expected.append(call(c, router_create[c]))
|
125
125
|
calls = ocm.create_additional_router.call_args_list
|
126
126
|
self.assertEqual(calls, expected)
|
127
127
|
|
128
128
|
router_delete = ocm_act["delete"]
|
129
129
|
expected = []
|
130
|
-
for c in router_delete
|
130
|
+
for c in router_delete:
|
131
131
|
expected.append(call(c, router_delete[c]))
|
132
132
|
calls = ocm.delete_additional_router.call_args_list
|
133
133
|
self.assertEqual(calls, expected)
|
@@ -29,14 +29,14 @@ def test_get_highest(version_set):
|
|
29
29
|
highest = get_highest(version_set)
|
30
30
|
assert highest == "1.1.1"
|
31
31
|
|
32
|
-
assert get_highest(
|
32
|
+
assert get_highest({"1.1.1"}) == "1.1.1"
|
33
33
|
|
34
34
|
|
35
35
|
def test_get_majority(versions, version_set):
|
36
36
|
majority = get_majority(version_set, versions)
|
37
37
|
assert majority == "1.1.0"
|
38
38
|
|
39
|
-
assert get_majority(
|
39
|
+
assert get_majority({"1.1.1"}, ["1.1.1"]) == "1.1.1"
|
40
40
|
|
41
41
|
|
42
42
|
def test_recommended_version(versions, version_set):
|
@@ -125,7 +125,7 @@ def test_openshift_serviceaccount_tokens__write_outputs_to_vault(
|
|
125
125
|
value=construct_sa_token_oc_resource("name", "token"),
|
126
126
|
)
|
127
127
|
write_outputs_to_vault(vault_client, "path/to/secrets", ri)
|
128
|
-
vault_client.write.call_count == 2
|
128
|
+
assert vault_client.write.call_count == 2
|
129
129
|
vault_client.write.assert_has_calls([
|
130
130
|
call({
|
131
131
|
"path": "path/to/secrets/openshift-serviceaccount-tokens/cluster/namespace/name",
|
@@ -167,14 +167,14 @@ def test_openshift_serviceaccount_tokens__canonicalize_namespaces(
|
|
167
167
|
assert nss[2].openshift_service_account_tokens is None
|
168
168
|
|
169
169
|
# namespace with tokens or shared resources defined
|
170
|
-
nss[3].name == "with-shared-resources"
|
171
|
-
nss[3].cluster.name == "cluster"
|
170
|
+
assert nss[3].name == "with-shared-resources"
|
171
|
+
assert nss[3].cluster.name == "cluster"
|
172
172
|
assert len(nss[3].openshift_service_account_tokens or []) == 1
|
173
173
|
|
174
|
-
nss[4].name == "with-openshift-serviceaccount-tokens"
|
174
|
+
assert nss[4].name == "with-openshift-serviceaccount-tokens"
|
175
175
|
assert len(nss[4].openshift_service_account_tokens or []) == 2
|
176
176
|
|
177
|
-
nss[5].name == "with-openshift-serviceaccount-tokens-and-shared-resources"
|
177
|
+
assert nss[5].name == "with-openshift-serviceaccount-tokens-and-shared-resources"
|
178
178
|
assert len(nss[5].openshift_service_account_tokens or []) == 2
|
179
179
|
|
180
180
|
|
@@ -121,7 +121,7 @@ class TestOpenshiftTektonResources:
|
|
121
121
|
self.test_data.providers = [self.provider1, self.provider2_wr]
|
122
122
|
|
123
123
|
tkn_providers = otr.fetch_tkn_providers(None)
|
124
|
-
keys_expected =
|
124
|
+
keys_expected = {self.provider1["name"], self.provider2_wr["name"]}
|
125
125
|
assert tkn_providers.keys() == keys_expected
|
126
126
|
|
127
127
|
def test_duplicate_providers(self) -> None:
|
@@ -146,10 +146,10 @@ class TestOpenshiftTektonResources:
|
|
146
146
|
self.test_data.providers = [self.provider1]
|
147
147
|
desired_resources = otr.fetch_desired_resources(otr.fetch_tkn_providers(None))
|
148
148
|
|
149
|
-
expected_task_names =
|
149
|
+
expected_task_names = {
|
150
150
|
"o-push-gateway-openshift-saas-deploy-task-status-metric",
|
151
151
|
"o-openshift-saas-deploy-saas1",
|
152
|
-
|
152
|
+
}
|
153
153
|
expected_pipeline_name = "o-saas-deploy-saas1"
|
154
154
|
|
155
155
|
task_names = set()
|