]> git.proxmox.com Git - ceph.git/blame - ceph/src/pybind/mgr/dashboard/services/iscsi_config.py
import quincy beta 17.1.0
[ceph.git] / ceph / src / pybind / mgr / dashboard / services / iscsi_config.py
CommitLineData
11fdf7f2 1# -*- coding: utf-8 -*-
11fdf7f2
TL
2
3import json
4
5try:
6 from urlparse import urlparse
7except ImportError:
8 from urllib.parse import urlparse
9
11fdf7f2
TL
10from .. import mgr
11
12
13class IscsiGatewayAlreadyExists(Exception):
14 def __init__(self, gateway_name):
15 super(IscsiGatewayAlreadyExists, self).__init__(
16 "iSCSI gateway '{}' already exists".format(gateway_name))
17
18
19class IscsiGatewayDoesNotExist(Exception):
20 def __init__(self, hostname):
21 super(IscsiGatewayDoesNotExist, self).__init__(
22 "iSCSI gateway '{}' does not exist".format(hostname))
23
24
11fdf7f2
TL
25class InvalidServiceUrl(Exception):
26 def __init__(self, service_url):
27 super(InvalidServiceUrl, self).__init__(
28 "Invalid service URL '{}'. "
29 "Valid format: '<scheme>://<username>:<password>@<host>[:port]'.".format(service_url))
30
31
32class ManagedByOrchestratorException(Exception):
33 def __init__(self):
34 super(ManagedByOrchestratorException, self).__init__(
35 "iSCSI configuration is managed by the orchestrator")
36
37
38_ISCSI_STORE_KEY = "_iscsi_config"
39
40
41class IscsiGatewaysConfig(object):
42 @classmethod
81eedcae 43 def _load_config_from_store(cls):
11fdf7f2
TL
44 json_db = mgr.get_store(_ISCSI_STORE_KEY,
45 '{"gateways": {}}')
494da23a
TL
46 config = json.loads(json_db)
47 cls.update_iscsi_config(config)
48 return config
49
50 @classmethod
51 def update_iscsi_config(cls, config):
52 """
53 Since `ceph-iscsi` config v10, gateway names were renamed from host short name to FQDN.
54 If Ceph Dashboard were configured before v10, we try to update our internal gateways
55 database automatically.
56 """
57 for gateway_name, gateway_config in config['gateways'].items():
58 if '.' not in gateway_name:
494da23a 59 from ..rest_client import RequestException
f67539c2 60 from .iscsi_client import IscsiClient # pylint: disable=cyclic-import
494da23a
TL
61 try:
62 service_url = gateway_config['service_url']
63 new_gateway_name = IscsiClient.instance(
64 service_url=service_url).get_hostname()['data']
65 if gateway_name != new_gateway_name:
66 config['gateways'][new_gateway_name] = gateway_config
67 del config['gateways'][gateway_name]
68 cls._save_config(config)
69 except RequestException:
70 # If gateway is not acessible, it should be removed manually
71 # or we will try to update automatically next time
72 continue
11fdf7f2
TL
73
74 @classmethod
75 def _save_config(cls, config):
76 mgr.set_store(_ISCSI_STORE_KEY, json.dumps(config))
77
78 @classmethod
79 def validate_service_url(cls, service_url):
80 url = urlparse(service_url)
81 if not url.scheme or not url.hostname or not url.username or not url.password:
82 raise InvalidServiceUrl(service_url)
83
84 @classmethod
85 def add_gateway(cls, name, service_url):
81eedcae 86 config = cls.get_gateways_config()
11fdf7f2
TL
87 if name in config:
88 raise IscsiGatewayAlreadyExists(name)
89 IscsiGatewaysConfig.validate_service_url(service_url)
90 config['gateways'][name] = {'service_url': service_url}
91 cls._save_config(config)
92
93 @classmethod
94 def remove_gateway(cls, name):
81eedcae 95 config = cls._load_config_from_store()
11fdf7f2
TL
96 if name not in config['gateways']:
97 raise IscsiGatewayDoesNotExist(name)
98
99 del config['gateways'][name]
100 cls._save_config(config)
101
102 @classmethod
103 def get_gateways_config(cls):
e306af50 104 return cls._load_config_from_store()
11fdf7f2
TL
105
106 @classmethod
107 def get_gateway_config(cls, name):
108 config = IscsiGatewaysConfig.get_gateways_config()
109 if name not in config['gateways']:
110 raise IscsiGatewayDoesNotExist(name)
111 return config['gateways'][name]