d15f8db597
All Barbican resources have a project-id in their URI. This helps to correlate the resource with the specified project when no external authentication mechanism is used. However, most Barbican deployments would use Keystone to authenticate the API requests. With Keystone, the project-id information is already obtained when the X-Auth-Token header from the request is validated. This makes the project-id in the URI redundant. This commit removes project-id from the URI. Tests have been updated as well to not expect project-id in the URI. Patch 3: removed unauthenticated-context from admin pipeline to fix tempest failure. version api doesn't need auth context now Patch 4: refactored based on review comments removed the Noop policy enforcer class Patch 5: rebased and fixed failing tests fixed issue in parsing performance_uri Patch 6: updated functional tests to remove project-id from uri removed rbac check for versions controller expecting X-Project-ID to be present in request for all requests this needs to be fixed in the next pass when the admin paste pipeline is updated Patch 7: fixed failing functional test refactoring based on review comments Patch 8: rebased and fixed failing unit tests Patch 9: fixed merge issue by removing keystone_id from few more lines and files Patch 10: fixed failing functional tests (consumers) Spec: https://review.openstack.org/#/c/100386 Client CR: https://review.openstack.org/#/c/112149 Change-Id: If54911718188eb26b7380331d0b61d70206522a5 Blueprint: https://blueprints.launchpad.net/barbican/+spec/api-remove-uri-tenant-id
212 lines
7.6 KiB
Python
212 lines
7.6 KiB
Python
# Copyright (c) 2014 Rackspace, 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 json
|
|
|
|
from functionaltests.api import base
|
|
|
|
create_secret_data = {
|
|
"name": "AES key",
|
|
"expiration": "2018-02-28T19:14:44.180394",
|
|
"algorithm": "aes",
|
|
"bit_length": 256,
|
|
"mode": "cbc",
|
|
"payload": "gF6+lLoF3ohA9aPRpt+6bQ==",
|
|
"payload_content_type": "application/octet-stream",
|
|
"payload_content_encoding": "base64",
|
|
}
|
|
|
|
create_consumer_data = {
|
|
"name": "consumername",
|
|
"URL": "consumerURL"
|
|
}
|
|
|
|
create_consumer_data_for_delete = {
|
|
"name": "consumername2",
|
|
"URL": "consumerURL2"
|
|
}
|
|
|
|
create_consumer_data_for_recreate = {
|
|
"name": "consumername3",
|
|
"URL": "consumerURL3"
|
|
}
|
|
|
|
create_consumer_data_for_idempotency = {
|
|
"name": "consumername4",
|
|
"URL": "consumerURL4"
|
|
}
|
|
|
|
create_container_data = {
|
|
"name": "containername",
|
|
"type": "generic",
|
|
"secret_refs": [
|
|
{
|
|
"name": "secret1",
|
|
},
|
|
{
|
|
"name": "secret2",
|
|
}
|
|
]
|
|
}
|
|
|
|
|
|
class ConsumersTestCase(base.TestCase):
|
|
|
|
def setUp(self):
|
|
super(ConsumersTestCase, self).setUp()
|
|
# Set up two secrets
|
|
secret_json_data = json.dumps(create_secret_data)
|
|
resp, body = self.client.post(
|
|
'/secrets', secret_json_data, headers={
|
|
'content-type': 'application/json'})
|
|
self.assertEqual(resp.status, 201)
|
|
|
|
returned_data = json.loads(body)
|
|
secret_ref_1 = returned_data['secret_ref']
|
|
self.assertIsNotNone(secret_ref_1)
|
|
resp, body = self.client.post(
|
|
'/secrets', secret_json_data, headers={
|
|
'content-type': 'application/json'})
|
|
self.assertEqual(resp.status, 201)
|
|
|
|
returned_data = json.loads(body)
|
|
secret_ref_2 = returned_data['secret_ref']
|
|
self.assertIsNotNone(secret_ref_2)
|
|
|
|
# Create a container with our secrets
|
|
create_container_data['secret_refs'][0]['secret_ref'] = secret_ref_1
|
|
create_container_data['secret_refs'][1]['secret_ref'] = secret_ref_2
|
|
container_json_data = json.dumps(create_container_data)
|
|
resp, body = self.client.post(
|
|
'/containers', container_json_data,
|
|
headers={'content-type': 'application/json'})
|
|
self.assertEqual(resp.status, 201)
|
|
|
|
returned_data = json.loads(body)
|
|
container_ref = returned_data['container_ref']
|
|
self.assertIsNotNone(container_ref)
|
|
self.container_id = container_ref.split('/')[-1]
|
|
|
|
def test_create_consumer(self):
|
|
"""Covers consumer creation. All of the data needed to
|
|
create the consumer is provided in a single POST.
|
|
"""
|
|
json_data = json.dumps(create_consumer_data)
|
|
resp, body = self.client.post(
|
|
'/containers/{0}/consumers'.format(self.container_id),
|
|
json_data, headers={'content-type': 'application/json'})
|
|
self.assertEqual(resp.status, 200)
|
|
|
|
returned_data = json.loads(body)
|
|
consumer_data = returned_data['consumers']
|
|
self.assertIsNotNone(consumer_data)
|
|
self.assertIn(create_consumer_data, consumer_data)
|
|
|
|
def test_delete_consumer(self):
|
|
"""Covers consumer deletion. A consumer is first created, and then
|
|
the consumer is deleted and verified to no longer exist.
|
|
"""
|
|
json_data = json.dumps(create_consumer_data_for_delete)
|
|
|
|
#Register the consumer once
|
|
resp, body = self.client.post(
|
|
'/containers/{0}/consumers'.format(self.container_id),
|
|
json_data, headers={'content-type': 'application/json'})
|
|
self.assertEqual(resp.status, 200)
|
|
|
|
returned_data = json.loads(body)
|
|
consumer_data = returned_data['consumers']
|
|
self.assertIsNotNone(consumer_data)
|
|
self.assertIn(create_consumer_data_for_delete, consumer_data)
|
|
|
|
#Delete the consumer
|
|
resp, body = self.client.delete(
|
|
'/containers/{0}/consumers'.format(self.container_id),
|
|
body=json_data, headers={'content-type': 'application/json'})
|
|
self.assertEqual(resp.status, 200)
|
|
|
|
returned_data = json.loads(body)
|
|
consumer_data = returned_data['consumers']
|
|
self.assertIsNotNone(consumer_data)
|
|
self.assertNotIn(create_consumer_data_for_delete, consumer_data)
|
|
|
|
def test_recreate_consumer(self):
|
|
"""Covers consumer deletion. A consumer is first created, and then
|
|
the consumer is deleted and verified to no longer exist.
|
|
"""
|
|
json_data = json.dumps(create_consumer_data_for_recreate)
|
|
|
|
#Register the consumer once
|
|
resp, body = self.client.post(
|
|
'/containers/{0}/consumers'.format(self.container_id),
|
|
json_data, headers={'content-type': 'application/json'})
|
|
self.assertEqual(resp.status, 200)
|
|
|
|
returned_data = json.loads(body)
|
|
consumer_data = returned_data['consumers']
|
|
self.assertIsNotNone(consumer_data)
|
|
self.assertIn(create_consumer_data_for_recreate, consumer_data)
|
|
|
|
#Delete the consumer
|
|
resp, body = self.client.delete(
|
|
'/containers/{0}/consumers'.format(self.container_id),
|
|
body=json_data, headers={'content-type': 'application/json'})
|
|
self.assertEqual(resp.status, 200)
|
|
|
|
returned_data = json.loads(body)
|
|
consumer_data = returned_data['consumers']
|
|
self.assertIsNotNone(consumer_data)
|
|
self.assertNotIn(create_consumer_data_for_recreate, consumer_data)
|
|
|
|
#Register the consumer again
|
|
resp, body = self.client.post(
|
|
'/containers/{0}/consumers'.format(self.container_id),
|
|
json_data, headers={'content-type': 'application/json'})
|
|
self.assertEqual(resp.status, 200)
|
|
|
|
returned_data = json.loads(body)
|
|
consumer_data = returned_data['consumers']
|
|
self.assertIsNotNone(consumer_data)
|
|
self.assertIn(create_consumer_data_for_recreate, consumer_data)
|
|
|
|
def test_create_consumer_is_idempotent(self):
|
|
"""Covers consumer deletion. A consumer is first created, and then
|
|
the consumer is deleted and verified to no longer exist.
|
|
"""
|
|
json_data = json.dumps(create_consumer_data_for_idempotency)
|
|
|
|
#Register the consumer once
|
|
resp, body = self.client.post(
|
|
'/containers/{0}/consumers'.format(self.container_id),
|
|
json_data, headers={'content-type': 'application/json'})
|
|
self.assertEqual(resp.status, 200)
|
|
|
|
returned_data = json.loads(body)
|
|
consumer_data = returned_data['consumers']
|
|
self.assertIsNotNone(consumer_data)
|
|
self.assertIn(create_consumer_data_for_idempotency, consumer_data)
|
|
|
|
#Register the consumer again, without deleting it first
|
|
resp, body = self.client.post(
|
|
'/containers/{0}/consumers'.format(self.container_id),
|
|
json_data, headers={'content-type': 'application/json'})
|
|
self.assertEqual(resp.status, 200)
|
|
|
|
returned_data = json.loads(body)
|
|
consumer_data = returned_data['consumers']
|
|
self.assertIsNotNone(consumer_data)
|
|
self.assertIn(create_consumer_data_for_idempotency, consumer_data)
|
|
count = consumer_data.count(create_consumer_data_for_idempotency)
|
|
self.assertEqual(1, count)
|