summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/index.rst14
-rw-r--r--docs/install.rst8
-rw-r--r--tuskar_ui/api.py269
-rw-r--r--tuskar_ui/infrastructure/resource_management/nodes/tests.py16
-rw-r--r--tuskar_ui/infrastructure/resource_management/racks/tests.py12
-rw-r--r--tuskar_ui/infrastructure/resource_management/resource_classes/tests.py3
-rw-r--r--tuskar_ui/infrastructure/resource_management/resource_classes/workflows.py4
-rw-r--r--tuskar_ui/infrastructure/resource_management/tabs.py2
-rw-r--r--tuskar_ui/infrastructure/resource_management/templates/resource_management/nodes/_detail_overview.html10
-rw-r--r--tuskar_ui/infrastructure/resource_management/templates/resource_management/nodes/detail.html4
-rw-r--r--tuskar_ui/test/api_tests/tuskar_tests.py260
-rw-r--r--tuskar_ui/test/test_data/tuskar_data.py65
12 files changed, 301 insertions, 366 deletions
diff --git a/docs/index.rst b/docs/index.rst
index 8960aa8b..195f5f1c 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -2,7 +2,7 @@
Tuskar-UI
=========
-Tuskar-UI is a user interface for `Tuskar <https://github.com/stackforge/tuskar>`_, a management API for OpenStack deployments. It is a plugin for `OpenStack Horizon <https://wiki.openstack.org/wiki/Horizon>`_.
+Tuskar-UI is a user interface for `Tuskar <https://github.com/openstack/tuskar>`_, a management API for OpenStack deployments. It is a plugin for `OpenStack Horizon <https://wiki.openstack.org/wiki/Horizon>`_.
High-Level Overview
-------------------
@@ -18,16 +18,16 @@ Developer Information
Installation Guide
~~~~~~~~~~~~~~~~~~
-Follow the `Installation Guide <https://github.com/stackforge/tuskar-ui/blob/master/docs/install.rst>`_ to install Tuskar-UI.
+Follow the `Installation Guide <https://github.com/openstack/tuskar-ui/blob/master/docs/install.rst>`_ to install Tuskar-UI.
Contributing
~~~~~~~~~~~~
-We've moved the code to `stackforge <https://github.com/stackforge>`__
+We've moved the code to `openstack <https://github.com/openstack>`__
to be more familiar to the OpenStack developers. Please go there if you
want to check it out:
- git clone https://github.com/stackforge/tuskar-ui.git
+ git clone https://github.com/openstack/tuskar-ui.git
The list of bugs and blueprints is on Launchpad:
@@ -35,14 +35,14 @@ The list of bugs and blueprints is on Launchpad:
We use OpenStack's Gerrit for the code contributions:
-`<https://review.openstack.org/#/q/status:open+project:stackforge/tuskar-ui,n,z>`__
+`<https://review.openstack.org/#/q/status:open+project:openstack/tuskar-ui,n,z>`__
and we follow the `OpenStack Gerrit Workflow <https://wiki.openstack.org/wiki/Gerrit_Workflow>`__.
If you're interested in the code, here are some key places to start:
-* `tuskar_ui/api.py <https://github.com/stackforge/tuskar-ui/blob/master/tuskar_ui/api.py>`_ - This file contains all the API calls made to the Tuskar API (through python-tuskarclient).
-* `tuskar_ui/infrastructure <https://github.com/stackforge/tuskar-ui/tree/master/tuskar_ui/infrastructure>`_ - The Tuskar UI code is contained within this directory. Up to this point, UI development has been focused within the resource_management/ subdirectory.
+* `tuskar_ui/api.py <https://github.com/openstack/tuskar-ui/blob/master/tuskar_ui/api.py>`_ - This file contains all the API calls made to the Tuskar API (through python-tuskarclient).
+* `tuskar_ui/infrastructure <https://github.com/openstack/tuskar-ui/tree/master/tuskar_ui/infrastructure>`_ - The Tuskar UI code is contained within this directory. Up to this point, UI development has been focused within the resource_management/ subdirectory.
Future Work
-----------
diff --git a/docs/install.rst b/docs/install.rst
index 9e174a9d..1defc8d5 100644
--- a/docs/install.rst
+++ b/docs/install.rst
@@ -20,7 +20,7 @@ Installation prerequisites are:
machine as tuskar-ui, but it must be network accessible.
You may find
-`the Tuskar install guide <https://github.com/stackforge/tuskar/blob/master/INSTALL.rst>`_
+`the Tuskar install guide <https://github.com/openstack/tuskar/blob/master/INSTALL.rst>`_
helpful.
For baremetal provisioning, you will want a Nova Baremetal driver
@@ -28,7 +28,7 @@ installed and registered in the Keystone services catalog. (You can
`read more about setting up Nova Baremetal here <https://wiki.openstack.org/wiki/Baremetal>`_.)
If you are using Devstack to run OpenStack, you can use
-`Devstack Baremetal configuration <https://github.com/stackforge/tuskar-ui/blob/master/docs/devstack_baremetal.rst>`_.
+`Devstack Baremetal configuration <https://github.com/openstack/tuskar-ui/blob/master/docs/devstack_baremetal.rst>`_.
Installing the packages
-----------------------
@@ -62,7 +62,7 @@ Begin by cloning the horizon and tuskar-ui repositories:
::
git clone git://github.com/openstack/horizon.git
- git clone git://github.com/stackforge/tuskar-ui.git
+ git clone git://github.com/openstack/tuskar-ui.git
Go into horizon and create a symlink to the tuskar-ui code:
@@ -137,7 +137,7 @@ tuskar-ui introduces one additional dependency - python-tuskarclient:
::
- pip install git+http://github.com/stackforge/python-tuskarclient.git
+ pip install git+http://github.com/openstack/python-tuskarclient.git
Starting the app
----------------
diff --git a/tuskar_ui/api.py b/tuskar_ui/api.py
index 834b5b13..81a36ff2 100644
--- a/tuskar_ui/api.py
+++ b/tuskar_ui/api.py
@@ -21,7 +21,6 @@ import random
import django.conf
import django.db.models
from django.utils.translation import ugettext_lazy as _ # noqa
-from horizon import exceptions
import requests
from novaclient.v1_1.contrib import baremetal
@@ -163,20 +162,36 @@ class Capacity(StringIdAPIResourceWrapper):
return self._average
-class Node(StringIdAPIResourceWrapper):
- """Wrapper for the Node object returned by the
- dummy model.
- """
+class BaremetalNode(StringIdAPIResourceWrapper):
_attrs = ['id', 'pm_address', 'cpus', 'memory_mb', 'service_host',
'local_gb', 'pm_user']
@classmethod
+ def create(cls, request, **kwargs):
+ # The pm_address, pm_user and terminal_port need to be None when
+ # empty for the baremetal vm to work.
+ # terminal_port needs separate handling because 0 is a valid value.
+ terminal_port = kwargs['terminal_port']
+ if terminal_port == '':
+ terminal_port = None
+ node = baremetalclient(request).create(kwargs['name'],
+ kwargs['cpus'],
+ kwargs['memory_mb'],
+ kwargs['local_gb'],
+ kwargs['prov_mac_address'],
+ kwargs['pm_address'] or None,
+ kwargs['pm_user'] or None,
+ kwargs['pm_password'],
+ terminal_port)
+ return cls(node)
+
+ @classmethod
def get(cls, request, node_id):
node = cls(baremetalclient(request).get(node_id))
node.request = request
# FIXME ugly, fix after demo, make abstraction of instance details
- # this is realy not optimal, but i dont have time do fix it now
+ # this is realy not optimal, but i dont hve time do fix it now
instances, more = nova.server_list(
request,
search_opts={'paginate': True},
@@ -192,8 +207,8 @@ class Node(StringIdAPIResourceWrapper):
if detail:
addresses = detail._apiresource.addresses.get('ctlplane')
if addresses:
- node.ip_address_other = (", ".join([addr['addr']
- for addr in addresses]))
+ node.ip_address_other = (", "
+ .join([addr['addr'] for addr in addresses]))
node.status = detail._apiresource._info['OS-EXT-STS:vm_state']
node.power_management = ""
@@ -206,74 +221,24 @@ class Node(StringIdAPIResourceWrapper):
@classmethod
def list(cls, request):
- return [Node(n, request) for n in baremetalclient(request).list()]
+ return [cls(n, request) for n in
+ baremetalclient(request).list()]
@classmethod
def list_unracked(cls, request):
try:
- return [n for n in Node.list(request) if (n.rack is None)]
+ racked_node_ids = [node.nova_baremetal_node_id
+ for node in Node.list(request)]
+ return [bn for bn in BaremetalNode.list(request)
+ if bn.id not in racked_node_ids]
except requests.ConnectionError:
return []
- @classmethod
- def create(cls, request, **kwargs):
- # The pm_address, pm_user and terminal_port need to be None when
- # empty for the baremetal vm to work.
- # terminal_port needs separate handling because 0 is a valid value.
- terminal_port = kwargs['terminal_port']
- if terminal_port == '':
- terminal_port = None
- node = baremetalclient(request).create(kwargs['name'],
- kwargs['cpus'],
- kwargs['memory_mb'],
- kwargs['local_gb'],
- kwargs['prov_mac_address'],
- kwargs['pm_address'] or None,
- kwargs['pm_user'] or None,
- kwargs['pm_password'],
- terminal_port)
- return cls(node)
-
- @property
- def list_flavors(self):
- if not hasattr(self, '_flavors'):
- # FIXME: just a mock of used instances, add real values
- used_instances = 0
-
- if not self.rack or not self.rack.get_resource_class:
- return []
- resource_class = self.rack.get_resource_class
-
- added_flavors = tuskarclient(self.request).flavors\
- .list(resource_class.id)
- self._flavors = []
- if added_flavors:
- for f in added_flavors:
- flavor_obj = Flavor(f)
- #flavor_obj.max_vms = f.max_vms
-
- # FIXME just a mock of used instances, add real values
- used_instances += 5
- flavor_obj.used_instances = used_instances
- self._flavors.append(flavor_obj)
-
- return self._flavors
-
@property
- def rack(self):
+ def mac_address(self):
try:
- if not hasattr(self, '_rack'):
- # FIXME the node.rack association should be stored somewhere
- self._rack = None
- for rack in Rack.list(self.request):
- for node_obj in rack.list_nodes:
- if node_obj.id == self.id:
- self._rack = rack
-
- return self._rack
+ return self._apiresource.interfaces[0]['address']
except Exception:
- msg = "Could not obtain Nodes's rack"
- LOG.debug(exceptions.error_color(msg))
return None
@property
@@ -287,24 +252,6 @@ class Node(StringIdAPIResourceWrapper):
return 100 - self.running_instances
@property
- # FIXME: just mock implementation, add proper one
- def is_provisioned(self):
- return self.status != "unprovisioned" and self.rack
-
- @property
- def alerts(self):
- if not hasattr(self, '_alerts'):
- self._alerts = []
- return self._alerts
-
- @property
- def mac_address(self):
- try:
- return self._apiresource.interfaces[0]['address']
- except Exception:
- return None
-
- @property
def running_virtual_machines(self):
if not hasattr(self, '_running_virtual_machines'):
if OVERCLOUD_CREDS:
@@ -321,67 +268,115 @@ class Node(StringIdAPIResourceWrapper):
return self._running_virtual_machines
-class BaremetalNode(Node):
- _attrs = ['id', 'pm_address', 'cpus', 'memory_mb', 'service_host',
- 'local_gb', 'pm_user']
-
- @classmethod
- def create(cls, request, **kwargs):
- # The pm_address, pm_user and terminal_port need to be None when
- # empty for the baremetal vm to work.
- # terminal_port needs separate handling because 0 is a valid value.
- terminal_port = kwargs['terminal_port']
- if terminal_port == '':
- terminal_port = None
- node = baremetalclient(request).create(kwargs['name'],
- kwargs['cpus'],
- kwargs['memory_mb'],
- kwargs['local_gb'],
- kwargs['prov_mac_address'],
- kwargs['pm_address'] or None,
- kwargs['pm_user'] or None,
- kwargs['pm_password'],
- terminal_port)
- return cls(node)
+class Node(StringIdAPIResourceWrapper):
+ """
+ Wrapper for the Node object returned by the
+ dummy model.
+ """
+ _attrs = ['id', 'rack', 'nova_baremetal_node_id']
@classmethod
def get(cls, request, node_id):
- node = cls(baremetalclient(request).get(node_id))
+ node = cls(tuskarclient(request).nodes.get(node_id))
node.request = request
+ return node
- # FIXME ugly, fix after demo, make abstraction of instance details
- # this is realy not optimal, but i dont hve time do fix it now
- instances, more = nova.server_list(
- request,
- search_opts={'paginate': True},
- all_tenants=True)
-
- instance_details = {}
- for instance in instances:
- id = (instance.
- _apiresource._info['OS-EXT-SRV-ATTR:hypervisor_hostname'])
- instance_details[id] = instance
+ @classmethod
+ def list(cls, request):
+ return [cls(n, request) for n in (tuskarclient(request).nodes.list())]
- detail = instance_details.get(node_id)
- if detail:
- addresses = detail._apiresource.addresses.get('ctlplane')
- if addresses:
- node.ip_address_other = (", "
- .join([addr['addr'] for addr in addresses]))
+ @property
+ def get_rack(self):
+ if not hasattr(self, '_rack'):
+ if self.rack:
+ self._rack = Rack.get(self.request, self.rack['id'])
+ else:
+ self._rack = None
+ return self._rack
- node.status = detail._apiresource._info['OS-EXT-STS:vm_state']
- node.power_management = ""
- if node.pm_user:
- node.power_management = node.pm_user + "/********"
+ @property
+ def rack_id(self):
+ if self.rack:
+ return unicode(self.rack['id'])
else:
- node.status = 'unprovisioned'
+ return None
- return node
+ @property
+ def nova_baremetal_node(self):
+ if not hasattr(self, '_nova_baremetal_node'):
+ if self.nova_baremetal_node_id:
+ self._nova_baremetal_node = BaremetalNode.get(
+ self.request,
+ self.nova_baremetal_node_id)
+ else:
+ self._nova_baremetal_node = None
+ return self._nova_baremetal_node
- @classmethod
- def list(cls, request):
- return [cls(n, request) for n in
- baremetalclient(request).list()]
+ def nova_baremetal_node_attribute(self, attr_name):
+ key = "_%s" % attr_name
+ if not hasattr(self, key):
+ if self.nova_baremetal_node:
+ value = getattr(self.nova_baremetal_node, attr_name, None)
+ else:
+ value = None
+ setattr(self, key, value)
+ return getattr(self, key)
+
+ @property
+ def service_host(self):
+ return self.nova_baremetal_node_attribute('service_host')
+
+ @property
+ def mac_address(self):
+ return self.nova_baremetal_node_attribute('mac_address')
+
+ @property
+ def pm_address(self):
+ return self.nova_baremetal_node_attribute('pm_address')
+
+ @property
+ def status(self):
+ return self.nova_baremetal_node_attribute('status')
+
+ @property
+ def running_virtual_machines(self):
+ return self.nova_baremetal_node_attribute('running_virtual_machines')
+
+ @property
+ def list_flavors(self):
+ if not hasattr(self, '_flavors'):
+ # FIXME: just a mock of used instances, add real values
+ used_instances = 0
+
+ if not self.rack or not self.get_rack.get_resource_class:
+ return []
+ resource_class = self.get_rack.get_resource_class
+
+ added_flavors = tuskarclient(self.request).flavors\
+ .list(resource_class.id)
+ self._flavors = []
+ if added_flavors:
+ for f in added_flavors:
+ flavor_obj = Flavor(f)
+ #flavor_obj.max_vms = f.max_vms
+
+ # FIXME just a mock of used instances, add real values
+ used_instances += 5
+ flavor_obj.used_instances = used_instances
+ self._flavors.append(flavor_obj)
+
+ return self._flavors
+
+ @property
+ # FIXME: just mock implementation, add proper one
+ def is_provisioned(self):
+ return (self.status != "unprovisioned" and self.rack)
+
+ @property
+ def alerts(self):
+ if not hasattr(self, '_alerts'):
+ self._alerts = []
+ return self._alerts
class Rack(StringIdAPIResourceWrapper):
@@ -648,8 +643,8 @@ class ResourceClass(StringIdAPIResourceWrapper):
@property
def nodes(self):
if not hasattr(self, '_nodes'):
- nodes_lists = [rack.list_nodes for rack in self.list_racks]
- self._nodes = [node for nodes in nodes_lists for node in nodes]
+ self._nodes = [n for n in Node.list(self.request)
+ if n.rack_id in self.racks_ids]
return self._nodes
@property
diff --git a/tuskar_ui/infrastructure/resource_management/nodes/tests.py b/tuskar_ui/infrastructure/resource_management/nodes/tests.py
index f1bd3758..045c267d 100644
--- a/tuskar_ui/infrastructure/resource_management/nodes/tests.py
+++ b/tuskar_ui/infrastructure/resource_management/nodes/tests.py
@@ -40,16 +40,26 @@ class NodeViewTests(test.BaseAdminViewTests):
unracked_nodes_table = res.context['unracked_nodes_table'].data
self.assertItemsEqual(unracked_nodes_table, unracked_nodes)
- @test.create_stubs({tuskar.Node: ('get', 'running_virtual_machines')})
+ @test.create_stubs({tuskar.Node: ('get', 'running_virtual_machines',
+ 'list_flavors'),
+ tuskar.Rack: ('get',),
+ tuskar.BaremetalNode: ('get',)})
def test_detail_node(self):
node = self.tuskar_nodes.first()
+ node.request = self.request
+ rack = self.tuskar_racks.first()
+ bm_node = self.baremetal_nodes.first()
tuskar.Node.get(mox.IsA(http.HttpRequest),
node.id).AndReturn(node)
-
+ tuskar.Rack.get(mox.IsA(http.HttpRequest),
+ rack.id).AndReturn(rack)
+ tuskar.BaremetalNode.get(mox.IsA(http.HttpRequest),
+ bm_node.id).AndReturn(bm_node)
self.mox.ReplayAll()
tuskar.Node.running_virtual_machines = []
+ tuskar.Node.list_flavors = []
url = urlresolvers.reverse('horizon:infrastructure:'
'resource_management:nodes:'
@@ -62,7 +72,7 @@ class NodeViewTests(test.BaseAdminViewTests):
@test.create_stubs({tuskar.Node: ('get',)})
def test_detail_node_exception(self):
- node = self.baremetal_nodes.first()
+ node = self.tuskar_nodes.first()
tuskar.Node.get(
mox.IsA(http.HttpRequest),
diff --git a/tuskar_ui/infrastructure/resource_management/racks/tests.py b/tuskar_ui/infrastructure/resource_management/racks/tests.py
index d0addcf7..62cdff95 100644
--- a/tuskar_ui/infrastructure/resource_management/racks/tests.py
+++ b/tuskar_ui/infrastructure/resource_management/racks/tests.py
@@ -71,7 +71,7 @@ class RackViewTests(test.BaseAdminViewTests):
resource_class_id=u'1',
location='Tokyo',
subnet='1.2.3.4',
- nodes=[{'id': '1'}]).AndReturn(None)
+ nodes=[{'id': '11'}]).AndReturn(None)
tuskar.ResourceClass.list(
mox.IsA(http.HttpRequest)).AndReturn(
self.tuskar_resource_classes.list())
@@ -262,21 +262,21 @@ class RackViewTests(test.BaseAdminViewTests):
self.assertMessageCount(success=1)
self.assertMessageCount(error=0)
- @test.create_stubs({
- tuskar.Rack: ('get', 'list_nodes', 'list_flavors',
- 'get_resource_class')})
+ @test.create_stubs({tuskar.Rack: ('get', 'list_nodes', 'list_flavors'),
+ tuskar.ResourceClass: ('get',)})
def test_detail_rack(self):
rack = self.tuskar_racks.first()
+ rack.request = self.request
resource_class = self.tuskar_resource_classes.first()
tuskar.Rack.get(mox.IsA(http.HttpRequest),
rack.id).AndReturn(rack)
-
+ tuskar.ResourceClass.get(mox.IsA(http.HttpRequest),
+ resource_class.id).AndReturn(resource_class)
self.mox.ReplayAll()
tuskar.Rack.list_nodes = []
tuskar.Rack.list_flavors = []
- tuskar.Rack.get_resource_class = resource_class
url = urlresolvers.reverse('horizon:infrastructure:'
'resource_management:racks:detail',
diff --git a/tuskar_ui/infrastructure/resource_management/resource_classes/tests.py b/tuskar_ui/infrastructure/resource_management/resource_classes/tests.py
index 47d0b7c4..8ba274b7 100644
--- a/tuskar_ui/infrastructure/resource_management/resource_classes/tests.py
+++ b/tuskar_ui/infrastructure/resource_management/resource_classes/tests.py
@@ -297,7 +297,7 @@ class ResourceClassViewTests(test.BaseAdminViewTests):
'horizon:infrastructure:resource_management:index'))
@test.create_stubs({
- tuskar.ResourceClass: ('get', 'list_flavors', 'list_racks')
+ tuskar.ResourceClass: ('get', 'list_flavors', 'list_racks', 'nodes')
})
def test_detail_get(self):
resource_class = self.tuskar_resource_classes.first()
@@ -311,6 +311,7 @@ class ResourceClassViewTests(test.BaseAdminViewTests):
tuskar.ResourceClass.list_flavors = flavors
tuskar.ResourceClass.list_racks = racks
+ tuskar.ResourceClass.nodes = []
url = urlresolvers.reverse(
'horizon:infrastructure:resource_management:resource_classes:'
diff --git a/tuskar_ui/infrastructure/resource_management/resource_classes/workflows.py b/tuskar_ui/infrastructure/resource_management/resource_classes/workflows.py
index 04f01bfc..e018ff5b 100644
--- a/tuskar_ui/infrastructure/resource_management/resource_classes/workflows.py
+++ b/tuskar_ui/infrastructure/resource_management/resource_classes/workflows.py
@@ -154,10 +154,6 @@ class CreateRacks(tuskar_ui.workflows.TableStep):
'resource_classes/_racks_step.html'
def contribute(self, data, context):
- request = self.workflow.request
- context["racks_object_ids"] =\
- request.POST.getlist("racks_object_ids")
-
context.update(data)
return context
diff --git a/tuskar_ui/infrastructure/resource_management/tabs.py b/tuskar_ui/infrastructure/resource_management/tabs.py
index b42bbe3d..b418fc9e 100644
--- a/tuskar_ui/infrastructure/resource_management/tabs.py
+++ b/tuskar_ui/infrastructure/resource_management/tabs.py
@@ -85,7 +85,7 @@ class RacksTab(ProvisioningInfoMixin, tabs.TableTab):
def get_context_data(self, request):
context = super(RacksTab, self).get_context_data(request)
try:
- context["nodes"] = tuskar.Node.list_unracked(self.request)
+ context["nodes"] = tuskar.BaremetalNode.list_unracked(self.request)
except Exception:
context["nodes"] = []
exceptions.handle(request,
diff --git a/tuskar_ui/infrastructure/resource_management/templates/resource_management/nodes/_detail_overview.html b/tuskar_ui/infrastructure/resource_management/templates/resource_management/nodes/_detail_overview.html
index a6a4b9ae..e28c04a9 100644
--- a/tuskar_ui/infrastructure/resource_management/templates/resource_management/nodes/_detail_overview.html
+++ b/tuskar_ui/infrastructure/resource_management/templates/resource_management/nodes/_detail_overview.html
@@ -14,7 +14,7 @@
<dt>{% trans "Management IP" %}</dt>
<dd>{{ node.pm_address|default:_("None") }}</dd>
<dt>{% trans "Power Management" %}</dt>
- <dd>{{ node.rack.power_management|default:_("-") }}</dd>
+ <dd>{{ node.get_rack.power_management|default:_("-") }}</dd>
<dt>{% trans "Status" %}</dt>
<dd>{{ node.status|default:_("None") }}</dd>
</dl>
@@ -24,8 +24,8 @@
<hr class="header_rule">
<dl>
<dt>{% trans "Rack" %}</dt>
- {% if node.rack %}
- <dd><a href="{% url 'horizon:infrastructure:resource_management:racks:detail' node.rack.id %}">{{ node.rack.name|default:_("None") }}</a></dd>
+ {% if node.get_rack %}
+ <dd><a href="{% url 'horizon:infrastructure:resource_management:racks:detail' node.rack_id %}">{{ node.get_rack.name|default:_("None") }}</a></dd>
{% else %}
<dd>{% trans "None" %}</dd>
{% endif %}
@@ -170,7 +170,7 @@
<tr>
{% for flavor in node.list_flavors %}
<td class="flavor_usage_label">
- <a href="{% url 'horizon:infrastructure:resource_management:resource_classes:flavors:detail' node.rack.resource_class.id flavor.id %}">{{ flavor.name }}</a>
+ <a href="{% url 'horizon:infrastructure:resource_management:resource_classes:flavors:detail' node.get_rack.resource_class.id flavor.id %}">{{ flavor.name }}</a>
</td>
{% endfor %}
</tr>
@@ -234,7 +234,7 @@
<div id="most_contacting_racks"
class="communication_chart"
data-chart-type="circles_chart"
- data-url="{% url 'horizon:infrastructure:resource_management:racks:top_communicating' node.rack.id %}?cond=from"
+ data-url="{% url 'horizon:infrastructure:resource_management:racks:top_communicating' node.rack_id %}?cond=from"
data-time="now"
data-size="22">
</div>
diff --git a/tuskar_ui/infrastructure/resource_management/templates/resource_management/nodes/detail.html b/tuskar_ui/infrastructure/resource_management/templates/resource_management/nodes/detail.html
index efa0f280..6b9278f0 100644
--- a/tuskar_ui/infrastructure/resource_management/templates/resource_management/nodes/detail.html
+++ b/tuskar_ui/infrastructure/resource_management/templates/resource_management/nodes/detail.html
@@ -12,8 +12,8 @@
<span class="separator"></span>
<a href="{% url 'horizon:infrastructure:resource_management:index' %}?tab=resource_management_tabs__racks_tab" >Racks</a>
<span class="separator"></span>
- {% if node.rack %}
- <a href="{% url 'horizon:infrastructure:resource_management:racks:detail' node.rack.id %}">{{ node.rack.name }}</a>
+ {% if node.get_rack %}
+ <a href="{% url 'horizon:infrastructure:resource_management:racks:detail' node.rack_id %}">{{ node.get_rack.name }}</a>
{% else %}
<a href="{% url 'horizon:infrastructure:resource_management:nodes:unracked' %}" >Unracked Nodes</a>
{% endif %}
diff --git a/tuskar_ui/test/api_tests/tuskar_tests.py b/tuskar_ui/test/api_tests/tuskar_tests.py
index 627c316d..be098723 100644
--- a/tuskar_ui/test/api_tests/tuskar_tests.py
+++ b/tuskar_ui/test/api_tests/tuskar_tests.py
@@ -22,22 +22,6 @@ from tuskar_ui.test import helpers as test
class TuskarApiTests(test.APITestCase):
- def test_baremetal_node_get(self):
- node = self.baremetalclient_nodes.first()
-
- self.mox.StubOutWithMock(baremetal.BareMetalNodeManager, 'get')
- baremetal.BareMetalNodeManager.get(node.id).AndReturn(node)
-
- novaclient = self.stub_novaclient()
- novaclient.servers = self.mox.CreateMockAnything()
- novaclient.servers.list(True,
- {'all_tenants': True,
- 'limit': 21}).AndReturn([])
- self.mox.ReplayAll()
-
- ret_val = api.BaremetalNode.get(self.request, node.id)
- self.assertIsInstance(ret_val, api.BaremetalNode)
-
def test_baremetal_node_create(self):
node = self.baremetalclient_nodes.first()
@@ -63,7 +47,7 @@ class TuskarApiTests(test.APITestCase):
pm_user='user',
pm_password='password',
terminal_port=0)
- self.assertIsInstance(ret_val, api.Node)
+ self.assertIsInstance(ret_val, api.BaremetalNode)
def test_baremetal_node_create_with_empty_pm(self):
"""
@@ -82,7 +66,23 @@ class TuskarApiTests(test.APITestCase):
self.request, name='node', cpus=1,
memory_mb=1024, local_gb=10, prov_mac_address='aa:bb:cc:dd:ee',
pm_address='', pm_user='', pm_password='', terminal_port='')
- self.assertIsInstance(ret_val, api.Node)
+ self.assertIsInstance(ret_val, api.BaremetalNode)
+
+ def test_baremetal_node_get(self):
+ node = self.baremetalclient_nodes.first()
+
+ self.mox.StubOutWithMock(baremetal.BareMetalNodeManager, 'get')
+ baremetal.BareMetalNodeManager.get(node.id).AndReturn(node)
+
+ novaclient = self.stub_novaclient()
+ novaclient.servers = self.mox.CreateMockAnything()
+ novaclient.servers.list(True,
+ {'all_tenants': True,
+ 'limit': 21}).AndReturn([])
+ self.mox.ReplayAll()
+
+ ret_val = api.BaremetalNode.get(self.request, node.id)
+ self.assertIsInstance(ret_val, api.BaremetalNode)
def test_baremetal_node_list(self):
nodes = self.baremetalclient_nodes_all.list()
@@ -93,102 +93,105 @@ class TuskarApiTests(test.APITestCase):
ret_val = api.BaremetalNode.list(self.request)
for node in ret_val:
- self.assertIsInstance(node, api.Node)
+ self.assertIsInstance(node, api.BaremetalNode)
- def test_node_get(self):
- node = self.tuskarclient_nodes.first()
+ def test_baremetal_node_list_unracked(self):
+ tuskarclient_nodes = self.tuskarclient_nodes.list()
+ baremetal_nodes = self.baremetalclient_nodes_all.list()
- self.mox.StubOutWithMock(baremetal.BareMetalNodeManager, 'get')
- baremetal.BareMetalNodeManager.get(node.id).AndReturn(node)
+ tuskarclient = self.stub_tuskarclient()
+ tuskarclient.nodes = self.mox.CreateMockAnything()
+ tuskarclient.nodes.list().AndReturn(tuskarclient_nodes)
+
+ self.mox.StubOutWithMock(baremetal.BareMetalNodeManager, 'list')
+ baremetal.BareMetalNodeManager.list().AndReturn(baremetal_nodes)
- novaclient = self.stub_novaclient()
- novaclient.servers = self.mox.CreateMockAnything()
- novaclient.servers.list(True,
- {'all_tenants': True,
- 'limit': 21}).AndReturn([])
self.mox.ReplayAll()
- ret_val = api.Node.get(self.request, node.id)
- self.assertIsInstance(ret_val, api.Node)
+ ret_val = api.BaremetalNode.list_unracked(self.request)
+ for node in ret_val:
+ self.assertIsInstance(node, api.BaremetalNode)
+ self.assertEquals(1, len(ret_val))
+
+ def test_baremetal_node_running_instances(self):
+ node = self.baremetal_nodes.first()
+
+ self.assertEquals(4, node.running_instances)
+
+ def test_baremetal_node_remaining_capacity(self):
+ node = self.baremetal_nodes.first()
- def test_node_create(self):
+ self.assertEquals(96, node.remaining_capacity)
+
+ def test_node_get(self):
node = self.tuskarclient_nodes.first()
- self.mox.StubOutWithMock(baremetal.BareMetalNodeManager, 'create')
- baremetal.BareMetalNodeManager.create('node', 1, 1024, 10,
- 'aa:bb:cc:dd:ee', '0.0.0.0', 'user', 'password', 0).AndReturn(node)
+ tuskarclient = self.stub_tuskarclient()
+ tuskarclient.nodes = self.mox.CreateMockAnything()
+ tuskarclient.nodes.get(node.id).AndReturn(node)
self.mox.ReplayAll()
- ret_val = api.Node.create(self.request, name='node', cpus=1,
- memory_mb=1024, local_gb=10, prov_mac_address='aa:bb:cc:dd:ee',
- pm_address='0.0.0.0', pm_user='user', pm_password='password',
- terminal_port=0)
+ ret_val = api.Node.get(self.request, node.id)
self.assertIsInstance(ret_val, api.Node)
def test_node_list(self):
- nodes = self.tuskarclient_nodes_all.list()
+ nodes = self.tuskarclient_nodes.list()
- self.mox.StubOutWithMock(baremetal.BareMetalNodeManager, 'list')
- baremetal.BareMetalNodeManager.list().AndReturn(nodes)
+ tuskarclient = self.stub_tuskarclient()
+ tuskarclient.nodes = self.mox.CreateMockAnything()
+ tuskarclient.nodes.list().AndReturn(nodes)
self.mox.ReplayAll()
ret_val = api.Node.list(self.request)
for node in ret_val:
self.assertIsInstance(node, api.Node)
- def test_node_list_unracked(self):
- nodes = self.tuskarclient_nodes.list()
- all_nodes = self.tuskarclient_nodes_all.list()
- racks = self.tuskarclient_racks.list()
-
- self.mox.StubOutWithMock(baremetal.BareMetalNodeManager, 'list')
- baremetal.BareMetalNodeManager.list().AndReturn(all_nodes)
+ def test_node_rack(self):
+ node = self.tuskar_nodes.first()
+ rack = self.tuskarclient_racks.first()
tuskarclient = self.stub_tuskarclient()
tuskarclient.racks = self.mox.CreateMockAnything()
- tuskarclient.racks.list().MultipleTimes().AndReturn(racks)
+ tuskarclient.racks.get(rack.id).AndReturn(rack)
+ self.mox.ReplayAll()
+
+ node.request = self.request
+ self.assertIsInstance(node.get_rack, api.Rack)
+ self.assertEquals('1', node.rack_id)
+
+ def test_node_nova_baremetal_node(self):
+ node = self.tuskar_nodes.first()
+ bm_node = self.baremetalclient_nodes.first()
+
+ self.mox.StubOutWithMock(baremetal.BareMetalNodeManager, 'get')
+ baremetal.BareMetalNodeManager.get(
+ node.nova_baremetal_node_id).AndReturn(bm_node)
novaclient = self.stub_novaclient()
novaclient.servers = self.mox.CreateMockAnything()
novaclient.servers.list(True,
{'all_tenants': True,
- 'limit': 21}).MultipleTimes().AndReturn([])
-
- self.mox.StubOutWithMock(baremetal.BareMetalNodeManager, 'get')
- for n in nodes:
- baremetal.BareMetalNodeManager.get(n.id).\
- MultipleTimes().AndReturn(n)
+ 'limit': 21}).AndReturn([])
self.mox.ReplayAll()
- ret_val = api.Node.list_unracked(self.request)
- for node in ret_val:
- self.assertIsInstance(node, api.Node)
- self.assertEquals(1, len(ret_val))
+ node.request = self.request
+ n = node.nova_baremetal_node
+ self.assertIsInstance(n, api.BaremetalNode)
+ self.assertEquals('11', n.id)
def test_node_flavors(self):
node = self.tuskar_nodes.first()
- nodes = self.tuskarclient_nodes.list()
- racks = self.tuskarclient_racks.list()
+ rack = self.tuskarclient_racks.first()
rc = self.tuskarclient_resource_classes.first()
flavors = self.tuskarclient_flavors.list()
tuskarclient = self.stub_tuskarclient()
tuskarclient.racks = self.mox.CreateMockAnything()
- tuskarclient.racks.list().AndReturn(racks)
+ tuskarclient.racks.get(rack.id).AndReturn(rack)
tuskarclient.resource_classes = self.mox.CreateMockAnything()
tuskarclient.resource_classes.get(rc.id).AndReturn(rc)
tuskarclient.flavors = self.mox.CreateMockAnything()
tuskarclient.flavors.list(rc.id).AndReturn(flavors)
-
- novaclient = self.stub_novaclient()
- novaclient.servers = self.mox.CreateMockAnything()
- novaclient.servers.list(True,
- {'all_tenants': True,
- 'limit': 21}).MultipleTimes().AndReturn([])
-
- self.mox.StubOutWithMock(baremetal.BareMetalNodeManager, 'get')
- for n in nodes:
- baremetal.BareMetalNodeManager.get(n.id).AndReturn(n)
self.mox.ReplayAll()
node.request = self.request
@@ -197,64 +200,28 @@ class TuskarApiTests(test.APITestCase):
self.assertIsInstance(flavor, api.Flavor)
self.assertEquals(2, len(ret_val))
- def test_node_rack(self):
+ def test_node_is_provisioned(self):
node = self.tuskar_nodes.first()
- nodes = self.tuskarclient_nodes.list()
- racks = self.tuskarclient_racks.list()
+ node.request = self.request
+ bm_node = self.baremetalclient_nodes.first()
- tuskarclient = self.stub_tuskarclient()
- tuskarclient.racks = self.mox.CreateMockAnything()
- tuskarclient.racks.list().AndReturn(racks)
+ self.mox.StubOutWithMock(baremetal.BareMetalNodeManager, 'get')
+ baremetal.BareMetalNodeManager.get(
+ node.nova_baremetal_node_id).AndReturn(bm_node)
novaclient = self.stub_novaclient()
novaclient.servers = self.mox.CreateMockAnything()
novaclient.servers.list(True,
{'all_tenants': True,
- 'limit': 21}).MultipleTimes().AndReturn([])
-
- self.mox.StubOutWithMock(baremetal.BareMetalNodeManager, 'get')
- for n in nodes:
- baremetal.BareMetalNodeManager.get(n.id).AndReturn(n)
+ 'limit': 21}).AndReturn([])
self.mox.ReplayAll()
- node.request = self.request
- rack = node.rack
- self.assertIsInstance(rack, api.Rack)
- self.assertEquals('1', rack.id)
-
- def test_node_running_instances(self):
- node = self.tuskar_nodes.first()
-
- self.assertEquals(4, node.running_instances)
-
- def test_node_remaining_capacity(self):
- node = self.tuskar_nodes.first()
-
- self.assertEquals(96, node.remaining_capacity)
+ self.assertFalse(node.is_provisioned)
- def test_node_is_provisioned(self):
+ def test_node_alerts(self):
node = self.tuskar_nodes.first()
- nodes = self.tuskarclient_nodes.list()
- racks = self.tuskarclient_racks.list()
-
- tuskarclient = self.stub_tuskarclient()
- tuskarclient.racks = self.mox.CreateMockAnything()
- tuskarclient.racks.list().AndReturn(racks)
-
- novaclient = self.stub_novaclient()
- novaclient.servers = self.mox.CreateMockAnything()
- novaclient.servers.list(True,
- {'all_tenants': True,
- 'limit': 21}).MultipleTimes().AndReturn([])
-
- self.mox.StubOutWithMock(baremetal.BareMetalNodeManager, 'get')
- for n in nodes:
- baremetal.BareMetalNodeManager.get(n.id).AndReturn(n)
- self.mox.ReplayAll()
- node.request = self.request
- node.status = 'provisioned'
- self.assertTrue(node.is_provisioned)
+ self.assertEquals([], node.alerts)
def test_resource_class_list(self):
rcs = self.tuskarclient_resource_classes.list()
@@ -375,23 +342,11 @@ class TuskarApiTests(test.APITestCase):
def test_resource_class_nodes(self):
rc = self.tuskar_resource_classes.first()
- racks = self.tuskarclient_racks.list()
- nodes = self.baremetalclient_nodes.list()
+ nodes = self.tuskarclient_nodes.list()
tuskarclient = self.stub_tuskarclient()
- tuskarclient.racks = self.mox.CreateMockAnything()
- tuskarclient.racks.get('1').AndReturn(racks[0])
- tuskarclient.racks.get('2').AndReturn(racks[1])
-
- self.mox.StubOutWithMock(baremetal.BareMetalNodeManager, 'get')
- for n in nodes:
- baremetal.BareMetalNodeManager.get(n.id).AndReturn(n)
-
- novaclient = self.stub_novaclient()
- novaclient.servers = self.mox.CreateMockAnything()
- novaclient.servers.list(True,
- {'all_tenants': True,
- 'limit': 21}).MultipleTimes().AndReturn([])
+ tuskarclient.nodes = self.mox.CreateMockAnything()
+ tuskarclient.nodes.list().AndReturn(nodes)
self.mox.ReplayAll()
rc.request = self.request
@@ -478,6 +433,7 @@ class TuskarApiTests(test.APITestCase):
def test_resource_class_aggregated_alerts(self):
rc = self.tuskar_resource_classes.list()[0]
rc.request = self.request
+ nodes = self.tuskarclient_nodes.list()
tuskarclient = self.stub_tuskarclient()
tuskarclient.racks = self.mox.CreateMockAnything()
@@ -485,16 +441,9 @@ class TuskarApiTests(test.APITestCase):
tuskarclient.racks.get('1').AndReturn(racks[0])
tuskarclient.racks.get('2').AndReturn(racks[1])
- self.mox.StubOutWithMock(baremetal.BareMetalNodeManager, 'get')
- nodes = self.baremetalclient_nodes.list()
+ tuskarclient.nodes = self.mox.CreateMockAnything()
for n in nodes:
- baremetal.BareMetalNodeManager.get(n.id).AndReturn(n)
-
- novaclient = self.stub_novaclient()
- novaclient.servers = self.mox.CreateMockAnything()
- novaclient.servers.list(True,
- {'all_tenants': True,
- 'limit': 21}).MultipleTimes().AndReturn([])
+ tuskarclient.nodes.get(n.id).AndReturn(n)
self.mox.ReplayAll()
@@ -571,17 +520,12 @@ class TuskarApiTests(test.APITestCase):
def test_rack_nodes(self):
rack = self.tuskar_racks.first()
- nodes = self.baremetalclient_nodes.list()
+ nodes = self.tuskarclient_nodes.list()
- self.mox.StubOutWithMock(baremetal.BareMetalNodeManager, 'get')
+ tuskarclient = self.stub_tuskarclient()
+ tuskarclient.nodes = self.mox.CreateMockAnything()
for n in nodes:
- baremetal.BareMetalNodeManager.get(n.id).AndReturn(n)
-
- novaclient = self.stub_novaclient()
- novaclient.servers = self.mox.CreateMockAnything()
- novaclient.servers.list(True,
- {'all_tenants': True,
- 'limit': 21}).MultipleTimes().AndReturn([])
+ tuskarclient.nodes.get(n.id).AndReturn(n)
self.mox.ReplayAll()
rack.request = self.request
@@ -695,18 +639,12 @@ class TuskarApiTests(test.APITestCase):
def test_rack_aggregated_alerts(self):
rack = self.tuskar_racks.first()
rack.request = self.request
+ nodes = self.tuskarclient_nodes.list()
- self.mox.StubOutWithMock(baremetal.BareMetalNodeManager, 'get')
- nodes = self.baremetalclient_nodes.list()
+ tuskarclient = self.stub_tuskarclient()
+ tuskarclient.nodes = self.mox.CreateMockAnything()
for n in nodes:
- baremetal.BareMetalNodeManager.get(n.id).AndReturn(n)
-
- novaclient = self.stub_novaclient()
- novaclient.servers = self.mox.CreateMockAnything()
- novaclient.servers.list(True,
- {'all_tenants': True,
- 'limit': 21}).MultipleTimes().AndReturn([])
-
+ tuskarclient.nodes.get(n.id).AndReturn(n)
self.mox.ReplayAll()
for node in rack.aggregated_alerts:
diff --git a/tuskar_ui/test/test_data/tuskar_data.py b/tuskar_ui/test/test_data/tuskar_data.py
index 68b71fca..39d6c23a 100644
--- a/tuskar_ui/test/test_data/tuskar_data.py
+++ b/tuskar_ui/test/test_data/tuskar_data.py
@@ -16,6 +16,7 @@ from openstack_dashboard.test.test_data import utils as test_data_utils
from novaclient.v1_1.contrib import baremetal
from tuskarclient.v1 import flavors
+from tuskarclient.v1 import nodes
from tuskarclient.v1 import racks
from tuskarclient.v1 import resource_classes
@@ -129,42 +130,36 @@ def data(TEST):
# Nodes
TEST.tuskarclient_nodes = test_data_utils.TestDataContainer()
TEST.tuskar_nodes = test_data_utils.TestDataContainer()
- # FIXME this will be removed once Node/BaremetalNode separation is complete
- TEST.tuskarclient_nodes_all = test_data_utils.TestDataContainer()
- tuskar_node_1 = baremetal.BareMetalNode(
- baremetal.BareMetalNodeManager(None),
+ tuskar_node_1 = nodes.Node(
+ nodes.NodeManager(None),
{'id': '1',
- 'name': 'node1',
- 'prov_mac_address': '00-B0-D0-86-AB-F7'})
- tuskar_node_2 = baremetal.BareMetalNode(
- baremetal.BareMetalNodeManager(None),
+ 'nova_baremetal_node_id': '11',
+ 'rack': {"id": "1"}})
+ tuskar_node_2 = nodes.Node(
+ nodes.NodeManager(None),
{'id': '2',
- 'name': 'node2',
- 'prov_mac_address': '00-B0-D0-86-AB-F8'})
- tuskar_node_3 = baremetal.BareMetalNode(
- baremetal.BareMetalNodeManager(None),
+ 'nova_baremetal_node_id': '12',
+ 'rack': {"id": "1"}})
+ tuskar_node_3 = nodes.Node(
+ nodes.NodeManager(None),
{'id': '3',
- 'name': 'node3',
- 'prov_mac_address': '00-B0-D0-86-AB-F9'})
- tuskar_node_4 = baremetal.BareMetalNode(
- baremetal.BareMetalNodeManager(None),
+ 'nova_baremetal_node_id': '13',
+ 'rack': {"id": "1"}})
+ tuskar_node_4 = nodes.Node(
+ nodes.NodeManager(None),
{'id': '4',
- 'name': 'node4',
- 'prov_mac_address': '00-B0-D0-86-AB-F0'})
- tuskar_node_5 = baremetal.BareMetalNode(
- baremetal.BareMetalNodeManager(None),
- {'id': '5',
- 'name': 'node5',
- 'prov_mac_address': '00-B0-D0-86-AB-F1'})
+ 'nova_baremetal_node_id': '14',
+ 'rack': {"id": "1"}})
- TEST.tuskarclient_nodes.add(tuskar_node_1, tuskar_node_2,
- tuskar_node_3, tuskar_node_4)
- TEST.tuskarclient_nodes_all.add(tuskar_node_1, tuskar_node_2,
- tuskar_node_3, tuskar_node_4,
- tuskar_node_5)
- TEST.tuskar_nodes.add(api.Node(tuskar_node_1), api.Node(tuskar_node_2),
- api.Node(tuskar_node_3), api.Node(tuskar_node_4))
+ TEST.tuskarclient_nodes.add(tuskar_node_1,
+ tuskar_node_2,
+ tuskar_node_3,
+ tuskar_node_4)
+ TEST.tuskar_nodes.add(api.Node(tuskar_node_1),
+ api.Node(tuskar_node_2),
+ api.Node(tuskar_node_3),
+ api.Node(tuskar_node_4))
TEST.baremetalclient_nodes = test_data_utils.TestDataContainer()
TEST.baremetal_nodes = test_data_utils.TestDataContainer()
@@ -175,27 +170,27 @@ def data(TEST):
node_1 = baremetal.BareMetalNode(
baremetal.BareMetalNodeManager(None),
- {'id': '1',
+ {'id': '11',
'name': 'node1',
'prov_mac_address': '00-B0-D0-86-AB-F7'})
node_2 = baremetal.BareMetalNode(
baremetal.BareMetalNodeManager(None),
- {'id': '2',
+ {'id': '12',
'name': 'node2',
'prov_mac_address': '00-B0-D0-86-AB-F8'})
node_3 = baremetal.BareMetalNode(
baremetal.BareMetalNodeManager(None),
- {'id': '3',
+ {'id': '13',
'name': 'node3',
'prov_mac_address': '00-B0-D0-86-AB-F9'})
node_4 = baremetal.BareMetalNode(
baremetal.BareMetalNodeManager(None),
- {'id': '4',
+ {'id': '14',
'name': 'node4',
'prov_mac_address': '00-B0-D0-86-AB-F0'})
node_5 = baremetal.BareMetalNode(
baremetal.BareMetalNodeManager(None),
- {'id': '5',
+ {'id': '15',
'name': 'node5',
'prov_mac_address': '00-B0-D0-86-AB-F1'})