sigs.k8s.io/cluster-api-provider-azure@v1.14.3/azure/services/vmextensions/client.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 vmextensions
    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/compute/armcompute/v5"
    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  // azureClient contains the Azure go-sdk Client.
    32  type azureClient struct {
    33  	vmextensions   *armcompute.VirtualMachineExtensionsClient
    34  	apiCallTimeout time.Duration
    35  }
    36  
    37  // newClient creates a new vm extensions client from an authorizer.
    38  func newClient(auth azure.Authorizer, apiCallTimeout time.Duration) (*azureClient, error) {
    39  	opts, err := azure.ARMClientOptions(auth.CloudEnvironment())
    40  	if err != nil {
    41  		return nil, errors.Wrap(err, "failed to create virtualmachineextensions client options")
    42  	}
    43  	factory, err := armcompute.NewClientFactory(auth.SubscriptionID(), auth.Token(), opts)
    44  	if err != nil {
    45  		return nil, errors.Wrap(err, "failed to create armcompute client factory")
    46  	}
    47  	return &azureClient{factory.NewVirtualMachineExtensionsClient(), apiCallTimeout}, nil
    48  }
    49  
    50  // Get the specified virtual machine extension.
    51  func (ac *azureClient) Get(ctx context.Context, spec azure.ResourceSpecGetter) (result interface{}, err error) {
    52  	ctx, _, done := tele.StartSpanWithLogger(ctx, "vmextensions.azureClient.Get")
    53  	defer done()
    54  
    55  	resp, err := ac.vmextensions.Get(ctx, spec.ResourceGroupName(), spec.OwnerResourceName(), spec.ResourceName(), nil)
    56  	if err != nil {
    57  		return nil, err
    58  	}
    59  	return resp.VirtualMachineExtension, nil
    60  }
    61  
    62  // CreateOrUpdateAsync creates or updates a VM extension asynchronously.
    63  // 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
    64  // progress of the operation.
    65  func (ac *azureClient) CreateOrUpdateAsync(ctx context.Context, spec azure.ResourceSpecGetter, resumeToken string, parameters interface{}) (result interface{}, poller *runtime.Poller[armcompute.VirtualMachineExtensionsClientCreateOrUpdateResponse], err error) {
    66  	ctx, _, done := tele.StartSpanWithLogger(ctx, "vmextensions.azureClient.CreateOrUpdateAsync")
    67  	defer done()
    68  
    69  	vmextension, ok := parameters.(armcompute.VirtualMachineExtension)
    70  	if !ok && parameters != nil {
    71  		return nil, nil, errors.Errorf("%T is not an armcompute.VirtualMachineExtension", parameters)
    72  	}
    73  
    74  	opts := &armcompute.VirtualMachineExtensionsClientBeginCreateOrUpdateOptions{ResumeToken: resumeToken}
    75  	poller, err = ac.vmextensions.BeginCreateOrUpdate(ctx, spec.ResourceGroupName(), spec.OwnerResourceName(), spec.ResourceName(), vmextension, opts)
    76  	if err != nil {
    77  		return nil, nil, err
    78  	}
    79  
    80  	ctx, cancel := context.WithTimeout(ctx, ac.apiCallTimeout)
    81  	defer cancel()
    82  
    83  	pollOpts := &runtime.PollUntilDoneOptions{Frequency: async.DefaultPollerFrequency}
    84  	resp, err := poller.PollUntilDone(ctx, pollOpts)
    85  	if err != nil {
    86  		// if an error occurs, return the poller.
    87  		// this means the long-running operation didn't finish in the specified timeout.
    88  		return nil, poller, err
    89  	}
    90  
    91  	// if the operation completed, return a nil poller
    92  	return resp.VirtualMachineExtension, nil, err
    93  }
    94  
    95  // DeleteAsync deletes a VM extension asynchronously. DeleteAsync sends a DELETE
    96  // request to Azure and if accepted without error, the func will return a Poller which can be used to track the ongoing
    97  // progress of the operation.
    98  func (ac *azureClient) DeleteAsync(ctx context.Context, spec azure.ResourceSpecGetter, resumeToken string) (poller *runtime.Poller[armcompute.VirtualMachineExtensionsClientDeleteResponse], err error) {
    99  	ctx, _, done := tele.StartSpanWithLogger(ctx, "vmextensions.azureClient.DeleteAsync")
   100  	defer done()
   101  
   102  	opts := &armcompute.VirtualMachineExtensionsClientBeginDeleteOptions{ResumeToken: resumeToken}
   103  	poller, err = ac.vmextensions.BeginDelete(ctx, spec.ResourceGroupName(), spec.OwnerResourceName(), spec.ResourceName(), opts)
   104  	if err != nil {
   105  		return nil, err
   106  	}
   107  
   108  	ctx, cancel := context.WithTimeout(ctx, ac.apiCallTimeout)
   109  	defer cancel()
   110  
   111  	pollOpts := &runtime.PollUntilDoneOptions{Frequency: async.DefaultPollerFrequency}
   112  	_, 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 poller, err
   117  	}
   118  
   119  	// if the operation completed, return a nil poller.
   120  	return nil, err
   121  }