Add support for server groups
This adds support to create and delete server groups. Change-Id: Iecf0ffabe50801ec9bd2bb9ea2dbb17ead4d7cd2
This commit is contained in:
parent
31ac451e12
commit
068028cbe7
@ -0,0 +1,3 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- Adds support to create and delete server groups.
|
@ -172,6 +172,26 @@ class ServerRebuild(task_manager.Task):
|
|||||||
return client.nova_client.servers.rebuild(**self.args)
|
return client.nova_client.servers.rebuild(**self.args)
|
||||||
|
|
||||||
|
|
||||||
|
class ServerGroupList(task_manager.Task):
|
||||||
|
def main(self, client):
|
||||||
|
return client.nova_client.server_groups.list(**self.args)
|
||||||
|
|
||||||
|
|
||||||
|
class ServerGroupGet(task_manager.Task):
|
||||||
|
def main(self, client):
|
||||||
|
return client.nova_client.server_groups.get(**self.args)
|
||||||
|
|
||||||
|
|
||||||
|
class ServerGroupCreate(task_manager.Task):
|
||||||
|
def main(self, client):
|
||||||
|
return client.nova_client.server_groups.create(**self.args)
|
||||||
|
|
||||||
|
|
||||||
|
class ServerGroupDelete(task_manager.Task):
|
||||||
|
def main(self, client):
|
||||||
|
return client.nova_client.server_groups.delete(**self.args)
|
||||||
|
|
||||||
|
|
||||||
class HypervisorList(task_manager.Task):
|
class HypervisorList(task_manager.Task):
|
||||||
def main(self, client):
|
def main(self, client):
|
||||||
return client.nova_client.hypervisors.list(**self.args)
|
return client.nova_client.hypervisors.list(**self.args)
|
||||||
|
@ -1212,6 +1212,20 @@ class OpenStackCloud(object):
|
|||||||
servers = self.list_servers(detailed=detailed)
|
servers = self.list_servers(detailed=detailed)
|
||||||
return _utils._filter_list(servers, name_or_id, filters)
|
return _utils._filter_list(servers, name_or_id, filters)
|
||||||
|
|
||||||
|
def search_server_groups(self, name_or_id=None, filters=None):
|
||||||
|
"""Seach server groups.
|
||||||
|
|
||||||
|
:param name: server group name or id.
|
||||||
|
:param filters: a dict containing additional filters to use.
|
||||||
|
|
||||||
|
:returns: a list of dicts containing the server groups
|
||||||
|
|
||||||
|
:raises: ``OpenStackCloudException``: if something goes wrong during
|
||||||
|
the openstack API call.
|
||||||
|
"""
|
||||||
|
server_groups = self.list_server_groups()
|
||||||
|
return _utils._filter_list(server_groups, name_or_id, filters)
|
||||||
|
|
||||||
def search_images(self, name_or_id=None, filters=None):
|
def search_images(self, name_or_id=None, filters=None):
|
||||||
images = self.list_images()
|
images = self.list_images()
|
||||||
return _utils._filter_list(images, name_or_id, filters)
|
return _utils._filter_list(images, name_or_id, filters)
|
||||||
@ -1461,6 +1475,15 @@ class OpenStackCloud(object):
|
|||||||
for server in servers
|
for server in servers
|
||||||
]
|
]
|
||||||
|
|
||||||
|
def list_server_groups(self):
|
||||||
|
"""List all available server groups.
|
||||||
|
|
||||||
|
:returns: A list of server group dicts.
|
||||||
|
|
||||||
|
"""
|
||||||
|
with _utils.shade_exceptions("Error fetching server group list"):
|
||||||
|
return self.manager.submitTask(_tasks.ServerGroupList())
|
||||||
|
|
||||||
@_utils.cache_on_arguments(should_cache_fn=_no_pending_images)
|
@_utils.cache_on_arguments(should_cache_fn=_no_pending_images)
|
||||||
def list_images(self, filter_deleted=True):
|
def list_images(self, filter_deleted=True):
|
||||||
"""Get available glance images.
|
"""Get available glance images.
|
||||||
@ -1933,6 +1956,25 @@ class OpenStackCloud(object):
|
|||||||
self.manager.submitTask(_tasks.ServerGet(server=id)),
|
self.manager.submitTask(_tasks.ServerGet(server=id)),
|
||||||
cloud_name=self.name, region_name=self.region_name))
|
cloud_name=self.name, region_name=self.region_name))
|
||||||
|
|
||||||
|
def get_server_group(self, name_or_id=None, filters=None):
|
||||||
|
"""Get a server group by name or ID.
|
||||||
|
|
||||||
|
:param name_or_id: Name or ID of the server group.
|
||||||
|
:param dict filters:
|
||||||
|
A dictionary of meta data to use for further filtering. Elements
|
||||||
|
of this dictionary may, themselves, be dictionaries. Example::
|
||||||
|
|
||||||
|
{
|
||||||
|
'policy': 'affinity',
|
||||||
|
}
|
||||||
|
|
||||||
|
:returns: A server groups dict or None if no matching server group
|
||||||
|
is found.
|
||||||
|
|
||||||
|
"""
|
||||||
|
return _utils._get_entity(self.search_server_groups, name_or_id,
|
||||||
|
filters)
|
||||||
|
|
||||||
def get_image(self, name_or_id, filters=None):
|
def get_image(self, name_or_id, filters=None):
|
||||||
"""Get an image by name or ID.
|
"""Get an image by name or ID.
|
||||||
|
|
||||||
@ -4352,6 +4394,44 @@ class OpenStackCloud(object):
|
|||||||
self._servers_time = self._servers_time - self._SERVER_AGE
|
self._servers_time = self._servers_time - self._SERVER_AGE
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def create_server_group(self, name, policies):
|
||||||
|
"""Create a new server group.
|
||||||
|
|
||||||
|
:param name: Name of the server group being created
|
||||||
|
:param policies: List of policies for the server group.
|
||||||
|
|
||||||
|
:returns: a dict representing the new server group.
|
||||||
|
|
||||||
|
:raises: OpenStackCloudException on operation error.
|
||||||
|
"""
|
||||||
|
with _utils.shade_exceptions(
|
||||||
|
"Unable to create server group {name}".format(
|
||||||
|
name=name)):
|
||||||
|
return self.manager.submitTask(_tasks.ServerGroupCreate(
|
||||||
|
name=name, policies=policies))
|
||||||
|
|
||||||
|
def delete_server_group(self, name_or_id):
|
||||||
|
"""Delete a server group.
|
||||||
|
|
||||||
|
:param name_or_id: Name or id of the server group to delete
|
||||||
|
|
||||||
|
:returns: True if delete succeeded, False otherwise
|
||||||
|
|
||||||
|
:raises: OpenStackCloudException on operation error.
|
||||||
|
"""
|
||||||
|
server_group = self.get_server_group(name_or_id)
|
||||||
|
if not server_group:
|
||||||
|
self.log.debug("Server group %s not found for deleting" %
|
||||||
|
name_or_id)
|
||||||
|
return False
|
||||||
|
|
||||||
|
with _utils.shade_exceptions(
|
||||||
|
"Error deleting server group {name}".format(name=name_or_id)):
|
||||||
|
self.manager.submitTask(
|
||||||
|
_tasks.ServerGroupDelete(id=server_group['id']))
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
def list_containers(self, full_listing=True):
|
def list_containers(self, full_listing=True):
|
||||||
try:
|
try:
|
||||||
return self.manager.submitTask(_tasks.ContainerList(
|
return self.manager.submitTask(_tasks.ContainerList(
|
||||||
|
@ -114,6 +114,13 @@ class FakeServer(object):
|
|||||||
self.interface_ip = interface_ip
|
self.interface_ip = interface_ip
|
||||||
|
|
||||||
|
|
||||||
|
class FakeServerGroup(object):
|
||||||
|
def __init__(self, id, name, policies):
|
||||||
|
self.id = id
|
||||||
|
self.name = name
|
||||||
|
self.policies = policies
|
||||||
|
|
||||||
|
|
||||||
class FakeService(object):
|
class FakeService(object):
|
||||||
def __init__(self, id, name, type, service_type, description='',
|
def __init__(self, id, name, type, service_type, description='',
|
||||||
enabled=True):
|
enabled=True):
|
||||||
|
45
shade/tests/functional/test_server_group.py
Normal file
45
shade/tests/functional/test_server_group.py
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
"""
|
||||||
|
test_server_group
|
||||||
|
----------------------------------
|
||||||
|
|
||||||
|
Functional tests for `shade` server_group resource.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from shade.tests.functional import base
|
||||||
|
|
||||||
|
|
||||||
|
class TestServerGroup(base.BaseFunctionalTestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestServerGroup, self).setUp()
|
||||||
|
|
||||||
|
def test_server_group(self):
|
||||||
|
server_group_name = self.getUniqueString()
|
||||||
|
self.addCleanup(self.cleanup, server_group_name)
|
||||||
|
server_group = self.demo_cloud.create_server_group(
|
||||||
|
server_group_name, ['affinity'])
|
||||||
|
|
||||||
|
server_group_ids = [v['id']
|
||||||
|
for v in self.demo_cloud.list_server_groups()]
|
||||||
|
self.assertIn(server_group['id'], server_group_ids)
|
||||||
|
|
||||||
|
self.demo_cloud.delete_server_group(server_group_name)
|
||||||
|
|
||||||
|
def cleanup(self, server_group_name):
|
||||||
|
server_group = self.demo_cloud.get_server_group(server_group_name)
|
||||||
|
if server_group:
|
||||||
|
self.demo_cloud.delete_server_group(server_group['id'])
|
44
shade/tests/unit/test_server_group.py
Normal file
44
shade/tests/unit/test_server_group.py
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
|
import shade
|
||||||
|
from shade.tests.unit import base
|
||||||
|
from shade.tests import fakes
|
||||||
|
|
||||||
|
|
||||||
|
class TestServerGroup(base.TestCase):
|
||||||
|
|
||||||
|
@mock.patch.object(shade.OpenStackCloud, 'nova_client')
|
||||||
|
def test_create_server_group(self, mock_nova):
|
||||||
|
server_group_name = 'my-server-group'
|
||||||
|
self.cloud.create_server_group(name=server_group_name,
|
||||||
|
policies=['affinity'])
|
||||||
|
|
||||||
|
mock_nova.server_groups.create.assert_called_once_with(
|
||||||
|
name=server_group_name, policies=['affinity']
|
||||||
|
)
|
||||||
|
|
||||||
|
@mock.patch.object(shade.OpenStackCloud, 'nova_client')
|
||||||
|
def test_delete_server_group(self, mock_nova):
|
||||||
|
mock_nova.server_groups.list.return_value = [
|
||||||
|
fakes.FakeServerGroup('1234', 'name', ['affinity'])
|
||||||
|
]
|
||||||
|
self.assertTrue(self.cloud.delete_server_group('1234'))
|
||||||
|
mock_nova.server_groups.list.assert_called_once_with()
|
||||||
|
mock_nova.server_groups.delete.assert_called_once_with(
|
||||||
|
id='1234'
|
||||||
|
)
|
Loading…
Reference in New Issue
Block a user