sigs.k8s.io/cluster-api-provider-azure@v1.14.3/controllers/azuremachine_reconciler.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 controllers
    18  
    19  import (
    20  	"context"
    21  
    22  	"github.com/pkg/errors"
    23  	"sigs.k8s.io/cluster-api-provider-azure/azure"
    24  	"sigs.k8s.io/cluster-api-provider-azure/azure/scope"
    25  	"sigs.k8s.io/cluster-api-provider-azure/azure/services/availabilitysets"
    26  	"sigs.k8s.io/cluster-api-provider-azure/azure/services/disks"
    27  	"sigs.k8s.io/cluster-api-provider-azure/azure/services/inboundnatrules"
    28  	"sigs.k8s.io/cluster-api-provider-azure/azure/services/networkinterfaces"
    29  	"sigs.k8s.io/cluster-api-provider-azure/azure/services/publicips"
    30  	"sigs.k8s.io/cluster-api-provider-azure/azure/services/resourceskus"
    31  	"sigs.k8s.io/cluster-api-provider-azure/azure/services/roleassignments"
    32  	"sigs.k8s.io/cluster-api-provider-azure/azure/services/tags"
    33  	"sigs.k8s.io/cluster-api-provider-azure/azure/services/virtualmachines"
    34  	"sigs.k8s.io/cluster-api-provider-azure/azure/services/vmextensions"
    35  	"sigs.k8s.io/cluster-api-provider-azure/util/tele"
    36  )
    37  
    38  // azureMachineService is the group of services called by the AzureMachine controller.
    39  type azureMachineService struct {
    40  	scope *scope.MachineScope
    41  	// services is the list of services to be reconciled.
    42  	// The order of the services is important as it determines the order in which the services are reconciled.
    43  	services  []azure.ServiceReconciler
    44  	skuCache  *resourceskus.Cache
    45  	Reconcile func(context.Context) error
    46  	Pause     func(context.Context) error
    47  	Delete    func(context.Context) error
    48  }
    49  
    50  // newAzureMachineService populates all the services based on input scope.
    51  func newAzureMachineService(machineScope *scope.MachineScope) (*azureMachineService, error) {
    52  	cache, err := resourceskus.GetCache(machineScope, machineScope.Location())
    53  	if err != nil {
    54  		return nil, errors.Wrap(err, "failed creating a NewCache")
    55  	}
    56  	availabilitySetsSvc, err := availabilitysets.New(machineScope, cache)
    57  	if err != nil {
    58  		return nil, errors.Wrap(err, "failed creating availabilitysets service")
    59  	}
    60  	disksSvc, err := disks.New(machineScope)
    61  	if err != nil {
    62  		return nil, errors.Wrap(err, "failed creating disks service")
    63  	}
    64  	inboundnatrulesSvc, err := inboundnatrules.New(machineScope)
    65  	if err != nil {
    66  		return nil, errors.Wrap(err, "failed creating inboundnatrules service")
    67  	}
    68  	publicIPsSvc, err := publicips.New(machineScope)
    69  	if err != nil {
    70  		return nil, errors.Wrap(err, "failed creating publicips service")
    71  	}
    72  	roleAssignmentsSvc, err := roleassignments.New(machineScope)
    73  	if err != nil {
    74  		return nil, errors.Wrap(err, "failed creating roleassignments service")
    75  	}
    76  	tagsSvc, err := tags.New(machineScope)
    77  	if err != nil {
    78  		return nil, errors.Wrap(err, "failed creating tags service")
    79  	}
    80  	virtualmachinesSvc, err := virtualmachines.New(machineScope)
    81  	if err != nil {
    82  		return nil, errors.Wrap(err, "failed creating virtualmachines service")
    83  	}
    84  	vmextensionsSvc, err := vmextensions.New(machineScope)
    85  	if err != nil {
    86  		return nil, errors.Wrap(err, "failed creating vmextensions service")
    87  	}
    88  	networkInterfacesSvc, err := networkinterfaces.New(machineScope, cache)
    89  	if err != nil {
    90  		return nil, errors.Wrap(err, "failed creating networkinterfaces service")
    91  	}
    92  	ams := &azureMachineService{
    93  		scope: machineScope,
    94  		services: []azure.ServiceReconciler{
    95  			publicIPsSvc,
    96  			inboundnatrulesSvc,
    97  			networkInterfacesSvc,
    98  			availabilitySetsSvc,
    99  			disksSvc,
   100  			virtualmachinesSvc,
   101  			roleAssignmentsSvc,
   102  			vmextensionsSvc,
   103  			tagsSvc,
   104  		},
   105  		skuCache: cache,
   106  	}
   107  	ams.Reconcile = ams.reconcile
   108  	ams.Pause = ams.pause
   109  	ams.Delete = ams.delete
   110  
   111  	return ams, nil
   112  }
   113  
   114  // reconcile reconciles all the services in a predetermined order.
   115  func (s *azureMachineService) reconcile(ctx context.Context) error {
   116  	ctx, _, done := tele.StartSpanWithLogger(ctx, "controllers.azureMachineService.reconcile")
   117  	defer done()
   118  
   119  	// Ensure that the deprecated networking field values have been migrated to the new NetworkInterfaces field.
   120  	s.scope.AzureMachine.Spec.SetNetworkInterfacesDefaults()
   121  
   122  	if err := s.scope.SetSubnetName(); err != nil {
   123  		return errors.Wrap(err, "failed defaulting subnet name")
   124  	}
   125  
   126  	for _, service := range s.services {
   127  		if err := service.Reconcile(ctx); err != nil {
   128  			return errors.Wrapf(err, "failed to reconcile AzureMachine service %s", service.Name())
   129  		}
   130  	}
   131  
   132  	return nil
   133  }
   134  
   135  // pause pauses all components making up the machine.
   136  func (s *azureMachineService) pause(ctx context.Context) error {
   137  	ctx, _, done := tele.StartSpanWithLogger(ctx, "controllers.azureMachineService.pause")
   138  	defer done()
   139  
   140  	for _, service := range s.services {
   141  		pauser, ok := service.(azure.Pauser)
   142  		if !ok {
   143  			continue
   144  		}
   145  		if err := pauser.Pause(ctx); err != nil {
   146  			return errors.Wrapf(err, "failed to pause AzureMachine service %s", service.Name())
   147  		}
   148  	}
   149  
   150  	return nil
   151  }
   152  
   153  // delete deletes all the services in a predetermined order.
   154  func (s *azureMachineService) delete(ctx context.Context) error {
   155  	ctx, _, done := tele.StartSpanWithLogger(ctx, "controllers.azureMachineService.delete")
   156  	defer done()
   157  
   158  	// Delete services in reverse order of creation.
   159  	for i := len(s.services) - 1; i >= 0; i-- {
   160  		if err := s.services[i].Delete(ctx); err != nil {
   161  			return errors.Wrapf(err, "failed to delete AzureMachine service %s", s.services[i].Name())
   162  		}
   163  	}
   164  
   165  	return nil
   166  }