func()

in pkg/controllers/hub/trafficmanagerbackend/controller.go [636:706]


func (r *Reconciler) updateTrafficManagerEndpointsAndUpdateStatusIfUnknown(ctx context.Context, resourceGroup string, backend *fleetnetv1beta1.TrafficManagerBackend, profile *armtrafficmanager.Profile, desiredEndpoints map[string]desiredEndpoint) ([]fleetnetv1beta1.TrafficManagerEndpointStatus, []error, error) {
	backendKObj := klog.KObj(backend)
	acceptedEndpoints := make([]fleetnetv1beta1.TrafficManagerEndpointStatus, 0, len(desiredEndpoints))
	for _, endpoint := range profile.Properties.Endpoints {
		if endpoint.Name == nil {
			err := controller.NewUnexpectedBehaviorError(errors.New("azure Traffic Manager endpoint name is nil"))
			klog.ErrorS(err, "Invalid Traffic Manager endpoint", "atmEndpoint", endpoint)
			continue
		}

		endpointName := strings.ToLower(*endpoint.Name) // resource name are case-insensitive
		if !isEndpointOwnedByBackend(backend, endpointName) {
			continue // skipping the endpoint which is not owned by this backend
		}

		desired, ok := desiredEndpoints[endpointName]
		if !ok {
			klog.V(2).InfoS("Deleting the Azure Traffic Manager endpoint", "resourceGroup", resourceGroup, "trafficManagerBackend", backendKObj, "atmProfile", profile.Name, "atmEndpoint", endpointName)
			if _, deleteErr := r.EndpointsClient.Delete(ctx, resourceGroup, *profile.Name, armtrafficmanager.EndpointTypeAzureEndpoints, *endpoint.Name, nil); deleteErr != nil {
				if azureerrors.IsNotFound(deleteErr) {
					klog.V(2).InfoS("Ignoring NotFound Azure Traffic Manager endpoint", "resourceGroup", resourceGroup, "trafficManagerBackend", backendKObj, "atmProfile", profile.Name, "atmEndpoint", endpointName)
					continue
				}
				klog.ErrorS(deleteErr, "Failed to delete the Azure Traffic Manager endpoint", "resourceGroup", resourceGroup, "trafficManagerBackend", backendKObj, "atmProfile", profile.Name, "atmEndpoint", endpointName)
				setUnknownCondition(backend, fmt.Sprintf("Failed to cleanup the existing %q for %q: %v", endpointName, *profile.Name, deleteErr))
				if err := r.updateTrafficManagerBackendStatus(ctx, backend); err != nil {
					return nil, nil, err
				}
				return nil, nil, deleteErr
			}
			klog.V(2).InfoS("Deleted the Azure Traffic Manager endpoint", "resourceGroup", resourceGroup, "trafficManagerBackend", backendKObj, "atmProfile", profile.Name, "atmEndpoint", endpointName)
			continue
		}
		if equalAzureTrafficManagerEndpoint(*endpoint, desired.Endpoint) {
			klog.V(2).InfoS("Skipping updating the existing Traffic Manager endpoint", "resourceGroup", resourceGroup, "trafficManagerBackend", backendKObj, "atmProfile", profile.Name, "atmEndpoint", endpointName)
			delete(desiredEndpoints, endpointName) // no need to update the existing endpoint
			acceptedEndpoints = append(acceptedEndpoints, buildAcceptedEndpointStatus(endpoint, desired))
			continue
		} // no need to update the endpoint if it's the same
	}
	badEndpointsError := make([]error, 0, len(desiredEndpoints))
	// The remaining endpoints in the desiredEndpoints should be created or updated.
	for _, endpoint := range desiredEndpoints {
		klog.V(2).InfoS("Creating new Traffic Manager endpoint", "resourceGroup", resourceGroup, "trafficManagerBackend", backendKObj, "atmProfile", profile.Name, "atmEndpoint", endpoint)
		var responseError *azcore.ResponseError
		endpointName := *endpoint.Endpoint.Name
		res, updateErr := r.EndpointsClient.CreateOrUpdate(ctx, resourceGroup, *profile.Name, armtrafficmanager.EndpointTypeAzureEndpoints, endpointName, endpoint.Endpoint, nil)
		if updateErr != nil {
			if !errors.As(updateErr, &responseError) {
				klog.ErrorS(updateErr, "Failed to send the createOrUpdate request", "resourceGroup", resourceGroup, "trafficManagerBackend", backendKObj, "atmProfile", *profile.Name, "atmEndpoint", endpointName)
				return nil, nil, updateErr
			}
			klog.ErrorS(updateErr, "Failed to create or update the Traffic Manager endpoint", "resourceGroup", resourceGroup, "trafficManagerBackend", backendKObj, "atmProfile", *profile.Name, "atmEndpoint", endpointName)
			if azureerrors.IsClientError(updateErr) && !azureerrors.IsThrottled(updateErr) {
				// When the failure is caused by the client error, will continue to process others.
				badEndpointsError = append(badEndpointsError, updateErr)
				continue
			}
			// For any internal error, we'll retry the request using the backoff.
			setUnknownCondition(backend, fmt.Sprintf("Failed to create or update %q for %q: %v", *endpoint.Endpoint.Name, *profile.Name, updateErr))
			if err := r.updateTrafficManagerBackendStatus(ctx, backend); err != nil {
				return nil, nil, err
			}
			return nil, nil, updateErr
		}
		klog.V(2).InfoS("Created or updated Traffic Manager endpoint", "resourceGroup", resourceGroup, "trafficManagerBackend", backendKObj, "atmProfile", profile.Name, "atmEndpoint", endpointName)
		acceptedEndpoints = append(acceptedEndpoints, buildAcceptedEndpointStatus(&res.Endpoint, endpoint))
	}
	klog.V(2).InfoS("Successfully updated the Traffic Manager endpoints", "resourceGroup", resourceGroup, "trafficManagerBackend", backendKObj, "atmProfile", profile.Name, "numberOfAcceptedEndpoints", len(acceptedEndpoints), "numberOfBadEndpoints", len(badEndpointsError))
	return acceptedEndpoints, badEndpointsError, nil
}