]> git.proxmox.com Git - ceph.git/blob - ceph/src/pybind/mgr/cephadm/nfs.py
import 15.2.1 Octopus source
[ceph.git] / ceph / src / pybind / mgr / cephadm / nfs.py
1 import logging
2 import rados
3
4 from typing import Dict, Optional
5
6 from ceph.deployment.service_spec import NFSServiceSpec
7
8 import cephadm
9 from orchestrator import OrchestratorError
10
11 from . import utils
12
13 logger = logging.getLogger(__name__)
14
15 class NFSGanesha(object):
16 def __init__(self,
17 mgr,
18 daemon_id,
19 spec):
20 # type: (cephadm.CephadmOrchestrator, str, NFSServiceSpec) -> None
21 self.mgr = mgr
22 self.daemon_id = daemon_id
23 self.spec = spec
24
25 def get_rados_user(self):
26 # type: () -> str
27 return '%s.%s' % (self.spec.service_type, self.daemon_id)
28
29 def get_rados_config_name(self):
30 # type: () -> str
31 return 'conf-' + self.get_rados_user()
32
33 def get_rados_config_url(self):
34 # type: () -> str
35 url = 'rados://' + self.spec.pool + '/'
36 if self.spec.namespace:
37 url += self.spec.namespace + '/'
38 url += self.get_rados_config_name()
39 return url
40
41 def get_keyring_entity(self):
42 # type: () -> str
43 return utils.name_to_config_section(self.get_rados_user())
44
45 def get_or_create_keyring(self, entity=None):
46 # type: (Optional[str]) -> str
47 if not entity:
48 entity = self.get_keyring_entity()
49
50 logger.info('Create keyring: %s' % entity)
51 ret, keyring, err = self.mgr.mon_command({
52 'prefix': 'auth get-or-create',
53 'entity': entity,
54 })
55
56 if ret != 0:
57 raise OrchestratorError(
58 'Unable to create keyring %s: %s %s' \
59 % (entity, ret, err))
60 return keyring
61
62 def update_keyring_caps(self, entity=None):
63 # type: (Optional[str]) -> None
64 if not entity:
65 entity = self.get_keyring_entity()
66
67 osd_caps='allow rw pool=%s' % (self.spec.pool)
68 if self.spec.namespace:
69 osd_caps='%s namespace=%s' % (osd_caps, self.spec.namespace)
70
71 logger.info('Updating keyring caps: %s' % entity)
72 ret, out, err = self.mgr.mon_command({
73 'prefix': 'auth caps',
74 'entity': entity,
75 'caps': ['mon', 'allow r',
76 'osd', osd_caps,
77 'mds', 'allow rw'],
78 })
79
80 if ret != 0:
81 raise OrchestratorError(
82 'Unable to update keyring caps %s: %s %s' \
83 % (entity, ret, err))
84
85 def create_rados_config_obj(self, clobber=False):
86 # type: (Optional[bool]) -> None
87 obj = self.get_rados_config_name()
88
89 with self.mgr.rados.open_ioctx(self.spec.pool) as ioctx:
90 if self.spec.namespace:
91 ioctx.set_namespace(self.spec.namespace)
92
93 exists = True
94 try:
95 ioctx.stat(obj)
96 except rados.ObjectNotFound as e:
97 exists = False
98
99 if exists and not clobber:
100 # Assume an existing config
101 logger.info('Rados config object exists: %s' % obj)
102 else:
103 # Create an empty config object
104 logger.info('Creating rados config object: %s' % obj)
105 ioctx.write_full(obj, ''.encode('utf-8'))
106
107 def get_ganesha_conf(self):
108 # type: () -> str
109 return '''# generated by cephadm
110 RADOS_URLS {{
111 UserId = "{user}";
112 watch_url = "{url}";
113 }}
114
115 %url {url}
116 '''.format(user=self.get_rados_user(),
117 url=self.get_rados_config_url())
118
119 def get_cephadm_config(self):
120 # type: () -> Dict
121 config = {'pool' : self.spec.pool} # type: Dict
122 if self.spec.namespace:
123 config['namespace'] = self.spec.namespace
124 config['files'] = {
125 'ganesha.conf' : self.get_ganesha_conf(),
126 }
127 logger.debug('Generated cephadm config-json: %s' % config)
128 return config