Coverage for manila/api/v2/share_export_locations.py: 84%
150 statements
« prev ^ index » next coverage.py v7.11.0, created at 2026-02-18 22:19 +0000
« prev ^ index » next coverage.py v7.11.0, created at 2026-02-18 22:19 +0000
1# Copyright 2015 Mirantis inc.
2# All Rights Reserved.
3#
4# Licensed under the Apache License, Version 2.0 (the "License"); you may
5# not use this file except in compliance with the License. You may obtain
6# a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13# License for the specific language governing permissions and limitations
14# under the License.
16from oslo_config import cfg
17from oslo_log import log
18from webob import exc
20from manila.api.openstack import wsgi
21from manila.api.schemas import share_export_locations as schema
22from manila.api.v2 import metadata
23from manila.api import validation
24from manila.api.views import export_locations as export_locations_views
25from manila.db import api as db_api
26from manila import exception
27from manila.i18n import _
28from manila import policy
30LOG = log.getLogger(__name__)
31CONF = cfg.CONF
34@validation.validated
35class ShareExportLocationController(wsgi.Controller,
36 metadata.MetadataController):
37 """The Share Export Locations API controller."""
39 def __init__(self):
40 self._view_builder_class = export_locations_views.ViewBuilder
41 self.resource_name = 'share_export_location'
42 super(ShareExportLocationController, self).__init__()
43 self._conf_admin_only_metadata_keys = getattr(
44 CONF, 'admin_only_el_metadata', []
45 )
47 def _verify_share(self, context, share_id):
48 try:
49 share = db_api.share_get(context, share_id)
50 if not share['is_public']: 50 ↛ exitline 50 didn't return from function '_verify_share' because the condition on line 50 was always true
51 policy.check_policy(context, 'share', 'get', share)
52 except exception.NotFound:
53 msg = _("Share '%s' not found.") % share_id
54 raise exc.HTTPNotFound(explanation=msg)
56 @wsgi.Controller.authorize('index')
57 def _index(self, req, share_id, ignore_secondary_replicas=False):
58 context = req.environ['manila.context']
59 self._verify_share(context, share_id)
60 kwargs = {
61 'include_admin_only': context.is_admin,
62 'ignore_migration_destination': True,
63 'ignore_secondary_replicas': ignore_secondary_replicas,
64 }
65 export_locations = db_api.export_location_get_all_by_share_id(
66 context, share_id, **kwargs)
67 return self._view_builder.summary_list(req, export_locations)
69 @wsgi.Controller.authorize('show')
70 def _show(self, req, share_id, export_location_uuid,
71 ignore_secondary_replicas=False):
72 context = req.environ['manila.context']
73 self._verify_share(context, share_id)
74 try:
75 export_location = db_api.export_location_get_by_uuid(
76 context, export_location_uuid,
77 ignore_secondary_replicas=ignore_secondary_replicas)
78 except exception.ExportLocationNotFound:
79 msg = _("Export location '%s' not found.") % export_location_uuid
80 raise exc.HTTPNotFound(explanation=msg)
82 if export_location.is_admin_only and not context.is_admin:
83 raise exc.HTTPForbidden()
85 return self._view_builder.detail(req, export_location)
87 @wsgi.Controller.api_version('2.9', '2.46')
88 @validation.request_query_schema(schema.empty_query_schema)
89 @validation.response_body_schema(schema.index_response_body, '2.9', '2.13')
90 @validation.response_body_schema(schema.index_response_body_v214, '2.14')
91 def index(self, req, share_id):
92 """Return a list of export locations for share."""
93 return self._index(req, share_id)
95 @wsgi.Controller.api_version('2.47') # noqa: F811
96 # NOTE(jonathon): The new microversion removes secondary replicas from
97 # the results but doesn't change the schema, so we can re-use the schema
98 @validation.request_query_schema(schema.empty_query_schema)
99 @validation.response_body_schema(
100 schema.index_response_body_v214, '2.14', '2.86')
101 @validation.response_body_schema(schema.index_response_body_v287, '2.87')
102 def index(self, req, share_id): # pylint: disable=function-redefined # noqa F811
103 """Return a list of export locations for share."""
104 return self._index(req, share_id,
105 ignore_secondary_replicas=True)
107 @wsgi.Controller.api_version('2.9', '2.46')
108 @validation.request_query_schema(schema.empty_query_schema)
109 @validation.response_body_schema(schema.show_response_body, '2.9', '2.13')
110 @validation.response_body_schema(schema.show_response_body_v214, '2.14')
111 def show(self, req, share_id, export_location_uuid):
112 """Return data about the requested export location."""
113 return self._show(req, share_id, export_location_uuid)
115 @wsgi.Controller.api_version('2.47') # noqa: F811
116 # NOTE(jonathon): The new microversion removes secondary replicas from
117 # the results but doesn't change the schema, so we can re-use the schema
118 @validation.request_query_schema(schema.empty_query_schema)
119 @validation.response_body_schema(
120 schema.show_response_body_v214, '2.14', '2.86')
121 @validation.response_body_schema(schema.show_response_body_v287, '2.87')
122 def show(self, req, share_id, # pylint: disable=function-redefined # noqa F811
123 export_location_uuid):
124 """Return data about the requested export location."""
125 return self._show(req, share_id, export_location_uuid,
126 ignore_secondary_replicas=True)
128 def _validate_metadata_for_update(self, req, share_export_location,
129 metadata, delete=True):
130 persistent_keys = set(self._conf_admin_only_metadata_keys)
131 context = req.environ['manila.context']
132 if set(metadata).intersection(persistent_keys): 132 ↛ 143line 132 didn't jump to line 143 because the condition on line 132 was always true
133 try:
134 policy.check_policy(
135 context, 'share_export_location',
136 'update_admin_only_metadata')
137 except exception.PolicyNotAuthorized:
138 msg = _("Cannot set or update admin only metadata.")
139 LOG.exception(msg)
140 raise exc.HTTPForbidden(explanation=msg)
141 persistent_keys = []
143 current_export_metadata = db_api.export_location_metadata_get(
144 context, share_export_location)
145 if delete: 145 ↛ 151line 145 didn't jump to line 151 because the condition on line 145 was always true
146 _metadata = metadata
147 for key in persistent_keys: 147 ↛ 148line 147 didn't jump to line 148 because the loop on line 147 never started
148 if key in current_export_metadata:
149 _metadata[key] = current_export_metadata[key]
150 else:
151 metadata_copy = metadata.copy()
152 for key in persistent_keys:
153 metadata_copy.pop(key, None)
154 _metadata = current_export_metadata.copy()
155 _metadata.update(metadata_copy)
157 return _metadata
159 @wsgi.Controller.api_version("2.87")
160 @wsgi.Controller.authorize("get_metadata")
161 @validation.request_query_schema(schema.empty_query_schema)
162 @validation.response_body_schema(schema.show_metadata_response_body)
163 def index_metadata(self, req, share_id, resource_id):
164 """Returns the list of metadata for a given share export location."""
165 context = req.environ['manila.context']
166 self._verify_share(context, share_id)
167 return self._index_metadata(req, resource_id)
169 @wsgi.Controller.api_version("2.87")
170 @wsgi.Controller.authorize("update_metadata")
171 @validation.request_body_schema(schema.create_metadata_response_body)
172 @validation.response_body_schema(schema.create_metadata_response_body)
173 def create_metadata(self, req, share_id, resource_id, body):
174 """Create metadata for a given share export location."""
175 _metadata = self._validate_metadata_for_update(req, resource_id,
176 body['metadata'],
177 delete=False)
178 body['metadata'] = _metadata
179 context = req.environ['manila.context']
180 self._verify_share(context, share_id)
181 return self._create_metadata(req, resource_id, body)
183 @wsgi.Controller.api_version("2.87")
184 @wsgi.Controller.authorize("update_metadata")
185 @validation.request_body_schema(schema.update_metadata_request_body)
186 @validation.response_body_schema(schema.update_metadata_response_body)
187 def update_all_metadata(self, req, share_id, resource_id, body):
188 """Update entire metadata for a given share export location."""
189 _metadata = self._validate_metadata_for_update(req, resource_id,
190 body['metadata'])
191 body['metadata'] = _metadata
192 context = req.environ['manila.context']
193 self._verify_share(context, share_id)
194 return self._update_all_metadata(req, resource_id, body)
196 @wsgi.Controller.api_version("2.87")
197 @wsgi.Controller.authorize("update_metadata")
198 @validation.request_body_schema(schema.update_metadata_request_body)
199 @validation.response_body_schema(schema.update_metadata_response_body)
200 def update_metadata_item(self, req, share_id, resource_id, body, key):
201 """Update metadata item for a given share export location."""
202 _metadata = self._validate_metadata_for_update(req, resource_id,
203 body['metadata'],
204 delete=False)
205 body['metadata'] = _metadata
206 context = req.environ['manila.context']
207 self._verify_share(context, share_id)
208 return self._update_metadata_item(req, resource_id, body, key)
210 @wsgi.Controller.api_version("2.87")
211 @wsgi.Controller.authorize("get_metadata")
212 @validation.request_query_schema(schema.empty_query_schema)
213 @validation.response_body_schema(schema.show_metadata_response_body)
214 def show_metadata(self, req, share_id, resource_id, key):
215 """Show metadata for a given share export location."""
216 context = req.environ['manila.context']
217 self._verify_share(context, share_id)
218 return self._show_metadata(req, resource_id, key)
220 @wsgi.Controller.api_version("2.87")
221 @wsgi.Controller.authorize("delete_metadata")
222 @validation.response_body_schema(schema.delete_metadata_response_body)
223 def delete_metadata(self, req, share_id, resource_id, key):
224 """Delete metadata for a given share export location."""
225 context = req.environ['manila.context']
226 self._verify_share(context, share_id)
227 return self._delete_metadata(req, resource_id, key)
230def create_resource():
231 return wsgi.Resource(ShareExportLocationController())