deb-manila/manila/api/v1/security_service.py
Valeriy Ponomaryov df6ca7ee5f Fix policy check for API 'security service update'
Manila API for update of security service reads policy for "show" operation
but should do it for "update" operation.

Change-Id: I675f834fcb75f3b7864094601e47c15f60a0864b
Closes-Bug: #1459631
2015-05-28 19:20:35 +03:00

219 lines
8.2 KiB
Python

# Copyright 2014 Mirantis Inc.
# 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.
"""The security service api."""
from oslo_log import log
import six
import webob
from webob import exc
from manila.api import common
from manila.api.openstack import wsgi
from manila.api.views import security_service as security_service_views
from manila.common import constants
from manila import db
from manila import exception
from manila.i18n import _
from manila.i18n import _LI
from manila import policy
RESOURCE_NAME = 'security_service'
LOG = log.getLogger(__name__)
class SecurityServiceController(wsgi.Controller):
"""The Shares API controller for the OpenStack API."""
_view_builder_class = security_service_views.ViewBuilder
def show(self, req, id):
"""Return data about the given security service."""
context = req.environ['manila.context']
try:
security_service = db.security_service_get(context, id)
policy.check_policy(context, RESOURCE_NAME, 'show',
security_service)
except exception.NotFound:
raise exc.HTTPNotFound()
return self._view_builder.detail(req, security_service)
def delete(self, req, id):
"""Delete a security service."""
context = req.environ['manila.context']
LOG.info(_LI("Delete security service with id: %s"),
id, context=context)
try:
security_service = db.security_service_get(context, id)
except exception.NotFound:
raise exc.HTTPNotFound()
share_nets = db.share_network_get_all_by_security_service(
context, id)
if share_nets:
# Cannot delete security service
# if it is assigned to share networks
raise exc.HTTPForbidden()
policy.check_policy(context, RESOURCE_NAME,
'delete', security_service)
db.security_service_delete(context, id)
return webob.Response(status_int=202)
def index(self, req):
"""Returns a summary list of security services."""
policy.check_policy(req.environ['manila.context'], RESOURCE_NAME,
'index')
return self._get_security_services(req, is_detail=False)
def detail(self, req):
"""Returns a detailed list of security services."""
policy.check_policy(req.environ['manila.context'], RESOURCE_NAME,
'detail')
return self._get_security_services(req, is_detail=True)
def _get_security_services(self, req, is_detail):
"""Returns a transformed list of security services.
The list gets transformed through view builder.
"""
context = req.environ['manila.context']
search_opts = {}
search_opts.update(req.GET)
# NOTE(vponomaryov): remove 'status' from search opts
# since it was removed from security service model.
search_opts.pop('status', None)
if 'share_network_id' in search_opts:
share_nw = db.share_network_get(context,
search_opts['share_network_id'])
security_services = share_nw['security_services']
del search_opts['share_network_id']
else:
if 'all_tenants' in search_opts:
policy.check_policy(context, RESOURCE_NAME,
'get_all_security_services')
security_services = db.security_service_get_all(context)
else:
security_services = db.security_service_get_all_by_project(
context, context.project_id)
search_opts.pop('all_tenants', None)
common.remove_invalid_options(
context,
search_opts,
self._get_security_services_search_options())
if search_opts:
results = []
not_found = object()
for ss in security_services:
if all(ss.get(opt, not_found) == value for opt, value in
six.iteritems(search_opts)):
results.append(ss)
security_services = results
limited_list = common.limited(security_services, req)
if is_detail:
security_services = self._view_builder.detail_list(
req, limited_list)
for ss in security_services['security_services']:
share_networks = db.share_network_get_all_by_security_service(
context,
ss['id'])
ss['share_networks'] = [sn['id'] for sn in share_networks]
else:
security_services = self._view_builder.summary_list(
req, limited_list)
return security_services
def _get_security_services_search_options(self):
return ('name', 'id', 'type', 'user',
'server', 'dns_ip', 'domain', )
def _share_servers_dependent_on_sn_exist(self, context,
security_service_id):
share_networks = db.share_network_get_all_by_security_service(
context, security_service_id)
for sn in share_networks:
if sn['share_servers']:
return True
return False
def update(self, req, id, body):
"""Update a security service."""
context = req.environ['manila.context']
if not body or 'security_service' not in body:
raise exc.HTTPUnprocessableEntity()
security_service_data = body['security_service']
valid_update_keys = (
'description',
'name'
)
try:
security_service = db.security_service_get(context, id)
policy.check_policy(context, RESOURCE_NAME, 'update',
security_service)
except exception.NotFound:
raise exc.HTTPNotFound()
if self._share_servers_dependent_on_sn_exist(context, id):
for item in security_service_data:
if item not in valid_update_keys:
msg = _("Cannot update security service %s. It is "
"attached to share network with share server "
"associated. Only 'name' and 'description' "
"fields are available for update.") % id
raise exc.HTTPForbidden(explanation=msg)
policy.check_policy(context, RESOURCE_NAME, 'update', security_service)
security_service = db.security_service_update(
context, id, security_service_data)
return self._view_builder.detail(req, security_service)
def create(self, req, body):
"""Creates a new security service."""
context = req.environ['manila.context']
policy.check_policy(context, RESOURCE_NAME, 'create')
if not self.is_valid_body(body, 'security_service'):
raise exc.HTTPUnprocessableEntity()
security_service_args = body['security_service']
security_srv_type = security_service_args.get('type')
allowed_types = constants.SECURITY_SERVICES_ALLOWED_TYPES
if security_srv_type not in allowed_types:
raise exception.InvalidInput(
reason=(_("Invalid type %(type)s specified for security "
"service. Valid types are %(types)s") %
{'type': security_srv_type,
'types': ','.join(allowed_types)}))
security_service_args['project_id'] = context.project_id
security_service = db.security_service_create(
context, security_service_args)
return self._view_builder.detail(req, security_service)
def create_resource():
return wsgi.Resource(SecurityServiceController())