func()

in pkg/controllers/hub/trafficmanagerprofile/controller.go [171:221]


func (r *Reconciler) handleUpdate(ctx context.Context, profile *fleetnetv1beta1.TrafficManagerProfile) (ctrl.Result, error) {
	profileKObj := klog.KObj(profile)
	atmProfileName := generateAzureTrafficManagerProfileNameFunc(profile)
	desiredATMProfile := generateAzureTrafficManagerProfile(profile)
	var responseError *azcore.ResponseError
	getRes, getErr := r.ProfilesClient.Get(ctx, profile.Spec.ResourceGroup, atmProfileName, nil)
	if getErr != nil {
		if !azureerrors.IsNotFound(getErr) {
			klog.ErrorS(getErr, "Failed to get the profile", "trafficManagerProfile", profileKObj, "atmProfileName", atmProfileName)
			// If a user specifies an invalid resource group or the agent does not have the permission to access the resource,
			// Return invalid profile
			if azureerrors.IsForbidden(getErr) {
				return r.updateProfileStatus(ctx, profile, nil, getErr)
			}
			return ctrl.Result{}, getErr
		}
		klog.V(2).InfoS("Azure Traffic Manager profile does not exist", "trafficManagerProfile", profileKObj, "atmProfileName", atmProfileName)
	} else {
		if equalAzureTrafficManagerProfile(getRes.Profile, desiredATMProfile) {
			// skip creating or updating the profile
			klog.V(2).InfoS("No profile update needed", "trafficManagerProfile", profileKObj, "atmProfileName", atmProfileName)
			return r.updateProfileStatus(ctx, profile, &getRes.Profile, nil)
		}
		// build the desired profile based on the current profile and reset any managed fields' value
		desiredATMProfile = buildAzureTrafficManagerProfileRequest(getRes.Profile, desiredATMProfile)
	}

	// register finalizer only before creating atm profile
	// So that when a user specifies an invalid resource group, the controller will fail to create the profile because of the 403 error.
	// Otherwise, the deletion will be stuck because of the 403 error and the finalizer cannot be removed.
	if !controllerutil.ContainsFinalizer(profile, objectmeta.TrafficManagerProfileFinalizer) {
		controllerutil.AddFinalizer(profile, objectmeta.TrafficManagerProfileFinalizer)
		if err := r.Update(ctx, profile); err != nil {
			klog.ErrorS(err, "Failed to add finalizer to trafficManagerProfile", "trafficManagerProfile", profileKObj)
			return ctrl.Result{}, controller.NewUpdateIgnoreConflictError(err)
		}
	}

	res, updateErr := r.ProfilesClient.CreateOrUpdate(ctx, profile.Spec.ResourceGroup, atmProfileName, desiredATMProfile, nil)
	if updateErr != nil {
		if !errors.As(updateErr, &responseError) {
			klog.ErrorS(updateErr, "Failed to send the createOrUpdate request", "trafficManagerProfile", profileKObj, "atmProfileName", atmProfileName)
			return ctrl.Result{}, updateErr
		}
		klog.ErrorS(updateErr, "Failed to create or update a profile", "trafficManagerProfile", profileKObj,
			"atmProfileName", atmProfileName,
			"errorCode", responseError.ErrorCode, "statusCode", responseError.StatusCode)
	}
	klog.V(2).InfoS("Created or updated Azure Traffic Manager Profile", "trafficManagerProfile", profileKObj, "atmProfileName", atmProfileName)
	return r.updateProfileStatus(ctx, profile, &res.Profile, updateErr)
}