Blame tests/cloud_tests/platforms/azurecloud/platform.py

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()