Skip to content

Commit 38955af

Browse files
authored
feat: implement proxy for request visibility and extend reconcile status (#34)
* feat: proxy keycloak requests and extend status information * doc: update readme * refactor: ignore returns * fix: bump chart * feat: add trace span attribute for realm and namespace * build: tidy * fix: set USER env
1 parent c333156 commit 38955af

17 files changed

+424
-882
lines changed

Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,6 @@ COPY --from=builder /workspace/manager .
2525
USER 65532:65532
2626
COPY assets /assets
2727
ENV ASSETS_PATH="/assets"
28+
ENV USER k8skeycloak-controller
2829

2930
ENTRYPOINT ["/manager"]

Dockerfile.release

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@ COPY manager manager
66
USER 65532:65532
77
COPY assets /assets
88
ENV ASSETS_PATH="/assets"
9+
ENV USER k8skeycloak-controller
910

1011
ENTRYPOINT ["/manager"]

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,9 @@ Available env variables:
122122
| `NAMESPACES` | The controller listens by default for all namespaces. This may be limited to a comma delimted list of dedicated namespaces. | `` |
123123
| `CONCURRENT` | The number of concurrent reconcile workers. | `4` |
124124
| `ASSETS_PATH` | The directory where to look for keycloak-config-cli | `/assets` |
125+
| `OTEL_EXPORTER_OTLP_ENDPOINT` | The gRPC opentelemtry-collector endpoint uri | `` |
126+
127+
**Note:** The proxy implements opentelemetry tracing, see [further possible env](https://opentelemetry.io/docs/reference/specification/sdk-environment-variables/) variables to configure it.
125128

126129
## Dealing with managed realms
127130

api/v1beta1/keycloakclient_types.go

Lines changed: 2 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@ type KeycloakClient struct {
1111
metav1.TypeMeta `json:",inline"`
1212
metav1.ObjectMeta `json:"metadata,omitempty"`
1313

14-
Spec KeycloakClientSpec `json:"spec,omitempty"`
15-
Status KeycloakClientStatus `json:"status,omitempty"`
14+
Spec KeycloakClientSpec `json:"spec,omitempty"`
1615
}
1716

1817
// KeycloakClientList contains a list of KeycloakClient.
@@ -35,21 +34,7 @@ type KeycloakClientSpec struct {
3534
RealmSelector *metav1.LabelSelector `json:"realmSelector"`
3635
// Keycloak Client REST object.
3736
// +kubebuilder:validation:Required
38-
Client *KeycloakAPIClient `json:"client"`
39-
// Client Roles
40-
// +optional
41-
// +listType=map
42-
// +listMapKey=name
43-
Roles []RoleRepresentation `json:"roles,omitempty"`
44-
// Scope Mappings
45-
// +optional
46-
ScopeMappings *MappingsRepresentation `json:"scopeMappings,omitempty"`
47-
// Service account realm roles for this client.
48-
// +optional
49-
ServiceAccountRealmRoles []string `json:"serviceAccountRealmRoles,omitempty"`
50-
// Service account client roles for this client.
51-
// +optional
52-
ServiceAccountClientRoles map[string][]string `json:"serviceAccountClientRoles,omitempty"`
37+
Client KeycloakAPIClient `json:"client"`
5338
}
5439

5540
// https://www.keycloak.org/docs-api/11.0/rest-api/index.html#_mappingsrepresentation
@@ -372,18 +357,3 @@ type KeycloakScope struct {
372357
// +optional
373358
Resources []KeycloakResource `json:"resources,omitempty"`
374359
}
375-
376-
// KeycloakClientStatus defines the observed state of KeycloakClient
377-
// +k8s:openapi-gen=true
378-
type KeycloakClientStatus struct {
379-
// Conditions holds the conditions for the KeycloakRealm.
380-
// +optional
381-
Conditions []metav1.Condition `json:"conditions,omitempty"`
382-
383-
// ObservedGeneration is the last generation reconciled by the controller
384-
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
385-
386-
// LastExececutionOutput is the stdout dump of keycloak-config-cli
387-
// +optional
388-
LastExececutionOutput string `json:"lastExececutionOutput,omitempty"`
389-
}

api/v1beta1/keycloakrealm_types.go

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ func init() {
5252
// KeycloakRealmSpec defines the desired state of KeycloakRealm
5353
type KeycloakRealmSpec struct {
5454
// +required
55-
Address string `json:"address"`
55+
Address string `json:"address,omitempty"`
5656

5757
// Contains a credentials set of a user with enough permission to manage keycloak
5858
// +optional
@@ -103,9 +103,35 @@ type KeycloakRealmStatus struct {
103103
// ObservedGeneration is the last generation reconciled by the controller
104104
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
105105

106-
// LastExececutionOutput is the stdout dump of keycloak-config-cli
106+
// LastExececutionOutput failed requests
107107
// +optional
108108
LastExececutionOutput string `json:"lastExececutionOutput,omitempty"`
109+
110+
// LastReconcileDuration is the total time the reconcile of the realm took
111+
LastReconcileDuration metav1.Duration `json:"lastReconcileDuration,omitempty"`
112+
113+
// LastFailedRequests failed requests
114+
// +optional
115+
LastFailedRequests []RequestStatus `json:"lastFailedRequests,omitempty"`
116+
117+
// SubResourceCatalog holds references to all sub resources including KeycloakClient and KeycloakUser associated with this realm
118+
SubResourceCatalog []ResourceReference `json:"subResourceCatalog,omitempty"`
119+
}
120+
121+
// ResourceReference metadata to lookup another resource
122+
type ResourceReference struct {
123+
Kind string `json:"kind,omitempty"`
124+
Name string `json:"name,omitempty"`
125+
APIVersion string `json:"apiVersion,omitempty"`
126+
}
127+
128+
// RequestStatus knows details about a keycloak API request
129+
type RequestStatus struct {
130+
URL string `json:"url,omitempty"`
131+
Verb string `json:"verb,omitempty"`
132+
ResponseCode int `json:"responseCode,omitempty"`
133+
ResponseBody string `json:"responseBody,omitempty"`
134+
Error string `json:"error,omitempty"`
109135
}
110136

111137
// KeycloakRealmNotReady
@@ -146,16 +172,16 @@ type KeycloakAPIRealm struct {
146172
PasswordPolicy string `json:"passwordPolicy,omitempty"`
147173
// A set of Keycloak Users.
148174
// +optional
149-
Users []*KeycloakAPIUser `json:"users,omitempty"`
175+
Users []KeycloakAPIUser `json:"users,omitempty"`
150176
// A set of Keycloak Clients.
151177
// +optional
152-
Clients []*KeycloakAPIClient `json:"clients,omitempty"`
178+
Clients []KeycloakAPIClient `json:"clients,omitempty"`
153179
// A set of Identity Providers.
154180
// +optional
155-
IdentityProviders []*KeycloakIdentityProvider `json:"identityProviders,omitempty"`
181+
IdentityProviders []KeycloakIdentityProvider `json:"identityProviders,omitempty"`
156182
// A set of Identity Provider Mappers.
157183
// +optional
158-
IdentityProviderMappers []*KeycloakIdentityProviderMapper `json:"identityProviderMappers,omitempty"`
184+
IdentityProviderMappers []KeycloakIdentityProviderMapper `json:"identityProviderMappers,omitempty"`
159185
// A set of Event Listeners.
160186
// +optional
161187
EventsListeners []string `json:"eventsListeners,omitempty"`

api/v1beta1/keycloakuser_types.go

Lines changed: 2 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@ type KeycloakUser struct {
1414
metav1.TypeMeta `json:",inline"`
1515
metav1.ObjectMeta `json:"metadata,omitempty"`
1616

17-
Spec KeycloakUserSpec `json:"spec,omitempty"`
18-
Status KeycloakUserStatus `json:"status,omitempty"`
17+
Spec KeycloakUserSpec `json:"spec,omitempty"`
1918
}
2019

2120
// +kubebuilder:object:root=true
@@ -31,37 +30,6 @@ func init() {
3130
SchemeBuilder.Register(&KeycloakUser{}, &KeycloakUserList{})
3231
}
3332

34-
// KeycloakUserStatus defines the observed state of KeycloakUser
35-
type KeycloakUserStatus struct {
36-
// Conditions holds the conditions for the KeycloakUser.
37-
// +optional
38-
Conditions []metav1.Condition `json:"conditions,omitempty"`
39-
40-
// ObservedGeneration is the last generation reconciled by the controller
41-
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
42-
43-
// LastExececutionOutput is the stdout dump of keycloak-config-cli
44-
// +optional
45-
LastExececutionOutput string `json:"lastExececutionOutput,omitempty"`
46-
}
47-
48-
// KeycloakUserNotReady
49-
func KeycloakUserNotReady(realm KeycloakUser, reason, message string) KeycloakUser {
50-
setResourceCondition(&realm, ReadyCondition, metav1.ConditionFalse, reason, message)
51-
return realm
52-
}
53-
54-
// KeycloakUserReady
55-
func KeycloakUserReady(realm KeycloakUser, reason, message string) KeycloakUser {
56-
setResourceCondition(&realm, ReadyCondition, metav1.ConditionTrue, reason, message)
57-
return realm
58-
}
59-
60-
// GetStatusConditions returns a pointer to the Status.Conditions slice
61-
func (in *KeycloakUser) GetStatusConditions() *[]metav1.Condition {
62-
return &in.Status.Conditions
63-
}
64-
6533
// KeycloakUserSpec defines the desired state of KeycloakUser.
6634
// +k8s:openapi-gen=true
6735
type KeycloakUserSpec struct {
@@ -120,6 +88,7 @@ type KeycloakAPIUser struct {
12088

12189
DisableableCredentialTypes []string `json:"disableableCredentialTypes,omitempty"`
12290
ServiceAccountClientId string `json:"serviceAccountClientId,omitempty"`
91+
TOTP bool `json:"totp,omitempty"`
12392
}
12493

12594
type KeycloakCredential struct {

0 commit comments

Comments
 (0)