sigs.k8s.io/cluster-api-provider-azure@v1.14.3/azure/services/inboundnatrules/client.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 inboundnatrules 18 19 import ( 20 "context" 21 "time" 22 23 "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" 24 "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v4" 25 "github.com/pkg/errors" 26 "sigs.k8s.io/cluster-api-provider-azure/azure" 27 "sigs.k8s.io/cluster-api-provider-azure/azure/services/async" 28 "sigs.k8s.io/cluster-api-provider-azure/util/tele" 29 ) 30 31 // client wraps go-sdk. 32 type client interface { 33 List(context.Context, string, string) (result []armnetwork.InboundNatRule, err error) 34 } 35 36 // azureClient contains the Azure go-sdk Client. 37 type azureClient struct { 38 inboundnatrules *armnetwork.InboundNatRulesClient 39 apiCallTimeout time.Duration 40 } 41 42 var _ client = (*azureClient)(nil) 43 44 // newClient creates a new inbound NAT rules client from an authorizer. 45 func newClient(auth azure.Authorizer, apiCallTimeout time.Duration) (*azureClient, error) { 46 opts, err := azure.ARMClientOptions(auth.CloudEnvironment()) 47 if err != nil { 48 return nil, errors.Wrap(err, "failed to create inboundnatrules client options") 49 } 50 factory, err := armnetwork.NewClientFactory(auth.SubscriptionID(), auth.Token(), opts) 51 if err != nil { 52 return nil, errors.Wrap(err, "failed to create armnetwork client factory") 53 } 54 return &azureClient{factory.NewInboundNatRulesClient(), apiCallTimeout}, nil 55 } 56 57 // Get gets the specified inbound NAT rules. 58 func (ac *azureClient) Get(ctx context.Context, spec azure.ResourceSpecGetter) (result interface{}, err error) { 59 ctx, _, done := tele.StartSpanWithLogger(ctx, "inboundnatrules.azureClient.Get") 60 defer done() 61 62 resp, err := ac.inboundnatrules.Get(ctx, spec.ResourceGroupName(), spec.OwnerResourceName(), spec.ResourceName(), nil) 63 if err != nil { 64 return nil, err 65 } 66 return resp.InboundNatRule, nil 67 } 68 69 // List returns all inbound NAT rules on a load balancer. 70 func (ac *azureClient) List(ctx context.Context, resourceGroupName, lbName string) (result []armnetwork.InboundNatRule, err error) { 71 ctx, _, done := tele.StartSpanWithLogger(ctx, "inboundnatrules.azureClient.List") 72 defer done() 73 74 var natRules []armnetwork.InboundNatRule 75 pager := ac.inboundnatrules.NewListPager(resourceGroupName, lbName, nil) 76 for pager.More() { 77 nextResult, err := pager.NextPage(ctx) 78 if err != nil { 79 return natRules, errors.Wrap(err, "could not iterate inbound NAT rules") 80 } 81 for _, natRule := range nextResult.Value { 82 natRules = append(natRules, *natRule) 83 } 84 } 85 86 return natRules, nil 87 } 88 89 // CreateOrUpdateAsync creates or updates an inbound NAT rule asynchronously. 90 // It sends a PUT request to Azure and if accepted without error, the func will return a Poller which can be used to track the ongoing 91 // progress of the operation. 92 func (ac *azureClient) CreateOrUpdateAsync(ctx context.Context, spec azure.ResourceSpecGetter, resumeToken string, parameters interface{}) (result interface{}, poller *runtime.Poller[armnetwork.InboundNatRulesClientCreateOrUpdateResponse], err error) { 93 ctx, log, done := tele.StartSpanWithLogger(ctx, "inboundnatrules.azureClient.CreateOrUpdateAsync") 94 defer done() 95 96 natRule, ok := parameters.(armnetwork.InboundNatRule) 97 if !ok && parameters != nil { 98 return nil, nil, errors.Errorf("%T is not an armnetwork.InboundNatRule", parameters) 99 } 100 101 opts := &armnetwork.InboundNatRulesClientBeginCreateOrUpdateOptions{ResumeToken: resumeToken} 102 log.V(4).Info("sending request", "resumeToken", resumeToken) 103 poller, err = ac.inboundnatrules.BeginCreateOrUpdate(ctx, spec.ResourceGroupName(), spec.OwnerResourceName(), spec.ResourceName(), natRule, opts) 104 if err != nil { 105 return nil, nil, err 106 } 107 108 ctx, cancel := context.WithTimeout(ctx, ac.apiCallTimeout) 109 defer cancel() 110 111 pollOpts := &runtime.PollUntilDoneOptions{Frequency: async.DefaultPollerFrequency} 112 resp, err := poller.PollUntilDone(ctx, pollOpts) 113 if err != nil { 114 // If an error occurs, return the poller. 115 // This means the long-running operation didn't finish in the specified timeout. 116 return nil, poller, err 117 } 118 119 // if the operation completed, return a nil poller 120 return resp.InboundNatRule, nil, err 121 } 122 123 // DeleteAsync deletes an inbound NAT rule asynchronously. DeleteAsync sends a DELETE 124 // request to Azure and if accepted without error, the func will return a Poller which can be used to track the ongoing 125 // progress of the operation. 126 func (ac *azureClient) DeleteAsync(ctx context.Context, spec azure.ResourceSpecGetter, resumeToken string) (poller *runtime.Poller[armnetwork.InboundNatRulesClientDeleteResponse], err error) { 127 ctx, log, done := tele.StartSpanWithLogger(ctx, "inboundnatrules.azureClient.DeleteAsync") 128 defer done() 129 130 opts := &armnetwork.InboundNatRulesClientBeginDeleteOptions{ResumeToken: resumeToken} 131 log.V(4).Info("sending request", "resumeToken", resumeToken) 132 poller, err = ac.inboundnatrules.BeginDelete(ctx, spec.ResourceGroupName(), spec.OwnerResourceName(), spec.ResourceName(), opts) 133 if err != nil { 134 return nil, err 135 } 136 137 ctx, cancel := context.WithTimeout(ctx, ac.apiCallTimeout) 138 defer cancel() 139 140 pollOpts := &runtime.PollUntilDoneOptions{Frequency: async.DefaultPollerFrequency} 141 _, err = poller.PollUntilDone(ctx, pollOpts) 142 if err != nil { 143 // if an error occurs, return the poller. 144 // this means the long-running operation didn't finish in the specified timeout. 145 return poller, err 146 } 147 // if the operation completed, return a nil poller. 148 return nil, err 149 }