From 5eaadad9218210ed2a616104a6e56665c38f9277 Mon Sep 17 00:00:00 2001
From: Adam Williamson <awilliam@redhat.com>
Date: Wed, 26 Oct 2016 20:42:53 -0700
Subject: [PATCH 2/4] iSCSI: Store auth info in NodeInfo tuples

This seems to have been overlooked in 9280eff7 . When we were
using libiscsi, the `node` objects were `PyIscsiNode` instances
(I think), with `getAuth` and `setAuth` methods that let you
read and set the authentication information for the node. We
used `getAuth` in `iScsiDiskDevice.dracut_setup_args()` to
include the auth information in the `netroot` arg. anaconda
also expects the `node` attribute of an `iScsiDiskDevice`
instance to be a `PyIscsiNode` and calls its `getAuth` method
to populate the kickstart data for the node.

When we ditched libiscsi and turned the `node` objects into
`NodeInfo` namedtuples, this was missed and not handled at all.
Both blivet and anaconda are still trying to call methods that
these node objects just don't have any more. The blivet call
was changed from `getAuth()` to `get_auth()` in 4e8f941b , but
apparently whoever did that didn't notice that neither method
exists at all for these objects any more...

Here's my attempt to fix this: basically, just stuff the auth
information into the `NodeInfo` instances when we log in. I
thought of several different ways to do this, but I think in
the end it always has to boil down to storing the auth details
on the node object when we log in, so let's just go with the
obvious way. We could mimic the `getAuth` and `setAuth` methods
pretty easily for 'compatibility', but it doesn't seem worth
it, we'd probably still be missing other bits of the interface.
---
 blivet/devices/disk.py | 11 +++++------
 blivet/iscsi.py        | 33 +++++++++++++++++++++++++++++++--
 2 files changed, 36 insertions(+), 8 deletions(-)

diff --git a/blivet/devices/disk.py b/blivet/devices/disk.py
index 6880e1e..acf31ee 100644
--- a/blivet/devices/disk.py
+++ b/blivet/devices/disk.py
@@ -452,12 +452,11 @@ class iScsiDiskDevice(DiskDevice, NetworkStorageDevice):
             address = "[%s]" % address
 
         netroot = "netroot=iscsi:"
-        auth = self.node.get_auth()
-        if auth:
-            netroot += "%s:%s" % (auth.username, auth.password)
-            if len(auth.reverse_username) or len(auth.reverse_password):
-                netroot += ":%s:%s" % (auth.reverse_username,
-                                       auth.reverse_password)
+        if self.node.username and self.node.password:
+            netroot += "%s:%s" % (self.node.username, self.node.password)
+            if self.node.r_username and self.node.r_password:
+                netroot += ":%s:%s" % (self.node.r_username,
+                                       self.node.r_password)
 
         iface_spec = ""
         if self.nic != "default":
diff --git a/blivet/iscsi.py b/blivet/iscsi.py
index 14c4b9a..1969fc8 100644
--- a/blivet/iscsi.py
+++ b/blivet/iscsi.py
@@ -66,10 +66,31 @@ def has_iscsi():
     return True
 
 
-NodeInfo = namedtuple("NodeInfo", ["name", "tpgt", "address", "port", "iface"])
 TargetInfo = namedtuple("TargetInfo", ["ipaddr", "port"])
 
 
+class NodeInfo(object):
+    """Simple representation of node information."""
+    def __init__(self, name, tpgt, address, port, iface):
+        self.name = name
+        self.tpgt = tpgt
+        self.address = address
+        self.port = port
+        self.iface = iface
+        # These get set by log_into_node, but *NOT* _login
+        self.username = None
+        self.password = None
+        self.r_username = None
+        self.r_password = None
+
+    @property
+    def conn_info(self):
+        """The 5-tuple of connection info (no auth info). This form
+        is useful for interacting with storaged.
+        """
+        return (self.name, self.tpgt, self.address, self.port, self.iface)
+
+
 class LoginInfo(object):
     def __init__(self, node, logged_in):
         self.node = node
@@ -239,7 +260,7 @@ class iSCSI(object):
             extra = dict()
         extra["node.startup"] = GLib.Variant("s", "automatic")
 
-        args = GLib.Variant("(sisisa{sv})", tuple(list(node_info) + [extra]))
+        args = GLib.Variant("(sisisa{sv})", node_info.conn_info + (extra,))
         self._call_initiator_method("Login", args)
 
     @storaged_iscsi_required(critical=False, eval_mode=util.EvalMode.onetime)
@@ -414,6 +435,14 @@ class iSCSI(object):
                      node.name, node.address, node.port, node.iface)
             if not self._mark_node_active(node):
                 log.error("iSCSI: node not found among discovered")
+            if username:
+                node.username = username
+            if password:
+                node.password = password
+            if r_username:
+                node.r_username = r_username
+            if r_password:
+                node.r_password = r_password
         except safe_dbus.DBusCallError as e:
             msg = str(e)
             log.warning("iSCSI: could not log into %s: %s", node.name, msg)
-- 
2.7.4

