pkg/controller/dns/external_dns_crd.go (86 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 ExternalDNSCRDControllerName = controllername.New("externaldns", "crd") type ExternalDNSCRDController struct { config *config.Config client client.Client events record.EventRecorder } func NewExternalDNSCRDController(manager ctrl.Manager, config config.Config) error { return ExternalDNSCRDControllerName.AddToController(ctrl.NewControllerManagedBy(manager). For(&v1alpha1.ExternalDNS{}). Owns(&appsv1.Deployment{}), manager.GetLogger()). Complete(&ExternalDNSCRDController{ config: &config, client: manager.GetClient(), events: manager.GetEventRecorderFor("aks-app-routing-operator"), }) } func (e *ExternalDNSCRDController) Reconcile(ctx context.Context, req ctrl.Request) (res ctrl.Result, err error) { defer func() { metrics.HandleControllerReconcileMetrics(ExternalDNSCRDControllerName, res, err) }() // set up logger logger, err := logr.FromContext(ctx) if err != nil { return ctrl.Result{}, fmt.Errorf("creating logger: %w", err) } logger = ExternalDNSCRDControllerName.AddToLogger(logger).WithValues("namespace", req.Namespace, "name", req.Name) obj := &v1alpha1.ExternalDNS{} if err = e.client.Get(ctx, req.NamespacedName, obj); err != nil { if k8serrors.IsNotFound(err) { logger.Info("externaldns crd object not found, will ignore not found error") return ctrl.Result{}, nil } logger.Error(err, "failed to get externaldns object") return ctrl.Result{}, err } // verify serviceaccount if _, err = util.GetServiceAccountAndVerifyWorkloadIdentity(ctx, e.client, obj.GetInputServiceAccount(), obj.GetNamespace()); 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()) e.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(e.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()) e.events.Eventf(obj, corev1.EventTypeWarning, "FailedUpdateOrCreateExternalDNSResources", userErr.UserError()) return ctrl.Result{}, nil } } err = deployExternalDNSResources(ctx, e.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") e.events.Eventf(obj, corev1.EventTypeWarning, "FailedUpdateOrCreateExternalDNSResources", "failed to deploy external DNS resources: %s", err.Error()) return ctrl.Result{}, err } return ctrl.Result{}, nil }