Merge "Modernizing the compute servers model"
This commit is contained in:
commit
b0996cffaa
@ -42,6 +42,55 @@ class NovaServerStatusTypes(object):
|
||||
PAUSED = "PAUSED"
|
||||
|
||||
|
||||
class ComputeTaskStates(object):
|
||||
NONE = 'none'
|
||||
|
||||
# Basic server lifecycle
|
||||
SCHEDULING = 'scheduling'
|
||||
SPAWNING = 'spawning'
|
||||
BLOCK_DEVICE_MAPPING = 'block_device_mapping'
|
||||
DELETING = 'deleting'
|
||||
SOFT_DELETING = 'soft-deleting'
|
||||
RESTORING = 'restoring'
|
||||
SHELVING = 'shelving'
|
||||
SHELVING_IMAGE_PENDING_UPLOAD = 'shelving_image_pending_upload'
|
||||
SHELVING_IMAGE_UPLOADING = 'shelving_image_uploading'
|
||||
SHELVING_OFFLOADING = 'shelving_offloading'
|
||||
UNSHELVING = 'unshelving'
|
||||
|
||||
# Server Actions
|
||||
REBUILDING = 'rebuilding'
|
||||
REBUILD_BLOCK_DEVICE_MAPPING = 'rebuild_block_device_mapping'
|
||||
REBUILD_SPAWNING = 'rebuild_spawning'
|
||||
RESIZE_PREP = 'resize_prep'
|
||||
RESIZE_MIGRATING = 'resize_migrating'
|
||||
RESIZE_MIGRATED = 'resize_migrated'
|
||||
RESIZE_FINISH = 'resize_finish'
|
||||
RESIZE_REVERTING = 'resize_reverting'
|
||||
RESIZE_CONFIRMING = 'resize_confirming'
|
||||
RESCUING = 'rescuing'
|
||||
UNRESCUING = 'unrescuing'
|
||||
UPDATING_PASSWORD = 'updating_password'
|
||||
PAUSING = 'pausing'
|
||||
UNPAUSING = 'unpausing'
|
||||
SUSPENDING = 'suspending'
|
||||
RESUMING = 'resuming'
|
||||
STOPPING = 'stopping'
|
||||
STARTING = 'starting'
|
||||
POWERING_OFF = 'powering-off'
|
||||
POWERING_ON = 'powering-on'
|
||||
MIGRATING = 'migrating'
|
||||
REBOOTING = 'rebooting'
|
||||
REBOOTING_HARD = 'rebooting_hard'
|
||||
|
||||
# Imaging
|
||||
IMAGE_SNAPSHOT = 'image_snapshot'
|
||||
IMAGE_PENDING_UPLOAD = 'image_pending_upload'
|
||||
IMAGE_UPLOADING = 'image_uploading'
|
||||
IMAGE_BACKUP = 'image_backup'
|
||||
IMAGE_LIVE_SNAPSHOT = 'image_live_snapshot'
|
||||
|
||||
|
||||
class NovaImageStatusTypes(object):
|
||||
"""
|
||||
@summary: Types dictating an individual Server Status
|
||||
|
@ -20,7 +20,8 @@ from cloudcafe.compute.common.models.metadata import Metadata
|
||||
from cloudcafe.compute.common.models.metadata import MetadataItem
|
||||
from cloudcafe.compute.extensions.security_groups_api.models.security_group \
|
||||
import SecurityGroups, SecurityGroup
|
||||
from cloudcafe.compute.servers_api.models.servers import Server
|
||||
from cloudcafe.compute.servers_api.models.servers import Server, Servers, \
|
||||
ServerMins
|
||||
from cloudcafe.compute.servers_api.models.servers import Addresses
|
||||
from cloudcafe.compute.servers_api.models.servers import InstanceActions
|
||||
from cloudcafe.compute.servers_api.models.requests import CreateServer, \
|
||||
@ -89,7 +90,7 @@ class ServersClient(AutoMarshallingRestClient):
|
||||
'limit': limit, 'changes-since': changes_since}
|
||||
url = '{base_url}/servers'.format(base_url=self.url)
|
||||
resp = self.request('GET', url, params=params,
|
||||
response_entity_type=Server,
|
||||
response_entity_type=ServerMins,
|
||||
requestslib_kwargs=requestslib_kwargs)
|
||||
return resp
|
||||
|
||||
@ -123,7 +124,7 @@ class ServersClient(AutoMarshallingRestClient):
|
||||
'changes-since': changes_since}
|
||||
url = '{base_url}/servers/detail'.format(base_url=self.url)
|
||||
resp = self.request('GET', url, params=params,
|
||||
response_entity_type=Server,
|
||||
response_entity_type=Servers,
|
||||
requestslib_kwargs=requestslib_kwargs)
|
||||
return resp
|
||||
|
||||
|
@ -16,36 +16,38 @@ limitations under the License.
|
||||
|
||||
import IPy
|
||||
import json
|
||||
import re
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
from cafe.engine.models.base import AutoMarshallingModel, \
|
||||
AutoMarshallingListModel
|
||||
from cafe.engine.models.base import BaseModel
|
||||
from cafe.engine.models.base import AutoMarshallingModel
|
||||
from cloudcafe.compute.common.constants import Constants
|
||||
from cloudcafe.compute.common.types import ComputeTaskStates
|
||||
from cloudcafe.compute.common.equality_tools import EqualityTools
|
||||
from cloudcafe.compute.common.models.link import Links
|
||||
from cloudcafe.compute.common.models.metadata import Metadata
|
||||
from cloudcafe.compute.flavors_api.models.flavor import Flavor, FlavorMin
|
||||
from cloudcafe.compute.images_api.models.image import Image, ImageMin
|
||||
from cloudcafe.compute.common.equality_tools import EqualityTools
|
||||
from cloudcafe.compute.common.constants import Constants
|
||||
from cloudcafe.compute.common.models.metadata import Metadata
|
||||
|
||||
|
||||
class Server(AutoMarshallingModel):
|
||||
|
||||
def __init__(self, id=None, disk_config=None, config_drive=None,
|
||||
power_state=None, progress=None, task_state=None,
|
||||
vm_state=None, name=None, tenant_id=None, status=None,
|
||||
updated=None, created=None, host_id=None, user_id=None,
|
||||
accessIPv4=None, accessIPv6=None, addresses=None,
|
||||
flavor=None, image=None, links=None, metadata=None,
|
||||
admin_pass=None, key_name=None):
|
||||
self.diskConfig = disk_config
|
||||
def __init__(self, id=None, disk_config=None, power_state=None,
|
||||
progress=None, task_state=None, vm_state=None, name=None,
|
||||
tenant_id=None, status=None, updated=None, created=None,
|
||||
host_id=None, user_id=None, accessIPv4=None, accessIPv6=None,
|
||||
addresses=None, flavor=None, image=None, links=None,
|
||||
metadata=None, admin_pass=None, key_name=None,
|
||||
config_drive=None):
|
||||
super(Server, self).__init__()
|
||||
self.disk_config = disk_config
|
||||
self.config_drive = config_drive
|
||||
try:
|
||||
self.power_state = int(power_state)
|
||||
except TypeError:
|
||||
self.power_state = 0
|
||||
self.progress = progress
|
||||
self.task_state = task_state
|
||||
self.task_state = task_state or ComputeTaskStates.NONE
|
||||
self.vm_state = vm_state
|
||||
self.name = name
|
||||
self.id = id
|
||||
@ -59,12 +61,10 @@ class Server(AutoMarshallingModel):
|
||||
self.accessIPv4 = str(IPy.IP(accessIPv4))
|
||||
else:
|
||||
self.accessIPv4 = None
|
||||
|
||||
if accessIPv6:
|
||||
self.accessIPv6 = str(IPy.IP(accessIPv6))
|
||||
else:
|
||||
self.accessIPv6 = None
|
||||
|
||||
self.addresses = addresses
|
||||
self.flavor = flavor
|
||||
self.image = image
|
||||
@ -75,27 +75,12 @@ class Server(AutoMarshallingModel):
|
||||
|
||||
@classmethod
|
||||
def _json_to_obj(cls, serialized_str):
|
||||
'''
|
||||
Returns an instance of a Server based on the json serialized_str
|
||||
passed in
|
||||
'''
|
||||
ret = None
|
||||
json_dict = json.loads(serialized_str)
|
||||
if 'server' in json_dict.keys():
|
||||
ret = cls._dict_to_obj(json_dict['server'])
|
||||
if 'servers' in json_dict.keys():
|
||||
ret = []
|
||||
for server in json_dict['servers']:
|
||||
s = cls._dict_to_obj(server)
|
||||
ret.append(s)
|
||||
ret = cls._dict_to_obj(json_dict['server'])
|
||||
return ret
|
||||
|
||||
@classmethod
|
||||
def _xml_to_obj(cls, serialized_str):
|
||||
'''
|
||||
Returns an instance of a Server based on the xml serialized_str
|
||||
passed in
|
||||
'''
|
||||
element = ET.fromstring(serialized_str)
|
||||
cls._remove_xml_etree_namespace(
|
||||
element, Constants.XML_API_NAMESPACE)
|
||||
@ -105,18 +90,11 @@ class Server(AutoMarshallingModel):
|
||||
element, Constants.XML_API_DISK_CONFIG_NAMESPACE)
|
||||
cls._remove_xml_etree_namespace(
|
||||
element, Constants.XML_API_ATOM_NAMESPACE)
|
||||
if element.tag == 'server':
|
||||
ret = cls._xml_ele_to_obj(element)
|
||||
if element.tag == 'servers':
|
||||
ret = []
|
||||
for server in element.findall('server'):
|
||||
s = cls._xml_ele_to_obj(server)
|
||||
ret.append(s)
|
||||
ret = cls._xml_ele_to_obj(element)
|
||||
return ret
|
||||
|
||||
@classmethod
|
||||
def _xml_ele_to_obj(cls, element):
|
||||
'''Helper method to turn ElementTree instance to Server instance.'''
|
||||
server = element.attrib
|
||||
|
||||
addresses = None
|
||||
@ -135,19 +113,19 @@ class Server(AutoMarshallingModel):
|
||||
metadata = Metadata._xml_ele_to_obj(element.find('metadata'))
|
||||
|
||||
if 'progress' in server:
|
||||
progress = server.get('progress') \
|
||||
and int(server.get('progress'))
|
||||
progress = (server.get('progress')
|
||||
and int(server.get('progress')))
|
||||
else:
|
||||
progress = None
|
||||
|
||||
server = Server(
|
||||
id=server.get('id'), disk_config=server.get('diskConfig'),
|
||||
power_state=server.get('power_state'), progress=progress,
|
||||
task_state=server.get('task_state'),
|
||||
task_state=server.get('task_state').lower(),
|
||||
vm_state=server.get('vm_state'), name=server.get('name'),
|
||||
tenant_id=server.get('tenant_id'), status=server.get('status'),
|
||||
tenant_id=server.get('tenantId'), status=server.get('status'),
|
||||
updated=server.get('updated'), created=server.get('created'),
|
||||
host_id=server.get('hostId'), user_id=server.get('user_id'),
|
||||
host_id=server.get('hostId'), user_id=server.get('userId'),
|
||||
accessIPv4=server.get('accessIPv4'),
|
||||
config_drive=server.get('config_drive'),
|
||||
accessIPv6=server.get('accessIPv6'), addresses=addresses,
|
||||
@ -159,7 +137,6 @@ class Server(AutoMarshallingModel):
|
||||
|
||||
@classmethod
|
||||
def _dict_to_obj(cls, server_dict):
|
||||
'''Helper method to turn dictionary into Server instance.'''
|
||||
|
||||
addresses = None
|
||||
flavor = None
|
||||
@ -202,92 +179,82 @@ class Server(AutoMarshallingModel):
|
||||
return server
|
||||
|
||||
def __eq__(self, other):
|
||||
"""
|
||||
@summary: Overrides the default equals
|
||||
@param other: Server object to compare with
|
||||
@type other: Server
|
||||
@return: True if Server objects are equal, False otherwise
|
||||
@rtype: bool
|
||||
"""
|
||||
return EqualityTools.are_objects_equal(self, other,
|
||||
['admin_pass', 'updated',
|
||||
'progress'])
|
||||
|
||||
def __ne__(self, other):
|
||||
"""
|
||||
@summary: Overrides the default not-equals
|
||||
@param other: Server object to compare with
|
||||
@type other: Server
|
||||
@return: True if Server objects are not equal, False otherwise
|
||||
@rtype: bool
|
||||
"""
|
||||
return not self == other
|
||||
|
||||
def min_details(self):
|
||||
"""
|
||||
@summary: Get the Minimum details of server
|
||||
@return: Minimum details of server
|
||||
@rtype: ServerMin
|
||||
"""
|
||||
return ServerMin(name=self.name, id=self.id, links=self.links)
|
||||
|
||||
|
||||
class ServerMin(Server):
|
||||
"""
|
||||
@summary: Represents minimum details of a server
|
||||
"""
|
||||
def __init__(self, **kwargs):
|
||||
for keys, values in kwargs.items():
|
||||
setattr(self, keys, values)
|
||||
|
||||
def __init__(self, id=None, name=None, links=None):
|
||||
super(ServerMin, self).__init__()
|
||||
self.id = id
|
||||
self.name = name
|
||||
self.links = links
|
||||
|
||||
def __eq__(self, other):
|
||||
"""
|
||||
@summary: Overrides the default equals
|
||||
@param other: ServerMin object to compare with
|
||||
@type other: ServerMin
|
||||
@return: True if ServerMin objects are equal, False otherwise
|
||||
@rtype: bool
|
||||
"""
|
||||
return EqualityTools.are_objects_equal(self, other)
|
||||
|
||||
def __ne__(self, other):
|
||||
"""
|
||||
@summary: Overrides the default equals
|
||||
@param other: ServerMin object to compare with
|
||||
@type other: ServerMin
|
||||
@return: True if ServerMin objects are not equal, False otherwise
|
||||
@rtype: bool
|
||||
"""
|
||||
return not self == other
|
||||
|
||||
@classmethod
|
||||
def _xml_ele_to_obj(cls, element):
|
||||
'''Helper method to turn ElementTree instance to Server instance.'''
|
||||
if element.find('server') is not None:
|
||||
element = element.find('server')
|
||||
server_dict = element.attrib
|
||||
servermin = ServerMin(**server_dict)
|
||||
servermin.links = Links._xml_ele_to_obj(element)
|
||||
return servermin
|
||||
server_dict = element.attrib
|
||||
links = Links._xml_ele_to_obj(element)
|
||||
server = ServerMin(id=server_dict.get('id'),
|
||||
name=server_dict.get('name'), links=links)
|
||||
return server
|
||||
|
||||
@classmethod
|
||||
def _dict_to_obj(cls, server_dict):
|
||||
'''Helper method to turn dictionary into Server instance.'''
|
||||
servermin = ServerMin(**server_dict)
|
||||
if hasattr(servermin, 'links'):
|
||||
servermin.links = Links._dict_to_obj(servermin.links)
|
||||
'''
|
||||
Parse for those keys which have the namespace prefixed,
|
||||
strip the namespace out
|
||||
and take only the actual values such as diskConfig,
|
||||
power_state and assign to server obj
|
||||
'''
|
||||
for each in server_dict:
|
||||
if each.startswith("{"):
|
||||
newkey = re.split("}", each)[1]
|
||||
setattr(servermin, newkey, server_dict[each])
|
||||
links = Links._dict_to_obj(server_dict['links'])
|
||||
server = ServerMin(id=server_dict.get('id'),
|
||||
name=server_dict.get('name'), links=links)
|
||||
return server
|
||||
|
||||
return servermin
|
||||
|
||||
class Servers(AutoMarshallingListModel):
|
||||
|
||||
server_type = Server
|
||||
|
||||
@classmethod
|
||||
def _json_to_obj(cls, serialized_str):
|
||||
json_dict = json.loads(serialized_str)
|
||||
return cls._list_to_obj(json_dict.get('servers'))
|
||||
|
||||
@classmethod
|
||||
def _list_to_obj(cls, server_dict_list):
|
||||
servers = Servers()
|
||||
for server_dict in server_dict_list:
|
||||
server = cls.server_type._dict_to_obj(server_dict)
|
||||
servers.append(server)
|
||||
return servers
|
||||
|
||||
@classmethod
|
||||
def _xml_to_obj(cls, serialized_str):
|
||||
element = ET.fromstring(serialized_str)
|
||||
if element.tag != 'servers':
|
||||
return None
|
||||
return cls._xml_list_to_obj(element.findall('server'))
|
||||
|
||||
@classmethod
|
||||
def _xml_list_to_obj(cls, xml_list):
|
||||
servers = Servers()
|
||||
for ele in xml_list:
|
||||
servers.append(cls.server_type._xml_ele_to_obj(ele))
|
||||
return servers
|
||||
|
||||
|
||||
class ServerMins(Servers):
|
||||
|
||||
server_type = ServerMin
|
||||
|
||||
|
||||
class Addresses(AutoMarshallingModel):
|
||||
|
@ -16,6 +16,7 @@ limitations under the License.
|
||||
|
||||
import unittest2 as unittest
|
||||
|
||||
from cloudcafe.compute.common.types import ComputeTaskStates
|
||||
from cloudcafe.compute.servers_api.models.servers import Server
|
||||
|
||||
|
||||
@ -31,7 +32,7 @@ class ServerDomainTest(object):
|
||||
self.assertEqual(self.server.progress, 100)
|
||||
|
||||
def test_server_task_state(self):
|
||||
self.assertEqual(self.server.task_state, None)
|
||||
self.assertEqual(self.server.task_state, ComputeTaskStates.NONE)
|
||||
|
||||
def test_server_vm_state(self):
|
||||
self.assertEqual(self.server.vm_state, "active")
|
||||
|
Loading…
x
Reference in New Issue
Block a user