qontract-reconcile 0.10.1rc506__py3-none-any.whl → 0.10.1rc507__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.1rc506.dist-info → qontract_reconcile-0.10.1rc507.dist-info}/METADATA +1 -1
- {qontract_reconcile-0.10.1rc506.dist-info → qontract_reconcile-0.10.1rc507.dist-info}/RECORD +11 -9
- reconcile/acs_policies.py +232 -0
- reconcile/acs_rbac.py +12 -33
- reconcile/cli.py +11 -0
- reconcile/gql_definitions/acs/acs_policies.py +159 -0
- reconcile/test/test_acs_policies.py +444 -0
- reconcile/test/test_acs_rbac.py +51 -51
- reconcile/utils/acs_api.py +0 -326
- {qontract_reconcile-0.10.1rc506.dist-info → qontract_reconcile-0.10.1rc507.dist-info}/WHEEL +0 -0
- {qontract_reconcile-0.10.1rc506.dist-info → qontract_reconcile-0.10.1rc507.dist-info}/entry_points.txt +0 -0
- {qontract_reconcile-0.10.1rc506.dist-info → qontract_reconcile-0.10.1rc507.dist-info}/top_level.txt +0 -0
reconcile/test/test_acs_rbac.py
CHANGED
@@ -19,7 +19,7 @@ from reconcile.gql_definitions.acs.acs_rbac import (
|
|
19
19
|
RoleV1,
|
20
20
|
UserV1,
|
21
21
|
)
|
22
|
-
from reconcile.utils import
|
22
|
+
from reconcile.utils.acs import rbac
|
23
23
|
|
24
24
|
AUTH_PROVIDER_ID = "6a41743c-792b-11ee-b962-0242ac120002"
|
25
25
|
|
@@ -196,9 +196,9 @@ def modeled_acs_roles() -> list[AcsRole]:
|
|
196
196
|
|
197
197
|
|
198
198
|
@pytest.fixture
|
199
|
-
def api_response_roles() -> list[
|
199
|
+
def api_response_roles() -> list[rbac.Role]:
|
200
200
|
return [
|
201
|
-
|
201
|
+
rbac.Role(
|
202
202
|
api_data={
|
203
203
|
"name": "app-sre-acs-admin",
|
204
204
|
"permissionSetId": "1",
|
@@ -207,7 +207,7 @@ def api_response_roles() -> list[acs_api.Role]:
|
|
207
207
|
"system_default": False,
|
208
208
|
}
|
209
209
|
),
|
210
|
-
|
210
|
+
rbac.Role(
|
211
211
|
api_data={
|
212
212
|
"name": "cluster-analyst",
|
213
213
|
"permissionSetId": "2",
|
@@ -216,7 +216,7 @@ def api_response_roles() -> list[acs_api.Role]:
|
|
216
216
|
"system_default": False,
|
217
217
|
}
|
218
218
|
),
|
219
|
-
|
219
|
+
rbac.Role(
|
220
220
|
api_data={
|
221
221
|
"name": "service-vuln-admin",
|
222
222
|
"permissionSetId": "3",
|
@@ -229,9 +229,9 @@ def api_response_roles() -> list[acs_api.Role]:
|
|
229
229
|
|
230
230
|
|
231
231
|
@pytest.fixture
|
232
|
-
def api_response_groups() -> list[
|
232
|
+
def api_response_groups() -> list[rbac.Group]:
|
233
233
|
return [
|
234
|
-
|
234
|
+
rbac.Group(
|
235
235
|
api_data={
|
236
236
|
"roleName": "app-sre-acs-admin",
|
237
237
|
"props": {
|
@@ -242,7 +242,7 @@ def api_response_groups() -> list[acs_api.Group]:
|
|
242
242
|
},
|
243
243
|
}
|
244
244
|
),
|
245
|
-
|
245
|
+
rbac.Group(
|
246
246
|
api_data={
|
247
247
|
"roleName": "app-sre-acs-admin",
|
248
248
|
"props": {
|
@@ -253,7 +253,7 @@ def api_response_groups() -> list[acs_api.Group]:
|
|
253
253
|
},
|
254
254
|
}
|
255
255
|
),
|
256
|
-
|
256
|
+
rbac.Group(
|
257
257
|
api_data={
|
258
258
|
"roleName": "cluster-analyst",
|
259
259
|
"props": {
|
@@ -264,7 +264,7 @@ def api_response_groups() -> list[acs_api.Group]:
|
|
264
264
|
},
|
265
265
|
}
|
266
266
|
),
|
267
|
-
|
267
|
+
rbac.Group(
|
268
268
|
api_data={
|
269
269
|
"roleName": "cluster-analyst",
|
270
270
|
"props": {
|
@@ -275,7 +275,7 @@ def api_response_groups() -> list[acs_api.Group]:
|
|
275
275
|
},
|
276
276
|
}
|
277
277
|
),
|
278
|
-
|
278
|
+
rbac.Group(
|
279
279
|
api_data={
|
280
280
|
"roleName": "service-vuln-admin",
|
281
281
|
"props": {
|
@@ -290,9 +290,9 @@ def api_response_groups() -> list[acs_api.Group]:
|
|
290
290
|
|
291
291
|
|
292
292
|
@pytest.fixture
|
293
|
-
def api_response_access_scopes() -> list[
|
293
|
+
def api_response_access_scopes() -> list[rbac.AccessScope]:
|
294
294
|
return [
|
295
|
-
|
295
|
+
rbac.AccessScope(
|
296
296
|
api_data={
|
297
297
|
"id": "1",
|
298
298
|
"name": "Unrestricted",
|
@@ -300,7 +300,7 @@ def api_response_access_scopes() -> list[acs_api.AccessScope]:
|
|
300
300
|
"rules": None,
|
301
301
|
}
|
302
302
|
),
|
303
|
-
|
303
|
+
rbac.AccessScope(
|
304
304
|
api_data={
|
305
305
|
"id": "2",
|
306
306
|
"name": "cluster-analyst",
|
@@ -311,7 +311,7 @@ def api_response_access_scopes() -> list[acs_api.AccessScope]:
|
|
311
311
|
},
|
312
312
|
}
|
313
313
|
),
|
314
|
-
|
314
|
+
rbac.AccessScope(
|
315
315
|
api_data={
|
316
316
|
"id": "3",
|
317
317
|
"name": "service-vuln-admin",
|
@@ -335,21 +335,21 @@ def api_response_access_scopes() -> list[acs_api.AccessScope]:
|
|
335
335
|
|
336
336
|
|
337
337
|
@pytest.fixture
|
338
|
-
def api_response_permission_sets() -> list[
|
338
|
+
def api_response_permission_sets() -> list[rbac.PermissionSet]:
|
339
339
|
return [
|
340
|
-
|
340
|
+
rbac.PermissionSet(
|
341
341
|
api_data={
|
342
342
|
"id": "1",
|
343
343
|
"name": "Admin",
|
344
344
|
}
|
345
345
|
),
|
346
|
-
|
346
|
+
rbac.PermissionSet(
|
347
347
|
api_data={
|
348
348
|
"id": "2",
|
349
349
|
"name": "Analyst",
|
350
350
|
}
|
351
351
|
),
|
352
|
-
|
352
|
+
rbac.PermissionSet(
|
353
353
|
api_data={
|
354
354
|
"id": "3",
|
355
355
|
"name": "Vulnerability Management Admin",
|
@@ -374,15 +374,15 @@ def test_get_desired_state(
|
|
374
374
|
|
375
375
|
def test_get_current_state(
|
376
376
|
modeled_acs_roles: list[AcsRole],
|
377
|
-
api_response_roles: list[
|
378
|
-
api_response_groups: list[
|
379
|
-
api_response_access_scopes: list[
|
380
|
-
api_response_permission_sets: list[
|
377
|
+
api_response_roles: list[rbac.Role],
|
378
|
+
api_response_groups: list[rbac.Group],
|
379
|
+
api_response_access_scopes: list[rbac.AccessScope],
|
380
|
+
api_response_permission_sets: list[rbac.PermissionSet],
|
381
381
|
):
|
382
382
|
integration = AcsRbacIntegration()
|
383
383
|
result = integration.get_current_state(
|
384
384
|
AUTH_PROVIDER_ID,
|
385
|
-
|
385
|
+
rbac.RbacResources(
|
386
386
|
roles=api_response_roles,
|
387
387
|
access_scopes=api_response_access_scopes,
|
388
388
|
groups=api_response_groups,
|
@@ -396,8 +396,8 @@ def test_get_current_state(
|
|
396
396
|
def test_add_rbac_dry_run(
|
397
397
|
mocker: MockerFixture,
|
398
398
|
modeled_acs_roles: list[AcsRole],
|
399
|
-
api_response_access_scopes: list[
|
400
|
-
api_response_permission_sets: list[
|
399
|
+
api_response_access_scopes: list[rbac.AccessScope],
|
400
|
+
api_response_permission_sets: list[rbac.PermissionSet],
|
401
401
|
):
|
402
402
|
dry_run = True
|
403
403
|
desired = modeled_acs_roles
|
@@ -407,7 +407,7 @@ def test_add_rbac_dry_run(
|
|
407
407
|
|
408
408
|
acs_mock = Mock()
|
409
409
|
|
410
|
-
rbac_api_resources =
|
410
|
+
rbac_api_resources = rbac.RbacResources(
|
411
411
|
roles=[],
|
412
412
|
access_scopes=current_access_scopes,
|
413
413
|
groups=[],
|
@@ -437,8 +437,8 @@ def test_add_rbac_dry_run(
|
|
437
437
|
def test_add_rbac(
|
438
438
|
mocker: MockerFixture,
|
439
439
|
modeled_acs_roles: list[AcsRole],
|
440
|
-
api_response_access_scopes: list[
|
441
|
-
api_response_permission_sets: list[
|
440
|
+
api_response_access_scopes: list[rbac.AccessScope],
|
441
|
+
api_response_permission_sets: list[rbac.PermissionSet],
|
442
442
|
):
|
443
443
|
dry_run = False
|
444
444
|
desired = modeled_acs_roles
|
@@ -448,7 +448,7 @@ def test_add_rbac(
|
|
448
448
|
|
449
449
|
acs_mock = Mock()
|
450
450
|
|
451
|
-
rbac_api_resources =
|
451
|
+
rbac_api_resources = rbac.RbacResources(
|
452
452
|
roles=[],
|
453
453
|
access_scopes=current_access_scopes,
|
454
454
|
groups=[],
|
@@ -488,7 +488,7 @@ def test_add_rbac(
|
|
488
488
|
])
|
489
489
|
acs_mock.create_group_batch.assert_has_calls([
|
490
490
|
mocker.call([
|
491
|
-
|
491
|
+
rbac.AcsRbacApi.GroupAdd(
|
492
492
|
role_name=desired[2].name,
|
493
493
|
key=a.key,
|
494
494
|
value=a.value,
|
@@ -502,8 +502,8 @@ def test_add_rbac(
|
|
502
502
|
def test_delete_rbac_dry_run(
|
503
503
|
mocker: MockerFixture,
|
504
504
|
modeled_acs_roles: list[AcsRole],
|
505
|
-
api_response_access_scopes: list[
|
506
|
-
api_response_groups: list[
|
505
|
+
api_response_access_scopes: list[rbac.AccessScope],
|
506
|
+
api_response_groups: list[rbac.Group],
|
507
507
|
):
|
508
508
|
dry_run = True
|
509
509
|
current = modeled_acs_roles
|
@@ -511,7 +511,7 @@ def test_delete_rbac_dry_run(
|
|
511
511
|
|
512
512
|
acs_mock = Mock()
|
513
513
|
|
514
|
-
rbac_api_resources =
|
514
|
+
rbac_api_resources = rbac.RbacResources(
|
515
515
|
roles=[],
|
516
516
|
access_scopes=api_response_access_scopes,
|
517
517
|
groups=api_response_groups,
|
@@ -539,8 +539,8 @@ def test_delete_rbac_dry_run(
|
|
539
539
|
def test_delete_rbac(
|
540
540
|
mocker: MockerFixture,
|
541
541
|
modeled_acs_roles: list[AcsRole],
|
542
|
-
api_response_access_scopes: list[
|
543
|
-
api_response_groups: list[
|
542
|
+
api_response_access_scopes: list[rbac.AccessScope],
|
543
|
+
api_response_groups: list[rbac.Group],
|
544
544
|
):
|
545
545
|
dry_run = False
|
546
546
|
current = modeled_acs_roles
|
@@ -550,7 +550,7 @@ def test_delete_rbac(
|
|
550
550
|
|
551
551
|
acs_mock = Mock()
|
552
552
|
|
553
|
-
rbac_api_resources =
|
553
|
+
rbac_api_resources = rbac.RbacResources(
|
554
554
|
roles=[],
|
555
555
|
access_scopes=api_response_access_scopes,
|
556
556
|
groups=api_response_groups,
|
@@ -582,9 +582,9 @@ def test_delete_rbac(
|
|
582
582
|
def test_update_rbac_groups_only(
|
583
583
|
mocker: MockerFixture,
|
584
584
|
modeled_acs_roles: list[AcsRole],
|
585
|
-
api_response_access_scopes: list[
|
586
|
-
api_response_permission_sets: list[
|
587
|
-
api_response_groups: list[
|
585
|
+
api_response_access_scopes: list[rbac.AccessScope],
|
586
|
+
api_response_permission_sets: list[rbac.PermissionSet],
|
587
|
+
api_response_groups: list[rbac.Group],
|
588
588
|
):
|
589
589
|
dry_run = False
|
590
590
|
desired = modeled_acs_roles
|
@@ -597,7 +597,7 @@ def test_update_rbac_groups_only(
|
|
597
597
|
|
598
598
|
acs_mock = Mock()
|
599
599
|
|
600
|
-
rbac_api_resources =
|
600
|
+
rbac_api_resources = rbac.RbacResources(
|
601
601
|
roles=[],
|
602
602
|
access_scopes=api_response_access_scopes,
|
603
603
|
groups=current_groups,
|
@@ -621,7 +621,7 @@ def test_update_rbac_groups_only(
|
|
621
621
|
mocker.call(
|
622
622
|
[current_groups[0]],
|
623
623
|
[
|
624
|
-
|
624
|
+
rbac.AcsRbacApi.GroupAdd(
|
625
625
|
role_name=desired[0].name,
|
626
626
|
key=desired[0].assignments[0].key,
|
627
627
|
value=desired[0].assignments[0].value,
|
@@ -638,9 +638,9 @@ def test_update_rbac_groups_only(
|
|
638
638
|
def test_full_reconcile(
|
639
639
|
mocker: MockerFixture,
|
640
640
|
modeled_acs_roles: list[AcsRole],
|
641
|
-
api_response_access_scopes: list[
|
642
|
-
api_response_permission_sets: list[
|
643
|
-
api_response_groups: list[
|
641
|
+
api_response_access_scopes: list[rbac.AccessScope],
|
642
|
+
api_response_permission_sets: list[rbac.PermissionSet],
|
643
|
+
api_response_groups: list[rbac.Group],
|
644
644
|
):
|
645
645
|
dry_run = False
|
646
646
|
|
@@ -674,7 +674,7 @@ def test_full_reconcile(
|
|
674
674
|
|
675
675
|
acs_mock = Mock()
|
676
676
|
|
677
|
-
rbac_api_resources =
|
677
|
+
rbac_api_resources = rbac.RbacResources(
|
678
678
|
roles=[],
|
679
679
|
access_scopes=current_access_scopes,
|
680
680
|
groups=api_response_groups,
|
@@ -710,7 +710,7 @@ def test_full_reconcile(
|
|
710
710
|
])
|
711
711
|
acs_mock.create_group_batch.assert_has_calls([
|
712
712
|
mocker.call([
|
713
|
-
|
713
|
+
rbac.AcsRbacApi.GroupAdd(
|
714
714
|
role_name=desired[2].name,
|
715
715
|
key=a.key,
|
716
716
|
value=a.value,
|
@@ -755,9 +755,9 @@ def test_full_reconcile(
|
|
755
755
|
def test_full_reconcile_with_errors(
|
756
756
|
mocker: MockerFixture,
|
757
757
|
modeled_acs_roles: list[AcsRole],
|
758
|
-
api_response_access_scopes: list[
|
759
|
-
api_response_permission_sets: list[
|
760
|
-
api_response_groups: list[
|
758
|
+
api_response_access_scopes: list[rbac.AccessScope],
|
759
|
+
api_response_permission_sets: list[rbac.PermissionSet],
|
760
|
+
api_response_groups: list[rbac.Group],
|
761
761
|
):
|
762
762
|
dry_run = False
|
763
763
|
|
@@ -790,7 +790,7 @@ def test_full_reconcile_with_errors(
|
|
790
790
|
|
791
791
|
acs_mock = Mock()
|
792
792
|
|
793
|
-
rbac_api_resources =
|
793
|
+
rbac_api_resources = rbac.RbacResources(
|
794
794
|
roles=[],
|
795
795
|
access_scopes=current_access_scopes,
|
796
796
|
groups=api_response_groups,
|
reconcile/utils/acs_api.py
DELETED
@@ -1,326 +0,0 @@
|
|
1
|
-
from typing import (
|
2
|
-
Any,
|
3
|
-
Optional,
|
4
|
-
Self,
|
5
|
-
)
|
6
|
-
|
7
|
-
import requests
|
8
|
-
from pydantic import BaseModel
|
9
|
-
|
10
|
-
|
11
|
-
class Role(BaseModel):
|
12
|
-
name: str
|
13
|
-
permission_set_id: str
|
14
|
-
access_scope_id: str
|
15
|
-
description: str
|
16
|
-
system_default: bool
|
17
|
-
|
18
|
-
def __init__(self, api_data: Any) -> None:
|
19
|
-
# attributes defined within stackrox(ACS) API for GET /v1/roles
|
20
|
-
check_len_attributes(
|
21
|
-
["name", "permissionSetId", "accessScopeId"],
|
22
|
-
api_data,
|
23
|
-
)
|
24
|
-
|
25
|
-
# traits is populated for system default resources and contains `origin: DEFAULT`
|
26
|
-
# this attribute is used to ignore such resources from reconciliation
|
27
|
-
traits = api_data.get("traits")
|
28
|
-
is_default = traits is not None and traits.get("origin") == "DEFAULT"
|
29
|
-
|
30
|
-
super().__init__(
|
31
|
-
name=api_data["name"],
|
32
|
-
permission_set_id=api_data["permissionSetId"],
|
33
|
-
access_scope_id=api_data["accessScopeId"],
|
34
|
-
description=api_data.get("description", ""),
|
35
|
-
system_default=is_default,
|
36
|
-
)
|
37
|
-
|
38
|
-
|
39
|
-
class Group(BaseModel):
|
40
|
-
id: str
|
41
|
-
role_name: str
|
42
|
-
auth_provider_id: str
|
43
|
-
key: str
|
44
|
-
value: str
|
45
|
-
|
46
|
-
def __init__(self, api_data: Any) -> None:
|
47
|
-
# attributes defined within stackrox(ACS) API for GET /v1/groups
|
48
|
-
check_len_attributes(["roleName", "props"], api_data)
|
49
|
-
if api_data["roleName"] != "None":
|
50
|
-
check_len_attributes(
|
51
|
-
["id", "authProviderId", "key", "value"], api_data["props"]
|
52
|
-
)
|
53
|
-
else:
|
54
|
-
# it is valid for the default None group to contain empty key/value
|
55
|
-
check_len_attributes(["id", "authProviderId"], api_data["props"])
|
56
|
-
|
57
|
-
super().__init__(
|
58
|
-
role_name=api_data["roleName"],
|
59
|
-
id=api_data["props"]["id"],
|
60
|
-
auth_provider_id=api_data["props"]["authProviderId"],
|
61
|
-
key=api_data["props"]["key"],
|
62
|
-
value=api_data["props"]["value"],
|
63
|
-
)
|
64
|
-
|
65
|
-
|
66
|
-
class AccessScope(BaseModel):
|
67
|
-
id: str
|
68
|
-
name: str
|
69
|
-
description: str
|
70
|
-
clusters: list[str]
|
71
|
-
namespaces: list[dict[str, str]]
|
72
|
-
|
73
|
-
def __init__(self, api_data: Any) -> None:
|
74
|
-
# attributes defined within stackrox(ACS) API for GET /v1/simpleaccessscopes/{id}
|
75
|
-
unrestricted = False
|
76
|
-
check_len_attributes(["id", "name"], api_data)
|
77
|
-
|
78
|
-
# it is valid for the default Unrestricted access scope to have null 'rules'
|
79
|
-
unrestricted = api_data["name"] == "Unrestricted"
|
80
|
-
if not unrestricted:
|
81
|
-
check_len_attributes(["rules"], api_data)
|
82
|
-
|
83
|
-
super().__init__(
|
84
|
-
id=api_data["id"],
|
85
|
-
name=api_data["name"],
|
86
|
-
clusters=[]
|
87
|
-
if unrestricted
|
88
|
-
else api_data["rules"].get("includedClusters", []),
|
89
|
-
namespaces=[]
|
90
|
-
if unrestricted
|
91
|
-
else api_data["rules"].get("includedNamespaces", []),
|
92
|
-
description=api_data.get("description", ""),
|
93
|
-
)
|
94
|
-
|
95
|
-
|
96
|
-
class PermissionSet(BaseModel):
|
97
|
-
id: str
|
98
|
-
name: str
|
99
|
-
|
100
|
-
def __init__(self, api_data: Any) -> None:
|
101
|
-
# attributes defined within stackrox(ACS) API for GET /v1/permissionsets/{id}
|
102
|
-
check_len_attributes(["id", "name"], api_data)
|
103
|
-
|
104
|
-
super().__init__(id=api_data["id"], name=api_data["name"])
|
105
|
-
|
106
|
-
|
107
|
-
class RbacResources(BaseModel):
|
108
|
-
roles: list[Role]
|
109
|
-
access_scopes: list[AccessScope]
|
110
|
-
groups: list[Group]
|
111
|
-
permission_sets: list[PermissionSet]
|
112
|
-
|
113
|
-
|
114
|
-
def check_len_attributes(attrs: list[Any], api_data: Any) -> None:
|
115
|
-
# generic attribute check function for expected types with valid len()
|
116
|
-
for attr in attrs:
|
117
|
-
value = api_data.get(attr)
|
118
|
-
if value is None or len(value) == 0:
|
119
|
-
raise ValueError(
|
120
|
-
f"Attribute '{attr}' must exist and not be empty\n\t{api_data}"
|
121
|
-
)
|
122
|
-
|
123
|
-
|
124
|
-
class AcsApi:
|
125
|
-
def __init__(
|
126
|
-
self,
|
127
|
-
instance: Any,
|
128
|
-
timeout: int = 30,
|
129
|
-
) -> None:
|
130
|
-
self.base_url = instance["url"]
|
131
|
-
self.token = instance["token"]
|
132
|
-
self.timeout = timeout
|
133
|
-
self.session = requests.Session()
|
134
|
-
|
135
|
-
def __enter__(self) -> Self:
|
136
|
-
return self
|
137
|
-
|
138
|
-
def __exit__(self, exc_type: Any, exc_value: Any, traceback: Any) -> None:
|
139
|
-
self.session.close()
|
140
|
-
|
141
|
-
def generic_request(
|
142
|
-
self, path: str, verb: str, json: Optional[Any] = None
|
143
|
-
) -> requests.Response:
|
144
|
-
url = f"{self.base_url}{path}"
|
145
|
-
headers = {
|
146
|
-
"Authorization": f"Bearer {self.token}",
|
147
|
-
"Content-Type": "application/json",
|
148
|
-
}
|
149
|
-
|
150
|
-
response = self.session.request(
|
151
|
-
verb,
|
152
|
-
url,
|
153
|
-
headers=headers,
|
154
|
-
json=json,
|
155
|
-
timeout=self.timeout,
|
156
|
-
)
|
157
|
-
|
158
|
-
response.raise_for_status()
|
159
|
-
return response
|
160
|
-
|
161
|
-
def get_roles(self) -> list[Role]:
|
162
|
-
response = self.generic_request("/v1/roles", "GET")
|
163
|
-
return [Role(r) for r in response.json()["roles"]]
|
164
|
-
|
165
|
-
def create_role(
|
166
|
-
self, name: str, desc: str, permission_set_id: str, access_scope_id: str
|
167
|
-
) -> None:
|
168
|
-
json = {
|
169
|
-
"name": name,
|
170
|
-
"description": desc,
|
171
|
-
"permissionSetId": permission_set_id,
|
172
|
-
"accessScopeId": access_scope_id,
|
173
|
-
}
|
174
|
-
|
175
|
-
self.generic_request(f"/v1/roles/{name}", "POST", json)
|
176
|
-
|
177
|
-
def update_role(
|
178
|
-
self, name: str, desc: str, permission_set_id: str, access_scope_id: str
|
179
|
-
) -> None:
|
180
|
-
json = {
|
181
|
-
"name": name,
|
182
|
-
"description": desc,
|
183
|
-
"permissionSetId": permission_set_id,
|
184
|
-
"accessScopeId": access_scope_id,
|
185
|
-
}
|
186
|
-
|
187
|
-
self.generic_request(f"/v1/roles/{name}", "PUT", json)
|
188
|
-
|
189
|
-
def delete_role(self, name: str) -> None:
|
190
|
-
self.generic_request(f"/v1/roles/{name}", "DELETE")
|
191
|
-
|
192
|
-
def get_groups(self) -> list[Group]:
|
193
|
-
response = self.generic_request("/v1/groups", "GET")
|
194
|
-
return [Group(g) for g in response.json()["groups"]]
|
195
|
-
|
196
|
-
class GroupAdd(BaseModel):
|
197
|
-
role_name: str
|
198
|
-
key: str
|
199
|
-
value: str
|
200
|
-
auth_provider_id: str
|
201
|
-
|
202
|
-
def create_group_batch(self, additions: list[GroupAdd]) -> None:
|
203
|
-
json = {
|
204
|
-
"previousGroups": [],
|
205
|
-
"requiredGroups": [
|
206
|
-
{
|
207
|
-
"roleName": group.role_name,
|
208
|
-
"props": {
|
209
|
-
"id": "",
|
210
|
-
"authProviderId": group.auth_provider_id,
|
211
|
-
"key": group.key,
|
212
|
-
"value": group.value,
|
213
|
-
},
|
214
|
-
}
|
215
|
-
for group in additions
|
216
|
-
],
|
217
|
-
}
|
218
|
-
|
219
|
-
self.generic_request("/v1/groupsbatch", "POST", json)
|
220
|
-
|
221
|
-
def delete_group_batch(self, removals: list[Group]) -> None:
|
222
|
-
json = {
|
223
|
-
"previousGroups": [
|
224
|
-
{
|
225
|
-
"roleName": group.role_name,
|
226
|
-
"props": {
|
227
|
-
"id": group.id,
|
228
|
-
"authProviderId": group.auth_provider_id,
|
229
|
-
"key": group.key,
|
230
|
-
"value": group.value,
|
231
|
-
},
|
232
|
-
}
|
233
|
-
for group in removals
|
234
|
-
],
|
235
|
-
"requiredGroups": [],
|
236
|
-
}
|
237
|
-
|
238
|
-
self.generic_request("/v1/groupsbatch", "POST", json)
|
239
|
-
|
240
|
-
def update_group_batch(self, old: list[Group], new: list[GroupAdd]) -> None:
|
241
|
-
json = {
|
242
|
-
"previousGroups": [
|
243
|
-
{
|
244
|
-
"roleName": o.role_name,
|
245
|
-
"props": {
|
246
|
-
"id": o.id,
|
247
|
-
"authProviderId": o.auth_provider_id,
|
248
|
-
"key": o.key,
|
249
|
-
"value": o.value,
|
250
|
-
},
|
251
|
-
}
|
252
|
-
for o in old
|
253
|
-
],
|
254
|
-
"requiredGroups": [
|
255
|
-
{
|
256
|
-
"roleName": n.role_name,
|
257
|
-
"props": {
|
258
|
-
"id": "",
|
259
|
-
"authProviderId": n.auth_provider_id,
|
260
|
-
"key": n.key,
|
261
|
-
"value": n.value,
|
262
|
-
},
|
263
|
-
}
|
264
|
-
for n in new
|
265
|
-
],
|
266
|
-
}
|
267
|
-
self.generic_request("/v1/groupsbatch", "POST", json)
|
268
|
-
|
269
|
-
def get_access_scopes(self) -> list[AccessScope]:
|
270
|
-
response = self.generic_request("/v1/simpleaccessscopes", "GET")
|
271
|
-
return [AccessScope(a) for a in response.json()["accessScopes"]]
|
272
|
-
|
273
|
-
def create_access_scope(
|
274
|
-
self,
|
275
|
-
name: str,
|
276
|
-
desc: str,
|
277
|
-
clusters: list[str],
|
278
|
-
namespaces: list[dict[str, str]],
|
279
|
-
) -> str:
|
280
|
-
# response is the created access_scope id
|
281
|
-
json = {
|
282
|
-
"name": name,
|
283
|
-
"description": desc,
|
284
|
-
"rules": {
|
285
|
-
"includedClusters": clusters,
|
286
|
-
"includedNamespaces": namespaces,
|
287
|
-
},
|
288
|
-
}
|
289
|
-
|
290
|
-
response = self.generic_request("/v1/simpleaccessscopes", "POST", json)
|
291
|
-
|
292
|
-
return response.json()["id"]
|
293
|
-
|
294
|
-
def delete_access_scope(self, id: str) -> None:
|
295
|
-
self.generic_request(f"/v1/simpleaccessscopes/{id}", "DELETE")
|
296
|
-
|
297
|
-
def update_access_scope(
|
298
|
-
self,
|
299
|
-
id: str,
|
300
|
-
name: str,
|
301
|
-
desc: str,
|
302
|
-
clusters: list[str],
|
303
|
-
namespaces: list[dict[str, str]],
|
304
|
-
) -> None:
|
305
|
-
json = {
|
306
|
-
"name": name,
|
307
|
-
"description": desc,
|
308
|
-
"rules": {
|
309
|
-
"includedClusters": clusters,
|
310
|
-
"includedNamespaces": namespaces,
|
311
|
-
},
|
312
|
-
}
|
313
|
-
|
314
|
-
self.generic_request(f"/v1/simpleaccessscopes/{id}", "PUT", json)
|
315
|
-
|
316
|
-
def get_permission_sets(self) -> list[PermissionSet]:
|
317
|
-
response = self.generic_request("/v1/permissionsets", "GET")
|
318
|
-
return [PermissionSet(p) for p in response.json()["permissionSets"]]
|
319
|
-
|
320
|
-
def get_rbac_resources(self) -> RbacResources:
|
321
|
-
return RbacResources(
|
322
|
-
roles=self.get_roles(),
|
323
|
-
access_scopes=self.get_access_scopes(),
|
324
|
-
groups=self.get_groups(),
|
325
|
-
permission_sets=self.get_permission_sets(),
|
326
|
-
)
|
File without changes
|
File without changes
|
{qontract_reconcile-0.10.1rc506.dist-info → qontract_reconcile-0.10.1rc507.dist-info}/top_level.txt
RENAMED
File without changes
|