qontract-reconcile 0.10.1rc1065__py3-none-any.whl → 0.10.1rc1067__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.1rc1065
3
+ Version: 0.10.1rc1067
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
@@ -94,7 +94,7 @@ reconcile/quay_mirror.py,sha256=dWvYqZcFu6RFUwyOVxNByRWx2FLIYTO2OFr2N1YtjJc,1470
94
94
  reconcile/quay_mirror_org.py,sha256=utrJpJaKCs7U6WX6DODdfCeB0EmX-lUC8Y5fkmpgFSs,10764
95
95
  reconcile/quay_permissions.py,sha256=9KOutS1w4RFQqkvMSy54VtsKNx56-phzP6yI_rEW-B8,4244
96
96
  reconcile/quay_repos.py,sha256=cuEYG0HUe0ut5yvLdEwOF5-CmccpXQHRb_wDazvDrvQ,6895
97
- reconcile/queries.py,sha256=-mwZ0V89Tik0zB585ID0jEqC4VSuUVaAPlaSXaNAR-E,50180
97
+ reconcile/queries.py,sha256=HAhD9d9TYRfkJMA5PQpv_eXuO2_wLt2Mlu2PaaBU3Xc,50201
98
98
  reconcile/query_validator.py,sha256=MSh5pKLBksws4AqfuvT8nrIGucIbqX-IOzYyPYTLO7k,1491
99
99
  reconcile/requests_sender.py,sha256=914iluuF4UVgG3VyxxtnHOu4yf6YKS2fIy6PViSsFTQ,3875
100
100
  reconcile/resource_scraper.py,sha256=znXCHrU7YwPfKuxGBiUrV7T1tYtn4vlz9qmZlfy6Flg,2307
@@ -161,7 +161,7 @@ reconcile/aws_version_sync/merge_request_manager/merge_request_manager.py,sha256
161
161
  reconcile/change_owners/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
162
162
  reconcile/change_owners/approver.py,sha256=Z3_11vnK2WNOxjEEXVDh0224-_-qbt9d6mBeVE-7fsc,2259
163
163
  reconcile/change_owners/bundle.py,sha256=ZIlXRo6Z2raeWSCUqYsexBdol-q-r9kWJs5O_YPaEYk,5273
164
- reconcile/change_owners/change_log_tracking.py,sha256=zFpean5UB3-u5VQLJHzik8GmhBwYoNorR-l90-D1Pis,4160
164
+ reconcile/change_owners/change_log_tracking.py,sha256=V8J6Whi0F4tbm0KidGuOUuNfv3e6SgE0ddDHdx9JB9o,5158
165
165
  reconcile/change_owners/change_owners.py,sha256=0HRJhDm0oW3uYJFgzynqA1gA0lbhalhSkmWOiQmr-NM,17062
166
166
  reconcile/change_owners/change_types.py,sha256=TjVtvmkU0s8w2NA6qvWQccB6PwlCrChFySlsHLYZjpE,32027
167
167
  reconcile/change_owners/changes.py,sha256=pa3cNAL-Xawh700ARJJQjY0p09NA1J2329RcE0F0MHM,17224
@@ -251,6 +251,7 @@ reconcile/gql_definitions/common/app_interface_repo_settings.py,sha256=rud0rz9NI
251
251
  reconcile/gql_definitions/common/app_interface_state_settings.py,sha256=VXIK0Hmyv6GTShI86IGkjxyHGwufqUBAh617XKUAKaI,2507
252
252
  reconcile/gql_definitions/common/app_interface_vault_settings.py,sha256=w8quvdG0cSq71ZyJokPPp7MyMpoDb6-HLQ3o9JHVGRQ,1771
253
253
  reconcile/gql_definitions/common/app_quay_repos_escalation_policies.py,sha256=ckdoGse7O5uAWdZdNinkWicA2EflUb5pe8jWEBtflE8,3236
254
+ reconcile/gql_definitions/common/apps.py,sha256=lC7uZjyHAvJXhCDPJJ-dQJInBJkUCNZoe129XMa67wo,1868
254
255
  reconcile/gql_definitions/common/aws_vpc_requests.py,sha256=2lpyy-QSfHPSTvV_zbnqzqUoFzVNl-CJDmoqd_zVSX4,2366
255
256
  reconcile/gql_definitions/common/aws_vpcs.py,sha256=Dss9dQ3xagnz3Ltg1e9mtG2PAmQGBbUzKCmmzvuN28s,1892
256
257
  reconcile/gql_definitions/common/clusters.py,sha256=Dr5AsSsTuqjAxkI9fU0fdiaP6u5qkmRpkkCcYDnU584,21868
@@ -604,6 +605,7 @@ reconcile/typed_queries/app_interface_repo_url.py,sha256=9fhgWihjWNYOmK65irBWw9j
604
605
  reconcile/typed_queries/app_interface_state_settings.py,sha256=GdtxrjKs6JONthBzXJO66wHx80v3YyHvbZScj0XFM1Q,447
605
606
  reconcile/typed_queries/app_interface_vault_settings.py,sha256=ffkKVDD5cukQWOorUIrGvpcVr3lCbUHRIz0HWX_h7gI,715
606
607
  reconcile/typed_queries/app_quay_repos_escalation_policies.py,sha256=qpO9z9ev2RSH8sdZprLxhhrrbI0kvzmliSPfIVnfPbE,397
608
+ reconcile/typed_queries/apps.py,sha256=IzgDQnKnvGKvFsgfIkha935I1T24tAYEp_LwrLrwVgQ,339
607
609
  reconcile/typed_queries/aws_vpc_requests.py,sha256=3LmBX9usfK8Uqr-pAux2oap01sXiMdGC_ihln6w4oV8,358
608
610
  reconcile/typed_queries/aws_vpcs.py,sha256=Fd0QCwXOH46UHw3-Xo_1ghtGYgUVJDpKf5Q3r1GpJGI,339
609
611
  reconcile/typed_queries/cloudflare.py,sha256=jOsqgCzMrjomPaIWc1isTcQAGONmMIJDTBcpmCheonA,308
@@ -837,7 +839,7 @@ tools/app_interface_metrics_exporter.py,sha256=zkwkxdAUAxjdc-pzx2_oJXG25fo0Fnyd5
837
839
  tools/app_interface_reporter.py,sha256=oZPib4HPq0aZ2Zui1QGJGk6qQdfpeihujGDBnSdKyGE,17627
838
840
  tools/glitchtip_access_reporter.py,sha256=oPBnk_YoDuljU3v0FaChzOwwnk4vap1xEE67QEjzdqs,2948
839
841
  tools/glitchtip_access_revalidation.py,sha256=8kbBJk04mkq28kWoRDDkfCGIF3GRg3pJrFAh1sW0dbk,2821
840
- tools/qontract_cli.py,sha256=5RQemctfItbH3S4TPjX2AmqmS1vCoI5j9zqhxFRJB44,129495
842
+ tools/qontract_cli.py,sha256=scWaC5D_s4s_F9z1bdxi2yCWk8UAmVIo-6u665Y6ikA,130526
841
843
  tools/sd_app_sre_alert_report.py,sha256=e9vAdyenUz2f5c8-z-5WY0wv-SJ9aePKDH2r4IwB6pc,5063
842
844
  tools/template_validation.py,sha256=qpKYaTgk0GOPGa2Ct5_5sKdwIHtCAKIBGzsMPuJU5fw,3371
843
845
  tools/cli_commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -868,8 +870,8 @@ tools/test/test_qontract_cli.py,sha256=_D61RFGAN5x44CY1tYbouhlGXXABwYfxKSWSQx3Jr
868
870
  tools/test/test_saas_promotion_state.py,sha256=dy4kkSSAQ7bC0Xp2CociETGN-2aABEfL6FU5D9Jl00Y,6056
869
871
  tools/test/test_sd_app_sre_alert_report.py,sha256=v363r9zM7__0kR5K6mvJoGFcM9BvE33fWAayrqkpojA,2116
870
872
  tools/test/test_sre_checkpoints.py,sha256=SKqPPTl9ua0RFdSSofnoQX-JZE6dFLO3LRhfQzqtfh8,2607
871
- qontract_reconcile-0.10.1rc1065.dist-info/METADATA,sha256=m4tokwe6Lqt4qrgjrUnsAPAuYikH3iysJX1DQQgfDaU,2213
872
- qontract_reconcile-0.10.1rc1065.dist-info/WHEEL,sha256=eOLhNAGa2EW3wWl_TU484h7q1UNgy0JXjjoqKoxAAQc,92
873
- qontract_reconcile-0.10.1rc1065.dist-info/entry_points.txt,sha256=GKQqCl2j2X1BJQ69een6rHcR26PmnxnONLNOQB-nRjY,491
874
- qontract_reconcile-0.10.1rc1065.dist-info/top_level.txt,sha256=l5ISPoXzt0SdR4jVdkfa7RPSKNc8zAHYWAnR-Dw8Ey8,24
875
- qontract_reconcile-0.10.1rc1065.dist-info/RECORD,,
873
+ qontract_reconcile-0.10.1rc1067.dist-info/METADATA,sha256=GzMBK4NWaoCkELds21CK4FUw7n6XnchzFSPOtm1FbSs,2213
874
+ qontract_reconcile-0.10.1rc1067.dist-info/WHEEL,sha256=eOLhNAGa2EW3wWl_TU484h7q1UNgy0JXjjoqKoxAAQc,92
875
+ qontract_reconcile-0.10.1rc1067.dist-info/entry_points.txt,sha256=GKQqCl2j2X1BJQ69een6rHcR26PmnxnONLNOQB-nRjY,491
876
+ qontract_reconcile-0.10.1rc1067.dist-info/top_level.txt,sha256=l5ISPoXzt0SdR4jVdkfa7RPSKNc8zAHYWAnR-Dw8Ey8,24
877
+ qontract_reconcile-0.10.1rc1067.dist-info/RECORD,,
@@ -9,6 +9,7 @@ from reconcile.change_owners.bundle import (
9
9
  from reconcile.change_owners.change_owners import fetch_change_type_processors
10
10
  from reconcile.change_owners.change_types import ChangeTypeContext
11
11
  from reconcile.change_owners.changes import aggregate_file_moves, parse_bundle_changes
12
+ from reconcile.typed_queries.apps import get_apps
12
13
  from reconcile.utils import gql
13
14
  from reconcile.utils.defer import defer
14
15
  from reconcile.utils.runtime.integration import (
@@ -26,6 +27,7 @@ class ChangeLogItem:
26
27
  commit: str
27
28
  change_types: list[str] = field(default_factory=list)
28
29
  error: bool = False
30
+ apps: list[str] = field(default_factory=list)
29
31
 
30
32
 
31
33
  @dataclass
@@ -55,6 +57,8 @@ class ChangeLogIntegration(QontractReconcileIntegration[ChangeLogIntegrationPara
55
57
  )
56
58
  if ctp.labels and "change_log_tracking" in ctp.labels
57
59
  ]
60
+ apps = get_apps()
61
+ app_name_by_path = {a.path: a.name for a in apps}
58
62
 
59
63
  integration_state = init_state(
60
64
  integration=self.name,
@@ -101,6 +105,22 @@ class ChangeLogIntegration(QontractReconcileIntegration[ChangeLogIntegrationPara
101
105
  changes = aggregate_file_moves(parse_bundle_changes(diff))
102
106
  for change in changes:
103
107
  logging.debug(f"Processing change {change}")
108
+ change_versions = filter(None, [change.old, change.new])
109
+ match change.fileref.schema:
110
+ case "/app-sre/app-1.yml":
111
+ changed_apps = {c["name"] for c in change_versions}
112
+ change_log_item.apps.extend(changed_apps)
113
+ case "/app-sre/saas-file-2.yml" | "/openshift/namespace-1.yml":
114
+ changed_apps = {
115
+ name
116
+ for c in change_versions
117
+ if (name := app_name_by_path.get(c["app"]["$ref"]))
118
+ }
119
+ change_log_item.apps.extend(changed_apps)
120
+
121
+ # TODO(maorfr): switch apps to set
122
+ change_log_item.apps = list(set(change_log_item.apps))
123
+
104
124
  for ctp in change_type_processors:
105
125
  logging.info(f"Processing change type {ctp.name}")
106
126
  ctx = ChangeTypeContext(
@@ -0,0 +1,72 @@
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 Apps {
23
+ apps: apps_v1 {
24
+ path
25
+ name
26
+ parentApp {
27
+ path
28
+ name
29
+ }
30
+ }
31
+ }
32
+ """
33
+
34
+
35
+ class ConfiguredBaseModel(BaseModel):
36
+ class Config:
37
+ smart_union=True
38
+ extra=Extra.forbid
39
+
40
+
41
+ class AppV1_AppV1(ConfiguredBaseModel):
42
+ path: str = Field(..., alias="path")
43
+ name: str = Field(..., alias="name")
44
+
45
+
46
+ class AppV1(ConfiguredBaseModel):
47
+ path: str = Field(..., alias="path")
48
+ name: str = Field(..., alias="name")
49
+ parent_app: Optional[AppV1_AppV1] = Field(..., alias="parentApp")
50
+
51
+
52
+ class AppsQueryData(ConfiguredBaseModel):
53
+ apps: Optional[list[AppV1]] = Field(..., alias="apps")
54
+
55
+
56
+ def query(query_func: Callable, **kwargs: Any) -> AppsQueryData:
57
+ """
58
+ This is a convenience function which queries and parses the data into
59
+ concrete types. It should be compatible with most GQL clients.
60
+ You do not have to use it to consume the generated data classes.
61
+ Alternatively, you can also mime and alternate the behavior
62
+ of this function in the caller.
63
+
64
+ Parameters:
65
+ query_func (Callable): Function which queries your GQL Server
66
+ kwargs: optional arguments that will be passed to the query function
67
+
68
+ Returns:
69
+ AppsQueryData: queried data parsed into generated classes
70
+ """
71
+ raw_data: dict[Any, Any] = query_func(DEFINITION, **kwargs)
72
+ return AppsQueryData(**raw_data)
reconcile/queries.py CHANGED
@@ -880,6 +880,7 @@ CLUSTERS_QUERY = """
880
880
  }
881
881
  tags
882
882
  cidrBlock
883
+ cidrBlocks
883
884
  manageSecurityGroups
884
885
  assumeRole
885
886
  }
@@ -0,0 +1,11 @@
1
+ from collections.abc import Callable
2
+
3
+ from reconcile.gql_definitions.common.apps import AppV1, query
4
+ from reconcile.utils import gql
5
+
6
+
7
+ def get_apps(query_func: Callable | None = None) -> list[AppV1]:
8
+ if not query_func:
9
+ gqlapi = gql.get_api()
10
+ query_func = gqlapi.query
11
+ return query(query_func=query_func).apps or []
tools/qontract_cli.py CHANGED
@@ -48,6 +48,7 @@ from reconcile.aus.base import (
48
48
  from reconcile.aus.models import OrganizationUpgradeSpec
49
49
  from reconcile.change_owners.bundle import NoOpFileDiffResolver
50
50
  from reconcile.change_owners.change_log_tracking import (
51
+ BUNDLE_DIFFS_OBJ,
51
52
  ChangeLog,
52
53
  ChangeLogIntegration,
53
54
  ChangeLogIntegrationParams,
@@ -1093,6 +1094,27 @@ def cidr_blocks(ctx, for_cluster: int, mask: int) -> None:
1093
1094
  for c in clusters
1094
1095
  ]
1095
1096
 
1097
+ tgw_cidrs = [
1098
+ {
1099
+ "type": "account-tgw",
1100
+ "name": connection["account"]["name"],
1101
+ "account": connection["account"]["name"],
1102
+ "cidr": cidr,
1103
+ "from": str(ipaddress.ip_network(cidr)[0]),
1104
+ "to": str(ipaddress.ip_network(cidr)[-1]),
1105
+ "hosts": str(ipaddress.ip_network(cidr).num_addresses),
1106
+ "description": f'CIDR {cidr} routed through account {connection["account"]["name"]} transit gateways',
1107
+ }
1108
+ for c in clusters
1109
+ for connection in (c["peering"] or {}).get("connections") or []
1110
+ if connection["provider"] == "account-tgw"
1111
+ for cidr in [connection["cidrBlock"]] + (connection["cidrBlocks"] or [])
1112
+ if cidr is not None
1113
+ ]
1114
+ # removing dupes using a set of tuple (since dicts are not hashable)
1115
+ unique_tgw_cidrs = [dict(t) for t in {tuple(d.items()) for d in tgw_cidrs}]
1116
+ cidrs.extend(unique_tgw_cidrs)
1117
+
1096
1118
  vpcs = get_aws_vpcs()
1097
1119
  cidrs.extend(
1098
1120
  {
@@ -2872,7 +2894,7 @@ def change_log_tracking(ctx):
2872
2894
  state = init_state(
2873
2895
  integration=ChangeLogIntegration(ChangeLogIntegrationParams()).name
2874
2896
  )
2875
- change_log = ChangeLog(**state.get("bundle-diffs.json"))
2897
+ change_log = ChangeLog(**state.get(BUNDLE_DIFFS_OBJ))
2876
2898
  data: list[dict[str, str]] = []
2877
2899
  for item in change_log.items:
2878
2900
  change_log_item = ChangeLogItem(**item)
@@ -2884,12 +2906,13 @@ def change_log_tracking(ctx):
2884
2906
  ]
2885
2907
  item = {
2886
2908
  "commit": f"[{commit}]({repo_url}/commit/{commit})",
2909
+ "apps": ", ".join(change_log_item.apps),
2887
2910
  "changes": ", ".join(covered_change_types_descriptions),
2888
2911
  "error": change_log_item.error,
2889
2912
  }
2890
2913
  data.append(item)
2891
2914
 
2892
- columns = ["commit", "changes", "error"]
2915
+ columns = ["commit", "apps", "changes", "error"]
2893
2916
  print_output(ctx.obj["options"], data, columns)
2894
2917
 
2895
2918