Add availability zones API
Users should have the ability of listing all availability zones, so they can specify which az they want the instance to be built. Change-Id: Id04f2e0fb64d6e88c4860e695d258239d2349dea Implements: blueprint availability-zone
This commit is contained in:
parent
80983ab56b
commit
44ac91540f
32
api-ref/source/availability_zones.inc
Normal file
32
api-ref/source/availability_zones.inc
Normal file
@ -0,0 +1,32 @@
|
||||
.. -*- rst -*-
|
||||
|
||||
====================
|
||||
Availability Zones
|
||||
====================
|
||||
|
||||
Lists availability zones.
|
||||
|
||||
List Availability Zone information
|
||||
==================================
|
||||
|
||||
.. rest_method:: GET /availability_zones
|
||||
|
||||
Lists availability zone information.
|
||||
|
||||
Normal response codes: 200
|
||||
|
||||
Error response codes: unauthorized(401), forbidden(403)
|
||||
|
||||
Response
|
||||
--------
|
||||
|
||||
.. rest_parameters:: parameters.yaml
|
||||
|
||||
- availability_zones: availability_zones
|
||||
|
||||
|
|
||||
|
||||
**Example List availability zone information**
|
||||
|
||||
.. literalinclude:: ../../doc/api_samples/availability_zones/availability-zone-list-resp.json
|
||||
:language: javascript
|
@ -9,3 +9,4 @@
|
||||
.. include:: urls.inc
|
||||
.. include:: instances.inc
|
||||
.. include:: types.inc
|
||||
.. include:: availability_zones.inc
|
||||
|
@ -79,6 +79,12 @@ availability_zone:
|
||||
in: body
|
||||
required: false
|
||||
type: string
|
||||
availability_zones:
|
||||
description: |
|
||||
An array of availability zone name.
|
||||
in: body
|
||||
required: true
|
||||
type: array
|
||||
created_at:
|
||||
description: |
|
||||
The date and time when the resource was created. The date and time
|
||||
|
@ -0,0 +1,7 @@
|
||||
{
|
||||
"availability_zones": [
|
||||
"az1",
|
||||
"az2",
|
||||
"az3"
|
||||
]
|
||||
}
|
@ -21,6 +21,7 @@ Specification can be found at doc/source/webapi/v1.rst
|
||||
|
||||
from pecan import rest
|
||||
|
||||
from nimble.api.controllers.v1 import availability_zone
|
||||
from nimble.api.controllers.v1 import instance_types
|
||||
from nimble.api.controllers.v1 import instances
|
||||
|
||||
@ -30,6 +31,7 @@ class Controller(rest.RestController):
|
||||
|
||||
types = instance_types.InstanceTypeController()
|
||||
instances = instances.InstanceController()
|
||||
availability_zones = availability_zone.AvailabilityZoneController()
|
||||
|
||||
|
||||
__all__ = ('Controller',)
|
||||
|
47
nimble/api/controllers/v1/availability_zone.py
Normal file
47
nimble/api/controllers/v1/availability_zone.py
Normal file
@ -0,0 +1,47 @@
|
||||
# Copyright 2016 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 nimble.api.controllers import base
|
||||
from nimble.api import expose
|
||||
from nimble.engine import api as engineapi
|
||||
|
||||
|
||||
class AvailabilityZones(base.APIBase):
|
||||
"""API representation of a collection of availability zone."""
|
||||
|
||||
availability_zones = [wtypes.text]
|
||||
"""A list containing availability zone names"""
|
||||
|
||||
|
||||
class AvailabilityZoneController(rest.RestController):
|
||||
"""REST controller for Availability Zone."""
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(AvailabilityZoneController, self).__init__(**kwargs)
|
||||
self.engine_api = engineapi.API()
|
||||
|
||||
@expose.expose(AvailabilityZones)
|
||||
def get_all(self):
|
||||
"""Retrieve a list of availability zone."""
|
||||
|
||||
azs = self.engine_api.list_availability_zones(pecan.request.context)
|
||||
|
||||
collection = AvailabilityZones()
|
||||
collection.availability_zones = azs['availability_zones']
|
||||
return collection
|
@ -110,15 +110,23 @@ class API(object):
|
||||
self._delete_instance(context, instance)
|
||||
|
||||
def states(self, context, instance):
|
||||
"""Get instance states."""
|
||||
return self.engine_rpcapi.instance_states(context, instance)
|
||||
|
||||
def power(self, context, instance, target):
|
||||
"""Set power state of an instance."""
|
||||
self.engine_rpcapi.set_power_state(context, instance, target)
|
||||
|
||||
def get_ironic_node(self, context, instance_uuid, fields):
|
||||
"""Get a ironic node by instance UUID."""
|
||||
return self.engine_rpcapi.get_ironic_node(context,
|
||||
instance_uuid,
|
||||
fields)
|
||||
|
||||
def get_ironic_node_list(self, context, fields):
|
||||
"""Get a list of ironic node."""
|
||||
return self.engine_rpcapi.get_ironic_node_list(context, fields)
|
||||
|
||||
def list_availability_zones(self, context):
|
||||
"""Get a list of availability zones."""
|
||||
return self.engine_rpcapi.list_availability_zones(context)
|
||||
|
@ -155,7 +155,7 @@ class EngineManager(base_manager.BaseEngineManager):
|
||||
|
||||
def create_instance(self, context, instance,
|
||||
requested_networks, instance_type):
|
||||
"""Signal to engine service to perform a deployment."""
|
||||
"""Perform a deployment."""
|
||||
LOG.debug("Starting instance...")
|
||||
|
||||
# Populate request spec
|
||||
@ -212,7 +212,7 @@ class EngineManager(base_manager.BaseEngineManager):
|
||||
return instance
|
||||
|
||||
def delete_instance(self, context, instance):
|
||||
"""Signal to engine service to delete an instance."""
|
||||
"""Delete an instance."""
|
||||
LOG.debug("Deleting instance...")
|
||||
|
||||
self._destroy_networks(context, instance)
|
||||
@ -228,7 +228,7 @@ class EngineManager(base_manager.BaseEngineManager):
|
||||
return states.to_dict()
|
||||
|
||||
def instance_states(self, context, instance):
|
||||
"""Signal to engine service to get an instance states."""
|
||||
"""Get an instance states."""
|
||||
LOG.debug("get instance states")
|
||||
|
||||
return self._instance_states(context, instance)
|
||||
@ -239,17 +239,29 @@ class EngineManager(base_manager.BaseEngineManager):
|
||||
state)
|
||||
|
||||
def set_power_state(self, context, instance, state):
|
||||
"""Signal to engine service to get an instance states."""
|
||||
"""Get an instance states."""
|
||||
LOG.debug("set power state...")
|
||||
|
||||
return self._set_power_state(context, instance, state)
|
||||
|
||||
def get_ironic_node(self, context, instance_uuid, fields):
|
||||
"""Get a ironic node."""
|
||||
node = ironic.get_node_by_instance(self.ironicclient,
|
||||
instance_uuid, fields)
|
||||
return node.to_dict()
|
||||
|
||||
def get_ironic_node_list(self, context, fields):
|
||||
"""Get a ironic node list."""
|
||||
nodes = ironic.get_node_list(self.ironicclient, associated=True,
|
||||
limit=0, fields=fields)
|
||||
return {'nodes': [node.to_dict() for node in nodes]}
|
||||
|
||||
def list_availability_zones(self, context):
|
||||
"""Get availability zone list."""
|
||||
azs = set()
|
||||
for node in self.node_cache:
|
||||
az = node.properties.get('availability_zone')
|
||||
if az is not None:
|
||||
azs.add(az)
|
||||
|
||||
return {'availability_zones': list(azs)}
|
||||
|
@ -86,3 +86,8 @@ class EngineAPI(object):
|
||||
cctxt = self.client.prepare(topic=self.topic, server=CONF.host)
|
||||
return cctxt.call(context, 'get_ironic_node_list',
|
||||
fields=fields)
|
||||
|
||||
def list_availability_zones(self, context):
|
||||
"""Signal to engine service to get availability zone list."""
|
||||
cctxt = self.client.prepare(topic=self.topic, server=CONF.host)
|
||||
return cctxt.call(context, 'list_availability_zones')
|
||||
|
29
nimble/tests/functional/api/v1/test_availability_zones.py
Normal file
29
nimble/tests/functional/api/v1/test_availability_zones.py
Normal file
@ -0,0 +1,29 @@
|
||||
# Copyright 2016 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 nimble.tests.functional.api import v1 as v1_test
|
||||
|
||||
|
||||
class TestAvailabilityZone(v1_test.APITestV1):
|
||||
|
||||
def setUp(self):
|
||||
super(TestAvailabilityZone, self).setUp()
|
||||
|
||||
@mock.patch('nimble.engine.api.API.list_availability_zones')
|
||||
def test_availability_zone_get_all(self, list_azs):
|
||||
list_azs.return_value = {'availability_zones': ['az1', 'az2']}
|
||||
resp = self.get_json('/availability_zones')
|
||||
self.assertItemsEqual(['az1', 'az2'], resp['availability_zones'])
|
Loading…
Reference in New Issue
Block a user