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