qontract-reconcile 0.10.2.dev345__py3-none-any.whl → 0.10.2.dev408__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.
Files changed (126) hide show
  1. {qontract_reconcile-0.10.2.dev345.dist-info → qontract_reconcile-0.10.2.dev408.dist-info}/METADATA +11 -10
  2. {qontract_reconcile-0.10.2.dev345.dist-info → qontract_reconcile-0.10.2.dev408.dist-info}/RECORD +126 -120
  3. reconcile/aus/base.py +17 -14
  4. reconcile/automated_actions/config/integration.py +12 -0
  5. reconcile/aws_account_manager/integration.py +2 -2
  6. reconcile/aws_ami_cleanup/integration.py +6 -7
  7. reconcile/aws_ami_share.py +69 -62
  8. reconcile/aws_cloudwatch_log_retention/integration.py +155 -126
  9. reconcile/aws_ecr_image_pull_secrets.py +2 -2
  10. reconcile/aws_iam_keys.py +1 -0
  11. reconcile/aws_saml_idp/integration.py +7 -1
  12. reconcile/aws_saml_roles/integration.py +9 -3
  13. reconcile/change_owners/change_owners.py +1 -1
  14. reconcile/change_owners/diff.py +2 -4
  15. reconcile/checkpoint.py +11 -3
  16. reconcile/cli.py +33 -8
  17. reconcile/dashdotdb_dora.py +4 -11
  18. reconcile/database_access_manager.py +118 -111
  19. reconcile/endpoints_discovery/integration.py +4 -1
  20. reconcile/endpoints_discovery/merge_request_manager.py +9 -11
  21. reconcile/external_resources/factories.py +5 -12
  22. reconcile/external_resources/integration.py +1 -1
  23. reconcile/external_resources/manager.py +5 -3
  24. reconcile/external_resources/meta.py +0 -1
  25. reconcile/external_resources/model.py +10 -10
  26. reconcile/external_resources/reconciler.py +5 -2
  27. reconcile/external_resources/secrets_sync.py +4 -6
  28. reconcile/external_resources/state.py +5 -4
  29. reconcile/gabi_authorized_users.py +8 -5
  30. reconcile/gitlab_housekeeping.py +13 -15
  31. reconcile/gitlab_mr_sqs_consumer.py +2 -2
  32. reconcile/gitlab_owners.py +15 -11
  33. reconcile/gql_definitions/automated_actions/instance.py +41 -2
  34. reconcile/gql_definitions/aws_ami_cleanup/aws_accounts.py +10 -0
  35. reconcile/gql_definitions/aws_cloudwatch_log_retention/aws_accounts.py +22 -61
  36. reconcile/gql_definitions/aws_saml_idp/aws_accounts.py +10 -0
  37. reconcile/gql_definitions/aws_saml_roles/aws_accounts.py +10 -0
  38. reconcile/gql_definitions/common/aws_vpc_requests.py +10 -0
  39. reconcile/gql_definitions/common/clusters.py +2 -0
  40. reconcile/gql_definitions/external_resources/external_resources_namespaces.py +84 -1
  41. reconcile/gql_definitions/external_resources/external_resources_settings.py +2 -0
  42. reconcile/gql_definitions/fragments/aws_account_common.py +2 -0
  43. reconcile/gql_definitions/fragments/aws_organization.py +33 -0
  44. reconcile/gql_definitions/fragments/aws_vpc_request.py +2 -0
  45. reconcile/gql_definitions/introspection.json +3474 -1986
  46. reconcile/gql_definitions/jira_permissions_validator/jira_boards_for_permissions_validator.py +4 -0
  47. reconcile/gql_definitions/terraform_init/aws_accounts.py +14 -0
  48. reconcile/gql_definitions/terraform_resources/terraform_resources_namespaces.py +33 -1
  49. reconcile/gql_definitions/terraform_tgw_attachments/aws_accounts.py +10 -0
  50. reconcile/jenkins_worker_fleets.py +1 -0
  51. reconcile/jira_permissions_validator.py +236 -121
  52. reconcile/ocm/types.py +6 -0
  53. reconcile/openshift_base.py +47 -1
  54. reconcile/openshift_cluster_bots.py +2 -1
  55. reconcile/openshift_resources_base.py +6 -2
  56. reconcile/openshift_saas_deploy.py +2 -2
  57. reconcile/openshift_saas_deploy_trigger_cleaner.py +3 -5
  58. reconcile/openshift_upgrade_watcher.py +3 -3
  59. reconcile/queries.py +131 -0
  60. reconcile/saas_auto_promotions_manager/subscriber.py +4 -3
  61. reconcile/slack_usergroups.py +4 -3
  62. reconcile/sql_query.py +1 -0
  63. reconcile/statuspage/integrations/maintenances.py +4 -3
  64. reconcile/statuspage/status.py +5 -8
  65. reconcile/templates/rosa-classic-cluster-creation.sh.j2 +4 -0
  66. reconcile/templates/rosa-hcp-cluster-creation.sh.j2 +3 -0
  67. reconcile/templating/renderer.py +2 -1
  68. reconcile/terraform_aws_route53.py +7 -1
  69. reconcile/terraform_init/integration.py +185 -21
  70. reconcile/terraform_resources.py +11 -1
  71. reconcile/terraform_tgw_attachments.py +7 -1
  72. reconcile/terraform_users.py +7 -0
  73. reconcile/terraform_vpc_peerings.py +14 -3
  74. reconcile/terraform_vpc_resources/integration.py +7 -0
  75. reconcile/typed_queries/aws_account_tags.py +41 -0
  76. reconcile/typed_queries/saas_files.py +2 -2
  77. reconcile/utils/aggregated_list.py +4 -3
  78. reconcile/utils/aws_api.py +51 -20
  79. reconcile/utils/aws_api_typed/api.py +38 -9
  80. reconcile/utils/aws_api_typed/cloudformation.py +149 -0
  81. reconcile/utils/aws_api_typed/logs.py +73 -0
  82. reconcile/utils/datetime_util.py +67 -0
  83. reconcile/utils/differ.py +2 -3
  84. reconcile/utils/early_exit_cache.py +3 -2
  85. reconcile/utils/expiration.py +7 -3
  86. reconcile/utils/external_resource_spec.py +24 -1
  87. reconcile/utils/filtering.py +1 -1
  88. reconcile/utils/helm.py +2 -1
  89. reconcile/utils/helpers.py +1 -1
  90. reconcile/utils/jinja2/utils.py +4 -96
  91. reconcile/utils/jira_client.py +82 -63
  92. reconcile/utils/jjb_client.py +9 -12
  93. reconcile/utils/jobcontroller/controller.py +1 -1
  94. reconcile/utils/jobcontroller/models.py +17 -1
  95. reconcile/utils/json.py +32 -0
  96. reconcile/utils/merge_request_manager/merge_request_manager.py +3 -3
  97. reconcile/utils/merge_request_manager/parser.py +2 -2
  98. reconcile/utils/mr/app_interface_reporter.py +2 -2
  99. reconcile/utils/mr/base.py +2 -2
  100. reconcile/utils/mr/notificator.py +2 -2
  101. reconcile/utils/mr/update_access_report_base.py +3 -4
  102. reconcile/utils/oc.py +113 -95
  103. reconcile/utils/oc_filters.py +3 -3
  104. reconcile/utils/ocm/products.py +6 -0
  105. reconcile/utils/ocm/search_filters.py +3 -6
  106. reconcile/utils/ocm/service_log.py +3 -5
  107. reconcile/utils/openshift_resource.py +10 -5
  108. reconcile/utils/output.py +3 -2
  109. reconcile/utils/pagerduty_api.py +5 -5
  110. reconcile/utils/runtime/integration.py +1 -2
  111. reconcile/utils/runtime/runner.py +2 -2
  112. reconcile/utils/saasherder/models.py +2 -1
  113. reconcile/utils/saasherder/saasherder.py +9 -7
  114. reconcile/utils/slack_api.py +24 -2
  115. reconcile/utils/sloth.py +171 -2
  116. reconcile/utils/sqs_gateway.py +2 -1
  117. reconcile/utils/state.py +2 -1
  118. reconcile/utils/terraform_client.py +4 -3
  119. reconcile/utils/terrascript_aws_client.py +165 -111
  120. reconcile/utils/vault.py +1 -1
  121. reconcile/vault_replication.py +107 -42
  122. tools/app_interface_reporter.py +4 -4
  123. tools/cli_commands/systems_and_tools.py +5 -1
  124. tools/qontract_cli.py +25 -13
  125. {qontract_reconcile-0.10.2.dev345.dist-info → qontract_reconcile-0.10.2.dev408.dist-info}/WHEEL +0 -0
  126. {qontract_reconcile-0.10.2.dev345.dist-info → qontract_reconcile-0.10.2.dev408.dist-info}/entry_points.txt +0 -0
@@ -70,10 +70,13 @@ class ReconciliationK8sJob(K8sJob, BaseModel, frozen=True):
70
70
  dry_run_suffix: str = ""
71
71
 
72
72
  def name_prefix(self) -> str:
73
+ identifier = (
74
+ f"{self.reconciliation.key.provider}-{self.reconciliation.key.identifier}"
75
+ )
73
76
  if self.is_dry_run:
74
- return f"er-dry-run-mr-{self.dry_run_suffix}"
77
+ return f"er-dry-run-mr-{self.dry_run_suffix}-{identifier}"
75
78
  else:
76
- return "er"
79
+ return f"er-{identifier}"
77
80
 
78
81
  def unit_of_work_identity(self) -> Any:
79
82
  return self.reconciliation.key
@@ -3,7 +3,6 @@ import json
3
3
  import logging
4
4
  from abc import abstractmethod
5
5
  from collections.abc import Iterable, Mapping
6
- from datetime import UTC, datetime
7
6
  from hashlib import shake_128
8
7
  from typing import Any
9
8
 
@@ -18,17 +17,18 @@ from reconcile.external_resources.meta import (
18
17
  SECRET_ANN_PROVISION_PROVIDER,
19
18
  SECRET_ANN_PROVISIONER,
20
19
  SECRET_UPDATED_AT,
21
- SECRET_UPDATED_AT_TIMEFORMAT,
22
20
  )
23
21
  from reconcile.external_resources.model import (
24
22
  ExternalResourceKey,
25
23
  )
26
24
  from reconcile.openshift_base import ApplyOptions, apply_action
27
25
  from reconcile.typed_queries.clusters_minimal import get_clusters_minimal
26
+ from reconcile.utils.datetime_util import to_utc_seconds_iso_format, utc_now
28
27
  from reconcile.utils.differ import diff_mappings
29
28
  from reconcile.utils.external_resource_spec import (
30
29
  ExternalResourceSpec,
31
30
  )
31
+ from reconcile.utils.json import json_dumps
32
32
  from reconcile.utils.oc import (
33
33
  OCCli,
34
34
  )
@@ -154,7 +154,7 @@ class SecretsReconciler:
154
154
  annotations[SECRET_ANN_PROVIDER] = spec.provider
155
155
  annotations[SECRET_ANN_IDENTIFIER] = spec.identifier
156
156
  annotations[SECRET_UPDATED_AT] = spec.metadata[SECRET_UPDATED_AT]
157
- spec.resource["annotations"] = json.dumps(annotations)
157
+ spec.resource["annotations"] = json_dumps(annotations)
158
158
 
159
159
  def _specs_with_secret(
160
160
  self,
@@ -351,9 +351,7 @@ class InClusterSecretsReconciler(SecretsReconciler):
351
351
  secret_name = secret["metadata"]["name"]
352
352
  spec = secrets_map[secret_name]
353
353
  spec.secret = self.output_secrets_formatter.format(secret["data"])
354
- spec.metadata[SECRET_UPDATED_AT] = datetime.now(UTC).strftime(
355
- SECRET_UPDATED_AT_TIMEFORMAT
356
- )
354
+ spec.metadata[SECRET_UPDATED_AT] = to_utc_seconds_iso_format(utc_now())
357
355
 
358
356
  def _delete_source_secret(self, spec: ExternalResourceSpec) -> None:
359
357
  secret_name = self._get_spec_outputs_secret_name(spec)
@@ -1,6 +1,6 @@
1
1
  import logging
2
2
  from collections.abc import Mapping
3
- from datetime import UTC, datetime
3
+ from datetime import datetime
4
4
  from enum import StrEnum
5
5
  from typing import Any
6
6
 
@@ -16,6 +16,7 @@ from reconcile.external_resources.model import (
16
16
  ResourceStatus,
17
17
  )
18
18
  from reconcile.utils.aws_api_typed.api import AWSApi
19
+ from reconcile.utils.datetime_util import to_utc_microseconds_iso_format, utc_now
19
20
 
20
21
  DATE_FORMAT = "%Y-%m-%dT%H:%M:%SZ"
21
22
 
@@ -41,7 +42,7 @@ class ExternalResourceState(BaseModel):
41
42
  self, reconciliation_status: ReconciliationStatus
42
43
  ) -> None:
43
44
  if self.reconciliation_needs_state_update(reconciliation_status):
44
- self.ts = datetime.now()
45
+ self.ts = utc_now()
45
46
  self.resource_status = reconciliation_status.resource_status
46
47
 
47
48
  def reconciliation_needs_state_update(
@@ -170,7 +171,7 @@ class DynamoDBStateAdapter:
170
171
  def serialize(self, state: ExternalResourceState) -> dict[str, Any]:
171
172
  return {
172
173
  self.ER_KEY_HASH: {"S": state.key.hash()},
173
- self.TIMESTAMP: {"S": state.ts.isoformat()},
174
+ self.TIMESTAMP: {"S": to_utc_microseconds_iso_format(state.ts)},
174
175
  self.RESOURCE_STATUS: {"S": state.resource_status.value},
175
176
  self.ER_KEY: {
176
177
  "M": {
@@ -271,7 +272,7 @@ class ExternalResourcesStateDynamoDB:
271
272
  else:
272
273
  return ExternalResourceState(
273
274
  key=key,
274
- ts=datetime.now(UTC),
275
+ ts=utc_now(),
275
276
  resource_status=ResourceStatus.NOT_EXISTS,
276
277
  reconciliation=Reconciliation(key=key),
277
278
  reconciliation_errors=0,
@@ -1,4 +1,3 @@
1
- import json
2
1
  import logging
3
2
  import sys
4
3
  from collections.abc import (
@@ -17,9 +16,11 @@ from reconcile import queries
17
16
  from reconcile.status import ExitCodes
18
17
  from reconcile.utils.aggregated_list import RunnerError
19
18
  from reconcile.utils.constants import DEFAULT_THREAD_POOL_SIZE
19
+ from reconcile.utils.datetime_util import ensure_utc, utc_now
20
20
  from reconcile.utils.defer import defer
21
21
  from reconcile.utils.disabled_integrations import integration_is_enabled
22
22
  from reconcile.utils.external_resources import get_external_resource_specs
23
+ from reconcile.utils.json import json_dumps
23
24
  from reconcile.utils.openshift_resource import (
24
25
  OpenshiftResource,
25
26
  ResourceInventory,
@@ -39,12 +40,12 @@ def construct_gabi_oc_resource(
39
40
  "kind": "ConfigMap",
40
41
  "metadata": {"name": name, "annotations": {"qontract.recycle": "true"}},
41
42
  "data": {
42
- "config.json": json.dumps(
43
+ "config.json": json_dumps(
43
44
  {
44
45
  "expiration": str(expiration_date),
45
46
  "users": users,
46
47
  },
47
- separators=(",", ":"),
48
+ compact=True,
48
49
  ),
49
50
  },
50
51
  }
@@ -65,8 +66,10 @@ def fetch_desired_state(
65
66
  gabi_instances: Iterable[Mapping], ri: ResourceInventory
66
67
  ) -> None:
67
68
  for g in gabi_instances:
68
- expiration_date = datetime.strptime(g["expirationDate"], "%Y-%m-%d").date()
69
- if (expiration_date - date.today()).days > EXPIRATION_DAYS_MAX:
69
+ expiration_date = ensure_utc(
70
+ datetime.strptime(g["expirationDate"], "%Y-%m-%d") # noqa: DTZ007
71
+ ).date()
72
+ if (expiration_date - utc_now().date()).days > EXPIRATION_DAYS_MAX:
70
73
  raise RunnerError(
71
74
  f"The maximum expiration date of {g['name']} shall not "
72
75
  f"exceed {EXPIRATION_DAYS_MAX} days from today"
@@ -6,7 +6,6 @@ from collections.abc import (
6
6
  from contextlib import suppress
7
7
  from dataclasses import dataclass
8
8
  from datetime import (
9
- UTC,
10
9
  datetime,
11
10
  timedelta,
12
11
  )
@@ -30,6 +29,7 @@ from sretoolbox.utils import retry
30
29
 
31
30
  from reconcile import queries
32
31
  from reconcile.change_owners.change_types import ChangeTypePriority
32
+ from reconcile.utils.datetime_util import ensure_utc, from_utc_iso_format, utc_now
33
33
  from reconcile.utils.gitlab_api import (
34
34
  GitLabApi,
35
35
  MRState,
@@ -72,7 +72,6 @@ HOLD_LABELS = [
72
72
  ]
73
73
 
74
74
  QONTRACT_INTEGRATION = "gitlab-housekeeping"
75
- DATE_FORMAT = "%Y-%m-%dT%H:%M:%S.%fZ"
76
75
  EXPIRATION_DATE_FORMAT = "%Y-%m-%d"
77
76
  SQUASH_OPTION_ALWAYS = "always"
78
77
 
@@ -128,9 +127,7 @@ def _calculate_time_since_approval(approved_at: str) -> float:
128
127
  Returns the number of minutes since a MR has been approved.
129
128
  :param approved_at: the datetime the MR was approved in format %Y-%m-%dT%H:%M:%S.%fZ
130
129
  """
131
- time_since_approval = datetime.utcnow() - datetime.strptime(
132
- approved_at, DATE_FORMAT
133
- )
130
+ time_since_approval = utc_now() - from_utc_iso_format(approved_at)
134
131
  return time_since_approval.total_seconds() / 60
135
132
 
136
133
 
@@ -138,7 +135,7 @@ def get_timed_out_pipelines(
138
135
  pipelines: list[ProjectMergeRequestPipeline],
139
136
  pipeline_timeout: int = 60,
140
137
  ) -> list[ProjectMergeRequestPipeline]:
141
- now = datetime.utcnow()
138
+ now = utc_now()
142
139
 
143
140
  pending_pipelines = [
144
141
  p
@@ -152,7 +149,7 @@ def get_timed_out_pipelines(
152
149
  timed_out_pipelines = []
153
150
 
154
151
  for p in pending_pipelines:
155
- update_time = datetime.strptime(p.updated_at, DATE_FORMAT)
152
+ update_time = from_utc_iso_format(p.updated_at)
156
153
 
157
154
  elapsed = (now - update_time).total_seconds()
158
155
 
@@ -279,7 +276,7 @@ def handle_stale_items(
279
276
  ) -> None:
280
277
  LABEL = "stale" # noqa: N806
281
278
 
282
- now = datetime.utcnow()
279
+ now = utc_now()
283
280
  for item in items:
284
281
  if AUTO_MERGE in item.labels:
285
282
  if item.merge_status == MRStatus.UNCHECKED:
@@ -287,7 +284,7 @@ def handle_stale_items(
287
284
  item = gl.get_merge_request(item.iid)
288
285
  if item.merge_status == MRStatus.CANNOT_BE_MERGED:
289
286
  close_item(dry_run, gl, enable_closing, item_type, item)
290
- update_date = datetime.strptime(item.updated_at, DATE_FORMAT)
287
+ update_date = from_utc_iso_format(item.updated_at)
291
288
 
292
289
  # if item is over days_interval
293
290
  current_interval = now.date() - update_date.date()
@@ -315,10 +312,9 @@ def handle_stale_items(
315
312
  if not cancel_notes:
316
313
  continue
317
314
 
318
- cancel_notes_dates = [
319
- datetime.strptime(item.updated_at, DATE_FORMAT) for note in cancel_notes
320
- ]
321
- latest_cancel_note_date = max(d for d in cancel_notes_dates)
315
+ latest_cancel_note_date = max(
316
+ from_utc_iso_format(note.updated_at) for note in cancel_notes
317
+ )
322
318
  # if the latest cancel note is under
323
319
  # days_interval - remove 'stale' label
324
320
  current_interval = now.date() - latest_cancel_note_date.date()
@@ -653,8 +649,10 @@ def publish_access_token_expiration_metrics(gl: GitLabApi) -> None:
653
649
 
654
650
  for pat in pats:
655
651
  if pat.active:
656
- expiration_date = datetime.strptime(pat.expires_at, EXPIRATION_DATE_FORMAT)
657
- days_until_expiration = expiration_date.date() - datetime.now(UTC).date()
652
+ expiration_date = ensure_utc(
653
+ datetime.strptime(pat.expires_at, EXPIRATION_DATE_FORMAT) # noqa: DTZ007
654
+ )
655
+ days_until_expiration = expiration_date.date() - utc_now().date()
658
656
  gitlab_token_expiration.labels(pat.name).set(days_until_expiration.days)
659
657
  else:
660
658
  with suppress(KeyError, ValueError):
@@ -2,7 +2,6 @@
2
2
  SQS Consumer to create Gitlab merge requests.
3
3
  """
4
4
 
5
- import json
6
5
  import logging
7
6
  import sys
8
7
  from collections.abc import Callable
@@ -11,6 +10,7 @@ from reconcile import queries
11
10
  from reconcile.utils import mr
12
11
  from reconcile.utils.defer import defer
13
12
  from reconcile.utils.gitlab_api import GitLabApi
13
+ from reconcile.utils.json import json_dumps
14
14
  from reconcile.utils.secret_reader import SecretReader
15
15
  from reconcile.utils.sqs_gateway import SQSGateway
16
16
 
@@ -51,7 +51,7 @@ def run(dry_run: str, gitlab_project_id: str, defer: Callable | None = None) ->
51
51
  for m in messages:
52
52
  receipt_handle, body = m[0], m[1]
53
53
  logging.info(
54
- "received message %s with body %s", receipt_handle[:6], json.dumps(body)
54
+ "received message %s with body %s", receipt_handle[:6], json_dumps(body)
55
55
  )
56
56
 
57
57
  if not dry_run:
@@ -2,12 +2,12 @@ import logging
2
2
  from collections.abc import Callable, Mapping
3
3
  from typing import Any
4
4
 
5
- from dateutil import parser as dateparser
6
5
  from gitlab.v4.objects import ProjectMergeRequest
7
6
  from sretoolbox.utils import threaded
8
7
 
9
8
  from reconcile import queries
10
9
  from reconcile.utils.constants import DEFAULT_THREAD_POOL_SIZE
10
+ from reconcile.utils.datetime_util import from_utc_iso_format
11
11
  from reconcile.utils.defer import defer
12
12
  from reconcile.utils.gitlab_api import (
13
13
  GitLabApi,
@@ -49,12 +49,14 @@ class MRApproval:
49
49
  self.dry_run = dry_run
50
50
  self.persistent_lgtm = persistent_lgtm
51
51
 
52
- # Get the date of the most recent commit (top commit) in the MR, but avoid comparing against None
53
- self.top_commit_created_at = dateparser.parse("2000-01-01")
54
- commits = self.mr.commits()
55
- if commits:
56
- top_commit = next(commits)
57
- self.top_commit_created_at = dateparser.parse(top_commit.created_at)
52
+ # Get the date of the most recent commit (top commit) in the MR
53
+ self.top_commit_created_at = next(
54
+ (
55
+ from_utc_iso_format(commit.created_at)
56
+ for commit in merge_request.commits()
57
+ ),
58
+ None,
59
+ )
58
60
 
59
61
  def get_change_owners_map(self) -> dict[str, dict[str, list[str]]]:
60
62
  """
@@ -95,9 +97,10 @@ class MRApproval:
95
97
 
96
98
  # Only interested in comments created after the top commit
97
99
  # creation time
98
- comment_created_at = dateparser.parse(comment.created_at)
100
+ comment_created_at = from_utc_iso_format(comment.created_at)
99
101
  if (
100
- comment_created_at < self.top_commit_created_at
102
+ self.top_commit_created_at is not None
103
+ and comment_created_at < self.top_commit_created_at
101
104
  and not self.persistent_lgtm
102
105
  ):
103
106
  continue
@@ -185,9 +188,10 @@ class MRApproval:
185
188
  # If the comment was created before the last commit,
186
189
  # it means we had a push after the comment. In this case,
187
190
  # we delete the comment and move on.
188
- comment_created_at = dateparser.parse(comment.created_at)
191
+ comment_created_at = from_utc_iso_format(comment.created_at)
189
192
  if (
190
- comment_created_at < self.top_commit_created_at
193
+ self.top_commit_created_at is not None
194
+ and comment_created_at < self.top_commit_created_at
191
195
  and comment.note is not None
192
196
  ):
193
197
  # Deleting stale comments
@@ -132,6 +132,21 @@ query AutomatedActionsInstances {
132
132
  identifier
133
133
  }
134
134
  }
135
+ ... on AutomatedActionOpenshiftTriggerCronjob_v1 {
136
+ openshift_trigger_cronjob_arguments: arguments {
137
+ namespace {
138
+ name
139
+ delete
140
+ cluster {
141
+ name
142
+ disable {
143
+ integrations
144
+ }
145
+ }
146
+ }
147
+ cronjob
148
+ }
149
+ }
135
150
  ... on AutomatedActionOpenshiftWorkloadDelete_v1 {
136
151
  openshift_workload_delete_arguments: arguments {
137
152
  namespace {
@@ -297,11 +312,35 @@ class DisableClusterAutomationsV1(ConfiguredBaseModel):
297
312
  integrations: Optional[list[str]] = Field(..., alias="integrations")
298
313
 
299
314
 
300
- class AutomatedActionOpenshiftWorkloadDeleteArgumentV1_NamespaceV1_ClusterV1(ConfiguredBaseModel):
315
+ class AutomatedActionOpenshiftTriggerCronjobArgumentV1_NamespaceV1_ClusterV1(ConfiguredBaseModel):
301
316
  name: str = Field(..., alias="name")
302
317
  disable: Optional[DisableClusterAutomationsV1] = Field(..., alias="disable")
303
318
 
304
319
 
320
+ class AutomatedActionOpenshiftTriggerCronjobArgumentV1_NamespaceV1(ConfiguredBaseModel):
321
+ name: str = Field(..., alias="name")
322
+ delete: Optional[bool] = Field(..., alias="delete")
323
+ cluster: AutomatedActionOpenshiftTriggerCronjobArgumentV1_NamespaceV1_ClusterV1 = Field(..., alias="cluster")
324
+
325
+
326
+ class AutomatedActionOpenshiftTriggerCronjobArgumentV1(ConfiguredBaseModel):
327
+ namespace: AutomatedActionOpenshiftTriggerCronjobArgumentV1_NamespaceV1 = Field(..., alias="namespace")
328
+ cronjob: str = Field(..., alias="cronjob")
329
+
330
+
331
+ class AutomatedActionOpenshiftTriggerCronjobV1(AutomatedActionV1):
332
+ openshift_trigger_cronjob_arguments: list[AutomatedActionOpenshiftTriggerCronjobArgumentV1] = Field(..., alias="openshift_trigger_cronjob_arguments")
333
+
334
+
335
+ class AutomatedActionOpenshiftWorkloadDeleteArgumentV1_NamespaceV1_ClusterV1_DisableClusterAutomationsV1(ConfiguredBaseModel):
336
+ integrations: Optional[list[str]] = Field(..., alias="integrations")
337
+
338
+
339
+ class AutomatedActionOpenshiftWorkloadDeleteArgumentV1_NamespaceV1_ClusterV1(ConfiguredBaseModel):
340
+ name: str = Field(..., alias="name")
341
+ disable: Optional[AutomatedActionOpenshiftWorkloadDeleteArgumentV1_NamespaceV1_ClusterV1_DisableClusterAutomationsV1] = Field(..., alias="disable")
342
+
343
+
305
344
  class AutomatedActionOpenshiftWorkloadDeleteArgumentV1_NamespaceV1(ConfiguredBaseModel):
306
345
  name: str = Field(..., alias="name")
307
346
  delete: Optional[bool] = Field(..., alias="delete")
@@ -347,7 +386,7 @@ class AutomatedActionOpenshiftWorkloadRestartV1(AutomatedActionV1):
347
386
  class AutomatedActionsInstanceV1(ConfiguredBaseModel):
348
387
  name: str = Field(..., alias="name")
349
388
  deployment: NamespaceV1 = Field(..., alias="deployment")
350
- actions: Optional[list[Union[AutomatedActionActionListV1, AutomatedActionExternalResourceFlushElastiCacheV1, AutomatedActionExternalResourceRdsRebootV1, AutomatedActionExternalResourceRdsSnapshotV1, AutomatedActionOpenshiftWorkloadDeleteV1, AutomatedActionOpenshiftWorkloadRestartV1, AutomatedActionV1]]] = Field(..., alias="actions")
389
+ actions: Optional[list[Union[AutomatedActionActionListV1, AutomatedActionExternalResourceFlushElastiCacheV1, AutomatedActionExternalResourceRdsRebootV1, AutomatedActionExternalResourceRdsSnapshotV1, AutomatedActionOpenshiftTriggerCronjobV1, AutomatedActionOpenshiftWorkloadDeleteV1, AutomatedActionOpenshiftWorkloadRestartV1, AutomatedActionV1]]] = Field(..., alias="actions")
351
390
 
352
391
 
353
392
  class AutomatedActionsInstancesQueryData(ConfiguredBaseModel):
@@ -51,6 +51,16 @@ fragment AWSAccountCommon on AWSAccount_v1 {
51
51
  deleteKeys
52
52
  premiumSupport
53
53
  partition
54
+ organization {
55
+ ...AWSOrganization
56
+ }
57
+ }
58
+
59
+ fragment AWSOrganization on AWSOrganization_v1 {
60
+ payerAccount {
61
+ organizationAccountTags
62
+ }
63
+ tags
54
64
  }
55
65
 
56
66
  fragment TerraformState on TerraformStateAWS_v1 {
@@ -17,43 +17,38 @@ from pydantic import ( # noqa: F401 # pylint: disable=W0611
17
17
  Json,
18
18
  )
19
19
 
20
+ from reconcile.gql_definitions.fragments.aws_organization import AWSOrganization
21
+ from reconcile.gql_definitions.fragments.vault_secret import VaultSecret
22
+
20
23
 
21
24
  DEFINITION = """
25
+ fragment AWSOrganization on AWSOrganization_v1 {
26
+ payerAccount {
27
+ organizationAccountTags
28
+ }
29
+ tags
30
+ }
31
+
32
+ fragment VaultSecret on VaultSecret_v1 {
33
+ path
34
+ field
35
+ version
36
+ format
37
+ }
38
+
22
39
  query AWSAccountsCloudwatchLogRetentionCleanup {
23
40
  accounts: awsaccounts_v1 {
24
- path
25
41
  name
26
- uid
27
- terraformUsername
28
- consoleUrl
29
42
  resourcesDefaultRegion
30
- supportedDeploymentRegions
31
- providerVersion
32
- accountOwners {
33
- name
34
- email
35
- }
36
43
  automationToken {
37
- path
38
- field
39
- version
40
- format
41
- }
42
- enableDeletion
43
- deletionApprovals {
44
- type
45
- name
46
- expiration
44
+ ...VaultSecret
47
45
  }
48
46
  disable {
49
47
  integrations
50
48
  }
51
- deleteKeys
52
- premiumSupport
53
- ecrs {
54
- region
49
+ organization {
50
+ ...AWSOrganization
55
51
  }
56
- partition
57
52
  cleanup {
58
53
  provider
59
54
  ... on AWSAccountCleanupOptionCloudWatch_v1 {
@@ -74,32 +69,10 @@ class ConfiguredBaseModel(BaseModel):
74
69
  extra=Extra.forbid
75
70
 
76
71
 
77
- class OwnerV1(ConfiguredBaseModel):
78
- name: str = Field(..., alias="name")
79
- email: str = Field(..., alias="email")
80
-
81
-
82
- class VaultSecretV1(ConfiguredBaseModel):
83
- path: str = Field(..., alias="path")
84
- field: str = Field(..., alias="field")
85
- version: Optional[int] = Field(..., alias="version")
86
- q_format: Optional[str] = Field(..., alias="format")
87
-
88
-
89
- class DeletionApprovalV1(ConfiguredBaseModel):
90
- q_type: str = Field(..., alias="type")
91
- name: str = Field(..., alias="name")
92
- expiration: str = Field(..., alias="expiration")
93
-
94
-
95
72
  class DisableClusterAutomationsV1(ConfiguredBaseModel):
96
73
  integrations: Optional[list[str]] = Field(..., alias="integrations")
97
74
 
98
75
 
99
- class AWSECRV1(ConfiguredBaseModel):
100
- region: str = Field(..., alias="region")
101
-
102
-
103
76
  class AWSAccountCleanupOptionV1(ConfiguredBaseModel):
104
77
  provider: str = Field(..., alias="provider")
105
78
 
@@ -112,23 +85,11 @@ class AWSAccountCleanupOptionCloudWatchV1(AWSAccountCleanupOptionV1):
112
85
 
113
86
 
114
87
  class AWSAccountV1(ConfiguredBaseModel):
115
- path: str = Field(..., alias="path")
116
88
  name: str = Field(..., alias="name")
117
- uid: str = Field(..., alias="uid")
118
- terraform_username: Optional[str] = Field(..., alias="terraformUsername")
119
- console_url: str = Field(..., alias="consoleUrl")
120
89
  resources_default_region: str = Field(..., alias="resourcesDefaultRegion")
121
- supported_deployment_regions: Optional[list[str]] = Field(..., alias="supportedDeploymentRegions")
122
- provider_version: str = Field(..., alias="providerVersion")
123
- account_owners: list[OwnerV1] = Field(..., alias="accountOwners")
124
- automation_token: VaultSecretV1 = Field(..., alias="automationToken")
125
- enable_deletion: Optional[bool] = Field(..., alias="enableDeletion")
126
- deletion_approvals: Optional[list[DeletionApprovalV1]] = Field(..., alias="deletionApprovals")
90
+ automation_token: VaultSecret = Field(..., alias="automationToken")
127
91
  disable: Optional[DisableClusterAutomationsV1] = Field(..., alias="disable")
128
- delete_keys: Optional[list[str]] = Field(..., alias="deleteKeys")
129
- premium_support: bool = Field(..., alias="premiumSupport")
130
- ecrs: Optional[list[AWSECRV1]] = Field(..., alias="ecrs")
131
- partition: Optional[str] = Field(..., alias="partition")
92
+ organization: Optional[AWSOrganization] = Field(..., alias="organization")
132
93
  cleanup: Optional[list[Union[AWSAccountCleanupOptionCloudWatchV1, AWSAccountCleanupOptionV1]]] = Field(..., alias="cleanup")
133
94
 
134
95
 
@@ -51,6 +51,16 @@ fragment AWSAccountCommon on AWSAccount_v1 {
51
51
  deleteKeys
52
52
  premiumSupport
53
53
  partition
54
+ organization {
55
+ ...AWSOrganization
56
+ }
57
+ }
58
+
59
+ fragment AWSOrganization on AWSOrganization_v1 {
60
+ payerAccount {
61
+ organizationAccountTags
62
+ }
63
+ tags
54
64
  }
55
65
 
56
66
  fragment TerraformState on TerraformStateAWS_v1 {
@@ -51,6 +51,16 @@ fragment AWSAccountCommon on AWSAccount_v1 {
51
51
  deleteKeys
52
52
  premiumSupport
53
53
  partition
54
+ organization {
55
+ ...AWSOrganization
56
+ }
57
+ }
58
+
59
+ fragment AWSOrganization on AWSOrganization_v1 {
60
+ payerAccount {
61
+ organizationAccountTags
62
+ }
63
+ tags
54
64
  }
55
65
 
56
66
  fragment TerraformState on TerraformStateAWS_v1 {
@@ -21,6 +21,13 @@ from reconcile.gql_definitions.fragments.aws_vpc_request import VPCRequest
21
21
 
22
22
 
23
23
  DEFINITION = """
24
+ fragment AWSOrganization on AWSOrganization_v1 {
25
+ payerAccount {
26
+ organizationAccountTags
27
+ }
28
+ tags
29
+ }
30
+
24
31
  fragment TerraformState on TerraformStateAWS_v1 {
25
32
  provider
26
33
  bucket
@@ -53,6 +60,9 @@ fragment VPCRequest on VPCRequest_v1 {
53
60
  name
54
61
  expiration
55
62
  }
63
+ organization {
64
+ ...AWSOrganization
65
+ }
56
66
  }
57
67
  region
58
68
  cidr_block {
@@ -207,6 +207,7 @@ query Clusters($name: String) {
207
207
  private
208
208
  provision_shard_id
209
209
  disable_user_workload_monitoring
210
+ fips
210
211
  }
211
212
  externalConfiguration {
212
213
  labels
@@ -419,6 +420,7 @@ class ClusterSpecV1(ConfiguredBaseModel):
419
420
  private: bool = Field(..., alias="private")
420
421
  provision_shard_id: Optional[str] = Field(..., alias="provision_shard_id")
421
422
  disable_user_workload_monitoring: Optional[bool] = Field(..., alias="disable_user_workload_monitoring")
423
+ fips: Optional[bool] = Field(..., alias="fips")
422
424
 
423
425
 
424
426
  class ClusterSpecOSDV1(ClusterSpecV1):