Committing changes for PCQE-210 and PCQE-219

Change-Id: Idd9a9782baa3eb50a14a6f12b9fbb8143f552fdc
This commit is contained in:
Sourav Kumar Sanki 2018-07-16 17:32:53 +05:30
parent e9693983f6
commit 1b10ddc00d
4 changed files with 244 additions and 1 deletions

View File

@ -382,3 +382,9 @@ class VolumesAPIConfig(ConfigSectionInterface):
def allow_snapshot_restore_to_different_type(self):
return self.get_boolean(
"allow_snapshot_restore_to_different_type", False)
@property
def primary_bootable_volume(self):
"""Introducing this property to handle VIRT-3099- SKS 11-JUL-2018."""
return self.get("primary_bootable_volume")

View File

@ -17,7 +17,7 @@ limitations under the License.
from cafe.engine.http.client import AutoMarshallingHTTPClient
from cloudcafe.compute.extensions.volumes_boot_api.models.request import \
CreateServerFromVolume
CreateServerFromVolume, CreateServerFromVolumeVirt2837
from cloudcafe.compute.servers_api.models.servers import Server
@ -118,3 +118,74 @@ class VolumesBootClient(AutoMarshallingHTTPClient):
request_entity=server_request_object,
requestslib_kwargs=requestslib_kwargs)
return resp
def create_server_virt2837(self, name, flavor_ref, block_device_mapping_v1,
max_count=None, min_count=None, networks=None,
image_ref=None, personality=None, user_data=None,
metadata=None, accessIPv4=None, accessIPv6=None,
disk_config=None, admin_pass=None, key_name=None,
config_drive=None, scheduler_hints=None,
security_groups=None, requestslib_kwargs=None):
"""
@summary: Creates an instance of a block Version 2 server given the
provided parameters
@param name: Name of the server
@type name: String
@param flavor_ref: Identifier for the flavor used to build the server
@type flavor_ref: String
@param block_device_mapping_v2: A list of dictionaries needed for boot
from volume V2 feature
@type block_device_mapping: List
@param max_count: max_count parameter for the server.
@type max_count: String
@param min_count: min_count parameter for the server.
@type min_count: String
@param networks: Networks for the server.
@type networks: List
@param image_ref: Will be used for negative testing
@type image_ref: String
@param personality: A list of dictionaries for files to be
injected into the server.
@type personality: List
@param user_data: Config Init User data
@type user_data: String
@param metadata: A dictionary of values to be used as server metadata
@type meta: Dictionary
@param accessIPv4: IPv4 address for the server.
@type accessIPv4: String
@param accessIPv6: IPv6 address for the server.
@type accessIPv6: String
@param disk_config: MANUAL/AUTO/None
@type disk_config: String
@param admin_pass: Injected Pass
@type admin_pass: String
@param key_name: Key name
@type key_name: String
@param config_drive: false/true
@type config_drive: String
@param scheduler_hints: Target compute
@type scheduler_hints: String
@param security_groups: List of security groups for the server
@type security_groups: List of dict
@return: Response Object containing response code and
the server domain object
@rtype: Requests.response
"""
server_request_object = CreateServerFromVolumeVirt2837(
name=name, flavor_ref=flavor_ref,
block_device_mapping=block_device_mapping_v1,
max_count=max_count, min_count=min_count, networks=networks,
image_ref=image_ref, personality=personality, user_data=user_data,
metadata=metadata, accessIPv4=accessIPv4, accessIPv6=accessIPv6,
disk_config=disk_config, admin_pass=admin_pass, key_name=key_name,
config_drive=config_drive, scheduler_hints=scheduler_hints,
security_groups=security_groups)
url = '{base_url}/os-volumes_boot'.format(base_url=self.url)
resp = self.request('POST', url,
response_entity_type=Server,
request_entity=server_request_object,
requestslib_kwargs=requestslib_kwargs)
return resp

View File

@ -127,6 +127,146 @@ class CreateServerFromVolume(AutoMarshallingModel):
return ''.join([Constants.XML_HEADER, ET.tostring(element)])
class CreateServerFromVolumeVirt2837(AutoMarshallingModel):
def __init__(self, name, flavor_ref, block_device_mapping,
max_count=None, min_count=None, networks=None,
image_ref=None, personality=None, user_data=None,
metadata=None, accessIPv4=None, accessIPv6=None,
disk_config=None, admin_pass=None, key_name=None,
config_drive=None, scheduler_hints=None,
security_groups=None):
super(CreateServerFromVolumeVirt2837, self).__init__()
self.name = name
self.flavor_ref = flavor_ref
self.block_device_mapping = block_device_mapping
self.max_count = max_count
self.min_count = min_count
self.networks = networks
self.image_ref = image_ref
self.personality = personality
self.user_data = user_data
self.metadata = metadata
self.accessIPv4 = accessIPv4
self.accessIPv6 = accessIPv6
self.disk_config = disk_config
self.admin_pass = admin_pass
self.key_name = key_name
self.config_drive = config_drive
self.scheduler_hints = scheduler_hints
self.security_groups = security_groups
def _obj_to_json(self):
body = {
'name': self.name,
'flavorRef': self.flavor_ref,
'block_device_mapping': self.block_device_mapping,
'max_count': self.max_count,
'min_count': self.min_count,
'networks': self.networks,
'imageRef': self.image_ref,
'personality': self.personality,
'user_data': self.user_data,
'metadata': self.metadata,
'accessIPv4': self.accessIPv4,
'accessIPv6': self.accessIPv6,
'OS-DCF:diskConfig': self.disk_config,
'adminPass': self.admin_pass,
'key_name': self.key_name,
'config_drive': self.config_drive,
'security_groups': self.security_groups
}
body = self._remove_empty_values(body)
main_body = {'server': body}
if self.scheduler_hints:
main_body['os:scheduler_hints'] = self.scheduler_hints
return json.dumps(main_body)
def _obj_to_xml(self):
elements_dict = {
'name': self.name,
'flavorRef': self.flavor_ref,
'max_count': self.max_count,
'min_count': self.min_count,
'image_ref': self.image_ref,
'user_data': self.user_data,
'accessIPv4': self.accessIPv4,
'accessIPv6': self.accessIPv6,
'adminPass': self.admin_pass,
'key_name': self.key_name,
'config_drive': self.config_drive,
'security_groups': self.security_groups
}
element = ET.Element('server')
element.set('xmlns', Constants.XML_API_NAMESPACE)
block_device_ele = ET.Element('block_device_mapping')
block_device_ele.append(BlockDeviceMappingV1VIRT2837._obj_to_xml(
self.block_device_mapping))
element.append(block_device_ele)
if self.networks is not None:
networks_ele = ET.Element('networks')
for network_id in self.networks:
network = ET.Element('network')
network.set('uuid', network_id['uuid'])
networks_ele.append(network)
element.append(networks_ele)
if self.personality is not None:
personality_ele = ET.Element('personality')
personality_ele.append(Personality._obj_to_xml(self.personality))
element.append(personality_ele)
if self.metadata is not None:
meta_ele = ET.Element('metadata')
for key, value in self.metadata.items():
meta_ele.append(Metadata._dict_to_xml(key, value))
element.append(meta_ele)
if self.disk_config is not None:
element.set('xmlns:OS-DCF',
Constants.XML_API_DISK_CONFIG_NAMESPACE)
element.set('OS-DCF:diskConfig', self.disk_config)
element = self._set_xml_etree_element(element, elements_dict)
return ''.join([Constants.XML_HEADER, ET.tostring(element)])
class BlockDeviceMappingV1VIRT2837(AutoMarshallingModel):
"""
@summary: Block Device Mapping Request Object for Version 1
of boot from volume extension
"""
ROOT_TAG = 'block_device_mapping'
def __init__(self, volume_id, device_name, delete_on_termination):
super(BlockDeviceMappingV1VIRT2837, self).__init__()
self.volume_id = volume_id
self.device_name = device_name
self.delete_on_termination = delete_on_termination
@classmethod
def _obj_to_json(self):
body = {
'volume_id': self.volume_id,
'device_name': self.device_name,
'delete_on_termination': self.delete_on_termination
}
body = self._remove_empty_values(body)
return json.dumps({'block_device_mapping': body})
@classmethod
def _obj_to_xml(self, list_dicts):
device_dict = None
for device_dict in list_dicts:
device_element = ET.Element('block_device_mapping')
device_element.set('volume_id', device_dict.get('volume_id'))
device_element.set('device_name', device_dict.get('device_name'))
device_element.set('delete_on_termination',
device_dict.get('delete_on_termination'))
return device_element
class BlockDeviceMappingV2(AutoMarshallingModel):
"""
@summary: Block Device Mapping Request Object for Version 2 Havana

View File

@ -687,6 +687,32 @@ class ServerBehaviors(BaseComputeBehavior):
"type": type}]
return block_device_mapping_matrix
def create_block_device_mapping_v1_virt2837(self, device_name, volume_id, delete_on_termination):
"""
@summary: Creates Block Device mapping on the fly
@param volume_id: The uuid of the volume
@type volume_id: String
@param delete_on_termination: True or False also 0 or 1
@type delete_on_termination: Boolean
@param device_name: Device name
@type device_name: String
@param size: Volume Size in GB
@type size: Int
@param type: snap or blank, from where the volume was created
@type type: String
@return: The Block Device Mapping
@rtype: List of dicts
"""
# Creating block device mapping
block_device_mapping_matrix = [{
"device_name": device_name,
"volume_id": volume_id,
"delete_on_termination": delete_on_termination}]
return block_device_mapping_matrix
def create_block_device_mapping_v2(self, boot_index, uuid, volume_size,
source_type, destination_type,
delete_on_termination):