Coverage for manila/share/drivers/quobyte/jsonrpc.py: 92%
58 statements
« prev ^ index » next coverage.py v7.11.0, created at 2026-02-18 22:19 +0000
« prev ^ index » next coverage.py v7.11.0, created at 2026-02-18 22:19 +0000
1# Copyright (c) 2015 Quobyte Inc.
2# All Rights Reserved.
3#
4# Licensed under the Apache License, Version 2.0 (the "License"); you may
5# not use this file except in compliance with the License. You may obtain
6# a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13# License for the specific language governing permissions and limitations
14# under the License.
16"""Quobyte driver helper.
18Control Quobyte over its JSON RPC API.
19"""
21import requests
22from requests import auth
23from requests import codes
24from urllib import parse as urlparse
26from oslo_log import log
27from oslo_serialization import jsonutils
29from manila import exception
30from manila import utils
32LOG = log.getLogger(__name__)
34ERROR_ENOENT = 2
35ERROR_ENTITY_NOT_FOUND = -24
36ERROR_GARBAGE_ARGS = -3
39class JsonRpc(object):
41 def __init__(self, url, user_credentials, ca_file=None, key_file=None,
42 cert_file=None):
43 parsedurl = urlparse.urlparse(url)
44 self._url = parsedurl.geturl()
45 self._netloc = parsedurl.netloc
46 self._ca_file = ca_file
47 self._url_scheme = parsedurl.scheme
48 if self._url_scheme == 'https':
49 if not self._ca_file:
50 self._ca_file = False
51 LOG.warning(
52 "Will not verify the server certificate of the API service"
53 " because the CA certificate is not available.")
54 self._id = 0
55 self._credentials = auth.HTTPBasicAuth(
56 user_credentials[0], user_credentials[1])
57 self._key_file = key_file
58 self._cert_file = cert_file
60 @utils.synchronized('quobyte-request')
61 def call(self, method_name, user_parameters, expected_errors=None):
62 if expected_errors is None:
63 expected_errors = []
64 # prepare request
65 self._id += 1
66 parameters = {'retry': 'INFINITELY'} # Backend specific setting
67 if user_parameters: 67 ↛ 69line 67 didn't jump to line 69 because the condition on line 67 was always true
68 parameters.update(user_parameters)
69 post_data = {
70 'jsonrpc': '2.0',
71 'method': method_name,
72 'params': parameters,
73 'id': str(self._id),
74 }
75 LOG.debug("Request payload to be send is: %s",
76 jsonutils.dumps(post_data))
78 # send request
79 if self._url_scheme == 'https':
80 if self._cert_file:
81 result = requests.post(url=self._url,
82 json=post_data,
83 auth=self._credentials,
84 verify=self._ca_file,
85 cert=(self._cert_file, self._key_file),
86 timeout=60)
87 else:
88 result = requests.post(url=self._url,
89 json=post_data,
90 auth=self._credentials,
91 verify=self._ca_file,
92 timeout=60)
93 else:
94 result = requests.post(url=self._url,
95 json=post_data,
96 auth=self._credentials,
97 timeout=60)
99 # eval request response
100 if result.status_code == codes['OK']: 100 ↛ 107line 100 didn't jump to line 107 because the condition on line 100 was always true
101 LOG.debug("Retrieved data from Quobyte backend: %s", result.text)
102 response = result.json()
103 return self._checked_for_application_error(response,
104 expected_errors)
106 # If things did not work out provide error info
107 LOG.debug("Backend request resulted in error: %s", result.text)
108 result.raise_for_status()
110 def _checked_for_application_error(self, result, expected_errors=None):
111 if expected_errors is None:
112 expected_errors = []
113 if 'error' in result and result['error']:
114 if 'message' in result['error'] and 'code' in result['error']: 114 ↛ 123line 114 didn't jump to line 123 because the condition on line 114 was always true
115 if result["error"]["code"] in expected_errors:
116 # hit an expected error, return empty result
117 return None
118 else:
119 raise exception.QBRpcException(
120 result=result["error"]["message"],
121 qbcode=result["error"]["code"])
122 else:
123 raise exception.QBException(str(result["error"]))
124 return result["result"]