qontract-reconcile 0.10.2.dev481__py3-none-any.whl → 0.10.2.dev484__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.dev481.dist-info → qontract_reconcile-0.10.2.dev484.dist-info}/METADATA +1 -1
- {qontract_reconcile-0.10.2.dev481.dist-info → qontract_reconcile-0.10.2.dev484.dist-info}/RECORD +14 -8
- reconcile/cli.py +31 -16
- reconcile/gql_definitions/common/app_interface_clusterrole.py +104 -0
- reconcile/openshift_bindings/__init__.py +0 -0
- reconcile/openshift_bindings/constants.py +7 -0
- reconcile/openshift_bindings/models.py +264 -0
- reconcile/openshift_bindings/openshift_clusterrolebindings.py +129 -0
- reconcile/openshift_bindings/openshift_rolebindings.py +135 -0
- reconcile/openshift_bindings/utils.py +14 -0
- reconcile/openshift_users.py +50 -5
- reconcile/typed_queries/app_interface_clusterroles.py +10 -0
- reconcile/openshift_clusterrolebindings.py +0 -192
- reconcile/openshift_rolebindings.py +0 -323
- {qontract_reconcile-0.10.2.dev481.dist-info → qontract_reconcile-0.10.2.dev484.dist-info}/WHEEL +0 -0
- {qontract_reconcile-0.10.2.dev481.dist-info → qontract_reconcile-0.10.2.dev484.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"""OpenShift RoleBindings integration.
|
|
2
|
+
|
|
3
|
+
Manages namespace-scoped RoleBindings within OpenShift namespaces.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import sys
|
|
7
|
+
from collections.abc import Callable
|
|
8
|
+
from typing import TYPE_CHECKING
|
|
9
|
+
|
|
10
|
+
import reconcile.openshift_base as ob
|
|
11
|
+
from reconcile.openshift_bindings.constants import (
|
|
12
|
+
OPENSHIFT_ROLEBINDINGS_INTEGRATION_NAME,
|
|
13
|
+
)
|
|
14
|
+
from reconcile.openshift_bindings.models import RoleBindingSpec
|
|
15
|
+
from reconcile.openshift_bindings.utils import (
|
|
16
|
+
is_valid_namespace,
|
|
17
|
+
)
|
|
18
|
+
from reconcile.typed_queries.app_interface_roles import get_app_interface_roles
|
|
19
|
+
from reconcile.typed_queries.namespaces import get_namespaces
|
|
20
|
+
from reconcile.utils import expiration
|
|
21
|
+
from reconcile.utils.constants import DEFAULT_THREAD_POOL_SIZE
|
|
22
|
+
from reconcile.utils.defer import defer
|
|
23
|
+
from reconcile.utils.oc import OC_Map
|
|
24
|
+
from reconcile.utils.openshift_resource import ResourceInventory
|
|
25
|
+
from reconcile.utils.runtime.integration import (
|
|
26
|
+
PydanticRunParams,
|
|
27
|
+
QontractReconcileIntegration,
|
|
28
|
+
)
|
|
29
|
+
from reconcile.utils.semver_helper import make_semver
|
|
30
|
+
|
|
31
|
+
if TYPE_CHECKING:
|
|
32
|
+
from reconcile.gql_definitions.common.app_interface_roles import RoleV1
|
|
33
|
+
|
|
34
|
+
QONTRACT_INTEGRATION_VERSION = make_semver(0, 3, 0)
|
|
35
|
+
QONTRACT_INTEGRATION_MANAGED_TYPE = "RoleBinding.rbac.authorization.k8s.io"
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class OpenShiftRoleBindingsIntegrationParams(PydanticRunParams):
|
|
39
|
+
support_role_ref: bool = False
|
|
40
|
+
enforced_user_keys: list[str] | None = None
|
|
41
|
+
thread_pool_size: int = DEFAULT_THREAD_POOL_SIZE
|
|
42
|
+
internal: bool | None = None
|
|
43
|
+
use_jump_host: bool = True
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class OpenShiftRoleBindingsIntegration(
|
|
47
|
+
QontractReconcileIntegration[OpenShiftRoleBindingsIntegrationParams],
|
|
48
|
+
):
|
|
49
|
+
"""Manages RoleBindings within OpenShift namespaces."""
|
|
50
|
+
|
|
51
|
+
@defer
|
|
52
|
+
def run(self, dry_run: bool, defer: Callable | None = None) -> None:
|
|
53
|
+
ri, oc_map = self.fetch_current_state()
|
|
54
|
+
if defer:
|
|
55
|
+
defer(oc_map.cleanup)
|
|
56
|
+
self.fetch_desired_state(
|
|
57
|
+
ri,
|
|
58
|
+
support_role_ref=self.params.support_role_ref,
|
|
59
|
+
enforced_user_keys=self.params.enforced_user_keys,
|
|
60
|
+
allowed_clusters=set(oc_map.clusters()),
|
|
61
|
+
)
|
|
62
|
+
ob.publish_metrics(ri, self.name)
|
|
63
|
+
ob.realize_data(dry_run, oc_map, ri, self.params.thread_pool_size)
|
|
64
|
+
if ri.has_error_registered():
|
|
65
|
+
sys.exit(1)
|
|
66
|
+
|
|
67
|
+
@property
|
|
68
|
+
def integration_version(self) -> str:
|
|
69
|
+
return QONTRACT_INTEGRATION_VERSION
|
|
70
|
+
|
|
71
|
+
@property
|
|
72
|
+
def name(self) -> str:
|
|
73
|
+
return OPENSHIFT_ROLEBINDINGS_INTEGRATION_NAME
|
|
74
|
+
|
|
75
|
+
def fetch_current_state(self) -> tuple[ResourceInventory, OC_Map]:
|
|
76
|
+
"""Fetch current RoleBindings state from namespaces."""
|
|
77
|
+
namespaces = [
|
|
78
|
+
namespace.model_dump(by_alias=True, exclude={"openshift_resources"})
|
|
79
|
+
for namespace in get_namespaces()
|
|
80
|
+
if is_valid_namespace(namespace)
|
|
81
|
+
]
|
|
82
|
+
return ob.fetch_current_state(
|
|
83
|
+
namespaces=namespaces,
|
|
84
|
+
thread_pool_size=self.params.thread_pool_size,
|
|
85
|
+
integration=self.name,
|
|
86
|
+
integration_version=self.integration_version,
|
|
87
|
+
override_managed_types=[QONTRACT_INTEGRATION_MANAGED_TYPE],
|
|
88
|
+
internal=self.params.internal,
|
|
89
|
+
use_jump_host=self.params.use_jump_host,
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
def fetch_desired_state(
|
|
93
|
+
self,
|
|
94
|
+
ri: ResourceInventory | None,
|
|
95
|
+
support_role_ref: bool = False,
|
|
96
|
+
enforced_user_keys: list[str] | None = None,
|
|
97
|
+
allowed_clusters: set[str] | None = None,
|
|
98
|
+
) -> None:
|
|
99
|
+
if allowed_clusters is not None and not allowed_clusters:
|
|
100
|
+
return
|
|
101
|
+
if ri is None:
|
|
102
|
+
return
|
|
103
|
+
roles: list[RoleV1] = expiration.filter(get_app_interface_roles())
|
|
104
|
+
for role in roles:
|
|
105
|
+
rolebindings: list[RoleBindingSpec] = (
|
|
106
|
+
RoleBindingSpec.create_rb_specs_from_role(
|
|
107
|
+
role, enforced_user_keys, support_role_ref
|
|
108
|
+
)
|
|
109
|
+
)
|
|
110
|
+
if allowed_clusters is not None:
|
|
111
|
+
rolebindings = [
|
|
112
|
+
rolebinding
|
|
113
|
+
for rolebinding in rolebindings
|
|
114
|
+
if rolebinding.cluster.name in allowed_clusters
|
|
115
|
+
]
|
|
116
|
+
for rolebinding in rolebindings:
|
|
117
|
+
for oc_resource in rolebinding.get_openshift_resources(
|
|
118
|
+
self.name,
|
|
119
|
+
self.integration_version,
|
|
120
|
+
privileged=rolebinding.privileged,
|
|
121
|
+
):
|
|
122
|
+
if not ri.get_desired(
|
|
123
|
+
rolebinding.cluster.name,
|
|
124
|
+
rolebinding.namespace.name,
|
|
125
|
+
QONTRACT_INTEGRATION_MANAGED_TYPE,
|
|
126
|
+
oc_resource.resource_name,
|
|
127
|
+
):
|
|
128
|
+
ri.add_desired(
|
|
129
|
+
cluster=rolebinding.cluster.name,
|
|
130
|
+
namespace=rolebinding.namespace.name,
|
|
131
|
+
resource_type=QONTRACT_INTEGRATION_MANAGED_TYPE,
|
|
132
|
+
name=oc_resource.resource_name,
|
|
133
|
+
value=oc_resource.resource,
|
|
134
|
+
privileged=oc_resource.privileged,
|
|
135
|
+
)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import reconcile.openshift_base as ob
|
|
2
|
+
from reconcile.gql_definitions.common.app_interface_roles import NamespaceV1
|
|
3
|
+
from reconcile.gql_definitions.common.namespaces import NamespaceV1 as CommonNamespaceV1
|
|
4
|
+
from reconcile.utils.sharding import is_in_shard
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def is_valid_namespace(
|
|
8
|
+
namespace: NamespaceV1 | CommonNamespaceV1,
|
|
9
|
+
) -> bool:
|
|
10
|
+
return (
|
|
11
|
+
bool(namespace.managed_roles)
|
|
12
|
+
and is_in_shard(f"{namespace.cluster.name}/{namespace.name}")
|
|
13
|
+
and not ob.is_namespace_deleted(namespace.model_dump(by_alias=True))
|
|
14
|
+
)
|
reconcile/openshift_users.py
CHANGED
|
@@ -5,23 +5,28 @@ from collections.abc import (
|
|
|
5
5
|
Iterable,
|
|
6
6
|
Mapping,
|
|
7
7
|
)
|
|
8
|
-
from typing import Any
|
|
8
|
+
from typing import TYPE_CHECKING, Any
|
|
9
9
|
|
|
10
10
|
from sretoolbox.utils import threaded
|
|
11
11
|
|
|
12
12
|
from reconcile import (
|
|
13
13
|
openshift_groups,
|
|
14
|
-
openshift_rolebindings,
|
|
15
14
|
)
|
|
15
|
+
|
|
16
|
+
if TYPE_CHECKING:
|
|
17
|
+
from reconcile.gql_definitions.common.app_interface_roles import RoleV1
|
|
16
18
|
from reconcile.gql_definitions.common.clusters_minimal import (
|
|
17
19
|
ClusterAuthOIDCV1,
|
|
18
20
|
ClusterAuthRHIDPV1,
|
|
19
21
|
ClusterV1,
|
|
20
22
|
)
|
|
23
|
+
from reconcile.openshift_bindings.models import RoleBindingSpec
|
|
24
|
+
from reconcile.typed_queries.app_interface_roles import get_app_interface_roles
|
|
21
25
|
from reconcile.typed_queries.app_interface_vault_settings import (
|
|
22
26
|
get_app_interface_vault_settings,
|
|
23
27
|
)
|
|
24
28
|
from reconcile.typed_queries.clusters_minimal import get_clusters_minimal
|
|
29
|
+
from reconcile.utils import expiration
|
|
25
30
|
from reconcile.utils.constants import DEFAULT_THREAD_POOL_SIZE
|
|
26
31
|
from reconcile.utils.defer import defer
|
|
27
32
|
from reconcile.utils.oc_map import (
|
|
@@ -97,15 +102,55 @@ def fetch_current_state(
|
|
|
97
102
|
return oc_map, current_state
|
|
98
103
|
|
|
99
104
|
|
|
105
|
+
def fetch_rolebindings_desired_state(
|
|
106
|
+
allowed_clusters: set[str] | None = None,
|
|
107
|
+
enforced_user_keys: list[str] | None = None,
|
|
108
|
+
) -> list[dict[str, str]]:
|
|
109
|
+
if allowed_clusters is not None and not allowed_clusters:
|
|
110
|
+
return []
|
|
111
|
+
roles: list[RoleV1] = expiration.filter(get_app_interface_roles())
|
|
112
|
+
|
|
113
|
+
users_desired_state: list[dict[str, str]] = [
|
|
114
|
+
user
|
|
115
|
+
for role in roles
|
|
116
|
+
for rolebinding in filter_rolebindings(
|
|
117
|
+
RoleBindingSpec.create_rb_specs_from_role(role, enforced_user_keys),
|
|
118
|
+
allowed_clusters,
|
|
119
|
+
)
|
|
120
|
+
for user in get_users_from_rolebinding_desired_state(rolebinding)
|
|
121
|
+
]
|
|
122
|
+
return users_desired_state
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def get_users_from_rolebinding_desired_state(
|
|
126
|
+
role_binding: RoleBindingSpec,
|
|
127
|
+
) -> list[dict[str, str]]:
|
|
128
|
+
return [
|
|
129
|
+
{"cluster": role_binding.cluster.name, "user": user}
|
|
130
|
+
for user in role_binding.usernames
|
|
131
|
+
]
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def filter_rolebindings(
|
|
135
|
+
rolebindings: list[RoleBindingSpec], allowed_clusters: set[str] | None = None
|
|
136
|
+
) -> list[RoleBindingSpec]:
|
|
137
|
+
if allowed_clusters is not None:
|
|
138
|
+
return [
|
|
139
|
+
rolebinding
|
|
140
|
+
for rolebinding in rolebindings
|
|
141
|
+
if rolebinding.cluster.name in allowed_clusters
|
|
142
|
+
]
|
|
143
|
+
return rolebindings
|
|
144
|
+
|
|
145
|
+
|
|
100
146
|
def fetch_desired_state(
|
|
101
147
|
oc_map: OCMap | None, enforced_user_keys: Any = None
|
|
102
148
|
) -> list[Any]:
|
|
103
149
|
desired_state = []
|
|
104
150
|
filtered_clusters = oc_map.clusters() if oc_map else None
|
|
105
|
-
flat_rolebindings_desired_state =
|
|
106
|
-
ri=None,
|
|
107
|
-
enforced_user_keys=enforced_user_keys,
|
|
151
|
+
flat_rolebindings_desired_state = fetch_rolebindings_desired_state(
|
|
108
152
|
allowed_clusters=set(filtered_clusters) if filtered_clusters else None,
|
|
153
|
+
enforced_user_keys=enforced_user_keys,
|
|
109
154
|
)
|
|
110
155
|
desired_state.extend(flat_rolebindings_desired_state)
|
|
111
156
|
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
from reconcile.gql_definitions.common.app_interface_clusterrole import (
|
|
2
|
+
RoleV1,
|
|
3
|
+
query,
|
|
4
|
+
)
|
|
5
|
+
from reconcile.utils import gql
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def get_app_interface_clusterroles() -> list[RoleV1]:
|
|
9
|
+
data = query(gql.get_api().query)
|
|
10
|
+
return list(data.cluster_roles or [])
|
|
@@ -1,192 +0,0 @@
|
|
|
1
|
-
import contextlib
|
|
2
|
-
import sys
|
|
3
|
-
from collections.abc import Callable
|
|
4
|
-
|
|
5
|
-
import reconcile.openshift_base as ob
|
|
6
|
-
from reconcile import queries
|
|
7
|
-
from reconcile.utils import (
|
|
8
|
-
expiration,
|
|
9
|
-
gql,
|
|
10
|
-
)
|
|
11
|
-
from reconcile.utils.constants import DEFAULT_THREAD_POOL_SIZE
|
|
12
|
-
from reconcile.utils.defer import defer
|
|
13
|
-
from reconcile.utils.openshift_resource import OpenshiftResource as OR
|
|
14
|
-
from reconcile.utils.openshift_resource import (
|
|
15
|
-
ResourceInventory,
|
|
16
|
-
ResourceKeyExistsError,
|
|
17
|
-
)
|
|
18
|
-
from reconcile.utils.semver_helper import make_semver
|
|
19
|
-
|
|
20
|
-
ROLES_QUERY = """
|
|
21
|
-
{
|
|
22
|
-
roles: roles_v1 {
|
|
23
|
-
name
|
|
24
|
-
users {
|
|
25
|
-
org_username
|
|
26
|
-
github_username
|
|
27
|
-
}
|
|
28
|
-
bots {
|
|
29
|
-
openshift_serviceaccount
|
|
30
|
-
}
|
|
31
|
-
access {
|
|
32
|
-
cluster {
|
|
33
|
-
name
|
|
34
|
-
auth {
|
|
35
|
-
service
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
clusterRole
|
|
39
|
-
}
|
|
40
|
-
expirationDate
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
"""
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
QONTRACT_INTEGRATION = "openshift-clusterrolebindings"
|
|
47
|
-
QONTRACT_INTEGRATION_VERSION = make_semver(0, 1, 0)
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
def construct_user_oc_resource(role: str, user: str) -> tuple[OR, str]:
|
|
51
|
-
name = f"{role}-{user}"
|
|
52
|
-
# Note: In OpenShift 4.x this resource is in rbac.authorization.k8s.io/v1
|
|
53
|
-
body = {
|
|
54
|
-
"apiVersion": "rbac.authorization.k8s.io/v1",
|
|
55
|
-
"kind": "ClusterRoleBinding",
|
|
56
|
-
"metadata": {"name": name},
|
|
57
|
-
"roleRef": {"name": role, "kind": "ClusterRole"},
|
|
58
|
-
"subjects": [{"kind": "User", "name": user}],
|
|
59
|
-
}
|
|
60
|
-
return (
|
|
61
|
-
OR(
|
|
62
|
-
body, QONTRACT_INTEGRATION, QONTRACT_INTEGRATION_VERSION, error_details=name
|
|
63
|
-
),
|
|
64
|
-
name,
|
|
65
|
-
)
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
def construct_sa_oc_resource(role: str, namespace: str, sa_name: str) -> tuple[OR, str]:
|
|
69
|
-
name = f"{role}-{namespace}-{sa_name}"
|
|
70
|
-
# Note: In OpenShift 4.x this resource is in rbac.authorization.k8s.io/v1
|
|
71
|
-
body = {
|
|
72
|
-
"apiVersion": "rbac.authorization.k8s.io/v1",
|
|
73
|
-
"kind": "ClusterRoleBinding",
|
|
74
|
-
"metadata": {"name": name},
|
|
75
|
-
"roleRef": {"name": role, "kind": "ClusterRole"},
|
|
76
|
-
"subjects": [
|
|
77
|
-
{"kind": "ServiceAccount", "name": sa_name, "namespace": namespace}
|
|
78
|
-
],
|
|
79
|
-
}
|
|
80
|
-
return (
|
|
81
|
-
OR(
|
|
82
|
-
body, QONTRACT_INTEGRATION, QONTRACT_INTEGRATION_VERSION, error_details=name
|
|
83
|
-
),
|
|
84
|
-
name,
|
|
85
|
-
)
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
def fetch_desired_state(
|
|
89
|
-
ri: ResourceInventory | None, oc_map: ob.ClusterMap
|
|
90
|
-
) -> list[dict[str, str]]:
|
|
91
|
-
gqlapi = gql.get_api()
|
|
92
|
-
roles: list[dict] = expiration.filter(gqlapi.query(ROLES_QUERY)["roles"])
|
|
93
|
-
users_desired_state = []
|
|
94
|
-
# set namespace to something indicative
|
|
95
|
-
namespace_cluster_scope = "cluster"
|
|
96
|
-
for role in roles:
|
|
97
|
-
permissions = [
|
|
98
|
-
{"cluster": a["cluster"], "cluster_role": a["clusterRole"]}
|
|
99
|
-
for a in role["access"] or []
|
|
100
|
-
if a["cluster"] and a["clusterRole"]
|
|
101
|
-
]
|
|
102
|
-
if not permissions:
|
|
103
|
-
continue
|
|
104
|
-
|
|
105
|
-
service_accounts = [
|
|
106
|
-
bot["openshift_serviceaccount"]
|
|
107
|
-
for bot in role["bots"]
|
|
108
|
-
if bot.get("openshift_serviceaccount")
|
|
109
|
-
]
|
|
110
|
-
|
|
111
|
-
for permission in permissions:
|
|
112
|
-
cluster_info = permission["cluster"]
|
|
113
|
-
cluster = cluster_info["name"]
|
|
114
|
-
if not oc_map.get(cluster):
|
|
115
|
-
continue
|
|
116
|
-
|
|
117
|
-
# get username keys based on used IDPs
|
|
118
|
-
user_keys = ob.determine_user_keys_for_access(cluster, cluster_info["auth"])
|
|
119
|
-
for user in role["users"]:
|
|
120
|
-
for username in {user[user_key] for user_key in user_keys}:
|
|
121
|
-
# used by openshift-users and github integrations
|
|
122
|
-
# this is just to simplify things a bit on the their side
|
|
123
|
-
users_desired_state.append({"cluster": cluster, "user": username})
|
|
124
|
-
if ri is None:
|
|
125
|
-
continue
|
|
126
|
-
oc_resource, resource_name = construct_user_oc_resource(
|
|
127
|
-
permission["cluster_role"], username
|
|
128
|
-
)
|
|
129
|
-
with contextlib.suppress(ResourceKeyExistsError):
|
|
130
|
-
# a user may have a Role assigned to them
|
|
131
|
-
# from multiple app-interface roles
|
|
132
|
-
ri.add_desired(
|
|
133
|
-
cluster,
|
|
134
|
-
namespace_cluster_scope,
|
|
135
|
-
"ClusterRoleBinding.rbac.authorization.k8s.io",
|
|
136
|
-
resource_name,
|
|
137
|
-
oc_resource,
|
|
138
|
-
)
|
|
139
|
-
|
|
140
|
-
for sa in service_accounts:
|
|
141
|
-
if ri is None:
|
|
142
|
-
continue
|
|
143
|
-
namespace, sa_name = sa.split("/")
|
|
144
|
-
oc_resource, resource_name = construct_sa_oc_resource(
|
|
145
|
-
permission["cluster_role"], namespace, sa_name
|
|
146
|
-
)
|
|
147
|
-
|
|
148
|
-
with contextlib.suppress(ResourceKeyExistsError):
|
|
149
|
-
# a ServiceAccount may have a Role assigned to it
|
|
150
|
-
# from multiple app-interface roles
|
|
151
|
-
ri.add_desired(
|
|
152
|
-
cluster,
|
|
153
|
-
namespace_cluster_scope,
|
|
154
|
-
"ClusterRoleBinding.rbac.authorization.k8s.io",
|
|
155
|
-
resource_name,
|
|
156
|
-
oc_resource,
|
|
157
|
-
)
|
|
158
|
-
|
|
159
|
-
return users_desired_state
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
@defer
|
|
163
|
-
def run(
|
|
164
|
-
dry_run: bool,
|
|
165
|
-
thread_pool_size: int = DEFAULT_THREAD_POOL_SIZE,
|
|
166
|
-
internal: bool | None = None,
|
|
167
|
-
use_jump_host: bool = True,
|
|
168
|
-
defer: Callable | None = None,
|
|
169
|
-
) -> None:
|
|
170
|
-
clusters = [
|
|
171
|
-
cluster_info
|
|
172
|
-
for cluster_info in queries.get_clusters()
|
|
173
|
-
if cluster_info.get("managedClusterRoles")
|
|
174
|
-
and cluster_info.get("automationToken")
|
|
175
|
-
]
|
|
176
|
-
ri, oc_map = ob.fetch_current_state(
|
|
177
|
-
clusters=clusters,
|
|
178
|
-
thread_pool_size=thread_pool_size,
|
|
179
|
-
integration=QONTRACT_INTEGRATION,
|
|
180
|
-
integration_version=QONTRACT_INTEGRATION_VERSION,
|
|
181
|
-
override_managed_types=["ClusterRoleBinding.rbac.authorization.k8s.io"],
|
|
182
|
-
internal=internal,
|
|
183
|
-
use_jump_host=use_jump_host,
|
|
184
|
-
)
|
|
185
|
-
if defer:
|
|
186
|
-
defer(oc_map.cleanup)
|
|
187
|
-
fetch_desired_state(ri, oc_map)
|
|
188
|
-
ob.publish_metrics(ri, QONTRACT_INTEGRATION)
|
|
189
|
-
ob.realize_data(dry_run, oc_map, ri, thread_pool_size)
|
|
190
|
-
|
|
191
|
-
if ri.has_error_registered():
|
|
192
|
-
sys.exit(1)
|