github.com/jenkins-x/test-infra@v0.0.7/kubetest/azure_helpers.go (about)

     1  /*
     2  Copyright 2018 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 main
    18  
    19  import (
    20  	"context"
    21  	"fmt"
    22  	"time"
    23  
    24  	resources "github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-05-01/resources"
    25  	"github.com/Azure/go-autorest/autorest"
    26  	"github.com/Azure/go-autorest/autorest/adal"
    27  	"github.com/Azure/go-autorest/autorest/azure"
    28  )
    29  
    30  type AcsEngineAPIModel struct {
    31  	Location   string            `json:"location,omitempty"`
    32  	Name       string            `json:"name,omitempty"`
    33  	Tags       map[string]string `json:"tags,omitempty"`
    34  	APIVersion string            `json:"APIVersion"`
    35  
    36  	Properties *Properties `json:"properties"`
    37  }
    38  
    39  type Properties struct {
    40  	OrchestratorProfile     *OrchestratorProfile     `json:"orchestratorProfile,omitempty"`
    41  	MasterProfile           *MasterProfile           `json:"masterProfile,omitempty"`
    42  	AgentPoolProfiles       []*AgentPoolProfile      `json:"agentPoolProfiles,omitempty"`
    43  	LinuxProfile            *LinuxProfile            `json:"linuxProfile,omitempty"`
    44  	WindowsProfile          *WindowsProfile          `json:"windowsProfile,omitempty"`
    45  	ServicePrincipalProfile *ServicePrincipalProfile `json:"servicePrincipalProfile,omitempty"`
    46  	ExtensionProfiles       []map[string]string      `json:"extensionProfiles,omitempty"`
    47  }
    48  
    49  type ServicePrincipalProfile struct {
    50  	ClientID string `json:"clientId,omitempty"`
    51  	Secret   string `json:"secret,omitempty"`
    52  }
    53  
    54  type LinuxProfile struct {
    55  	AdminUsername string `json:"adminUsername"`
    56  	SSHKeys       *SSH   `json:"ssh"`
    57  }
    58  
    59  type SSH struct {
    60  	PublicKeys []PublicKey `json:"publicKeys"`
    61  }
    62  
    63  type PublicKey struct {
    64  	KeyData string `json:"keyData"`
    65  }
    66  
    67  type WindowsProfile struct {
    68  	AdminUsername string `json:"adminUsername,omitempty"`
    69  	AdminPassword string `json:"adminPassword,omitempty"`
    70  }
    71  
    72  type KubernetesConfig struct {
    73  	CustomWindowsPackageURL string `json:"customWindowsPackageURL,omitempty"`
    74  	CustomHyperkubeImage    string `json:"customHyperkubeImage,omitempty"`
    75  	NetworkPlugin           string `json:"networkPlugin,omitempty"`
    76  }
    77  type OrchestratorProfile struct {
    78  	OrchestratorType    string            `json:"orchestratorType"`
    79  	OrchestratorRelease string            `json:"orchestratorRelease"`
    80  	KubernetesConfig    *KubernetesConfig `json:"kubernetesConfig,omitempty"`
    81  }
    82  
    83  type MasterProfile struct {
    84  	Count          int                 `json:"count"`
    85  	DNSPrefix      string              `json:"dnsPrefix"`
    86  	VMSize         string              `json:"vmSize" validate:"required"`
    87  	IPAddressCount int                 `json:"ipAddressCount,omitempty"`
    88  	Extensions     []map[string]string `json:"extensions,omitempty"`
    89  }
    90  
    91  type AgentPoolProfile struct {
    92  	Name                  string              `json:"name"`
    93  	Count                 int                 `json:"count"`
    94  	VMSize                string              `json:"vmSize"`
    95  	OSType                string              `json:"osType,omitempty"`
    96  	AvailabilityProfile   string              `json:"availabilityProfile"`
    97  	IPAddressCount        int                 `json:"ipAddressCount,omitempty"`
    98  	PreProvisionExtension map[string]string   `json:"preProvisionExtension,omitempty"`
    99  	Extensions            []map[string]string `json:"extensions,omitempty"`
   100  }
   101  
   102  type AzureClient struct {
   103  	environment       azure.Environment
   104  	subscriptionID    string
   105  	deploymentsClient resources.DeploymentsClient
   106  	groupsClient      resources.GroupsClient
   107  }
   108  
   109  func (az *AzureClient) ValidateDeployment(ctx context.Context, resourceGroupName, deploymentName string, template, params *map[string]interface{}) (valid resources.DeploymentValidateResult, err error) {
   110  	return az.deploymentsClient.Validate(ctx,
   111  		resourceGroupName,
   112  		deploymentName,
   113  		resources.Deployment{
   114  			Properties: &resources.DeploymentProperties{
   115  				Template:   template,
   116  				Parameters: params,
   117  				Mode:       resources.Incremental,
   118  			},
   119  		})
   120  }
   121  
   122  func (az *AzureClient) DeployTemplate(ctx context.Context, resourceGroupName, deploymentName string, template, parameters *map[string]interface{}) (de resources.DeploymentExtended, err error) {
   123  	future, err := az.deploymentsClient.CreateOrUpdate(
   124  		ctx,
   125  		resourceGroupName,
   126  		deploymentName,
   127  		resources.Deployment{
   128  			Properties: &resources.DeploymentProperties{
   129  				Template:   template,
   130  				Parameters: parameters,
   131  				Mode:       resources.Incremental,
   132  			},
   133  		})
   134  	if err != nil {
   135  		return de, fmt.Errorf("cannot create deployment: %v", err)
   136  	}
   137  
   138  	err = future.WaitForCompletion(ctx, az.deploymentsClient.Client)
   139  	if err != nil {
   140  		return de, fmt.Errorf("cannot get the create deployment future response: %v", err)
   141  	}
   142  
   143  	return future.Result(az.deploymentsClient)
   144  }
   145  
   146  func (az *AzureClient) EnsureResourceGroup(ctx context.Context, name, location string, managedBy *string) (resourceGroup *resources.Group, err error) {
   147  	var tags map[string]*string
   148  	group, err := az.groupsClient.Get(ctx, name)
   149  	if err == nil {
   150  		tags = group.Tags
   151  	}
   152  
   153  	response, err := az.groupsClient.CreateOrUpdate(ctx, name, resources.Group{
   154  		Name:      &name,
   155  		Location:  &location,
   156  		ManagedBy: managedBy,
   157  		Tags:      tags,
   158  	})
   159  	if err != nil {
   160  		return &response, err
   161  	}
   162  
   163  	return &response, nil
   164  }
   165  
   166  func (az *AzureClient) DeleteResourceGroup(ctx context.Context, groupName string) error {
   167  	_, err := az.groupsClient.Get(ctx, groupName)
   168  	if err == nil {
   169  		future, err := az.groupsClient.Delete(ctx, groupName)
   170  		if err != nil {
   171  			return fmt.Errorf("cannot delete resource group %v: %v", groupName, err)
   172  		}
   173  		err = future.WaitForCompletion(ctx, az.groupsClient.Client)
   174  		if err != nil {
   175  			return fmt.Errorf("cannot get the delete resource group future response: %v", err)
   176  		}
   177  	}
   178  	return nil
   179  }
   180  
   181  func getOAuthConfig(env azure.Environment, subscriptionID, tenantID string) (*adal.OAuthConfig, error) {
   182  
   183  	oauthConfig, err := adal.NewOAuthConfig(env.ActiveDirectoryEndpoint, tenantID)
   184  	if err != nil {
   185  		return nil, err
   186  	}
   187  
   188  	return oauthConfig, nil
   189  }
   190  
   191  func getAzureClient(env azure.Environment, subscriptionID, clientID, tenantID, clientSecret string) (*AzureClient, error) {
   192  	oauthConfig, err := getOAuthConfig(env, subscriptionID, tenantID)
   193  	if err != nil {
   194  		return nil, err
   195  	}
   196  
   197  	armSpt, err := adal.NewServicePrincipalToken(*oauthConfig, clientID, clientSecret, env.ServiceManagementEndpoint)
   198  	if err != nil {
   199  		return nil, err
   200  	}
   201  
   202  	return getClient(env, subscriptionID, tenantID, armSpt), nil
   203  }
   204  
   205  func getClient(env azure.Environment, subscriptionID, tenantID string, armSpt *adal.ServicePrincipalToken) *AzureClient {
   206  	c := &AzureClient{
   207  		environment:    env,
   208  		subscriptionID: subscriptionID,
   209  
   210  		deploymentsClient: resources.NewDeploymentsClientWithBaseURI(env.ResourceManagerEndpoint, subscriptionID),
   211  		groupsClient:      resources.NewGroupsClientWithBaseURI(env.ResourceManagerEndpoint, subscriptionID),
   212  	}
   213  
   214  	authorizer := autorest.NewBearerAuthorizer(armSpt)
   215  	c.deploymentsClient.Authorizer = authorizer
   216  	c.deploymentsClient.PollingDuration = 60 * time.Minute
   217  	c.groupsClient.Authorizer = authorizer
   218  
   219  	return c
   220  }