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