Add ServerGroup API interfaces
This change adds ServerGroup interfaces Partially Implements: bp server-group-api-extension Change-Id: I56647ac7f871aee357b3cf05ab78d31548c96ee3
This commit is contained in:
parent
3760f43af4
commit
2dc155534f
@ -15,3 +15,4 @@ Baremetal Compute API V1 (CURRENT)
|
||||
.. include:: flavor_access.inc
|
||||
.. include:: availability_zones.inc
|
||||
.. include:: aggregates.inc
|
||||
.. include:: server_groups.inc
|
||||
|
@ -45,6 +45,12 @@ port_ident:
|
||||
in: path
|
||||
required: true
|
||||
type: string
|
||||
server_group_uuid_path:
|
||||
description: |
|
||||
The UUID of the server group.
|
||||
in: path
|
||||
required: true
|
||||
type: string
|
||||
server_ident:
|
||||
description: |
|
||||
The UUID of the server.
|
||||
@ -529,6 +535,42 @@ server_fault:
|
||||
in: body
|
||||
required: false
|
||||
type: object
|
||||
server_group_members:
|
||||
description: |
|
||||
A list of uuids of servers which belong to this server group.
|
||||
in: body
|
||||
required: false
|
||||
type: array
|
||||
server_group_name:
|
||||
description: |
|
||||
The server group name.
|
||||
in: body
|
||||
required: true
|
||||
type: string
|
||||
server_group_policies:
|
||||
description: |
|
||||
A list of exactly one policy name to associate with the server group. The
|
||||
current valid policy names are:
|
||||
|
||||
- ``anti-affinity`` - servers in this group must be scheduled to
|
||||
different affinity-zones.
|
||||
- ``affinity`` - servers in this group must be scheduled to the same
|
||||
affinity-zone.
|
||||
in: body
|
||||
required: true
|
||||
type: array
|
||||
server_group_uuid:
|
||||
description: |
|
||||
The UUID of the server group.
|
||||
in: body
|
||||
required: true
|
||||
type: string
|
||||
server_groups:
|
||||
description: |
|
||||
The list of existing server groups.
|
||||
in: body
|
||||
required: true
|
||||
type: array
|
||||
server_name:
|
||||
description: |
|
||||
The server name.
|
||||
|
@ -0,0 +1,22 @@
|
||||
{
|
||||
"user_id": "9851baf53c75452dad7951bca7b3dbac",
|
||||
"uuid": "73f9f8be-2e4e-4de8-b3f9-e1bf6618c1b1",
|
||||
"links": [
|
||||
{
|
||||
"href": "http://10.229.40.107/v1/server_groups/73f9f8be-2e4e-4de8-b3f9-e1bf6618c1b1",
|
||||
"rel": "self"
|
||||
},
|
||||
{
|
||||
"href": "http://10.229.40.107/server_groups/73f9f8be-2e4e-4de8-b3f9-e1bf6618c1b1",
|
||||
"rel": "bookmark"
|
||||
}
|
||||
],
|
||||
"created_at": "2017-08-02T09:18:24+00:00",
|
||||
"updated_at": null,
|
||||
"members": [],
|
||||
"project_id": "b5f8b7e5429449a8a1366088abede8d1",
|
||||
"policies": [
|
||||
"anti-affinity"
|
||||
],
|
||||
"name": "test"
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
{
|
||||
"server_groups": [
|
||||
{
|
||||
"user_id": "9851baf53c75452dad7951bca7b3dbac",
|
||||
"uuid": "73f9f8be-2e4e-4de8-b3f9-e1bf6618c1b1",
|
||||
"links": [
|
||||
{
|
||||
"href": "http://10.229.40.107/v1/server_groups/73f9f8be-2e4e-4de8-b3f9-e1bf6618c1b1",
|
||||
"rel": "self"
|
||||
},
|
||||
{
|
||||
"href": "http://10.229.40.107/server_groups/73f9f8be-2e4e-4de8-b3f9-e1bf6618c1b1",
|
||||
"rel": "bookmark"
|
||||
}
|
||||
],
|
||||
"created_at": "2017-08-02T09:18:24+00:00",
|
||||
"updated_at": null,
|
||||
"members": [],
|
||||
"project_id": "b5f8b7e5429449a8a1366088abede8d1",
|
||||
"policies": [
|
||||
"anti-affinity"
|
||||
],
|
||||
"name": "test"
|
||||
},
|
||||
{
|
||||
"user_id": "9851baf53c75452dad7951bca7b3dbac",
|
||||
"uuid": "fd2dab04-ab3e-4893-9ee4-837cc0ea2d9c",
|
||||
"links": [
|
||||
{
|
||||
"href": "http://10.229.40.107/v1/server_groups/fd2dab04-ab3e-4893-9ee4-837cc0ea2d9c",
|
||||
"rel": "self"
|
||||
},
|
||||
{
|
||||
"href": "http://10.229.40.107/server_groups/fd2dab04-ab3e-4893-9ee4-837cc0ea2d9c",
|
||||
"rel": "bookmark"
|
||||
}
|
||||
],
|
||||
"created_at": "2017-08-02T09:20:24+00:00",
|
||||
"updated_at": null,
|
||||
"members": [],
|
||||
"project_id": "b5f8b7e5429449a8a1366088abede8d1",
|
||||
"policies": [
|
||||
"affinity"
|
||||
],
|
||||
"name": "test2"
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "test",
|
||||
"policies": [
|
||||
"anti-affinity"
|
||||
]
|
||||
}
|
||||
|
@ -0,0 +1,22 @@
|
||||
{
|
||||
"user_id": "9851baf53c75452dad7951bca7b3dbac",
|
||||
"uuid": "159628a2-2f07-42cf-aebf-83bb5eb0ff3c",
|
||||
"links": [
|
||||
{
|
||||
"href": "http://10.229.40.107/v1/server_groups/159628a2-2f07-42cf-aebf-83bb5eb0ff3c",
|
||||
"rel": "self"
|
||||
},
|
||||
{
|
||||
"href": "http://10.229.40.107/server_groups/159628a2-2f07-42cf-aebf-83bb5eb0ff3c",
|
||||
"rel": "bookmark"
|
||||
}
|
||||
],
|
||||
"created_at": "2017-08-02T09:15:36+00:00",
|
||||
"updated_at": null,
|
||||
"members": [],
|
||||
"project_id": "b5f8b7e5429449a8a1366088abede8d1",
|
||||
"policies": [
|
||||
"anti-affinity"
|
||||
],
|
||||
"name": "test"
|
||||
}
|
154
api-ref/source/v1/server_groups.inc
Normal file
154
api-ref/source/v1/server_groups.inc
Normal file
@ -0,0 +1,154 @@
|
||||
.. -*- rst -*-
|
||||
|
||||
=============
|
||||
ServerGroups
|
||||
=============
|
||||
|
||||
Lists, creates, shows and deletes server groups.
|
||||
|
||||
List ServerGroups
|
||||
=================
|
||||
|
||||
.. rest_method:: GET /server_groups
|
||||
|
||||
Lists server groups.
|
||||
|
||||
Normal response codes: 200
|
||||
|
||||
Error response codes: unauthorized(401), forbidden(403)
|
||||
|
||||
Request
|
||||
-------
|
||||
|
||||
.. rest_parameters:: parameters.yaml
|
||||
|
||||
- all_tenants: all_tenants
|
||||
|
||||
Response
|
||||
--------
|
||||
|
||||
.. rest_parameters:: parameters.yaml
|
||||
|
||||
- server_groups: server_groups
|
||||
- name: server_group_name
|
||||
- links: links
|
||||
- uuid: server_group_uuid
|
||||
- policies: server_group_policies
|
||||
- members: server_group_members
|
||||
- project_id: project_id_body
|
||||
- user_id: user_id_body
|
||||
- created_at: created_at
|
||||
- updated_at: updated_at
|
||||
|
||||
**Example List server groups: JSON response**
|
||||
|
||||
.. literalinclude:: samples/server_groups/server-group-list-resp.json
|
||||
:language: javascript
|
||||
|
||||
Create ServerGroup
|
||||
==================
|
||||
|
||||
.. rest_method:: POST /server_groups
|
||||
|
||||
Creates a server group.
|
||||
|
||||
Normal response codes: 201
|
||||
|
||||
Error response codes: badRequest(400), unauthorized(401), forbidden(403),
|
||||
conflict(409)
|
||||
|
||||
Request
|
||||
-------
|
||||
|
||||
.. rest_parameters:: parameters.yaml
|
||||
|
||||
- name: server_group_name
|
||||
- policies: server_group_policies
|
||||
|
||||
**Example Create a ServerGroup: JSON request**
|
||||
|
||||
.. literalinclude:: samples/server_groups/server-group-post-req.json
|
||||
:language: javascript
|
||||
|
||||
Response
|
||||
--------
|
||||
|
||||
.. rest_parameters:: parameters.yaml
|
||||
|
||||
- name: server_group_name
|
||||
- links: links
|
||||
- uuid: server_group_uuid
|
||||
- policies: server_group_policies
|
||||
- members: server_group_members
|
||||
- project_id: project_id_body
|
||||
- user_id: user_id_body
|
||||
- created_at: created_at
|
||||
- updated_at: updated_at
|
||||
|
||||
**Example Create ServerGroup: JSON response**
|
||||
|
||||
.. literalinclude:: samples/server_groups/server-group-post-resp.json
|
||||
:language: javascript
|
||||
|
||||
|
||||
Show ServerGroup Details
|
||||
========================
|
||||
|
||||
.. rest_method:: GET /server_groups/{server_group_uuid}
|
||||
|
||||
Shows details for a server group.
|
||||
|
||||
Normal response codes: 200
|
||||
|
||||
Error response codes: unauthorized(401), forbidden(403), itemNotFound(404)
|
||||
|
||||
Request
|
||||
-------
|
||||
|
||||
.. rest_parameters:: parameters.yaml
|
||||
|
||||
- server_group_uuid: server_group_uuid_path
|
||||
|
||||
Response
|
||||
--------
|
||||
|
||||
.. rest_parameters:: parameters.yaml
|
||||
|
||||
- name: server_group_name
|
||||
- links: links
|
||||
- uuid: server_group_uuid
|
||||
- policies: server_group_policies
|
||||
- members: server_group_members
|
||||
- project_id: project_id_body
|
||||
- user_id: user_id_body
|
||||
- created_at: created_at
|
||||
- updated_at: updated_at
|
||||
|
||||
**Example Show ServerGroup Details**
|
||||
|
||||
.. literalinclude:: samples/server_groups/server-group-get-resp.json
|
||||
:language: javascript
|
||||
|
||||
|
||||
Delete a ServerGroup
|
||||
====================
|
||||
|
||||
.. rest_method:: DELETE /server_groups/{server_group_uuid}
|
||||
|
||||
Deletes a server group.
|
||||
|
||||
Normal response codes: 204
|
||||
|
||||
Error response codes: unauthorized(401), forbidden(403), itemNotFound(404)
|
||||
|
||||
Request
|
||||
-------
|
||||
|
||||
.. rest_parameters:: parameters.yaml
|
||||
|
||||
- server_group_uuid: server_group_uuid_path
|
||||
|
||||
Response
|
||||
--------
|
||||
|
||||
No body content is returned on a successful DELETE.
|
@ -30,6 +30,7 @@ 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 server_groups
|
||||
from mogan.api.controllers.v1 import servers
|
||||
from mogan.api import expose
|
||||
|
||||
@ -58,6 +59,9 @@ class V1(base.APIBase):
|
||||
nodes = [link.Link]
|
||||
"""Links to the nodes resource"""
|
||||
|
||||
server_groups = [link.Link]
|
||||
"""Links to the server groups resource"""
|
||||
|
||||
@staticmethod
|
||||
def convert():
|
||||
v1 = V1()
|
||||
@ -108,6 +112,14 @@ class V1(base.APIBase):
|
||||
'nodes', '',
|
||||
bookmark=True)
|
||||
]
|
||||
v1.server_groups = [link.Link.make_link('self',
|
||||
pecan.request.public_url,
|
||||
'server_groups', ''),
|
||||
link.Link.make_link('bookmark',
|
||||
pecan.request.public_url,
|
||||
'server_groups', '',
|
||||
bookmark=True)
|
||||
]
|
||||
return v1
|
||||
|
||||
|
||||
@ -120,6 +132,7 @@ class Controller(rest.RestController):
|
||||
keypairs = keypairs.KeyPairController()
|
||||
aggregates = aggregates.AggregateController()
|
||||
nodes = nodes.NodeController()
|
||||
server_groups = server_groups.ServerGroupController()
|
||||
|
||||
@expose.expose(V1)
|
||||
def get(self):
|
||||
|
34
mogan/api/controllers/v1/schemas/server_groups.py
Normal file
34
mogan/api/controllers/v1/schemas/server_groups.py
Normal file
@ -0,0 +1,34 @@
|
||||
# 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.
|
||||
|
||||
|
||||
from mogan.api.validation import parameter_types
|
||||
|
||||
create_server_group = {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'name': parameter_types.name,
|
||||
'policies': {
|
||||
'type': 'array',
|
||||
'items': [{
|
||||
'type': 'string',
|
||||
'enum': ['anti-affinity', 'affinity']}],
|
||||
'uniqueItems': True,
|
||||
'additionalItems': False,
|
||||
}
|
||||
},
|
||||
'required': ['name', 'policies'],
|
||||
'additionalProperties': False,
|
||||
}
|
155
mogan/api/controllers/v1/server_groups.py
Normal file
155
mogan/api/controllers/v1/server_groups.py
Normal file
@ -0,0 +1,155 @@
|
||||
# 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 six.moves import http_client
|
||||
import wsme
|
||||
from wsme import types as wtypes
|
||||
|
||||
from mogan.api.controllers import base
|
||||
from mogan.api.controllers import link
|
||||
from mogan.api.controllers.v1.schemas import server_groups as sg_schema
|
||||
from mogan.api.controllers.v1 import types
|
||||
from mogan.api import expose
|
||||
from mogan.api import validation
|
||||
from mogan.common import policy
|
||||
from mogan import objects
|
||||
|
||||
|
||||
class ServerGroup(base.APIBase):
|
||||
"""API representation of a server group.
|
||||
|
||||
This class enforces type checking and value constraints, and converts
|
||||
between the internal object model and the API representation of
|
||||
a server group.
|
||||
"""
|
||||
uuid = types.uuid
|
||||
"""The UUID of the server group"""
|
||||
|
||||
name = wtypes.text
|
||||
"""The name of the server group"""
|
||||
|
||||
project_id = types.uuid
|
||||
"""The project UUID of the server group"""
|
||||
|
||||
user_id = types.uuid
|
||||
"""The user UUID of the server group"""
|
||||
|
||||
policies = [wtypes.text]
|
||||
"""The policies of the server group"""
|
||||
|
||||
members = [types.uuid]
|
||||
"""The server members of the server group"""
|
||||
|
||||
links = wsme.wsattr([link.Link], readonly=True)
|
||||
"""A list containing a self link"""
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
self.fields = []
|
||||
for field in objects.ServerGroup.fields:
|
||||
# Skip fields we do not expose.
|
||||
if not hasattr(self, field):
|
||||
continue
|
||||
self.fields.append(field)
|
||||
setattr(self, field, kwargs.get(field, wtypes.Unset))
|
||||
|
||||
@classmethod
|
||||
def convert_with_links(cls, db_server_groups):
|
||||
server_group = ServerGroup(**db_server_groups.as_dict())
|
||||
url = pecan.request.public_url
|
||||
server_group.links = [link.Link.make_link('self', url,
|
||||
'server_groups',
|
||||
server_group.uuid),
|
||||
link.Link.make_link('bookmark', url,
|
||||
'server_groups',
|
||||
server_group.uuid,
|
||||
bookmark=True)
|
||||
]
|
||||
|
||||
return server_group
|
||||
|
||||
|
||||
class ServerGroupCollection(base.APIBase):
|
||||
"""API representation of a collection of server groups."""
|
||||
|
||||
server_groups = [ServerGroup]
|
||||
"""A list containing ServerGroup objects"""
|
||||
|
||||
@staticmethod
|
||||
def convert_with_links(server_groups, url=None, **kwargs):
|
||||
collection = ServerGroupCollection()
|
||||
collection.server_groups = [ServerGroup.convert_with_links(
|
||||
server_group) for server_group in server_groups]
|
||||
return collection
|
||||
|
||||
|
||||
class ServerGroupController(rest.RestController):
|
||||
"""REST controller for server groups."""
|
||||
|
||||
@policy.authorize_wsgi("mogan:server_group", "get_all")
|
||||
@expose.expose(ServerGroupCollection, types.boolean)
|
||||
def get_all(self, all_tenants=False):
|
||||
"""Retrieve a list of server groups."""
|
||||
|
||||
if pecan.request.context.is_admin and all_tenants:
|
||||
server_groups = objects.ServerGroupList.get_all(
|
||||
pecan.request.context)
|
||||
else:
|
||||
project_id = pecan.request.context.project_id
|
||||
server_groups = objects.ServerGroupList.get_by_project_id(
|
||||
pecan.request.context, project_id)
|
||||
return ServerGroupCollection.convert_with_links(server_groups)
|
||||
|
||||
@policy.authorize_wsgi("mogan:server_group", "create")
|
||||
@expose.expose(ServerGroup, body=types.jsontype,
|
||||
status_code=http_client.CREATED)
|
||||
def post(self, server_group):
|
||||
"""Create an new server group.
|
||||
|
||||
:param server_group: a server group within the request body.
|
||||
"""
|
||||
validation.check_schema(server_group, sg_schema.create_server_group)
|
||||
new_server_group = objects.ServerGroup(pecan.request.context,
|
||||
**server_group)
|
||||
new_server_group.project_id = pecan.request.context.project_id
|
||||
new_server_group.user_id = pecan.request.context.user_id
|
||||
new_server_group.create()
|
||||
# Set the HTTP Location Header
|
||||
pecan.response.location = link.build_url('server_groups',
|
||||
new_server_group.uuid)
|
||||
return ServerGroup.convert_with_links(new_server_group)
|
||||
|
||||
@policy.authorize_wsgi("mogan:server_group", "get_one")
|
||||
@expose.expose(ServerGroup, types.uuid)
|
||||
def get_one(self, server_group_uuid):
|
||||
"""Retrieve information about the given server group.
|
||||
|
||||
:param server_group_uuid: UUID of a server group.
|
||||
"""
|
||||
db_server_group = objects.ServerGroup.get_by_uuid(
|
||||
pecan.request.context, server_group_uuid)
|
||||
return ServerGroup.convert_with_links(db_server_group)
|
||||
|
||||
@policy.authorize_wsgi("mogan:server_group", "delete")
|
||||
@expose.expose(None, types.uuid, status_code=http_client.NO_CONTENT)
|
||||
def delete(self, server_group_uuid):
|
||||
"""Delete a server group.
|
||||
|
||||
:param server_group_uuid: UUID of a server group.
|
||||
"""
|
||||
db_server_group = objects.ServerGroup.get_by_uuid(
|
||||
pecan.request.context, server_group_uuid)
|
||||
db_server_group.destroy()
|
@ -171,6 +171,18 @@ server_policies = [
|
||||
policy.RuleDefault('mogan:node:get_all',
|
||||
'rule:admin_api',
|
||||
description='Get the nodes list'),
|
||||
policy.RuleDefault('mogan:server_group:get_all',
|
||||
'rule:default',
|
||||
description='Get the server group list'),
|
||||
policy.RuleDefault('mogan:server_group:get_one',
|
||||
'rule:default',
|
||||
description='Show a server group details'),
|
||||
policy.RuleDefault('mogan:server_group:create',
|
||||
'rule:default',
|
||||
description='Create a server group'),
|
||||
policy.RuleDefault('mogan:server_group:delete',
|
||||
'rule:default',
|
||||
description='Delete a server group'),
|
||||
]
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user