github.com/kubernetes-sigs/azuredisk-csi-driver@v0.7.0/test/utils/azure/azure_helpers.go (about)

     1  /*
     2  Copyright 2020 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package azure
    18  
    19  import (
    20  	"context"
    21  	"fmt"
    22  	"log"
    23  	"os"
    24  	"time"
    25  
    26  	"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2019-03-01/compute"
    27  	"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network"
    28  	"github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-05-01/resources"
    29  	"github.com/Azure/go-autorest/autorest"
    30  	"github.com/Azure/go-autorest/autorest/adal"
    31  	"github.com/Azure/go-autorest/autorest/azure"
    32  	"github.com/Azure/go-autorest/autorest/to"
    33  )
    34  
    35  type AzureClient struct {
    36  	environment    azure.Environment
    37  	subscriptionID string
    38  	groupsClient   resources.GroupsClient
    39  	vmClient       compute.VirtualMachinesClient
    40  	nicClient      network.InterfacesClient
    41  	subnetsClient  network.SubnetsClient
    42  	vnetClient     network.VirtualNetworksClient
    43  }
    44  
    45  func GetAzureClient(cloud, subscriptionID, clientID, tenantID, clientSecret string) (*AzureClient, error) {
    46  	env, err := azure.EnvironmentFromName(cloud)
    47  	if err != nil {
    48  		return nil, err
    49  	}
    50  
    51  	oauthConfig, err := getOAuthConfig(env, subscriptionID, tenantID)
    52  	if err != nil {
    53  		return nil, err
    54  	}
    55  
    56  	armSpt, err := adal.NewServicePrincipalToken(*oauthConfig, clientID, clientSecret, env.ServiceManagementEndpoint)
    57  	if err != nil {
    58  		return nil, err
    59  	}
    60  
    61  	return getClient(env, subscriptionID, tenantID, armSpt), nil
    62  }
    63  
    64  func (az *AzureClient) EnsureResourceGroup(ctx context.Context, name, location string, managedBy *string) (resourceGroup *resources.Group, err error) {
    65  	var tags map[string]*string
    66  	group, err := az.groupsClient.Get(ctx, name)
    67  	if err == nil && group.Tags != nil {
    68  		tags = group.Tags
    69  	} else {
    70  		tags = make(map[string]*string)
    71  	}
    72  	// Tags for correlating resource groups with prow jobs on testgrid
    73  	tags["buildID"] = stringPointer(os.Getenv("BUILD_ID"))
    74  	tags["jobName"] = stringPointer(os.Getenv("JOB_NAME"))
    75  	tags["creationTimestamp"] = stringPointer(time.Now().UTC().Format(time.RFC3339))
    76  
    77  	response, err := az.groupsClient.CreateOrUpdate(ctx, name, resources.Group{
    78  		Name:      &name,
    79  		Location:  &location,
    80  		ManagedBy: managedBy,
    81  		Tags:      tags,
    82  	})
    83  	if err != nil {
    84  		return &response, err
    85  	}
    86  
    87  	return &response, nil
    88  }
    89  
    90  func (az *AzureClient) DeleteResourceGroup(ctx context.Context, groupName string) error {
    91  	_, err := az.groupsClient.Get(ctx, groupName)
    92  	if err == nil {
    93  		future, err := az.groupsClient.Delete(ctx, groupName)
    94  		if err != nil {
    95  			return fmt.Errorf("cannot delete resource group %v: %v", groupName, err)
    96  		}
    97  		err = future.WaitForCompletionRef(ctx, az.groupsClient.Client)
    98  		if err != nil {
    99  			// Skip the teardown errors because of https://github.com/Azure/go-autorest/issues/357
   100  			// TODO(feiskyer): fix the issue by upgrading go-autorest version >= v11.3.2.
   101  			log.Printf("Warning: failed to delete resource group %q with error %v", groupName, err)
   102  		}
   103  	}
   104  	return nil
   105  }
   106  
   107  func (az *AzureClient) EnsureVirtualMachine(ctx context.Context, groupName, location, vmName string) (vm compute.VirtualMachine, err error) {
   108  	nic, err := az.EnsureNIC(ctx, groupName, location, vmName+"-nic", vmName+"-vnet", vmName+"-subnet")
   109  	if err != nil {
   110  		return vm, err
   111  	}
   112  
   113  	future, err := az.vmClient.CreateOrUpdate(
   114  		ctx,
   115  		groupName,
   116  		vmName,
   117  		compute.VirtualMachine{
   118  			Location: to.StringPtr(location),
   119  			VirtualMachineProperties: &compute.VirtualMachineProperties{
   120  				HardwareProfile: &compute.HardwareProfile{
   121  					VMSize: compute.VirtualMachineSizeTypesStandardDS2V2,
   122  				},
   123  				StorageProfile: &compute.StorageProfile{
   124  					ImageReference: &compute.ImageReference{
   125  						Publisher: to.StringPtr("Canonical"),
   126  						Offer:     to.StringPtr("UbuntuServer"),
   127  						Sku:       to.StringPtr("16.04.0-LTS"),
   128  						Version:   to.StringPtr("latest"),
   129  					},
   130  				},
   131  				OsProfile: &compute.OSProfile{
   132  					ComputerName:  to.StringPtr(vmName),
   133  					AdminUsername: to.StringPtr("azureuser"),
   134  					AdminPassword: to.StringPtr("Azureuser1234"),
   135  				},
   136  				NetworkProfile: &compute.NetworkProfile{
   137  					NetworkInterfaces: &[]compute.NetworkInterfaceReference{
   138  						{
   139  							ID: nic.ID,
   140  							NetworkInterfaceReferenceProperties: &compute.NetworkInterfaceReferenceProperties{
   141  								Primary: to.BoolPtr(true),
   142  							},
   143  						},
   144  					},
   145  				},
   146  			},
   147  		},
   148  	)
   149  	if err != nil {
   150  		return vm, fmt.Errorf("cannot create vm: %v", err)
   151  	}
   152  
   153  	err = future.WaitForCompletionRef(ctx, az.vmClient.Client)
   154  	if err != nil {
   155  		return vm, fmt.Errorf("cannot get the vm create or update future response: %v", err)
   156  	}
   157  
   158  	return future.Result(az.vmClient)
   159  }
   160  
   161  func (az *AzureClient) EnsureNIC(ctx context.Context, groupName, location, nicName, vnetName, subnetName string) (nic network.Interface, err error) {
   162  	_, err = az.EnsureVirtualNetworkAndSubnet(ctx, groupName, location, vnetName, subnetName)
   163  	if err != nil {
   164  		return nic, err
   165  	}
   166  
   167  	subnet, err := az.GetVirtualNetworkSubnet(ctx, groupName, vnetName, subnetName)
   168  	if err != nil {
   169  		return nic, fmt.Errorf("cannot get subnet %s of virtual network %s in %s: %v", subnetName, vnetName, groupName, err)
   170  	}
   171  
   172  	future, err := az.nicClient.CreateOrUpdate(
   173  		ctx,
   174  		groupName,
   175  		nicName,
   176  		network.Interface{
   177  			Name:     to.StringPtr(nicName),
   178  			Location: to.StringPtr(location),
   179  			InterfacePropertiesFormat: &network.InterfacePropertiesFormat{
   180  				IPConfigurations: &[]network.InterfaceIPConfiguration{
   181  					{
   182  						Name: to.StringPtr("ipConfig1"),
   183  						InterfaceIPConfigurationPropertiesFormat: &network.InterfaceIPConfigurationPropertiesFormat{
   184  							Subnet:                    &subnet,
   185  							PrivateIPAllocationMethod: network.Dynamic,
   186  						},
   187  					},
   188  				},
   189  			},
   190  		},
   191  	)
   192  	if err != nil {
   193  		return nic, fmt.Errorf("cannot create nic: %v", err)
   194  	}
   195  
   196  	err = future.WaitForCompletionRef(ctx, az.nicClient.Client)
   197  	if err != nil {
   198  		return nic, fmt.Errorf("cannot get nic create or update future response: %v", err)
   199  	}
   200  
   201  	return future.Result(az.nicClient)
   202  }
   203  
   204  func (az *AzureClient) EnsureVirtualNetworkAndSubnet(ctx context.Context, groupName, location, vnetName, subnetName string) (vnet network.VirtualNetwork, err error) {
   205  	future, err := az.vnetClient.CreateOrUpdate(
   206  		ctx,
   207  		groupName,
   208  		vnetName,
   209  		network.VirtualNetwork{
   210  			Location: to.StringPtr(location),
   211  			VirtualNetworkPropertiesFormat: &network.VirtualNetworkPropertiesFormat{
   212  				AddressSpace: &network.AddressSpace{
   213  					AddressPrefixes: &[]string{"10.0.0.0/8"},
   214  				},
   215  				Subnets: &[]network.Subnet{
   216  					{
   217  						Name: to.StringPtr(subnetName),
   218  						SubnetPropertiesFormat: &network.SubnetPropertiesFormat{
   219  							AddressPrefix: to.StringPtr("10.0.0.0/16"),
   220  						},
   221  					},
   222  				},
   223  			},
   224  		})
   225  
   226  	if err != nil {
   227  		return vnet, fmt.Errorf("cannot create virtual network: %v", err)
   228  	}
   229  
   230  	err = future.WaitForCompletionRef(ctx, az.vnetClient.Client)
   231  	if err != nil {
   232  		return vnet, fmt.Errorf("cannot get the vnet create or update future response: %v", err)
   233  	}
   234  
   235  	return future.Result(az.vnetClient)
   236  }
   237  
   238  func (az *AzureClient) GetVirtualNetworkSubnet(ctx context.Context, groupName, vnetName, subnetName string) (network.Subnet, error) {
   239  	return az.subnetsClient.Get(ctx, groupName, vnetName, subnetName, "")
   240  }
   241  
   242  func getOAuthConfig(env azure.Environment, subscriptionID, tenantID string) (*adal.OAuthConfig, error) {
   243  	oauthConfig, err := adal.NewOAuthConfig(env.ActiveDirectoryEndpoint, tenantID)
   244  	if err != nil {
   245  		return nil, err
   246  	}
   247  
   248  	return oauthConfig, nil
   249  }
   250  
   251  func getClient(env azure.Environment, subscriptionID, tenantID string, armSpt *adal.ServicePrincipalToken) *AzureClient {
   252  	c := &AzureClient{
   253  		environment:    env,
   254  		subscriptionID: subscriptionID,
   255  		groupsClient:   resources.NewGroupsClientWithBaseURI(env.ResourceManagerEndpoint, subscriptionID),
   256  		vmClient:       compute.NewVirtualMachinesClient(subscriptionID),
   257  		nicClient:      network.NewInterfacesClient(subscriptionID),
   258  		subnetsClient:  network.NewSubnetsClient(subscriptionID),
   259  		vnetClient:     network.NewVirtualNetworksClient(subscriptionID),
   260  	}
   261  
   262  	authorizer := autorest.NewBearerAuthorizer(armSpt)
   263  	c.groupsClient.Authorizer = authorizer
   264  	c.vmClient.Authorizer = authorizer
   265  	c.nicClient.Authorizer = authorizer
   266  	c.subnetsClient.Authorizer = authorizer
   267  	c.vnetClient.Authorizer = authorizer
   268  
   269  	return c
   270  }
   271  
   272  func stringPointer(s string) *string {
   273  	return &s
   274  }