target_nodes=(pnode.primary, snode.primary))
+def TestFilters():
+ """Testing filter management via the remote API.
+
+ """
+
+ body = {
+ "priority": 10,
+ "predicates": [],
+ "action": "CONTINUE",
+ "reason": [(constants.OPCODE_REASON_SRC_USER,
+ "reason1",
+ utils.EpochNano())],
+ }
+
+ body1 = copy.deepcopy(body)
+ body1["priority"] = 20
+
+ # Query filters
+ _DoTests([("/2/filters", [], "GET", None)])
+
+ # Add a filter via POST and delete it again
+ uuid = _DoTests([("/2/filters", None, "POST", body)])[0]
+ uuid_module.UUID(uuid) # Check if uuid is a valid UUID
+ _DoTests([("/2/filters/%s" % uuid, lambda r: r is None, "DELETE", None)])
+
+ _DoTests([
+ # Check PUT-inserting a nonexistent filter with given UUID
+ ("/2/filters/%s" % uuid, lambda u: u == uuid, "PUT", body),
+ # Check PUT-inserting an existent filter with given UUID
+ ("/2/filters/%s" % uuid, lambda u: u == uuid, "PUT", body1),
+ # Check that the update changed the filter
+ ("/2/filters/%s" % uuid, lambda f: f["priority"] == 20, "GET", None),
+ # Delete it again
+ ("/2/filters/%s" % uuid, lambda r: r is None, "DELETE", None),
+ ])
+
+ # Add multiple filters, query and delete them
+ uuids = _DoTests([
+ ("/2/filters", None, "POST", body),
+ ("/2/filters", None, "POST", body),
+ ("/2/filters", None, "POST", body),
+ ])
+ _DoTests([("/2/filters", lambda rs: [r["uuid"] for r in rs] == uuids,
+ "GET", None)])
+ for u in uuids:
+ _DoTests([("/2/filters/%s" % u, lambda r: r is None, "DELETE", None)])
++
++
+ _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.")