3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
20 from cmdatahandlers.api.configmanager import ConfigManager
21 from cmframework.apis import cmmanage
23 from cliff import command
24 from cliff.show import ShowOne
25 from cliff.lister import Lister
26 from cliff.formatters.table import TableFormatter
30 class VerboseLogger(object):
31 def __init__(self, logger):
34 def __call__(self, msg):
35 self.logger.debug(msg)
38 def _add_basic_arguments(parser):
39 parser.add_argument('--cmserver-ip',
43 default='config-manager',
46 parser.add_argument('--cmserver-port',
53 parser.add_argument('--client-lib',
57 default='cmframework.lib.CMClientImpl',
62 class ShowProperty(ShowOne):
63 """A command for showing the value associated with a property"""
65 log = logging.getLogger(__name__)
67 def get_parser(self, prog_name):
68 parser = super(ShowProperty, self).get_parser(prog_name)
69 _add_basic_arguments(parser)
73 help=('Property name'),
80 return json.dumps(data, sort_keys=True, indent=4, separators=(',', ':'))
82 def take_action(self, parsed_args):
84 logger = VerboseLogger(self.log)
86 api = cmmanage.CMManage(parsed_args.cmserverip,
87 parsed_args.cmserverport,
88 parsed_args.clientlib,
91 cm_property = parsed_args.property
93 data = api.get_properties('')
96 for name, value in data.iteritems():
98 d[name] = json.loads(value)
99 except Exception as ex:
102 cm = ConfigManager(d)
103 cm.mask_sensitive_data()
105 prop = d.get(cm_property)
108 split = cm_property.split('.')
109 cm_property = '.'.join(split[:2])
110 prop = d.get(cm_property)
112 if prop == '' or prop == None:
113 raise Exception('{} not configured'.format(cm_property))
118 for field in split[2:]:
121 except KeyError as ex:
122 raise Exception('{} not found in {}'.format(field, cm_property))
124 if isinstance(d, dict):
125 columns = tuple(d.keys())
126 if isinstance(self.formatter, TableFormatter):
127 data = tuple(map(ShowProperty.dumps, d.values()))
129 data = tuple(d.values())
131 columns = (parsed_args.property, )
133 return (columns, data)
139 class ListProperties(Lister):
140 """A command for showing properties matching some filter"""
142 log = logging.getLogger(__name__)
144 def get_parser(self, prog_name):
145 parser = super(ListProperties, self).get_parser(prog_name)
146 _add_basic_arguments(parser)
147 parser.add_argument('--matching-filter',
157 def take_action(self, parsed_args):
159 logger = VerboseLogger(self.log)
161 api = cmmanage.CMManage(parsed_args.cmserverip,
162 parsed_args.cmserverport,
163 parsed_args.clientlib,
166 prop_filter = parsed_args.filter
167 data = api.get_properties('')
169 header = ('property', 'value')
174 for name, value in data.iteritems():
176 d[name] = json.loads(value)
177 except Exception as ex:
180 cm = ConfigManager(d)
181 cm.mask_sensitive_data()
183 pattern = re.compile(prop_filter)
184 for name, value in d.iteritems():
185 if not pattern.match(name):
187 if isinstance(self.formatter, TableFormatter):
189 v = json.dumps(value, sort_keys=True, indent=1, separators=(',', ':'))
195 columns = (entry,) + columns
197 raise Exception('Not found')
199 return (header, columns)
205 class DeleteProperty(command.Command):
206 """A command for deleting a property"""
208 log = logging.getLogger(__name__)
210 def get_parser(self, prog_name):
211 parser = super(DeleteProperty, self).get_parser(prog_name)
212 _add_basic_arguments(parser)
216 metavar='<property>',
217 help=('Property name'),
222 def take_action(self, parsed_args):
224 logger = VerboseLogger(self.log)
226 api = cmmanage.CMManage(parsed_args.cmserverip,
227 parsed_args.cmserverport,
228 parsed_args.clientlib,
232 api.delete_property(parsed_args.property)
235 self.app.stdout.write('%s deleted successfully\n' % parsed_args.property)
237 except Exception as exp:
238 self.app.stderr.write('Failed with error %s\n' % str(exp))
241 class SetProperty(command.Command):
242 """A command for setting a property"""
244 log = logging.getLogger(__name__)
246 def get_parser(self, prog_name):
247 parser = super(SetProperty, self).get_parser(prog_name)
248 _add_basic_arguments(parser)
252 metavar='<property>',
253 help=('Property name'),
256 parser.add_argument('--value',
263 parser.add_argument('--file',
271 def take_action(self, parsed_args):
273 logger = VerboseLogger(self.log)
275 api = cmmanage.CMManage(parsed_args.cmserverip,
276 parsed_args.cmserverport,
277 parsed_args.clientlib,
280 if parsed_args.value and parsed_args.file:
281 raise Exception('Either --value or --file needs to be specified')
283 if parsed_args.value:
284 api.set_property(parsed_args.property, parsed_args.value)
285 elif parsed_args.file:
286 if not os.path.exists(parsed_args.file):
287 raise Exception('File %s is not valid' % parsed_args.file)
289 with open(parsed_args.file, 'r') as f:
295 except Exception as exp:
298 api.set_property(parsed_args.property, data)
300 raise Exception('--value or --file needs to be specified')
303 self.app.stdout.write('%s set successfully\n' % parsed_args.property)
305 except Exception as exp:
306 self.app.stderr.write('Failed with error %s\n' % str(exp))
309 class DumpPropertyToFile(command.Command):
310 """A command for dumping property value to a file"""
312 log = logging.getLogger(__name__)
314 def get_parser(self, prog_name):
315 parser = super(DumpPropertyToFile, self).get_parser(prog_name)
316 _add_basic_arguments(parser)
320 metavar='<property>',
321 help=('Property name'),
332 def take_action(self, parsed_args):
334 logger = VerboseLogger(self.log)
336 api = cmmanage.CMManage(parsed_args.cmserverip,
337 parsed_args.cmserverport,
338 parsed_args.clientlib,
341 cm_property = parsed_args.property
342 config = api.get_properties('')
344 if os.path.exists(parsed_args.file):
345 raise Exception('File %s already exists' % parsed_args.file)
347 with open(parsed_args.file, 'w') as f:
349 if cm_property not in config.keys():
350 raise Exception('Property not found')
351 for name, value in config.iteritems():
353 d[name] = json.loads(value)
354 except Exception as ex:
356 cm = ConfigManager(d)
357 cm.mask_sensitive_data()
358 d = d.get(cm_property)
360 data = json.dumps(d, sort_keys=True, indent=1, separators=(',', ':'))
361 except Exception as exp:
363 if data == 'null' or data == '""':
367 self.app.stdout.write('Completed successfully\n')
369 except Exception as exp:
370 self.app.stderr.write('Failed with error %s\n' % str(exp))