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 waitingFor indicator #109

Merged
merged 1 commit into from
Jun 13, 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
8 changes: 8 additions & 0 deletions helm/crds/resourceclaims.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,14 @@ spec:
validationError:
description: Error message from resource provider.
type: string
waitingFor:
description: >-
Indication indicating that resource creation is blocked waiting on a condition.
enum:
- ResourceClaim
- Linked ResourceProvider
- Resource Definition
type: string
summary:
description: >-
Status summary from current resources state, generated from ResourceProvider configuration.
Expand Down
8 changes: 8 additions & 0 deletions helm/crds/resourcehandles.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,14 @@ spec:
claim's template is used to manage the handle template.
type: object
x-kubernetes-preserve-unknown-fields: true
waitingFor:
description: >-
Indication indicating that resource creation is blocked waiting on a condition.
enum:
- ResourceClaim
- Linked ResourceProvider
- Resource Definition
type: string
vars:
description: >-
Variables to use when evaluating validation checks and templates.
Expand Down
8 changes: 8 additions & 0 deletions helm/templates/crds/resourceclaims.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,14 @@ spec:
validationError:
description: Error message from resource provider.
type: string
waitingFor:
description: >-
Indication indicating that resource creation is blocked waiting on a condition.
enum:
- ResourceClaim
- Linked ResourceProvider
- Resource Definition
type: string
summary:
description: >-
Status summary from current resources state, generated from ResourceProvider configuration.
Expand Down
8 changes: 8 additions & 0 deletions helm/templates/crds/resourcehandles.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,14 @@ spec:
claim's template is used to manage the handle template.
type: object
x-kubernetes-preserve-unknown-fields: true
waitingFor:
description: >-
Indication indicating that resource creation is blocked waiting on a condition.
enum:
- ResourceClaim
- Linked ResourceProvider
- Resource Definition
type: string
vars:
description: >-
Variables to use when evaluating validation checks and templates.
Expand Down
13 changes: 13 additions & 0 deletions operator/resourceclaim.py
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,19 @@ async def update_status_from_handle(self,
"path": "/status/lifespan/relativeMaximum",
})

for index, resource in enumerate(resource_handle.spec['resources']):
if 'waitingFor' in resource:
patch.append({
"op": "add",
"path": f"/status/resources/{index}/waitingFor",
"value": resource['waitingFor'],
})
elif 'waitingFor' in self.status_resources[index]:
patch.append({
"op": "remove",
"path": f"/status/resources/{index}/waitingFor",
})

if patch:
await self.json_patch_status(patch)

Expand Down
27 changes: 26 additions & 1 deletion operator/resourcehandle.py
Original file line number Diff line number Diff line change
Expand Up @@ -841,7 +841,6 @@ async def manage(self, logger: kopf.ObjectLogger) -> None:
if self.is_bound:
try:
resource_claim = await self.get_resource_claim()
await resource_claim.update_status_from_handle(logger=logger, resource_handle=self)
except kubernetes_asyncio.client.exceptions.ApiException as e:
if e.status == 404:
logger.info(
Expand All @@ -868,6 +867,12 @@ async def manage(self, logger: kopf.ObjectLogger) -> None:
resource_state = resource_states[resource_index]

if resource_provider.resource_requires_claim and not resource_claim:
if 'ResourceClaim' != resource.get('waitingFor'):
patch.append({
"op": "add",
"path": f"/spec/resources/{resource_index}/waitingFor",
"value": "ResourceClaim",
})
continue

vars_ = deepcopy(self.vars)
Expand Down Expand Up @@ -907,6 +912,12 @@ async def manage(self, logger: kopf.ObjectLogger) -> None:
)

if wait_for_linked_provider:
if 'Linked ResourceProvider' != resource.get('waitingFor'):
patch.append({
"op": "add",
"path": f"/spec/resources/{resource_index}/waitingFor",
"value": "Linked ResourceProvider",
})
continue

resource_definition = await resource_provider.resource_definition_from_template(
Expand All @@ -918,6 +929,12 @@ async def manage(self, logger: kopf.ObjectLogger) -> None:
vars_ = vars_,
)
if not resource_definition:
if 'Resource Definition' != resource.get('waitingFor'):
patch.append({
"op": "add",
"path": f"/spec/resources/{resource_index}/waitingFor",
"value": "Resource Definition",
})
continue

resource_api_version = resource_definition['apiVersion']
Expand All @@ -939,6 +956,11 @@ async def manage(self, logger: kopf.ObjectLogger) -> None:
"path": f"/spec/resources/{resource_index}/reference",
"value": reference,
})
if 'waitingFor' in resource:
patch.append({
"op": "remove",
"path": f"/spec/resources/{resource_index}/waitingFor",
})
try:
resource_states[resource_index] = resource_state = await poolboy_k8s.get_object(
api_version = resource_api_version,
Expand Down Expand Up @@ -1004,6 +1026,9 @@ async def manage(self, logger: kopf.ObjectLogger) -> None:
)
self.refresh_from_definition(definition)

if resource_claim:
await resource_claim.update_status_from_handle(logger=logger, resource_handle=self)

for resource_definition in resources_to_create:
changes = await poolboy_k8s.create_object(resource_definition)
if changes:
Expand Down
6 changes: 4 additions & 2 deletions operator/resourceprovider.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,9 @@ def create_disabled(self) -> bool:

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

@property
def lifespan_maximum(self) -> Optional[str]:
Expand Down Expand Up @@ -483,7 +485,7 @@ def processed_template(self,
) -> Mapping:
resource_handle_vars = resource_handle.vars if resource_handle else {}
return recursive_process_template_strings(
self.spec['template'].get('definition', {}),
self.spec.get('template', {}).get('definition', {}),
variables = {
**self.vars,
**resource_handle_vars,
Expand Down
2 changes: 2 additions & 0 deletions test/roles/poolboy_test_simple/tasks/setup.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
apiVersion: v1
kind: Namespace
metadata:
annotations:
openshift.io/requester: test-user
name: "{{ poolboy_test_namespace }}"

- name: Create poolboy-test ClusterRole and ClusteRoleBinding
Expand Down
88 changes: 71 additions & 17 deletions test/roles/poolboy_test_simple/tasks/test-linked-01.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,24 @@
linkedResourceProviders:
- name: test-linked-01-base
parameterValues:
numbervar: "{% raw %}{{ (numbervar * 10) | int }}{% endraw %}"
stringvar: "{% raw %}{{ stringvar | upper }}{% endraw %}"
numbervar: "{% raw %}{{ numbervar | int }}{% endraw %}"
stringvar: "{% raw %}{{ stringvar }}{% endraw %}"
resourceName: base
templateVars:
- from: /spec/numbervalue
name: base_numbervalue
- from: /spec/stringvalue
name: base_stringvalue
waitFor: base_numbervalue | default(0) | int > 0
override:
apiVersion: "{{ poolboy_domain }}/v1"
kind: ResourceClaimTest
metadata:
name: test-linked-01-{% raw %}{{ guid }}{% endraw %}-binder
namespace: "{{ poolboy_test_namespace }}"
spec:
numbervalue: "{% raw %}{{ (base_numbervalue | int * 10) | int }}{% endraw %}"
stringvalue: "{% raw %}{{ base_stringvalue | upper }}{% endraw %}"
parameters:
- name: stringvar
allowUpdate: true
Expand All @@ -95,10 +104,6 @@
minimum: 0
resourceName: binder
template:
definition:
spec:
numbervalue: "{% raw %}{{ numbervar | int }}{% endraw %}"
stringvalue: "{% raw %}{{ stringvar }}{% endraw %}"
enable: true
updateFilters:
- pathMatch: /spec/.*
Expand All @@ -122,7 +127,7 @@
name: test-linked-01-binder
parameterValues:
stringvar: one
numbervar: 1
numbervar: 0

- name: Verify handling of ResourceClaim test-linked-01-a
kubernetes.core.k8s_info:
Expand All @@ -140,7 +145,7 @@
__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
__resource_claim.status.resources[1].waitingFor != 'Linked ResourceProvider'
until: r_get_resource_claim is success
delay: 1
retries: 10
Expand All @@ -160,7 +165,21 @@
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: Get 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

- name: Verify state of ResourceHandle for test-linked-01-a
vars:
__state: "{{ r_get_resource_handle.resources[0] }}"
assert:
that:
- __state.spec.resources[1].waitingFor == 'Linked ResourceProvider'

- name: Verify creation of ResourceClaimTest test-linked-01-a-base
kubernetes.core.k8s_info:
Expand All @@ -179,8 +198,43 @@
__state: "{{ r_get_resource_claim_test.resources[0] }}"
assert:
that:
- __state.spec.numbervalue | int == 10
- __state.spec.stringvalue == 'ONE'
- __state.spec.numbervalue | int == 0
- __state.spec.stringvalue == 'one'

- name: Update ResourceClaim to unblock creation
kubernetes.core.k8s:
api_version: "{{ poolboy_domain }}/v1"
kind: ResourceClaim
name: test-linked-01-a
namespace: "{{ poolboy_test_namespace }}"
definition:
spec:
provider:
parameterValues:
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[1].state is undefined or
__resource_claim.status.resources[1].waitingFor is defined
until: r_get_resource_claim is success
delay: 1
retries: 10

- name: Verify state of ResourceClaim test-linked-01-a binder
vars:
__state: "{{ r_get_resource_claim.resources[0] }}"
assert:
that:
- __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-binder
kubernetes.core.k8s_info:
Expand All @@ -199,8 +253,8 @@
__state: "{{ r_get_resource_claim_test.resources[0] }}"
assert:
that:
- __state.spec.numbervalue | int == 1
- __state.spec.stringvalue == 'one'
- __state.spec.numbervalue | int == 10
- __state.spec.stringvalue == 'ONE'

- name: Update parameters of ResourceClaim test-linked-01-a
kubernetes.core.k8s:
Expand All @@ -224,8 +278,8 @@
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
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
Expand All @@ -239,8 +293,8 @@
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
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
Expand Down
Loading
Loading