Add node list support
This adds support for listing node names from resource providers, which will only available for admins. Partially Implements: bp node-aggregate Change-Id: I414bf176302fc076288e6a6fbfd88a7090541622
This commit is contained in:
parent
9627106519
commit
8a8dc20660
32
api-ref/source/v1/nodes.inc
Normal file
32
api-ref/source/v1/nodes.inc
Normal file
@ -0,0 +1,32 @@
|
||||
.. -*- rst -*-
|
||||
|
||||
===============
|
||||
Compute Nodes
|
||||
===============
|
||||
|
||||
Lists compute nodes.
|
||||
|
||||
List Compute Node information
|
||||
=============================
|
||||
|
||||
.. rest_method:: GET /nodes
|
||||
|
||||
Lists compute nodes, including name.
|
||||
|
||||
Normal response codes: 200
|
||||
|
||||
Error response codes: unauthorized(401), forbidden(403)
|
||||
|
||||
Response
|
||||
--------
|
||||
|
||||
.. rest_parameters:: parameters.yaml
|
||||
|
||||
- nodes: nodes
|
||||
|
||||
|
|
||||
|
||||
**Example List compute node information**
|
||||
|
||||
.. literalinclude:: samples/nodes/node-list-resp.json
|
||||
:language: javascript
|
@ -435,6 +435,12 @@ nics:
|
||||
in: body
|
||||
required: true
|
||||
type: dict
|
||||
nodes:
|
||||
description: |
|
||||
The compute node name list.
|
||||
in: body
|
||||
required: true
|
||||
type: dict
|
||||
personality:
|
||||
description: |
|
||||
The file path and contents, text only, to inject into the server at launch. The
|
||||
|
7
api-ref/source/v1/samples/nodes/node-list-resp.json
Normal file
7
api-ref/source/v1/samples/nodes/node-list-resp.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"nodes" : [
|
||||
"node-0",
|
||||
"node-1",
|
||||
"node-2"
|
||||
]
|
||||
}
|
@ -29,6 +29,7 @@ from mogan.api.controllers.v1 import aggregates
|
||||
from mogan.api.controllers.v1 import availability_zone
|
||||
from mogan.api.controllers.v1 import flavors
|
||||
from mogan.api.controllers.v1 import keypairs
|
||||
from mogan.api.controllers.v1 import nodes
|
||||
from mogan.api.controllers.v1 import servers
|
||||
from mogan.api import expose
|
||||
|
||||
@ -54,6 +55,9 @@ class V1(base.APIBase):
|
||||
aggregates = [link.Link]
|
||||
"""Links to the aggregates resource"""
|
||||
|
||||
nodes = [link.Link]
|
||||
"""Links to the nodes resource"""
|
||||
|
||||
@staticmethod
|
||||
def convert():
|
||||
v1 = V1()
|
||||
@ -96,6 +100,14 @@ class V1(base.APIBase):
|
||||
'aggregates', '',
|
||||
bookmark=True)
|
||||
]
|
||||
v1.nodes = [link.Link.make_link('self',
|
||||
pecan.request.public_url,
|
||||
'nodes', ''),
|
||||
link.Link.make_link('bookmark',
|
||||
pecan.request.public_url,
|
||||
'nodes', '',
|
||||
bookmark=True)
|
||||
]
|
||||
return v1
|
||||
|
||||
|
||||
@ -107,6 +119,7 @@ class Controller(rest.RestController):
|
||||
availability_zones = availability_zone.AvailabilityZoneController()
|
||||
keypairs = keypairs.KeyPairController()
|
||||
aggregates = aggregates.AggregateController()
|
||||
nodes = nodes.NodeController()
|
||||
|
||||
@expose.expose(V1)
|
||||
def get(self):
|
||||
|
46
mogan/api/controllers/v1/nodes.py
Normal file
46
mogan/api/controllers/v1/nodes.py
Normal file
@ -0,0 +1,46 @@
|
||||
# Copyright 2017 Huawei Technologies Co.,LTD.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import pecan
|
||||
from pecan import rest
|
||||
from wsme import types as wtypes
|
||||
|
||||
from mogan.api.controllers import base
|
||||
from mogan.api import expose
|
||||
from mogan.common import policy
|
||||
|
||||
|
||||
class Nodes(base.APIBase):
|
||||
"""API representation of a collection of nodes."""
|
||||
|
||||
nodes = [wtypes.text]
|
||||
"""A list containing compute node names"""
|
||||
|
||||
|
||||
class NodeController(rest.RestController):
|
||||
"""REST controller for Node."""
|
||||
|
||||
@policy.authorize_wsgi("mogan:node", "get_all",
|
||||
need_target=False)
|
||||
@expose.expose(Nodes)
|
||||
def get_all(self):
|
||||
"""Retrieve a list of nodes."""
|
||||
|
||||
nodes = pecan.request.engine_api.list_compute_nodes(
|
||||
pecan.request.context)
|
||||
|
||||
collection = Nodes()
|
||||
collection.nodes = nodes['nodes']
|
||||
return collection
|
@ -159,6 +159,9 @@ server_policies = [
|
||||
policy.RuleDefault('mogan:aggregate:get_one',
|
||||
'rule:admin_api',
|
||||
description='Show aggregate details'),
|
||||
policy.RuleDefault('mogan:node:get_all',
|
||||
'rule:admin_api',
|
||||
description='Get the nodes list'),
|
||||
]
|
||||
|
||||
|
||||
|
@ -516,3 +516,7 @@ class API(object):
|
||||
def detach_interface(self, context, server, port_id):
|
||||
self.engine_rpcapi.detach_interface(context, server=server,
|
||||
port_id=port_id)
|
||||
|
||||
def list_compute_nodes(self, context):
|
||||
"""Get compute node list."""
|
||||
return self.engine_rpcapi.list_compute_nodes(context)
|
||||
|
@ -580,3 +580,8 @@ class EngineManager(base_manager.BaseEngineManager):
|
||||
nic.delete(context)
|
||||
|
||||
LOG.info('Interface was successfully detached')
|
||||
|
||||
def list_compute_nodes(self, context):
|
||||
nodes = self.scheduler_client.reportclient \
|
||||
.get_nodes_from_resource_providers()
|
||||
return nodes
|
||||
|
@ -92,3 +92,7 @@ class EngineAPI(object):
|
||||
cctxt = self.client.prepare(topic=self.topic, server=CONF.host)
|
||||
cctxt.call(context, 'detach_interface', server=server,
|
||||
port_id=port_id)
|
||||
|
||||
def list_compute_nodes(self, context):
|
||||
cctxt = self.client.prepare(topic=self.topic, server=CONF.host)
|
||||
return cctxt.call(context, 'list_compute_nodes')
|
||||
|
@ -709,3 +709,8 @@ class SchedulerReportClient(object):
|
||||
LOG.info('Deleted allocation for resource provider %s', rp_uuid)
|
||||
for consumer_id in allocations:
|
||||
self.delete_allocation_for_server(consumer_id)
|
||||
|
||||
def get_nodes_from_resource_providers(self):
|
||||
# Use the rps we cached
|
||||
rps = self._resource_providers
|
||||
return {'nodes': [rp['name'] for id, rp in rps.items()]}
|
||||
|
30
mogan/tests/functional/api/v1/test_nodes.py
Normal file
30
mogan/tests/functional/api/v1/test_nodes.py
Normal file
@ -0,0 +1,30 @@
|
||||
# Copyright 2017 Huawei Technologies Co., Ltd.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import mock
|
||||
|
||||
from mogan.tests.functional.api import v1 as v1_test
|
||||
|
||||
|
||||
class TestNode(v1_test.APITestV1):
|
||||
|
||||
def setUp(self):
|
||||
super(TestNode, self).setUp()
|
||||
|
||||
@mock.patch('mogan.engine.rpcapi.EngineAPI.list_compute_nodes')
|
||||
def test_node_get_all(self, get_nodes):
|
||||
get_nodes.return_value = {'nodes': ['node-0', 'node-1']}
|
||||
headers = self.gen_headers(self.context, roles="admin")
|
||||
resp = self.get_json('/nodes', headers=headers)
|
||||
self.assertItemsEqual(['node-0', 'node-1'], resp['nodes'])
|
29
mogan/tests/tempest/api/test_nodes.py
Normal file
29
mogan/tests/tempest/api/test_nodes.py
Normal file
@ -0,0 +1,29 @@
|
||||
# Copyright 2017 Huawei Technologies Co., Ltd.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
from mogan.tests.tempest.api import base
|
||||
|
||||
|
||||
class BaremetalComputeAPINodesTest(base.BaseBaremetalComputeTest):
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def resource_cleanup(cls):
|
||||
pass
|
||||
|
||||
def test_nodes_list(self):
|
||||
nodes = self.baremetal_compute_client.list_nodes()
|
||||
self.assertIsInstance(nodes, list)
|
||||
self.assertEqual(len(nodes), 1)
|
Loading…
Reference in New Issue
Block a user