Example #1
0
    def add_arguments(cls, parser, object_name, allow_unset=True):
        for opt_key, option in sorted(cls.drbd_options[object_name].items(),
                                      key=lambda k: k[0]):
            if opt_key in cls.CLASH_OPTIONS:
                opt_key = "drbd-" + opt_key
            if option['type'] == 'symbol':
                parser.add_argument('--' + opt_key, choices=option['values'])
            elif option['type'] == 'boolean':
                parser.add_argument('--' + opt_key,
                                    choices=['yes', 'no'],
                                    type=str.lower,
                                    help="yes/no (Default: %s)" %
                                    (option['default']))
            elif option['type'] == 'string':
                parser.add_argument('--' + opt_key)
            elif option['type'] == 'numeric-or-symbol':
                min_ = int(option['min'])
                max_ = int(option['max'])
                parser.add_argument(
                    '--' + opt_key,
                    type=DrbdOptions.numeric_symbol(min_, max_,
                                                    option['values']),
                    help="Integer between [{min}-{max}] or one of ['{syms}']".
                    format(min=min_,
                           max=max_,
                           syms="','".join(option['values'])))
            elif option['type'] == 'range':
                min_ = option['min']
                max_ = option['max']
                default = option['default']
                unit = ""
                if "unit" in option:
                    unit = "; Unit: " + cls.unit_str(option['unit'],
                                                     option['unit_prefix'])
                # sp.add_argument('--' + opt, type=rangecheck(min_, max_),
                #                 default=default, help="Range: [%d, %d]; Default: %d" %(min_, max_, default))
                # setting a default sets the option to != None, which makes
                # filterNew relatively complex
                if DrbdOptions._is_byte_unit(option):
                    parser.add_argument(
                        '--' + opt_key,
                        type=str,
                        help="Range: [%d%s, %d%s]; Default: %s%s" %
                        (min_, option.get('unit_prefix', ''), max_,
                         option.get('unit_prefix', ''), str(default), unit))
                else:
                    parser.add_argument('--' + opt_key,
                                        type=rangecheck(min_, max_),
                                        help="Range: [%d, %d]; Default: %s%s" %
                                        (min_, max_, str(default), unit))
            else:
                raise LinstorError('Unknown option type ' + option['type'])

            if allow_unset:
                parser.add_argument('--%s-%s' % (cls.unsetprefix, opt_key),
                                    action='store_true',
                                    help=argparse.SUPPRESS)
Example #2
0
 def add_arguments(cls, parser, option_list):
     assert(len(option_list) > 0)
     options = DrbdOptions._options['options']
     for opt_key in option_list:
         option = options[opt_key]
         if opt_key in ['help', '_name']:
             continue
         if option['type'] == 'symbol':
             parser.add_argument('--' + opt_key, choices=option['symbols'])
         if option['type'] == 'boolean':
             parser.add_argument(
                 '--' + opt_key,
                 choices=['yes', 'no'],
                 help="yes/no (Default: %s)" % (option['default'])
             )
         if option['type'] == 'string':
             parser.add_argument('--' + opt_key)
         if option['type'] == 'numeric-or-symbol':
             min_ = int(option['min'])
             max_ = int(option['max'])
             parser.add_argument(
                 '--' + opt_key,
                 type=DrbdOptions.numeric_symbol(min_, max_, option['symbols']),
                 help="Integer between [{min}-{max}] or one of ['{syms}']".format(
                     min=min_,
                     max=max_,
                     syms="','".join(option['symbols'])
                 )
             )
         if option['type'] == 'numeric':
             min_ = option['min']
             max_ = option['max']
             default = option['default']
             if "unit" in option:
                 unit = "; Unit: " + option['unit']
             else:
                 unit = ""
             # sp.add_argument('--' + opt, type=rangecheck(min_, max_),
             #                 default=default, help="Range: [%d, %d]; Default: %d" %(min_, max_, default))
             # setting a default sets the option to != None, which makes
             # filterNew relatively complex
             parser.add_argument('--' + opt_key, type=rangecheck(min_, max_),
                                 help="Range: [%d, %d]; Default: %d%s" % (min_, max_, default, unit))
     for opt_key in option_list:
         if opt_key == 'help':
             continue
         else:
             parser.add_argument('--%s-%s' % (cls.unsetprefix, opt_key),
                                 action='store_true')
Example #3
0
    def setup_commands(self, parser):
        # Node subcommands
        subcmds = [
            Commands.Subcommands.Create,
            NodeCommands.CreateOpenFlexTarget,
            Commands.Subcommands.List,
            Commands.Subcommands.Delete,
            Commands.Subcommands.Lost,
            Commands.Subcommands.Describe,
            Commands.Subcommands.Interface,
            Commands.Subcommands.Info,
            Commands.Subcommands.SetProperty,
            Commands.Subcommands.ListProperties,
            Commands.Subcommands.Modify,
            NodeCommands.Reconnect,
            Commands.Subcommands.Restore
        ]

        node_parser = parser.add_parser(
            Commands.NODE,
            aliases=["n"],
            formatter_class=argparse.RawTextHelpFormatter,
            description="Node subcommands"
        )

        node_subp = node_parser.add_subparsers(
            title="Node commands",
            metavar="",
            description=Commands.Subcommands.generate_desc(subcmds)
        )

        node_types = [
            apiconsts.VAL_NODE_TYPE_CTRL,
            apiconsts.VAL_NODE_TYPE_AUX,
            apiconsts.VAL_NODE_TYPE_CMBD,
            apiconsts.VAL_NODE_TYPE_STLT
        ]

        # create node
        p_new_node = node_subp.add_parser(
            Commands.Subcommands.Create.LONG,
            aliases=[Commands.Subcommands.Create.SHORT],
            description='Creates a node entry for a node that participates in the linstor cluster.'
        )
        p_new_node.add_argument('-p', '--port', type=rangecheck(1, 65535),
                                help='default: Satellite %s for %s; Controller %s for %s; %s for %s' % (
                                    apiconsts.DFLT_STLT_PORT_PLAIN,
                                    apiconsts.VAL_NETCOM_TYPE_PLAIN,
                                    apiconsts.DFLT_CTRL_PORT_PLAIN,
                                    apiconsts.VAL_NETCOM_TYPE_PLAIN,
                                    apiconsts.DFLT_CTRL_PORT_SSL,
                                    apiconsts.VAL_NETCOM_TYPE_SSL))
        ntype_def = apiconsts.VAL_NODE_TYPE_STLT
        p_new_node.add_argument('--node-type', choices=[x.lower() for x in node_types],
                                default=apiconsts.VAL_NODE_TYPE_STLT,
                                type=str.lower,
                                help='Node type (default: %s)' % ntype_def.lower())
        ctype_def = apiconsts.VAL_NETCOM_TYPE_PLAIN
        p_new_node.add_argument('--communication-type',
                                choices=(apiconsts.VAL_NETCOM_TYPE_PLAIN.lower(),
                                         apiconsts.VAL_NETCOM_TYPE_SSL.lower()),
                                default=ctype_def,
                                type=str.lower,
                                help='Communication type (default: %s)' % ctype_def.lower())
        itype_def = apiconsts.VAL_NETIF_TYPE_IP
        p_new_node.add_argument('--interface-type', choices=(apiconsts.VAL_NETIF_TYPE_IP.lower(),),
                                type=str.lower,
                                default=itype_def,
                                help='Interface type (default: %s)' % itype_def.lower())
        iname_def = 'default'
        p_new_node.add_argument('--interface-name', default=iname_def,
                                help='Interface name (default: %s)' % iname_def)
        p_new_node.add_argument(
            'name',
            help='Name of the new node, must match the nodes hostname',
            type=str)
        p_new_node.add_argument(
            'ip',
            nargs='?',
            help='IP address of the new node, if not specified it will be resolved by the name.'
        ).completer = ip_completer("name")
        p_new_node.set_defaults(func=self.create)

        # openflex create
        p_create_of_target = node_subp.add_parser(
            NodeCommands.CreateOpenFlexTarget.LONG,
            aliases=[NodeCommands.CreateOpenFlexTarget.SHORT],
            description='Creates a virtual on controller openflex target node.'
        )
        p_create_of_target.add_argument(
            'node_name',
            help='Name of the new openflex target node',
            type=str
        )
        p_create_of_target.add_argument('stor_dev_host', help='OpenFlex storage device host')
        p_create_of_target.add_argument('stor_dev', help='OpenFlex storage device id')
        p_create_of_target.set_defaults(func=self.create_of_target)

        # modify node
        p_modify_node = node_subp.add_parser(
            Commands.Subcommands.Modify.LONG,
            aliases=[Commands.Subcommands.Modify.SHORT],
            description='Modify a node'
        )
        p_modify_node.add_argument(
            '--node-type', '-t',
            choices=[x.lower() for x in node_types],
            type=str.lower,
            default=apiconsts.VAL_NODE_TYPE_STLT,
            help='Node type (default: %s)' % ntype_def.lower()
        )
        p_modify_node.add_argument(
            'node_name',
            help='Name of the node to modify.'
        ).completer = self.node_completer
        p_modify_node.set_defaults(func=self.modify_node)

        # describe-node
        p_desc_node = node_subp.add_parser(
            Commands.Subcommands.Describe.LONG,
            aliases=[Commands.Subcommands.Describe.SHORT],
            description='describe a node (or all nodes), list storage pools, resources and volumes under this node, '
            'in this order')
        p_desc_node.add_argument(
            'name',
            nargs='?',
            help='Name of the node to be described. With no name, all nodes are described'
        ).completer = self.node_completer
        p_desc_node.set_defaults(func=self.describe)

        # remove-node
        p_rm_node = node_subp.add_parser(
            Commands.Subcommands.Delete.LONG,
            aliases=[Commands.Subcommands.Delete.SHORT],
            description='Removes a node from the linstor cluster. '
            'All linstor resources that are still deployed on the specified '
            'node are marked for undeployment, and the node entry is marked for '
            "removal from linstor's data tables. The specified node is "
            'expected to undeploy all resources. As soon as all resources have been '
            'undeployed from the node, the node entry is removed from '
            "linstor's data tables.")
        p_rm_node.add_argument(
            '--async',
            action='store_true',
            help='Deprecated, kept for compatibility'
        )
        p_rm_node.add_argument('name',
                               help='Name of the node to remove').completer = self.node_completer
        p_rm_node.set_defaults(func=self.delete)

        # lost-node
        p_lost_node = node_subp.add_parser(
            Commands.Subcommands.Lost.LONG,
            aliases=[Commands.Subcommands.Lost.SHORT],
            description='Removes an unrecoverable node from the linstor cluster. '
            'All linstor resources attached to this node will be deleted from the database.'
        )
        p_lost_node.add_argument(
            '--async',
            action='store_true',
            help='Deprecated, kept for compatibility'
        )
        p_lost_node.add_argument(
            'name',
            help='Name of the node to delete.').completer = self.node_completer
        p_lost_node.set_defaults(func=self.lost)

        # reconnect node(s)
        p_recon_node = node_subp.add_parser(
            NodeCommands.Reconnect.LONG,
            aliases=[NodeCommands.Reconnect.SHORT],
            description='Reconnect a node reinitializing the nodes state.'
        )
        p_recon_node.add_argument(
            'nodes',
            nargs="+",
            help='List of nodes to reconnect.'
        ).completer = self.node_completer
        p_recon_node.set_defaults(func=self.reconnect)

        # Interface commands
        netif_subcmds = [
            Commands.Subcommands.Create,
            Commands.Subcommands.List,
            Commands.Subcommands.Modify,
            Commands.Subcommands.Delete
        ]

        interface_parser = node_subp.add_parser(
            Commands.Subcommands.Interface.LONG,
            formatter_class=argparse.RawTextHelpFormatter,
            aliases=[Commands.Subcommands.Interface.SHORT],
            description="%s subcommands" % Commands.Subcommands.Interface.LONG)

        interface_subp = interface_parser.add_subparsers(
            title="%s subcommands" % Commands.Subcommands.Interface.LONG,
            metavar="",
            description=Commands.Subcommands.generate_desc(netif_subcmds))

        # create net interface
        p_create_netinterface = interface_subp.add_parser(
            Commands.Subcommands.Create.LONG,
            aliases=[Commands.Subcommands.Create.SHORT],
            description='Creates and adds a new netinterface to a given node.'
                        ' If port is specified this net interface is used as satellite port'
        )
        p_create_netinterface.add_argument(
            '-p', '--port',
            type=rangecheck(1, 65535),
            help='Port to use for satellite connections'
        )
        p_create_netinterface.add_argument(
            '--communication-type',
            choices=(apiconsts.VAL_NETCOM_TYPE_PLAIN.lower(), apiconsts.VAL_NETCOM_TYPE_SSL.lower()),
            type=str.lower,
            default=ctype_def,
            help='Communication type (default: %s)' % ctype_def.lower()
        )
        p_create_netinterface.add_argument(
            '--active',
            action='store_true',
            help='Create this net interface as the active satellite connection'
        )
        p_create_netinterface.add_argument(
            "node_name",
            help="Name of the node to add the net interface"
        ).completer = self.node_completer
        p_create_netinterface.add_argument("interface_name", help="Interface name")
        p_create_netinterface.add_argument('ip', help='New IP address for the network interface')
        p_create_netinterface.set_defaults(func=self.create_netif)

        # modify net interface
        p_mod_netif = interface_subp.add_parser(
            Commands.Subcommands.Modify.LONG,
            aliases=[Commands.Subcommands.Modify.SHORT],
            description='Change the ip listen address of a netinterface on the given node.'
        )
        p_mod_netif.add_argument(
            '-p', '--port', type=rangecheck(1, 65535),
            help='Port to use for satellite connections'
        )
        p_mod_netif.add_argument(
            '--communication-type',
            choices=(apiconsts.VAL_NETCOM_TYPE_PLAIN.lower(), apiconsts.VAL_NETCOM_TYPE_SSL.lower()),
            type=str.lower,
            default=ctype_def,
            help='Communication type (default: %s)' % ctype_def.lower()
        )
        p_mod_netif.add_argument(
            '--active',
            action='store_true',
            help='Set this net interface as the active satellite connection'
        )
        p_mod_netif.add_argument('--ip', help='New IP address for the network interface')
        p_mod_netif.add_argument("node_name", help="Name of the node").completer = self.node_completer
        p_mod_netif.add_argument("interface_name", help="Interface to change").completer = self.netif_completer
        p_mod_netif.set_defaults(func=self.modify_netif)

        # delete net interface
        p_delete_netinterface = interface_subp.add_parser(
            Commands.Subcommands.Delete.LONG,
            aliases=[Commands.Subcommands.Delete.SHORT],
            description='Delete a netinterface from a node.'
        )
        p_delete_netinterface.add_argument(
            "node_name",
            help="Name of the node to remove the net interface"
        ).completer = self.node_completer
        p_delete_netinterface.add_argument(
            "interface_name",
            nargs='+',
            help="Interface name"
        ).completer = self.netif_completer
        p_delete_netinterface.set_defaults(func=self.delete_netif)

        # list nodes
        node_groupby = [x.name.lower() for x in self._node_headers]
        node_group_completer = Commands.show_group_completer(node_groupby, "groupby")

        p_lnodes = node_subp.add_parser(
            Commands.Subcommands.List.LONG,
            aliases=[Commands.Subcommands.List.SHORT],
            description='Prints a list of all cluster nodes known to linstor. '
            'By default, the list is printed as a human readable table.')
        p_lnodes.add_argument('-p', '--pastable', action="store_true", help='Generate pastable output')
        p_lnodes.add_argument('-g', '--groupby', nargs='+', type=str.lower,
                              choices=node_groupby).completer = node_group_completer
        p_lnodes.add_argument('-n', '--nodes', nargs='+', type=str,
                              help='Filter by list of nodes').completer = self.node_completer
        p_lnodes.add_argument('--show-aux-props', action="store_true", help='Show aux properties for nodes')
        p_lnodes.add_argument('--props', nargs='+', type=str, help='Filter list by object properties')
        p_lnodes.set_defaults(func=self.list)

        # list info
        p_info_node = node_subp.add_parser(
            Commands.Subcommands.Info.LONG,
            aliases=[Commands.Subcommands.Info.SHORT],
            description='Prints detailed info for all cluster nodes known to linstor. '
                        'By default, the list is printed as a human readable table.'
        )
        p_info_node.add_argument('-p', '--pastable', action="store_true", help='Generate pastable output')
        p_info_node.add_argument(
            '-n', '--nodes', nargs='+', type=str, help='Filter by list of nodes'
        ).completer = self.node_completer
        p_info_node.set_defaults(func=self.info)

        # list netinterface
        p_lnetif = interface_subp.add_parser(
            Commands.Subcommands.List.LONG,
            aliases=[Commands.Subcommands.List.SHORT],
            description='Prints a list of netinterfaces of a node.'
        )
        p_lnetif.add_argument('-p', '--pastable', action="store_true", help='Generate pastable output')
        p_lnetif.add_argument(
            'node_name',
            help='Node name for which to print the net interfaces'
        ).completer = self.node_completer
        p_lnetif.set_defaults(func=self.list_netinterfaces)

        # show properties
        p_sp = node_subp.add_parser(
            Commands.Subcommands.ListProperties.LONG,
            aliases=[Commands.Subcommands.ListProperties.SHORT],
            description="Prints all properties of the given node.")
        p_sp.add_argument('-p', '--pastable', action="store_true", help='Generate pastable output')
        p_sp.add_argument(
            'node_name',
            help="Node for which to print the properties").completer = self.node_completer
        p_sp.set_defaults(func=self.print_props)

        # set properties
        p_setp = node_subp.add_parser(
            Commands.Subcommands.SetProperty.LONG,
            aliases=[Commands.Subcommands.SetProperty.SHORT],
            formatter_class=argparse.RawTextHelpFormatter,
            description="Set a property on the given node."
        )
        p_setp.add_argument(
            'node_name',
            help="Node for which to set the property"
        ).completer = self.node_completer
        Commands.add_parser_keyvalue(p_setp, "node")
        p_setp.set_defaults(func=self.set_props)

        # restore evicted node
        p_restore_node = node_subp.add_parser(
            Commands.Subcommands.Restore.LONG,
            aliases=[Commands.Subcommands.Restore.SHORT],
            formatter_class=argparse.RawTextHelpFormatter,
            description="Restore an evicted node."
        )
        p_restore_node.add_argument(
            'node_name',
            help="Evicted node to restore"
        ).completer = self.node_completer
        p_restore_node.set_defaults(func=self.restore_node)

        self.check_subcommands(interface_subp, netif_subcmds)
        self.check_subcommands(node_subp, subcmds)
Example #4
0
    def setup_commands(self, parser):
        # Node subcommands
        subcmds = [
            Commands.Subcommands.Create, Commands.Subcommands.List,
            Commands.Subcommands.Delete, Commands.Subcommands.Lost,
            Commands.Subcommands.Describe, Commands.Subcommands.Interface,
            Commands.Subcommands.SetProperty,
            Commands.Subcommands.ListProperties
        ]

        node_parser = parser.add_parser(
            Commands.NODE,
            aliases=["n"],
            formatter_class=argparse.RawTextHelpFormatter,
            description="Node subcommands")

        node_subp = node_parser.add_subparsers(
            title="Node commands",
            metavar="",
            description=Commands.Subcommands.generate_desc(subcmds))

        # create node
        p_new_node = node_subp.add_parser(
            Commands.Subcommands.Create.LONG,
            aliases=[Commands.Subcommands.Create.SHORT],
            description=
            'Creates a node entry for a node that participates in the '
            'linstor cluster.')
        p_new_node.add_argument(
            '-p',
            '--port',
            type=rangecheck(1, 65535),
            help='default: Satellite %s for %s; Controller %s for %s; %s for %s'
            %
            (DFLT_STLT_PORT_PLAIN, VAL_NETCOM_TYPE_PLAIN, DFLT_CTRL_PORT_PLAIN,
             VAL_NETCOM_TYPE_PLAIN, DFLT_CTRL_PORT_SSL, VAL_NETCOM_TYPE_SSL))
        ntype_def = VAL_NODE_TYPE_STLT
        p_new_node.add_argument('--node-type',
                                choices=(VAL_NODE_TYPE_CTRL, VAL_NODE_TYPE_AUX,
                                         VAL_NODE_TYPE_CMBD,
                                         VAL_NODE_TYPE_STLT),
                                default=VAL_NODE_TYPE_STLT,
                                help='Node type (default: %s)' % ntype_def)
        ctype_def = VAL_NETCOM_TYPE_PLAIN
        p_new_node.add_argument(
            '--communication-type',
            choices=(VAL_NETCOM_TYPE_PLAIN, VAL_NETCOM_TYPE_SSL),
            default=ctype_def,
            help='Communication type (default: %s)' % ctype_def)
        itype_def = VAL_NETIF_TYPE_IP
        p_new_node.add_argument('--interface-type',
                                choices=(VAL_NETIF_TYPE_IP, ),
                                default=itype_def,
                                help='Interface type (default: %s)' %
                                itype_def)
        iname_def = 'default'
        p_new_node.add_argument('--interface-name',
                                default=iname_def,
                                help='Interface name (default: %s)' %
                                iname_def)
        p_new_node.add_argument(
            'name',
            help='Name of the new node, must match the nodes hostname',
            type=namecheck(NODE_NAME))
        p_new_node.add_argument(
            'ip',
            help='IP address of the new node').completer = ip_completer("name")
        p_new_node.set_defaults(func=self.create)

        #describe-node
        p_desc_node = node_subp.add_parser(
            Commands.Subcommands.Describe.LONG,
            aliases=[Commands.Subcommands.Describe.SHORT],
            description=
            'describe a node (or all nodes), list storage pools, resources and volumes under this node, '
            'in this order')
        p_desc_node.add_argument(
            'name',
            nargs='?',
            help=
            'Name of the node to be described. With no name, all nodes are described'
        ).completer = self.node_completer
        p_desc_node.set_defaults(func=self.describe)

        # remove-node
        p_rm_node = node_subp.add_parser(
            Commands.Subcommands.Delete.LONG,
            aliases=[Commands.Subcommands.Delete.SHORT],
            description='Removes a node from the linstor cluster. '
            'All linstor resources that are still deployed on the specified '
            'node are marked for undeployment, and the node entry is marked for '
            "removal from linstor's data tables. The specified node is "
            'expected to undeploy all resources. As soon as all resources have been '
            'undeployed from the node, the node entry is removed from '
            "linstor's data tables.")
        p_rm_node.add_argument(
            '-q',
            '--quiet',
            action="store_true",
            help=
            'Unless this option is used, linstor will issue a safety question '
            'that must be answered with yes, otherwise the operation is canceled.'
        )
        p_rm_node.add_argument(
            'name',
            help='Name of the node to remove').completer = self.node_completer
        p_rm_node.set_defaults(func=self.delete)

        # lost-node
        p_lost_node = node_subp.add_parser(
            Commands.Subcommands.Lost.LONG,
            aliases=[Commands.Subcommands.Lost.SHORT],
            description=
            'Removes an unrecoverable node from the linstor cluster. '
            'All linstor resources attached to this node will be deleted from the database.'
        )
        p_lost_node.add_argument(
            'name',
            help='Name of the node to delete.').completer = self.node_completer
        p_lost_node.set_defaults(func=self.lost)

        # Interface commands
        netif_subcmds = [
            Commands.Subcommands.Create, Commands.Subcommands.List,
            Commands.Subcommands.Modify, Commands.Subcommands.Delete
        ]

        interface_parser = node_subp.add_parser(
            Commands.Subcommands.Interface.LONG,
            formatter_class=argparse.RawTextHelpFormatter,
            aliases=[Commands.Subcommands.Interface.SHORT],
            description="%s subcommands" % Commands.Subcommands.Interface.LONG)

        interface_subp = interface_parser.add_subparsers(
            title="%s subcommands" % Commands.Subcommands.Interface.LONG,
            metavar="",
            description=Commands.Subcommands.generate_desc(netif_subcmds))

        # create net interface
        p_create_netinterface = interface_subp.add_parser(
            Commands.Subcommands.Create.LONG,
            aliases=[Commands.Subcommands.Create.SHORT],
            description=
            'Creates and adds a new netinterface to a given node. If port is specified this netinterface '
            'is used as satellite port')
        p_create_netinterface.add_argument(
            '-p',
            '--port',
            type=rangecheck(1, 65535),
            help='Port to use for satellite connections')
        p_create_netinterface.add_argument(
            '--communication-type',
            choices=(VAL_NETCOM_TYPE_PLAIN, VAL_NETCOM_TYPE_SSL),
            default=ctype_def,
            help='Communication type (default: %s)' % ctype_def)
        p_create_netinterface.add_argument(
            "node_name", help="Name of the node to add the net interface"
        ).completer = self.node_completer
        p_create_netinterface.add_argument("interface_name",
                                           help="Interface name")
        p_create_netinterface.add_argument(
            'ip', help='New IP address for the network interface')
        p_create_netinterface.set_defaults(func=self.create_netif)

        # modify net interface
        p_mod_netif = interface_subp.add_parser(
            Commands.Subcommands.Modify.LONG,
            aliases=[Commands.Subcommands.Modify.SHORT],
            description=
            'Change the ip listen address of a netinterface on the given node.'
        )
        p_mod_netif.add_argument('-p',
                                 '--port',
                                 type=rangecheck(1, 65535),
                                 help='Port to use for satellite connections')
        p_mod_netif.add_argument(
            '--communication-type',
            choices=(VAL_NETCOM_TYPE_PLAIN, VAL_NETCOM_TYPE_SSL),
            default=ctype_def,
            help='Communication type (default: %s)' % ctype_def)
        p_mod_netif.add_argument(
            "node_name",
            help="Name of the node").completer = self.node_completer
        p_mod_netif.add_argument(
            "interface_name",
            help="Interface name to change").completer = self.netif_completer
        p_mod_netif.add_argument(
            'ip', help='New IP address for the network interface')
        p_mod_netif.set_defaults(func=self.modify_netif)

        # delete net interface
        p_delete_netinterface = interface_subp.add_parser(
            Commands.Subcommands.Delete.LONG,
            aliases=[Commands.Subcommands.Delete.SHORT],
            description='Delete a netinterface from a node.')
        p_delete_netinterface.add_argument(
            "node_name", help="Name of the node to remove the net interface"
        ).completer = self.node_completer
        p_delete_netinterface.add_argument(
            "interface_name", nargs='+',
            help="Interface name").completer = self.netif_completer
        p_delete_netinterface.set_defaults(func=self.delete_netif)

        # list nodes
        node_groupby = [x.name for x in self._node_headers]
        node_group_completer = Commands.show_group_completer(
            node_groupby, "groupby")

        p_lnodes = node_subp.add_parser(
            Commands.Subcommands.List.LONG,
            aliases=[Commands.Subcommands.List.SHORT],
            description='Prints a list of all cluster nodes known to linstor. '
            'By default, the list is printed as a human readable table.')
        p_lnodes.add_argument('-p',
                              '--pastable',
                              action="store_true",
                              help='Generate pastable output')
        p_lnodes.add_argument(
            '-g', '--groupby', nargs='+',
            choices=node_groupby).completer = node_group_completer
        p_lnodes.add_argument(
            '-N',
            '--nodes',
            nargs='+',
            type=namecheck(NODE_NAME),
            help='Filter by list of nodes').completer = self.node_completer
        p_lnodes.set_defaults(func=self.list)

        # list netinterface
        p_lnetif = interface_subp.add_parser(
            Commands.Subcommands.List.LONG,
            aliases=[Commands.Subcommands.List.SHORT],
            description='Prints a list of netinterfaces from a node.')
        p_lnetif.add_argument('-p',
                              '--pastable',
                              action="store_true",
                              help='Generate pastable output')
        p_lnetif.add_argument(
            'node_name',
            help='Node name for which to print the net interfaces'
        ).completer = self.node_completer
        p_lnetif.set_defaults(func=self.list_netinterfaces)

        # show properties
        p_sp = node_subp.add_parser(
            Commands.Subcommands.ListProperties.LONG,
            aliases=[Commands.Subcommands.ListProperties.SHORT],
            description="Prints all properties of the given node.")
        p_sp.add_argument('-p',
                          '--pastable',
                          action="store_true",
                          help='Generate pastable output')
        p_sp.add_argument('node_name',
                          help="Node for which to print the properties"
                          ).completer = self.node_completer
        p_sp.set_defaults(func=self.print_props)

        # set properties
        p_setp = node_subp.add_parser(
            Commands.Subcommands.SetProperty.LONG,
            aliases=[Commands.Subcommands.SetProperty.SHORT],
            description="Set a property on the given node.")
        p_setp.add_argument('node_name',
                            help="Node for which to set the property"
                            ).completer = self.node_completer
        Commands.add_parser_keyvalue(p_setp, "node")
        p_setp.set_defaults(func=self.set_props)

        self.check_subcommands(interface_subp, netif_subcmds)
        self.check_subcommands(node_subp, subcmds)
Example #5
0
    def setup_commands(self, parser):
        subcmds = [
            Commands.Subcommands.Create,
            Commands.Subcommands.List,
            Commands.Subcommands.Delete,
            Commands.Subcommands.SetProperty,
            Commands.Subcommands.ListProperties,
            Commands.Subcommands.DrbdOptions
        ]

        # Resource subcommands
        res_def_parser = parser.add_parser(
            Commands.RESOURCE_DEF,
            aliases=["rd"],
            formatter_class=argparse.RawTextHelpFormatter,
            description="Resource definition subcommands")

        res_def_subp = res_def_parser.add_subparsers(
            title="resource definition subcommands",
            metavar="",
            description=Commands.Subcommands.generate_desc(subcmds)
        )

        p_new_res_dfn = res_def_subp.add_parser(
            Commands.Subcommands.Create.LONG,
            aliases=[Commands.Subcommands.Create.SHORT],
            description='Defines a Linstor resource definition for use with linstor.')
        p_new_res_dfn.add_argument('-p', '--port', type=rangecheck(1, 65535))
        # p_new_res_dfn.add_argument('-s', '--secret', type=str)
        p_new_res_dfn.add_argument('name', type=namecheck(RES_NAME), help='Name of the new resource definition')
        p_new_res_dfn.set_defaults(func=self.create)

        # remove-resource definition
        # TODO description
        p_rm_res_dfn = res_def_subp.add_parser(
            Commands.Subcommands.Delete.LONG,
            aliases=[Commands.Subcommands.Delete.SHORT],
            description=" Removes a resource definition "
            "from the linstor cluster. The resource is undeployed from all nodes "
            "and the resource entry is marked for removal from linstor's data "
            "tables. After all nodes have undeployed the resource, the resource "
            "entry is removed from linstor's data tables.")
        p_rm_res_dfn.add_argument('-q', '--quiet', action="store_true",
                                  help='Unless this option is used, linstor will issue a safety question '
                                  'that must be answered with yes, otherwise the operation is canceled.')
        p_rm_res_dfn.add_argument(
            'name',
            nargs="+",
            help='Name of the resource to delete').completer = self.resource_dfn_completer
        p_rm_res_dfn.set_defaults(func=self.delete)

        rsc_dfn_groupby = [x.name for x in self._rsc_dfn_headers]
        rsc_dfn_group_completer = Commands.show_group_completer(rsc_dfn_groupby, "groupby")

        p_lrscdfs = res_def_subp.add_parser(
            Commands.Subcommands.List.LONG,
            aliases=[Commands.Subcommands.List.SHORT],
            description='Prints a list of all resource definitions known to '
            'linstor. By default, the list is printed as a human readable table.')
        p_lrscdfs.add_argument('-p', '--pastable', action="store_true", help='Generate pastable output')
        p_lrscdfs.add_argument('-g', '--groupby', nargs='+',
                               choices=rsc_dfn_groupby).completer = rsc_dfn_group_completer
        p_lrscdfs.add_argument('-R', '--resources', nargs='+', type=namecheck(RES_NAME),
                               help='Filter by list of resources').completer = self.resource_dfn_completer
        p_lrscdfs.set_defaults(func=self.list)

        # show properties
        p_sp = res_def_subp.add_parser(
            Commands.Subcommands.ListProperties.LONG,
            aliases=[Commands.Subcommands.ListProperties.SHORT],
            description="Prints all properties of the given resource definitions.")
        p_sp.add_argument('-p', '--pastable', action="store_true", help='Generate pastable output')
        p_sp.add_argument(
            'resource_name',
            help="Resource definition for which to print the properties"
        ).completer = self.resource_dfn_completer
        p_sp.set_defaults(func=self.print_props)

        # set properties
        p_setprop = res_def_subp.add_parser(
            Commands.Subcommands.SetProperty.LONG,
            aliases=[Commands.Subcommands.SetProperty.SHORT],
            description='Sets properties for the given resource definition.')
        p_setprop.add_argument('name', type=namecheck(RES_NAME), help='Name of the resource definition')
        Commands.add_parser_keyvalue(p_setprop, 'resource-definition')
        p_setprop.set_defaults(func=self.set_props)

        # drbd options
        p_drbd_opts = res_def_subp.add_parser(
            Commands.Subcommands.DrbdOptions.LONG,
            aliases=[Commands.Subcommands.DrbdOptions.SHORT],
            description="Set drbd resource options."
        )
        p_drbd_opts.add_argument(
            'resource_name',
            type=namecheck(RES_NAME),
            help="Resource name"
        ).completer = self.resource_dfn_completer
        DrbdOptions.add_arguments(
            p_drbd_opts,
            [x for x in DrbdOptions.drbd_options()['options'] if x in DrbdOptions.drbd_options()['filters']['resource']]
        )
        p_drbd_opts.set_defaults(func=self.set_drbd_opts)

        self.check_subcommands(res_def_subp, subcmds)
Example #6
0
    def setup_commands(self, parser):
        subcmds = [
            Commands.Subcommands.Create, Commands.Subcommands.Modify,
            Commands.Subcommands.List, Commands.Subcommands.Delete,
            Commands.Subcommands.SetProperty,
            Commands.Subcommands.ListProperties,
            Commands.Subcommands.DrbdOptions
        ]

        # Resource definition subcommands
        res_def_parser = parser.add_parser(
            Commands.RESOURCE_DEF,
            aliases=["rd"],
            formatter_class=argparse.RawTextHelpFormatter,
            description="Resource definition subcommands")

        res_def_subp = res_def_parser.add_subparsers(
            title="resource definition subcommands",
            metavar="",
            description=Commands.Subcommands.generate_desc(subcmds))

        p_new_res_dfn = res_def_subp.add_parser(
            Commands.Subcommands.Create.LONG,
            aliases=[Commands.Subcommands.Create.SHORT],
            description=
            'Defines a Linstor resource definition for use with linstor.')
        p_new_res_dfn.add_argument('-p', '--port', type=rangecheck(1, 65535))
        p_new_res_dfn.add_argument('-e',
                                   '--external-name',
                                   type=str,
                                   help='User specified name.')
        # p_new_res_dfn.add_argument('-s', '--secret', type=str)
        p_new_res_dfn.add_argument(
            '-l',
            '--layer-list',
            type=self.layer_data_check,
            help="Comma separated layer list, order is from right to left. "
            "This means the top most layer is on the left. "
            "Possible layers are: " + ",".join(linstor.Linstor.layer_list()))
        p_new_res_dfn.add_argument('--peer-slots',
                                   type=rangecheck(1, 31),
                                   help='(DRBD) peer slots for new resources')
        p_new_res_dfn.add_argument(
            '--resource-group',
            help="Attach the resource definition to this resource group"
        ).completer = self.resource_grp_completer
        p_new_res_dfn.add_argument(
            'name',
            nargs="?",
            type=str,
            help=
            'Name of the new resource definition. Will be ignored if EXTERNAL_NAME is set.'
        )
        p_new_res_dfn.set_defaults(func=self.create)

        # modify-resource definition
        p_mod_res_dfn = res_def_subp.add_parser(
            Commands.Subcommands.Modify.LONG,
            aliases=[Commands.Subcommands.Modify.SHORT],
            description='Modifies a Linstor resource definition')
        p_mod_res_dfn.add_argument('--peer-slots',
                                   type=rangecheck(1, 31),
                                   help='(DRBD) peer slots for new resources')
        p_mod_res_dfn.add_argument('name',
                                   help='Name of the resource definition'
                                   ).completer = self.resource_dfn_completer
        p_mod_res_dfn.set_defaults(func=self.modify)

        # remove-resource definition
        # TODO description
        p_rm_res_dfn = res_def_subp.add_parser(
            Commands.Subcommands.Delete.LONG,
            aliases=[Commands.Subcommands.Delete.SHORT],
            description=" Removes a resource definition "
            "from the linstor cluster. The resource is undeployed from all nodes "
            "and the resource entry is marked for removal from linstor's data "
            "tables. After all nodes have undeployed the resource, the resource "
            "entry is removed from linstor's data tables.")
        p_rm_res_dfn.add_argument(
            '--async',
            action='store_true',
            help=
            'Do not wait for actual deletion on satellites before returning')
        p_rm_res_dfn.add_argument('name',
                                  nargs="+",
                                  help='Name of the resource to delete'
                                  ).completer = self.resource_dfn_completer
        p_rm_res_dfn.set_defaults(func=self.delete)

        rsc_dfn_groupby = [x.name for x in self._rsc_dfn_headers]
        rsc_dfn_group_completer = Commands.show_group_completer(
            rsc_dfn_groupby, "groupby")

        p_lrscdfs = res_def_subp.add_parser(
            Commands.Subcommands.List.LONG,
            aliases=[Commands.Subcommands.List.SHORT],
            description='Prints a list of all resource definitions known to '
            'linstor. By default, the list is printed as a human readable table.'
        )
        p_lrscdfs.add_argument('-p',
                               '--pastable',
                               action="store_true",
                               help='Generate pastable output')
        p_lrscdfs.add_argument(
            '-g', '--groupby', nargs='+',
            choices=rsc_dfn_groupby).completer = rsc_dfn_group_completer
        p_lrscdfs.add_argument('-r',
                               '--resource-definitions',
                               nargs='+',
                               type=str,
                               help='Filter by list of resource definitions'
                               ).completer = self.resource_dfn_completer
        p_lrscdfs.add_argument('-e',
                               '--external-name',
                               action="store_true",
                               help='Show user specified name.')
        p_lrscdfs.set_defaults(func=self.list)

        # show properties
        p_sp = res_def_subp.add_parser(
            Commands.Subcommands.ListProperties.LONG,
            aliases=[Commands.Subcommands.ListProperties.SHORT],
            description=
            "Prints all properties of the given resource definitions.")
        p_sp.add_argument('-p',
                          '--pastable',
                          action="store_true",
                          help='Generate pastable output')
        p_sp.add_argument(
            'resource_name',
            help="Resource definition for which to print the properties"
        ).completer = self.resource_dfn_completer
        p_sp.set_defaults(func=self.print_props)

        # set properties
        p_setprop = res_def_subp.add_parser(
            Commands.Subcommands.SetProperty.LONG,
            aliases=[Commands.Subcommands.SetProperty.SHORT],
            formatter_class=argparse.RawTextHelpFormatter,
            description='Sets properties for the given resource definition.')
        p_setprop.add_argument('name',
                               type=str,
                               help='Name of the resource definition')
        Commands.add_parser_keyvalue(p_setprop, 'resource-definition')
        p_setprop.set_defaults(func=self.set_props)

        # drbd options
        p_drbd_opts = res_def_subp.add_parser(
            Commands.Subcommands.DrbdOptions.LONG,
            aliases=[Commands.Subcommands.DrbdOptions.SHORT],
            description=DrbdOptions.description("resource"))
        p_drbd_opts.add_argument(
            'resource_name', type=str,
            help="Resource name").completer = self.resource_dfn_completer
        DrbdOptions.add_arguments(p_drbd_opts, self.OBJECT_NAME)
        p_drbd_opts.set_defaults(func=self.set_drbd_opts)

        self.check_subcommands(res_def_subp, subcmds)
Example #7
0
    def setup_commands(self, parser):
        subcmds = [
            Commands.Subcommands.Create,
            Commands.Subcommands.AutoPlace,
            Commands.Subcommands.Modify,
            Commands.Subcommands.List,
            Commands.Subcommands.Delete,
            Commands.Subcommands.SetProperty,
            Commands.Subcommands.ListProperties,
            Commands.Subcommands.DrbdOptions,
            Commands.Subcommands.Clone,
            Commands.Subcommands.WaitSync,
        ]

        # Resource definition subcommands
        res_def_parser = parser.add_parser(
            Commands.RESOURCE_DEF,
            aliases=["rd"],
            formatter_class=argparse.RawTextHelpFormatter,
            description="Resource definition subcommands")

        res_def_subp = res_def_parser.add_subparsers(
            title="resource definition subcommands",
            metavar="",
            description=Commands.Subcommands.generate_desc(subcmds))

        p_new_res_dfn = res_def_subp.add_parser(
            Commands.Subcommands.Create.LONG,
            aliases=[Commands.Subcommands.Create.SHORT],
            description=
            'Defines a Linstor resource definition for use with linstor.')
        p_new_res_dfn.add_argument('-p', '--port', type=rangecheck(1, 65535))
        p_new_res_dfn.add_argument('-e',
                                   '--external-name',
                                   type=str,
                                   help='User specified name.')
        # p_new_res_dfn.add_argument('-s', '--secret', type=str)
        p_new_res_dfn.add_argument(
            '-l',
            '--layer-list',
            type=self.layer_data_check,
            help="Comma separated layer list, order is from right to left. "
            "This means the top most layer is on the left. "
            "Possible layers are: " + ",".join(linstor.Linstor.layer_list()))
        p_new_res_dfn.add_argument('--peer-slots',
                                   type=rangecheck(1, 31),
                                   help='(DRBD) peer slots for new resources')
        p_new_res_dfn.add_argument(
            '--resource-group',
            help="Attach the resource definition to this resource group"
        ).completer = self.resource_grp_completer
        p_new_res_dfn.add_argument(
            'name',
            nargs="?",
            type=str,
            help=
            'Name of the new resource definition. Will be ignored if EXTERNAL_NAME is set.'
        )
        p_new_res_dfn.set_defaults(func=self.create)

        p_auto_place = res_def_subp.add_parser(
            Commands.Subcommands.AutoPlace.LONG,
            aliases=[Commands.Subcommands.AutoPlace.SHORT],
            description='Auto place a resource definition')
        self.add_auto_select_argparse_arguments(p_auto_place,
                                                use_place_count=True)
        p_auto_place.add_argument(
            'resource_definition_name',
            help='Name of the resource definition to auto place')
        p_auto_place.add_argument('--nvme-initiator',
                                  action="store_true",
                                  help='Mark this resource as initiator')
        p_auto_place.add_argument('--drbd-diskless',
                                  action="store_true",
                                  help='Mark this resource as drbd diskless')
        p_auto_place.set_defaults(func=self.auto_place)

        # modify-resource definition
        p_mod_res_dfn = res_def_subp.add_parser(
            Commands.Subcommands.Modify.LONG,
            aliases=[Commands.Subcommands.Modify.SHORT],
            description='Modifies a Linstor resource definition')
        p_mod_res_dfn.add_argument('--peer-slots',
                                   type=rangecheck(1, 31),
                                   help='(DRBD) peer slots for new resources')
        p_mod_res_dfn.add_argument(
            '--resource-group', help='Change resource group to the given one.'
        ).completer = self.resource_grp_completer
        p_mod_res_dfn.add_argument('name',
                                   help='Name of the resource definition'
                                   ).completer = self.resource_dfn_completer
        p_mod_res_dfn.set_defaults(func=self.modify)

        # remove-resource definition
        p_rm_res_dfn = res_def_subp.add_parser(
            Commands.Subcommands.Delete.LONG,
            aliases=[Commands.Subcommands.Delete.SHORT],
            description=" Removes a resource definition "
            "from the linstor cluster. The resource is undeployed from all nodes "
            "and the resource entry is marked for removal from linstor's data "
            "tables. After all nodes have undeployed the resource, the resource "
            "entry is removed from linstor's data tables.")
        p_rm_res_dfn.add_argument('--async',
                                  action='store_true',
                                  help='Deprecated, kept for compatibility')
        p_rm_res_dfn.add_argument('name',
                                  nargs="+",
                                  help='Name of the resource to delete'
                                  ).completer = self.resource_dfn_completer
        p_rm_res_dfn.set_defaults(func=self.delete)

        rsc_dfn_groupby = [x.name.lower() for x in self._rsc_dfn_headers]
        rsc_dfn_group_completer = Commands.show_group_completer(
            rsc_dfn_groupby, "groupby")

        p_clone_rscdfn = res_def_subp.add_parser(
            Commands.Subcommands.Clone.LONG,
            aliases=[Commands.Subcommands.Clone.SHORT],
            description=
            "Clones a resource definition with all resources and volumes(including data)."
        )
        p_clone_rscdfn.add_argument('-e',
                                    '--external-name',
                                    type=str,
                                    help='User specified name.')
        p_clone_rscdfn.add_argument('--no-wait',
                                    action="store_true",
                                    help="Wait till cloning is done.")
        p_clone_rscdfn.add_argument(
            '--wait-timeout',
            type=int,
            help="Wait this seconds for the clone to finish.")
        p_clone_rscdfn.add_argument(
            '--use-zfs-clone',
            action="store_true",
            default=None,
            help=
            "Use ZFS clone instead send/recv, but have a dependent snapshot")
        p_clone_rscdfn.add_argument('source_resource',
                                    help="Source resource definition name"
                                    ).completer = self.resource_dfn_completer
        p_clone_rscdfn.add_argument(
            'clone_name',
            nargs="?",
            type=str,
            help='Name of the new resource definition. '
            'Will be ignored if EXTERNAL_NAME is set.')
        p_clone_rscdfn.set_defaults(func=self.clone)

        p_wait_sync = res_def_subp.add_parser(
            Commands.Subcommands.WaitSync.LONG,
            aliases=[Commands.Subcommands.WaitSync.SHORT],
            description=
            "Wait till the given resource is synced or e.g. ready to be resized."
        )
        p_wait_sync.add_argument(
            '--wait-timeout',
            type=int,
            help="Wait this seconds for the clone to finish.")
        p_wait_sync.add_argument("resource_name",
                                 help="Resource name to be checked."
                                 ).completer = self.resource_dfn_completer
        p_wait_sync.set_defaults(func=self.wait_sync)

        p_lrscdfs = res_def_subp.add_parser(
            Commands.Subcommands.List.LONG,
            aliases=[Commands.Subcommands.List.SHORT],
            description='Prints a list of all resource definitions known to '
            'linstor. By default, the list is printed as a human readable table.'
        )
        p_lrscdfs.add_argument('-p',
                               '--pastable',
                               action="store_true",
                               help='Generate pastable output')
        p_lrscdfs.add_argument(
            '-g',
            '--groupby',
            nargs='+',
            choices=rsc_dfn_groupby,
            type=str.lower).completer = rsc_dfn_group_completer
        p_lrscdfs.add_argument('-r',
                               '--resource-definitions',
                               nargs='+',
                               type=str,
                               help='Filter by list of resource definitions'
                               ).completer = self.resource_dfn_completer
        p_lrscdfs.add_argument('-e',
                               '--external-name',
                               action="store_true",
                               help='Show user specified name.')
        p_lrscdfs.add_argument('--props',
                               nargs='+',
                               type=str,
                               help='Filter list by object properties')
        p_lrscdfs.set_defaults(func=self.list)

        # show properties
        p_sp = res_def_subp.add_parser(
            Commands.Subcommands.ListProperties.LONG,
            aliases=[Commands.Subcommands.ListProperties.SHORT],
            description=
            "Prints all properties of the given resource definitions.")
        p_sp.add_argument('-p',
                          '--pastable',
                          action="store_true",
                          help='Generate pastable output')
        p_sp.add_argument(
            'resource_name',
            help="Resource definition for which to print the properties"
        ).completer = self.resource_dfn_completer
        p_sp.set_defaults(func=self.print_props)

        # set properties
        p_setprop = res_def_subp.add_parser(
            Commands.Subcommands.SetProperty.LONG,
            aliases=[Commands.Subcommands.SetProperty.SHORT],
            formatter_class=argparse.RawTextHelpFormatter,
            description='Sets properties for the given resource definition.')
        p_setprop.add_argument('name',
                               type=str,
                               help='Name of the resource definition')
        Commands.add_parser_keyvalue(p_setprop, 'resource-definition')
        p_setprop.set_defaults(func=self.set_props)

        # drbd options
        p_drbd_opts = res_def_subp.add_parser(
            Commands.Subcommands.DrbdOptions.LONG,
            aliases=[Commands.Subcommands.DrbdOptions.SHORT],
            description=DrbdOptions.description("resource"))
        p_drbd_opts.add_argument(
            'resource_name', type=str,
            help="Resource name").completer = self.resource_dfn_completer
        DrbdOptions.add_arguments(p_drbd_opts, self.OBJECT_NAME)
        p_drbd_opts.set_defaults(func=self.set_drbd_opts)

        self.check_subcommands(res_def_subp, subcmds)