diff --git a/scripts/rpc.py b/scripts/rpc.py index a7c6869b7..daeef0e55 100755 --- a/scripts/rpc.py +++ b/scripts/rpc.py @@ -387,7 +387,24 @@ if __name__ == "__main__": # iSCSI def set_iscsi_options(args): - rpc.iscsi.set_iscsi_options(args.client, args) + rpc.iscsi.set_iscsi_options( + args.client, + auth_file=args.auth_file, + node_base=args.node_base, + nop_timeout=args.nop_timeout, + nop_in_interval=args.nop_in_interval, + no_discovery_auth=args.no_discovery_auth, + req_discovery_auth=args.req_discovery_auth, + req_discovery_auth_mutual=args.req_discovery_auth_mutual, + discovery_auth_group=args.discovery_auth_group, + max_sessions=args.max_sessions, + max_connections_per_session=args.max_connections_per_session, + default_time2wait=args.default_time2wait, + default_time2retain=args.default_time2retain, + immediate_data=args.immediate_data, + error_recovery_level=args.error_recovery_level, + allow_duplicated_isid=args.allow_duplicated_isid, + min_connections_per_session=args.min_connections_per_session) p = subparsers.add_parser('set_iscsi_options', help="""Set options of iSCSI subsystem""") p.add_argument('-f', '--auth-file', help='Path to CHAP shared secret file for discovery session') @@ -413,7 +430,7 @@ if __name__ == "__main__": @call_cmd def get_portal_groups(args): - print_dict(rpc.iscsi.get_portal_groups(args.client, args)) + print_dict(rpc.iscsi.get_portal_groups(args.client)) p = subparsers.add_parser( 'get_portal_groups', help='Display current portal group configuration') @@ -421,7 +438,7 @@ if __name__ == "__main__": @call_cmd def get_initiator_groups(args): - print_dict(rpc.iscsi.get_initiator_groups(args.client, args)) + print_dict(rpc.iscsi.get_initiator_groups(args.client)) p = subparsers.add_parser('get_initiator_groups', help='Display current initiator group configuration') @@ -429,14 +446,36 @@ if __name__ == "__main__": @call_cmd def get_target_nodes(args): - print_dict(rpc.iscsi.get_target_nodes(args.client, args)) + print_dict(rpc.iscsi.get_target_nodes(args.client)) p = subparsers.add_parser('get_target_nodes', help='Display target nodes') p.set_defaults(func=get_target_nodes) @call_cmd def construct_target_node(args): - rpc.iscsi.construct_target_node(args.client, args) + luns = [] + for u in args.bdev_name_id_pairs.strip().split(" "): + bdev_name, lun_id = u.split(":") + luns.append({"bdev_name": bdev_name, "lun_id": int(lun_id)}) + + pg_ig_maps = [] + for u in args.pg_ig_mappings.strip().split(" "): + pg, ig = u.split(":") + pg_ig_maps.append({"pg_tag": int(pg), "ig_tag": int(ig)}) + + rpc.iscsi.construct_target_node( + args.client, + luns=luns, + pg_ig_maps=pg_ig_maps, + name=args.name, + alias_name=args.alias_name, + queue_depth=args.queue_depth, + chap_group=args.chap_group, + disable_chap=args.disable_chap, + require_chap=args.require_chap, + mutual_chap=args.mutual_chap, + header_digest=args.header_digest, + data_digest=args.data_digest) p = subparsers.add_parser('construct_target_node', help='Add a target node') @@ -470,7 +509,11 @@ if __name__ == "__main__": @call_cmd def target_node_add_lun(args): - rpc.iscsi.target_node_add_lun(args.client, args) + rpc.iscsi.target_node_add_lun( + args.client, + name=args.name, + bdev_name=args.bdev_name, + lun_id=args.lun_id) p = subparsers.add_parser('target_node_add_lun', help='Add LUN to the target node') p.add_argument('name', help='Target node name (ASCII)') @@ -482,7 +525,14 @@ if __name__ == "__main__": @call_cmd def add_pg_ig_maps(args): - rpc.iscsi.add_pg_ig_maps(args.client, args) + pg_ig_maps = [] + for u in args.pg_ig_mappings.strip().split(" "): + pg, ig = u.split(":") + pg_ig_maps.append({"pg_tag": int(pg), "ig_tag": int(ig)}) + rpc.iscsi.add_pg_ig_maps( + args.client, + pg_ig_maps=pg_ig_maps, + name=args.name) p = subparsers.add_parser('add_pg_ig_maps', help='Add PG-IG maps to the target node') p.add_argument('name', help='Target node name (ASCII)') @@ -495,7 +545,12 @@ if __name__ == "__main__": @call_cmd def delete_pg_ig_maps(args): - rpc.iscsi.delete_pg_ig_maps(args.client, args) + pg_ig_maps = [] + for u in args.pg_ig_mappings.strip().split(" "): + pg, ig = u.split(":") + pg_ig_maps.append({"pg_tag": int(pg), "ig_tag": int(ig)}) + rpc.iscsi.delete_pg_ig_maps( + args.client, pg_ig_maps=pg_ig_maps, name=args.name) p = subparsers.add_parser('delete_pg_ig_maps', help='Delete PG-IG maps from the target node') p.add_argument('name', help='Target node name (ASCII)') @@ -508,7 +563,21 @@ if __name__ == "__main__": @call_cmd def add_portal_group(args): - rpc.iscsi.add_portal_group(args.client, args) + portals = [] + for p in args.portal_list: + ip, separator, port_cpumask = p.rpartition(':') + split_port_cpumask = port_cpumask.split('@') + if len(split_port_cpumask) == 1: + port = port_cpumask + portals.append({'host': ip, 'port': port}) + else: + port = split_port_cpumask[0] + cpumask = split_port_cpumask[1] + portals.append({'host': ip, 'port': port, 'cpumask': cpumask}) + rpc.iscsi.add_portal_group( + args.client, + portals=portals, + tag=args.tag) p = subparsers.add_parser('add_portal_group', help='Add a portal group') p.add_argument( @@ -520,7 +589,17 @@ if __name__ == "__main__": @call_cmd def add_initiator_group(args): - rpc.iscsi.add_initiator_group(args.client, args) + initiators = [] + netmasks = [] + for i in args.initiator_list.strip().split(' '): + initiators.append(i) + for n in args.netmask_list.strip().split(' '): + netmasks.append(n) + rpc.iscsi.add_initiator_group( + args.client, + tag=args.tag, + initiators=initiators, + netmasks=netmasks) p = subparsers.add_parser('add_initiator_group', help='Add an initiator group') @@ -534,7 +613,21 @@ if __name__ == "__main__": @call_cmd def add_initiators_to_initiator_group(args): - rpc.iscsi.add_initiators_to_initiator_group(args.client, args) + initiators = None + netmasks = None + if args.initiator_list: + initiators = [] + for i in args.initiator_list.strip().split(' '): + initiators.append(i) + if args.netmask_list: + netmasks = [] + for n in args.netmask_list.strip().split(' '): + netmasks.append(n) + rpc.iscsi.add_initiators_to_initiator_group( + args.client, + tag=args.tag, + initiators=initiators, + netmasks=netmasks) p = subparsers.add_parser('add_initiators_to_initiator_group', help='Add initiators to an existing initiator group') @@ -548,7 +641,21 @@ if __name__ == "__main__": @call_cmd def delete_initiators_from_initiator_group(args): - rpc.iscsi.delete_initiators_from_initiator_group(args.client, args) + initiators = None + netmasks = None + if args.initiator_list: + initiators = [] + for i in args.initiator_list.strip().split(' '): + initiators.append(i) + if args.netmask_list: + netmasks = [] + for n in args.netmask_list.strip().split(' '): + netmasks.append(n) + rpc.iscsi.delete_initiators_from_initiator_group( + args.client, + tag=args.tag, + initiators=initiators, + netmasks=netmasks) p = subparsers.add_parser('delete_initiators_from_initiator_group', help='Delete initiators from an existing initiator group') @@ -562,7 +669,8 @@ if __name__ == "__main__": @call_cmd def delete_target_node(args): - rpc.iscsi.delete_target_node(args.client, args) + rpc.iscsi.delete_target_node( + args.client, target_node_name=args.target_node_name) p = subparsers.add_parser('delete_target_node', help='Delete a target node') @@ -572,7 +680,7 @@ if __name__ == "__main__": @call_cmd def delete_portal_group(args): - rpc.iscsi.delete_portal_group(args.client, args) + rpc.iscsi.delete_portal_group(args.client, tag=args.tag) p = subparsers.add_parser('delete_portal_group', help='Delete a portal group') @@ -582,7 +690,7 @@ if __name__ == "__main__": @call_cmd def delete_initiator_group(args): - rpc.iscsi.delete_initiator_group(args.client, args) + rpc.iscsi.delete_initiator_group(args.client, tag=args.tag) p = subparsers.add_parser('delete_initiator_group', help='Delete an initiator group') @@ -592,7 +700,7 @@ if __name__ == "__main__": @call_cmd def get_iscsi_connections(args): - print_dict(rpc.iscsi.get_iscsi_connections(args.client, args)) + print_dict(rpc.iscsi.get_iscsi_connections(args.client)) p = subparsers.add_parser('get_iscsi_connections', help='Display iSCSI connections') @@ -600,14 +708,14 @@ if __name__ == "__main__": @call_cmd def get_iscsi_global_params(args): - print_dict(rpc.iscsi.get_iscsi_global_params(args.client, args)) + print_dict(rpc.iscsi.get_iscsi_global_params(args.client)) p = subparsers.add_parser('get_iscsi_global_params', help='Display iSCSI global parameters') p.set_defaults(func=get_iscsi_global_params) @call_cmd def get_scsi_devices(args): - print_dict(rpc.iscsi.get_scsi_devices(args.client, args)) + print_dict(rpc.iscsi.get_scsi_devices(args.client)) p = subparsers.add_parser('get_scsi_devices', help='Display SCSI devices') p.set_defaults(func=get_scsi_devices) diff --git a/scripts/rpc/iscsi.py b/scripts/rpc/iscsi.py index 1dd68e2df..541f57868 100755 --- a/scripts/rpc/iscsi.py +++ b/scripts/rpc/iscsi.py @@ -1,201 +1,344 @@ -def set_iscsi_options(client, args): + + +def set_iscsi_options( + client, + auth_file=None, + node_base=None, + nop_timeout=None, + nop_in_interval=None, + no_discovery_auth=None, + req_discovery_auth=None, + req_discovery_auth_mutual=None, + discovery_auth_group=None, + max_sessions=None, + max_connections_per_session=None, + default_time2wait=None, + default_time2retain=None, + immediate_data=None, + error_recovery_level=None, + allow_duplicated_isid=None, + min_connections_per_session=None): + """Set iSCSI target options. + + Args: + auth_file: Path to CHAP shared secret file for discovery session (optional) + node_base: Prefix of the name of iSCSI target node (optional) + nop_timeout: Timeout in seconds to nop-in request to the initiator (optional) + nop_in_interval: Time interval in secs between nop-in requests by the target (optional) + no_discovery_auth: CHAP for discovery session should be disabled (optional) + req_discovery_auth: CHAP for discovery session should be required + req_discovery_auth_mutual: CHAP for discovery session should be mutual + discovery_auth_group: Authentication group ID for discovery session + max_sessions:Maximum number of sessions in the host + max_connections_per_session:Negotiated parameter, MaxConnections + default_time2wait: Negotiated parameter, DefaultTime2Wait + default_time2retain: Negotiated parameter, DefaultTime2Retain + immediate_data: Negotiated parameter, ImmediateData + error_recovery_level: Negotiated parameter, ErrorRecoveryLevel + allow_duplicated_isid: Allow duplicated initiator session ID + min_connections_per_session: Allocation unit of connections per core + + Returns: + True or False + """ params = {} - if args.auth_file: - params['auth_file'] = args.auth_file - if args.node_base: - params['node_base'] = args.node_base - if args.nop_timeout: - params['nop_timeout'] = args.nop_timeout - if args.nop_in_interval: - params['nop_in_interval'] = args.nop_in_interval - if args.no_discovery_auth: - params['no_discovery_auth'] = args.no_discovery_auth - if args.req_discovery_auth: - params['req_discovery_auth'] = args.req_discovery_auth - if args.req_discovery_auth_mutual: - params['req_discovery_auth_mutual'] = args.req_discovery_auth_mutual - if args.discovery_auth_group: - params['discovery_auth_group'] = args.discovery_auth_group - if args.max_sessions: - params['max_sessions'] = args.max_sessions - if args.max_connections_per_session: - params['max_connections_per_session'] = args.max_connections_per_session - if args.default_time2wait: - params['default_time2wait'] = args.default_time2wait - if args.default_time2retain: - params['default_time2retain'] = args.default_time2retain - if args.immediate_data: - params['immediate_data'] = args.immediate_data - if args.error_recovery_level: - params['error_recovery_level'] = args.error_recovery_level - if args.allow_duplicated_isid: - params['allow_duplicated_isid'] = args.allow_duplicated_isid - if args.min_connections_per_session: - params['min_connections_per_session'] = args.min_connections_per_session + if auth_file: + params['auth_file'] = auth_file + if node_base: + params['node_base'] = node_base + if nop_timeout: + params['nop_timeout'] = nop_timeout + if nop_in_interval: + params['nop_in_interval'] = nop_in_interval + if no_discovery_auth: + params['no_discovery_auth'] = no_discovery_auth + if req_discovery_auth: + params['req_discovery_auth'] = req_discovery_auth + if req_discovery_auth_mutual: + params['req_discovery_auth_mutual'] = req_discovery_auth_mutual + if discovery_auth_group: + params['discovery_auth_group'] = discovery_auth_group + if max_sessions: + params['max_sessions'] = max_sessions + if max_connections_per_session: + params['max_connections_per_session'] = max_connections_per_session + if default_time2wait: + params['default_time2wait'] = default_time2wait + if default_time2retain: + params['default_time2retain'] = default_time2retain + if immediate_data: + params['immediate_data'] = immediate_data + if error_recovery_level: + params['error_recovery_level'] = error_recovery_level + if allow_duplicated_isid: + params['allow_duplicated_isid'] = allow_duplicated_isid + if min_connections_per_session: + params['min_connections_per_session'] = min_connections_per_session + return client.call('set_iscsi_options', params) -def get_portal_groups(client, args): +def get_portal_groups(client): + """Display current portal group configuration. + + Returns: + List of current portal group configuration. + """ return client.call('get_portal_groups') -def get_initiator_groups(client, args): +def get_initiator_groups(client): + """Display current initiator group configuration. + + Returns: + List of current initiator group configuration. + """ return client.call('get_initiator_groups') -def get_target_nodes(client, args): +def get_target_nodes(client): + """Display target nodes. + + Returns: + List of ISCSI target node objects. + """ return client.call('get_target_nodes') -def construct_target_node(client, args): - luns = [] - for u in args.bdev_name_id_pairs.strip().split(" "): - bdev_name, lun_id = u.split(":") - luns.append({"bdev_name": bdev_name, "lun_id": int(lun_id)}) +def construct_target_node( + client, + luns, + pg_ig_maps, + name, + alias_name, + queue_depth, + chap_group=None, + disable_chap=None, + require_chap=None, + mutual_chap=None, + header_digest=None, + data_digest=None): + """Add a target node. - pg_ig_maps = [] - for u in args.pg_ig_mappings.strip().split(" "): - pg, ig = u.split(":") - pg_ig_maps.append({"pg_tag": int(pg), "ig_tag": int(ig)}) + Args: + luns: List of bdev_name_id_pairs, e.g. [{"bdev_name": "Malloc1", "lun_id": 1}] + pg_ig_maps: List of pg_ig_mappings, e.g. [{"pg_tag": pg, "ig_tag": ig}] + name: Target node name (ASCII) + alias_name: Target node alias name (ASCII) + queue_depth: Desired target queue depth + chap_group: Authentication group ID for this target node + disable_chap: CHAP authentication should be disabled for this target node + require_chap: CHAP authentication should be required for this target node + mutual_chap: CHAP authentication should be mutual/bidirectional + header_digest: Header Digest should be required for this target node + data_digest: Data Digest should be required for this target node + Returns: + True or False + """ params = { - 'name': args.name, - 'alias_name': args.alias_name, + 'name': name, + 'alias_name': alias_name, 'pg_ig_maps': pg_ig_maps, 'luns': luns, - 'queue_depth': args.queue_depth, + 'queue_depth': queue_depth, } - if args.chap_group: - params['chap_group'] = args.chap_group - if args.disable_chap: - params['disable_chap'] = args.disable_chap - if args.require_chap: - params['require_chap'] = args.require_chap - if args.mutual_chap: - params['mutual_chap'] = args.mutual_chap - if args.header_digest: - params['header_digest'] = args.header_digest - if args.data_digest: - params['data_digest'] = args.data_digest + if chap_group: + params['chap_group'] = chap_group + if disable_chap: + params['disable_chap'] = disable_chap + if require_chap: + params['require_chap'] = require_chap + if mutual_chap: + params['mutual_chap'] = mutual_chap + if header_digest: + params['header_digest'] = header_digest + if data_digest: + params['data_digest'] = data_digest return client.call('construct_target_node', params) -def target_node_add_lun(client, args): +def target_node_add_lun(client, name, bdev_name, lun_id=None): + """Add LUN to the target node. + + Args: + name: Target node name (ASCII) + bdev_name: bdev name + lun_id: LUN ID (integer >= 0) + + Returns: + True or False + """ params = { - 'name': args.name, - 'bdev_name': args.bdev_name, + 'name': name, + 'bdev_name': bdev_name, } - if args.lun_id: - params['lun_id'] = args.lun_id + if lun_id: + params['lun_id'] = lun_id return client.call('target_node_add_lun', params) -def delete_pg_ig_maps(client, args): - pg_ig_maps = [] - for u in args.pg_ig_mappings.strip().split(" "): - pg, ig = u.split(":") - pg_ig_maps.append({"pg_tag": int(pg), "ig_tag": int(ig)}) +def delete_pg_ig_maps(client, pg_ig_maps, name): + """Delete PG-IG maps from the target node. + + Args: + pg_ig_maps: List of pg_ig_mappings, e.g. [{"pg_tag": pg, "ig_tag": ig}] + name: Target node alias name (ASCII) + + Returns: + True or False + """ params = { - 'name': args.name, + 'name': name, 'pg_ig_maps': pg_ig_maps, } return client.call('delete_pg_ig_maps', params) -def add_pg_ig_maps(client, args): - pg_ig_maps = [] - for u in args.pg_ig_mappings.strip().split(" "): - pg, ig = u.split(":") - pg_ig_maps.append({"pg_tag": int(pg), "ig_tag": int(ig)}) +def add_pg_ig_maps(client, pg_ig_maps, name): + """Add PG-IG maps to the target node. + + Args: + pg_ig_maps: List of pg_ig_mappings, e.g. [{"pg_tag": pg, "ig_tag": ig}] + name: Target node alias name (ASCII) + + Returns: + True or False + """ params = { - 'name': args.name, + 'name': name, 'pg_ig_maps': pg_ig_maps, } return client.call('add_pg_ig_maps', params) -def add_portal_group(client, args): - # parse out portal list host1:port1 host2:port2 - portals = [] - for p in args.portal_list: - ip, separator, port_cpumask = p.rpartition(':') - split_port_cpumask = port_cpumask.split('@') - if len(split_port_cpumask) == 1: - port = port_cpumask - portals.append({'host': ip, 'port': port}) - else: - port = split_port_cpumask[0] - cpumask = split_port_cpumask[1] - portals.append({'host': ip, 'port': port, 'cpumask': cpumask}) +def add_portal_group(client, portals, tag): + """Add a portal group. - params = {'tag': args.tag, 'portals': portals} + Args: + portals: List of portals, e.g. [{'host': ip, 'port': port}] or [{'host': ip, 'port': port, 'cpumask': cpumask}] + tag: Initiator group tag (unique, integer > 0) + + Returns: + True or False + """ + params = {'tag': tag, 'portals': portals} return client.call('add_portal_group', params) -def add_initiator_group(client, args): - initiators = [] - netmasks = [] - for i in args.initiator_list.strip().split(' '): - initiators.append(i) - for n in args.netmask_list.strip().split(' '): - netmasks.append(n) +def add_initiator_group(client, tag, initiators, netmasks): + """Add an initiator group. - params = {'tag': args.tag, 'initiators': initiators, 'netmasks': netmasks} + Args: + tag: Initiator group tag (unique, integer > 0) + initiators: List of initiator hostnames or IP addresses, e.g. ["127.0.0.1","192.168.200.100"] + netmasks: List of initiator netmasks, e.g. ["255.255.0.0","255.248.0.0"] + + Returns: + True or False + """ + params = {'tag': tag, 'initiators': initiators, 'netmasks': netmasks} return client.call('add_initiator_group', params) -def add_initiators_to_initiator_group(client, args): - initiators = [] - netmasks = [] - if args.initiator_list: - for i in args.initiator_list.strip().split(' '): - initiators.append(i) - if args.netmask_list: - for n in args.netmask_list.strip().split(' '): - netmasks.append(n) +def add_initiators_to_initiator_group( + client, + tag, + initiators=None, + netmasks=None): + """Add initiators to an existing initiator group. - params = {'tag': args.tag, 'initiators': initiators, 'netmasks': netmasks} + Args: + tag: Initiator group tag (unique, integer > 0) + initiators: List of initiator hostnames or IP addresses, e.g. ["127.0.0.1","192.168.200.100"] + netmasks: List of initiator netmasks, e.g. ["255.255.0.0","255.248.0.0"] + + Returns: + True or False + """ + params = {'tag': tag, 'initiators': initiators, 'netmasks': netmasks} return client.call('add_initiators_to_initiator_group', params) -def delete_initiators_from_initiator_group(client, args): - initiators = [] - netmasks = [] - if args.initiator_list: - for i in args.initiator_list.strip().split(' '): - initiators.append(i) - if args.netmask_list: - for n in args.netmask_list.strip().split(' '): - netmasks.append(n) +def delete_initiators_from_initiator_group( + client, tag, initiators=None, netmasks=None): + """Delete initiators from an existing initiator group. - params = {'tag': args.tag, 'initiators': initiators, 'netmasks': netmasks} + Args: + tag: Initiator group tag (unique, integer > 0) + initiators: List of initiator hostnames or IP addresses, e.g. ["127.0.0.1","192.168.200.100"] + netmasks: List of initiator netmasks, e.g. ["255.255.0.0","255.248.0.0"] + + Returns: + True or False + """ + params = {'tag': tag, 'initiators': initiators, 'netmasks': netmasks} return client.call('delete_initiators_from_initiator_group', params) -def delete_target_node(client, args): - params = {'name': args.target_node_name} +def delete_target_node(client, target_node_name): + """Delete a target node. + + Args: + target_node_name: Target node name to be deleted. Example: iqn.2016-06.io.spdk:disk1. + + Returns: + True or False + """ + params = {'name': target_node_name} return client.call('delete_target_node', params) -def delete_portal_group(client, args): - params = {'tag': args.tag} +def delete_portal_group(client, tag): + """Delete a portal group. + + Args: + tag: Portal group tag (unique, integer > 0) + + Returns: + True or False + """ + params = {'tag': tag} return client.call('delete_portal_group', params) -def delete_initiator_group(client, args): - params = {'tag': args.tag} +def delete_initiator_group(client, tag): + """Delete an initiator group. + + Args: + tag: Initiator group tag (unique, integer > 0) + + Returns: + True or False + """ + params = {'tag': tag} return client.call('delete_initiator_group', params) -def get_iscsi_connections(client, args): +def get_iscsi_connections(client): + """Display iSCSI connections. + + Returns: + List of iSCSI connection. + """ return client.call('get_iscsi_connections') -def get_iscsi_global_params(client, args): +def get_iscsi_global_params(client): + """Display iSCSI global parameters. + + Returns: + List of iSCSI global parameter. + """ return client.call('get_iscsi_global_params') -def get_scsi_devices(client, args): +def get_scsi_devices(client): + """Display SCSI devices. + + Returns: + List of SCSI device. + """ return client.call('get_scsi_devices')