13f9e02a64
Blueprint make-authz-orthogonal This patch implements part #3 of this blueprint, according to its specification. It does so by allowing the view generator in the API layer to strip off fields which do not satify authorization policies. Also, some checks in unit tests for plugins relied on the capability of the plugin to invoke directly the policy engine. This checks have been removed and replaced by equivalent unit tests. Finally, this patch required changes to most test cases for API extensions in order to ensure the resource attribute map was updated with the extension's attributes Change-Id: I1ef94a8a628d34697254b68d7a539bd1c636876e
164 lines
5.2 KiB
Python
164 lines
5.2 KiB
Python
# Copyright (c) 2013 OpenStack Foundation.
|
|
#
|
|
# 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 abc import abstractmethod
|
|
|
|
from quantum.api import extensions
|
|
from quantum.api.v2 import attributes as attr
|
|
from quantum.api.v2 import base
|
|
from quantum.common import exceptions
|
|
from quantum import manager
|
|
|
|
|
|
# Attribute Map
|
|
RESOURCE_NAME = 'agent'
|
|
RESOURCE_ATTRIBUTE_MAP = {
|
|
RESOURCE_NAME + 's': {
|
|
'id': {'allow_post': False, 'allow_put': False,
|
|
'validate': {'type:uuid': None},
|
|
'is_visible': True},
|
|
'agent_type': {'allow_post': False, 'allow_put': False,
|
|
'is_visible': True},
|
|
'binary': {'allow_post': False, 'allow_put': False,
|
|
'is_visible': True},
|
|
'topic': {'allow_post': False, 'allow_put': False,
|
|
'is_visible': True},
|
|
'host': {'allow_post': False, 'allow_put': False,
|
|
'is_visible': True},
|
|
'admin_state_up': {'allow_post': False, 'allow_put': True,
|
|
'convert_to': attr.convert_to_boolean,
|
|
'is_visible': True},
|
|
'created_at': {'allow_post': False, 'allow_put': False,
|
|
'is_visible': True},
|
|
'started_at': {'allow_post': False, 'allow_put': False,
|
|
'is_visible': True},
|
|
'heartbeat_timestamp': {'allow_post': False, 'allow_put': False,
|
|
'is_visible': True},
|
|
'alive': {'allow_post': False, 'allow_put': False,
|
|
'is_visible': True},
|
|
'configurations': {'allow_post': False, 'allow_put': False,
|
|
'is_visible': True},
|
|
'description': {'allow_post': False, 'allow_put': True,
|
|
'is_visible': True,
|
|
'validate': {'type:string': None}},
|
|
},
|
|
}
|
|
|
|
|
|
class AgentNotFound(exceptions.NotFound):
|
|
message = _("Agent %(id)s could not be found")
|
|
|
|
|
|
class AgentNotFoundByTypeHost(exceptions.NotFound):
|
|
message = _("Agent with agent_type=%(agent_type)s and host=%(host)s "
|
|
"could not be found")
|
|
|
|
|
|
class MultipleAgentFoundByTypeHost(exceptions.Conflict):
|
|
message = _("Multiple agents with agent_type=%(agent_type)s and "
|
|
"host=%(host)s found")
|
|
|
|
|
|
class Agent(object):
|
|
"""Agent management extension."""
|
|
|
|
@classmethod
|
|
def get_name(cls):
|
|
return "agent"
|
|
|
|
@classmethod
|
|
def get_alias(cls):
|
|
return "agent"
|
|
|
|
@classmethod
|
|
def get_description(cls):
|
|
return "The agent management extension."
|
|
|
|
@classmethod
|
|
def get_namespace(cls):
|
|
return "http://docs.openstack.org/ext/agent/api/v2.0"
|
|
|
|
@classmethod
|
|
def get_updated(cls):
|
|
return "2013-02-03T10:00:00-00:00"
|
|
|
|
@classmethod
|
|
def get_resources(cls):
|
|
"""Returns Ext Resources."""
|
|
my_plurals = [(key, key[:-1]) for key in RESOURCE_ATTRIBUTE_MAP.keys()]
|
|
attr.PLURALS.update(dict(my_plurals))
|
|
plugin = manager.QuantumManager.get_plugin()
|
|
params = RESOURCE_ATTRIBUTE_MAP.get(RESOURCE_NAME + 's')
|
|
controller = base.create_resource(RESOURCE_NAME + 's',
|
|
RESOURCE_NAME,
|
|
plugin, params
|
|
)
|
|
|
|
ex = extensions.ResourceExtension(RESOURCE_NAME + 's',
|
|
controller)
|
|
|
|
return [ex]
|
|
|
|
def get_extended_resources(self, version):
|
|
if version == "2.0":
|
|
return RESOURCE_ATTRIBUTE_MAP
|
|
else:
|
|
return {}
|
|
|
|
|
|
class AgentPluginBase(object):
|
|
"""REST API to operate the Agent.
|
|
|
|
All of method must be in an admin context.
|
|
"""
|
|
|
|
def create_agent(self, context, agent):
|
|
"""Create agent.
|
|
|
|
This operation is not allow in REST API.
|
|
@raise exceptions.BadRequest:
|
|
"""
|
|
raise exceptions.BadRequest
|
|
|
|
@abstractmethod
|
|
def delete_agent(self, context, id):
|
|
"""Delete agent.
|
|
|
|
Agents register themselves on reporting state.
|
|
But if a agent does not report its status
|
|
for a long time (for example, it is dead for ever. ),
|
|
admin can remove it. Agents must be disabled before
|
|
being removed.
|
|
"""
|
|
pass
|
|
|
|
@abstractmethod
|
|
def update_agent(self, context, agent):
|
|
"""Disable or Enable the agent.
|
|
|
|
Discription also can be updated. Some agents cannot be disabled, such
|
|
as plugins, services. An error code should be reported in this case.
|
|
@raise exceptions.BadRequest:
|
|
"""
|
|
pass
|
|
|
|
@abstractmethod
|
|
def get_agents(self, context, filters=None, fields=None):
|
|
pass
|
|
|
|
@abstractmethod
|
|
def get_agent(self, context, id, fields=None):
|
|
pass
|