1#
2#    Licensed under the Apache License, Version 2.0 (the "License"); you may
3#    not use this file except in compliance with the License. You may obtain
4#    a copy of the License at
5#
6#         http://www.apache.org/licenses/LICENSE-2.0
7#
8#    Unless required by applicable law or agreed to in writing, software
9#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11#    License for the specific language governing permissions and limitations
12#    under the License.
13
14"""The consistencygroups V3 API."""
15
16from oslo_log import log as logging
17from six.moves import http_client
18import webob
19from webob import exc
20
21from cinder.api.contrib import consistencygroups as cg_v2
22from cinder.api import microversions as mv
23from cinder.api.openstack import wsgi
24from cinder.i18n import _
25from cinder.policies import groups as group_policy
26
27LOG = logging.getLogger(__name__)
28
29
30class ConsistencyGroupsController(cg_v2.ConsistencyGroupsController):
31    """The ConsistencyGroups API controller for the OpenStack API V3."""
32
33    def _check_update_parameters_v3(self, req, name, description, add_volumes,
34                                    remove_volumes):
35        allow_empty = req.api_version_request.matches(
36            mv.CG_UPDATE_BLANK_PROPERTIES, None)
37        if allow_empty:
38            if (name is None and description is None
39                    and not add_volumes and not remove_volumes):
40                msg = _("Must specify one or more of the following keys to "
41                        "update: name, description, "
42                        "add_volumes, remove_volumes.")
43                raise exc.HTTPBadRequest(explanation=msg)
44        else:
45            if not (name or description or add_volumes or remove_volumes):
46                msg = _("Name, description, add_volumes, and remove_volumes "
47                        "can not be all empty in the request body.")
48                raise exc.HTTPBadRequest(explanation=msg)
49        return allow_empty
50
51    def update(self, req, id, body):
52        """Update the consistency group.
53
54        Expected format of the input parameter 'body':
55
56        .. code-block:: json
57
58            {
59                "consistencygroup":
60                {
61                    "name": "my_cg",
62                    "description": "My consistency group",
63                    "add_volumes": "volume-uuid-1,volume-uuid-2,...",
64                    "remove_volumes": "volume-uuid-8,volume-uuid-9,..."
65                }
66            }
67
68        """
69        LOG.debug('Update called for consistency group %s.', id)
70        if not body:
71            msg = _("Missing request body.")
72            raise exc.HTTPBadRequest(explanation=msg)
73
74        self.assert_valid_body(body, 'consistencygroup')
75        context = req.environ['cinder.context']
76        group = self._get(context, id)
77        context.authorize(group_policy.UPDATE_POLICY, target_obj=group)
78        consistencygroup = body.get('consistencygroup', None)
79        self.validate_name_and_description(consistencygroup)
80        name = consistencygroup.get('name', None)
81        description = consistencygroup.get('description', None)
82        add_volumes = consistencygroup.get('add_volumes', None)
83        remove_volumes = consistencygroup.get('remove_volumes', None)
84
85        allow_empty = self._check_update_parameters_v3(req, name,
86                                                       description,
87                                                       add_volumes,
88                                                       remove_volumes)
89        self._update(context, group, name, description, add_volumes,
90                     remove_volumes, allow_empty)
91        return webob.Response(status_int=http_client.ACCEPTED)
92
93
94def create_resource():
95    return wsgi.Resource(ConsistencyGroupsController())
96