qontract-reconcile 0.10.1rc1048__py3-none-any.whl → 0.10.1rc1049__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.1rc1048
3
+ Version: 0.10.1rc1049
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
@@ -72,7 +72,7 @@ reconcile/openshift_network_policies.py,sha256=DyjaeJvSFHmslbM8nyHCxpF9EtU2m-MJo
72
72
  reconcile/openshift_prometheus_rules.py,sha256=onowXab248zmHH8SbYDTc1W1bl7JiqRFU1xdTkZyLFg,1332
73
73
  reconcile/openshift_resourcequotas.py,sha256=yUi56PiOn3inMMfq_x_FEHmaW-reGipzoorjdar372g,2415
74
74
  reconcile/openshift_resources.py,sha256=I2nO_C37mG3rfyGrd4cGwN3mVseVGuTAHAyhFzLyqF4,1518
75
- reconcile/openshift_resources_base.py,sha256=SKlJffnYjnc7AHIOvi7Ui9TmDA93_t81d5t54wnqCOA,40745
75
+ reconcile/openshift_resources_base.py,sha256=1A5_699p0rdsMwRQRPzePEfjhhq5eB2Obwxx4Ibr8jA,41205
76
76
  reconcile/openshift_rolebindings.py,sha256=9mlJ2FjWUoH-rsjtasreA_hV-K5Z_YR00qR_RR60OZM,6555
77
77
  reconcile/openshift_routes.py,sha256=fXvuPSjcjVw1X3j2EQvUAdbOepmIFdKk-M3qP8QzPiw,1075
78
78
  reconcile/openshift_saas_deploy.py,sha256=UZlm29JujJVS3MzSm6uehlC3y-jZxl6WVwMeKRdN11U,12773
@@ -571,7 +571,7 @@ reconcile/test/test_terraform_users.py,sha256=XOAfGvITCJPI1LTlISmHbA4ONMQMkxYUMT
571
571
  reconcile/test/test_terraform_vpc_peerings.py,sha256=bpjCjhmic07cw3XKSHf-2JvmLuWlyQG8laXlC-H7qtI,20796
572
572
  reconcile/test/test_terraform_vpc_peerings_build_desired_state.py,sha256=cHmr1_yhRgfdqlFX6TMw-aiKXebaRv0szl16M9YRJic,49988
573
573
  reconcile/test/test_three_way_diff_strategy.py,sha256=v3rNkQFNy5e1uyfeNSlNBA07fvrPGD0aXD91Lgv8oxc,4062
574
- reconcile/test/test_utils_jinja2.py,sha256=TpzQlpFnLGzNEZp5WOh0o7AuBiGEktqO4MuwiiJW2YY,3895
574
+ reconcile/test/test_utils_jinja2.py,sha256=rKugJEPl0qFC9joenJBXyk2qe-9md31-4EdxvQ2h5cs,4058
575
575
  reconcile/test/test_vault_replication.py,sha256=wlc4jm9f8P641UvvxIFFFc5_unJysNkOVrKJscjhQr0,16867
576
576
  reconcile/test/test_vault_utils.py,sha256=vbJnc89XAuE07qbTuWxHM5o9F6R9SO5aHXA38fwxT7A,1122
577
577
  reconcile/test/test_version_bump.py,sha256=q6-3Y1roriI6YWpFwaHOMN7emEP3yL33sh_0VdbmG7E,511
@@ -652,7 +652,7 @@ reconcile/unleash_feature_toggles/integration.py,sha256=nx7BhtzCsTfPbOp60vI5MkNw
652
652
  reconcile/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
653
653
  reconcile/utils/aggregated_list.py,sha256=km0xadW0jO4G_CqZPsXmoBURQ8c90FaTu5x4X1K1cZs,3357
654
654
  reconcile/utils/amtool.py,sha256=ngtBuVPETH6oAy5RnKzvreVbjwQCaATS_PYYwBprzjQ,2288
655
- reconcile/utils/aws_api.py,sha256=tYjTEW1uSkWsMWNFxwavJsI9xtq1dEeJ2HPlN5LAHzA,66861
655
+ reconcile/utils/aws_api.py,sha256=1EC9l2cxMW2IvnhsXaIcq6iohZ4rRgqyHJsXPs9Vtes,67398
656
656
  reconcile/utils/aws_helper.py,sha256=MDbv5jrNdqqJ5pfBxniGdJXBBO_EYc2_Uf2w9ZzeMNs,2854
657
657
  reconcile/utils/batches.py,sha256=TtEm64a8lWhFuNbUVpFEmXVdU2Q0sTBrP_I0Cjbgh7g,320
658
658
  reconcile/utils/binary.py,sha256=7MaAFBpzuBUTJ_aA6G6-eult_BPMVyiXbBLD0Y6F-DM,2301
@@ -761,8 +761,8 @@ reconcile/utils/internal_groups/client.py,sha256=V3uubJJHqW_wjwrwbC0halZrhOy7_yx
761
761
  reconcile/utils/internal_groups/models.py,sha256=y_IqBVqfGqNXiu0VudvBWFrm_-uafVm5KgLG-ca8XAs,2281
762
762
  reconcile/utils/jinja2/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
763
763
  reconcile/utils/jinja2/extensions.py,sha256=7K-uo6G2eCWa98MHT8fRPYIKCLQB_5D2keqQ_LyAfHM,1293
764
- reconcile/utils/jinja2/filters.py,sha256=tmiaYMhji5fv4B66YtR7zc-mE3wQLyj5I5SeX0WA2l4,4754
765
- reconcile/utils/jinja2/utils.py,sha256=a4vpt8f0UHerPAZs5zFESkVzZdEZRJjZ4mzJ19nubjI,8048
764
+ reconcile/utils/jinja2/filters.py,sha256=JfO_14APySBPidsMvHXG-8dULNPddZCE15Umjk_aSBk,4830
765
+ reconcile/utils/jinja2/utils.py,sha256=adxVFY4WvBGIToEEr8KwqLzp6uDxSipTBzZWwnRqbNQ,8700
766
766
  reconcile/utils/jobcontroller/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
767
767
  reconcile/utils/jobcontroller/controller.py,sha256=n9twSH_xZtp5vknM3qByp0eWCn9ED4U1a6yOFBS-GTg,14488
768
768
  reconcile/utils/jobcontroller/models.py,sha256=x9YIvWfYOOvXNKToFVx1H7qDrZb0Sa1KI_4Y0gl7rMM,6336
@@ -867,8 +867,8 @@ tools/test/test_qontract_cli.py,sha256=_D61RFGAN5x44CY1tYbouhlGXXABwYfxKSWSQx3Jr
867
867
  tools/test/test_saas_promotion_state.py,sha256=dy4kkSSAQ7bC0Xp2CociETGN-2aABEfL6FU5D9Jl00Y,6056
868
868
  tools/test/test_sd_app_sre_alert_report.py,sha256=v363r9zM7__0kR5K6mvJoGFcM9BvE33fWAayrqkpojA,2116
869
869
  tools/test/test_sre_checkpoints.py,sha256=SKqPPTl9ua0RFdSSofnoQX-JZE6dFLO3LRhfQzqtfh8,2607
870
- qontract_reconcile-0.10.1rc1048.dist-info/METADATA,sha256=0w3Sz5JM9zH3Sa3crv-Owf8f3uYAgeEafoXtXm0TdXg,2213
871
- qontract_reconcile-0.10.1rc1048.dist-info/WHEEL,sha256=eOLhNAGa2EW3wWl_TU484h7q1UNgy0JXjjoqKoxAAQc,92
872
- qontract_reconcile-0.10.1rc1048.dist-info/entry_points.txt,sha256=GKQqCl2j2X1BJQ69een6rHcR26PmnxnONLNOQB-nRjY,491
873
- qontract_reconcile-0.10.1rc1048.dist-info/top_level.txt,sha256=l5ISPoXzt0SdR4jVdkfa7RPSKNc8zAHYWAnR-Dw8Ey8,24
874
- qontract_reconcile-0.10.1rc1048.dist-info/RECORD,,
870
+ qontract_reconcile-0.10.1rc1049.dist-info/METADATA,sha256=D5PDDDmCzGGwdJ4MCHf2rBEApxpHBaSAtT97Krh_aWA,2213
871
+ qontract_reconcile-0.10.1rc1049.dist-info/WHEEL,sha256=eOLhNAGa2EW3wWl_TU484h7q1UNgy0JXjjoqKoxAAQc,92
872
+ qontract_reconcile-0.10.1rc1049.dist-info/entry_points.txt,sha256=GKQqCl2j2X1BJQ69een6rHcR26PmnxnONLNOQB-nRjY,491
873
+ qontract_reconcile-0.10.1rc1049.dist-info/top_level.txt,sha256=l5ISPoXzt0SdR4jVdkfa7RPSKNc8zAHYWAnR-Dw8Ey8,24
874
+ qontract_reconcile-0.10.1rc1049.dist-info/RECORD,,
@@ -1194,6 +1194,7 @@ def early_exit_monkey_patch() -> Generator:
1194
1194
  lookup_github_file_content=DEFAULT,
1195
1195
  url_makes_sense=DEFAULT,
1196
1196
  lookup_s3_object=DEFAULT,
1197
+ list_s3_objects=DEFAULT,
1197
1198
  ) as mocks:
1198
1199
  # mock lookup_secret
1199
1200
  mocks["lookup_secret"].side_effect = (
@@ -1239,6 +1240,17 @@ def early_exit_monkey_patch() -> Generator:
1239
1240
  mocks["lookup_s3_object"].unsafe_callable = False
1240
1241
  mocks["lookup_s3_object"].alters_data = False
1241
1242
 
1243
+ # mock list_s3_objects
1244
+ mocks["list_s3_objects"].side_effect = (
1245
+ lambda account_name,
1246
+ bucket_name,
1247
+ path,
1248
+ region_name=None: f"list_s3_objects({account_name}, {bucket_name}, {path}, {region_name})"
1249
+ )
1250
+ # needed for jinja2 `is_safe_callable`
1251
+ mocks["list_s3_objects"].unsafe_callable = False
1252
+ mocks["list_s3_objects"].alters_data = False
1253
+
1242
1254
  with patch(
1243
1255
  "reconcile.openshift_resources_base.check_alertmanager_config",
1244
1256
  return_value=True,
@@ -6,6 +6,7 @@ from reconcile.utils.jinja2.filters import (
6
6
  hash_list,
7
7
  json_pointers,
8
8
  matches_jsonpath,
9
+ str_format,
9
10
  )
10
11
 
11
12
 
@@ -121,3 +122,9 @@ def test_json_pointers() -> None:
121
122
  assert json_pointers(input, "items[?@.name=='a']") == ["/items/0"]
122
123
  assert json_pointers(input, "items[?@.name=='b']") == ["/items/1", "/items/2"]
123
124
  assert json_pointers(input, "items[?@.name=='c']") == []
125
+
126
+
127
+ def test_str_format() -> None:
128
+ value = "path/to/object"
129
+ format = "s3://%s"
130
+ assert str_format(value, format) == "s3://path/to/object"
@@ -1665,6 +1665,24 @@ class AWSApi: # pylint: disable=too-many-public-methods
1665
1665
  s3.get_object(Bucket=bucket_name, Key=path)["Body"].read().decode("utf-8")
1666
1666
  )
1667
1667
 
1668
+ def list_s3_objects(
1669
+ self,
1670
+ account_name: str,
1671
+ bucket_name: str,
1672
+ path: str,
1673
+ region_name: str | None = None,
1674
+ ) -> list[str]:
1675
+ s3 = self._account_s3_client(account_name, region_name=region_name)
1676
+ objects = s3.list_objects_v2(Bucket=bucket_name, Prefix=path, Delimiter="/")[
1677
+ "Contents"
1678
+ ]
1679
+ return [
1680
+ obj["Key"]
1681
+ for obj in sorted(
1682
+ objects, key=lambda obj: obj["LastModified"], reverse=True
1683
+ )
1684
+ ]
1685
+
1668
1686
 
1669
1687
  def aws_config_file_path() -> str | None:
1670
1688
  config_file_path = os.path.expanduser(
@@ -136,3 +136,7 @@ def json_pointers(input: Any, jsonpath: str) -> list[str]:
136
136
  Finds the RFC6901 JSON pointers of the input elements matching the given jsonpath
137
137
  """
138
138
  return [_convert_pointer(str(i.full_path)) for i in _find_jsonpath(input, jsonpath)]
139
+
140
+
141
+ def str_format(value: str, format: str) -> str:
142
+ return format % value
@@ -21,6 +21,7 @@ from reconcile.utils.jinja2.filters import (
21
21
  json_pointers,
22
22
  json_to_dict,
23
23
  matches_jsonpath,
24
+ str_format,
24
25
  urlescape,
25
26
  urlunescape,
26
27
  yaml_to_dict,
@@ -89,6 +90,7 @@ def compile_jinja2_template(
89
90
  "extract_jsonpath": extract_jsonpath,
90
91
  "matches_jsonpath": matches_jsonpath,
91
92
  "json_pointers": json_pointers,
93
+ "str_format": str_format,
92
94
  })
93
95
 
94
96
  return jinja_env.from_string(body)
@@ -146,6 +148,26 @@ def lookup_s3_object(
146
148
  )
147
149
 
148
150
 
151
+ def list_s3_objects(
152
+ account_name: str,
153
+ bucket_name: str,
154
+ path: str,
155
+ region_name: str | None = None,
156
+ ) -> list[str]:
157
+ settings = queries.get_app_interface_settings()
158
+ accounts = queries.get_aws_accounts(name=account_name)
159
+ if not accounts:
160
+ raise Exception(f"aws account not found: {account_name}")
161
+
162
+ with AWSApi(1, accounts, settings=settings, init_users=False) as aws_api:
163
+ return aws_api.list_s3_objects(
164
+ account_name,
165
+ bucket_name,
166
+ path,
167
+ region_name=region_name,
168
+ )
169
+
170
+
149
171
  @retry()
150
172
  def lookup_secret(
151
173
  path: str,
@@ -214,6 +236,7 @@ def process_jinja2_template(
214
236
  "query": lookup_graphql_query_results,
215
237
  "url": url_makes_sense,
216
238
  "s3": lookup_s3_object,
239
+ "s3_ls": list_s3_objects,
217
240
  "flatten_dict": flatten,
218
241
  "yesterday": lambda: (datetime.datetime.now() - datetime.timedelta(1)).strftime(
219
242
  "%Y-%m-%d"