Skip to content

Commit 954ef3c

Browse files
committed
ApiObjectController: fix protocol mappers
protocol mappers fail to update when the request does not contain the id. Rustcloak now adds the ID to requests.
1 parent dd1e4c9 commit 954ef3c

7 files changed

Lines changed: 45 additions & 0 deletions

File tree

charts/rustcloak-operator/crds/clusterkeycloakapiobjects.rustcloak.k8s.eboland.de.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,10 @@ spec:
194194
type: object
195195
payload:
196196
type: string
197+
primaryKey:
198+
description: The name of the primary key field in the payload (e.g. "id", "name", "alias"). Used to inject the resource ID extracted from the stored resource path into PUT requests, working around Keycloak versions that don't populate the model ID from the URL path parameter.
199+
nullable: true
200+
type: string
197201
required:
198202
- endpoint
199203
- immutablePayload

charts/rustcloak-operator/crds/keycloakapiobjects.rustcloak.k8s.eboland.de.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,10 @@ spec:
194194
type: object
195195
payload:
196196
type: string
197+
primaryKey:
198+
description: The name of the primary key field in the payload (e.g. "id", "name", "alias"). Used to inject the resource ID extracted from the stored resource path into PUT requests, working around Keycloak versions that don't populate the model ID from the URL path parameter.
199+
nullable: true
200+
type: string
197201
required:
198202
- endpoint
199203
- immutablePayload

docs/src/crds/clusterkeycloakapiobject.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ Custom Resource for Keycloak API requests. The user should not use this resource
3434
|[spec.options.patchFrom[].value](#specoptionspatchfromvalue)|string||
3535
|[spec.options.patchFrom[].value_as](#specoptionspatchfromvalueas)|string||
3636
|[spec.payload](#specpayload)|string||
37+
|[spec.primaryKey](#specprimarykey)|string||
3738
|[status](#status)|object||
3839
|[status.conditions[]](#statusconditions)|object||
3940
|[status.conditions[].lastTransitionTime](#statusconditionslasttransitiontime)|string||
@@ -64,6 +65,7 @@ Type: object
6465
|[immutablePayload](#specimmutablepayload)|string||
6566
|[options](#specoptions)|object||
6667
|[payload](#specpayload)|string||
68+
|[primaryKey](#specprimarykey)|string||
6769

6870
defines an API request to the Keycloak Admin API.
6971

@@ -365,6 +367,14 @@ Type: string
365367

366368
---
367369

370+
### spec.primaryKey
371+
372+
Type: string
373+
374+
The name of the primary key field in the payload (e.g. "id", "name", "alias"). Used to inject the resource ID extracted from the stored resource path into PUT requests, working around Keycloak versions that don't populate the model ID from the URL path parameter.
375+
376+
---
377+
368378
### status
369379

370380
Type: object

docs/src/crds/keycloakapiobject.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ Custom Resource for Keycloak API requests. The user should not use this resource
3434
|[spec.options.patchFrom[].value](#specoptionspatchfromvalue)|string||
3535
|[spec.options.patchFrom[].value_as](#specoptionspatchfromvalueas)|string||
3636
|[spec.payload](#specpayload)|string||
37+
|[spec.primaryKey](#specprimarykey)|string||
3738
|[status](#status)|object||
3839
|[status.conditions[]](#statusconditions)|object||
3940
|[status.conditions[].lastTransitionTime](#statusconditionslasttransitiontime)|string||
@@ -64,6 +65,7 @@ Type: object
6465
|[immutablePayload](#specimmutablepayload)|string||
6566
|[options](#specoptions)|object||
6667
|[payload](#specpayload)|string||
68+
|[primaryKey](#specprimarykey)|string||
6769

6870
defines an API request to the Keycloak Admin API.
6971

@@ -365,6 +367,14 @@ Type: string
365367

366368
---
367369

370+
### spec.primaryKey
371+
372+
Type: string
373+
374+
The name of the primary key field in the payload (e.g. "id", "name", "alias"). Used to inject the resource ID extracted from the stored resource path into PUT requests, working around Keycloak versions that don't populate the model ID from the URL path parameter.
375+
376+
---
377+
368378
### status
369379

370380
Type: object

rustcloak-crd/src/crd/api_object.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@ both_scopes! {
3030
pub endpoint: KeycloakApiEndpoint,
3131
pub immutable_payload: ImmutableString,
3232
pub payload: String,
33+
/// The name of the primary key field in the payload (e.g. "id",
34+
/// "name", "alias"). Used to inject the resource ID extracted
35+
/// from the stored resource path into PUT requests, working
36+
/// around Keycloak versions that don't populate the model ID
37+
/// from the URL path parameter.
38+
#[serde(default, skip_serializing_if = "Option::is_none")]
39+
pub primary_key: Option<String>,
3340
}
3441
}
3542
}

rustcloak-operator/src/controller/api_object_controller.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,15 @@ where
253253
if let Some(endpoint) =
254254
resource.status().as_ref().and_then(|s| s.endpoint.as_ref())
255255
{
256+
// Inject the resource ID into the payload before PUT. Some
257+
// Keycloak versions do not populate the model ID from the URL
258+
// path parameter during updates, causing a NullPointerException.
259+
if let Some(primary_key) = &spec.primary_key
260+
&& let Some(id) = endpoint.resource_path.rsplit('/').next()
261+
&& let Some(obj) = payload.as_object_mut() {
262+
obj.entry(primary_key.clone())
263+
.or_insert_with(|| Value::String(id.to_string()));
264+
}
256265
match keycloak.put(&endpoint.resource_path, &payload).await {
257266
Ok(_) => {
258267
success = true;

rustcloak-operator/src/controller/representation_controller.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ where
222222
options: resource.inner_spec().options().cloned(),
223223
immutable_payload,
224224
payload,
225+
primary_key: Some(primary_key.to_string()),
225226
},
226227
);
227228

0 commit comments

Comments
 (0)