Skip to content

Commit

Permalink
Wrapped reference and added retry for tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Alexandru Mahmoud authored and nuwang committed Jul 13, 2018
1 parent 0f77c1e commit c6d33f8
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 55 deletions.
36 changes: 26 additions & 10 deletions cloudbridge/cloud/providers/azure/azure_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from azure.common.credentials import ServicePrincipalCredentials
from azure.mgmt.compute import ComputeManagementClient
from azure.mgmt.devtestlabs.models import GalleryImageReference
from azure.mgmt.network import NetworkManagementClient
from azure.mgmt.resource import ResourceManagementClient
from azure.mgmt.resource.subscriptions import SubscriptionClient
Expand Down Expand Up @@ -79,8 +80,14 @@
# Listing possible somewhat through:
# azure.mgmt.devtestlabs.operations.GalleryImageOperations
gallery_image_references = \
['Canonical/UbuntuServer/16.04.0-LTS/latest',
'Canonical/UbuntuServer/14.04.5-LTS/latest']
[GalleryImageReference(publisher='Canonical',
offer='UbuntuServer',
sku='16.04.0-LTS',
version='latest'),
GalleryImageReference(publisher='Canonical',
offer='UbuntuServer',
sku='14.04.5-LTS',
version='latest')]


class AzureClient(object):
Expand Down Expand Up @@ -376,6 +383,12 @@ def update_snapshot_tags(self, snapshot_id, tags):
raw=True
)

def is_gallery_image(self, image_id):
url_params = azure_helpers.parse_url(IMAGE_RESOURCE_ID,
image_id)
# If it is a gallery image, it will always have an offer
return 'offer' in url_params

def create_image(self, name, params):
return self.compute_client.images. \
create_or_update(self.resource_group, name,
Expand All @@ -384,29 +397,32 @@ def create_image(self, name, params):
def delete_image(self, image_id):
url_params = azure_helpers.parse_url(IMAGE_RESOURCE_ID,
image_id)
if len(url_params) <= 3:
if not self.is_gallery_image(image_id):
name = url_params.get(IMAGE_NAME)
self.compute_client.images.delete(self.resource_group, name).wait()

def list_images(self):
return self.compute_client.images. \
list_by_resource_group(self.resource_group) \
+ gallery_image_references
return list(self.compute_client.images.
list_by_resource_group(self.resource_group)).\
append(gallery_image_references)

def get_image(self, image_id):
url_params = azure_helpers.parse_url(IMAGE_RESOURCE_ID,
image_id)
if len(url_params) > 3:
return url_params
if self.is_gallery_image(image_id):
return GalleryImageReference(publisher=url_params['publisher'],
offer=url_params['offer'],
sku=url_params['sku'],
version=url_params['version'])
else:
name = url_params.get(IMAGE_NAME)
return self.compute_client.images.get(self.resource_group, name)

def update_image_tags(self, image_id, tags):
url_params = azure_helpers.parse_url(IMAGE_RESOURCE_ID,
image_id)
if len(url_params) > 3:
return 1
if self.is_gallery_image(image_id):
return True
else:
name = url_params.get(IMAGE_NAME)
return self.compute_client.images. \
Expand Down
34 changes: 20 additions & 14 deletions cloudbridge/cloud/providers/azure/provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def __init__(self, config):
# optional config values
self.region_name = self._get_config_value(
'azure_region_name', os.environ.get('AZURE_REGION_NAME',
'eastus'))
'westus2'))
self.resource_group = self._get_config_value(
'azure_resource_group', os.environ.get('AZURE_RESOURCE_GROUP',
'cloudbridge'))
Expand Down Expand Up @@ -111,16 +111,22 @@ def _initialize(self):
self._azure_client.create_resource_group(self.resource_group,
resource_group_params)

try:
self._azure_client.get_storage_account(self.storage_account)
except CloudError:
storage_account_params = {
'sku': {
'name': 'Standard_LRS'
},
'kind': 'storage',
'location': self.region_name,
}
self._azure_client. \
create_storage_account(self.storage_account,
storage_account_params)
for i in range(5):
try:
self._azure_client.get_storage_account(self.storage_account)
break
except CloudError:
storage_account_params = {
'sku': {
'name': 'Standard_LRS'
},
'kind': 'storage',
'location': self.region_name,
}
try:
self._azure_client. \
create_storage_account(self.storage_account,
storage_account_params)
break
except CloudError:
pass
62 changes: 38 additions & 24 deletions cloudbridge/cloud/providers/azure/resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import uuid

from azure.common import AzureException
from azure.mgmt.devtestlabs.models import GalleryImageReference
from azure.mgmt.network.models import NetworkSecurityGroup

import cloudbridge.cloud.base.helpers as cb_helpers
Expand Down Expand Up @@ -676,12 +677,13 @@ def __init__(self, provider, image):
# Image can be either a dict for public image reference
# or the Azure iamge object
self._image = image
if not isinstance(self._image, dict):
if not isinstance(self._image, GalleryImageReference):
self._state = self._image.provisioning_state
else:
self._state = 'AVAILABLE'
self._state = 'SUCCEEDED'

if not isinstance(self._image, dict) and not self._image.tags:
if not isinstance(self._image, GalleryImageReference) \
and not self._image.tags:
self._image.tags = {}

@property
Expand All @@ -692,17 +694,21 @@ def id(self):
:rtype: ``str``
:return: ID for this instance as returned by the cloud middleware.
"""
if not isinstance(self._image, dict):
if not isinstance(self._image, GalleryImageReference):
return self._image.id
else:
return self._image['offer']

@property
def resource_id(self):
if not isinstance(self._image, dict):
if not isinstance(self._image, GalleryImageReference):
return self._image.id
else:
return self._image['offer']
reference_dict = self._image.as_dict()
return '/'.join([reference_dict['publisher'],
reference_dict['offer'],
reference_dict['sku'],
reference_dict['version']])

@property
def name(self):
Expand All @@ -712,17 +718,21 @@ def name(self):
:rtype: ``str``
:return: Name for this image as returned by the cloud middleware.
"""
if not isinstance(self._image, dict):
if not isinstance(self._image, GalleryImageReference):
return self._image.tags.get('Name', self._image.name)
else:
return self._image['offer']
reference_dict = self._image.as_dict()
return ':'.join([reference_dict['publisher'],
reference_dict['offer'],
reference_dict['sku'],
reference_dict['version']])

@name.setter
def name(self, value):
"""
Set the image name.
"""
if not isinstance(self._image, dict):
if not isinstance(self._image, GalleryImageReference):
self.assert_valid_resource_name(value)
self._image.tags.update(Name=value)
self._provider.azure_client. \
Expand All @@ -736,17 +746,18 @@ def description(self):
:rtype: ``str``
:return: Description for this image as returned by the cloud middleware
"""
if not isinstance(self._image, dict):
if not isinstance(self._image, GalleryImageReference):
return self._image.tags.get('Description', None)
else:
return 'Public Image'
return 'Public gallery image from the Azure Marketplace: '\
+ self.name

@description.setter
def description(self, value):
"""
Set the image name.
Set the image description.
"""
if not isinstance(self._image, dict):
if not isinstance(self._image, GalleryImageReference):
self._image.tags.update(Description=value)
self._provider.azure_client. \
update_image_tags(self.id, self._image.tags)
Expand All @@ -762,23 +773,33 @@ def min_disk(self):
:rtype: ``int``
:return: The minimum disk size needed by this image
"""
if not isinstance(self._image, dict):
if not isinstance(self._image, GalleryImageReference):
return self._image.storage_profile.os_disk.disk_size_gb or 0
else:
return 0

def delete(self):
"""
Delete this image
"""
if not isinstance(self._image, dict):
if not isinstance(self._image, GalleryImageReference):
self._provider.azure_client.delete_image(self.id)

@property
def state(self):
if not isinstance(self._image, dict):
if not isinstance(self._image, GalleryImageReference):
return AzureMachineImage.IMAGE_STATE_MAP.get(
self._state, MachineImageState.UNKNOWN)
else:
return MachineImageState.RUNNING
return MachineImageState.AVAILABLE

@property
def is_gallery_image(self):
"""
Returns true if the image is a public reference and false if it
is a private image in the resource group.
"""
return isinstance(self._image, GalleryImageReference)

def refresh(self):
"""
Expand All @@ -794,13 +815,6 @@ def refresh(self):
# image no longer exists
self._state = "unknown"

def isgalleryimage(self):
"""
Returns true if the image is a public reference and false if it
is a private image in the resource group.
"""
return isinstance(self._image, dict)


class AzureGatewayContainer(BaseGatewayContainer):
def __init__(self, provider, network):
Expand Down
4 changes: 2 additions & 2 deletions cloudbridge/cloud/providers/azure/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -603,8 +603,8 @@ def _resolve_launch_options(self, name, subnet=None, zone_id=None,
def _create_storage_profile(self, image, launch_config, instance_name,
zone_id):

if image.isgalleryimage:
reference = image._image
if image.is_gallery_image:
reference = image._image.as_dict()
storage_profile = {
'image_reference': {
'publisher': reference['publisher'],
Expand Down
File renamed without changes.
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
REQS_AZURE = ['msrest>=0.4.7',
'msrestazure>=0.4.7',
'azure-common>=1.1.5',
'azure-mgmt-devtestlabs>=1.0.0',
'azure-mgmt-resource>=1.0.0rc1',
'azure-mgmt-compute>=1.0.0rc1',
'azure-mgmt-network>=1.0.0rc1',
Expand Down
8 changes: 3 additions & 5 deletions test/helpers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,18 +86,16 @@ def wrapper(self, *args, **kwargs):
},
"OpenStackCloudProvider": {
"image": os.environ.get('CB_IMAGE_OS',
'842b949c-ea76-48df-998d-8a41f2626243'),
'acb53109-941f-4593-9bf8-4a53cb9e0739'),
"vm_type": os.environ.get('CB_VM_TYPE_OS', 'm1.tiny'),
"placement": os.environ.get('CB_PLACEMENT_OS', 'zone-r1'),
},
"AzureCloudProvider": {
"placement":
os.environ.get('CB_PLACEMENT_AZURE', 'eastus'),
os.environ.get('CB_PLACEMENT_AZURE', 'westus2'),
"image":
os.environ.get('CB_IMAGE_AZURE',
'/subscriptions/7904d702-e01c-4826-8519-f5a25c866a9'
'6/resourceGroups/cloudbridge/providers/Microsoft.C'
'ompute/images/cb-test-image'),
'Canonical/UbuntuServer/16.04.0-LTS/latest'),
"vm_type":
os.environ.get('CB_VM_TYPE_AZURE', 'Basic_A2'),
}
Expand Down

0 comments on commit c6d33f8

Please sign in to comment.