Add tag support for Glare client
Change-Id: I08bdfe3260e68bff3955e6dc39941a90c262c112
This commit is contained in:
parent
6ed07b9320
commit
847615851c
@ -508,6 +508,92 @@ class PublishArtifact(command.Lister):
|
||||
return print_artifact(client, data, parsed_args.type_name)
|
||||
|
||||
|
||||
class AddTag(command.Lister):
|
||||
"""Add tag to artifact"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(AddTag, 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 publish.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'tag',
|
||||
metavar='<TAG>',
|
||||
help='Value of the tag to add to the artifact.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--artifact-version', '-V',
|
||||
metavar='<VERSION>',
|
||||
default='latest',
|
||||
help='Version of the artifact.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--id', '-i',
|
||||
action='store_true',
|
||||
help='Flag indicates to use artifact id instead of its name.',
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
LOG.debug('take_action({0})'.format(parsed_args))
|
||||
client = self.app.client_manager.artifact
|
||||
af_id = get_artifact_id(client, parsed_args)
|
||||
data = client.artifacts.add_tag(
|
||||
af_id, tag_value=parsed_args.tag, type_name=parsed_args.type_name)
|
||||
return print_artifact(client, data, parsed_args.type_name)
|
||||
|
||||
|
||||
class RemoveTag(command.Lister):
|
||||
"""Remove tag from the artifact"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(RemoveTag, 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 publish.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'tag',
|
||||
metavar='<TAG>',
|
||||
help='Value of the tag to remove from the artifact.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--artifact-version', '-V',
|
||||
metavar='<VERSION>',
|
||||
default='latest',
|
||||
help='Version of the artifact.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--id', '-i',
|
||||
action='store_true',
|
||||
help='Flag indicates to use artifact id instead of its name.',
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
LOG.debug('take_action({0})'.format(parsed_args))
|
||||
client = self.app.client_manager.artifact
|
||||
af_id = get_artifact_id(client, parsed_args)
|
||||
data = client.artifacts.remove_tag(
|
||||
af_id, tag_value=parsed_args.tag, type_name=parsed_args.type_name)
|
||||
return print_artifact(client, data, parsed_args.type_name)
|
||||
|
||||
|
||||
class TypeList(command.Lister):
|
||||
"""List of type names"""
|
||||
|
||||
|
@ -89,6 +89,8 @@ class TestArtifacts(utils.TestCommand):
|
||||
self.app.client_manager.artifact.artifacts.list = mock_list
|
||||
self.app.client_manager.artifact.artifacts.get = mock_get
|
||||
self.app.client_manager.artifact.artifacts.get_by_name = mock_get
|
||||
self.app.client_manager.artifact.artifacts.add_tag = mock_g_servs
|
||||
self.app.client_manager.artifact.artifacts.remove_tag = mock_g_servs
|
||||
self.app.client_manager.artifact.artifacts.create = mock_g_servs
|
||||
self.app.client_manager.artifact.artifacts.update = mock_g_servs
|
||||
self.app.client_manager.artifact.artifacts.delete = mock_g_servs
|
||||
|
@ -423,6 +423,58 @@ class TestReactivateArtifacts(TestArtifacts):
|
||||
self.assertEqual(self.COLUMNS, name_fields)
|
||||
|
||||
|
||||
class TestAddTag(TestArtifacts):
|
||||
|
||||
def setUp(self):
|
||||
super(TestAddTag, self).setUp()
|
||||
self.artifact_mock.call.return_value = \
|
||||
api_art.Controller(self.http, type_name='images')
|
||||
|
||||
# Command to test
|
||||
self.cmd = osc_art.AddTag(self.app, None)
|
||||
|
||||
def test_artifact_add_tag(self):
|
||||
arglist = ['images',
|
||||
'fc15c365-d4f9-4b8b-a090-d9e230f1f6ba', '--id',
|
||||
'123']
|
||||
verify = [('type_name', 'images'),
|
||||
('name', 'fc15c365-d4f9-4b8b-a090-d9e230f1f6ba'),
|
||||
('id', True),
|
||||
('tag', '123')]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verify)
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
name_fields = set([column[0] for column in data])
|
||||
# Check that columns are correct
|
||||
self.assertEqual(self.COLUMNS, name_fields)
|
||||
|
||||
|
||||
class TestRemoveTag(TestArtifacts):
|
||||
|
||||
def setUp(self):
|
||||
super(TestRemoveTag, self).setUp()
|
||||
self.artifact_mock.call.return_value = \
|
||||
api_art.Controller(self.http, type_name='images')
|
||||
|
||||
# Command to test
|
||||
self.cmd = osc_art.RemoveTag(self.app, None)
|
||||
|
||||
def test_artifact_add_tag(self):
|
||||
arglist = ['images',
|
||||
'fc15c365-d4f9-4b8b-a090-d9e230f1f6ba', '--id',
|
||||
'123']
|
||||
verify = [('type_name', 'images'),
|
||||
('name', 'fc15c365-d4f9-4b8b-a090-d9e230f1f6ba'),
|
||||
('id', True),
|
||||
('tag', '123')]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verify)
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
name_fields = set([column[0] for column in data])
|
||||
# Check that columns are correct
|
||||
self.assertEqual(self.COLUMNS, name_fields)
|
||||
|
||||
|
||||
class TestPublishArtifacts(TestArtifacts):
|
||||
|
||||
def setUp(self):
|
||||
|
@ -243,4 +243,19 @@ data_fixtures = {
|
||||
]},
|
||||
),
|
||||
},
|
||||
'/artifacts/images/07a679d8-d0a8-45ff-8d6e-2f32f2097b7c': {
|
||||
'PATCH': (
|
||||
{},
|
||||
''
|
||||
),
|
||||
'GET': (
|
||||
{},
|
||||
{
|
||||
'name': 'art_1',
|
||||
'id': '07a679d8-d0a8-45ff-8d6e-2f32f2097b7c',
|
||||
'version': '0.0.0',
|
||||
'tags': ["a", "b", "c"]
|
||||
}
|
||||
)
|
||||
},
|
||||
}
|
||||
|
@ -412,3 +412,55 @@ class TestController(testtools.TestCase):
|
||||
'http://fake_url')]
|
||||
self.assertEqual(expect_call, self.api.calls)
|
||||
self.assertIsNone(data)
|
||||
|
||||
def test_add_tag(self):
|
||||
art_id = '07a679d8-d0a8-45ff-8d6e-2f32f2097b7c'
|
||||
data = self.controller.add_tag(
|
||||
art_id, tag_value="123", type_name='images')
|
||||
expect_call = [
|
||||
('GET', '/artifacts/images/07a679d8-d0a8-45ff-8d6e-2f32f2097b7c',
|
||||
{}, None),
|
||||
('PATCH',
|
||||
'/artifacts/images/07a679d8-d0a8-45ff-8d6e-2f32f2097b7c',
|
||||
{'Content-Type': 'application/json-patch+json'},
|
||||
[{'op': 'add',
|
||||
'path': '/tags',
|
||||
'value': ['a', 'b', 'c', '123']}])]
|
||||
self.assertEqual(expect_call, self.api.calls)
|
||||
self.assertIsNotNone(data)
|
||||
|
||||
def test_add_existing_tag(self):
|
||||
art_id = '07a679d8-d0a8-45ff-8d6e-2f32f2097b7c'
|
||||
data = self.controller.add_tag(
|
||||
art_id, tag_value="a", type_name='images')
|
||||
expect_call = [
|
||||
('GET', '/artifacts/images/07a679d8-d0a8-45ff-8d6e-2f32f2097b7c',
|
||||
{}, None)]
|
||||
self.assertEqual(expect_call, self.api.calls)
|
||||
self.assertIsNotNone(data)
|
||||
|
||||
def test_remove_tag(self):
|
||||
art_id = '07a679d8-d0a8-45ff-8d6e-2f32f2097b7c'
|
||||
data = self.controller.remove_tag(
|
||||
art_id, tag_value="a", type_name='images')
|
||||
expect_call = [
|
||||
('GET', '/artifacts/images/07a679d8-d0a8-45ff-8d6e-2f32f2097b7c',
|
||||
{}, None),
|
||||
('PATCH',
|
||||
'/artifacts/images/07a679d8-d0a8-45ff-8d6e-2f32f2097b7c',
|
||||
{'Content-Type': 'application/json-patch+json'},
|
||||
[{'op': 'add',
|
||||
'path': '/tags',
|
||||
'value': ['b', 'c']}])]
|
||||
self.assertEqual(expect_call, self.api.calls)
|
||||
self.assertIsNotNone(data)
|
||||
|
||||
def test_remove_nonexisting_tag(self):
|
||||
art_id = '07a679d8-d0a8-45ff-8d6e-2f32f2097b7c'
|
||||
data = self.controller.remove_tag(
|
||||
art_id, tag_value="123", type_name='images')
|
||||
expect_call = [
|
||||
('GET', '/artifacts/images/07a679d8-d0a8-45ff-8d6e-2f32f2097b7c',
|
||||
{}, None)]
|
||||
self.assertEqual(expect_call, self.api.calls)
|
||||
self.assertIsNotNone(data)
|
||||
|
@ -274,3 +274,33 @@ class Controller(object):
|
||||
url = '/schemas/%s' % type_name
|
||||
resp, body = self.http_client.get(url)
|
||||
return body['schemas'][type_name]
|
||||
|
||||
def add_tag(self, artifact_id, tag_value, type_name=None):
|
||||
"""Add tag to artifact.
|
||||
|
||||
:param artifact_id: ID of the artifact to add a tag
|
||||
:param tag_value: value of the tag to add
|
||||
"""
|
||||
type_name = self._check_type_name(type_name)
|
||||
url = '/artifacts/%s/%s' % (type_name, artifact_id)
|
||||
resp, body = self.http_client.get(url)
|
||||
tags = body['tags']
|
||||
if tag_value in tags:
|
||||
return body
|
||||
tags.append(tag_value)
|
||||
return self.update(artifact_id, type_name, tags=tags)
|
||||
|
||||
def remove_tag(self, artifact_id, tag_value, type_name=None):
|
||||
"""Remove tag from artifact.
|
||||
|
||||
:param artifact_id: ID of the artifact to remove a tag
|
||||
:param tag_value: value of the tag to remove
|
||||
"""
|
||||
type_name = self._check_type_name(type_name)
|
||||
url = '/artifacts/%s/%s' % (type_name, artifact_id)
|
||||
resp, body = self.http_client.get(url)
|
||||
tags = body['tags']
|
||||
if tag_value not in tags:
|
||||
return body
|
||||
tags.remove(tag_value)
|
||||
return self.update(artifact_id, type_name, tags=tags)
|
||||
|
@ -49,6 +49,8 @@ openstack.artifact.v1 =
|
||||
artifact_download = glareclient.osc.v1.blobs:DownloadBlob
|
||||
artifact_type-list = glareclient.osc.v1.artifacts:TypeList
|
||||
artifact_schema = glareclient.osc.v1.artifacts:TypeSchema
|
||||
artifact_add_tag = glareclient.osc.v1.artifacts:AddTag
|
||||
artifact_remove_tag = glareclient.osc.v1.artifacts:RemoveTag
|
||||
|
||||
[build_sphinx]
|
||||
source-dir = doc/source
|
||||
|
Loading…
x
Reference in New Issue
Block a user