From abc56a82ae529444b8950cde893c0d3c7ef09967 Mon Sep 17 00:00:00 2001 From: tengqm Date: Mon, 5 Jan 2015 19:46:22 +0800 Subject: [PATCH] More operations added --- senlinclient/v1/shell.py | 516 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 516 insertions(+) diff --git a/senlinclient/v1/shell.py b/senlinclient/v1/shell.py index b5129869..92bba763 100644 --- a/senlinclient/v1/shell.py +++ b/senlinclient/v1/shell.py @@ -12,12 +12,286 @@ import logging +from oslo.serialization import jsonutils + +from senlinclient.common import exc from senlinclient.common.i18n import _ from senlinclient.common import utils logger = logging.getLogger(__name__) +def do_build_info(sc, args): + '''Retrieve build information.''' + result = sc.build_info.build_info() + formatters = { + 'api': utils.json_formatter, + 'engine': utils.json_formatter, + } + utils.print_dict(result, formatters=formatters) + + +#### PROFILE TYPES + + +def do_profile_type_list(sc, args): + '''List the available profile types.''' + types = sc.profile_types.list() + utils.print_list(types, ['profile_type'], sortby_index=0) + + +@utils.arg('profile_type', metavar='', + help=_('Profile type to get the details for.')) +def do_profile_type_show(sc, args): + '''Show the profile type.''' + try: + profile_type = sc.profile_types.get(args.profile_type) + except exc.HTTPNotFound: + raise exc.CommandError( + _('Profile Type not found: %s') % args.profile_type) + else: + print(jsonutils.dumps(profile_type, indent=2)) + + +@utils.arg('profile_type', metavar='', + help=_('Profile type to generate a template for.')) +@utils.arg('-F', '--format', metavar='', + help=_("The template output format, one of: %s.") + % ', '.join(utils.supported_formats.keys())) +def do_profile_type_template(sc, args): + '''Generate a template based on a profile type.''' + try: + template = sc.profile_types.generate_template(args.profile_type) + except exc.HTTPNotFound: + raise exc.CommandError( + _('Profile Type %s not found.') % args.profile_type) + + if args.format: + print(utils.format_output(template, format=args.format)) + else: + print(utils.format_output(template)) + + +#### PROFILES + + +#### POLICY TYPES + + +def do_policy_type_list(sc, args): + '''List the available policy types.''' + types = sc.policy_types.list() + utils.print_list(types, ['policy_type'], sortby_index=0) + + +@utils.arg('policy_type', metavar='', + help=_('Policy type to get the details for.')) +def do_policy_type_show(sc, args): + '''Show the policy type.''' + try: + policy_type = sc.policy_types.get(args.policy_type) + except exc.HTTPNotFound: + raise exc.CommandError( + _('Policy Type not found: %s') % args.policy_type) + else: + print(jsonutils.dumps(policy_type, indent=2)) + + +@utils.arg('policy_type', metavar='', + help=_('Policy type to generate a template for.')) +@utils.arg('-F', '--format', metavar='', + help=_("The template output format, one of: %s.") + % ', '.join(utils.supported_formats.keys())) +def do_policy_type_template(sc, args): + '''Generate a template based on a policy type.''' + try: + template = sc.policy_types.generate_template(args.policy_type) + except exc.HTTPNotFound: + raise exc.CommandError( + _('Policy Type %s not found.') % args.policy_type) + + if args.format: + print(utils.format_output(template, format=args.format)) + else: + print(utils.format_output(template)) + + +#### POLICIES + + +#### CLUSTERS + + +@utils.arg('-p', '--profile', metavar='', + help=_('Profile Id used for this cluster.')) +@utils.arg('-n', '--size', metavar='', + help=_('Initial size of the cluster.')) +@utils.arg('-t', '--timeout', metavar='', + type=int, + help=_('Cluster creation timeout in minutes.')) +@utils.arg('-g', '--tags', metavar='', + help=_('Tag values to be attached to the cluster. ' + 'This can be specified multiple times, or once with tags' + 'separated by a semicolon.'), + action='append') +@utils.arg('name', metavar='', + help=_('Name of the cluster to create.')) +def do_cluster_create(sc, args): + '''Create the cluster.''' + fields = { + 'name': args.name, + 'profile_id': args.profile, + 'tags': utils.format_parameters(args.tags), + 'size': args.size, + 'timeout': args.timeout + } + + sc.clusters.create(**fields) + do_cluster_list(sc) + + +@utils.arg('id', metavar='', nargs='+', + help=_('Name or ID of cluster(s) to delete.')) +def do_cluster_delete(sc, args): + '''Delete the cluster(s).''' + failure_count = 0 + + for cid in args.id: + try: + sc.clusters.delete(cid) + except exc.HTTPNotFound as ex: + failure_count += 1 + print(ex) + if failure_count == len(args.id): + msg = _('Failed to delete any of the specified clusters.') + raise exc.CommandError(msg) + do_cluster_list(sc) + + +@utils.arg('-p', '--profile', metavar='', + help=_('ID of new profile to use.')) +@utils.arg('-t', '--timeout', metavar='', + type=int, + help=_('Cluster update timeout in minutes.')) +@utils.arg('-g', '--tags', metavar='', + help=_('Tag values to be attached to the cluster. ' + 'This can be specified multiple times, or once with tags' + 'separated by a semicolon.'), + action='append') +@utils.arg('id', metavar='', + help=_('Name or ID of cluster to update.')) +def do_cluster_update(sc, args): + '''Update the cluster.''' + + fields = { + 'cluster_id': args.id, + 'profile_id': args.profile, + 'tags': utils.format_parameters(args.tags), + } + + if args.timeout: + fields['timeout'] = args.timeout + + sc.clusters.update(**fields) + do_cluster_list(sc) + + +@utils.arg('-n', '--nodes', metavar='', + help=_('ID of nodes to be added.')) +@utils.arg('id', metavar='', + help=_('Name or ID of cluster to operate on.')) +def do_cluster_node_add(sc, args): + '''Add specified nodes to cluster.''' + failure_count = 0 + for nid in args.nodes: + try: + sc.clusters.add_node(args.id, nid) + except Exception as ex: + failure_count += 1 + print(ex) + if failure_count == len(args.nodes): + msg = _('Failed to add any of the specified nodes.') + raise exc.CommandError(msg) + + do_cluster_node_list(sc, id=args.id) + + +@utils.arg('-n', '--nodes', metavar='', + help=_('ID of nodes to be deleted.')) +@utils.arg('id', metavar='', + help=_('Name or ID of cluster to operate on.')) +def do_cluster_node_del(sc, args): + '''Delete specified nodes from cluster.''' + failure_count = 0 + for nid in args.nodes: + try: + sc.clusters.del_node(args.id, nid) + except Exception as ex: + failure_count += 1 + print(ex) + if failure_count == len(args.nodes): + msg = _('Failed to delete any of the specified nodes.') + raise exc.CommandError(msg) + + do_cluster_node_list(sc, id=args.id) + + +@utils.arg('id', metavar='', + help=_('Name or ID of cluster to nodes from.')) +def do_cluster_node_list(sc, args): + '''List nodes from cluster.''' + sc.clusters.list_nodes(args.id) + + +@utils.arg('-p', '--policy', metavar='', + help=_('ID of policy to be attached.')) +@utils.arg('id', metavar='', + help=_('Name or ID of cluster to operate on.')) +def do_cluster_policy_attach(sc, args): + '''Attach policy to cluster.''' + sc.clusters.attach_policy(args.id, args.policy) + do_cluster_policy_list(sc, args.id) + + +@utils.arg('-p', '--policy', metavar='', + help=_('ID of policy to be enabled.')) +@utils.arg('id', metavar='', + help=_('Name or ID of cluster to operate on.')) +def do_cluster_policy_enable(sc, args): + '''Enable policy on cluster.''' + sc.clusters.enable_policy(args.id, args.policy) + do_cluster_policy_list(sc, args.id) + + +@utils.arg('-p', '--policy', metavar='', + help=_('ID of policy to be disabled.')) +@utils.arg('id', metavar='', + help=_('Name or ID of cluster to operate on.')) +def do_cluster_policy_disable(sc, args): + '''Disable policy on cluster.''' + sc.clusters.disable_policy(args.id, args.policy) + do_cluster_policy_list(sc, args.id) + + +@utils.arg('-p', '--policy', metavar='', + help=_('ID of policy to be detached.')) +@utils.arg('id', metavar='', + help=_('Name or ID of cluster to operate on.')) +def do_cluster_policy_detach(sc, args): + '''Detach policy from cluster.''' + sc.clusters.detach_policy(args.id, args.policy) + do_cluster_policy_list(sc, args.id) + + +@utils.arg('id', metavar='', + help=_('Name or ID of cluster to operate on.')) +def do_cluster_policy_list(sc, args): + '''List policies from cluster.''' + policies = sc.clusters.list_policy(args.id) + fields = ['id', 'name', 'enabled', 'level'] + utils.print_list(policies, fields, sortby_index=1) + + @utils.arg('-s', '--show-deleted', default=False, action="store_true", help=_('Include soft-deleted clusters if any.')) @utils.arg('-n', '--show-nested', default=False, action="store_true", @@ -59,3 +333,245 @@ def do_cluster_list(sc, args=None): clusters = sc.clusters.list(**kwargs) utils.print_list(clusters, fields, sortby_index=3) + + +@utils.arg('id', metavar='', + help=_('Name or ID of cluster to show.')) +def do_cluster_show(sc, args): + '''Show details of the cluster.''' + try: + cluster = sc.clusters.get(args.id) + except exc.HTTPNotFound: + raise exc.CommandError(_('Cluster not found: %s') % args.id) + else: + formatters = { + 'profile': utils.json_formatter, + 'status': utils.text_wrap_formatter, + 'status_reason': utils.text_wrap_formatter, + 'tags': utils.json_formatter, + 'links': utils.link_formatter + } + utils.print_dict(cluster.to_dict(), formatters=formatters) + + +#### NODES + + +@utils.arg('-c', '--cluster', metavar='', + help=_('Cluster Id for this node.')) +@utils.arg('-p', '--profile', metavar='', + help=_('Profile Id used for this node.')) +@utils.arg('-r', '--role', metavar='', + help=_('Role for this node in the specific cluster.')) +@utils.arg('-g', '--tags', metavar='', + help=_('Tag values to be attached to the cluster. ' + 'This can be specified multiple times, or once with tags' + 'separated by a semicolon.'), + action='append') +@utils.arg('name', metavar='', + help=_('Name of the node to create.')) +def do_node_create(sc, args): + '''Create the node.''' + fields = { + 'name': args.name, + 'cluster_id': args.cluster, + 'profile_id': args.profile, + 'role': args.role, + 'tags': utils.format_parameters(args.tags), + } + + sc.nodes.create(**fields) + do_node_list(sc) + + +@utils.arg('id', metavar='', nargs='+', + help=_('Name or ID of node(s) to delete.')) +def do_node_delete(sc, args): + '''Delete the node(s).''' + failure_count = 0 + + for nid in args.id: + try: + sc.nodes.delete(nid) + except exc.HTTPNotFound as ex: + failure_count += 1 + print(ex) + if failure_count == len(args.id): + msg = _('Failed to delete any of the specified nodes.') + raise exc.CommandError(msg) + do_node_list(sc) + + +@utils.arg('-p', '--profile', metavar='', + help=_('ID of new profile to use.')) +@utils.arg('-g', '--tags', metavar='', + help=_('Tag values to be attached to the node. ' + 'This can be specified multiple times, or once with tags' + 'separated by a semicolon.'), + action='append') +@utils.arg('id', metavar='', + help=_('Name or ID of node to update.')) +def do_node_update(sc, args): + '''Update the node.''' + fields = { + 'id': args.id, + 'profile': args.profile, + 'tags': utils.format_parameters(args.tags), + } + + sc.nodes.update(**fields) + do_node_list(sc) + + +@utils.arg('id', metavar='', + help=_('Name or ID of node to operate on.')) +def do_node_leave(sc, args): + '''Make node leave its current cluster.''' + sc.nodes.leave(args.id) + do_node_list(sc) + + +@utils.arg('-c', '--cluster', + help=_('ID or name of cluster for node to join.')) +@utils.arg('id', metavar='', + help=_('Name or ID of node to operate on.')) +def do_node_join(sc, args): + '''Make node join the specified cluster.''' + sc.nodes.join(args.id, args.cluster) + do_node_list(sc) + + +@utils.arg('-c', '--cluster', default=None, + help=_('ID or name of cluster for nodes to list.')) +@utils.arg('-s', '--show-deleted', default=False, action="store_true", + help=_('Include soft-deleted nodes if any.')) +@utils.arg('-f', '--filters', metavar='', + help=_('Filter parameters to apply on returned nodes. ' + 'This can be specified multiple times, or once with ' + 'parameters separated by a semicolon.'), + action='append') +@utils.arg('-l', '--limit', metavar='', + help=_('Limit the number of nodes returned.')) +@utils.arg('-m', '--marker', metavar='', + help=_('Only return nodes that appear after the given node ID.')) +@utils.arg('-g', '--global-tenant', action='store_true', default=False, + help=_('List nodes from all tenants. Operation only authorized ' + 'for users who match the policy in policy file.')) +def do_node_list(sc, args): + '''Show list of nodes.''' + fields = ['id', 'name', 'status', 'cluster_id', 'physical_id', + 'created_time'] + if args.global_tenant: + fields.insert(2, 'project') + + kwargs = { + 'cluster_id': args.cluster, + 'show_deleted': args.show_deleted, + 'filters': utils.format_parameters(args.filters), + 'limit': args.limit, + 'marker': args.marker, + 'global_tenant': args.global_tenant, + } + + try: + nodes = sc.nodes.list(**kwargs) + except exc.HTTPNotFound: + msg = _('No node matching criteria is found') + raise exc.CommandError(msg) + + utils.print_list(nodes, fields, sortby_index=5) + + +@utils.arg('id', metavar='', + help=_('Name or ID of the node to show the details for.')) +def do_node_show(sc, args): + '''Show detailed info about the specified node.''' + try: + node = sc.nodes.get(args.id) + except exc.HTTPNotFound: + msg = _('Node %(id)s is not found') % args.id + raise exc.CommandError(msg) + + formatters = { + 'links': utils.link_formatter, + 'required_by': utils.newline_list_formatter + } + + utils.print_dict(node.to_dict(), formatters=formatters) + + +##### EVENTS + + +@utils.arg('-i', '--id', metavar='', + help=_('Name or ID of objects to show the events for.')) +@utils.arg('-t', '--type', metavar='', + help=_('Types of the objects to filter events by.' + 'The types can be CLUSTER, NODE, PROFILE, POLICY.')) +@utils.arg('-f', '--filters', metavar='', + help=_('Filter parameters to apply on returned events. ' + 'This can be specified multiple times, or once with ' + 'parameters separated by a semicolon.'), + action='append') +@utils.arg('-l', '--limit', metavar='', + help=_('Limit the number of events returned.')) +@utils.arg('-m', '--marker', metavar='', + help=_('Only return events that appear after the given event ID.')) +def do_event_list(sc, args): + '''List events.''' + fields = {'obj_id': args.id, + 'obj_type': args.type, + 'limit': args.limit, + 'marker': args.marker, + 'filters': utils.format_parameters(args.filters)} + try: + events = sc.events.list(**fields) + except exc.HTTPNotFound as ex: + raise exc.CommandError(str(ex)) + + fields = ['timestamp', 'obj_type', 'obj_id', 'action', 'status', + 'status_reason'] + utils.print_list(events, fields, sortby_index=0) + + +@utils.arg('event', metavar='', + help=_('ID of event to display details for.')) +def do_event_show(sc, args): + '''Describe the event.''' + try: + event = sc.events.get(args.event) + except exc.HTTPNotFound as ex: + raise exc.CommandError(str(ex)) + + utils.print_dict(event.to_dict()) + + +#### EVENTS + + +@utils.arg('-f', '--filters', metavar='', + help=_('Filter parameters to apply on returned actions. ' + 'This can be specified multiple times, or once with ' + 'parameters separated by a semicolon.'), + action='append') +@utils.arg('-l', '--limit', metavar='', + help=_('Limit the number of actions returned.')) +@utils.arg('-m', '--marker', metavar='', + help=_('Only return action that appear after the given action ID.')) +def do_action_list(sc, args): + '''List actions.''' + fields = { + 'limit': args.limit, + 'marker': args.marker, + 'filters': utils.format_parameters(args.filters) + } + + try: + actions = sc.actions.list(**fields) + except exc.HTTPNotFound as ex: + raise exc.CommandError(str(ex)) + + fields = ['name', 'action', 'status', 'status_reason', 'depends_on', + 'depended_by'] + + utils.print_list(actions, fields, sortby_index=0)