Add KeycloakClient resource

This commit is contained in:
paul 2021-01-10 23:53:43 +01:00
parent b3c1d98534
commit 28381df56e
14 changed files with 357 additions and 0 deletions

View file

@ -7,6 +7,10 @@ resources:
group: keycloak group: keycloak
kind: KeycloakRealm kind: KeycloakRealm
version: v1alpha1 version: v1alpha1
- crdVersion: v1
group: keycloak
kind: KeycloakClient
version: v1alpha1
version: 3-alpha version: 3-alpha
plugins: plugins:
manifests.sdk.operatorframework.io/v2: {} manifests.sdk.operatorframework.io/v2: {}

View file

@ -6,6 +6,7 @@ scaffolded with
operator-sdk init --domain=bitmask.me --repo=git.zom.bi/images/keycloak-operator operator-sdk init --domain=bitmask.me --repo=git.zom.bi/images/keycloak-operator
# Edit Manager options to watch all namespaces (Namespace: "") # Edit Manager options to watch all namespaces (Namespace: "")
operator-sdk create api --group=keycloak --version=v1alpha1 --kind=KeycloakRealm operator-sdk create api --group=keycloak --version=v1alpha1 --kind=KeycloakRealm
operator-sdk create api --group=keycloak --version=v1alpha1 --kind=KeycloakClient
``` ```
for testing locally: for testing locally:

View file

@ -0,0 +1,64 @@
/*
Copyright 2021.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1alpha1
import (
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
type KeycloakClientSpec struct {
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
// Important: Run "make" to regenerate code after modifying this file
// Foo is an example field of KeycloakClient. Edit KeycloakClient_types.go to remove/update
Foo string `json:"foo,omitempty"`
}
// KeycloakClientStatus defines the observed state of KeycloakClient
type KeycloakClientStatus struct {
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
// Important: Run "make" to regenerate code after modifying this file
}
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// KeycloakClient is the Schema for the keycloakclients API
type KeycloakClient struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec KeycloakClientSpec `json:"spec,omitempty"`
Status KeycloakClientStatus `json:"status,omitempty"`
}
// +kubebuilder:object:root=true
// KeycloakClientList contains a list of KeycloakClient
type KeycloakClientList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []KeycloakClient `json:"items"`
}
func init() {
SchemeBuilder.Register(&KeycloakClient{}, &KeycloakClientList{})
}

View file

@ -24,6 +24,95 @@ import (
runtime "k8s.io/apimachinery/pkg/runtime" runtime "k8s.io/apimachinery/pkg/runtime"
) )
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *KeycloakClient) DeepCopyInto(out *KeycloakClient) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
out.Spec = in.Spec
out.Status = in.Status
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KeycloakClient.
func (in *KeycloakClient) DeepCopy() *KeycloakClient {
if in == nil {
return nil
}
out := new(KeycloakClient)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *KeycloakClient) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *KeycloakClientList) DeepCopyInto(out *KeycloakClientList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]KeycloakClient, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KeycloakClientList.
func (in *KeycloakClientList) DeepCopy() *KeycloakClientList {
if in == nil {
return nil
}
out := new(KeycloakClientList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *KeycloakClientList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *KeycloakClientSpec) DeepCopyInto(out *KeycloakClientSpec) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KeycloakClientSpec.
func (in *KeycloakClientSpec) DeepCopy() *KeycloakClientSpec {
if in == nil {
return nil
}
out := new(KeycloakClientSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *KeycloakClientStatus) DeepCopyInto(out *KeycloakClientStatus) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KeycloakClientStatus.
func (in *KeycloakClientStatus) DeepCopy() *KeycloakClientStatus {
if in == nil {
return nil
}
out := new(KeycloakClientStatus)
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 *KeycloakRealm) DeepCopyInto(out *KeycloakRealm) { func (in *KeycloakRealm) DeepCopyInto(out *KeycloakRealm) {
*out = *in *out = *in

View file

@ -0,0 +1,57 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.4.1
creationTimestamp: null
name: keycloakclients.keycloak.bitmask.me
spec:
group: keycloak.bitmask.me
names:
kind: KeycloakClient
listKind: KeycloakClientList
plural: keycloakclients
singular: keycloakclient
scope: Namespaced
versions:
- name: v1alpha1
schema:
openAPIV3Schema:
description: KeycloakClient is the Schema for the keycloakclients API
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
description: KeycloakClientSpec defines the desired state of KeycloakClient
properties:
foo:
description: Foo is an example field of KeycloakClient. Edit KeycloakClient_types.go
to remove/update
type: string
type: object
status:
description: KeycloakClientStatus defines the observed state of KeycloakClient
type: object
type: object
served: true
storage: true
subresources:
status: {}
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []

View file

@ -3,17 +3,20 @@
# It should be run by config/default # It should be run by config/default
resources: resources:
- bases/keycloak.bitmask.me_keycloakrealms.yaml - bases/keycloak.bitmask.me_keycloakrealms.yaml
- bases/keycloak.bitmask.me_keycloakclients.yaml
# +kubebuilder:scaffold:crdkustomizeresource # +kubebuilder:scaffold:crdkustomizeresource
patchesStrategicMerge: patchesStrategicMerge:
# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix. # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix.
# patches here are for enabling the conversion webhook for each CRD # patches here are for enabling the conversion webhook for each CRD
#- patches/webhook_in_keycloakrealms.yaml #- patches/webhook_in_keycloakrealms.yaml
#- patches/webhook_in_keycloakclients.yaml
# +kubebuilder:scaffold:crdkustomizewebhookpatch # +kubebuilder:scaffold:crdkustomizewebhookpatch
# [CERTMANAGER] To enable webhook, uncomment all the sections with [CERTMANAGER] prefix. # [CERTMANAGER] To enable webhook, uncomment all the sections with [CERTMANAGER] prefix.
# patches here are for enabling the CA injection for each CRD # patches here are for enabling the CA injection for each CRD
#- patches/cainjection_in_keycloakrealms.yaml #- patches/cainjection_in_keycloakrealms.yaml
#- patches/cainjection_in_keycloakclients.yaml
# +kubebuilder:scaffold:crdkustomizecainjectionpatch # +kubebuilder:scaffold:crdkustomizecainjectionpatch
# the following config is for teaching kustomize how to do kustomization for CRDs. # the following config is for teaching kustomize how to do kustomization for CRDs.

View file

@ -0,0 +1,7 @@
# The following patch adds a directive for certmanager to inject CA into the CRD
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME)
name: keycloakclients.keycloak.bitmask.me

View file

@ -0,0 +1,14 @@
# The following patch enables a conversion webhook for the CRD
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: keycloakclients.keycloak.bitmask.me
spec:
conversion:
strategy: Webhook
webhook:
clientConfig:
service:
namespace: system
name: webhook-service
path: /convert

View file

@ -0,0 +1,24 @@
# permissions for end users to edit keycloakclients.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: keycloakclient-editor-role
rules:
- apiGroups:
- keycloak.bitmask.me
resources:
- keycloakclients
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- keycloak.bitmask.me
resources:
- keycloakclients/status
verbs:
- get

View file

@ -0,0 +1,20 @@
# permissions for end users to view keycloakclients.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: keycloakclient-viewer-role
rules:
- apiGroups:
- keycloak.bitmask.me
resources:
- keycloakclients
verbs:
- get
- list
- watch
- apiGroups:
- keycloak.bitmask.me
resources:
- keycloakclients/status
verbs:
- get

View file

@ -0,0 +1,7 @@
apiVersion: keycloak.bitmask.me/v1alpha1
kind: KeycloakClient
metadata:
name: keycloakclient-sample
spec:
# Add fields here
foo: bar

View file

@ -1,4 +1,5 @@
## Append samples you want in your CSV to this file as resources ## ## Append samples you want in your CSV to this file as resources ##
resources: resources:
- keycloak_v1alpha1_keycloakrealm.yaml - keycloak_v1alpha1_keycloakrealm.yaml
- keycloak_v1alpha1_keycloakclient.yaml
# +kubebuilder:scaffold:manifestskustomizesamples # +kubebuilder:scaffold:manifestskustomizesamples

View file

@ -0,0 +1,63 @@
/*
Copyright 2021.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package controllers
import (
"context"
"github.com/go-logr/logr"
"k8s.io/apimachinery/pkg/runtime"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
keycloakv1alpha1 "git.zom.bi/images/keycloak-operator/api/v1alpha1"
)
// KeycloakClientReconciler reconciles a KeycloakClient object
type KeycloakClientReconciler struct {
client.Client
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/status,verbs=get;update;patch
// +kubebuilder:rbac:groups=keycloak.bitmask.me,resources=keycloakclients/finalizers,verbs=update
// Reconcile is part of the main kubernetes reconciliation loop which aims to
// move the current state of the cluster closer to the desired state.
// TODO(user): Modify the Reconcile function to compare the state specified by
// the KeycloakClient object against the actual cluster state, and then
// perform operations to make the cluster state reflect the state specified by
// the user.
//
// For more details, check Reconcile and its Result here:
// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.7.0/pkg/reconcile
func (r *KeycloakClientReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
_ = r.Log.WithValues("keycloakclient", req.NamespacedName)
// your logic here
return ctrl.Result{}, nil
}
// SetupWithManager sets up the controller with the Manager.
func (r *KeycloakClientReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
For(&keycloakv1alpha1.KeycloakClient{}).
Complete(r)
}

View file

@ -64,6 +64,9 @@ var _ = BeforeSuite(func() {
err = keycloakv1alpha1.AddToScheme(scheme.Scheme) err = keycloakv1alpha1.AddToScheme(scheme.Scheme)
Expect(err).NotTo(HaveOccurred()) Expect(err).NotTo(HaveOccurred())
err = keycloakv1alpha1.AddToScheme(scheme.Scheme)
Expect(err).NotTo(HaveOccurred())
// +kubebuilder:scaffold:scheme // +kubebuilder:scaffold:scheme
k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}) k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme})