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:
parent
081e07a1b7
commit
abedb2836d
@ -275,3 +275,52 @@ class AddLocation(command.ShowOne):
|
|||||||
else:
|
else:
|
||||||
data_to_display.update(data[parsed_args.blob_property])
|
data_to_display.update(data[parsed_args.blob_property])
|
||||||
return self.dict2columns(data_to_display)
|
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)
|
||||||
|
@ -293,7 +293,8 @@ class GlareShell(app.App):
|
|||||||
'schema': glareclient.osc.v1.artifacts.TypeSchema,
|
'schema': glareclient.osc.v1.artifacts.TypeSchema,
|
||||||
'upload': glareclient.osc.v1.blobs.UploadBlob,
|
'upload': glareclient.osc.v1.blobs.UploadBlob,
|
||||||
'download': glareclient.osc.v1.blobs.DownloadBlob,
|
'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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -221,3 +221,31 @@ class TestAddLocation(TestBlobs):
|
|||||||
columns, data = self.cmd.take_action(parsed_args)
|
columns, data = self.cmd.take_action(parsed_args)
|
||||||
self.app.client_manager.artifact.artifacts.get = fakes.mock_get
|
self.app.client_manager.artifact.artifacts.get = fakes.mock_get
|
||||||
self.assertEqual(self.COLUMNS, columns)
|
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))
|
||||||
|
@ -151,6 +151,16 @@ class TestController(testtools.TestCase):
|
|||||||
'application/vnd+openstack.glare-custom-location+json'})
|
'application/vnd+openstack.glare-custom-location+json'})
|
||||||
self.assertIsNone(resp)
|
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):
|
def test_add_tag(self):
|
||||||
art_id = '07a679d8-d0a8-45ff-8d6e-2f32f2097b7c'
|
art_id = '07a679d8-d0a8-45ff-8d6e-2f32f2097b7c'
|
||||||
d = {'tags': ['a', 'b', 'c']}
|
d = {'tags': ['a', 'b', 'c']}
|
||||||
|
@ -267,6 +267,18 @@ class Controller(object):
|
|||||||
raise exc.HTTPBadRequest("json is malformed.")
|
raise exc.HTTPBadRequest("json is malformed.")
|
||||||
self.http_client.put(url, headers=hdrs, data=data)
|
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,
|
def download_blob(self, artifact_id, blob_property, type_name=None,
|
||||||
do_checksum=True):
|
do_checksum=True):
|
||||||
"""Get blob data.
|
"""Get blob data.
|
||||||
|
@ -49,6 +49,7 @@ openstack.artifact.v1 =
|
|||||||
artifact_publish = glareclient.osc.v1.artifacts:PublishArtifact
|
artifact_publish = glareclient.osc.v1.artifacts:PublishArtifact
|
||||||
artifact_upload = glareclient.osc.v1.blobs:UploadBlob
|
artifact_upload = glareclient.osc.v1.blobs:UploadBlob
|
||||||
artifact_location = glareclient.osc.v1.blobs:AddLocation
|
artifact_location = glareclient.osc.v1.blobs:AddLocation
|
||||||
|
artifact_remove-location = glareclient.osc.v1.blobs:RemoveLocation
|
||||||
artifact_download = glareclient.osc.v1.blobs:DownloadBlob
|
artifact_download = glareclient.osc.v1.blobs:DownloadBlob
|
||||||
artifact_type-list = glareclient.osc.v1.artifacts:TypeList
|
artifact_type-list = glareclient.osc.v1.artifacts:TypeList
|
||||||
artifact_schema = glareclient.osc.v1.artifacts:TypeSchema
|
artifact_schema = glareclient.osc.v1.artifacts:TypeSchema
|
||||||
|
Loading…
Reference in New Issue
Block a user