]> git.proxmox.com Git - ceph.git/blob - ceph/src/pybind/mgr/dashboard/services/iscsi_config.py
import ceph nautilus 14.2.2
[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 from orchestrator import OrchestratorError
7
8 try:
9 from urlparse import urlparse
10 except ImportError:
11 from urllib.parse import urlparse
12
13 from mgr_util import merge_dicts
14 from .orchestrator import OrchClient
15 from .. import mgr
16
17
18 class IscsiGatewayAlreadyExists(Exception):
19 def __init__(self, gateway_name):
20 super(IscsiGatewayAlreadyExists, self).__init__(
21 "iSCSI gateway '{}' already exists".format(gateway_name))
22
23
24 class IscsiGatewayDoesNotExist(Exception):
25 def __init__(self, hostname):
26 super(IscsiGatewayDoesNotExist, self).__init__(
27 "iSCSI gateway '{}' does not exist".format(hostname))
28
29
30 class IscsiGatewayInUse(Exception):
31 def __init__(self, hostname):
32 super(IscsiGatewayInUse, self).__init__(
33 "iSCSI gateway '{}' is in use".format(hostname))
34
35
36 class InvalidServiceUrl(Exception):
37 def __init__(self, service_url):
38 super(InvalidServiceUrl, self).__init__(
39 "Invalid service URL '{}'. "
40 "Valid format: '<scheme>://<username>:<password>@<host>[:port]'.".format(service_url))
41
42
43 class ManagedByOrchestratorException(Exception):
44 def __init__(self):
45 super(ManagedByOrchestratorException, self).__init__(
46 "iSCSI configuration is managed by the orchestrator")
47
48
49 _ISCSI_STORE_KEY = "_iscsi_config"
50
51
52 class IscsiGatewaysConfig(object):
53 @classmethod
54 def _load_config_from_store(cls):
55 json_db = mgr.get_store(_ISCSI_STORE_KEY,
56 '{"gateways": {}}')
57 return json.loads(json_db)
58
59 @staticmethod
60 def _load_config_from_orchestrator():
61 config = {'gateways': {}}
62 try:
63 instances = OrchClient().list_service_info("iscsi")
64 for instance in instances:
65 config['gateways'][instance.nodename] = {
66 'service_url': instance.service_url
67 }
68 except (RuntimeError, OrchestratorError, ImportError):
69 pass
70 return config
71
72 @classmethod
73 def _save_config(cls, config):
74 mgr.set_store(_ISCSI_STORE_KEY, json.dumps(config))
75
76 @classmethod
77 def validate_service_url(cls, service_url):
78 url = urlparse(service_url)
79 if not url.scheme or not url.hostname or not url.username or not url.password:
80 raise InvalidServiceUrl(service_url)
81
82 @classmethod
83 def add_gateway(cls, name, service_url):
84 config = cls.get_gateways_config()
85 if name in config:
86 raise IscsiGatewayAlreadyExists(name)
87 IscsiGatewaysConfig.validate_service_url(service_url)
88 config['gateways'][name] = {'service_url': service_url}
89 cls._save_config(config)
90
91 @classmethod
92 def remove_gateway(cls, name):
93 if name in cls._load_config_from_orchestrator()['gateways']:
94 raise ManagedByOrchestratorException()
95
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 orch_config = cls._load_config_from_orchestrator()
106 local_config = cls._load_config_from_store()
107
108 return {'gateways': merge_dicts(orch_config['gateways'], local_config['gateways'])}
109
110 @classmethod
111 def get_gateway_config(cls, name):
112 config = IscsiGatewaysConfig.get_gateways_config()
113 if name not in config['gateways']:
114 raise IscsiGatewayDoesNotExist(name)
115 return config['gateways'][name]