Skip to content

Commit bbd6540

Browse files
committed
feat: Add support for list of attributes with the same key
Signed-off-by: Douglass Kirkley <doug.kirkley@gmail.com>
1 parent c22c55a commit bbd6540

22 files changed

+300
-71
lines changed

api/common/attributes.go

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package common
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
)
7+
8+
// UserAttributes is a map of user attributes. It supports both string and []string values for attributes.
9+
// +kubebuilder:validation:Type=object
10+
type UserAttributes map[string][]string
11+
12+
// UnmarshalJSON implements json.Unmarshaler.
13+
func (a *UserAttributes) UnmarshalJSON(data []byte) error {
14+
var raw map[string]interface{}
15+
if err := json.Unmarshal(data, &raw); err != nil {
16+
return err
17+
}
18+
19+
if *a == nil {
20+
*a = make(UserAttributes)
21+
}
22+
23+
result := *a
24+
25+
for k, v := range raw {
26+
switch value := v.(type) {
27+
case string:
28+
result[k] = []string{value}
29+
case []interface{}:
30+
var strSlice []string
31+
32+
for _, item := range value {
33+
if str, ok := item.(string); ok {
34+
strSlice = append(strSlice, str)
35+
} else {
36+
return fmt.Errorf("attribute '%s' contains a non-string value in the list", k)
37+
}
38+
}
39+
40+
result[k] = strSlice
41+
default:
42+
return fmt.Errorf("unsupported type for attribute '%s': %T", k, v)
43+
}
44+
}
45+
46+
return nil
47+
}
48+
49+
// MarshalJSON implements json.Marshaler.
50+
func (a UserAttributes) MarshalJSON() ([]byte, error) {
51+
result := make(map[string]interface{})
52+
53+
for k, v := range a {
54+
if len(v) == 1 {
55+
result[k] = v[0]
56+
} else {
57+
result[k] = v
58+
}
59+
}
60+
61+
return json.Marshal(result)
62+
}

api/common/zz_generated.deepcopy.go

Lines changed: 30 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/v1/keycloakclient_types.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ type ServiceAccount struct {
209209
// Attributes is a map of service account attributes.
210210
// +nullable
211211
// +optional
212-
Attributes map[string]string `json:"attributes,omitempty"`
212+
Attributes common.UserAttributes `json:"attributes,omitempty"`
213213

214214
// Groups is a list of groups assigned to service account
215215
// +nullable

api/v1/keycloakrealmuser_types.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ type KeycloakRealmUserSpec struct {
5858
// Attributes is a map of user attributes.
5959
// +nullable
6060
// +optional
61-
Attributes map[string]string `json:"attributes,omitempty"`
61+
Attributes common.UserAttributes `json:"attributes,omitempty"`
6262

6363
// ReconciliationStrategy is a strategy for reconciliation. Possible values: full, create-only.
6464
// Default value: full. If set to create-only, user will be created only if it does not exist. If user exists, it will not be updated.

api/v1/zz_generated.deepcopy.go

Lines changed: 22 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/crd/bases/v1.edp.epam.com_keycloakclients.yaml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -587,8 +587,6 @@ spec:
587587
nullable: true
588588
properties:
589589
attributes:
590-
additionalProperties:
591-
type: string
592590
description: Attributes is a map of service account attributes.
593591
nullable: true
594592
type: object

config/crd/bases/v1.edp.epam.com_keycloakrealmusers.yaml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,6 @@ spec:
4545
description: KeycloakRealmUserSpec defines the desired state of KeycloakRealmUser.
4646
properties:
4747
attributes:
48-
additionalProperties:
49-
type: string
5048
description: Attributes is a map of user attributes.
5149
nullable: true
5250
type: object

deploy-templates/crds/v1.edp.epam.com_keycloakclients.yaml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -587,8 +587,6 @@ spec:
587587
nullable: true
588588
properties:
589589
attributes:
590-
additionalProperties:
591-
type: string
592590
description: Attributes is a map of service account attributes.
593591
nullable: true
594592
type: object

deploy-templates/crds/v1.edp.epam.com_keycloakrealmusers.yaml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,6 @@ spec:
4545
description: KeycloakRealmUserSpec defines the desired state of KeycloakRealmUser.
4646
properties:
4747
attributes:
48-
additionalProperties:
49-
type: string
5048
description: Attributes is a map of user attributes.
5149
nullable: true
5250
type: object

docs/api.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3342,7 +3342,7 @@ ServiceAccount is a service account configuration.
33423342
</thead>
33433343
<tbody><tr>
33443344
<td><b>attributes</b></td>
3345-
<td>map[string]string</td>
3345+
<td>object</td>
33463346
<td>
33473347
Attributes is a map of service account attributes.<br/>
33483348
</td>
@@ -6367,7 +6367,7 @@ KeycloakRealmUserSpec defines the desired state of KeycloakRealmUser.
63676367
<td>true</td>
63686368
</tr><tr>
63696369
<td><b>attributes</b></td>
6370-
<td>map[string]string</td>
6370+
<td>object</td>
63716371
<td>
63726372
Attributes is a map of user attributes.<br/>
63736373
</td>

0 commit comments

Comments
 (0)