diff --git a/driver-requirements.txt b/driver-requirements.txt
index 711c3379e2..b5a418fdc7 100644
--- a/driver-requirements.txt
+++ b/driver-requirements.txt
@@ -8,7 +8,7 @@ proliantutils>=2.1.11
 pyghmi>=0.8.0
 pysnmp
 python-ironic-inspector-client>=1.5.0
-python-oneviewclient<3.0.0,>=2.0.2
+python-oneviewclient<3.0.0,>=2.5.1
 python-scciclient>=0.4.0
 python-seamicroclient>=0.4.0
 UcsSdk==0.8.2.2
diff --git a/ironic/drivers/fake.py b/ironic/drivers/fake.py
index 996c152a57..124e383545 100644
--- a/ironic/drivers/fake.py
+++ b/ironic/drivers/fake.py
@@ -354,3 +354,4 @@ class FakeOneViewDriver(base.BaseDriver):
         self.management = oneview_management.OneViewManagement()
         self.boot = fake.FakeBoot()
         self.deploy = fake.FakeDeploy()
+        self.inspect = fake.FakeInspect()
diff --git a/ironic/drivers/modules/oneview/common.py b/ironic/drivers/modules/oneview/common.py
index 2e09c3f03a..f971036be7 100644
--- a/ironic/drivers/modules/oneview/common.py
+++ b/ironic/drivers/modules/oneview/common.py
@@ -155,13 +155,12 @@ def validate_oneview_resources_compatibility(task):
     including server_hardware_uri, server_hardware_type_uri,
     server_profile_template_uri, enclosure_group_uri and node ports. Also
     verifies if a Server Profile is applied to the Server Hardware the node
-    represents. If any validation fails, python-oneviewclient will raise
-    an appropriate OneViewException.
+    represents when in pre-allocation model. If any validation fails,
+    python-oneviewclient will raise an appropriate OneViewException.
 
     :param: task: a TaskManager instance containing the node to act on.
     """
 
-    node = task.node
     node_ports = task.ports
 
     oneview_info = get_oneview_info(task.node)
@@ -169,13 +168,15 @@ def validate_oneview_resources_compatibility(task):
     try:
         oneview_client = get_oneview_client()
 
-        oneview_client.validate_node_server_hardware(
-            oneview_info, node.properties.get('memory_mb'),
-            node.properties.get('cpus')
-        )
+        oneview_client.validate_node_server_profile_template(oneview_info)
         oneview_client.validate_node_server_hardware_type(oneview_info)
         oneview_client.validate_node_enclosure_group(oneview_info)
-        oneview_client.validate_node_server_profile_template(oneview_info)
+
+        oneview_client.validate_node_server_hardware(
+            oneview_info,
+            task.node.properties.get('memory_mb'),
+            task.node.properties.get('cpus')
+        )
 
         # NOTE(thiagop): Support to pre-allocation will be dropped in the Pike
         # release
@@ -183,12 +184,12 @@ def validate_oneview_resources_compatibility(task):
             oneview_client.is_node_port_mac_compatible_with_server_hardware(
                 oneview_info, node_ports
             )
-            oneview_client.validate_node_server_profile_template(oneview_info)
         else:
             oneview_client.check_server_profile_is_applied(oneview_info)
             oneview_client.is_node_port_mac_compatible_with_server_profile(
                 oneview_info, node_ports
             )
+
     except oneview_exceptions.OneViewException as oneview_exc:
         msg = (_("Error validating node resources with OneView: %s") %
                oneview_exc)
diff --git a/ironic/drivers/modules/oneview/deploy.py b/ironic/drivers/modules/oneview/deploy.py
index 19262ca4c9..72c23f2e19 100644
--- a/ironic/drivers/modules/oneview/deploy.py
+++ b/ironic/drivers/modules/oneview/deploy.py
@@ -211,6 +211,14 @@ class OneViewIscsiDeploy(iscsi_deploy.ISCSIDeploy, OneViewPeriodicTasks):
     def get_properties(self):
         deploy_utils.get_properties()
 
+    def validate(self, task):
+        common.verify_node_info(task.node)
+        try:
+            common.validate_oneview_resources_compatibility(task)
+        except exception.OneViewError as oneview_exc:
+            raise exception.InvalidParameterValue(oneview_exc)
+        super(OneViewIscsiDeploy, self).validate(task)
+
     def prepare(self, task):
         if common.is_dynamic_allocation_enabled(task.node):
             deploy_utils.prepare(task)
@@ -241,6 +249,14 @@ class OneViewAgentDeploy(agent.AgentDeploy, OneViewPeriodicTasks):
     def get_properties(self):
         deploy_utils.get_properties()
 
+    def validate(self, task):
+        common.verify_node_info(task.node)
+        try:
+            common.validate_oneview_resources_compatibility(task)
+        except exception.OneViewError as oneview_exc:
+            raise exception.InvalidParameterValue(oneview_exc)
+        super(OneViewAgentDeploy, self).validate(task)
+
     def prepare(self, task):
         if common.is_dynamic_allocation_enabled(task.node):
             deploy_utils.prepare(task)
diff --git a/ironic/drivers/modules/oneview/deploy_utils.py b/ironic/drivers/modules/oneview/deploy_utils.py
index b96f9885be..d10db36aff 100644
--- a/ironic/drivers/modules/oneview/deploy_utils.py
+++ b/ironic/drivers/modules/oneview/deploy_utils.py
@@ -14,11 +14,13 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import operator
+
 from oslo_log import log as logging
 from oslo_utils import importutils
 
 from ironic.common import exception
-from ironic.common.i18n import _, _LE, _LI, _LW
+from ironic.common.i18n import _, _LE, _LI
 from ironic.common import states
 from ironic.drivers.modules.oneview import common
 
@@ -54,7 +56,7 @@ def prepare(task):
                 {"instance_name": instance_display_name,
                  "instance_uuid": instance_uuid}
             )
-            _allocate_server_hardware_to_ironic(task.node, server_profile_name)
+            allocate_server_hardware_to_ironic(task.node, server_profile_name)
         except exception.OneViewError as e:
             raise exception.InstanceDeployFailure(node=task.node.uuid,
                                                   reason=e)
@@ -74,7 +76,7 @@ def tear_down(task):
 
     """
     try:
-        _deallocate_server_hardware_from_ironic(task.node)
+        deallocate_server_hardware_from_ironic(task.node)
     except exception.OneViewError as e:
         raise exception.InstanceDeployFailure(node=task.node.uuid, reason=e)
 
@@ -94,7 +96,7 @@ def prepare_cleaning(task):
     """
     try:
         server_profile_name = "Ironic Cleaning [%s]" % task.node.uuid
-        _allocate_server_hardware_to_ironic(task.node, server_profile_name)
+        allocate_server_hardware_to_ironic(task.node, server_profile_name)
     except exception.OneViewError as e:
         oneview_error = common.SERVER_HARDWARE_ALLOCATION_ERROR
         driver_internal_info = task.node.driver_internal_info
@@ -119,11 +121,29 @@ def tear_down_cleaning(task):
 
     """
     try:
-        _deallocate_server_hardware_from_ironic(task.node)
+        deallocate_server_hardware_from_ironic(task.node)
     except exception.OneViewError as e:
         raise exception.NodeCleaningFailure(node=task.node.uuid, reason=e)
 
 
+def _is_node_in_use(server_hardware, applied_sp_uri, by_oneview=False):
+    """Check if node is in use by ironic or by OneView.
+
+    :param by_oneview: Boolean value. True when want to verify if node is in
+                       use by OneView. False to verify if node is in use by
+                       ironic.
+    :param node: an ironic node object
+    :returns: Boolean value. True if by_oneview param is also True and node is
+              in use by OneView, False otherwise. True if by_oneview param is
+              False and node is in use by ironic, False otherwise.
+
+    """
+
+    operation = operator.ne if by_oneview else operator.eq
+    return (server_hardware.server_profile_uri not in (None, '') and
+            operation(applied_sp_uri, server_hardware.server_profile_uri))
+
+
 def is_node_in_use_by_oneview(node):
     """Check if node is in use by OneView user.
 
@@ -131,6 +151,54 @@ def is_node_in_use_by_oneview(node):
     :returns: Boolean value. True if node is in use by OneView,
               False otherwise.
     :raises OneViewError: if not possible to get OneView's informations
+            for the given node, if not possible to retrieve Server Hardware
+            from OneView.
+
+    """
+
+    positive = _("Node '%s' is in use by OneView.") % node.uuid
+    negative = _("Node '%s' is not in use by OneView.") % node.uuid
+
+    def predicate(server_hardware, applied_sp_uri):
+        # Check if Profile exists in Oneview and it is different of the one
+        # applied by ironic
+        return _is_node_in_use(server_hardware, applied_sp_uri,
+                               by_oneview=True)
+
+    return _check_applied_server_profile(node, predicate, positive, negative)
+
+
+def is_node_in_use_by_ironic(node):
+    """Check if node is in use by ironic in OneView.
+
+    :param node: an ironic node object
+    :returns: Boolean value. True if node is in use by ironic,
+              False otherwise.
+    :raises OneViewError: if not possible to get OneView's information
+            for the given node, if not possible to retrieve Server Hardware
+            from OneView.
+
+    """
+
+    positive = _("Node '%s' is in use by Ironic.") % node.uuid
+    negative = _("Node '%s' is not in use by Ironic.") % node.uuid
+
+    def predicate(server_hardware, applied_sp_uri):
+        # Check if Profile exists in Oneview and it is equals of the one
+        # applied by ironic
+        return _is_node_in_use(server_hardware, applied_sp_uri,
+                               by_oneview=False)
+
+    return _check_applied_server_profile(node, predicate, positive, negative)
+
+
+def _check_applied_server_profile(node, predicate, positive, negative):
+    """Check if node is in use by ironic in OneView.
+
+    :param node: an ironic node object
+    :returns: Boolean value. True if node is in use by ironic,
+              False otherwise.
+    :raises OneViewError: if not possible to get OneView's information
              for the given node, if not possible to retrieve Server Hardware
              from OneView.
 
@@ -157,24 +225,14 @@ def is_node_in_use_by_oneview(node):
         node.driver_info.get('applied_server_profile_uri')
     )
 
-    # Check if Profile exists in Oneview and it is different of the one
-    # applied by ironic
-    if (server_hardware.server_profile_uri not in (None, '') and
-            applied_sp_uri != server_hardware.server_profile_uri):
-
-        LOG.warning(_LW("Node %s is already in use by OneView."),
-                    node.uuid)
-
-        return True
+    result = predicate(server_hardware, applied_sp_uri)
 
+    if result:
+        LOG.debug(positive)
     else:
-        LOG.debug(_(
-            "Hardware %(hardware_uri)s is free for use by "
-            "ironic on node %(node_uuid)s."),
-            {"hardware_uri": server_hardware.uri,
-             "node_uuid": node.uuid})
+        LOG.debug(negative)
 
-        return False
+    return result
 
 
 def _add_applied_server_profile_uri_field(node, applied_profile):
@@ -201,7 +259,7 @@ def _del_applied_server_profile_uri_field(node):
     node.save()
 
 
-def _allocate_server_hardware_to_ironic(node, server_profile_name):
+def allocate_server_hardware_to_ironic(node, server_profile_name):
     """Allocate Server Hardware to ironic.
 
     :param node: an ironic node object
@@ -276,7 +334,7 @@ def _allocate_server_hardware_to_ironic(node, server_profile_name):
         raise exception.OneViewError(error=msg)
 
 
-def _deallocate_server_hardware_from_ironic(node):
+def deallocate_server_hardware_from_ironic(node):
     """Deallocate Server Hardware from ironic.
 
     :param node: an ironic node object
diff --git a/ironic/drivers/modules/oneview/inspect.py b/ironic/drivers/modules/oneview/inspect.py
new file mode 100644
index 0000000000..dde2e65834
--- /dev/null
+++ b/ironic/drivers/modules/oneview/inspect.py
@@ -0,0 +1,98 @@
+# Copyright 2016 Hewlett Packard Enterprise Development LP.
+# Copyright 2016 Universidade Federal de Campina Grande
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from futurist import periodics
+from oslo_log import log as logging
+from oslo_utils import importutils
+
+from ironic.common import exception
+from ironic.common import states
+from ironic.conductor import task_manager
+from ironic.drivers.modules import inspector
+from ironic.drivers.modules.oneview import common
+from ironic.drivers.modules.oneview import deploy_utils
+
+from ironic.conf import CONF
+
+LOG = logging.getLogger(__name__)
+
+oneview_exception = importutils.try_import('oneview_client.exceptions')
+oneview_utils = importutils.try_import('oneview_client.utils')
+
+
+class OneViewInspect(inspector.Inspector):
+    """Interface for in band inspection."""
+
+    def get_properties(self):
+        return common.COMMON_PROPERTIES
+
+    def validate(self, task):
+        """Checks required info on 'driver_info' and validates node with OneView
+
+        Validates whether the 'driver_info' property of the supplied
+        task's node contains the required info such as server_hardware_uri,
+        server_hardware_type, server_profile_template_uri and
+        enclosure_group_uri. Also, checks if the server profile of the node is
+        applied, if NICs are valid for the server profile of the node.
+
+        :param task: a task from TaskManager.
+        :raises: InvalidParameterValue if parameters set are inconsistent with
+                 resources in OneView
+        """
+
+        common.verify_node_info(task.node)
+
+        try:
+            common.validate_oneview_resources_compatibility(task)
+        except exception.OneViewError as oneview_exc:
+            raise exception.InvalidParameterValue(oneview_exc)
+
+    def inspect_hardware(self, task):
+        profile_name = 'Ironic Inspecting [%s]' % task.node.uuid
+        deploy_utils.allocate_server_hardware_to_ironic(
+            task.node, profile_name
+        )
+        return super(OneViewInspect, self).inspect_hardware(task)
+
+    @periodics.periodic(spacing=CONF.inspector.status_check_period,
+                        enabled=CONF.inspector.enabled)
+    def _periodic_check_result(self, manager, context):
+        filters = {'provision_state': states.INSPECTING}
+        node_iter = manager.iter_nodes(filters=filters)
+
+        for node_uuid, driver in node_iter:
+            if driver in [common.AGENT_PXE_ONEVIEW,
+                          common.ISCSI_PXE_ONEVIEW]:
+                try:
+                    lock_purpose = 'checking hardware inspection status'
+                    with task_manager.acquire(context, node_uuid,
+                                              shared=True,
+                                              purpose=lock_purpose) as task:
+                        self._check_status(task)
+                except (exception.NodeLocked, exception.NodeNotFound):
+                    continue
+
+    def _check_status(self, task):
+        state_before = task.node.provision_state
+        result = inspector._check_status(task)
+        state_after = task.node.provision_state
+
+        # inspection finished
+        if (state_before == states.INSPECTING and
+            state_after in [states.MANAGEABLE, states.INSPECTFAIL]):
+            deploy_utils.deallocate_server_hardware_from_ironic(task.node)
+
+        return result
diff --git a/ironic/drivers/modules/oneview/management.py b/ironic/drivers/modules/oneview/management.py
index 2f48323403..b0bf2941e0 100644
--- a/ironic/drivers/modules/oneview/management.py
+++ b/ironic/drivers/modules/oneview/management.py
@@ -23,6 +23,7 @@ from ironic.common.i18n import _
 from ironic.conductor import task_manager
 from ironic.drivers import base
 from ironic.drivers.modules.oneview import common
+from ironic.drivers.modules.oneview import deploy_utils
 
 LOG = logging.getLogger(__name__)
 
@@ -65,6 +66,10 @@ class OneViewManagement(base.ManagementInterface):
 
         try:
             common.validate_oneview_resources_compatibility(task)
+
+            if not deploy_utils.is_node_in_use_by_ironic(task.node):
+                raise exception.InvalidParameterValue(
+                    _("Node %s is not in use by ironic.") % task.node.uuid)
         except exception.OneViewError as oneview_exc:
             raise exception.InvalidParameterValue(oneview_exc)
 
diff --git a/ironic/drivers/oneview.py b/ironic/drivers/oneview.py
index 4d5992d2b1..941e62d9d4 100644
--- a/ironic/drivers/oneview.py
+++ b/ironic/drivers/oneview.py
@@ -24,6 +24,7 @@ from ironic.drivers import base
 from ironic.drivers.modules import iscsi_deploy
 from ironic.drivers.modules.oneview import common
 from ironic.drivers.modules.oneview import deploy
+from ironic.drivers.modules.oneview import inspect
 from ironic.drivers.modules.oneview import management
 from ironic.drivers.modules.oneview import power
 from ironic.drivers.modules.oneview import vendor
@@ -55,6 +56,8 @@ class AgentPXEOneViewDriver(base.BaseDriver):
         self.boot = pxe.PXEBoot()
         self.deploy = deploy.OneViewAgentDeploy()
         self.vendor = vendor.AgentVendorInterface()
+        self.inspect = inspect.OneViewInspect.create_if_enabled(
+            'AgentPXEOneViewDriver')
 
 
 class ISCSIPXEOneViewDriver(base.BaseDriver):
@@ -82,3 +85,5 @@ class ISCSIPXEOneViewDriver(base.BaseDriver):
         self.boot = pxe.PXEBoot()
         self.deploy = deploy.OneViewIscsiDeploy()
         self.vendor = iscsi_deploy.VendorPassthru()
+        self.inspect = inspect.OneViewInspect.create_if_enabled(
+            'ISCSIPXEOneViewDriver')
diff --git a/ironic/tests/unit/drivers/modules/oneview/test_common.py b/ironic/tests/unit/drivers/modules/oneview/test_common.py
index 6eab2690af..7a3daf3f17 100644
--- a/ironic/tests/unit/drivers/modules/oneview/test_common.py
+++ b/ironic/tests/unit/drivers/modules/oneview/test_common.py
@@ -237,8 +237,6 @@ class OneViewCommonTestCase(db_base.DbTestCase):
         oneview_client = mock_get_ov_client()
         with task_manager.acquire(self.context, self.node.uuid) as task:
             common.validate_oneview_resources_compatibility(task)
-            self.assertTrue(
-                oneview_client.validate_node_server_hardware.called)
             self.assertTrue(
                 oneview_client.validate_node_server_hardware_type.called)
             self.assertTrue(
@@ -264,15 +262,14 @@ class OneViewCommonTestCase(db_base.DbTestCase):
         """Validate compatibility of resources for Dynamic Allocation model.
 
         1) Set 'dynamic_allocation' flag as True on node's driver_info
-        2) Check validate_node_server_hardware method is called
-        3) Check validate_node_server_hardware_type method is called
-        4) Check validate_node_enclosure_group method is called
-        5) Check validate_node_server_profile_template method is called
-        6) Check is_node_port_mac_compatible_with_server_hardware method
+        2) Check validate_node_server_hardware_type method is called
+        3) Check validate_node_enclosure_group method is called
+        4) Check validate_node_server_profile_template method is called
+        5) Check is_node_port_mac_compatible_with_server_hardware method
            is called
-        7) Check validate_node_server_profile_template method is called
-        8) Check check_server_profile_is_applied method is not called
-        9) Check is_node_port_mac_compatible_with_server_profile method is
+        6) Check validate_node_server_profile_template method is called
+        7) Check check_server_profile_is_applied method is not called
+        8) Check is_node_port_mac_compatible_with_server_profile method is
            not called
 
         """
@@ -283,8 +280,6 @@ class OneViewCommonTestCase(db_base.DbTestCase):
             task.node.driver_info = driver_info
 
             common.validate_oneview_resources_compatibility(task)
-            self.assertTrue(
-                oneview_client.validate_node_server_hardware.called)
             self.assertTrue(
                 oneview_client.validate_node_server_hardware_type.called)
             self.assertTrue(
diff --git a/ironic/tests/unit/drivers/modules/oneview/test_deploy_utils.py b/ironic/tests/unit/drivers/modules/oneview/test_deploy_utils.py
index 695ed7fb15..a291765b71 100644
--- a/ironic/tests/unit/drivers/modules/oneview/test_deploy_utils.py
+++ b/ironic/tests/unit/drivers/modules/oneview/test_deploy_utils.py
@@ -242,6 +242,43 @@ class OneViewDeployUtilsTestCase(db_base.DbTestCase):
                 deploy_utils.is_node_in_use_by_oneview(task.node)
             )
 
+    # Tests for is_node_in_use_by_oneview
+    def test_is_node_in_use_by_ironic(self, mock_get_ov_client):
+        """Node has a Server Profile applied by ironic.
+
+        """
+        fake_sh = oneview_models.ServerHardware()
+        fake_sh.server_profile_uri = "same/applied_sp_uri/"
+
+        ov_client = mock_get_ov_client.return_value
+        ov_client.get_server_hardware_by_uuid.return_value = fake_sh
+
+        with task_manager.acquire(self.context, self.node.uuid) as task:
+            driver_info = task.node.driver_info
+            driver_info['dynamic_allocation'] = True
+            driver_info['applied_server_profile_uri'] = 'same/applied_sp_uri/'
+            task.node.driver_info = driver_info
+            self.assertTrue(
+                deploy_utils.is_node_in_use_by_ironic(task.node)
+            )
+
+    def test_is_node_in_use_by_ironic_no_server_profile(
+        self, mock_get_ov_client
+    ):
+        """Node has no Server Profile.
+
+        """
+        fake_sh = oneview_models.ServerHardware()
+        fake_sh.server_profile_uri = None
+
+        ov_client = mock_get_ov_client.return_value
+        ov_client.get_server_hardware_by_uuid.return_value = fake_sh
+
+        with task_manager.acquire(self.context, self.node.uuid) as task:
+            self.assertFalse(
+                deploy_utils.is_node_in_use_by_ironic(task.node)
+            )
+
     # Tests for _add_applied_server_profile_uri_field
     def test__add_applied_server_profile_uri_field(self, mock_get_ov_client):
         """Checks if applied_server_profile_uri was added to driver_info.
@@ -276,9 +313,9 @@ class OneViewDeployUtilsTestCase(db_base.DbTestCase):
             self.assertNotIn('applied_server_profile_uri',
                              task.node.driver_info)
 
-    # Tests for _allocate_server_hardware_to_ironic
+    # Tests for allocate_server_hardware_to_ironic
     @mock.patch.object(objects.Node, 'save')
-    def test__allocate_server_hardware_to_ironic(
+    def test_allocate_server_hardware_to_ironic(
         self, mock_node_save, mock_get_ov_client
     ):
         """Checks if a Server Profile was created and its uri is in driver_info.
@@ -291,7 +328,7 @@ class OneViewDeployUtilsTestCase(db_base.DbTestCase):
         mock_get_ov_client.return_value = ov_client
 
         with task_manager.acquire(self.context, self.node.uuid) as task:
-            deploy_utils._allocate_server_hardware_to_ironic(
+            deploy_utils.allocate_server_hardware_to_ironic(
                 task.node, 'serverProfileName'
             )
             self.assertTrue(ov_client.clone_template_and_apply.called)
@@ -300,7 +337,7 @@ class OneViewDeployUtilsTestCase(db_base.DbTestCase):
     @mock.patch.object(objects.Node, 'save')
     @mock.patch.object(deploy_utils,
                        '_del_applied_server_profile_uri_field')
-    def test__allocate_server_hardware_to_ironic_node_has_server_profile(
+    def test_allocate_server_hardware_to_ironic_node_has_server_profile(
         self, mock_delete_applied_sp, mock_node_save, mock_get_ov_client
     ):
         """Tests server profile allocation when applied_server_profile_uri exists.
@@ -321,14 +358,14 @@ class OneViewDeployUtilsTestCase(db_base.DbTestCase):
             driver_info['applied_server_profile_uri'] = 'any/applied_sp_uri/'
             task.node.driver_info = driver_info
 
-            deploy_utils._allocate_server_hardware_to_ironic(
+            deploy_utils.allocate_server_hardware_to_ironic(
                 task.node, 'serverProfileName'
             )
             self.assertTrue(mock_delete_applied_sp.called)
 
-    # Tests for _deallocate_server_hardware_from_ironic
+    # Tests for deallocate_server_hardware_from_ironic
     @mock.patch.object(objects.Node, 'save')
-    def test__deallocate_server_hardware_from_ironic(
+    def test_deallocate_server_hardware_from_ironic(
         self, mock_node_save, mock_get_ov_client
     ):
         ov_client = mock_get_ov_client.return_value
@@ -342,7 +379,7 @@ class OneViewDeployUtilsTestCase(db_base.DbTestCase):
             driver_info['applied_server_profile_uri'] = 'any/applied_sp_uri/'
             task.node.driver_info = driver_info
 
-            deploy_utils._deallocate_server_hardware_from_ironic(task.node)
+            deploy_utils.deallocate_server_hardware_from_ironic(task.node)
             self.assertTrue(ov_client.delete_server_profile.called)
             self.assertTrue(
                 'applied_server_profile_uri' not in task.node.driver_info
diff --git a/ironic/tests/unit/drivers/modules/oneview/test_inspect.py b/ironic/tests/unit/drivers/modules/oneview/test_inspect.py
new file mode 100644
index 0000000000..4ffb5de13f
--- /dev/null
+++ b/ironic/tests/unit/drivers/modules/oneview/test_inspect.py
@@ -0,0 +1,95 @@
+# Copyright 2016 Hewlett Packard Enterprise Development LP.
+# Copyright 2016 Universidade Federal de Campina Grande
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+import mock
+
+from ironic.conductor import task_manager
+from ironic.drivers.modules.oneview import common as oneview_common
+from ironic.drivers.modules.oneview import deploy_utils
+from ironic.tests.unit.conductor import mgr_utils
+from ironic.tests.unit.db import base as db_base
+from ironic.tests.unit.db import utils as db_utils
+from ironic.tests.unit.objects import utils as obj_utils
+
+
+class AgentPXEOneViewInspectTestCase(db_base.DbTestCase):
+
+    def setUp(self):
+        super(AgentPXEOneViewInspectTestCase, self).setUp()
+        self.config(enabled=True, group='inspector')
+        mgr_utils.mock_the_extension_manager(driver="agent_pxe_oneview")
+        self.node = obj_utils.create_test_node(
+            self.context, driver='agent_pxe_oneview',
+            properties=db_utils.get_test_oneview_properties(),
+            driver_info=db_utils.get_test_oneview_driver_info(),
+        )
+
+    def test_get_properties(self):
+        expected = oneview_common.COMMON_PROPERTIES
+        with task_manager.acquire(self.context, self.node.uuid,
+                                  shared=True) as task:
+            self.assertEqual(expected, task.driver.inspect.get_properties())
+
+    @mock.patch.object(oneview_common, 'verify_node_info', spec_set=True,
+                       autospec=True)
+    def test_validate(self, mock_verify_node_info):
+        self.config(enabled=False, group='inspector')
+        with task_manager.acquire(self.context, self.node.uuid,
+                                  shared=False) as task:
+            task.driver.inspect.validate(task)
+            mock_verify_node_info.assert_called_once_with(task.node)
+
+    @mock.patch.object(deploy_utils, 'allocate_server_hardware_to_ironic')
+    def test_inspect_hardware(self, mock_allocate_server_hardware_to_ironic):
+        with task_manager.acquire(self.context, self.node.uuid,
+                                  shared=False) as task:
+            task.driver.inspect.inspect_hardware(task)
+            self.assertTrue(mock_allocate_server_hardware_to_ironic.called)
+
+
+class ISCSIPXEOneViewInspectTestCase(db_base.DbTestCase):
+
+    def setUp(self):
+        super(ISCSIPXEOneViewInspectTestCase, self).setUp()
+        self.config(enabled=True, group='inspector')
+        mgr_utils.mock_the_extension_manager(driver="iscsi_pxe_oneview")
+        self.node = obj_utils.create_test_node(
+            self.context, driver='iscsi_pxe_oneview',
+            properties=db_utils.get_test_oneview_properties(),
+            driver_info=db_utils.get_test_oneview_driver_info(),
+        )
+
+    def test_get_properties(self):
+        expected = oneview_common.COMMON_PROPERTIES
+        with task_manager.acquire(self.context, self.node.uuid,
+                                  shared=True) as task:
+            self.assertEqual(expected, task.driver.inspect.get_properties())
+
+    @mock.patch.object(oneview_common, 'verify_node_info', spec_set=True,
+                       autospec=True)
+    def test_validate(self, mock_verify_node_info):
+        self.config(enabled=False, group='inspector')
+        with task_manager.acquire(self.context, self.node.uuid,
+                                  shared=False) as task:
+            task.driver.inspect.validate(task)
+            mock_verify_node_info.assert_called_once_with(task.node)
+
+    @mock.patch.object(deploy_utils, 'allocate_server_hardware_to_ironic')
+    def test_inspect_hardware(self, mock_allocate_server_hardware_to_ironic):
+        with task_manager.acquire(self.context, self.node.uuid,
+                                  shared=False) as task:
+            task.driver.inspect.inspect_hardware(task)
+            self.assertTrue(mock_allocate_server_hardware_to_ironic.called)
diff --git a/ironic/tests/unit/drivers/modules/oneview/test_management.py b/ironic/tests/unit/drivers/modules/oneview/test_management.py
index 0199c6fdb8..b5778e5076 100644
--- a/ironic/tests/unit/drivers/modules/oneview/test_management.py
+++ b/ironic/tests/unit/drivers/modules/oneview/test_management.py
@@ -32,6 +32,7 @@ from ironic.tests.unit.objects import utils as obj_utils
 
 
 oneview_exceptions = importutils.try_import('oneview_client.exceptions')
+oneview_models = importutils.try_import('oneview_client.models')
 
 
 @mock.patch.object(common, 'get_oneview_client', spect_set=True, autospec=True)
@@ -56,10 +57,37 @@ class OneViewManagementDriverTestCase(db_base.DbTestCase):
     @mock.patch.object(common, 'validate_oneview_resources_compatibility',
                        spect_set=True, autospec=True)
     def test_validate(self, mock_validate, mock_get_ov_client):
+        client = mock_get_ov_client.return_value
+        fake_server_hardware = oneview_models.ServerHardware()
+        fake_server_hardware.server_profile_uri = 'any/applied_sp_uri/'
+        client.get_server_hardware_by_uuid.return_value = fake_server_hardware
+        mock_get_ov_client.return_value = client
+        driver_info = self.node.driver_info
+        driver_info['applied_server_profile_uri'] = 'any/applied_sp_uri/'
+        self.node.driver_info = driver_info
+        self.node.save()
         with task_manager.acquire(self.context, self.node.uuid) as task:
             task.driver.management.validate(task)
             self.assertTrue(mock_validate.called)
 
+    @mock.patch.object(common, 'validate_oneview_resources_compatibility',
+                       spect_set=True, autospec=True)
+    def test_validate_for_node_not_in_use_by_ironic(self,
+                                                    mock_validate,
+                                                    mock_get_ov_client):
+        client = mock_get_ov_client.return_value
+        fake_server_hardware = oneview_models.ServerHardware()
+        fake_server_hardware.server_profile_uri = 'any/applied_sp_uri/'
+        client.get_server_hardware_by_uuid.return_value = fake_server_hardware
+        mock_get_ov_client.return_value = client
+        driver_info = self.node.driver_info
+        driver_info['applied_server_profile_uri'] = 'other/applied_sp_uri/'
+        self.node.driver_info = driver_info
+        self.node.save()
+        with task_manager.acquire(self.context, self.node.uuid) as task:
+            self.assertRaises(exception.InvalidParameterValue,
+                              task.driver.management.validate, task)
+
     def test_validate_fail(self, mock_get_ov_client):
         node = obj_utils.create_test_node(self.context,
                                           uuid=uuidutils.generate_uuid(),
diff --git a/ironic/tests/unit/drivers/modules/oneview/test_vendor.py b/ironic/tests/unit/drivers/modules/oneview/test_vendor.py
index ace029e21c..aae708fa5a 100644
--- a/ironic/tests/unit/drivers/modules/oneview/test_vendor.py
+++ b/ironic/tests/unit/drivers/modules/oneview/test_vendor.py
@@ -15,16 +15,18 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import mock
 import time
 import types
 
-import mock
+from oslo_utils import importutils
 
 from ironic.common import exception
 from ironic.common import states
 from ironic.conductor import task_manager
 from ironic.conductor import utils as manager_utils
 from ironic.drivers.modules import agent_client
+from ironic.drivers.modules.oneview import common
 from ironic.drivers.modules.oneview import power
 from ironic.drivers.modules.oneview import vendor
 from ironic.drivers.modules import pxe
@@ -34,10 +36,13 @@ from ironic.tests.unit.db import base as db_base
 from ironic.tests.unit.db import utils as db_utils
 from ironic.tests.unit.objects import utils as obj_utils
 
+oneview_models = importutils.try_import('oneview_client.models')
+
 
 GET_POWER_STATE_RETRIES = 5
 
 
+@mock.patch.object(common, 'get_oneview_client', spec_set=True, autospec=True)
 class TestBaseAgentVendor(db_base.DbTestCase):
 
     def setUp(self):
@@ -63,7 +68,8 @@ class TestBaseAgentVendor(db_base.DbTestCase):
     @mock.patch('ironic.conductor.utils.node_set_boot_device', autospec=True)
     def test_reboot_and_finish_deploy(self, set_bootdev_mock, power_off_mock,
                                       get_power_state_mock,
-                                      node_power_action_mock):
+                                      node_power_action_mock,
+                                      mock_get_ov_client):
         self.node.provision_state = states.DEPLOYING
         self.node.target_provision_state = states.ACTIVE
         self.node.save()
@@ -89,9 +95,18 @@ class TestBaseAgentVendor(db_base.DbTestCase):
                        spec=types.FunctionType)
     def test_reboot_and_finish_deploy_soft_poweroff_doesnt_complete(
             self, power_off_mock, get_power_state_mock,
-            node_power_action_mock):
+            node_power_action_mock, mock_get_ov_client):
+        client = mock_get_ov_client.return_value
+        fake_server_hardware = oneview_models.ServerHardware()
+        fake_server_hardware.server_profile_uri = 'any/applied_sp_uri/'
+        client.get_server_hardware_by_uuid.return_value = fake_server_hardware
+        mock_get_ov_client.return_value = client
+
         self.node.provision_state = states.DEPLOYING
         self.node.target_provision_state = states.ACTIVE
+        driver_info = self.node.driver_info
+        driver_info['applied_server_profile_uri'] = 'any/applied_sp_uri/'
+        self.node.driver_info = driver_info
         self.node.save()
         with task_manager.acquire(self.context, self.node.uuid,
                                   shared=False) as task:
@@ -111,10 +126,20 @@ class TestBaseAgentVendor(db_base.DbTestCase):
     @mock.patch.object(agent_client.AgentClient, 'power_off',
                        spec=types.FunctionType)
     def test_reboot_and_finish_deploy_soft_poweroff_fails(
-            self, power_off_mock, node_power_action_mock):
+            self, power_off_mock, node_power_action_mock,
+            mock_get_ov_client):
+        client = mock_get_ov_client.return_value
+        fake_server_hardware = oneview_models.ServerHardware()
+        fake_server_hardware.server_profile_uri = 'any/applied_sp_uri/'
+        client.get_server_hardware_by_uuid.return_value = fake_server_hardware
+        mock_get_ov_client.return_value = client
+
         power_off_mock.side_effect = RuntimeError("boom")
         self.node.provision_state = states.DEPLOYING
         self.node.target_provision_state = states.ACTIVE
+        driver_info = self.node.driver_info
+        driver_info['applied_server_profile_uri'] = 'any/applied_sp_uri/'
+        self.node.driver_info = driver_info
         self.node.save()
         with task_manager.acquire(self.context, self.node.uuid,
                                   shared=False) as task:
@@ -135,9 +160,18 @@ class TestBaseAgentVendor(db_base.DbTestCase):
                        spec=types.FunctionType)
     def test_reboot_and_finish_deploy_get_power_state_fails(
             self, power_off_mock, get_power_state_mock,
-            node_power_action_mock):
+            node_power_action_mock, mock_get_ov_client):
+        client = mock_get_ov_client.return_value
+        fake_server_hardware = oneview_models.ServerHardware()
+        fake_server_hardware.server_profile_uri = 'any/applied_sp_uri/'
+        client.get_server_hardware_by_uuid.return_value = fake_server_hardware
+        mock_get_ov_client.return_value = client
+
         self.node.provision_state = states.DEPLOYING
         self.node.target_provision_state = states.ACTIVE
+        driver_info = self.node.driver_info
+        driver_info['applied_server_profile_uri'] = 'any/applied_sp_uri/'
+        self.node.driver_info = driver_info
         self.node.save()
         with task_manager.acquire(self.context, self.node.uuid,
                                   shared=False) as task:
@@ -162,7 +196,8 @@ class TestBaseAgentVendor(db_base.DbTestCase):
                        spec=types.FunctionType)
     def test_reboot_and_finish_deploy_power_action_fails(
             self, power_off_mock, get_power_state_mock,
-            node_power_action_mock, collect_ramdisk_logs_mock):
+            node_power_action_mock, collect_ramdisk_logs_mock,
+            mock_get_ov_client):
         self.node.provision_state = states.DEPLOYING
         self.node.target_provision_state = states.ACTIVE
         self.node.save()
@@ -193,11 +228,20 @@ class TestBaseAgentVendor(db_base.DbTestCase):
     @mock.patch.object(pxe.PXEBoot, 'clean_up_ramdisk', autospec=True)
     def test_reboot_to_instance(self, clean_pxe_mock, check_deploy_mock,
                                 power_off_mock, get_power_state_mock,
-                                node_power_action_mock):
+                                node_power_action_mock, mock_get_ov_client):
         check_deploy_mock.return_value = None
 
+        client = mock_get_ov_client.return_value
+        fake_server_hardware = oneview_models.ServerHardware()
+        fake_server_hardware.server_profile_uri = 'any/applied_sp_uri/'
+        client.get_server_hardware_by_uuid.return_value = fake_server_hardware
+        mock_get_ov_client.return_value = client
+
         self.node.provision_state = states.DEPLOYWAIT
         self.node.target_provision_state = states.ACTIVE
+        driver_info = self.node.driver_info
+        driver_info['applied_server_profile_uri'] = 'any/applied_sp_uri/'
+        self.node.driver_info = driver_info
         self.node.save()
         with task_manager.acquire(self.context, self.node.uuid,
                                   shared=False) as task:
@@ -227,11 +271,21 @@ class TestBaseAgentVendor(db_base.DbTestCase):
                                           check_deploy_mock,
                                           power_off_mock,
                                           get_power_state_mock,
-                                          node_power_action_mock):
+                                          node_power_action_mock,
+                                          mock_get_ov_client):
+        client = mock_get_ov_client.return_value
+        fake_server_hardware = oneview_models.ServerHardware()
+        fake_server_hardware.server_profile_uri = 'any/applied_sp_uri/'
+        client.get_server_hardware_by_uuid.return_value = fake_server_hardware
+        mock_get_ov_client.return_value = client
+
         check_deploy_mock.return_value = None
 
         self.node.provision_state = states.DEPLOYWAIT
         self.node.target_provision_state = states.ACTIVE
+        driver_info = self.node.driver_info
+        driver_info['applied_server_profile_uri'] = 'any/applied_sp_uri/'
+        self.node.driver_info = driver_info
         self.node.save()
         with task_manager.acquire(self.context, self.node.uuid,
                                   shared=False) as task:
diff --git a/releasenotes/notes/oneview-inspection-interface-c2d6902bbeca0501.yaml b/releasenotes/notes/oneview-inspection-interface-c2d6902bbeca0501.yaml
new file mode 100644
index 0000000000..092633b6c6
--- /dev/null
+++ b/releasenotes/notes/oneview-inspection-interface-c2d6902bbeca0501.yaml
@@ -0,0 +1,5 @@
+---
+upgrade:
+  - Minimum required version of python-oneviewclient bumped to 2.5.1
+features:
+  - Adds in-band inspection interface usable by OneView drivers.