Updated based on review comments.

Change-Id: I0e009fa4d7b96544e4b4ef1e335052648df7d672
This commit is contained in:
Steve Heyman 2013-12-08 18:19:25 -06:00
parent 1a8fe4ca76
commit a7298751e2
8 changed files with 467 additions and 0 deletions

View File

@ -0,0 +1,15 @@
"""
Copyright 2013 Rackspace
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.
"""

View File

@ -0,0 +1,146 @@
"""
Copyright 2013 Rackspace
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 httplib import BadStatusLine
from requests.exceptions import ConnectionError
from cloudcafe.cloudkeep.common.responses import CloudkeepResponse
class VerificationsBehavior(object):
def __init__(self, verifications_client, config):
super(VerificationsBehavior, self).__init__()
self.verifications_client = verifications_client
self.config = config
self.created_verifications = []
def create_and_check_verification(self, resource_type=None,
resource_ref=None,
resource_action=None,
impersonation_allowed=False):
"""Creates verification, gets verification."""
resp = self.create_verification_overriding_cfg(
resource_type=resource_type, resource_ref=resource_ref,
resource_action=resource_action,
impersonation_allowed=impersonation_allowed)
get_verification_resp = self.verifications_client.get_verification(
verification_id=resp.id)
behavior_response = CloudkeepResponse(resp=resp.create_resp,
get_resp=get_verification_resp)
return behavior_response
def create_verification_from_config(self):
"""Creates verification from configuration."""
resp = self.create_verification(
resource_type=self.config.resource_type,
resource_ref=self.config.resource_ref,
resource_action=self.config.resource_action,
impersonation_allowed=self.config.impersonation_allowed)
return resp
def create_verification_overriding_cfg(self, resource_type=None,
resource_ref=None,
resource_action=None,
impersonation_allowed=False):
"""Creates verification using provided parameters or default
configurations. Allows for testing individual parameters on creation.
"""
if impersonation_allowed is None:
imp_allowed = False
else:
imp_allowed = impersonation_allowed
resp = self.create_verification(
resource_type=resource_type or self.config.resource_type,
resource_ref=resource_ref or self.config.resource_ref,
resource_action=resource_action or self.config.resource_action,
impersonation_allowed=imp_allowed)
return resp
def create_verification(self,
resource_type=None,
resource_ref=None,
resource_action=None,
impersonation_allowed=False):
try:
resp = self.verifications_client.create_verification(
resource_type=resource_type,
resource_ref=resource_ref,
resource_action=resource_action,
impersonation_allowed=impersonation_allowed)
except ConnectionError as e:
# Gracefully handling when Falcon doesn't properly handle our req
if type(e.message.reason) is BadStatusLine:
return {'status_code': 0}
raise e
behavior_response = CloudkeepResponse(resp=resp)
verification_id = behavior_response.id
if verification_id is not None:
self.created_verifications.append(behavior_response.id)
return behavior_response
def delete_verification(self, verification_id):
resp = self.verifications_client.delete_verification(verification_id)
if verification_id in self.created_verifications:
self.created_verifications.remove(verification_id)
return resp
def delete_all_verifications_in_db(self):
verification_group = \
self.verifications_client.get_verifications().entity
found_ids = []
found_ids.extend(verification_group.get_ids())
while verification_group.next is not None:
query = verification_group.get_next_query_data()
verification_group = self.verifications_client.get_verifications(
limit=query.get('limit'),
offset=query.get('offset')).entity
found_ids.extend(verification_group.get_ids())
for verification_id in found_ids:
self.delete_verification(verification_id)
def delete_all_created_verifications(self):
for verification_id in list(self.created_verifications):
self.delete_verification(verification_id)
self.created_verifications = []
def remove_from_created_verifications(self, verification_id):
if verification_id in self.created_verifications:
self.created_verifications.remove(verification_id)
def find_verification(self, verification_id):
verification_group = \
self.verifications_client.get_verifications().entity
ids = verification_group.get_ids()
while verification_id not in ids and \
verification_group.next is not None:
query = verification_group.get_next_query_data()
verification_group = self.verifications_client.get_verifications(
limit=query.get('limit'),
offset=query.get('offset')).entity
ids = verification_group.get_ids()
for verification in verification_group.verifications:
if verification.get_id() == verification_id:
return verification
else:
return None

View File

@ -0,0 +1,86 @@
"""
Copyright 2013 Rackspace
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 cloudcafe.cloudkeep.barbican.client import BarbicanRestClient
from cloudcafe.cloudkeep.barbican.verifications.models.verification \
import Verification, VerificationRequest, \
VerificationRef, VerificationGroup
class VerificationsClient(BarbicanRestClient):
def __init__(self, url, api_version, tenant_id, token=None,
serialize_format=None, deserialize_format=None):
super(VerificationsClient, self).__init__(
token=token, serialize_format=serialize_format,
deserialize_format=deserialize_format)
self.url = url
self.api_version = api_version
self.tenant_id = tenant_id
def _get_base_url(self):
return '{base}/{api_version}/{tenant_id}/verifications'.format(
base=self.url,
api_version=self.api_version,
tenant_id=self.tenant_id)
def _get_verification_url(self, verification_id):
return '{base}/{verification_id}'.format(
base=self._get_base_url(), verification_id=verification_id)
def create_verification(self, resource_type=None, resource_ref=None,
resource_action=None, impersonation_allowed=False):
"""
POST http://.../v1/{tenant_id}/verifications
Creates a request to verify a resource
"""
remote_url = self._get_base_url()
req_obj = VerificationRequest(resource_type=resource_type,
resource_ref=resource_ref,
resource_action=resource_action,
impersonation_allowed=
impersonation_allowed)
resp = self.request('POST', remote_url, request_entity=req_obj,
response_entity_type=VerificationRef)
return resp
def get_verification(self, verification_id=None, ref=None):
"""
GET http://.../v1/{tenant_id}/verifications/{verification_uuid}
Retrieves a verification
"""
remote_url = ref or self._get_verification_url(verification_id)
return self.request('GET', remote_url,
response_entity_type=Verification)
def delete_verification(self, verification_id):
"""
DELETE http://.../v1/{tenant_id}/verifications/{verification_uuid}
Cancels a verification
"""
return self.request('DELETE',
self._get_verification_url(verification_id))
def get_verifications(self, limit=None, offset=None, ref=None):
"""
GET http://.../v1/verifications?limit={limit}&offset={offset} or {ref}
Gets a list of verifications
"""
remote_url = ref or self._get_base_url()
resp = self.request('GET', remote_url,
params={'limit': limit, 'offset': offset},
response_entity_type=VerificationGroup)
return resp

View File

@ -0,0 +1,15 @@
"""
Copyright 2013 Rackspace
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.
"""

View File

@ -0,0 +1,175 @@
"""
Copyright 2013 Rackspace
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 re
from os import path
from json import dumps as dict_to_str, loads as str_to_dict
from cafe.engine.models.base import AutoMarshallingModel
class VerificationRequest(AutoMarshallingModel):
def __init__(self,
resource_action=None,
resource_ref=None,
impersonation_allowed=False,
resource_type=None):
super(VerificationRequest, self).__init__()
self.resource_action = resource_action
self.resource_ref = resource_ref
self.impersonation_allowed = impersonation_allowed
self.resource_type = resource_type
def get_id_from_ref(self, ref):
"""Returns id from reference."""
ref_id = None
if ref is not None and len(ref) > 0:
ref_id = path.split(ref)[1]
return ref_id
def get_id(self):
"""Returns verification id."""
return self.get_id_from_ref(ref=self.verification_ref)
def _obj_to_json(self):
the_dict = {
'resource_action': self.resource_action,
'resource_ref': self.resource_ref,
'impersonation_allowed': self.impersonation_allowed,
'resource_type': self.resource_type
}
return dict_to_str(the_dict)
@classmethod
def _json_to_obj(cls, serialized_str):
json_dict = str_to_dict(serialized_str)
return cls._dict_to_obj(json_dict)
@classmethod
def _dict_to_obj(cls, json_dict):
args = {
'resource_action': json_dict.get('resource_action'),
'resource_ref': json_dict.get('resource_ref'),
'impersonation_allowed': json_dict.get('impersonation_allowed'),
'resource_type': json_dict.get('resource_type')
}
return Verification(**args)
class Verification(AutoMarshallingModel):
def __init__(self, status=None, updated=None, created=None,
resource_action=None, resource_ref=None,
impersonation_allowed=False, verification_ref=None,
is_verified=None, resource_type=None):
super(Verification, self).__init__()
self.status = status
self.updated = updated
self.created = created
self.resource_action = resource_action
self.resource_ref = resource_ref
self.impersonation_allowed = impersonation_allowed
self.verification_ref = verification_ref
self.is_verified = is_verified
self.resource_type = resource_type
def get_id_from_ref(self, ref):
"""Returns id from reference."""
ref_id = None
if ref is not None and len(ref) > 0:
ref_id = path.split(ref)[1]
return ref_id
def get_id(self):
"""Returns verification id."""
return self.get_id_from_ref(ref=self.verification_ref)
def _obj_to_json(self):
return dict_to_str(self._obj_to_dict())
@classmethod
def _json_to_obj(cls, serialized_str):
json_dict = str_to_dict(serialized_str)
return cls._dict_to_obj(json_dict)
@classmethod
def _dict_to_obj(cls, json_dict):
args = {
'status': json_dict.get('status'),
'updated': json_dict.get('updated'),
'created': json_dict.get('created'),
'resource_action': json_dict.get('resource_action'),
'resource_ref': json_dict.get('resource_ref'),
'impersonation_allowed': json_dict.get('impersonation_allowed'),
'verification_ref': json_dict.get('verification_ref'),
'is_verified': json_dict.get('is_verified'),
'resource_type': json_dict.get('resource_type')
}
return Verification(**args)
class VerificationRef(AutoMarshallingModel):
def __init__(self, reference):
super(VerificationRef, self).__init__()
self.reference = reference
@classmethod
def _json_to_obj(cls, serialized_str):
json_dict = str_to_dict(serialized_str)
return cls._dict_to_obj(json_dict)
@classmethod
def _dict_to_obj(cls, json_dict):
return VerificationRef(reference=json_dict.get('verification_ref'))
class VerificationGroup(AutoMarshallingModel):
def __init__(self, verifications, next_list=None, previous_list=None):
super(VerificationGroup, self).__init__()
self.verifications = verifications
self.next = next_list
self.previous = previous_list
def get_ids(self):
return [verification.get_id() for verification in self.verifications]
def get_next_query_data(self):
matches = re.search('.*\?(.*?)\=(\d*)&(.*?)\=(\d*)', self.next)
return {
'limit': matches.group(2),
'offset': matches.group(4)
}
@classmethod
def _json_to_obj(cls, serialized_str):
json_dict = str_to_dict(serialized_str)
return cls._dict_to_obj(json_dict)
@classmethod
def _dict_to_obj(cls, json_dict):
verifications, next_list, prev_list = [], None, None
for verification_dict in json_dict.get('verifications'):
verifications.append(Verification._dict_to_obj(verification_dict))
if 'next' in json_dict:
next_list = json_dict.get('next')
if 'previous' in json_dict:
prev_list = json_dict.get('previous')
return VerificationGroup(verifications, next_list, prev_list)

View File

@ -22,3 +22,7 @@ class SecretsStates(object):
class OrdersStates(SecretsStates):
PENDING = "PENDING"
class VerificationsStates(SecretsStates):
PENDING = "PENDING"

View File

@ -123,3 +123,23 @@ class CloudKeepRBACRoleConfig(ConfigSectionInterface):
@property
def audit(self):
return self.get('audit')
class CloudKeepVerificationsConfig(ConfigSectionInterface):
SECTION_NAME = 'cloudkeep-verifications'
@property
def resource_type(self):
return self.get("resource_type")
@property
def resource_ref(self):
return self.get("resource_ref")
@property
def resource_action(self):
return self.get("resource_action")
@property
def impersonation_allowed(self):
return self.get("impersonation_allowed")

View File

@ -34,6 +34,12 @@ payload=testdata
payload_content_type=application/octet-stream
payload_content_encoding=base64
[cloudkeep-verifications]
resource_ref=<resource_ref>
resource_type=image
resource_action=vm_attach
impersonation_allowed=False
[cloudkeep-orders]
name=secretname
algorithm=aes