1 # Copyright 2018 Intel Corporation, Inc
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
16 import requests.exceptions
19 name = "onap-sms-client"
22 class InvalidRequestException(Exception):
26 class InternalServerError(Exception):
30 class UnexpectedError(Exception):
35 """Python Client for Secret Management Service"""
37 def __init__(self, url='http://localhost:10443', timeout=30, cacert=None):
38 """Creates a new SMS client instance
41 url (str): Base URL with port pointing to the SMS service
42 timeout (int): Number of seconds before aborting the connection
43 cacert (str): Path to the cacert that will be used to verify
44 If this is None, verify will be False and the server cert
45 is not verified by the client.
47 A Client object which can be used to interact with SMS service
51 self.timeout = timeout
53 self.session = requests.Session()
55 self._base_api_url = '/v1/sms'
57 def _urlJoin(self, *urls):
58 """Joins given urls into a single url
61 urls (str): url fragments to be combined.
69 def _raiseException(self, statuscode, errors=None):
70 """ Handles Exception Raising based on statusCode
73 statuscode (int): status code returned by the server
74 errors (str): list of strings containing error messages
77 exception: An exception is raised based on error message
81 raise InvalidRequestException(errors)
83 raise InternalServerError(errors)
85 raise UnexpectedError(errors)
87 def _request(self, method, url, headers=None, **kwargs):
88 """Handles request for all the client methods
91 method (str): type of HTTP method (get, post or delete).
93 headers (dict): custom headers if any.
94 **kwargs: various args supported by requests library
97 requests.Response: An object containing status_code and returned
98 json data is returned here.
103 'content-type': "application/json",
104 'Accept': "application/json"
107 # Verify the server or not based on the cacert argument
108 if self.cacert is None:
113 url = urlparse.urljoin(self.base_url, url)
114 response = self.session.request(method, url, headers=headers,
115 allow_redirects=False, verify=verify,
116 timeout=self.timeout, **kwargs)
119 if response.status_code >= 400 and response.status_code < 600:
120 # Request Failed. Raise Exception.
121 errors = response.text
122 self._raiseException(response.status_code, errors)
127 """Returns Status of SMS Service
130 bool: True or False depending on if SMS Service is ready.
133 url = self._urlJoin(self._base_api_url, 'quorum', 'status')
135 response = self._request('get', url)
136 return response.json()['sealstatus']
138 def createDomain(self, domainName):
139 """Creates a Secret Domain
142 domainName (str): Name of the secret domain to create
145 string: UUID of the created domain name
148 domainName = domainName.strip()
149 data = {"name": domainName}
150 url = self._urlJoin(self._base_api_url, 'domain')
152 response = self._request('post', url, json=data)
153 return response.json()['uuid']
155 def deleteDomain(self, domainName):
156 """Deletes a Secret Domain
159 domainName (str): Name of the secret domain to delete
162 bool: True. An exception will be raised if delete failed.
165 domainName = domainName.strip()
166 url = self._urlJoin(self._base_api_url, 'domain', domainName)
168 self._request('delete', url)
171 def getSecretNames(self, domainName):
172 """Get all Secret Names in Domain
175 domainName (str): Name of the secret domain
178 string[]: List of strings each corresponding to a
179 Secret's Name in this Domain.
182 domainName = domainName.strip()
183 url = self._urlJoin(self._base_api_url, 'domain', domainName,
186 response = self._request('get', url)
187 return response.json()['secretnames']
189 def storeSecret(self, domainName, secretName, values):
190 """Store a Secret in given Domain
193 domainName (str): Name of the secret domain
194 secretName (str): Name for the Secret
195 values (dict): A dict containing name-value pairs which
199 bool: True. An exception will be raised if store failed.
202 domainName = domainName.strip()
203 secretName = secretName.strip()
204 url = self._urlJoin(self._base_api_url, 'domain', domainName,
207 if not isinstance(values, dict):
208 raise TypeError('Input values is not a dictionary')
210 data = {"name": secretName, "values": values}
211 self._request('post', url, json=data)
214 def getSecret(self, domainName, secretName):
215 """Get a particular Secret from Domain.
218 domainName (str): Name of the secret domain
219 secretName (str): Name of the secret
222 dict: dictionary containing the name-value pairs
223 which form the secret
226 domainName = domainName.strip()
227 secretName = secretName.strip()
228 url = self._urlJoin(self._base_api_url, 'domain', domainName,
229 'secret', secretName)
231 response = self._request('get', url)
232 return response.json()['values']
234 def deleteSecret(self, domainName, secretName):
235 """Delete a particular Secret from Domain.
238 domainName (str): Name of the secret domain
239 secretName (str): Name of the secret
242 bool: True. An exception will be raised if delete failed.
245 domainName = domainName.strip()
246 secretName = secretName.strip()
247 url = self._urlJoin(self._base_api_url, 'domain', domainName,
248 'secret', secretName)
250 self._request('delete', url)