Add project-id and user-id when list server-groups
Currently, command "nova server-group-list" and "nova server-group-get" doesn't return groups' project id and user id information. It is really hard to identify which group belong to which project/user when admin user use this command with option "--all-projects". This patch add project-id and user-id to the list. All os-server-groups APIs will contain the above mentioned data in the response data. DocImpact: This adds API microversion APIImpact: Project id information will be returned for os-servers-group API Change-Id: I0405ed6271c33981578841cfade220758615b1fd Implements: blueprint add-project-id-and-user-id Partial-bug: #1481210 Depends-On: I167141676ef4f597a1c022c1fd5dc96fd55d02ad
This commit is contained in:
parent
3f8c69b2ef
commit
6c74a145bc
@ -0,0 +1,11 @@
|
||||
{
|
||||
"server_group": {
|
||||
"id": "5bbcc3c4-1da2-4437-a48a-66f15b1b13f9",
|
||||
"name": "test",
|
||||
"policies": ["anti-affinity"],
|
||||
"members": [],
|
||||
"metadata": {},
|
||||
"project_id": "c7c9f4f175e247acb56c108fd724d667",
|
||||
"user_id": "fake"
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
{
|
||||
"server_groups": [
|
||||
{
|
||||
"id": "616fb98f-46ca-475e-917e-2563e5a8cd19",
|
||||
"name": "test",
|
||||
"policies": ["anti-affinity"],
|
||||
"members": [],
|
||||
"metadata": {},
|
||||
"project_id": "c7c9f4f175e247acb56c108fd724d667",
|
||||
"user_id": "fake"
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"server_group": {
|
||||
"name": "test",
|
||||
"policies": ["anti-affinity"]
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
{
|
||||
"server_group": {
|
||||
"id": "5bbcc3c4-1da2-4437-a48a-66f15b1b13f9",
|
||||
"name": "test",
|
||||
"policies": ["anti-affinity"],
|
||||
"members": [],
|
||||
"metadata": {},
|
||||
"project_id": "c7c9f4f175e247acb56c108fd724d667",
|
||||
"user_id": "fake"
|
||||
}
|
||||
}
|
@ -19,7 +19,7 @@
|
||||
}
|
||||
],
|
||||
"status": "CURRENT",
|
||||
"version": "2.12",
|
||||
"version": "2.13",
|
||||
"min_version": "2.1",
|
||||
"updated": "2013-07-23T11:33:21Z"
|
||||
}
|
||||
|
@ -22,7 +22,7 @@
|
||||
}
|
||||
],
|
||||
"status": "CURRENT",
|
||||
"version": "2.12",
|
||||
"version": "2.13",
|
||||
"min_version": "2.1",
|
||||
"updated": "2013-07-23T11:33:21Z"
|
||||
}
|
||||
|
@ -53,6 +53,7 @@ REST_API_VERSION_HISTORY = """REST API Version History:
|
||||
user.
|
||||
* 2.11 - Exposes forced_down attribute for os-services
|
||||
* 2.12 - Exposes VIF net-id in os-virtual-interfaces
|
||||
* 2.13 - Add project id and user id information for os-server-groups API
|
||||
"""
|
||||
|
||||
# The minimum and maximum versions of the API supported
|
||||
@ -61,7 +62,7 @@ REST_API_VERSION_HISTORY = """REST API Version History:
|
||||
# Note(cyeoh): This only applies for the v2.1 API once microversions
|
||||
# support is fully merged. It does not affect the V2 API.
|
||||
_MIN_API_VERSION = "2.1"
|
||||
_MAX_API_VERSION = "2.12"
|
||||
_MAX_API_VERSION = "2.13"
|
||||
DEFAULT_API_VERSION = _MIN_API_VERSION
|
||||
|
||||
|
||||
|
@ -19,6 +19,7 @@ from oslo_log import log as logging
|
||||
import webob
|
||||
from webob import exc
|
||||
|
||||
from nova.api.openstack import api_version_request
|
||||
from nova.api.openstack import common
|
||||
from nova.api.openstack.compute.schemas import server_groups as schema
|
||||
from nova.api.openstack import extensions
|
||||
@ -46,7 +47,7 @@ def _authorize_context(req):
|
||||
class ServerGroupController(wsgi.Controller):
|
||||
"""The Server group API controller for the OpenStack API."""
|
||||
|
||||
def _format_server_group(self, context, group):
|
||||
def _format_server_group(self, context, group, req_ver):
|
||||
# the id field has its value as the uuid of the server group
|
||||
# There is no 'uuid' key in server_group seen by clients.
|
||||
# In addition, clients see policies as a ["policy-name"] list;
|
||||
@ -66,17 +67,25 @@ class ServerGroupController(wsgi.Controller):
|
||||
context, filters=filters)
|
||||
members = [instance.uuid for instance in instances]
|
||||
server_group['members'] = members
|
||||
# Add project id information to the response data for
|
||||
# API version v2.13
|
||||
if req_ver >= api_version_request.APIVersionRequest("2.13"):
|
||||
server_group['project_id'] = group.project_id
|
||||
server_group['user_id'] = group.user_id
|
||||
return server_group
|
||||
|
||||
@extensions.expected_errors(404)
|
||||
def show(self, req, id):
|
||||
"""Return data about the given server group."""
|
||||
req_ver = req.api_version_request
|
||||
|
||||
context = _authorize_context(req)
|
||||
try:
|
||||
sg = objects.InstanceGroup.get_by_uuid(context, id)
|
||||
except nova.exception.InstanceGroupNotFound as e:
|
||||
raise webob.exc.HTTPNotFound(explanation=e.format_message())
|
||||
return {'server_group': self._format_server_group(context, sg)}
|
||||
return {'server_group': self._format_server_group(
|
||||
context, sg, req_ver)}
|
||||
|
||||
@wsgi.response(204)
|
||||
@extensions.expected_errors(404)
|
||||
@ -113,6 +122,8 @@ class ServerGroupController(wsgi.Controller):
|
||||
@extensions.expected_errors(())
|
||||
def index(self, req):
|
||||
"""Returns a list of server groups."""
|
||||
req_ver = req.api_version_request
|
||||
|
||||
context = _authorize_context(req)
|
||||
project_id = context.project_id
|
||||
if 'all_projects' in req.GET and context.is_admin:
|
||||
@ -121,7 +132,7 @@ class ServerGroupController(wsgi.Controller):
|
||||
sgs = objects.InstanceGroupList.get_by_project_id(
|
||||
context, project_id)
|
||||
limited_list = common.limited(sgs.objects, req)
|
||||
result = [self._format_server_group(context, group)
|
||||
result = [self._format_server_group(context, group, req_ver)
|
||||
for group in limited_list]
|
||||
return {'server_groups': result}
|
||||
|
||||
@ -129,6 +140,8 @@ class ServerGroupController(wsgi.Controller):
|
||||
@validation.schema(schema.create)
|
||||
def create(self, req, body):
|
||||
"""Creates a new server group."""
|
||||
req_ver = req.api_version_request
|
||||
|
||||
context = _authorize_context(req)
|
||||
|
||||
quotas = objects.Quotas(context=context)
|
||||
@ -152,8 +165,8 @@ class ServerGroupController(wsgi.Controller):
|
||||
raise exc.HTTPBadRequest(explanation=e)
|
||||
|
||||
quotas.commit()
|
||||
|
||||
return {'server_group': self._format_server_group(context, sg)}
|
||||
return {'server_group': self._format_server_group(context, sg,
|
||||
req_ver)}
|
||||
|
||||
|
||||
class ServerGroups(extensions.V21APIExtensionBase):
|
||||
|
@ -130,3 +130,10 @@ user documentation.
|
||||
Exposes VIF ``net-id`` attribute in ``os-virtual-interfaces``.
|
||||
User will be able to get Virtual Interfaces ``net-id`` in Virtual Interfaces
|
||||
list and can determine in which network a Virtual Interface is plugged into.
|
||||
|
||||
2.13
|
||||
----
|
||||
|
||||
Add information ``project_id`` and ``user_id`` to ``os-server-groups``
|
||||
API response data.
|
||||
|
||||
|
@ -0,0 +1,11 @@
|
||||
{
|
||||
"server_group": {
|
||||
"id": "%(id)s",
|
||||
"name": "%(name)s",
|
||||
"policies": ["anti-affinity"],
|
||||
"members": [],
|
||||
"metadata": {},
|
||||
"project_id": "c7c9f4f175e247acb56c108fd724d667",
|
||||
"user_id": "fake"
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
{
|
||||
"server_groups": [
|
||||
{
|
||||
"id": "%(id)s",
|
||||
"name": "test",
|
||||
"policies": ["anti-affinity"],
|
||||
"members": [],
|
||||
"metadata": {},
|
||||
"project_id": "c7c9f4f175e247acb56c108fd724d667",
|
||||
"user_id": "fake"
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"server_group": {
|
||||
"name": "%(name)s",
|
||||
"policies": ["anti-affinity"]
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
{
|
||||
"server_group": {
|
||||
"id": "%(id)s",
|
||||
"name": "%(name)s",
|
||||
"policies": ["anti-affinity"],
|
||||
"members": [],
|
||||
"metadata": {},
|
||||
"project_id": "c7c9f4f175e247acb56c108fd724d667",
|
||||
"user_id": "fake"
|
||||
}
|
||||
}
|
@ -19,7 +19,7 @@
|
||||
}
|
||||
],
|
||||
"status": "CURRENT",
|
||||
"version": "2.12",
|
||||
"version": "2.13",
|
||||
"min_version": "2.1",
|
||||
"updated": "2013-07-23T11:33:21Z"
|
||||
}
|
||||
|
@ -22,7 +22,7 @@
|
||||
}
|
||||
],
|
||||
"status": "CURRENT",
|
||||
"version": "2.12",
|
||||
"version": "2.13",
|
||||
"min_version": "2.1",
|
||||
"updated": "2013-07-23T11:33:21Z"
|
||||
}
|
||||
|
@ -77,3 +77,9 @@ class ServerGroupsSampleJsonTest(api_sample_base.ApiSampleTestBaseV21):
|
||||
uuid = self._post_server_group()
|
||||
response = self._do_delete('os-server-groups/%s' % uuid)
|
||||
self.assertEqual(204, response.status_code)
|
||||
|
||||
|
||||
class ServerGroupsV213SampleJsonTest(api_sample_base.ApiSampleTestBaseV21):
|
||||
extension_name = "os-server-groups"
|
||||
request_api_version = '2.13'
|
||||
scenarios = [('v2_13', {})]
|
||||
|
@ -16,6 +16,8 @@
|
||||
from oslo_utils import uuidutils
|
||||
import webob
|
||||
|
||||
import mock
|
||||
|
||||
from nova.api.openstack.compute.legacy_v2.contrib import server_groups
|
||||
from nova.api.openstack.compute import server_groups as sg_v21
|
||||
from nova.api.openstack import extensions
|
||||
@ -127,6 +129,120 @@ class ServerGroupTestV21(test.TestCase):
|
||||
ig_uuid = self._create_instance_group(ctx, members)
|
||||
return (ig_uuid, instances, members)
|
||||
|
||||
@mock.patch.object(nova.db, 'instance_group_get_all_by_project_id')
|
||||
@mock.patch.object(nova.db, 'instance_group_get_all')
|
||||
def _test_list_server_group_all(self,
|
||||
mock_get_all,
|
||||
mock_get_by_project,
|
||||
api_version='2.1'):
|
||||
policies = ['anti-affinity']
|
||||
members = []
|
||||
metadata = {} # always empty
|
||||
names = ['default-x', 'test']
|
||||
p_id = 'project_id'
|
||||
u_id = 'user_id'
|
||||
if api_version >= '2.13':
|
||||
sg1 = server_group_resp_template(id=str(1345),
|
||||
name=names[0],
|
||||
policies=policies,
|
||||
members=members,
|
||||
metadata=metadata,
|
||||
project_id=p_id,
|
||||
user_id=u_id)
|
||||
sg2 = server_group_resp_template(id=str(891),
|
||||
name=names[1],
|
||||
policies=policies,
|
||||
members=members,
|
||||
metadata=metadata,
|
||||
project_id=p_id,
|
||||
user_id=u_id)
|
||||
else:
|
||||
sg1 = server_group_resp_template(id=str(1345),
|
||||
name=names[0],
|
||||
policies=policies,
|
||||
members=members,
|
||||
metadata=metadata)
|
||||
sg2 = server_group_resp_template(id=str(891),
|
||||
name=names[1],
|
||||
policies=policies,
|
||||
members=members,
|
||||
metadata=metadata)
|
||||
tenant_groups = [sg2]
|
||||
all_groups = [sg1, sg2]
|
||||
|
||||
all = {'server_groups': all_groups}
|
||||
tenant_specific = {'server_groups': tenant_groups}
|
||||
|
||||
def return_all_server_groups():
|
||||
return [server_group_db(sg) for sg in all_groups]
|
||||
|
||||
mock_get_all.return_value = return_all_server_groups()
|
||||
|
||||
def return_tenant_server_groups():
|
||||
return [server_group_db(sg) for sg in tenant_groups]
|
||||
|
||||
mock_get_by_project.return_value = return_tenant_server_groups()
|
||||
|
||||
path = '/os-server-groups?all_projects=True'
|
||||
|
||||
req = fakes.HTTPRequest.blank(path, use_admin_context=True,
|
||||
version=api_version)
|
||||
res_dict = self.controller.index(req)
|
||||
self.assertEqual(all, res_dict)
|
||||
req = fakes.HTTPRequest.blank(path,
|
||||
version=api_version)
|
||||
res_dict = self.controller.index(req)
|
||||
self.assertEqual(tenant_specific, res_dict)
|
||||
|
||||
@mock.patch.object(nova.db, 'instance_group_get_all_by_project_id')
|
||||
def _test_list_server_group_by_tenant(self, mock_get_by_project,
|
||||
api_version='2.1'):
|
||||
policies = ['anti-affinity']
|
||||
members = []
|
||||
metadata = {} # always empty
|
||||
names = ['default-x', 'test']
|
||||
p_id = 'project_id'
|
||||
u_id = 'user_id'
|
||||
if api_version >= '2.13':
|
||||
sg1 = server_group_resp_template(id=str(1345),
|
||||
name=names[0],
|
||||
policies=policies,
|
||||
members=members,
|
||||
metadata=metadata,
|
||||
project_id=p_id,
|
||||
user_id=u_id)
|
||||
sg2 = server_group_resp_template(id=str(891),
|
||||
name=names[1],
|
||||
policies=policies,
|
||||
members=members,
|
||||
metadata=metadata,
|
||||
project_id=p_id,
|
||||
user_id=u_id)
|
||||
else:
|
||||
sg1 = server_group_resp_template(id=str(1345),
|
||||
name=names[0],
|
||||
policies=policies,
|
||||
members=members,
|
||||
metadata=metadata)
|
||||
sg2 = server_group_resp_template(id=str(891),
|
||||
name=names[1],
|
||||
policies=policies,
|
||||
members=members,
|
||||
metadata=metadata)
|
||||
groups = [sg1, sg2]
|
||||
expected = {'server_groups': groups}
|
||||
|
||||
def return_server_groups():
|
||||
return [server_group_db(sg) for sg in groups]
|
||||
|
||||
return_get_by_project = return_server_groups()
|
||||
mock_get_by_project.return_value = return_get_by_project
|
||||
path = '/os-server-groups'
|
||||
self.req = fakes.HTTPRequest.blank(path,
|
||||
version=api_version)
|
||||
res_dict = self.controller.index(self.req)
|
||||
self.assertEqual(expected, res_dict)
|
||||
|
||||
def test_display_members(self):
|
||||
ctx = context.RequestContext('fake_user', 'fake')
|
||||
(ig_uuid, instances, members) = self._create_groups_and_instances(ctx)
|
||||
@ -262,76 +378,10 @@ class ServerGroupTestV21(test.TestCase):
|
||||
self.controller.create, self.req, body=body)
|
||||
|
||||
def test_list_server_group_by_tenant(self):
|
||||
groups = []
|
||||
policies = ['anti-affinity']
|
||||
members = []
|
||||
metadata = {} # always empty
|
||||
names = ['default-x', 'test']
|
||||
sg1 = server_group_resp_template(id=str(1345),
|
||||
name=names[0],
|
||||
policies=policies,
|
||||
members=members,
|
||||
metadata=metadata)
|
||||
sg2 = server_group_resp_template(id=str(891),
|
||||
name=names[1],
|
||||
policies=policies,
|
||||
members=members,
|
||||
metadata=metadata)
|
||||
groups = [sg1, sg2]
|
||||
expected = {'server_groups': groups}
|
||||
|
||||
def return_server_groups(context, project_id):
|
||||
return [server_group_db(sg) for sg in groups]
|
||||
|
||||
self.stubs.Set(nova.db, 'instance_group_get_all_by_project_id',
|
||||
return_server_groups)
|
||||
|
||||
res_dict = self.controller.index(self.req)
|
||||
self.assertEqual(res_dict, expected)
|
||||
self._test_list_server_group_by_tenant(api_version='2.1')
|
||||
|
||||
def test_list_server_group_all(self):
|
||||
all_groups = []
|
||||
tenant_groups = []
|
||||
policies = ['anti-affinity']
|
||||
members = []
|
||||
metadata = {} # always empty
|
||||
names = ['default-x', 'test']
|
||||
sg1 = server_group_resp_template(id=str(1345),
|
||||
name=names[0],
|
||||
policies=[],
|
||||
members=members,
|
||||
metadata=metadata)
|
||||
sg2 = server_group_resp_template(id=str(891),
|
||||
name=names[1],
|
||||
policies=policies,
|
||||
members=members,
|
||||
metadata={})
|
||||
tenant_groups = [sg2]
|
||||
all_groups = [sg1, sg2]
|
||||
|
||||
all = {'server_groups': all_groups}
|
||||
tenant_specific = {'server_groups': tenant_groups}
|
||||
|
||||
def return_all_server_groups(context):
|
||||
return [server_group_db(sg) for sg in all_groups]
|
||||
|
||||
self.stubs.Set(nova.db, 'instance_group_get_all',
|
||||
return_all_server_groups)
|
||||
|
||||
def return_tenant_server_groups(context, project_id):
|
||||
return [server_group_db(sg) for sg in tenant_groups]
|
||||
|
||||
self.stubs.Set(nova.db, 'instance_group_get_all_by_project_id',
|
||||
return_tenant_server_groups)
|
||||
|
||||
path = '/os-server-groups?all_projects=True'
|
||||
|
||||
req = fakes.HTTPRequest.blank(path, use_admin_context=True)
|
||||
res_dict = self.controller.index(req)
|
||||
self.assertEqual(res_dict, all)
|
||||
req = fakes.HTTPRequest.blank(path)
|
||||
res_dict = self.controller.index(req)
|
||||
self.assertEqual(res_dict, tenant_specific)
|
||||
self._test_list_server_group_all(api_version='2.1')
|
||||
|
||||
def test_delete_server_group_by_id(self):
|
||||
sg = server_group_template(id='123')
|
||||
@ -373,3 +423,16 @@ class ServerGroupTestV2(ServerGroupTestV21):
|
||||
ext_mgr = extensions.ExtensionManager()
|
||||
ext_mgr.extensions = {}
|
||||
self.controller = server_groups.ServerGroupController(ext_mgr)
|
||||
|
||||
|
||||
class ServerGroupTestV213(ServerGroupTestV21):
|
||||
wsgi_api_version = '2.13'
|
||||
|
||||
def _setup_controller(self):
|
||||
self.controller = sg_v21.ServerGroupController()
|
||||
|
||||
def test_list_server_group_all(self):
|
||||
self._test_list_server_group_all(api_version='2.13')
|
||||
|
||||
def test_list_server_group_by_tenant(self):
|
||||
self._test_list_server_group_by_tenant(api_version='2.13')
|
||||
|
@ -66,7 +66,7 @@ EXP_VERSIONS = {
|
||||
"v2.1": {
|
||||
"id": "v2.1",
|
||||
"status": "CURRENT",
|
||||
"version": "2.12",
|
||||
"version": "2.13",
|
||||
"min_version": "2.1",
|
||||
"updated": "2013-07-23T11:33:21Z",
|
||||
"links": [
|
||||
@ -128,7 +128,7 @@ class VersionsTestV20(test.NoDBTestCase):
|
||||
{
|
||||
"id": "v2.1",
|
||||
"status": "CURRENT",
|
||||
"version": "2.12",
|
||||
"version": "2.13",
|
||||
"min_version": "2.1",
|
||||
"updated": "2013-07-23T11:33:21Z",
|
||||
"links": [
|
||||
|
@ -0,0 +1,8 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Project-id and user-id are now also returned in
|
||||
the return data of os-server-groups APIs. In order
|
||||
to use this new feature, user have to contain the
|
||||
header of request microversion v2.13 in the API
|
||||
request.
|
Loading…
x
Reference in New Issue
Block a user