Support multi DNS server
Using comma delimited ipv4 address list to specify multi dns server "8.8.8.8,114.114.114.114". Task: 29465 Story: 2004994 Change-Id: I031247b0cc2ae417f18b2a5b9b3832e78ed9dafd
This commit is contained in:
parent
fb82777983
commit
3cb6226ff0
|
@ -67,7 +67,7 @@ parameters:
|
||||||
default: 10.0.0.0/24
|
default: 10.0.0.0/24
|
||||||
|
|
||||||
dns_nameserver:
|
dns_nameserver:
|
||||||
type: string
|
type: comma_delimited_list
|
||||||
description: address of a dns nameserver reachable in your environment
|
description: address of a dns nameserver reachable in your environment
|
||||||
|
|
||||||
http_proxy:
|
http_proxy:
|
||||||
|
|
|
@ -31,7 +31,7 @@ parameters:
|
||||||
description: flavor to use when booting the server for minions
|
description: flavor to use when booting the server for minions
|
||||||
|
|
||||||
dns_nameserver:
|
dns_nameserver:
|
||||||
type: string
|
type: comma_delimited_list
|
||||||
description: address of a DNS nameserver reachable in your environment
|
description: address of a DNS nameserver reachable in your environment
|
||||||
default: 8.8.8.8
|
default: 8.8.8.8
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,7 @@ class ClusterTemplate(base.APIBase):
|
||||||
master_flavor_id = wtypes.StringType(min_length=1, max_length=255)
|
master_flavor_id = wtypes.StringType(min_length=1, max_length=255)
|
||||||
"""The flavor of the master node for this ClusterTemplate"""
|
"""The flavor of the master node for this ClusterTemplate"""
|
||||||
|
|
||||||
dns_nameserver = wtypes.IPv4AddressType()
|
dns_nameserver = types.dns_list
|
||||||
"""The DNS nameserver address"""
|
"""The DNS nameserver address"""
|
||||||
|
|
||||||
keypair_id = wsme.wsattr(wtypes.StringType(min_length=1, max_length=255),
|
keypair_id = wsme.wsattr(wtypes.StringType(min_length=1, max_length=255),
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import inspect
|
import inspect
|
||||||
|
import six
|
||||||
|
|
||||||
from oslo_utils import strutils
|
from oslo_utils import strutils
|
||||||
from oslo_utils import uuidutils
|
from oslo_utils import uuidutils
|
||||||
|
@ -25,6 +26,17 @@ from magnum.common import utils
|
||||||
from magnum.i18n import _
|
from magnum.i18n import _
|
||||||
|
|
||||||
|
|
||||||
|
class DNSListType(wtypes.UserType):
|
||||||
|
"""A comman delimited dns nameserver list"""
|
||||||
|
|
||||||
|
basetype = six.string_types
|
||||||
|
name = "dnslist"
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def validate(value):
|
||||||
|
return utils.validate_dns(value)
|
||||||
|
|
||||||
|
|
||||||
class MacAddressType(wtypes.UserType):
|
class MacAddressType(wtypes.UserType):
|
||||||
"""A simple MAC address type."""
|
"""A simple MAC address type."""
|
||||||
|
|
||||||
|
@ -129,6 +141,7 @@ class MultiType(wtypes.UserType):
|
||||||
% {'type': self.types, 'value': type(value)})
|
% {'type': self.types, 'value': type(value)})
|
||||||
|
|
||||||
|
|
||||||
|
dns_list = DNSListType()
|
||||||
macaddress = MacAddressType()
|
macaddress = MacAddressType()
|
||||||
uuid = UuidType()
|
uuid = UuidType()
|
||||||
name = NameType()
|
name = NameType()
|
||||||
|
|
|
@ -220,6 +220,12 @@ class InvalidMAC(Invalid):
|
||||||
message = _("Expected a MAC address but received %(mac)s.")
|
message = _("Expected a MAC address but received %(mac)s.")
|
||||||
|
|
||||||
|
|
||||||
|
class InvalidDNS(Invalid):
|
||||||
|
message = _(
|
||||||
|
"Expected a single dns address or comma separated dns list, "
|
||||||
|
"but received %(dns)s.")
|
||||||
|
|
||||||
|
|
||||||
class ConfigInvalid(Invalid):
|
class ConfigInvalid(Invalid):
|
||||||
message = _("Invalid configuration file. %(error_msg)s")
|
message = _("Invalid configuration file. %(error_msg)s")
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ import re
|
||||||
import shutil
|
import shutil
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
|
import netaddr
|
||||||
from oslo_concurrency import processutils
|
from oslo_concurrency import processutils
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
from oslo_utils import netutils
|
from oslo_utils import netutils
|
||||||
|
@ -115,6 +116,24 @@ def validate_and_normalize_mac(address):
|
||||||
return address.lower()
|
return address.lower()
|
||||||
|
|
||||||
|
|
||||||
|
def validate_dns(dns_list):
|
||||||
|
"""Validate a string is a single dns address or comma separated dns list
|
||||||
|
|
||||||
|
:param dns_list: dns_list to be validated
|
||||||
|
:returns: original dns_list.
|
||||||
|
:raise: InvalidDNS if dns format is invalid
|
||||||
|
|
||||||
|
"""
|
||||||
|
dns_nameservers = dns_list.split(',')
|
||||||
|
try:
|
||||||
|
for dns in dns_nameservers:
|
||||||
|
netaddr.IPAddress(dns, version=4, flags=netaddr.INET_PTON)
|
||||||
|
except netaddr.AddrFormatError:
|
||||||
|
raise exception.InvalidDNS(dns=dns_list)
|
||||||
|
else:
|
||||||
|
return dns_list
|
||||||
|
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
def tempdir(**kwargs):
|
def tempdir(**kwargs):
|
||||||
tempfile.tempdir = CONF.tempdir
|
tempfile.tempdir = CONF.tempdir
|
||||||
|
|
|
@ -23,7 +23,7 @@ parameters:
|
||||||
default: ""
|
default: ""
|
||||||
|
|
||||||
dns_nameserver:
|
dns_nameserver:
|
||||||
type: string
|
type: comma_delimited_list
|
||||||
description: address of a dns nameserver reachable in your environment
|
description: address of a dns nameserver reachable in your environment
|
||||||
|
|
||||||
external_network:
|
external_network:
|
||||||
|
@ -41,8 +41,7 @@ resources:
|
||||||
properties:
|
properties:
|
||||||
cidr: {get_param: private_network_cidr}
|
cidr: {get_param: private_network_cidr}
|
||||||
network: {get_resource: private_network}
|
network: {get_resource: private_network}
|
||||||
dns_nameservers:
|
dns_nameservers: {get_param: dns_nameserver}
|
||||||
- {get_param: dns_nameserver}
|
|
||||||
|
|
||||||
extrouter:
|
extrouter:
|
||||||
type: Magnum::Optional::Neutron::Router
|
type: Magnum::Optional::Neutron::Router
|
||||||
|
|
|
@ -59,7 +59,7 @@ parameters:
|
||||||
admin user password for the Grafana monitoring interface
|
admin user password for the Grafana monitoring interface
|
||||||
|
|
||||||
dns_nameserver:
|
dns_nameserver:
|
||||||
type: string
|
type: comma_delimited_list
|
||||||
description: address of a DNS nameserver reachable in your environment
|
description: address of a DNS nameserver reachable in your environment
|
||||||
default: 8.8.8.8
|
default: 8.8.8.8
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ parameters:
|
||||||
admin user password for the Grafana monitoring interface
|
admin user password for the Grafana monitoring interface
|
||||||
|
|
||||||
dns_nameserver:
|
dns_nameserver:
|
||||||
type: string
|
type: comma_delimited_list
|
||||||
description: address of a DNS nameserver reachable in your environment
|
description: address of a DNS nameserver reachable in your environment
|
||||||
default: 8.8.8.8
|
default: 8.8.8.8
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,7 @@ parameters:
|
||||||
admin user password for the Grafana monitoring interface
|
admin user password for the Grafana monitoring interface
|
||||||
|
|
||||||
dns_nameserver:
|
dns_nameserver:
|
||||||
type: string
|
type: comma_delimited_list
|
||||||
description: address of a dns nameserver reachable in your environment
|
description: address of a dns nameserver reachable in your environment
|
||||||
default: 8.8.8.8
|
default: 8.8.8.8
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ parameters:
|
||||||
description: flavor to use when booting the slave server
|
description: flavor to use when booting the slave server
|
||||||
|
|
||||||
dns_nameserver:
|
dns_nameserver:
|
||||||
type: string
|
type: comma_delimited_list
|
||||||
description: address of a dns nameserver reachable in your environment
|
description: address of a dns nameserver reachable in your environment
|
||||||
default: 8.8.8.8
|
default: 8.8.8.8
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,7 @@ parameters:
|
||||||
description: flavor to use when booting the swarm node
|
description: flavor to use when booting the swarm node
|
||||||
|
|
||||||
dns_nameserver:
|
dns_nameserver:
|
||||||
type: string
|
type: comma_delimited_list
|
||||||
description: address of a dns nameserver reachable in your environment
|
description: address of a dns nameserver reachable in your environment
|
||||||
default: 8.8.8.8
|
default: 8.8.8.8
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ parameters:
|
||||||
description: flavor to use when booting the swarm node
|
description: flavor to use when booting the swarm node
|
||||||
|
|
||||||
dns_nameserver:
|
dns_nameserver:
|
||||||
type: string
|
type: comma_delimited_list
|
||||||
description: address of a dns nameserver reachable in your environment
|
description: address of a dns nameserver reachable in your environment
|
||||||
default: 8.8.8.8
|
default: 8.8.8.8
|
||||||
|
|
||||||
|
|
|
@ -775,7 +775,7 @@ class TestPost(api_base.FunctionalTest):
|
||||||
mock_image_data.return_value = {'name': 'mock_name',
|
mock_image_data.return_value = {'name': 'mock_name',
|
||||||
'os_distro': 'fedora-atomic'}
|
'os_distro': 'fedora-atomic'}
|
||||||
for k, v in cluster_template_config_dict.items():
|
for k, v in cluster_template_config_dict.items():
|
||||||
cfg.CONF.set_override(k, v, 'cluster_template')
|
cfg.CONF.set_override(k, v, 'cluster_template')
|
||||||
with mock.patch.object(
|
with mock.patch.object(
|
||||||
self.dbapi, 'create_cluster_template',
|
self.dbapi, 'create_cluster_template',
|
||||||
wraps=self.dbapi.create_cluster_template) as cc_mock:
|
wraps=self.dbapi.create_cluster_template) as cc_mock:
|
||||||
|
@ -1115,6 +1115,30 @@ class TestPost(api_base.FunctionalTest):
|
||||||
self.assertRaises(AppError, self.post_json, '/clustertemplates',
|
self.assertRaises(AppError, self.post_json, '/clustertemplates',
|
||||||
bdict)
|
bdict)
|
||||||
|
|
||||||
|
@mock.patch('magnum.api.attr_validator.validate_image')
|
||||||
|
@mock.patch('oslo_utils.timeutils.utcnow')
|
||||||
|
def test_create_cluster_template_with_multi_dns(self, mock_utcnow,
|
||||||
|
mock_image_data):
|
||||||
|
bdict = apiutils.cluster_template_post_data(
|
||||||
|
dns_nameserver="8.8.8.8,114.114.114.114")
|
||||||
|
test_time = datetime.datetime(2000, 1, 1, 0, 0)
|
||||||
|
mock_utcnow.return_value = test_time
|
||||||
|
mock_image_data.return_value = {'name': 'mock_name',
|
||||||
|
'os_distro': 'fedora-atomic'}
|
||||||
|
|
||||||
|
response = self.post_json('/clustertemplates', bdict)
|
||||||
|
self.assertEqual(201, response.status_int)
|
||||||
|
# Check location header
|
||||||
|
self.assertIsNotNone(response.location)
|
||||||
|
expected_location = '/v1/clustertemplates/%s' % bdict['uuid']
|
||||||
|
self.assertEqual(expected_location,
|
||||||
|
urlparse.urlparse(response.location).path)
|
||||||
|
self.assertEqual(bdict['uuid'], response.json['uuid'])
|
||||||
|
self.assertNotIn('updated_at', response.json.keys)
|
||||||
|
return_created_at = timeutils.parse_isotime(
|
||||||
|
response.json['created_at']).replace(tzinfo=None)
|
||||||
|
self.assertEqual(test_time, return_created_at)
|
||||||
|
|
||||||
|
|
||||||
class TestDelete(api_base.FunctionalTest):
|
class TestDelete(api_base.FunctionalTest):
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,24 @@ from magnum.common import utils
|
||||||
from magnum.tests.unit.api import base
|
from magnum.tests.unit.api import base
|
||||||
|
|
||||||
|
|
||||||
|
class TestDNSListType(base.FunctionalTest):
|
||||||
|
def test_valid_single_dns(self):
|
||||||
|
test_dns = "8.8.8.8"
|
||||||
|
with mock.patch.object(utils, 'validate_dns') as m_mock:
|
||||||
|
types.DNSListType.validate(test_dns)
|
||||||
|
m_mock.assert_called_once_with(test_dns)
|
||||||
|
|
||||||
|
def test_valid_multi_dns(self):
|
||||||
|
test_dns = "8.8.8.8,114.114.114.114"
|
||||||
|
with mock.patch.object(utils, 'validate_dns') as m_mock:
|
||||||
|
types.DNSListType.validate(test_dns)
|
||||||
|
m_mock.assert_called_once_with(test_dns)
|
||||||
|
|
||||||
|
def test_invalid_single_dns(self):
|
||||||
|
self.assertRaises(exception.InvalidDNS,
|
||||||
|
types.DNSListType.validate, 'invalid-dns')
|
||||||
|
|
||||||
|
|
||||||
class TestMacAddressType(base.FunctionalTest):
|
class TestMacAddressType(base.FunctionalTest):
|
||||||
|
|
||||||
def test_valid_mac_addr(self):
|
def test_valid_mac_addr(self):
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
---
|
||||||
|
features:
|
||||||
|
- Support multi DNS server when creating template.
|
||||||
|
User can use a comma delimited ipv4 address list
|
||||||
|
to specify multi dns server, for example
|
||||||
|
"8.8.8.8,114.114.114.114"
|
Loading…
Reference in New Issue