]>
git.proxmox.com Git - ceph.git/blob - ceph/src/pybind/mgr/nfs/export_utils.py
1 class GaneshaConfParser
:
2 def __init__(self
, raw_config
):
5 self
.clean_config(raw_config
)
7 def clean_config(self
, raw_config
):
8 for line
in raw_config
.split("\n"):
10 if line
.startswith("%"):
13 def remove_whitespaces_quotes(self
):
14 if self
.text
.startswith("%url"):
15 self
.text
= self
.text
.replace('"', "")
17 self
.text
= "".join(self
.text
.split())
20 return self
.text
[self
.pos
:]
22 def parse_block_name(self
):
23 idx
= self
.stream().find('{')
25 raise Exception("Cannot find block name")
26 block_name
= self
.stream()[:idx
]
30 def parse_block_or_section(self
):
31 if self
.stream().startswith("%url "):
34 idx
= self
.stream().find('\n')
37 self
.pos
+= len(value
)
39 value
= self
.stream()[:idx
]
41 block_dict
= {'block_name': '%url', 'value': value
}
44 block_dict
= {'block_name': self
.parse_block_name().upper()}
45 self
.parse_block_body(block_dict
)
46 if self
.stream()[0] != '}':
47 raise Exception("No closing bracket '}' found at the end of block")
51 def parse_parameter_value(self
, raw_value
):
52 if raw_value
.find(',') != -1:
53 return [self
.parse_parameter_value(v
.strip())
54 for v
in raw_value
.split(',')]
58 if raw_value
== "true":
60 if raw_value
== "false":
62 if raw_value
.find('"') == 0:
63 return raw_value
[1:-1]
66 def parse_stanza(self
, block_dict
):
67 equal_idx
= self
.stream().find('=')
69 raise Exception("Malformed stanza: no equal symbol found.")
70 semicolon_idx
= self
.stream().find(';')
71 parameter_name
= self
.stream()[:equal_idx
].lower()
72 parameter_value
= self
.stream()[equal_idx
+1:semicolon_idx
]
73 block_dict
[parameter_name
] = self
.parse_parameter_value(parameter_value
)
74 self
.pos
+= semicolon_idx
+1
76 def parse_block_body(self
, block_dict
):
78 if self
.stream().find('}') == 0:
83 semicolon_idx
= self
.stream().find(';')
84 lbracket_idx
= self
.stream().find('{')
85 is_semicolon
= (semicolon_idx
!= -1)
86 is_lbracket
= (lbracket_idx
!= -1)
87 is_semicolon_lt_lbracket
= (semicolon_idx
< lbracket_idx
)
89 if is_semicolon
and ((is_lbracket
and is_semicolon_lt_lbracket
) or not is_lbracket
):
90 self
.parse_stanza(block_dict
)
91 elif is_lbracket
and ((is_semicolon
and not is_semicolon_lt_lbracket
) or
93 if '_blocks_' not in block_dict
:
94 block_dict
['_blocks_'] = []
95 block_dict
['_blocks_'].append(self
.parse_block_or_section())
97 raise Exception("Malformed stanza: no semicolon found.")
99 if last_pos
== self
.pos
:
100 raise Exception("Infinite loop while parsing block content")
103 self
.remove_whitespaces_quotes()
106 blocks
.append(self
.parse_block_or_section())
110 def _indentation(depth
, size
=4):
112 for _
in range(0, depth
*size
):
117 def write_block_body(block
, depth
=0):
118 def format_val(key
, val
):
119 if isinstance(val
, list):
120 return ', '.join([format_val(key
, v
) for v
in val
])
121 if isinstance(val
, bool):
122 return str(val
).lower()
123 if isinstance(val
, int) or (block
['block_name'] == 'CLIENT'
124 and key
== 'clients'):
125 return '{}'.format(val
)
126 return '"{}"'.format(val
)
129 for key
, val
in block
.items():
130 if key
== 'block_name':
132 elif key
== '_blocks_':
134 conf_str
+= GaneshaConfParser
.write_block(blo
, depth
)
136 conf_str
+= GaneshaConfParser
._indentation
(depth
)
137 conf_str
+= '{} = {};\n'.format(key
, format_val(key
, val
))
141 def write_block(block
, depth
=0):
142 if block
['block_name'] == "%url":
143 return '%url "{}"\n\n'.format(block
['value'])
146 conf_str
+= GaneshaConfParser
._indentation
(depth
)
147 conf_str
+= format(block
['block_name'])
149 conf_str
+= GaneshaConfParser
.write_block_body(block
, depth
+1)
150 conf_str
+= GaneshaConfParser
._indentation
(depth
)
156 def __init__(self
, name
, user_id
=None, fs_name
=None, sec_label_xattr
=None,
159 self
.fs_name
= fs_name
160 self
.user_id
= user_id
161 self
.sec_label_xattr
= sec_label_xattr
162 self
.cephx_key
= cephx_key
165 def from_fsal_block(cls
, fsal_block
):
166 return cls(fsal_block
['name'],
167 fsal_block
.get('user_id', None),
168 fsal_block
.get('filesystem', None),
169 fsal_block
.get('sec_label_xattr', None),
170 fsal_block
.get('secret_access_key', None))
172 def to_fsal_block(self
):
174 'block_name': 'FSAL',
178 result
['user_id'] = self
.user_id
180 result
['filesystem'] = self
.fs_name
181 if self
.sec_label_xattr
:
182 result
['sec_label_xattr'] = self
.sec_label_xattr
184 result
['secret_access_key'] = self
.cephx_key
188 def from_dict(cls
, fsal_dict
):
189 return cls(fsal_dict
['name'], fsal_dict
['user_id'],
190 fsal_dict
['fs_name'], fsal_dict
['sec_label_xattr'], None)
195 'user_id': self
.user_id
,
196 'fs_name': self
.fs_name
,
197 'sec_label_xattr': self
.sec_label_xattr
202 def __init__(self
, addresses
, access_type
=None, squash
=None):
203 self
.addresses
= addresses
204 self
.access_type
= access_type
208 def from_client_block(cls
, client_block
):
209 addresses
= client_block
['clients']
210 if not isinstance(addresses
, list):
211 addresses
= [addresses
]
212 return cls(addresses
,
213 client_block
.get('access_type', None),
214 client_block
.get('squash', None))
216 def to_client_block(self
):
218 'block_name': 'CLIENT',
219 'clients': self
.addresses
,
222 result
['access_type'] = self
.access_type
224 result
['squash'] = self
.squash
228 def from_dict(cls
, client_dict
):
229 return cls(client_dict
['addresses'], client_dict
['access_type'],
230 client_dict
['squash'])
234 'addresses': self
.addresses
,
235 'access_type': self
.access_type
,
236 'squash': self
.squash
241 def __init__(self
, export_id
, path
, cluster_id
, pseudo
, access_type
, squash
, security_label
,
242 protocols
, transports
, fsal
, clients
=None):
243 self
.export_id
= export_id
246 self
.cluster_id
= cluster_id
248 self
.access_type
= access_type
250 self
.attr_expiration_time
= 0
251 self
.security_label
= security_label
252 self
.protocols
= protocols
253 self
.transports
= transports
254 self
.clients
= clients
257 def from_export_block(cls
, export_block
, cluster_id
):
258 fsal_block
= [b
for b
in export_block
['_blocks_']
259 if b
['block_name'] == "FSAL"]
261 client_blocks
= [b
for b
in export_block
['_blocks_']
262 if b
['block_name'] == "CLIENT"]
264 protocols
= export_block
.get('protocols')
265 if not isinstance(protocols
, list):
266 protocols
= [protocols
]
268 transports
= export_block
.get('transports')
269 if not isinstance(transports
, list):
270 transports
= [transports
]
272 return cls(export_block
['export_id'],
273 export_block
['path'],
275 export_block
['pseudo'],
276 export_block
['access_type'],
277 export_block
['squash'],
278 export_block
['security_label'],
281 CephFSFSal
.from_fsal_block(fsal_block
[0]),
282 [Client
.from_client_block(client
)
283 for client
in client_blocks
])
285 def to_export_block(self
):
287 'block_name': 'EXPORT',
288 'export_id': self
.export_id
,
290 'pseudo': self
.pseudo
,
291 'access_type': self
.access_type
,
292 'squash': self
.squash
,
293 'attr_expiration_time': self
.attr_expiration_time
,
294 'security_label': self
.security_label
,
295 'protocols': self
.protocols
,
296 'transports': self
.transports
,
298 result
['_blocks_'] = [self
.fsal
.to_fsal_block()]
299 result
['_blocks_'].extend([client
.to_client_block()
300 for client
in self
.clients
])
304 def from_dict(cls
, export_id
, ex_dict
):
305 return cls(export_id
,
307 ex_dict
['cluster_id'],
309 ex_dict
.get('access_type', 'R'),
310 ex_dict
.get('squash', 'no_root_squash'),
311 ex_dict
.get('security_label', True),
312 ex_dict
.get('protocols', [4]),
313 ex_dict
.get('transports', ['TCP']),
314 CephFSFSal
.from_dict(ex_dict
['fsal']),
315 [Client
.from_dict(client
) for client
in ex_dict
['clients']])
319 'export_id': self
.export_id
,
321 'cluster_id': self
.cluster_id
,
322 'pseudo': self
.pseudo
,
323 'access_type': self
.access_type
,
324 'squash': self
.squash
,
325 'security_label': self
.security_label
,
326 'protocols': sorted([p
for p
in self
.protocols
]),
327 'transports': sorted([t
for t
in self
.transports
]),
328 'fsal': self
.fsal
.to_dict(),
329 'clients': [client
.to_dict() for client
in self
.clients
]