Merge "Refactor Key Manager for resource2"
This commit is contained in:
commit
a4ac7f437a
@ -6,4 +6,51 @@ connection to your OpenStack cloud by following the :doc:`connect` user
|
||||
guide. This will provide you with the ``conn`` variable used in the examples
|
||||
below.
|
||||
|
||||
.. TODO(thowe): Implement this guide
|
||||
.. contents:: Table of Contents
|
||||
:local:
|
||||
|
||||
.. note:: Some interactions with the Key Manager service differ from that
|
||||
of other services in that resources do not have a proper ``id`` parameter,
|
||||
which is necessary to make some calls. Instead, resources have a separately
|
||||
named id attribute, e.g., the Secret resource has ``secret_id``.
|
||||
|
||||
The examples below outline when to pass in those id values.
|
||||
|
||||
Create a Secret
|
||||
---------------
|
||||
|
||||
The Key Manager service allows you to create new secrets by passing the
|
||||
attributes of the :class:`~openstack.key_manager.v1.secret.Secret` to the
|
||||
:meth:`~openstack.key_manager.v1._proxy.Proxy.create_secret` method.
|
||||
|
||||
.. literalinclude:: ../examples/key_manager/create.py
|
||||
:pyobject: create_secret
|
||||
|
||||
List Secrets
|
||||
------------
|
||||
|
||||
Once you have stored some secrets, they are available for you to list
|
||||
via the :meth:`~openstack.key_manager.v1._proxy.Proxy.secrets` method.
|
||||
This method returns a generator, which yields each
|
||||
:class:`~openstack.key_manager.v1.secret.Secret`.
|
||||
|
||||
.. literalinclude:: ../examples/key_manager/list.py
|
||||
:pyobject: list_secrets
|
||||
|
||||
The :meth:`~openstack.key_manager.v1._proxy.Proxy.secrets` method can
|
||||
also make more advanced queries to limit the secrets that are returned.
|
||||
|
||||
.. literalinclude:: ../examples/key_manager/list.py
|
||||
:pyobject: list_secrets_query
|
||||
|
||||
Get Secret Payload
|
||||
------------------
|
||||
|
||||
Once you have received a :class:`~openstack.key_manager.v1.secret.Secret`,
|
||||
you can obtain the payload for it by passing the secret's id value to
|
||||
the :meth:`~openstack.key_manager.v1._proxy.Proxy.secrets` method.
|
||||
Use the :data:`~openstack.key_manager.v1.secret.Secret.secret_id` attribute
|
||||
when making this request.
|
||||
|
||||
.. literalinclude:: ../examples/key_manager/get.py
|
||||
:pyobject: get_secret_payload
|
||||
|
0
examples/key_manager/__init__.py
Normal file
0
examples/key_manager/__init__.py
Normal file
25
examples/key_manager/create.py
Normal file
25
examples/key_manager/create.py
Normal file
@ -0,0 +1,25 @@
|
||||
# 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.
|
||||
|
||||
"""
|
||||
List resources from the Key Manager service.
|
||||
"""
|
||||
|
||||
|
||||
def create_secret(conn):
|
||||
print("Create a secret:")
|
||||
|
||||
conn.key_manager.create_secret(name="My public key",
|
||||
secret_type="public",
|
||||
expiration="2020-02-28T23:59:59",
|
||||
payload="ssh rsa...",
|
||||
payload_content_type="text/plain")
|
26
examples/key_manager/get.py
Normal file
26
examples/key_manager/get.py
Normal file
@ -0,0 +1,26 @@
|
||||
# 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.
|
||||
|
||||
"""
|
||||
List resources from the Key Manager service.
|
||||
"""
|
||||
|
||||
s = None
|
||||
|
||||
|
||||
def get_secret_payload(conn):
|
||||
print("Get a secret's payload:")
|
||||
|
||||
# Assuming you have an object `s` which you perhaps received from
|
||||
# a conn.key_manager.secrets() call...
|
||||
secret = conn.key_manager.get_secret(s.secret_id)
|
||||
print(secret.payload)
|
31
examples/key_manager/list.py
Normal file
31
examples/key_manager/list.py
Normal file
@ -0,0 +1,31 @@
|
||||
# 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.
|
||||
|
||||
"""
|
||||
List resources from the Key Manager service.
|
||||
"""
|
||||
|
||||
|
||||
def list_secrets(conn):
|
||||
print("List Secrets:")
|
||||
|
||||
for secret in conn.key_manager.secrets():
|
||||
print(secret)
|
||||
|
||||
|
||||
def list_secrets_query(conn):
|
||||
print("List Secrets:")
|
||||
|
||||
for secret in conn.key_manager.secrets(
|
||||
secret_type="symmetric",
|
||||
expiration="gte:2020-01-01T00:00:00"):
|
||||
print(secret)
|
39
openstack/key_manager/v1/_format.py
Normal file
39
openstack/key_manager/v1/_format.py
Normal file
@ -0,0 +1,39 @@
|
||||
# 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 openstack import format
|
||||
|
||||
from six.moves.urllib import parse
|
||||
|
||||
|
||||
class HREFToUUID(format.Formatter):
|
||||
|
||||
@classmethod
|
||||
def deserialize(cls, value):
|
||||
"""Convert a HREF to the UUID portion"""
|
||||
parts = parse.urlsplit(value)
|
||||
|
||||
# Only try to proceed if we have an actual URI.
|
||||
# Just check that we have a scheme, netloc, and path.
|
||||
if not all(parts[:3]):
|
||||
raise ValueError("Unable to convert %s to an ID" % value)
|
||||
|
||||
# The UUID will be the last portion of the URI.
|
||||
return parts.path.split("/")[-1]
|
||||
|
||||
@classmethod
|
||||
def serialize(cls, value):
|
||||
# NOTE(briancurtin): If we had access to the session to get
|
||||
# the endpoint we could do something smart here like take an ID
|
||||
# and give back an HREF, but this will just have to be something
|
||||
# that works different because Barbican does what it does...
|
||||
return value
|
@ -13,10 +13,10 @@
|
||||
from openstack.key_manager.v1 import container as _container
|
||||
from openstack.key_manager.v1 import order as _order
|
||||
from openstack.key_manager.v1 import secret as _secret
|
||||
from openstack import proxy
|
||||
from openstack import proxy2
|
||||
|
||||
|
||||
class Proxy(proxy.BaseProxy):
|
||||
class Proxy(proxy2.BaseProxy):
|
||||
|
||||
def create_container(self, **attrs):
|
||||
"""Create a new container from attributes
|
||||
|
@ -11,34 +11,39 @@
|
||||
# under the License.
|
||||
|
||||
from openstack.key_manager import key_manager_service
|
||||
from openstack import resource
|
||||
from openstack.key_manager.v1 import _format
|
||||
from openstack import resource2
|
||||
|
||||
|
||||
class Container(resource.Resource):
|
||||
id_attribute = 'container_ref'
|
||||
class Container(resource2.Resource):
|
||||
resources_key = 'containers'
|
||||
base_path = '/containers'
|
||||
service = key_manager_service.KeyManagerService()
|
||||
|
||||
# capabilities
|
||||
allow_create = True
|
||||
allow_retrieve = True
|
||||
allow_get = True
|
||||
allow_update = True
|
||||
allow_delete = True
|
||||
allow_list = True
|
||||
|
||||
# Properties
|
||||
#: A URI for this container
|
||||
container_ref = resource.prop('container_ref')
|
||||
container_ref = resource2.Body('container_ref')
|
||||
#: The ID for this container
|
||||
container_id = resource2.Body('container_ref', alternate_id=True,
|
||||
type=_format.HREFToUUID)
|
||||
#: The timestamp when this container was created.
|
||||
created_at = resource.prop('created')
|
||||
created_at = resource2.Body('created')
|
||||
#: The name of this container
|
||||
name = resource.prop('name')
|
||||
name = resource2.Body('name')
|
||||
#: A list of references to secrets in this container
|
||||
secret_refs = resource.prop('secret_refs')
|
||||
secret_refs = resource2.Body('secret_refs', type=list)
|
||||
#: The status of this container
|
||||
status = resource.prop('status')
|
||||
status = resource2.Body('status')
|
||||
#: The type of this container
|
||||
type = resource.prop('type')
|
||||
type = resource2.Body('type')
|
||||
#: The timestamp when this container was updated.
|
||||
updated_at = resource.prop('updated')
|
||||
updated_at = resource2.Body('updated')
|
||||
#: A party interested in this container.
|
||||
consumers = resource2.Body('consumers', type=list)
|
||||
|
@ -11,34 +11,45 @@
|
||||
# under the License.
|
||||
|
||||
from openstack.key_manager import key_manager_service
|
||||
from openstack import resource
|
||||
from openstack.key_manager.v1 import _format
|
||||
from openstack import resource2
|
||||
|
||||
|
||||
class Order(resource.Resource):
|
||||
class Order(resource2.Resource):
|
||||
resources_key = 'orders'
|
||||
base_path = '/orders'
|
||||
service = key_manager_service.KeyManagerService()
|
||||
|
||||
# capabilities
|
||||
allow_create = True
|
||||
allow_retrieve = True
|
||||
allow_get = True
|
||||
allow_update = True
|
||||
allow_delete = True
|
||||
allow_list = True
|
||||
|
||||
# Properties
|
||||
# TODO(briancurtin): not documented
|
||||
error_reason = resource.prop('error_reason')
|
||||
# TODO(briancurtin): not documented
|
||||
error_status_code = resource.prop('error_status_code')
|
||||
#: a dictionary containing key-value parameters which specify the
|
||||
#: Timestamp in ISO8601 format of when the order was created
|
||||
created_at = resource2.Body('created')
|
||||
#: Keystone Id of the user who created the order
|
||||
creator_id = resource2.Body('creator_id')
|
||||
#: A dictionary containing key-value parameters which specify the
|
||||
#: details of an order request
|
||||
meta = resource.prop('meta')
|
||||
meta = resource2.Body('meta', type=dict)
|
||||
#: A URI for this order
|
||||
order_ref = resource.prop('order_ref')
|
||||
#: TODO(briancurtin): not documented
|
||||
secret_ref = resource.prop('secret_ref')
|
||||
order_ref = resource2.Body('order_ref')
|
||||
#: The ID of this order
|
||||
order_id = resource2.Body('order_ref', alternate_id=True,
|
||||
type=_format.HREFToUUID)
|
||||
#: Secret href associated with the order
|
||||
secret_ref = resource2.Body('secret_ref')
|
||||
#: Secret ID associated with the order
|
||||
secret_id = resource2.Body('secret_ref', type=_format.HREFToUUID)
|
||||
# The status of this order
|
||||
status = resource.prop('status')
|
||||
status = resource2.Body('status')
|
||||
#: Metadata associated with the order
|
||||
sub_status = resource2.Body('sub_status')
|
||||
#: Metadata associated with the order
|
||||
sub_status_message = resource2.Body('sub_status_message')
|
||||
# The type of order
|
||||
type = resource.prop('type')
|
||||
type = resource2.Body('type')
|
||||
#: Timestamp in ISO8601 format of the last time the order was updated.
|
||||
updated_at = resource2.Body('updated')
|
||||
|
@ -11,39 +11,96 @@
|
||||
# under the License.
|
||||
|
||||
from openstack.key_manager import key_manager_service
|
||||
from openstack import resource
|
||||
from openstack.key_manager.v1 import _format
|
||||
from openstack import resource2
|
||||
from openstack import utils
|
||||
|
||||
|
||||
class Secret(resource.Resource):
|
||||
id_attribute = 'secret_ref'
|
||||
class Secret(resource2.Resource):
|
||||
resources_key = 'secrets'
|
||||
base_path = '/secrets'
|
||||
service = key_manager_service.KeyManagerService()
|
||||
|
||||
# capabilities
|
||||
allow_create = True
|
||||
allow_retrieve = True
|
||||
allow_get = True
|
||||
allow_update = True
|
||||
allow_delete = True
|
||||
allow_list = True
|
||||
|
||||
_query_mapping = resource2.QueryParameters("name", "mode", "bits",
|
||||
"secret_type", "acl_only",
|
||||
"created", "updated",
|
||||
"expiration", "sort",
|
||||
algorithm="alg")
|
||||
|
||||
# Properties
|
||||
#: Metadata provided by a user or system for informational purposes
|
||||
algorithm = resource.prop('algorithm')
|
||||
algorithm = resource2.Body('algorithm')
|
||||
#: Metadata provided by a user or system for informational purposes.
|
||||
#: Value must be greater than zero.
|
||||
bit_length = resource.prop('bit_length')
|
||||
bit_length = resource2.Body('bit_length')
|
||||
#: A list of content types
|
||||
content_types = resource.prop('content_types')
|
||||
content_types = resource2.Body('content_types', type=dict)
|
||||
#: Once this timestamp has past, the secret will no longer be available.
|
||||
expires_at = resource.prop('expiration')
|
||||
expires_at = resource2.Body('expiration')
|
||||
#: Timestamp of when the secret was created.
|
||||
created_at = resource2.Body('created')
|
||||
#: Timestamp of when the secret was last updated.
|
||||
updated_at = resource2.Body('updated')
|
||||
#: The type/mode of the algorithm associated with the secret information.
|
||||
mode = resource.prop('mode')
|
||||
mode = resource2.Body('mode')
|
||||
#: The name of the secret set by the user
|
||||
name = resource.prop('name')
|
||||
name = resource2.Body('name')
|
||||
#: A URI to the sercret
|
||||
secret_ref = resource.prop('secret_ref')
|
||||
secret_ref = resource2.Body('secret_ref')
|
||||
#: The ID of the secret
|
||||
# NOTE: This is not really how alternate IDs are supposed to work and
|
||||
# ultimately means this has to work differently than all other services
|
||||
# in all of OpenStack because of the departure from using actual IDs
|
||||
# that even this service can't even use itself.
|
||||
secret_id = resource2.Body('secret_ref', alternate_id=True,
|
||||
type=_format.HREFToUUID)
|
||||
#: Used to indicate the type of secret being stored.
|
||||
secret_type = resource2.Body('secret_type')
|
||||
#: The status of this secret
|
||||
status = resource.prop('status')
|
||||
status = resource2.Body('status')
|
||||
#: A timestamp when this secret was updated.
|
||||
updated_at = resource.prop('updated')
|
||||
updated_at = resource2.Body('updated')
|
||||
#: The secret's data to be stored. payload_content_type must also
|
||||
#: be supplied if payload is included. (optional)
|
||||
payload = resource2.Body('payload')
|
||||
#: The media type for the content of the payload.
|
||||
#: (required if payload is included)
|
||||
payload_content_type = resource2.Body('payload_content_type')
|
||||
#: The encoding used for the payload to be able to include it in
|
||||
#: the JSON request. Currently only base64 is supported.
|
||||
#: (required if payload is encoded)
|
||||
payload_content_encoding = resource2.Body('payload_content_encoding')
|
||||
|
||||
def get(self, session, requires_id=True):
|
||||
request = self._prepare_request(requires_id=requires_id)
|
||||
|
||||
response = session.get(request.uri,
|
||||
endpoint_filter=self.service).json()
|
||||
|
||||
content_type = None
|
||||
if self.payload_content_type is not None:
|
||||
content_type = self.payload_content_type
|
||||
elif "content_types" in response:
|
||||
content_type = response["content_types"]["default"]
|
||||
|
||||
# Only try to get the payload if a content type has been explicitly
|
||||
# specified or if one was found in the metadata response
|
||||
if content_type is not None:
|
||||
payload = session.get(utils.urljoin(request.uri, "payload"),
|
||||
endpoint_filter=self.service,
|
||||
headers={"Accept": content_type})
|
||||
response["payload"] = payload.text
|
||||
|
||||
# We already have the JSON here so don't call into _translate_response
|
||||
body = self._filter_component(response, self._body_mapping())
|
||||
self._body.attributes.update(body)
|
||||
self._body.clean()
|
||||
|
||||
return self
|
||||
|
@ -14,15 +14,17 @@ import testtools
|
||||
|
||||
from openstack.key_manager.v1 import container
|
||||
|
||||
IDENTIFIER = 'http://localhost/containers/IDENTIFIER'
|
||||
ID_VAL = "123"
|
||||
IDENTIFIER = 'http://localhost/containers/%s' % ID_VAL
|
||||
EXAMPLE = {
|
||||
'container_ref': IDENTIFIER,
|
||||
'created': '2015-03-09T12:14:57.233772',
|
||||
'name': '3',
|
||||
'secret_refs': '4',
|
||||
'secret_refs': ['4'],
|
||||
'status': '5',
|
||||
'type': '6',
|
||||
'updated': '2015-03-09T12:15:57.233772',
|
||||
'consumers': ['7']
|
||||
}
|
||||
|
||||
|
||||
@ -35,14 +37,13 @@ class TestContainer(testtools.TestCase):
|
||||
self.assertEqual('/containers', sot.base_path)
|
||||
self.assertEqual('key-manager', sot.service.service_type)
|
||||
self.assertTrue(sot.allow_create)
|
||||
self.assertTrue(sot.allow_retrieve)
|
||||
self.assertTrue(sot.allow_get)
|
||||
self.assertTrue(sot.allow_update)
|
||||
self.assertTrue(sot.allow_delete)
|
||||
self.assertTrue(sot.allow_list)
|
||||
|
||||
def test_make_it(self):
|
||||
sot = container.Container(EXAMPLE)
|
||||
self.assertEqual(EXAMPLE['container_ref'], sot.container_ref)
|
||||
sot = container.Container(**EXAMPLE)
|
||||
self.assertEqual(EXAMPLE['created'], sot.created_at)
|
||||
self.assertEqual(EXAMPLE['name'], sot.name)
|
||||
self.assertEqual(EXAMPLE['secret_refs'], sot.secret_refs)
|
||||
@ -50,3 +51,6 @@ class TestContainer(testtools.TestCase):
|
||||
self.assertEqual(EXAMPLE['type'], sot.type)
|
||||
self.assertEqual(EXAMPLE['updated'], sot.updated_at)
|
||||
self.assertEqual(EXAMPLE['container_ref'], sot.id)
|
||||
self.assertEqual(EXAMPLE['container_ref'], sot.container_ref)
|
||||
self.assertEqual(ID_VAL, sot.container_id)
|
||||
self.assertEqual(EXAMPLE['consumers'], sot.consumers)
|
||||
|
@ -14,15 +14,20 @@ import testtools
|
||||
|
||||
from openstack.key_manager.v1 import order
|
||||
|
||||
IDENTIFIER = 'IDENTIFIER'
|
||||
ID_VAL = "123"
|
||||
SECRET_ID = "5"
|
||||
IDENTIFIER = 'http://localhost/orders/%s' % ID_VAL
|
||||
EXAMPLE = {
|
||||
'error_reason': '1',
|
||||
'error_status_code': '2',
|
||||
'meta': '3',
|
||||
'order_ref': '4',
|
||||
'secret_ref': '5',
|
||||
'created': '1',
|
||||
'creator_id': '2',
|
||||
'meta': {'key': '3'},
|
||||
'order_ref': IDENTIFIER,
|
||||
'secret_ref': 'http://localhost/secrets/%s' % SECRET_ID,
|
||||
'status': '6',
|
||||
'type': '7',
|
||||
'sub_status': '7',
|
||||
'sub_status_message': '8',
|
||||
'type': '9',
|
||||
'updated': '10'
|
||||
}
|
||||
|
||||
|
||||
@ -35,17 +40,22 @@ class TestOrder(testtools.TestCase):
|
||||
self.assertEqual('/orders', sot.base_path)
|
||||
self.assertEqual('key-manager', sot.service.service_type)
|
||||
self.assertTrue(sot.allow_create)
|
||||
self.assertTrue(sot.allow_retrieve)
|
||||
self.assertTrue(sot.allow_get)
|
||||
self.assertTrue(sot.allow_update)
|
||||
self.assertTrue(sot.allow_delete)
|
||||
self.assertTrue(sot.allow_list)
|
||||
|
||||
def test_make_it(self):
|
||||
sot = order.Order(EXAMPLE)
|
||||
self.assertEqual(EXAMPLE['error_reason'], sot.error_reason)
|
||||
self.assertEqual(EXAMPLE['error_status_code'], sot.error_status_code)
|
||||
sot = order.Order(**EXAMPLE)
|
||||
self.assertEqual(EXAMPLE['created'], sot.created_at)
|
||||
self.assertEqual(EXAMPLE['creator_id'], sot.creator_id)
|
||||
self.assertEqual(EXAMPLE['meta'], sot.meta)
|
||||
self.assertEqual(EXAMPLE['order_ref'], sot.order_ref)
|
||||
self.assertEqual(ID_VAL, sot.order_id)
|
||||
self.assertEqual(EXAMPLE['secret_ref'], sot.secret_ref)
|
||||
self.assertEqual(SECRET_ID, sot.secret_id)
|
||||
self.assertEqual(EXAMPLE['status'], sot.status)
|
||||
self.assertEqual(EXAMPLE['sub_status'], sot.sub_status)
|
||||
self.assertEqual(EXAMPLE['sub_status_message'], sot.sub_status_message)
|
||||
self.assertEqual(EXAMPLE['type'], sot.type)
|
||||
self.assertEqual(EXAMPLE['updated'], sot.updated_at)
|
||||
|
@ -14,12 +14,12 @@ from openstack.key_manager.v1 import _proxy
|
||||
from openstack.key_manager.v1 import container
|
||||
from openstack.key_manager.v1 import order
|
||||
from openstack.key_manager.v1 import secret
|
||||
from openstack.tests.unit import test_proxy_base
|
||||
from openstack.tests.unit import test_proxy_base2
|
||||
|
||||
|
||||
class TestKeyManagementProxy(test_proxy_base.TestProxyBase):
|
||||
class TestKeyManagerProxy(test_proxy_base2.TestProxyBase):
|
||||
def setUp(self):
|
||||
super(TestKeyManagementProxy, self).setUp()
|
||||
super(TestKeyManagerProxy, self).setUp()
|
||||
self.proxy = _proxy.Proxy(self.session)
|
||||
|
||||
def test_server_create_attrs(self):
|
||||
|
@ -10,21 +10,28 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import mock
|
||||
import testtools
|
||||
|
||||
from openstack.key_manager.v1 import secret
|
||||
|
||||
IDENTIFIER = 'http://localhost:9311/v1/secrets/ID'
|
||||
ID_VAL = "123"
|
||||
IDENTIFIER = 'http://localhost:9311/v1/secrets/%s' % ID_VAL
|
||||
EXAMPLE = {
|
||||
'algorithm': '1',
|
||||
'bit_length': '2',
|
||||
'content_types': '3',
|
||||
'content_types': {'default': '3'},
|
||||
'expiration': '2017-03-09T12:14:57.233772',
|
||||
'mode': '5',
|
||||
'name': '6',
|
||||
'secret_ref': IDENTIFIER,
|
||||
'status': '8',
|
||||
'updated': '2015-03-09T12:15:57.233772',
|
||||
'updated': '2015-03-09T12:15:57.233773',
|
||||
'created': '2015-03-09T12:15:57.233774',
|
||||
'secret_type': '9',
|
||||
'payload': '10',
|
||||
'payload_content_type': '11',
|
||||
'payload_content_encoding': '12'
|
||||
}
|
||||
|
||||
|
||||
@ -37,13 +44,25 @@ class TestSecret(testtools.TestCase):
|
||||
self.assertEqual('/secrets', sot.base_path)
|
||||
self.assertEqual('key-manager', sot.service.service_type)
|
||||
self.assertTrue(sot.allow_create)
|
||||
self.assertTrue(sot.allow_retrieve)
|
||||
self.assertTrue(sot.allow_get)
|
||||
self.assertTrue(sot.allow_update)
|
||||
self.assertTrue(sot.allow_delete)
|
||||
self.assertTrue(sot.allow_list)
|
||||
|
||||
self.assertDictEqual({"name": "name",
|
||||
"mode": "mode",
|
||||
"bits": "bits",
|
||||
"secret_type": "secret_type",
|
||||
"acl_only": "acl_only",
|
||||
"created": "created",
|
||||
"updated": "updated",
|
||||
"expiration": "expiration",
|
||||
"sort": "sort",
|
||||
"algorithm": "alg"},
|
||||
sot._query_mapping._mapping)
|
||||
|
||||
def test_make_it(self):
|
||||
sot = secret.Secret(EXAMPLE)
|
||||
sot = secret.Secret(**EXAMPLE)
|
||||
self.assertEqual(EXAMPLE['algorithm'], sot.algorithm)
|
||||
self.assertEqual(EXAMPLE['bit_length'], sot.bit_length)
|
||||
self.assertEqual(EXAMPLE['content_types'], sot.content_types)
|
||||
@ -51,6 +70,64 @@ class TestSecret(testtools.TestCase):
|
||||
self.assertEqual(EXAMPLE['mode'], sot.mode)
|
||||
self.assertEqual(EXAMPLE['name'], sot.name)
|
||||
self.assertEqual(EXAMPLE['secret_ref'], sot.secret_ref)
|
||||
self.assertEqual(EXAMPLE['secret_ref'], sot.id)
|
||||
self.assertEqual(ID_VAL, sot.secret_id)
|
||||
self.assertEqual(EXAMPLE['status'], sot.status)
|
||||
self.assertEqual(EXAMPLE['updated'], sot.updated_at)
|
||||
self.assertEqual(EXAMPLE['secret_ref'], sot.id)
|
||||
self.assertEqual(EXAMPLE['secret_type'], sot.secret_type)
|
||||
self.assertEqual(EXAMPLE['payload'], sot.payload)
|
||||
self.assertEqual(EXAMPLE['payload_content_type'],
|
||||
sot.payload_content_type)
|
||||
self.assertEqual(EXAMPLE['payload_content_encoding'],
|
||||
sot.payload_content_encoding)
|
||||
|
||||
def test_get_no_payload(self):
|
||||
sot = secret.Secret(id="id")
|
||||
|
||||
sess = mock.Mock()
|
||||
rv = mock.Mock()
|
||||
return_body = {"status": "cool"}
|
||||
rv.json = mock.Mock(return_value=return_body)
|
||||
sess.get = mock.Mock(return_value=rv)
|
||||
|
||||
sot.get(sess)
|
||||
|
||||
sess.get.assert_called_once_with("secrets/id",
|
||||
endpoint_filter=sot.service)
|
||||
|
||||
def _test_payload(self, sot, metadata, content_type):
|
||||
content_type = "some/type"
|
||||
sot = secret.Secret(id="id", payload_content_type=content_type)
|
||||
|
||||
metadata_response = mock.Mock()
|
||||
metadata_response.json = mock.Mock(return_value=metadata)
|
||||
|
||||
payload_response = mock.Mock()
|
||||
payload = "secret info"
|
||||
payload_response.text = payload
|
||||
|
||||
sess = mock.Mock()
|
||||
sess.get = mock.Mock(side_effect=[metadata_response, payload_response])
|
||||
|
||||
rv = sot.get(sess)
|
||||
|
||||
sess.get.assert_has_calls(
|
||||
[mock.call("secrets/id", endpoint_filter=sot.service),
|
||||
mock.call("secrets/id/payload", endpoint_filter=sot.service,
|
||||
headers={"Accept": content_type})])
|
||||
|
||||
self.assertEqual(rv.payload, payload)
|
||||
self.assertEqual(rv.status, metadata["status"])
|
||||
|
||||
def test_get_with_payload_from_argument(self):
|
||||
metadata = {"status": "great"}
|
||||
content_type = "some/type"
|
||||
sot = secret.Secret(id="id", payload_content_type=content_type)
|
||||
self._test_payload(sot, metadata, content_type)
|
||||
|
||||
def test_get_with_payload_from_content_types(self):
|
||||
content_type = "some/type"
|
||||
metadata = {"status": "fine",
|
||||
"content_types": {"default": content_type}}
|
||||
sot = secret.Secret(id="id")
|
||||
self._test_payload(sot, metadata, content_type)
|
||||
|
Loading…
Reference in New Issue
Block a user