Merge "Remove override of 'expected_error_codes' with defaults"
diff --git a/patrole_tempest_plugin/tests/api/image/test_images_member_rbac.py b/patrole_tempest_plugin/tests/api/image/test_images_member_rbac.py
index 952c41f..4b5fd08 100644
--- a/patrole_tempest_plugin/tests/api/image/test_images_member_rbac.py
+++ b/patrole_tempest_plugin/tests/api/image/test_images_member_rbac.py
@@ -68,8 +68,8 @@
                                                          self.alt_tenant_id)
 
     @rbac_rule_validation.action(service="glance",
-                                 rule="get_member",
-                                 expected_error_code=404)
+                                 rules=["get_member"],
+                                 expected_error_codes=[404])
     @decorators.idempotent_id('c01fd308-6484-11e6-881e-080027d0d606')
     def test_show_image_member(self):
 
diff --git a/patrole_tempest_plugin/tests/api/network/test_agents_rbac.py b/patrole_tempest_plugin/tests/api/network/test_agents_rbac.py
index 2756a10..7567275 100644
--- a/patrole_tempest_plugin/tests/api/network/test_agents_rbac.py
+++ b/patrole_tempest_plugin/tests/api/network/test_agents_rbac.py
@@ -38,8 +38,8 @@
 
     @decorators.idempotent_id('f88e38e0-ab52-4b97-8ffa-48a27f9d199b')
     @rbac_rule_validation.action(service="neutron",
-                                 rule="get_agent",
-                                 expected_error_code=404)
+                                 rules=["get_agent"],
+                                 expected_error_codes=[404])
     def test_show_agent(self):
         """Show agent test.
 
diff --git a/patrole_tempest_plugin/tests/api/network/test_floating_ips_rbac.py b/patrole_tempest_plugin/tests/api/network/test_floating_ips_rbac.py
index 3da6491..8a02149 100644
--- a/patrole_tempest_plugin/tests/api/network/test_floating_ips_rbac.py
+++ b/patrole_tempest_plugin/tests/api/network/test_floating_ips_rbac.py
@@ -104,8 +104,8 @@
                 floating_ip['id'], port_id=None)
 
     @rbac_rule_validation.action(service="neutron",
-                                 rule="get_floatingip",
-                                 expected_error_code=404)
+                                 rules=["get_floatingip"],
+                                 expected_error_codes=[404])
     @decorators.idempotent_id('f8846fd0-c976-48fe-a148-105303931b32')
     def test_show_floating_ip(self):
         """Show floating IP.
diff --git a/patrole_tempest_plugin/tests/api/network/test_metering_label_rules_rbac.py b/patrole_tempest_plugin/tests/api/network/test_metering_label_rules_rbac.py
index adab1e6..db099a1 100644
--- a/patrole_tempest_plugin/tests/api/network/test_metering_label_rules_rbac.py
+++ b/patrole_tempest_plugin/tests/api/network/test_metering_label_rules_rbac.py
@@ -74,8 +74,8 @@
             self._create_metering_label_rule(self.label)
 
     @rbac_rule_validation.action(service="neutron",
-                                 rule="get_metering_label_rule",
-                                 expected_error_code=404)
+                                 rules=["get_metering_label_rule"],
+                                 expected_error_codes=[404])
     @decorators.idempotent_id('e21b40c3-d44d-412f-84ea-836ca8603bcb')
     def test_show_metering_label_rule(self):
         """Show metering label rule.
diff --git a/patrole_tempest_plugin/tests/api/network/test_metering_labels_rbac.py b/patrole_tempest_plugin/tests/api/network/test_metering_labels_rbac.py
index 0231868..0e10f5b 100644
--- a/patrole_tempest_plugin/tests/api/network/test_metering_labels_rbac.py
+++ b/patrole_tempest_plugin/tests/api/network/test_metering_labels_rbac.py
@@ -58,8 +58,8 @@
             self._create_metering_label()
 
     @rbac_rule_validation.action(service="neutron",
-                                 rule="get_metering_label",
-                                 expected_error_code=404)
+                                 rules=["get_metering_label"],
+                                 expected_error_codes=[404])
     @decorators.idempotent_id('c57f6636-c702-4755-8eac-5e73bc1f7d14')
     def test_show_metering_label(self):
         """Show metering label.
diff --git a/patrole_tempest_plugin/tests/api/network/test_networks_rbac.py b/patrole_tempest_plugin/tests/api/network/test_networks_rbac.py
index 923ac7f..2e69f89 100644
--- a/patrole_tempest_plugin/tests/api/network/test_networks_rbac.py
+++ b/patrole_tempest_plugin/tests/api/network/test_networks_rbac.py
@@ -332,8 +332,8 @@
                 str(exc))
 
     @rbac_rule_validation.action(service="neutron",
-                                 rule="get_network",
-                                 expected_error_code=404)
+                                 rules=["get_network"],
+                                 expected_error_codes=[404])
     @decorators.idempotent_id('0eb62d04-338a-4ff4-a8fa-534e52110534')
     def test_show_network(self):
 
diff --git a/patrole_tempest_plugin/tests/api/network/test_ports_rbac.py b/patrole_tempest_plugin/tests/api/network/test_ports_rbac.py
index a808735..175d051 100644
--- a/patrole_tempest_plugin/tests/api/network/test_ports_rbac.py
+++ b/patrole_tempest_plugin/tests/api/network/test_ports_rbac.py
@@ -159,8 +159,8 @@
             self.create_port(**post_body)
 
     @rbac_rule_validation.action(service="neutron",
-                                 rule="get_port",
-                                 expected_error_code=404)
+                                 rules=["get_port"],
+                                 expected_error_codes=[404])
     @decorators.idempotent_id('a9d41cb8-78a2-4b97-985c-44e4064416f4')
     def test_show_port(self):
         with self.rbac_utils.override_role(self):
diff --git a/patrole_tempest_plugin/tests/api/network/test_rbac_policies_rbac.py b/patrole_tempest_plugin/tests/api/network/test_rbac_policies_rbac.py
new file mode 100644
index 0000000..a8813e7
--- /dev/null
+++ b/patrole_tempest_plugin/tests/api/network/test_rbac_policies_rbac.py
@@ -0,0 +1,111 @@
+# Copyright 2018 AT&T Corporation.
+# 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 tempest.lib.common.utils import test_utils
+from tempest.lib import decorators
+
+from patrole_tempest_plugin import rbac_rule_validation
+from patrole_tempest_plugin.tests.api.network import rbac_base as base
+
+
+class RbacPoliciesPluginRbacTest(base.BaseNetworkPluginRbacTest):
+
+    @classmethod
+    def resource_setup(cls):
+        super(RbacPoliciesPluginRbacTest, cls).resource_setup()
+        cls.tenant_id = cls.os_primary.credentials.tenant_id
+        cls.network_id = cls.create_network()['id']
+
+    def create_rbac_policy(self, tenant_id, network_id):
+        policy = self.ntp_client.create_rbac_policy(
+            target_tenant=self.tenant_id,
+            object_type="network",
+            object_id=self.network_id,
+            action="access_as_shared"
+        )
+        self.addCleanup(
+            test_utils.call_and_ignore_notfound_exc,
+            self.ntp_client.delete_rbac_policy, policy["rbac_policy"]["id"])
+
+        return policy["rbac_policy"]["id"]
+
+    @decorators.idempotent_id('effd9545-99ad-4c3c-92dd-ea422602c868')
+    @rbac_rule_validation.action(service="neutron",
+                                 rules=["create_rbac_policy",
+                                        "create_rbac_policy:target_tenant"])
+    def test_create_rbac_policy(self):
+        """Create RBAC policy.
+
+        RBAC test for the neutron "create_rbac_policy" policy
+
+        We can't validate "create_rbac_policy:target_tenant" for all cases
+        since if "restrict_wildcard" rule is modified then Patrole won't be
+        able to determine the correct result since that requires relying on
+        Neutron's custom FieldCheck oslo.policy rule.
+        """
+
+        with self.rbac_utils.override_role(self):
+            self.create_rbac_policy(self.tenant_id, self.network_id)
+
+    @decorators.idempotent_id('f5d836d8-3b64-412d-a283-ee29761017f3')
+    @rbac_rule_validation.action(service="neutron",
+                                 rules=["get_rbac_policy",
+                                        "update_rbac_policy",
+                                        "update_rbac_policy:target_tenant"],
+                                 expected_error_codes=[404, 403, 403])
+    def test_update_rbac_policy(self):
+        """Update RBAC policy.
+
+        RBAC test for the neutron "update_rbac_policy" policy
+
+        We can't validate "create_rbac_policy:target_tenant" for all cases
+        since if "restrict_wildcard" rule is modified then Patrole won't be
+        able to determine the correct result since that requires relying on
+        Neutron's custom FieldCheck oslo.policy rule.
+        """
+        policy_id = self.create_rbac_policy(self.tenant_id, self.network_id)
+
+        with self.rbac_utils.override_role(self):
+            self.ntp_client.update_rbac_policy(
+                policy_id, target_tenant=self.tenant_id)
+
+    @decorators.idempotent_id('9308ab18-426c-41b7-bce5-11081f7dd259')
+    @rbac_rule_validation.action(service="neutron",
+                                 rules=["get_rbac_policy"],
+                                 expected_error_codes=[404])
+    def test_show_rbac_policy(self):
+        """Show RBAC policy.
+
+        RBAC test for the neutron "get_rbac_policy" policy
+        """
+        policy_id = self.create_rbac_policy(self.tenant_id, self.network_id)
+
+        with self.rbac_utils.override_role(self):
+            self.ntp_client.show_rbac_policy(policy_id)
+
+    @decorators.idempotent_id('54aa9bce-efea-47fb-b0e4-12012f82f285')
+    @rbac_rule_validation.action(service="neutron",
+                                 rules=["get_rbac_policy",
+                                        "delete_rbac_policy"],
+                                 expected_error_codes=[404, 403])
+    def test_delete_rbac_policy(self):
+        """Delete RBAC policy.
+
+        RBAC test for the neutron "delete_rbac_policy" policy
+        """
+        policy_id = self.create_rbac_policy(self.tenant_id, self.network_id)
+
+        with self.rbac_utils.override_role(self):
+            self.ntp_client.delete_rbac_policy(policy_id)
diff --git a/patrole_tempest_plugin/tests/api/network/test_routers_rbac.py b/patrole_tempest_plugin/tests/api/network/test_routers_rbac.py
index 5efa7ab..3d7631a 100644
--- a/patrole_tempest_plugin/tests/api/network/test_routers_rbac.py
+++ b/patrole_tempest_plugin/tests/api/network/test_routers_rbac.py
@@ -147,8 +147,8 @@
                         router['router']['id'])
 
     @rbac_rule_validation.action(service="neutron",
-                                 rule="get_router",
-                                 expected_error_code=404)
+                                 rules=["get_router"],
+                                 expected_error_codes=[404])
     @decorators.idempotent_id('bfbdbcff-f115-4d3e-8cd5-6ada33fd0e21')
     def test_show_router(self):
         """Get Router
diff --git a/patrole_tempest_plugin/tests/api/network/test_security_groups_rbac.py b/patrole_tempest_plugin/tests/api/network/test_security_groups_rbac.py
index 1cf841d..4536fdb 100644
--- a/patrole_tempest_plugin/tests/api/network/test_security_groups_rbac.py
+++ b/patrole_tempest_plugin/tests/api/network/test_security_groups_rbac.py
@@ -78,8 +78,8 @@
             self._create_security_group()
 
     @rbac_rule_validation.action(service="neutron",
-                                 rule="get_security_group",
-                                 expected_error_code=404)
+                                 rules=["get_security_group"],
+                                 expected_error_codes=[404])
     @decorators.idempotent_id('56335e77-aef2-4b54-86c7-7f772034b585')
     def test_show_security_group(self):
 
@@ -149,8 +149,8 @@
                 sec_group_rule['id'])
 
     @rbac_rule_validation.action(service="neutron",
-                                 rule="get_security_group_rule",
-                                 expected_error_code=404)
+                                 rules=["get_security_group_rule"],
+                                 expected_error_codes=[404])
     @decorators.idempotent_id('84b4038c-261e-4a94-90d5-c885739ab0d5')
     def test_show_security_group_rule(self):
 
diff --git a/patrole_tempest_plugin/tests/api/network/test_subnetpools_rbac.py b/patrole_tempest_plugin/tests/api/network/test_subnetpools_rbac.py
index 15a24a4..7d02271 100644
--- a/patrole_tempest_plugin/tests/api/network/test_subnetpools_rbac.py
+++ b/patrole_tempest_plugin/tests/api/network/test_subnetpools_rbac.py
@@ -76,8 +76,8 @@
             self._create_subnetpool(shared=True)
 
     @rbac_rule_validation.action(service="neutron",
-                                 rule="get_subnetpool",
-                                 expected_error_code=404)
+                                 rules=["get_subnetpool"],
+                                 expected_error_codes=[404])
     @decorators.idempotent_id('4f5aee26-0507-4b6d-b44c-3128a25094d2')
     def test_show_subnetpool(self):
         """Show subnetpool.
diff --git a/patrole_tempest_plugin/tests/api/network/test_subnets_rbac.py b/patrole_tempest_plugin/tests/api/network/test_subnets_rbac.py
index 77d4b42..93d79a9 100644
--- a/patrole_tempest_plugin/tests/api/network/test_subnets_rbac.py
+++ b/patrole_tempest_plugin/tests/api/network/test_subnets_rbac.py
@@ -50,8 +50,8 @@
 
     @decorators.idempotent_id('c02618e7-bb20-4abd-83c8-6eec2af08752')
     @rbac_rule_validation.action(service="neutron",
-                                 rule="get_subnet",
-                                 expected_error_code=404)
+                                 rules=["get_subnet"],
+                                 expected_error_codes=[404])
     def test_show_subnet(self):
         """Show subnet.
 
diff --git a/test-requirements.txt b/test-requirements.txt
index 9085c07..a08c27a 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -8,3 +8,4 @@
 nose>=1.3.7 # LGPL
 nosexcover>=1.0.10 # BSD
 oslotest>=3.2.0 # Apache-2.0
+bandit>=1.5 # Apache-2.0
diff --git a/tox.ini b/tox.ini
index a09822f..ea9abf1 100644
--- a/tox.ini
+++ b/tox.ini
@@ -22,8 +22,12 @@
 
 [testenv:pep8]
 basepython = python3
-commands = flake8 {posargs}
-           check-uuid --package patrole_tempest_plugin.tests.api
+deps =
+    -r{toxinidir}/test-requirements.txt
+commands =
+    flake8 {posargs}
+    bandit -r patrole_tempest_plugin -x patrole_tempest_plugin/tests -n 5
+    check-uuid --package patrole_tempest_plugin.tests.api
 
 [testenv:uuidgen]
 basepython = python3