qontract-reconcile 0.10.1rc607__py3-none-any.whl → 0.10.1rc609__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.1rc607.dist-info → qontract_reconcile-0.10.1rc609.dist-info}/METADATA +1 -1
- {qontract_reconcile-0.10.1rc607.dist-info → qontract_reconcile-0.10.1rc609.dist-info}/RECORD +10 -8
- reconcile/cli.py +28 -28
- reconcile/gql_definitions/common/state_aws_account.py +77 -0
- reconcile/typed_queries/get_state_aws_account.py +20 -0
- reconcile/utils/binary.py +3 -3
- reconcile/utils/state.py +83 -46
- {qontract_reconcile-0.10.1rc607.dist-info → qontract_reconcile-0.10.1rc609.dist-info}/WHEEL +0 -0
- {qontract_reconcile-0.10.1rc607.dist-info → qontract_reconcile-0.10.1rc609.dist-info}/entry_points.txt +0 -0
- {qontract_reconcile-0.10.1rc607.dist-info → qontract_reconcile-0.10.1rc609.dist-info}/top_level.txt +0 -0
{qontract_reconcile-0.10.1rc607.dist-info → qontract_reconcile-0.10.1rc609.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.1rc609
|
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.1rc607.dist-info → qontract_reconcile-0.10.1rc609.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=iYjF1R-M2FdokkMzjlCFennx-E9Go8xdJN5QGTFZMjU,91560
|
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
|
@@ -225,6 +225,7 @@ reconcile/gql_definitions/common/saas_files.py,sha256=B7HE_jV5ky8AFxOCleSg2RYDrt
|
|
225
225
|
reconcile/gql_definitions/common/saas_target_namespaces.py,sha256=gcTU9jrsNq9-HX-oOkj-nEZKYFTRytDHLs4SpEs93aw,2755
|
226
226
|
reconcile/gql_definitions/common/saasherder_settings.py,sha256=nqQLcMwYxLseqq0BEcVvmrpIj2eQq0h8XDSpLN6GGCw,1793
|
227
227
|
reconcile/gql_definitions/common/smtp_client_settings.py,sha256=JU6t6D-Qj-z1gLlgUiHKe0W7AxWQdty9jlv-ig_43tM,2248
|
228
|
+
reconcile/gql_definitions/common/state_aws_account.py,sha256=LAdpCG2-ykVpWBPO0Zu1WvG-hwKXyDC0fJQxJRpbqCk,2198
|
228
229
|
reconcile/gql_definitions/common/users.py,sha256=uDiEDqa4QP89I2oFuKhCtVB61ZviIt7Y75fgrcCm7M4,1681
|
229
230
|
reconcile/gql_definitions/dashdotdb_slo/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
230
231
|
reconcile/gql_definitions/dashdotdb_slo/slo_documents_query.py,sha256=zUa-CmpOwiymVmOV6KwDHH5mMl06p000320FcOas6hU,4315
|
@@ -518,6 +519,7 @@ reconcile/typed_queries/aws_vpcs.py,sha256=bM7dWpVHV6J1WYjgHOe2rfAl4vKpUoC8khPQS
|
|
518
519
|
reconcile/typed_queries/clusters.py,sha256=tptLP2Ov1lNqtDGuPKBOVvpDtREm5CQFDDVyp0xKkRQ,506
|
519
520
|
reconcile/typed_queries/clusters_minimal.py,sha256=flvs4oXVR4b971h-zMTK3C2GL3bjMnvZgrAeI3XgBQQ,517
|
520
521
|
reconcile/typed_queries/clusters_with_peering.py,sha256=lIai7SJJD0bqIJbe7virgrbYRqjLouSL2OpJD0itpAY,330
|
522
|
+
reconcile/typed_queries/get_state_aws_account.py,sha256=CSJjVPWsUZ2rkGIt8ehoQt7hokFqrUDgG9HFlg2lVD8,492
|
521
523
|
reconcile/typed_queries/github_orgs.py,sha256=UZhoPl8qvA_tcO7CZlN8GuMKckt3ywd47Suu61rgHsc,258
|
522
524
|
reconcile/typed_queries/gitlab_instances.py,sha256=ZVQHy2W9xIp53f5qYkjKLHLHgOVtQpxTfcmM1C2046g,291
|
523
525
|
reconcile/typed_queries/jira_settings.py,sha256=i0ddx5xxHrM1v-9mtL_6OB-jBFLw7-HS6xenpIDjrkw,570
|
@@ -541,7 +543,7 @@ reconcile/utils/aggregated_list.py,sha256=pkYoBj7WwmaNgEefETqEOFTnQMcUzHE3mdsVdz
|
|
541
543
|
reconcile/utils/amtool.py,sha256=JV5-to_e_FaIcvJWTKYA9d6L3LwzwijM0MjUWn83eD4,2204
|
542
544
|
reconcile/utils/aws_api.py,sha256=sgmxCXYle0jjmMHPpBOAKl-kWTDWwuc0AlLO2NmDB8M,65612
|
543
545
|
reconcile/utils/aws_helper.py,sha256=6Nfgsz0aQ97LBAJ0JBRdnPaFTAkEBSqXvCH6_pVIWdw,2006
|
544
|
-
reconcile/utils/binary.py,sha256=
|
546
|
+
reconcile/utils/binary.py,sha256=EsOGg82Y2QJh91SGJE0tYpBKqU0iaaagQVoYONBtQn8,2359
|
545
547
|
reconcile/utils/config.py,sha256=aId5zrPjM_84u_T4yTRE_Psu3zo5-5_JCR6_7Wgv5UQ,990
|
546
548
|
reconcile/utils/constants.py,sha256=pOUd97bqZdsAu5RWJ8NUs9cwCY7K9y0eW9VVeJ4fZIU,138
|
547
549
|
reconcile/utils/data_structures.py,sha256=VyKfnlNJTiRvZKNpfgIrjESQ2YgmEpWuPQXT14WA1vI,311
|
@@ -603,7 +605,7 @@ reconcile/utils/sharding.py,sha256=gkYf0lD3IUKQPEmdRJZ70mdDT1c9qWjbdP7evRsUis4,8
|
|
603
605
|
reconcile/utils/slack_api.py,sha256=OPmzU6L9rJx2XXDlZkMlxLjOWu17yC-fVCoUItzQrXw,16295
|
604
606
|
reconcile/utils/smtp_client.py,sha256=gJNbBQJpAt5PX4t_TaeNHsXM8vt50bFgndml6yK2b5o,2800
|
605
607
|
reconcile/utils/sqs_gateway.py,sha256=gFl9DM4DmGnptuxTOe4lS3YTyE80eSAvK42ljS8h4dA,2287
|
606
|
-
reconcile/utils/state.py,sha256=
|
608
|
+
reconcile/utils/state.py,sha256=zjsprjbOb0WddzmAvh8ACqAt0fcayrX2YPfz7qceRWw,16090
|
607
609
|
reconcile/utils/structs.py,sha256=LcbLEg8WxfRqM6nW7NhcWN0YeqF7SQzxOgntmLs1SgY,352
|
608
610
|
reconcile/utils/template.py,sha256=wTvRU4AnAV_o042tD4Mwls2dwWMuk7MKnde3MaCjaYg,331
|
609
611
|
reconcile/utils/terraform_client.py,sha256=6hcC0ibXkiFBn-0krVl11Bz29QcW2RI7l40pmTRrRfg,32092
|
@@ -710,8 +712,8 @@ tools/test/test_app_interface_metrics_exporter.py,sha256=SX7qL3D1SIRKFo95FoQztvf
|
|
710
712
|
tools/test/test_qontract_cli.py,sha256=OvalpVRfY4pNmpMaWHHYqBjV68b1eGQjX8SCyTAXb1w,3501
|
711
713
|
tools/test/test_sd_app_sre_alert_report.py,sha256=v363r9zM7__0kR5K6mvJoGFcM9BvE33fWAayrqkpojA,2116
|
712
714
|
tools/test/test_sre_checkpoints.py,sha256=SKqPPTl9ua0RFdSSofnoQX-JZE6dFLO3LRhfQzqtfh8,2607
|
713
|
-
qontract_reconcile-0.10.
|
714
|
-
qontract_reconcile-0.10.
|
715
|
-
qontract_reconcile-0.10.
|
716
|
-
qontract_reconcile-0.10.
|
717
|
-
qontract_reconcile-0.10.
|
715
|
+
qontract_reconcile-0.10.1rc609.dist-info/METADATA,sha256=oL9FPRy78cqHHZ7uyBOLtfr24QUHtZ_mv0Vc-ElwUOg,2382
|
716
|
+
qontract_reconcile-0.10.1rc609.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
717
|
+
qontract_reconcile-0.10.1rc609.dist-info/entry_points.txt,sha256=rIxI5zWtHNlfpDeq1a7pZXAPoqf7HG32KMTN3MeWK_8,429
|
718
|
+
qontract_reconcile-0.10.1rc609.dist-info/top_level.txt,sha256=l5ISPoXzt0SdR4jVdkfa7RPSKNc8zAHYWAnR-Dw8Ey8,24
|
719
|
+
qontract_reconcile-0.10.1rc609.dist-info/RECORD,,
|
reconcile/cli.py
CHANGED
@@ -43,10 +43,10 @@ from reconcile.utils.runtime.runner import (
|
|
43
43
|
)
|
44
44
|
from reconcile.utils.unleash import get_feature_toggle_state
|
45
45
|
|
46
|
-
TERRAFORM_VERSION = "0.13.7"
|
46
|
+
TERRAFORM_VERSION = ["0.13.7"]
|
47
47
|
TERRAFORM_VERSION_REGEX = r"^Terraform\sv([\d]+\.[\d]+\.[\d]+)$"
|
48
48
|
|
49
|
-
|
49
|
+
OC_VERSIONS = ["4.12.46", "4.10.15"]
|
50
50
|
OC_VERSION_REGEX = r"^Client\sVersion:\s([\d]+\.[\d]+\.[\d]+)$"
|
51
51
|
|
52
52
|
|
@@ -793,7 +793,7 @@ def github_validator(ctx):
|
|
793
793
|
@integration.command(short_help="Configures ClusterRolebindings in OpenShift clusters.")
|
794
794
|
@threaded()
|
795
795
|
@binary(["oc", "ssh"])
|
796
|
-
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX,
|
796
|
+
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
|
797
797
|
@internal()
|
798
798
|
@use_jump_host()
|
799
799
|
@click.pass_context
|
@@ -812,7 +812,7 @@ def openshift_clusterrolebindings(ctx, thread_pool_size, internal, use_jump_host
|
|
812
812
|
@integration.command(short_help="Configures Rolebindings in OpenShift clusters.")
|
813
813
|
@threaded()
|
814
814
|
@binary(["oc", "ssh"])
|
815
|
-
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX,
|
815
|
+
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
|
816
816
|
@internal()
|
817
817
|
@use_jump_host()
|
818
818
|
@click.pass_context
|
@@ -831,7 +831,7 @@ def openshift_rolebindings(ctx, thread_pool_size, internal, use_jump_host):
|
|
831
831
|
@integration.command(short_help="Manages OpenShift Groups.")
|
832
832
|
@threaded()
|
833
833
|
@binary(["oc", "ssh"])
|
834
|
-
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX,
|
834
|
+
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
|
835
835
|
@internal()
|
836
836
|
@use_jump_host()
|
837
837
|
@click.pass_context
|
@@ -846,7 +846,7 @@ def openshift_groups(ctx, thread_pool_size, internal, use_jump_host):
|
|
846
846
|
@integration.command(short_help="Deletion of users from OpenShift clusters.")
|
847
847
|
@threaded()
|
848
848
|
@binary(["oc", "ssh"])
|
849
|
-
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX,
|
849
|
+
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
|
850
850
|
@internal()
|
851
851
|
@use_jump_host()
|
852
852
|
@click.pass_context
|
@@ -863,7 +863,7 @@ def openshift_users(ctx, thread_pool_size, internal, use_jump_host):
|
|
863
863
|
)
|
864
864
|
@threaded()
|
865
865
|
@binary(["oc", "ssh"])
|
866
|
-
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX,
|
866
|
+
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
|
867
867
|
@internal()
|
868
868
|
@use_jump_host()
|
869
869
|
@vault_output_path
|
@@ -1032,7 +1032,7 @@ def jira_watcher(ctx):
|
|
1032
1032
|
short_help="Watches for OpenShift upgrades and sends notifications."
|
1033
1033
|
)
|
1034
1034
|
@binary(["oc", "ssh"])
|
1035
|
-
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX,
|
1035
|
+
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
|
1036
1036
|
@threaded()
|
1037
1037
|
@internal()
|
1038
1038
|
@use_jump_host()
|
@@ -1181,7 +1181,7 @@ def aws_support_cases_sos(ctx, gitlab_project_id, thread_pool_size):
|
|
1181
1181
|
@integration.command(short_help="Manages OpenShift Resources.")
|
1182
1182
|
@threaded()
|
1183
1183
|
@binary(["oc", "ssh", "amtool"])
|
1184
|
-
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX,
|
1184
|
+
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
|
1185
1185
|
@internal()
|
1186
1186
|
@use_jump_host()
|
1187
1187
|
@cluster_name
|
@@ -1216,7 +1216,7 @@ def openshift_resources(
|
|
1216
1216
|
@throughput
|
1217
1217
|
@use_jump_host()
|
1218
1218
|
@binary(["oc", "ssh"])
|
1219
|
-
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX,
|
1219
|
+
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
|
1220
1220
|
@click.option("--saas-file-name", default=None, help="saas-file to act on.")
|
1221
1221
|
@click.option("--env-name", default=None, help="environment to deploy to.")
|
1222
1222
|
@trigger_integration
|
@@ -1258,7 +1258,7 @@ def openshift_saas_deploy(
|
|
1258
1258
|
help="bundle sha to compare to to find changes",
|
1259
1259
|
)
|
1260
1260
|
@binary(["oc", "ssh"])
|
1261
|
-
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX,
|
1261
|
+
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
|
1262
1262
|
@use_jump_host()
|
1263
1263
|
@click.pass_context
|
1264
1264
|
def openshift_saas_deploy_change_tester(
|
@@ -1293,7 +1293,7 @@ def saas_file_validator(ctx):
|
|
1293
1293
|
@integration.command(short_help="Trigger deployments when a commit changed for a ref.")
|
1294
1294
|
@threaded()
|
1295
1295
|
@binary(["oc", "ssh"])
|
1296
|
-
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX,
|
1296
|
+
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
|
1297
1297
|
@internal()
|
1298
1298
|
@use_jump_host()
|
1299
1299
|
@include_trigger_trace
|
@@ -1316,7 +1316,7 @@ def openshift_saas_deploy_trigger_moving_commits(
|
|
1316
1316
|
@integration.command(short_help="Trigger deployments when upstream job runs.")
|
1317
1317
|
@threaded()
|
1318
1318
|
@binary(["oc", "ssh"])
|
1319
|
-
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX,
|
1319
|
+
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
|
1320
1320
|
@internal()
|
1321
1321
|
@use_jump_host()
|
1322
1322
|
@include_trigger_trace
|
@@ -1339,7 +1339,7 @@ def openshift_saas_deploy_trigger_upstream_jobs(
|
|
1339
1339
|
@integration.command(short_help="Trigger deployments when images are pushed.")
|
1340
1340
|
@threaded()
|
1341
1341
|
@binary(["oc", "ssh"])
|
1342
|
-
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX,
|
1342
|
+
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
|
1343
1343
|
@internal()
|
1344
1344
|
@use_jump_host()
|
1345
1345
|
@include_trigger_trace
|
@@ -1362,7 +1362,7 @@ def openshift_saas_deploy_trigger_images(
|
|
1362
1362
|
@integration.command(short_help="Trigger deployments when configuration changes.")
|
1363
1363
|
@threaded()
|
1364
1364
|
@binary(["oc", "ssh"])
|
1365
|
-
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX,
|
1365
|
+
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
|
1366
1366
|
@internal()
|
1367
1367
|
@use_jump_host()
|
1368
1368
|
@include_trigger_trace
|
@@ -1385,7 +1385,7 @@ def openshift_saas_deploy_trigger_configs(
|
|
1385
1385
|
@integration.command(short_help="Clean up deployment related resources.")
|
1386
1386
|
@threaded()
|
1387
1387
|
@binary(["oc", "ssh"])
|
1388
|
-
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX,
|
1388
|
+
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
|
1389
1389
|
@internal()
|
1390
1390
|
@use_jump_host()
|
1391
1391
|
@click.pass_context
|
@@ -1444,7 +1444,7 @@ def gitlab_labeler(ctx, gitlab_project_id, gitlab_merge_request_id):
|
|
1444
1444
|
@integration.command(short_help="Manages labels on OpenShift namespaces.")
|
1445
1445
|
@threaded()
|
1446
1446
|
@binary(["oc", "ssh"])
|
1447
|
-
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX,
|
1447
|
+
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
|
1448
1448
|
@internal()
|
1449
1449
|
@use_jump_host()
|
1450
1450
|
@click.pass_context
|
@@ -1463,7 +1463,7 @@ def openshift_namespace_labels(ctx, thread_pool_size, internal, use_jump_host):
|
|
1463
1463
|
@integration.command(short_help="Manages OpenShift Namespaces.")
|
1464
1464
|
@threaded()
|
1465
1465
|
@binary(["oc", "ssh"])
|
1466
|
-
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX,
|
1466
|
+
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
|
1467
1467
|
@internal()
|
1468
1468
|
@use_jump_host()
|
1469
1469
|
@cluster_name
|
@@ -1488,7 +1488,7 @@ def openshift_namespaces(
|
|
1488
1488
|
@integration.command(short_help="Manages OpenShift NetworkPolicies.")
|
1489
1489
|
@threaded()
|
1490
1490
|
@binary(["oc", "ssh"])
|
1491
|
-
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX,
|
1491
|
+
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
|
1492
1492
|
@internal()
|
1493
1493
|
@use_jump_host()
|
1494
1494
|
@click.pass_context
|
@@ -1508,7 +1508,7 @@ def openshift_network_policies(ctx, thread_pool_size, internal, use_jump_host):
|
|
1508
1508
|
@threaded()
|
1509
1509
|
@take_over()
|
1510
1510
|
@binary(["oc", "ssh"])
|
1511
|
-
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX,
|
1511
|
+
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
|
1512
1512
|
@internal()
|
1513
1513
|
@use_jump_host()
|
1514
1514
|
@click.pass_context
|
@@ -1529,7 +1529,7 @@ def openshift_limitranges(ctx, thread_pool_size, internal, use_jump_host, take_o
|
|
1529
1529
|
@threaded()
|
1530
1530
|
@take_over()
|
1531
1531
|
@binary(["oc", "ssh"])
|
1532
|
-
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX,
|
1532
|
+
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
|
1533
1533
|
@internal()
|
1534
1534
|
@use_jump_host()
|
1535
1535
|
@click.pass_context
|
@@ -1549,7 +1549,7 @@ def openshift_resourcequotas(ctx, thread_pool_size, internal, use_jump_host, tak
|
|
1549
1549
|
@integration.command(short_help="Manages OpenShift Secrets from Vault.")
|
1550
1550
|
@threaded()
|
1551
1551
|
@binary(["oc", "ssh"])
|
1552
|
-
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX,
|
1552
|
+
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
|
1553
1553
|
@internal()
|
1554
1554
|
@use_jump_host()
|
1555
1555
|
@cluster_name
|
@@ -1574,7 +1574,7 @@ def openshift_vault_secrets(
|
|
1574
1574
|
@integration.command(short_help="Manages OpenShift Routes.")
|
1575
1575
|
@threaded()
|
1576
1576
|
@binary(["oc", "ssh"])
|
1577
|
-
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX,
|
1577
|
+
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
|
1578
1578
|
@internal()
|
1579
1579
|
@use_jump_host()
|
1580
1580
|
@cluster_name
|
@@ -1899,7 +1899,7 @@ def template_renderer(ctx, app_interface_data_path):
|
|
1899
1899
|
@threaded()
|
1900
1900
|
@binary(["terraform", "oc", "git"])
|
1901
1901
|
@binary_version("terraform", ["version"], TERRAFORM_VERSION_REGEX, TERRAFORM_VERSION)
|
1902
|
-
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX,
|
1902
|
+
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
|
1903
1903
|
@internal()
|
1904
1904
|
@use_jump_host()
|
1905
1905
|
@enable_deletion(default=False)
|
@@ -2922,7 +2922,7 @@ def resource_scraper(ctx, namespace_name, resource_kind, vault_output_path):
|
|
2922
2922
|
@integration.command(short_help="Manages user access for GABI instances.")
|
2923
2923
|
@threaded()
|
2924
2924
|
@binary(["oc", "ssh"])
|
2925
|
-
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX,
|
2925
|
+
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
|
2926
2926
|
@internal()
|
2927
2927
|
@use_jump_host()
|
2928
2928
|
@click.pass_context
|
@@ -3056,7 +3056,7 @@ def vault_replication(ctx):
|
|
3056
3056
|
@environment_name
|
3057
3057
|
@threaded()
|
3058
3058
|
@binary(["oc", "ssh", "helm"])
|
3059
|
-
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX,
|
3059
|
+
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
|
3060
3060
|
@internal()
|
3061
3061
|
@use_jump_host()
|
3062
3062
|
@click.option(
|
@@ -3182,7 +3182,7 @@ def glitchtip_project_alerts(ctx, instance):
|
|
3182
3182
|
@integration.command(short_help="Glitchtip project dsn as openshift secret.")
|
3183
3183
|
@threaded()
|
3184
3184
|
@binary(["oc", "ssh"])
|
3185
|
-
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX,
|
3185
|
+
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
|
3186
3186
|
@internal()
|
3187
3187
|
@use_jump_host()
|
3188
3188
|
@click.option("--instance", help="Reconcile just this instance.", default=None)
|
@@ -3203,7 +3203,7 @@ def glitchtip_project_dsn(ctx, thread_pool_size, internal, use_jump_host, instan
|
|
3203
3203
|
@integration.command(short_help="Manages Skupper Networks.")
|
3204
3204
|
@threaded()
|
3205
3205
|
@binary(["oc", "ssh"])
|
3206
|
-
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX,
|
3206
|
+
@binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
|
3207
3207
|
@internal()
|
3208
3208
|
@use_jump_host()
|
3209
3209
|
@click.pass_context
|
@@ -0,0 +1,77 @@
|
|
1
|
+
"""
|
2
|
+
Generated by qenerate plugin=pydantic_v1. DO NOT MODIFY MANUALLY!
|
3
|
+
"""
|
4
|
+
from collections.abc import Callable # noqa: F401 # pylint: disable=W0611
|
5
|
+
from datetime import datetime # noqa: F401 # pylint: disable=W0611
|
6
|
+
from enum import Enum # noqa: F401 # pylint: disable=W0611
|
7
|
+
from typing import ( # noqa: F401 # pylint: disable=W0611
|
8
|
+
Any,
|
9
|
+
Optional,
|
10
|
+
Union,
|
11
|
+
)
|
12
|
+
|
13
|
+
from pydantic import ( # noqa: F401 # pylint: disable=W0611
|
14
|
+
BaseModel,
|
15
|
+
Extra,
|
16
|
+
Field,
|
17
|
+
Json,
|
18
|
+
)
|
19
|
+
|
20
|
+
|
21
|
+
DEFINITION = """
|
22
|
+
query StateAwsAccount($name: String){
|
23
|
+
accounts: awsaccounts_v1 (name: $name)
|
24
|
+
{
|
25
|
+
name
|
26
|
+
resourcesDefaultRegion
|
27
|
+
automationToken {
|
28
|
+
path
|
29
|
+
field
|
30
|
+
version
|
31
|
+
format
|
32
|
+
}
|
33
|
+
}
|
34
|
+
}
|
35
|
+
"""
|
36
|
+
|
37
|
+
|
38
|
+
class ConfiguredBaseModel(BaseModel):
|
39
|
+
class Config:
|
40
|
+
smart_union=True
|
41
|
+
extra=Extra.forbid
|
42
|
+
|
43
|
+
|
44
|
+
class VaultSecretV1(ConfiguredBaseModel):
|
45
|
+
path: str = Field(..., alias="path")
|
46
|
+
field: str = Field(..., alias="field")
|
47
|
+
version: Optional[int] = Field(..., alias="version")
|
48
|
+
q_format: Optional[str] = Field(..., alias="format")
|
49
|
+
|
50
|
+
|
51
|
+
class AWSAccountV1(ConfiguredBaseModel):
|
52
|
+
name: str = Field(..., alias="name")
|
53
|
+
resources_default_region: str = Field(..., alias="resourcesDefaultRegion")
|
54
|
+
automation_token: VaultSecretV1 = Field(..., alias="automationToken")
|
55
|
+
|
56
|
+
|
57
|
+
class StateAwsAccountQueryData(ConfiguredBaseModel):
|
58
|
+
accounts: Optional[list[AWSAccountV1]] = Field(..., alias="accounts")
|
59
|
+
|
60
|
+
|
61
|
+
def query(query_func: Callable, **kwargs: Any) -> StateAwsAccountQueryData:
|
62
|
+
"""
|
63
|
+
This is a convenience function which queries and parses the data into
|
64
|
+
concrete types. It should be compatible with most GQL clients.
|
65
|
+
You do not have to use it to consume the generated data classes.
|
66
|
+
Alternatively, you can also mime and alternate the behavior
|
67
|
+
of this function in the caller.
|
68
|
+
|
69
|
+
Parameters:
|
70
|
+
query_func (Callable): Function which queries your GQL Server
|
71
|
+
kwargs: optional arguments that will be passed to the query function
|
72
|
+
|
73
|
+
Returns:
|
74
|
+
StateAwsAccountQueryData: queried data parsed into generated classes
|
75
|
+
"""
|
76
|
+
raw_data: dict[Any, Any] = query_func(DEFINITION, **kwargs)
|
77
|
+
return StateAwsAccountQueryData(**raw_data)
|
@@ -0,0 +1,20 @@
|
|
1
|
+
from collections.abc import Callable
|
2
|
+
|
3
|
+
from reconcile.gql_definitions.common.state_aws_account import (
|
4
|
+
AWSAccountV1,
|
5
|
+
query,
|
6
|
+
)
|
7
|
+
from reconcile.utils import gql
|
8
|
+
|
9
|
+
|
10
|
+
def get_state_aws_account(
|
11
|
+
name: str, query_func: Callable | None = None
|
12
|
+
) -> AWSAccountV1 | None:
|
13
|
+
if not query_func:
|
14
|
+
query_func = gql.get_api().query
|
15
|
+
if (
|
16
|
+
accounts := query(query_func=query_func, variables={"name": name}).accounts
|
17
|
+
or []
|
18
|
+
):
|
19
|
+
return accounts[0]
|
20
|
+
return None
|
reconcile/utils/binary.py
CHANGED
@@ -25,7 +25,7 @@ def binary(binaries=None):
|
|
25
25
|
return deco_binary
|
26
26
|
|
27
27
|
|
28
|
-
def binary_version(binary, version_args, search_regex,
|
28
|
+
def binary_version(binary, version_args, search_regex, expected_versions):
|
29
29
|
"""Check that a binary exists and is a desired version"""
|
30
30
|
|
31
31
|
def deco_binary_version(f):
|
@@ -62,10 +62,10 @@ def binary_version(binary, version_args, search_regex, expected_version):
|
|
62
62
|
)
|
63
63
|
|
64
64
|
version = match.group(1)
|
65
|
-
if version
|
65
|
+
if version not in expected_versions:
|
66
66
|
raise Exception(
|
67
67
|
f"Binary version check for binary {binary} failed! "
|
68
|
-
f"Expected: {
|
68
|
+
f"Expected: {expected_versions}, found: {version}"
|
69
69
|
)
|
70
70
|
|
71
71
|
f(*args, **kwargs)
|
reconcile/utils/state.py
CHANGED
@@ -2,14 +2,16 @@ import json
|
|
2
2
|
import logging
|
3
3
|
import os
|
4
4
|
from abc import abstractmethod
|
5
|
+
from collections.abc import Callable, Mapping
|
6
|
+
from types import TracebackType
|
5
7
|
from typing import (
|
6
8
|
Any,
|
7
9
|
Optional,
|
10
|
+
Self,
|
8
11
|
)
|
9
12
|
|
10
13
|
import boto3
|
11
14
|
from botocore.errorfactory import ClientError
|
12
|
-
from jinja2 import Template
|
13
15
|
from mypy_boto3_s3 import S3Client
|
14
16
|
from pydantic import BaseModel
|
15
17
|
|
@@ -23,7 +25,7 @@ from reconcile.typed_queries.app_interface_state_settings import (
|
|
23
25
|
from reconcile.typed_queries.app_interface_vault_settings import (
|
24
26
|
get_app_interface_vault_settings,
|
25
27
|
)
|
26
|
-
from reconcile.
|
28
|
+
from reconcile.typed_queries.get_state_aws_account import get_state_aws_account
|
27
29
|
from reconcile.utils.aws_api import aws_config_file_path
|
28
30
|
from reconcile.utils.secret_reader import (
|
29
31
|
SecretReaderBase,
|
@@ -35,23 +37,6 @@ class StateInaccessibleException(Exception):
|
|
35
37
|
pass
|
36
38
|
|
37
39
|
|
38
|
-
STATE_ACCOUNT_QUERY = """
|
39
|
-
{
|
40
|
-
accounts: awsaccounts_v1 (name: "{{ name }}")
|
41
|
-
{
|
42
|
-
name
|
43
|
-
resourcesDefaultRegion
|
44
|
-
automationToken {
|
45
|
-
path
|
46
|
-
field
|
47
|
-
version
|
48
|
-
format
|
49
|
-
}
|
50
|
-
}
|
51
|
-
}
|
52
|
-
"""
|
53
|
-
|
54
|
-
|
55
40
|
def init_state(
|
56
41
|
integration: str,
|
57
42
|
secret_reader: Optional[SecretReaderBase] = None,
|
@@ -99,7 +84,9 @@ class S3ProfileBasedStateConfiguration(S3StateConfiguration):
|
|
99
84
|
return session.client("s3")
|
100
85
|
|
101
86
|
|
102
|
-
def acquire_state_settings(
|
87
|
+
def acquire_state_settings(
|
88
|
+
secret_reader: SecretReaderBase, query_func: Callable | None = None
|
89
|
+
) -> S3StateConfiguration:
|
103
90
|
"""
|
104
91
|
Finds the settings for the app-interface state provider in the following order:
|
105
92
|
|
@@ -183,17 +170,17 @@ def acquire_state_settings(secret_reader: SecretReaderBase) -> S3StateConfigurat
|
|
183
170
|
logging.debug(
|
184
171
|
f"access state via {state_bucket_account_name} automation token from app-interface"
|
185
172
|
)
|
186
|
-
account =
|
173
|
+
account = get_state_aws_account(
|
174
|
+
state_bucket_account_name, query_func=query_func
|
175
|
+
)
|
187
176
|
if not account:
|
188
177
|
raise StateInaccessibleException(
|
189
178
|
f"The AWS account {state_bucket_account_name} that holds the state bucket can't be found in app-interface."
|
190
179
|
)
|
191
|
-
secret = secret_reader.read_all_secret(
|
192
|
-
VaultSecret(**account["automationToken"])
|
193
|
-
)
|
180
|
+
secret = secret_reader.read_all_secret(account.automation_token)
|
194
181
|
return S3CredsBasedStateConfiguration(
|
195
182
|
bucket=state_bucket_name,
|
196
|
-
region=state_bucket_region or account
|
183
|
+
region=state_bucket_region or account.resources_default_region,
|
197
184
|
access_key_id=secret["aws_access_key_id"],
|
198
185
|
secret_access_key=secret["aws_secret_access_key"],
|
199
186
|
)
|
@@ -225,14 +212,6 @@ def acquire_state_settings(secret_reader: SecretReaderBase) -> S3StateConfigurat
|
|
225
212
|
)
|
226
213
|
|
227
214
|
|
228
|
-
def _get_aws_account_by_name(name: str) -> Optional[dict[str, Any]]:
|
229
|
-
query = Template(STATE_ACCOUNT_QUERY).render(name=name)
|
230
|
-
aws_accounts = gql.get_api().query(query)["accounts"]
|
231
|
-
if aws_accounts:
|
232
|
-
return aws_accounts[0]
|
233
|
-
return None
|
234
|
-
|
235
|
-
|
236
215
|
class State:
|
237
216
|
"""
|
238
217
|
A state object to be used by stateful integrations.
|
@@ -264,19 +243,19 @@ class State:
|
|
264
243
|
f"Bucket {self.bucket} is not accessible - {str(details)}"
|
265
244
|
)
|
266
245
|
|
267
|
-
def __enter__(self):
|
246
|
+
def __enter__(self) -> Self:
|
268
247
|
return self
|
269
248
|
|
270
|
-
def __exit__(self, *exc):
|
249
|
+
def __exit__(self, *exc: Any) -> None:
|
271
250
|
self.cleanup()
|
272
251
|
|
273
|
-
def cleanup(self):
|
252
|
+
def cleanup(self) -> None:
|
274
253
|
"""
|
275
254
|
Closes the S3 client
|
276
255
|
"""
|
277
256
|
self.client.close()
|
278
257
|
|
279
|
-
def exists(self, key):
|
258
|
+
def exists(self, key: str) -> bool:
|
280
259
|
"""
|
281
260
|
Checks if a key exists in the state.
|
282
261
|
|
@@ -290,7 +269,7 @@ class State:
|
|
290
269
|
exists, _ = self.head(key)
|
291
270
|
return exists
|
292
271
|
|
293
|
-
def head(self, key) -> tuple[bool, dict[str, str]]:
|
272
|
+
def head(self, key: str) -> tuple[bool, dict[str, str]]:
|
294
273
|
"""
|
295
274
|
Checks if a key exists in the state. Returns the metadata of a key in the state.
|
296
275
|
|
@@ -315,7 +294,7 @@ class State:
|
|
315
294
|
f"in bucket {self.bucket} - {str(details)}"
|
316
295
|
)
|
317
296
|
|
318
|
-
def ls(self):
|
297
|
+
def ls(self) -> list[str]:
|
319
298
|
"""
|
320
299
|
Returns a list of keys in the state
|
321
300
|
"""
|
@@ -339,7 +318,13 @@ class State:
|
|
339
318
|
|
340
319
|
return [c["Key"].replace(self.state_path, "") for c in contents]
|
341
320
|
|
342
|
-
def add(
|
321
|
+
def add(
|
322
|
+
self,
|
323
|
+
key: str,
|
324
|
+
value: Any = None,
|
325
|
+
metadata: Mapping[str, str] | None = None,
|
326
|
+
force: bool = False,
|
327
|
+
) -> None:
|
343
328
|
"""
|
344
329
|
Adds a key/value to the state and fails if the key already exists
|
345
330
|
|
@@ -354,7 +339,9 @@ class State:
|
|
354
339
|
raise KeyError(f"[state] key {key} already " f"exists in {self.state_path}")
|
355
340
|
self._set(key, value, metadata=metadata)
|
356
341
|
|
357
|
-
def _set(
|
342
|
+
def _set(
|
343
|
+
self, key: str, value: Any, metadata: Mapping[str, str] | None = None
|
344
|
+
) -> None:
|
358
345
|
self.client.put_object(
|
359
346
|
Bucket=self.bucket,
|
360
347
|
Key=f"{self.state_path}/{key}",
|
@@ -362,7 +349,7 @@ class State:
|
|
362
349
|
Metadata=metadata or {},
|
363
350
|
)
|
364
351
|
|
365
|
-
def rm(self, key):
|
352
|
+
def rm(self, key: str) -> None:
|
366
353
|
"""
|
367
354
|
Removes a key from the state and fails if the key does not exists
|
368
355
|
|
@@ -374,7 +361,7 @@ class State:
|
|
374
361
|
raise KeyError(f"[state] key {key} does not exists in {self.state_path}")
|
375
362
|
self.client.delete_object(Bucket=self.bucket, Key=f"{self.state_path}/{key}")
|
376
363
|
|
377
|
-
def get(self, key, *args):
|
364
|
+
def get(self, key: str, *args: Any) -> Any:
|
378
365
|
"""
|
379
366
|
Gets a key value from the state and return the default
|
380
367
|
value or raises and exception if the key does not exist.
|
@@ -392,7 +379,7 @@ class State:
|
|
392
379
|
return args[0]
|
393
380
|
raise
|
394
381
|
|
395
|
-
def get_all(self, path):
|
382
|
+
def get_all(self, path: str) -> dict[str, Any]:
|
396
383
|
"""
|
397
384
|
Gets all keys and values from the state in the specified path.
|
398
385
|
"""
|
@@ -402,7 +389,7 @@ class State:
|
|
402
389
|
if k.startswith(f"/{path}")
|
403
390
|
}
|
404
391
|
|
405
|
-
def __getitem__(self, item):
|
392
|
+
def __getitem__(self, item: str) -> Any:
|
406
393
|
try:
|
407
394
|
response = self.client.get_object(
|
408
395
|
Bucket=self.bucket, Key=f"{self.state_path}/{item}"
|
@@ -415,5 +402,55 @@ class State:
|
|
415
402
|
except json.decoder.JSONDecodeError:
|
416
403
|
raise KeyError(item)
|
417
404
|
|
418
|
-
def __setitem__(self, key, value):
|
405
|
+
def __setitem__(self, key: str, value: Any) -> None:
|
419
406
|
self._set(key, value)
|
407
|
+
|
408
|
+
def transaction(self, key: str, value: Any) -> "_TransactionContext":
|
409
|
+
"""Get a context manager to set the key in the state if no exception occurs.
|
410
|
+
|
411
|
+
Attention!
|
412
|
+
|
413
|
+
This is not a locking mechanism. It is a way to ensure that a key is set in the state if no exception occurs.
|
414
|
+
This method is not thread-safe nor multi-process-safe! There is no locking mechanism in place.
|
415
|
+
"""
|
416
|
+
return _TransactionContext(self, key, value)
|
417
|
+
|
418
|
+
|
419
|
+
class _TransactionContext:
|
420
|
+
"""A context manager to set a key in the state if no exception occurs."""
|
421
|
+
|
422
|
+
def __init__(
|
423
|
+
self,
|
424
|
+
state: State,
|
425
|
+
key: str,
|
426
|
+
value: Any,
|
427
|
+
):
|
428
|
+
self.state = state
|
429
|
+
self.key = key
|
430
|
+
self.value = value
|
431
|
+
|
432
|
+
def __enter__(self) -> bool:
|
433
|
+
"""Return True if the key exists in the state, False otherwise.
|
434
|
+
|
435
|
+
Cache the previous value to avoid unnecessary updates.
|
436
|
+
"""
|
437
|
+
self._previous_value = None
|
438
|
+
try:
|
439
|
+
self._previous_value = self.state[self.key]
|
440
|
+
return True
|
441
|
+
except KeyError:
|
442
|
+
return False
|
443
|
+
|
444
|
+
def __exit__(
|
445
|
+
self,
|
446
|
+
exc_type: type[BaseException] | None,
|
447
|
+
exc_value: BaseException | None,
|
448
|
+
traceback: TracebackType | None,
|
449
|
+
) -> None:
|
450
|
+
if exc_type:
|
451
|
+
# if an exception occurred, we don't want to write to the state
|
452
|
+
return
|
453
|
+
if self._previous_value == self.value:
|
454
|
+
# if the value didn't change, we don't want to write to the state
|
455
|
+
return
|
456
|
+
self.state[self.key] = self.value
|
File without changes
|
File without changes
|
{qontract_reconcile-0.10.1rc607.dist-info → qontract_reconcile-0.10.1rc609.dist-info}/top_level.txt
RENAMED
File without changes
|