pkg/controller/dns/cluster_external_dns.go (88 lines of code) (raw):

package dns import ( "context" "errors" "fmt" "github.com/Azure/aks-app-routing-operator/api/v1alpha1" "github.com/Azure/aks-app-routing-operator/pkg/config" "github.com/Azure/aks-app-routing-operator/pkg/controller/controllername" "github.com/Azure/aks-app-routing-operator/pkg/controller/metrics" "github.com/Azure/aks-app-routing-operator/pkg/util" "github.com/go-logr/logr" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" k8serrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/tools/record" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" ) var ClusterExternalDNSControllerName = controllername.New("cluster", "externaldns", "crd") func NewClusterExternalDNSController(mgr ctrl.Manager, config *config.Config) error { return ClusterExternalDNSControllerName.AddToController( ctrl.NewControllerManagedBy(mgr). For(&v1alpha1.ClusterExternalDNS{}). Owns(&appsv1.Deployment{}), mgr.GetLogger()).Complete( &ClusterExternalDNSController{ config: config, client: mgr.GetClient(), events: mgr.GetEventRecorderFor("aks-app-routing-operator"), }) } type ClusterExternalDNSController struct { config *config.Config client client.Client events record.EventRecorder } func (c *ClusterExternalDNSController) Reconcile(ctx context.Context, req ctrl.Request) (res ctrl.Result, err error) { // set up metrics defer func() { metrics.HandleControllerReconcileMetrics(ClusterExternalDNSControllerName, res, err) }() // set up logger logger, err := logr.FromContext(ctx) if err != nil { return ctrl.Result{}, fmt.Errorf("setting up logger: %s", err) } logger = ClusterExternalDNSControllerName.AddToLogger(logger).WithValues("namespace", req.Namespace, "name", req.Name) // get the ClusterExternalDNS object obj := &v1alpha1.ClusterExternalDNS{} if err = c.client.Get(ctx, req.NamespacedName, obj); err != nil { if k8serrors.IsNotFound(err) { logger.Info("ClusterExternalDNS object not found, will ignore not found error") return ctrl.Result{}, nil } return ctrl.Result{}, fmt.Errorf("getting ClusterExternalDNS object: %w", err) } // verify serviceaccount if _, err = util.GetServiceAccountAndVerifyWorkloadIdentity(ctx, c.client, obj.GetInputServiceAccount(), obj.GetResourceNamespace()); err != nil { var userErr util.UserError if errors.As(err, &userErr) { logger.Info("failed to verify service account due to user error, sending warning event: " + userErr.UserError()) c.events.Eventf(obj, corev1.EventTypeWarning, "FailedUpdateOrCreateExternalDNSResources", "failed serviceaccount verification: %s", userErr.UserError()) return ctrl.Result{}, nil } logger.Error(err, "failed to verify service account") return ctrl.Result{}, err } manifestsConf, err := generateManifestsConf(c.config, obj) if err != nil { var userErr util.UserError if errors.As(err, &userErr) { logger.Info("failed to generate manifests config due to user error, sending warning event: " + userErr.UserError()) c.events.Eventf(obj, corev1.EventTypeWarning, "FailedUpdateOrCreateExternalDNSResources", userErr.UserError()) return ctrl.Result{}, nil } logger.Error(err, "failed to generate manifests config") return ctrl.Result{}, err } err = deployExternalDNSResources(ctx, c.client, manifestsConf, []metav1.OwnerReference{{ APIVersion: obj.APIVersion, Controller: util.ToPtr(true), Kind: obj.Kind, Name: obj.Name, UID: obj.UID, }}) if err != nil { logger.Error(err, "failed to upsert externaldns resources") c.events.Eventf(obj, corev1.EventTypeWarning, "FailedUpdateOrCreateExternalDNSResources", "failed to deploy external DNS resources: %s", err.Error()) return ctrl.Result{}, err } return ctrl.Result{}, nil }