Spdk/scripts/spdkcli/ui_node_iscsi.py
Seth Howell b7c4b7bc4e spdkcli: minor startup fixes
There are a couple of runtime errors in spdkcli that prevent it from
properly loading. One is the fact that it doesn't properly check to make
sure that specific subsystems are enabled before trying to load them.
The other is an apparently uninitialized variable in the iscsi object.

Change-Id: I458c6da71b60697b19c924308ac0e33a12f7a8a6
Signed-off-by: Seth Howell <seth.howell@intel.com>
Reviewed-on: https://review.gerrithub.io/430638
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Chandler-Test-Pool: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
2018-11-02 18:04:06 +00:00

637 lines
22 KiB
Python

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([])
for param, val in self.get_root().get_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)
try:
self.get_root().set_iscsi_discovery_auth(
chap_group=chap_group, disable_chap=disable_chap,
require_chap=require_chap, mutual_chap=mutual_chap)
except JSONRPCException as e:
self.shell.log.error(e.message)
self.refresh()
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().get_target_nodes())
self.scsi_devices = list(self.get_root().get_scsi_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 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)
try:
self.get_root().construct_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)
except JSONRPCException as e:
self.shell.log.error(e.message)
self.refresh()
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.
"""
if name is None:
for device in self.devices:
try:
self.get_root().delete_target_node(
target_node_name=device.device_name)
except JSONRPCException as e:
self.shell.log.error(e.message)
else:
try:
self.get_root().delete_target_node(target_node_name=name)
except JSONRPCException as e:
self.shell.log.error(e.message)
self.refresh()
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)
try:
self.get_root().target_node_add_lun(
name=name, bdev_name=bdev_name, lun_id=lun_id)
except JSONRPCException as e:
self.shell.log.error(e.message)
self.parent.refresh()
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)
try:
self.get_root().set_iscsi_target_node_auth(
name=self.device.device_name, chap_group=chap_group,
disable_chap=disable_chap,
require_chap=require_chap, mutual_chap=mutual_chap)
except JSONRPCException as e:
self.shell.log.error(e.message)
self.parent.refresh()
def ui_command_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)})
try:
self.get_root().add_pg_ig_maps(
pg_ig_maps=pg_ig_maps, name=self.device.device_name)
except JSONRPCException as e:
self.shell.log.error(e.message)
self.parent.refresh()
def ui_command_delete_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)})
try:
self.get_root().delete_pg_ig_maps(
pg_ig_maps=pg_ig_maps, name=self.device.device_name)
except JSONRPCException as e:
self.shell.log.error(e.message)
self.parent.refresh()
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 ui_command_create(self, tag, portal_list):
"""Add a portal group.
Args:
portals: List of portals e.g. ip:port@cpumask ip2:port2
tag: Portal group tag (unique, integer > 0)
"""
portals = []
print("portal_list: %s" % portal_list)
for portal in portal_list.strip().split(" "):
host = portal
cpumask = None
if "@" in portal:
host, cpumask = portal.split("@")
host, port = host.rsplit(":", -1)
portals.append({'host': host, 'port': port})
if cpumask:
portals[-1]['cpumask'] = cpumask
tag = self.ui_eval_param(tag, "number", None)
try:
self.get_root().construct_portal_group(tag=tag, portals=portals)
except JSONRPCException as e:
self.shell.log.error(e.message)
self.refresh()
def ui_command_delete(self, tag):
"""Delete a portal group with given tag (unique, integer > 0))"""
tag = self.ui_eval_param(tag, "number", None)
try:
self.get_root().delete_portal_group(tag=tag)
except JSONRPCException as e:
self.shell.log.error(e.message)
self.refresh()
def refresh(self):
self._children = set([])
self.pgs = list(self.get_root().get_portal_groups())
for pg in self.pgs:
UIPortalGroup(pg, self)
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'], portal['cpumask'], self)
def summary(self):
return "Portals: %d" % len(self.pg.portals), None
class UIPortal(UINode):
def __init__(self, host, port, cpumask, parent):
UINode.__init__(self, "host=%s, port=%s, cpumask=%s" % (
host, port, cpumask), parent)
self.refresh()
class UIInitiatorGroups(UINode):
def __init__(self, parent):
UINode.__init__(self, "initiator_groups", parent)
self.refresh()
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)
try:
self.get_root().construct_initiator_group(
tag=tag, initiators=initiator_list.split(" "),
netmasks=netmask_list.split(" "))
except JSONRPCException as e:
self.shell.log.error(e.message)
self.refresh()
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)
try:
self.get_root().delete_initiator_group(tag=tag)
except JSONRPCException as e:
self.shell.log.error(e.message)
self.refresh()
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)
try:
self.get_root().add_initiators_to_initiator_group(
tag=tag, initiators=initiators.split(" "),
netmasks=netmasks.split(" "))
except JSONRPCException as e:
self.shell.log.error(e.message)
self.refresh()
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(" ")
try:
self.get_root().delete_initiators_from_initiator_group(
tag=tag, initiators=initiators,
netmasks=netmasks)
except JSONRPCException as e:
self.shell.log.error(e.message)
self.refresh()
def refresh(self):
self._children = set([])
self.igs = list(self.get_root().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().get_iscsi_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.iteritems():
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().get_iscsi_auth_groups())
if self.iscsi_auth_groups is None:
self.iscsi_auth_groups = []
for ag in self.iscsi_auth_groups:
UIISCSIAuthGroup(ag, self)
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(",")]
try:
self.get_root().add_iscsi_auth_group(tag=tag, secrets=secrets)
except JSONRPCException as e:
self.shell.log.error(e.message)
self.refresh()
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)
try:
self.get_root().delete_iscsi_auth_group(tag=tag)
except JSONRPCException as e:
self.shell.log.error(e.message)
self.refresh()
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)
try:
self.get_root().add_secret_to_iscsi_auth_group(
tag=tag, user=user, secret=secret,
muser=muser, msecret=msecret)
except JSONRPCException as e:
self.shell.log.error(e.message)
self.refresh()
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)
try:
self.get_root().delete_secret_from_iscsi_auth_group(
tag=tag, user=user)
except JSONRPCException as e:
self.shell.log.error(e.message)
self.refresh()
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 = ", ".join("%s=%s" % (key, val)
for key, val in secret.items())
UINode.__init__(self, info, parent)
self.secret = secret
self.refresh()