Tempest: add auto-discovery test

Add test, which delete pre-created baremetal vms, and discovers it
via 'enroll' not_found_hook with default configuration.

Note, test contains workaround for working on infra, as infra 'tempest'
user doesn't have access to virsh, for running node and whitelisting
firewall rules on existing node, inspector's inspect api is used.

Change-Id: Ib0ec63295a496229b27552cd1bcf7e763c0c3e03
diff --git a/ironic_tempest_plugin/tests/manager.py b/ironic_tempest_plugin/tests/manager.py
index 6d0f7d2..445a15e 100644
--- a/ironic_tempest_plugin/tests/manager.py
+++ b/ironic_tempest_plugin/tests/manager.py
@@ -10,13 +10,16 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-
+import json
 import os
+import six
 import time
 
 import tempest
 from tempest import config
 from tempest.lib.common.api_version_utils import LATEST_MICROVERSION
+from tempest.lib import exceptions as lib_exc
+from tempest import test
 
 from ironic_inspector.test.inspector_tempest_plugin import exceptions
 from ironic_inspector.test.inspector_tempest_plugin.services import \
@@ -69,16 +72,28 @@
     def node_list(self):
         return self.baremetal_client.list_nodes()[1]['nodes']
 
+    def node_port_list(self, node_uuid):
+        return self.baremetal_client.list_node_ports(node_uuid)[1]['ports']
+
     def node_update(self, uuid, patch):
         return self.baremetal_client.update_node(uuid, **patch)
 
     def node_show(self, uuid):
         return self.baremetal_client.show_node(uuid)[1]
 
+    def node_delete(self, uuid):
+        return self.baremetal_client.delete_node(uuid)
+
     def node_filter(self, filter=lambda node: True, nodes=None):
         return self.item_filter(self.node_list, self.node_show,
                                 filter=filter, items=nodes)
 
+    def node_set_power_state(self, uuid, state):
+        self.baremetal_client.set_node_power_state(uuid, state)
+
+    def node_set_provision_state(self, uuid, state):
+        self.baremetal_client.set_node_provision_state(self, uuid, state)
+
     def hypervisor_stats(self):
         return (self.admin_manager.hypervisor_client.
                 show_hypervisor_statistics())
@@ -90,7 +105,12 @@
         self.introspection_client.purge_rules()
 
     def rule_import(self, rule_path):
-        self.introspection_client.import_rule(rule_path)
+        with open(rule_path, 'r') as fp:
+            rules = json.load(fp)
+        self.introspection_client.create_rules(rules)
+
+    def rule_import_from_dict(self, rules):
+        self.introspection_client.create_rules(rules)
 
     def introspection_status(self, uuid):
         return self.introspection_client.get_status(uuid)[1]
@@ -98,6 +118,9 @@
     def introspection_data(self, uuid):
         return self.introspection_client.get_data(uuid)[1]
 
+    def introspection_start(self, uuid):
+        return self.introspection_client.start_introspection(uuid)
+
     def baremetal_flavor(self):
         flavor_id = CONF.compute.flavor_ref
         flavor = self.flavors_client.show_flavor(flavor_id)['flavor']
@@ -118,11 +141,31 @@
     def terminate_instance(self, instance):
         return super(InspectorScenarioTest, self).terminate_instance(instance)
 
+    def wait_for_node(self, node_name):
+        def check_node():
+            try:
+                self.node_show(node_name)
+            except lib_exc.NotFound:
+                return False
+            return True
+
+        if not test.call_until_true(
+                check_node,
+                duration=CONF.baremetal_introspection.discovery_timeout,
+                sleep_for=20):
+            msg = ("Timed out waiting for node %s " % node_name)
+            raise lib_exc.TimeoutException(msg)
+
+        inspected_node = self.node_show(self.node_info['name'])
+        self.wait_for_introspection_finished(inspected_node['uuid'])
+
     # TODO(aarefiev): switch to call_until_true
     def wait_for_introspection_finished(self, node_ids):
         """Waits for introspection of baremetal nodes to finish.
 
         """
+        if isinstance(node_ids, six.text_type):
+            node_ids = [node_ids]
         start = int(time.time())
         not_introspected = {node_id for node_id in node_ids}