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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: qontract-reconcile
3
- Version: 0.10.2.dev183
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
@@ -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=hMh0Eq6ze5llWGoDV3l4OGcWY5OeJdS6Xy4b1Y4C_MY,17855
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=ske7cHJ-41jnaywgRlDnR2z9E1yLDSJ0tivq6bhhZdc,1827
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=S8DOputtxAX-MXvWuTLEOsgLlVkXJHALODPSnWOpvGk,4500
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=vMifpbnrQDLeckGtUmpIg7sVvlhpaJz8HZH_loA7fpY,30221
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=iOzR8PyWwKmUoB6Zx4bmbWFEiDPsP9tXuWia_bSW4vA,10921
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=lgoJW52hU7zL4UKNpKywvyL--o36MggUI1eFWWlvYLk,2300074
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=D50v0exLeK5hvjQKvxQ5V-6DnYZo_L6cX_Gaf3PGREs,5491
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=qQMN9JwaUvbirbLBy1BImkeJ4iFR-OCfWExphrfkmXs,28610
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=-FNQXltzl4OYGO7eMyvH7-wYUMHNFEVhiNwCvhN6WrI,292307
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=_S_QZ5UYXOnhNDOBQ-jNVOB6VpYh7Y96YLsM5T3ivug,8836
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=PjwJ36Eki5X0Wqu7-sE1slApMh6th3NojAWfZpOz_OQ,87111
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.dev183.dist-info/METADATA,sha256=2wN6rP5VfQjaP3NLAKUMYzPS5K4iHPrhgKKruSonpk4,24627
811
- qontract_reconcile-0.10.2.dev183.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
812
- qontract_reconcile-0.10.2.dev183.dist-info/entry_points.txt,sha256=5i9l54La3vQrDLAdwDKQWC0iG4sV9RRfOb1BpvzOWLc,698
813
- qontract_reconcile-0.10.2.dev183.dist-info/RECORD,,
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
- AutomatedActionArgumentOpenshiftV1,
20
- AutomatedActionArgumentV1,
19
+ AutomatedActionActionListV1,
20
+ AutomatedActionOpenshiftWorkloadRestartArgumentV1,
21
+ AutomatedActionOpenshiftWorkloadRestartV1,
21
22
  AutomatedActionsInstanceV1,
22
- PermissionAutomatedActionsV1,
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, 0)
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.permissions = list(
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(self, argument: AutomatedActionArgumentV1) -> bool:
95
+ def is_enabled(
96
+ self, argument: AutomatedActionOpenshiftWorkloadRestartArgumentV1
97
+ ) -> bool:
98
98
  """Check if the integration is enabled for the given argument namespace."""
99
- if isinstance(argument, AutomatedActionArgumentOpenshiftV1):
100
- return (
101
- integration_is_enabled("automated-actions", argument.namespace.cluster)
102
- and not argument.namespace.delete
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 filter_permissions(
107
- self, permissions: Iterable[PermissionAutomatedActionsV1]
108
- ) -> Generator[PermissionAutomatedActionsV1, None, None]:
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 permission in permissions:
111
- # automated actions disabled for the cluster?
112
- permission.arguments = [
113
- arg for arg in permission.arguments or [] if self.is_enabled(arg)
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
- # remove expired roles
116
- permission.roles = expiration.filter(permission.roles)
117
- if not permission.roles:
128
+
129
+ if not action.permissions:
118
130
  continue
119
- yield permission
131
+
132
+ yield action
120
133
 
121
134
  def compile_users(
122
- self, permissions: Iterable[PermissionAutomatedActionsV1]
135
+ self, actions: Iterable[AutomatedActionV1]
123
136
  ) -> list[AutomatedActionsUser]:
124
- """Compile all automated actions roles."""
137
+ """Compile a list of all automated actions users with their role relations."""
125
138
  users: dict[str, AutomatedActionsUser] = {}
126
- for permission in permissions:
127
- for role in permission.roles or []:
128
- for user in (role.users or []) + (role.bots or []):
129
- if not user.org_username:
130
- continue
131
- aa_user = users.setdefault(
132
- user.org_username,
133
- AutomatedActionsUser(username=user.org_username, roles=[]),
134
- )
135
- aa_user.roles.add(role.name)
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, permissions: Iterable[PermissionAutomatedActionsV1]
154
+ self, actions: Iterable[AutomatedActionV1]
141
155
  ) -> AutomatedActionRoles:
142
156
  """Compile all automated actions policies."""
143
157
  roles: AutomatedActionRoles = {}
144
158
 
145
- for permission in permissions or []:
146
- action = permission.action
147
-
148
- parameters: list[dict[str, str]] = [] if permission.arguments else [{}]
149
- for arg in permission.arguments or []:
150
- match arg:
151
- case AutomatedActionArgumentOpenshiftV1():
152
- parameters.append({
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.kind_pattern,
158
- "name": arg.name_pattern,
159
- })
160
- case _:
161
- raise NotImplementedError(
162
- f"Unsupported argument type: {arg.q_type}"
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
- for role in permission.roles or []:
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.permissions or [])
277
- policies = self.compile_roles(instance.permissions or [])
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!"
@@ -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 GITHUB_BASE_URL
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
- if rc.repo_url.startswith(GITHUB_BASE_URL):
426
- try:
427
- commits = self._github_compare_commits(rc)
428
- except GithubException as e:
429
- if e.status == 404:
430
- LOG.info(
431
- f"Ignoring RepoChanges for {rc} because could not calculate them: {e.data['message']}"
432
- )
433
- return rc, []
434
- elif rc.repo_url.startswith(self.gl.server):
435
- commits = self._gitlab_compare_commits(rc)
436
- else:
437
- raise Exception(f"Unknown git hosting {rc.repo_url}")
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 GITHUB_BASE_URL
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
- repo_name = repo_url.removeprefix(GITHUB_BASE_URL).rstrip("/")
50
- repo = gh.get_repo(repo_name)
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
- permissions {
73
- roles {
74
- name
75
- users {
76
- org_username
77
- }
78
- bots {
79
- org_username
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
- action {
85
- operationId
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
- kind_pattern
104
- name_pattern
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 AutomatedActionV1(ConfiguredBaseModel):
142
- operation_id: str = Field(..., alias="operationId")
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 AutomatedActionArgumentV1(ConfiguredBaseModel):
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 AutomatedActionArgumentOpenshiftV1_NamespaceV1_ClusterV1(ConfiguredBaseModel):
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 AutomatedActionArgumentOpenshiftV1_NamespaceV1(ConfiguredBaseModel):
162
+ class AutomatedActionOpenshiftWorkloadRestartArgumentV1_NamespaceV1(ConfiguredBaseModel):
161
163
  name: str = Field(..., alias="name")
162
164
  delete: Optional[bool] = Field(..., alias="delete")
163
- cluster: AutomatedActionArgumentOpenshiftV1_NamespaceV1_ClusterV1 = Field(..., alias="cluster")
165
+ cluster: AutomatedActionOpenshiftWorkloadRestartArgumentV1_NamespaceV1_ClusterV1 = Field(..., alias="cluster")
164
166
 
165
167
 
166
- class AutomatedActionArgumentOpenshiftV1(AutomatedActionArgumentV1):
167
- namespace: AutomatedActionArgumentOpenshiftV1_NamespaceV1 = Field(..., alias="namespace")
168
- kind_pattern: str = Field(..., alias="kind_pattern")
169
- name_pattern: str = Field(..., alias="name_pattern")
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 PermissionAutomatedActionsV1(ConfiguredBaseModel):
173
- roles: Optional[list[RoleV1]] = Field(..., alias="roles")
174
- action: AutomatedActionV1 = Field(..., alias="action")
175
- arguments: Optional[list[Union[AutomatedActionArgumentOpenshiftV1, AutomatedActionArgumentV1]]] = Field(..., alias="arguments")
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
- permissions: Optional[list[PermissionAutomatedActionsV1]] = Field(..., alias="permissions")
190
+ actions: Optional[list[Union[AutomatedActionOpenshiftWorkloadRestartV1, AutomatedActionActionListV1, AutomatedActionV1]]] = Field(..., alias="actions")
182
191
 
183
192
 
184
193
  class AutomatedActionsInstancesQueryData(ConfiguredBaseModel):