Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add delete flag to external-resources #4521

Merged
merged 1 commit into from
Jul 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 15 additions & 13 deletions reconcile/external_resources/manager.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import json
import logging
from collections.abc import Iterable
from datetime import UTC, datetime
Expand Down Expand Up @@ -43,6 +42,7 @@
from reconcile.utils.secret_reader import SecretReaderBase

FLAG_RESOURCE_MANAGED_BY_ERV2 = "managed_by_erv2"
FLAG_DELETE_RESOURCE = "delete"


def setup_factories(
Expand Down Expand Up @@ -157,13 +157,13 @@ def _resource_needs_reconciliation(
def _get_desired_objects_reconciliations(self) -> set[Reconciliation]:
r: set[Reconciliation] = set()
for key, spec in self.er_inventory.items():
if spec.marked_to_delete:
continue
module = self.module_inventory.get_from_spec(spec)

try:
resource = self._build_external_resource(spec, self.er_inventory)
except ExternalResourceValidationError as e:
k = ExternalResourceKey.from_spec(spec)
self.errors[k] = e
self.errors[key] = e
continue

reconciliation = Reconciliation(
Expand All @@ -179,21 +179,23 @@ def _get_desired_objects_reconciliations(self) -> set[Reconciliation]:
return r

def _get_deleted_objects_reconciliations(self) -> set[Reconciliation]:
desired_keys = set(self.er_inventory.keys())
state_resource_keys = self.state_mgr.get_all_resource_keys()
deleted_keys = state_resource_keys - desired_keys
r: set[Reconciliation] = set()
to_reconcile: set[Reconciliation] = set()
deleted_keys = (k for k, v in self.er_inventory.items() if v.marked_to_delete)
for key in deleted_keys:
state = self.state_mgr.get_external_resource_state(key)
reconciliation = Reconciliation(
if state.resource_status == ResourceStatus.NOT_EXISTS:
logging.debug("Resource has already been removed. key: %s", key)
continue

r = Reconciliation(
key=key,
resource_hash=state.reconciliation.resource_hash,
module_configuration=state.reconciliation.module_configuration,
input=state.reconciliation.input,
action=Action.DESTROY,
)
r.add(reconciliation)
return r
to_reconcile.add(r)
return to_reconcile

def _update_in_progress_state(
self, r: Reconciliation, state: ExternalResourceState
Expand Down Expand Up @@ -310,8 +312,8 @@ def _build_external_resource(
return resource

def _serialize_resource_input(self, resource: ExternalResource) -> str:
return json.dumps(
resource.dict(exclude={"data": {FLAG_RESOURCE_MANAGED_BY_ERV2}})
return resource.json(
exclude={"data": {FLAG_RESOURCE_MANAGED_BY_ERV2, FLAG_DELETE_RESOURCE}}
)

def handle_resources(self) -> None:
Expand Down
3 changes: 3 additions & 0 deletions reconcile/external_resources/meta.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,6 @@
SECRET_ANN_IDENTIFIER = SECRET_ANN_PREFIX + "/identifier"
SECRET_UPDATED_AT = SECRET_ANN_PREFIX + "/updated_at"
SECRET_UPDATED_AT_TIMEFORMAT = "%Y-%m-%dT%H:%M:%SZ"

FLAG_RESOURCE_MANAGED_BY_ERV2 = "managed_by_erv2"
FLAG_DELETE_RESOURCE = "delete"
5 changes: 0 additions & 5 deletions reconcile/external_resources/model.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import base64
import hashlib
import json
from abc import (
Expand Down Expand Up @@ -88,7 +87,6 @@ def __init__(self, namespaces: Iterable[NamespaceV1]) -> None:
]

for spec in desired_specs:
# self.set(ExternalResourceKey.from_spec(spec), spec)
self._inventory[ExternalResourceKey.from_spec(spec)] = spec

def __getitem__(self, key: ExternalResourceKey) -> ExternalResourceSpec | None:
Expand Down Expand Up @@ -239,6 +237,3 @@ def hash(self) -> str:
return hashlib.md5(
json.dumps(self.data, sort_keys=True).encode("utf-8")
).hexdigest()

def serialize_input(self) -> str:
return base64.b64encode(json.dumps(self.dict()).encode()).decode()
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ query ExternalResourcesNamespaces {
loss_impact
}
managed_by_erv2
delete
}
... on NamespaceTerraformResourceS3_v1 {
region
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@
loss_impact
}
managed_by_erv2
delete
}
... on NamespaceTerraformResourceS3_v1 {
region
Expand Down Expand Up @@ -552,6 +553,7 @@ class NamespaceTerraformResourceRDSV1(NamespaceTerraformResourceAWSV1):
event_notifications: Optional[list[AWSRDSEventNotificationV1]] = Field(..., alias="event_notifications")
data_classification: Optional[AWSRDSDataClassificationV1] = Field(..., alias="data_classification")
managed_by_erv2: Optional[bool] = Field(..., alias="managed_by_erv2")
delete: Optional[bool] = Field(..., alias="delete")


class AWSS3EventNotificationV1(ConfiguredBaseModel):
Expand Down
12 changes: 12 additions & 0 deletions reconcile/gql_definitions/introspection.json
Original file line number Diff line number Diff line change
Expand Up @@ -42173,6 +42173,18 @@
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "delete",
"description": null,
"args": [],
"type": {
"kind": "SCALAR",
"name": "Boolean",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
}
],
"inputFields": null,
Expand Down
4 changes: 4 additions & 0 deletions reconcile/utils/external_resource_spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@ class ExternalResourceSpec:
init=False, compare=False, repr=False, hash=False, default_factory=lambda: {}
)

@property
def marked_to_delete(self) -> bool:
return self.resource.get("delete") or False

@property
def provider(self) -> str:
return self.resource["provider"]
Expand Down