Coverage for manila/share/drivers/nexenta/ns4/jsonrpc.py: 92%

47 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2026-02-18 22:19 +0000

1# Copyright 2016 Nexenta Systems, 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. 

15""" 

16:mod:`nexenta.jsonrpc` -- Nexenta-specific JSON RPC client 

17===================================================================== 

18 

19.. automodule:: nexenta.jsonrpc 

20""" 

21 

22import base64 

23import json 

24import requests 

25 

26from oslo_log import log 

27from oslo_serialization import jsonutils 

28 

29from manila import exception 

30from manila import utils 

31 

32LOG = log.getLogger(__name__) 

33 

34 

35class NexentaJSONProxy(object): 

36 

37 retry_exc_tuple = (requests.exceptions.ConnectionError,) 

38 

39 def __init__(self, scheme, host, port, path, user, password, auto=False, 

40 obj=None, method=None): 

41 self.scheme = scheme.lower() 

42 self.host = host 

43 self.port = port 

44 self.path = path 

45 self.user = user 

46 self.password = password 

47 self.auto = auto 

48 self.obj = obj 

49 self.method = method 

50 

51 def __getattr__(self, name): 

52 if not self.obj: 

53 obj, method = name, None 

54 elif not self.method: 54 ↛ 57line 54 didn't jump to line 57 because the condition on line 54 was always true

55 obj, method = self.obj, name 

56 else: 

57 obj, method = '%s.%s' % (self.obj, self.method), name 

58 return NexentaJSONProxy(self.scheme, self.host, self.port, self.path, 

59 self.user, self.password, self.auto, obj, 

60 method) 

61 

62 @property 

63 def url(self): 

64 return '%s://%s:%s%s' % (self.scheme, self.host, self.port, self.path) 

65 

66 def __hash__(self): 

67 return self.url.__hash__() 

68 

69 def __repr__(self): 

70 return 'NMS proxy: %s' % self.url 

71 

72 @utils.retry(retry_param=retry_exc_tuple, retries=6) 

73 def __call__(self, *args): 

74 data = jsonutils.dumps({ 

75 'object': self.obj, 

76 'method': self.method, 

77 'params': args, 

78 }) 

79 auth = base64.b64encode( 

80 ('%s:%s' % (self.user, self.password)).encode('utf-8')) 

81 headers = { 

82 'Content-Type': 'application/json', 

83 'Authorization': 'Basic %s' % auth, 

84 } 

85 LOG.debug('Sending JSON data: %s', data) 

86 r = requests.post(self.url, data=data, headers=headers, timeout=60) 

87 response = json.loads(r.content) if r.content else None 

88 LOG.debug('Got response: %s', response) 

89 if response.get('error') is not None: 

90 message = response['error'].get('message', '') 

91 raise exception.NexentaException(reason=message) 

92 return response.get('result')