azure: Migrate cloudup to new SDK version

This commit is contained in:
Ciprian Hacman 2024-01-28 07:13:17 +02:00
parent 6c4c7d9c00
commit a1242efe71
18 changed files with 563 additions and 443 deletions

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2023 The Kubernetes Authors. Copyright 2024 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -20,14 +20,14 @@ import (
"context" "context"
"fmt" "fmt"
"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2022-05-01/network" "github.com/Azure/azure-sdk-for-go/sdk/azidentity"
"github.com/Azure/go-autorest/autorest" network "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork"
) )
// ApplicationSecurityGroupsClient is a client for managing Application Security Groups. // ApplicationSecurityGroupsClient is a client for managing application security groups.
type ApplicationSecurityGroupsClient interface { type ApplicationSecurityGroupsClient interface {
CreateOrUpdate(ctx context.Context, resourceGroupName, applicationSecurityGroupName string, parameters network.ApplicationSecurityGroup) (*network.ApplicationSecurityGroup, error) CreateOrUpdate(ctx context.Context, resourceGroupName, applicationSecurityGroupName string, parameters network.ApplicationSecurityGroup) (*network.ApplicationSecurityGroup, error)
List(ctx context.Context, resourceGroupName string) ([]network.ApplicationSecurityGroup, error) List(ctx context.Context, resourceGroupName string) ([]*network.ApplicationSecurityGroup, error)
Delete(ctx context.Context, resourceGroupName, applicationSecurityGroupName string) error Delete(ctx context.Context, resourceGroupName, applicationSecurityGroupName string) error
} }
@ -38,46 +38,47 @@ type ApplicationSecurityGroupsClientImpl struct {
var _ ApplicationSecurityGroupsClient = &ApplicationSecurityGroupsClientImpl{} var _ ApplicationSecurityGroupsClient = &ApplicationSecurityGroupsClientImpl{}
func (c *ApplicationSecurityGroupsClientImpl) CreateOrUpdate(ctx context.Context, resourceGroupName, applicationSecurityGroupName string, parameters network.ApplicationSecurityGroup) (*network.ApplicationSecurityGroup, error) { func (c *ApplicationSecurityGroupsClientImpl) CreateOrUpdate(ctx context.Context, resourceGroupName, applicationSecurityGroupName string, parameters network.ApplicationSecurityGroup) (*network.ApplicationSecurityGroup, error) {
future, err := c.c.CreateOrUpdate(ctx, resourceGroupName, applicationSecurityGroupName, parameters) future, err := c.c.BeginCreateOrUpdate(ctx, resourceGroupName, applicationSecurityGroupName, parameters, nil)
if err != nil { if err != nil {
return nil, fmt.Errorf("creating/updating Application Security Group: %w", err) return nil, fmt.Errorf("creating/updating application security group: %w", err)
} }
if err := future.WaitForCompletionRef(ctx, c.c.Client); err != nil { asg, err := future.PollUntilDone(ctx, nil)
return nil, fmt.Errorf("waiting for Application Security Group create/update completion: %w", err)
}
asg, err := future.Result(*c.c)
if err != nil { if err != nil {
return nil, fmt.Errorf("obtaining result for Application Security Group create/update: %w", err) return nil, fmt.Errorf("waiting for application security group create/update completion: %w", err)
} }
return &asg, err return &asg.ApplicationSecurityGroup, err
} }
func (c *ApplicationSecurityGroupsClientImpl) List(ctx context.Context, resourceGroupName string) ([]network.ApplicationSecurityGroup, error) { func (c *ApplicationSecurityGroupsClientImpl) List(ctx context.Context, resourceGroupName string) ([]*network.ApplicationSecurityGroup, error) {
var l []network.ApplicationSecurityGroup var l []*network.ApplicationSecurityGroup
for iter, err := c.c.ListComplete(ctx, resourceGroupName); iter.NotDone(); err = iter.NextWithContext(ctx) { pager := c.c.NewListPager(resourceGroupName, nil)
for pager.More() {
resp, err := pager.NextPage(ctx)
if err != nil { if err != nil {
return nil, fmt.Errorf("listing application security groups: %w", err) return nil, fmt.Errorf("listing application security groups: %w", err)
} }
l = append(l, iter.Value()) l = append(l, resp.Value...)
} }
return l, nil return l, nil
} }
func (c *ApplicationSecurityGroupsClientImpl) Delete(ctx context.Context, resourceGroupName, applicationSecurityGroupName string) error { func (c *ApplicationSecurityGroupsClientImpl) Delete(ctx context.Context, resourceGroupName, applicationSecurityGroupName string) error {
future, err := c.c.Delete(ctx, resourceGroupName, applicationSecurityGroupName) future, err := c.c.BeginDelete(ctx, resourceGroupName, applicationSecurityGroupName, nil)
if err != nil { if err != nil {
return fmt.Errorf("deleting application security group: %w", err) return fmt.Errorf("deleting application security group: %w", err)
} }
if err := future.WaitForCompletionRef(ctx, c.c.Client); err != nil { if _, err = future.PollUntilDone(ctx, nil); err != nil {
return fmt.Errorf("waiting for application security group deletion completion: %w", err) return fmt.Errorf("waiting for application security group deletion completion: %w", err)
} }
return nil return nil
} }
func newApplicationSecurityGroupsClientImpl(subscriptionID string, authorizer autorest.Authorizer) *ApplicationSecurityGroupsClientImpl { func newApplicationSecurityGroupsClientImpl(subscriptionID string, cred *azidentity.DefaultAzureCredential) (*ApplicationSecurityGroupsClientImpl, error) {
c := network.NewApplicationSecurityGroupsClient(subscriptionID) c, err := network.NewApplicationSecurityGroupsClient(subscriptionID, cred, nil)
c.Authorizer = authorizer if err != nil {
return &ApplicationSecurityGroupsClientImpl{ return nil, fmt.Errorf("creating application security groups client: %w", err)
c: &c,
} }
return &ApplicationSecurityGroupsClientImpl{
c: c,
}, nil
} }

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2020 The Kubernetes Authors. Copyright 2024 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -21,7 +21,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"github.com/Azure/go-autorest/autorest/azure/auth" "github.com/Azure/azure-sdk-for-go/sdk/azidentity"
"k8s.io/klog/v2" "k8s.io/klog/v2"
"k8s.io/kops/dnsprovider/pkg/dnsprovider" "k8s.io/kops/dnsprovider/pkg/dnsprovider"
"k8s.io/kops/pkg/apis/kops" "k8s.io/kops/pkg/apis/kops"
@ -85,30 +85,61 @@ var _ fi.Cloud = &azureCloudImplementation{}
// NewAzureCloud creates a new AzureCloud. // NewAzureCloud creates a new AzureCloud.
func NewAzureCloud(subscriptionID, location string, tags map[string]string) (AzureCloud, error) { func NewAzureCloud(subscriptionID, location string, tags map[string]string) (AzureCloud, error) {
authorizer, err := auth.NewAuthorizerFromEnvironment() cred, err := azidentity.NewDefaultAzureCredential(nil)
if err != nil { if err != nil {
return nil, fmt.Errorf("error creating an identity: %s", err)
}
azureCloudImpl := &azureCloudImplementation{
subscriptionID: subscriptionID,
location: location,
tags: tags,
}
if azureCloudImpl.resourceGroupsClient, err = newResourceGroupsClientImpl(subscriptionID, cred); err != nil {
return nil, err
}
if azureCloudImpl.vnetsClient, err = newVirtualNetworksClientImpl(subscriptionID, cred); err != nil {
return nil, err
}
if azureCloudImpl.subnetsClient, err = newSubnetsClientImpl(subscriptionID, cred); err != nil {
return nil, err
}
if azureCloudImpl.routeTablesClient, err = newRouteTablesClientImpl(subscriptionID, cred); err != nil {
return nil, err
}
if azureCloudImpl.networkSecurityGroupsClient, err = newNetworkSecurityGroupsClientImpl(subscriptionID, cred); err != nil {
return nil, err
}
if azureCloudImpl.applicationSecurityGroupsClient, err = newApplicationSecurityGroupsClientImpl(subscriptionID, cred); err != nil {
return nil, err
}
if azureCloudImpl.vmscaleSetsClient, err = newVMScaleSetsClientImpl(subscriptionID, cred); err != nil {
return nil, err
}
if azureCloudImpl.vmscaleSetVMsClient, err = newVMScaleSetVMsClientImpl(subscriptionID, cred); err != nil {
return nil, err
}
if azureCloudImpl.disksClient, err = newDisksClientImpl(subscriptionID, cred); err != nil {
return nil, err
}
if azureCloudImpl.roleAssignmentsClient, err = newRoleAssignmentsClientImpl(subscriptionID, cred); err != nil {
return nil, err
}
if azureCloudImpl.networkInterfacesClient, err = newNetworkInterfacesClientImpl(subscriptionID, cred); err != nil {
return nil, err
}
if azureCloudImpl.loadBalancersClient, err = newLoadBalancersClientImpl(subscriptionID, cred); err != nil {
return nil, err
}
if azureCloudImpl.publicIPAddressesClient, err = newPublicIPAddressesClientImpl(subscriptionID, cred); err != nil {
return nil, err
}
if azureCloudImpl.natGatewaysClient, err = newNatGatewaysClientImpl(subscriptionID, cred); err != nil {
return nil, err return nil, err
} }
return &azureCloudImplementation{ return azureCloudImpl, nil
subscriptionID: subscriptionID,
location: location,
tags: tags,
resourceGroupsClient: newResourceGroupsClientImpl(subscriptionID, authorizer),
vnetsClient: newVirtualNetworksClientImpl(subscriptionID, authorizer),
subnetsClient: newSubnetsClientImpl(subscriptionID, authorizer),
routeTablesClient: newRouteTablesClientImpl(subscriptionID, authorizer),
networkSecurityGroupsClient: newNetworkSecurityGroupsClientImpl(subscriptionID, authorizer),
applicationSecurityGroupsClient: newApplicationSecurityGroupsClientImpl(subscriptionID, authorizer),
vmscaleSetsClient: newVMScaleSetsClientImpl(subscriptionID, authorizer),
vmscaleSetVMsClient: newVMScaleSetVMsClientImpl(subscriptionID, authorizer),
disksClient: newDisksClientImpl(subscriptionID, authorizer),
roleAssignmentsClient: newRoleAssignmentsClientImpl(subscriptionID, authorizer),
networkInterfacesClient: newNetworkInterfacesClientImpl(subscriptionID, authorizer),
loadBalancersClient: newLoadBalancersClientImpl(subscriptionID, authorizer),
publicIPAddressesClient: newPublicIPAddressesClientImpl(subscriptionID, authorizer),
natGatewaysClient: newNatGatewaysClientImpl(subscriptionID, authorizer),
}, nil
} }
func (c *azureCloudImplementation) Region() string { func (c *azureCloudImplementation) Region() string {
@ -136,15 +167,24 @@ func (c *azureCloudImplementation) FindVNetInfo(id, resourceGroup string) (*fi.V
if *vnet.ID != id { if *vnet.ID != id {
continue continue
} }
if vnet.Properties == nil {
continue
}
subnets := make([]*fi.SubnetInfo, 0) subnets := make([]*fi.SubnetInfo, 0)
for _, subnet := range *vnet.Subnets { for _, subnet := range vnet.Properties.Subnets {
if subnet.Properties == nil {
continue
}
subnets = append(subnets, &fi.SubnetInfo{ subnets = append(subnets, &fi.SubnetInfo{
ID: *subnet.ID, ID: *subnet.ID,
CIDR: *subnet.AddressPrefix, CIDR: *subnet.Properties.AddressPrefix,
}) })
} }
if vnet.Properties.AddressSpace == nil || len(vnet.Properties.AddressSpace.AddressPrefixes) == 0 {
continue
}
return &fi.VPCInfo{ return &fi.VPCInfo{
CIDR: (*vnet.AddressSpace.AddressPrefixes)[0], CIDR: *vnet.Properties.AddressSpace.AddressPrefixes[0],
Subnets: subnets, Subnets: subnets,
}, nil }, nil
} }
@ -182,10 +222,10 @@ func (c *azureCloudImplementation) GetApiIngressStatus(cluster *kops.Cluster) ([
lbSpec := cluster.Spec.API.LoadBalancer lbSpec := cluster.Spec.API.LoadBalancer
if lbSpec != nil { if lbSpec != nil {
// Get loadbalancers in cluster resource group // Get load balancers in cluster resource group
lbs, err := c.loadBalancersClient.List(context.TODO(), rg) lbs, err := c.loadBalancersClient.List(context.TODO(), rg)
if err != nil { if err != nil {
return nil, fmt.Errorf("error getting Loadbalancer for API Ingress Status: %s", err) return nil, fmt.Errorf("getting Loadbalancer for API Ingress Status: %w", err)
} }
for _, lb := range lbs { for _, lb := range lbs {
@ -193,24 +233,23 @@ func (c *azureCloudImplementation) GetApiIngressStatus(cluster *kops.Cluster) ([
if val == nil || *val != cluster.Name { if val == nil || *val != cluster.Name {
continue continue
} }
if lb.LoadBalancerPropertiesFormat == nil { if lb.Properties == nil {
continue continue
} }
for _, i := range *lb.LoadBalancerPropertiesFormat.FrontendIPConfigurations { for _, i := range lb.Properties.FrontendIPConfigurations {
if i.FrontendIPConfigurationPropertiesFormat == nil { if i.Properties == nil {
continue continue
} }
switch lbSpec.Type { switch lbSpec.Type {
case kops.LoadBalancerTypeInternal: case kops.LoadBalancerTypeInternal:
if i.FrontendIPConfigurationPropertiesFormat.PrivateIPAddress == nil { if i.Properties.PrivateIPAddress == nil {
continue continue
} }
ingresses = append(ingresses, fi.ApiIngressStatus{ ingresses = append(ingresses, fi.ApiIngressStatus{
IP: *i.FrontendIPConfigurationPropertiesFormat.PrivateIPAddress, IP: *i.Properties.PrivateIPAddress,
}) })
case kops.LoadBalancerTypePublic: case kops.LoadBalancerTypePublic:
if i.FrontendIPConfigurationPropertiesFormat.PublicIPAddress == nil || if i.Properties.PublicIPAddress == nil || i.Properties.PublicIPAddress.ID == nil {
i.FrontendIPConfigurationPropertiesFormat.PublicIPAddress.ID == nil {
continue continue
} }
pips, err := c.publicIPAddressesClient.List(context.TODO(), rg) pips, err := c.publicIPAddressesClient.List(context.TODO(), rg)
@ -218,17 +257,15 @@ func (c *azureCloudImplementation) GetApiIngressStatus(cluster *kops.Cluster) ([
return nil, fmt.Errorf("error getting PublicIPAddress for API Ingress Status: %w", err) return nil, fmt.Errorf("error getting PublicIPAddress for API Ingress Status: %w", err)
} }
for _, pip := range pips { for _, pip := range pips {
if *pip.ID != *i.FrontendIPConfigurationPropertiesFormat.PublicIPAddress.ID { if pip.ID == nil || pip.Properties == nil || pip.Properties.IPAddress == nil || *pip.ID != *i.Properties.PublicIPAddress.ID {
continue continue
} }
if pip.IPAddress != nil { ingresses = append(ingresses, fi.ApiIngressStatus{
ingresses = append(ingresses, fi.ApiIngressStatus{ IP: *pip.Properties.IPAddress,
IP: *pip.IPAddress, })
})
}
} }
default: default:
return nil, fmt.Errorf("unknown load balancer Type: %q", lbSpec.Type) return nil, fmt.Errorf("unknown load balancer type: %q", lbSpec.Type)
} }
} }
} }
@ -236,7 +273,7 @@ func (c *azureCloudImplementation) GetApiIngressStatus(cluster *kops.Cluster) ([
// Get scale sets in cluster resource group and find masters scale set // Get scale sets in cluster resource group and find masters scale set
scaleSets, err := c.vmscaleSetsClient.List(context.TODO(), rg) scaleSets, err := c.vmscaleSetsClient.List(context.TODO(), rg)
if err != nil { if err != nil {
return nil, fmt.Errorf("error getting Cluster Master Scale Set for API Ingress Status: %s", err) return nil, fmt.Errorf("getting cluster control plane VMSS for API ingress status: %w", err)
} }
var vmssName string var vmssName string
for _, scaleSet := range scaleSets { for _, scaleSet := range scaleSets {
@ -249,26 +286,29 @@ func (c *azureCloudImplementation) GetApiIngressStatus(cluster *kops.Cluster) ([
} }
} }
if vmssName == "" { if vmssName == "" {
return nil, fmt.Errorf("error getting Master Scale Set Name for API Ingress Status") return nil, fmt.Errorf("getting control plane VMSS name for API ingress status")
} }
// Get masters scale set network interfaces and append to api ingress status // Get masters scale set network interfaces and append to api ingress status
nis, err := c.NetworkInterface().ListScaleSetsNetworkInterfaces(context.TODO(), rg, vmssName) nis, err := c.NetworkInterface().ListScaleSetsNetworkInterfaces(context.TODO(), rg, vmssName)
if err != nil { if err != nil {
return nil, fmt.Errorf("error getting Master Scale Set Network Interfaces for API Ingress Status: %s", err) return nil, fmt.Errorf("getting control plane VMSS network interfaces for API ingress status: %w", err)
} }
for _, ni := range nis { for _, ni := range nis {
if ni.Primary == nil || !*ni.Primary { if ni.Properties == nil || ni.Properties.Primary == nil || !*ni.Properties.Primary {
continue continue
} }
for _, i := range *ni.IPConfigurations { for _, i := range ni.Properties.IPConfigurations {
if i.Properties == nil || i.Properties.PrivateIPAddress == nil {
continue
}
ingresses = append(ingresses, fi.ApiIngressStatus{ ingresses = append(ingresses, fi.ApiIngressStatus{
IP: *i.PrivateIPAddress, IP: *i.Properties.PrivateIPAddress,
}) })
} }
} }
if ingresses == nil { if ingresses == nil {
return nil, fmt.Errorf("error getting API Ingress Status so make sure to update your kubecfg accordingly") return nil, fmt.Errorf("getting API ingress status")
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2020 The Kubernetes Authors. Copyright 2024 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -20,14 +20,14 @@ import (
"context" "context"
"fmt" "fmt"
"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2022-08-01/compute" "github.com/Azure/azure-sdk-for-go/sdk/azidentity"
"github.com/Azure/go-autorest/autorest" compute "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute"
) )
// DisksClient is a client for managing VM Scale Set. // DisksClient is a client for managing disks.
type DisksClient interface { type DisksClient interface {
CreateOrUpdate(ctx context.Context, resourceGroupName, diskName string, parameters compute.Disk) error CreateOrUpdate(ctx context.Context, resourceGroupName, diskName string, parameters compute.Disk) (*compute.Disk, error)
List(ctx context.Context, resourceGroupName string) ([]compute.Disk, error) List(ctx context.Context, resourceGroupName string) ([]*compute.Disk, error)
Delete(ctx context.Context, resourceGroupName, diskname string) error Delete(ctx context.Context, resourceGroupName, diskname string) error
} }
@ -37,37 +37,48 @@ type disksClientImpl struct {
var _ DisksClient = &disksClientImpl{} var _ DisksClient = &disksClientImpl{}
func (c *disksClientImpl) CreateOrUpdate(ctx context.Context, resourceGroupName, diskName string, parameters compute.Disk) error { func (c *disksClientImpl) CreateOrUpdate(ctx context.Context, resourceGroupName, diskName string, parameters compute.Disk) (*compute.Disk, error) {
_, err := c.c.CreateOrUpdate(ctx, resourceGroupName, diskName, parameters) future, err := c.c.BeginCreateOrUpdate(ctx, resourceGroupName, diskName, parameters, nil)
return err if err != nil {
return nil, fmt.Errorf("creating/updating disk: %w", err)
}
resp, err := future.PollUntilDone(ctx, nil)
if err != nil {
return nil, fmt.Errorf("waiting for disk create/update completion: %w", err)
}
return &resp.Disk, err
} }
func (c *disksClientImpl) List(ctx context.Context, resourceGroupName string) ([]compute.Disk, error) { func (c *disksClientImpl) List(ctx context.Context, resourceGroupName string) ([]*compute.Disk, error) {
var l []compute.Disk var l []*compute.Disk
for iter, err := c.c.ListByResourceGroupComplete(ctx, resourceGroupName); iter.NotDone(); err = iter.Next() { pager := c.c.NewListPager(nil)
for pager.More() {
resp, err := pager.NextPage(ctx)
if err != nil { if err != nil {
return nil, err return nil, fmt.Errorf("listing disks: %w", err)
} }
l = append(l, iter.Value()) l = append(l, resp.Value...)
} }
return l, nil return l, nil
} }
func (c *disksClientImpl) Delete(ctx context.Context, resourceGroupName, diskName string) error { func (c *disksClientImpl) Delete(ctx context.Context, resourceGroupName, diskName string) error {
future, err := c.c.Delete(ctx, resourceGroupName, diskName) future, err := c.c.BeginDelete(ctx, resourceGroupName, diskName, nil)
if err != nil { if err != nil {
return fmt.Errorf("error deleting disk: %s", err) return fmt.Errorf("deleting disk: %w", err)
} }
if err := future.WaitForCompletionRef(ctx, c.c.Client); err != nil { if _, err := future.PollUntilDone(ctx, nil); err != nil {
return fmt.Errorf("error waiting for disk deletion completion: %s", err) return fmt.Errorf("waiting for disk deletion completion: %w", err)
} }
return nil return nil
} }
func newDisksClientImpl(subscriptionID string, authorizer autorest.Authorizer) *disksClientImpl { func newDisksClientImpl(subscriptionID string, cred *azidentity.DefaultAzureCredential) (*disksClientImpl, error) {
c := compute.NewDisksClient(subscriptionID) c, err := compute.NewDisksClient(subscriptionID, cred, nil)
c.Authorizer = authorizer if err != nil {
return &disksClientImpl{ return nil, fmt.Errorf("creating disks client: %w", err)
c: &c,
} }
return &disksClientImpl{
c: c,
}, nil
} }

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2020 The Kubernetes Authors. Copyright 2024 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -20,14 +20,15 @@ import (
"context" "context"
"fmt" "fmt"
"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2022-05-01/network" "github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
"github.com/Azure/go-autorest/autorest" "github.com/Azure/azure-sdk-for-go/sdk/azidentity"
network "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork"
) )
// LoadBalancersClient is a client for connecting to the kubernetes api. // LoadBalancersClient is a client for managing load balancers.
type LoadBalancersClient interface { type LoadBalancersClient interface {
CreateOrUpdate(ctx context.Context, resourceGroupName, loadBalancerName string, parameters network.LoadBalancer) error CreateOrUpdate(ctx context.Context, resourceGroupName, loadBalancerName string, parameters network.LoadBalancer) (*network.LoadBalancer, error)
List(ctx context.Context, resourceGroupName string) ([]network.LoadBalancer, error) List(ctx context.Context, resourceGroupName string) ([]*network.LoadBalancer, error)
Get(ctx context.Context, resourceGroupName string, loadBalancerName string) (*network.LoadBalancer, error) Get(ctx context.Context, resourceGroupName string, loadBalancerName string) (*network.LoadBalancer, error)
Delete(ctx context.Context, resourceGroupName, loadBalancerName string) error Delete(ctx context.Context, resourceGroupName, loadBalancerName string) error
} }
@ -38,45 +39,59 @@ type loadBalancersClientImpl struct {
var _ LoadBalancersClient = &loadBalancersClientImpl{} var _ LoadBalancersClient = &loadBalancersClientImpl{}
func (c *loadBalancersClientImpl) CreateOrUpdate(ctx context.Context, resourceGroupName, loadBalancerName string, parameters network.LoadBalancer) error { func (c *loadBalancersClientImpl) CreateOrUpdate(ctx context.Context, resourceGroupName, loadBalancerName string, parameters network.LoadBalancer) (*network.LoadBalancer, error) {
_, err := c.c.CreateOrUpdate(ctx, resourceGroupName, loadBalancerName, parameters) future, err := c.c.BeginCreateOrUpdate(ctx, resourceGroupName, loadBalancerName, parameters, nil)
return err if err != nil {
return nil, fmt.Errorf("creating/updating load balancer: %w", err)
}
resp, err := future.PollUntilDone(ctx, nil)
if err != nil {
return nil, fmt.Errorf("waiting for load balancer create/update: %w", err)
}
return &resp.LoadBalancer, nil
} }
func (c *loadBalancersClientImpl) List(ctx context.Context, resourceGroupName string) ([]network.LoadBalancer, error) { func (c *loadBalancersClientImpl) List(ctx context.Context, resourceGroupName string) ([]*network.LoadBalancer, error) {
var l []network.LoadBalancer var l []*network.LoadBalancer
for iter, err := c.c.ListComplete(ctx, resourceGroupName); iter.NotDone(); err = iter.Next() { pager := c.c.NewListPager(resourceGroupName, nil)
for pager.More() {
resp, err := pager.NextPage(ctx)
if err != nil { if err != nil {
return nil, err return nil, fmt.Errorf("listing load balancers: %w", err)
} }
l = append(l, iter.Value()) l = append(l, resp.Value...)
} }
return l, nil return l, nil
} }
func (c *loadBalancersClientImpl) Get(ctx context.Context, resourceGroupName string, loadBalancerName string) (*network.LoadBalancer, error) { func (c *loadBalancersClientImpl) Get(ctx context.Context, resourceGroupName string, loadBalancerName string) (*network.LoadBalancer, error) {
l, err := c.c.Get(ctx, resourceGroupName, loadBalancerName, "frontendIpConfigurations/publicIpAddress") opts := &network.LoadBalancersClientGetOptions{
if err != nil { Expand: to.Ptr("frontendIpConfigurations/publicIpAddress"),
return nil, err
} }
return &l, nil resp, err := c.c.Get(ctx, resourceGroupName, loadBalancerName, opts)
if err != nil {
return nil, fmt.Errorf("getting load balancer: %w", err)
}
return &resp.LoadBalancer, nil
} }
func (c *loadBalancersClientImpl) Delete(ctx context.Context, resourceGroupName, loadBalancerName string) error { func (c *loadBalancersClientImpl) Delete(ctx context.Context, resourceGroupName, loadBalancerName string) error {
future, err := c.c.Delete(ctx, resourceGroupName, loadBalancerName) future, err := c.c.BeginDelete(ctx, resourceGroupName, loadBalancerName, nil)
if err != nil { if err != nil {
return fmt.Errorf("error deleting loadbalancer: %s", err) return fmt.Errorf("deleting load balancer: %w", err)
} }
if err := future.WaitForCompletionRef(ctx, c.c.Client); err != nil { if _, err := future.PollUntilDone(ctx, nil); err != nil {
return fmt.Errorf("error waiting for loadbalancer deletion completion: %s", err) return fmt.Errorf("waiting for load balancer deletion completion: %w", err)
} }
return nil return nil
} }
func newLoadBalancersClientImpl(subscriptionID string, authorizer autorest.Authorizer) *loadBalancersClientImpl { func newLoadBalancersClientImpl(subscriptionID string, cred *azidentity.DefaultAzureCredential) (*loadBalancersClientImpl, error) {
c := network.NewLoadBalancersClient(subscriptionID) c, err := network.NewLoadBalancersClient(subscriptionID, cred, nil)
c.Authorizer = authorizer if err != nil {
return &loadBalancersClientImpl{ return nil, fmt.Errorf("creating load balancers client: %w", err)
c: &c,
} }
return &loadBalancersClientImpl{
c: c,
}, nil
} }

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2023 The Kubernetes Authors. Copyright 2024 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -20,14 +20,14 @@ import (
"context" "context"
"fmt" "fmt"
"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2022-05-01/network" "github.com/Azure/azure-sdk-for-go/sdk/azidentity"
"github.com/Azure/go-autorest/autorest" network "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork"
) )
// NatGatewaysClient is a client for managing Nat Gateways. // NatGatewaysClient is a client for managing Nat Gateways.
type NatGatewaysClient interface { type NatGatewaysClient interface {
CreateOrUpdate(ctx context.Context, resourceGroupName, natGatewayName string, parameters network.NatGateway) (*network.NatGateway, error) CreateOrUpdate(ctx context.Context, resourceGroupName, natGatewayName string, parameters network.NatGateway) (*network.NatGateway, error)
List(ctx context.Context, resourceGroupName string) ([]network.NatGateway, error) List(ctx context.Context, resourceGroupName string) ([]*network.NatGateway, error)
Delete(ctx context.Context, resourceGroupName, natGatewayName string) error Delete(ctx context.Context, resourceGroupName, natGatewayName string) error
} }
@ -38,46 +38,47 @@ type NatGatewaysClientImpl struct {
var _ NatGatewaysClient = &NatGatewaysClientImpl{} var _ NatGatewaysClient = &NatGatewaysClientImpl{}
func (c *NatGatewaysClientImpl) CreateOrUpdate(ctx context.Context, resourceGroupName, natGatewayName string, parameters network.NatGateway) (*network.NatGateway, error) { func (c *NatGatewaysClientImpl) CreateOrUpdate(ctx context.Context, resourceGroupName, natGatewayName string, parameters network.NatGateway) (*network.NatGateway, error) {
future, err := c.c.CreateOrUpdate(ctx, resourceGroupName, natGatewayName, parameters) future, err := c.c.BeginCreateOrUpdate(ctx, resourceGroupName, natGatewayName, parameters, nil)
if err != nil { if err != nil {
return nil, fmt.Errorf("creating/updating nat gateway: %w", err) return nil, fmt.Errorf("creating/updating nat gateway: %w", err)
} }
if err := future.WaitForCompletionRef(ctx, c.c.Client); err != nil { resp, err := future.PollUntilDone(ctx, nil)
return nil, fmt.Errorf("waiting for nat gateway create/update completion: %w", err)
}
asg, err := future.Result(*c.c)
if err != nil { if err != nil {
return nil, fmt.Errorf("obtaining result for nat gateway create/update: %w", err) return nil, fmt.Errorf("waiting for nat gateway create/update: %w", err)
} }
return &asg, err return &resp.NatGateway, err
} }
func (c *NatGatewaysClientImpl) List(ctx context.Context, resourceGroupName string) ([]network.NatGateway, error) { func (c *NatGatewaysClientImpl) List(ctx context.Context, resourceGroupName string) ([]*network.NatGateway, error) {
var l []network.NatGateway var l []*network.NatGateway
for iter, err := c.c.ListComplete(ctx, resourceGroupName); iter.NotDone(); err = iter.NextWithContext(ctx) { pager := c.c.NewListPager(resourceGroupName, nil)
for pager.More() {
resp, err := pager.NextPage(ctx)
if err != nil { if err != nil {
return nil, fmt.Errorf("listing nat gateways: %w", err) return nil, fmt.Errorf("listing nat gateways: %w", err)
} }
l = append(l, iter.Value()) l = append(l, resp.Value...)
} }
return l, nil return l, nil
} }
func (c *NatGatewaysClientImpl) Delete(ctx context.Context, resourceGroupName, natGatewayName string) error { func (c *NatGatewaysClientImpl) Delete(ctx context.Context, resourceGroupName, natGatewayName string) error {
future, err := c.c.Delete(ctx, resourceGroupName, natGatewayName) future, err := c.c.BeginDelete(ctx, resourceGroupName, natGatewayName, nil)
if err != nil { if err != nil {
return fmt.Errorf("deleting nat gateway: %w", err) return fmt.Errorf("deleting nat gateway: %w", err)
} }
if err := future.WaitForCompletionRef(ctx, c.c.Client); err != nil { if _, err := future.PollUntilDone(ctx, nil); err != nil {
return fmt.Errorf("waiting for nat gateway deletion completion: %w", err) return fmt.Errorf("waiting for nat gateway deletion completion: %w", err)
} }
return nil return nil
} }
func newNatGatewaysClientImpl(subscriptionID string, authorizer autorest.Authorizer) *NatGatewaysClientImpl { func newNatGatewaysClientImpl(subscriptionID string, cred *azidentity.DefaultAzureCredential) (*NatGatewaysClientImpl, error) {
c := network.NewNatGatewaysClient(subscriptionID) c, err := network.NewNatGatewaysClient(subscriptionID, cred, nil)
c.Authorizer = authorizer if err != nil {
return &NatGatewaysClientImpl{ return nil, fmt.Errorf("creating nat gateways client: %w", err)
c: &c,
} }
return &NatGatewaysClientImpl{
c: c,
}, nil
} }

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2020 The Kubernetes Authors. Copyright 2024 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -18,14 +18,15 @@ package azure
import ( import (
"context" "context"
"fmt"
"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2022-05-01/network" "github.com/Azure/azure-sdk-for-go/sdk/azidentity"
"github.com/Azure/go-autorest/autorest" network "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork"
) )
// NetworkInterfacesClient is a client for managing Network Interfaces. // NetworkInterfacesClient is a client for managing Network Interfaces.
type NetworkInterfacesClient interface { type NetworkInterfacesClient interface {
ListScaleSetsNetworkInterfaces(ctx context.Context, resourceGroupName, vmssName string) ([]network.Interface, error) ListScaleSetsNetworkInterfaces(ctx context.Context, resourceGroupName, vmssName string) ([]*network.Interface, error)
} }
type networkInterfacesClientImpl struct { type networkInterfacesClientImpl struct {
@ -34,21 +35,25 @@ type networkInterfacesClientImpl struct {
var _ NetworkInterfacesClient = &networkInterfacesClientImpl{} var _ NetworkInterfacesClient = &networkInterfacesClientImpl{}
func (c *networkInterfacesClientImpl) ListScaleSetsNetworkInterfaces(ctx context.Context, resourceGroupName, vmssName string) ([]network.Interface, error) { func (c *networkInterfacesClientImpl) ListScaleSetsNetworkInterfaces(ctx context.Context, resourceGroupName, vmssName string) ([]*network.Interface, error) {
var l []network.Interface var l []*network.Interface
for iter, err := c.c.ListVirtualMachineScaleSetNetworkInterfacesComplete(ctx, resourceGroupName, vmssName); iter.NotDone(); err = iter.Next() { pager := c.c.NewListVirtualMachineScaleSetNetworkInterfacesPager(resourceGroupName, vmssName, nil)
for pager.More() {
resp, err := pager.NextPage(ctx)
if err != nil { if err != nil {
return nil, err return nil, fmt.Errorf("listing network interfaces: %w", err)
} }
l = append(l, iter.Value()) l = append(l, resp.Value...)
} }
return l, nil return l, nil
} }
func newNetworkInterfacesClientImpl(subscriptionID string, authorizer autorest.Authorizer) *networkInterfacesClientImpl { func newNetworkInterfacesClientImpl(subscriptionID string, cred *azidentity.DefaultAzureCredential) (*networkInterfacesClientImpl, error) {
c := network.NewInterfacesClient(subscriptionID) c, err := network.NewInterfacesClient(subscriptionID, cred, nil)
c.Authorizer = authorizer if err != nil {
return &networkInterfacesClientImpl{ return nil, fmt.Errorf("creating network interfaces client: %w", err)
c: &c,
} }
return &networkInterfacesClientImpl{
c: c,
}, nil
} }

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2023 The Kubernetes Authors. Copyright 2024 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -20,14 +20,14 @@ import (
"context" "context"
"fmt" "fmt"
"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2022-05-01/network" "github.com/Azure/azure-sdk-for-go/sdk/azidentity"
"github.com/Azure/go-autorest/autorest" network "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork"
) )
// NetworkSecurityGroupsClient is a client for managing Network Security Groups. // NetworkSecurityGroupsClient is a client for managing network security groups.
type NetworkSecurityGroupsClient interface { type NetworkSecurityGroupsClient interface {
CreateOrUpdate(ctx context.Context, resourceGroupName, NetworkSecurityGroupName string, parameters network.SecurityGroup) (*network.SecurityGroup, error) CreateOrUpdate(ctx context.Context, resourceGroupName, NetworkSecurityGroupName string, parameters network.SecurityGroup) (*network.SecurityGroup, error)
List(ctx context.Context, resourceGroupName string) ([]network.SecurityGroup, error) List(ctx context.Context, resourceGroupName string) ([]*network.SecurityGroup, error)
Delete(ctx context.Context, resourceGroupName, NetworkSecurityGroupName string) error Delete(ctx context.Context, resourceGroupName, NetworkSecurityGroupName string) error
} }
@ -38,46 +38,47 @@ type NetworkSecurityGroupsClientImpl struct {
var _ NetworkSecurityGroupsClient = &NetworkSecurityGroupsClientImpl{} var _ NetworkSecurityGroupsClient = &NetworkSecurityGroupsClientImpl{}
func (c *NetworkSecurityGroupsClientImpl) CreateOrUpdate(ctx context.Context, resourceGroupName, NetworkSecurityGroupName string, parameters network.SecurityGroup) (*network.SecurityGroup, error) { func (c *NetworkSecurityGroupsClientImpl) CreateOrUpdate(ctx context.Context, resourceGroupName, NetworkSecurityGroupName string, parameters network.SecurityGroup) (*network.SecurityGroup, error) {
future, err := c.c.CreateOrUpdate(ctx, resourceGroupName, NetworkSecurityGroupName, parameters) future, err := c.c.BeginCreateOrUpdate(ctx, resourceGroupName, NetworkSecurityGroupName, parameters, nil)
if err != nil { if err != nil {
return nil, fmt.Errorf("error creating/updating Network Security Group: %w", err) return nil, fmt.Errorf("creating/updating network security group: %w", err)
} }
if err := future.WaitForCompletionRef(ctx, c.c.Client); err != nil { asg, err := future.PollUntilDone(ctx, nil)
return nil, fmt.Errorf("error waiting for Network Security Group create/update completion: %w", err)
}
asg, err := future.Result(*c.c)
if err != nil { if err != nil {
return nil, fmt.Errorf("error obtaining result for Network Security Group create/update: %w", err) return nil, fmt.Errorf("waiting for network security group create/update completion: %w", err)
} }
return &asg, err return &asg.SecurityGroup, err
} }
func (c *NetworkSecurityGroupsClientImpl) List(ctx context.Context, resourceGroupName string) ([]network.SecurityGroup, error) { func (c *NetworkSecurityGroupsClientImpl) List(ctx context.Context, resourceGroupName string) ([]*network.SecurityGroup, error) {
var l []network.SecurityGroup var l []*network.SecurityGroup
for iter, err := c.c.ListComplete(ctx, resourceGroupName); iter.NotDone(); err = iter.NextWithContext(ctx) { pager := c.c.NewListPager(resourceGroupName, nil)
for pager.More() {
resp, err := pager.NextPage(ctx)
if err != nil { if err != nil {
return nil, err return nil, fmt.Errorf("listing network security groups: %w", err)
} }
l = append(l, iter.Value()) l = append(l, resp.Value...)
} }
return l, nil return l, nil
} }
func (c *NetworkSecurityGroupsClientImpl) Delete(ctx context.Context, resourceGroupName, NetworkSecurityGroupName string) error { func (c *NetworkSecurityGroupsClientImpl) Delete(ctx context.Context, resourceGroupName, NetworkSecurityGroupName string) error {
future, err := c.c.Delete(ctx, resourceGroupName, NetworkSecurityGroupName) future, err := c.c.BeginDelete(ctx, resourceGroupName, NetworkSecurityGroupName, nil)
if err != nil { if err != nil {
return fmt.Errorf("error deleting Network Security Group: %w", err) return fmt.Errorf("deleting network security group: %w", err)
} }
if err := future.WaitForCompletionRef(ctx, c.c.Client); err != nil { if _, err = future.PollUntilDone(ctx, nil); err != nil {
return fmt.Errorf("error waiting for Network Security Group deletion completion: %w", err) return fmt.Errorf("waiting for network security group deletion completion: %w", err)
} }
return nil return nil
} }
func newNetworkSecurityGroupsClientImpl(subscriptionID string, authorizer autorest.Authorizer) *NetworkSecurityGroupsClientImpl { func newNetworkSecurityGroupsClientImpl(subscriptionID string, cred *azidentity.DefaultAzureCredential) (*NetworkSecurityGroupsClientImpl, error) {
c := network.NewSecurityGroupsClient(subscriptionID) c, err := network.NewSecurityGroupsClient(subscriptionID, cred, nil)
c.Authorizer = authorizer if err != nil {
return &NetworkSecurityGroupsClientImpl{ return nil, fmt.Errorf("creating network security groups client: %w", err)
c: &c,
} }
return &NetworkSecurityGroupsClientImpl{
c: c,
}, nil
} }

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2020 The Kubernetes Authors. Copyright 2024 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -20,14 +20,14 @@ import (
"context" "context"
"fmt" "fmt"
"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2022-05-01/network" "github.com/Azure/azure-sdk-for-go/sdk/azidentity"
"github.com/Azure/go-autorest/autorest" network "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork"
) )
// PublicIPAddressesClient is a client for public ip addresses. // PublicIPAddressesClient is a client for public IP addresses.
type PublicIPAddressesClient interface { type PublicIPAddressesClient interface {
CreateOrUpdate(ctx context.Context, resourceGroupName, publicIPAddressName string, parameters network.PublicIPAddress) (*network.PublicIPAddress, error) CreateOrUpdate(ctx context.Context, resourceGroupName, publicIPAddressName string, parameters network.PublicIPAddress) (*network.PublicIPAddress, error)
List(ctx context.Context, resourceGroupName string) ([]network.PublicIPAddress, error) List(ctx context.Context, resourceGroupName string) ([]*network.PublicIPAddress, error)
Delete(ctx context.Context, resourceGroupName, publicIPAddressName string) error Delete(ctx context.Context, resourceGroupName, publicIPAddressName string) error
} }
@ -38,46 +38,47 @@ type publicIPAddressesClientImpl struct {
var _ PublicIPAddressesClient = &publicIPAddressesClientImpl{} var _ PublicIPAddressesClient = &publicIPAddressesClientImpl{}
func (c *publicIPAddressesClientImpl) CreateOrUpdate(ctx context.Context, resourceGroupName, publicIPAddressName string, parameters network.PublicIPAddress) (*network.PublicIPAddress, error) { func (c *publicIPAddressesClientImpl) CreateOrUpdate(ctx context.Context, resourceGroupName, publicIPAddressName string, parameters network.PublicIPAddress) (*network.PublicIPAddress, error) {
future, err := c.c.CreateOrUpdate(ctx, resourceGroupName, publicIPAddressName, parameters) future, err := c.c.BeginCreateOrUpdate(ctx, resourceGroupName, publicIPAddressName, parameters, nil)
if err != nil { if err != nil {
return nil, fmt.Errorf("creating/updating public ip address: %w", err) return nil, fmt.Errorf("creating/updating public ip address: %w", err)
} }
if err := future.WaitForCompletionRef(ctx, c.c.Client); err != nil { resp, err := future.PollUntilDone(ctx, nil)
if err != nil {
return nil, fmt.Errorf("waiting for public ip address create/update completion: %w", err) return nil, fmt.Errorf("waiting for public ip address create/update completion: %w", err)
} }
pip, err := future.Result(*c.c) return &resp.PublicIPAddress, err
if err != nil {
return nil, fmt.Errorf("obtaining result for public ip address create/update: %w", err)
}
return &pip, err
} }
func (c *publicIPAddressesClientImpl) List(ctx context.Context, resourceGroupName string) ([]network.PublicIPAddress, error) { func (c *publicIPAddressesClientImpl) List(ctx context.Context, resourceGroupName string) ([]*network.PublicIPAddress, error) {
var l []network.PublicIPAddress var l []*network.PublicIPAddress
for iter, err := c.c.ListComplete(ctx, resourceGroupName); iter.NotDone(); err = iter.Next() { pager := c.c.NewListPager(resourceGroupName, nil)
for pager.More() {
resp, err := pager.NextPage(ctx)
if err != nil { if err != nil {
return nil, err return nil, fmt.Errorf("listing public ip addresses: %w", err)
} }
l = append(l, iter.Value()) l = append(l, resp.Value...)
} }
return l, nil return l, nil
} }
func (c *publicIPAddressesClientImpl) Delete(ctx context.Context, resourceGroupName, publicIPAddressName string) error { func (c *publicIPAddressesClientImpl) Delete(ctx context.Context, resourceGroupName, publicIPAddressName string) error {
future, err := c.c.Delete(ctx, resourceGroupName, publicIPAddressName) future, err := c.c.BeginDelete(ctx, resourceGroupName, publicIPAddressName, nil)
if err != nil { if err != nil {
return fmt.Errorf("error deleting public ip address: %s", err) return fmt.Errorf("deleting public ip address: %w", err)
} }
if err := future.WaitForCompletionRef(ctx, c.c.Client); err != nil { if _, err := future.PollUntilDone(ctx, nil); err != nil {
return fmt.Errorf("error waiting for public ip address deletion completion: %s", err) return fmt.Errorf("waiting for public ip address deletion completion: %w", err)
} }
return nil return nil
} }
func newPublicIPAddressesClientImpl(subscriptionID string, authorizer autorest.Authorizer) *publicIPAddressesClientImpl { func newPublicIPAddressesClientImpl(subscriptionID string, cred *azidentity.DefaultAzureCredential) (*publicIPAddressesClientImpl, error) {
c := network.NewPublicIPAddressesClient(subscriptionID) c, err := network.NewPublicIPAddressesClient(subscriptionID, cred, nil)
c.Authorizer = authorizer if err != nil {
return &publicIPAddressesClientImpl{ return nil, fmt.Errorf("creating public ip addresses client: %w", err)
c: &c,
} }
return &publicIPAddressesClientImpl{
c: c,
}, nil
} }

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2020 The Kubernetes Authors. Copyright 2024 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -20,54 +20,58 @@ import (
"context" "context"
"fmt" "fmt"
"github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2021-04-01/resources" "github.com/Azure/azure-sdk-for-go/sdk/azidentity"
"github.com/Azure/go-autorest/autorest" resources "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources"
) )
// ResourceGroupsClient is a client for managing Resource Groups. // ResourceGroupsClient is a client for managing resource groups.
type ResourceGroupsClient interface { type ResourceGroupsClient interface {
CreateOrUpdate(ctx context.Context, name string, parameters resources.Group) error CreateOrUpdate(ctx context.Context, name string, parameters resources.ResourceGroup) error
List(ctx context.Context, filter string) ([]resources.Group, error) List(ctx context.Context) ([]*resources.ResourceGroup, error)
Delete(ctx context.Context, name string) error Delete(ctx context.Context, name string) error
} }
type resourceGroupsClientImpl struct { type resourceGroupsClientImpl struct {
c *resources.GroupsClient c *resources.ResourceGroupsClient
} }
var _ ResourceGroupsClient = &resourceGroupsClientImpl{} var _ ResourceGroupsClient = &resourceGroupsClientImpl{}
func (c *resourceGroupsClientImpl) CreateOrUpdate(ctx context.Context, name string, parameters resources.Group) error { func (c *resourceGroupsClientImpl) CreateOrUpdate(ctx context.Context, name string, parameters resources.ResourceGroup) error {
_, err := c.c.CreateOrUpdate(ctx, name, parameters) _, err := c.c.CreateOrUpdate(ctx, name, parameters, nil)
return err return err
} }
func (c *resourceGroupsClientImpl) List(ctx context.Context, filter string) ([]resources.Group, error) { func (c *resourceGroupsClientImpl) List(ctx context.Context) ([]*resources.ResourceGroup, error) {
var l []resources.Group var l []*resources.ResourceGroup
for iter, err := c.c.ListComplete(ctx, filter, nil /* top */); iter.NotDone(); err = iter.Next() { pager := c.c.NewListPager(nil)
for pager.More() {
resp, err := pager.NextPage(ctx)
if err != nil { if err != nil {
return nil, err return nil, fmt.Errorf("listing resource groups: %w", err)
} }
l = append(l, iter.Value()) l = append(l, resp.Value...)
} }
return l, nil return l, nil
} }
func (c *resourceGroupsClientImpl) Delete(ctx context.Context, name string) error { func (c *resourceGroupsClientImpl) Delete(ctx context.Context, name string) error {
future, err := c.c.Delete(ctx, name, "") future, err := c.c.BeginDelete(ctx, name, nil)
if err != nil { if err != nil {
return fmt.Errorf("error deleting resource group: %s", err) return fmt.Errorf("deleting resource group: %w", err)
} }
if err := future.WaitForCompletionRef(ctx, c.c.Client); err != nil { if _, err = future.PollUntilDone(ctx, nil); err != nil {
return fmt.Errorf("error waiting for resource group deletion completion: %s", err) return fmt.Errorf("waiting for resource group deletion completion: %w", err)
} }
return nil return nil
} }
func newResourceGroupsClientImpl(subscriptionID string, authorizer autorest.Authorizer) *resourceGroupsClientImpl { func newResourceGroupsClientImpl(subscriptionID string, cred *azidentity.DefaultAzureCredential) (*resourceGroupsClientImpl, error) {
c := resources.NewGroupsClient(subscriptionID) c, err := resources.NewResourceGroupsClient(subscriptionID, cred, nil)
c.Authorizer = authorizer if err != nil {
return &resourceGroupsClientImpl{ return nil, fmt.Errorf("creating resource group client: %w", err)
c: &c,
} }
return &resourceGroupsClientImpl{
c: c,
}, nil
} }

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2020 The Kubernetes Authors. Copyright 2024 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -18,19 +18,16 @@ package azure
import ( import (
"context" "context"
"fmt"
// Use 2018-01-01-preview API as we need the version to create "github.com/Azure/azure-sdk-for-go/sdk/azidentity"
// a role assignment with Data Actions (https://github.com/Azure/azure-sdk-for-go/issues/1895). authz "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v3"
// The non-preview version of the authorization API (2015-07-01)
// doesn't support Data Actions.
authz "github.com/Azure/azure-sdk-for-go/services/preview/authorization/mgmt/2020-04-01-preview/authorization"
"github.com/Azure/go-autorest/autorest"
) )
// RoleAssignmentsClient is a client for managing Role Assignments // RoleAssignmentsClient is a client for managing role assignments
type RoleAssignmentsClient interface { type RoleAssignmentsClient interface {
Create(ctx context.Context, scope, roleAssignmentName string, parameters authz.RoleAssignmentCreateParameters) (*authz.RoleAssignment, error) Create(ctx context.Context, scope, roleAssignmentName string, parameters authz.RoleAssignmentCreateParameters) (*authz.RoleAssignment, error)
List(ctx context.Context, resourceGroupName string) ([]authz.RoleAssignment, error) List(ctx context.Context, resourceGroupName string) ([]*authz.RoleAssignment, error)
Delete(ctx context.Context, scope, raName string) error Delete(ctx context.Context, scope, raName string) error
} }
@ -46,30 +43,37 @@ func (c *roleAssignmentsClientImpl) Create(
roleAssignmentName string, roleAssignmentName string,
parameters authz.RoleAssignmentCreateParameters, parameters authz.RoleAssignmentCreateParameters,
) (*authz.RoleAssignment, error) { ) (*authz.RoleAssignment, error) {
ra, err := c.c.Create(ctx, scope, roleAssignmentName, parameters) resp, err := c.c.Create(ctx, scope, roleAssignmentName, parameters, nil)
return &ra, err return &resp.RoleAssignment, err
} }
func (c *roleAssignmentsClientImpl) List(ctx context.Context, resourceGroupName string) ([]authz.RoleAssignment, error) { func (c *roleAssignmentsClientImpl) List(ctx context.Context, resourceGroupName string) ([]*authz.RoleAssignment, error) {
var l []authz.RoleAssignment var l []*authz.RoleAssignment
for iter, err := c.c.ListForResourceGroupComplete(ctx, resourceGroupName, "", ""); iter.NotDone(); err = iter.Next() { pager := c.c.NewListForResourceGroupPager(resourceGroupName, nil)
for pager.More() {
resp, err := pager.NextPage(ctx)
if err != nil { if err != nil {
return nil, err return nil, fmt.Errorf("listing role assignments: %w", err)
} }
l = append(l, iter.Value()) l = append(l, resp.Value...)
} }
return l, nil return l, nil
} }
func (c *roleAssignmentsClientImpl) Delete(ctx context.Context, scope, raName string) error { func (c *roleAssignmentsClientImpl) Delete(ctx context.Context, scope, raName string) error {
_, err := c.c.Delete(ctx, scope, raName, "") _, err := c.c.Delete(ctx, scope, raName, nil)
return err if err != nil {
return fmt.Errorf("deleting role assignment: %w", err)
}
return nil
} }
func newRoleAssignmentsClientImpl(subscriptionID string, authorizer autorest.Authorizer) *roleAssignmentsClientImpl { func newRoleAssignmentsClientImpl(subscriptionID string, cred *azidentity.DefaultAzureCredential) (*roleAssignmentsClientImpl, error) {
c := authz.NewRoleAssignmentsClient(subscriptionID) c, err := authz.NewRoleAssignmentsClient(subscriptionID, cred, nil)
c.Authorizer = authorizer if err != nil {
return &roleAssignmentsClientImpl{ return nil, fmt.Errorf("creating role assignments client: %w", err)
c: &c,
} }
return &roleAssignmentsClientImpl{
c: c,
}, nil
} }

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2020 The Kubernetes Authors. Copyright 2024 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -20,14 +20,14 @@ import (
"context" "context"
"fmt" "fmt"
"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2022-05-01/network" "github.com/Azure/azure-sdk-for-go/sdk/azidentity"
"github.com/Azure/go-autorest/autorest" network "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork"
) )
// RouteTablesClient is a client for managing Virtual Networks. // RouteTablesClient is a client for managing route tables.
type RouteTablesClient interface { type RouteTablesClient interface {
CreateOrUpdate(ctx context.Context, resourceGroupName, routeTableName string, parameters network.RouteTable) error CreateOrUpdate(ctx context.Context, resourceGroupName, routeTableName string, parameters network.RouteTable) (*network.RouteTable, error)
List(ctx context.Context, resourceGroupName string) ([]network.RouteTable, error) List(ctx context.Context, resourceGroupName string) ([]*network.RouteTable, error)
Delete(ctx context.Context, resourceGroupName, vnetName string) error Delete(ctx context.Context, resourceGroupName, vnetName string) error
} }
@ -37,37 +37,48 @@ type routeTablesClientImpl struct {
var _ RouteTablesClient = &routeTablesClientImpl{} var _ RouteTablesClient = &routeTablesClientImpl{}
func (c *routeTablesClientImpl) CreateOrUpdate(ctx context.Context, resourceGroupName, routeTableName string, parameters network.RouteTable) error { func (c *routeTablesClientImpl) CreateOrUpdate(ctx context.Context, resourceGroupName, routeTableName string, parameters network.RouteTable) (*network.RouteTable, error) {
_, err := c.c.CreateOrUpdate(ctx, resourceGroupName, routeTableName, parameters) future, err := c.c.BeginCreateOrUpdate(ctx, resourceGroupName, routeTableName, parameters, nil)
return err if err != nil {
return nil, fmt.Errorf("creating/updating route table: %w", err)
}
rt, err := future.PollUntilDone(ctx, nil)
if err != nil {
return nil, fmt.Errorf("waiting for route table create/update completion: %w", err)
}
return &rt.RouteTable, err
} }
func (c *routeTablesClientImpl) List(ctx context.Context, resourceGroupName string) ([]network.RouteTable, error) { func (c *routeTablesClientImpl) List(ctx context.Context, resourceGroupName string) ([]*network.RouteTable, error) {
var l []network.RouteTable var l []*network.RouteTable
for iter, err := c.c.ListComplete(ctx, resourceGroupName); iter.NotDone(); err = iter.Next() { pager := c.c.NewListPager(resourceGroupName, nil)
for pager.More() {
resp, err := pager.NextPage(ctx)
if err != nil { if err != nil {
return nil, err return nil, fmt.Errorf("listing route tables: %w", err)
} }
l = append(l, iter.Value()) l = append(l, resp.Value...)
} }
return l, nil return l, nil
} }
func (c *routeTablesClientImpl) Delete(ctx context.Context, resourceGroupName, vnetName string) error { func (c *routeTablesClientImpl) Delete(ctx context.Context, resourceGroupName, vnetName string) error {
future, err := c.c.Delete(ctx, resourceGroupName, vnetName) future, err := c.c.BeginDelete(ctx, resourceGroupName, vnetName, nil)
if err != nil { if err != nil {
return fmt.Errorf("error deleting virtual network: %s", err) return fmt.Errorf("deleting route table: %w", err)
} }
if err := future.WaitForCompletionRef(ctx, c.c.Client); err != nil { if _, err := future.PollUntilDone(ctx, nil); err != nil {
return fmt.Errorf("error waiting for virtual network deletion completion: %s", err) return fmt.Errorf("waiting for route table deletion completion: %w", err)
} }
return nil return nil
} }
func newRouteTablesClientImpl(subscriptionID string, authorizer autorest.Authorizer) *routeTablesClientImpl { func newRouteTablesClientImpl(subscriptionID string, cred *azidentity.DefaultAzureCredential) (*routeTablesClientImpl, error) {
c := network.NewRouteTablesClient(subscriptionID) c, err := network.NewRouteTablesClient(subscriptionID, cred, nil)
c.Authorizer = authorizer if err != nil {
return &routeTablesClientImpl{ return nil, fmt.Errorf("creating route tables client: %w", err)
c: &c,
} }
return &routeTablesClientImpl{
c: c,
}, nil
} }

View File

@ -21,7 +21,7 @@ import (
"fmt" "fmt"
"strings" "strings"
"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2022-08-01/compute" compute "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute"
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
"k8s.io/klog/v2" "k8s.io/klog/v2"
"k8s.io/kops/pkg/apis/kops" "k8s.io/kops/pkg/apis/kops"
@ -49,10 +49,10 @@ func (c *azureCloudImplementation) FindClusterStatus(cluster *kops.Cluster) (*ko
return status, nil return status, nil
} }
func (c *azureCloudImplementation) findEtcdStatus(disks []compute.Disk) ([]kops.EtcdClusterStatus, error) { func (c *azureCloudImplementation) findEtcdStatus(disks []*compute.Disk) ([]kops.EtcdClusterStatus, error) {
statusMap := make(map[string]*kops.EtcdClusterStatus) statusMap := make(map[string]*kops.EtcdClusterStatus)
for _, disk := range disks { for _, disk := range disks {
if !c.isDiskForCluster(&disk) { if !c.isDiskForCluster(disk) {
continue continue
} }
@ -135,7 +135,7 @@ func (c *azureCloudImplementation) GetCloudGroups(
groups := make(map[string]*cloudinstances.CloudInstanceGroup) groups := make(map[string]*cloudinstances.CloudInstanceGroup)
for _, vmss := range vmsses { for _, vmss := range vmsses {
if !isOwnedByCluster(&vmss, cluster.Name) { if !isOwnedByCluster(vmss, cluster.Name) {
continue continue
} }
@ -147,7 +147,7 @@ func (c *azureCloudImplementation) GetCloudGroups(
continue continue
} }
cig, err := c.buildCloudInstanceGroup(ctx, cluster, ig, &vmss, nodeMap) cig, err := c.buildCloudInstanceGroup(ctx, cluster, ig, vmss, nodeMap)
if err != nil { if err != nil {
return nil, fmt.Errorf("error getting cloud instance group %q: %v", ig.Name, err) return nil, fmt.Errorf("error getting cloud instance group %q: %v", ig.Name, err)
} }
@ -163,7 +163,7 @@ func (c *azureCloudImplementation) buildCloudInstanceGroup(
vmss *compute.VirtualMachineScaleSet, vmss *compute.VirtualMachineScaleSet,
nodeMap map[string]*v1.Node, nodeMap map[string]*v1.Node,
) (*cloudinstances.CloudInstanceGroup, error) { ) (*cloudinstances.CloudInstanceGroup, error) {
cap := int(*vmss.Sku.Capacity) cap := int(*vmss.SKU.Capacity)
cg := &cloudinstances.CloudInstanceGroup{ cg := &cloudinstances.CloudInstanceGroup{
HumanName: *vmss.Name, HumanName: *vmss.Name,
InstanceGroup: ig, InstanceGroup: ig,

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2020 The Kubernetes Authors. Copyright 2024 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -22,15 +22,15 @@ import (
"reflect" "reflect"
"testing" "testing"
"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2022-08-01/compute" "github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
"github.com/Azure/go-autorest/autorest/to" compute "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute"
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kops/pkg/apis/kops" "k8s.io/kops/pkg/apis/kops"
) )
type mockVMScaleSetsClient struct { type mockVMScaleSetsClient struct {
vmsses []compute.VirtualMachineScaleSet vmsses []*compute.VirtualMachineScaleSet
} }
var _ VMScaleSetsClient = &mockVMScaleSetsClient{} var _ VMScaleSetsClient = &mockVMScaleSetsClient{}
@ -40,14 +40,14 @@ func (c *mockVMScaleSetsClient) CreateOrUpdate(ctx context.Context, resourceGrou
return nil, fmt.Errorf("unimplemented") return nil, fmt.Errorf("unimplemented")
} }
func (c *mockVMScaleSetsClient) List(ctx context.Context, resourceGroupName string) ([]compute.VirtualMachineScaleSet, error) { func (c *mockVMScaleSetsClient) List(ctx context.Context, resourceGroupName string) ([]*compute.VirtualMachineScaleSet, error) {
return c.vmsses, nil return c.vmsses, nil
} }
func (c *mockVMScaleSetsClient) Get(ctx context.Context, resourceGroupName string, vmssName string) (*compute.VirtualMachineScaleSet, error) { func (c *mockVMScaleSetsClient) Get(ctx context.Context, resourceGroupName string, vmssName string) (*compute.VirtualMachineScaleSet, error) {
for _, vmss := range c.vmsses { for _, vmss := range c.vmsses {
if *vmss.Name == vmssName { if *vmss.Name == vmssName {
return &vmss, nil return vmss, nil
} }
} }
return nil, nil return nil, nil
@ -58,12 +58,12 @@ func (c *mockVMScaleSetsClient) Delete(ctx context.Context, resourceGroupName, v
} }
type mockVMScaleSetVMsClient struct { type mockVMScaleSetVMsClient struct {
vms []compute.VirtualMachineScaleSetVM vms []*compute.VirtualMachineScaleSetVM
} }
var _ VMScaleSetVMsClient = &mockVMScaleSetVMsClient{} var _ VMScaleSetVMsClient = &mockVMScaleSetVMsClient{}
func (c *mockVMScaleSetVMsClient) List(ctx context.Context, resourceGroupName, vmssName string) ([]compute.VirtualMachineScaleSetVM, error) { func (c *mockVMScaleSetVMsClient) List(ctx context.Context, resourceGroupName, vmssName string) ([]*compute.VirtualMachineScaleSetVM, error) {
return c.vms, nil return c.vms, nil
} }
@ -76,46 +76,46 @@ func TestFindEtcdStatus(t *testing.T) {
} }
etcdClusterName := "main" etcdClusterName := "main"
disks := []compute.Disk{ disks := []*compute.Disk{
{ {
Name: to.StringPtr("d0"), Name: to.Ptr("d0"),
Tags: map[string]*string{ Tags: map[string]*string{
TagClusterName: to.StringPtr(clusterName), TagClusterName: to.Ptr(clusterName),
TagNameRolePrefix + TagRoleControlPlane: to.StringPtr("1"), TagNameRolePrefix + TagRoleControlPlane: to.Ptr("1"),
TagNameRolePrefix + TagRoleMaster: to.StringPtr("1"), TagNameRolePrefix + TagRoleMaster: to.Ptr("1"),
TagNameEtcdClusterPrefix + etcdClusterName: to.StringPtr("a/a,b,c"), TagNameEtcdClusterPrefix + etcdClusterName: to.Ptr("a/a,b,c"),
}, },
}, },
{ {
Name: to.StringPtr("d1"), Name: to.Ptr("d1"),
Tags: map[string]*string{ Tags: map[string]*string{
TagClusterName: to.StringPtr(clusterName), TagClusterName: to.Ptr(clusterName),
TagNameRolePrefix + TagRoleControlPlane: to.StringPtr("1"), TagNameRolePrefix + TagRoleControlPlane: to.Ptr("1"),
TagNameRolePrefix + TagRoleMaster: to.StringPtr("1"), TagNameRolePrefix + TagRoleMaster: to.Ptr("1"),
TagNameEtcdClusterPrefix + etcdClusterName: to.StringPtr("b/a,b,c"), TagNameEtcdClusterPrefix + etcdClusterName: to.Ptr("b/a,b,c"),
}, },
}, },
{ {
Name: to.StringPtr("d2"), Name: to.Ptr("d2"),
Tags: map[string]*string{ Tags: map[string]*string{
TagClusterName: to.StringPtr(clusterName), TagClusterName: to.Ptr(clusterName),
TagNameRolePrefix + TagRoleControlPlane: to.StringPtr("1"), TagNameRolePrefix + TagRoleControlPlane: to.Ptr("1"),
TagNameRolePrefix + TagRoleMaster: to.StringPtr("1"), TagNameRolePrefix + TagRoleMaster: to.Ptr("1"),
TagNameEtcdClusterPrefix + etcdClusterName: to.StringPtr("c/a,b,c"), TagNameEtcdClusterPrefix + etcdClusterName: to.Ptr("c/a,b,c"),
}, },
}, },
{ {
// No etcd tag. // No etcd tag.
Name: to.StringPtr("not_relevant"), Name: to.Ptr("not_relevant"),
Tags: map[string]*string{ Tags: map[string]*string{
TagClusterName: to.StringPtr("different_cluster"), TagClusterName: to.Ptr("different_cluster"),
}, },
}, },
{ {
// No corresponding cluster tag. // No corresponding cluster tag.
Name: to.StringPtr("not_relevant"), Name: to.Ptr("not_relevant"),
Tags: map[string]*string{ Tags: map[string]*string{
TagClusterName: to.StringPtr("different_cluster"), TagClusterName: to.Ptr("different_cluster"),
}, },
}, },
} }
@ -171,36 +171,36 @@ func TestGetCloudGroups(t *testing.T) {
vmssClient := &mockVMScaleSetsClient{} vmssClient := &mockVMScaleSetsClient{}
vmssClient.vmsses = append(vmssClient.vmsses, vmssClient.vmsses = append(vmssClient.vmsses,
compute.VirtualMachineScaleSet{ &compute.VirtualMachineScaleSet{
Name: to.StringPtr(masterVMSS), Name: to.Ptr(masterVMSS),
Tags: map[string]*string{ Tags: map[string]*string{
TagClusterName: to.StringPtr(clusterName), TagClusterName: to.Ptr(clusterName),
}, },
Sku: &compute.Sku{ SKU: &compute.SKU{
Capacity: to.Int64Ptr(1), Capacity: to.Ptr[int64](1),
}, },
}, },
compute.VirtualMachineScaleSet{ &compute.VirtualMachineScaleSet{
Name: to.StringPtr(nodeVMSS), Name: to.Ptr(nodeVMSS),
Tags: map[string]*string{ Tags: map[string]*string{
TagClusterName: to.StringPtr(clusterName), TagClusterName: to.Ptr(clusterName),
}, },
Sku: &compute.Sku{ SKU: &compute.SKU{
Capacity: to.Int64Ptr(2), Capacity: to.Ptr[int64](2),
}, },
}, },
) )
vmClient := &mockVMScaleSetVMsClient{} vmClient := &mockVMScaleSetVMsClient{}
vmClient.vms = append(vmClient.vms, vmClient.vms = append(vmClient.vms,
compute.VirtualMachineScaleSetVM{ &compute.VirtualMachineScaleSetVM{
Name: to.StringPtr(masterVM), Name: to.Ptr(masterVM),
}, },
compute.VirtualMachineScaleSetVM{ &compute.VirtualMachineScaleSetVM{
Name: to.StringPtr(nodeVM0), Name: to.Ptr(nodeVM0),
}, },
compute.VirtualMachineScaleSetVM{ &compute.VirtualMachineScaleSetVM{
Name: to.StringPtr(nodeVM1), Name: to.Ptr(nodeVM1),
}, },
) )

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2020 The Kubernetes Authors. Copyright 2024 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -20,14 +20,14 @@ import (
"context" "context"
"fmt" "fmt"
"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2022-05-01/network" "github.com/Azure/azure-sdk-for-go/sdk/azidentity"
"github.com/Azure/go-autorest/autorest" network "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork"
) )
// SubnetsClient is a client for managing Subnets. // SubnetsClient is a client for managing subnets.
type SubnetsClient interface { type SubnetsClient interface {
CreateOrUpdate(ctx context.Context, resourceGroupName, virtualNetworkName, subnetName string, parameters network.Subnet) (*network.Subnet, error) CreateOrUpdate(ctx context.Context, resourceGroupName, virtualNetworkName, subnetName string, parameters network.Subnet) (*network.Subnet, error)
List(ctx context.Context, resourceGroupName, virtualNetworkName string) ([]network.Subnet, error) List(ctx context.Context, resourceGroupName, virtualNetworkName string) ([]*network.Subnet, error)
Delete(ctx context.Context, resourceGroupName, vnetName, subnetName string) error Delete(ctx context.Context, resourceGroupName, vnetName, subnetName string) error
} }
@ -38,46 +38,47 @@ type subnetsClientImpl struct {
var _ SubnetsClient = &subnetsClientImpl{} var _ SubnetsClient = &subnetsClientImpl{}
func (c *subnetsClientImpl) CreateOrUpdate(ctx context.Context, resourceGroupName, virtualNetworkName, subnetName string, parameters network.Subnet) (*network.Subnet, error) { func (c *subnetsClientImpl) CreateOrUpdate(ctx context.Context, resourceGroupName, virtualNetworkName, subnetName string, parameters network.Subnet) (*network.Subnet, error) {
future, err := c.c.CreateOrUpdate(ctx, resourceGroupName, virtualNetworkName, subnetName, parameters) future, err := c.c.BeginCreateOrUpdate(ctx, resourceGroupName, virtualNetworkName, subnetName, parameters, nil)
if err != nil { if err != nil {
return nil, fmt.Errorf("creating/updating subnet: %w", err) return nil, fmt.Errorf("creating/updating subnet: %w", err)
} }
if err := future.WaitForCompletionRef(ctx, c.c.Client); err != nil { resp, err := future.PollUntilDone(ctx, nil)
if err != nil {
return nil, fmt.Errorf("waiting for subnet create/update completion: %w", err) return nil, fmt.Errorf("waiting for subnet create/update completion: %w", err)
} }
sn, err := future.Result(*c.c) return &resp.Subnet, err
if err != nil {
return nil, fmt.Errorf("obtaining result for subnet create/update: %w", err)
}
return &sn, err
} }
func (c *subnetsClientImpl) List(ctx context.Context, resourceGroupName, virtualNetworkName string) ([]network.Subnet, error) { func (c *subnetsClientImpl) List(ctx context.Context, resourceGroupName, virtualNetworkName string) ([]*network.Subnet, error) {
var l []network.Subnet var l []*network.Subnet
for iter, err := c.c.ListComplete(ctx, resourceGroupName, virtualNetworkName); iter.NotDone(); err = iter.Next() { pager := c.c.NewListPager(resourceGroupName, virtualNetworkName, nil)
for pager.More() {
resp, err := pager.NextPage(ctx)
if err != nil { if err != nil {
return nil, err return nil, fmt.Errorf("listing subnets: %w", err)
} }
l = append(l, iter.Value()) l = append(l, resp.Value...)
} }
return l, nil return l, nil
} }
func (c *subnetsClientImpl) Delete(ctx context.Context, resourceGroupName, vnetName, subnetName string) error { func (c *subnetsClientImpl) Delete(ctx context.Context, resourceGroupName, vnetName, subnetName string) error {
future, err := c.c.Delete(ctx, resourceGroupName, vnetName, subnetName) future, err := c.c.BeginDelete(ctx, resourceGroupName, vnetName, subnetName, nil)
if err != nil { if err != nil {
return fmt.Errorf("error deleting subnet: %s", err) return fmt.Errorf("deleting subnet: %w", err)
} }
if err := future.WaitForCompletionRef(ctx, c.c.Client); err != nil { if _, err := future.PollUntilDone(ctx, nil); err != nil {
return fmt.Errorf("error waiting for subnet deletion completion: %s", err) return fmt.Errorf("waiting for subnet deletion completion: %w", err)
} }
return nil return nil
} }
func newSubnetsClientImpl(subscriptionID string, authorizer autorest.Authorizer) *subnetsClientImpl { func newSubnetsClientImpl(subscriptionID string, cred *azidentity.DefaultAzureCredential) (*subnetsClientImpl, error) {
c := network.NewSubnetsClient(subscriptionID) c, err := network.NewSubnetsClient(subscriptionID, cred, nil)
c.Authorizer = authorizer if err != nil {
return &subnetsClientImpl{ return nil, fmt.Errorf("creating subnets client: %w", err)
c: &c,
} }
return &subnetsClientImpl{
c: c,
}, nil
} }

View File

@ -24,9 +24,9 @@ import (
"strconv" "strconv"
"strings" "strings"
"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2022-08-01/compute" "github.com/Azure/azure-sdk-for-go/sdk/azidentity"
"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2022-05-01/network" compute "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute"
"github.com/Azure/go-autorest/autorest/azure/auth" network "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork"
"k8s.io/kops/pkg/bootstrap" "k8s.io/kops/pkg/bootstrap"
"k8s.io/kops/pkg/wellknownports" "k8s.io/kops/pkg/wellknownports"
) )
@ -76,32 +76,32 @@ func (a azureVerifier) VerifyToken(ctx context.Context, rawRequest *http.Request
} }
igName := strings.TrimSuffix(vmssName, "."+a.clusterName) igName := strings.TrimSuffix(vmssName, "."+a.clusterName)
vm, err := a.client.vmsClient.Get(ctx, a.client.resourceGroup, vmssName, vmssIndex, "") vm, err := a.client.vmsClient.Get(ctx, a.client.resourceGroup, vmssName, vmssIndex, nil)
if err != nil { if err != nil {
return nil, fmt.Errorf("getting info for VMSS virtual machine %q #%s: %w", vmssName, vmssIndex, err) return nil, fmt.Errorf("getting info for VMSS virtual machine %q #%s: %w", vmssName, vmssIndex, err)
} }
if vm.VMID == nil { if vm.Properties == nil || vm.Properties.VMID == nil {
return nil, fmt.Errorf("determining VMID for VMSS %q virtual machine #%s", vmssName, vmssIndex) return nil, fmt.Errorf("determining VMID for VMSS %q virtual machine #%s", vmssName, vmssIndex)
} }
if vmId != *vm.VMID { if vmId != *vm.Properties.VMID {
return nil, fmt.Errorf("matching VMID %q to VMSS %q virtual machine #%s", vmId, vmssName, vmssIndex) return nil, fmt.Errorf("matching VMID %q to VMSS %q virtual machine #%s", vmId, vmssName, vmssIndex)
} }
if vm.OsProfile == nil || vm.OsProfile.ComputerName == nil || *vm.OsProfile.ComputerName == "" { if vm.Properties.OSProfile == nil || vm.Properties.OSProfile.ComputerName == nil || *vm.Properties.OSProfile.ComputerName == "" {
return nil, fmt.Errorf("determining ComputerName for VMSS %q virtual machine #%s", vmssName, vmssIndex) return nil, fmt.Errorf("determining ComputerName for VMSS %q virtual machine #%s", vmssName, vmssIndex)
} }
nodeName := *vm.OsProfile.ComputerName nodeName := *vm.Properties.OSProfile.ComputerName
ni, err := a.client.nisClient.GetVirtualMachineScaleSetNetworkInterface(ctx, a.client.resourceGroup, vmssName, vmssIndex, vmssName+"-netconfig", "") ni, err := a.client.nisClient.GetVirtualMachineScaleSetNetworkInterface(ctx, a.client.resourceGroup, vmssName, vmssIndex, vmssName+"-netconfig", nil)
if err != nil { if err != nil {
return nil, fmt.Errorf("getting info for VMSS network interface %q #%s: %w", vmssName, vmssIndex, err) return nil, fmt.Errorf("getting info for VMSS network interface %q #%s: %w", vmssName, vmssIndex, err)
} }
var addrs []string var addrs []string
var challengeEndpoints []string var challengeEndpoints []string
for _, ipc := range *ni.IPConfigurations { for _, ipc := range ni.Properties.IPConfigurations {
if ipc.PrivateIPAddress != nil { if ipc.Properties != nil && ipc.Properties.PrivateIPAddress != nil {
addrs = append(addrs, *ipc.PrivateIPAddress) addrs = append(addrs, *ipc.Properties.PrivateIPAddress)
challengeEndpoints = append(challengeEndpoints, net.JoinHostPort(*ipc.PrivateIPAddress, strconv.Itoa(wellknownports.NodeupChallenge))) challengeEndpoints = append(challengeEndpoints, net.JoinHostPort(*ipc.Properties.PrivateIPAddress, strconv.Itoa(wellknownports.NodeupChallenge)))
} }
} }
if len(addrs) == 0 { if len(addrs) == 0 {
@ -141,19 +141,23 @@ func newClient() (*client, error) {
return nil, fmt.Errorf("empty subscription name") return nil, fmt.Errorf("empty subscription name")
} }
authorizer, err := auth.NewAuthorizerFromEnvironment() cred, err := azidentity.NewDefaultAzureCredential(nil)
if err != nil { if err != nil {
return nil, fmt.Errorf("creating authorizer: %w", err) return nil, fmt.Errorf("creating an identity: %w", err)
} }
nisClient := network.NewInterfacesClient(m.Compute.SubscriptionID) nisClient, err := network.NewInterfacesClient(m.Compute.SubscriptionID, cred, nil)
nisClient.Authorizer = authorizer if err != nil {
vmsClient := compute.NewVirtualMachineScaleSetVMsClient(m.Compute.SubscriptionID) return nil, fmt.Errorf("creating interfaces client: %w", err)
vmsClient.Authorizer = authorizer }
vmsClient, err := compute.NewVirtualMachineScaleSetVMsClient(m.Compute.SubscriptionID, cred, nil)
if err != nil {
return nil, fmt.Errorf("creating VMSSVMs client: %w", err)
}
return &client{ return &client{
resourceGroup: m.Compute.ResourceGroupName, resourceGroup: m.Compute.ResourceGroupName,
nisClient: &nisClient, nisClient: nisClient,
vmsClient: &vmsClient, vmsClient: vmsClient,
}, nil }, nil
} }

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2020 The Kubernetes Authors. Copyright 2024 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -20,14 +20,14 @@ import (
"context" "context"
"fmt" "fmt"
"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2022-05-01/network" "github.com/Azure/azure-sdk-for-go/sdk/azidentity"
"github.com/Azure/go-autorest/autorest" network "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork"
) )
// VirtualNetworksClient is a client for managing Virtual Networks. // VirtualNetworksClient is a client for managing Virtual Networks.
type VirtualNetworksClient interface { type VirtualNetworksClient interface {
CreateOrUpdate(ctx context.Context, resourceGroupName, virtualNetworkName string, parameters network.VirtualNetwork) error CreateOrUpdate(ctx context.Context, resourceGroupName, virtualNetworkName string, parameters network.VirtualNetwork) (*network.VirtualNetwork, error)
List(ctx context.Context, resourceGroupName string) ([]network.VirtualNetwork, error) List(ctx context.Context, resourceGroupName string) ([]*network.VirtualNetwork, error)
Delete(ctx context.Context, resourceGroupName, vnetName string) error Delete(ctx context.Context, resourceGroupName, vnetName string) error
} }
@ -37,37 +37,48 @@ type virtualNetworksClientImpl struct {
var _ VirtualNetworksClient = &virtualNetworksClientImpl{} var _ VirtualNetworksClient = &virtualNetworksClientImpl{}
func (c *virtualNetworksClientImpl) CreateOrUpdate(ctx context.Context, resourceGroupName, virtualNetworkName string, parameters network.VirtualNetwork) error { func (c *virtualNetworksClientImpl) CreateOrUpdate(ctx context.Context, resourceGroupName, virtualNetworkName string, parameters network.VirtualNetwork) (*network.VirtualNetwork, error) {
_, err := c.c.CreateOrUpdate(ctx, resourceGroupName, virtualNetworkName, parameters) future, err := c.c.BeginCreateOrUpdate(ctx, resourceGroupName, virtualNetworkName, parameters, nil)
return err if err != nil {
return nil, fmt.Errorf("creating/updating virtual network: %w", err)
}
vnet, err := future.PollUntilDone(ctx, nil)
if err != nil {
return nil, fmt.Errorf("waiting for virtual network create/update completion: %w", err)
}
return &vnet.VirtualNetwork, err
} }
func (c *virtualNetworksClientImpl) List(ctx context.Context, resourceGroupName string) ([]network.VirtualNetwork, error) { func (c *virtualNetworksClientImpl) List(ctx context.Context, resourceGroupName string) ([]*network.VirtualNetwork, error) {
var l []network.VirtualNetwork var l []*network.VirtualNetwork
for iter, err := c.c.ListComplete(ctx, resourceGroupName); iter.NotDone(); err = iter.Next() { pager := c.c.NewListPager(resourceGroupName, nil)
for pager.More() {
resp, err := pager.NextPage(ctx)
if err != nil { if err != nil {
return nil, err return nil, fmt.Errorf("listing virtual networks: %w", err)
} }
l = append(l, iter.Value()) l = append(l, resp.Value...)
} }
return l, nil return l, nil
} }
func (c *virtualNetworksClientImpl) Delete(ctx context.Context, resourceGroupName, vnetName string) error { func (c *virtualNetworksClientImpl) Delete(ctx context.Context, resourceGroupName, vnetName string) error {
future, err := c.c.Delete(ctx, resourceGroupName, vnetName) future, err := c.c.BeginDelete(ctx, resourceGroupName, vnetName, nil)
if err != nil { if err != nil {
return fmt.Errorf("error deleting virtual network: %s", err) return fmt.Errorf("deleting virtual network: %w", err)
} }
if err := future.WaitForCompletionRef(ctx, c.c.Client); err != nil { if _, err = future.PollUntilDone(ctx, nil); err != nil {
return fmt.Errorf("error waiting for virtual network deletion completion: %s", err) return fmt.Errorf("waiting for virtual network deletion completion: %w", err)
} }
return nil return nil
} }
func newVirtualNetworksClientImpl(subscriptionID string, authorizer autorest.Authorizer) *virtualNetworksClientImpl { func newVirtualNetworksClientImpl(subscriptionID string, cred *azidentity.DefaultAzureCredential) (*virtualNetworksClientImpl, error) {
c := network.NewVirtualNetworksClient(subscriptionID) c, err := network.NewVirtualNetworksClient(subscriptionID, cred, nil)
c.Authorizer = authorizer if err != nil {
return &virtualNetworksClientImpl{ return nil, fmt.Errorf("creating virtual networks client: %w", err)
c: &c,
} }
return &virtualNetworksClientImpl{
c: c,
}, nil
} }

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2020 The Kubernetes Authors. Copyright 2024 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -20,14 +20,15 @@ import (
"context" "context"
"fmt" "fmt"
"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2022-08-01/compute" "github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
"github.com/Azure/go-autorest/autorest" "github.com/Azure/azure-sdk-for-go/sdk/azidentity"
compute "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute"
) )
// VMScaleSetsClient is a client for managing VM Scale Set. // VMScaleSetsClient is a client for managing VMSSs.
type VMScaleSetsClient interface { type VMScaleSetsClient interface {
CreateOrUpdate(ctx context.Context, resourceGroupName, vmScaleSetName string, parameters compute.VirtualMachineScaleSet) (*compute.VirtualMachineScaleSet, error) CreateOrUpdate(ctx context.Context, resourceGroupName, vmScaleSetName string, parameters compute.VirtualMachineScaleSet) (*compute.VirtualMachineScaleSet, error)
List(ctx context.Context, resourceGroupName string) ([]compute.VirtualMachineScaleSet, error) List(ctx context.Context, resourceGroupName string) ([]*compute.VirtualMachineScaleSet, error)
Get(ctx context.Context, resourceGroupName string, vmssName string) (*compute.VirtualMachineScaleSet, error) Get(ctx context.Context, resourceGroupName string, vmssName string) (*compute.VirtualMachineScaleSet, error)
Delete(ctx context.Context, resourceGroupName, vmssName string) error Delete(ctx context.Context, resourceGroupName, vmssName string) error
} }
@ -39,54 +40,58 @@ type vmScaleSetsClientImpl struct {
var _ VMScaleSetsClient = &vmScaleSetsClientImpl{} var _ VMScaleSetsClient = &vmScaleSetsClientImpl{}
func (c *vmScaleSetsClientImpl) CreateOrUpdate(ctx context.Context, resourceGroupName, vmScaleSetName string, parameters compute.VirtualMachineScaleSet) (*compute.VirtualMachineScaleSet, error) { func (c *vmScaleSetsClientImpl) CreateOrUpdate(ctx context.Context, resourceGroupName, vmScaleSetName string, parameters compute.VirtualMachineScaleSet) (*compute.VirtualMachineScaleSet, error) {
future, err := c.c.CreateOrUpdate(ctx, resourceGroupName, vmScaleSetName, parameters) future, err := c.c.BeginCreateOrUpdate(ctx, resourceGroupName, vmScaleSetName, parameters, nil)
if err != nil { if err != nil {
return nil, fmt.Errorf("error creating/updating VM Scale Set: %s", err) return nil, fmt.Errorf("creating/updating VMSS: %w", err)
} }
if err := future.WaitForCompletionRef(ctx, c.c.Client); err != nil { resp, err := future.PollUntilDone(ctx, nil)
return nil, fmt.Errorf("error waiting for VM Scale Set create/update completion: %s", err)
}
vmss, err := future.Result(*c.c)
if err != nil { if err != nil {
return nil, fmt.Errorf("error obtaining result for VM Scale Set create/update: %s", err) return nil, fmt.Errorf("waiting for VMSS create/update: %w", err)
} }
return &vmss, nil return &resp.VirtualMachineScaleSet, nil
} }
func (c *vmScaleSetsClientImpl) List(ctx context.Context, resourceGroupName string) ([]compute.VirtualMachineScaleSet, error) { func (c *vmScaleSetsClientImpl) List(ctx context.Context, resourceGroupName string) ([]*compute.VirtualMachineScaleSet, error) {
var l []compute.VirtualMachineScaleSet var l []*compute.VirtualMachineScaleSet
for iter, err := c.c.ListComplete(ctx, resourceGroupName); iter.NotDone(); err = iter.Next() { pager := c.c.NewListPager(resourceGroupName, nil)
for pager.More() {
resp, err := pager.NextPage(ctx)
if err != nil { if err != nil {
return nil, err return nil, fmt.Errorf("listing VMSSs: %w", err)
} }
l = append(l, iter.Value()) l = append(l, resp.Value...)
} }
return l, nil return l, nil
} }
func (c *vmScaleSetsClientImpl) Get(ctx context.Context, resourceGroupName string, vmssName string) (*compute.VirtualMachineScaleSet, error) { func (c *vmScaleSetsClientImpl) Get(ctx context.Context, resourceGroupName string, vmssName string) (*compute.VirtualMachineScaleSet, error) {
vmss, err := c.c.Get(ctx, resourceGroupName, vmssName, compute.UserData) opts := &compute.VirtualMachineScaleSetsClientGetOptions{
if err != nil { Expand: to.Ptr(compute.ExpandTypesForGetVMScaleSetsUserData),
return nil, err
} }
return &vmss, nil resp, err := c.c.Get(ctx, resourceGroupName, vmssName, opts)
if err != nil {
return nil, fmt.Errorf("getting VMSS: %w", err)
}
return &resp.VirtualMachineScaleSet, nil
} }
func (c *vmScaleSetsClientImpl) Delete(ctx context.Context, resourceGroupName, vmssName string) error { func (c *vmScaleSetsClientImpl) Delete(ctx context.Context, resourceGroupName, vmssName string) error {
future, err := c.c.Delete(ctx, resourceGroupName, vmssName, nil) future, err := c.c.BeginDelete(ctx, resourceGroupName, vmssName, nil)
if err != nil { if err != nil {
return fmt.Errorf("error deleting VM Scale Set: %s", err) return fmt.Errorf("deleting VMSS: %w", err)
} }
if err := future.WaitForCompletionRef(ctx, c.c.Client); err != nil { if _, err := future.PollUntilDone(ctx, nil); err != nil {
return fmt.Errorf("error waiting for VM Scale Set deletion completion: %s", err) return fmt.Errorf("waiting for VMSS deletion completion: %w", err)
} }
return nil return nil
} }
func newVMScaleSetsClientImpl(subscriptionID string, authorizer autorest.Authorizer) *vmScaleSetsClientImpl { func newVMScaleSetsClientImpl(subscriptionID string, cred *azidentity.DefaultAzureCredential) (*vmScaleSetsClientImpl, error) {
c := compute.NewVirtualMachineScaleSetsClient(subscriptionID) c, err := compute.NewVirtualMachineScaleSetsClient(subscriptionID, cred, nil)
c.Authorizer = authorizer if err != nil {
return &vmScaleSetsClientImpl{ return nil, fmt.Errorf("creating VMSSs client: %w", err)
c: &c,
} }
return &vmScaleSetsClientImpl{
c: c,
}, nil
} }

View File

@ -18,14 +18,15 @@ package azure
import ( import (
"context" "context"
"fmt"
"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2022-08-01/compute" "github.com/Azure/azure-sdk-for-go/sdk/azidentity"
"github.com/Azure/go-autorest/autorest" compute "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute"
) )
// VMScaleSetVMsClient is a client for managing VMs in VM Scale Sets. // VMScaleSetVMsClient is a client for managing VMs in VM Scale Sets.
type VMScaleSetVMsClient interface { type VMScaleSetVMsClient interface {
List(ctx context.Context, resourceGroupName, vmssName string) ([]compute.VirtualMachineScaleSetVM, error) List(ctx context.Context, resourceGroupName, vmssName string) ([]*compute.VirtualMachineScaleSetVM, error)
} }
type vmScaleSetVMsClientImpl struct { type vmScaleSetVMsClientImpl struct {
@ -34,21 +35,25 @@ type vmScaleSetVMsClientImpl struct {
var _ VMScaleSetVMsClient = &vmScaleSetVMsClientImpl{} var _ VMScaleSetVMsClient = &vmScaleSetVMsClientImpl{}
func (c *vmScaleSetVMsClientImpl) List(ctx context.Context, resourceGroupName, vmssName string) ([]compute.VirtualMachineScaleSetVM, error) { func (c *vmScaleSetVMsClientImpl) List(ctx context.Context, resourceGroupName, vmssName string) ([]*compute.VirtualMachineScaleSetVM, error) {
var l []compute.VirtualMachineScaleSetVM var l []*compute.VirtualMachineScaleSetVM
for iter, err := c.c.ListComplete(ctx, resourceGroupName, vmssName, "", "", ""); iter.NotDone(); err = iter.Next() { pager := c.c.NewListPager(resourceGroupName, vmssName, nil)
for pager.More() {
resp, err := pager.NextPage(ctx)
if err != nil { if err != nil {
return nil, err return nil, fmt.Errorf("listing VMSS VMs: %w", err)
} }
l = append(l, iter.Value()) l = append(l, resp.Value...)
} }
return l, nil return l, nil
} }
func newVMScaleSetVMsClientImpl(subscriptionID string, authorizer autorest.Authorizer) *vmScaleSetVMsClientImpl { func newVMScaleSetVMsClientImpl(subscriptionID string, cred *azidentity.DefaultAzureCredential) (*vmScaleSetVMsClientImpl, error) {
c := compute.NewVirtualMachineScaleSetVMsClient(subscriptionID) c, err := compute.NewVirtualMachineScaleSetVMsClient(subscriptionID, cred, nil)
c.Authorizer = authorizer if err != nil {
return &vmScaleSetVMsClientImpl{ return nil, fmt.Errorf("creating VMSS VMs client: %w", err)
c: &c,
} }
return &vmScaleSetVMsClientImpl{
c: c,
}, nil
} }