Merge "Add Ceph Native driver"
diff --git a/manila_tempest_tests/config.py b/manila_tempest_tests/config.py
index 3f8c08a..c0c38bd 100644
--- a/manila_tempest_tests/config.py
+++ b/manila_tempest_tests/config.py
@@ -36,7 +36,7 @@
                help="The minimum api microversion is configured to be the "
                     "value of the minimum microversion supported by Manila."),
     cfg.StrOpt("max_api_microversion",
-               default="2.12",
+               default="2.13",
                help="The maximum api microversion is configured to be the "
                     "value of the latest microversion supported by Manila."),
     cfg.StrOpt("region",
@@ -73,6 +73,9 @@
     cfg.ListOpt("enable_cert_rules_for_protocols",
                 default=["glusterfs", ],
                 help="Protocols that should be covered with cert rule tests."),
+    cfg.ListOpt("enable_cephx_rules_for_protocols",
+                default=["cephfs", ],
+                help="Protocols to be covered with cephx rule tests."),
     cfg.StrOpt("username_for_user_rules",
                default="Administrator",
                help="Username, that will be used in user tests."),
diff --git a/manila_tempest_tests/tests/api/admin/test_share_manage.py b/manila_tempest_tests/tests/api/admin/test_share_manage.py
index bbd98bc..3651564 100644
--- a/manila_tempest_tests/tests/api/admin/test_share_manage.py
+++ b/manila_tempest_tests/tests/api/admin/test_share_manage.py
@@ -196,3 +196,7 @@
 
 class ManageHDFSShareTest(ManageNFSShareTest):
     protocol = 'hdfs'
+
+
+class ManageCephFSShareTest(ManageNFSShareTest):
+    protocol = 'cephfs'
diff --git a/manila_tempest_tests/tests/api/base.py b/manila_tempest_tests/tests/api/base.py
index 8ee5ddd..524f248 100644
--- a/manila_tempest_tests/tests/api/base.py
+++ b/manila_tempest_tests/tests/api/base.py
@@ -86,7 +86,7 @@
     """Base test case class for all Manila API tests."""
 
     force_tenant_isolation = False
-    protocols = ["nfs", "cifs", "glusterfs", "hdfs"]
+    protocols = ["nfs", "cifs", "glusterfs", "hdfs", "cephfs"]
 
     # Will be cleaned up in resource_cleanup
     class_resources = []
diff --git a/manila_tempest_tests/tests/api/test_rules.py b/manila_tempest_tests/tests/api/test_rules.py
index 0b0bc08..5fc99a2 100644
--- a/manila_tempest_tests/tests/api/test_rules.py
+++ b/manila_tempest_tests/tests/api/test_rules.py
@@ -359,6 +359,41 @@
 
 
 @ddt.ddt
+class ShareCephxRulesForCephFSTest(base.BaseSharesTest):
+    protocol = "cephfs"
+
+    @classmethod
+    def resource_setup(cls):
+        super(ShareCephxRulesForCephFSTest, cls).resource_setup()
+        if (cls.protocol not in CONF.share.enable_protocols or
+                cls.protocol not in
+                CONF.share.enable_cephx_rules_for_protocols):
+            msg = ("Cephx rule tests for %s protocol are disabled." %
+                   cls.protocol)
+            raise cls.skipException(msg)
+        cls.share = cls.create_share(cls.protocol)
+        cls.access_type = "cephx"
+        # Provide access to a client identified by a cephx auth id.
+        cls.access_to = "bob"
+
+    @test.attr(type=["gate", ])
+    @ddt.data("alice", "alice_bob", "alice bob")
+    def test_create_delete_cephx_rule(self, access_to):
+        rule = self.shares_v2_client.create_access_rule(
+            self.share["id"], self.access_type, access_to)
+
+        self.assertEqual('rw', rule['access_level'])
+        for key in ('deleted', 'deleted_at', 'instance_mappings'):
+            self.assertNotIn(key, rule.keys())
+        self.shares_v2_client.wait_for_access_rule_status(
+            self.share["id"], rule["id"], "active")
+
+        self.shares_v2_client.delete_access_rule(self.share["id"], rule["id"])
+        self.shares_v2_client.wait_for_resource_deletion(
+            rule_id=rule["id"], share_id=self.share['id'])
+
+
+@ddt.ddt
 class ShareRulesTest(base.BaseSharesTest):
 
     @classmethod
@@ -369,6 +404,8 @@
                 any(p in CONF.share.enable_user_rules_for_protocols
                     for p in cls.protocols) or
                 any(p in CONF.share.enable_cert_rules_for_protocols
+                    for p in cls.protocols) or
+                any(p in CONF.share.enable_cephx_rules_for_protocols
                     for p in cls.protocols)):
             cls.message = "Rule tests are disabled"
             raise cls.skipException(cls.message)
@@ -384,12 +421,21 @@
             cls.protocol = CONF.share.enable_cert_rules_for_protocols[0]
             cls.access_type = "cert"
             cls.access_to = "client3.com"
+        elif CONF.share.enable_cephx_rules_for_protocols:
+            cls.protocol = CONF.share.enable_cephx_rules_for_protocols[0]
+            cls.access_type = "cephx"
+            cls.access_to = "alice"
         cls.shares_v2_client.share_protocol = cls.protocol
         cls.share = cls.create_share()
 
     @test.attr(type=["gate", ])
     @ddt.data('1.0', '2.9', LATEST_MICROVERSION)
     def test_list_access_rules(self, version):
+        if (utils.is_microversion_lt(version, '2.13') and
+                CONF.share.enable_cephx_rules_for_protocols):
+            msg = ("API version %s does not support cephx access type, "
+                   "need version greater than 2.13." % version)
+            raise self.skipException(msg)
 
         # create rule
         if utils.is_microversion_eq(version, '1.0'):
@@ -447,6 +493,11 @@
     @test.attr(type=["gate", ])
     @ddt.data('1.0', '2.9', LATEST_MICROVERSION)
     def test_access_rules_deleted_if_share_deleted(self, version):
+        if (utils.is_microversion_lt(version, '2.13') and
+                CONF.share.enable_cephx_rules_for_protocols):
+            msg = ("API version %s does not support cephx access type, "
+                   "need version greater than 2.13." % version)
+            raise self.skipException(msg)
 
         # create share
         share = self.create_share()
diff --git a/manila_tempest_tests/tests/api/test_rules_negative.py b/manila_tempest_tests/tests/api/test_rules_negative.py
index 47f5a52..8e7f620 100644
--- a/manila_tempest_tests/tests/api/test_rules_negative.py
+++ b/manila_tempest_tests/tests/api/test_rules_negative.py
@@ -19,6 +19,7 @@
 from tempest_lib import exceptions as lib_exc
 import testtools
 
+from manila_tempest_tests import share_exceptions
 from manila_tempest_tests.tests.api import base
 from manila_tempest_tests import utils
 
@@ -317,6 +318,48 @@
 
 
 @ddt.ddt
+class ShareCephxRulesForCephFSNegativeTest(base.BaseSharesTest):
+    protocol = "cephfs"
+
+    @classmethod
+    def resource_setup(cls):
+        super(ShareCephxRulesForCephFSNegativeTest, cls).resource_setup()
+        if not (cls.protocol in CONF.share.enable_protocols and
+                cls.protocol in CONF.share.enable_cephx_rules_for_protocols):
+            msg = ("CEPHX rule tests for %s protocol are disabled" %
+                   cls.protocol)
+            raise cls.skipException(msg)
+        # create share
+        cls.share = cls.create_share(cls.protocol)
+        cls.access_type = "cephx"
+        cls.access_to = "david"
+
+    @test.attr(type=["negative", "gate", ])
+    @ddt.data('jane.doe', u"bj\u00F6rn")
+    def test_create_access_rule_cephx_with_invalid_cephx_id(self, access_to):
+        self.assertRaises(lib_exc.BadRequest,
+                          self.shares_v2_client.create_access_rule,
+                          self.share["id"], self.access_type, access_to)
+
+    @test.attr(type=["negative", "gate", ])
+    def test_create_access_rule_cephx_with_wrong_level(self):
+        self.assertRaises(lib_exc.BadRequest,
+                          self.shares_v2_client.create_access_rule,
+                          self.share["id"], self.access_type, self.access_to,
+                          access_level="su")
+
+    @test.attr(type=["negative", "gate", ])
+    def test_create_access_rule_cephx_with_unsupported_access_level_ro(self):
+        rule = self.shares_v2_client.create_access_rule(
+            self.share["id"], self.access_type, self.access_to,
+            access_level="ro")
+        self.assertRaises(
+            share_exceptions.AccessRuleBuildErrorException,
+            self.shares_client.wait_for_access_rule_status,
+            self.share['id'], rule['id'], "active")
+
+
+@ddt.ddt
 class ShareRulesNegativeTest(base.BaseSharesTest):
     # Tests independent from rule type and share protocol
 
@@ -328,6 +371,8 @@
                 any(p in CONF.share.enable_user_rules_for_protocols
                     for p in cls.protocols) or
                 any(p in CONF.share.enable_cert_rules_for_protocols
+                    for p in cls.protocols) or
+                any(p in CONF.share.enable_cephx_rules_for_protocols
                     for p in cls.protocols)):
             cls.message = "Rule tests are disabled"
             raise cls.skipException(cls.message)
@@ -337,9 +382,21 @@
             # create snapshot
             cls.snap = cls.create_snapshot_wait_for_active(cls.share["id"])
 
+    def skip_if_cephx_access_type_not_supported_by_client(self, client):
+        if client == 'shares_client':
+            version = '1.0'
+        else:
+            version = LATEST_MICROVERSION
+        if (CONF.share.enable_cephx_rules_for_protocols and
+                utils.is_microversion_lt(version, '2.13')):
+            msg = ("API version %s does not support cephx access type, "
+                   "need version greater than 2.13." % version)
+            raise self.skipException(msg)
+
     @test.attr(type=["negative", "gate", ])
     @ddt.data('shares_client', 'shares_v2_client')
     def test_delete_access_rule_with_wrong_id(self, client_name):
+        self.skip_if_cephx_access_type_not_supported_by_client(client_name)
         self.assertRaises(lib_exc.NotFound,
                           getattr(self, client_name).delete_access_rule,
                           self.share["id"], "wrong_rule_id")
@@ -347,6 +404,7 @@
     @test.attr(type=["negative", "gate", ])
     @ddt.data('shares_client', 'shares_v2_client')
     def test_create_access_rule_ip_with_wrong_type(self, client_name):
+        self.skip_if_cephx_access_type_not_supported_by_client(client_name)
         self.assertRaises(lib_exc.BadRequest,
                           getattr(self, client_name).create_access_rule,
                           self.share["id"], "wrong_type", "1.2.3.4")
@@ -354,6 +412,7 @@
     @test.attr(type=["negative", "gate", ])
     @ddt.data('shares_client', 'shares_v2_client')
     def test_create_access_rule_ip_with_wrong_share_id(self, client_name):
+        self.skip_if_cephx_access_type_not_supported_by_client(client_name)
         self.assertRaises(lib_exc.NotFound,
                           getattr(self, client_name).create_access_rule,
                           "wrong_share_id")
@@ -363,6 +422,7 @@
     @testtools.skipUnless(CONF.share.run_snapshot_tests,
                           "Snapshot tests are disabled.")
     def test_create_access_rule_ip_to_snapshot(self, client_name):
+        self.skip_if_cephx_access_type_not_supported_by_client(client_name)
         self.assertRaises(lib_exc.NotFound,
                           getattr(self, client_name).create_access_rule,
                           self.snap["id"])
diff --git a/manila_tempest_tests/tests/api/test_shares.py b/manila_tempest_tests/tests/api/test_shares.py
index 46d1558..db829a1 100644
--- a/manila_tempest_tests/tests/api/test_shares.py
+++ b/manila_tempest_tests/tests/api/test_shares.py
@@ -187,3 +187,8 @@
 class SharesHDFSTest(SharesNFSTest):
     """Covers share functionality that is related to HDFS share type."""
     protocol = "hdfs"
+
+
+class SharesCephFSTest(SharesNFSTest):
+    """Covers share functionality that is related to CEPHFS share type."""
+    protocol = "cephfs"