Skip to content

Commit

Permalink
Remove deployment and statefulset mutating webhooks
Browse files Browse the repository at this point in the history
  • Loading branch information
nickytd committed Feb 15, 2024
1 parent d1b7261 commit 5655b12
Show file tree
Hide file tree
Showing 23 changed files with 475 additions and 945 deletions.
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v0.1.8-dev
v0.2.0-dev
2 changes: 1 addition & 1 deletion charts/oidc-apps-controller/templates/clusterrole.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ rules:
resources: [ "services","secrets","events" ]
verbs: [ "*" ]
- apiGroups: [ "apps" ]
resources: [ "deployments","statefulsets" ]
resources: [ "deployments","statefulsets", "replicasets" ]
verbs: [ "*" ]
- apiGroups: [ "networking.k8s.io" ]
resources: [ "ingresses" ]
Expand Down
55 changes: 3 additions & 52 deletions charts/oidc-apps-controller/templates/webhook.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,56 +10,6 @@ metadata:
cert-manager.io/inject-ca-from: {{ include "oidc-apps-extension.certificateRef" . }}
{{- end }}
webhooks:
- name: {{ include "oidc-apps-extension.fullname" . }}-deployments.gardener.cloud
clientConfig:
service:
name: {{ include "oidc-apps-extension.fullname" . }}
namespace: {{ .Release.Namespace }}
path: /oidc-mutate-v1-deployment
port: {{ .Values.service.port | int }}
caBundle:
rules:
- operations: ["CREATE", "UPDATE"]
apiGroups: ["apps"]
apiVersions: ["v1"]
resources: ["deployments"]
{{- with .Values.webhook.objectSelector }}
objectSelector:
{{- toYaml . | nindent 6 }}
{{- end }}
{{- with .Values.webhook.namespaceSelector }}
namespaceSelector:
{{- toYaml . | nindent 6 }}
{{- end }}
sideEffects: NoneOnDryRun
admissionReviewVersions:
- v1
reinvocationPolicy: IfNeeded
- name: {{ include "oidc-apps-extension.fullname" . }}-statefulsets.gardener.cloud
clientConfig:
service:
name: {{ include "oidc-apps-extension.fullname" . }}
namespace: {{ .Release.Namespace }}
path: /oidc-mutate-v1-statefulset
port: {{ .Values.service.port | int }}
caBundle:
rules:
- operations: [ "CREATE", "UPDATE" ]
apiGroups: [ "apps" ]
apiVersions: [ "v1" ]
resources: [ "statefulsets" ]
{{- with .Values.webhook.objectSelector }}
objectSelector:
{{- toYaml . | nindent 6 }}
{{- end }}
{{- with .Values.webhook.namespaceSelector }}
namespaceSelector:
{{- toYaml . | nindent 6 }}
{{- end }}
sideEffects: NoneOnDryRun
admissionReviewVersions:
- v1
reinvocationPolicy: IfNeeded
- name: {{ include "oidc-apps-extension.fullname" . }}-pods.gardener.cloud
clientConfig:
service:
Expand All @@ -73,9 +23,10 @@ webhooks:
apiGroups: [ "" ]
apiVersions: [ "v1" ]
resources: [ "pods" ]
{{- with .Values.webhook.objectSelector }}
objectSelector:
matchLabels:
oidc-application-controller/component: pod
{{- toYaml . | nindent 6 }}
{{- end }}
{{- with .Values.webhook.namespaceSelector }}
namespaceSelector:
{{- toYaml . | nindent 6 }}
Expand Down
11 changes: 5 additions & 6 deletions charts/oidc-apps-controller/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -156,12 +156,11 @@ targets:
# In case of Gardener there can be a mapping between seed names and oidc client ids
clients:
# Seed name shall match the seed identifier
- name: app1
# clientId shall be the oidc client id configured at the oidc provider
clientId: 10365f8c-d9ba-44f9-8e85-741e8cc01f9c
- name: app2
clientId : 98a36b69-6592-463a-b605-d4c563f8b016

# - name: app1
# clientId shall be the oidc client id configured at the oidc provider
# clientId: 10365f8c-d9ba-44f9-8e85-741e8cc01f9c
# - name: app2
# clientId : 98a36b69-6592-463a-b605-d4c563f8b016

gardener:
# seed:
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ require (
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/emicklei/go-restful/v3 v3.11.2 // indirect
github.com/evanphx/json-patch v5.6.0+incompatible
github.com/evanphx/json-patch v5.6.0+incompatible // indirect
github.com/evanphx/json-patch/v5 v5.8.1 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/go-logr/zapr v1.3.0 // indirect
Expand Down
53 changes: 2 additions & 51 deletions pkg/controllers/deployment-reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import (
"context"

"github.com/gardener/oidc-apps-controller/pkg/configuration"
oidc_apps_controller "github.com/gardener/oidc-apps-controller/pkg/constants"

appsv1 "k8s.io/api/apps/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
Expand All @@ -34,22 +33,18 @@ type DeploymentReconciler struct {
// Reconcile creates the auth & zutz secrets mounted to the target deployment
func (d *DeploymentReconciler) Reconcile(ctx context.Context, request reconcile.Request) (reconcile.Result, error) {

_log := log.FromContext(ctx)

reconciledDeployment := &appsv1.Deployment{}
if err := d.Client.Get(ctx, request.NamespacedName, reconciledDeployment); client.IgnoreNotFound(err) != nil {
return reconcile.Result{}, err
}
_log := log.FromContext(ctx).WithValues("resourceVersion", reconciledDeployment.GetResourceVersion())

// Skip resource without an identity
if reconciledDeployment.GetName() == "" && reconciledDeployment.GetNamespace() == "" {
_log.V(9).Info("reconciled deployment is empty, returning ...")
return reconcile.Result{}, nil
}
_log = _log.WithValues(
"resourceVersion", reconciledDeployment.GetResourceVersion(),
"generation", reconciledDeployment.GetGeneration(),
)

_log.V(9).Info("handling deployment reconcile request")

if reconciledDeployment.GetLabels() != nil {
Expand All @@ -59,63 +54,19 @@ func (d *DeploymentReconciler) Reconcile(ctx context.Context, request reconcile.
}
}

// In case the deployment is an OIDC target but has not been modified by the oidc admission controller
// then we trigger an update of the resource
annotations := reconciledDeployment.GetAnnotations()
if len(annotations) == 0 {
_log.Info("Reconciled deployment is not annotated with the oidc-application-controller annotations, " +
"re-triggering the admission controller...")
return reconcile.Result{}, nil
}
if _, found := annotations[oidc_apps_controller.AnnotationTargetKey]; !found {
_log.Info("Reconciled deployment is not annotated with the oidc-application-controller annotations, " +
"re-triggering the admission controller...")
return reconcile.Result{}, nil
}

// add a finalizer
/*
if !controllerutil.ContainsFinalizer(reconciledDeployment, oidc_apps_controller.Finalizer) && !reconciledDeployment.
GetDeletionTimestamp().IsZero() {
controllerutil.AddFinalizer(reconciledDeployment, oidc_apps_controller.Finalizer)
if err := d.Client.Update(ctx, reconciledDeployment); err != nil {
return reconcile.Result{}, err
}
}*/

// Check for deletion & handle cleanup of the dependencies
if !reconciledDeployment.GetDeletionTimestamp().IsZero() {
_log.V(9).Info("Remove owned resources")
if err := deleteOwnedResources(ctx, d.Client, reconciledDeployment); err != nil {
return reconcile.Result{}, err
}

/*
_log.V(9).Info("Remove finalizer")
if err := retry.RetryOnConflict(retry.DefaultRetry, func() error {
if err := d.Client.Get(ctx, request.NamespacedName, reconciledDeployment); client.IgnoreNotFound(
err) != nil {
return err
}
controllerutil.RemoveFinalizer(reconciledDeployment, oidc_apps_controller.Finalizer)
return d.Client.Update(ctx, reconciledDeployment)
}); err != nil {
_log.Error(err, "Error removing finalizer")
return reconcile.Result{}, nil
}
*/

return reconcile.Result{}, nil
}

if err := reconcileDeploymentDependencies(ctx, d.Client, reconciledDeployment); err != nil {
return reconcile.Result{}, err
}

if _log.GetV() == 9 {
logOwnedResources(ctx, d.Client, reconciledDeployment)
}

return reconcile.Result{}, nil

}
36 changes: 11 additions & 25 deletions pkg/controllers/modifiers.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ func reconcileDeploymentDependencies(ctx context.Context, c client.Client, objec
}

// Create or update the oauth2 service setting the owner reference
if oauth2Service, err = createOauth2Service("", object); err != nil {
if oauth2Service, err = createOauth2Service(object); err != nil {
return fmt.Errorf("failed to create oauth2 service: %w", err)
}
if err := controllerutil.SetOwnerReference(object, &oauth2Service, c.Scheme()); err != nil {
Expand Down Expand Up @@ -227,12 +227,10 @@ func reconcileDeploymentDependencies(ctx context.Context, c client.Client, objec
}

// Create or update the oauth2 ingress setting the owner reference
if oauth2Ingress, err = createIngress(object.GetAnnotations()[oidc_apps_controller.AnnotationHostKey], "",
object); err != nil {
if oauth2Ingress, err = createIngressForDeployment(object); err != nil {
return fmt.Errorf("failed to create oauth2 ingress: %w", err)
}
if err = controllerutil.SetOwnerReference(object, &oauth2Ingress,
c.Scheme()); err != nil {
if err = controllerutil.SetOwnerReference(object, &oauth2Ingress, c.Scheme()); err != nil {
return fmt.Errorf("failed to set owner reference to oauth2 ingress: %w", err)
}
if _, err = controllerutil.CreateOrUpdate(ctx, c, &oauth2Ingress, mutateFn); err != nil {
Expand Down Expand Up @@ -282,28 +280,16 @@ func reconcileStatefulSetDependencies(ctx context.Context, c client.Client, obje
if err := c.List(ctx, podList, labelSelector, client.InNamespace(object.GetNamespace())); err != nil {
return fmt.Errorf("failed to list pods: %w", err)
}
hostPrefix := object.GetAnnotations()[oidc_apps_controller.AnnotationHostKey]
suffix := object.GetAnnotations()[oidc_apps_controller.AnnotationSuffixKey]

for _, pod := range podList.Items {
if len(pod.Annotations) == 0 {
pod.Annotations = make(map[string]string, 1)
}
pod.Annotations[oidc_apps_controller.AnnotationSuffixKey] = suffix

var podIndex string
host, domain, found := strings.Cut(hostPrefix, ".")
if found {
// In some environments, the pod index is added as a label: apps.kubernetes.io/pod-index
if idx, present := pod.GetObjectMeta().GetLabels()["statefulset.kubernetes.io/pod-name"]; present {
l := strings.Split(idx, "-")
host = fmt.Sprintf("%s-%s.%s", host, l[len(l)-1], domain)
podIndex = l[len(l)-1]
} else {
host = fmt.Sprintf("%s.%s", host, domain)
}
log.FromContext(ctx).V(9).Info("Reconciling pod", "pod", pod.GetName(), "annotations", pod.GetAnnotations())
_, found := pod.GetAnnotations()[oidc_apps_controller.AnnotationHostKey]
if !found {
continue
}

// Create or update the oauth2 service setting the owner reference
if oauth2Service, err = createOauth2Service(podIndex, &pod); err != nil {
if oauth2Service, err = createOauth2Service(&pod); err != nil {
return fmt.Errorf("failed to create oauth2 service: %w", err)
}
if err := controllerutil.SetOwnerReference(&pod, &oauth2Service, c.Scheme()); err != nil {
Expand All @@ -314,7 +300,7 @@ func reconcileStatefulSetDependencies(ctx context.Context, c client.Client, obje
}

// Create or update the oauth2 ingress setting the owner reference
if oauth2Ingress, err = createIngress(host, podIndex, object); err != nil {
if oauth2Ingress, err = createIngressForStatefulSetPod(&pod, object); err != nil {
return fmt.Errorf("failed to create oauth2 ingress: %w", err)
}
if err = controllerutil.SetOwnerReference(&pod, &oauth2Ingress, c.Scheme()); err != nil {
Expand Down
66 changes: 60 additions & 6 deletions pkg/controllers/oidc-apps-ingresses.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,28 @@ package controllers

import (
"fmt"
"strings"

"github.com/gardener/oidc-apps-controller/pkg/configuration"
oidc_apps_controller "github.com/gardener/oidc-apps-controller/pkg/constants"
"github.com/gardener/oidc-apps-controller/pkg/rand"

corev1 "k8s.io/api/core/v1"
networkingv1 "k8s.io/api/networking/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/utils/ptr"
"sigs.k8s.io/controller-runtime/pkg/client"
)

func createIngress(host string, index string, object client.Object) (networkingv1.Ingress, error) {
suffix, ok := object.GetAnnotations()[oidc_apps_controller.AnnotationSuffixKey]
if !ok {
return networkingv1.Ingress{}, fmt.Errorf("missing suffix annotation")
}
func createIngressForDeployment(object client.Object) (networkingv1.Ingress, error) {
suffix := rand.GenerateSha256(object.GetName() + "-" + object.GetNamespace())
ingressClassName := configuration.GetOIDCAppsControllerConfig().GetIngressClassName(object)
ingressTLSSecretName := configuration.GetOIDCAppsControllerConfig().GetIngressTLSSecretName(object)
host := configuration.GetOIDCAppsControllerConfig().GetHost(object)

return networkingv1.Ingress{
ObjectMeta: metav1.ObjectMeta{
Name: "ingress-" + addOptionalIndex(index+"-") + suffix,
Name: "ingress-" + suffix,
Namespace: object.GetNamespace(),
Labels: map[string]string{oidc_apps_controller.LabelKey: "oauth2"},
},
Expand All @@ -50,6 +52,58 @@ func createIngress(host string, index string, object client.Object) (networkingv
Rules: []networkingv1.IngressRule{
{
Host: host,
IngressRuleValue: networkingv1.IngressRuleValue{
HTTP: &networkingv1.HTTPIngressRuleValue{
Paths: []networkingv1.HTTPIngressPath{
{
Path: "/",
PathType: ptr.To(networkingv1.PathTypePrefix),
Backend: networkingv1.IngressBackend{
Service: &networkingv1.IngressServiceBackend{
Name: "oauth2-service-" + suffix,
Port: networkingv1.ServiceBackendPort{
Name: "http",
},
},
},
},
},
},
},
},
},
},
}, nil
}

func createIngressForStatefulSetPod(pod *corev1.Pod, object client.Object) (networkingv1.Ingress, error) {
suffix := rand.GenerateSha256(pod.GetName() + "-" + pod.GetNamespace())
ingressClassName := configuration.GetOIDCAppsControllerConfig().GetIngressClassName(object)
ingressTLSSecretName := configuration.GetOIDCAppsControllerConfig().GetIngressTLSSecretName(object)
hostPrefix, ok := pod.GetAnnotations()[oidc_apps_controller.AnnotationHostKey]
if !ok {
return networkingv1.Ingress{}, fmt.Errorf("host annotation not found in pod %s/%s", pod.GetNamespace(), pod.GetName())
}
host, domain, _ := strings.Cut(hostPrefix, ".")
index := fetchStrIndexIfPresent(pod)

return networkingv1.Ingress{
ObjectMeta: metav1.ObjectMeta{
Name: "ingress-" + addOptionalIndex(index+"-") + suffix,
Namespace: object.GetNamespace(),
Labels: map[string]string{oidc_apps_controller.LabelKey: "oauth2"},
},
Spec: networkingv1.IngressSpec{
IngressClassName: ptr.To(ingressClassName),
TLS: []networkingv1.IngressTLS{
{
Hosts: []string{fmt.Sprintf("%s-%s.%s", host, fetchStrIndexIfPresent(pod), domain)},
SecretName: ingressTLSSecretName,
},
},
Rules: []networkingv1.IngressRule{
{
Host: fmt.Sprintf("%s-%s.%s", host, fetchStrIndexIfPresent(pod), domain),
IngressRuleValue: networkingv1.IngressRuleValue{
HTTP: &networkingv1.HTTPIngressRuleValue{
Paths: []networkingv1.HTTPIngressPath{
Expand Down
Loading

0 comments on commit 5655b12

Please sign in to comment.