Refactor barbicanclient

Add v1 directory for APIs, CLIs and API testcases.
Currently, v1 is supported and the default api version. If version is not
specified when constructing barbicanclient, default api version will be used.

Implements: blueprint refactor-barbicanclient
Change-Id: Ib91e7049de007f4d4254abcd4c125b4dc7e03c55
This commit is contained in:
Jeremy Liu 2016-11-28 10:32:42 +08:00
parent 83eb7b3b3a
commit 97906c853e
25 changed files with 179 additions and 84 deletions

View File

@ -18,7 +18,7 @@ Command-line interface sub-commands related to ACLs.
from cliff import command
from cliff import lister
from barbicanclient import acls
from barbicanclient.v1 import acls
class ArgMixin(object):

View File

@ -16,7 +16,7 @@ Command-line interface sub-commands related to cas.
from cliff import lister
from cliff import show
from barbicanclient import cas
from barbicanclient.v1 import cas
class GetCA(show.ShowOne):

View File

@ -17,9 +17,9 @@ from cliff import command
from cliff import lister
from cliff import show
from barbicanclient.containers import CertificateContainer
from barbicanclient.containers import Container
from barbicanclient.containers import RSAContainer
from barbicanclient.v1.containers import CertificateContainer
from barbicanclient.v1.containers import Container
from barbicanclient.v1.containers import RSAContainer
class DeleteContainer(command.Command):

View File

@ -17,7 +17,7 @@ from cliff import command
from cliff import lister
from cliff import show
from barbicanclient import secrets
from barbicanclient.v1 import secrets
class DeleteSecret(command.Command):

View File

@ -18,19 +18,16 @@ import os
from keystoneauth1 import adapter
from keystoneauth1 import session as ks_session
from oslo_utils import importutils
from barbicanclient import acls
from barbicanclient import cas
from barbicanclient import containers
from barbicanclient import exceptions
from barbicanclient import orders
from barbicanclient import secrets
LOG = logging.getLogger(__name__)
_DEFAULT_SERVICE_TYPE = 'key-manager'
_DEFAULT_SERVICE_INTERFACE = 'public'
_DEFAULT_API_VERSION = 'v1'
_SUPPORTED_API_VERSION_MAP = {'v1': 'barbicanclient.v1.client.Client'}
class _HTTPClient(adapter.Adapter):
@ -119,11 +116,10 @@ class _HTTPClient(adapter.Adapter):
return message
class Client(object):
def __init__(self, session=None, *args, **kwargs):
"""Barbican client object used to interact with barbican service.
def Client(version=None, session=None, *args, **kwargs):
"""Barbican client used to interact with barbican service.
:param version: The API version to use.
:param session: An instance of keystoneclient.session.Session that
can be either authenticated, or not authenticated. When using
a non-authenticated Session, you must provide some additional
@ -146,7 +142,7 @@ class Client(object):
certificate authorities.
WARNING: This option should be used with caution.
:param service_type: Used as an endpoint filter when using an
authenticated keystone session. Defaults to 'key-management'.
authenticated keystone session. Defaults to 'key-manager'.
:param service_name: Used as an endpoint filter when using an
authenticated keystone session.
:param interface: Used as an endpoint filter when using an
@ -167,14 +163,19 @@ class Client(object):
if kwargs.get('project_id') is None:
raise ValueError('Project ID must be provided when not using '
'auth in the Keystone Session')
if not version:
version = _DEFAULT_API_VERSION
httpclient = _HTTPClient(session=session, *args, **kwargs)
self.secrets = secrets.SecretManager(httpclient)
self.orders = orders.OrderManager(httpclient)
self.containers = containers.ContainerManager(httpclient)
self.cas = cas.CAManager(httpclient)
self.acls = acls.ACLManager(httpclient)
try:
client_path = _SUPPORTED_API_VERSION_MAP[version]
client_class = importutils.import_class(client_path)
return client_class(session=session, *args, **kwargs)
except (KeyError, ValueError):
supported_versions = ', '.join(_SUPPORTED_API_VERSION_MAP.keys())
msg = ("Invalid client version %(version)s; must be one of: "
"%(versions)s") % {'version': version,
'versions': supported_versions}
raise exceptions.UnsupportedVersion(msg)
def env(*vars, **kwargs):

View File

@ -22,6 +22,11 @@ class PayloadException(BarbicanException):
pass
class UnsupportedVersion(BarbicanException):
"""User is trying to use an unsupported version of the API."""
pass
class HTTPError(Exception):
"""Base exception for HTTP errors."""

View File

@ -25,7 +25,8 @@ API_VERSIONS = {
def make_client(instance):
"""Returns a Barbican service client."""
return client.Client(session=instance.session,
return client.Client(version=DEFAULT_API_VERSION,
session=instance.session,
region_name=instance._region_name)

View File

@ -17,6 +17,7 @@ import six
from barbicanclient import barbican as barb
from barbicanclient.barbican import Barbican
from barbicanclient import client
from barbicanclient import exceptions
from barbicanclient.tests import keystone_client_fixtures
from barbicanclient.tests import test_client
@ -171,13 +172,13 @@ class WhenTestingBarbicanCLI(test_client.BaseEntityResource):
self.assertIsNone(httpclient.service_name)
def test_endpoint_filter_kwargs_set_correctly(self):
auth_args = ('--no-auth --endpoint http://barbican_endpoint:9311/v1 '
auth_args = ('--no-auth --endpoint http://barbican_endpoint:9311 '
'--os-project-id project1')
endpoint_filter_args = ('--interface private '
'--service-type custom-type '
'--service-name Burrbican '
'--region-name RegionTwo '
'--barbican-api-version v2')
'--barbican-api-version v1')
args = auth_args + ' ' + endpoint_filter_args
argv, remainder = self.parser.parse_known_args(args.split())
barbican_client = self.barbican.create_client(argv)
@ -187,7 +188,22 @@ class WhenTestingBarbicanCLI(test_client.BaseEntityResource):
self.assertEqual('custom-type', httpclient.service_type)
self.assertEqual('Burrbican', httpclient.service_name)
self.assertEqual('RegionTwo', httpclient.region_name)
self.assertEqual('v2', httpclient.version)
self.assertEqual('v1', httpclient.version)
def test_should_fail_if_provide_unsupported_api_version(self):
auth_args = ('--no-auth --endpoint http://barbican_endpoint:9311/v1 '
'--os-project-id project1')
endpoint_filter_args = ('--interface private '
'--service-type custom-type '
'--service-name Burrbican '
'--region-name RegionTwo '
'--barbican-api-version v2')
args = auth_args + ' ' + endpoint_filter_args
argv, remainder = self.parser.parse_known_args(args.split())
self.assertRaises(exceptions.UnsupportedVersion,
self.barbican.create_client,
argv)
class TestBarbicanWithKeystonePasswordAuth(

View File

View File

@ -16,8 +16,8 @@
from oslo_utils import timeutils
import requests_mock
from barbicanclient import acls
from barbicanclient.tests import test_client
from barbicanclient.v1 import acls
class ACLTestCase(test_client.BaseEntityResource):

View File

@ -14,8 +14,8 @@
# limitations under the License.
from oslo_utils import timeutils
from barbicanclient import cas
from barbicanclient.tests import test_client
from barbicanclient.v1 import cas
class CAData(object):

View File

@ -19,11 +19,11 @@ import mock
from oslo_utils import timeutils
import six
from barbicanclient import acls
from barbicanclient import base
from barbicanclient import containers
from barbicanclient import secrets
from barbicanclient.tests import test_client
from barbicanclient.v1 import acls
from barbicanclient.v1 import containers
from barbicanclient.v1 import secrets
class ContainerData(object):

View File

@ -18,8 +18,8 @@ from oslo_utils import timeutils
import uuid
from barbicanclient import base
from barbicanclient import orders
from barbicanclient.tests import test_client
from barbicanclient.v1 import orders
class OrdersTestCase(test_client.BaseEntityResource):

View File

@ -17,11 +17,11 @@ import json
from oslo_utils import timeutils
from barbicanclient import acls
from barbicanclient import base
from barbicanclient import exceptions
from barbicanclient import secrets
from barbicanclient.tests import test_client
from barbicanclient.v1 import acls
from barbicanclient.v1 import secrets
class SecretData(object):

View File

View File

@ -0,0 +1,69 @@
# Copyright (c) 2016 GohighSec, Inc.
#
# 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 barbicanclient import client as base_client
from barbicanclient.v1 import acls
from barbicanclient.v1 import cas
from barbicanclient.v1 import containers
from barbicanclient.v1 import orders
from barbicanclient.v1 import secrets
LOG = logging.getLogger(__name__)
class Client(object):
def __init__(self, session=None, *args, **kwargs):
"""Barbican client object used to interact with barbican service.
:param session: An instance of keystoneclient.session.Session that
can be either authenticated, or not authenticated. When using
a non-authenticated Session, you must provide some additional
parameters. When no session is provided it will default to a
non-authenticated Session.
:param endpoint: Barbican endpoint url. Required when a session is not
given, or when using a non-authenticated session.
When using an authenticated session, the client will attempt
to get an endpoint from the session.
:param project_id: The project ID used for context in Barbican.
Required when a session is not given, or when using a
non-authenticated session.
When using an authenticated session, the project ID will be
provided by the authentication mechanism.
:param verify: When a session is not given, the client will create
a non-authenticated session. This parameter is passed to the
session that is created. If set to False, it allows
barbicanclient to perform "insecure" TLS (https) requests.
The server's certificate will not be verified against any
certificate authorities.
WARNING: This option should be used with caution.
:param service_type: Used as an endpoint filter when using an
authenticated keystone session. Defaults to 'key-management'.
:param service_name: Used as an endpoint filter when using an
authenticated keystone session.
:param interface: Used as an endpoint filter when using an
authenticated keystone session. Defaults to 'public'.
:param region_name: Used as an endpoint filter when using an
authenticated keystone session.
"""
self.client = base_client._HTTPClient(session=session, *args, **kwargs)
self.secrets = secrets.SecretManager(self.client)
self.orders = orders.OrderManager(self.client)
self.containers = containers.ContainerManager(self.client)
self.cas = cas.CAManager(self.client)
self.acls = acls.ACLManager(self.client)

View File

@ -17,11 +17,10 @@ import logging
from oslo_utils.timeutils import parse_isotime
from barbicanclient import acls as acl_manager
from barbicanclient import base
from barbicanclient import formatter
from barbicanclient import secrets as secret_manager
from barbicanclient.v1 import acls as acl_manager
from barbicanclient.v1 import secrets as secret_manager
LOG = logging.getLogger(__name__)

View File

@ -19,11 +19,10 @@ import logging
from oslo_utils.timeutils import parse_isotime
import six
from barbicanclient._i18n import _LW
from barbicanclient import acls as acl_manager
from barbicanclient import base
from barbicanclient import exceptions
from barbicanclient import formatter
from barbicanclient.v1 import acls as acl_manager
LOG = logging.getLogger(__name__)
@ -193,7 +192,7 @@ class Secret(SecretFormatter):
try:
self._fetch_payload()
except ValueError:
LOG.warning(_LW("Secret does not contain a payload"))
LOG.warning("Secret does not contain a payload")
return None
return self._payload
@ -242,22 +241,20 @@ class Secret(SecretFormatter):
@immutable_after_save
def payload_content_type(self, value):
LOG.warning(
_LW('DEPRECATION WARNING: Manually setting the '
'payload_content_type can lead to unexpected '
'results. It will be removed in a future release. '
'See Launchpad Bug #1419166.')
)
'DEPRECATION WARNING: Manually setting the '
'payload_content_type can lead to unexpected '
'results. It will be removed in a future release. '
'See Launchpad Bug #1419166.')
self._payload_content_type = value
@payload_content_encoding.setter
@immutable_after_save
def payload_content_encoding(self, value):
LOG.warning(
_LW('DEPRECATION WARNING: Manually setting the '
'payload_content_encoding can lead to unexpected '
'results. It will be removed in a future release. '
'See Launchpad Bug #1419166.')
)
'DEPRECATION WARNING: Manually setting the '
'payload_content_encoding can lead to unexpected '
'results. It will be removed in a future release. '
'See Launchpad Bug #1419166.')
self._payload_content_encoding = value
def _fetch_payload(self):

View File

@ -150,20 +150,27 @@ class WhenTestingClientConnectivity(BaseTestCase):
self.assert_client_cannot_get_endpoint(barbicanclient)
def test_client_cannot_access_server_if_nonexistent_version_specified(self): # noqa
barbicanclient_1 = client.Client(
def test_cannot_create_client_if_nonexistent_version_specified(self):
self.assertRaises(exceptions.UnsupportedVersion,
client.Client,
**{"project_id": CONF.keymanager.project_id,
"auth": self.auth,
"interface": client._DEFAULT_SERVICE_INTERFACE,
"service_type": client._DEFAULT_SERVICE_TYPE,
"version": 'wrong-version'})
self.assertRaises(exceptions.UnsupportedVersion,
client.Client,
**{"endpoint": CONF.keymanager.url,
"project_id": CONF.keymanager.project_id,
"auth": self.auth,
"version": 'nonexistent_version'})
def test_client_can_access_server_if_no_version_is_specified(self):
barbicanclient = client.Client(
project_id=CONF.keymanager.project_id,
auth=self.auth,
interface=client._DEFAULT_SERVICE_INTERFACE,
service_type=client._DEFAULT_SERVICE_TYPE,
version='wrong-version')
service_type=client._DEFAULT_SERVICE_TYPE)
self.assertRaises(TypeError, barbicanclient_1.containers.list)
barbicanclient_2 = client.Client(
endpoint=CONF.keymanager.url,
project_id=CONF.keymanager.project_id,
auth=self.auth,
version='nonexistent_version')
self.assert_client_cannot_contact_barbican(barbicanclient_2)
self.assert_client_can_contact_barbican(barbicanclient)

View File

@ -31,30 +31,30 @@ openstack.cli.extension =
openstack.key_manager.v1 =
secret_order_create = barbicanclient.barbican_cli.orders:CreateOrder
secret_order_delete = barbicanclient.barbican_cli.orders:DeleteOrder
secret_order_get = barbicanclient.barbican_cli.orders:GetOrder
secret_order_list = barbicanclient.barbican_cli.orders:ListOrder
secret_order_create = barbicanclient.barbican_cli.v1.orders:CreateOrder
secret_order_delete = barbicanclient.barbican_cli.v1.orders:DeleteOrder
secret_order_get = barbicanclient.barbican_cli.v1.orders:GetOrder
secret_order_list = barbicanclient.barbican_cli.v1.orders:ListOrder
secret_delete = barbicanclient.barbican_cli.secrets:DeleteSecret
secret_get = barbicanclient.barbican_cli.secrets:GetSecret
secret_list = barbicanclient.barbican_cli.secrets:ListSecret
secret_store = barbicanclient.barbican_cli.secrets:StoreSecret
secret_update = barbicanclient.barbican_cli.secrets:UpdateSecret
secret_delete = barbicanclient.barbican_cli.v1.secrets:DeleteSecret
secret_get = barbicanclient.barbican_cli.v1.secrets:GetSecret
secret_list = barbicanclient.barbican_cli.v1.secrets:ListSecret
secret_store = barbicanclient.barbican_cli.v1.secrets:StoreSecret
secret_update = barbicanclient.barbican_cli.v1.secrets:UpdateSecret
secret_container_delete = barbicanclient.barbican_cli.containers:DeleteContainer
secret_container_get = barbicanclient.barbican_cli.containers:GetContainer
secret_container_list = barbicanclient.barbican_cli.containers:ListContainer
secret_container_create = barbicanclient.barbican_cli.containers:CreateContainer
secret_container_delete = barbicanclient.barbican_cli.v1.containers:DeleteContainer
secret_container_get = barbicanclient.barbican_cli.v1.containers:GetContainer
secret_container_list = barbicanclient.barbican_cli.v1.containers:ListContainer
secret_container_create = barbicanclient.barbican_cli.v1.containers:CreateContainer
ca_get = barbicanclient.barbican_cli.cas:GetCA
ca_list = barbicanclient.barbican_cli.cas:ListCA
ca_get = barbicanclient.barbican_cli.v1.cas:GetCA
ca_list = barbicanclient.barbican_cli.v1.cas:ListCA
acl_delete = barbicanclient.barbican_cli.acls:DeleteACLs
acl_get = barbicanclient.barbican_cli.acls:GetACLs
acl_submit = barbicanclient.barbican_cli.acls:SubmitACL
acl_user_add = barbicanclient.barbican_cli.acls:AddACLUsers
acl_user_remove = barbicanclient.barbican_cli.acls:RemoveACLUsers
acl_delete = barbicanclient.barbican_cli.v1.acls:DeleteACLs
acl_get = barbicanclient.barbican_cli.v1.acls:GetACLs
acl_submit = barbicanclient.barbican_cli.v1.acls:SubmitACL
acl_user_add = barbicanclient.barbican_cli.v1.acls:AddACLUsers
acl_user_remove = barbicanclient.barbican_cli.v1.acls:RemoveACLUsers
[build_sphinx]
source-dir = doc/source