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 support for linked resource providers with no template #98

Merged
merged 1 commit into from
Nov 13, 2023
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
12 changes: 11 additions & 1 deletion operator/resourceclaim.py
Original file line number Diff line number Diff line change
Expand Up @@ -614,7 +614,17 @@ async def manage(self, logger) -> None:
delay = 600
)

provider = await self.get_resource_provider()
try:
provider = await self.get_resource_provider()
except kubernetes_asyncio.client.exceptions.ApiException as e:
if e.status == 404:
raise kopf.TemporaryError(
f"ResourceProvider ({self.resource_provider_name_from_spec}) not found",
delay = 600
)
else:
raise

if provider.approval_required:
if not 'approval' in self.status:
await self.merge_patch_status({
Expand Down
33 changes: 20 additions & 13 deletions operator/resourceprovider.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,10 @@ def approval_required(self) -> bool:
def create_disabled(self) -> bool:
return self.spec.get('disableCreation', False)

@property
def has_template_definition(self) -> bool:
return 'template' in self.spec and 'definition' in self.spec['template']

@property
def lifespan_maximum(self) -> Optional[str]:
return self.spec.get('lifespan', {}).get('maximum')
Expand Down Expand Up @@ -401,6 +405,8 @@ async def get_claim_resources(self,
resource_name: Optional[str] = None,
) -> List[Mapping]:
"""Return list of resources for managed ResourceClaim"""
resources = []

if parameter_values == None:
parameter_values = {
**self.parameter_defaults,
Expand All @@ -417,20 +423,10 @@ async def get_claim_resources(self,
"resource_provider": self,
}

resource = {
"name": resource_name or self.resource_name,
"provider": self.as_reference(),
"template": self.processed_template(
parameter_values = parameter_values,
resource_claim = resource_claim,
resource_handle = resource_handle,
)
}

linked_resources = []
resources = []
for linked_resource_provider in self.linked_resource_providers:
resource_provider = await ResourceProvider.get(linked_resource_provider.name)
linked_resources.extend(
resources.extend(
await resource_provider.get_claim_resources(
resource_claim = resource_claim,
resource_handle = resource_handle,
Expand All @@ -442,7 +438,18 @@ async def get_claim_resources(self,
)
)

return [*linked_resources, resource]
if self.has_template_definition:
resources.append({
"name": resource_name or self.resource_name,
"provider": self.as_reference(),
"template": self.processed_template(
parameter_values = parameter_values,
resource_claim = resource_claim,
resource_handle = resource_handle,
)
})

return resources

def is_match_for_template(self, template: Mapping) -> bool:
"""
Expand Down
2 changes: 1 addition & 1 deletion test/roles/poolboy_test_simple/tasks/cleanup.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,4 @@
register: r_get_namespace
until: r_get_namespace.resources | default([]) | length == 0
delay: 5
retries: 10
retries: 30
303 changes: 303 additions & 0 deletions test/roles/poolboy_test_simple/tasks/test-linked-01.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,303 @@
---
# Test basic linked resource provider
- name: Create ResourceProvider test-linked-01-base
kubernetes.core.k8s:
definition:
apiVersion: "{{ poolboy_domain }}/v1"
kind: ResourceProvider
metadata:
name: test-linked-01-base
namespace: "{{ poolboy_namespace }}"
labels: >-
{{ {
poolboy_domain ~ "/test": "simple"
} }}
spec:
override:
apiVersion: "{{ poolboy_domain }}/v1"
kind: ResourceClaimTest
metadata:
name: test-linked-01-{% raw %}{{ guid }}-{{ resource_name }}{% endraw %}
namespace: "{{ poolboy_test_namespace }}"
parameters:
- name: stringvar
allowUpdate: true
required: true
validation:
openAPIV3Schema:
type: string
default: one
enum:
- one
- two
- three
- name: numbervar
allowUpdate: true
validation:
openAPIV3Schema:
type: integer
default: 0
minimum: 0
template:
definition:
spec:
numbervalue: "{% raw %}{{ numbervar | int }}{% endraw %}"
stringvalue: "{% raw %}{{ stringvar }}{% endraw %}"
enable: true
updateFilters:
- pathMatch: /spec/.*
allowedOps:
- replace

- name: Create ResourceProvider test-linked-01-binder
kubernetes.core.k8s:
definition:
apiVersion: "{{ poolboy_domain }}/v1"
kind: ResourceProvider
metadata:
name: test-linked-01-binder
namespace: "{{ poolboy_namespace }}"
labels: >-
{{ {
poolboy_domain ~ "/test": "simple"
} }}
spec:
linkedResourceProviders:
- name: test-linked-01-base
parameterValues:
numbervar: "{% raw %}{{ (numbervar * 10) | int }}{% endraw %}"
stringvar: "{% raw %}{{ stringvar | upper }}{% endraw %}"
resourceName: base
override:
apiVersion: "{{ poolboy_domain }}/v1"
kind: ResourceClaimTest
metadata:
name: test-linked-01-{% raw %}{{ guid }}{% endraw %}-binder
namespace: "{{ poolboy_test_namespace }}"
parameters:
- name: stringvar
allowUpdate: true
required: true
validation:
openAPIV3Schema:
type: string
default: one
enum:
- one
- two
- three
- name: numbervar
allowUpdate: true
validation:
openAPIV3Schema:
type: integer
default: 0
minimum: 0
resourceName: binder
template:
definition:
spec:
numbervalue: "{% raw %}{{ numbervar | int }}{% endraw %}"
stringvalue: "{% raw %}{{ stringvar }}{% endraw %}"
enable: true
updateFilters:
- pathMatch: /spec/.*
allowedOps:
- replace

- name: Create ResourceClaim test-linked-01-a
kubernetes.core.k8s:
definition:
apiVersion: "{{ poolboy_domain }}/v1"
kind: ResourceClaim
metadata:
name: test-linked-01-a
namespace: "{{ poolboy_test_namespace }}"
labels: >-
{{ {
poolboy_domain ~ "/test": "simple"
} }}
spec:
provider:
name: test-linked-01-binder
parameterValues:
stringvar: one
numbervar: 1

- name: Verify handling of ResourceClaim test-linked-01-a
kubernetes.core.k8s_info:
api_version: "{{ poolboy_domain }}/v1"
kind: ResourceClaim
name: test-linked-01-a
namespace: "{{ poolboy_test_namespace }}"
register: r_get_resource_claim
vars:
__resource_claim: "{{ r_get_resource_claim.resources[0] }}"
failed_when: >-
__resource_claim.status.resources | length != 2 or
__resource_claim.status.resources[0].name != 'base' or
__resource_claim.status.resources[0].provider.name != 'test-linked-01-base' or
__resource_claim.status.resources[0].state is undefined or
__resource_claim.status.resources[1].name != 'binder' or
__resource_claim.status.resources[1].provider.name != 'test-linked-01-binder' or
__resource_claim.status.resources[1].state is undefined
until: r_get_resource_claim is success
delay: 1
retries: 10

- name: Save facts from for ResourceClaim test-linked-01-a
vars:
__name: >-
{{ r_get_resource_claim.resources[0].status.resourceHandle.name }}
set_fact:
resource_claim_test_linked_01_a_resource_handle_name: "{{ __name }}"
resource_claim_test_linked_01_a_base_resource_name: test-linked-01-{{ __name[5:] }}-base
resource_claim_test_linked_01_a_binder_resource_name: test-linked-01-{{ __name[5:] }}-binder

- name: Verify state of ResourceClaim test-linked-01-a binder
vars:
__state: "{{ r_get_resource_claim.resources[0] }}"
assert:
that:
- __state.status.resources[0].state.metadata.name == resource_claim_test_linked_01_a_base_resource_name
- __state.status.resources[1].state.metadata.name == resource_claim_test_linked_01_a_binder_resource_name

- name: Verify creation of ResourceClaimTest test-linked-01-a-base
kubernetes.core.k8s_info:
api_version: "{{ poolboy_domain }}/v1"
kind: ResourceClaimTest
name: "{{ resource_claim_test_linked_01_a_base_resource_name }}"
namespace: "{{ poolboy_test_namespace }}"
register: r_get_resource_claim_test
failed_when: r_get_resource_claim_test.resources | length != 1
until: r_get_resource_claim_test is success
delay: 1
retries: 10

- name: Verify state of ResourceClaimTest for test-linked-01-a-base
vars:
__state: "{{ r_get_resource_claim_test.resources[0] }}"
assert:
that:
- __state.spec.numbervalue | int == 10
- __state.spec.stringvalue == 'ONE'

- name: Verify creation of ResourceClaimTest test-linked-01-a-binder
kubernetes.core.k8s_info:
api_version: "{{ poolboy_domain }}/v1"
kind: ResourceClaimTest
name: "{{ resource_claim_test_linked_01_a_binder_resource_name }}"
namespace: "{{ poolboy_test_namespace }}"
register: r_get_resource_claim_test
failed_when: r_get_resource_claim_test.resources | length != 1
until: r_get_resource_claim_test is success
delay: 1
retries: 10

- name: Verify state of ResourceClaimTest for test-linked-01-a-binder
vars:
__state: "{{ r_get_resource_claim_test.resources[0] }}"
assert:
that:
- __state.spec.numbervalue | int == 1
- __state.spec.stringvalue == 'one'

- name: Update parameters of ResourceClaim test-linked-01-a
kubernetes.core.k8s:
api_version: "{{ poolboy_domain }}/v1"
kind: ResourceClaim
name: test-linked-01-a
namespace: "{{ poolboy_test_namespace }}"
definition:
spec:
provider:
parameterValues:
stringvar: two
numbervar: 2

- name: Verify update of ResourceClaimTest test-linked-01-a-base
kubernetes.core.k8s_info:
api_version: "{{ poolboy_domain }}/v1"
kind: ResourceClaimTest
name: "{{ resource_claim_test_linked_01_a_base_resource_name }}"
namespace: "{{ poolboy_test_namespace }}"
register: r_get_resource_claim_test
failed_when: >-
r_get_resource_claim_test.resources | length != 1 or
r_get_resource_claim_test.resources[0].spec.stringvalue != 'TWO' or
r_get_resource_claim_test.resources[0].spec.numbervalue != 20
until: r_get_resource_claim_test is success
delay: 1
retries: 10

- name: Verify update of ResourceClaimTest test-linked-01-a-binder
kubernetes.core.k8s_info:
api_version: "{{ poolboy_domain }}/v1"
kind: ResourceClaimTest
name: "{{ resource_claim_test_linked_01_a_binder_resource_name }}"
namespace: "{{ poolboy_test_namespace }}"
register: r_get_resource_claim_test
failed_when: >-
r_get_resource_claim_test.resources | length != 1 or
r_get_resource_claim_test.resources[0].spec.stringvalue != 'two' or
r_get_resource_claim_test.resources[0].spec.numbervalue != 2
until: r_get_resource_claim_test is success
delay: 1
retries: 10

- name: Delete ResourceClaim test-linked-01-a
kubernetes.core.k8s:
api_version: "{{ poolboy_domain }}/v1"
kind: ResourceClaim
name: test-linked-01-a
namespace: "{{ poolboy_test_namespace }}"
state: absent

- name: Verify delete of ResourceClaim test-linked-01-a
kubernetes.core.k8s_info:
api_version: "{{ poolboy_domain }}/v1"
kind: ResourceClaim
name: test-linked-01-a
namespace: "{{ poolboy_test_namespace }}"
register: r_get_resource_claim
failed_when: r_get_resource_claim.resources | length != 0
until: r_get_resource_claim is success
retries: 5
delay: 1

- name: Verify delete of ResourceHandle for test-linked-01-a
kubernetes.core.k8s_info:
api_version: "{{ poolboy_domain }}/v1"
kind: ResourceHandle
name: "{{ resource_claim_test_linked_01_a_resource_handle_name }}"
namespace: "{{ poolboy_namespace }}"
register: r_get_resource_handle
failed_when: r_get_resource_handle.resources | length != 0
until: r_get_resource_handle is success
retries: 5
delay: 1

- name: Verify delete of ResourceClaimTest test-linked-01-a-base
kubernetes.core.k8s_info:
api_version: "{{ poolboy_domain }}/v1"
kind: ResourceClaimTest
name: "{{ resource_claim_test_linked_01_a_base_resource_name }}"
namespace: "{{ poolboy_test_namespace }}"
register: r_get_resource_claim_test
failed_when: r_get_resource_claim_test.resources | length != 0
until: r_get_resource_claim_test is success
delay: 1
retries: 10

- name: Verify delete of ResourceClaimTest test-linked-01-a-binder
kubernetes.core.k8s_info:
api_version: "{{ poolboy_domain }}/v1"
kind: ResourceClaimTest
name: "{{ resource_claim_test_linked_01_a_binder_resource_name }}"
namespace: "{{ poolboy_test_namespace }}"
register: r_get_resource_claim_test
failed_when: r_get_resource_claim_test.resources | length != 0
until: r_get_resource_claim_test is success
delay: 1
retries: 10
...
Loading
Loading