In SPDK iSCSI target, portal group works almost as identifier of portal. To support iSCSI login redirection, we need to have two types of portal groups, public and private portal groups. We need portals of public portal groups to redirect to a portal in a private portal groups at login via temporary login redirection funciton, and we need to make SendTargets return only portals in public portal groups. To do these simply, we mark primary or secondary portal group expicitly at its creation by this patch. Signed-off-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Change-Id: Iccf87a4b9dd1f4a8fbb857a399b8f2dbc7c0b3ab Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/3491 Community-CI: Mellanox Build Bot Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
640 lines
22 KiB
Python
640 lines
22 KiB
Python
from configshell_fb import ExecutionError
|
|
from rpc.client import JSONRPCException
|
|
from .ui_node import UINode
|
|
|
|
|
|
class UIISCSI(UINode):
|
|
def __init__(self, parent):
|
|
UINode.__init__(self, "iscsi", parent)
|
|
self.refresh()
|
|
|
|
def refresh(self):
|
|
self._children = set([])
|
|
UIISCSIDevices(self)
|
|
UIPortalGroups(self)
|
|
UIInitiatorGroups(self)
|
|
UIISCSIConnections(self)
|
|
UIISCSIAuthGroups(self)
|
|
UIISCSIGlobalParams(self)
|
|
|
|
|
|
class UIISCSIGlobalParams(UINode):
|
|
def __init__(self, parent):
|
|
UINode.__init__(self, "global_params", parent)
|
|
self.refresh()
|
|
|
|
def refresh(self):
|
|
self._children = set([])
|
|
iscsi_global_params = self.get_root().iscsi_get_options()
|
|
if not iscsi_global_params:
|
|
return
|
|
for param, val in iscsi_global_params.items():
|
|
UIISCSIGlobalParam("%s: %s" % (param, val), self)
|
|
|
|
def ui_command_set_auth(self, g=None, d=None, r=None, m=None):
|
|
"""Set CHAP authentication for discovery service.
|
|
|
|
Optional arguments:
|
|
g = chap_group: Authentication group ID for discovery session
|
|
d = disable_chap: CHAP for discovery session should be disabled
|
|
r = require_chap: CHAP for discovery session should be required
|
|
m = mutual_chap: CHAP for discovery session should be mutual
|
|
"""
|
|
chap_group = self.ui_eval_param(g, "number", None)
|
|
disable_chap = self.ui_eval_param(d, "bool", None)
|
|
require_chap = self.ui_eval_param(r, "bool", None)
|
|
mutual_chap = self.ui_eval_param(m, "bool", None)
|
|
self.get_root().iscsi_set_discovery_auth(
|
|
chap_group=chap_group, disable_chap=disable_chap,
|
|
require_chap=require_chap, mutual_chap=mutual_chap)
|
|
|
|
|
|
class UIISCSIGlobalParam(UINode):
|
|
def __init__(self, param, parent):
|
|
UINode.__init__(self, param, parent)
|
|
|
|
|
|
class UIISCSIDevices(UINode):
|
|
def __init__(self, parent):
|
|
UINode.__init__(self, "target_nodes", parent)
|
|
self.scsi_devices = list()
|
|
self.refresh()
|
|
|
|
def refresh(self):
|
|
self._children = set([])
|
|
self.target_nodes = list(self.get_root().iscsi_get_target_nodes())
|
|
self.scsi_devices = list(self.get_root().scsi_get_devices())
|
|
for device in self.scsi_devices:
|
|
for node in self.target_nodes:
|
|
if hasattr(device, "device_name") and node['name'] \
|
|
== device.device_name:
|
|
UIISCSIDevice(device, node, self)
|
|
|
|
def delete(self, name):
|
|
self.get_root().iscsi_delete_target_node(target_node_name=name)
|
|
|
|
def ui_command_create(self, name, alias_name, bdev_name_id_pairs,
|
|
pg_ig_mappings, queue_depth, g=None, d=None, r=None,
|
|
m=None, h=None, t=None):
|
|
"""Create target node
|
|
|
|
Positional args:
|
|
name: Target node name (ASCII)
|
|
alias_name: Target node alias name (ASCII)
|
|
bdev_name_id_pairs: List of bdev_name_id_pairs
|
|
pg_ig_mappings: List of pg_ig_mappings
|
|
queue_depth: Desired target queue depth
|
|
Optional args:
|
|
g = chap_group: Authentication group ID for this target node
|
|
d = disable_chap: CHAP authentication should be disabled for this target node
|
|
r = require_chap: CHAP authentication should be required for this target node
|
|
m = mutual_chap: CHAP authentication should be mutual/bidirectional
|
|
h = header_digest: Header Digest should be required for this target node
|
|
t = data_digest: Data Digest should be required for this target node
|
|
"""
|
|
luns = []
|
|
print("bdev_name_id_pairs: %s" % bdev_name_id_pairs)
|
|
print("pg_ig_mappings: %s" % pg_ig_mappings)
|
|
for u in 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 pg_ig_mappings.strip().split(" "):
|
|
pg, ig = u.split(":")
|
|
pg_ig_maps.append({"pg_tag": int(pg), "ig_tag": int(ig)})
|
|
queue_depth = self.ui_eval_param(queue_depth, "number", None)
|
|
chap_group = self.ui_eval_param(g, "number", None)
|
|
disable_chap = self.ui_eval_param(d, "bool", None)
|
|
require_chap = self.ui_eval_param(r, "bool", None)
|
|
mutual_chap = self.ui_eval_param(m, "bool", None)
|
|
header_digest = self.ui_eval_param(h, "bool", None)
|
|
data_digest = self.ui_eval_param(t, "bool", None)
|
|
self.get_root().iscsi_create_target_node(
|
|
name=name, alias_name=alias_name, luns=luns,
|
|
pg_ig_maps=pg_ig_maps, queue_depth=queue_depth,
|
|
chap_group=chap_group, disable_chap=disable_chap,
|
|
require_chap=require_chap, mutual_chap=mutual_chap,
|
|
header_digest=header_digest, data_digest=data_digest)
|
|
|
|
def ui_command_delete(self, name=None):
|
|
"""Delete a target node. If name is not specified delete all target nodes.
|
|
|
|
Arguments:
|
|
name - Target node name.
|
|
"""
|
|
self.delete(name)
|
|
|
|
def ui_command_delete_all(self):
|
|
"""Delete all target nodes"""
|
|
rpc_messages = ""
|
|
for device in self.scsi_devices:
|
|
try:
|
|
self.delete(device.device_name)
|
|
except JSONRPCException as e:
|
|
rpc_messages += e.message
|
|
if rpc_messages:
|
|
raise JSONRPCException(rpc_messages)
|
|
|
|
def ui_command_add_lun(self, name, bdev_name, lun_id=None):
|
|
"""Add lun to the target node.
|
|
|
|
Required args:
|
|
name: Target node name (ASCII)
|
|
bdev_name: bdev name
|
|
Positional args:
|
|
lun_id: LUN ID (integer >= 0)
|
|
"""
|
|
if lun_id:
|
|
lun_id = self.ui_eval_param(lun_id, "number", None)
|
|
self.get_root().iscsi_target_node_add_lun(
|
|
name=name, bdev_name=bdev_name, lun_id=lun_id)
|
|
|
|
def summary(self):
|
|
count = 0
|
|
for device in self.scsi_devices:
|
|
for node in self.target_nodes:
|
|
if hasattr(device, "device_name") and node['name'] \
|
|
== device.device_name:
|
|
count = count + 1
|
|
return "Target nodes: %d" % count, None
|
|
|
|
|
|
class UIISCSIDevice(UINode):
|
|
def __init__(self, device, target, parent):
|
|
UINode.__init__(self, device.device_name, parent)
|
|
self.device = device
|
|
self.target = target
|
|
self.refresh()
|
|
|
|
def ui_command_set_auth(self, g=None, d=None, r=None, m=None):
|
|
"""Set CHAP authentication for the target node.
|
|
|
|
Optionals args:
|
|
g = chap_group: Authentication group ID for this target node
|
|
d = disable_chap: CHAP authentication should be disabled for this target node
|
|
r = require_chap: CHAP authentication should be required for this target node
|
|
m = mutual_chap: CHAP authentication should be mutual/bidirectional
|
|
"""
|
|
chap_group = self.ui_eval_param(g, "number", None)
|
|
disable_chap = self.ui_eval_param(d, "bool", None)
|
|
require_chap = self.ui_eval_param(r, "bool", None)
|
|
mutual_chap = self.ui_eval_param(m, "bool", None)
|
|
self.get_root().iscsi_target_node_set_auth(
|
|
name=self.device.device_name, chap_group=chap_group,
|
|
disable_chap=disable_chap,
|
|
require_chap=require_chap, mutual_chap=mutual_chap)
|
|
|
|
def ui_command_iscsi_target_node_add_pg_ig_maps(self, pg_ig_mappings):
|
|
"""Add PG-IG maps to the target node.
|
|
|
|
Args:
|
|
pg_ig_maps: List of pg_ig_mappings, e.g. pg_tag:ig_tag pg_tag2:ig_tag2
|
|
"""
|
|
pg_ig_maps = []
|
|
for u in pg_ig_mappings.strip().split(" "):
|
|
pg, ig = u.split(":")
|
|
pg_ig_maps.append({"pg_tag": int(pg), "ig_tag": int(ig)})
|
|
self.get_root().iscsi_target_node_add_pg_ig_maps(
|
|
pg_ig_maps=pg_ig_maps, name=self.device.device_name)
|
|
|
|
def ui_command_iscsi_target_node_remove_pg_ig_maps(self, pg_ig_mappings):
|
|
"""Remove PG-IG maps from the target node.
|
|
|
|
Args:
|
|
pg_ig_maps: List of pg_ig_mappings, e.g. pg_tag:ig_tag pg_tag2:ig_tag2
|
|
"""
|
|
pg_ig_maps = []
|
|
for u in pg_ig_mappings.strip().split(" "):
|
|
pg, ig = u.split(":")
|
|
pg_ig_maps.append({"pg_tag": int(pg), "ig_tag": int(ig)})
|
|
self.get_root().iscsi_target_node_remove_pg_ig_maps(
|
|
pg_ig_maps=pg_ig_maps, name=self.device.device_name)
|
|
|
|
def refresh(self):
|
|
self._children = set([])
|
|
UIISCSILuns(self.target['luns'], self)
|
|
UIISCSIPgIgMaps(self.target['pg_ig_maps'], self)
|
|
auths = {"disable_chap": self.target["disable_chap"],
|
|
"require_chap": self.target["require_chap"],
|
|
"mutual_chap": self.target["mutual_chap"],
|
|
"chap_group": self.target["chap_group"],
|
|
"data_digest": self.target["data_digest"]}
|
|
UIISCSIAuth(auths, self)
|
|
|
|
def summary(self):
|
|
return "Id: %s, QueueDepth: %s" % (self.device.id,
|
|
self.target['queue_depth']), None
|
|
|
|
|
|
class UIISCSIAuth(UINode):
|
|
def __init__(self, auths, parent):
|
|
UINode.__init__(self, "auths", parent)
|
|
self.auths = auths
|
|
self.refresh()
|
|
|
|
def summary(self):
|
|
return "disable_chap: %s, require_chap: %s, mutual_chap: %s, chap_group: %s" % (
|
|
self.auths['disable_chap'], self.auths['require_chap'],
|
|
self.auths['mutual_chap'], self.auths['chap_group']), None
|
|
|
|
|
|
class UIISCSILuns(UINode):
|
|
def __init__(self, luns, parent):
|
|
UINode.__init__(self, "luns", parent)
|
|
self.luns = luns
|
|
self.refresh()
|
|
|
|
def refresh(self):
|
|
self._children = set([])
|
|
for lun in self.luns:
|
|
UIISCSILun(lun, self)
|
|
|
|
def summary(self):
|
|
return "Luns: %d" % len(self.luns), None
|
|
|
|
|
|
class UIISCSILun(UINode):
|
|
def __init__(self, lun, parent):
|
|
UINode.__init__(self, "lun %s" % lun['lun_id'], parent)
|
|
self.lun = lun
|
|
self.refresh()
|
|
|
|
def summary(self):
|
|
return "%s" % self.lun['bdev_name'], None
|
|
|
|
|
|
class UIISCSIPgIgMaps(UINode):
|
|
def __init__(self, pg_ig_maps, parent):
|
|
UINode.__init__(self, "pg_ig_maps", parent)
|
|
self.pg_ig_maps = pg_ig_maps
|
|
self.refresh()
|
|
|
|
def refresh(self):
|
|
self._children = set([])
|
|
for pg_ig in self.pg_ig_maps:
|
|
UIISCSIPgIg(pg_ig, self)
|
|
|
|
def summary(self):
|
|
return "Pg_ig_maps: %d" % len(self.pg_ig_maps), None
|
|
|
|
|
|
class UIISCSIPgIg(UINode):
|
|
def __init__(self, pg_ig, parent):
|
|
UINode.__init__(self, "portal_group%s - initiator_group%s" %
|
|
(pg_ig['pg_tag'], pg_ig['ig_tag']), parent)
|
|
self.pg_ig = pg_ig
|
|
self.refresh()
|
|
|
|
|
|
class UIPortalGroups(UINode):
|
|
def __init__(self, parent):
|
|
UINode.__init__(self, "portal_groups", parent)
|
|
self.refresh()
|
|
|
|
def delete(self, tag):
|
|
self.get_root().iscsi_delete_portal_group(tag=tag)
|
|
|
|
def ui_command_create(self, tag, portal_list):
|
|
"""Add a portal group.
|
|
|
|
Args:
|
|
portals: List of portals e.g. ip:port ip2:port2
|
|
tag: Portal group tag (unique, integer > 0)
|
|
"""
|
|
portals = []
|
|
for portal in portal_list.strip().split(" "):
|
|
host = portal
|
|
cpumask = None
|
|
if "@" in portal:
|
|
host, cpumask = portal.split("@")
|
|
if ":" not in host:
|
|
raise ExecutionError("Incorrect format of portal group. Port is missing."
|
|
"Use 'help create' to see the command syntax.")
|
|
host, port = host.rsplit(":", -1)
|
|
portals.append({'host': host, 'port': port})
|
|
if cpumask:
|
|
print("WARNING: Specifying a CPU mask for portal groups is no longer supported. Ignoring.")
|
|
tag = self.ui_eval_param(tag, "number", None)
|
|
self.get_root().construct_portal_group(tag=tag, portals=portals, private=None)
|
|
|
|
def ui_command_delete(self, tag):
|
|
"""Delete a portal group with given tag (unique, integer > 0))"""
|
|
tag = self.ui_eval_param(tag, "number", None)
|
|
self.delete(tag)
|
|
|
|
def ui_command_delete_all(self):
|
|
"""Delete all portal groups"""
|
|
rpc_messages = ""
|
|
for pg in self.pgs:
|
|
try:
|
|
self.delete(pg.tag)
|
|
except JSONRPCException as e:
|
|
rpc_messages += e.message
|
|
if rpc_messages:
|
|
raise JSONRPCException(rpc_messages)
|
|
|
|
def refresh(self):
|
|
self._children = set([])
|
|
self.pgs = list(self.get_root().iscsi_get_portal_groups())
|
|
for pg in self.pgs:
|
|
try:
|
|
UIPortalGroup(pg, self)
|
|
except JSONRPCException as e:
|
|
self.shell.log.error(e.message)
|
|
|
|
def summary(self):
|
|
return "Portal groups: %d" % len(self.pgs), None
|
|
|
|
|
|
class UIPortalGroup(UINode):
|
|
def __init__(self, pg, parent):
|
|
UINode.__init__(self, "portal_group%s" % pg.tag, parent)
|
|
self.pg = pg
|
|
self.refresh()
|
|
|
|
def refresh(self):
|
|
self._children = set([])
|
|
for portal in self.pg.portals:
|
|
UIPortal(portal['host'], portal['port'], self)
|
|
|
|
def summary(self):
|
|
return "Portals: %d" % len(self.pg.portals), None
|
|
|
|
|
|
class UIPortal(UINode):
|
|
def __init__(self, host, port, parent):
|
|
UINode.__init__(self, "host=%s, port=%s" % (
|
|
host, port), parent)
|
|
self.refresh()
|
|
|
|
|
|
class UIInitiatorGroups(UINode):
|
|
def __init__(self, parent):
|
|
UINode.__init__(self, "initiator_groups", parent)
|
|
self.refresh()
|
|
|
|
def delete(self, tag):
|
|
self.get_root().iscsi_delete_initiator_group(tag=tag)
|
|
|
|
def ui_command_create(self, tag, initiator_list, netmask_list):
|
|
"""Add an initiator group.
|
|
|
|
Args:
|
|
tag: Initiator group tag (unique, integer > 0)
|
|
initiators: List of initiator hostnames or IP addresses
|
|
separated with whitespaces, e.g. 127.0.0.1 192.168.200.100
|
|
netmasks: List of initiator netmasks separated with whitespaces,
|
|
e.g. 255.255.0.0 255.248.0.0
|
|
"""
|
|
tag = self.ui_eval_param(tag, "number", None)
|
|
self.get_root().construct_initiator_group(
|
|
tag=tag, initiators=initiator_list.split(" "),
|
|
netmasks=netmask_list.split(" "))
|
|
|
|
def ui_command_delete(self, tag):
|
|
"""Delete an initiator group.
|
|
|
|
Args:
|
|
tag: Initiator group tag (unique, integer > 0)
|
|
"""
|
|
tag = self.ui_eval_param(tag, "number", None)
|
|
self.delete(tag)
|
|
|
|
def ui_command_delete_all(self):
|
|
"""Delete all initiator groups"""
|
|
rpc_messages = ""
|
|
for ig in self.igs:
|
|
try:
|
|
self.delete(ig.tag)
|
|
except JSONRPCException as e:
|
|
rpc_messages += e.message
|
|
if rpc_messages:
|
|
raise JSONRPCException(rpc_messages)
|
|
|
|
def ui_command_add_initiator(self, tag, initiators, netmasks):
|
|
"""Add initiators to an existing initiator group.
|
|
|
|
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
|
|
"""
|
|
tag = self.ui_eval_param(tag, "number", None)
|
|
self.get_root().iscsi_initiator_group_add_initiators(
|
|
tag=tag, initiators=initiators.split(" "),
|
|
netmasks=netmasks.split(" "))
|
|
|
|
def ui_command_delete_initiator(self, tag, initiators=None, netmasks=None):
|
|
"""Delete initiators from an existing initiator group.
|
|
|
|
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
|
|
"""
|
|
tag = self.ui_eval_param(tag, "number", None)
|
|
if initiators:
|
|
initiators = initiators.split(" ")
|
|
if netmasks:
|
|
netmasks = netmasks.split(" ")
|
|
self.get_root().iscsi_initiator_group_remove_initiators(
|
|
tag=tag, initiators=initiators,
|
|
netmasks=netmasks)
|
|
|
|
def refresh(self):
|
|
self._children = set([])
|
|
self.igs = list(self.get_root().iscsi_get_initiator_groups())
|
|
for ig in self.igs:
|
|
UIInitiatorGroup(ig, self)
|
|
|
|
def summary(self):
|
|
return "Initiator groups: %d" % len(self.igs), None
|
|
|
|
|
|
class UIInitiatorGroup(UINode):
|
|
def __init__(self, ig, parent):
|
|
UINode.__init__(self, "initiator_group%s" % ig.tag, parent)
|
|
self.ig = ig
|
|
self.refresh()
|
|
|
|
def refresh(self):
|
|
self._children = set([])
|
|
for initiator, netmask in zip(self.ig.initiators, self.ig.netmasks):
|
|
UIInitiator(initiator, netmask, self)
|
|
|
|
def summary(self):
|
|
return "Initiators: %d" % len(self.ig.initiators), None
|
|
|
|
|
|
class UIInitiator(UINode):
|
|
def __init__(self, initiator, netmask, parent):
|
|
UINode.__init__(self, "hostname=%s, netmask=%s" % (initiator, netmask), parent)
|
|
self.refresh()
|
|
|
|
|
|
class UIISCSIConnections(UINode):
|
|
def __init__(self, parent):
|
|
UINode.__init__(self, "iscsi_connections", parent)
|
|
self.refresh()
|
|
|
|
def refresh(self):
|
|
self._children = set([])
|
|
self.iscsicons = list(self.get_root().iscsi_get_connections())
|
|
for ic in self.iscsicons:
|
|
UIISCSIConnection(ic, self)
|
|
|
|
def summary(self):
|
|
return "Connections: %d" % len(self.iscsicons), None
|
|
|
|
|
|
class UIISCSIConnection(UINode):
|
|
def __init__(self, ic, parent):
|
|
UINode.__init__(self, "%s" % ic['id'], parent)
|
|
self.ic = ic
|
|
self.refresh()
|
|
|
|
def refresh(self):
|
|
self._children = set([])
|
|
for key, val in self.ic.items():
|
|
if key == "id":
|
|
continue
|
|
UIISCSIConnectionDetails("%s: %s" % (key, val), self)
|
|
|
|
|
|
class UIISCSIConnectionDetails(UINode):
|
|
def __init__(self, info, parent):
|
|
UINode.__init__(self, "%s" % info, parent)
|
|
self.refresh()
|
|
|
|
|
|
class UIISCSIAuthGroups(UINode):
|
|
def __init__(self, parent):
|
|
UINode.__init__(self, "auth_groups", parent)
|
|
self.refresh()
|
|
|
|
def refresh(self):
|
|
self._children = set([])
|
|
self.iscsi_auth_groups = list(self.get_root().iscsi_get_auth_groups())
|
|
if self.iscsi_auth_groups is None:
|
|
self.iscsi_auth_groups = []
|
|
for ag in self.iscsi_auth_groups:
|
|
UIISCSIAuthGroup(ag, self)
|
|
|
|
def delete(self, tag):
|
|
self.get_root().iscsi_delete_auth_group(tag=tag)
|
|
|
|
def delete_secret(self, tag, user):
|
|
self.get_root().iscsi_auth_group_remove_secret(
|
|
tag=tag, user=user)
|
|
|
|
def ui_command_create(self, tag, secrets=None):
|
|
"""Add authentication group for CHAP authentication.
|
|
|
|
Args:
|
|
tag: Authentication group tag (unique, integer > 0).
|
|
Optional args:
|
|
secrets: Array of secrets objects separated by comma sign,
|
|
e.g. user:test secret:test muser:mutual_test msecret:mutual_test
|
|
"""
|
|
tag = self.ui_eval_param(tag, "number", None)
|
|
if secrets:
|
|
secrets = [dict(u.split(":") for u in a.split(" "))
|
|
for a in secrets.split(",")]
|
|
self.get_root().iscsi_create_auth_group(tag=tag, secrets=secrets)
|
|
|
|
def ui_command_delete(self, tag):
|
|
"""Delete an authentication group.
|
|
|
|
Args:
|
|
tag: Authentication group tag (unique, integer > 0)
|
|
"""
|
|
tag = self.ui_eval_param(tag, "number", None)
|
|
self.delete(tag)
|
|
|
|
def ui_command_delete_all(self):
|
|
"""Delete all authentication groups."""
|
|
rpc_messages = ""
|
|
for iscsi_auth_group in self.iscsi_auth_groups:
|
|
try:
|
|
self.delete(iscsi_auth_group['tag'])
|
|
except JSONRPCException as e:
|
|
rpc_messages += e.message
|
|
if rpc_messages:
|
|
raise JSONRPCException(rpc_messages)
|
|
|
|
def ui_command_add_secret(self, tag, user, secret,
|
|
muser=None, msecret=None):
|
|
"""Add a secret to an authentication group.
|
|
|
|
Args:
|
|
tag: Authentication group tag (unique, integer > 0)
|
|
user: User name for one-way CHAP authentication
|
|
secret: Secret for one-way CHAP authentication
|
|
Optional args:
|
|
muser: User name for mutual CHAP authentication
|
|
msecret: Secret for mutual CHAP authentication
|
|
"""
|
|
tag = self.ui_eval_param(tag, "number", None)
|
|
self.get_root().iscsi_auth_group_add_secret(
|
|
tag=tag, user=user, secret=secret,
|
|
muser=muser, msecret=msecret)
|
|
|
|
def ui_command_delete_secret(self, tag, user):
|
|
"""Delete a secret from an authentication group.
|
|
|
|
Args:
|
|
tag: Authentication group tag (unique, integer > 0)
|
|
user: User name for one-way CHAP authentication
|
|
"""
|
|
tag = self.ui_eval_param(tag, "number", None)
|
|
self.delete_secret(tag, user)
|
|
|
|
def ui_command_delete_secret_all(self, tag):
|
|
"""Delete all secrets from an authentication group.
|
|
|
|
Args:
|
|
tag: Authentication group tag (unique, integer > 0)
|
|
"""
|
|
rpc_messages = ""
|
|
tag = self.ui_eval_param(tag, "number", None)
|
|
for ag in self.iscsi_auth_groups:
|
|
if ag['tag'] == tag:
|
|
for secret in ag['secrets']:
|
|
try:
|
|
self.delete_secret(tag, secret['user'])
|
|
except JSONRPCException as e:
|
|
rpc_messages += e.message
|
|
if rpc_messages:
|
|
raise JSONRPCException(rpc_messages)
|
|
|
|
def summary(self):
|
|
return "Groups: %s" % len(self.iscsi_auth_groups), None
|
|
|
|
|
|
class UIISCSIAuthGroup(UINode):
|
|
def __init__(self, ag, parent):
|
|
UINode.__init__(self, "group" + str(ag['tag']), parent)
|
|
self.ag = ag
|
|
self.refresh()
|
|
|
|
def refresh(self):
|
|
self._children = set([])
|
|
for secret in self.ag['secrets']:
|
|
UISCSIAuthSecret(secret, self)
|
|
|
|
def summary(self):
|
|
return "Secrets: %s" % len(self.ag['secrets']), None
|
|
|
|
|
|
class UISCSIAuthSecret(UINode):
|
|
def __init__(self, secret, parent):
|
|
info_list = ["%s=%s" % (key, val)
|
|
for key, val in secret.items()]
|
|
info_list.sort(reverse=True)
|
|
info = ", ".join(info_list)
|
|
UINode.__init__(self, info, parent)
|
|
self.secret = secret
|
|
self.refresh()
|