Allow to delete blobs with external urls

This patch support new API request to delete blobs from
artifact:
DELETE /artifacts/{type_name}/{artifact_id}/{blob_name}

if user wants to delete internal blob glare raises 403 error.

Co-Authored-By: Mike Fedosin <mikhail.fedosin.ext@nokia.com>

Change-Id: I8daa686df3a05158f59b33546397b23a494d5ab1
This commit is contained in:
Idan Narotzki 2017-08-07 16:03:01 +00:00 committed by Mike Fedosin
parent 081e07a1b7
commit abedb2836d
6 changed files with 102 additions and 1 deletions

View File

@ -275,3 +275,52 @@ class AddLocation(command.ShowOne):
else:
data_to_display.update(data[parsed_args.blob_property])
return self.dict2columns(data_to_display)
class RemoveLocation(command.ShowOne):
"""Remove external location"""
def get_parser(self, prog_name):
parser = super(RemoveLocation, self).get_parser(prog_name)
parser.add_argument(
'type_name',
metavar='<TYPE_NAME>',
action=TypeMapperAction,
help='Name of artifact type.',
),
parser.add_argument(
'name',
metavar='<NAME>',
help='Name or id of the artifact to download.',
),
parser.add_argument(
'--artifact-version', '-V',
metavar='<VERSION>',
default='latest',
help='Version of the artifact.',
),
parser.add_argument(
'--id', '-i',
action='store_true',
help='The specified id of the artifact.',
),
parser.add_argument(
'--blob-property', '-p',
metavar='<BLOB_PROPERTY>',
help='Name of the blob field.'
)
return parser
def take_action(self, parsed_args):
LOG.debug('take_action({0})'.format(parsed_args))
client = self.app.client_manager.artifact
af_id = utils.get_artifact_id(client, parsed_args)
if not parsed_args.blob_property:
parsed_args.blob_property = _default_blob_property(
parsed_args.type_name)
client.artifacts.remove_external_location(
af_id,
parsed_args.blob_property,
type_name=parsed_args.type_name)

View File

@ -293,7 +293,8 @@ class GlareShell(app.App):
'schema': glareclient.osc.v1.artifacts.TypeSchema,
'upload': glareclient.osc.v1.blobs.UploadBlob,
'download': glareclient.osc.v1.blobs.DownloadBlob,
'location': glareclient.osc.v1.blobs.AddLocation
'location': glareclient.osc.v1.blobs.AddLocation,
'remove-location': glareclient.osc.v1.blobs.RemoveLocation
}

View File

@ -221,3 +221,31 @@ class TestAddLocation(TestBlobs):
columns, data = self.cmd.take_action(parsed_args)
self.app.client_manager.artifact.artifacts.get = fakes.mock_get
self.assertEqual(self.COLUMNS, columns)
class TestRemoveLocation(TestBlobs):
def setUp(self):
super(TestRemoveLocation, self).setUp()
self.blob_mock.call.return_value = \
api_art.Controller(self.http, type_name='images')
# Command to test
self.cmd = osc_blob.RemoveLocation(self.app, None)
def test_remove_location(self):
arglist = ['images',
'fc15c365-d4f9-4b8b-a090-d9e230f1f6ba', '--id']
verify = [('type_name', 'images'),
('name', 'fc15c365-d4f9-4b8b-a090-d9e230f1f6ba'),
('id', True)]
parsed_args = self.check_parser(self.cmd, arglist, verify)
self.assertIsNone(self.cmd.take_action(parsed_args))
def test_remove_dict_location(self):
arglist = ['images', '--blob-property', 'nested_templates/blob',
'fc15c365-d4f9-4b8b-a090-d9e230f1f6ba', '--id']
verify = [('type_name', 'images'),
('name', 'fc15c365-d4f9-4b8b-a090-d9e230f1f6ba'),
('id', True)]
parsed_args = self.check_parser(self.cmd, arglist, verify)
self.assertIsNone(self.cmd.take_action(parsed_args))

View File

@ -151,6 +151,16 @@ class TestController(testtools.TestCase):
'application/vnd+openstack.glare-custom-location+json'})
self.assertIsNone(resp)
def test_remove_external_location(self):
art_id = '3a4560a1-e585-443e-9b39-553b46ec92a8'
resp = self.c.remove_external_location(
art_id, 'image',
type_name='images')
self.c.http_client.delete.assert_called_once_with(
'/artifacts/checked_name/'
'3a4560a1-e585-443e-9b39-553b46ec92a8/image')
self.assertIsNone(resp)
def test_add_tag(self):
art_id = '07a679d8-d0a8-45ff-8d6e-2f32f2097b7c'
d = {'tags': ['a', 'b', 'c']}

View File

@ -267,6 +267,18 @@ class Controller(object):
raise exc.HTTPBadRequest("json is malformed.")
self.http_client.put(url, headers=hdrs, data=data)
def remove_external_location(self, artifact_id, blob_property,
type_name=None):
"""Remove external location.
:param artifact_id: ID of the artifact with external location
to be removed
:param blob_property: blob property name
"""
type_name = self._check_type_name(type_name)
url = '/artifacts/%s/%s/%s' % (type_name, artifact_id, blob_property)
self.http_client.delete(url)
def download_blob(self, artifact_id, blob_property, type_name=None,
do_checksum=True):
"""Get blob data.

View File

@ -49,6 +49,7 @@ openstack.artifact.v1 =
artifact_publish = glareclient.osc.v1.artifacts:PublishArtifact
artifact_upload = glareclient.osc.v1.blobs:UploadBlob
artifact_location = glareclient.osc.v1.blobs:AddLocation
artifact_remove-location = glareclient.osc.v1.blobs:RemoveLocation
artifact_download = glareclient.osc.v1.blobs:DownloadBlob
artifact_type-list = glareclient.osc.v1.artifacts:TypeList
artifact_schema = glareclient.osc.v1.artifacts:TypeSchema