From 4b62848a4cbfe8d270a3386fcd43393bbefb973f Mon Sep 17 00:00:00 2001 From: Brian Waldon <bcwaldon@gmail.com> Date: Thu, 17 May 2012 14:33:43 -0700 Subject: [PATCH] Add minimal support for the v2 API This only allows you to run image-list, but sets up a framework that we can use to fill in the rest of the v2 functionality. * Related to bp glance-client-v2 Change-Id: I8827e36fdcf79fe402990a6d05898ec00cbd54c6 --- glanceclient/client.py | 22 +++++++++++++++++++++ glanceclient/common/utils.py | 8 ++++++++ glanceclient/shell.py | 18 ++++++++++------- glanceclient/v2/__init__.py | 0 glanceclient/v2/client.py | 38 ++++++++++++++++++++++++++++++++++++ glanceclient/v2/images.py | 29 +++++++++++++++++++++++++++ glanceclient/v2/schemas.py | 0 glanceclient/v2/shell.py | 23 ++++++++++++++++++++++ 8 files changed, 131 insertions(+), 7 deletions(-) create mode 100644 glanceclient/client.py create mode 100644 glanceclient/v2/__init__.py create mode 100644 glanceclient/v2/client.py create mode 100644 glanceclient/v2/images.py create mode 100644 glanceclient/v2/schemas.py create mode 100644 glanceclient/v2/shell.py diff --git a/glanceclient/client.py b/glanceclient/client.py new file mode 100644 index 00000000..22cd4a2b --- /dev/null +++ b/glanceclient/client.py @@ -0,0 +1,22 @@ +# Copyright 2012 OpenStack LLC. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from glanceclient.common import utils + + +def Client(version, *args, **kwargs): + module = utils.import_versioned_module(version, 'client') + client_class = getattr(module, 'Client') + return client_class(*args, **kwargs) diff --git a/glanceclient/common/utils.py b/glanceclient/common/utils.py index 814622e3..48f6b774 100644 --- a/glanceclient/common/utils.py +++ b/glanceclient/common/utils.py @@ -19,6 +19,7 @@ import uuid import prettytable from glanceclient.common import exceptions +from glanceclient.openstack.common import importutils # Decorator for cli-args @@ -115,3 +116,10 @@ def env(*vars, **kwargs): if value: return value return kwargs.get('default', '') + + +def import_versioned_module(version, submodule=None): + module = 'glanceclient.v%s' % version + if submodule: + module = '.'.join((module, submodule)) + return importutils.import_module(module) diff --git a/glanceclient/shell.py b/glanceclient/shell.py index ee002f58..8afee009 100644 --- a/glanceclient/shell.py +++ b/glanceclient/shell.py @@ -24,10 +24,9 @@ import sys from keystoneclient.v2_0 import client as ksclient +import glanceclient.client from glanceclient.common import exceptions as exc from glanceclient.common import utils -from glanceclient.v1 import shell as shell_v1 -from glanceclient.v1 import client as client_v1 class OpenStackImagesShell(object): @@ -36,7 +35,7 @@ class OpenStackImagesShell(object): parser = argparse.ArgumentParser( prog='glance', description=__doc__.strip(), - epilog='See "glance help COMMAND" '\ + epilog='See "glance help COMMAND" ' 'for help on a specific command.', add_help=False, formatter_class=HelpFormatter, @@ -90,6 +89,10 @@ class OpenStackImagesShell(object): default=utils.env('OS_IMAGE_URL'), help='Defaults to env[OS_IMAGE_URL]') + parser.add_argument('--os-image-api-version', + default=utils.env('OS_IMAGE_API_VERSION', default='1'), + help='Defaults to env[OS_IMAGE_API_VERSION] or 1') + parser.add_argument('--os-service-type', default=utils.env('OS_SERVICE_TYPE'), help='Defaults to env[OS_SERVICE_TYPE]') @@ -101,7 +104,8 @@ class OpenStackImagesShell(object): self.subcommands = {} subparsers = parser.add_subparsers(metavar='<subcommand>') - self._find_actions(subparsers, shell_v1) + submodule = utils.import_versioned_module(version, 'shell') + self._find_actions(subparsers, submodule) self._find_actions(subparsers, self) return parser @@ -172,7 +176,7 @@ class OpenStackImagesShell(object): (options, args) = parser.parse_known_args(argv) # build available subcommands based on version - api_version = '1' + api_version = options.os_image_api_version subcommand_parser = self.get_subcommand_parser(api_version) self.parser = subcommand_parser @@ -226,8 +230,8 @@ class OpenStackImagesShell(object): } endpoint, token = self._authenticate(**kwargs) - image_service = client_v1.Client(endpoint, token, - insecure=args.insecure) + image_service = glanceclient.client.Client( + api_version, endpoint, token, insecure=args.insecure) try: args.func(image_service, args) diff --git a/glanceclient/v2/__init__.py b/glanceclient/v2/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/glanceclient/v2/client.py b/glanceclient/v2/client.py new file mode 100644 index 00000000..99b17933 --- /dev/null +++ b/glanceclient/v2/client.py @@ -0,0 +1,38 @@ +# Copyright 2012 OpenStack LLC. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import logging + +from glanceclient.common import http +from glanceclient.v2 import images + + +logger = logging.getLogger(__name__) + + +class Client(object): + """Client for the OpenStack Images v2 API. + + :param string endpoint: A user-supplied endpoint URL for the glance + service. + :param string token: Token for authentication. + :param integer timeout: Allows customization of the timeout for client + http requests. (optional) + """ + + def __init__(self, endpoint, token=None, timeout=600): + self.http_client = http.HTTPClient( + endpoint, token=token, timeout=timeout) + self.images = images.Controller(self.http_client) diff --git a/glanceclient/v2/images.py b/glanceclient/v2/images.py new file mode 100644 index 00000000..61990863 --- /dev/null +++ b/glanceclient/v2/images.py @@ -0,0 +1,29 @@ +# Copyright 2012 OpenStack LLC. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + + +class Image(object): + def __init__(self, id, name): + self.id = id + self.name = name + + +class Controller(object): + def __init__(self, http_client): + self.http_client = http_client + + def list(self): + resp, body = self.http_client.json_request('GET', '/v2/images') + return [Image(i['id'], i['name']) for i in body['images']] diff --git a/glanceclient/v2/schemas.py b/glanceclient/v2/schemas.py new file mode 100644 index 00000000..e69de29b diff --git a/glanceclient/v2/shell.py b/glanceclient/v2/shell.py new file mode 100644 index 00000000..b12b1b90 --- /dev/null +++ b/glanceclient/v2/shell.py @@ -0,0 +1,23 @@ +# Copyright 2012 OpenStack LLC. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from glanceclient.common import utils + + +def do_image_list(gc, args): + """List images.""" + images = gc.images.list() + columns = ['ID', 'Name'] + utils.print_list(images, columns)