1# Licensed under the Apache License, Version 2.0 (the "License"); you may 2# not use this file except in compliance with the License. You may obtain 3# a copy of the License at 4# 5# http://www.apache.org/licenses/LICENSE-2.0 6# 7# Unless required by applicable law or agreed to in writing, software 8# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10# License for the specific language governing permissions and limitations 11# under the License. 12 13from openstack.key_manager.v1 import _format 14from openstack import resource 15from openstack import utils 16 17 18class Secret(resource.Resource): 19 resources_key = 'secrets' 20 base_path = '/secrets' 21 22 # capabilities 23 allow_create = True 24 allow_fetch = True 25 allow_commit = True 26 allow_delete = True 27 allow_list = True 28 29 _query_mapping = resource.QueryParameters( 30 "name", "mode", "bits", 31 "secret_type", "acl_only", 32 "created", "updated", 33 "expiration", "sort", 34 algorithm="alg") 35 36 # Properties 37 #: Metadata provided by a user or system for informational purposes 38 algorithm = resource.Body('algorithm') 39 #: Metadata provided by a user or system for informational purposes. 40 #: Value must be greater than zero. 41 bit_length = resource.Body('bit_length') 42 #: A list of content types 43 content_types = resource.Body('content_types', type=dict) 44 #: Once this timestamp has past, the secret will no longer be available. 45 expires_at = resource.Body('expiration') 46 #: Timestamp of when the secret was created. 47 created_at = resource.Body('created') 48 #: Timestamp of when the secret was last updated. 49 updated_at = resource.Body('updated') 50 #: The type/mode of the algorithm associated with the secret information. 51 mode = resource.Body('mode') 52 #: The name of the secret set by the user 53 name = resource.Body('name') 54 #: A URI to the sercret 55 secret_ref = resource.Body('secret_ref') 56 #: The ID of the secret 57 # NOTE: This is not really how alternate IDs are supposed to work and 58 # ultimately means this has to work differently than all other services 59 # in all of OpenStack because of the departure from using actual IDs 60 # that even this service can't even use itself. 61 secret_id = resource.Body( 62 'secret_ref', alternate_id=True, type=_format.HREFToUUID) 63 #: Used to indicate the type of secret being stored. 64 secret_type = resource.Body('secret_type') 65 #: The status of this secret 66 status = resource.Body('status') 67 #: A timestamp when this secret was updated. 68 updated_at = resource.Body('updated') 69 #: The secret's data to be stored. payload_content_type must also 70 #: be supplied if payload is included. (optional) 71 payload = resource.Body('payload') 72 #: The media type for the content of the payload. 73 #: (required if payload is included) 74 payload_content_type = resource.Body('payload_content_type') 75 #: The encoding used for the payload to be able to include it in 76 #: the JSON request. Currently only base64 is supported. 77 #: (required if payload is encoded) 78 payload_content_encoding = resource.Body('payload_content_encoding') 79 80 def fetch(self, session, requires_id=True, 81 base_path=None, error_message=None): 82 request = self._prepare_request(requires_id=requires_id, 83 base_path=base_path) 84 85 response = session.get(request.url).json() 86 87 content_type = None 88 if self.payload_content_type is not None: 89 content_type = self.payload_content_type 90 elif "content_types" in response: 91 content_type = response["content_types"]["default"] 92 93 # Only try to get the payload if a content type has been explicitly 94 # specified or if one was found in the metadata response 95 if content_type is not None: 96 payload = session.get(utils.urljoin(request.url, "payload"), 97 headers={"Accept": content_type}) 98 response["payload"] = payload.text 99 100 # We already have the JSON here so don't call into _translate_response 101 self._update_from_body_attrs(response) 102 103 return self 104