def save(self): updates = self.cinder_obj_get_changes() if updates: volume_types.update(self._context, self.id, self.name, self.description) self.obj_reset_changes()
def _update(self, req, id, body): # Update description for a given volume type. context = req.environ["cinder.context"] authorize(context) if not self.is_valid_body(body, "volume_type"): raise webob.exc.HTTPBadRequest() vol_type = body["volume_type"] description = vol_type.get("description", None) if description is None: msg = _("Specify the description to update.") raise webob.exc.HTTPBadRequest(explanation=msg) try: # check it exists vol_type = volume_types.get_volume_type(context, id) volume_types.update(context, id, description) # get the updated vol_type = volume_types.get_volume_type(context, id) req.cache_resource(vol_type, name="types") self._notify_volume_type_info(context, "volume_type.update", vol_type) except exception.VolumeTypeNotFound as err: self._notify_volume_type_error(context, "volume_type.update", err, id=id) raise webob.exc.HTTPNotFound(explanation=six.text_type(err)) except exception.VolumeTypeExists as err: self._notify_volume_type_error(context, "volume_type.update", err, volume_type=vol_type) raise webob.exc.HTTPConflict(explanation=six.text_type(err)) except exception.VolumeTypeUpdateFailed as err: self._notify_volume_type_error(context, "volume_type.update", err, volume_type=vol_type) raise webob.exc.HTTPInternalServerError(explanation=six.text_type(err)) return self._view_builder.show(req, vol_type)
def _update(self, req, id, body): # Update description for a given volume type. context = req.environ['cinder.context'] authorize(context) self.assert_valid_body(body, 'volume_type') vol_type = body['volume_type'] description = vol_type.get('description') name = vol_type.get('name') is_public = vol_type.get('is_public') # Name and description can not be both None. # If name specified, name can not be empty. if name and len(name.strip()) == 0: msg = _("Volume type name can not be empty.") raise webob.exc.HTTPBadRequest(explanation=msg) if name is None and description is None and is_public is None: msg = _("Specify volume type name, description, is_public or " "a combination thereof.") raise webob.exc.HTTPBadRequest(explanation=msg) if is_public is not None and not utils.is_valid_boolstr(is_public): msg = _("Invalid value '%s' for is_public. Accepted values: " "True or False.") % is_public raise webob.exc.HTTPBadRequest(explanation=msg) if name: utils.check_string_length(name, 'Type name', min_length=1, max_length=255) if description is not None: utils.check_string_length(description, 'Type description', min_length=0, max_length=255) try: volume_types.update(context, id, name, description, is_public=is_public) # Get the updated vol_type = volume_types.get_volume_type(context, id) req.cache_resource(vol_type, name='types') self._notify_volume_type_info( context, 'volume_type.update', vol_type) except exception.VolumeTypeNotFound as err: self._notify_volume_type_error( context, 'volume_type.update', err, id=id) raise webob.exc.HTTPNotFound(explanation=six.text_type(err)) except exception.VolumeTypeExists as err: self._notify_volume_type_error( context, 'volume_type.update', err, volume_type=vol_type) raise webob.exc.HTTPConflict(explanation=six.text_type(err)) except exception.VolumeTypeUpdateFailed as err: self._notify_volume_type_error( context, 'volume_type.update', err, volume_type=vol_type) raise webob.exc.HTTPInternalServerError( explanation=six.text_type(err)) return self._view_builder.show(req, vol_type)
def test_update_volume_type_name(self, mock_update_quota): type_ref = volume_types.create( self.ctxt, self.vol_type1_name, self.vol_type1_specs, description=self.vol_type1_description ) new_type_name = self.vol_type1_name + "_updated" volume_types.update(self.ctxt, type_ref.id, new_type_name, None) mock_update_quota.assert_called_once_with(self.ctxt, self.vol_type1_name, new_type_name) volume_types.destroy(self.ctxt, type_ref.id)
def _update(self, req, id, body): # Update description for a given volume type. context = req.environ['cinder.context'] context.authorize(policy.MANAGE_POLICY) vol_type = body['volume_type'] description = vol_type.get('description') name = vol_type.get('name') is_public = vol_type.get('is_public') if is_public is not None: is_public = strutils.bool_from_string(is_public, strict=True) # If name specified, name can not be empty. if name and len(name.strip()) == 0: msg = _("Volume type name can not be empty.") raise webob.exc.HTTPBadRequest(explanation=msg) # Name, description and is_public can not be None. # Specify one of them, or a combination thereof. if name is None and description is None and is_public is None: msg = _("Specify volume type name, description, is_public or " "a combination thereof.") raise webob.exc.HTTPBadRequest(explanation=msg) try: volume_types.update(context, id, name, description, is_public=is_public) # Get the updated vol_type = volume_types.get_volume_type(context, id) req.cache_resource(vol_type, name='types') self._notify_volume_type_info(context, 'volume_type.update', vol_type) except exception.VolumeTypeNotFound as err: self._notify_volume_type_error(context, 'volume_type.update', err, id=id) # Not found exception will be handled at the wsgi level raise except exception.VolumeTypeExists as err: self._notify_volume_type_error(context, 'volume_type.update', err, volume_type=vol_type) raise webob.exc.HTTPConflict(explanation=six.text_type(err)) except exception.VolumeTypeUpdateFailed as err: self._notify_volume_type_error(context, 'volume_type.update', err, volume_type=vol_type) raise webob.exc.HTTPInternalServerError( explanation=six.text_type(err)) return self._view_builder.show(req, vol_type)
def test_update_volume_type_name(self, mock_update_quota): type_ref = volume_types.create(self.ctxt, self.vol_type1_name, self.vol_type1_specs, description=self.vol_type1_description) new_type_name = self.vol_type1_name + '_updated' volume_types.update(self.ctxt, type_ref.id, new_type_name, None) mock_update_quota.assert_called_once_with(self.ctxt, self.vol_type1_name, new_type_name) volume_types.destroy(self.ctxt, type_ref.id)
def test_volume_type_create_then_destroy(self): """Ensure volume types can be created and deleted.""" project_id = fake.PROJECT_ID prev_all_vtypes = volume_types.get_all_types(self.ctxt) # create type_ref = volume_types.create(self.ctxt, self.vol_type1_name, self.vol_type1_specs, description=self.vol_type1_description, projects=[project_id], is_public=False) new = volume_types.get_volume_type_by_name(self.ctxt, self.vol_type1_name) self.assertEqual(self.vol_type1_description, new['description']) for k, v in self.vol_type1_specs.items(): self.assertEqual(v, new['extra_specs'][k], 'one of fields does not match') new_all_vtypes = volume_types.get_all_types(self.ctxt) self.assertEqual( len(prev_all_vtypes) + 1, len(new_all_vtypes), 'drive type was not created') # Assert that volume type is associated to a project vol_type_access = db.volume_type_access_get_all( self.ctxt, type_ref['id']) self.assertIn(project_id, [a.project_id for a in vol_type_access]) # update new_type_name = self.vol_type1_name + '_updated' new_type_desc = self.vol_type1_description + '_updated' volume_types.update(self.ctxt, type_ref.id, new_type_name, new_type_desc) type_ref_updated = volume_types.get_volume_type(self.ctxt, type_ref.id) self.assertEqual(new_type_name, type_ref_updated['name']) self.assertEqual(new_type_desc, type_ref_updated['description']) # destroy volume_types.destroy(self.ctxt, type_ref['id']) new_all_vtypes = volume_types.get_all_types(self.ctxt) self.assertEqual(prev_all_vtypes, new_all_vtypes, 'drive type was not deleted') # Assert that associated volume type access is deleted successfully # on destroying the volume type with db_api.main_context_manager.reader.using(self.ctxt): vol_type_access = db_api._volume_type_access_query( self.ctxt).filter_by(volume_type_id=type_ref['id']).all() self.assertEqual([], vol_type_access)
def _update(self, req, id, body): # Update description for a given volume type. context = req.environ['cinder.context'] context.authorize(policy.MANAGE_POLICY) vol_type = body['volume_type'] description = vol_type.get('description') name = vol_type.get('name') is_public = vol_type.get('is_public') if is_public is not None: is_public = strutils.bool_from_string(is_public, strict=True) # If name specified, name can not be empty. if name and len(name.strip()) == 0: msg = _("Volume type name can not be empty.") raise webob.exc.HTTPBadRequest(explanation=msg) # Name, description and is_public can not be None. # Specify one of them, or a combination thereof. if name is None and description is None and is_public is None: msg = _("Specify volume type name, description, is_public or " "a combination thereof.") raise webob.exc.HTTPBadRequest(explanation=msg) try: volume_types.update(context, id, name, description, is_public=is_public) # Get the updated vol_type = volume_types.get_volume_type(context, id) req.cache_resource(vol_type, name='types') self._notify_volume_type_info( context, 'volume_type.update', vol_type) except exception.VolumeTypeNotFound as err: self._notify_volume_type_error( context, 'volume_type.update', err, id=id) # Not found exception will be handled at the wsgi level raise except exception.VolumeTypeExists as err: self._notify_volume_type_error( context, 'volume_type.update', err, volume_type=vol_type) raise webob.exc.HTTPConflict(explanation=six.text_type(err)) except exception.VolumeTypeUpdateFailed as err: self._notify_volume_type_error( context, 'volume_type.update', err, volume_type=vol_type) raise webob.exc.HTTPInternalServerError( explanation=six.text_type(err)) return self._view_builder.show(req, vol_type)
def test_volume_type_create_then_destroy(self): """Ensure volume types can be created and deleted.""" project_id = fake.PROJECT_ID prev_all_vtypes = volume_types.get_all_types(self.ctxt) # create type_ref = volume_types.create(self.ctxt, self.vol_type1_name, self.vol_type1_specs, description=self.vol_type1_description, projects=[project_id], is_public=False) new = volume_types.get_volume_type_by_name(self.ctxt, self.vol_type1_name) self.assertEqual(self.vol_type1_description, new['description']) for k, v in self.vol_type1_specs.items(): self.assertEqual(v, new['extra_specs'][k], 'one of fields does not match') new_all_vtypes = volume_types.get_all_types(self.ctxt) self.assertEqual(len(prev_all_vtypes) + 1, len(new_all_vtypes), 'drive type was not created') # Assert that volume type is associated to a project vol_type_access = db.volume_type_access_get_all(self.ctxt, type_ref['id']) self.assertIn(project_id, [a.project_id for a in vol_type_access]) # update new_type_name = self.vol_type1_name + '_updated' new_type_desc = self.vol_type1_description + '_updated' volume_types.update(self.ctxt, type_ref.id, new_type_name, new_type_desc) type_ref_updated = volume_types.get_volume_type(self.ctxt, type_ref.id) self.assertEqual(new_type_name, type_ref_updated['name']) self.assertEqual(new_type_desc, type_ref_updated['description']) # destroy volume_types.destroy(self.ctxt, type_ref['id']) new_all_vtypes = volume_types.get_all_types(self.ctxt) self.assertEqual(prev_all_vtypes, new_all_vtypes, 'drive type was not deleted') # Assert that associated volume type access is deleted successfully # on destroying the volume type vol_type_access = db_api._volume_type_access_query( self.ctxt).filter_by(volume_type_id=type_ref['id']).all() self.assertFalse(vol_type_access)
def test_volume_type_create_then_destroy(self): """Ensure volume types can be created and deleted.""" prev_all_vtypes = volume_types.get_all_types(self.ctxt) # create type_ref = volume_types.create( self.ctxt, self.vol_type1_name, self.vol_type1_specs, description=self.vol_type1_description ) new = volume_types.get_volume_type_by_name(self.ctxt, self.vol_type1_name) LOG.info(_("Given data: %s"), self.vol_type1_specs) LOG.info(_("Result data: %s"), new) self.assertEqual(self.vol_type1_description, new["description"]) for k, v in self.vol_type1_specs.items(): self.assertEqual(v, new["extra_specs"][k], "one of fields does not match") new_all_vtypes = volume_types.get_all_types(self.ctxt) self.assertEqual(len(prev_all_vtypes) + 1, len(new_all_vtypes), "drive type was not created") # update new_type_name = self.vol_type1_name + "_updated" new_type_desc = self.vol_type1_description + "_updated" type_ref_updated = volume_types.update(self.ctxt, type_ref.id, new_type_name, new_type_desc) self.assertEqual(new_type_name, type_ref_updated["name"]) self.assertEqual(new_type_desc, type_ref_updated["description"]) # destroy volume_types.destroy(self.ctxt, type_ref["id"]) new_all_vtypes = volume_types.get_all_types(self.ctxt) self.assertEqual(prev_all_vtypes, new_all_vtypes, "drive type was not deleted")
def test_volume_type_create_then_destroy_with_non_admin(self): """Ensure volume types can be created and deleted by non-admin user. If a non-admn user is authorized at API, volume type operations should be permitted. """ prev_all_vtypes = volume_types.get_all_types(self.ctxt) self.ctxt = context.RequestContext("fake", "fake", is_admin=False) # create type_ref = volume_types.create( self.ctxt, self.vol_type1_name, self.vol_type1_specs, description=self.vol_type1_description ) new = volume_types.get_volume_type_by_name(self.ctxt, self.vol_type1_name) self.assertEqual(self.vol_type1_description, new["description"]) new_all_vtypes = volume_types.get_all_types(self.ctxt) self.assertEqual(len(prev_all_vtypes) + 1, len(new_all_vtypes), "drive type was not created") # update new_type_name = self.vol_type1_name + "_updated" new_type_desc = self.vol_type1_description + "_updated" type_ref_updated = volume_types.update(self.ctxt, type_ref.id, new_type_name, new_type_desc) self.assertEqual(new_type_name, type_ref_updated["name"]) self.assertEqual(new_type_desc, type_ref_updated["description"]) # destroy volume_types.destroy(self.ctxt, type_ref["id"]) new_all_vtypes = volume_types.get_all_types(self.ctxt) self.assertEqual(prev_all_vtypes, new_all_vtypes, "drive type was not deleted")
def _update(self, req, id, body): # Update description for a given volume type. context = req.environ['cinder.context'] authorize(context) if not self.is_valid_body(body, 'volume_type'): raise webob.exc.HTTPBadRequest() vol_type = body['volume_type'] description = vol_type.get('description', None) if description is None: msg = _("Specify the description to update.") raise webob.exc.HTTPBadRequest(explanation=msg) try: # check it exists vol_type = volume_types.get_volume_type(context, id) volume_types.update(context, id, description) # get the updated vol_type = volume_types.get_volume_type(context, id) req.cache_resource(vol_type, name='types') self._notify_volume_type_info(context, 'volume_type.update', vol_type) except exception.VolumeTypeNotFound as err: self._notify_volume_type_error(context, 'volume_type.update', err, id=id) raise webob.exc.HTTPNotFound(explanation=six.text_type(err)) except exception.VolumeTypeExists as err: self._notify_volume_type_error(context, 'volume_type.update', err, volume_type=vol_type) raise webob.exc.HTTPConflict(explanation=six.text_type(err)) except exception.VolumeTypeUpdateFailed as err: self._notify_volume_type_error(context, 'volume_type.update', err, volume_type=vol_type) raise webob.exc.HTTPInternalServerError( explanation=six.text_type(err)) return self._view_builder.show(req, vol_type)
def _update(self, req, id, body): # Update description for a given volume type. context = req.environ['cinder.context'] context.authorize(policy.MANAGE_POLICY) vol_type = body['volume_type'] description = vol_type.get('description') name = vol_type.get('name') is_public = vol_type.get('is_public') if is_public is not None: is_public = strutils.bool_from_string(is_public, strict=True) try: volume_types.update(context, id, name, description, is_public=is_public) # Get the updated vol_type = volume_types.get_volume_type(context, id) req.cache_resource(vol_type, name='types') self._notify_volume_type_info(context, 'volume_type.update', vol_type) except exception.VolumeTypeNotFound as err: self._notify_volume_type_error(context, 'volume_type.update', err, id=id) # Not found exception will be handled at the wsgi level raise except exception.VolumeTypeExists as err: self._notify_volume_type_error(context, 'volume_type.update', err, volume_type=vol_type) raise webob.exc.HTTPConflict(explanation=six.text_type(err)) except exception.VolumeTypeUpdateFailed as err: self._notify_volume_type_error(context, 'volume_type.update', err, volume_type=vol_type) raise webob.exc.HTTPInternalServerError( explanation=six.text_type(err)) return self._view_builder.show(req, vol_type)
def _update(self, req, id, body): # Update description for a given volume type. context = req.environ["cinder.context"] authorize(context) self.assert_valid_body(body, "volume_type") vol_type = body["volume_type"] description = vol_type.get("description") name = vol_type.get("name") # Name and description can not be both None. # If name specified, name can not be empty. if name and len(name.strip()) == 0: msg = _("Volume type name can not be empty.") raise webob.exc.HTTPBadRequest(explanation=msg) if name is None and description is None: msg = _("Specify either volume type name and/or description.") raise webob.exc.HTTPBadRequest(explanation=msg) if name: utils.check_string_length(name, "Type name", min_length=1, max_length=255) if description is not None: utils.check_string_length(description, "Type description", min_length=0, max_length=255) try: volume_types.update(context, id, name, description) # Get the updated vol_type = volume_types.get_volume_type(context, id) req.cache_resource(vol_type, name="types") self._notify_volume_type_info(context, "volume_type.update", vol_type) except exception.VolumeTypeNotFound as err: self._notify_volume_type_error(context, "volume_type.update", err, id=id) raise webob.exc.HTTPNotFound(explanation=six.text_type(err)) except exception.VolumeTypeExists as err: self._notify_volume_type_error(context, "volume_type.update", err, volume_type=vol_type) raise webob.exc.HTTPConflict(explanation=six.text_type(err)) except exception.VolumeTypeUpdateFailed as err: self._notify_volume_type_error(context, "volume_type.update", err, volume_type=vol_type) raise webob.exc.HTTPInternalServerError(explanation=six.text_type(err)) return self._view_builder.show(req, vol_type)
def _update(self, req, id, body): # Update description for a given volume type. context = req.environ['cinder.context'] authorize(context) if not self.is_valid_body(body, 'volume_type'): raise webob.exc.HTTPBadRequest() vol_type = body['volume_type'] description = vol_type.get('description') name = vol_type.get('name') # Name and description can not be both None. # If name specified, name can not be empty. if name and len(name.strip()) == 0: msg = _("Volume type name can not be empty.") raise webob.exc.HTTPBadRequest(explanation=msg) if name is None and description is None: msg = _("Specify either volume type name and/or description.") raise webob.exc.HTTPBadRequest(explanation=msg) try: volume_types.update(context, id, name, description) # Get the updated vol_type = volume_types.get_volume_type(context, id) req.cache_resource(vol_type, name='types') self._notify_volume_type_info( context, 'volume_type.update', vol_type) except exception.VolumeTypeNotFound as err: self._notify_volume_type_error( context, 'volume_type.update', err, id=id) raise webob.exc.HTTPNotFound(explanation=six.text_type(err)) except exception.VolumeTypeExists as err: self._notify_volume_type_error( context, 'volume_type.update', err, volume_type=vol_type) raise webob.exc.HTTPConflict(explanation=six.text_type(err)) except exception.VolumeTypeUpdateFailed as err: self._notify_volume_type_error( context, 'volume_type.update', err, volume_type=vol_type) raise webob.exc.HTTPInternalServerError( explanation=six.text_type(err)) return self._view_builder.show(req, vol_type)
def test_volume_type_create_then_destroy_with_non_admin(self): """Ensure volume types can be created and deleted by non-admin user. If a non-admn user is authorized at API, volume type operations should be permitted. """ prev_all_vtypes = volume_types.get_all_types(self.ctxt) self.ctxt = context.RequestContext('fake', 'fake', is_admin=False) # create type_ref = volume_types.create(self.ctxt, self.vol_type1_name, self.vol_type1_specs, description=self.vol_type1_description) new = volume_types.get_volume_type_by_name(self.ctxt, self.vol_type1_name) self.assertEqual(self.vol_type1_description, new['description']) new_all_vtypes = volume_types.get_all_types(self.ctxt) self.assertEqual(len(prev_all_vtypes) + 1, len(new_all_vtypes), 'drive type was not created') # update new_type_name = self.vol_type1_name + '_updated' new_type_desc = self.vol_type1_description + '_updated' volume_types.update(self.ctxt, type_ref.id, new_type_name, new_type_desc) type_ref_updated = volume_types.get_volume_type(self.ctxt, type_ref.id) self.assertEqual(new_type_name, type_ref_updated['name']) self.assertEqual(new_type_desc, type_ref_updated['description']) # destroy volume_types.destroy(self.ctxt, type_ref['id']) new_all_vtypes = volume_types.get_all_types(self.ctxt) self.assertEqual(prev_all_vtypes, new_all_vtypes, 'drive type was not deleted')
def test_volume_type_create_then_destroy(self): """Ensure volume types can be created and deleted.""" prev_all_vtypes = volume_types.get_all_types(self.ctxt) # create type_ref = volume_types.create(self.ctxt, self.vol_type1_name, self.vol_type1_specs, description=self.vol_type1_description) new = volume_types.get_volume_type_by_name(self.ctxt, self.vol_type1_name) LOG.info(_("Given data: %s"), self.vol_type1_specs) LOG.info(_("Result data: %s"), new) self.assertEqual(self.vol_type1_description, new['description']) for k, v in self.vol_type1_specs.iteritems(): self.assertEqual(v, new['extra_specs'][k], 'one of fields does not match') new_all_vtypes = volume_types.get_all_types(self.ctxt) self.assertEqual(len(prev_all_vtypes) + 1, len(new_all_vtypes), 'drive type was not created') # update new_type_name = self.vol_type1_name + '_updated' new_type_desc = self.vol_type1_description + '_updated' type_ref_updated = volume_types.update(self.ctxt, type_ref.id, new_type_name, new_type_desc) self.assertEqual(new_type_name, type_ref_updated['name']) self.assertEqual(new_type_desc, type_ref_updated['description']) # destroy volume_types.destroy(self.ctxt, type_ref['id']) new_all_vtypes = volume_types.get_all_types(self.ctxt) self.assertEqual(prev_all_vtypes, new_all_vtypes, 'drive type was not deleted')
def test_volume_type_create_then_destroy(self): """Ensure volume types can be created and deleted.""" prev_all_vtypes = volume_types.get_all_types(self.ctxt) # create type_ref = volume_types.create(self.ctxt, self.vol_type1_name, self.vol_type1_specs, description=self.vol_type1_description) new = volume_types.get_volume_type_by_name(self.ctxt, self.vol_type1_name) LOG.info(_("Given data: %s"), self.vol_type1_specs) LOG.info(_("Result data: %s"), new) self.assertEqual(self.vol_type1_description, new['description']) for k, v in self.vol_type1_specs.iteritems(): self.assertEqual(v, new['extra_specs'][k], 'one of fields does not match') new_all_vtypes = volume_types.get_all_types(self.ctxt) self.assertEqual(len(prev_all_vtypes) + 1, len(new_all_vtypes), 'drive type was not created') # update new_type_desc = self.vol_type1_description + '_updated' type_ref_updated = volume_types.update(self.ctxt, type_ref.id, new_type_desc) self.assertEqual(new_type_desc, type_ref_updated['description']) # destroy volume_types.destroy(self.ctxt, type_ref['id']) new_all_vtypes = volume_types.get_all_types(self.ctxt) self.assertEqual(prev_all_vtypes, new_all_vtypes, 'drive type was not deleted')