def do_profile_create(service, args): """Create a profile.""" spec = utils.get_spec_content(args.spec_file) type_name = spec.get('type', None) type_version = spec.get('version', None) properties = spec.get('properties', None) if type_name is None: raise exc.CommandError(_("Missing 'type' key in spec file.")) if type_version is None: raise exc.CommandError(_("Missing 'version' key in spec file.")) if properties is None: raise exc.CommandError(_("Missing 'properties' key in spec file.")) if type_name == 'os.heat.stack': stack_properties = utils.process_stack_spec(properties) spec['properties'] = stack_properties params = { 'name': args.name, 'spec': spec, 'metadata': utils.format_parameters(args.metadata), } profile = service.create_profile(**params) _show_profile(service, profile.id)
def format_parameters(params, parse_semicolon=True): """Reformat parameters into dict of format expected by the API.""" if not params or params == ['{}']: return {} if parse_semicolon: # expect multiple invocations of --parameters but fall back to ';' # delimited if only one --parameters is specified if len(params) == 1: params = params[0].split(';') parameters = {} for p in params: try: (n, v) = p.split(('='), 1) except ValueError: msg = _('Malformed parameter(%s). Use the key=value format.') % p 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_event_show(service, args): """Describe the event.""" try: event = service.get_event(args.id) except sdk_exc.ResourceNotFound: raise exc.CommandError(_("Event not found: %s") % args.id) utils.print_dict(event.to_dict())
def get_spec_content(filename): with open(filename, 'r') as f: try: data = yaml.safe_load(f) except Exception as ex: raise exc.CommandError(_('The specified file is not a valid ' 'YAML file: %s') % six.text_type(ex)) return data
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 _show_cluster(service, cluster_id): try: cluster = service.get_cluster(cluster_id) except sdk_exc.ResourceNotFound: raise exc.CommandError(_('Cluster not found: %s') % cluster_id) formatters = { 'metadata': utils.json_formatter, 'nodes': utils.list_formatter, } utils.print_dict(cluster.to_dict(), formatters=formatters)
def _show_policy(service, policy_id): try: policy = service.get_policy(policy_id) except sdk_exc.ResourceNotFound: raise exc.CommandError(_('Policy not found: %s') % policy_id) formatters = { 'metadata': utils.json_formatter, 'spec': utils.json_formatter, } utils.print_dict(policy.to_dict(), formatters=formatters)
def do_policy_type_show(service, args): """Get the details about a policy type.""" try: res = service.get_policy_type(args.type_name) except sdk_exc.ResourceNotFound: raise exc.CommandError(_('Policy type not found: %s') % args.type_name) pt = res.to_dict() if args.format: print(utils.format_output(pt, format=args.format)) else: print(utils.format_output(pt))
def _show_receiver(service, receiver_id): try: receiver = service.get_receiver(receiver_id) except sdk_exc.ResourceNotFound: raise exc.CommandError(_('Receiver not found: %s') % receiver_id) formatters = { 'actor': utils.json_formatter, 'params': utils.json_formatter, 'channel': utils.json_formatter, } utils.print_dict(receiver.to_dict(), formatters=formatters)
def do_policy_delete(service, args): """Delete policy(s).""" failure_count = 0 for pid in args.id: try: service.delete_policy(pid, False) except Exception as ex: failure_count += 1 print(ex) if failure_count > 0: msg = _('Failed to delete some of the specified policy(s).') raise exc.CommandError(msg) print('Policy deleted: %s' % args.id)
def do_node_delete(service, args): """Delete the node(s).""" failure_count = 0 for nid in args.id: try: service.delete_node(nid, False) except Exception as ex: failure_count += 1 print(ex) if failure_count > 0: msg = _('Failed to delete some of the specified nodes.') raise exc.CommandError(msg) print('Request accepted')
def format_json_parameter(param): '''Return JSON dict from JSON formatted param. :parameter param JSON formatted string :return JSON dict ''' if not param: return {} try: return jsonutils.loads(param) except ValueError: msg = _('Malformed parameter(%s). Use the JSON format.') % param raise exc.CommandError(msg)
def do_receiver_delete(service, args): """Delete receiver(s).""" failure_count = 0 for wid in args.id: try: service.delete_receiver(wid, False) except Exception as ex: failure_count += 1 print(ex) if failure_count > 0: msg = _('Failed to delete some of the specified receiver(s).') raise exc.CommandError(msg) print('Receivers deleted: %s' % args.id)
def do_profile_update(service, args): """Update a profile.""" params = { 'name': args.name, } if args.metadata: params['metadata'] = utils.format_parameters(args.metadata) # Find the profile first, we need its id try: profile = service.get_profile(args.id) except sdk_exc.ResourceNotFound: raise exc.CommandError(_('Profile not found: %s') % args.id) service.update_profile(profile.id, **params) _show_profile(service, profile.id)
def _show_profile(service, profile_id): try: profile = service.get_profile(profile_id) except sdk_exc.ResourceNotFound: raise exc.CommandError(_('Profile not found: %s') % profile_id) formatters = { 'metadata': utils.json_formatter, } formatters['spec'] = utils.nested_dict_formatter( ['type', 'version', 'properties'], ['property', 'value']) utils.print_dict(profile.to_dict(), formatters=formatters)
def do_node_update(service, args): """Update the node.""" # Find the node first, we need its UUID try: node = service.get_node(args.id) except sdk_exc.ResourceNotFound: raise exc.CommandError(_('Node not found: %s') % args.id) attrs = { 'name': args.name, 'role': args.role, 'profile_id': args.profile, 'metadata': utils.format_parameters(args.metadata), } service.update_node(args.id, **attrs) _show_node(service, node.id)
def do_action_show(service, args): """Show detailed info about the specified action.""" try: action = service.get_action(args.id) except sdk_exc.ResourceNotFound: raise exc.CommandError(_('Action not found: %s') % args.id) formatters = { 'inputs': utils.json_formatter, 'outputs': utils.json_formatter, 'metadata': utils.json_formatter, 'data': utils.json_formatter, 'depends_on': utils.list_formatter, 'depended_by': utils.list_formatter, } utils.print_dict(action.to_dict(), formatters=formatters)
def _show_node(service, node_id, show_details=False): """Show detailed info about the specified node.""" args = {'show_details': True} if show_details else None try: node = service.get_node(node_id, args=args) except sdk_exc.ResourceNotFound: raise exc.CommandError(_('Node not found: %s') % node_id) formatters = { 'metadata': utils.json_formatter, 'data': utils.json_formatter, } data = node.to_dict() if show_details: formatters['details'] = utils.nested_dict_formatter( list(node['details'].keys()), ['property', 'value']) utils.print_dict(data, formatters=formatters)
def _check_identity_arguments(self, args): # TODO(Qiming): validate the token authentication path and the trust # authentication path if not args.auth_url: msg = _('You must provide an auth url via --os-auth-url (or ' ' env[OS_AUTH_URL])') raise exc.CommandError(msg) # username or user_id or token must be specified if not (args.username or args.user_id or args.token): msg = _('You must provide a user name, a user_id or a ' 'token for authentication') raise exc.CommandError(msg) # if both username and user_id are specified, user_id takes precedence if (args.username and args.user_id): msg = _('Both user name and user ID are specified, Senlin will ' 'use user ID for authentication') print(_('WARNING: %s') % msg) if 'v3' in args.auth_url: if (args.username and not args.user_id): if not (args.user_domain_id or args.user_domain_name): msg = _('Either user domain ID (--user-domain-id / ' 'env[OS_USER_DOMAIN_ID]) or user domain name ' '(--user-domain-name / env[OS_USER_DOMAIN_NAME]) ' 'must be specified, because user name may not be ' 'unique.') raise exc.CommandError(msg) # password is needed if username or user_id is present if (args.username or args.user_id) and not (args.password): msg = _('You must provide a password for user %s') % ( args.username or args.user_id) raise exc.CommandError(msg) # project name or ID is needed, or else sdk may find the wrong project if (not (args.project_id or args.project_name or args.tenant_id or args.tenant_name)): if not (args.user_id): msg = _('Either project/tenant ID or project/tenant name ' 'must be specified, or else Senlin cannot know ' 'which project to use.') raise exc.CommandError(msg) else: msg = _('Neither project ID nor project name is specified. ' 'Senlin will use user\'s default project which may ' 'result in authentication error.') print(_('WARNING: %s') % msg) # both project name and ID are specified, ID takes precedence if ((args.project_id or args.tenant_id) and (args.project_name or args.tenant_name)): msg = _('Both project/tenant name and project/tenant ID are ' 'specified, Senlin will use project ID for ' 'authentication') print(_('WARNING: %s') % msg) # project name may not be unique if 'v3' in args.auth_url: if (not (args.project_id or args.tenant_id) and (args.project_name or args.tenant_name) and not (args.project_domain_id or args.project_domain_name)): msg = _('Either project domain ID (--project-domain-id / ' 'env[OS_PROJECT_DOMAIN_ID]) orr project domain name ' '(--project-domain-name / env[OS_PROJECT_DOMAIN_NAME ' 'must be specified, because project/tenant name may ' 'not be unique.') raise exc.CommandError(msg)
def do_cluster_resize(service, args): """Resize a cluster.""" # validate parameters # NOTE: this will be much simpler if cliutils supports exclusive groups action_args = {} capacity = args.capacity adjustment = args.adjustment percentage = args.percentage min_size = args.min_size max_size = args.max_size min_step = args.min_step if sum(v is not None for v in (capacity, adjustment, percentage)) > 1: raise exc.CommandError(_("Only one of 'capacity', 'adjustment' and " "'percentage' can be specified.")) action_args['adjustment_type'] = None action_args['number'] = None if capacity is not None: if capacity < 0: raise exc.CommandError(_('Cluster capacity must be larger than ' ' or equal to zero.')) action_args['adjustment_type'] = 'EXACT_CAPACITY' action_args['number'] = capacity if adjustment is not None: if adjustment == 0: raise exc.CommandError(_('Adjustment cannot be zero.')) action_args['adjustment_type'] = 'CHANGE_IN_CAPACITY' action_args['number'] = adjustment if percentage is not None: if (percentage == 0 or percentage == 0.0): raise exc.CommandError(_('Percentage cannot be zero.')) action_args['adjustment_type'] = 'CHANGE_IN_PERCENTAGE' action_args['number'] = percentage if min_step is not None: if percentage is None: raise exc.CommandError(_('Min step is only used with percentage.')) if min_size is not None: if min_size < 0: raise exc.CommandError(_('Min size cannot be less than zero.')) if max_size is not None and max_size >= 0 and min_size > max_size: raise exc.CommandError(_('Min size cannot be larger than ' 'max size.')) if capacity is not None and min_size > capacity: raise exc.CommandError(_('Min size cannot be larger than the ' 'specified capacity')) if max_size is not None: if capacity is not None and max_size > 0 and max_size < capacity: raise exc.CommandError(_('Max size cannot be less than the ' 'specified capacity.')) # do a normalization if max_size < 0: max_size = -1 action_args['min_size'] = min_size action_args['max_size'] = max_size action_args['min_step'] = min_step action_args['strict'] = args.strict resp = service.cluster_resize(args.id, **action_args) print('Request accepted by action: %s' % resp['action'])