sigs.k8s.io/cluster-api-provider-azure@v1.17.0/azure/services/networkinterfaces/networkinterfaces.go (about)

     1  /*
     2  Copyright 2019 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package networkinterfaces
    18  
    19  import (
    20  	"context"
    21  
    22  	"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v4"
    23  	infrav1 "sigs.k8s.io/cluster-api-provider-azure/api/v1beta1"
    24  	"sigs.k8s.io/cluster-api-provider-azure/azure"
    25  	"sigs.k8s.io/cluster-api-provider-azure/azure/services/async"
    26  	"sigs.k8s.io/cluster-api-provider-azure/azure/services/resourceskus"
    27  	"sigs.k8s.io/cluster-api-provider-azure/util/tele"
    28  )
    29  
    30  const serviceName = "interfaces"
    31  
    32  // NICScope defines the scope interface for a network interfaces service.
    33  type NICScope interface {
    34  	azure.ClusterDescriber
    35  	azure.AsyncStatusUpdater
    36  	NICSpecs() []azure.ResourceSpecGetter
    37  }
    38  
    39  // Service provides operations on Azure resources.
    40  type Service struct {
    41  	Scope NICScope
    42  	async.Reconciler
    43  	resourceSKUCache *resourceskus.Cache
    44  }
    45  
    46  // New creates a new service.
    47  func New(scope NICScope, skuCache *resourceskus.Cache) (*Service, error) {
    48  	client, err := NewClient(scope, scope.DefaultedAzureCallTimeout())
    49  	if err != nil {
    50  		return nil, err
    51  	}
    52  	return &Service{
    53  		Scope: scope,
    54  		Reconciler: async.New[armnetwork.InterfacesClientCreateOrUpdateResponse,
    55  			armnetwork.InterfacesClientDeleteResponse](scope, client, client),
    56  		resourceSKUCache: skuCache,
    57  	}, nil
    58  }
    59  
    60  // Name returns the service name.
    61  func (s *Service) Name() string {
    62  	return serviceName
    63  }
    64  
    65  // Reconcile idempotently creates or updates a network interface.
    66  func (s *Service) Reconcile(ctx context.Context) error {
    67  	ctx, _, done := tele.StartSpanWithLogger(ctx, "networkinterfaces.Service.Reconcile")
    68  	defer done()
    69  
    70  	ctx, cancel := context.WithTimeout(ctx, s.Scope.DefaultedAzureServiceReconcileTimeout())
    71  	defer cancel()
    72  
    73  	specs := s.Scope.NICSpecs()
    74  	if len(specs) == 0 {
    75  		return nil
    76  	}
    77  
    78  	// We go through the list of NICSpecs to reconcile each one, independently of the result of the previous one.
    79  	// If multiple errors occur, we return the most pressing one.
    80  	//  Order of precedence (highest -> lowest) is: error that is not an operationNotDoneError (i.e. error creating) -> operationNotDoneError (i.e. creating in progress) -> no error (i.e. created)
    81  	var result error
    82  	for _, nicSpec := range specs {
    83  		if _, err := s.CreateOrUpdateResource(ctx, nicSpec, serviceName); err != nil {
    84  			if !azure.IsOperationNotDoneError(err) || result == nil {
    85  				result = err
    86  			}
    87  		}
    88  	}
    89  
    90  	s.Scope.UpdatePutStatus(infrav1.NetworkInterfaceReadyCondition, serviceName, result)
    91  	return result
    92  }
    93  
    94  // Delete deletes the network interface with the provided name.
    95  func (s *Service) Delete(ctx context.Context) error {
    96  	ctx, _, done := tele.StartSpanWithLogger(ctx, "networkinterfaces.Service.Delete")
    97  	defer done()
    98  
    99  	ctx, cancel := context.WithTimeout(ctx, s.Scope.DefaultedAzureServiceReconcileTimeout())
   100  	defer cancel()
   101  
   102  	specs := s.Scope.NICSpecs()
   103  	if len(specs) == 0 {
   104  		return nil
   105  	}
   106  
   107  	// We go through the list of NICSpecs to delete each one, independently of the result of the previous one.
   108  	// If multiple errors occur, we return the most pressing one.
   109  	//  Order of precedence (highest -> lowest) is: error that is not an operationNotDoneError (i.e. error deleting) -> operationNotDoneError (i.e. deleting in progress) -> no error (i.e. deleted)
   110  	var result error
   111  	for _, nicSpec := range specs {
   112  		if err := s.DeleteResource(ctx, nicSpec, serviceName); err != nil {
   113  			if !azure.IsOperationNotDoneError(err) || result == nil {
   114  				result = err
   115  			}
   116  		}
   117  	}
   118  
   119  	s.Scope.UpdateDeleteStatus(infrav1.NetworkInterfaceReadyCondition, serviceName, result)
   120  	return result
   121  }
   122  
   123  // IsManaged returns always returns true as CAPZ does not support BYO network interfaces.
   124  func (s *Service) IsManaged(ctx context.Context) (bool, error) {
   125  	return true, nil
   126  }