]> git.proxmox.com Git - ceph.git/blob - ceph/src/pybind/mgr/dashboard/services/iscsi_config.py
import ceph 15.2.10
[ceph.git] / ceph / src / pybind / mgr / dashboard / services / iscsi_config.py
1 # -*- coding: utf-8 -*-
2 from __future__ import absolute_import
3
4 import json
5
6 try:
7 from urlparse import urlparse
8 except ImportError:
9 from urllib.parse import urlparse
10
11 from .. import mgr
12
13
14 class IscsiGatewayAlreadyExists(Exception):
15 def __init__(self, gateway_name):
16 super(IscsiGatewayAlreadyExists, self).__init__(
17 "iSCSI gateway '{}' already exists".format(gateway_name))
18
19
20 class IscsiGatewayDoesNotExist(Exception):
21 def __init__(self, hostname):
22 super(IscsiGatewayDoesNotExist, self).__init__(
23 "iSCSI gateway '{}' does not exist".format(hostname))
24
25
26 class 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
33 class 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
42 class IscsiGatewaysConfig(object):
43 @classmethod
44 def _load_config_from_store(cls):
45 json_db = mgr.get_store(_ISCSI_STORE_KEY,
46 '{"gateways": {}}')
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
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):
87 config = cls.get_gateways_config()
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):
96 config = cls._load_config_from_store()
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):
105 return cls._load_config_from_store()
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]