qontract-reconcile 0.10.1rc613__py3-none-any.whl → 0.10.1rc614__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.1rc613.dist-info → qontract_reconcile-0.10.1rc614.dist-info}/METADATA +1 -1
- {qontract_reconcile-0.10.1rc613.dist-info → qontract_reconcile-0.10.1rc614.dist-info}/RECORD +17 -15
- reconcile/cli.py +57 -4
- reconcile/ocm/types.py +1 -1
- reconcile/ocm_clusters.py +171 -103
- reconcile/templates/rosa-hcp-cluster-creation.sh.j2 +54 -0
- reconcile/test/test_ocm_clusters.py +119 -44
- reconcile/test/test_ocm_upgrade_scheduler_org_updater.py +1 -5
- reconcile/utils/jobcontroller/controller.py +1 -1
- reconcile/utils/ocm/__init__.py +29 -0
- reconcile/utils/ocm/clusters.py +7 -0
- reconcile/utils/ocm/ocm.py +58 -665
- reconcile/utils/ocm/products.py +743 -0
- reconcile/utils/rosa/session.py +53 -0
- {qontract_reconcile-0.10.1rc613.dist-info → qontract_reconcile-0.10.1rc614.dist-info}/WHEEL +0 -0
- {qontract_reconcile-0.10.1rc613.dist-info → qontract_reconcile-0.10.1rc614.dist-info}/entry_points.txt +0 -0
- {qontract_reconcile-0.10.1rc613.dist-info → qontract_reconcile-0.10.1rc614.dist-info}/top_level.txt +0 -0
{qontract_reconcile-0.10.1rc613.dist-info → qontract_reconcile-0.10.1rc614.dist-info}/METADATA
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: qontract-reconcile
|
3
|
-
Version: 0.10.
|
3
|
+
Version: 0.10.1rc614
|
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
|
{qontract_reconcile-0.10.1rc613.dist-info → qontract_reconcile-0.10.1rc614.dist-info}/RECORD
RENAMED
@@ -9,7 +9,7 @@ reconcile/aws_iam_password_reset.py,sha256=NwErtrqgBiXr7eGCAHdtGGOx0S7-4JnSc29Ie
|
|
9
9
|
reconcile/aws_support_cases_sos.py,sha256=Jk6_XjDeJSYxgRGqcEAOcynt9qJF2r5HPIPcSKmoBv8,2974
|
10
10
|
reconcile/blackbox_exporter_endpoint_monitoring.py,sha256=W_VJagnsJR1v5oqjlI3RJJE0_nhtJ0m81RS8zWA5u5c,3538
|
11
11
|
reconcile/checkpoint.py,sha256=R2WFXUXLTB4sWMi4GeA4eegsuf_1-Q4vH8M0Toh3Ij4,5036
|
12
|
-
reconcile/cli.py,sha256=
|
12
|
+
reconcile/cli.py,sha256=Gu9RMIRj9mA9vP7AkTj1sxqMyMdKZk1VU4XNQGVhuX0,93058
|
13
13
|
reconcile/closedbox_endpoint_monitoring_base.py,sha256=SMhkcQqprWvThrIJa3U_3uh5w1h-alleW1QnCJFY4Qw,4909
|
14
14
|
reconcile/cluster_deployment_mapper.py,sha256=2Ah-nu-Mdig0pjuiZl_XLrmVAjYzFjORR3dMlCgkmw0,2352
|
15
15
|
reconcile/dashdotdb_base.py,sha256=a5aPLVxyqPSbjdB0Ty-uliOtxwvEbbEljHJKxdK3-Zk,4813
|
@@ -53,7 +53,7 @@ reconcile/ocm_additional_routers.py,sha256=KfcFDVbNoc6n5dHWjYdAf1_DiVqVG6Tw23WLK
|
|
53
53
|
reconcile/ocm_addons.py,sha256=qqAyqRBRbdZQvAcjb-QlSVyRAyQBZk6iVlgnI4jyi7s,3353
|
54
54
|
reconcile/ocm_addons_upgrade_tests_trigger.py,sha256=L1ktYynIR7pmHiYtdCTdLGJRKX72B54KUAuPLOccXzo,3995
|
55
55
|
reconcile/ocm_aws_infrastructure_access.py,sha256=iq6Rj5SgF7yIMvBhukTuy-KcrFsvLs1ATG6-dyiArqY,6960
|
56
|
-
reconcile/ocm_clusters.py,sha256=
|
56
|
+
reconcile/ocm_clusters.py,sha256=YWfBF25E55Odm0L3dXnqRbC_bDuYIsBPg4j6DEpWCGw,16703
|
57
57
|
reconcile/ocm_external_configuration_labels.py,sha256=imEpDv1RBpCSj8tHDv0R76hmNCFtcUzVNgS1yOVl8vs,3870
|
58
58
|
reconcile/ocm_github_idp.py,sha256=glwXMsIBcl38-OmDDQCpe0YoLLXfoRgVQmqwXMEXjds,3946
|
59
59
|
reconcile/ocm_groups.py,sha256=AmQ61fjJYS5PxwNEWtOAvOoJM86VfRQ0-ic6wgw6PU0,2888
|
@@ -338,7 +338,7 @@ reconcile/jenkins/types.py,sha256=0UlyJxv3KY1WXHkfI_ghUI6FAwRJTL4EwvLg-62tNcg,30
|
|
338
338
|
reconcile/ldap_groups/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
339
339
|
reconcile/ldap_groups/integration.py,sha256=GscI7833EOEOiaySc2yKMg0u0hqzVJ3D3r27JfCMY4g,11425
|
340
340
|
reconcile/ocm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
341
|
-
reconcile/ocm/types.py,sha256=
|
341
|
+
reconcile/ocm/types.py,sha256=ibJYvzfAZyyMFkcF1bP8u3rkXciYJRplt_7Z1pKHFh0,2484
|
342
342
|
reconcile/ocm_internal_notifications/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
343
343
|
reconcile/ocm_internal_notifications/integration.py,sha256=6JFLu6TlcMC1OB5WgTAd-ITlhH_56W5uBytggukNk3A,4391
|
344
344
|
reconcile/ocm_labels/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -392,6 +392,7 @@ reconcile/templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSu
|
|
392
392
|
reconcile/templates/aws_access_key_email.j2,sha256=2MUr1ERmyISzKgHqsWYLd-1Wbl-peUa-FsGUS-JLUFc,238
|
393
393
|
reconcile/templates/email.yml.j2,sha256=OZgczNRgXPj2gVYTgwQyHAQrMGu7xp-e4W1rX19GcrU,690
|
394
394
|
reconcile/templates/jira-checkpoint-missinginfo.j2,sha256=c_Vvg-lEENsB3tgxm9B6Y9igCUQhCnFDYh6xw-zcIbU,570
|
395
|
+
reconcile/templates/rosa-hcp-cluster-creation.sh.j2,sha256=6qjnvWgkJ6A0Mh08uRKMWewxDeOqc0ju4JSmlp5sW_I,2146
|
395
396
|
reconcile/templating/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
396
397
|
reconcile/templating/renderer.py,sha256=IOZN0ASSKqp4JGXZ1BDba4XosD3nCuqhStxHMGBcxDI,5119
|
397
398
|
reconcile/templating/rendering.py,sha256=msMGqCNh7M0c6A1l_7KBmT3GRHH9gsB8htN_9bGtwe4,4949
|
@@ -429,11 +430,11 @@ reconcile/test/test_jump_host.py,sha256=yczTqvT-hNAf9zBMuFjqka9fQOA31SCNG7D-9K9M
|
|
429
430
|
reconcile/test/test_ldap_users.py,sha256=8jjzVgoiRRylGad6-TvkugoFGXt3eko--zVVKjmZDn4,3812
|
430
431
|
reconcile/test/test_make.py,sha256=zTdjgq-3idFlec_0qJenk9wWw0QMLvSpJfPsptXmync,677
|
431
432
|
reconcile/test/test_ocm_additional_routers.py,sha256=dtbpUnD5un6Q3VoLbuFRb_njmt5SSCnBzvSSBcO_Xxs,4248
|
432
|
-
reconcile/test/test_ocm_clusters.py,sha256=
|
433
|
+
reconcile/test/test_ocm_clusters.py,sha256=yiymyepNwV_JiCGEsvqKVAxq3WNJHsvrpJRuNRlyvtM,25468
|
433
434
|
reconcile/test/test_ocm_clusters_manifest_updates.py,sha256=jFRVfc5jby1kI2x_gT6wcqPPgkav1et9wZH6JqQbNSY,3278
|
434
435
|
reconcile/test/test_ocm_machine_pools.py,sha256=3qo6t2Jfr1Wee0NUacyLTDmatp0o7CUNpkVOpHiOiGk,29737
|
435
436
|
reconcile/test/test_ocm_update_recommended_version.py,sha256=iA4BVirTGVXlwcOyeR52IuNO81X_8NR6ZNd7ZFE7igs,4328
|
436
|
-
reconcile/test/test_ocm_upgrade_scheduler_org_updater.py,sha256=
|
437
|
+
reconcile/test/test_ocm_upgrade_scheduler_org_updater.py,sha256=V91g2XQMa2nvKwkLVWkiPwNL6pMQE16s4jO0oXJ6wdk,4330
|
437
438
|
reconcile/test/test_openshift_base.py,sha256=uVsnMghAQhHaJTreeOw4x2INTKJ6qeiZiiteWeKflW8,33874
|
438
439
|
reconcile/test/test_openshift_cluster_bots.py,sha256=L-yuKvMgB0LBCdfLu7wozh_lk6S_m3umXt3m_ECfLEI,8023
|
439
440
|
reconcile/test/test_openshift_namespace_labels.py,sha256=P1hqi6P88NijNrurdXG_QR2usyo3EYZSy9zpwYHvDsM,12104
|
@@ -638,7 +639,7 @@ reconcile/utils/jinja2/extensions.py,sha256=zV_x8MhSHAynKhFnG3fULXrwsm5fUG_88Iyg
|
|
638
639
|
reconcile/utils/jinja2/filters.py,sha256=_kJjdMsY3lGS5PUn4NnpXUQDNrL1IwiKsB-0MhTMGYM,4521
|
639
640
|
reconcile/utils/jinja2/utils.py,sha256=1TV_BoKrCFxVPbRY4hhUmbasrPa_wm9AoabCEIOXRLg,5947
|
640
641
|
reconcile/utils/jobcontroller/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
641
|
-
reconcile/utils/jobcontroller/controller.py,sha256=
|
642
|
+
reconcile/utils/jobcontroller/controller.py,sha256=QE4x-ahIWLA5GlI0KZEET0Elxq_aq4Hw1GBCRFSfv3U,14185
|
642
643
|
reconcile/utils/jobcontroller/models.py,sha256=z0gRJy8Ow1leYS-GrvTUv-t-mQDPHTJVDoHb1nVcZ_8,6349
|
643
644
|
reconcile/utils/membershipsources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
644
645
|
reconcile/utils/membershipsources/app_interface_resolver.py,sha256=IlDiRtJZ0AfAGKEawybB6SvsKbm1POTXL6fpEt699E0,1979
|
@@ -655,14 +656,15 @@ reconcile/utils/mr/notificator.py,sha256=2Xyg5Xh3xFQITdTmZ8Nry5qe0uC_w_On4uMPdlN
|
|
655
656
|
reconcile/utils/mr/ocm_update_recommended_version.py,sha256=p_aVP0TGrlKk9WBwgQnYWqUDsED_Hg6G5Bqj0UvtRwA,1536
|
656
657
|
reconcile/utils/mr/ocm_upgrade_scheduler_org_updates.py,sha256=RzEKRT_BhvB2ud9pyNFZ1cNZFmDGBUah9vjpP0y9f9w,2810
|
657
658
|
reconcile/utils/mr/user_maintenance.py,sha256=cHPBn8zrReWLHalyk-EFdkFJe9zjVjRoZhT4t2zZfGE,3956
|
658
|
-
reconcile/utils/ocm/__init__.py,sha256=
|
659
|
+
reconcile/utils/ocm/__init__.py,sha256=xv7CJp7K9LCQfa4gL_W0MMCOD1P4qOy8t5aZj1xXNUE,808
|
659
660
|
reconcile/utils/ocm/addons.py,sha256=8wVrt16i69KkXq1fQByVheSQRhrRELbuOHb7Tz9bKT0,1675
|
660
661
|
reconcile/utils/ocm/base.py,sha256=GclZtCrPkPJmGP9HHvqIlV-8VXSKuaQTQJkA2pklN60,13817
|
661
662
|
reconcile/utils/ocm/cluster_groups.py,sha256=F8oqVqN_4QUnGL0K61zZhoYIzJeP57EcmZpwmoV0mr4,1751
|
662
|
-
reconcile/utils/ocm/clusters.py,sha256=
|
663
|
+
reconcile/utils/ocm/clusters.py,sha256=Nw9m-jgN3GHHCh6w9UOBbMV4rtS24_-Ep09jAWQ-_fE,7653
|
663
664
|
reconcile/utils/ocm/identity_providers.py,sha256=dKed09N8iWmn39tI_MpwgVe47x23eLsknGbjMUxtwr4,2175
|
664
665
|
reconcile/utils/ocm/labels.py,sha256=pRzTE506hKAgVbBNO51IBlGOuCbJmTYDMsL0pWBEwp8,5945
|
665
|
-
reconcile/utils/ocm/ocm.py,sha256=
|
666
|
+
reconcile/utils/ocm/ocm.py,sha256=axXuTUpJR-fqhDo6OiDzEygOsR9OCX8ZV1I_Q2vWJQc,36712
|
667
|
+
reconcile/utils/ocm/products.py,sha256=tm8uRc1FxeIhqHv-f_ColD5IHKcsqGaEnoe1RFQtH-8,25296
|
666
668
|
reconcile/utils/ocm/search_filters.py,sha256=zExZpYBh7_tucG-xKoPHUxz1b_6l9qwbEMpMihQg7nA,15043
|
667
669
|
reconcile/utils/ocm/service_log.py,sha256=XmGOP6hwhKwMEMeD0GhErTGzdgk1IHaKs-QatL1mAdY,2052
|
668
670
|
reconcile/utils/ocm/sre_capability_labels.py,sha256=-TUmTzvK5yu7qY8SUMGj6-684wa8ZVYbjrJ6X3M7z-o,1576
|
@@ -672,7 +674,7 @@ reconcile/utils/ocm/syncsets.py,sha256=zvji9qWvInIRTdoybMaM9-VUhq4L1VewWfWCQmp4u
|
|
672
674
|
reconcile/utils/ocm/upgrades.py,sha256=ZWDfg3VrmRGx7Re-JjecRjwmn7Rh-dsuLA3OljbCByg,6616
|
673
675
|
reconcile/utils/rosa/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
674
676
|
reconcile/utils/rosa/rosa_cli.py,sha256=b7V3EgO4b4hOnvZzrxdn-bxRbkINQysOg_ecuB8l5GA,11364
|
675
|
-
reconcile/utils/rosa/session.py,sha256=
|
677
|
+
reconcile/utils/rosa/session.py,sha256=imjCFgHHjlh3TPUDg6dZFzkmQqFq2kCKAM948XDKiUI,6098
|
676
678
|
reconcile/utils/runtime/__init__.py,sha256=sfk92MGfsBh9tKYHl_FH17NdEsrGBwgDFTb7KNKoIfY,107
|
677
679
|
reconcile/utils/runtime/desired_state_diff.py,sha256=finZnWoVDCiYTgu4lGk8G4QOFAGgiIDhD3fcnVqYoxM,8108
|
678
680
|
reconcile/utils/runtime/environment.py,sha256=JLptHJoYyeLdMBghJppttP3wZ5HxHLMLgUcfGjIiKLM,2087
|
@@ -712,8 +714,8 @@ tools/test/test_app_interface_metrics_exporter.py,sha256=SX7qL3D1SIRKFo95FoQztvf
|
|
712
714
|
tools/test/test_qontract_cli.py,sha256=OvalpVRfY4pNmpMaWHHYqBjV68b1eGQjX8SCyTAXb1w,3501
|
713
715
|
tools/test/test_sd_app_sre_alert_report.py,sha256=v363r9zM7__0kR5K6mvJoGFcM9BvE33fWAayrqkpojA,2116
|
714
716
|
tools/test/test_sre_checkpoints.py,sha256=SKqPPTl9ua0RFdSSofnoQX-JZE6dFLO3LRhfQzqtfh8,2607
|
715
|
-
qontract_reconcile-0.10.
|
716
|
-
qontract_reconcile-0.10.
|
717
|
-
qontract_reconcile-0.10.
|
718
|
-
qontract_reconcile-0.10.
|
719
|
-
qontract_reconcile-0.10.
|
717
|
+
qontract_reconcile-0.10.1rc614.dist-info/METADATA,sha256=-4XRtExmYEBBglO9ovJfxuTQRZdgwNWRUWLEXfb1Yx4,2382
|
718
|
+
qontract_reconcile-0.10.1rc614.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
719
|
+
qontract_reconcile-0.10.1rc614.dist-info/entry_points.txt,sha256=rIxI5zWtHNlfpDeq1a7pZXAPoqf7HG32KMTN3MeWK_8,429
|
720
|
+
qontract_reconcile-0.10.1rc614.dist-info/top_level.txt,sha256=l5ISPoXzt0SdR4jVdkfa7RPSKNc8zAHYWAnR-Dw8Ey8,24
|
721
|
+
qontract_reconcile-0.10.1rc614.dist-info/RECORD,,
|
reconcile/cli.py
CHANGED
@@ -2235,12 +2235,65 @@ def ocm_groups(ctx, thread_pool_size):
|
|
2235
2235
|
@integration.command(short_help="Manages clusters via OCM.")
|
2236
2236
|
@gitlab_project_id
|
2237
2237
|
@threaded()
|
2238
|
+
@click.option(
|
2239
|
+
"--job-controller-cluster",
|
2240
|
+
help="The cluster holding the job-controller namepsace",
|
2241
|
+
required=False,
|
2242
|
+
envvar="JOB_CONTROLLER_CLUSTER",
|
2243
|
+
)
|
2244
|
+
@click.option(
|
2245
|
+
"--job-controller-namespace",
|
2246
|
+
help="The namespace used for ROSA jobs",
|
2247
|
+
required=False,
|
2248
|
+
envvar="JOB_CONTROLLER_NAMESPACE",
|
2249
|
+
)
|
2250
|
+
@click.option(
|
2251
|
+
"--rosa-job-service-account",
|
2252
|
+
help="The service-account used for ROSA jobs",
|
2253
|
+
required=False,
|
2254
|
+
envvar="ROSA_JOB_SERVICE_ACCOUNT",
|
2255
|
+
)
|
2256
|
+
@click.option(
|
2257
|
+
"--rosa-job-image",
|
2258
|
+
help="The container image to use to run ROSA cli command jobs",
|
2259
|
+
required=False,
|
2260
|
+
envvar="ROSA_JOB_IMAGE",
|
2261
|
+
)
|
2262
|
+
@click.option(
|
2263
|
+
"--rosa-role",
|
2264
|
+
help="The role to assume in the ROSA cluster account",
|
2265
|
+
required=False,
|
2266
|
+
envvar="ROSA_ROLE",
|
2267
|
+
)
|
2238
2268
|
@click.pass_context
|
2239
|
-
def ocm_clusters(
|
2240
|
-
|
2269
|
+
def ocm_clusters(
|
2270
|
+
ctx,
|
2271
|
+
gitlab_project_id: Optional[str],
|
2272
|
+
thread_pool_size: int,
|
2273
|
+
job_controller_cluster: Optional[str],
|
2274
|
+
job_controller_namespace: Optional[str],
|
2275
|
+
rosa_job_service_account: Optional[str],
|
2276
|
+
rosa_role: Optional[str],
|
2277
|
+
rosa_job_image: Optional[str],
|
2278
|
+
):
|
2279
|
+
from reconcile.ocm_clusters import (
|
2280
|
+
OcmClusters,
|
2281
|
+
OcmClustersParams,
|
2282
|
+
)
|
2241
2283
|
|
2242
|
-
|
2243
|
-
|
2284
|
+
run_class_integration(
|
2285
|
+
integration=OcmClusters(
|
2286
|
+
OcmClustersParams(
|
2287
|
+
gitlab_project_id=gitlab_project_id,
|
2288
|
+
thread_pool_size=thread_pool_size,
|
2289
|
+
job_controller_cluster=job_controller_cluster,
|
2290
|
+
job_controller_namespace=job_controller_namespace,
|
2291
|
+
rosa_job_service_account=rosa_job_service_account,
|
2292
|
+
rosa_job_image=rosa_job_image,
|
2293
|
+
rosa_role=rosa_role,
|
2294
|
+
)
|
2295
|
+
),
|
2296
|
+
ctx=ctx.obj,
|
2244
2297
|
)
|
2245
2298
|
|
2246
2299
|
|
reconcile/ocm/types.py
CHANGED
reconcile/ocm_clusters.py
CHANGED
@@ -4,7 +4,9 @@ from collections.abc import (
|
|
4
4
|
Iterable,
|
5
5
|
Mapping,
|
6
6
|
)
|
7
|
-
from typing import Any
|
7
|
+
from typing import Any, Optional
|
8
|
+
|
9
|
+
import semver
|
8
10
|
|
9
11
|
import reconcile.utils.mr.clusters_updates as cu
|
10
12
|
import reconcile.utils.ocm as ocmmod
|
@@ -21,9 +23,22 @@ from reconcile.ocm.types import (
|
|
21
23
|
)
|
22
24
|
from reconcile.status import ExitCodes
|
23
25
|
from reconcile.utils.disabled_integrations import integration_is_enabled
|
26
|
+
from reconcile.utils.jobcontroller.controller import build_job_controller
|
27
|
+
from reconcile.utils.ocm.products import (
|
28
|
+
OCMProduct,
|
29
|
+
OCMProductPortfolio,
|
30
|
+
OCMValidationException,
|
31
|
+
build_product_portfolio,
|
32
|
+
)
|
33
|
+
from reconcile.utils.rosa.session import RosaSessionBuilder
|
34
|
+
from reconcile.utils.runtime.integration import (
|
35
|
+
PydanticRunParams,
|
36
|
+
QontractReconcileIntegration,
|
37
|
+
)
|
24
38
|
from reconcile.utils.semver_helper import parse_semver
|
25
39
|
|
26
40
|
QONTRACT_INTEGRATION = "ocm-clusters"
|
41
|
+
QONTRACT_INTEGRATION_VERSION = semver.format_version(0, 1, 0)
|
27
42
|
|
28
43
|
|
29
44
|
def _set_rosa_ocm_attrs(cluster: Mapping[str, Any]):
|
@@ -32,26 +47,24 @@ def _set_rosa_ocm_attrs(cluster: Mapping[str, Any]):
|
|
32
47
|
but the cluster only needs the target OCM environment where it belongs.
|
33
48
|
This method changes the cluster dictionary to include just those.
|
34
49
|
"""
|
35
|
-
ocm_env = [
|
36
|
-
env
|
37
|
-
for env in cluster["spec"]["account"]["rosa"]["ocm_environments"]
|
38
|
-
if env["ocm"]["name"] == cluster["ocm"]["name"]
|
39
|
-
]
|
40
|
-
|
41
|
-
if len(ocm_env) != 1:
|
42
|
-
logging.error(
|
43
|
-
"The cluster's OCM reference does not exist or it is duplicated in the AWS account manifest. "
|
44
|
-
"Check the cluster's AWS account rosa configuration. "
|
45
|
-
f"OCM:{cluster['ocm']['name']}, AWSAcc:{cluster['spec']['account']['uid']}"
|
46
|
-
)
|
47
|
-
sys.exit(ExitCodes.ERROR)
|
48
|
-
|
49
50
|
uid = cluster["spec"]["account"]["uid"]
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
51
|
+
rosa_ocm_configs = cluster["spec"]["account"]["rosa"]
|
52
|
+
rosa: ROSAOcmAwsAttrs | None = None
|
53
|
+
if rosa_ocm_configs:
|
54
|
+
ocm_env = [
|
55
|
+
env
|
56
|
+
for env in rosa_ocm_configs["ocm_environments"]
|
57
|
+
if env["ocm"]["name"] == cluster["ocm"]["name"]
|
58
|
+
]
|
59
|
+
if len(ocm_env) != 1:
|
60
|
+
logging.error(
|
61
|
+
"The cluster's OCM reference does not exist or it is duplicated in the AWS account manifest. "
|
62
|
+
"Check the cluster's AWS account rosa configuration. "
|
63
|
+
f"OCM:{cluster['ocm']['name']}, AWSAcc:{cluster['spec']['account']['uid']}"
|
64
|
+
)
|
65
|
+
sys.exit(ExitCodes.ERROR)
|
66
|
+
env = ocm_env[0]
|
67
|
+
rosa = ROSAOcmAwsAttrs(
|
55
68
|
creator_role_arn=env["creator_role_arn"],
|
56
69
|
sts=ROSAOcmAwsStsAttrs(
|
57
70
|
installer_role_arn=env["installer_role_arn"],
|
@@ -59,7 +72,14 @@ def _set_rosa_ocm_attrs(cluster: Mapping[str, Any]):
|
|
59
72
|
controlplane_role_arn=env.get("controlplane_role_arn"),
|
60
73
|
worker_role_arn=env["worker_role_arn"],
|
61
74
|
),
|
62
|
-
)
|
75
|
+
)
|
76
|
+
else:
|
77
|
+
rosa = None
|
78
|
+
|
79
|
+
# doing this allows to exclude account fields which can be queried in graphql
|
80
|
+
cluster["spec"]["account"] = ROSAClusterAWSAccount(
|
81
|
+
uid=uid,
|
82
|
+
rosa=rosa,
|
63
83
|
)
|
64
84
|
|
65
85
|
|
@@ -210,7 +230,7 @@ def get_app_interface_spec_updates(
|
|
210
230
|
|
211
231
|
|
212
232
|
def get_cluster_ocm_update_spec(
|
213
|
-
|
233
|
+
product: OCMProduct, cluster: str, current_spec: OCMSpec, desired_spec: OCMSpec
|
214
234
|
) -> tuple[dict[str, Any], bool]:
|
215
235
|
"""Get cluster updates to request to OCM api
|
216
236
|
|
@@ -221,8 +241,6 @@ def get_cluster_ocm_update_spec(
|
|
221
241
|
:return: a tuple with the updates to request to OCM and a bool to notify errors
|
222
242
|
"""
|
223
243
|
|
224
|
-
impl = ocmmod.OCM_PRODUCTS_IMPL[current_spec.spec.product]
|
225
|
-
|
226
244
|
error = False
|
227
245
|
if not desired_spec.network.type:
|
228
246
|
desired_spec.network.type = "OVNKubernetes"
|
@@ -237,13 +255,13 @@ def get_cluster_ocm_update_spec(
|
|
237
255
|
current_ocm_spec = {
|
238
256
|
k: v
|
239
257
|
for k, v in cspec.items()
|
240
|
-
if v is not None and k not in
|
258
|
+
if v is not None and k not in product.EXCLUDED_SPEC_FIELDS
|
241
259
|
}
|
242
260
|
|
243
261
|
desired_ocm_spec = {
|
244
262
|
k: v
|
245
263
|
for k, v in dspec.items()
|
246
|
-
if v is not None and k not in
|
264
|
+
if v is not None and k not in product.EXCLUDED_SPEC_FIELDS
|
247
265
|
}
|
248
266
|
|
249
267
|
# Updated attributes in app-interface
|
@@ -258,7 +276,7 @@ def get_cluster_ocm_update_spec(
|
|
258
276
|
|
259
277
|
diffs = deleted_attrs | updated_attrs
|
260
278
|
|
261
|
-
not_allowed_updates = set(diffs) -
|
279
|
+
not_allowed_updates = set(diffs) - product.ALLOWED_SPEC_UPDATE_FIELDS
|
262
280
|
if not_allowed_updates:
|
263
281
|
error = True
|
264
282
|
logging.error(f"[{cluster}] invalid updates: {not_allowed_updates}")
|
@@ -267,7 +285,7 @@ def get_cluster_ocm_update_spec(
|
|
267
285
|
|
268
286
|
|
269
287
|
def _app_interface_updates_mr(
|
270
|
-
clusters_updates: Mapping[str, Any], gitlab_project_id: str, dry_run: bool
|
288
|
+
clusters_updates: Mapping[str, Any], gitlab_project_id: Optional[str], dry_run: bool
|
271
289
|
):
|
272
290
|
"""Creates an MR to app-interface with the necessary cluster manifest updates
|
273
291
|
|
@@ -301,83 +319,133 @@ def _cluster_is_compatible(cluster: Mapping[str, Any]) -> bool:
|
|
301
319
|
return cluster.get("ocm") is not None
|
302
320
|
|
303
321
|
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
clusters = [
|
308
|
-
c
|
309
|
-
for c in clusters
|
310
|
-
if integration_is_enabled(QONTRACT_INTEGRATION, c) and _cluster_is_compatible(c)
|
311
|
-
]
|
312
|
-
if not clusters:
|
313
|
-
logging.debug("No OCM cluster definitions found in app-interface")
|
314
|
-
sys.exit(ExitCodes.SUCCESS)
|
315
|
-
|
316
|
-
ocm_map = ocmmod.OCMMap(
|
317
|
-
clusters=clusters,
|
318
|
-
integration=QONTRACT_INTEGRATION,
|
319
|
-
settings=settings,
|
320
|
-
init_provision_shards=True,
|
321
|
-
)
|
322
|
+
class OcmClustersParams(PydanticRunParams):
|
323
|
+
gitlab_project_id: Optional[str] = None
|
324
|
+
thread_pool_size: int = 10
|
322
325
|
|
323
|
-
#
|
324
|
-
|
325
|
-
|
326
|
+
# rosa job controller params
|
327
|
+
job_controller_cluster: Optional[str] = None
|
328
|
+
job_controller_namespace: Optional[str] = None
|
329
|
+
rosa_job_service_account: Optional[str] = None
|
330
|
+
rosa_role: Optional[str] = None
|
331
|
+
rosa_job_image: Optional[str] = None
|
326
332
|
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
333
|
+
|
334
|
+
class OcmClusters(QontractReconcileIntegration[OcmClustersParams]):
|
335
|
+
@property
|
336
|
+
def name(self) -> str:
|
337
|
+
return QONTRACT_INTEGRATION
|
338
|
+
|
339
|
+
def rosa_session_builder(self) -> RosaSessionBuilder | None:
|
340
|
+
if (
|
341
|
+
self.params.job_controller_cluster is None
|
342
|
+
or self.params.job_controller_namespace is None
|
343
|
+
or self.params.rosa_job_service_account is None
|
344
|
+
or self.params.rosa_role is None
|
345
|
+
or self.params.rosa_job_image is None
|
346
|
+
):
|
347
|
+
return None
|
348
|
+
return RosaSessionBuilder(
|
349
|
+
aws_iam_role=self.params.rosa_role,
|
350
|
+
image=self.params.rosa_job_image,
|
351
|
+
service_account=self.params.rosa_job_service_account,
|
352
|
+
job_controller=build_job_controller(
|
353
|
+
cluster=self.params.job_controller_cluster,
|
354
|
+
namespace=self.params.job_controller_namespace,
|
355
|
+
integration=self.name,
|
356
|
+
integration_version=QONTRACT_INTEGRATION_VERSION,
|
357
|
+
secret_reader=self.secret_reader,
|
358
|
+
dry_run=False,
|
359
|
+
),
|
360
|
+
)
|
361
|
+
|
362
|
+
def assemble_product_portfolio(self) -> OCMProductPortfolio:
|
363
|
+
return build_product_portfolio(self.rosa_session_builder())
|
364
|
+
|
365
|
+
def run(self, dry_run: bool) -> None:
|
366
|
+
settings = queries.get_app_interface_settings()
|
367
|
+
clusters = queries.get_clusters()
|
368
|
+
clusters = [
|
369
|
+
c
|
370
|
+
for c in clusters
|
371
|
+
if integration_is_enabled(self.name, c) and _cluster_is_compatible(c)
|
372
|
+
]
|
373
|
+
if not clusters:
|
374
|
+
logging.debug("No OCM cluster definitions found in app-interface")
|
375
|
+
sys.exit(ExitCodes.SUCCESS)
|
376
|
+
|
377
|
+
product_portfolio = self.assemble_product_portfolio()
|
378
|
+
ocm_map = ocmmod.OCMMap(
|
379
|
+
clusters=clusters,
|
380
|
+
integration=self.name,
|
381
|
+
settings=settings,
|
382
|
+
init_provision_shards=True,
|
383
|
+
product_portfolio=product_portfolio,
|
384
|
+
)
|
385
|
+
|
386
|
+
# current_state is the state got from the ocm api
|
387
|
+
current_state, pending_state = ocm_map.cluster_specs()
|
388
|
+
desired_state = fetch_desired_state(clusters)
|
389
|
+
|
390
|
+
error = False
|
391
|
+
clusters_updates = {}
|
392
|
+
|
393
|
+
for cluster_name, desired_spec in desired_state.items():
|
394
|
+
current_spec = current_state.get(cluster_name)
|
395
|
+
if current_spec:
|
396
|
+
# App-Interface manifests updates.
|
397
|
+
# OCM populated attributes that are not set in app-interface.
|
398
|
+
# These updates are performed with a single MR out of this main loop
|
399
|
+
clusters_updates[cluster_name], err = get_app_interface_spec_updates(
|
400
|
+
cluster_name, current_spec, desired_spec
|
358
401
|
)
|
402
|
+
if err:
|
403
|
+
error = True
|
404
|
+
|
405
|
+
# OCM API Updates
|
406
|
+
# Changes made to app-interface manifests that need to be requested
|
407
|
+
# to the OCM Api
|
359
408
|
ocm = ocm_map.get(cluster_name)
|
360
|
-
|
361
|
-
|
362
|
-
else:
|
363
|
-
# create cluster
|
364
|
-
if cluster_name in pending_state:
|
365
|
-
continue
|
366
|
-
logging.info(["create_cluster", cluster_name])
|
367
|
-
ocm = ocm_map.get(cluster_name)
|
368
|
-
try:
|
369
|
-
ocm.create_cluster(cluster_name, desired_spec, dry_run)
|
370
|
-
except NotImplementedError:
|
371
|
-
logging.error(
|
372
|
-
f"[{cluster_name}] Create clusters is not currently implemented "
|
373
|
-
f"for [{desired_spec.spec.product}] product type. Make sure the "
|
374
|
-
"cluster exists and it is returned by the OCM api before adding "
|
375
|
-
"its manifest to app-interface"
|
409
|
+
product = product_portfolio.get_product_impl(
|
410
|
+
current_spec.spec.product, current_spec.spec.hypershift
|
376
411
|
)
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
412
|
+
update_spec, err = get_cluster_ocm_update_spec(
|
413
|
+
product, cluster_name, current_spec, desired_spec
|
414
|
+
)
|
415
|
+
if err:
|
416
|
+
error = True
|
417
|
+
continue
|
418
|
+
|
419
|
+
# update cluster
|
420
|
+
if update_spec:
|
421
|
+
logging.info(["update_cluster", cluster_name])
|
422
|
+
logging.debug(
|
423
|
+
f"current_spec: {current_spec}, desired_spec: {desired_spec}"
|
424
|
+
)
|
425
|
+
ocm = ocm_map.get(cluster_name)
|
426
|
+
ocm.update_cluster(cluster_name, update_spec, dry_run)
|
427
|
+
|
428
|
+
else:
|
429
|
+
# create cluster
|
430
|
+
if cluster_name in pending_state:
|
431
|
+
continue
|
432
|
+
logging.info(["create_cluster", cluster_name])
|
433
|
+
ocm = ocm_map.get(cluster_name)
|
434
|
+
try:
|
435
|
+
ocm.create_cluster(cluster_name, desired_spec, dry_run)
|
436
|
+
except NotImplementedError:
|
437
|
+
logging.error(
|
438
|
+
f"[{cluster_name}] Create clusters is not currently implemented "
|
439
|
+
f"for [{desired_spec.spec.product}] product type. Make sure the "
|
440
|
+
"cluster exists and it is returned by the OCM api before adding "
|
441
|
+
"its manifest to app-interface"
|
442
|
+
)
|
443
|
+
error = True
|
444
|
+
except OCMValidationException as e:
|
445
|
+
logging.error("[%s] Error creating cluster: %s", cluster_name, e)
|
446
|
+
error = True
|
447
|
+
|
448
|
+
_app_interface_updates_mr(
|
449
|
+
clusters_updates, self.params.gitlab_project_id, dry_run
|
450
|
+
)
|
451
|
+
sys.exit(int(error))
|
@@ -0,0 +1,54 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
rosa init
|
4
|
+
rosa create ocm-role --admin -y -m auto
|
5
|
+
rosa create account-roles --hosted-cp -y -m auto
|
6
|
+
rosa create user-role -y -m auto
|
7
|
+
|
8
|
+
# OIDC config
|
9
|
+
{% if cluster.spec.oidc_endpoint_url %}
|
10
|
+
OIDC_CONFIG_ID="{{ (cluster.spec.oidc_endpoint_url | split("/")) | last }}"
|
11
|
+
{% else %}
|
12
|
+
OIDC_CONFIG_ID=$(rosa list oidc-provider -o json | jq '.[0].arn // "/" | split("/") | .[-1]' -r)
|
13
|
+
if [[ -z "${OIDC_CONFIG_ID}" ]]; then
|
14
|
+
rosa create oidc-config -m auto -y
|
15
|
+
OIDC_CONFIG_ID=$(rosa list oidc-provider -o json | jq '.[0].arn // "/" | split("/") | .[-1]' -r)
|
16
|
+
else
|
17
|
+
echo "reuse existing OIDC config ${OIDC_CONFIG_ID}"
|
18
|
+
fi
|
19
|
+
{% endif %}
|
20
|
+
|
21
|
+
# operator roles
|
22
|
+
INSTALLER_ROLE_ARN=$(rosa list account-roles --region us-east-1 -o json | jq '.[] | select(.RoleType == "Installer") | .RoleARN' -r)
|
23
|
+
rosa create operator-roles --prefix {{ cluster_name }} --oidc-config-id ${OIDC_CONFIG_ID} --hosted-cp --installer-role-arn ${INSTALLER_ROLE_ARN} -m auto -y
|
24
|
+
|
25
|
+
# cluster creation
|
26
|
+
BILLING_ACCOUNT_ID=$(aws organizations describe-organization | jq .Organization.MasterAccountId -r)
|
27
|
+
rosa create cluster --cluster-name={{ cluster_name }} \
|
28
|
+
--billing-account ${BILLING_ACCOUNT_ID} \
|
29
|
+
{% if dry_run -%}
|
30
|
+
--dry-run \
|
31
|
+
{% endif -%}
|
32
|
+
--sts \
|
33
|
+
--hosted-cp \
|
34
|
+
--oidc-config-id ${OIDC_CONFIG_ID} \
|
35
|
+
--operator-roles-prefix {{ cluster_name }} \
|
36
|
+
--subnet-ids {{ cluster.spec.subnet_ids | join(",") }} \
|
37
|
+
--region {{ cluster.spec.region }} \
|
38
|
+
--version {{ cluster.spec.version }} \
|
39
|
+
--machine-cidr {{ cluster.network.vpc }} \
|
40
|
+
--service-cidr {{ cluster.network.service }} \
|
41
|
+
--pod-cidr {{ cluster.network.pod }} \
|
42
|
+
--host-prefix 23 \
|
43
|
+
--replicas {{ cluster.machine_pools | length }} \
|
44
|
+
--compute-machine-type {{ cluster.machine_pools[0].instance_type }} \
|
45
|
+
{% if cluster.spec.private -%}
|
46
|
+
--private \
|
47
|
+
{% endif -%}
|
48
|
+
{% if cluster.spec.disable_user_workload_monitoring -%}
|
49
|
+
--disable-workload-monitoring \
|
50
|
+
{% endif -%}
|
51
|
+
{% if cluster.spec.provision_shard_id -%}
|
52
|
+
--properties provision_shard_id:{{ cluster.spec.provision_shard_id }} \
|
53
|
+
{% endif -%}
|
54
|
+
--channel-group {{ cluster.spec.channel }}
|