qontract-reconcile 0.10.2.dev184__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.dev184
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
@@ -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
@@ -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.dev184.dist-info/METADATA,sha256=4cOL2ogbG9Fe9GL834sDkyleO4EK2cgWR-AoP0ZIuls,24627
811
- qontract_reconcile-0.10.2.dev184.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
812
- qontract_reconcile-0.10.2.dev184.dist-info/entry_points.txt,sha256=5i9l54La3vQrDLAdwDKQWC0iG4sV9RRfOb1BpvzOWLc,698
813
- qontract_reconcile-0.10.2.dev184.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!"
@@ -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):