Merge branch 'stable-2.11' into stable-2.12
authorHrvoje Ribicic <riba@google.com>
Tue, 1 Dec 2015 15:57:49 +0000 (15:57 +0000)
committerHrvoje Ribicic <riba@google.com>
Tue, 1 Dec 2015 16:38:50 +0000 (16:38 +0000)
* stable-2.11
  (no changes)

* stable-2.10
  (no changes)

* stable-2.9
  QA: Ensure the DRBD secret is not retrievable via RAPI
  Redact the DRBD secret in instance queries
  Do not attempt to use the DRBD secret in gnt-instance info

Conflicts:
  lib/client/gnt_instance.py - taken the 2.11 version, with explicit
                               parameter use
  qa/qa_rapi.py - merged imports, resolved trivial conflict

Signed-off-by: Hrvoje Ribicic <riba@google.com>
Reviewed-by: Klaus Aehlig <aehlig@google.com>

1  2 
lib/client/gnt_instance.py
lib/cmdlib/instance_query.py
qa/ganeti-qa.py
qa/qa_rapi.py

Simple merge
Simple merge
diff --cc qa/ganeti-qa.py
Simple merge
diff --cc qa/qa_rapi.py
@@@ -61,12 -59,11 +61,13 @@@ import qa_erro
  import qa_logging
  import qa_utils
  
+ from qa_instance import GetInstanceInfo
 +from qa_instance import IsDiskReplacingSupported
  from qa_instance import IsFailoverSupported
  from qa_instance import IsMigrationSupported
 -from qa_instance import IsDiskReplacingSupported
 -from qa_utils import (AssertEqual, AssertIn, AssertMatch, StartLocalCommand)
 +from qa_job_utils import RunWithLocks
 +from qa_utils import (AssertEqual, AssertIn, AssertMatch, AssertCommand,
 +                      StartLocalCommand)
  from qa_utils import InstanceCheck, INST_DOWN, INST_UP, FIRST_ARG
  
  
@@@ -1237,17 -1045,88 +1238,71 @@@ def TestInterClusterInstanceMove(src_in
      # (which will be ignored)
      snode = tnode
    pnode = inodes[0]
 -  # note: pnode:snode are the *current* nodes, so we move it first to
 -  # tnode:pnode, then back to pnode:snode
 -  for current_src_inst, current_dest_inst, target_pnode, target_snode in \
 -    [(src_instance.name, dest_instance.name, tnode.primary, pnode.primary),
 -     (dest_instance.name, src_instance.name, pnode.primary, snode.primary)]:
 -    cmd = [
 -      "../tools/move-instance",
 -      "--verbose",
 -      "--src-ca-file=%s" % _rapi_ca.name,
 -      "--src-username=%s" % _rapi_username,
 -      "--src-password-file=%s" % rapi_pw_file.name,
 -      "--dest-instance-name=%s" % current_dest_inst,
 -      "--dest-primary-node=%s" % target_pnode,
 -      "--dest-secondary-node=%s" % target_snode,
 -      "--net=0:mac=%s" % constants.VALUE_GENERATE,
 -      master.primary,
 -      master.primary,
 -      current_src_inst,
 -      ]
 -
 -    # Some uses of this test might require that RAPI-only commands are used,
 -    # and the checks are command-line based.
 -
 -    if perform_checks:
 -      qa_utils.RunInstanceCheck(current_dest_inst, False)
 -
 -    AssertEqual(StartLocalCommand(cmd).wait(), 0)
  
 -    if perform_checks:
 -      qa_utils.RunInstanceCheck(current_src_inst, False)
 -      qa_utils.RunInstanceCheck(current_dest_inst, True)
 +  # pnode:snode are the *current* nodes, and the first move is an
 +  # iallocator-guided move outside of pnode. The node lock for the pnode
 +  # assures that this happens, and while we cannot be sure where the instance
 +  # will land, it is a real move.
 +  locks = {locking.LEVEL_NODE: [pnode.primary]}
 +  RunWithLocks(_InvokeMoveInstance, locks, 600.0, False,
 +               dest_instance.name, src_instance.name, rapi_pw_file.name,
 +               master.primary, perform_checks)
 +
 +  # And then back to pnode:snode
 +  _InvokeMoveInstance(src_instance.name, dest_instance.name, rapi_pw_file.name,
 +                      master.primary, perform_checks,
 +                      target_nodes=(pnode.primary, snode.primary))
+ _DRBD_SECRET_RE = re.compile('shared-secret.*"([0-9A-Fa-f]+)"')
+ def _RetrieveSecret(instance, pnode):
+   """Retrieves the DRBD secret given an instance object and the primary node.
+   @type instance: L{qa_config._QaInstance}
+   @type pnode: L{qa_config._QaNode}
+   @rtype: string
+   """
+   instance_info = GetInstanceInfo(instance.name)
+   # We are interested in only the first disk on the primary
+   drbd_minor = instance_info["drbd-minors"][pnode.primary][0]
+   # This form should work for all DRBD versions
+   drbd_command = ("drbdsetup show %d; drbdsetup %d show || true" %
+                   (drbd_minor, drbd_minor))
+   instance_drbd_info = \
+     qa_utils.GetCommandOutput(pnode.primary, drbd_command)
+   match_obj = _DRBD_SECRET_RE.search(instance_drbd_info)
+   if match_obj is None:
+     raise qa_error.Error("Could not retrieve DRBD secret for instance %s from"
+                          " node %s." % (instance.name, pnode.primary))
+   return match_obj.groups(0)[0]
+ def TestInstanceDataCensorship(instance, inodes):
+   """Test protection of sensitive instance data."""
+   if instance.disk_template != constants.DT_DRBD8:
+     print qa_utils.FormatInfo("Only the DRBD secret is a sensitive parameter"
+                               " right now, skipping for non-DRBD instance.")
+     return
+   drbd_secret = _RetrieveSecret(instance, inodes[0])
+   job_id = _rapi_client.GetInstanceInfo(instance.name)
+   if not _rapi_client.WaitForJobCompletion(job_id):
+     raise qa_error.Error("Could not fetch instance info for instance %s" %
+                          instance.name)
+   info_dict = _rapi_client.GetJobStatus(job_id)
+   if drbd_secret in str(info_dict):
+     print qa_utils.FormatInfo("DRBD secret: %s" % drbd_secret)
+     print qa_utils.FormatInfo("Retrieved data\n%s" % str(info_dict))
+     raise qa_error.Error("Found DRBD secret in contents of RAPI instance info"
+                          " call; see above.")