Unify common output keys across Heat templates

After this commit, all Heat templates have five common outputs:
* api_address: API endpoint of specific COE.
* kube_masters/swarm_master/mesos_master: Public IP address(es) of
  master node(s).
* kube_masters_private/swarm_master_private/mesos_master_private:
  Private IP address(es) of master node(s).
* kube_minions/swarm_nodes/mesos_slaves: List of public IP addresses
  of worker nodes.
* kube_minions_private/swarm_nodes_private/mesos_slaves_private:
  List of private IP addresses of worker nodes.

Change-Id: Ie44136dafa326db598a5f17978d89adce8e69801
Closes-Bug: #1514252
This commit is contained in:
Hongbin Lu 2015-11-08 18:24:26 -05:00
parent c603b300c8
commit 1b928008bd
9 changed files with 164 additions and 77 deletions

View File

@ -437,10 +437,14 @@ class AtomicK8sTemplateDefinition(BaseTemplateDefinition):
self.add_output('api_address',
bay_attr='api_address',
mapping_type=K8sApiAddressOutputMapping)
self.add_output('kube_minions',
self.add_output('kube_minions_private',
bay_attr=None)
self.add_output('kube_minions_external',
self.add_output('kube_minions',
bay_attr='node_addresses')
self.add_output('kube_masters_private',
bay_attr=None)
self.add_output('kube_masters',
bay_attr='master_addresses')
def get_discovery_url(self, bay):
if hasattr(bay, 'discovery_url') and bay.discovery_url:
@ -553,9 +557,15 @@ class AtomicSwarmTemplateDefinition(BaseTemplateDefinition):
self.add_parameter('tls_disabled',
baymodel_attr='tls_disabled',
required=True)
self.add_output('swarm_master',
self.add_output('api_address',
bay_attr='api_address')
self.add_output('swarm_nodes_external',
self.add_output('swarm_master_private',
bay_attr=None)
self.add_output('swarm_master',
bay_attr=None)
self.add_output('swarm_nodes_private',
bay_attr=None)
self.add_output('swarm_nodes',
bay_attr='node_addresses')
self.add_output('discovery_url',
bay_attr='discovery_url')
@ -620,8 +630,14 @@ class UbuntuMesosTemplateDefinition(BaseTemplateDefinition):
self.add_parameter('slave_flavor',
baymodel_attr='flavor_id')
self.add_output('mesos_master',
self.add_output('api_address',
bay_attr='api_address')
self.add_output('mesos_master_private',
bay_attr=None)
self.add_output('mesos_master',
bay_attr=None)
self.add_output('mesos_slaves_private',
bay_attr=None)
self.add_output('mesos_slaves',
bay_attr='node_addresses')

View File

@ -402,13 +402,19 @@ resources:
outputs:
api_address:
value: {get_attr: [swarm_master_floating, floating_ip_address]}
swarm_master_private:
value: {get_attr: [swarm_master_eth0, fixed_ips, 0, ip_address]}
swarm_master:
value: {get_attr: [swarm_master_floating, floating_ip_address]}
swarm_nodes:
swarm_nodes_private:
value: {get_attr: [swarm_nodes, swarm_node_ip]}
swarm_nodes_external:
swarm_nodes:
value: {get_attr: [swarm_nodes, swarm_node_external_ip]}
discovery_url:

View File

@ -77,7 +77,7 @@ If you enable docker registry v2, you must provide values for:
You can get the ip address of the Kubernetes master using the `heat
output-show` command:
$ heat output-show my-kube-cluster kube_master
$ heat output-show my-kube-cluster kube_masters
"192.168.200.86"
You can ssh into that server as the `minion` user:
@ -93,7 +93,7 @@ And once logged in you can run `kubectl`, etc:
You can log into your minions using the `minion` user as well. You
can get a list of minion addresses by running:
$ heat output-show my-kube-cluster kube_minions_external
$ heat output-show my-kube-cluster kube_minions
[
"192.168.200.182"
]

View File

@ -225,11 +225,17 @@ resources:
outputs:
kube_master:
api_address:
value: {get_attr: [kube_master, kube_master_external_ip]}
kube_minions:
kube_masters_private:
value: {get_attr: [kube_master, kube_master_ip]}
kube_masters:
value: {get_attr: [kube_master, kube_master_external_ip]}
kube_minions_private:
value: {get_attr: [kube_minions, kube_minion_ip]}
kube_minions_external:
kube_minions:
value: {get_attr: [kube_minions, kube_minion_external_ip]}

View File

@ -162,11 +162,17 @@ resources:
outputs:
kube_master:
api_address:
value: {get_attr: [kube_master, kube_master_external_ip]}
kube_minions:
kube_masters_private:
value: {get_attr: [kube_master, kube_master_ip]}
kube_masters:
value: {get_attr: [kube_master, kube_master_external_ip]}
kube_minions_private:
value: {get_attr: [kube_minions, kube_node_ip]}
kube_minions_external:
kube_minions:
value: {get_attr: [kube_minions, kube_node_external_ip]}

View File

@ -493,18 +493,23 @@ outputs:
This is the url of docker registry server where you can store docker
images.
kube_masters_private:
value: {get_attr: [kube_masters, kube_master_ip]}
description: >
This is a list of the "private" addresses of all the Kubernetes masters.
kube_masters:
value: {get_attr: [kube_masters, kube_master_external_ip]}
description: >
This is a list of "public" ip addresses of all Kubernetes master servers.
Use these addresses to log in to the Kubernetes masters via ssh.
kube_minions:
kube_minions_private:
value: {get_attr: [kube_minions, kube_minion_ip]}
description: >
This is a list of the "private" addresses of all the Kubernetes minions.
kube_minions_external:
kube_minions:
value: {get_attr: [kube_minions, kube_minion_external_ip]}
description: >
This is a list of the "public" addresses of all the Kubernetes minions. Use

View File

@ -206,5 +206,8 @@ resources:
outputs:
kube_master_ip:
value: {get_attr: [kube_master, networks, private, 0]}
kube_master_external_ip:
value: {get_attr: [kube_master_floating, floating_ip_address]}

View File

@ -250,6 +250,12 @@ resources:
outputs:
api_address:
value: {get_attr: [mesos_master_floating, floating_ip_address]}
mesos_master_private:
value: {get_attr: [mesos_master_eth0, fixed_ips, 0, ip_address]}
mesos_master:
value: {get_attr: [mesos_master_floating, floating_ip_address]}
description: >
@ -257,6 +263,9 @@ outputs:
log in to the Mesos master via ssh or to access the Mesos API
from outside the cluster.
mesos_slaves_private:
value: {get_attr: [mesos_slaves, mesos_slave_ip]}
mesos_slaves:
value: {get_attr: [mesos_slaves, mesos_slave_external_ip]}
description: >

View File

@ -153,32 +153,6 @@ class TemplateDefinitionTestCase(base.TestCase):
self.assertIn(mock_mapping_type.return_value,
definition.output_mappings)
def test_update_outputs(self):
definition = tdef.TemplateDefinition.get_template_definition(
'vm',
'fedora-atomic',
'kubernetes')
expected_node_addresses = ['ex_minion', 'address']
outputs = [
{"output_value": expected_node_addresses,
"description": "No description given",
"output_key": "kube_minions_external"},
{"output_value": ['any', 'output'],
"description": "No description given",
"output_key": "kube_minions"}
]
mock_stack = mock.MagicMock()
mock_stack.outputs = outputs
mock_bay = mock.MagicMock()
mock_bay.api_address = None
mock_baymodel = mock.MagicMock()
definition.update_outputs(mock_stack, mock_baymodel, mock_bay)
self.assertEqual(expected_node_addresses, mock_bay.node_addresses)
class AtomicK8sTemplateDefinitionTestCase(base.TestCase):
@ -328,65 +302,61 @@ class AtomicK8sTemplateDefinitionTestCase(base.TestCase):
fake_bay)
def test_update_outputs_api_address(self):
definition = tdef.TemplateDefinition.get_template_definition(
'vm',
'fedora-atomic',
'kubernetes')
address = 'updated_address'
protocol = 'http'
port = '8080'
params = {
'protocol': protocol,
'address': address,
'port': port,
}
expected_api_address = '%(protocol)s://%(address)s:%(port)s' % params
outputs = [
{"output_value": address,
"description": "No description given",
"output_key": "api_address"},
]
mock_stack = mock.MagicMock()
mock_stack.outputs = outputs
mock_bay = mock.MagicMock()
mock_baymodel = mock.MagicMock()
mock_baymodel.tls_disabled = True
definition.update_outputs(mock_stack, mock_baymodel, mock_bay)
self.assertEqual(expected_api_address, mock_bay.api_address)
self._test_update_outputs(tls_disabled=True,
expected_protocol='http',
expected_port='8080')
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'
protocol = 'https'
port = '6443'
params = {
'protocol': protocol,
'protocol': expected_protocol,
'address': address,
'port': port,
'port': expected_port,
}
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,
"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"},
]
mock_stack = mock.MagicMock()
mock_stack.outputs = outputs
mock_bay = mock.MagicMock()
mock_baymodel = mock.MagicMock()
mock_baymodel.tls_disabled = False
mock_baymodel.tls_disabled = tls_disabled
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)
class AtomicSwarmTemplateDefinitionTestCase(base.TestCase):
@ -455,6 +425,39 @@ class AtomicSwarmTemplateDefinitionTestCase(base.TestCase):
heat_param = swarm_def.get_heat_param(bay_attr='node_count')
self.assertEqual('number_of_nodes', heat_param)
def test_update_outputs(self):
swarm_def = tdef.AtomicSwarmTemplateDefinition()
expected_api_address = 'updated_address'
expected_node_addresses = ['ex_minion', 'address']
outputs = [
{"output_value": expected_api_address,
"description": "No description given",
"output_key": "api_address"},
{"output_value": ['any', 'output'],
"description": "No description given",
"output_key": "swarm_master_private"},
{"output_value": ['any', 'output'],
"description": "No description given",
"output_key": "swarm_master"},
{"output_value": ['any', 'output'],
"description": "No description given",
"output_key": "swarm_nodes_private"},
{"output_value": expected_node_addresses,
"description": "No description given",
"output_key": "swarm_nodes"},
]
mock_stack = mock.MagicMock()
mock_stack.outputs = outputs
mock_bay = mock.MagicMock()
mock_baymodel = mock.MagicMock()
swarm_def.update_outputs(mock_stack, mock_baymodel, mock_bay)
self.assertEqual(expected_api_address, mock_bay.api_address)
self.assertEqual(expected_node_addresses, mock_bay.node_addresses)
class UbuntuMesosTemplateDefinitionTestCase(base.TestCase):
@ -463,3 +466,36 @@ class UbuntuMesosTemplateDefinitionTestCase(base.TestCase):
heat_param = mesos_def.get_heat_param(bay_attr='node_count')
self.assertEqual('number_of_slaves', heat_param)
def test_update_outputs(self):
mesos_def = tdef.UbuntuMesosTemplateDefinition()
expected_api_address = 'updated_address'
expected_node_addresses = ['ex_minion', 'address']
outputs = [
{"output_value": expected_api_address,
"description": "No description given",
"output_key": "api_address"},
{"output_value": ['any', 'output'],
"description": "No description given",
"output_key": "mesos_master_private"},
{"output_value": ['any', 'output'],
"description": "No description given",
"output_key": "mesos_master"},
{"output_value": ['any', 'output'],
"description": "No description given",
"output_key": "mesos_slaves_private"},
{"output_value": expected_node_addresses,
"description": "No description given",
"output_key": "mesos_slaves"},
]
mock_stack = mock.MagicMock()
mock_stack.outputs = outputs
mock_bay = mock.MagicMock()
mock_baymodel = mock.MagicMock()
mesos_def.update_outputs(mock_stack, mock_baymodel, mock_bay)
self.assertEqual(expected_api_address, mock_bay.api_address)
self.assertEqual(expected_node_addresses, mock_bay.node_addresses)