]>
Commit | Line | Data |
---|---|---|
11fdf7f2 TL |
1 | # -*- coding: utf-8 -*- |
2 | # pylint: disable=too-many-public-methods | |
11fdf7f2 TL |
3 | |
4 | import json | |
9f95a23c | 5 | import logging |
11fdf7f2 TL |
6 | |
7 | from requests.auth import HTTPBasicAuth | |
8 | ||
9 | try: | |
10 | from urlparse import urlparse | |
11 | except ImportError: | |
12 | from urllib.parse import urlparse | |
13 | ||
11fdf7f2 | 14 | from ..rest_client import RestClient |
f67539c2 TL |
15 | from ..settings import Settings |
16 | from .iscsi_config import IscsiGatewaysConfig | |
11fdf7f2 | 17 | |
9f95a23c TL |
18 | logger = logging.getLogger('iscsi_client') |
19 | ||
20 | ||
11fdf7f2 TL |
21 | class IscsiClient(RestClient): |
22 | _CLIENT_NAME = 'iscsi' | |
9f95a23c | 23 | _instances = {} # type: dict |
11fdf7f2 TL |
24 | |
25 | service_url = None | |
26 | gateway_name = None | |
27 | ||
28 | @classmethod | |
29 | def instance(cls, gateway_name=None, service_url=None): | |
30 | if not service_url: | |
31 | if not gateway_name: | |
32 | gateway_name = list(IscsiGatewaysConfig.get_gateways_config()['gateways'].keys())[0] | |
33 | gateways_config = IscsiGatewaysConfig.get_gateway_config(gateway_name) | |
34 | service_url = gateways_config['service_url'] | |
35 | ||
36 | instance = cls._instances.get(gateway_name) | |
37 | if not instance or service_url != instance.service_url or \ | |
38 | instance.session.verify != Settings.ISCSI_API_SSL_VERIFICATION: | |
39 | url = urlparse(service_url) | |
40 | ssl = url.scheme == 'https' | |
41 | host = url.hostname | |
42 | port = url.port | |
43 | username = url.username | |
44 | password = url.password | |
45 | if not port: | |
46 | port = 443 if ssl else 80 | |
47 | ||
48 | auth = HTTPBasicAuth(username, password) | |
49 | instance = IscsiClient(host, port, IscsiClient._CLIENT_NAME, ssl, | |
50 | auth, Settings.ISCSI_API_SSL_VERIFICATION) | |
51 | instance.service_url = service_url | |
52 | instance.gateway_name = gateway_name | |
53 | if gateway_name: | |
54 | cls._instances[gateway_name] = instance | |
55 | ||
56 | return instance | |
57 | ||
58 | @RestClient.api_get('/api/_ping') | |
59 | def ping(self, request=None): | |
60 | return request() | |
61 | ||
62 | @RestClient.api_get('/api/settings') | |
63 | def get_settings(self, request=None): | |
64 | return request() | |
65 | ||
66 | @RestClient.api_get('/api/sysinfo/ip_addresses') | |
67 | def get_ip_addresses(self, request=None): | |
68 | return request() | |
69 | ||
70 | @RestClient.api_get('/api/sysinfo/hostname') | |
71 | def get_hostname(self, request=None): | |
72 | return request() | |
73 | ||
74 | @RestClient.api_get('/api/config') | |
75 | def get_config(self, request=None): | |
76 | return request({ | |
77 | 'decrypt_passwords': True | |
78 | }) | |
79 | ||
80 | @RestClient.api_put('/api/target/{target_iqn}') | |
81 | def create_target(self, target_iqn, target_controls, request=None): | |
9f95a23c | 82 | logger.debug("[%s] Creating target: %s", self.gateway_name, target_iqn) |
11fdf7f2 TL |
83 | return request({ |
84 | 'controls': json.dumps(target_controls) | |
85 | }) | |
86 | ||
87 | @RestClient.api_delete('/api/target/{target_iqn}') | |
88 | def delete_target(self, target_iqn, request=None): | |
9f95a23c | 89 | logger.debug("[%s] Deleting target: %s", self.gateway_name, target_iqn) |
11fdf7f2 TL |
90 | return request() |
91 | ||
92 | @RestClient.api_put('/api/target/{target_iqn}') | |
93 | def reconfigure_target(self, target_iqn, target_controls, request=None): | |
9f95a23c | 94 | logger.debug("[%s] Reconfiguring target: %s", self.gateway_name, target_iqn) |
11fdf7f2 TL |
95 | return request({ |
96 | 'mode': 'reconfigure', | |
97 | 'controls': json.dumps(target_controls) | |
98 | }) | |
99 | ||
100 | @RestClient.api_put('/api/gateway/{target_iqn}/{gateway_name}') | |
101 | def create_gateway(self, target_iqn, gateway_name, ip_address, request=None): | |
9f95a23c | 102 | logger.debug("[%s] Creating gateway: %s/%s", self.gateway_name, target_iqn, |
11fdf7f2 TL |
103 | gateway_name) |
104 | return request({ | |
105 | 'ip_address': ','.join(ip_address), | |
106 | 'skipchecks': 'true' | |
107 | }) | |
108 | ||
109 | @RestClient.api_get('/api/gatewayinfo') | |
110 | def get_gatewayinfo(self, request=None): | |
111 | return request() | |
112 | ||
494da23a TL |
113 | @RestClient.api_delete('/api/gateway/{target_iqn}/{gateway_name}') |
114 | def delete_gateway(self, target_iqn, gateway_name, request=None): | |
9f95a23c | 115 | logger.debug("Deleting gateway: %s/%s", target_iqn, gateway_name) |
494da23a TL |
116 | return request() |
117 | ||
11fdf7f2 | 118 | @RestClient.api_put('/api/disk/{pool}/{image}') |
eafe8130 | 119 | def create_disk(self, pool, image, backstore, wwn, request=None): |
9f95a23c | 120 | logger.debug("[%s] Creating disk: %s/%s", self.gateway_name, pool, image) |
11fdf7f2 TL |
121 | return request({ |
122 | 'mode': 'create', | |
eafe8130 TL |
123 | 'backstore': backstore, |
124 | 'wwn': wwn | |
11fdf7f2 TL |
125 | }) |
126 | ||
127 | @RestClient.api_delete('/api/disk/{pool}/{image}') | |
128 | def delete_disk(self, pool, image, request=None): | |
9f95a23c | 129 | logger.debug("[%s] Deleting disk: %s/%s", self.gateway_name, pool, image) |
11fdf7f2 TL |
130 | return request({ |
131 | 'preserve_image': 'true' | |
132 | }) | |
133 | ||
134 | @RestClient.api_put('/api/disk/{pool}/{image}') | |
135 | def reconfigure_disk(self, pool, image, controls, request=None): | |
9f95a23c | 136 | logger.debug("[%s] Reconfiguring disk: %s/%s", self.gateway_name, pool, image) |
11fdf7f2 TL |
137 | return request({ |
138 | 'controls': json.dumps(controls), | |
139 | 'mode': 'reconfigure' | |
140 | }) | |
141 | ||
142 | @RestClient.api_put('/api/targetlun/{target_iqn}') | |
eafe8130 | 143 | def create_target_lun(self, target_iqn, image_id, lun, request=None): |
9f95a23c | 144 | logger.debug("[%s] Creating target lun: %s/%s", self.gateway_name, target_iqn, |
11fdf7f2 TL |
145 | image_id) |
146 | return request({ | |
eafe8130 TL |
147 | 'disk': image_id, |
148 | 'lun_id': lun | |
11fdf7f2 TL |
149 | }) |
150 | ||
151 | @RestClient.api_delete('/api/targetlun/{target_iqn}') | |
152 | def delete_target_lun(self, target_iqn, image_id, request=None): | |
9f95a23c | 153 | logger.debug("[%s] Deleting target lun: %s/%s", self.gateway_name, target_iqn, |
11fdf7f2 TL |
154 | image_id) |
155 | return request({ | |
156 | 'disk': image_id | |
157 | }) | |
158 | ||
159 | @RestClient.api_put('/api/client/{target_iqn}/{client_iqn}') | |
160 | def create_client(self, target_iqn, client_iqn, request=None): | |
9f95a23c | 161 | logger.debug("[%s] Creating client: %s/%s", self.gateway_name, target_iqn, client_iqn) |
11fdf7f2 TL |
162 | return request() |
163 | ||
164 | @RestClient.api_delete('/api/client/{target_iqn}/{client_iqn}') | |
165 | def delete_client(self, target_iqn, client_iqn, request=None): | |
9f95a23c | 166 | logger.debug("[%s] Deleting client: %s/%s", self.gateway_name, target_iqn, client_iqn) |
11fdf7f2 TL |
167 | return request() |
168 | ||
169 | @RestClient.api_put('/api/clientlun/{target_iqn}/{client_iqn}') | |
170 | def create_client_lun(self, target_iqn, client_iqn, image_id, request=None): | |
9f95a23c | 171 | logger.debug("[%s] Creating client lun: %s/%s", self.gateway_name, target_iqn, |
11fdf7f2 TL |
172 | client_iqn) |
173 | return request({ | |
174 | 'disk': image_id | |
175 | }) | |
176 | ||
eafe8130 TL |
177 | @RestClient.api_delete('/api/clientlun/{target_iqn}/{client_iqn}') |
178 | def delete_client_lun(self, target_iqn, client_iqn, image_id, request=None): | |
179 | logger.debug("iSCSI[%s] Deleting client lun: %s/%s", self.gateway_name, target_iqn, | |
180 | client_iqn) | |
181 | return request({ | |
182 | 'disk': image_id | |
183 | }) | |
184 | ||
11fdf7f2 TL |
185 | @RestClient.api_put('/api/clientauth/{target_iqn}/{client_iqn}') |
186 | def create_client_auth(self, target_iqn, client_iqn, username, password, mutual_username, | |
187 | mutual_password, request=None): | |
9f95a23c | 188 | logger.debug("[%s] Creating client auth: %s/%s/%s/%s/%s/%s", |
11fdf7f2 TL |
189 | self.gateway_name, target_iqn, client_iqn, username, password, mutual_username, |
190 | mutual_password) | |
191 | return request({ | |
192 | 'username': username, | |
193 | 'password': password, | |
194 | 'mutual_username': mutual_username, | |
195 | 'mutual_password': mutual_password | |
196 | }) | |
197 | ||
198 | @RestClient.api_put('/api/hostgroup/{target_iqn}/{group_name}') | |
199 | def create_group(self, target_iqn, group_name, members, image_ids, request=None): | |
9f95a23c | 200 | logger.debug("[%s] Creating group: %s/%s", self.gateway_name, target_iqn, group_name) |
11fdf7f2 TL |
201 | return request({ |
202 | 'members': ','.join(members), | |
203 | 'disks': ','.join(image_ids) | |
204 | }) | |
205 | ||
f91f0fd5 TL |
206 | @RestClient.api_put('/api/hostgroup/{target_iqn}/{group_name}') |
207 | def update_group(self, target_iqn, group_name, members, image_ids, request=None): | |
208 | logger.debug("iSCSI[%s] Updating group: %s/%s", self.gateway_name, target_iqn, group_name) | |
209 | return request({ | |
210 | 'action': 'remove', | |
211 | 'members': ','.join(members), | |
212 | 'disks': ','.join(image_ids) | |
213 | }) | |
214 | ||
11fdf7f2 TL |
215 | @RestClient.api_delete('/api/hostgroup/{target_iqn}/{group_name}') |
216 | def delete_group(self, target_iqn, group_name, request=None): | |
9f95a23c | 217 | logger.debug("[%s] Deleting group: %s/%s", self.gateway_name, target_iqn, group_name) |
11fdf7f2 TL |
218 | return request() |
219 | ||
220 | @RestClient.api_put('/api/discoveryauth') | |
221 | def update_discoveryauth(self, user, password, mutual_user, mutual_password, request=None): | |
9f95a23c | 222 | logger.debug("[%s] Updating discoveryauth: %s/%s/%s/%s", self.gateway_name, user, |
11fdf7f2 TL |
223 | password, mutual_user, mutual_password) |
224 | return request({ | |
225 | 'username': user, | |
226 | 'password': password, | |
227 | 'mutual_username': mutual_user, | |
228 | 'mutual_password': mutual_password | |
229 | }) | |
230 | ||
231 | @RestClient.api_put('/api/targetauth/{target_iqn}') | |
eafe8130 | 232 | def update_targetacl(self, target_iqn, action, request=None): |
9f95a23c | 233 | logger.debug("[%s] Updating targetacl: %s/%s", self.gateway_name, target_iqn, action) |
11fdf7f2 TL |
234 | return request({ |
235 | 'action': action | |
236 | }) | |
237 | ||
eafe8130 TL |
238 | @RestClient.api_put('/api/targetauth/{target_iqn}') |
239 | def update_targetauth(self, target_iqn, user, password, mutual_user, mutual_password, | |
240 | request=None): | |
9f95a23c | 241 | logger.debug("[%s] Updating targetauth: %s/%s/%s/%s/%s", self.gateway_name, |
eafe8130 TL |
242 | target_iqn, user, password, mutual_user, mutual_password) |
243 | return request({ | |
244 | 'username': user, | |
245 | 'password': password, | |
246 | 'mutual_username': mutual_user, | |
247 | 'mutual_password': mutual_password | |
248 | }) | |
249 | ||
11fdf7f2 TL |
250 | @RestClient.api_get('/api/targetinfo/{target_iqn}') |
251 | def get_targetinfo(self, target_iqn, request=None): | |
81eedcae | 252 | # pylint: disable=unused-argument |
11fdf7f2 | 253 | return request() |
494da23a TL |
254 | |
255 | @RestClient.api_get('/api/clientinfo/{target_iqn}/{client_iqn}') | |
256 | def get_clientinfo(self, target_iqn, client_iqn, request=None): | |
257 | # pylint: disable=unused-argument | |
258 | return request() |