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 }