pkg/controller/osm/ingress_cert_config_reconciler.go (95 lines of code) (raw):

// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. package osm import ( "context" "fmt" "github.com/Azure/aks-app-routing-operator/pkg/controller/controllername" "github.com/go-logr/logr" cfgv1alpha2 "github.com/openservicemesh/osm/pkg/apis/config/v1alpha2" apierrors "k8s.io/apimachinery/pkg/api/errors" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" "github.com/Azure/aks-app-routing-operator/pkg/config" "github.com/Azure/aks-app-routing-operator/pkg/controller/metrics" ) const ( osmNamespace = "kube-system" osmMeshConfigName = "osm-mesh-config" osmNginxSAN = "ingress-nginx.ingress.cluster.local" osmClientCertValidity = "24h" osmClientCertName = "osm-ingress-client-cert" ) var ingressCertConfigControllerName = controllername.New("osm", "ingress", "cert", "config") // IngressCertConfigReconciler updates the Open Service Mesh configuration to generate a client cert // to be used by the ingress controller when contacting upstreams. type IngressCertConfigReconciler struct { client client.Client } func NewIngressCertConfigReconciler(manager ctrl.Manager, conf *config.Config) error { metrics.InitControllerMetrics(ingressCertConfigControllerName) if conf.DisableOSM { return nil } return ingressCertConfigControllerName.AddToController( ctrl. NewControllerManagedBy(manager). For(&cfgv1alpha2.MeshConfig{}), manager.GetLogger(), ).Complete(&IngressCertConfigReconciler{client: manager.GetClient()}) } func (i *IngressCertConfigReconciler) Reconcile(ctx context.Context, req ctrl.Request) (res ctrl.Result, retErr error) { defer func() { metrics.HandleControllerReconcileMetrics(ingressCertConfigControllerName, res, retErr) }() logger, err := logr.FromContext(ctx) if err != nil { return ctrl.Result{}, err } logger = ingressCertConfigControllerName.AddToLogger(logger).WithValues("namespace", req.Namespace, "name", req.Name) if req.Name != osmMeshConfigName || req.Namespace != osmNamespace { logger.Info(fmt.Sprintf("ignoring mesh config, we only reconcile mesh config %s/%s", osmNamespace, osmMeshConfigName)) return ctrl.Result{}, nil } logger.Info("getting OSM ingress mesh config") conf := &cfgv1alpha2.MeshConfig{} err = i.client.Get(ctx, req.NamespacedName, conf) if err != nil { return ctrl.Result{}, client.IgnoreNotFound(err) } logger = logger.WithValues("generation", conf.Generation) var dirty bool if conf.Spec.Certificate.IngressGateway == nil { conf.Spec.Certificate.IngressGateway = &cfgv1alpha2.IngressGatewayCertSpec{} } if conf.Spec.Certificate.IngressGateway.Secret.Name != osmClientCertName { logger.Info("updating IngressGateway client cert secret name") dirty = true conf.Spec.Certificate.IngressGateway.Secret.Name = osmClientCertName } if conf.Spec.Certificate.IngressGateway.Secret.Namespace != osmNamespace { logger.Info("updating IngressGateway client cert secret namespace") dirty = true conf.Spec.Certificate.IngressGateway.Secret.Namespace = osmNamespace } if conf.Spec.Certificate.IngressGateway.ValidityDuration != osmClientCertValidity { logger.Info("updating IngressGateway client cert validity duration") dirty = true conf.Spec.Certificate.IngressGateway.ValidityDuration = osmClientCertValidity } if l := len(conf.Spec.Certificate.IngressGateway.SubjectAltNames); l != 1 || (l == 1 && conf.Spec.Certificate.IngressGateway.SubjectAltNames[0] != osmNginxSAN) { logger.Info("updating IngressGateway SAN") dirty = true conf.Spec.Certificate.IngressGateway.SubjectAltNames = []string{osmNginxSAN} } if !dirty { logger.Info("no changes required for OSM ingress client cert configuration") return ctrl.Result{}, nil } logger.Info("updating OSM ingress mesh config") if err = i.client.Update(ctx, conf); client.IgnoreNotFound(err) != nil { if apierrors.IsConflict(err) { logger.Info("OSM ingress mesh config was updated by another process, retrying") return ctrl.Result{Requeue: true}, nil } logger.Error(err, "failed to update OSM ingress mesh config") return ctrl.Result{}, err } return ctrl.Result{}, nil }