Adding nova-baremetal, heat and nova API
Adding nova-baremetal, heat and nova API instead of mock API. nova-baremetal is supposed to be just temporary solution, replaced by ironic later. Tests were fixed accordingly. Change-Id: Iee6436196d52db626a9cfccc24ae303f5917707c
This commit is contained in:
parent
41015e2e58
commit
ca2f3792e4
297
tuskar_ui/api.py
297
tuskar_ui/api.py
@ -19,6 +19,11 @@ import django.conf
|
||||
from horizon.utils import memoized
|
||||
|
||||
from openstack_dashboard.api import base
|
||||
from openstack_dashboard.api import glance
|
||||
from openstack_dashboard.api import heat
|
||||
from openstack_dashboard.api import nova
|
||||
|
||||
from novaclient.v1_1.contrib import baremetal
|
||||
from openstack_dashboard.test.test_data import utils
|
||||
from tuskar_ui.cached_property import cached_property # noqa
|
||||
from tuskar_ui.test.test_data import tuskar_data
|
||||
@ -28,6 +33,11 @@ LOG = logging.getLogger(__name__)
|
||||
TUSKAR_ENDPOINT_URL = getattr(django.conf.settings, 'TUSKAR_ENDPOINT_URL')
|
||||
|
||||
|
||||
def baremetalclient(request):
|
||||
nc = nova.novaclient(request)
|
||||
return baremetal.BareMetalNodeManager(nc)
|
||||
|
||||
|
||||
# TODO(Tzu-Mainn Chen): remove test data when possible
|
||||
def test_data():
|
||||
test_data = utils.TestDataContainer()
|
||||
@ -35,8 +45,8 @@ def test_data():
|
||||
return test_data
|
||||
|
||||
|
||||
# FIXME: request isn't used right in the tuskar client right now, but looking
|
||||
# at other clients, it seems like it will be in the future
|
||||
# FIXME: request isn't used right in the tuskar client right now,
|
||||
# but looking at other clients, it seems like it will be in the future
|
||||
def tuskarclient(request):
|
||||
c = tuskar_client.Client(TUSKAR_ENDPOINT_URL)
|
||||
return c
|
||||
@ -57,11 +67,33 @@ def list_to_dict(object_list, key_attribute='id'):
|
||||
return dict((getattr(o, key_attribute), o) for o in object_list)
|
||||
|
||||
|
||||
# FIXME(lsmola) This should be done in Horizon, they don't have caching
|
||||
@memoized.memoized
|
||||
def image_get(request, image_id):
|
||||
"""Returns an Image object with metadata
|
||||
|
||||
Returns an Image object populated with metadata for image
|
||||
with supplied identifier.
|
||||
|
||||
:param image_id: list of objects to be put into a dict
|
||||
:type object_list: list
|
||||
|
||||
:return: object
|
||||
:rtype: glanceclient.v1.images.Image
|
||||
"""
|
||||
image = glance.image_get(request, image_id)
|
||||
return image
|
||||
|
||||
|
||||
# TODO(Tzu-Mainn Chen): change this to APIResourceWrapper once
|
||||
# ResourceCategory object exists in tuskar
|
||||
class Overcloud(base.APIDictWrapper):
|
||||
_attrs = ('id', 'stack_id', 'name', 'description')
|
||||
|
||||
def __init__(self, apiresource, request=None):
|
||||
super(Overcloud, self).__init__(apiresource)
|
||||
self._request = request
|
||||
|
||||
@classmethod
|
||||
def create(cls, request, overcloud_sizing):
|
||||
"""Create an Overcloud in Tuskar
|
||||
@ -82,7 +114,7 @@ class Overcloud(base.APIDictWrapper):
|
||||
# overcloud_sizing)
|
||||
overcloud = test_data().tuskarclient_overclouds.first()
|
||||
|
||||
return cls(overcloud)
|
||||
return cls(overcloud, request=request)
|
||||
|
||||
@classmethod
|
||||
def list(cls, request):
|
||||
@ -98,7 +130,7 @@ class Overcloud(base.APIDictWrapper):
|
||||
# ocs = tuskarclient(request).overclouds.list()
|
||||
ocs = test_data().tuskarclient_overclouds.list()
|
||||
|
||||
return [cls(oc) for oc in ocs]
|
||||
return [cls(oc, request=request) for oc in ocs]
|
||||
|
||||
@classmethod
|
||||
def get(cls, request, overcloud_id):
|
||||
@ -118,7 +150,7 @@ class Overcloud(base.APIDictWrapper):
|
||||
# overcloud = tuskarclient(request).overclouds.get(overcloud_id)
|
||||
overcloud = test_data().tuskarclient_overclouds.first()
|
||||
|
||||
return cls(overcloud)
|
||||
return cls(overcloud, request=request)
|
||||
|
||||
@cached_property
|
||||
def stack(self):
|
||||
@ -132,7 +164,8 @@ class Overcloud(base.APIDictWrapper):
|
||||
if self.stack_id:
|
||||
# TODO(Tzu-Mainn Chen): remove test data when possible
|
||||
# stack = heatclient(request).stacks.get(self.stack_id)
|
||||
stack = test_data().heatclient_stacks.first()
|
||||
# stack = test_data().heatclient_stacks.first()
|
||||
stack = heat.stack_get(self._request, 'overcloud')
|
||||
return stack
|
||||
return None
|
||||
|
||||
@ -160,11 +193,42 @@ class Overcloud(base.APIDictWrapper):
|
||||
False otherwise
|
||||
:rtype: bool
|
||||
"""
|
||||
# TODO(rdopieralski) Actually implement it
|
||||
return False
|
||||
return self.stack.stack_status in ('CREATE_COMPLETE',
|
||||
'UPDATE_COMPLETE')
|
||||
|
||||
@memoized.memoized
|
||||
def resources(self, resource_category, with_joins=False):
|
||||
def all_resources(self, with_joins=True):
|
||||
"""Return a list of all Overcloud Resources
|
||||
|
||||
:param with_joins: should we also retrieve objects associated with each
|
||||
retrieved Resource?
|
||||
:type with_joins: bool
|
||||
|
||||
:return: list of all Overcloud Resources or an empty list if there
|
||||
are none
|
||||
:rtype: list of tuskar_ui.api.Resource
|
||||
"""
|
||||
|
||||
resources = [r for r in heat.resources_list(self._request,
|
||||
self.stack.stack_name)]
|
||||
|
||||
if not with_joins:
|
||||
return [Resource(r, request=self._request) for r in resources]
|
||||
|
||||
nodes_dict = list_to_dict(Node.list(self._request, associated=True),
|
||||
key_attribute='instance_uuid')
|
||||
joined_resources = []
|
||||
for r in resources:
|
||||
node = nodes_dict.get(r.physical_resource_id, None)
|
||||
joined_resources.append(Resource(r,
|
||||
node=node,
|
||||
request=self._request))
|
||||
# TODO(lsmola) I want just resources with nova instance
|
||||
# this could be probably filtered a better way, investigate
|
||||
return [r for r in joined_resources if r.node is not None]
|
||||
|
||||
@memoized.memoized
|
||||
def resources(self, resource_category, with_joins=True):
|
||||
"""Return a list of Overcloud Resources that match a Resource Category
|
||||
|
||||
:param resource_category: category of resources to be returned
|
||||
@ -178,34 +242,57 @@ class Overcloud(base.APIDictWrapper):
|
||||
or an empty list if there are none
|
||||
:rtype: list of tuskar_ui.api.Resource
|
||||
"""
|
||||
# TODO(Tzu-Mainn Chen): uncomment when possible
|
||||
#resources = tuskarclient(request).overclouds.get_resources(
|
||||
# self.id, resource_category.id)
|
||||
resources = [r for r in test_data().heatclient_resources.list()
|
||||
if r.logical_resource_id.startswith(
|
||||
resource_category.name)]
|
||||
# FIXME(lsmola) with_joins is not necessary here, I need at least
|
||||
# nova instance
|
||||
all_resources = self.all_resources(with_joins)
|
||||
filtered_resources = [resource for resource in all_resources if
|
||||
(resource.image_name ==
|
||||
resource_category.image_name)]
|
||||
|
||||
if not with_joins:
|
||||
return [Resource(r) for r in resources]
|
||||
|
||||
nodes_dict = list_to_dict(Node.list(None, associated=True),
|
||||
key_attribute='instance_uuid')
|
||||
joined_resources = []
|
||||
for r in resources:
|
||||
node = nodes_dict.get(r.physical_resource_id, None)
|
||||
joined_resources.append(Resource(r,
|
||||
node=node))
|
||||
return joined_resources
|
||||
return filtered_resources
|
||||
|
||||
|
||||
class Node(base.APIResourceWrapper):
|
||||
_attrs = ('uuid', 'instance_uuid', 'driver', 'driver_info',
|
||||
'properties', 'power_state')
|
||||
# FIXME(lsmola) uncomment this and delete equivalent methods
|
||||
#_attrs = ('uuid', 'instance_uuid', 'driver', 'driver_info',
|
||||
# 'properties', 'power_state')
|
||||
_attrs = ('id', 'uuid', 'instance_uuid')
|
||||
|
||||
def __init__(self, apiresource, instance=None):
|
||||
def __init__(self, apiresource, request=None, **kwargs):
|
||||
"""Initialize a node
|
||||
|
||||
:param apiresource: apiresource we want to wrap
|
||||
:type apiresource: novaclient.v1_1.contrib.baremetal.BareMetalNode
|
||||
|
||||
:param request: request
|
||||
:type request: django.core.handlers.wsgi.WSGIRequest
|
||||
|
||||
:param instance: instance relation we want to cache
|
||||
:type instance: openstack_dashboard.api.nova.Server
|
||||
|
||||
:return: Node object
|
||||
:rtype: Node
|
||||
"""
|
||||
super(Node, self).__init__(apiresource)
|
||||
if instance is not None:
|
||||
self._instance = instance
|
||||
self._request = request
|
||||
if 'instance' in kwargs:
|
||||
self._instance = kwargs['instance']
|
||||
|
||||
@classmethod
|
||||
def nova_baremetal_format(cls, ipmi_address, cpu, ram, local_disk,
|
||||
mac_addresses, ipmi_username=None,
|
||||
ipmi_password=None):
|
||||
"""Converts Ironic parameters to Nova-baremetal format
|
||||
"""
|
||||
return {'service_host': 'undercloud',
|
||||
'cpus': cpu,
|
||||
'memory_mb': ram,
|
||||
'local_gb': local_disk,
|
||||
'prov_mac_address': mac_addresses,
|
||||
'pm_address': ipmi_address,
|
||||
'pm_user': ipmi_username,
|
||||
'pm_password': ipmi_password,
|
||||
'terminal_port': None}
|
||||
|
||||
@classmethod
|
||||
def create(cls, request, ipmi_address, cpu, ram, local_disk,
|
||||
@ -254,7 +341,9 @@ class Node(base.APIResourceWrapper):
|
||||
# node_uuid=node.uuid,
|
||||
# address=mac_address
|
||||
# )
|
||||
node = test_data().ironicclient_nodes.first()
|
||||
node = baremetalclient(request).create(**cls.nova_baremetal_format(
|
||||
ipmi_address, cpu, ram, local_disk, mac_addresses,
|
||||
ipmi_username=None, ipmi_password=None))
|
||||
|
||||
return cls(node)
|
||||
|
||||
@ -273,15 +362,12 @@ class Node(base.APIResourceWrapper):
|
||||
"""
|
||||
# TODO(Tzu-Mainn Chen): remove test data when possible
|
||||
# node = ironicclient(request).nodes.get(uuid)
|
||||
nodes = test_data().ironicclient_nodes.list()
|
||||
node = next((n for n in nodes if uuid == n.uuid),
|
||||
None)
|
||||
|
||||
node = baremetalclient(request).get(uuid)
|
||||
|
||||
if node.instance_uuid is not None:
|
||||
# server = novaclient(request).servers.get(node.instance_uuid)
|
||||
servers = test_data().novaclient_servers.list()
|
||||
server = next((s for s in servers if node.instance_uuid == s.id),
|
||||
None)
|
||||
return cls(node, instance=server)
|
||||
server = nova.server_get(request, node.instance_uuid)
|
||||
return cls(node, instance=server, request=request)
|
||||
|
||||
return cls(node)
|
||||
|
||||
@ -303,17 +389,16 @@ class Node(base.APIResourceWrapper):
|
||||
matching instance UUID
|
||||
"""
|
||||
# TODO(Tzu-Mainn Chen): remove test data when possible
|
||||
#node = ironicclient(request).nodes.get_by_instance_uuid(
|
||||
# node = ironicclient(request).nodes.get_by_instance_uuid(
|
||||
# instance_uuid)
|
||||
#server = novaclient(request).servers.get(instance_id)
|
||||
nodes = test_data().ironicclient_nodes.list()
|
||||
|
||||
server = nova.server_get(request, instance_uuid)
|
||||
nodes = baremetalclient(request).list()
|
||||
|
||||
node = next((n for n in nodes if instance_uuid == n.instance_uuid),
|
||||
None)
|
||||
servers = test_data().novaclient_servers.list()
|
||||
server = next((s for s in servers if instance_uuid == s.id),
|
||||
None)
|
||||
|
||||
return cls(node, instance=server)
|
||||
return cls(node, instance=server, request=request)
|
||||
|
||||
@classmethod
|
||||
def list(cls, request, associated=None):
|
||||
@ -333,7 +418,9 @@ class Node(base.APIResourceWrapper):
|
||||
# TODO(Tzu-Mainn Chen): remove test data when possible
|
||||
# nodes = ironicclient(request).nodes.list(
|
||||
# associated=associated)
|
||||
nodes = test_data().ironicclient_nodes.list()
|
||||
|
||||
# nodes = test_data().ironicclient_nodes.list()
|
||||
nodes = baremetalclient(request).list()
|
||||
|
||||
if associated is not None:
|
||||
if associated:
|
||||
@ -342,14 +429,16 @@ class Node(base.APIResourceWrapper):
|
||||
else:
|
||||
nodes = [node for node in nodes
|
||||
if node.instance_uuid is None]
|
||||
return [cls(node) for node in nodes]
|
||||
return [cls(node, request=request) for node in nodes]
|
||||
|
||||
# servers = novaclient(request).servers.list(detailed=True)
|
||||
servers_dict = list_to_dict(test_data().novaclient_servers.list())
|
||||
servers, has_more_data = nova.server_list(request)
|
||||
|
||||
servers_dict = list_to_dict(servers)
|
||||
nodes_with_instance = []
|
||||
for n in nodes:
|
||||
server = servers_dict.get(n.instance_uuid, None)
|
||||
nodes_with_instance.append(cls(n, instance=server))
|
||||
nodes_with_instance.append(cls(n, instance=server,
|
||||
request=request))
|
||||
|
||||
return nodes_with_instance
|
||||
|
||||
@ -366,6 +455,7 @@ class Node(base.APIResourceWrapper):
|
||||
"""
|
||||
# TODO(Tzu-Mainn Chen): uncomment when possible
|
||||
# ironicclient(request).nodes.delete(uuid)
|
||||
baremetalclient(request).delete(uuid)
|
||||
return
|
||||
|
||||
@cached_property
|
||||
@ -379,18 +469,16 @@ class Node(base.APIResourceWrapper):
|
||||
"""
|
||||
if hasattr(self, '_instance'):
|
||||
return self._instance
|
||||
if self.instance_uuid:
|
||||
# TODO(Tzu-Mainn Chen): remove test data when possible
|
||||
# server = novaclient(request).servers.get(self.instance_uuid)
|
||||
servers = test_data().novaclient_servers.list()
|
||||
server = next((s for s in servers if self.instance_uuid == s.id),
|
||||
None)
|
||||
|
||||
if self.instance_uuid:
|
||||
server = nova.server_get(self._request, self.instance_uuid)
|
||||
return server
|
||||
|
||||
return None
|
||||
|
||||
@cached_property
|
||||
def addresses(self):
|
||||
# FIXME(lsmola) remove when Ironic is in
|
||||
"""Return a list of port addresses associated with this Node
|
||||
|
||||
:return: list of port addresses associated with this Node, or
|
||||
@ -400,17 +488,71 @@ class Node(base.APIResourceWrapper):
|
||||
"""
|
||||
# TODO(Tzu-Mainn Chen): uncomment when possible
|
||||
# ports = self.list_ports()
|
||||
ports = test_data().ironicclient_ports.list()[:2]
|
||||
# ports = test_data().ironicclient_ports.list()[:2]
|
||||
|
||||
return [port.address for port in ports]
|
||||
# return [port.address for port in ports]
|
||||
return [interface["address"] for interface in
|
||||
self._apiresource.interfaces]
|
||||
|
||||
@cached_property
|
||||
def power_state(self):
|
||||
# FIXME(lsmola) remove when Ironic is in
|
||||
"""Return a power state of this Node
|
||||
|
||||
:return: power state of this node
|
||||
:rtype: str
|
||||
"""
|
||||
return self._apiresource.task_state
|
||||
|
||||
@cached_property
|
||||
def properties(self):
|
||||
# FIXME(lsmola) remove when Ironic is in
|
||||
"""Return properties of this Node
|
||||
|
||||
:return: return memory, cpus and local_disk properties
|
||||
of this Node
|
||||
:rtype: dict of str
|
||||
"""
|
||||
return {
|
||||
'ram': self._apiresource.memory_mb / 1024.0,
|
||||
'cpu': self._apiresource.cpus,
|
||||
'local_disk': self._apiresource.local_gb / 1000.0
|
||||
}
|
||||
|
||||
@cached_property
|
||||
def driver_info(self):
|
||||
# FIXME(lsmola) remove when Ironic is in
|
||||
"""Return driver_info this Node
|
||||
|
||||
:return: return pm_address property of this Node
|
||||
:rtype: dict of str
|
||||
"""
|
||||
return {
|
||||
'ipmi_address': self._apiresource.pm_address
|
||||
}
|
||||
|
||||
|
||||
class Resource(base.APIResourceWrapper):
|
||||
_attrs = ('resource_name', 'resource_type', 'resource_status',
|
||||
'physical_resource_id')
|
||||
|
||||
def __init__(self, apiresource, **kwargs):
|
||||
def __init__(self, apiresource, request=None, **kwargs):
|
||||
"""Initialize a resource
|
||||
|
||||
:param apiresource: apiresource we want to wrap
|
||||
:type apiresource: heatclient.v1.resources.Resource
|
||||
|
||||
:param request: request
|
||||
:type request: django.core.handlers.wsgi.WSGIRequest
|
||||
|
||||
:param node: node relation we want to cache
|
||||
:type node: tuskar_ui.api.Node
|
||||
|
||||
:return: Resource object
|
||||
:rtype: Resource
|
||||
"""
|
||||
super(Resource, self).__init__(apiresource)
|
||||
self._request = request
|
||||
if 'node' in kwargs:
|
||||
self._node = kwargs['node']
|
||||
|
||||
@ -431,17 +573,9 @@ class Resource(base.APIResourceWrapper):
|
||||
stack matches the resource name
|
||||
:rtype: tuskar_ui.api.Resource
|
||||
"""
|
||||
# TODO(Tzu-Mainn Chen): uncomment when possible
|
||||
# resource = heatclient(request).resources.get(
|
||||
# overcloud.id,
|
||||
# resource_name)
|
||||
resources = test_data().heatclient_resources.list()
|
||||
resource = next((r for r in resources
|
||||
if overcloud['id'] == r.stack_id
|
||||
and resource_name == r.resource_name),
|
||||
None)
|
||||
|
||||
return cls(resource)
|
||||
resource = heat.resource_get(overcloud.stack.id,
|
||||
resource_name)
|
||||
return cls(resource, request=request)
|
||||
|
||||
@cached_property
|
||||
def node(self):
|
||||
@ -457,14 +591,29 @@ class Resource(base.APIResourceWrapper):
|
||||
if hasattr(self, '_node'):
|
||||
return self._node
|
||||
if self.physical_resource_id:
|
||||
return Node.get_by_instance_uuid(None, self.physical_resource_id)
|
||||
return Node.get_by_instance_uuid(self._request,
|
||||
self.physical_resource_id)
|
||||
return None
|
||||
|
||||
@cached_property
|
||||
def image_name(self):
|
||||
"""Return image name of resource
|
||||
|
||||
Returns image name of instance associated with resource
|
||||
|
||||
:return: Image name of resources
|
||||
:rtype: string
|
||||
"""
|
||||
instance = getattr(getattr(self, 'node', None), 'instance', None)
|
||||
if instance is not None:
|
||||
return image_get(self._request, instance.image['id']).name
|
||||
return None
|
||||
|
||||
|
||||
# TODO(Tzu-Mainn Chen): change this to APIResourceWrapper once
|
||||
# ResourceCategory object exists in tuskar
|
||||
class ResourceCategory(base.APIDictWrapper):
|
||||
_attrs = ('id', 'name', 'description', 'image_id')
|
||||
_attrs = ('id', 'name', 'description', 'image_id', 'image_name')
|
||||
|
||||
@classmethod
|
||||
def list(cls, request):
|
||||
|
@ -41,9 +41,13 @@ class NumberPickerInput(NumberInput):
|
||||
|
||||
class MACField(forms.fields.Field):
|
||||
def clean(self, value):
|
||||
class mac_dialect(netaddr.mac_eui48):
|
||||
"""Same validation as Nova uses."""
|
||||
word_fmt = '%.02x'
|
||||
word_sep = ':'
|
||||
try:
|
||||
return str(netaddr.EUI(
|
||||
value.strip(), version=48, dialect=netaddr.mac_unix)).upper()
|
||||
value.strip(), version=48, dialect=mac_dialect)).upper()
|
||||
except (netaddr.AddrFormatError, TypeError):
|
||||
raise forms.ValidationError(_(u'Enter a valid MAC address.'))
|
||||
|
||||
|
@ -26,9 +26,9 @@ class NodeForm(django.forms.Form):
|
||||
required=False,
|
||||
widget=django.forms.HiddenInput(),
|
||||
)
|
||||
|
||||
ip_address = django.forms.IPAddressField(
|
||||
label=_("IP Address"),
|
||||
ipmi_address = django.forms.IPAddressField(
|
||||
label=_("IPMI Address"),
|
||||
required=False,
|
||||
widget=django.forms.TextInput(attrs={'class': 'input input-medium'}),
|
||||
)
|
||||
ipmi_user = django.forms.CharField(
|
||||
@ -42,26 +42,12 @@ class NodeForm(django.forms.Form):
|
||||
widget=django.forms.PasswordInput(
|
||||
render_value=False, attrs={'class': 'input input-medium'}),
|
||||
)
|
||||
|
||||
mac_address = tuskar_ui.forms.MACField(
|
||||
label=_("NIC MAC Address"),
|
||||
widget=django.forms.Textarea(attrs={
|
||||
'class': 'input input-medium',
|
||||
'rows': 2,
|
||||
widget=django.forms.TextInput(attrs={
|
||||
'class': 'input input-medium'
|
||||
}),
|
||||
)
|
||||
|
||||
ipmi_user = django.forms.CharField(
|
||||
label=_("IPMI User"),
|
||||
required=False,
|
||||
widget=django.forms.TextInput(attrs={'class': 'input input-medium'}),
|
||||
)
|
||||
ipmi_password = django.forms.CharField(
|
||||
label=_("IPMI Password"),
|
||||
required=False,
|
||||
widget=django.forms.PasswordInput(
|
||||
render_value=False, attrs={'class': 'input input-medium'}),
|
||||
)
|
||||
cpus = django.forms.IntegerField(
|
||||
label=_("CPUs"),
|
||||
required=True,
|
||||
@ -89,7 +75,8 @@ class NodeForm(django.forms.Form):
|
||||
|
||||
def get_name(self):
|
||||
try:
|
||||
name = self.fields['ip_address'].value()
|
||||
# FIXME(lsmola) show somethign meaningful here
|
||||
name = self.fields['ipmi_address'].value()
|
||||
except AttributeError:
|
||||
# when the field is not bound
|
||||
name = _("Undefined node")
|
||||
@ -103,11 +90,11 @@ class BaseNodeFormset(django.forms.formsets.BaseFormSet):
|
||||
try:
|
||||
api.Node.create(
|
||||
request,
|
||||
form.cleaned_data['ip_address'],
|
||||
form.cleaned_data['ipmi_address'],
|
||||
form.cleaned_data.get('cpus'),
|
||||
form.cleaned_data.get('memory'),
|
||||
form.cleaned_data.get('local_disk'),
|
||||
[form.cleaned_data['mac_address']],
|
||||
form.cleaned_data['mac_address'],
|
||||
form.cleaned_data.get('ipmi_username'),
|
||||
form.cleaned_data.get('ipmi_password'),
|
||||
)
|
||||
|
@ -17,9 +17,25 @@ from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from horizon import tables
|
||||
|
||||
from tuskar_ui import api
|
||||
|
||||
|
||||
class DeleteNode(tables.BatchAction):
|
||||
name = "delete"
|
||||
action_present = _("Delete")
|
||||
action_past = _("Deleting")
|
||||
data_type_singular = _("Node")
|
||||
data_type_plural = _("Nodes")
|
||||
classes = ('btn-danger',)
|
||||
|
||||
def allowed(self, request, obj=None):
|
||||
return getattr(obj, 'instance', None) is None
|
||||
|
||||
def action(self, request, obj_id):
|
||||
api.Node.delete(request, obj_id)
|
||||
|
||||
|
||||
class NodesTable(tables.DataTable):
|
||||
|
||||
uuid = tables.Column("uuid",
|
||||
link="horizon:infrastructure:nodes:detail",
|
||||
verbose_name=_("UUID"))
|
||||
@ -51,7 +67,7 @@ class NodesTable(tables.DataTable):
|
||||
row_actions = ()
|
||||
|
||||
def get_object_id(self, datum):
|
||||
return datum.uuid
|
||||
return datum.id
|
||||
|
||||
def get_object_display(self, datum):
|
||||
return datum.uuid
|
||||
@ -62,8 +78,8 @@ class FreeNodesTable(NodesTable):
|
||||
class Meta:
|
||||
name = "free_nodes"
|
||||
verbose_name = _("Free Nodes")
|
||||
table_actions = ()
|
||||
row_actions = ()
|
||||
table_actions = (DeleteNode,)
|
||||
row_actions = (DeleteNode,)
|
||||
|
||||
|
||||
class DeployedNodesTable(NodesTable):
|
||||
|
@ -7,7 +7,7 @@
|
||||
</div>
|
||||
<div class="row-fluid">
|
||||
<h4>Power Management</h4>
|
||||
{% include 'infrastructure/nodes/_nodes_formset_field.html' with field=form.ip_address required=True %}
|
||||
{% include 'infrastructure/nodes/_nodes_formset_field.html' with field=form.ipmi_address %}
|
||||
{% include 'infrastructure/nodes/_nodes_formset_field.html' with field=form.ipmi_user %}
|
||||
{% include 'infrastructure/nodes/_nodes_formset_field.html' with field=form.ipmi_password %}
|
||||
</div>
|
||||
@ -38,7 +38,8 @@
|
||||
var $nav_link = $('a[href="#' + $form.attr('id') + '"]');
|
||||
var undefined_name = '{{ form.get_name|escapejs }}';
|
||||
|
||||
$form.find('input[name$="-ip_address"]').change(function () {
|
||||
// FIXME(lsmola) what is this good for exactly?
|
||||
$form.find('input[name$="-ipmi_address"]').change(function () {
|
||||
$nav_link.html($(this).val() || undefined_name);
|
||||
});
|
||||
});
|
||||
|
@ -31,7 +31,15 @@ tuskar_data.data(TEST_DATA)
|
||||
|
||||
class NodesTests(test.BaseAdminViewTests):
|
||||
def test_index_get(self):
|
||||
res = self.client.get(INDEX_URL)
|
||||
|
||||
with patch('tuskar_ui.api.Node', **{
|
||||
'spec_set': ['list'], # Only allow these attributes
|
||||
'list.return_value': [],
|
||||
}) as mock:
|
||||
res = self.client.get(INDEX_URL)
|
||||
# FIXME(lsmola) optimize, this should call 1 time, what the hell
|
||||
self.assertEqual(mock.list.call_count, 8)
|
||||
|
||||
self.assertTemplateUsed(
|
||||
res, 'infrastructure/nodes/index.html')
|
||||
self.assertTemplateUsed(res, 'infrastructure/nodes/_overview.html')
|
||||
@ -102,13 +110,13 @@ class NodesTests(test.BaseAdminViewTests):
|
||||
'register_nodes-INITIAL_FORMS': 1,
|
||||
'register_nodes-MAX_NUM_FORMS': 1000,
|
||||
|
||||
'register_nodes-0-ip_address': '127.0.0.1',
|
||||
'register_nodes-0-ipmi_address': '127.0.0.1',
|
||||
'register_nodes-0-mac_address': 'de:ad:be:ef:ca:fe',
|
||||
'register_nodes-0-cpus': '1',
|
||||
'register_nodes-0-memory': '2',
|
||||
'register_nodes-0-local_disk': '3',
|
||||
|
||||
'register_nodes-1-ip_address': '127.0.0.2',
|
||||
'register_nodes-1-ipmi_address': '127.0.0.2',
|
||||
'register_nodes-1-mac_address': 'de:ad:be:ef:ca:ff',
|
||||
'register_nodes-1-cpus': '4',
|
||||
'register_nodes-1-memory': '5',
|
||||
@ -122,9 +130,9 @@ class NodesTests(test.BaseAdminViewTests):
|
||||
request = Node.create.call_args_list[0][0][0] # This is a hack.
|
||||
self.assertListEqual(Node.create.call_args_list, [
|
||||
call(request, '127.0.0.1', 1, 2, 3,
|
||||
['DE:AD:BE:EF:CA:FE'], None, u''),
|
||||
'DE:AD:BE:EF:CA:FE', None, u''),
|
||||
call(request, '127.0.0.2', 4, 5, 6,
|
||||
['DE:AD:BE:EF:CA:FF'], None, u''),
|
||||
'DE:AD:BE:EF:CA:FF', None, u''),
|
||||
])
|
||||
self.assertRedirectsNoFollow(res, INDEX_URL)
|
||||
|
||||
@ -134,13 +142,13 @@ class NodesTests(test.BaseAdminViewTests):
|
||||
'register_nodes-INITIAL_FORMS': 1,
|
||||
'register_nodes-MAX_NUM_FORMS': 1000,
|
||||
|
||||
'register_nodes-0-ip_address': '127.0.0.1',
|
||||
'register_nodes-0-ipmi_address': '127.0.0.1',
|
||||
'register_nodes-0-mac_address': 'de:ad:be:ef:ca:fe',
|
||||
'register_nodes-0-cpus': '1',
|
||||
'register_nodes-0-memory': '2',
|
||||
'register_nodes-0-local_disk': '3',
|
||||
|
||||
'register_nodes-1-ip_address': '127.0.0.2',
|
||||
'register_nodes-1-ipmi_address': '127.0.0.2',
|
||||
'register_nodes-1-mac_address': 'de:ad:be:ef:ca:ff',
|
||||
'register_nodes-1-cpus': '4',
|
||||
'register_nodes-1-memory': '5',
|
||||
@ -154,9 +162,9 @@ class NodesTests(test.BaseAdminViewTests):
|
||||
request = Node.create.call_args_list[0][0][0] # This is a hack.
|
||||
self.assertListEqual(Node.create.call_args_list, [
|
||||
call(request, '127.0.0.1', 1, 2, 3,
|
||||
['DE:AD:BE:EF:CA:FE'], None, u''),
|
||||
'DE:AD:BE:EF:CA:FE', None, u''),
|
||||
call(request, '127.0.0.2', 4, 5, 6,
|
||||
['DE:AD:BE:EF:CA:FF'], None, u''),
|
||||
'DE:AD:BE:EF:CA:FF', None, u''),
|
||||
])
|
||||
self.assertTemplateUsed(
|
||||
res, 'infrastructure/nodes/register.html')
|
||||
|
@ -41,7 +41,7 @@ class ResourceCategoryNodeTable(tables.DataTable):
|
||||
))
|
||||
|
||||
def get_object_id(self, datum):
|
||||
return datum.uuid
|
||||
return datum.id
|
||||
|
||||
class Meta:
|
||||
name = "resource_category__nodetable"
|
||||
|
@ -26,7 +26,7 @@ INDEX_URL = urlresolvers.reverse(
|
||||
CREATE_URL = urlresolvers.reverse(
|
||||
'horizon:infrastructure:overcloud:create')
|
||||
DETAIL_URL = urlresolvers.reverse(
|
||||
'horizon:infrastructure:overcloud:create')
|
||||
'horizon:infrastructure:overcloud:detail', args=(1,))
|
||||
TEST_DATA = utils.TestDataContainer()
|
||||
tuskar_data.data(TEST_DATA)
|
||||
|
||||
@ -34,12 +34,13 @@ tuskar_data.data(TEST_DATA)
|
||||
class OvercloudTests(test.BaseAdminViewTests):
|
||||
|
||||
def test_index_overcloud_undeployed_get(self):
|
||||
oc = api.Overcloud(TEST_DATA.tuskarclient_overclouds.first())
|
||||
oc = None
|
||||
with patch('tuskar_ui.api.Overcloud', **{
|
||||
'spec_set': ['get', 'is_deployed'],
|
||||
'is_deployed': False,
|
||||
'get.return_value': oc,
|
||||
'get.side_effect': lambda request, overcloud_id: oc,
|
||||
}) as Overcloud:
|
||||
oc = api.Overcloud
|
||||
res = self.client.get(INDEX_URL)
|
||||
request = Overcloud.get.call_args_list[0][0][0] # This is a hack.
|
||||
self.assertListEqual(Overcloud.get.call_args_list,
|
||||
@ -82,12 +83,14 @@ class OvercloudTests(test.BaseAdminViewTests):
|
||||
self.assertRedirectsNoFollow(res, INDEX_URL)
|
||||
|
||||
def test_index_overcloud_deployed(self):
|
||||
oc = api.Overcloud(TEST_DATA.tuskarclient_overclouds.first())
|
||||
oc = None
|
||||
with patch('tuskar_ui.api.Overcloud', **{
|
||||
'spec_set': ['get', 'is_deployed'],
|
||||
'spec_set': ['get', 'is_deployed', 'id'],
|
||||
'is_deployed': True,
|
||||
'get.return_value': oc,
|
||||
'id': 1,
|
||||
'get.side_effect': lambda request, overcloud_id: oc,
|
||||
}) as Overcloud:
|
||||
oc = Overcloud
|
||||
res = self.client.get(INDEX_URL)
|
||||
request = Overcloud.get.call_args_list[0][0][0] # This is a hack.
|
||||
self.assertListEqual(Overcloud.get.call_args_list,
|
||||
|
@ -14,6 +14,8 @@
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
from mock import patch # noqa
|
||||
|
||||
from glanceclient.v1 import images
|
||||
from heatclient.v1 import events
|
||||
from heatclient.v1 import stacks
|
||||
@ -27,16 +29,11 @@ from tuskar_ui.test import helpers as test
|
||||
|
||||
|
||||
class TuskarAPITests(test.APITestCase):
|
||||
|
||||
def test_overcloud_create(self):
|
||||
#overcloud = self.tuskarclient_overclouds.first()
|
||||
|
||||
ret_val = api.Overcloud.create(self.request, [])
|
||||
self.assertIsInstance(ret_val, api.Overcloud)
|
||||
|
||||
def test_overcloud_list(self):
|
||||
#overclouds = self.tuskarclient_overclouds.list()
|
||||
|
||||
ret_val = api.Overcloud.list(self.request)
|
||||
for oc in ret_val:
|
||||
self.assertIsInstance(oc, api.Overcloud)
|
||||
@ -49,10 +46,12 @@ class TuskarAPITests(test.APITestCase):
|
||||
self.assertIsInstance(ret_val, api.Overcloud)
|
||||
|
||||
def test_overcloud_stack(self):
|
||||
overcloud = self.tuskarclient_overclouds.first()
|
||||
|
||||
ret_val = api.Overcloud(overcloud).stack
|
||||
self.assertIsInstance(ret_val, stacks.Stack)
|
||||
stack = self.heatclient_stacks.first()
|
||||
oc = api.Overcloud(self.tuskarclient_overclouds.first(), request=None)
|
||||
with patch('openstack_dashboard.api.heat.stack_get',
|
||||
return_value=stack):
|
||||
ret_val = oc.stack
|
||||
self.assertIsInstance(ret_val, stacks.Stack)
|
||||
|
||||
def test_overcloud_stack_events(self):
|
||||
overcloud = self.tuskarclient_overclouds.first()
|
||||
@ -70,65 +69,150 @@ class TuskarAPITests(test.APITestCase):
|
||||
self.assertListEqual([], ret_val)
|
||||
|
||||
def test_overcloud_is_deployed(self):
|
||||
overcloud = self.tuskarclient_overclouds.first()
|
||||
stack = self.heatclient_stacks.first()
|
||||
oc = api.Overcloud(self.tuskarclient_overclouds.first(), request=None)
|
||||
with patch('openstack_dashboard.api.heat.stack_get',
|
||||
return_value=stack):
|
||||
ret_val = oc.is_deployed
|
||||
self.assertFalse(ret_val)
|
||||
|
||||
ret_val = api.Overcloud(overcloud).is_deployed
|
||||
self.assertFalse(ret_val)
|
||||
def test_overcloud_all_resources(self):
|
||||
oc = api.Overcloud(self.tuskarclient_overclouds.first(), request=None)
|
||||
|
||||
def test_overcloud_resources(self):
|
||||
overcloud = self.tuskarclient_overclouds.first()
|
||||
category = self.tuskarclient_resource_categories.first()
|
||||
# FIXME(lsmola) the stack call should not be tested in this unit test
|
||||
# anybody has idea how to do it?
|
||||
stack = self.heatclient_stacks.first()
|
||||
resources = self.heatclient_resources.list()
|
||||
nodes = self.ironicclient_nodes.list()
|
||||
instances = []
|
||||
|
||||
with patch('openstack_dashboard.api.heat.resources_list',
|
||||
return_value=resources):
|
||||
with patch('openstack_dashboard.api.nova.server_list',
|
||||
return_value=(instances, None)):
|
||||
with patch('novaclient.v1_1.contrib.baremetal.'
|
||||
'BareMetalNodeManager.list',
|
||||
return_value=nodes):
|
||||
with patch('openstack_dashboard.api.heat.stack_get',
|
||||
return_value=stack):
|
||||
ret_val = oc.all_resources()
|
||||
|
||||
ret_val = api.Overcloud(overcloud).resources(
|
||||
api.ResourceCategory(category))
|
||||
for i in ret_val:
|
||||
self.assertIsInstance(i, api.Resource)
|
||||
self.assertEqual(1, len(ret_val))
|
||||
self.assertEqual(4, len(ret_val))
|
||||
|
||||
def test_overcloud_resources(self):
|
||||
oc = api.Overcloud(self.tuskarclient_overclouds.first(), request=None)
|
||||
category = api.ResourceCategory(self.tuskarclient_resource_categories.
|
||||
first())
|
||||
|
||||
# FIXME(lsmola) only all_resources and image_name should be tested
|
||||
# here, anybody has idea how to do that?
|
||||
image = self.glanceclient_images.first()
|
||||
stack = self.heatclient_stacks.first()
|
||||
resources = self.heatclient_resources.list()
|
||||
instances = self.novaclient_servers.list()
|
||||
nodes = self.ironicclient_nodes.list()
|
||||
with patch('openstack_dashboard.api.heat.resources_list',
|
||||
return_value=resources) as resource_list:
|
||||
with patch('openstack_dashboard.api.nova.server_list',
|
||||
return_value=(instances, None)) as server_list:
|
||||
with patch('openstack_dashboard.api.glance.image_get',
|
||||
return_value=image) as image_get:
|
||||
with patch('novaclient.v1_1.contrib.baremetal.'
|
||||
'BareMetalNodeManager.list',
|
||||
return_value=nodes) as node_list:
|
||||
with patch('openstack_dashboard.api.heat.stack_get',
|
||||
return_value=stack) as stack_get:
|
||||
ret_val = oc.resources(category)
|
||||
self.assertEqual(resource_list.call_count, 1)
|
||||
self.assertEqual(server_list.call_count, 1)
|
||||
# TODO(lsmola) isn't it better to call image_list?
|
||||
# this will call image_get for every unique image
|
||||
# used that should not be much (4 images should be
|
||||
# there for start)
|
||||
# FIXME(lsmola) testing caching here is bad,
|
||||
# because it gets cached for the whole tests run
|
||||
self.assertEqual(image_get.call_count, 2)
|
||||
# FIXME(lsmola) optimize this, it's enough to call
|
||||
# node_list once
|
||||
self.assertEqual(node_list.call_count, 1)
|
||||
self.assertEqual(stack_get.call_count, 1)
|
||||
|
||||
for i in ret_val:
|
||||
self.assertIsInstance(i, api.Resource)
|
||||
self.assertEqual(4, len(ret_val))
|
||||
|
||||
def test_node_create(self):
|
||||
node = self.ironicclient_nodes.first()
|
||||
node = api.Node(self.ironicclient_nodes.first())
|
||||
|
||||
ret_val = api.Node.create(
|
||||
self.request,
|
||||
node.driver_info['ipmi_address'],
|
||||
node.properties['cpu'],
|
||||
node.properties['ram'],
|
||||
node.properties['local_disk'],
|
||||
['aa:aa:aa:aa:aa:aa'],
|
||||
ipmi_username='admin',
|
||||
ipmi_password='password')
|
||||
ret_val.instance_uuid = None
|
||||
# FIXME(lsmola) this should be mocking client call no Node
|
||||
with patch('novaclient.v1_1.contrib.baremetal.'
|
||||
'BareMetalNodeManager.create',
|
||||
return_value=node):
|
||||
ret_val = api.Node.create(
|
||||
self.request,
|
||||
node.driver_info['ipmi_address'],
|
||||
node.properties['cpu'],
|
||||
node.properties['ram'],
|
||||
node.properties['local_disk'],
|
||||
['aa:aa:aa:aa:aa:aa'],
|
||||
ipmi_username='admin',
|
||||
ipmi_password='password')
|
||||
|
||||
self.assertIsInstance(ret_val, api.Node)
|
||||
self.assertIsNone(ret_val.instance)
|
||||
|
||||
def test_node_get(self):
|
||||
node = self.ironicclient_nodes.first()
|
||||
instance = self.novaclient_servers.first()
|
||||
|
||||
with patch('openstack_dashboard.api.nova.server_get',
|
||||
return_value=instance):
|
||||
with patch('novaclient.v1_1.contrib.baremetal.'
|
||||
'BareMetalNodeManager.get',
|
||||
return_value=node):
|
||||
ret_val = api.Node.get(self.request, node.uuid)
|
||||
|
||||
ret_val = api.Node.get(self.request, node.uuid)
|
||||
self.assertIsInstance(ret_val, api.Node)
|
||||
self.assertIsInstance(ret_val.instance, servers.Server)
|
||||
|
||||
def test_node_get_by_instance_uuid(self):
|
||||
instance = self.novaclient_servers.first()
|
||||
node = self.ironicclient_nodes.first()
|
||||
nodes = self.ironicclient_nodes.list()
|
||||
|
||||
with patch('openstack_dashboard.api.nova.server_get',
|
||||
return_value=instance):
|
||||
with patch('novaclient.v1_1.contrib.baremetal.'
|
||||
'BareMetalNodeManager.list',
|
||||
return_value=nodes):
|
||||
ret_val = api.Node.get_by_instance_uuid(self.request,
|
||||
node.instance_uuid)
|
||||
|
||||
ret_val = api.Node.get_by_instance_uuid(self.request,
|
||||
node.instance_uuid)
|
||||
self.assertIsInstance(ret_val, api.Node)
|
||||
self.assertIsInstance(ret_val.instance, servers.Server)
|
||||
|
||||
def test_node_list(self):
|
||||
#nodes = self.tuskarclient_overclouds.list()
|
||||
instances = self.novaclient_servers.list()
|
||||
nodes = self.ironicclient_nodes.list()
|
||||
|
||||
with patch('openstack_dashboard.api.nova.server_list',
|
||||
return_value=(instances, None)):
|
||||
with patch('novaclient.v1_1.contrib.baremetal.'
|
||||
'BareMetalNodeManager.list',
|
||||
return_value=nodes):
|
||||
ret_val = api.Node.list(self.request)
|
||||
|
||||
ret_val = api.Node.list(self.request)
|
||||
for node in ret_val:
|
||||
self.assertIsInstance(node, api.Node)
|
||||
self.assertEqual(5, len(ret_val))
|
||||
|
||||
def test_node_delete(self):
|
||||
node = self.ironicclient_nodes.first()
|
||||
|
||||
api.Node.delete(self.request, node.uuid)
|
||||
with patch('novaclient.v1_1.contrib.baremetal.'
|
||||
'BareMetalNodeManager.delete',
|
||||
return_value=None):
|
||||
api.Node.delete(self.request, node.uuid)
|
||||
|
||||
def test_node_addresses(self):
|
||||
node = self.ironicclient_nodes.first()
|
||||
@ -137,17 +221,30 @@ class TuskarAPITests(test.APITestCase):
|
||||
self.assertEqual(2, len(ret_val))
|
||||
|
||||
def test_resource_get(self):
|
||||
overcloud = self.tuskarclient_overclouds.first()
|
||||
stack = self.heatclient_stacks.first()
|
||||
overcloud = api.Overcloud(self.tuskarclient_overclouds.first(),
|
||||
request=None)
|
||||
resource = self.heatclient_resources.first()
|
||||
|
||||
ret_val = api.Resource.get(self.request, overcloud,
|
||||
resource.resource_name)
|
||||
with patch('openstack_dashboard.api.heat.resource_get',
|
||||
return_value=resource):
|
||||
with patch('openstack_dashboard.api.heat.stack_get',
|
||||
return_value=stack):
|
||||
ret_val = api.Resource.get(None, overcloud,
|
||||
resource.resource_name)
|
||||
self.assertIsInstance(ret_val, api.Resource)
|
||||
|
||||
def test_resource_node(self):
|
||||
resource = self.heatclient_resources.first()
|
||||
nodes = self.ironicclient_nodes.list()
|
||||
instance = self.novaclient_servers.first()
|
||||
|
||||
ret_val = api.Resource(resource).node
|
||||
with patch('openstack_dashboard.api.nova.server_get',
|
||||
return_value=instance):
|
||||
with patch('novaclient.v1_1.contrib.baremetal.'
|
||||
'BareMetalNodeManager.list',
|
||||
return_value=nodes):
|
||||
ret_val = api.Resource(resource, request=None).node
|
||||
self.assertIsInstance(ret_val, api.Node)
|
||||
self.assertIsInstance(ret_val.instance, servers.Server)
|
||||
|
||||
|
@ -105,7 +105,8 @@ def data(TEST):
|
||||
TEST.ironicclient_nodes = test_data_utils.TestDataContainer()
|
||||
node_1 = node.Node(
|
||||
node.NodeManager(None),
|
||||
{'uuid': 'aa-11',
|
||||
{'id': '1',
|
||||
'uuid': 'aa-11',
|
||||
'instance_uuid': 'aa',
|
||||
'driver': 'pxe_ipmitool',
|
||||
'driver_info': {
|
||||
@ -118,10 +119,23 @@ def data(TEST):
|
||||
'ram': '16',
|
||||
'local_disk': '10',
|
||||
},
|
||||
'power_state': 'on'})
|
||||
'power_state': 'on',
|
||||
|
||||
# FIXME(lsmola) nova-baremetal test attrs, delete when Ironic is in
|
||||
"pm_address": None,
|
||||
"pm_user": None,
|
||||
"task_state": "active",
|
||||
"interfaces": [{"address": "52:54:00:90:38:01"},
|
||||
{"address": "52:54:00:90:38:01"}],
|
||||
"cpus": 1,
|
||||
"memory_mb": 4096,
|
||||
"service_host": "undercloud",
|
||||
"local_gb": 20,
|
||||
})
|
||||
node_2 = node.Node(
|
||||
node.NodeManager(None),
|
||||
{'uuid': 'bb-22',
|
||||
{'id': '2',
|
||||
'uuid': 'bb-22',
|
||||
'instance_uuid': 'bb',
|
||||
'driver': 'pxe_ipmitool',
|
||||
'driver_info': {
|
||||
@ -134,10 +148,22 @@ def data(TEST):
|
||||
'ram': '32',
|
||||
'local_disk': '100',
|
||||
},
|
||||
'power_state': 'on'})
|
||||
'power_state': 'on',
|
||||
|
||||
# FIXME(lsmola) nova-baremetal test attrs, delete when Ironic is in
|
||||
"pm_address": None,
|
||||
"pm_user": None,
|
||||
"task_state": "active",
|
||||
"interfaces": [{"address": "52:54:00:90:38:01"}],
|
||||
"cpus": 1,
|
||||
"memory_mb": 4096,
|
||||
"service_host": "undercloud",
|
||||
"local_gb": 20,
|
||||
})
|
||||
node_3 = node.Node(
|
||||
node.NodeManager(None),
|
||||
{'uuid': 'cc-33',
|
||||
{'id': '3',
|
||||
'uuid': 'cc-33',
|
||||
'instance_uuid': None,
|
||||
'driver': 'pxe_ipmitool',
|
||||
'driver_info': {
|
||||
@ -150,10 +176,22 @@ def data(TEST):
|
||||
'ram': '64',
|
||||
'local_disk': '1',
|
||||
},
|
||||
'power_state': 'rebooting'})
|
||||
'power_state': 'rebooting',
|
||||
|
||||
# FIXME(lsmola) nova-baremetal test attrs, delete when Ironic is in
|
||||
"pm_address": None,
|
||||
"pm_user": None,
|
||||
"task_state": "active",
|
||||
"interfaces": [{"address": "52:54:00:90:38:01"}],
|
||||
"cpus": 1,
|
||||
"memory_mb": 4096,
|
||||
"service_host": "undercloud",
|
||||
"local_gb": 20,
|
||||
})
|
||||
node_4 = node.Node(
|
||||
node.NodeManager(None),
|
||||
{'uuid': 'cc-44',
|
||||
{'id': '4',
|
||||
'uuid': 'cc-44',
|
||||
'instance_uuid': 'cc',
|
||||
'driver': 'pxe_ipmitool',
|
||||
'driver_info': {
|
||||
@ -166,10 +204,22 @@ def data(TEST):
|
||||
'ram': '16',
|
||||
'local_disk': '10',
|
||||
},
|
||||
'power_state': 'on'})
|
||||
'power_state': 'on',
|
||||
|
||||
# FIXME(lsmola) nova-baremetal test attrs, delete when Ironic is in
|
||||
"pm_address": None,
|
||||
"pm_user": None,
|
||||
"task_state": "active",
|
||||
"interfaces": [{"address": "52:54:00:90:38:01"}],
|
||||
"cpus": 1,
|
||||
"memory_mb": 4096,
|
||||
"service_host": "undercloud",
|
||||
"local_gb": 20,
|
||||
})
|
||||
node_5 = node.Node(
|
||||
node.NodeManager(None),
|
||||
{'uuid': 'dd-55',
|
||||
{'id': '5',
|
||||
'uuid': 'dd-55',
|
||||
'instance_uuid': 'dd',
|
||||
'driver': 'pxe_ipmitool',
|
||||
'driver_info': {
|
||||
@ -182,7 +232,18 @@ def data(TEST):
|
||||
'ram': '16',
|
||||
'local_disk': '10',
|
||||
},
|
||||
'power_state': 'on'})
|
||||
'power_state': 'on',
|
||||
|
||||
# FIXME(lsmola) nova-baremetal test attrs, delete when Ironic is in
|
||||
"pm_address": None,
|
||||
"pm_user": None,
|
||||
"task_state": "active",
|
||||
"interfaces": [{"address": "52:54:00:90:38:01"}],
|
||||
"cpus": 1,
|
||||
"memory_mb": 4096,
|
||||
"service_host": "undercloud",
|
||||
"local_gb": 20,
|
||||
})
|
||||
TEST.ironicclient_nodes.add(node_1, node_2, node_3, node_4, node_5)
|
||||
|
||||
# Ports
|
||||
@ -258,25 +319,25 @@ def data(TEST):
|
||||
servers.ServerManager(None),
|
||||
{'id': 'aa',
|
||||
'name': 'Compute',
|
||||
'image': 'compute-image',
|
||||
'image': {'id': 1},
|
||||
'status': 'ACTIVE'})
|
||||
s_2 = servers.Server(
|
||||
servers.ServerManager(None),
|
||||
{'id': 'bb',
|
||||
'name': 'Controller',
|
||||
'image': 'controller-image',
|
||||
'image': {'id': 2},
|
||||
'status': 'ACTIVE'})
|
||||
s_3 = servers.Server(
|
||||
servers.ServerManager(None),
|
||||
{'id': 'cc',
|
||||
'name': 'Compute',
|
||||
'image': 'compute-image',
|
||||
'image': {'id': 1},
|
||||
'status': 'BUILD'})
|
||||
s_4 = servers.Server(
|
||||
servers.ServerManager(None),
|
||||
{'id': 'dd',
|
||||
'name': 'Compute',
|
||||
'image': 'compute-image',
|
||||
'image': {'id': 1},
|
||||
'status': 'ERROR'})
|
||||
TEST.novaclient_servers.add(s_1, s_2, s_3, s_4)
|
||||
|
||||
@ -297,37 +358,41 @@ def data(TEST):
|
||||
rc_1 = {'id': 1,
|
||||
'name': 'Controller',
|
||||
'description': 'controller resource category',
|
||||
'image_id': 'image-id-1'}
|
||||
'image_id': '2',
|
||||
'image_name': 'overcloud-control'}
|
||||
rc_2 = {'id': 2,
|
||||
'name': 'Compute',
|
||||
'description': 'compute resource category',
|
||||
'image_id': 'image-id-2'}
|
||||
'image_id': '1',
|
||||
'image_name': 'overcloud-compute'}
|
||||
rc_3 = {'id': 3,
|
||||
'name': 'Object Storage',
|
||||
'description': 'object storage resource category',
|
||||
'image_id': 'image-id-3'}
|
||||
'image_id': '3',
|
||||
'image_name': 'overcloud-object-storage'}
|
||||
rc_4 = {'id': 4,
|
||||
'name': 'Block Storage',
|
||||
'description': 'block storage resource category',
|
||||
'image_id': 'image-id-4'}
|
||||
'image_id': '4',
|
||||
'image_name': 'overcloud-block-storage'}
|
||||
TEST.tuskarclient_resource_categories.add(rc_1, rc_2, rc_3, rc_4)
|
||||
|
||||
# Image
|
||||
TEST.glanceclient_images = test_data_utils.TestDataContainer()
|
||||
image_1 = images.Image(
|
||||
images.ImageManager(None),
|
||||
{'id': 'image-id-1',
|
||||
'name': 'Controller Image'})
|
||||
{'id': '2',
|
||||
'name': 'overcloud-control'})
|
||||
image_2 = images.Image(
|
||||
images.ImageManager(None),
|
||||
{'id': 'image-id-2',
|
||||
'name': 'Compute Image'})
|
||||
{'id': '1',
|
||||
'name': 'overcloud-compute'})
|
||||
image_3 = images.Image(
|
||||
images.ImageManager(None),
|
||||
{'id': 'image-id-3',
|
||||
{'id': '3',
|
||||
'name': 'Object Storage Image'})
|
||||
image_4 = images.Image(
|
||||
images.ImageManager(None),
|
||||
{'id': 'image-id-4',
|
||||
{'id': '4',
|
||||
'name': 'Block Storage Image'})
|
||||
TEST.glanceclient_images.add(image_1, image_2, image_3, image_4)
|
||||
|
Loading…
x
Reference in New Issue
Block a user