def format_parameters(params): '''Reformat parameters into dict of format expected by the API.''' if not params: return {} # expect multiple invocations of --parameters but fall back # to ; delimited if only one --parameters is specified if len(params) == 1: if params[0].find(';') != -1: # found params = params[0].split(';') else: params = params[0].split(',') parameters = {} for p in params: try: (n, v) = p.split(('='), 1) except ValueError: msg = '%s(%s). %s.' % ('Malformed parameter', p, 'Use the key=value format') raise exc.CommandError(msg) if n not in parameters: parameters[n] = v else: if not isinstance(parameters[n], list): parameters[n] = [parameters[n]] parameters[n].append(v) return parameters
def do_metric_list(mc, args): '''List metrics for this tenant.''' fields = {} if args.name: fields['name'] = args.name if args.dimensions: fields['dimensions'] = utils.format_parameters(args.dimensions) if args.limit: fields['limit'] = args.limit if args.offset: fields['offset'] = args.offset try: metric = mc.metrics.list(**fields) except exc.HTTPException as he: raise exc.CommandError('HTTPException code=%s message=%s' % (he.code, he.message)) else: if args.json: print(utils.json_formatter(metric)) return cols = ['name', 'dimensions'] formatters = { 'name': lambda x: x['name'], 'dimensions': lambda x: utils.format_dict(x['dimensions']), } if isinstance(metric, list): # print the list utils.print_list(metric, cols, formatters=formatters) else: # add the dictionary to a list, so print_list works metric_list = list() metric_list.append(metric) utils.print_list(metric_list, cols, formatters=formatters)
def do_alarm_definition_show(mc, args): '''Describe the alarm definition.''' fields = {} fields['alarm_id'] = args.id try: alarm = mc.alarm_definitions.get(**fields) except exc.HTTPException as he: raise exc.CommandError('HTTPException code=%s message=%s' % (he.code, he.message)) else: if args.json: print(utils.json_formatter(alarm)) return # print out detail of a single alarm formatters = { 'name': utils.json_formatter, 'id': utils.json_formatter, 'expression': utils.json_formatter, 'expression_data': utils.format_expression_data, 'match_by': utils.json_formatter, 'actions_enabled': utils.json_formatter, 'alarm_actions': utils.json_formatter, 'ok_actions': utils.json_formatter, 'severity': utils.json_formatter, 'undetermined_actions': utils.json_formatter, 'description': utils.json_formatter, 'links': utils.format_dictlist, } utils.print_dict(alarm, formatters=formatters)
def do_alarm_definition_create(mc, args): '''Create an alarm definition.''' fields = {} fields['name'] = args.name if args.description: fields['description'] = args.description fields['expression'] = args.expression if args.alarm_actions: fields['alarm_actions'] = args.alarm_actions if args.ok_actions: fields['ok_actions'] = args.ok_actions if args.undetermined_actions: fields['undetermined_actions'] = args.undetermined_actions if args.severity: if args.severity.upper() not in severity_types: errmsg = 'Invalid severity, not one of [' + \ ', '.join(severity_types) + ']' print(errmsg) return fields['severity'] = args.severity if args.match_by: fields['match_by'] = args.match_by.split(',') try: alarm = mc.alarm_definitions.create(**fields) except exc.HTTPException as he: raise exc.CommandError('HTTPException code=%s message=%s' % (he.code, he.message)) else: print(jsonutils.dumps(alarm, indent=2))
def do_notification_list(mc, args): '''List notifications for this tenant.''' fields = {} if args.limit: fields['limit'] = args.limit if args.offset: fields['offset'] = args.offset try: notification = mc.notifications.list(**fields) except exc.HTTPException as he: raise exc.CommandError('HTTPException code=%s message=%s' % (he.code, he.message)) else: if args.json: print(utils.json_formatter(notification)) return cols = ['name', 'id', 'type', 'address'] formatters = { 'name': lambda x: x['name'], 'id': lambda x: x['id'], 'type': lambda x: x['type'], 'address': lambda x: x['address'], } if isinstance(notification, list): utils.print_list(notification, cols, formatters=formatters) else: notif_list = list() notif_list.append(notification) utils.print_list(notif_list, cols, formatters=formatters)
def do_alarm_history_list(mc, args): '''List alarms state history.''' fields = {} if args.dimensions: fields['dimensions'] = utils.format_parameters(args.dimensions) if args.starttime: if args.starttime[0] == '-': deltaT = time.time() + (int(args.starttime) * 60) utc = str(datetime.datetime.utcfromtimestamp(deltaT)) utc = utc.replace(" ", "T")[:-7] + 'Z' args.starttime = utc fields['start_time'] = args.starttime if args.endtime: fields['end_time'] = args.endtime if args.limit: fields['limit'] = args.limit if args.offset: fields['offset'] = args.offset try: alarm = mc.alarms.history_list(**fields) except exc.HTTPException as he: raise exc.CommandError('HTTPException code=%s message=%s' % (he.code, he.message)) else: output_alarm_history(args, alarm)
def do_help(self, args): """Display help about this program or one of its subcommands.""" if getattr(args, 'command', None): if args.command in self.subcommands: self.subcommands[args.command].print_help() else: raise exc.CommandError("'%s' is not a valid subcommand" % args.command) else: self.parser.print_help()
def do_notification_delete(mc, args): '''Delete notification.''' fields = {} fields['notification_id'] = args.id try: mc.notifications.delete(**fields) except exc.HTTPException as he: raise exc.CommandError('HTTPException code=%s message=%s' % (he.code, he.message)) else: print('Successfully deleted notification')
def do_metric_create_raw(mc, args): '''Create metric from raw json body.''' fields = {} fields['jsonbody'] = args.jsonbody try: mc.metrics.create(**fields) except exc.HTTPException as he: raise exc.CommandError('HTTPException code=%s message=%s' % (he.code, he.message)) else: print('Successfully created metric')
def do_alarm_definition_delete(mc, args): '''Delete the alarm definition.''' fields = {} fields['alarm_id'] = args.id try: mc.alarm_definitions.delete(**fields) except exc.HTTPException as he: raise exc.CommandError('HTTPException code=%s message=%s' % (he.code, he.message)) else: print('Successfully deleted alarm definition')
def token(self): """Token property Validate token is project scoped and return it if it is project_id and auth_token were fetched when keystone client was created """ if self._token is None: if self._keystone.project_id: self._token = self._keystone.auth_token else: raise exc.CommandError("No project id or project name.") return self._token
def do_alarm_history(mc, args): '''Alarm state transition history.''' fields = {} fields['alarm_id'] = args.id if args.limit: fields['limit'] = args.limit if args.offset: fields['offset'] = args.offset try: alarm = mc.alarms.history(**fields) except exc.HTTPException as he: raise exc.CommandError('HTTPException code=%s message=%s' % (he.code, he.message)) else: output_alarm_history(args, alarm)
def do_measurement_list(mc, args): '''List measurements for the specified metric.''' fields = {} fields['name'] = args.name if args.dimensions: fields['dimensions'] = utils.format_parameters(args.dimensions) if args.starttime[0] == '-': deltaT = time.time() + (int(args.starttime) * 60) utc = str(datetime.datetime.utcfromtimestamp(deltaT)) utc = utc.replace(" ", "T")[:-7] + 'Z' args.starttime = utc fields['start_time'] = args.starttime if args.endtime: fields['end_time'] = args.endtime if args.limit: fields['limit'] = args.limit if args.offset: fields['offset'] = args.offset if args.merge_metrics: fields['merge_metrics'] = args.merge_metrics try: metric = mc.metrics.list_measurements(**fields) except exc.HTTPException as he: raise exc.CommandError('HTTPException code=%s message=%s' % (he.code, he.message)) else: if args.json: print(utils.json_formatter(metric)) return cols = ['name', 'dimensions', 'timestamp', 'value', 'value_meta'] formatters = { 'name': lambda x: x['name'], 'dimensions': lambda x: utils.format_dict(x['dimensions']), 'timestamp': lambda x: format_measure_timestamp(x['measurements']), 'value': lambda x: format_measure_value(x['measurements']), 'value_meta': lambda x: format_value_meta(x['measurements']), } if isinstance(metric, list): # print the list utils.print_list(metric, cols, formatters=formatters) else: # add the dictionary to a list, so print_list works metric_list = list() metric_list.append(metric) utils.print_list(metric_list, cols, formatters=formatters)
def do_notification_create(mc, args): '''Create notification.''' if args.type.upper() not in notification_types: errmsg = 'Invalid type, not one of [' + \ ', '.join(notification_types) + ']' print(errmsg) return fields = {} fields['name'] = args.name fields['type'] = args.type fields['address'] = args.address try: notification = mc.notifications.create(**fields) except exc.HTTPException as he: raise exc.CommandError('HTTPException code=%s message=%s' % (he.code, he.message)) else: print(jsonutils.dumps(notification, indent=2))
def do_metric_create(mc, args): '''Create metric.''' fields = {} fields['name'] = args.name if args.dimensions: fields['dimensions'] = utils.format_parameters(args.dimensions) fields['timestamp'] = args.time fields['value'] = args.value if args.value_meta: fields['value_meta'] = utils.format_parameters(args.value_meta) if args.project_id: fields['tenant_id'] = args.project_id try: mc.metrics.create(**fields) except exc.HTTPException as he: raise exc.CommandError('HTTPException code=%s message=%s' % (he.code, he.message)) else: print('Successfully created metric')
def do_alarm_update(mc, args): '''Update the alarm state.''' fields = {} fields['alarm_id'] = args.id if args.state.upper() not in state_types: errmsg = 'Invalid state, not one of [' + \ ', '.join(state_types) + ']' print(errmsg) return fields['state'] = args.state fields['lifecycle_state'] = args.lifecycle_state fields['link'] = args.link try: alarm = mc.alarms.update(**fields) except exc.HTTPException as he: raise exc.CommandError('HTTPException code=%s message=%s' % (he.code, he.message)) else: print(jsonutils.dumps(alarm, indent=2))
def do_notification_show(mc, args): '''Describe the notification.''' fields = {} fields['notification_id'] = args.id try: notification = mc.notifications.get(**fields) except exc.HTTPException as he: raise exc.CommandError('HTTPException code=%s message=%s' % (he.code, he.message)) else: if args.json: print(utils.json_formatter(notification)) return formatters = { 'name': utils.json_formatter, 'id': utils.json_formatter, 'type': utils.json_formatter, 'address': utils.json_formatter, 'links': utils.format_dictlist, } utils.print_dict(notification, formatters=formatters)
def do_alarm_show(mc, args): '''Describe the alarm.''' fields = {} fields['alarm_id'] = args.id try: alarm = mc.alarms.get(**fields) except exc.HTTPException as he: raise exc.CommandError('HTTPException code=%s message=%s' % (he.code, he.message)) else: if args.json: print(utils.json_formatter(alarm)) return # print out detail of a single alarm formatters = { 'id': utils.json_formatter, 'alarm_definition': utils.json_formatter, 'metrics': utils.json_formatter, 'state': utils.json_formatter, 'links': utils.format_dictlist, } utils.print_dict(alarm, formatters=formatters)
def find_resource(manager, name_or_id): """Helper for the _find_* methods.""" # first try to get entity as integer id try: if isinstance(name_or_id, int) or name_or_id.isdigit(): return manager.get(int(name_or_id)) except exc.NotFound: pass # now try to get entity as uuid try: uuid.UUID(str(name_or_id)) return manager.get(name_or_id) except (ValueError, exc.NotFound): pass # finally try to find entity by name try: return manager.find(name=name_or_id) except exc.NotFound: msg = "No %s with a name or ID of '%s' exists." % \ (manager.resource_class.__name__.lower(), name_or_id) raise exc.CommandError(msg)
def do_alarm_definition_patch(mc, args): '''Patch the alarm definition.''' fields = {} fields['alarm_id'] = args.id if args.name: fields['name'] = args.name if args.description: fields['description'] = args.description if args.expression: fields['expression'] = args.expression if args.alarm_actions: fields['alarm_actions'] = args.alarm_actions if args.ok_actions: fields['ok_actions'] = args.ok_actions if args.undetermined_actions: fields['undetermined_actions'] = args.undetermined_actions if args.actions_enabled: if args.actions_enabled not in enabled_types: errmsg = 'Invalid value, not one of [' + \ ', '.join(enabled_types) + ']' print(errmsg) return fields['actions_enabled'] = args.actions_enabled in ['true', 'True'] if args.severity: if args.severity.upper() not in severity_types: errmsg = 'Invalid severity, not one of [' + \ ', '.join(severity_types) + ']' print(errmsg) return fields['severity'] = args.severity try: alarm = mc.alarm_definitions.patch(**fields) except exc.HTTPException as he: raise exc.CommandError('HTTPException code=%s message=%s' % (he.code, he.message)) else: print(jsonutils.dumps(alarm, indent=2))
def do_alarm_definition_list(mc, args): '''List alarm definitions for this tenant.''' fields = {} if args.name: fields['name'] = args.name if args.dimensions: fields['dimensions'] = utils.format_parameters(args.dimensions) if args.limit: fields['limit'] = args.limit if args.offset: fields['offset'] = args.offset try: alarm = mc.alarm_definitions.list(**fields) except exc.HTTPException as he: raise exc.CommandError('HTTPException code=%s message=%s' % (he.code, he.message)) else: if args.json: print(utils.json_formatter(alarm)) return cols = ['name', 'id', 'expression', 'match_by', 'actions_enabled'] formatters = { 'name': lambda x: x['name'], 'id': lambda x: x['id'], 'expression': lambda x: x['expression'], 'match_by': lambda x: utils.format_list(x['match_by']), 'actions_enabled': lambda x: x['actions_enabled'], } if isinstance(alarm, list): # print the list utils.print_list(alarm, cols, formatters=formatters) else: # add the dictionary to a list, so print_list works alarm_list = list() alarm_list.append(alarm) utils.print_list(alarm_list, cols, formatters=formatters)
def do_metric_statistics(mc, args): '''List measurement statistics for the specified metric.''' statistic_types = ['AVG', 'MIN', 'MAX', 'COUNT', 'SUM'] statlist = args.statistics.split(',') for stat in statlist: if stat.upper() not in statistic_types: errmsg = 'Invalid type, not one of [' + \ ', '.join(statistic_types) + ']' print(errmsg) return fields = {} fields['name'] = args.name if args.dimensions: fields['dimensions'] = utils.format_parameters(args.dimensions) if args.starttime[0] == '-': deltaT = time.time() + (int(args.starttime) * 60) utc = str(datetime.datetime.utcfromtimestamp(deltaT)) utc = utc.replace(" ", "T")[:-7] + 'Z' args.starttime = utc fields['start_time'] = args.starttime if args.endtime: fields['end_time'] = args.endtime if args.period: fields['period'] = args.period fields['statistics'] = args.statistics if args.limit: fields['limit'] = args.limit if args.offset: fields['offset'] = args.offset if args.merge_metrics: fields['merge_metrics'] = args.merge_metrics try: metric = mc.metrics.list_statistics(**fields) except exc.HTTPException as he: raise exc.CommandError('HTTPException code=%s message=%s' % (he.code, he.message)) else: if args.json: print(utils.json_formatter(metric)) return cols = ['name', 'dimensions'] # add dynamic column names if metric: column_names = metric[0]['columns'] for name in column_names: cols.append(name) else: # when empty set, print_list needs a col cols.append('timestamp') formatters = { 'name': lambda x: x['name'], 'dimensions': lambda x: utils.format_dict(x['dimensions']), 'timestamp': lambda x: format_statistic_timestamp(x['statistics'], x['columns'], 'timestamp'), 'avg': lambda x: format_statistic_value(x['statistics'], x['columns'], 'avg'), 'min': lambda x: format_statistic_value(x['statistics'], x['columns'], 'min'), 'max': lambda x: format_statistic_value(x['statistics'], x['columns'], 'max'), 'count': lambda x: format_statistic_value(x['statistics'], x['columns'], 'count'), 'sum': lambda x: format_statistic_value(x['statistics'], x['columns'], 'sum'), } if isinstance(metric, list): # print the list utils.print_list(metric, cols, formatters=formatters) else: # add the dictionary to a list, so print_list works metric_list = list() metric_list.append(metric) utils.print_list(metric_list, cols, formatters=formatters)
def do_alarm_list(mc, args): '''List alarms for this tenant.''' fields = {} if args.alarm_definition_id: fields['alarm_definition_id'] = args.alarm_definition_id if args.metric_name: fields['metric_name'] = args.metric_name if args.metric_dimensions: fields['metric_dimensions'] = utils.format_parameters( args.metric_dimensions) if args.state: if args.state.upper() not in state_types: errmsg = 'Invalid state, not one of [' + \ ', '.join(state_types) + ']' print(errmsg) return fields['state'] = args.state if args.state_updated_start_time: fields['state_updated_start_time'] = args.state_updated_start_time if args.lifecycle_state: fields['lifecycle_state'] = args.lifecycle_state if args.link: fields['link'] = args.link if args.limit: fields['limit'] = args.limit if args.offset: fields['offset'] = args.offset try: alarm = mc.alarms.list(**fields) except exc.HTTPException as he: raise exc.CommandError('HTTPException code=%s message=%s' % (he.code, he.message)) else: if args.json: print(utils.json_formatter(alarm)) return cols = [ 'id', 'alarm_definition_id', 'alarm_definition_name', 'metric_name', 'metric_dimensions', 'severity', 'state', 'lifecycle_state', 'link', 'state_updated_timestamp', 'updated_timestamp', "created_timestamp" ] formatters = { 'id': lambda x: x['id'], 'alarm_definition_id': lambda x: x['alarm_definition']['id'], 'alarm_definition_name': lambda x: x['alarm_definition']['name'], 'metric_name': lambda x: format_metric_name(x['metrics']), 'metric_dimensions': lambda x: format_metric_dimensions(x['metrics']), 'severity': lambda x: x['alarm_definition']['severity'], 'state': lambda x: x['state'], 'lifecycle_state': lambda x: x['lifecycle_state'], 'link': lambda x: x['link'], 'state_updated_timestamp': lambda x: x['state_updated_timestamp'], 'updated_timestamp': lambda x: x['updated_timestamp'], 'created_timestamp': lambda x: x['created_timestamp'], } if isinstance(alarm, list): # print the list utils.print_list(alarm, cols, formatters=formatters) else: # add the dictionary to a list, so print_list works alarm_list = list() alarm_list.append(alarm) utils.print_list(alarm_list, cols, formatters=formatters)
def main(self, argv): # Parse args once to find version parser = self.get_base_parser() (options, args) = parser.parse_known_args(argv) self._setup_logging(options.debug) self._setup_verbose(options.verbose) # build available subcommands based on version api_version = options.monasca_api_version subcommand_parser = self.get_subcommand_parser(api_version) self.parser = subcommand_parser # Handle top-level --help/-h before attempting to parse # a command off the command line if not args and options.help or not argv: self.do_help(options) return 0 # Parse args again and call whatever callback was selected args = subcommand_parser.parse_args(argv) # Short-circuit and deal with help command right away. if args.func == self.do_help: self.do_help(args) return 0 elif args.func == self.do_bash_completion: self.do_bash_completion(args) return 0 if not args.os_username and not args.os_auth_token: raise exc.CommandError("You must provide a username via" " either --os-username or env[OS_USERNAME]" " or a token via --os-auth-token or" " env[OS_AUTH_TOKEN]") if not args.os_password and not args.os_auth_token: raise exc.CommandError("You must provide a password via" " either --os-password or env[OS_PASSWORD]" " or a token via --os-auth-token or" " env[OS_AUTH_TOKEN]") if args.os_no_client_auth: if not args.monasca_api_url: raise exc.CommandError("If you specify --os-no-client-auth" " you must specify a Monasca API URL" " via either --monasca-api-url or" " env[MONASCA_API_URL]") else: if not args.os_auth_url: raise exc.CommandError("You must provide an auth url via" " either --os-auth-url or via" " env[OS_AUTH_URL]") if args.os_auth_url and 'v2.0' in args.os_auth_url: args.os_auth_url = string.replace(args.os_auth_url, 'v2.0', 'v3') kwargs = { 'username': args.os_username, 'password': args.os_password, 'token': args.os_auth_token, 'auth_url': args.os_auth_url, 'service_type': args.os_service_type, 'endpoint_type': args.os_endpoint_type, 'os_cacert': args.os_cacert, 'user_domain_id': args.os_user_domain_id, 'user_domain_name': args.os_user_domain_name, 'project_id': args.os_project_id, 'project_name': args.os_project_name, 'domain_id': args.os_domain_id, 'domain_name': args.os_domain_name, 'insecure': args.insecure, 'region_name': args.os_region_name, 'keystone_timeout': args.keystone_timeout } endpoint = args.monasca_api_url if not args.os_no_client_auth: _ksclient = ksclient.KSClient(**kwargs) if args.os_auth_token: token = args.os_auth_token else: try: token = _ksclient.token except exc.CommandError: raise exc.CommandError( "User does not have a default project. " "You must provide a project id using " "--os-project-id or via env[OS_PROJECT_ID], " "or you must provide a project name using " "--os-project-name or via env[OS_PROJECT_NAME] " "and a project domain using --os-domain-name, via " "env[OS_DOMAIN_NAME], using --os-domain-id or " "via env[OS_DOMAIN_ID]") kwargs = { 'token': token, 'insecure': args.insecure, 'os_cacert': args.os_cacert, 'cert_file': args.cert_file, 'key_file': args.key_file, 'username': args.os_username, 'password': args.os_password, 'service_type': args.os_service_type, 'endpoint_type': args.os_endpoint_type, 'auth_url': args.os_auth_url, 'keystone_timeout': args.keystone_timeout } if args.os_user_domain_name: kwargs['user_domain_name'] = args.os_user_domain_name if args.os_user_domain_id: kwargs['user_domain_id'] = args.os_user_domain_id if args.os_region_name: kwargs['region_name'] = args.os_region_name if args.os_project_name: kwargs['project_name'] = args.os_project_name if args.os_project_id: kwargs['project_id'] = args.os_project_id if args.os_domain_name: kwargs['domain_name'] = args.os_domain_name if args.os_domain_id: kwargs['domain_id'] = args.os_domain_id if not endpoint: endpoint = _ksclient.monasca_url client = monasca_client.Client(api_version, endpoint, **kwargs) args.func(client, args)