qontract-reconcile 0.10.1rc445__py3-none-any.whl → 0.10.1rc449__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.1
2
2
  Name: qontract-reconcile
3
- Version: 0.10.1rc445
3
+ Version: 0.10.1rc449
4
4
  Summary: Collection of tools to reconcile services with their desired state as defined in the app-interface DB.
5
5
  Home-page: https://github.com/app-sre/qontract-reconcile
6
6
  Author: Red Hat App-SRE Team
@@ -16,7 +16,7 @@ reconcile/dashdotdb_cso.py,sha256=FoXrWGpOwXG5jf0eklN84tjJVUAYzKat7rtq_28JMlQ,36
16
16
  reconcile/dashdotdb_dora.py,sha256=FINH-8dU3_r8EgUOMiF_fbxD9fKs6LFDxe6rufQ9XcM,17214
17
17
  reconcile/dashdotdb_dvo.py,sha256=YXqpI6fBQAql-ybGI0grj9gWMzmKiAvPE__pNju6obk,8996
18
18
  reconcile/dashdotdb_slo.py,sha256=bf1WSh5JP9obHVQsMy0OO71_VTYZgwAopElFZM6DmRo,6714
19
- reconcile/database_access_manager.py,sha256=1FWsBA7hgp2Wxo-khLfEyamkdi70u_0DvMHmkatqTBI,25486
19
+ reconcile/database_access_manager.py,sha256=AoeCrDIxC60sLct31M3gjbjry6DWjItjn9Y_3tA11s4,25586
20
20
  reconcile/dynatrace_token_provider.py,sha256=HWItJ_LavPcUJlpYz5fmfnfOpP2-0Qjkar0EAzBJ5Cw,16602
21
21
  reconcile/email_sender.py,sha256=-5L-Ag_jaEYSzYRoMr52KQBRXz1E8yx9GqLbg2X4XFU,3533
22
22
  reconcile/gabi_authorized_users.py,sha256=rCosZv8Iu9jhWG88YiwK-gftX475aJ1R-PYIJYp_svY,4342
@@ -56,7 +56,7 @@ reconcile/ocm_clusters.py,sha256=ibK0o0rXhAnq4TF522aPkVlH7i0bdtgD8-IKmZ8PHjs,134
56
56
  reconcile/ocm_external_configuration_labels.py,sha256=imEpDv1RBpCSj8tHDv0R76hmNCFtcUzVNgS1yOVl8vs,3870
57
57
  reconcile/ocm_github_idp.py,sha256=IlSpoUlUhYOahqWee6azJiN-N5EZNxNAWh-lrPXTfEc,3946
58
58
  reconcile/ocm_groups.py,sha256=_kiMUndKc6as6cbbvXxVnq8V_Lj7X5lxMJVCuRWuUFE,2888
59
- reconcile/ocm_machine_pools.py,sha256=YGIokK6cWhakPB4pj3h4F6w9Rn12kqsXf4TT4mdj1w8,15218
59
+ reconcile/ocm_machine_pools.py,sha256=eebJ6iiTdUcuKE5zBcfNxW1OGmPOvgBtmVu3xNVOoyY,16608
60
60
  reconcile/ocm_update_recommended_version.py,sha256=IYkfLXIprOW1jguZeELcGP1iBPuj-b53R-FTqKulMl8,4204
61
61
  reconcile/ocm_upgrade_scheduler_org_updater.py,sha256=Kti53htd5yeTSXzMW6jKvQojfaRIN7rMGe5-cC4k7N4,4105
62
62
  reconcile/openshift_base.py,sha256=PFV3XoshiayqSHjOMtW7cOB2jhFLrPN8wq9km1SiWio,47332
@@ -118,11 +118,11 @@ reconcile/vpc_peerings_validator.py,sha256=oiYwmQ2yYBobFhIixmHNUP1GxzUADocMPJnCB
118
118
  reconcile/aus/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
119
119
  reconcile/aus/advanced_upgrade_service.py,sha256=BxQU2O037MXopmTfcAaBDus4RJI4acXe05WqTKuPk_s,21098
120
120
  reconcile/aus/aus_label_source.py,sha256=X6FD4NYcX27llMUSmmBcCh-pG7U5FnBd0zl-0zwCj2U,4118
121
- reconcile/aus/base.py,sha256=MCR0QAtBifRut6N4g72ognryPYuRp1cQ2YBz_4jKnG4,43486
121
+ reconcile/aus/base.py,sha256=h_4MJbMHALy2TeaGs-d5KVTksu7EOGCBFljeFUERQbk,43635
122
122
  reconcile/aus/cluster_version_data.py,sha256=j4UyEBi5mQuvPq5Lo7a_L_0blxvH790wJV07uAiikFU,7126
123
- reconcile/aus/metrics.py,sha256=CI5H3kzWh5VUYjt8NfzcYdJ8L4HdTCcUQTZiLdwdLFc,3506
123
+ reconcile/aus/metrics.py,sha256=lUNIjCCyAvU9f4aTx4i5RkQrjKjKD37i4AE4LlTriHs,3544
124
124
  reconcile/aus/models.py,sha256=oBSVZ-3JTngxKg_bH1vAfREpz55t8K-Y3eC9TA4pOTw,6849
125
- reconcile/aus/ocm_addons_upgrade_scheduler_org.py,sha256=4f4AOoEUBxYdTIUnyev1ECPvbfVHSESQhXl7fuU-iGk,8811
125
+ reconcile/aus/ocm_addons_upgrade_scheduler_org.py,sha256=fshslI27hrqT40qrVsVOQaWxD-jkmzcVZryXzX7plhY,8960
126
126
  reconcile/aus/ocm_upgrade_scheduler.py,sha256=7cK2SakCFkl5EdnqUEAYdUo4pUnnf-SsUR10uytAGyE,3058
127
127
  reconcile/aus/ocm_upgrade_scheduler_org.py,sha256=OBgE5mnVdQQV4tMH0AE2V_PDt9Gy6d-LyuPceqjORts,2331
128
128
  reconcile/aus/upgrades.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -376,7 +376,7 @@ reconcile/test/test_checkpoint.py,sha256=sbDtqTbfw5yMZ_mCltMXxkyyGueVLGUjTDtcWhP
376
376
  reconcile/test/test_cli.py,sha256=qx_iBwh4Z-YkK3sbjK1wEziPTgn060EN-baf9DNvR3k,1096
377
377
  reconcile/test/test_closedbox_endpoint_monitoring.py,sha256=isMHYwRWMFARU2nbJgbl69kD6H0eA86noCM4MPVI1fo,7151
378
378
  reconcile/test/test_dashdotdb_dora.py,sha256=XDMdnLDvup8sSqQEynxdPhXQZAafYbd2IUo9flSRJ8I,7917
379
- reconcile/test/test_database_access_manager.py,sha256=wc2Ov9GX8iAc7_ubwPJxsLZQUYt0KpaRzEIF6gfnsqM,19497
379
+ reconcile/test/test_database_access_manager.py,sha256=9yGFmsDt5ar6fy1WvKxBovbFETX5kmkUMOykMe2fEDU,19594
380
380
  reconcile/test/test_gabi_authorized_users.py,sha256=6XnV5Q9inxP81ktGMVKyWucjBTUj8Imy2L0HG3YHyUE,2496
381
381
  reconcile/test/test_github_org.py,sha256=j3KeB4OnSln1gm2hidce49xdMru-j75NS3cM-AEgzZc,4511
382
382
  reconcile/test/test_github_repo_invites.py,sha256=QJ0VFk5B59rx4XtHoT6XOGWw9xRIZMen_cgtviN_Vi8,3419
@@ -392,7 +392,7 @@ reconcile/test/test_make.py,sha256=zTdjgq-3idFlec_0qJenk9wWw0QMLvSpJfPsptXmync,6
392
392
  reconcile/test/test_ocm_additional_routers.py,sha256=dtbpUnD5un6Q3VoLbuFRb_njmt5SSCnBzvSSBcO_Xxs,4248
393
393
  reconcile/test/test_ocm_clusters.py,sha256=MLH6r5G-T3e53tYDoyJYfC6X1oEZGmakk1SXR1w3jJw,22490
394
394
  reconcile/test/test_ocm_clusters_manifest_updates.py,sha256=jFRVfc5jby1kI2x_gT6wcqPPgkav1et9wZH6JqQbNSY,3278
395
- reconcile/test/test_ocm_machine_pools.py,sha256=4z-U3-vGVvYZPdvxP0d1HHfHoD5yXvo7Ek4N2Wyofvo,23547
395
+ reconcile/test/test_ocm_machine_pools.py,sha256=uPtu3XG1xmRiEIZ3Uw_RTsZIgRkm_n6EGURWXqTyGyU,29789
396
396
  reconcile/test/test_ocm_update_recommended_version.py,sha256=ONY3slwUHwEdonvIYRI2Z8nWPDMTSSLGZ2I1dqaz7fg,4328
397
397
  reconcile/test/test_ocm_upgrade_scheduler_org_updater.py,sha256=zYRGUX7pAmxSv9oFYw2ZnPGa-YAPgDfmqXOJM4eE-8A,4353
398
398
  reconcile/test/test_openshift_base.py,sha256=owJsyyatl_7z6igUEDeJcMMV5_jIwcV2Yj7YgsmYkXs,27035
@@ -646,8 +646,8 @@ tools/test/test_app_interface_metrics_exporter.py,sha256=dmEcNwZltP1rd_4DbxIYakO
646
646
  tools/test/test_qontract_cli.py,sha256=awwTHEc2DWlykuqGIYM0WOBoSL0KRnOraCLk3C7izis,1401
647
647
  tools/test/test_sd_app_sre_alert_report.py,sha256=v363r9zM7__0kR5K6mvJoGFcM9BvE33fWAayrqkpojA,2116
648
648
  tools/test/test_sre_checkpoints.py,sha256=SKqPPTl9ua0RFdSSofnoQX-JZE6dFLO3LRhfQzqtfh8,2607
649
- qontract_reconcile-0.10.1rc445.dist-info/METADATA,sha256=NGeStfO_tsa4WmT8aV_sX16TDRH-_jxeqYhw7dHCf_s,2348
650
- qontract_reconcile-0.10.1rc445.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
651
- qontract_reconcile-0.10.1rc445.dist-info/entry_points.txt,sha256=rTjAv28I_CHLM8ID3OPqMI_suoQ9s7tFbim4aYjn9kk,376
652
- qontract_reconcile-0.10.1rc445.dist-info/top_level.txt,sha256=l5ISPoXzt0SdR4jVdkfa7RPSKNc8zAHYWAnR-Dw8Ey8,24
653
- qontract_reconcile-0.10.1rc445.dist-info/RECORD,,
649
+ qontract_reconcile-0.10.1rc449.dist-info/METADATA,sha256=E2bO2KPEa-O0CBcDnYqJkEyOOndI0tpzL0CDdBumIDM,2348
650
+ qontract_reconcile-0.10.1rc449.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
651
+ qontract_reconcile-0.10.1rc449.dist-info/entry_points.txt,sha256=rTjAv28I_CHLM8ID3OPqMI_suoQ9s7tFbim4aYjn9kk,376
652
+ qontract_reconcile-0.10.1rc449.dist-info/top_level.txt,sha256=l5ISPoXzt0SdR4jVdkfa7RPSKNc8zAHYWAnR-Dw8Ey8,24
653
+ qontract_reconcile-0.10.1rc449.dist-info/RECORD,,
reconcile/aus/base.py CHANGED
@@ -296,6 +296,8 @@ class AdvancedUpgradeSchedulerBaseIntegration(
296
296
  cluster_upgrade_spec.upgrade_policy.conditions.soak_days or 0
297
297
  ),
298
298
  workloads=",".join(cluster_upgrade_spec.upgrade_policy.workloads),
299
+ product=cluster_upgrade_spec.cluster.product.id,
300
+ hypershift=cluster_upgrade_spec.cluster.hypershift.enabled,
299
301
  ),
300
302
  )
301
303
 
reconcile/aus/metrics.py CHANGED
@@ -66,6 +66,8 @@ class AUSClusterUpgradePolicyInfoMetric(AUSBaseMetric, InfoMetric):
66
66
  mutexes: str
67
67
  soak_days: str
68
68
  workloads: str
69
+ product: str
70
+ hypershift: bool
69
71
 
70
72
  @classmethod
71
73
  def name(cls) -> str:
@@ -211,6 +211,8 @@ class OCMAddonsUpgradeSchedulerOrgIntegration(
211
211
  ),
212
212
  workloads=",".join(cluster_upgrade_spec.upgrade_policy.workloads),
213
213
  addon=cluster_upgrade_spec.addon.id,
214
+ product=cluster_upgrade_spec.cluster.product.id,
215
+ hypershift=cluster_upgrade_spec.cluster.hypershift.enabled,
214
216
  ),
215
217
  )
216
218
 
@@ -102,9 +102,13 @@ REVOKE ALL ON DATABASE "{self._get_db()}" FROM public;
102
102
 
103
103
  \\c "{self._get_db()}"
104
104
 
105
- select 'CREATE ROLE "{self._get_user()}" WITH LOGIN PASSWORD ''{self.connection_parameter.password}'' VALID UNTIL ''infinity'''
105
+ select 'CREATE ROLE "{self._get_user()}"'
106
106
  WHERE NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname = '{self._get_db()}');\\gexec
107
107
 
108
+ ALTER ROLE "{self._get_user()}" WITH LOGIN PASSWORD '{self.connection_parameter.password}' VALID UNTIL 'infinity';
109
+
110
+ GRANT CONNECT ON DATABASE "{self._get_db()}" to "{self._get_user()}";
111
+
108
112
  -- rds specific, grant role to admin or create schema fails
109
113
  GRANT "{self._get_user()}" to "{self._get_admin_user()}";
110
114
  CREATE SCHEMA IF NOT EXISTS "{self._get_user()}" AUTHORIZATION "{self._get_user()}";"""
@@ -272,7 +276,7 @@ def get_job_spec(job_data: JobData) -> OpenshiftResource:
272
276
  command,
273
277
  ],
274
278
  "args": [
275
- "-ae",
279
+ "-b",
276
280
  "--host=$(db.host)",
277
281
  "--port=$(db.port)",
278
282
  "--username=$(db.user)",
@@ -4,6 +4,7 @@ from abc import (
4
4
  abstractmethod,
5
5
  )
6
6
  from collections.abc import Mapping
7
+ from enum import Enum
7
8
  from typing import (
8
9
  Iterable,
9
10
  Optional,
@@ -11,6 +12,7 @@ from typing import (
11
12
 
12
13
  from pydantic import (
13
14
  BaseModel,
15
+ Field,
14
16
  root_validator,
15
17
  )
16
18
 
@@ -24,6 +26,7 @@ from reconcile.typed_queries.clusters import get_clusters
24
26
  from reconcile.utils.differ import diff_mappings
25
27
  from reconcile.utils.disabled_integrations import integration_is_enabled
26
28
  from reconcile.utils.ocm import (
29
+ DEFAULT_OCM_MACHINE_POOL_ID,
27
30
  OCM,
28
31
  OCMMap,
29
32
  )
@@ -31,6 +34,12 @@ from reconcile.utils.ocm import (
31
34
  QONTRACT_INTEGRATION = "ocm-machine-pools"
32
35
 
33
36
 
37
+ class ClusterType(Enum):
38
+ OSD = "osd"
39
+ ROSA_CLASSIC = "rosa"
40
+ ROSA_HCP = "hypershift"
41
+
42
+
34
43
  class InvalidUpdateError(Exception):
35
44
  pass
36
45
 
@@ -95,6 +104,7 @@ class AbstractPool(ABC, BaseModel):
95
104
  taints: Optional[list[Mapping[str, str]]]
96
105
  labels: Optional[Mapping[str, str]]
97
106
  cluster: str
107
+ cluster_type: ClusterType = Field(..., exclude=True)
98
108
  autoscaling: Optional[AbstractAutoscaling]
99
109
 
100
110
  @root_validator()
@@ -180,10 +190,19 @@ class MachinePool(AbstractPool):
180
190
  return None
181
191
 
182
192
  def deletable(self) -> bool:
183
- return True
193
+ # OSD NON CCS clusters can't delete default worker machine pool
194
+ return not (
195
+ self.cluster_type == ClusterType.OSD
196
+ and self.id == DEFAULT_OCM_MACHINE_POOL_ID
197
+ )
184
198
 
185
199
  @classmethod
186
- def create_from_gql(cls, pool: ClusterMachinePoolV1, cluster: str):
200
+ def create_from_gql(
201
+ cls,
202
+ pool: ClusterMachinePoolV1,
203
+ cluster: str,
204
+ cluster_type: ClusterType,
205
+ ):
187
206
  autoscaling: Optional[MachinePoolAutoscaling] = None
188
207
  if pool.autoscale:
189
208
  autoscaling = MachinePoolAutoscaling(
@@ -198,6 +217,7 @@ class MachinePool(AbstractPool):
198
217
  taints=[p.dict(by_alias=True) for p in pool.taints or []],
199
218
  labels=pool.labels,
200
219
  cluster=cluster,
220
+ cluster_type=cluster_type,
201
221
  )
202
222
 
203
223
 
@@ -254,11 +274,15 @@ class NodePool(AbstractPool):
254
274
  return None
255
275
 
256
276
  def deletable(self) -> bool:
257
- # As of now, you can not delete the first worker pool(s)
258
- return not self.id.startswith("workers")
277
+ return True
259
278
 
260
279
  @classmethod
261
- def create_from_gql(cls, pool: ClusterMachinePoolV1, cluster: str):
280
+ def create_from_gql(
281
+ cls,
282
+ pool: ClusterMachinePoolV1,
283
+ cluster: str,
284
+ cluster_type: ClusterType,
285
+ ):
262
286
  autoscaling: Optional[NodePoolAutoscaling] = None
263
287
  if pool.autoscale:
264
288
  autoscaling = NodePoolAutoscaling(
@@ -277,6 +301,7 @@ class NodePool(AbstractPool):
277
301
  labels=pool.labels,
278
302
  subnet=pool.subnet,
279
303
  cluster=cluster,
304
+ cluster_type=cluster_type,
280
305
  )
281
306
 
282
307
 
@@ -303,7 +328,7 @@ class PoolHandler(BaseModel):
303
328
 
304
329
  class DesiredMachinePool(BaseModel):
305
330
  cluster_name: str
306
- hypershift: bool
331
+ cluster_type: ClusterType
307
332
  pools: list[ClusterMachinePoolV1]
308
333
 
309
334
  def build_pool_handler(
@@ -312,11 +337,13 @@ class DesiredMachinePool(BaseModel):
312
337
  pool: ClusterMachinePoolV1,
313
338
  ) -> PoolHandler:
314
339
  pool_builder = (
315
- NodePool.create_from_gql if self.hypershift else MachinePool.create_from_gql
340
+ NodePool.create_from_gql
341
+ if self.cluster_type == ClusterType.ROSA_HCP
342
+ else MachinePool.create_from_gql
316
343
  )
317
344
  return PoolHandler(
318
345
  action=action,
319
- pool=pool_builder(pool, self.cluster_name),
346
+ pool=pool_builder(pool, self.cluster_name, self.cluster_type),
320
347
  )
321
348
 
322
349
 
@@ -330,12 +357,25 @@ def fetch_current_state(
330
357
  }
331
358
 
332
359
 
333
- def _is_hypershift(cluster: ClusterV1) -> bool:
334
- return bool(cluster.spec and cluster.spec.hypershift)
360
+ def _classify_cluster_type(cluster: ClusterV1) -> ClusterType:
361
+ if cluster.spec is None:
362
+ raise ValueError(f"cluster {cluster.name} is missing spec")
363
+ match cluster.spec.product:
364
+ case "osd":
365
+ return ClusterType.OSD
366
+ case "rosa":
367
+ return (
368
+ ClusterType.ROSA_HCP
369
+ if cluster.spec.hypershift
370
+ else ClusterType.ROSA_CLASSIC
371
+ )
372
+ case _:
373
+ raise ValueError(f"unknown cluster type for cluster {cluster.name}")
335
374
 
336
375
 
337
376
  def fetch_current_state_for_cluster(cluster, ocm):
338
- if _is_hypershift(cluster):
377
+ cluster_type = _classify_cluster_type(cluster)
378
+ if cluster_type == ClusterType.ROSA_HCP:
339
379
  return [
340
380
  NodePool(
341
381
  id=node_pool["id"],
@@ -354,6 +394,7 @@ def fetch_current_state_for_cluster(cluster, ocm):
354
394
  labels=node_pool.get("labels"),
355
395
  subnet=node_pool.get("subnet"),
356
396
  cluster=cluster.name,
397
+ cluster_type=cluster_type,
357
398
  )
358
399
  for node_pool in ocm.get_node_pools(cluster.name)
359
400
  ]
@@ -371,6 +412,7 @@ def fetch_current_state_for_cluster(cluster, ocm):
371
412
  taints=machine_pool.get("taints"),
372
413
  labels=machine_pool.get("labels"),
373
414
  cluster=cluster.name,
415
+ cluster_type=cluster_type,
374
416
  )
375
417
  for machine_pool in ocm.get_machine_pools(cluster.name)
376
418
  ]
@@ -382,7 +424,7 @@ def create_desired_state_from_gql(
382
424
  return {
383
425
  cluster.name: DesiredMachinePool(
384
426
  cluster_name=cluster.name,
385
- hypershift=_is_hypershift(cluster),
427
+ cluster_type=_classify_cluster_type(cluster),
386
428
  pools=cluster.machine_pools,
387
429
  )
388
430
  for cluster in clusters
@@ -452,6 +494,12 @@ def calculate_diff(
452
494
  pool=current_machine_pool,
453
495
  )
454
496
  )
497
+ else:
498
+ errors.append(
499
+ InvalidUpdateError(
500
+ f"can not delete machine pool {current_machine_pool.id} for cluster {cluster_name}"
501
+ )
502
+ )
455
503
 
456
504
  return diffs, errors
457
505
 
@@ -131,7 +131,9 @@ def openshift_resource_secet() -> OpenshiftResource:
131
131
  def _assert_create_script(script: str) -> None:
132
132
  assert 'CREATE DATABASE "test"' in script
133
133
  assert "REVOKE ALL ON DATABASE" in script
134
- assert 'CREATE ROLE "test" WITH LOGIN PASSWORD' in script
134
+ assert 'CREATE ROLE "test"' in script
135
+ assert 'ALTER ROLE "test" WITH LOGIN' in script
136
+ assert 'GRANT CONNECT ON DATABASE "test" to "test"' in script
135
137
  assert "CREATE SCHEMA IF NOT EXISTS" in script
136
138
  assert 'GRANT "test" to "admin";' in script
137
139
 
@@ -19,6 +19,7 @@ from reconcile.gql_definitions.common.clusters import (
19
19
  from reconcile.ocm_machine_pools import (
20
20
  AbstractPool,
21
21
  AWSNodePool,
22
+ ClusterType,
22
23
  DesiredMachinePool,
23
24
  InvalidUpdateError,
24
25
  MachinePool,
@@ -63,6 +64,7 @@ def test_pool() -> TestPool:
63
64
  labels=None,
64
65
  taints=None,
65
66
  cluster="cluster1",
67
+ cluster_type=ClusterType.OSD,
66
68
  )
67
69
 
68
70
 
@@ -77,6 +79,7 @@ def current_with_pool() -> Mapping[str, list[AbstractPool]]:
77
79
  labels=None,
78
80
  taints=None,
79
81
  cluster="cluster1",
82
+ cluster_type=ClusterType.OSD,
80
83
  )
81
84
  ]
82
85
  }
@@ -90,6 +93,7 @@ def node_pool() -> NodePool:
90
93
  labels=None,
91
94
  taints=None,
92
95
  cluster="cluster1",
96
+ cluster_type=ClusterType.ROSA_HCP,
93
97
  subnet="subnet1",
94
98
  aws_node_pool=AWSNodePool(
95
99
  instance_type="m5.xlarge",
@@ -105,7 +109,7 @@ def machine_pool() -> MachinePool:
105
109
  labels=None,
106
110
  taints=None,
107
111
  cluster="cluster1",
108
- subnet="subnet1",
112
+ cluster_type=ClusterType.OSD,
109
113
  instance_type="m5.xlarge",
110
114
  )
111
115
 
@@ -129,7 +133,7 @@ def ocm_mock():
129
133
 
130
134
 
131
135
  def test_diff__has_diff_autoscale(cluster_machine_pool: ClusterMachinePoolV1):
132
- pool = TestPool(id="pool1", cluster="cluster1")
136
+ pool = TestPool(id="pool1", cluster="cluster1", cluster_type=ClusterType.OSD)
133
137
 
134
138
  assert cluster_machine_pool.autoscale is None
135
139
  assert not pool._has_diff_autoscale(cluster_machine_pool)
@@ -165,7 +169,7 @@ def test_calculate_diff_create():
165
169
  desired = {
166
170
  "cluster1": DesiredMachinePool(
167
171
  cluster_name="cluster1",
168
- hypershift=False,
172
+ cluster_type=ClusterType.OSD,
169
173
  pools=[
170
174
  ClusterMachinePoolV1(
171
175
  id="pool1",
@@ -190,7 +194,7 @@ def test_calculate_diff_noop(current_with_pool):
190
194
  desired = {
191
195
  "cluster1": DesiredMachinePool(
192
196
  cluster_name="cluster1",
193
- hypershift=False,
197
+ cluster_type=ClusterType.OSD,
194
198
  pools=[
195
199
  ClusterMachinePoolV1(
196
200
  id="pool1",
@@ -213,7 +217,7 @@ def test_calculate_diff_update(current_with_pool):
213
217
  desired = {
214
218
  "cluster1": DesiredMachinePool(
215
219
  cluster_name="cluster1",
216
- hypershift=False,
220
+ cluster_type=ClusterType.OSD,
217
221
  pools=[
218
222
  ClusterMachinePoolV1(
219
223
  id="pool1",
@@ -245,6 +249,7 @@ def current_with_2_pools() -> Mapping[str, list[AbstractPool]]:
245
249
  labels=None,
246
250
  taints=None,
247
251
  cluster="cluster1",
252
+ cluster_type=ClusterType.OSD,
248
253
  ),
249
254
  MachinePool(
250
255
  id="workers",
@@ -253,6 +258,7 @@ def current_with_2_pools() -> Mapping[str, list[AbstractPool]]:
253
258
  labels=None,
254
259
  taints=None,
255
260
  cluster="cluster1",
261
+ cluster_type=ClusterType.OSD,
256
262
  ),
257
263
  ]
258
264
  }
@@ -262,7 +268,7 @@ def test_calculate_diff_delete(current_with_2_pools):
262
268
  desired = {
263
269
  "cluster1": DesiredMachinePool(
264
270
  cluster_name="cluster1",
265
- hypershift=False,
271
+ cluster_type=ClusterType.OSD,
266
272
  pools=[
267
273
  ClusterMachinePoolV1(
268
274
  id="pool1",
@@ -287,7 +293,7 @@ def test_calculate_diff_delete_all_fail_validation(current_with_pool):
287
293
  desired = {
288
294
  "cluster1": DesiredMachinePool(
289
295
  cluster_name="cluster1",
290
- hypershift=False,
296
+ cluster_type=ClusterType.OSD,
291
297
  pools=[],
292
298
  ),
293
299
  }
@@ -450,7 +456,33 @@ def test_run_no_action(mocker: MockerFixture) -> None:
450
456
 
451
457
 
452
458
  @pytest.fixture
453
- def ocm_cluster_builder(
459
+ def osd_cluster_builder(
460
+ gql_class_factory: Callable[..., ClusterV1],
461
+ ) -> Callable[..., ClusterV1]:
462
+ def builder(machine_pools: list[dict]) -> ClusterV1:
463
+ return gql_class_factory(
464
+ ClusterV1,
465
+ {
466
+ "name": "ocm-cluster",
467
+ "auth": [],
468
+ "spec": {
469
+ "product": "osd",
470
+ },
471
+ "ocm": {
472
+ "name": "ocm-name",
473
+ "environment": {
474
+ "accessTokenClientSecret": {},
475
+ },
476
+ },
477
+ "machinePools": machine_pools,
478
+ },
479
+ )
480
+
481
+ return builder
482
+
483
+
484
+ @pytest.fixture
485
+ def rosa_cluster_builder(
454
486
  gql_class_factory: Callable[..., ClusterV1],
455
487
  ) -> Callable[..., ClusterV1]:
456
488
  def builder(machine_pools: list[dict]) -> ClusterV1:
@@ -459,6 +491,9 @@ def ocm_cluster_builder(
459
491
  {
460
492
  "name": "ocm-cluster",
461
493
  "auth": [],
494
+ "spec": {
495
+ "product": "rosa",
496
+ },
462
497
  "ocm": {
463
498
  "name": "ocm-name",
464
499
  "environment": {
@@ -482,11 +517,19 @@ def default_worker_machine_pool() -> dict:
482
517
 
483
518
 
484
519
  @pytest.fixture
485
- def ocm_cluster_with_default_machine_pool(
486
- ocm_cluster_builder: Callable[..., ClusterV1],
520
+ def osd_cluster_with_default_machine_pool(
521
+ osd_cluster_builder,
522
+ default_worker_machine_pool: dict,
523
+ ) -> ClusterV1:
524
+ return osd_cluster_builder([default_worker_machine_pool])
525
+
526
+
527
+ @pytest.fixture
528
+ def rosa_cluster_with_default_machine_pool(
529
+ rosa_cluster_builder,
487
530
  default_worker_machine_pool: dict,
488
531
  ) -> ClusterV1:
489
- return ocm_cluster_builder([default_worker_machine_pool])
532
+ return rosa_cluster_builder([default_worker_machine_pool])
490
533
 
491
534
 
492
535
  @pytest.fixture
@@ -499,12 +542,26 @@ def new_workers_machine_pool() -> dict:
499
542
 
500
543
 
501
544
  @pytest.fixture
502
- def ocm_cluster_with_default_and_new_machine_pools(
503
- ocm_cluster_builder: Callable[..., ClusterV1],
545
+ def osd_cluster_with_default_and_new_machine_pools(
546
+ osd_cluster_builder,
547
+ default_worker_machine_pool: dict,
548
+ new_workers_machine_pool: dict,
549
+ ) -> ClusterV1:
550
+ return osd_cluster_builder(
551
+ [
552
+ default_worker_machine_pool,
553
+ new_workers_machine_pool,
554
+ ]
555
+ )
556
+
557
+
558
+ @pytest.fixture
559
+ def rosa_cluster_with_default_and_new_machine_pools(
560
+ rosa_cluster_builder,
504
561
  default_worker_machine_pool: dict,
505
562
  new_workers_machine_pool: dict,
506
563
  ) -> ClusterV1:
507
- return ocm_cluster_builder(
564
+ return rosa_cluster_builder(
508
565
  [
509
566
  default_worker_machine_pool,
510
567
  new_workers_machine_pool,
@@ -525,22 +582,42 @@ def expected_ocm_machine_pool_create_payload() -> dict:
525
582
  }
526
583
 
527
584
 
528
- def test_run_create_machine_pool(
585
+ def test_run_create_machine_pool_for_osd_cluster(
529
586
  mocker: MockerFixture,
530
- ocm_cluster_with_default_and_new_machine_pools: ClusterV1,
587
+ osd_cluster_with_default_and_new_machine_pools: ClusterV1,
531
588
  default_worker_machine_pool: dict,
532
589
  expected_ocm_machine_pool_create_payload: dict,
533
590
  ) -> None:
534
591
  mocks = setup_mocks(
535
592
  mocker,
536
- clusters=[ocm_cluster_with_default_and_new_machine_pools],
593
+ clusters=[osd_cluster_with_default_and_new_machine_pools],
537
594
  machine_pools=[default_worker_machine_pool],
538
595
  )
539
596
 
540
597
  run(False)
541
598
 
542
599
  mocks["OCM"].create_machine_pool.assert_called_once_with(
543
- ocm_cluster_with_default_and_new_machine_pools.name,
600
+ osd_cluster_with_default_and_new_machine_pools.name,
601
+ expected_ocm_machine_pool_create_payload,
602
+ )
603
+
604
+
605
+ def test_run_create_machine_pool_for_rosa_cluster(
606
+ mocker: MockerFixture,
607
+ rosa_cluster_with_default_and_new_machine_pools: ClusterV1,
608
+ default_worker_machine_pool: dict,
609
+ expected_ocm_machine_pool_create_payload: dict,
610
+ ) -> None:
611
+ mocks = setup_mocks(
612
+ mocker,
613
+ clusters=[rosa_cluster_with_default_and_new_machine_pools],
614
+ machine_pools=[default_worker_machine_pool],
615
+ )
616
+
617
+ run(False)
618
+
619
+ mocks["OCM"].create_machine_pool.assert_called_once_with(
620
+ rosa_cluster_with_default_and_new_machine_pools.name,
544
621
  expected_ocm_machine_pool_create_payload,
545
622
  )
546
623
 
@@ -564,22 +641,42 @@ def expected_ocm_machine_pool_update_payload() -> dict:
564
641
  }
565
642
 
566
643
 
567
- def test_run_update_machine_pool(
644
+ def test_run_update_machine_pool_for_osd_cluster(
645
+ mocker: MockerFixture,
646
+ osd_cluster_with_default_machine_pool: ClusterV1,
647
+ existing_updated_default_machine_pool: dict,
648
+ expected_ocm_machine_pool_update_payload: dict,
649
+ ) -> None:
650
+ mocks = setup_mocks(
651
+ mocker,
652
+ clusters=[osd_cluster_with_default_machine_pool],
653
+ machine_pools=[existing_updated_default_machine_pool],
654
+ )
655
+
656
+ run(False)
657
+
658
+ mocks["OCM"].update_machine_pool.assert_called_once_with(
659
+ osd_cluster_with_default_machine_pool.name,
660
+ expected_ocm_machine_pool_update_payload,
661
+ )
662
+
663
+
664
+ def test_run_update_machine_pool_for_rosa_cluster(
568
665
  mocker: MockerFixture,
569
- ocm_cluster_with_default_machine_pool: ClusterV1,
666
+ rosa_cluster_with_default_machine_pool: ClusterV1,
570
667
  existing_updated_default_machine_pool: dict,
571
668
  expected_ocm_machine_pool_update_payload: dict,
572
669
  ) -> None:
573
670
  mocks = setup_mocks(
574
671
  mocker,
575
- clusters=[ocm_cluster_with_default_machine_pool],
672
+ clusters=[rosa_cluster_with_default_machine_pool],
576
673
  machine_pools=[existing_updated_default_machine_pool],
577
674
  )
578
675
 
579
676
  run(False)
580
677
 
581
678
  mocks["OCM"].update_machine_pool.assert_called_once_with(
582
- ocm_cluster_with_default_machine_pool.name,
679
+ rosa_cluster_with_default_machine_pool.name,
583
680
  expected_ocm_machine_pool_update_payload,
584
681
  )
585
682
 
@@ -593,14 +690,32 @@ def existing_default_machine_pool_with_different_instance_type() -> dict:
593
690
  }
594
691
 
595
692
 
596
- def test_run_update_machine_pool_error(
693
+ def test_run_update_machine_pool_error_for_osd_cluster(
597
694
  mocker: MockerFixture,
598
- ocm_cluster_with_default_machine_pool: ClusterV1,
695
+ osd_cluster_with_default_machine_pool: ClusterV1,
599
696
  existing_default_machine_pool_with_different_instance_type: dict,
600
697
  ) -> None:
601
698
  setup_mocks(
602
699
  mocker,
603
- clusters=[ocm_cluster_with_default_machine_pool],
700
+ clusters=[osd_cluster_with_default_machine_pool],
701
+ machine_pools=[existing_default_machine_pool_with_different_instance_type],
702
+ )
703
+
704
+ with pytest.raises(ExceptionGroup) as eg:
705
+ run(False)
706
+
707
+ assert len(eg.value.exceptions) == 1
708
+ assert isinstance(eg.value.exceptions[0], InvalidUpdateError)
709
+
710
+
711
+ def test_run_update_machine_pool_error_for_rosa_cluster(
712
+ mocker: MockerFixture,
713
+ rosa_cluster_with_default_machine_pool: ClusterV1,
714
+ existing_default_machine_pool_with_different_instance_type: dict,
715
+ ) -> None:
716
+ setup_mocks(
717
+ mocker,
718
+ clusters=[rosa_cluster_with_default_machine_pool],
604
719
  machine_pools=[existing_default_machine_pool_with_different_instance_type],
605
720
  )
606
721
 
@@ -624,42 +739,70 @@ def expected_ocm_machine_pool_delete_payload() -> dict:
624
739
  }
625
740
 
626
741
 
627
- def test_run_delete_machine_pool(
742
+ def test_run_delete_machine_pool_for_osd_cluster(
743
+ mocker: MockerFixture,
744
+ osd_cluster_with_default_machine_pool: ClusterV1,
745
+ default_worker_machine_pool: dict,
746
+ new_workers_machine_pool: dict,
747
+ expected_ocm_machine_pool_delete_payload: dict,
748
+ ) -> None:
749
+ mocks = setup_mocks(
750
+ mocker,
751
+ clusters=[osd_cluster_with_default_machine_pool],
752
+ machine_pools=[default_worker_machine_pool, new_workers_machine_pool],
753
+ )
754
+
755
+ run(False)
756
+
757
+ mocks["OCM"].delete_machine_pool.assert_called_once_with(
758
+ osd_cluster_with_default_machine_pool.name,
759
+ expected_ocm_machine_pool_delete_payload,
760
+ )
761
+
762
+
763
+ def test_run_delete_machine_pool_for_rosa_cluster(
628
764
  mocker: MockerFixture,
629
- ocm_cluster_with_default_machine_pool: ClusterV1,
630
- default_worker_machine_pool,
765
+ rosa_cluster_with_default_machine_pool: ClusterV1,
766
+ default_worker_machine_pool: dict,
631
767
  new_workers_machine_pool: dict,
632
768
  expected_ocm_machine_pool_delete_payload: dict,
633
769
  ) -> None:
634
770
  mocks = setup_mocks(
635
771
  mocker,
636
- clusters=[ocm_cluster_with_default_machine_pool],
772
+ clusters=[rosa_cluster_with_default_machine_pool],
637
773
  machine_pools=[default_worker_machine_pool, new_workers_machine_pool],
638
774
  )
639
775
 
640
776
  run(False)
641
777
 
642
778
  mocks["OCM"].delete_machine_pool.assert_called_once_with(
643
- ocm_cluster_with_default_machine_pool.name,
779
+ rosa_cluster_with_default_machine_pool.name,
644
780
  expected_ocm_machine_pool_delete_payload,
645
781
  )
646
782
 
647
783
 
648
784
  @pytest.fixture
649
- def ocm_cluster_without_machine_pools(
650
- ocm_cluster_builder: Callable[..., ClusterV1],
785
+ def osd_cluster_without_machine_pools(
786
+ osd_cluster_builder,
651
787
  ) -> ClusterV1:
652
- return ocm_cluster_builder([])
788
+ return osd_cluster_builder([])
653
789
 
654
790
 
655
- def test_run_delete_machine_pool_fail_validation(
791
+ @pytest.fixture
792
+ def rosa_cluster_without_machine_pools(
793
+ rosa_cluster_builder,
794
+ ) -> ClusterV1:
795
+ return rosa_cluster_builder([])
796
+
797
+
798
+ def test_run_delete_machine_pool_fail_validation_for_osd_cluster(
656
799
  mocker: MockerFixture,
657
- ocm_cluster_without_machine_pools: ClusterV1,
658
- default_worker_machine_pool,
800
+ osd_cluster_without_machine_pools: ClusterV1,
801
+ default_worker_machine_pool: dict,
659
802
  ) -> None:
660
803
  setup_mocks(
661
804
  mocker,
662
- clusters=[ocm_cluster_without_machine_pools],
805
+ clusters=[osd_cluster_without_machine_pools],
663
806
  machine_pools=[default_worker_machine_pool],
664
807
  )
665
808
 
@@ -670,6 +813,76 @@ def test_run_delete_machine_pool_fail_validation(
670
813
  assert isinstance(eg.value.exceptions[0], InvalidUpdateError)
671
814
 
672
815
 
816
+ def test_run_delete_machine_pool_fail_validation_for_rosa_cluster(
817
+ mocker: MockerFixture,
818
+ rosa_cluster_without_machine_pools: ClusterV1,
819
+ default_worker_machine_pool: dict,
820
+ ) -> None:
821
+ setup_mocks(
822
+ mocker,
823
+ clusters=[rosa_cluster_without_machine_pools],
824
+ machine_pools=[default_worker_machine_pool],
825
+ )
826
+
827
+ with pytest.raises(ExceptionGroup) as eg:
828
+ run(False)
829
+
830
+ assert len(eg.value.exceptions) == 1
831
+ assert isinstance(eg.value.exceptions[0], InvalidUpdateError)
832
+
833
+
834
+ @pytest.fixture
835
+ def osd_cluster_with_new_machine_pool(
836
+ osd_cluster_builder,
837
+ new_workers_machine_pool: dict,
838
+ ) -> ClusterV1:
839
+ return osd_cluster_builder([new_workers_machine_pool])
840
+
841
+
842
+ @pytest.fixture
843
+ def rosa_cluster_with_new_machine_pool(
844
+ rosa_cluster_builder,
845
+ new_workers_machine_pool: dict,
846
+ ) -> ClusterV1:
847
+ return rosa_cluster_builder([new_workers_machine_pool])
848
+
849
+
850
+ def test_run_delete_default_machine_pool_fail_validation_for_osd_cluster(
851
+ mocker: MockerFixture,
852
+ osd_cluster_with_new_machine_pool: ClusterV1,
853
+ default_worker_machine_pool: dict,
854
+ new_workers_machine_pool: dict,
855
+ ) -> None:
856
+ setup_mocks(
857
+ mocker,
858
+ clusters=[osd_cluster_with_new_machine_pool],
859
+ machine_pools=[default_worker_machine_pool, new_workers_machine_pool],
860
+ )
861
+
862
+ with pytest.raises(ExceptionGroup) as eg:
863
+ run(False)
864
+
865
+ assert len(eg.value.exceptions) == 1
866
+ assert isinstance(eg.value.exceptions[0], InvalidUpdateError)
867
+
868
+
869
+ def test_run_delete_default_machine_pool_success_for_rosa_cluster(
870
+ mocker: MockerFixture,
871
+ rosa_cluster_with_new_machine_pool: ClusterV1,
872
+ default_worker_machine_pool: dict,
873
+ new_workers_machine_pool: dict,
874
+ ) -> None:
875
+ mocks = setup_mocks(
876
+ mocker,
877
+ clusters=[rosa_cluster_with_new_machine_pool],
878
+ machine_pools=[default_worker_machine_pool, new_workers_machine_pool],
879
+ )
880
+
881
+ run(False)
882
+
883
+ mocks["OCM"].delete_machine_pool.assert_called_once()
884
+
885
+
673
886
  @pytest.fixture
674
887
  def hypershift_cluster_builder(
675
888
  gql_class_factory: Callable[..., ClusterV1],
@@ -687,6 +900,7 @@ def hypershift_cluster_builder(
687
900
  },
688
901
  },
689
902
  "spec": {
903
+ "product": "rosa",
690
904
  "hypershift": True,
691
905
  },
692
906
  "machinePools": machine_pools,
@@ -880,7 +1094,7 @@ def existing_multiple_hypershift_node_pools_with_defaults() -> list[dict]:
880
1094
  ]
881
1095
 
882
1096
 
883
- def test_run_delete_node_pool_skip_workers_ones(
1097
+ def test_run_delete_default_node_pool(
884
1098
  mocker: MockerFixture,
885
1099
  hypershift_cluster_without_default_worker_machine_pools: ClusterV1,
886
1100
  existing_multiple_hypershift_node_pools_with_defaults: list[dict],
@@ -893,4 +1107,4 @@ def test_run_delete_node_pool_skip_workers_ones(
893
1107
 
894
1108
  run(False)
895
1109
 
896
- mocks["OCM"].delete_node_pool.assert_not_called()
1110
+ mocks["OCM"].delete_node_pool.assert_called()