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 }