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  }