qontract-reconcile 0.10.2.dev183__py3-none-any.whl → 0.10.2.dev185__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.dev183.dist-info → qontract_reconcile-0.10.2.dev185.dist-info}/METADATA +1 -1
- {qontract_reconcile-0.10.2.dev183.dist-info → qontract_reconcile-0.10.2.dev185.dist-info}/RECORD +15 -15
- reconcile/automated_actions/config/integration.py +85 -65
- reconcile/dashdotdb_dora.py +18 -21
- reconcile/github_repo_permissions_validator.py +3 -3
- reconcile/gql_definitions/automated_actions/instance.py +47 -38
- reconcile/gql_definitions/introspection.json +634 -270
- reconcile/service_dependencies.py +8 -10
- reconcile/slack_usergroups.py +7 -9
- reconcile/utils/gitlab_api.py +1 -1
- reconcile/utils/saasherder/saasherder.py +69 -64
- reconcile/utils/terrascript_aws_client.py +15 -15
- reconcile/utils/vcs.py +67 -28
- {qontract_reconcile-0.10.2.dev183.dist-info → qontract_reconcile-0.10.2.dev185.dist-info}/WHEEL +0 -0
- {qontract_reconcile-0.10.2.dev183.dist-info → qontract_reconcile-0.10.2.dev185.dist-info}/entry_points.txt +0 -0
{qontract_reconcile-0.10.2.dev183.dist-info → qontract_reconcile-0.10.2.dev185.dist-info}/METADATA
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: qontract-reconcile
|
3
|
-
Version: 0.10.2.
|
3
|
+
Version: 0.10.2.dev185
|
4
4
|
Summary: Collection of tools to reconcile services with their desired state as defined in the app-interface DB.
|
5
5
|
Project-URL: homepage, https://github.com/app-sre/qontract-reconcile
|
6
6
|
Project-URL: repository, https://github.com/app-sre/qontract-reconcile
|
{qontract_reconcile-0.10.2.dev183.dist-info → qontract_reconcile-0.10.2.dev185.dist-info}/RECORD
RENAMED
@@ -15,7 +15,7 @@ reconcile/closedbox_endpoint_monitoring_base.py,sha256=al7m8EgnnYx90rY1REryW3byN
|
|
15
15
|
reconcile/cluster_deployment_mapper.py,sha256=5gumAaRCcFXsabUJ1dnuUy9WrP_FEEM5JnOnE8ch9sE,2326
|
16
16
|
reconcile/dashdotdb_base.py,sha256=83ZWIf5JJk3P_D69y2TmXRcQr6ELJGlv10OM0h7fJVs,4767
|
17
17
|
reconcile/dashdotdb_cso.py,sha256=QRK0YfIqO4rehs8btD3l_GXIO2ZIycTQEKEthBdB0xA,3639
|
18
|
-
reconcile/dashdotdb_dora.py,sha256=
|
18
|
+
reconcile/dashdotdb_dora.py,sha256=juZvr7R45f3TLbIZy290Oa1OtsSnqX-Ez71ppYAUjXw,17780
|
19
19
|
reconcile/dashdotdb_dvo.py,sha256=lCkZ0iby6HrNQb-3kYb6xrt8wCjVUZYxKzz9SiStfHU,8946
|
20
20
|
reconcile/dashdotdb_slo.py,sha256=TvKdMOtUZcZP9QydcUJMKh0zURHgOMN_RTpQpCkD1Z8,3960
|
21
21
|
reconcile/database_access_manager.py,sha256=Z3aAmw2LsmMIIor-bOGzziVZdVNC82Gmw8oHBUAFf-8,25577
|
@@ -26,7 +26,7 @@ reconcile/gcp_image_mirror.py,sha256=1ThuUff_04ZdF6uxcLoDuHhoNA3OIw0V-z0-CwdPE2w
|
|
26
26
|
reconcile/github_org.py,sha256=Wc5cZamatuWsW2ZJT2ib5ps8l3iY3RXHwNUxVJerqz0,14173
|
27
27
|
reconcile/github_owners.py,sha256=viE1KJ-zaTxuZ5yItg2C263J0brn-Q-3hR_DkYDMbhY,3122
|
28
28
|
reconcile/github_repo_invites.py,sha256=U9UCzNVwrZ7MqODtFah8ogH0NNY-XjBin7G9gqHtCUY,2690
|
29
|
-
reconcile/github_repo_permissions_validator.py,sha256=
|
29
|
+
reconcile/github_repo_permissions_validator.py,sha256=PNqL4dqa2OaNBy-NmLVN-t1HZa6eS6HgSYmfOunYqtA,1798
|
30
30
|
reconcile/github_users.py,sha256=QdX164LZrm8sqggMj-0beCzWofpS6OEBfzKNrWPrfj0,3934
|
31
31
|
reconcile/github_validator.py,sha256=-j17tn3csFVjPMSPL3te48iWVkPZCncRXdeKeLdGjjQ,931
|
32
32
|
reconcile/gitlab_fork_compliance.py,sha256=RbHckzLnE9zkOFHJANzoejEMMbMAivmqJVs3Suvp9lU,4591
|
@@ -102,10 +102,10 @@ reconcile/resource_template_tester.py,sha256=DsKvBuNLPxm4Fa-e1YHHySnhThm5i_j-nF3
|
|
102
102
|
reconcile/run_integration.py,sha256=8kc-lMKF9n2bvyrItJ-3nOgQMqK7lh1UAubXQrxQDPY,9711
|
103
103
|
reconcile/saas_file_validator.py,sha256=tyvFYU6lnkfDYIkAIr5pWqSvO5Yc6TagZ-quJYD2dtI,2547
|
104
104
|
reconcile/sendgrid_teammates.py,sha256=oO8QbLb4s1o8A6CGiCagN9CmS05BSS_WLztuY0Ym9D8,4773
|
105
|
-
reconcile/service_dependencies.py,sha256=
|
105
|
+
reconcile/service_dependencies.py,sha256=G2qCuYFc8wQLpRxkdhmibxSAl3nUM3hcan4x50W_mCA,4335
|
106
106
|
reconcile/signalfx_endpoint_monitoring.py,sha256=Nqgsg1cflSd2nNnm89y_e8c--7xLUqTrKOHkDs-qADE,2868
|
107
107
|
reconcile/slack_base.py,sha256=I-msunWxfgu5bSwXYulGbtLjxUB_tRmTCAUCU-3nabI,3484
|
108
|
-
reconcile/slack_usergroups.py,sha256=
|
108
|
+
reconcile/slack_usergroups.py,sha256=xFkVe67RXSUj8JvpfSFEiRdQzB0TnJJEHW_b5PEwLng,30213
|
109
109
|
reconcile/sql_query.py,sha256=OEzEZaqgv-kzG3GR2x9w3uMIfSFXP6EdhlW4u5mc1Dg,25895
|
110
110
|
reconcile/status.py,sha256=cY4IJFXemhxptRJqR4qaaOWqei9e4jgLXuVSGajMsjg,544
|
111
111
|
reconcile/status_board.py,sha256=kJ0bus_wdyX3zsFJuUPrH4n9BNG_jhDbiQ3waOLVRBE,8538
|
@@ -141,7 +141,7 @@ reconcile/aus/version_gates/ocp_gate_handler.py,sha256=RW1ppDaCZXVegV9AzzqYXxDUu
|
|
141
141
|
reconcile/aus/version_gates/sts_version_gate_handler.py,sha256=swwwz0YyvrEBf_InqrRRBCt2QzHYNvvq8jz9aYwElh4,3663
|
142
142
|
reconcile/automated_actions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
143
143
|
reconcile/automated_actions/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
144
|
-
reconcile/automated_actions/config/integration.py,sha256=
|
144
|
+
reconcile/automated_actions/config/integration.py,sha256=gDNUKxs8m_4GWH0GnW9QXubtsBF6idc0kHxo05hdj0U,11633
|
145
145
|
reconcile/aws_account_manager/README.md,sha256=_XFM3GZNHUzv--e_navqJuaUWpjC6QrHfulreHynFf0,262
|
146
146
|
reconcile/aws_account_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
147
147
|
reconcile/aws_account_manager/integration.py,sha256=XTamC824imAezzVoQhhwdMOawNcPCOghR_y7i_8bpJI,15343
|
@@ -227,7 +227,7 @@ reconcile/glitchtip_project_alerts/integration.py,sha256=BgMx-NyV9mTuv7Sotb2OioC
|
|
227
227
|
reconcile/glitchtip_project_dsn/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
228
228
|
reconcile/glitchtip_project_dsn/integration.py,sha256=2iugub-kHYkHNK33n0v9_TeWonuxCPah_VkoTPvaajE,8077
|
229
229
|
reconcile/gql_definitions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
230
|
-
reconcile/gql_definitions/introspection.json,sha256=
|
230
|
+
reconcile/gql_definitions/introspection.json,sha256=MT1HCR90ZahZxjrgaBEp34JNhjaEiDRblQK-qfSrfF0,2316277
|
231
231
|
reconcile/gql_definitions/acs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
232
232
|
reconcile/gql_definitions/acs/acs_instances.py,sha256=L91WW9LbhJbBSrECqShQpFtjoBOsmNIYLRpMbx1io5o,2181
|
233
233
|
reconcile/gql_definitions/acs/acs_policies.py,sha256=9IFpGAcrZ8nTFC05q3-12nwkNOEkquHB2-XbVq5_jy4,7219
|
@@ -241,7 +241,7 @@ reconcile/gql_definitions/app_sre_tekton_access_revalidation/__init__.py,sha256=
|
|
241
241
|
reconcile/gql_definitions/app_sre_tekton_access_revalidation/roles.py,sha256=8Y4NsS5T7tumDWxY5MuoV50MK2i-DsLYSpCRjb7KaLE,2353
|
242
242
|
reconcile/gql_definitions/app_sre_tekton_access_revalidation/users.py,sha256=XdVxBxiyTR6Cy939EHNw__0k7iWrZWlhrgS5DakST0I,2504
|
243
243
|
reconcile/gql_definitions/automated_actions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
244
|
-
reconcile/gql_definitions/automated_actions/instance.py,sha256=
|
244
|
+
reconcile/gql_definitions/automated_actions/instance.py,sha256=73vRFDvrD9t2cY1Y8jmjfVPNJ_osPrI8fHTAQz0CGv4,6105
|
245
245
|
reconcile/gql_definitions/aws_account_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
246
246
|
reconcile/gql_definitions/aws_account_manager/aws_accounts.py,sha256=vF51KrY2gwX0J9vESiaRMPQqdAMEtz9f_tBq52bInp0,5148
|
247
247
|
reconcile/gql_definitions/aws_ami_cleanup/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -616,7 +616,7 @@ reconcile/utils/external_resources.py,sha256=YzTb0xAcNdmKO326mGQy7BmST56CZcdru4l
|
|
616
616
|
reconcile/utils/filtering.py,sha256=S4PbMHuFr3ED0P2Q_ea5CAaB7FimI62B-F5YTaKrphA,402
|
617
617
|
reconcile/utils/git.py,sha256=o4p9m8jlzCJDcutl2HErvGLhL6sZ1NB4Aw3zGcQIzso,2427
|
618
618
|
reconcile/utils/github_api.py,sha256=o4J0ZU1ZSr9808uoorKHv19iae-eLo85yrCZX67p2kw,2822
|
619
|
-
reconcile/utils/gitlab_api.py,sha256=
|
619
|
+
reconcile/utils/gitlab_api.py,sha256=U7l26fM1lQ4g-O06D0ZawvOXF_yzzH5NdR5iDx2ZJFA,28616
|
620
620
|
reconcile/utils/gpg.py,sha256=EKG7_fdMv8BMlV5yUdPiqoTx-KrzmVSEAl2sLkaKwWI,1123
|
621
621
|
reconcile/utils/gql.py,sha256=C0thIm_k9MBldfqwHzyqtYZk9sIvMdm9IbbnXLGwjD8,14158
|
622
622
|
reconcile/utils/grouping.py,sha256=vr9SFHZ7bqmHYrvYcEZt-Er3-yQYfAAdq5sHLZVmXPY,456
|
@@ -667,12 +667,12 @@ reconcile/utils/state.py,sha256=az4tBmZ0EdbFcAGiBVUxs3cr2-BVWsuDQiNTvjjQq8s,1637
|
|
667
667
|
reconcile/utils/structs.py,sha256=LcbLEg8WxfRqM6nW7NhcWN0YeqF7SQzxOgntmLs1SgY,352
|
668
668
|
reconcile/utils/template.py,sha256=wTvRU4AnAV_o042tD4Mwls2dwWMuk7MKnde3MaCjaYg,331
|
669
669
|
reconcile/utils/terraform_client.py,sha256=IDlrNvGEc2i6ElZIL_fzaJEad1nRC3DkP9_VXhJXmU0,37329
|
670
|
-
reconcile/utils/terrascript_aws_client.py,sha256
|
670
|
+
reconcile/utils/terrascript_aws_client.py,sha256=RkiYjRietHFNXtfA1-WEZ1lZbJFBA_XCtTOsZUij5VM,292360
|
671
671
|
reconcile/utils/three_way_diff_strategy.py,sha256=oQcHXd9LVhirJfoaOBoHUYuZVGfyL2voKr6KVI34zZE,4833
|
672
672
|
reconcile/utils/throughput.py,sha256=iP4UWAe2LVhDo69mPPmgo9nQ7RxHD6_GS8MZe-aSiuM,344
|
673
673
|
reconcile/utils/vault.py,sha256=aSA8l9cJlPUHpChFGl27nSY-Mpq9FMjBo7Dcgb1BVfM,15036
|
674
674
|
reconcile/utils/vaultsecretref.py,sha256=0KUSzuvTRxPyKY919TO3-B_eYg4_76fzKvMF8j5s1G0,911
|
675
|
-
reconcile/utils/vcs.py,sha256=
|
675
|
+
reconcile/utils/vcs.py,sha256=AK35vIjx9bXYclKmvNekpaG_OETt-ZybibwV-m123xc,10186
|
676
676
|
reconcile/utils/acs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
677
677
|
reconcile/utils/acs/base.py,sha256=4UsDrCpAOuddL3PKNuIQYoJP1BtZQNNB8_KEX0lXneg,2532
|
678
678
|
reconcile/utils/acs/notifiers.py,sha256=DlzTDM9arWQlBSiDy70y5Mf38OKVs9V0FzFe2LfOKXA,5046
|
@@ -761,7 +761,7 @@ reconcile/utils/runtime/sharding.py,sha256=r0ieUtNed7NvknSw6qQrCkKpVXE1shuHGnfFc
|
|
761
761
|
reconcile/utils/saasherder/__init__.py,sha256=3U8plqMAPRE1kjwZ5YnIsYsggTf4_gS7flRUEuXVBAs,343
|
762
762
|
reconcile/utils/saasherder/interfaces.py,sha256=NEYQspYfyWQhBeJyNCqSFbixi1A4wRVGB7FeNM5BDCk,9141
|
763
763
|
reconcile/utils/saasherder/models.py,sha256=JaOz_DEtudJZhiDe90kaBlJkppFufn81V92oK9PHYx0,10208
|
764
|
-
reconcile/utils/saasherder/saasherder.py,sha256=
|
764
|
+
reconcile/utils/saasherder/saasherder.py,sha256=V8DOaMvY1POYd_EquIlU2sI62l64C-PjtaTCuzwVbn4,87306
|
765
765
|
reconcile/utils/terraform/__init__.py,sha256=zNbiyTWo35AT1sFTElL2j_AA0jJ_yWE_bfFn-nD2xik,250
|
766
766
|
reconcile/utils/terraform/config.py,sha256=5UVrd563TMcvi4ooa5JvWVDW1I3bIWg484u79evfV_8,164
|
767
767
|
reconcile/utils/terraform/config_client.py,sha256=gRL1rQ0AqvShei_rcGqC3HDYGskOFKE1nPrJyJE9yno,4676
|
@@ -807,7 +807,7 @@ tools/saas_promotion_state/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJ
|
|
807
807
|
tools/saas_promotion_state/saas_promotion_state.py,sha256=UfwwRLS5Ya4_Nh1w5n1dvoYtchQvYE9yj1VANt2IKqI,3925
|
808
808
|
tools/sre_checkpoints/__init__.py,sha256=CDaDaywJnmRCLyl_NCcvxi-Zc0hTi_3OdwKiFOyS39I,145
|
809
809
|
tools/sre_checkpoints/util.py,sha256=zEDbGr18ZeHNQwW8pUsr2JRjuXIPz--WAGJxZo9sv_Y,894
|
810
|
-
qontract_reconcile-0.10.2.
|
811
|
-
qontract_reconcile-0.10.2.
|
812
|
-
qontract_reconcile-0.10.2.
|
813
|
-
qontract_reconcile-0.10.2.
|
810
|
+
qontract_reconcile-0.10.2.dev185.dist-info/METADATA,sha256=-GBtujthD8qi9Bdj1oIRUOc5iAeTf-Xa5Lp5jpTyTPE,24627
|
811
|
+
qontract_reconcile-0.10.2.dev185.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
812
|
+
qontract_reconcile-0.10.2.dev185.dist-info/entry_points.txt,sha256=5i9l54La3vQrDLAdwDKQWC0iG4sV9RRfOb1BpvzOWLc,698
|
813
|
+
qontract_reconcile-0.10.2.dev185.dist-info/RECORD,,
|
@@ -16,10 +16,11 @@ from pydantic import BaseModel
|
|
16
16
|
|
17
17
|
import reconcile.openshift_base as ob
|
18
18
|
from reconcile.gql_definitions.automated_actions.instance import (
|
19
|
-
|
20
|
-
|
19
|
+
AutomatedActionActionListV1,
|
20
|
+
AutomatedActionOpenshiftWorkloadRestartArgumentV1,
|
21
|
+
AutomatedActionOpenshiftWorkloadRestartV1,
|
21
22
|
AutomatedActionsInstanceV1,
|
22
|
-
|
23
|
+
AutomatedActionV1,
|
23
24
|
)
|
24
25
|
from reconcile.gql_definitions.automated_actions.instance import query as instance_query
|
25
26
|
from reconcile.utils import expiration, gql
|
@@ -35,7 +36,7 @@ from reconcile.utils.runtime.integration import (
|
|
35
36
|
from reconcile.utils.semver_helper import make_semver
|
36
37
|
|
37
38
|
QONTRACT_INTEGRATION = "automated-actions-config"
|
38
|
-
QONTRACT_INTEGRATION_VERSION = make_semver(0, 1,
|
39
|
+
QONTRACT_INTEGRATION_VERSION = make_semver(0, 1, 1)
|
39
40
|
|
40
41
|
|
41
42
|
class AutomatedActionsConfigIntegrationParams(PydanticRunParams):
|
@@ -51,7 +52,6 @@ class AutomatedActionsUser(BaseModel):
|
|
51
52
|
|
52
53
|
|
53
54
|
class AutomatedActionsPolicy(BaseModel):
|
54
|
-
sub: str
|
55
55
|
obj: str
|
56
56
|
max_ops: int
|
57
57
|
params: dict[str, str] = {}
|
@@ -89,89 +89,109 @@ class AutomatedActionsConfigIntegration(
|
|
89
89
|
for instance in data.automated_actions_instances_v1 or []:
|
90
90
|
if instance.deployment.delete:
|
91
91
|
continue
|
92
|
-
instance.
|
93
|
-
self.filter_permissions(instance.permissions or [])
|
94
|
-
)
|
92
|
+
instance.actions = list(self.filter_actions(instance.actions or []))
|
95
93
|
yield instance
|
96
94
|
|
97
|
-
def is_enabled(
|
95
|
+
def is_enabled(
|
96
|
+
self, argument: AutomatedActionOpenshiftWorkloadRestartArgumentV1
|
97
|
+
) -> bool:
|
98
98
|
"""Check if the integration is enabled for the given argument namespace."""
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
)
|
104
|
-
return True
|
99
|
+
return (
|
100
|
+
integration_is_enabled("automated-actions", argument.namespace.cluster)
|
101
|
+
and not argument.namespace.delete
|
102
|
+
)
|
105
103
|
|
106
|
-
def
|
107
|
-
self,
|
108
|
-
) -> Generator[
|
104
|
+
def filter_actions(
|
105
|
+
self, actions: Iterable[AutomatedActionV1]
|
106
|
+
) -> Generator[AutomatedActionV1, None, None]:
|
109
107
|
"""Filter out expired roles and arguments (cluster.namespace) with disabled integrations."""
|
110
|
-
for
|
111
|
-
|
112
|
-
|
113
|
-
|
108
|
+
for action in actions:
|
109
|
+
match action:
|
110
|
+
case AutomatedActionOpenshiftWorkloadRestartV1():
|
111
|
+
# automated actions disabled for the cluster?
|
112
|
+
action.openshift_workload_restart_arguments = [
|
113
|
+
arg
|
114
|
+
for arg in action.openshift_workload_restart_arguments or []
|
115
|
+
if self.is_enabled(arg)
|
116
|
+
]
|
117
|
+
|
118
|
+
# Remove expired roles
|
119
|
+
for permission in action.permissions or []:
|
120
|
+
permission.roles = expiration.filter(permission.roles)
|
121
|
+
|
122
|
+
# Remove permissions without roles
|
123
|
+
action.permissions = [
|
124
|
+
permission
|
125
|
+
for permission in action.permissions or []
|
126
|
+
if permission.roles
|
114
127
|
]
|
115
|
-
|
116
|
-
|
117
|
-
if not permission.roles:
|
128
|
+
|
129
|
+
if not action.permissions:
|
118
130
|
continue
|
119
|
-
|
131
|
+
|
132
|
+
yield action
|
120
133
|
|
121
134
|
def compile_users(
|
122
|
-
self,
|
135
|
+
self, actions: Iterable[AutomatedActionV1]
|
123
136
|
) -> list[AutomatedActionsUser]:
|
124
|
-
"""Compile all automated actions
|
137
|
+
"""Compile a list of all automated actions users with their role relations."""
|
125
138
|
users: dict[str, AutomatedActionsUser] = {}
|
126
|
-
for
|
127
|
-
for
|
128
|
-
for
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
139
|
+
for action in actions:
|
140
|
+
for permission in action.permissions or []:
|
141
|
+
for role in permission.roles or []:
|
142
|
+
for user in (role.users or []) + (role.bots or []):
|
143
|
+
if not user.org_username:
|
144
|
+
continue
|
145
|
+
aa_user = users.setdefault(
|
146
|
+
user.org_username,
|
147
|
+
AutomatedActionsUser(username=user.org_username, roles=[]),
|
148
|
+
)
|
149
|
+
aa_user.roles.add(role.name)
|
136
150
|
|
137
151
|
return list(users.values())
|
138
152
|
|
139
153
|
def compile_roles(
|
140
|
-
self,
|
154
|
+
self, actions: Iterable[AutomatedActionV1]
|
141
155
|
) -> AutomatedActionRoles:
|
142
156
|
"""Compile all automated actions policies."""
|
143
157
|
roles: AutomatedActionRoles = {}
|
144
158
|
|
145
|
-
for
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
159
|
+
for action in actions:
|
160
|
+
parameters: list[dict[str, str]] = []
|
161
|
+
match action:
|
162
|
+
case AutomatedActionActionListV1():
|
163
|
+
# no special handling needed, just dump the values
|
164
|
+
parameters.extend(
|
165
|
+
arg.dict(exclude_none=True, exclude_defaults=True)
|
166
|
+
for arg in action.action_list_arguments or []
|
167
|
+
)
|
168
|
+
case AutomatedActionOpenshiftWorkloadRestartV1():
|
169
|
+
parameters.extend(
|
170
|
+
{
|
153
171
|
# all parameter values are regexes in the OPA policy
|
154
172
|
# therefore, cluster and namespace must be fixed to the current strings
|
155
173
|
"cluster": f"^{arg.namespace.cluster.name}$",
|
156
174
|
"namespace": f"^{arg.namespace.name}$",
|
157
|
-
"kind": arg.
|
158
|
-
"name": arg.
|
159
|
-
}
|
160
|
-
|
161
|
-
|
162
|
-
|
175
|
+
"kind": arg.kind,
|
176
|
+
"name": arg.name,
|
177
|
+
}
|
178
|
+
for arg in action.openshift_workload_restart_arguments
|
179
|
+
)
|
180
|
+
|
181
|
+
if not parameters:
|
182
|
+
parameters = [{}]
|
183
|
+
|
184
|
+
for permission in action.permissions or []:
|
185
|
+
for role in permission.roles or []:
|
186
|
+
aa_role = roles.setdefault(role.name, [])
|
187
|
+
aa_role.extend(
|
188
|
+
AutomatedActionsPolicy(
|
189
|
+
obj=action.q_type,
|
190
|
+
max_ops=action.max_ops,
|
191
|
+
params=params,
|
163
192
|
)
|
164
|
-
|
165
|
-
aa_role = roles.setdefault(role.name, [])
|
166
|
-
aa_role.extend(
|
167
|
-
AutomatedActionsPolicy(
|
168
|
-
sub=role.name,
|
169
|
-
obj=action.operation_id,
|
170
|
-
max_ops=action.max_ops,
|
171
|
-
params=params,
|
193
|
+
for params in parameters
|
172
194
|
)
|
173
|
-
for params in parameters
|
174
|
-
)
|
175
195
|
return roles
|
176
196
|
|
177
197
|
def build_policy_file(
|
@@ -273,8 +293,8 @@ class AutomatedActionsConfigIntegration(
|
|
273
293
|
ri = ResourceInventory()
|
274
294
|
|
275
295
|
for instance in instances:
|
276
|
-
users = self.compile_users(instance.
|
277
|
-
policies = self.compile_roles(instance.
|
296
|
+
users = self.compile_users(instance.actions or [])
|
297
|
+
policies = self.compile_roles(instance.actions or [])
|
278
298
|
if not users and not policies:
|
279
299
|
logging.info(
|
280
300
|
f"{instance.deployment.cluster.name}/{instance.deployment.name}: No enabled automated actions found. Skipping this instance!"
|
reconcile/dashdotdb_dora.py
CHANGED
@@ -34,7 +34,7 @@ from reconcile.typed_queries.saas_files import get_saas_files
|
|
34
34
|
from reconcile.utils.github_api import GithubRepositoryApi
|
35
35
|
from reconcile.utils.gitlab_api import GitLabApi
|
36
36
|
from reconcile.utils.secret_reader import create_secret_reader
|
37
|
-
from reconcile.utils.vcs import
|
37
|
+
from reconcile.utils.vcs import VCS
|
38
38
|
|
39
39
|
QONTRACT_INTEGRATION = "dashdotdb-dora"
|
40
40
|
|
@@ -422,19 +422,21 @@ class DashdotdbDORA(DashdotdbBase):
|
|
422
422
|
return rc, []
|
423
423
|
|
424
424
|
LOG.info("Fetching commits %s", rc)
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
425
|
+
repo_info = VCS.parse_repo_url(rc.repo_url)
|
426
|
+
match repo_info.platform:
|
427
|
+
case "github":
|
428
|
+
try:
|
429
|
+
commits = self._github_compare_commits(rc, repo_info.name)
|
430
|
+
except GithubException as e:
|
431
|
+
if e.status == 404:
|
432
|
+
LOG.info(
|
433
|
+
f"Ignoring RepoChanges for {rc} because could not calculate them: {e.data['message']}"
|
434
|
+
)
|
435
|
+
return rc, []
|
436
|
+
case "gitlab":
|
437
|
+
commits = self._gitlab_compare_commits(rc, repo_info.name)
|
438
|
+
case _:
|
439
|
+
raise Exception(f"Unknown git hosting {rc.repo_url}")
|
438
440
|
|
439
441
|
return rc, commits
|
440
442
|
|
@@ -455,13 +457,10 @@ class DashdotdbDORA(DashdotdbBase):
|
|
455
457
|
|
456
458
|
return app_env, datetime.fromisoformat(response.json()["finish_timestamp"])
|
457
459
|
|
458
|
-
def _gitlab_compare_commits(self, rc: RepoChanges) -> list[Commit]:
|
460
|
+
def _gitlab_compare_commits(self, rc: RepoChanges, repo: str) -> list[Commit]:
|
459
461
|
if not rc.repo_url or not rc.ref_from or not rc.ref_to:
|
460
462
|
return []
|
461
463
|
|
462
|
-
prefix = "https://gitlab.cee.redhat.com/"
|
463
|
-
repo = rc.repo_url[rc.repo_url.startswith(prefix) and len(prefix) :]
|
464
|
-
|
465
464
|
commits = self.gl.repository_compare(repo, rc.ref_from, rc.ref_to)
|
466
465
|
|
467
466
|
return [
|
@@ -473,12 +472,10 @@ class DashdotdbDORA(DashdotdbBase):
|
|
473
472
|
for commit in commits
|
474
473
|
]
|
475
474
|
|
476
|
-
def _github_compare_commits(self, rc: RepoChanges) -> list[Commit]:
|
475
|
+
def _github_compare_commits(self, rc: RepoChanges, repo: str) -> list[Commit]:
|
477
476
|
if not rc.repo_url:
|
478
477
|
return []
|
479
478
|
|
480
|
-
repo = rc.repo_url.removeprefix(GITHUB_BASE_URL).rstrip("/")
|
481
|
-
|
482
479
|
return [
|
483
480
|
Commit(rc.repo_url, commit.sha, commit.commit.committer.date)
|
484
481
|
for commit in self.gh_api(repo).compare(rc.ref_from, rc.ref_to)
|
@@ -11,7 +11,7 @@ from reconcile.jenkins_job_builder import init_jjb
|
|
11
11
|
from reconcile.utils.jjb_client import JJB
|
12
12
|
from reconcile.utils.secret_reader import SecretReader
|
13
13
|
from reconcile.utils.semver_helper import make_semver
|
14
|
-
from reconcile.utils.vcs import
|
14
|
+
from reconcile.utils.vcs import VCS
|
15
15
|
|
16
16
|
QONTRACT_INTEGRATION = "github-repo-permissions-validator"
|
17
17
|
QONTRACT_INTEGRATION_VERSION = make_semver(0, 1, 0)
|
@@ -46,8 +46,8 @@ def run(dry_run: bool, instance_name: str) -> None:
|
|
46
46
|
error = False
|
47
47
|
for job in pr_check_jobs:
|
48
48
|
repo_url = jjb.get_repo_url(job)
|
49
|
-
|
50
|
-
repo = gh.get_repo(
|
49
|
+
repo_info = VCS.parse_repo_url(repo_url)
|
50
|
+
repo = gh.get_repo(repo_info.name)
|
51
51
|
permissions = repo.permissions
|
52
52
|
if not permissions.push and repo_url not in invitations:
|
53
53
|
logging.error(f"missing write permissions for bot in repo {repo_url}")
|
@@ -69,27 +69,23 @@ query AutomatedActionsInstances {
|
|
69
69
|
...OcConnectionCluster
|
70
70
|
}
|
71
71
|
}
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
72
|
+
actions {
|
73
|
+
type
|
74
|
+
permissions {
|
75
|
+
roles {
|
76
|
+
name
|
77
|
+
users {
|
78
|
+
org_username
|
79
|
+
}
|
80
|
+
bots {
|
81
|
+
org_username
|
82
|
+
}
|
83
|
+
expirationDate
|
80
84
|
}
|
81
|
-
expirationDate
|
82
85
|
}
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
retries
|
87
|
-
maxOps
|
88
|
-
}
|
89
|
-
|
90
|
-
arguments {
|
91
|
-
type
|
92
|
-
... on AutomatedActionArgumentOpenshift_v1 {
|
86
|
+
maxOps
|
87
|
+
... on AutomatedActionOpenshiftWorkloadRestart_v1 {
|
88
|
+
openshift_workload_restart_arguments: arguments {
|
93
89
|
namespace {
|
94
90
|
name
|
95
91
|
delete
|
@@ -100,8 +96,14 @@ query AutomatedActionsInstances {
|
|
100
96
|
}
|
101
97
|
}
|
102
98
|
}
|
103
|
-
|
104
|
-
|
99
|
+
kind
|
100
|
+
name
|
101
|
+
}
|
102
|
+
}
|
103
|
+
... on AutomatedActionActionList_v1 {
|
104
|
+
action_list_arguments: arguments {
|
105
|
+
action_user
|
106
|
+
max_age_minutes
|
105
107
|
}
|
106
108
|
}
|
107
109
|
}
|
@@ -138,47 +140,54 @@ class RoleV1(ConfiguredBaseModel):
|
|
138
140
|
expiration_date: Optional[str] = Field(..., alias="expirationDate")
|
139
141
|
|
140
142
|
|
141
|
-
class
|
142
|
-
|
143
|
-
retries: int = Field(..., alias="retries")
|
144
|
-
max_ops: int = Field(..., alias="maxOps")
|
143
|
+
class PermissionAutomatedActionsV1(ConfiguredBaseModel):
|
144
|
+
roles: Optional[list[RoleV1]] = Field(..., alias="roles")
|
145
145
|
|
146
146
|
|
147
|
-
class
|
147
|
+
class AutomatedActionV1(ConfiguredBaseModel):
|
148
148
|
q_type: str = Field(..., alias="type")
|
149
|
+
permissions: Optional[list[PermissionAutomatedActionsV1]] = Field(..., alias="permissions")
|
150
|
+
max_ops: int = Field(..., alias="maxOps")
|
149
151
|
|
150
152
|
|
151
153
|
class DisableClusterAutomationsV1(ConfiguredBaseModel):
|
152
154
|
integrations: Optional[list[str]] = Field(..., alias="integrations")
|
153
155
|
|
154
156
|
|
155
|
-
class
|
157
|
+
class AutomatedActionOpenshiftWorkloadRestartArgumentV1_NamespaceV1_ClusterV1(ConfiguredBaseModel):
|
156
158
|
name: str = Field(..., alias="name")
|
157
159
|
disable: Optional[DisableClusterAutomationsV1] = Field(..., alias="disable")
|
158
160
|
|
159
161
|
|
160
|
-
class
|
162
|
+
class AutomatedActionOpenshiftWorkloadRestartArgumentV1_NamespaceV1(ConfiguredBaseModel):
|
161
163
|
name: str = Field(..., alias="name")
|
162
164
|
delete: Optional[bool] = Field(..., alias="delete")
|
163
|
-
cluster:
|
165
|
+
cluster: AutomatedActionOpenshiftWorkloadRestartArgumentV1_NamespaceV1_ClusterV1 = Field(..., alias="cluster")
|
164
166
|
|
165
167
|
|
166
|
-
class
|
167
|
-
namespace:
|
168
|
-
|
169
|
-
|
168
|
+
class AutomatedActionOpenshiftWorkloadRestartArgumentV1(ConfiguredBaseModel):
|
169
|
+
namespace: AutomatedActionOpenshiftWorkloadRestartArgumentV1_NamespaceV1 = Field(..., alias="namespace")
|
170
|
+
kind: str = Field(..., alias="kind")
|
171
|
+
name: str = Field(..., alias="name")
|
170
172
|
|
171
173
|
|
172
|
-
class
|
173
|
-
|
174
|
-
|
175
|
-
|
174
|
+
class AutomatedActionOpenshiftWorkloadRestartV1(AutomatedActionV1):
|
175
|
+
openshift_workload_restart_arguments: list[AutomatedActionOpenshiftWorkloadRestartArgumentV1] = Field(..., alias="openshift_workload_restart_arguments")
|
176
|
+
|
177
|
+
|
178
|
+
class AutomatedActionActionListArgumentV1(ConfiguredBaseModel):
|
179
|
+
action_user: Optional[str] = Field(..., alias="action_user")
|
180
|
+
max_age_minutes: Optional[int] = Field(..., alias="max_age_minutes")
|
181
|
+
|
182
|
+
|
183
|
+
class AutomatedActionActionListV1(AutomatedActionV1):
|
184
|
+
action_list_arguments: Optional[list[AutomatedActionActionListArgumentV1]] = Field(..., alias="action_list_arguments")
|
176
185
|
|
177
186
|
|
178
187
|
class AutomatedActionsInstanceV1(ConfiguredBaseModel):
|
179
188
|
name: str = Field(..., alias="name")
|
180
189
|
deployment: NamespaceV1 = Field(..., alias="deployment")
|
181
|
-
|
190
|
+
actions: Optional[list[Union[AutomatedActionOpenshiftWorkloadRestartV1, AutomatedActionActionListV1, AutomatedActionV1]]] = Field(..., alias="actions")
|
182
191
|
|
183
192
|
|
184
193
|
class AutomatedActionsInstancesQueryData(ConfiguredBaseModel):
|