sigs.k8s.io/cluster-api-provider-azure@v1.14.3/azure/services/vnetpeerings/vnetpeerings.go (about) 1 /* 2 Copyright 2021 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 vnetpeerings 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/util/tele" 27 ) 28 29 // ServiceName is the name of this service. 30 const ServiceName = "vnetpeerings" 31 32 // VnetPeeringScope defines the scope interface for a subnet service. 33 type VnetPeeringScope interface { 34 azure.Authorizer 35 azure.AsyncStatusUpdater 36 VnetPeeringSpecs() []azure.ResourceSpecGetter 37 } 38 39 // Service provides operations on Azure resources. 40 type Service struct { 41 Scope VnetPeeringScope 42 async.Reconciler 43 } 44 45 // New creates a new service. 46 func New(scope VnetPeeringScope) (*Service, error) { 47 Client, err := NewClient(scope, scope.DefaultedAzureCallTimeout()) 48 if err != nil { 49 return nil, err 50 } 51 return &Service{ 52 Scope: scope, 53 Reconciler: async.New[armnetwork.VirtualNetworkPeeringsClientCreateOrUpdateResponse, 54 armnetwork.VirtualNetworkPeeringsClientDeleteResponse](scope, Client, Client), 55 }, nil 56 } 57 58 // Name returns the service name. 59 func (s *Service) Name() string { 60 return ServiceName 61 } 62 63 // Reconcile idempotently creates or updates a peering. 64 func (s *Service) Reconcile(ctx context.Context) error { 65 ctx, _, done := tele.StartSpanWithLogger(ctx, "vnetpeerings.Service.Reconcile") 66 defer done() 67 68 ctx, cancel := context.WithTimeout(ctx, s.Scope.DefaultedAzureServiceReconcileTimeout()) 69 defer cancel() 70 71 specs := s.Scope.VnetPeeringSpecs() 72 if len(specs) == 0 { 73 return nil 74 } 75 76 // We go through the list of VnetPeeringSpecs to reconcile each one, independently of the result of the previous one. 77 // If multiple errors occur, we return the most pressing one. 78 // 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) 79 var result error 80 for _, peeringSpec := range specs { 81 if _, err := s.CreateOrUpdateResource(ctx, peeringSpec, ServiceName); err != nil { 82 if !azure.IsOperationNotDoneError(err) || result == nil { 83 result = err 84 } 85 } 86 } 87 88 s.Scope.UpdatePutStatus(infrav1.VnetPeeringReadyCondition, ServiceName, result) 89 return result 90 } 91 92 // Delete deletes the peering with the provided name. 93 func (s *Service) Delete(ctx context.Context) error { 94 ctx, _, done := tele.StartSpanWithLogger(ctx, "vnetpeerings.Service.Delete") 95 defer done() 96 97 ctx, cancel := context.WithTimeout(ctx, s.Scope.DefaultedAzureServiceReconcileTimeout()) 98 defer cancel() 99 100 specs := s.Scope.VnetPeeringSpecs() 101 if len(specs) == 0 { 102 return nil 103 } 104 105 // We go through the list of VnetPeeringSpecs to delete each one, independently of the result of the previous one. 106 // If multiple errors occur, we return the most pressing one. 107 // 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) 108 var result error 109 for _, peeringSpec := range specs { 110 if err := s.DeleteResource(ctx, peeringSpec, ServiceName); err != nil { 111 if !azure.IsOperationNotDoneError(err) || result == nil { 112 result = err 113 } 114 } 115 } 116 s.Scope.UpdateDeleteStatus(infrav1.VnetPeeringReadyCondition, ServiceName, result) 117 return result 118 } 119 120 // IsManaged returns always returns true as CAPZ does not support BYO VNet peering. 121 func (s *Service) IsManaged(ctx context.Context) (bool, error) { 122 return true, nil 123 }