diff options
| author | Wayne Okuma <wayne.okuma@hp.com> | 2014-12-02 14:32:58 -0800 |
|---|---|---|
| committer | Wayne Okuma <wayne.okuma@hp.com> | 2015-07-16 14:00:50 -0700 |
| commit | c0e90fa2bdaa58249f01acbc6eb3edc36f83a740 (patch) | |
| tree | d51436af67ee0ea9b556d79bb77b963703db517d /glanceclient/v2 | |
| parent | 16ab18b64d44a3eb1767308b4b25ac7a6a6c1aee (diff) | |
| download | python-glanceclient-c0e90fa2bdaa58249f01acbc6eb3edc36f83a740.tar.gz | |
Support for Metadata Definition Catalog for Tags
This set provides API and shell commands support for:
- CRUD on metadef_tags;
Change-Id: I09bdf43edee6fff615d223f1a6df7c15a1e40565
Implements: blueprint metadefs-tags-cli
DocImpact
Diffstat (limited to 'glanceclient/v2')
| -rw-r--r-- | glanceclient/v2/client.py | 3 | ||||
| -rw-r--r-- | glanceclient/v2/metadefs.py | 104 | ||||
| -rw-r--r-- | glanceclient/v2/shell.py | 114 |
3 files changed, 221 insertions, 0 deletions
diff --git a/glanceclient/v2/client.py b/glanceclient/v2/client.py index 803673b..e8f280c 100644 --- a/glanceclient/v2/client.py +++ b/glanceclient/v2/client.py @@ -56,5 +56,8 @@ class Client(object): self.metadefs_object = ( metadefs.ObjectController(self.http_client, self.schemas)) + self.metadefs_tag = ( + metadefs.TagController(self.http_client, self.schemas)) + self.metadefs_namespace = ( metadefs.NamespaceController(self.http_client, self.schemas)) diff --git a/glanceclient/v2/metadefs.py b/glanceclient/v2/metadefs.py index 84d83df..0cca6f8 100644 --- a/glanceclient/v2/metadefs.py +++ b/glanceclient/v2/metadefs.py @@ -385,3 +385,107 @@ class ObjectController(object): """Delete all objects in a namespace.""" url = '/v2/metadefs/namespaces/{0}/objects'.format(namespace) self.http_client.delete(url) + + +class TagController(object): + def __init__(self, http_client, schema_client): + self.http_client = http_client + self.schema_client = schema_client + + @utils.memoized_property + def model(self): + schema = self.schema_client.get('metadefs/tag') + return warlock.model_factory(schema.raw(), schemas.SchemaBasedModel) + + def create(self, namespace, tag_name): + """Create a tag. + + :param namespace: Name of a namespace the Tag belongs. + :param tag_name: The name of the new tag to create. + """ + + url = ('/v2/metadefs/namespaces/{0}/tags/{1}'.format(namespace, + tag_name)) + + resp, body = self.http_client.post(url) + body.pop('self', None) + return self.model(**body) + + def create_multiple(self, namespace, **kwargs): + """Create the list of tags. + + :param namespace: Name of a namespace to which the Tags belong. + :param kwargs: list of tags. + """ + + tag_names = kwargs.pop('tags', []) + md_tag_list = [] + + for tag_name in tag_names: + try: + md_tag_list.append(self.model(name=tag_name)) + except (warlock.InvalidOperation) as e: + raise TypeError(utils.exception_to_str(e)) + tags = {'tags': md_tag_list} + + url = '/v2/metadefs/namespaces/{0}/tags'.format(namespace) + + resp, body = self.http_client.post(url, data=tags) + body.pop('self', None) + for tag in body['tags']: + yield self.model(tag) + + def update(self, namespace, tag_name, **kwargs): + """Update a tag. + + :param namespace: Name of a namespace the Tag belongs. + :param prop_name: Name of the Tag (old one). + :param kwargs: Unpacked tag. + """ + tag = self.get(namespace, tag_name) + for (key, value) in kwargs.items(): + try: + setattr(tag, key, value) + except warlock.InvalidOperation as e: + raise TypeError(utils.exception_to_str(e)) + + # Remove read-only parameters. + read_only = ['updated_at', 'created_at'] + for elem in read_only: + if elem in tag: + del tag[elem] + + url = '/v2/metadefs/namespaces/{0}/tags/{1}'.format(namespace, + tag_name) + self.http_client.put(url, data=tag) + + return self.get(namespace, tag.name) + + def get(self, namespace, tag_name): + url = '/v2/metadefs/namespaces/{0}/tags/{1}'.format(namespace, + tag_name) + resp, body = self.http_client.get(url) + body.pop('self', None) + return self.model(**body) + + def list(self, namespace, **kwargs): + """Retrieve a listing of metadata tags. + + :returns generator over list of tags. + """ + url = '/v2/metadefs/namespaces/{0}/tags'.format(namespace) + resp, body = self.http_client.get(url) + + for tag in body['tags']: + yield self.model(tag) + + def delete(self, namespace, tag_name): + """Delete a tag.""" + url = '/v2/metadefs/namespaces/{0}/tags/{1}'.format(namespace, + tag_name) + self.http_client.delete(url) + + def delete_all(self, namespace): + """Delete all tags in a namespace.""" + url = '/v2/metadefs/namespaces/{0}/tags'.format(namespace) + self.http_client.delete(url) diff --git a/glanceclient/v2/shell.py b/glanceclient/v2/shell.py index a56e552..5da4444 100644 --- a/glanceclient/v2/shell.py +++ b/glanceclient/v2/shell.py @@ -417,6 +417,10 @@ def _namespace_show(namespace, max_column_width=None): objects = [obj['name'] for obj in namespace['objects']] namespace['objects'] = objects + if 'tags' in namespace: + tags = [tag['name'] for tag in namespace['tags']] + namespace['tags'] = tags + if max_column_width: utils.print_dict(namespace, max_column_width) else: @@ -775,6 +779,116 @@ def do_md_object_list(gc, args): utils.print_list(objects, columns, field_settings=column_settings) +def _tag_show(tag, max_column_width=None): + tag = dict(tag) # Warlock objects are compatible with dicts + if max_column_width: + utils.print_dict(tag, max_column_width) + else: + utils.print_dict(tag) + + +@utils.arg('namespace', metavar='<NAMESPACE>', + help='Name of the namespace the tag will belong to.') +@utils.arg('--name', metavar='<NAME>', required=True, + help='The name of the new tag to add.') +def do_md_tag_create(gc, args): + """Add a new metadata definitions tag inside a namespace.""" + name = args.name.strip() + if name: + new_tag = gc.metadefs_tag.create(args.namespace, name) + _tag_show(new_tag) + else: + utils.exit('Please supply at least one non-blank tag name.') + + +@utils.arg('namespace', metavar='<NAMESPACE>', + help='Name of the namespace the tags will belong to.') +@utils.arg('--names', metavar='<NAMES>', required=True, + help='A comma separated list of tag names.') +@utils.arg('--delim', metavar='<DELIM>', required=False, + help='The delimiter used to separate the names' + ' (if none is provided then the default is a comma).') +def do_md_tag_create_multiple(gc, args): + """Create new metadata definitions tags inside a namespace.""" + delim = args.delim or ',' + + tags = [] + names_list = args.names.split(delim) + for name in names_list: + name = name.strip() + if name: + tags.append(name) + + if not tags: + utils.exit('Please supply at least one tag name. For example: ' + '--names Tag1') + + fields = {'tags': tags} + new_tags = gc.metadefs_tag.create_multiple(args.namespace, **fields) + columns = ['name'] + column_settings = { + "description": { + "max_width": 50, + "align": "l" + } + } + utils.print_list(new_tags, columns, field_settings=column_settings) + + +@utils.arg('namespace', metavar='<NAMESPACE>', + help='Name of the namespace to which the tag belongs.') +@utils.arg('tag', metavar='<TAG>', help='Name of the old tag.') +@utils.arg('--name', metavar='<NAME>', default=None, required=True, + help='New name of the new tag.') +def do_md_tag_update(gc, args): + """Rename a metadata definitions tag inside a namespace.""" + name = args.name.strip() + if name: + fields = {'name': name} + new_tag = gc.metadefs_tag.update(args.namespace, args.tag, + **fields) + _tag_show(new_tag) + else: + utils.exit('Please supply at least one non-blank tag name.') + + +@utils.arg('namespace', metavar='<NAMESPACE>', + help='Name of the namespace to which the tag belongs.') +@utils.arg('tag', metavar='<TAG>', help='Name of the tag.') +def do_md_tag_show(gc, args): + """Describe a specific metadata definitions tag inside a namespace.""" + tag = gc.metadefs_tag.get(args.namespace, args.tag) + _tag_show(tag) + + +@utils.arg('namespace', metavar='<NAMESPACE>', + help='Name of the namespace to which the tag belongs.') +@utils.arg('tag', metavar='<TAG>', help='Name of the tag.') +def do_md_tag_delete(gc, args): + """Delete a specific metadata definitions tag inside a namespace.""" + gc.metadefs_tag.delete(args.namespace, args.tag) + + +@utils.arg('namespace', metavar='<NAMESPACE>', help='Name of namespace.') +def do_md_namespace_tags_delete(gc, args): + """Delete all metadata definitions tags inside a specific namespace.""" + gc.metadefs_tag.delete_all(args.namespace) + + +@utils.arg('namespace', metavar='<NAMESPACE>', help='Name of namespace.') +def do_md_tag_list(gc, args): + """List metadata definitions tags inside a specific namespace.""" + tags = gc.metadefs_tag.list(args.namespace) + columns = ['name'] + column_settings = { + "description": { + "max_width": 50, + "align": "l" + } + } + utils.print_list(tags, columns, field_settings=column_settings) + + @utils.arg('--sort-key', default='status', choices=tasks.SORT_KEY_VALUES, help='Sort task list by specified field.') |
