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