Enable IPv6 in manila(client)

Please read spec for design detail [1]

Access-allow command now validates and allows
access control to IPv6 clients.

[1] f7202a6cfe32a057f752a4e393f848f8a0211c36

Partial-Implements: blueprint support-ipv6-access
Change-Id: I88a1bd60e703bf9b434924ac347bbd74f72cec2b
This commit is contained in:
zhongjun 2016-06-13 03:54:32 +08:00 committed by Goutham Pacha Ravi
parent 8d887f5221
commit 39b72e58c9
4 changed files with 51 additions and 29 deletions

View File

@ -15,6 +15,7 @@
import ddt
from tempest.lib import exceptions as tempest_lib_exc
import testtools
from manilaclient import api_versions
from manilaclient import config
@ -65,6 +66,7 @@ class ShareAccessReadWriteBase(base.BaseTestCase):
# API testing.
'user': ['foo_user_%d' % i for i in int_range],
'cert': ['tenant_%d.example.com' % i for i in int_range],
'ipv6': ['2001:db8::%d' % i for i in int_range],
}
def _test_create_list_access_rule_for_share(self, microversion):
@ -170,6 +172,12 @@ class ShareAccessReadWriteBase(base.BaseTestCase):
self._create_delete_access_rule(
self.share_id, 'cert', self.access_to['cert'].pop(), microversion)
@ddt.data("2.38", api_versions.MAX_VERSION)
@testtools.skip("BUG: https://bugs.launchpad.net/manila/+bug/1707066")
def test_create_delete_ipv6_access_rule(self, microversion):
self._create_delete_access_rule(
self.share_id, 'ip', self.access_to['ipv6'].pop(), microversion)
class NFSShareRWAccessReadWriteTest(ShareAccessReadWriteBase):
protocol = 'nfs'

View File

@ -386,6 +386,18 @@ class SharesTest(utils.TestCase):
'action_name': 'allow_access', 'microversion': '2.13'},
{'access_to': 'alice bob', 'access_type': 'cephx',
'action_name': 'allow_access', 'microversion': '2.13'},
{'access_to': 'AD80:0000:0000:0000:ABAA:0000:00C2:0002',
'access_type': 'ip', 'action_name': 'allow_access',
'microversion': '2.38'},
{'access_to': 'AD80::/36',
'access_type': 'ip', 'action_name': 'allow_access',
'microversion': '2.38'},
{'access_to': 'AD80:ABAA::/128',
'access_type': 'ip', 'action_name': 'allow_access',
'microversion': '2.38'},
{'access_to': 'ad80::abaa:0:c2:2',
'access_type': 'ip', 'action_name': 'allow_access',
'microversion': '2.38'},
)
@ddt.unpack
def test_allow_access_to_share(self, access_to, access_type,
@ -436,6 +448,12 @@ class SharesTest(utils.TestCase):
'microversion': '2.13'},
{'access_to': u"bj\u00F6rn", 'access_type': 'cephx',
'microversion': '2.13'},
{'access_to': "AD80:0000:0000:0000:ABAA:0000:00C2:0002/65",
'access_type': 'ip', 'microversion': '2.38'},
{'access_to': "AD80:0000:0000:0000:ABAA:0000:00C2:0002*32",
'access_type': 'ip', 'microversion': '2.38'},
{'access_to': "AD80:0000:0000:0000:ABAA:0000:00C2:0002",
'access_type': 'ip', 'microversion': '2.37'},
)
@ddt.unpack
def test_allow_access_to_share_error_invalid_access(self, access_to,

View File

@ -15,8 +15,10 @@
"""Interface for shares extension."""
import collections
import ipaddress
from oslo_utils import uuidutils
import re
import six
import string
try:
from urllib import urlencode # noqa
@ -454,32 +456,6 @@ class ShareManager(base.ManagerWithFind):
'special characters ]{.-_\'`;}[\\')
raise exceptions.CommandError(exc_str)
@staticmethod
def _validate_ip_range(ip_range):
ip_range = ip_range.split('/')
exc_str = ('Supported ip format examples:\n'
'\t10.0.0.2, 10.0.0.0/24')
if len(ip_range) > 2:
raise exceptions.CommandError(exc_str)
if len(ip_range) == 2:
try:
prefix = int(ip_range[1])
if prefix < 0 or prefix > 32:
raise ValueError()
except ValueError:
msg = 'IP prefix should be in range from 0 to 32.'
raise exceptions.CommandError(msg)
ip_range = ip_range[0].split('.')
if len(ip_range) != 4:
raise exceptions.CommandError(exc_str)
for item in ip_range:
try:
if 0 <= int(item) <= 255:
continue
raise ValueError()
except ValueError:
raise exceptions.CommandError(exc_str)
@staticmethod
def _validate_cephx_id(cephx_id):
if not cephx_id:
@ -500,13 +476,20 @@ class ShareManager(base.ManagerWithFind):
raise exceptions.CommandError(
'Ceph IDs may not contain periods.')
def _validate_access(self, access_type, access, valid_access_types=None):
def _validate_access(self, access_type, access, valid_access_types=None,
enable_ipv6=False):
if not valid_access_types:
valid_access_types = ('ip', 'user', 'cert')
if access_type in valid_access_types:
if access_type == 'ip':
self._validate_ip_range(access)
try:
if enable_ipv6:
ipaddress.ip_network(six.text_type(access))
else:
ipaddress.IPv4Network(six.text_type(access))
except ValueError as error:
raise exceptions.CommandError(six.text_type(error))
elif access_type == 'user':
self._validate_username(access)
elif access_type == 'cert':
@ -553,13 +536,21 @@ class ShareManager(base.ManagerWithFind):
return self._do_allow(
share, access_type, access, access_level, "allow_access")
@api_versions.wraps("2.13") # noqa
@api_versions.wraps("2.13", "2.37") # noqa
def allow(self, share, access_type, access, access_level):
valid_access_types = ('ip', 'user', 'cert', 'cephx')
self._validate_access(access_type, access, valid_access_types)
return self._do_allow(
share, access_type, access, access_level, "allow_access")
@api_versions.wraps("2.38") # noqa
def allow(self, share, access_type, access, access_level):
valid_access_types = ('ip', 'user', 'cert', 'cephx')
self._validate_access(access_type, access, valid_access_types,
enable_ipv6=True)
return self._do_allow(
share, access_type, access, access_level, "allow_access")
def _do_deny(self, share, access_id, action_name):
"""Deny access to a share.

View File

@ -0,0 +1,5 @@
---
features:
- IPv6 ACL support has been added in manila. access-allow
command now validates and allows access control
to IPv6 clients.