pkg/providers/instance/azure_client.go (127 lines of code) (raw):

/* Portions Copyright (c) Microsoft Corporation. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package instance import ( "context" "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" "github.com/Azure/azure-sdk-for-go/sdk/azidentity" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute" armcomputev5 "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resourcegraph/armresourcegraph" "github.com/Azure/go-autorest/autorest/azure" "github.com/Azure/karpenter-provider-azure/pkg/auth" "github.com/Azure/karpenter-provider-azure/pkg/providers/imagefamily" "github.com/Azure/karpenter-provider-azure/pkg/providers/instance/skuclient" "github.com/Azure/karpenter-provider-azure/pkg/providers/loadbalancer" armopts "github.com/Azure/karpenter-provider-azure/pkg/utils/opts" klog "k8s.io/klog/v2" ) type VirtualMachinesAPI interface { BeginCreateOrUpdate(ctx context.Context, resourceGroupName string, vmName string, parameters armcompute.VirtualMachine, options *armcompute.VirtualMachinesClientBeginCreateOrUpdateOptions) (*runtime.Poller[armcompute.VirtualMachinesClientCreateOrUpdateResponse], error) Get(ctx context.Context, resourceGroupName string, vmName string, options *armcompute.VirtualMachinesClientGetOptions) (armcompute.VirtualMachinesClientGetResponse, error) BeginUpdate(ctx context.Context, resourceGroupName string, vmName string, parameters armcompute.VirtualMachineUpdate, options *armcompute.VirtualMachinesClientBeginUpdateOptions) (*runtime.Poller[armcompute.VirtualMachinesClientUpdateResponse], error) BeginDelete(ctx context.Context, resourceGroupName string, vmName string, options *armcompute.VirtualMachinesClientBeginDeleteOptions) (*runtime.Poller[armcompute.VirtualMachinesClientDeleteResponse], error) } type AzureResourceGraphAPI interface { Resources(ctx context.Context, query armresourcegraph.QueryRequest, options *armresourcegraph.ClientResourcesOptions) (armresourcegraph.ClientResourcesResponse, error) } type VirtualMachineExtensionsAPI interface { BeginCreateOrUpdate(ctx context.Context, resourceGroupName string, vmName string, vmExtensionName string, extensionParameters armcompute.VirtualMachineExtension, options *armcompute.VirtualMachineExtensionsClientBeginCreateOrUpdateOptions) (*runtime.Poller[armcompute.VirtualMachineExtensionsClientCreateOrUpdateResponse], error) } type NetworkInterfacesAPI interface { BeginCreateOrUpdate(ctx context.Context, resourceGroupName string, networkInterfaceName string, parameters armnetwork.Interface, options *armnetwork.InterfacesClientBeginCreateOrUpdateOptions) (*runtime.Poller[armnetwork.InterfacesClientCreateOrUpdateResponse], error) BeginDelete(ctx context.Context, resourceGroupName string, networkInterfaceName string, options *armnetwork.InterfacesClientBeginDeleteOptions) (*runtime.Poller[armnetwork.InterfacesClientDeleteResponse], error) Get(ctx context.Context, resourceGroupName string, networkInterfaceName string, options *armnetwork.InterfacesClientGetOptions) (armnetwork.InterfacesClientGetResponse, error) } // TODO: Move this to another package that more correctly reflects its usage across multiple providers type AZClient struct { azureResourceGraphClient AzureResourceGraphAPI virtualMachinesClient VirtualMachinesAPI virtualMachinesExtensionClient VirtualMachineExtensionsAPI networkInterfacesClient NetworkInterfacesAPI NodeImageVersionsClient imagefamily.NodeImageVersionsAPI ImageVersionsClient imagefamily.CommunityGalleryImageVersionsAPI // SKU CLIENT is still using track 1 because skewer does not support the track 2 path. We need to refactor this once skewer supports track 2 SKUClient skuclient.SkuClient LoadBalancersClient loadbalancer.LoadBalancersAPI } func NewAZClientFromAPI( virtualMachinesClient VirtualMachinesAPI, azureResourceGraphClient AzureResourceGraphAPI, virtualMachinesExtensionClient VirtualMachineExtensionsAPI, interfacesClient NetworkInterfacesAPI, loadBalancersClient loadbalancer.LoadBalancersAPI, imageVersionsClient imagefamily.CommunityGalleryImageVersionsAPI, nodeImageVersionsClient imagefamily.NodeImageVersionsAPI, skuClient skuclient.SkuClient, ) *AZClient { return &AZClient{ virtualMachinesClient: virtualMachinesClient, azureResourceGraphClient: azureResourceGraphClient, virtualMachinesExtensionClient: virtualMachinesExtensionClient, networkInterfacesClient: interfacesClient, ImageVersionsClient: imageVersionsClient, NodeImageVersionsClient: nodeImageVersionsClient, SKUClient: skuClient, LoadBalancersClient: loadBalancersClient, } } func CreateAZClient(ctx context.Context, cfg *auth.Config) (*AZClient, error) { // Defaulting env to Azure Public Cloud. env := azure.PublicCloud var err error if cfg.Cloud != "" { env, err = azure.EnvironmentFromName(cfg.Cloud) if err != nil { return nil, err } } azClient, err := NewAZClient(ctx, cfg, &env) if err != nil { return nil, err } return azClient, nil } func NewAZClient(ctx context.Context, cfg *auth.Config, env *azure.Environment) (*AZClient, error) { defaultAzureCred, err := azidentity.NewDefaultAzureCredential(nil) if err != nil { return nil, err } cred := auth.NewTokenWrapper(defaultAzureCred) opts := armopts.DefaultArmOpts() extensionsClient, err := armcompute.NewVirtualMachineExtensionsClient(cfg.SubscriptionID, cred, opts) if err != nil { return nil, err } interfacesClient, err := armnetwork.NewInterfacesClient(cfg.SubscriptionID, cred, opts) if err != nil { return nil, err } klog.V(5).Infof("Created network interface client %v using token credential", interfacesClient) virtualMachinesClient, err := armcompute.NewVirtualMachinesClient(cfg.SubscriptionID, cred, opts) if err != nil { return nil, err } klog.V(5).Infof("Created virtual machines client %v, using a token credential", virtualMachinesClient) azureResourceGraphClient, err := armresourcegraph.NewClient(cred, opts) if err != nil { return nil, err } klog.V(5).Infof("Created azure resource graph client %v, using a token credential", azureResourceGraphClient) communityImageVersionsClient, err := armcomputev5.NewCommunityGalleryImageVersionsClient(cfg.SubscriptionID, cred, opts) if err != nil { return nil, err } klog.V(5).Infof("Created image versions client %v, using a token credential", communityImageVersionsClient) nodeImageVersionsClient := imagefamily.NewNodeImageVersionsClient(cred) loadBalancersClient, err := armnetwork.NewLoadBalancersClient(cfg.SubscriptionID, cred, opts) if err != nil { return nil, err } klog.V(5).Infof("Created load balancers client %v, using a token credential", loadBalancersClient) // TODO: this one is not enabled for rate limiting / throttling ... // TODO Move this over to track 2 when skewer is migrated skuClient := skuclient.NewSkuClient(ctx, cfg, env) return NewAZClientFromAPI(virtualMachinesClient, azureResourceGraphClient, extensionsClient, interfacesClient, loadBalancersClient, communityImageVersionsClient, nodeImageVersionsClient, skuClient), nil }