|
Packit Service |
a04d08 |
# This file is part of cloud-init. See LICENSE file for license information.
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
"""Base Azure Cloud class."""
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
import os
|
|
Packit Service |
a04d08 |
import base64
|
|
Packit Service |
a04d08 |
import traceback
|
|
Packit Service |
a04d08 |
from datetime import datetime
|
|
Packit Service |
a04d08 |
from tests.cloud_tests import LOG
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
# pylint: disable=no-name-in-module
|
|
Packit Service |
a04d08 |
from azure.common.credentials import ServicePrincipalCredentials
|
|
Packit Service |
a04d08 |
# pylint: disable=no-name-in-module
|
|
Packit Service |
a04d08 |
from azure.mgmt.resource import ResourceManagementClient
|
|
Packit Service |
a04d08 |
# pylint: disable=no-name-in-module
|
|
Packit Service |
a04d08 |
from azure.mgmt.network import NetworkManagementClient
|
|
Packit Service |
a04d08 |
# pylint: disable=no-name-in-module
|
|
Packit Service |
a04d08 |
from azure.mgmt.compute import ComputeManagementClient
|
|
Packit Service |
a04d08 |
# pylint: disable=no-name-in-module
|
|
Packit Service |
a04d08 |
from azure.mgmt.storage import StorageManagementClient
|
|
Packit Service |
a04d08 |
from msrestazure.azure_exceptions import CloudError
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
from .image import AzureCloudImage
|
|
Packit Service |
a04d08 |
from .instance import AzureCloudInstance
|
|
Packit Service |
a04d08 |
from ..platforms import Platform
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
from cloudinit import util as c_util
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
class AzureCloudPlatform(Platform):
|
|
Packit Service |
a04d08 |
"""Azure Cloud test platforms."""
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
platform_name = 'azurecloud'
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def __init__(self, config):
|
|
Packit Service |
a04d08 |
"""Set up platform."""
|
|
Packit Service |
a04d08 |
super(AzureCloudPlatform, self).__init__(config)
|
|
Packit Service |
a04d08 |
self.tag = '%s-%s' % (
|
|
Packit Service |
a04d08 |
config['tag'], datetime.now().strftime('%Y%m%d%H%M%S'))
|
|
Packit Service |
a04d08 |
self.storage_sku = config['storage_sku']
|
|
Packit Service |
a04d08 |
self.vm_size = config['vm_size']
|
|
Packit Service |
a04d08 |
self.location = config['region']
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
try:
|
|
Packit Service |
a04d08 |
self.credentials, self.subscription_id = self._get_credentials()
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
self.resource_client = ResourceManagementClient(
|
|
Packit Service |
a04d08 |
self.credentials, self.subscription_id)
|
|
Packit Service |
a04d08 |
self.compute_client = ComputeManagementClient(
|
|
Packit Service |
a04d08 |
self.credentials, self.subscription_id)
|
|
Packit Service |
a04d08 |
self.network_client = NetworkManagementClient(
|
|
Packit Service |
a04d08 |
self.credentials, self.subscription_id)
|
|
Packit Service |
a04d08 |
self.storage_client = StorageManagementClient(
|
|
Packit Service |
a04d08 |
self.credentials, self.subscription_id)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
self.resource_group = self._create_resource_group()
|
|
Packit Service |
a04d08 |
self.public_ip = self._create_public_ip_address()
|
|
Packit Service |
a04d08 |
self.storage = self._create_storage_account(config)
|
|
Packit Service |
a04d08 |
self.vnet = self._create_vnet()
|
|
Packit Service |
a04d08 |
self.subnet = self._create_subnet()
|
|
Packit Service |
a04d08 |
self.nic = self._create_nic()
|
|
Packit Service |
11b429 |
except CloudError:
|
|
Packit Service |
11b429 |
raise RuntimeError('failed creating a resource:\n{}'.format(
|
|
Packit Service |
11b429 |
traceback.format_exc()))
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def create_instance(self, properties, config, features,
|
|
Packit Service |
a04d08 |
image_id, user_data=None):
|
|
Packit Service |
a04d08 |
"""Create an instance
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
@param properties: image properties
|
|
Packit Service |
a04d08 |
@param config: image configuration
|
|
Packit Service |
a04d08 |
@param features: image features
|
|
Packit Service |
a04d08 |
@param image_id: string of image id
|
|
Packit Service |
a04d08 |
@param user_data: test user-data to pass to instance
|
|
Packit Service |
a04d08 |
@return_value: cloud_tests.instances instance
|
|
Packit Service |
a04d08 |
"""
|
|
Packit Service |
11b429 |
user_data = str(base64.b64encode(
|
|
Packit Service |
11b429 |
user_data.encode('utf-8')), 'utf-8')
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
return AzureCloudInstance(self, properties, config, features,
|
|
Packit Service |
a04d08 |
image_id, user_data)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def get_image(self, img_conf):
|
|
Packit Service |
a04d08 |
"""Get image using specified image configuration.
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
@param img_conf: configuration for image
|
|
Packit Service |
a04d08 |
@return_value: cloud_tests.images instance
|
|
Packit Service |
a04d08 |
"""
|
|
Packit Service |
a04d08 |
ss_region = self.azure_location_to_simplestreams_region()
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
filters = [
|
|
Packit Service |
a04d08 |
'arch=%s' % 'amd64',
|
|
Packit Service |
a04d08 |
'endpoint=https://management.core.windows.net/',
|
|
Packit Service |
a04d08 |
'region=%s' % ss_region,
|
|
Packit Service |
a04d08 |
'release=%s' % img_conf['release']
|
|
Packit Service |
a04d08 |
]
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
LOG.debug('finding image using streams')
|
|
Packit Service |
a04d08 |
image = self._query_streams(img_conf, filters)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
try:
|
|
Packit Service |
a04d08 |
image_id = image['id']
|
|
Packit Service |
a04d08 |
LOG.debug('found image: %s', image_id)
|
|
Packit Service |
a04d08 |
if image_id.find('__') > 0:
|
|
Packit Service |
a04d08 |
image_id = image_id.split('__')[1]
|
|
Packit Service |
a04d08 |
LOG.debug('image_id shortened to %s', image_id)
|
|
Packit Service |
11b429 |
except KeyError:
|
|
Packit Service |
11b429 |
raise RuntimeError('no images found for %s' % img_conf['release'])
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
return AzureCloudImage(self, img_conf, image_id)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def destroy(self):
|
|
Packit Service |
a04d08 |
"""Delete all resources in resource group."""
|
|
Packit Service |
a04d08 |
LOG.debug("Deleting resource group: %s", self.resource_group.name)
|
|
Packit Service |
a04d08 |
delete = self.resource_client.resource_groups.delete(
|
|
Packit Service |
a04d08 |
self.resource_group.name)
|
|
Packit Service |
a04d08 |
delete.wait()
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def azure_location_to_simplestreams_region(self):
|
|
Packit Service |
a04d08 |
"""Convert location to simplestreams region"""
|
|
Packit Service |
a04d08 |
location = self.location.lower().replace(' ', '')
|
|
Packit Service |
a04d08 |
LOG.debug('finding location %s using simple streams', location)
|
|
Packit Service |
a04d08 |
regions_file = os.path.join(
|
|
Packit Service |
a04d08 |
os.path.dirname(os.path.abspath(__file__)), 'regions.json')
|
|
Packit Service |
a04d08 |
region_simplestreams_map = c_util.load_json(
|
|
Packit Service |
a04d08 |
c_util.load_file(regions_file))
|
|
Packit Service |
a04d08 |
return region_simplestreams_map.get(location, location)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def _get_credentials(self):
|
|
Packit Service |
a04d08 |
"""Get credentials from environment"""
|
|
Packit Service |
a04d08 |
LOG.debug('getting credentials from environment')
|
|
Packit Service |
a04d08 |
cred_file = os.path.expanduser('~/.azure/credentials.json')
|
|
Packit Service |
a04d08 |
try:
|
|
Packit Service |
a04d08 |
azure_creds = c_util.load_json(
|
|
Packit Service |
a04d08 |
c_util.load_file(cred_file))
|
|
Packit Service |
a04d08 |
subscription_id = azure_creds['subscriptionId']
|
|
Packit Service |
a04d08 |
credentials = ServicePrincipalCredentials(
|
|
Packit Service |
a04d08 |
client_id=azure_creds['clientId'],
|
|
Packit Service |
a04d08 |
secret=azure_creds['clientSecret'],
|
|
Packit Service |
a04d08 |
tenant=azure_creds['tenantId'])
|
|
Packit Service |
a04d08 |
return credentials, subscription_id
|
|
Packit Service |
11b429 |
except KeyError:
|
|
Packit Service |
11b429 |
raise RuntimeError('Please configure Azure service principal'
|
|
Packit Service |
11b429 |
' credentials in %s' % cred_file)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def _create_resource_group(self):
|
|
Packit Service |
a04d08 |
"""Create resource group"""
|
|
Packit Service |
a04d08 |
LOG.debug('creating resource group')
|
|
Packit Service |
a04d08 |
resource_group_name = self.tag
|
|
Packit Service |
a04d08 |
resource_group_params = {
|
|
Packit Service |
a04d08 |
'location': self.location
|
|
Packit Service |
a04d08 |
}
|
|
Packit Service |
a04d08 |
resource_group = self.resource_client.resource_groups.create_or_update(
|
|
Packit Service |
a04d08 |
resource_group_name, resource_group_params)
|
|
Packit Service |
a04d08 |
return resource_group
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def _create_storage_account(self, config):
|
|
Packit Service |
a04d08 |
LOG.debug('creating storage account')
|
|
Packit Service |
a04d08 |
storage_account_name = 'storage%s' % datetime.now().\
|
|
Packit Service |
a04d08 |
strftime('%Y%m%d%H%M%S')
|
|
Packit Service |
a04d08 |
storage_params = {
|
|
Packit Service |
a04d08 |
'sku': {
|
|
Packit Service |
a04d08 |
'name': config['storage_sku']
|
|
Packit Service |
a04d08 |
},
|
|
Packit Service |
a04d08 |
'kind': "Storage",
|
|
Packit Service |
a04d08 |
'location': self.location
|
|
Packit Service |
a04d08 |
}
|
|
Packit Service |
a04d08 |
storage_account = self.storage_client.storage_accounts.create(
|
|
Packit Service |
a04d08 |
self.resource_group.name, storage_account_name, storage_params)
|
|
Packit Service |
a04d08 |
return storage_account.result()
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def _create_public_ip_address(self):
|
|
Packit Service |
a04d08 |
"""Create public ip address"""
|
|
Packit Service |
a04d08 |
LOG.debug('creating public ip address')
|
|
Packit Service |
a04d08 |
public_ip_name = '%s-ip' % self.resource_group.name
|
|
Packit Service |
a04d08 |
public_ip_params = {
|
|
Packit Service |
a04d08 |
'location': self.location,
|
|
Packit Service |
a04d08 |
'public_ip_allocation_method': 'Dynamic'
|
|
Packit Service |
a04d08 |
}
|
|
Packit Service |
a04d08 |
ip = self.network_client.public_ip_addresses.create_or_update(
|
|
Packit Service |
a04d08 |
self.resource_group.name, public_ip_name, public_ip_params)
|
|
Packit Service |
a04d08 |
return ip.result()
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def _create_vnet(self):
|
|
Packit Service |
a04d08 |
"""create virtual network"""
|
|
Packit Service |
a04d08 |
LOG.debug('creating vnet')
|
|
Packit Service |
a04d08 |
vnet_name = '%s-vnet' % self.resource_group.name
|
|
Packit Service |
a04d08 |
vnet_params = {
|
|
Packit Service |
a04d08 |
'location': self.location,
|
|
Packit Service |
a04d08 |
'address_space': {
|
|
Packit Service |
a04d08 |
'address_prefixes': ['10.0.0.0/16']
|
|
Packit Service |
a04d08 |
}
|
|
Packit Service |
a04d08 |
}
|
|
Packit Service |
a04d08 |
vnet = self.network_client.virtual_networks.create_or_update(
|
|
Packit Service |
a04d08 |
self.resource_group.name, vnet_name, vnet_params)
|
|
Packit Service |
a04d08 |
return vnet.result()
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def _create_subnet(self):
|
|
Packit Service |
a04d08 |
"""create sub-network"""
|
|
Packit Service |
a04d08 |
LOG.debug('creating subnet')
|
|
Packit Service |
a04d08 |
subnet_name = '%s-subnet' % self.resource_group.name
|
|
Packit Service |
a04d08 |
subnet_params = {
|
|
Packit Service |
a04d08 |
'address_prefix': '10.0.0.0/24'
|
|
Packit Service |
a04d08 |
}
|
|
Packit Service |
a04d08 |
subnet = self.network_client.subnets.create_or_update(
|
|
Packit Service |
a04d08 |
self.resource_group.name, self.vnet.name,
|
|
Packit Service |
a04d08 |
subnet_name, subnet_params)
|
|
Packit Service |
a04d08 |
return subnet.result()
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def _create_nic(self):
|
|
Packit Service |
a04d08 |
"""Create network interface controller"""
|
|
Packit Service |
a04d08 |
LOG.debug('creating nic')
|
|
Packit Service |
a04d08 |
nic_name = '%s-nic' % self.resource_group.name
|
|
Packit Service |
a04d08 |
nic_params = {
|
|
Packit Service |
a04d08 |
'location': self.location,
|
|
Packit Service |
a04d08 |
'ip_configurations': [{
|
|
Packit Service |
a04d08 |
'name': 'ipconfig',
|
|
Packit Service |
a04d08 |
'subnet': {
|
|
Packit Service |
a04d08 |
'id': self.subnet.id
|
|
Packit Service |
a04d08 |
},
|
|
Packit Service |
a04d08 |
'publicIpAddress': {
|
|
Packit Service |
a04d08 |
'id': "/subscriptions/%s"
|
|
Packit Service |
a04d08 |
"/resourceGroups/%s/providers/Microsoft.Network"
|
|
Packit Service |
a04d08 |
"/publicIPAddresses/%s" % (
|
|
Packit Service |
a04d08 |
self.subscription_id, self.resource_group.name,
|
|
Packit Service |
a04d08 |
self.public_ip.name),
|
|
Packit Service |
a04d08 |
}
|
|
Packit Service |
a04d08 |
}]
|
|
Packit Service |
a04d08 |
}
|
|
Packit Service |
a04d08 |
nic = self.network_client.network_interfaces.create_or_update(
|
|
Packit Service |
a04d08 |
self.resource_group.name, nic_name, nic_params)
|
|
Packit Service |
a04d08 |
return nic.result()
|