Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
*/
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({ "service", "prompts" })
@JsonPropertyOrder({ "service", "prompts", "keepOnDelete" })
@Buildable(editableEnabled = false, builderPackage = "io.fabric8.kubernetes.api.builder")
public class PromptsSpec {

Expand All @@ -40,6 +40,9 @@ public class PromptsSpec {
@JsonPropertyDescription("The prompts are defined with name as key.")
private Map<String, PromptItem> prompts;

@JsonPropertyDescription("Flag to keep artifact in control plane when deleting this resource. Default is false.")
private boolean keepOnDelete = false;

public ServiceRef getService() {
return service;
}
Expand All @@ -55,4 +58,12 @@ public Map<String, PromptItem> getPrompts() {
public void setPrompts(Map<String, PromptItem> prompts) {
this.prompts = prompts;
}

public boolean isKeepOnDelete() {
return keepOnDelete;
}

public void setKeepOnDelete(boolean keepOnDelete) {
this.keepOnDelete = keepOnDelete;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
*/
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({ "service", "resources", "resourceTemplates" })
@JsonPropertyOrder({ "service", "resources", "resourceTemplates", "keepOnDelete" })
@Buildable(editableEnabled = false, builderPackage = "io.fabric8.kubernetes.api.builder")
public class ResourcesSpec {

Expand All @@ -49,6 +49,9 @@ public class ResourcesSpec {
@JsonPropertyDescription("The resource template definitions, keyed by URI template.")
private Map<String, ResourceTemplateItem> resourceTemplates;

@JsonPropertyDescription("Flag to keep artifact in control plane when deleting this resource. Default is false.")
private boolean keepOnDelete = false;

public ServiceRef getService() {
return service;
}
Expand All @@ -72,4 +75,12 @@ public Map<String, ResourceTemplateItem> getResourceTemplates() {
public void setResourceTemplates(Map<String, ResourceTemplateItem> resourceTemplates) {
this.resourceTemplates = resourceTemplates;
}

public boolean isKeepOnDelete() {
return keepOnDelete;
}

public void setKeepOnDelete(boolean keepOnDelete) {
this.keepOnDelete = keepOnDelete;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
*/
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({ "service", "customTools" })
@JsonPropertyOrder({ "service", "customTools", "keepOnDelete" })
@Buildable(editableEnabled = false, builderPackage = "io.fabric8.kubernetes.api.builder")
public class CustomToolsSpec {

Expand All @@ -40,6 +40,9 @@ public class CustomToolsSpec {
@JsonPropertyDescription("The custom tools are defined with name as key.")
private Map<String, CustomToolItem> customTools;

@JsonPropertyDescription("Flag to keep artifact in control plane when deleting this resource. Default is false.")
private boolean keepOnDelete = false;

public ServiceRef getService() {
return service;
}
Expand All @@ -55,4 +58,12 @@ public Map<String, CustomToolItem> getCustomTools() {
public void setCustomTools(Map<String, CustomToolItem> customTools) {
this.customTools = customTools;
}

public boolean isKeepOnDelete() {
return keepOnDelete;
}

public void setKeepOnDelete(boolean keepOnDelete) {
this.keepOnDelete = keepOnDelete;
}
}
4 changes: 4 additions & 0 deletions deploy/crd/customtools.reshapr.io-v1.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ spec:
type: "object"
description: "The custom tools are defined with name as key."
type: "object"
keepOnDelete:
description: "Flag to keep artifact in control plane when deleting this\
\ resource. Default is false"
type: "boolean"
service:
description: "Holds reference information about this Service custom\
\ tools relate."
Expand Down
4 changes: 4 additions & 0 deletions deploy/crd/prompts.reshapr.io-v1.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ spec:
properties:
spec:
properties:
keepOnDelete:
description: "Flag to keep artifact in control plane when deleting this\
\ resource. Default is false"
type: "boolean"
prompts:
additionalProperties:
properties:
Expand Down
4 changes: 4 additions & 0 deletions deploy/crd/resources.reshapr.io-v1.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ spec:
properties:
spec:
properties:
keepOnDelete:
description: "Flag to keep artifact in control plane when deleting this\
\ resource. Default is false"
type: "boolean"
resourceTemplates:
additionalProperties:
properties:
Expand Down
1 change: 1 addition & 0 deletions documentation/customtools-cr.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ status:
|----------------|------------------------------------------------------------------------------------------------------|
| `service` | **Mandatory**. Reference to the target Service — see _Service reference_ below. |
| `customTools` | **Mandatory**. Map of tool name → [_Custom tool item_](#custom-tool-item-specification). |
| `keepOnDelete` | **Optional**. When `true`, deleting the CR keeps the artifact in the control plane. Defaults to `false`. |

### Service reference (`spec.service`)

Expand Down
9 changes: 5 additions & 4 deletions documentation/prompts-cr.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,11 @@ mandatory — see the [Instance connection flow](./instance-connection.md). The

## Specification details

| Property | Description |
|-----------|--------------------------------------------------------------------------------------|
| `service` | **Mandatory**. Target Service reference (`name` and `version`). |
| `prompts` | Map of prompt name → prompt item (see below). |
| Property | Description |
|----------------|--------------------------------------------------------------------------------------|
| `service` | **Mandatory**. Target Service reference (`name` and `version`). |
| `prompts` | Map of prompt name → prompt item (see below). |
| `keepOnDelete` | **Optional**. When `true`, deleting the CR keeps the artifact in the control plane. Defaults to `false`. |

### Prompt item

Expand Down
1 change: 1 addition & 0 deletions documentation/resources-cr.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ status:
| `service` | **Mandatory**. Reference to the target Service — see _Service reference_ below. |
| `resources` | **Optional**. Map of URI → [_Resource item_](#resources-item-specification). At least one of `resources` or `resourceTemplates` must be present. |
| `resourceTemplates` | **Optional**. Map of URI template → [_Resource template item_](#resources-template-item-specification). At least one of `resources` or `resourceTemplates` must be present. |
| `keepOnDelete` | **Optional**. When `true`, deleting the CR keeps the artifact in the control plane. Defaults to `false`. |

### Service reference (`spec.service`)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,18 @@ protected BaseArtifactReconciler(ReshaprApiClientFactory apiClientFactory, Artif
protected abstract String getArtifactContent(R resource) throws Exception;
protected abstract String getArtifactName(R resource);
protected abstract String getArtifactId(R resource);
protected abstract boolean isKeepOnDelete(R resource);
protected abstract void updateStatus(R resource, String serviceId, String artifactId, Status status, String message);

@Override
public DeleteControl cleanup(R resource, Context<R> context) {
String name = resource.getMetadata().getName();

if (isKeepOnDelete(resource)) {
logger.infof("'keepOnDelete' is set for resource '%s' — leaving control plane Artifact in place", name);
return DeleteControl.defaultDelete();
}

try {
ApiClient apiClient = authenticatedClientFor(resource);
if (apiClient == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,11 @@ protected String getArtifactId(CustomTools resource) {
return resource.getStatus() != null ? resource.getStatus().getArtifactId() : null;
}

@Override
protected boolean isKeepOnDelete(CustomTools resource) {
return resource.getSpec() != null && resource.getSpec().isKeepOnDelete();
}

@Override
protected void updateStatus(CustomTools resource, String serviceId, String artifactId, Status status, String message) {
CustomToolsStatus s = resource.getStatus();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@ protected String getArtifactId(Prompts resource) {
return resource.getStatus() != null ? resource.getStatus().getArtifactId() : null;
}

@Override
protected boolean isKeepOnDelete(Prompts resource) {
return resource.getSpec() != null && resource.getSpec().isKeepOnDelete();
}

@Override
protected void updateStatus(Prompts resource, String serviceId, String artifactId, Status status, String message) {
PromptsStatus s = resource.getStatus();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@ protected String getArtifactId(Resources resources) {
return resources.getStatus() != null ? resources.getStatus().getArtifactId() : null;
}

@Override
protected boolean isKeepOnDelete(Resources resources) {
return resources.getSpec() != null && resources.getSpec().isKeepOnDelete();
}

@Override
protected void updateStatus(Resources resources, String serviceId, String artifactId, Status status, String message) {
ResourcesStatus s = resources.getStatus();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,5 +161,21 @@ void testCleanup_handles404Cleanly() throws Exception {
verify(mockedApi).deleteArtifact("art-123");
}
}

@Test
void testCleanup_honorsKeepOnDelete() throws Exception {
ReshaprApiClientFactory factory = mock(ReshaprApiClientFactory.class);
PromptsReconciler customReconciler = new PromptsReconciler(factory, null, objectMapper);
Prompts prompts = buildPrompts();
prompts.getSpec().setKeepOnDelete(true);
customReconciler.updateStatus(prompts, "svc-1", "art-123", Status.READY, "ok");

try (MockedConstruction<DefaultApi> mocked = Mockito.mockConstruction(DefaultApi.class)) {
DeleteControl control = customReconciler.cleanup(prompts, null);

assertTrue(control.isRemoveFinalizer());
assertEquals(0, mocked.constructed().size(), "DefaultApi should not be initialized when keepOnDelete is true");
}
}
}

Loading