Swarm: Map master address to api_address based on TLS

api_address is a API address instead of master node's IP address.
This patch fix it by adding a new OutputMapping, it will help to handle
the mapping from master address to api_address.

Also test cases added.

Closes-Bug: #1514311
Change-Id: I47baf92dd466150adbd75746d0cb804d108f7d5f
This commit is contained in:
Eli Qiao 2015-11-09 17:40:35 +08:00
parent 186e056acc
commit e36911f429
5 changed files with 77 additions and 49 deletions

View File

@ -81,12 +81,9 @@ def docker_for_container(context, container):
def docker_for_bay(context, bay):
baymodel = conductor_utils.retrieve_baymodel(context, bay)
tcp_url = 'tcp://%s:2376' % bay.api_address
ca_cert, magnum_key, magnum_cert = None, None, None
client_kwargs = dict()
if not baymodel.tls_disabled:
tcp_url = 'https://%s:2376' % bay.api_address
(ca_cert, magnum_key,
magnum_cert) = cert_manager.create_client_files(bay)
client_kwargs['ca_cert'] = ca_cert.name
@ -94,7 +91,7 @@ def docker_for_bay(context, bay):
client_kwargs['client_cert'] = magnum_cert.name
yield docker_client.DockerHTTPClient(
tcp_url,
bay.api_address,
CONF.docker.docker_remote_api_version,
CONF.docker.default_timeout,
**client_kwargs

View File

@ -31,6 +31,7 @@ LOG = logging.getLogger(__name__)
KUBE_SECURE_PORT = '6443'
KUBE_INSECURE_PORT = '8080'
DOCKER_PORT = '2376'
template_def_opts = [
cfg.StrOpt('k8s_atomic_template_path',
@ -399,6 +400,25 @@ class K8sApiAddressOutputMapping(OutputMapping):
setattr(bay, self.bay_attr, output_value)
class SwarmApiAddressOutputMapping(OutputMapping):
def set_output(self, stack, baymodel, bay):
protocol = 'https'
if baymodel.tls_disabled:
protocol = 'tcp'
output_value = self.get_output_value(stack)
params = {
'protocol': protocol,
'address': output_value,
'port': DOCKER_PORT,
}
output_value = "%(protocol)s://%(address)s:%(port)s" % params
if output_value is not None:
setattr(bay, self.bay_attr, output_value)
class AtomicK8sTemplateDefinition(BaseTemplateDefinition):
"""Kubernetes template for a Fedora Atomic VM."""
@ -558,7 +578,8 @@ class AtomicSwarmTemplateDefinition(BaseTemplateDefinition):
baymodel_attr='tls_disabled',
required=True)
self.add_output('api_address',
bay_attr='api_address')
bay_attr='api_address',
mapping_type=SwarmApiAddressOutputMapping)
self.add_output('swarm_master_private',
bay_attr=None)
self.add_output('swarm_master',

View File

@ -33,7 +33,7 @@ class TestDockerUtils(base.BaseTestCase):
mock_docker_client):
mock_container = mock.MagicMock()
mock_bay = mock.MagicMock()
mock_bay.api_address = '1.2.3.4'
mock_bay.api_address = 'https://1.2.3.4:2376'
mock_get_bay_by_uuid.return_value = mock_bay
mock_baymodel = mock.MagicMock()
mock_baymodel.tls_disabled = False
@ -78,7 +78,7 @@ class TestDockerUtils(base.BaseTestCase):
mock_container.uuid = '8e48ffb1-754d-4f21-bdd0-1a39bf796389'
mock_get_container_by_uuid.return_value = mock_container
mock_bay = mock.MagicMock()
mock_bay.api_address = '1.2.3.4'
mock_bay.api_address = 'https://1.2.3.4:2376'
mock_get_bay_by_uuid.return_value = mock_bay
mock_baymodel = mock.MagicMock()
mock_baymodel.tls_disabled = False
@ -120,7 +120,7 @@ class TestDockerUtils(base.BaseTestCase):
mock_docker_client):
mock_container = mock.MagicMock()
mock_bay = mock.MagicMock()
mock_bay.api_address = '1.2.3.4'
mock_bay.api_address = 'tcp://1.2.3.4:2376'
mock_get_bay_by_uuid.return_value = mock_bay
mock_baymodel = mock.MagicMock()
mock_baymodel.tls_disabled = True

View File

@ -40,7 +40,7 @@ class MonitorsTestCase(base.TestCase):
super(MonitorsTestCase, self).setUp()
bay = utils.get_test_bay(node_addresses=['1.2.3.4'],
api_address='5.6.7.8')
api_address='https://5.6.7.8:2376')
self.bay = objects.Bay(self.context, **bay)
self.monitor = swarm_monitor.SwarmMonitor(self.context, self.bay)
self.k8s_monitor = k8s_monitor.K8sMonitor(self.context, self.bay)

View File

@ -301,62 +301,72 @@ class AtomicK8sTemplateDefinitionTestCase(base.TestCase):
tdef.AtomicK8sTemplateDefinition().get_discovery_url,
fake_bay)
def test_update_outputs_api_address(self):
self._test_update_outputs(tls_disabled=True,
expected_protocol='http',
expected_port='8080')
def _test_update_outputs_api_address(self, coe, params, tls=True):
def test_update_outputs_if_baymodel_is_secure(self):
self._test_update_outputs(tls_disabled=False,
expected_protocol='https',
expected_port='6443')
def _test_update_outputs(self, tls_disabled, expected_protocol,
expected_port):
definition = tdef.TemplateDefinition.get_template_definition(
'vm',
'fedora-atomic',
'kubernetes')
address = 'updated_address'
params = {
'protocol': expected_protocol,
'address': address,
'port': expected_port,
}
coe)
expected_api_address = '%(protocol)s://%(address)s:%(port)s' % params
expected_master_addresses = ['ex_master', 'address']
expected_node_addresses = ['ex_minion', 'address']
outputs = [
{"output_value": address,
{"output_value": params['address'],
"description": "No description given",
"output_key": "api_address"},
{"output_value": ['any', 'output'],
"description": "No description given",
"output_key": "kube_masters_private"},
{"output_value": expected_master_addresses,
"description": "No description given",
"output_key": "kube_masters"},
{"output_value": ['any', 'output'],
"description": "No description given",
"output_key": "kube_minions_private"},
{"output_value": expected_node_addresses,
"description": "No description given",
"output_key": "kube_minions"},
"output_key": 'api_address'},
]
mock_stack = mock.MagicMock()
mock_stack.outputs = outputs
mock_bay = mock.MagicMock()
mock_baymodel = mock.MagicMock()
mock_baymodel.tls_disabled = tls_disabled
mock_baymodel.tls_disabled = tls
definition.update_outputs(mock_stack, mock_baymodel, mock_bay)
self.assertEqual(expected_api_address, mock_bay.api_address)
self.assertEqual(expected_master_addresses, mock_bay.master_addresses)
self.assertEqual(expected_node_addresses, mock_bay.node_addresses)
def test_update_k8s_outputs_api_address(self):
address = 'updated_address'
protocol = 'http'
port = '8080'
params = {
'protocol': protocol,
'address': address,
'port': port,
}
self._test_update_outputs_api_address('kubernetes', params)
def test_update_swarm_outputs_api_address(self):
address = 'updated_address'
protocol = 'tcp'
port = '2376'
params = {
'protocol': protocol,
'address': address,
'port': port,
}
self._test_update_outputs_api_address('swarm', params)
def test_update_k8s_outputs_if_baymodel_is_secure(self):
address = 'updated_address'
protocol = 'https'
port = '6443'
params = {
'protocol': protocol,
'address': address,
'port': port,
}
self._test_update_outputs_api_address('kubernetes', params, tls=False)
def test_update_swarm_outputs_if_baymodel_is_secure(self):
address = 'updated_address'
protocol = 'https'
port = '2376'
params = {
'protocol': protocol,
'address': address,
'port': port,
}
self._test_update_outputs_api_address('swarm', params, tls=False)
class AtomicSwarmTemplateDefinitionTestCase(base.TestCase):
@ -454,7 +464,7 @@ class AtomicSwarmTemplateDefinitionTestCase(base.TestCase):
mock_baymodel = mock.MagicMock()
swarm_def.update_outputs(mock_stack, mock_baymodel, mock_bay)
expected_api_address = "tcp://%s:2376" % expected_api_address
self.assertEqual(expected_api_address, mock_bay.api_address)
self.assertEqual(expected_node_addresses, mock_bay.node_addresses)