Coverage for manila/share/drivers/netapp/dataontap/client/client_base.py: 100%

55 statements  

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

1# Copyright (c) 2014 Alex Meade. All rights reserved. 

2# Copyright (c) 2014 Clinton Knight. 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 

16from oslo_log import log 

17from oslo_utils import excutils 

18 

19from manila.share.drivers.netapp.dataontap.client import api as netapp_api 

20from manila.share.drivers.netapp import utils as na_utils 

21 

22 

23LOG = log.getLogger(__name__) 

24 

25 

26class NetAppBaseClient(object): 

27 

28 def __init__(self, **kwargs): 

29 self.connection = netapp_api.NaServer( 

30 host=kwargs['hostname'], 

31 transport_type=kwargs['transport_type'], 

32 ssl_cert_path=kwargs['ssl_cert_path'], 

33 port=kwargs['port'], 

34 username=kwargs['username'], 

35 password=kwargs['password'], 

36 trace=kwargs.get('trace', False), 

37 api_trace_pattern=kwargs.get('api_trace_pattern', 

38 na_utils.API_TRACE_PATTERN), 

39 private_key_file=kwargs['private_key_file'], 

40 certificate_file=kwargs['certificate_file'], 

41 ca_certificate_file=kwargs['ca_certificate_file'], 

42 certificate_host_validation=kwargs['certificate_host_validation']) 

43 

44 def get_ontapi_version(self, cached=True): 

45 """Gets the supported ontapi version.""" 

46 

47 if cached: 

48 return self.connection.get_api_version() 

49 

50 result = self.send_request('system-get-ontapi-version', 

51 enable_tunneling=False) 

52 major = result.get_child_content('major-version') 

53 minor = result.get_child_content('minor-version') 

54 return major, minor 

55 

56 @na_utils.trace 

57 def get_system_version(self, cached=True): 

58 """Gets the current Data ONTAP version.""" 

59 

60 if cached: 

61 return self.connection.get_system_version() 

62 

63 result = self.send_request('system-get-version', 

64 enable_tunneling=False) 

65 

66 version_tuple = result.get_child_by_name( 

67 'version-tuple') or netapp_api.NaElement('none') 

68 system_version_tuple = version_tuple.get_child_by_name( 

69 'system-version-tuple') or netapp_api.NaElement('none') 

70 

71 version = {} 

72 version['version'] = result.get_child_content('version') 

73 version['version-tuple'] = ( 

74 int(system_version_tuple.get_child_content('generation')), 

75 int(system_version_tuple.get_child_content('major')), 

76 int(system_version_tuple.get_child_content('minor'))) 

77 

78 return version 

79 

80 def _init_features(self): 

81 """Set up the repository of available Data ONTAP features.""" 

82 self.features = Features() 

83 

84 def _strip_xml_namespace(self, string): 

85 if string.startswith('{') and '}' in string: 

86 return string.split('}', 1)[1] 

87 return string 

88 

89 def send_request(self, api_name, api_args=None, enable_tunneling=True, 

90 use_zapi=True): 

91 """Sends request to Ontapi.""" 

92 request = netapp_api.NaElement(api_name) 

93 return self.connection.invoke_successfully( 

94 request, api_args=api_args, enable_tunneling=enable_tunneling, 

95 use_zapi=use_zapi) 

96 

97 @na_utils.trace 

98 def get_licenses(self): 

99 try: 

100 result = self.send_request('license-v2-list-info') 

101 except netapp_api.NaApiError: 

102 with excutils.save_and_reraise_exception(): 

103 LOG.exception("Could not get licenses list.") 

104 

105 return sorted( 

106 [child.get_child_content('package').lower() 

107 for child in result.get_child_by_name('licenses').get_children()]) 

108 

109 def send_ems_log_message(self, message_dict): 

110 """Sends a message to the Data ONTAP EMS log.""" 

111 raise NotImplementedError() 

112 

113 

114class Features(object): 

115 

116 def __init__(self): 

117 self.defined_features = set() 

118 

119 def add_feature(self, name, supported=True): 

120 if not isinstance(supported, bool): 

121 raise TypeError("Feature value must be a bool type.") 

122 self.defined_features.add(name) 

123 setattr(self, name, supported) 

124 

125 def __getattr__(self, name): 

126 # NOTE(cknight): Needed to keep pylint happy. 

127 raise AttributeError