qontract-reconcile 0.10.1rc1010__py3-none-any.whl → 0.10.1rc1012__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.1rc1010.dist-info → qontract_reconcile-0.10.1rc1012.dist-info}/METADATA +1 -1
- {qontract_reconcile-0.10.1rc1010.dist-info → qontract_reconcile-0.10.1rc1012.dist-info}/RECORD +10 -10
- reconcile/external_resources/manager.py +3 -0
- reconcile/external_resources/state.py +1 -0
- reconcile/utils/aws_api.py +19 -0
- reconcile/utils/terraform_client.py +66 -0
- tools/qontract_cli.py +50 -0
- {qontract_reconcile-0.10.1rc1010.dist-info → qontract_reconcile-0.10.1rc1012.dist-info}/WHEEL +0 -0
- {qontract_reconcile-0.10.1rc1010.dist-info → qontract_reconcile-0.10.1rc1012.dist-info}/entry_points.txt +0 -0
- {qontract_reconcile-0.10.1rc1010.dist-info → qontract_reconcile-0.10.1rc1012.dist-info}/top_level.txt +0 -0
{qontract_reconcile-0.10.1rc1010.dist-info → qontract_reconcile-0.10.1rc1012.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.1rc1012
|
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.1rc1010.dist-info → qontract_reconcile-0.10.1rc1012.dist-info}/RECORD
RENAMED
@@ -190,13 +190,13 @@ reconcile/external_resources/aws.py,sha256=JvjKaABy2Pg8u8Lq82Acv4zMvpE3_qGKes7OG
|
|
190
190
|
reconcile/external_resources/factories.py,sha256=DXgaLxoO87zZ76VOpRpu2GeYGhsbfOnOx5mrzgo4Gf4,4767
|
191
191
|
reconcile/external_resources/integration.py,sha256=y1gJ16woMBC3J9qniMmS5y3lCkAs7V_ETZRUwjKqaO0,6628
|
192
192
|
reconcile/external_resources/integration_secrets_sync.py,sha256=cMEZhgCvABAMf-DWF051L6CRnJQdfbsISA_b1xuS940,1670
|
193
|
-
reconcile/external_resources/manager.py,sha256=
|
193
|
+
reconcile/external_resources/manager.py,sha256=xVwcFAPFG0HyMl_uzj8D6XXdH-Zmcw541DX0IHs57Jc,15278
|
194
194
|
reconcile/external_resources/meta.py,sha256=cMT9OsKcUY26qwEjlQ02EkorvOBNqWj0JVMwfJa3Mg0,634
|
195
195
|
reconcile/external_resources/metrics.py,sha256=m2TIOao2N7pD6k45driFbBGVCC_N7ai44m-lLPfa5qk,454
|
196
196
|
reconcile/external_resources/model.py,sha256=oXxJkjhV53lwwAuxUCBrjJ8aCJmQdgcKWv68ugJPK4k,7229
|
197
197
|
reconcile/external_resources/reconciler.py,sha256=E50X_lnOD0OWYXMzyZld1P6dCFJFYjHGyICWff9bxlc,9323
|
198
198
|
reconcile/external_resources/secrets_sync.py,sha256=6n0oDPLjd9Ql0lf6zsr1AZw8A6EEe3yCzl20XodtgkE,16229
|
199
|
-
reconcile/external_resources/state.py,sha256=
|
199
|
+
reconcile/external_resources/state.py,sha256=fKU6PLYOZ2ZTaIwvt1BNlNOnIqcewLijOyT3Lgcd1NE,9677
|
200
200
|
reconcile/glitchtip/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
201
201
|
reconcile/glitchtip/integration.py,sha256=XtewM9nfTPLnPSpYebP50GrveYOnhTvKNq3seSvL6u8,8343
|
202
202
|
reconcile/glitchtip/reconciler.py,sha256=nUvDv7qG1ly0cA16MmlL6NV71yl1mJYLT2mui7lmi0Y,12402
|
@@ -644,7 +644,7 @@ reconcile/unleash_feature_toggles/integration.py,sha256=nx7BhtzCsTfPbOp60vI5MkNw
|
|
644
644
|
reconcile/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
645
645
|
reconcile/utils/aggregated_list.py,sha256=km0xadW0jO4G_CqZPsXmoBURQ8c90FaTu5x4X1K1cZs,3357
|
646
646
|
reconcile/utils/amtool.py,sha256=ngtBuVPETH6oAy5RnKzvreVbjwQCaATS_PYYwBprzjQ,2288
|
647
|
-
reconcile/utils/aws_api.py,sha256=
|
647
|
+
reconcile/utils/aws_api.py,sha256=C90pODy5UB2YRV2Yd9Z4J5aTnMZk1CZv9YxbCN0I1-4,66822
|
648
648
|
reconcile/utils/aws_helper.py,sha256=MDbv5jrNdqqJ5pfBxniGdJXBBO_EYc2_Uf2w9ZzeMNs,2854
|
649
649
|
reconcile/utils/batches.py,sha256=TtEm64a8lWhFuNbUVpFEmXVdU2Q0sTBrP_I0Cjbgh7g,320
|
650
650
|
reconcile/utils/binary.py,sha256=7MaAFBpzuBUTJ_aA6G6-eult_BPMVyiXbBLD0Y6F-DM,2301
|
@@ -716,7 +716,7 @@ reconcile/utils/sqs_gateway.py,sha256=XNIf3PY4UCPNufP2Ul0UJj3fKlt5larBba-VTT-41F
|
|
716
716
|
reconcile/utils/state.py,sha256=a_EO5u7__Pqd0_E3MqzUttJ-0xRtuxcNx5oQi5WIahI,16392
|
717
717
|
reconcile/utils/structs.py,sha256=LcbLEg8WxfRqM6nW7NhcWN0YeqF7SQzxOgntmLs1SgY,352
|
718
718
|
reconcile/utils/template.py,sha256=wTvRU4AnAV_o042tD4Mwls2dwWMuk7MKnde3MaCjaYg,331
|
719
|
-
reconcile/utils/terraform_client.py,sha256=
|
719
|
+
reconcile/utils/terraform_client.py,sha256=QTLRB33dWOlf2AmZPntx3WWBV8d_-cwMZyLKd7eqclk,34176
|
720
720
|
reconcile/utils/terrascript_aws_client.py,sha256=1JgXcCF_-xbaAg7V9qihL1Xz5okQlSSrT1DeXGducHc,278037
|
721
721
|
reconcile/utils/three_way_diff_strategy.py,sha256=oQcHXd9LVhirJfoaOBoHUYuZVGfyL2voKr6KVI34zZE,4833
|
722
722
|
reconcile/utils/throughput.py,sha256=iP4UWAe2LVhDo69mPPmgo9nQ7RxHD6_GS8MZe-aSiuM,344
|
@@ -828,7 +828,7 @@ tools/app_interface_metrics_exporter.py,sha256=zkwkxdAUAxjdc-pzx2_oJXG25fo0Fnyd5
|
|
828
828
|
tools/app_interface_reporter.py,sha256=1ZP58LYV6ww3XOLVxgy8NKasMb1jQmp4BNqzTEB0VBE,17723
|
829
829
|
tools/glitchtip_access_reporter.py,sha256=oPBnk_YoDuljU3v0FaChzOwwnk4vap1xEE67QEjzdqs,2948
|
830
830
|
tools/glitchtip_access_revalidation.py,sha256=8kbBJk04mkq28kWoRDDkfCGIF3GRg3pJrFAh1sW0dbk,2821
|
831
|
-
tools/qontract_cli.py,sha256=
|
831
|
+
tools/qontract_cli.py,sha256=bFTYOymVksNKp_ntG2l9GoA40tODuxeRDU3rO4J-CjA,128875
|
832
832
|
tools/sd_app_sre_alert_report.py,sha256=e9vAdyenUz2f5c8-z-5WY0wv-SJ9aePKDH2r4IwB6pc,5063
|
833
833
|
tools/template_validation.py,sha256=qpKYaTgk0GOPGa2Ct5_5sKdwIHtCAKIBGzsMPuJU5fw,3371
|
834
834
|
tools/cli_commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -859,8 +859,8 @@ tools/test/test_qontract_cli.py,sha256=_D61RFGAN5x44CY1tYbouhlGXXABwYfxKSWSQx3Jr
|
|
859
859
|
tools/test/test_saas_promotion_state.py,sha256=dy4kkSSAQ7bC0Xp2CociETGN-2aABEfL6FU5D9Jl00Y,6056
|
860
860
|
tools/test/test_sd_app_sre_alert_report.py,sha256=v363r9zM7__0kR5K6mvJoGFcM9BvE33fWAayrqkpojA,2116
|
861
861
|
tools/test/test_sre_checkpoints.py,sha256=SKqPPTl9ua0RFdSSofnoQX-JZE6dFLO3LRhfQzqtfh8,2607
|
862
|
-
qontract_reconcile-0.10.
|
863
|
-
qontract_reconcile-0.10.
|
864
|
-
qontract_reconcile-0.10.
|
865
|
-
qontract_reconcile-0.10.
|
866
|
-
qontract_reconcile-0.10.
|
862
|
+
qontract_reconcile-0.10.1rc1012.dist-info/METADATA,sha256=mF7VTRaqvqomAcDgHl1erECgIQ54KoxAT6lFU0Sv690,2263
|
863
|
+
qontract_reconcile-0.10.1rc1012.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
864
|
+
qontract_reconcile-0.10.1rc1012.dist-info/entry_points.txt,sha256=GKQqCl2j2X1BJQ69een6rHcR26PmnxnONLNOQB-nRjY,491
|
865
|
+
qontract_reconcile-0.10.1rc1012.dist-info/top_level.txt,sha256=l5ISPoXzt0SdR4jVdkfa7RPSKNc8zAHYWAnR-Dw8Ey8,24
|
866
|
+
qontract_reconcile-0.10.1rc1012.dist-info/RECORD,,
|
@@ -79,6 +79,7 @@ class ReconcileAction(StrEnum):
|
|
79
79
|
APPLY_ERROR = "Resource status in ERROR state"
|
80
80
|
APPLY_SPEC_CHANGED = "Resource spec has changed"
|
81
81
|
APPLY_DRIFT_DETECTION = "Resource drift detection run"
|
82
|
+
APPLY_USER_REQUESTED = "Resource reconciliation requested"
|
82
83
|
DESTROY_CREATED = "Resource no longer exists in the configuration"
|
83
84
|
DESTROY_ERROR = "Resource status in ERROR state"
|
84
85
|
|
@@ -112,6 +113,8 @@ class ExternalResourcesManager:
|
|
112
113
|
) -> ReconcileAction:
|
113
114
|
if reconciliation.action == Action.APPLY:
|
114
115
|
match state.resource_status:
|
116
|
+
case ResourceStatus.RECONCILIATION_REQUESTED:
|
117
|
+
return ReconcileAction.APPLY_USER_REQUESTED
|
115
118
|
case ResourceStatus.NOT_EXISTS:
|
116
119
|
return ReconcileAction.APPLY_NOT_EXISTS
|
117
120
|
case ResourceStatus.ERROR:
|
@@ -36,6 +36,7 @@ class ResourceStatus(StrEnum):
|
|
36
36
|
DELETE_IN_PROGRESS: str = "DELETE_IN_PROGRESS"
|
37
37
|
ERROR: str = "ERROR"
|
38
38
|
PENDING_SECRET_SYNC: str = "PENDING_SECRET_SYNC"
|
39
|
+
RECONCILIATION_REQUESTED: str = "RECONCILIATION_REQUESTED"
|
39
40
|
|
40
41
|
|
41
42
|
class ExternalResourceState(BaseModel):
|
reconcile/utils/aws_api.py
CHANGED
@@ -1630,6 +1630,25 @@ class AWSApi: # pylint: disable=too-many-public-methods
|
|
1630
1630
|
return versions[0]["ValidUpgradeTarget"]
|
1631
1631
|
return []
|
1632
1632
|
|
1633
|
+
def describe_db_parameter_group(
|
1634
|
+
self,
|
1635
|
+
account_name: str,
|
1636
|
+
db_parameter_group_name: str,
|
1637
|
+
region_name: str | None = None,
|
1638
|
+
) -> dict[str, str]:
|
1639
|
+
optional_kwargs = {}
|
1640
|
+
|
1641
|
+
if region_name:
|
1642
|
+
optional_kwargs["region_name"] = region_name
|
1643
|
+
|
1644
|
+
rds = self._account_rds_client(account_name, **optional_kwargs)
|
1645
|
+
paginator = rds.get_paginator("describe_db_parameters")
|
1646
|
+
parameters = {}
|
1647
|
+
for page in paginator.paginate(DBParameterGroupName=db_parameter_group_name):
|
1648
|
+
for param in page.get("Parameters", []):
|
1649
|
+
parameters[param["ParameterName"]] = param["ParameterValue"]
|
1650
|
+
return parameters
|
1651
|
+
|
1633
1652
|
def get_organization_billing_account(self, account_name: str) -> str:
|
1634
1653
|
org = self._account_organizations_client(account_name)
|
1635
1654
|
return org.describe_organization()["Organization"]["MasterAccountId"]
|
@@ -24,6 +24,7 @@ from typing import (
|
|
24
24
|
)
|
25
25
|
|
26
26
|
from botocore.errorfactory import ClientError
|
27
|
+
from packaging import version as pkg_version
|
27
28
|
from sretoolbox.utils import (
|
28
29
|
retry,
|
29
30
|
threaded,
|
@@ -785,6 +786,71 @@ class TerraformClient: # pylint: disable=too-many-public-methods
|
|
785
786
|
f"{resource_name} to a new major version."
|
786
787
|
)
|
787
788
|
|
789
|
+
blue_green_update = after.get("blue_green_update", {}).get("enabled", False)
|
790
|
+
if blue_green_update:
|
791
|
+
self.validate_blue_green_update_requirements(
|
792
|
+
account_name,
|
793
|
+
engine,
|
794
|
+
after_version,
|
795
|
+
before["db_parameter_group_name"],
|
796
|
+
before.get("replica_source"),
|
797
|
+
region_name,
|
798
|
+
)
|
799
|
+
|
800
|
+
def validate_blue_green_update_requirements(
|
801
|
+
self,
|
802
|
+
account_name,
|
803
|
+
engine,
|
804
|
+
version,
|
805
|
+
parameter_group,
|
806
|
+
replica_source,
|
807
|
+
region_name,
|
808
|
+
):
|
809
|
+
min_supported_versions = {
|
810
|
+
"mysql": [pkg_version.parse("5.7"), pkg_version.parse("8.0.15")],
|
811
|
+
"postgres": [
|
812
|
+
pkg_version.parse("11.21"),
|
813
|
+
pkg_version.parse("12.16"),
|
814
|
+
pkg_version.parse("13.12"),
|
815
|
+
pkg_version.parse("14.9"),
|
816
|
+
pkg_version.parse("15.4"),
|
817
|
+
pkg_version.parse("16.1"),
|
818
|
+
],
|
819
|
+
}
|
820
|
+
|
821
|
+
def is_supported(engine, version):
|
822
|
+
parsed_version = pkg_version.parse(version)
|
823
|
+
if engine == "mysql":
|
824
|
+
return any(
|
825
|
+
parsed_version >= min_version
|
826
|
+
for min_version in min_supported_versions["mysql"]
|
827
|
+
)
|
828
|
+
elif engine == "postgres":
|
829
|
+
return any(
|
830
|
+
parsed_version >= min_version
|
831
|
+
for min_version in min_supported_versions["postgres"]
|
832
|
+
)
|
833
|
+
return False
|
834
|
+
|
835
|
+
if not is_supported(engine, version):
|
836
|
+
raise ValueError(
|
837
|
+
f"Engine version {version} is not supported for blue/green updates."
|
838
|
+
)
|
839
|
+
|
840
|
+
if replica_source:
|
841
|
+
raise ValueError(
|
842
|
+
"Blue/green updates are not supported for instances with read replicas."
|
843
|
+
)
|
844
|
+
|
845
|
+
if engine == "postgres" and parameter_group:
|
846
|
+
pg_details = self._aws_api.describe_db_parameter_group(
|
847
|
+
account_name, parameter_group, region_name
|
848
|
+
)
|
849
|
+
if pg_details.get("rds.logical_replication") != "1":
|
850
|
+
raise ValueError(
|
851
|
+
f"Parameter group {parameter_group} does not have logical replication enabled."
|
852
|
+
)
|
853
|
+
|
788
854
|
|
789
855
|
class TerraformPlanFailed(Exception):
|
790
856
|
pass
|
tools/qontract_cli.py
CHANGED
@@ -56,14 +56,22 @@ from reconcile.cli import (
|
|
56
56
|
config_file,
|
57
57
|
use_jump_host,
|
58
58
|
)
|
59
|
+
from reconcile.external_resources.integration import (
|
60
|
+
get_aws_api,
|
61
|
+
)
|
59
62
|
from reconcile.external_resources.manager import (
|
60
63
|
FLAG_RESOURCE_MANAGED_BY_ERV2,
|
61
64
|
setup_factories,
|
62
65
|
)
|
63
66
|
from reconcile.external_resources.model import (
|
67
|
+
ExternalResourceKey,
|
64
68
|
ExternalResourcesInventory,
|
65
69
|
load_module_inventory,
|
66
70
|
)
|
71
|
+
from reconcile.external_resources.state import (
|
72
|
+
ExternalResourcesStateDynamoDB,
|
73
|
+
ResourceStatus,
|
74
|
+
)
|
67
75
|
from reconcile.gql_definitions.advanced_upgrade_service.aus_clusters import (
|
68
76
|
query as aus_clusters_query,
|
69
77
|
)
|
@@ -3942,5 +3950,47 @@ def get_input(
|
|
3942
3950
|
print(resource.json(exclude={"data": {FLAG_RESOURCE_MANAGED_BY_ERV2}}))
|
3943
3951
|
|
3944
3952
|
|
3953
|
+
@external_resources.command()
|
3954
|
+
@click.argument("provision-provider", required=True)
|
3955
|
+
@click.argument("provisioner", required=True)
|
3956
|
+
@click.argument("provider", required=True)
|
3957
|
+
@click.argument("identifier", required=True)
|
3958
|
+
@click.pass_context
|
3959
|
+
def request_reconciliation(
|
3960
|
+
ctx, provision_provider: str, provisioner: str, provider: str, identifier: str
|
3961
|
+
):
|
3962
|
+
"""Marks a resource as it needs to get reconciled. The itegration will reconcile the resource at
|
3963
|
+
its next iteration.
|
3964
|
+
|
3965
|
+
e.g: e.g: qontract-reconcile --config=<config> external-resources request-reconciliation aws app-sre-stage rds dashdotdb-stage
|
3966
|
+
"""
|
3967
|
+
er_settings = get_settings()[0]
|
3968
|
+
vault_settings = get_app_interface_vault_settings()
|
3969
|
+
secret_reader = create_secret_reader(use_vault=vault_settings.vault)
|
3970
|
+
with get_aws_api(
|
3971
|
+
query_func=gql.get_api().query,
|
3972
|
+
account_name=er_settings.state_dynamodb_account.name,
|
3973
|
+
region=er_settings.state_dynamodb_region,
|
3974
|
+
secret_reader=secret_reader,
|
3975
|
+
) as aws_api:
|
3976
|
+
state_manager = ExternalResourcesStateDynamoDB(
|
3977
|
+
aws_api=aws_api,
|
3978
|
+
table_name=er_settings.state_dynamodb_table,
|
3979
|
+
)
|
3980
|
+
key = ExternalResourceKey(
|
3981
|
+
provision_provider=provision_provider,
|
3982
|
+
provisioner_name=provisioner,
|
3983
|
+
provider=provider,
|
3984
|
+
identifier=identifier,
|
3985
|
+
)
|
3986
|
+
current_state = state_manager.get_external_resource_state(key)
|
3987
|
+
if current_state.resource_status != ResourceStatus.NOT_EXISTS:
|
3988
|
+
state_manager.update_resource_status(
|
3989
|
+
key, ResourceStatus.RECONCILIATION_REQUESTED
|
3990
|
+
)
|
3991
|
+
else:
|
3992
|
+
logging.info("External Resource does not exist")
|
3993
|
+
|
3994
|
+
|
3945
3995
|
if __name__ == "__main__":
|
3946
3996
|
root() # pylint: disable=no-value-for-parameter
|
{qontract_reconcile-0.10.1rc1010.dist-info → qontract_reconcile-0.10.1rc1012.dist-info}/WHEEL
RENAMED
File without changes
|
File without changes
|
File without changes
|