qontract-reconcile 0.10.2.dev294__py3-none-any.whl → 0.10.2.dev296__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.
@@ -403,7 +403,7 @@ class OCM:
403
403
  api = (
404
404
  f"{CS_API_BASE}/v1/clusters/{cluster_id}" + "/external_configuration/labels"
405
405
  )
406
- items = self._get_json(api).get("items")
406
+ items = self._get_json(api).get("items", [])
407
407
  item = [item for item in items if label.items() <= item.items()]
408
408
  if not item:
409
409
  return
@@ -597,14 +597,14 @@ class OCM:
597
597
  def _init_addons(self):
598
598
  """Returns a list of Addons"""
599
599
  api = f"{CS_API_BASE}/v1/addons"
600
- self.addons = self._get_json(api).get("items")
600
+ self.addons = self._get_json(api).get("items", [])
601
601
 
602
602
  def _init_version_gates(self):
603
603
  """Returns a list of version gates"""
604
604
  if self.version_gates:
605
605
  return
606
606
  api = f"{CS_API_BASE}/v1/version_gates"
607
- self.version_gates = self._get_json(api).get("items")
607
+ self.version_gates = self._get_json(api).get("items", [])
608
608
 
609
609
  def get_addon(self, id):
610
610
  for addon in self.addons:
@@ -275,17 +275,17 @@ def get_apps_data(
275
275
  cluster = sample.labels["cluster"]
276
276
  if app_namespace["cluster"]["name"] != cluster:
277
277
  continue
278
- namespace = sample.labels["namespace"]
279
- if app_namespace["name"] != namespace:
278
+ sample_namespace = sample.labels["namespace"]
279
+ if app_namespace["name"] != sample_namespace:
280
280
  continue
281
281
  severity = sample.labels["severity"]
282
282
  if cluster not in vuln_mx:
283
283
  vuln_mx[cluster] = {}
284
- if namespace not in vuln_mx[cluster]:
285
- vuln_mx[cluster][namespace] = {}
286
- if severity not in vuln_mx[cluster][namespace]:
284
+ if sample_namespace not in vuln_mx[cluster]:
285
+ vuln_mx[cluster][sample_namespace] = {}
286
+ if severity not in vuln_mx[cluster][sample_namespace]:
287
287
  value = int(sample.value)
288
- vuln_mx[cluster][namespace][severity] = value
288
+ vuln_mx[cluster][sample_namespace][severity] = value
289
289
  for family in text_string_to_metric_families(validt_metrics):
290
290
  for sample in family.samples:
291
291
  if sample.name == "deploymentvalidation_total":
@@ -293,8 +293,8 @@ def get_apps_data(
293
293
  cluster = sample.labels["cluster"]
294
294
  if app_namespace["cluster"]["name"] != cluster:
295
295
  continue
296
- namespace = sample.labels["namespace"]
297
- if app_namespace["name"] != namespace:
296
+ sample_namespace = sample.labels["namespace"]
297
+ if app_namespace["name"] != sample_namespace:
298
298
  continue
299
299
  validation = sample.labels["validation"]
300
300
  # dvo: fail == 1, pass == 0, py: true == 1, false == 0
@@ -302,14 +302,19 @@ def get_apps_data(
302
302
  status = ("Passed", "Failed")[int(sample.labels["status"])]
303
303
  if cluster not in validt_mx:
304
304
  validt_mx[cluster] = {}
305
- if namespace not in validt_mx[cluster]:
306
- validt_mx[cluster][namespace] = {}
307
- if validation not in validt_mx[cluster][namespace]:
308
- validt_mx[cluster][namespace][validation] = {}
309
- if status not in validt_mx[cluster][namespace][validation]:
310
- validt_mx[cluster][namespace][validation][status] = {}
305
+ if sample_namespace not in validt_mx[cluster]:
306
+ validt_mx[cluster][sample_namespace] = {}
307
+ if validation not in validt_mx[cluster][sample_namespace]:
308
+ validt_mx[cluster][sample_namespace][validation] = {}
309
+ if (
310
+ status
311
+ not in validt_mx[cluster][sample_namespace][validation]
312
+ ):
313
+ validt_mx[cluster][sample_namespace][validation][
314
+ status
315
+ ] = {}
311
316
  value = int(sample.value)
312
- validt_mx[cluster][namespace][validation][status] = value
317
+ validt_mx[cluster][sample_namespace][validation][status] = value
313
318
  for family in text_string_to_metric_families(slo_metrics):
314
319
  for sample in family.samples:
315
320
  if sample.name == "serviceslometrics":
@@ -317,25 +322,28 @@ def get_apps_data(
317
322
  cluster = sample.labels["cluster"]
318
323
  if app_namespace["cluster"]["name"] != cluster:
319
324
  continue
320
- namespace = sample.labels["namespace"]
321
- if app_namespace["name"] != namespace:
325
+ sample_namespace = sample.labels["namespace"]
326
+ if app_namespace["name"] != sample_namespace:
322
327
  continue
323
328
  slo_doc_name = sample.labels["slodoc"]
324
329
  slo_name = sample.labels["name"]
325
330
  if cluster not in slo_mx:
326
331
  slo_mx[cluster] = {}
327
- if namespace not in slo_mx[cluster]:
328
- slo_mx[cluster][namespace] = {}
329
- if slo_doc_name not in slo_mx[cluster][namespace]:
330
- slo_mx[cluster][namespace][slo_doc_name] = {}
331
- if slo_name not in slo_mx[cluster][namespace][slo_doc_name]:
332
- slo_mx[cluster][namespace][slo_doc_name][slo_name] = {
333
- sample.labels["type"]: sample.value
334
- }
332
+ if sample_namespace not in slo_mx[cluster]:
333
+ slo_mx[cluster][sample_namespace] = {}
334
+ if slo_doc_name not in slo_mx[cluster][sample_namespace]:
335
+ slo_mx[cluster][sample_namespace][slo_doc_name] = {}
336
+ if (
337
+ slo_name
338
+ not in slo_mx[cluster][sample_namespace][slo_doc_name]
339
+ ):
340
+ slo_mx[cluster][sample_namespace][slo_doc_name][
341
+ slo_name
342
+ ] = {sample.labels["type"]: sample.value}
335
343
  else:
336
- slo_mx[cluster][namespace][slo_doc_name][slo_name].update({
337
- sample.labels["type"]: sample.value
338
- })
344
+ slo_mx[cluster][sample_namespace][slo_doc_name][
345
+ slo_name
346
+ ].update({sample.labels["type"]: sample.value})
339
347
  app["container_vulnerabilities"] = vuln_mx
340
348
  app["deployment_validations"] = validt_mx
341
349
  app["service_slo"] = slo_mx
tools/qontract_cli.py CHANGED
@@ -1715,7 +1715,10 @@ def add_resource(item: dict, resource: Mapping, columns: list[str]) -> None:
1715
1715
  @click.pass_context
1716
1716
  def cluster_openshift_resources(ctx: click.Context) -> None:
1717
1717
  gqlapi = gql.get_api()
1718
- namespaces = gqlapi.query(orb.NAMESPACES_QUERY)["namespaces"]
1718
+ data = gqlapi.query(orb.NAMESPACES_QUERY)
1719
+ if not data:
1720
+ raise ValueError("no namespaces found")
1721
+ namespaces = data.get("namespaces", [])
1719
1722
  columns = ["name", "total"]
1720
1723
  results: dict = {}
1721
1724
  for ns_info in namespaces:
@@ -1912,6 +1915,7 @@ def rds_recommendations(ctx: click.Context) -> None:
1912
1915
  print("[TOC]")
1913
1916
  for account in accounts:
1914
1917
  account_name = account.get("name")
1918
+ assert account_name is not None # make mypy happy
1915
1919
  account_deployment_regions = account.get("supportedDeploymentRegions")
1916
1920
  for region in account_deployment_regions or []:
1917
1921
  with AWSApi(1, [account], settings=settings, init_users=False) as aws:
@@ -1926,9 +1930,9 @@ def rds_recommendations(ctx: click.Context) -> None:
1926
1930
  recommendations = [
1927
1931
  {
1928
1932
  **rec,
1929
- "ResourceName": rec["ResourceArn"].split(":")[-1],
1933
+ "ResourceName": rec.get("ResourceArn", "").split(":")[-1],
1930
1934
  # The Description field has \n that are causing issues with the markdown table
1931
- "Description": rec["Description"].replace("\n", " "),
1935
+ "Description": rec.get("Description", "").replace("\n", " "),
1932
1936
  }
1933
1937
  for rec in db_recommendations
1934
1938
  if rec.get("Status") not in ignored_statuses
@@ -2710,16 +2714,16 @@ def ec2_jenkins_workers(
2710
2714
  )
2711
2715
  continue
2712
2716
  instance = ec2.Instance(i["InstanceId"])
2713
- state = instance.state["Name"]
2717
+ state = instance.state.get("Name")
2714
2718
  if state != "running":
2715
2719
  continue
2716
2720
  os = ""
2717
2721
  url = ""
2718
2722
  for t in instance.tags:
2719
2723
  if t.get("Key") == "os":
2720
- os = t["Value"]
2724
+ os = t.get("Value", "")
2721
2725
  if t.get("Key") == "jenkins_controller":
2722
- url = f"https://{t['Value'].replace('-', '.')}.devshift.net/computer/{instance.id}"
2726
+ url = f"https://{t.get('Value', '').replace('-', '.')}.devshift.net/computer/{instance.id}"
2723
2727
  image = ec2.Image(instance.image_id)
2724
2728
  commit_url = ""
2725
2729
  for t in image.tags:
@@ -3633,7 +3637,10 @@ def template(
3633
3637
  secret_reader: str,
3634
3638
  ) -> None:
3635
3639
  gqlapi = gql.get_api()
3636
- namespaces = gqlapi.query(orb.NAMESPACES_QUERY)["namespaces"]
3640
+ data = gqlapi.query(orb.NAMESPACES_QUERY)
3641
+ if not data:
3642
+ raise ValueError("no namespaces found")
3643
+ namespaces = data.get("namespaces", [])
3637
3644
  namespaces_info = [
3638
3645
  n
3639
3646
  for n in namespaces
@@ -3725,7 +3732,7 @@ def run_prometheus_test(
3725
3732
  ptr.run_test(test=test, alerting_services=get_alerting_services())
3726
3733
 
3727
3734
  print(test.result)
3728
- if not test.result:
3735
+ if test.result is None:
3729
3736
  sys.exit(1)
3730
3737
 
3731
3738
 
@@ -3804,7 +3811,10 @@ def alert_to_receiver(
3804
3811
  additional_labels[key] = value
3805
3812
 
3806
3813
  gqlapi = gql.get_api()
3807
- namespaces = gqlapi.query(orb.NAMESPACES_QUERY)["namespaces"]
3814
+ data = gqlapi.query(orb.NAMESPACES_QUERY)
3815
+ if not data:
3816
+ raise ValueError("no namespaces found")
3817
+ namespaces = data.get("namespaces", [])
3808
3818
  cluster_namespaces = [n for n in namespaces if n["cluster"]["name"] == cluster]
3809
3819
 
3810
3820
  if len(cluster_namespaces) == 0:
@@ -4027,15 +4037,16 @@ def query(output: str, query: str) -> None:
4027
4037
  def promquery(cluster: str, query: str) -> None:
4028
4038
  """Run a PromQL query"""
4029
4039
  config_data = config.get_config()
4030
- auth = {"path": config_data["promql-auth"]["secret_path"], "field": "token"}
4040
+ prom_auth = {"path": config_data["promql-auth"]["secret_path"], "field": "token"}
4031
4041
  settings = queries.get_app_interface_settings()
4032
4042
  secret_reader = SecretReader(settings=settings)
4033
- prom_auth_creds = secret_reader.read(auth)
4034
- prom_auth = requests.auth.HTTPBasicAuth(*prom_auth_creds.split(":"))
4043
+ prom_user, prom_pass = secret_reader.read(prom_auth).split(":")
4035
4044
 
4036
4045
  url = f"https://prometheus.{cluster}.devshift.net/api/v1/query"
4037
4046
 
4038
- response = requests.get(url, params={"query": query}, auth=prom_auth, timeout=60)
4047
+ response = requests.get(
4048
+ url, params={"query": query}, auth=(prom_user, prom_pass), timeout=60
4049
+ )
4039
4050
  response.raise_for_status()
4040
4051
 
4041
4052
  print(json.dumps(response.json(), indent=4))
@@ -4092,11 +4103,12 @@ def sre_checkpoint_metadata(
4092
4103
  board_info = queries.get_simple_jira_boards(jiradef)
4093
4104
  else:
4094
4105
  board_info = app["escalationPolicy"]["channels"]["jiraBoard"]
4095
- board_info = board_info[0]
4106
+ assert board_info # make mypy happy
4107
+ board = board_info[0]
4096
4108
  # Overrides for easier testing
4097
4109
  if jiraboard:
4098
- board_info["name"] = jiraboard
4099
- report_invalid_metadata(app, app_path, board_info, settings, parent_ticket, dry_run)
4110
+ board["name"] = jiraboard
4111
+ report_invalid_metadata(app, app_path, board, settings, parent_ticket, dry_run)
4100
4112
 
4101
4113
 
4102
4114
  @root.command()