qontract-reconcile 0.10.2.dev268__py3-none-any.whl → 0.10.2.dev270__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.dev268.dist-info → qontract_reconcile-0.10.2.dev270.dist-info}/METADATA +1 -1
- {qontract_reconcile-0.10.2.dev268.dist-info → qontract_reconcile-0.10.2.dev270.dist-info}/RECORD +60 -60
- reconcile/aws_account_manager/integration.py +1 -1
- reconcile/aws_iam_keys.py +2 -1
- reconcile/aws_saml_idp/integration.py +2 -1
- reconcile/aws_saml_roles/integration.py +2 -1
- reconcile/aws_support_cases_sos.py +4 -1
- reconcile/cli.py +3 -2
- reconcile/dashdotdb_dvo.py +2 -1
- reconcile/dashdotdb_slo.py +4 -1
- reconcile/endpoints_discovery/integration.py +2 -1
- reconcile/gabi_authorized_users.py +2 -1
- reconcile/gitlab_owners.py +2 -1
- reconcile/gitlab_permissions.py +4 -1
- reconcile/glitchtip_project_dsn/integration.py +2 -1
- reconcile/integrations_manager.py +2 -1
- reconcile/ocm_clusters.py +2 -1
- reconcile/ocm_external_configuration_labels.py +2 -1
- reconcile/ocm_groups.py +2 -1
- reconcile/ocm_upgrade_scheduler_org_updater.py +6 -5
- reconcile/openshift_base.py +46 -28
- reconcile/openshift_clusterrolebindings.py +20 -6
- reconcile/openshift_groups.py +2 -1
- reconcile/openshift_limitranges.py +22 -12
- reconcile/openshift_namespace_labels.py +21 -5
- reconcile/openshift_namespaces.py +2 -1
- reconcile/openshift_network_policies.py +25 -6
- reconcile/openshift_prometheus_rules.py +2 -1
- reconcile/openshift_resourcequotas.py +21 -12
- reconcile/openshift_resources.py +2 -1
- reconcile/openshift_resources_base.py +3 -2
- reconcile/openshift_rhcs_certs.py +2 -1
- reconcile/openshift_rolebindings.py +34 -10
- reconcile/openshift_routes.py +11 -9
- reconcile/openshift_saas_deploy.py +3 -2
- reconcile/openshift_saas_deploy_trigger_cleaner.py +2 -1
- reconcile/openshift_saas_deploy_trigger_configs.py +2 -1
- reconcile/openshift_saas_deploy_trigger_images.py +2 -1
- reconcile/openshift_saas_deploy_trigger_moving_commits.py +2 -1
- reconcile/openshift_saas_deploy_trigger_upstream_jobs.py +2 -1
- reconcile/openshift_serviceaccount_tokens.py +2 -1
- reconcile/openshift_tekton_resources.py +2 -1
- reconcile/openshift_upgrade_watcher.py +2 -1
- reconcile/openshift_users.py +2 -1
- reconcile/openshift_vault_secrets.py +11 -9
- reconcile/skupper_network/integration.py +2 -1
- reconcile/terraform_aws_route53.py +2 -1
- reconcile/terraform_resources.py +3 -2
- reconcile/terraform_tgw_attachments.py +3 -2
- reconcile/terraform_users.py +2 -1
- reconcile/terraform_vpc_peerings.py +2 -1
- reconcile/utils/aws_api_typed/account.py +40 -8
- reconcile/utils/aws_api_typed/iam.py +19 -9
- reconcile/utils/constants.py +1 -0
- reconcile/utils/jinja2/utils.py +5 -4
- reconcile/utils/slo_document_manager.py +1 -1
- tools/app_interface_reporter.py +4 -1
- tools/cli_commands/container_images_report.py +3 -2
- {qontract_reconcile-0.10.2.dev268.dist-info → qontract_reconcile-0.10.2.dev270.dist-info}/WHEEL +0 -0
- {qontract_reconcile-0.10.2.dev268.dist-info → qontract_reconcile-0.10.2.dev270.dist-info}/entry_points.txt +0 -0
@@ -22,6 +22,7 @@ from reconcile.typed_queries.app_interface_vault_settings import (
|
|
22
22
|
)
|
23
23
|
from reconcile.typed_queries.rhcs_provider_settings import get_rhcs_provider_settings
|
24
24
|
from reconcile.utils import gql, metrics
|
25
|
+
from reconcile.utils.constants import DEFAULT_THREAD_POOL_SIZE
|
25
26
|
from reconcile.utils.defer import defer
|
26
27
|
from reconcile.utils.disabled_integrations import integration_is_enabled
|
27
28
|
from reconcile.utils.metrics import GaugeMetric, normalize_integration_name
|
@@ -243,7 +244,7 @@ def fetch_desired_state(
|
|
243
244
|
@defer
|
244
245
|
def run(
|
245
246
|
dry_run: bool,
|
246
|
-
thread_pool_size: int =
|
247
|
+
thread_pool_size: int = DEFAULT_THREAD_POOL_SIZE,
|
247
248
|
internal: bool | None = None,
|
248
249
|
use_jump_host: bool = True,
|
249
250
|
cluster_name: Iterable[str] | None = None,
|
@@ -1,5 +1,7 @@
|
|
1
1
|
import contextlib
|
2
2
|
import sys
|
3
|
+
from collections.abc import Callable, Mapping, Sequence
|
4
|
+
from typing import Any
|
3
5
|
|
4
6
|
import reconcile.openshift_base as ob
|
5
7
|
from reconcile import queries
|
@@ -7,9 +9,13 @@ from reconcile.utils import (
|
|
7
9
|
expiration,
|
8
10
|
gql,
|
9
11
|
)
|
12
|
+
from reconcile.utils.constants import DEFAULT_THREAD_POOL_SIZE
|
10
13
|
from reconcile.utils.defer import defer
|
11
14
|
from reconcile.utils.openshift_resource import OpenshiftResource as OR
|
12
|
-
from reconcile.utils.openshift_resource import
|
15
|
+
from reconcile.utils.openshift_resource import (
|
16
|
+
ResourceInventory,
|
17
|
+
ResourceKeyExistsError,
|
18
|
+
)
|
13
19
|
from reconcile.utils.semver_helper import make_semver
|
14
20
|
from reconcile.utils.sharding import is_in_shard
|
15
21
|
|
@@ -49,7 +55,7 @@ QONTRACT_INTEGRATION = "openshift-rolebindings"
|
|
49
55
|
QONTRACT_INTEGRATION_VERSION = make_semver(0, 3, 0)
|
50
56
|
|
51
57
|
|
52
|
-
def construct_user_oc_resource(role, user):
|
58
|
+
def construct_user_oc_resource(role: str, user: str) -> tuple[OR, str]:
|
53
59
|
name = f"{role}-{user}"
|
54
60
|
body = {
|
55
61
|
"apiVersion": "rbac.authorization.k8s.io/v1",
|
@@ -66,7 +72,7 @@ def construct_user_oc_resource(role, user):
|
|
66
72
|
)
|
67
73
|
|
68
74
|
|
69
|
-
def construct_sa_oc_resource(role, namespace, sa_name):
|
75
|
+
def construct_sa_oc_resource(role: str, namespace: str, sa_name: str) -> tuple[OR, str]:
|
70
76
|
name = f"{role}-{namespace}-{sa_name}"
|
71
77
|
body = {
|
72
78
|
"apiVersion": "rbac.authorization.k8s.io/v1",
|
@@ -85,9 +91,16 @@ def construct_sa_oc_resource(role, namespace, sa_name):
|
|
85
91
|
)
|
86
92
|
|
87
93
|
|
88
|
-
def fetch_desired_state(
|
94
|
+
def fetch_desired_state(
|
95
|
+
ri: ResourceInventory | None,
|
96
|
+
oc_map: ob.ClusterMap | None,
|
97
|
+
enforced_user_keys: list[str] | None = None,
|
98
|
+
) -> list[dict[str, str]]:
|
89
99
|
gqlapi = gql.get_api()
|
90
|
-
|
100
|
+
roles_query_result = gqlapi.query(ROLES_QUERY)
|
101
|
+
if not roles_query_result:
|
102
|
+
return []
|
103
|
+
roles: Sequence[Mapping[str, Any]] = expiration.filter(roles_query_result["roles"])
|
91
104
|
users_desired_state = []
|
92
105
|
for role in roles:
|
93
106
|
permissions = [
|
@@ -124,11 +137,15 @@ def fetch_desired_state(ri, oc_map, enforced_user_keys=None):
|
|
124
137
|
|
125
138
|
# get username keys based on used IDPs
|
126
139
|
user_keys = ob.determine_user_keys_for_access(
|
127
|
-
cluster,
|
140
|
+
cluster,
|
141
|
+
cluster_info.get("auth") or [],
|
142
|
+
enforced_user_keys=enforced_user_keys,
|
128
143
|
)
|
129
144
|
# create user rolebindings for user * user_keys
|
130
|
-
for user in role
|
131
|
-
for username in {user
|
145
|
+
for user in role.get("users") or []:
|
146
|
+
for username in {user.get(key) for key in user_keys}:
|
147
|
+
if not username:
|
148
|
+
continue
|
132
149
|
# used by openshift-users and github integrations
|
133
150
|
# this is just to simplify things a bit on the their side
|
134
151
|
users_desired_state.append({"cluster": cluster, "user": username})
|
@@ -171,7 +188,13 @@ def fetch_desired_state(ri, oc_map, enforced_user_keys=None):
|
|
171
188
|
|
172
189
|
|
173
190
|
@defer
|
174
|
-
def run(
|
191
|
+
def run(
|
192
|
+
dry_run: bool,
|
193
|
+
thread_pool_size: int = DEFAULT_THREAD_POOL_SIZE,
|
194
|
+
internal: bool | None = None,
|
195
|
+
use_jump_host: bool = True,
|
196
|
+
defer: Callable | None = None,
|
197
|
+
) -> None:
|
175
198
|
namespaces = [
|
176
199
|
namespace_info
|
177
200
|
for namespace_info in queries.get_namespaces()
|
@@ -190,7 +213,8 @@ def run(dry_run, thread_pool_size=10, internal=None, use_jump_host=True, defer=N
|
|
190
213
|
internal=internal,
|
191
214
|
use_jump_host=use_jump_host,
|
192
215
|
)
|
193
|
-
defer
|
216
|
+
if defer:
|
217
|
+
defer(oc_map.cleanup)
|
194
218
|
fetch_desired_state(ri, oc_map)
|
195
219
|
ob.publish_metrics(ri, QONTRACT_INTEGRATION)
|
196
220
|
ob.realize_data(dry_run, oc_map, ri, thread_pool_size)
|
reconcile/openshift_routes.py
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
+
from collections.abc import Callable
|
1
2
|
from typing import Any
|
2
3
|
|
3
4
|
import reconcile.openshift_resources_base as orb
|
5
|
+
from reconcile.utils.constants import DEFAULT_THREAD_POOL_SIZE
|
4
6
|
from reconcile.utils.runtime.integration import DesiredStateShardConfig
|
5
7
|
from reconcile.utils.semver_helper import make_semver
|
6
8
|
|
@@ -10,14 +12,14 @@ PROVIDERS = ["route"]
|
|
10
12
|
|
11
13
|
|
12
14
|
def run(
|
13
|
-
dry_run,
|
14
|
-
thread_pool_size=
|
15
|
-
internal=None,
|
16
|
-
use_jump_host=True,
|
17
|
-
cluster_name=None,
|
18
|
-
namespace_name=None,
|
19
|
-
defer=None,
|
20
|
-
):
|
15
|
+
dry_run: bool,
|
16
|
+
thread_pool_size: int = DEFAULT_THREAD_POOL_SIZE,
|
17
|
+
internal: bool | None = None,
|
18
|
+
use_jump_host: bool = True,
|
19
|
+
cluster_name: str | None = None,
|
20
|
+
namespace_name: str | None = None,
|
21
|
+
defer: Callable | None = None,
|
22
|
+
) -> None:
|
21
23
|
orb.QONTRACT_INTEGRATION = QONTRACT_INTEGRATION
|
22
24
|
orb.QONTRACT_INTEGRATION_VERSION = QONTRACT_INTEGRATION_VERSION
|
23
25
|
|
@@ -32,7 +34,7 @@ def run(
|
|
32
34
|
)
|
33
35
|
|
34
36
|
|
35
|
-
def early_exit_desired_state(*args, **kwargs) -> dict[str, Any]:
|
37
|
+
def early_exit_desired_state(*args: Any, **kwargs: Any) -> dict[str, Any]:
|
36
38
|
return orb.early_exit_desired_state(PROVIDERS)
|
37
39
|
|
38
40
|
|
@@ -25,6 +25,7 @@ from reconcile.typed_queries.saas_files import (
|
|
25
25
|
SaasFileList,
|
26
26
|
get_saasherder_settings,
|
27
27
|
)
|
28
|
+
from reconcile.utils.constants import DEFAULT_THREAD_POOL_SIZE
|
28
29
|
from reconcile.utils.defer import defer
|
29
30
|
from reconcile.utils.gitlab_api import GitLabApi
|
30
31
|
from reconcile.utils.openshift_resource import ResourceInventory
|
@@ -109,7 +110,7 @@ def slack_notify(
|
|
109
110
|
@defer
|
110
111
|
def run(
|
111
112
|
dry_run: bool,
|
112
|
-
thread_pool_size: int =
|
113
|
+
thread_pool_size: int = DEFAULT_THREAD_POOL_SIZE,
|
113
114
|
io_dir: str = "throughput/",
|
114
115
|
use_jump_host: bool = True,
|
115
116
|
saas_file_name: str | None = None,
|
@@ -259,7 +260,7 @@ def run(
|
|
259
260
|
all_callers=[sf.name for sf in all_saas_files if not sf.deprecated],
|
260
261
|
wait_for_namespace=True,
|
261
262
|
no_dry_run_skip_compare=(not saasherder.compare),
|
262
|
-
take_over=saasherder.take_over,
|
263
|
+
take_over=bool(saasherder.take_over),
|
263
264
|
)
|
264
265
|
|
265
266
|
if not dry_run:
|
@@ -18,6 +18,7 @@ from reconcile.typed_queries.app_interface_vault_settings import (
|
|
18
18
|
from reconcile.typed_queries.tekton_pipeline_providers import (
|
19
19
|
get_tekton_pipeline_providers,
|
20
20
|
)
|
21
|
+
from reconcile.utils.constants import DEFAULT_THREAD_POOL_SIZE
|
21
22
|
from reconcile.utils.defer import defer
|
22
23
|
from reconcile.utils.oc_map import (
|
23
24
|
OCLogMsg,
|
@@ -63,7 +64,7 @@ def get_pipeline_runs_to_delete(
|
|
63
64
|
@defer
|
64
65
|
def run(
|
65
66
|
dry_run: bool,
|
66
|
-
thread_pool_size: int =
|
67
|
+
thread_pool_size: int = DEFAULT_THREAD_POOL_SIZE,
|
67
68
|
internal: bool | None = None,
|
68
69
|
use_jump_host: bool = True,
|
69
70
|
defer: Callable | None = None,
|
@@ -2,6 +2,7 @@ import sys
|
|
2
2
|
|
3
3
|
import reconcile.openshift_saas_deploy_trigger_base as osdt_base
|
4
4
|
from reconcile.status import ExitCodes
|
5
|
+
from reconcile.utils.constants import DEFAULT_THREAD_POOL_SIZE
|
5
6
|
from reconcile.utils.saasherder import TriggerTypes
|
6
7
|
from reconcile.utils.semver_helper import make_semver
|
7
8
|
|
@@ -11,7 +12,7 @@ QONTRACT_INTEGRATION_VERSION = make_semver(0, 3, 0)
|
|
11
12
|
|
12
13
|
def run(
|
13
14
|
dry_run: bool,
|
14
|
-
thread_pool_size: int =
|
15
|
+
thread_pool_size: int = DEFAULT_THREAD_POOL_SIZE,
|
15
16
|
internal: bool | None = None,
|
16
17
|
use_jump_host: bool = True,
|
17
18
|
include_trigger_trace: bool = False,
|
@@ -2,6 +2,7 @@ import sys
|
|
2
2
|
|
3
3
|
import reconcile.openshift_saas_deploy_trigger_base as osdt_base
|
4
4
|
from reconcile.status import ExitCodes
|
5
|
+
from reconcile.utils.constants import DEFAULT_THREAD_POOL_SIZE
|
5
6
|
from reconcile.utils.saasherder import TriggerTypes
|
6
7
|
from reconcile.utils.semver_helper import make_semver
|
7
8
|
|
@@ -11,7 +12,7 @@ QONTRACT_INTEGRATION_VERSION = make_semver(0, 1, 0)
|
|
11
12
|
|
12
13
|
def run(
|
13
14
|
dry_run: bool,
|
14
|
-
thread_pool_size: int =
|
15
|
+
thread_pool_size: int = DEFAULT_THREAD_POOL_SIZE,
|
15
16
|
internal: bool | None = None,
|
16
17
|
use_jump_host: bool = True,
|
17
18
|
include_trigger_trace: bool = False,
|
@@ -2,6 +2,7 @@ import sys
|
|
2
2
|
|
3
3
|
import reconcile.openshift_saas_deploy_trigger_base as osdt_base
|
4
4
|
from reconcile.status import ExitCodes
|
5
|
+
from reconcile.utils.constants import DEFAULT_THREAD_POOL_SIZE
|
5
6
|
from reconcile.utils.saasherder import TriggerTypes
|
6
7
|
from reconcile.utils.semver_helper import make_semver
|
7
8
|
|
@@ -11,7 +12,7 @@ QONTRACT_INTEGRATION_VERSION = make_semver(0, 3, 0)
|
|
11
12
|
|
12
13
|
def run(
|
13
14
|
dry_run: bool,
|
14
|
-
thread_pool_size: int =
|
15
|
+
thread_pool_size: int = DEFAULT_THREAD_POOL_SIZE,
|
15
16
|
internal: bool | None = None,
|
16
17
|
use_jump_host: bool = True,
|
17
18
|
include_trigger_trace: bool = False,
|
@@ -2,6 +2,7 @@ import sys
|
|
2
2
|
|
3
3
|
import reconcile.openshift_saas_deploy_trigger_base as osdt_base
|
4
4
|
from reconcile.status import ExitCodes
|
5
|
+
from reconcile.utils.constants import DEFAULT_THREAD_POOL_SIZE
|
5
6
|
from reconcile.utils.saasherder import TriggerTypes
|
6
7
|
from reconcile.utils.semver_helper import make_semver
|
7
8
|
|
@@ -11,7 +12,7 @@ QONTRACT_INTEGRATION_VERSION = make_semver(0, 3, 0)
|
|
11
12
|
|
12
13
|
def run(
|
13
14
|
dry_run: bool,
|
14
|
-
thread_pool_size: int =
|
15
|
+
thread_pool_size: int = DEFAULT_THREAD_POOL_SIZE,
|
15
16
|
internal: bool | None = None,
|
16
17
|
use_jump_host: bool = True,
|
17
18
|
include_trigger_trace: bool = False,
|
@@ -9,6 +9,7 @@ from reconcile.gql_definitions.openshift_serviceaccount_tokens.tokens import (
|
|
9
9
|
query as serviceaccount_tokens_query,
|
10
10
|
)
|
11
11
|
from reconcile.utils import gql
|
12
|
+
from reconcile.utils.constants import DEFAULT_THREAD_POOL_SIZE
|
12
13
|
from reconcile.utils.defer import defer
|
13
14
|
from reconcile.utils.disabled_integrations import integration_is_enabled
|
14
15
|
from reconcile.utils.oc import OC_Map
|
@@ -204,7 +205,7 @@ def get_namespaces_with_serviceaccount_tokens(
|
|
204
205
|
@defer
|
205
206
|
def run(
|
206
207
|
dry_run: bool,
|
207
|
-
thread_pool_size: int =
|
208
|
+
thread_pool_size: int = DEFAULT_THREAD_POOL_SIZE,
|
208
209
|
internal: bool | None = None,
|
209
210
|
use_jump_host: bool = True,
|
210
211
|
vault_output_path: str = "",
|
@@ -11,6 +11,7 @@ from reconcile import openshift_base as ob
|
|
11
11
|
from reconcile import queries
|
12
12
|
from reconcile.status import ExitCodes
|
13
13
|
from reconcile.utils import gql
|
14
|
+
from reconcile.utils.constants import DEFAULT_THREAD_POOL_SIZE
|
14
15
|
from reconcile.utils.defer import defer
|
15
16
|
from reconcile.utils.openshift_resource import OpenshiftResource as OR
|
16
17
|
from reconcile.utils.parse_dhms_duration import (
|
@@ -421,7 +422,7 @@ def build_one_per_saas_file_tkn_task_name(
|
|
421
422
|
|
422
423
|
def run(
|
423
424
|
dry_run: bool,
|
424
|
-
thread_pool_size: int =
|
425
|
+
thread_pool_size: int = DEFAULT_THREAD_POOL_SIZE,
|
425
426
|
internal: bool | None = None,
|
426
427
|
use_jump_host: bool = True,
|
427
428
|
saas_file_name: str | None = None,
|
@@ -12,6 +12,7 @@ from reconcile.typed_queries.app_interface_vault_settings import (
|
|
12
12
|
get_app_interface_vault_settings,
|
13
13
|
)
|
14
14
|
from reconcile.typed_queries.clusters import get_clusters
|
15
|
+
from reconcile.utils.constants import DEFAULT_THREAD_POOL_SIZE
|
15
16
|
from reconcile.utils.defer import defer
|
16
17
|
from reconcile.utils.oc_map import (
|
17
18
|
OCLogMsg,
|
@@ -155,7 +156,7 @@ def notify_cluster_new_version(
|
|
155
156
|
@defer
|
156
157
|
def run(
|
157
158
|
dry_run: bool,
|
158
|
-
thread_pool_size: int =
|
159
|
+
thread_pool_size: int = DEFAULT_THREAD_POOL_SIZE,
|
159
160
|
internal: bool | None = None,
|
160
161
|
use_jump_host: bool = True,
|
161
162
|
defer: Callable | None = None,
|
reconcile/openshift_users.py
CHANGED
@@ -22,6 +22,7 @@ from reconcile.typed_queries.app_interface_vault_settings import (
|
|
22
22
|
get_app_interface_vault_settings,
|
23
23
|
)
|
24
24
|
from reconcile.typed_queries.clusters_minimal import get_clusters_minimal
|
25
|
+
from reconcile.utils.constants import DEFAULT_THREAD_POOL_SIZE
|
25
26
|
from reconcile.utils.defer import defer
|
26
27
|
from reconcile.utils.oc_map import (
|
27
28
|
OCLogMsg,
|
@@ -167,7 +168,7 @@ def act(diff: Mapping[str, Any], oc_map: OCMap) -> None:
|
|
167
168
|
@defer
|
168
169
|
def run(
|
169
170
|
dry_run: bool,
|
170
|
-
thread_pool_size: int =
|
171
|
+
thread_pool_size: int = DEFAULT_THREAD_POOL_SIZE,
|
171
172
|
internal: bool | None = None,
|
172
173
|
use_jump_host: bool = True,
|
173
174
|
defer: Callable | None = None,
|
@@ -1,9 +1,11 @@
|
|
1
1
|
from collections import defaultdict
|
2
|
+
from collections.abc import Callable
|
2
3
|
from typing import Any
|
3
4
|
|
4
5
|
from deepdiff import DeepHash
|
5
6
|
|
6
7
|
import reconcile.openshift_resources_base as orb
|
8
|
+
from reconcile.utils.constants import DEFAULT_THREAD_POOL_SIZE
|
7
9
|
from reconcile.utils.runtime.integration import DesiredStateShardConfig
|
8
10
|
from reconcile.utils.semver_helper import make_semver
|
9
11
|
|
@@ -13,14 +15,14 @@ PROVIDERS = ["vault-secret"]
|
|
13
15
|
|
14
16
|
|
15
17
|
def run(
|
16
|
-
dry_run,
|
17
|
-
thread_pool_size=
|
18
|
-
internal=None,
|
19
|
-
use_jump_host=True,
|
20
|
-
cluster_name=None,
|
21
|
-
namespace_name=None,
|
22
|
-
defer=None,
|
23
|
-
):
|
18
|
+
dry_run: bool,
|
19
|
+
thread_pool_size: int = DEFAULT_THREAD_POOL_SIZE,
|
20
|
+
internal: bool | None = None,
|
21
|
+
use_jump_host: bool = True,
|
22
|
+
cluster_name: str | None = None,
|
23
|
+
namespace_name: str | None = None,
|
24
|
+
defer: Callable | None = None,
|
25
|
+
) -> None:
|
24
26
|
orb.QONTRACT_INTEGRATION = QONTRACT_INTEGRATION
|
25
27
|
orb.QONTRACT_INTEGRATION_VERSION = QONTRACT_INTEGRATION_VERSION
|
26
28
|
|
@@ -35,7 +37,7 @@ def run(
|
|
35
37
|
)
|
36
38
|
|
37
39
|
|
38
|
-
def early_exit_desired_state(*args, **kwargs) -> dict[str, Any]:
|
40
|
+
def early_exit_desired_state(*args: Any, **kwargs: Any) -> dict[str, Any]:
|
39
41
|
namespaces, _ = orb.get_namespaces(PROVIDERS)
|
40
42
|
|
41
43
|
state_for_clusters = defaultdict(list)
|
@@ -21,6 +21,7 @@ from reconcile.typed_queries.app_interface_vault_settings import (
|
|
21
21
|
get_app_interface_vault_settings,
|
22
22
|
)
|
23
23
|
from reconcile.utils import gql
|
24
|
+
from reconcile.utils.constants import DEFAULT_THREAD_POOL_SIZE
|
24
25
|
from reconcile.utils.defer import defer
|
25
26
|
from reconcile.utils.disabled_integrations import integration_is_enabled
|
26
27
|
from reconcile.utils.oc_map import (
|
@@ -246,7 +247,7 @@ def get_skupper_networks(query_func: Callable) -> list[SkupperNetworkV1]:
|
|
246
247
|
@defer
|
247
248
|
def run(
|
248
249
|
dry_run: bool,
|
249
|
-
thread_pool_size: int =
|
250
|
+
thread_pool_size: int = DEFAULT_THREAD_POOL_SIZE,
|
250
251
|
internal: bool | None = None,
|
251
252
|
use_jump_host: bool = True,
|
252
253
|
defer: Callable | None = None,
|
@@ -10,6 +10,7 @@ from reconcile import queries
|
|
10
10
|
from reconcile.status import ExitCodes
|
11
11
|
from reconcile.utils import dnsutils
|
12
12
|
from reconcile.utils.aws_api import AWSApi
|
13
|
+
from reconcile.utils.constants import DEFAULT_THREAD_POOL_SIZE
|
13
14
|
from reconcile.utils.defer import defer
|
14
15
|
from reconcile.utils.external_resources import (
|
15
16
|
PROVIDER_AWS,
|
@@ -205,7 +206,7 @@ def run(
|
|
205
206
|
dry_run: bool = False,
|
206
207
|
print_to_file: str | None = None,
|
207
208
|
enable_deletion: bool = True,
|
208
|
-
thread_pool_size: int =
|
209
|
+
thread_pool_size: int = DEFAULT_THREAD_POOL_SIZE,
|
209
210
|
account_name: str | None = None,
|
210
211
|
defer=None,
|
211
212
|
):
|
reconcile/terraform_resources.py
CHANGED
@@ -31,6 +31,7 @@ from reconcile.typed_queries.app_interface_vault_settings import (
|
|
31
31
|
from reconcile.typed_queries.terraform_namespaces import get_namespaces
|
32
32
|
from reconcile.utils import gql
|
33
33
|
from reconcile.utils.aws_api import AWSApi
|
34
|
+
from reconcile.utils.constants import DEFAULT_THREAD_POOL_SIZE
|
34
35
|
from reconcile.utils.defer import defer
|
35
36
|
from reconcile.utils.extended_early_exit import (
|
36
37
|
ExtendedEarlyExitRunnerResult,
|
@@ -367,7 +368,7 @@ def run(
|
|
367
368
|
dry_run: bool,
|
368
369
|
print_to_file: str | None = None,
|
369
370
|
enable_deletion: bool = False,
|
370
|
-
thread_pool_size: int =
|
371
|
+
thread_pool_size: int = DEFAULT_THREAD_POOL_SIZE,
|
371
372
|
internal: bool | None = None,
|
372
373
|
use_jump_host: bool = True,
|
373
374
|
light: bool = False,
|
@@ -473,7 +474,7 @@ def runner(
|
|
473
474
|
secret_reader: SecretReaderBase,
|
474
475
|
dry_run: bool,
|
475
476
|
enable_deletion: bool = False,
|
476
|
-
thread_pool_size: int =
|
477
|
+
thread_pool_size: int = DEFAULT_THREAD_POOL_SIZE,
|
477
478
|
internal: bool | None = None,
|
478
479
|
use_jump_host: bool = True,
|
479
480
|
light: bool = False,
|
@@ -37,6 +37,7 @@ from reconcile.typed_queries.terraform_tgw_attachments.aws_accounts import (
|
|
37
37
|
)
|
38
38
|
from reconcile.utils import gql
|
39
39
|
from reconcile.utils.aws_api import AWSApi
|
40
|
+
from reconcile.utils.constants import DEFAULT_THREAD_POOL_SIZE
|
40
41
|
from reconcile.utils.defer import defer
|
41
42
|
from reconcile.utils.disabled_integrations import integration_is_enabled
|
42
43
|
from reconcile.utils.extended_early_exit import (
|
@@ -423,7 +424,7 @@ def setup(
|
|
423
424
|
account_name: str | None,
|
424
425
|
desired_state_data_source: DesiredStateDataSource,
|
425
426
|
tgw_accounts: list[dict[str, Any]],
|
426
|
-
thread_pool_size: int =
|
427
|
+
thread_pool_size: int = DEFAULT_THREAD_POOL_SIZE,
|
427
428
|
print_to_file: str | None = None,
|
428
429
|
) -> tuple[SecretReaderBase, AWSApi, Terraform, Terrascript]:
|
429
430
|
tgw_clusters = desired_state_data_source.clusters
|
@@ -500,7 +501,7 @@ def run(
|
|
500
501
|
dry_run: bool,
|
501
502
|
print_to_file: str | None = None,
|
502
503
|
enable_deletion: bool = False,
|
503
|
-
thread_pool_size: int =
|
504
|
+
thread_pool_size: int = DEFAULT_THREAD_POOL_SIZE,
|
504
505
|
account_name: str | None = None,
|
505
506
|
defer: Callable | None = None,
|
506
507
|
enable_extended_early_exit: bool = False,
|
reconcile/terraform_users.py
CHANGED
@@ -16,6 +16,7 @@ from reconcile.utils import (
|
|
16
16
|
gql,
|
17
17
|
)
|
18
18
|
from reconcile.utils.aws_api import AWSApi
|
19
|
+
from reconcile.utils.constants import DEFAULT_THREAD_POOL_SIZE
|
19
20
|
from reconcile.utils.disabled_integrations import integration_is_enabled
|
20
21
|
from reconcile.utils.runtime.integration import DesiredStateShardConfig
|
21
22
|
from reconcile.utils.secret_reader import SecretReader
|
@@ -237,7 +238,7 @@ def run(
|
|
237
238
|
dry_run: bool,
|
238
239
|
print_to_file: str | None = None,
|
239
240
|
enable_deletion: bool = False,
|
240
|
-
thread_pool_size: int =
|
241
|
+
thread_pool_size: int = DEFAULT_THREAD_POOL_SIZE,
|
241
242
|
send_mails: bool = True,
|
242
243
|
account_name: str | None = None,
|
243
244
|
):
|
@@ -12,6 +12,7 @@ from reconcile.utils import (
|
|
12
12
|
ocm,
|
13
13
|
)
|
14
14
|
from reconcile.utils.aws_api import AWSApi
|
15
|
+
from reconcile.utils.constants import DEFAULT_THREAD_POOL_SIZE
|
15
16
|
from reconcile.utils.defer import defer
|
16
17
|
from reconcile.utils.extended_early_exit import (
|
17
18
|
ExtendedEarlyExitRunnerResult,
|
@@ -566,7 +567,7 @@ def run(
|
|
566
567
|
dry_run: bool,
|
567
568
|
print_to_file: bool | None = None,
|
568
569
|
enable_deletion: bool = False,
|
569
|
-
thread_pool_size: int =
|
570
|
+
thread_pool_size: int = DEFAULT_THREAD_POOL_SIZE,
|
570
571
|
account_name: str | None = None,
|
571
572
|
enable_extended_early_exit: bool = False,
|
572
573
|
extended_early_exit_cache_ttl_seconds: int = 3600,
|
@@ -1,11 +1,14 @@
|
|
1
|
+
import logging
|
1
2
|
from enum import StrEnum
|
2
3
|
from typing import TYPE_CHECKING
|
3
4
|
|
4
5
|
if TYPE_CHECKING:
|
5
6
|
from mypy_boto3_account import AccountClient
|
7
|
+
from mypy_boto3_account.type_defs import AlternateContactTypeDef
|
6
8
|
else:
|
7
|
-
AccountClient = object
|
9
|
+
AccountClient = AlternateContactTypeDef = object
|
8
10
|
|
11
|
+
import botocore
|
9
12
|
from pydantic import BaseModel
|
10
13
|
|
11
14
|
|
@@ -22,6 +25,9 @@ class Region(BaseModel):
|
|
22
25
|
status: OptStatus
|
23
26
|
|
24
27
|
|
28
|
+
log = logging.getLogger(__name__)
|
29
|
+
|
30
|
+
|
25
31
|
class AWSApiAccount:
|
26
32
|
def __init__(self, client: AccountClient) -> None:
|
27
33
|
self.client = client
|
@@ -30,13 +36,39 @@ class AWSApiAccount:
|
|
30
36
|
self, name: str, title: str, email: str, phone_number: str
|
31
37
|
) -> None:
|
32
38
|
"""Set the security contact for the account."""
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
39
|
+
try:
|
40
|
+
self.client.put_alternate_contact(
|
41
|
+
AlternateContactType="SECURITY",
|
42
|
+
EmailAddress=email,
|
43
|
+
Name=name,
|
44
|
+
Title=title,
|
45
|
+
PhoneNumber=phone_number,
|
46
|
+
)
|
47
|
+
except botocore.exceptions.ClientError as e:
|
48
|
+
if e.response["Error"]["Code"] != "AccessDenied":
|
49
|
+
raise
|
50
|
+
|
51
|
+
# This exception is raised if the user does not have permission to perform this action.
|
52
|
+
# Let's see if the current security contact is already set to the same values.
|
53
|
+
current_contact = self.get_security_contact()
|
54
|
+
if (
|
55
|
+
not current_contact
|
56
|
+
or current_contact["EmailAddress"] != email
|
57
|
+
or current_contact["Name"] != name
|
58
|
+
or current_contact["Title"] != title
|
59
|
+
or current_contact["PhoneNumber"] != phone_number
|
60
|
+
):
|
61
|
+
raise
|
62
|
+
|
63
|
+
def get_security_contact(self) -> AlternateContactTypeDef | None:
|
64
|
+
"""Get the security contact for the account."""
|
65
|
+
try:
|
66
|
+
return self.client.get_alternate_contact(AlternateContactType="SECURITY")[
|
67
|
+
"AlternateContact"
|
68
|
+
]
|
69
|
+
except self.client.exceptions.ResourceNotFoundException:
|
70
|
+
log.warning("Security contact not set.")
|
71
|
+
return None
|
40
72
|
|
41
73
|
def list_regions(self) -> list[Region]:
|
42
74
|
"""List all regions in the account."""
|
@@ -1,5 +1,6 @@
|
|
1
1
|
from typing import TYPE_CHECKING
|
2
2
|
|
3
|
+
import botocore
|
3
4
|
from pydantic import BaseModel, Field
|
4
5
|
|
5
6
|
if TYPE_CHECKING:
|
@@ -40,10 +41,12 @@ class AWSApiIam:
|
|
40
41
|
try:
|
41
42
|
user = self.client.create_user(UserName=user_name)
|
42
43
|
return AWSUser(**user["User"])
|
43
|
-
except
|
44
|
-
|
45
|
-
|
46
|
-
|
44
|
+
except botocore.exceptions.ClientError as e:
|
45
|
+
if e.response["Error"]["Code"] == "EntityAlreadyExists":
|
46
|
+
raise AWSEntityAlreadyExistsError(
|
47
|
+
f"User {user_name} already exists"
|
48
|
+
) from e
|
49
|
+
raise
|
47
50
|
|
48
51
|
def attach_user_policy(self, user_name: str, policy_arn: str) -> None:
|
49
52
|
"""Attach a policy to a user."""
|
@@ -60,8 +63,15 @@ class AWSApiIam:
|
|
60
63
|
"""Set the account alias."""
|
61
64
|
try:
|
62
65
|
self.client.create_account_alias(AccountAlias=account_alias)
|
63
|
-
except
|
64
|
-
if
|
65
|
-
|
66
|
-
|
67
|
-
|
66
|
+
except botocore.exceptions.ClientError as e:
|
67
|
+
if e.response["Error"]["Code"] == "EntityAlreadyExists":
|
68
|
+
if self.get_account_alias() != account_alias:
|
69
|
+
raise ValueError(
|
70
|
+
"Account alias already exists for another AWS account. Choose another one!"
|
71
|
+
) from e
|
72
|
+
elif e.response["Error"]["Code"] == "AccessDenied":
|
73
|
+
# AccessDeniedException can occur if the user does not have permission to create an account alias.
|
74
|
+
# This can happen if the alias is already set and we don't have permission to change it.
|
75
|
+
# If the existing alias is the one we want, we can ignore the error.
|
76
|
+
if self.get_account_alias() != account_alias:
|
77
|
+
raise
|
reconcile/utils/constants.py
CHANGED