Add new properties to CRDs
This commit is contained in:
parent
28381df56e
commit
fc6f1632da
9 changed files with 538 additions and 28 deletions
|
@ -20,22 +20,98 @@ import (
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
|
|
||||||
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
|
|
||||||
|
|
||||||
// KeycloakClientSpec defines the desired state of KeycloakClient
|
// KeycloakClientSpec defines the desired state of KeycloakClient
|
||||||
type KeycloakClientSpec struct {
|
type KeycloakClientSpec struct {
|
||||||
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
|
// +kubebuilder:validation:Required
|
||||||
// Important: Run "make" to regenerate code after modifying this file
|
// Name of the Realm the client should be created in
|
||||||
|
RealmName string `json:"realmName"`
|
||||||
|
|
||||||
// Foo is an example field of KeycloakClient. Edit KeycloakClient_types.go to remove/update
|
// +kubebuilder:validation:Required
|
||||||
Foo string `json:"foo,omitempty"`
|
// ClientID is the alphanumeric identifier of the client in a realm.
|
||||||
|
ClientID string `json:"clientId"`
|
||||||
|
|
||||||
|
// If the client is enabled and active
|
||||||
|
Enabled *bool `json:"enabled,omitempty"`
|
||||||
|
|
||||||
|
// Displayed Name of the Client
|
||||||
|
Name *string `json:"name,omitempty"`
|
||||||
|
|
||||||
|
// Human Readable description
|
||||||
|
Description *string `json:"description,omitempty"`
|
||||||
|
|
||||||
|
// Protocol, either 'openid-connect' or 'saml'
|
||||||
|
Protocol *string `json:"protocol,omitempty"`
|
||||||
|
|
||||||
|
// How should Clients authenticate to the server? either 'client-secret' or 'client-jwt'.
|
||||||
|
ClientAuthenticatorType *string `json:"clientAuthenticatorType,omitempty"`
|
||||||
|
|
||||||
|
// Are direct access grants enabled for this client or not (OpenID connect).
|
||||||
|
DirectAccessGrantsEnabled *bool `json:"directAccessGrantsEnabled,omitempty"`
|
||||||
|
|
||||||
|
// Is the access type for this client public or not.
|
||||||
|
PublicClient *bool `json:"publicClient,omitempty"`
|
||||||
|
|
||||||
|
// Enable implicit flow for this client or not (OpenID connect).
|
||||||
|
ImplicitFlowEnabled *bool `json:"implicitFlowEnabled,omitempty"`
|
||||||
|
|
||||||
|
// Enable standard flow for this client or not (OpenID connect).
|
||||||
|
StandardFlowEnabled *bool `json:"standardFlowEnabled,omitempty"`
|
||||||
|
|
||||||
|
// Are service accounts enabled for this client or not (OpenID connect).
|
||||||
|
ServiceAccountsEnabled *bool `json:"serviceAccountsEnabled,omitempty"`
|
||||||
|
|
||||||
|
// Used for authentication when registering new clients
|
||||||
|
RegistrationAccessToken *string `json:"registrationAccessToken,omitempty"`
|
||||||
|
|
||||||
|
// Whether or not surrogate auth is required.
|
||||||
|
SurrogateAuthRequired *bool `json:"surrogateAuthRequired,omitempty"`
|
||||||
|
|
||||||
|
// The access type of this client is bearer-only.
|
||||||
|
BearerOnly *bool `json:"bearerOnly,omitempty"`
|
||||||
|
|
||||||
|
// If enabled, users have to consent to client access.
|
||||||
|
ConsentRequired *bool `json:"consentRequired,omitempty"`
|
||||||
|
|
||||||
|
// Which client scopes chould be granted by default, even without
|
||||||
|
// specifying them.
|
||||||
|
DefaultClientScopes *[]string `json:"defaultClientScopes,omitempty"`
|
||||||
|
|
||||||
|
// Which additional scopes can be specified by the client
|
||||||
|
OptionalClientScopes *[]string `json:"optionalClientScopes,omitempty"`
|
||||||
|
|
||||||
|
// Default URL to use when the auth server needs to redirect or link back to the client
|
||||||
|
BaseURL *string `json:"baseUrl,omitempty"`
|
||||||
|
|
||||||
|
// Root URL appended to relative URLs for this client
|
||||||
|
RootURL *string `json:"rootUrl,omitempty"`
|
||||||
|
|
||||||
|
// URL to the admin interface of the client
|
||||||
|
AdminURL *string `json:"adminUrl,omitempty"`
|
||||||
|
|
||||||
|
// URL to the admin interface of the client
|
||||||
|
RedirectURIs *[]string `json:"redirectUris,omitempty"`
|
||||||
|
|
||||||
|
// List of allowed CORS origins
|
||||||
|
WebOrigins *[]string `json:"webOrigins,omitempty"`
|
||||||
|
|
||||||
|
// +kubebuilder:validation:Optional
|
||||||
|
// A client Secret is not always required
|
||||||
|
Secret *KeycloakClientSecret `json:"secret,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// KeycloakClientSecret contains the Secret storing the Client Secret
|
||||||
|
type KeycloakClientSecret struct {
|
||||||
|
// +kubebuilder:validation:Required
|
||||||
|
// Name of the Secret containing the client Secret.
|
||||||
|
Name string `json:"name"`
|
||||||
|
// +kubebuilder:default:=password
|
||||||
|
// Key of the attribute, that holds the value in the Secret.
|
||||||
|
Key string `json:"key,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// KeycloakClientStatus defines the observed state of KeycloakClient
|
// KeycloakClientStatus defines the observed state of KeycloakClient
|
||||||
type KeycloakClientStatus struct {
|
type KeycloakClientStatus struct {
|
||||||
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
|
Available bool `json:"available"`
|
||||||
// Important: Run "make" to regenerate code after modifying this file
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// +kubebuilder:object:root=true
|
// +kubebuilder:object:root=true
|
||||||
|
|
|
@ -22,11 +22,14 @@ import (
|
||||||
|
|
||||||
// KeycloakRealmSpec defines the desired state of KeycloakRealm
|
// KeycloakRealmSpec defines the desired state of KeycloakRealm
|
||||||
type KeycloakRealmSpec struct {
|
type KeycloakRealmSpec struct {
|
||||||
|
// +kubebuilder:validation:Required
|
||||||
// RealmName is the name and public identifier of the Realm
|
// RealmName is the name and public identifier of the Realm
|
||||||
RealmName string `json:"realmName"`
|
RealmName string `json:"realmName"`
|
||||||
|
|
||||||
// Secret containing SMTP configuration
|
// If the realm is enabled and active
|
||||||
SMTPSecretName string `json:"smtpSecretName,omitempty"`
|
Enabled *bool `json:"enabled,omitempty"`
|
||||||
|
|
||||||
|
SMTP *KeycloakRealmSMTP `json:"smtp,omitempty"`
|
||||||
|
|
||||||
// name shown to the user
|
// name shown to the user
|
||||||
DisplayName *string `json:"displayName,omitempty"`
|
DisplayName *string `json:"displayName,omitempty"`
|
||||||
|
@ -54,10 +57,69 @@ type KeycloakRealmSpec struct {
|
||||||
RememberMe *bool `json:"rememberMe,omitempty"`
|
RememberMe *bool `json:"rememberMe,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// KeycloakRealmSMTP contains information about the SMTP server used to send
|
||||||
|
// transactional mail (for registration and password reset).
|
||||||
|
type KeycloakRealmSMTP struct {
|
||||||
|
// auth: "true"
|
||||||
|
// from: noreply@bitmask.me
|
||||||
|
// fromDisplayName: Bitmask Accounts
|
||||||
|
// host: email-smtp.eu-west-1.amazonaws.com
|
||||||
|
// password: '**********'
|
||||||
|
// port: "587"
|
||||||
|
// ssl: "false"
|
||||||
|
// starttls: "true"
|
||||||
|
// user: XXXXXXXXXXXXXXXXXXXX
|
||||||
|
|
||||||
|
// +kubebuilder:default:=true
|
||||||
|
// If authentication should be used
|
||||||
|
Auth bool `json:"auth,omitempty"`
|
||||||
|
|
||||||
|
// From which address the emails will be sent, takes precedence
|
||||||
|
// over the attribute defined in the secret.
|
||||||
|
From string `json:"from,omitempty"`
|
||||||
|
|
||||||
|
// From which NAME the email should originate.
|
||||||
|
FromDisplayName string `json:"fromDisplayName,omitempty"`
|
||||||
|
|
||||||
|
Secret *KeycloakRealmSMTPSecret `json:"secret,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// KeycloakRealmSMTPSecret contains Credentials for connecting to a SMTP
|
||||||
|
// Server.
|
||||||
|
type KeycloakRealmSMTPSecret struct {
|
||||||
|
|
||||||
|
// +kubebuilder:validation:Required
|
||||||
|
// Secret containing SMTP configuration
|
||||||
|
Name string `json:"name"`
|
||||||
|
|
||||||
|
// +kubebuilder:default:=host
|
||||||
|
// Key of the host attribute
|
||||||
|
HostKey string `json:"hostKey,omitempty"`
|
||||||
|
|
||||||
|
// +kubebuilder:default:=port
|
||||||
|
// Key of the port attribute
|
||||||
|
PortKey string `json:"portKey,omitempty"`
|
||||||
|
|
||||||
|
// +kubebuilder:default:=ssl
|
||||||
|
// Key of the ssl attribute
|
||||||
|
SSLKey string `json:"sslKey,omitempty"`
|
||||||
|
|
||||||
|
// +kubebuilder:default:=starttls
|
||||||
|
// Key of the starttls attribute
|
||||||
|
StartTLSKey string `json:"startTLSKey,omitempty"`
|
||||||
|
|
||||||
|
// +kubebuilder:default:=username
|
||||||
|
// Key of the username attribute
|
||||||
|
UsernameKey string `json:"usernameKey,omitempty"`
|
||||||
|
|
||||||
|
// +kubebuilder:default:=from
|
||||||
|
// Key of the from attribute, contains the mail address that email will be sent from.
|
||||||
|
FromKey string `json:"fromKey,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
// KeycloakRealmStatus defines the observed state of KeycloakRealm
|
// KeycloakRealmStatus defines the observed state of KeycloakRealm
|
||||||
type KeycloakRealmStatus struct {
|
type KeycloakRealmStatus struct {
|
||||||
Available bool `json:"available"`
|
Available bool `json:"available"`
|
||||||
ID string `json:"id"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// +kubebuilder:object:root=true
|
// +kubebuilder:object:root=true
|
||||||
|
|
|
@ -29,7 +29,7 @@ func (in *KeycloakClient) DeepCopyInto(out *KeycloakClient) {
|
||||||
*out = *in
|
*out = *in
|
||||||
out.TypeMeta = in.TypeMeta
|
out.TypeMeta = in.TypeMeta
|
||||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||||
out.Spec = in.Spec
|
in.Spec.DeepCopyInto(&out.Spec)
|
||||||
out.Status = in.Status
|
out.Status = in.Status
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,9 +83,150 @@ func (in *KeycloakClientList) DeepCopyObject() runtime.Object {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *KeycloakClientSecret) DeepCopyInto(out *KeycloakClientSecret) {
|
||||||
|
*out = *in
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KeycloakClientSecret.
|
||||||
|
func (in *KeycloakClientSecret) DeepCopy() *KeycloakClientSecret {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(KeycloakClientSecret)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *KeycloakClientSpec) DeepCopyInto(out *KeycloakClientSpec) {
|
func (in *KeycloakClientSpec) DeepCopyInto(out *KeycloakClientSpec) {
|
||||||
*out = *in
|
*out = *in
|
||||||
|
if in.Enabled != nil {
|
||||||
|
in, out := &in.Enabled, &out.Enabled
|
||||||
|
*out = new(bool)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
if in.Name != nil {
|
||||||
|
in, out := &in.Name, &out.Name
|
||||||
|
*out = new(string)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
if in.Description != nil {
|
||||||
|
in, out := &in.Description, &out.Description
|
||||||
|
*out = new(string)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
if in.Protocol != nil {
|
||||||
|
in, out := &in.Protocol, &out.Protocol
|
||||||
|
*out = new(string)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
if in.ClientAuthenticatorType != nil {
|
||||||
|
in, out := &in.ClientAuthenticatorType, &out.ClientAuthenticatorType
|
||||||
|
*out = new(string)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
if in.DirectAccessGrantsEnabled != nil {
|
||||||
|
in, out := &in.DirectAccessGrantsEnabled, &out.DirectAccessGrantsEnabled
|
||||||
|
*out = new(bool)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
if in.PublicClient != nil {
|
||||||
|
in, out := &in.PublicClient, &out.PublicClient
|
||||||
|
*out = new(bool)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
if in.ImplicitFlowEnabled != nil {
|
||||||
|
in, out := &in.ImplicitFlowEnabled, &out.ImplicitFlowEnabled
|
||||||
|
*out = new(bool)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
if in.StandardFlowEnabled != nil {
|
||||||
|
in, out := &in.StandardFlowEnabled, &out.StandardFlowEnabled
|
||||||
|
*out = new(bool)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
if in.ServiceAccountsEnabled != nil {
|
||||||
|
in, out := &in.ServiceAccountsEnabled, &out.ServiceAccountsEnabled
|
||||||
|
*out = new(bool)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
if in.RegistrationAccessToken != nil {
|
||||||
|
in, out := &in.RegistrationAccessToken, &out.RegistrationAccessToken
|
||||||
|
*out = new(string)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
if in.SurrogateAuthRequired != nil {
|
||||||
|
in, out := &in.SurrogateAuthRequired, &out.SurrogateAuthRequired
|
||||||
|
*out = new(bool)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
if in.BearerOnly != nil {
|
||||||
|
in, out := &in.BearerOnly, &out.BearerOnly
|
||||||
|
*out = new(bool)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
if in.ConsentRequired != nil {
|
||||||
|
in, out := &in.ConsentRequired, &out.ConsentRequired
|
||||||
|
*out = new(bool)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
if in.DefaultClientScopes != nil {
|
||||||
|
in, out := &in.DefaultClientScopes, &out.DefaultClientScopes
|
||||||
|
*out = new([]string)
|
||||||
|
if **in != nil {
|
||||||
|
in, out := *in, *out
|
||||||
|
*out = make([]string, len(*in))
|
||||||
|
copy(*out, *in)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if in.OptionalClientScopes != nil {
|
||||||
|
in, out := &in.OptionalClientScopes, &out.OptionalClientScopes
|
||||||
|
*out = new([]string)
|
||||||
|
if **in != nil {
|
||||||
|
in, out := *in, *out
|
||||||
|
*out = make([]string, len(*in))
|
||||||
|
copy(*out, *in)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if in.BaseURL != nil {
|
||||||
|
in, out := &in.BaseURL, &out.BaseURL
|
||||||
|
*out = new(string)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
if in.RootURL != nil {
|
||||||
|
in, out := &in.RootURL, &out.RootURL
|
||||||
|
*out = new(string)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
if in.AdminURL != nil {
|
||||||
|
in, out := &in.AdminURL, &out.AdminURL
|
||||||
|
*out = new(string)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
if in.RedirectURIs != nil {
|
||||||
|
in, out := &in.RedirectURIs, &out.RedirectURIs
|
||||||
|
*out = new([]string)
|
||||||
|
if **in != nil {
|
||||||
|
in, out := *in, *out
|
||||||
|
*out = make([]string, len(*in))
|
||||||
|
copy(*out, *in)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if in.WebOrigins != nil {
|
||||||
|
in, out := &in.WebOrigins, &out.WebOrigins
|
||||||
|
*out = new([]string)
|
||||||
|
if **in != nil {
|
||||||
|
in, out := *in, *out
|
||||||
|
*out = make([]string, len(*in))
|
||||||
|
copy(*out, *in)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if in.Secret != nil {
|
||||||
|
in, out := &in.Secret, &out.Secret
|
||||||
|
*out = new(KeycloakClientSecret)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KeycloakClientSpec.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KeycloakClientSpec.
|
||||||
|
@ -172,9 +313,54 @@ func (in *KeycloakRealmList) DeepCopyObject() runtime.Object {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *KeycloakRealmSMTP) DeepCopyInto(out *KeycloakRealmSMTP) {
|
||||||
|
*out = *in
|
||||||
|
if in.Secret != nil {
|
||||||
|
in, out := &in.Secret, &out.Secret
|
||||||
|
*out = new(KeycloakRealmSMTPSecret)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KeycloakRealmSMTP.
|
||||||
|
func (in *KeycloakRealmSMTP) DeepCopy() *KeycloakRealmSMTP {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(KeycloakRealmSMTP)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *KeycloakRealmSMTPSecret) DeepCopyInto(out *KeycloakRealmSMTPSecret) {
|
||||||
|
*out = *in
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KeycloakRealmSMTPSecret.
|
||||||
|
func (in *KeycloakRealmSMTPSecret) DeepCopy() *KeycloakRealmSMTPSecret {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(KeycloakRealmSMTPSecret)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *KeycloakRealmSpec) DeepCopyInto(out *KeycloakRealmSpec) {
|
func (in *KeycloakRealmSpec) DeepCopyInto(out *KeycloakRealmSpec) {
|
||||||
*out = *in
|
*out = *in
|
||||||
|
if in.Enabled != nil {
|
||||||
|
in, out := &in.Enabled, &out.Enabled
|
||||||
|
*out = new(bool)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
if in.SMTP != nil {
|
||||||
|
in, out := &in.SMTP, &out.SMTP
|
||||||
|
*out = new(KeycloakRealmSMTP)
|
||||||
|
(*in).DeepCopyInto(*out)
|
||||||
|
}
|
||||||
if in.DisplayName != nil {
|
if in.DisplayName != nil {
|
||||||
in, out := &in.DisplayName, &out.DisplayName
|
in, out := &in.DisplayName, &out.DisplayName
|
||||||
*out = new(string)
|
*out = new(string)
|
||||||
|
|
|
@ -36,13 +36,114 @@ spec:
|
||||||
spec:
|
spec:
|
||||||
description: KeycloakClientSpec defines the desired state of KeycloakClient
|
description: KeycloakClientSpec defines the desired state of KeycloakClient
|
||||||
properties:
|
properties:
|
||||||
foo:
|
adminUrl:
|
||||||
description: Foo is an example field of KeycloakClient. Edit KeycloakClient_types.go
|
description: URL to the admin interface of the client
|
||||||
to remove/update
|
|
||||||
type: string
|
type: string
|
||||||
|
baseUrl:
|
||||||
|
description: Default URL to use when the auth server needs to redirect
|
||||||
|
or link back to the client
|
||||||
|
type: string
|
||||||
|
bearerOnly:
|
||||||
|
description: The access type of this client is bearer-only.
|
||||||
|
type: boolean
|
||||||
|
clientAuthenticatorType:
|
||||||
|
description: How should Clients authenticate to the server? either
|
||||||
|
'client-secret' or 'client-jwt'.
|
||||||
|
type: string
|
||||||
|
clientId:
|
||||||
|
description: ClientID is the alphanumeric identifier of the client
|
||||||
|
in a realm.
|
||||||
|
type: string
|
||||||
|
consentRequired:
|
||||||
|
description: If enabled, users have to consent to client access.
|
||||||
|
type: boolean
|
||||||
|
defaultClientScopes:
|
||||||
|
description: Which client scopes chould be granted by default, even
|
||||||
|
without specifying them.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
description:
|
||||||
|
description: Human Readable description
|
||||||
|
type: string
|
||||||
|
directAccessGrantsEnabled:
|
||||||
|
description: Are direct access grants enabled for this client or not
|
||||||
|
(OpenID connect).
|
||||||
|
type: boolean
|
||||||
|
enabled:
|
||||||
|
description: If the client is enabled and active
|
||||||
|
type: boolean
|
||||||
|
implicitFlowEnabled:
|
||||||
|
description: Enable implicit flow for this client or not (OpenID connect).
|
||||||
|
type: boolean
|
||||||
|
name:
|
||||||
|
description: Displayed Name of the Client
|
||||||
|
type: string
|
||||||
|
optionalClientScopes:
|
||||||
|
description: Which additional scopes can be specified by the client
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
protocol:
|
||||||
|
description: Protocol, either 'openid-connect' or 'saml'
|
||||||
|
type: string
|
||||||
|
publicClient:
|
||||||
|
description: Is the access type for this client public or not.
|
||||||
|
type: boolean
|
||||||
|
realmName:
|
||||||
|
description: Name of the Realm the client should be created in
|
||||||
|
type: string
|
||||||
|
redirectUris:
|
||||||
|
description: URL to the admin interface of the client
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
registrationAccessToken:
|
||||||
|
description: Used for authentication when registering new clients
|
||||||
|
type: string
|
||||||
|
rootUrl:
|
||||||
|
description: Root URL appended to relative URLs for this client
|
||||||
|
type: string
|
||||||
|
secret:
|
||||||
|
description: A client Secret is not always required
|
||||||
|
properties:
|
||||||
|
key:
|
||||||
|
default: password
|
||||||
|
description: Key of the attribute, that holds the value in the
|
||||||
|
Secret.
|
||||||
|
type: string
|
||||||
|
name:
|
||||||
|
description: Name of the Secret containing the client Secret.
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- name
|
||||||
|
type: object
|
||||||
|
serviceAccountsEnabled:
|
||||||
|
description: Are service accounts enabled for this client or not (OpenID
|
||||||
|
connect).
|
||||||
|
type: boolean
|
||||||
|
standardFlowEnabled:
|
||||||
|
description: Enable standard flow for this client or not (OpenID connect).
|
||||||
|
type: boolean
|
||||||
|
surrogateAuthRequired:
|
||||||
|
description: Whether or not surrogate auth is required.
|
||||||
|
type: boolean
|
||||||
|
webOrigins:
|
||||||
|
description: List of allowed CORS origins
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
required:
|
||||||
|
- clientId
|
||||||
|
- realmName
|
||||||
type: object
|
type: object
|
||||||
status:
|
status:
|
||||||
description: KeycloakClientStatus defines the observed state of KeycloakClient
|
description: KeycloakClientStatus defines the observed state of KeycloakClient
|
||||||
|
properties:
|
||||||
|
available:
|
||||||
|
type: boolean
|
||||||
|
required:
|
||||||
|
- available
|
||||||
type: object
|
type: object
|
||||||
type: object
|
type: object
|
||||||
served: true
|
served: true
|
||||||
|
|
|
@ -49,6 +49,9 @@ spec:
|
||||||
description: if the user should be able to change their username after
|
description: if the user should be able to change their username after
|
||||||
account creation
|
account creation
|
||||||
type: boolean
|
type: boolean
|
||||||
|
enabled:
|
||||||
|
description: If the realm is enabled and active
|
||||||
|
type: boolean
|
||||||
loginTheme:
|
loginTheme:
|
||||||
description: the name of the Theme used for the login pages
|
description: the name of the Theme used for the login pages
|
||||||
type: string
|
type: string
|
||||||
|
@ -74,9 +77,58 @@ spec:
|
||||||
resetPasswordAllowed:
|
resetPasswordAllowed:
|
||||||
description: if the user is allowed to use the reset password flow
|
description: if the user is allowed to use the reset password flow
|
||||||
type: boolean
|
type: boolean
|
||||||
smtpSecretName:
|
smtp:
|
||||||
description: Secret containing SMTP configuration
|
description: KeycloakRealmSMTP contains information about the SMTP
|
||||||
type: string
|
server used to send transactional mail (for registration and password
|
||||||
|
reset).
|
||||||
|
properties:
|
||||||
|
auth:
|
||||||
|
default: true
|
||||||
|
description: If authentication should be used
|
||||||
|
type: boolean
|
||||||
|
from:
|
||||||
|
description: From which address the emails will be sent, takes
|
||||||
|
precedence over the attribute defined in the secret.
|
||||||
|
type: string
|
||||||
|
fromDisplayName:
|
||||||
|
description: From which NAME the email should originate.
|
||||||
|
type: string
|
||||||
|
secret:
|
||||||
|
description: KeycloakRealmSMTPSecret contains Credentials for
|
||||||
|
connecting to a SMTP Server.
|
||||||
|
properties:
|
||||||
|
fromKey:
|
||||||
|
default: from
|
||||||
|
description: Key of the from attribute, contains the mail
|
||||||
|
address that email will be sent from.
|
||||||
|
type: string
|
||||||
|
hostKey:
|
||||||
|
default: host
|
||||||
|
description: Key of the host attribute
|
||||||
|
type: string
|
||||||
|
name:
|
||||||
|
description: Secret containing SMTP configuration
|
||||||
|
type: string
|
||||||
|
portKey:
|
||||||
|
default: port
|
||||||
|
description: Key of the port attribute
|
||||||
|
type: string
|
||||||
|
sslKey:
|
||||||
|
default: ssl
|
||||||
|
description: Key of the ssl attribute
|
||||||
|
type: string
|
||||||
|
startTLSKey:
|
||||||
|
default: starttls
|
||||||
|
description: Key of the starttls attribute
|
||||||
|
type: string
|
||||||
|
usernameKey:
|
||||||
|
default: username
|
||||||
|
description: Key of the username attribute
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- name
|
||||||
|
type: object
|
||||||
|
type: object
|
||||||
verifyEmail:
|
verifyEmail:
|
||||||
description: if emails should be verified before the user can log
|
description: if emails should be verified before the user can log
|
||||||
into their account
|
into their account
|
||||||
|
@ -89,11 +141,8 @@ spec:
|
||||||
properties:
|
properties:
|
||||||
available:
|
available:
|
||||||
type: boolean
|
type: boolean
|
||||||
id:
|
|
||||||
type: string
|
|
||||||
required:
|
required:
|
||||||
- available
|
- available
|
||||||
- id
|
|
||||||
type: object
|
type: object
|
||||||
type: object
|
type: object
|
||||||
served: true
|
served: true
|
||||||
|
|
|
@ -6,6 +6,32 @@ metadata:
|
||||||
creationTimestamp: null
|
creationTimestamp: null
|
||||||
name: manager-role
|
name: manager-role
|
||||||
rules:
|
rules:
|
||||||
|
- apiGroups:
|
||||||
|
- keycloak.bitmask.me
|
||||||
|
resources:
|
||||||
|
- keycloakclients
|
||||||
|
verbs:
|
||||||
|
- create
|
||||||
|
- delete
|
||||||
|
- get
|
||||||
|
- list
|
||||||
|
- patch
|
||||||
|
- update
|
||||||
|
- watch
|
||||||
|
- apiGroups:
|
||||||
|
- keycloak.bitmask.me
|
||||||
|
resources:
|
||||||
|
- keycloakclients/finalizers
|
||||||
|
verbs:
|
||||||
|
- update
|
||||||
|
- apiGroups:
|
||||||
|
- keycloak.bitmask.me
|
||||||
|
resources:
|
||||||
|
- keycloakclients/status
|
||||||
|
verbs:
|
||||||
|
- get
|
||||||
|
- patch
|
||||||
|
- update
|
||||||
- apiGroups:
|
- apiGroups:
|
||||||
- keycloak.bitmask.me
|
- keycloak.bitmask.me
|
||||||
resources:
|
resources:
|
||||||
|
|
|
@ -25,13 +25,15 @@ import (
|
||||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
|
|
||||||
keycloakv1alpha1 "git.zom.bi/images/keycloak-operator/api/v1alpha1"
|
keycloakv1alpha1 "git.zom.bi/images/keycloak-operator/api/v1alpha1"
|
||||||
|
"git.zom.bi/images/keycloak-operator/controllers/keycloak"
|
||||||
)
|
)
|
||||||
|
|
||||||
// KeycloakClientReconciler reconciles a KeycloakClient object
|
// KeycloakClientReconciler reconciles a KeycloakClient object
|
||||||
type KeycloakClientReconciler struct {
|
type KeycloakClientReconciler struct {
|
||||||
client.Client
|
client.Client
|
||||||
Log logr.Logger
|
Keycloak *keycloak.Keycloak
|
||||||
Scheme *runtime.Scheme
|
Log logr.Logger
|
||||||
|
Scheme *runtime.Scheme
|
||||||
}
|
}
|
||||||
|
|
||||||
// +kubebuilder:rbac:groups=keycloak.bitmask.me,resources=keycloakclients,verbs=get;list;watch;create;update;patch;delete
|
// +kubebuilder:rbac:groups=keycloak.bitmask.me,resources=keycloakclients,verbs=get;list;watch;create;update;patch;delete
|
||||||
|
|
|
@ -63,10 +63,10 @@ func (r *KeycloakRealmReconciler) Reconcile(ctx context.Context, req ctrl.Reques
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if realm.Status.ID != "" {
|
if realm.Status.Available {
|
||||||
// try to get existing realm
|
// try to get existing realm
|
||||||
log.Info("Would try to fetch the realm by its id.",
|
log.Info("Would try to fetch the realm by its id.",
|
||||||
"id", realm.Status.ID)
|
"id", realm.Spec.RealmName)
|
||||||
// if found {
|
// if found {
|
||||||
log.Info("will act like i found it, updating.")
|
log.Info("will act like i found it, updating.")
|
||||||
// update()
|
// update()
|
||||||
|
@ -76,7 +76,6 @@ func (r *KeycloakRealmReconciler) Reconcile(ctx context.Context, req ctrl.Reques
|
||||||
|
|
||||||
log.Info("Would now create the realm.")
|
log.Info("Would now create the realm.")
|
||||||
|
|
||||||
realm.Status.ID = "dummy"
|
|
||||||
realm.Status.Available = true
|
realm.Status.Available = true
|
||||||
r.Status().Update(ctx, &realm)
|
r.Status().Update(ctx, &realm)
|
||||||
|
|
||||||
|
|
9
main.go
9
main.go
|
@ -99,6 +99,15 @@ func main() {
|
||||||
setupLog.Error(err, "unable to create controller", "controller", "KeycloakRealm")
|
setupLog.Error(err, "unable to create controller", "controller", "KeycloakRealm")
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
if err = (&controllers.KeycloakClientReconciler{
|
||||||
|
Client: mgr.GetClient(),
|
||||||
|
Keycloak: kc,
|
||||||
|
Log: ctrl.Log.WithName("controllers").WithName("KeycloakClient"),
|
||||||
|
Scheme: mgr.GetScheme(),
|
||||||
|
}).SetupWithManager(mgr); err != nil {
|
||||||
|
setupLog.Error(err, "unable to create controller", "controller", "KeycloakClient")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
// +kubebuilder:scaffold:builder
|
// +kubebuilder:scaffold:builder
|
||||||
|
|
||||||
if err := mgr.AddHealthzCheck("health", healthz.Ping); err != nil {
|
if err := mgr.AddHealthzCheck("health", healthz.Ping); err != nil {
|
||||||
|
|
Loading…
Reference in a new issue