Cleanup ironic-ui REST API

Improvements include:
- Update the delete node/port endpoints to make them more RESTy and consistent with
the underlying Ironic web API
- Update the endpoint for retrieving the ports associated with a node
- Improve consistency of the code documentation.

Change-Id: I79165c75844dbc15ffd12536ba0e6edea532cd22
This commit is contained in:
Peter Piela 2017-09-01 15:40:28 -04:00
parent c5e47e36ff
commit 47c6cee5a8
3 changed files with 138 additions and 137 deletions

View File

@ -36,7 +36,7 @@ class Nodes(generic.View):
"""Get the list of nodes.
:param request: HTTP request.
:return: nodes.
:return: List of nodes.
"""
nodes = ironic.node_list(request)
return {
@ -45,22 +45,13 @@ class Nodes(generic.View):
@rest_utils.ajax(data_required=True)
def post(self, request):
"""Create an Ironic node
"""Create an Ironic node.
:param request: HTTP request
:param request: HTTP request.
"""
params = request.DATA.get('node')
return ironic.node_create(request, params)
@rest_utils.ajax(data_required=True)
def delete(self, request):
"""Delete an Ironic node from inventory
:param request: HTTP request
"""
params = request.DATA.get('node')
return ironic.node_delete(request, params)
@urls.register
class Node(generic.View):
@ -69,77 +60,73 @@ class Node(generic.View):
@rest_utils.ajax()
def get(self, request, node_id):
"""Get information on a specific node.
"""Get information on a specified node.
:param request: HTTP request.
:param node_id: Node id.
:param node_id: Node name or uuid.
:return: node.
"""
return ironic.node_get(request, node_id).to_dict()
@rest_utils.ajax(data_required=True)
def patch(self, request, node_id):
"""Update an Ironic node
"""Update an Ironic node.
:param request: HTTP request
:param node_uuid: Node uuid.
:param request: HTTP request.
:param node_id: Node name or uuid.
"""
patch = request.DATA.get('patch')
return ironic.node_update(request, node_id, patch)
@rest_utils.ajax()
def delete(self, request, node_id):
"""Delete an Ironic node from inventory
:param request: HTTP request.
:param node_id: Node name or uuid.
"""
return ironic.node_delete(request, node_id)
@urls.register
class Ports(generic.View):
url_regex = r'ironic/ports/$'
@rest_utils.ajax()
def get(self, request):
"""Get the list of ports associated with a specified node.
:param request: HTTP request
:return: List of ports.
"""
node_id = request.GET.get('node_id')
ports = ironic.node_list_ports(request, node_id)
return {
'ports': [i.to_dict() for i in ports]
}
@rest_utils.ajax(data_required=True)
def post(self, request):
"""Create a network port
"""Create a network port.
:param request: HTTP request
:param request: HTTP request.
:return: Port
"""
port = request.DATA.get('port')
return ironic.port_create(request, port).to_dict()
@rest_utils.ajax(data_required=True)
def delete(self, request):
"""Delete a network port
:param request: HTTP request
"""
params = request.DATA.get('port_uuid')
return ironic.port_delete(request, params)
@urls.register
class Port(generic.View):
url_regex = r'ironic/ports/(?P<port_id>[0-9a-f-]+)$'
url_regex = r'ironic/ports/(?P<port_uuid>[0-9a-f-]+)$'
@rest_utils.ajax(data_required=True)
def patch(self, request, port_id):
"""Update an Ironic port
def patch(self, request, port_uuid):
"""Update an Ironic port.
:param request: HTTP request
:param port_id: Port id.
:param request: HTTP request.
:param port_uuid: Port uuid.
"""
patch = request.DATA.get('patch')
return ironic.port_update(request, port_id, patch)
return ironic.port_update(request, port_uuid, patch)
@rest_utils.ajax()
def delete(self, request, port_uuid):
"""Delete a network port.
:param request: HTTP request
:param port_uuid: Port uuid.
"""
return ironic.port_delete(request, port_uuid)
@urls.register
@ -153,8 +140,8 @@ class StatesPower(generic.View):
"""Set the power state for a specified node.
:param request: HTTP request.
:param node_id: Node name or uuid
:return: Return code
:param node_id: Node name or uuid.
:return: Return code.
"""
return ironic.node_set_power_state(request,
node_id,
@ -165,21 +152,21 @@ class StatesPower(generic.View):
@urls.register
class StatesProvision(generic.View):
url_regex = r'ironic/nodes/(?P<node_uuid>{})/states/provision$'. \
url_regex = r'ironic/nodes/(?P<node_id>{})/states/provision$'. \
format(LOGICAL_NAME_PATTERN)
@rest_utils.ajax(data_required=True)
def put(self, request, node_uuid):
def put(self, request, node_id):
"""Set the provision state for a specified node.
:param request: HTTP request.
:param node_id: Node uuid
:return: Return code
:param node_id: Node name or uuid.
:return: Return code.
"""
verb = request.DATA.get('verb')
clean_steps = request.DATA.get('clean_steps')
return ironic.node_set_provision_state(request,
node_uuid,
node_id,
verb,
clean_steps)
@ -187,29 +174,29 @@ class StatesProvision(generic.View):
@urls.register
class StatesConsole(generic.View):
url_regex = r'ironic/nodes/(?P<node_uuid>{})/states/console$'. \
url_regex = r'ironic/nodes/(?P<node_id>{})/states/console$'. \
format(LOGICAL_NAME_PATTERN)
@rest_utils.ajax()
def get(self, request, node_uuid):
def get(self, request, node_id):
"""Get connection information for the node's console
:param request: HTTP request.
:param node_id: Node uuid
:return: Connection information
:param node_id: Node name or uuid.
:return: Connection information.
"""
return ironic.node_get_console(request, node_uuid)
return ironic.node_get_console(request, node_id)
@rest_utils.ajax(data_required=True)
def put(self, request, node_uuid):
def put(self, request, node_id):
"""Start or stop the serial console.
:param request: HTTP request.
:param node_id: Node uuid
:return: Return code
:param node_id: Node name or uuid.
:return: Return code.
"""
return ironic.node_set_console_mode(request,
node_uuid,
node_id,
request.DATA.get('enabled'))
@ -224,8 +211,8 @@ class Maintenance(generic.View):
"""Put a specified node into maintenance state
:param request: HTTP request.
:param node_id: Node name or uuid
:return: Return code
:param node_id: Node name or uuid.
:return: Return code.
"""
maint_reason = request.DATA.get('maint_reason')
return ironic.node_set_maintenance(
@ -239,8 +226,8 @@ class Maintenance(generic.View):
"""Take a specified node out of the maintenance state
:param request: HTTP request.
:param node_id: Node name or uuid
:return: Return code
:param node_id: Node name or uuid.
:return: Return code.
"""
return ironic.node_set_maintenance(request, node_id, 'off')
@ -256,8 +243,8 @@ class Validate(generic.View):
"""Validate a specified node
:param request: HTTP request.
:param node_id: Node name or uuid
:return: List of dictionaries of interface statuses
:param node_id: Node name or uuid.
:return: List of dictionaries of interface statuses.
"""
return ironic.node_validate(request, node_id)
@ -273,8 +260,8 @@ class BootDevice(generic.View):
"""Get the boot device for a specified node
:param request: HTTP request.
:param node_id: Node name or uuid
:return: Dictionary with keys "boot_device" and "persistent"
:param node_id: Node name or uuid.
:return: Dictionary with keys "boot_device" and "persistent".
"""
return ironic.node_get_boot_device(request, node_id)
@ -283,7 +270,7 @@ class BootDevice(generic.View):
"""Set the boot device for a specific node
:param request: HTTP request.
:param node_id: Node name or uuid
:param node_id: Node name or uuid.
:return: null.
"""
return ironic.node_set_boot_device(
@ -301,11 +288,11 @@ class SupportedBootDevices(generic.View):
@rest_utils.ajax()
def get(self, request, node_id):
"""Get the list of supported boot devices for a specified node
"""Get the list of supported boot devices for a specified node.
:param request: HTTP request.
:param node_id: Node name or uuid
:return: List of supported boot devices
:param node_id: Node name or uuid.
:return: List of supported boot devices.
"""
return ironic.node_get_supported_boot_devices(request, node_id)
@ -317,10 +304,10 @@ class Drivers(generic.View):
@rest_utils.ajax()
def get(self, request):
"""Get the list of drivers
"""Get the list of drivers.
:param request: HTTP request
:return: drivers
:param request: HTTP request.
:return: List of drivers.
"""
drivers = ironic.driver_list(request)
return {
@ -337,9 +324,9 @@ class DriverProperties(generic.View):
def get(self, request, driver_name):
"""Get the properties associated with a specified driver
:param request: HTTP request
:param driver_name: Driver name
:return: Dictionary of properties
:param request: HTTP request.
:param driver_name: Driver name.
:return: Dictionary of properties.
"""
return ironic.driver_properties(request, driver_name)
@ -359,6 +346,26 @@ class Portgroups(generic.View):
return ironic.portgroup_create(request, request.DATA).to_dict()
@urls.register
class NodePorts(generic.View):
url_regex = r'ironic/nodes/(?P<node_id>{})/ports/detail$' . \
format(LOGICAL_NAME_PATTERN)
@rest_utils.ajax()
def get(self, request, node_id):
"""Get the list of ports associated with a specified node.
:param request: HTTP request.
:param node_id: Node name or uuid.
:return: List of ports.
"""
ports = ironic.node_list_ports(request, node_id)
return {
'ports': [i.to_dict() for i in ports]
}
@urls.register
class NodePortgroups(generic.View):
@ -370,7 +377,7 @@ class NodePortgroups(generic.View):
"""Get the list of portgroups associated with a specified node.
:param request: HTTP request.
:param node_id: Node name or uuid
:param node_id: Node name or uuid.
:return: List of portgroups.
"""
portgroups = ironic.portgroup_list(request, node_id)
@ -387,9 +394,9 @@ class Portgroup(generic.View):
@rest_utils.ajax(data_required=True)
def patch(self, request, portgroup_id):
"""Update an Ironic portgroup
"""Update an Ironic portgroup.
:param request: HTTP request
:param request: HTTP request.
:param portgroup_id: UUID or name of portgroup.
"""
patch = request.DATA.get('patch')

View File

@ -404,9 +404,11 @@
});
// Delete node
$httpBackend.whenDELETE(/\/api\/ironic\/nodes\/$/)
.respond(function(method, url, data) {
var nodeId = JSON.parse(data).node;
$httpBackend.whenDELETE(/\/api\/ironic\/nodes\/([^\/]+)$/,
undefined,
['nodeId'])
.respond(function(method, url, data, headers, params) {
var nodeId = params.nodeId;
var status = responseCode.RESOURCE_NOT_FOUND;
if (angular.isDefined(nodes[nodeId])) {
var node = nodes[nodeId].base;
@ -623,9 +625,11 @@
});
// Delete port
$httpBackend.whenDELETE(/\/api\/ironic\/ports\/$/)
.respond(function(method, url, data) {
var portUuid = JSON.parse(data).port_uuid;
$httpBackend.whenDELETE(/\/api\/ironic\/ports\/([^\/]+)$/,
undefined,
['portUuid'])
.respond(function(method, url, data, headers, params) {
var portUuid = params.portUuid;
var status = responseCode.RESOURCE_NOT_FOUND;
if (angular.isDefined(ports[portUuid])) {
delete ports[portUuid];
@ -638,10 +642,10 @@
$httpBackend.whenPATCH(/\/api\/ironic\/ports\/([^\/]+)$/,
undefined,
undefined,
['portId'])
['portUuid'])
.respond(function(method, url, data, headers, params) {
var status = responseCode.RESOURCE_NOT_FOUND;
var port = service.getPort(params.portId);
var port = service.getPort(params.portUuid);
if (angular.isDefined(port)) {
patchObject(port, JSON.parse(data).patch);
status = responseCode.SUCCESS;
@ -649,10 +653,12 @@
return [status, port];
});
// Get ports
$httpBackend.whenGET(/\/api\/ironic\/ports\//)
// Get the ports associated with a node
$httpBackend.whenGET(/\/api\/ironic\/nodes\/([^\/]+)\/ports\/detail$/,
undefined,
['nodeId'])
.respond(function(method, url, data, header, params) {
var nodeId = params.node_id;
var nodeId = params.nodeId;
var status = responseCode.RESOURCE_NOT_FOUND;
var ports = [];
if (angular.isDefined(nodes[nodeId])) {
@ -672,7 +678,6 @@
// Get the portgroups associated with a node
$httpBackend.whenGET(/\/api\/ironic\/nodes\/(.+)\/portgroups/,
undefined,
undefined,
['nodeId'])
.respond(function(method, url, data, header, params) {

View File

@ -101,11 +101,11 @@
* http://developer.openstack.org/api-ref/baremetal/?
* expanded=create-node-detail#list-nodes-detailed
*
* @param {string} uuid UUID or logical name of a node.
* @param {string} nodeId UUID or logical name of a node.
* @return {promise} Node
*/
function getNode(uuid) {
return apiService.get('/api/ironic/nodes/' + uuid)
function getNode(nodeId) {
return apiService.get('/api/ironic/nodes/' + nodeId)
.then(function(response) {
nodeErrorService.checkNodeError(response.data);
return response.data; // The node
@ -171,16 +171,11 @@
*
* http://developer.openstack.org/api-ref/baremetal/#list-detailed-ports
*
* @param {string} uuid UUID or logical name of a node.
* @param {string} nodeId UUID or logical name of a node.
* @return {promise} List of ports
*/
function getPortsWithNode(uuid) {
var config = {
params : {
node_id: uuid
}
};
return apiService.get('/api/ironic/ports/', config)
function getPortsWithNode(nodeId) {
return apiService.get('/api/ironic/nodes/' + nodeId + '/ports/detail')
.then(function(response) {
// Add id and name properties to support delete operations
// using the deleteModalService
@ -261,19 +256,19 @@
*
* http://developer.openstack.org/api-ref/baremetal/#change-node-power-state
*
* @param {string} uuid UUID or logical name of a node.
* @param {string} nodeId UUID or logical name of a node.
* @param {string} state - Target power state ['on', 'off', 'reboot']
* @param {boolean} soft - Flag for graceful power 'off' or reboot
* @return {promise} Promise
*/
function nodeSetPowerState(uuid, state, soft) {
function nodeSetPowerState(nodeId, state, soft) {
var data = {
state: state
};
if (angular.isDefined(soft)) {
data.soft = soft;
}
return apiService.patch('/api/ironic/nodes/' + uuid + '/states/power',
return apiService.patch('/api/ironic/nodes/' + nodeId + '/states/power',
data)
.then(function() {
toastService.add('success',
@ -293,21 +288,21 @@
*
* http://developer.openstack.org/api-ref/baremetal/#change-node-provision-state
*
* @param {string} uuid UUID of a node.
* @param {string} nodeId UUID of a node.
* @param {string} verb Provisioning verb used to move node to desired
* target state
* @param {object []} cleanSteps - List of cleaning steps. Only used
* when the value of verb is 'clean'
* @return {promise} Promise
*/
function setNodeProvisionState(uuid, verb, cleanSteps) {
return apiService.put('/api/ironic/nodes/' + uuid + '/states/provision',
function setNodeProvisionState(nodeId, verb, cleanSteps) {
return apiService.put('/api/ironic/nodes/' + nodeId + '/states/provision',
{verb: verb,
clean_steps: cleanSteps})
.then(function() {
var msg = gettext(
'A request has been made to change the provisioning state of node %s');
toastService.add('success', interpolate(msg, [uuid], false));
toastService.add('success', interpolate(msg, [nodeId], false));
})
.catch(function(response) {
var msg = interpolate(
@ -347,17 +342,14 @@
*
* http://developer.openstack.org/api-ref/baremetal/#delete-node
*
* @param {string} nodeIdent UUID or logical name of a node.
* @param {string} nodeId UUID or logical name of a node.
* @return {promise} Promise
*/
function deleteNode(nodeIdent) {
var data = {
node: nodeIdent
};
return apiService.delete('/api/ironic/nodes/', data)
function deleteNode(nodeId) {
return apiService.delete('/api/ironic/nodes/' + nodeId)
.catch(function(response) {
var msg = interpolate(gettext('Unable to delete node %s: %s'),
[nodeIdent, response.data],
[nodeId, response.data],
false);
toastService.add('error', msg);
return $q.reject(msg);
@ -369,23 +361,23 @@
*
* http://developer.openstack.org/api-ref/baremetal/#update-node
*
* @param {string} uuid UUID of a node.
* @param {string} nodeId UUID or logical name of a node.
* @param {object[]} patch Sequence of update operations
* @return {promise} Promise
*/
function updateNode(uuid, patch) {
function updateNode(nodeId, patch) {
var data = {
patch: patch
};
return apiService.patch('/api/ironic/nodes/' + uuid, data)
return apiService.patch('/api/ironic/nodes/' + nodeId, data)
.then(function(response) {
var msg = gettext('Successfully updated node %s');
toastService.add('success', interpolate(msg, [uuid], false));
toastService.add('success', interpolate(msg, [nodeId], false));
return response.data; // The updated node
})
.catch(function(response) {
var msg = interpolate(gettext('Unable to update node %s: %s'),
[uuid, response.data],
[nodeId, response.data],
false);
toastService.add('error', msg);
return $q.reject(msg);
@ -496,10 +488,7 @@
* @return {promise} Promise
*/
function deletePort(portUuid) {
var data = {
port_uuid: portUuid
};
return apiService.delete('/api/ironic/ports/', data)
return apiService.delete('/api/ironic/ports/' + portUuid)
.catch(function(response) {
var msg = interpolate(gettext('Unable to delete port: %s'),
[response.data],
@ -541,16 +530,16 @@
* http://developer.openstack.org/api-ref/baremetal/?
* expanded=start-stop-console-detail#start-stop-console
*
* @param {string} uuid UUID of a node.
* @param {string} nodeId UUID or logical name of a node.
* @param {boolean} enabled true to start the console, false to stop it
* @return {promise} Promise
*/
function nodeSetConsoleMode(uuid, enabled) {
return apiService.put('/api/ironic/nodes/' + uuid + '/states/console',
function nodeSetConsoleMode(nodeId, enabled) {
return apiService.put('/api/ironic/nodes/' + nodeId + '/states/console',
{enabled: enabled})
.then(function(response) {
var msg = gettext('Refresh page to see updated console details');
toastService.add('success', interpolate(msg, [uuid], false));
toastService.add('success', interpolate(msg, [nodeId], false));
return response.data;
})
.catch(function(response) {
@ -560,15 +549,15 @@
});
}
function nodeGetConsole(uuid) {
return apiService.get('/api/ironic/nodes/' + uuid + '/states/console')
function nodeGetConsole(nodeId) {
return apiService.get('/api/ironic/nodes/' + nodeId + '/states/console')
.then(function(response) {
return response.data; // Object containing console information
})
.catch(function(response) {
var msg = gettext('Unable to get console for node %s: %s');
toastService.add('error',
interpolate(msg, [uuid, response.data], false));
interpolate(msg, [nodeId, response.data], false));
return $q.reject(msg);
});
}