pkg/azmanager/azmanager.go (253 lines of code) (raw):
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
package azmanager
import (
"context"
"fmt"
"time"
compute "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v6"
network "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v6"
"sigs.k8s.io/cloud-provider-azure/pkg/azclient"
"sigs.k8s.io/cloud-provider-azure/pkg/azclient/interfaceclient"
"sigs.k8s.io/cloud-provider-azure/pkg/azclient/loadbalancerclient"
"sigs.k8s.io/cloud-provider-azure/pkg/azclient/publicipprefixclient"
"sigs.k8s.io/cloud-provider-azure/pkg/azclient/subnetclient"
_ "sigs.k8s.io/cloud-provider-azure/pkg/azclient/trace"
"sigs.k8s.io/cloud-provider-azure/pkg/azclient/virtualmachinescalesetclient"
"sigs.k8s.io/cloud-provider-azure/pkg/azclient/virtualmachinescalesetvmclient"
"github.com/Azure/kube-egress-gateway/pkg/config"
"github.com/Azure/kube-egress-gateway/pkg/consts"
"github.com/Azure/kube-egress-gateway/pkg/utils/to"
)
const (
// LB frontendIPConfiguration ID template
LBFrontendIPConfigTemplate = "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Network/loadBalancers/%s/frontendIPConfigurations/%s"
// LB backendAddressPool ID template
LBBackendPoolIDTemplate = "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Network/loadBalancers/%s/backendAddressPools/%s"
// LB probe ID template
LBProbeIDTemplate = "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Network/loadBalancers/%s/probes/%s"
)
type AzureManager struct {
*config.CloudConfig
LoadBalancerClient loadbalancerclient.Interface
VmssClient virtualmachinescalesetclient.Interface
VmssVMClient virtualmachinescalesetvmclient.Interface
PublicIPPrefixClient publicipprefixclient.Interface
InterfaceClient interfaceclient.Interface
SubnetClient subnetclient.Interface
}
func CreateAzureManager(cloud *config.CloudConfig, factory azclient.ClientFactory) (*AzureManager, error) {
az := AzureManager{
CloudConfig: cloud,
}
az.LoadBalancerClient = factory.GetLoadBalancerClient()
az.VmssClient = factory.GetVirtualMachineScaleSetClient()
az.PublicIPPrefixClient = factory.GetPublicIPPrefixClient()
az.VmssVMClient = factory.GetVirtualMachineScaleSetVMClient()
az.InterfaceClient = factory.GetInterfaceClient()
az.SubnetClient = factory.GetSubnetClient()
return &az, nil
}
func (az *AzureManager) SubscriptionID() string {
return az.CloudConfig.SubscriptionID
}
func (az *AzureManager) Location() string {
return az.CloudConfig.Location
}
func (az *AzureManager) LoadBalancerName() string {
if az.CloudConfig.LoadBalancerName == "" {
return consts.DefaultGatewayLBName
}
return az.CloudConfig.LoadBalancerName
}
func (az *AzureManager) GetLBFrontendIPConfigurationID(name string) *string {
return to.Ptr(fmt.Sprintf(LBFrontendIPConfigTemplate, az.SubscriptionID(), az.LoadBalancerResourceGroup, az.LoadBalancerName(), name))
}
func (az *AzureManager) GetLBBackendAddressPoolID(name string) *string {
return to.Ptr(fmt.Sprintf(LBBackendPoolIDTemplate, az.SubscriptionID(), az.LoadBalancerResourceGroup, az.LoadBalancerName(), name))
}
func (az *AzureManager) GetLBProbeID(name string) *string {
return to.Ptr(fmt.Sprintf(LBProbeIDTemplate, az.SubscriptionID(), az.LoadBalancerResourceGroup, az.LoadBalancerName(), name))
}
func (az *AzureManager) GetLB(ctx context.Context) (*network.LoadBalancer, error) {
ctx, cancel := context.WithTimeout(ctx, 60*time.Second)
defer cancel()
lb, err := az.LoadBalancerClient.Get(ctx, az.LoadBalancerResourceGroup, az.LoadBalancerName(), nil)
if err != nil {
return nil, err
}
return lb, nil
}
func (az *AzureManager) CreateOrUpdateLB(ctx context.Context, lb network.LoadBalancer) (*network.LoadBalancer, error) {
ctx, cancel := context.WithTimeout(ctx, 60*time.Second)
defer cancel()
ret, err := az.LoadBalancerClient.CreateOrUpdate(ctx, az.LoadBalancerResourceGroup, to.Val(lb.Name), lb)
if err != nil {
return nil, err
}
return ret, nil
}
func (az *AzureManager) DeleteLB(ctx context.Context) error {
ctx, cancel := context.WithTimeout(ctx, 60*time.Second)
defer cancel()
if err := az.LoadBalancerClient.Delete(ctx, az.LoadBalancerResourceGroup, az.LoadBalancerName()); err != nil {
return err
}
return nil
}
func (az *AzureManager) ListVMSS(ctx context.Context) ([]*compute.VirtualMachineScaleSet, error) {
ctx, cancel := context.WithTimeout(ctx, 60*time.Second)
defer cancel()
vmssList, err := az.VmssClient.List(ctx, az.ResourceGroup)
if err != nil {
return nil, err
}
return vmssList, nil
}
func (az *AzureManager) GetVMSS(ctx context.Context, resourceGroup, vmssName string) (*compute.VirtualMachineScaleSet, error) {
ctx, cancel := context.WithTimeout(ctx, 60*time.Second)
defer cancel()
if resourceGroup == "" {
resourceGroup = az.ResourceGroup
}
if vmssName == "" {
return nil, fmt.Errorf("vmss name is empty")
}
vmss, err := az.VmssClient.Get(ctx, resourceGroup, vmssName, nil)
if err != nil {
return nil, err
}
return vmss, nil
}
func (az *AzureManager) CreateOrUpdateVMSS(ctx context.Context, resourceGroup, vmssName string, vmss compute.VirtualMachineScaleSet) (*compute.VirtualMachineScaleSet, error) {
ctx, cancel := context.WithTimeout(ctx, 60*time.Second)
defer cancel()
if resourceGroup == "" {
resourceGroup = az.ResourceGroup
}
if vmssName == "" {
return nil, fmt.Errorf("vmss name is empty")
}
retVmss, err := az.VmssClient.CreateOrUpdate(ctx, resourceGroup, vmssName, vmss)
if err != nil {
return nil, err
}
return retVmss, nil
}
func (az *AzureManager) ListVMSSInstances(ctx context.Context, resourceGroup, vmssName string) ([]*compute.VirtualMachineScaleSetVM, error) {
ctx, cancel := context.WithTimeout(ctx, 60*time.Second)
defer cancel()
if resourceGroup == "" {
resourceGroup = az.ResourceGroup
}
if vmssName == "" {
return nil, fmt.Errorf("vmss name is empty")
}
vms, err := az.VmssVMClient.List(ctx, resourceGroup, vmssName)
if err != nil {
return nil, err
}
return vms, nil
}
func (az *AzureManager) GetVMSSInstance(ctx context.Context, resourceGroup, vmssName, instanceID string) (*compute.VirtualMachineScaleSetVM, error) {
ctx, cancel := context.WithTimeout(ctx, 60*time.Second)
defer cancel()
if resourceGroup == "" {
resourceGroup = az.ResourceGroup
}
if vmssName == "" {
return nil, fmt.Errorf("vmss name is empty")
}
if instanceID == "" {
return nil, fmt.Errorf("vmss instanceID is empty")
}
vm, err := az.VmssVMClient.Get(ctx, resourceGroup, vmssName, instanceID)
if err != nil {
return nil, err
}
return vm, nil
}
func (az *AzureManager) UpdateVMSSInstance(ctx context.Context, resourceGroup, vmssName, instanceID string, vm compute.VirtualMachineScaleSetVM) (*compute.VirtualMachineScaleSetVM, error) {
ctx, cancel := context.WithTimeout(ctx, 60*time.Second)
defer cancel()
if resourceGroup == "" {
resourceGroup = az.ResourceGroup
}
if vmssName == "" {
return nil, fmt.Errorf("vmss name is empty")
}
if instanceID == "" {
return nil, fmt.Errorf("vmss instanceID is empty")
}
retVM, err := az.VmssVMClient.Update(ctx, resourceGroup, vmssName, instanceID, vm)
if err != nil {
return nil, err
}
return retVM, nil
}
func (az *AzureManager) GetPublicIPPrefix(ctx context.Context, resourceGroup, prefixName string) (*network.PublicIPPrefix, error) {
ctx, cancel := context.WithTimeout(ctx, 60*time.Second)
defer cancel()
if resourceGroup == "" {
resourceGroup = az.ResourceGroup
}
if prefixName == "" {
return nil, fmt.Errorf("public ip prefix name is empty")
}
prefix, err := az.PublicIPPrefixClient.Get(ctx, resourceGroup, prefixName, nil)
if err != nil {
return nil, err
}
return prefix, nil
}
func (az *AzureManager) CreateOrUpdatePublicIPPrefix(ctx context.Context, resourceGroup, prefixName string, ipPrefix network.PublicIPPrefix) (*network.PublicIPPrefix, error) {
ctx, cancel := context.WithTimeout(ctx, 60*time.Second)
defer cancel()
if resourceGroup == "" {
resourceGroup = az.ResourceGroup
}
if prefixName == "" {
return nil, fmt.Errorf("public ip prefix name is empty")
}
prefix, err := az.PublicIPPrefixClient.CreateOrUpdate(ctx, resourceGroup, prefixName, ipPrefix)
if err != nil {
return nil, err
}
return prefix, nil
}
func (az *AzureManager) DeletePublicIPPrefix(ctx context.Context, resourceGroup, prefixName string) error {
ctx, cancel := context.WithTimeout(ctx, 900*time.Second)
defer cancel()
if resourceGroup == "" {
resourceGroup = az.ResourceGroup
}
if prefixName == "" {
return fmt.Errorf("public ip prefix name is empty")
}
return az.PublicIPPrefixClient.Delete(ctx, resourceGroup, prefixName)
}
func (az *AzureManager) GetVMSSInterface(ctx context.Context, resourceGroup, vmssName, instanceID, interfaceName string) (*network.Interface, error) {
ctx, cancel := context.WithTimeout(ctx, 60*time.Second)
defer cancel()
if resourceGroup == "" {
resourceGroup = az.ResourceGroup
}
if vmssName == "" {
return nil, fmt.Errorf("vmss name is empty")
}
if instanceID == "" {
return nil, fmt.Errorf("instanceID is empty")
}
if interfaceName == "" {
return nil, fmt.Errorf("interface name is empty")
}
nicResp, err := az.InterfaceClient.GetVirtualMachineScaleSetNetworkInterface(ctx, resourceGroup, vmssName, instanceID, interfaceName)
if err != nil {
return nil, err
}
return nicResp, nil
}
func (az *AzureManager) GetSubnet(ctx context.Context) (*network.Subnet, error) {
ctx, cancel := context.WithTimeout(ctx, 60*time.Second)
defer cancel()
subnet, err := az.SubnetClient.Get(ctx, az.VnetResourceGroup, az.VnetName, az.SubnetName, nil)
if err != nil {
return nil, err
}
return subnet, nil
}