]> git.proxmox.com Git - ceph.git/blob - ceph/src/pybind/mgr/dashboard/services/iscsi_client.py
import ceph 15.2.10
[ceph.git] / ceph / src / pybind / mgr / dashboard / services / iscsi_client.py
1 # -*- coding: utf-8 -*-
2 # pylint: disable=too-many-public-methods
3 from __future__ import absolute_import
4
5 import json
6 import logging
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
15 from .iscsi_config import IscsiGatewaysConfig # pylint: disable=cyclic-import
16 from ..settings import Settings
17 from ..rest_client import RestClient
18
19
20 logger = logging.getLogger('iscsi_client')
21
22
23 class IscsiClient(RestClient):
24 _CLIENT_NAME = 'iscsi'
25 _instances = {} # type: dict
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):
84 logger.debug("[%s] Creating target: %s", self.gateway_name, target_iqn)
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):
91 logger.debug("[%s] Deleting target: %s", self.gateway_name, target_iqn)
92 return request()
93
94 @RestClient.api_put('/api/target/{target_iqn}')
95 def reconfigure_target(self, target_iqn, target_controls, request=None):
96 logger.debug("[%s] Reconfiguring target: %s", self.gateway_name, target_iqn)
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):
104 logger.debug("[%s] Creating gateway: %s/%s", self.gateway_name, target_iqn,
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
115 @RestClient.api_delete('/api/gateway/{target_iqn}/{gateway_name}')
116 def delete_gateway(self, target_iqn, gateway_name, request=None):
117 logger.debug("Deleting gateway: %s/%s", target_iqn, gateway_name)
118 return request()
119
120 @RestClient.api_put('/api/disk/{pool}/{image}')
121 def create_disk(self, pool, image, backstore, wwn, request=None):
122 logger.debug("[%s] Creating disk: %s/%s", self.gateway_name, pool, image)
123 return request({
124 'mode': 'create',
125 'backstore': backstore,
126 'wwn': wwn
127 })
128
129 @RestClient.api_delete('/api/disk/{pool}/{image}')
130 def delete_disk(self, pool, image, request=None):
131 logger.debug("[%s] Deleting disk: %s/%s", self.gateway_name, pool, image)
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):
138 logger.debug("[%s] Reconfiguring disk: %s/%s", self.gateway_name, pool, image)
139 return request({
140 'controls': json.dumps(controls),
141 'mode': 'reconfigure'
142 })
143
144 @RestClient.api_put('/api/targetlun/{target_iqn}')
145 def create_target_lun(self, target_iqn, image_id, lun, request=None):
146 logger.debug("[%s] Creating target lun: %s/%s", self.gateway_name, target_iqn,
147 image_id)
148 return request({
149 'disk': image_id,
150 'lun_id': lun
151 })
152
153 @RestClient.api_delete('/api/targetlun/{target_iqn}')
154 def delete_target_lun(self, target_iqn, image_id, request=None):
155 logger.debug("[%s] Deleting target lun: %s/%s", self.gateway_name, target_iqn,
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):
163 logger.debug("[%s] Creating client: %s/%s", self.gateway_name, target_iqn, client_iqn)
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):
168 logger.debug("[%s] Deleting client: %s/%s", self.gateway_name, target_iqn, client_iqn)
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):
173 logger.debug("[%s] Creating client lun: %s/%s", self.gateway_name, target_iqn,
174 client_iqn)
175 return request({
176 'disk': image_id
177 })
178
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
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):
190 logger.debug("[%s] Creating client auth: %s/%s/%s/%s/%s/%s",
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):
202 logger.debug("[%s] Creating group: %s/%s", self.gateway_name, target_iqn, group_name)
203 return request({
204 'members': ','.join(members),
205 'disks': ','.join(image_ids)
206 })
207
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
217 @RestClient.api_delete('/api/hostgroup/{target_iqn}/{group_name}')
218 def delete_group(self, target_iqn, group_name, request=None):
219 logger.debug("[%s] Deleting group: %s/%s", self.gateway_name, target_iqn, group_name)
220 return request()
221
222 @RestClient.api_put('/api/discoveryauth')
223 def update_discoveryauth(self, user, password, mutual_user, mutual_password, request=None):
224 logger.debug("[%s] Updating discoveryauth: %s/%s/%s/%s", self.gateway_name, user,
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}')
234 def update_targetacl(self, target_iqn, action, request=None):
235 logger.debug("[%s] Updating targetacl: %s/%s", self.gateway_name, target_iqn, action)
236 return request({
237 'action': action
238 })
239
240 @RestClient.api_put('/api/targetauth/{target_iqn}')
241 def update_targetauth(self, target_iqn, user, password, mutual_user, mutual_password,
242 request=None):
243 logger.debug("[%s] Updating targetauth: %s/%s/%s/%s/%s", self.gateway_name,
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
252 @RestClient.api_get('/api/targetinfo/{target_iqn}')
253 def get_targetinfo(self, target_iqn, request=None):
254 # pylint: disable=unused-argument
255 return request()
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()