Add Swarm TemplateDefinition
This change will allow deployers to select either Kubernetes or Swarm to be the CoE used in Magnum's bays. A Swarm bay uses a subset of the BayModel parameters used for Kubernetes. Node discovery is provided via Docker's public discovery endpoint, but operators and users can override this with Bay's discovery_url argument. Implements: bp multiple-bay-templates Change-Id: I5278e6d477298085d07673810e5d8813d21b7730
This commit is contained in:
parent
784643e142
commit
6d64188d50
@ -259,6 +259,35 @@ Now log into one of the other container hosts and access a redis slave from ther
|
|||||||
There are four redis instances, one master and three slaves, running across the bay,
|
There are four redis instances, one master and three slaves, running across the bay,
|
||||||
replicating data between one another.
|
replicating data between one another.
|
||||||
|
|
||||||
|
Building a Swarm bay
|
||||||
|
====================
|
||||||
|
|
||||||
|
First, we will need to reconfigure Magnum. We need to set 'cluster_coe' in
|
||||||
|
the 'k8s_head' section to 'swarm' in the magnum.conf. After changing
|
||||||
|
magnum.conf restart magnum-api and magnum-conductor.::
|
||||||
|
|
||||||
|
sudo cat >> /etc/magnum/magnum.conf << END_CONFIG
|
||||||
|
[k8s_heat]
|
||||||
|
cluster_coe=swarm
|
||||||
|
END_CONFIG
|
||||||
|
|
||||||
|
|
||||||
|
Next, create a baymodel, it is very similar to the Kubernetes baymodel,
|
||||||
|
it is only missing some Kubernetes specific arguments.::
|
||||||
|
|
||||||
|
NIC_ID=$(neutron net-show public | awk '/ id /{print $4}')
|
||||||
|
magnum baymodel-create --name swarmbaymodel --image-id fedora-21-atomic-2 \
|
||||||
|
--keypair-id testkey \
|
||||||
|
--external-network-id $NIC_ID \
|
||||||
|
--dns-nameserver 8.8.8.8 --flavor-id m1.small
|
||||||
|
|
||||||
|
Finally, create the bay. Use the baymodel 'swarmbaymodel' as a template for
|
||||||
|
bay creation. This bay will result in one swarm manager node and two extra
|
||||||
|
agent nodes. ::
|
||||||
|
|
||||||
|
magnum bay-create --name swarmbay --baymodel swarmbaymodel --node-count 2
|
||||||
|
|
||||||
|
|
||||||
Building developer documentation
|
Building developer documentation
|
||||||
================================
|
================================
|
||||||
|
|
||||||
|
@ -229,8 +229,12 @@
|
|||||||
# Deprecated group/name - [k8s_heat]/discovery_token_url
|
# Deprecated group/name - [k8s_heat]/discovery_token_url
|
||||||
#coreos_discovery_token_url = <None>
|
#coreos_discovery_token_url = <None>
|
||||||
|
|
||||||
|
# Location of template to build a swarm cluster on atomic. (string
|
||||||
|
# value)
|
||||||
|
#swarm_atomic_template_path = $pybasedir/templates/docker-swarm/swarm.yaml
|
||||||
|
|
||||||
# Enabled bay definition entry points. (list value)
|
# Enabled bay definition entry points. (list value)
|
||||||
#enabled_definitions = magnum_vm_atomic_k8s,magnum_vm_coreos_k8s
|
#enabled_definitions = magnum_vm_atomic_k8s,magnum_vm_coreos_k8s,magnum_vm_atomic_swarm
|
||||||
|
|
||||||
|
|
||||||
[conductor]
|
[conductor]
|
||||||
@ -430,6 +434,10 @@
|
|||||||
# Cluster types are fedora-atomic, coreos, ironic. (string value)
|
# Cluster types are fedora-atomic, coreos, ironic. (string value)
|
||||||
#cluster_type = fedora-atomic
|
#cluster_type = fedora-atomic
|
||||||
|
|
||||||
|
# Container Orchestration Environments are kubernetes or swarm.
|
||||||
|
# (string value)
|
||||||
|
#cluster_coe = kubernetes
|
||||||
|
|
||||||
# Number of attempts to query the Heat stack for finding out the
|
# Number of attempts to query the Heat stack for finding out the
|
||||||
# status of the created stack and getting url of the DU created in the
|
# status of the created stack and getting url of the DU created in the
|
||||||
# stack (integer value)
|
# stack (integer value)
|
||||||
|
@ -81,6 +81,9 @@ class Bay(base.APIBase):
|
|||||||
status = wtypes.text
|
status = wtypes.text
|
||||||
"""Status of the bay from the heat stack"""
|
"""Status of the bay from the heat stack"""
|
||||||
|
|
||||||
|
discovery_url = wtypes.text
|
||||||
|
"""Url used for bay node discovery"""
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
super(Bay, self).__init__()
|
super(Bay, self).__init__()
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ from oslo_config import cfg
|
|||||||
from magnum.common import clients
|
from magnum.common import clients
|
||||||
from magnum.common import exception
|
from magnum.common import exception
|
||||||
from magnum.common import short_id
|
from magnum.common import short_id
|
||||||
from magnum.conductor import template_definition as tdef
|
from magnum.conductor.template_definition import TemplateDefinition as TDef
|
||||||
from magnum import objects
|
from magnum import objects
|
||||||
from magnum.openstack.common._i18n import _
|
from magnum.openstack.common._i18n import _
|
||||||
from magnum.openstack.common._i18n import _LE
|
from magnum.openstack.common._i18n import _LE
|
||||||
@ -32,6 +32,10 @@ k8s_heat_opts = [
|
|||||||
cfg.StrOpt('cluster_type',
|
cfg.StrOpt('cluster_type',
|
||||||
default='fedora-atomic',
|
default='fedora-atomic',
|
||||||
help=_('Cluster types are fedora-atomic, coreos, ironic.')),
|
help=_('Cluster types are fedora-atomic, coreos, ironic.')),
|
||||||
|
cfg.StrOpt('cluster_coe',
|
||||||
|
default='kubernetes',
|
||||||
|
help=_('Container Orchestration Environments are '
|
||||||
|
'kubernetes or swarm. ')),
|
||||||
cfg.IntOpt('max_attempts',
|
cfg.IntOpt('max_attempts',
|
||||||
default=2000,
|
default=2000,
|
||||||
help=('Number of attempts to query the Heat stack for '
|
help=('Number of attempts to query the Heat stack for '
|
||||||
@ -51,9 +55,9 @@ LOG = logging.getLogger(__name__)
|
|||||||
|
|
||||||
def _extract_template_definition(context, bay):
|
def _extract_template_definition(context, bay):
|
||||||
baymodel = objects.BayModel.get_by_uuid(context, bay.baymodel_id)
|
baymodel = objects.BayModel.get_by_uuid(context, bay.baymodel_id)
|
||||||
definition = tdef.TemplateDefinition.get_template_definition('vm',
|
cluster_type = cfg.CONF.k8s_heat.cluster_type
|
||||||
cfg.CONF.k8s_heat.cluster_type,
|
cluster_coe = cfg.CONF.k8s_heat.cluster_coe
|
||||||
'kubernetes')
|
definition = TDef.get_template_definition('vm', cluster_type, cluster_coe)
|
||||||
return definition.extract_definition(baymodel, bay)
|
return definition.extract_definition(baymodel, bay)
|
||||||
|
|
||||||
|
|
||||||
@ -88,9 +92,9 @@ def _update_stack(context, osc, bay):
|
|||||||
|
|
||||||
|
|
||||||
def _update_stack_outputs(stack, bay):
|
def _update_stack_outputs(stack, bay):
|
||||||
definition = tdef.TemplateDefinition.get_template_definition('vm',
|
cluster_type = cfg.CONF.k8s_heat.cluster_type
|
||||||
cfg.CONF.k8s_heat.cluster_type,
|
cluster_coe = cfg.CONF.k8s_heat.cluster_coe
|
||||||
'kubernetes')
|
definition = TDef.get_template_definition('vm', cluster_type, cluster_coe)
|
||||||
return definition.update_outputs(stack, bay)
|
return definition.update_outputs(stack, bay)
|
||||||
|
|
||||||
|
|
||||||
|
@ -43,8 +43,26 @@ template_def_opts = [
|
|||||||
deprecated_name='discovery_token_url',
|
deprecated_name='discovery_token_url',
|
||||||
deprecated_group='k8s_heat',
|
deprecated_group='k8s_heat',
|
||||||
help=_('coreos discovery token url.')),
|
help=_('coreos discovery token url.')),
|
||||||
|
cfg.StrOpt('swarm_atomic_template_path',
|
||||||
|
default=paths.basedir_def('templates/docker-swarm/'
|
||||||
|
'swarm.yaml'),
|
||||||
|
help=_('Location of template to build a swarm '
|
||||||
|
'cluster on atomic. ')),
|
||||||
|
cfg.StrOpt('swarm_discovery_url_format',
|
||||||
|
default=None,
|
||||||
|
help=_('Format string to use for swarm discovery url. '
|
||||||
|
'Available values: bay_id, bay_uuid. '
|
||||||
|
'Example: "etcd://etcd.example.com/\%(bay_uuid)s" ')),
|
||||||
|
cfg.BoolOpt('public_swarm_discovery',
|
||||||
|
default=True,
|
||||||
|
help=_('Indicates Swarm discovery should use public '
|
||||||
|
'endpoint.')),
|
||||||
|
cfg.StrOpt('public_swarm_discovery_url',
|
||||||
|
default='https://discovery-stage.hub.docker.com/v1/clusters',
|
||||||
|
help=_('Url for swarm public discovery endpoint.')),
|
||||||
cfg.ListOpt('enabled_definitions',
|
cfg.ListOpt('enabled_definitions',
|
||||||
default=['magnum_vm_atomic_k8s', 'magnum_vm_coreos_k8s'],
|
default=['magnum_vm_atomic_k8s', 'magnum_vm_coreos_k8s',
|
||||||
|
'magnum_vm_atomic_swarm'],
|
||||||
help=_('Enabled bay definition entry points. ')),
|
help=_('Enabled bay definition entry points. ')),
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -263,11 +281,20 @@ class BaseTemplateDefinition(TemplateDefinition):
|
|||||||
self.add_parameter('ssh_key_name',
|
self.add_parameter('ssh_key_name',
|
||||||
baymodel_attr='keypair_id',
|
baymodel_attr='keypair_id',
|
||||||
required=True)
|
required=True)
|
||||||
|
self.add_parameter('external_network_id',
|
||||||
|
baymodel_attr='external_network_id',
|
||||||
|
required=True)
|
||||||
|
|
||||||
self.add_parameter('server_image',
|
self.add_parameter('server_image',
|
||||||
baymodel_attr='image_id')
|
baymodel_attr='image_id')
|
||||||
self.add_parameter('server_flavor',
|
self.add_parameter('server_flavor',
|
||||||
baymodel_attr='flavor_id')
|
baymodel_attr='flavor_id')
|
||||||
|
self.add_parameter('dns_nameserver',
|
||||||
|
baymodel_attr='dns_nameserver')
|
||||||
|
|
||||||
|
@abc.abstractproperty
|
||||||
|
def template_path(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class AtomicK8sTemplateDefinition(BaseTemplateDefinition):
|
class AtomicK8sTemplateDefinition(BaseTemplateDefinition):
|
||||||
@ -277,12 +304,6 @@ class AtomicK8sTemplateDefinition(BaseTemplateDefinition):
|
|||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(AtomicK8sTemplateDefinition, self).__init__()
|
super(AtomicK8sTemplateDefinition, self).__init__()
|
||||||
self.add_parameter('external_network_id',
|
|
||||||
baymodel_attr='external_network_id',
|
|
||||||
required=True)
|
|
||||||
|
|
||||||
self.add_parameter('dns_nameserver',
|
|
||||||
baymodel_attr='dns_nameserver')
|
|
||||||
self.add_parameter('master_flavor',
|
self.add_parameter('master_flavor',
|
||||||
baymodel_attr='master_flavor_id')
|
baymodel_attr='master_flavor_id')
|
||||||
self.add_parameter('fixed_network',
|
self.add_parameter('fixed_network',
|
||||||
@ -339,3 +360,57 @@ class CoreOSK8sTemplateDefinition(AtomicK8sTemplateDefinition):
|
|||||||
@property
|
@property
|
||||||
def template_path(self):
|
def template_path(self):
|
||||||
return cfg.CONF.bay.k8s_coreos_template_path
|
return cfg.CONF.bay.k8s_coreos_template_path
|
||||||
|
|
||||||
|
|
||||||
|
class AtomicSwarmTemplateDefinition(BaseTemplateDefinition):
|
||||||
|
provides = [
|
||||||
|
{'platform': 'vm', 'os': 'fedora-atomic', 'coe': 'swarm'},
|
||||||
|
]
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super(AtomicSwarmTemplateDefinition, self).__init__()
|
||||||
|
self.add_parameter('number_of_nodes',
|
||||||
|
bay_attr='node_count',
|
||||||
|
param_type=str)
|
||||||
|
self.add_parameter('fixed_network_cidr',
|
||||||
|
baymodel_attr='fixed_network')
|
||||||
|
|
||||||
|
self.add_output('swarm_manager',
|
||||||
|
bay_attr='api_address')
|
||||||
|
self.add_output('swarm_nodes_external',
|
||||||
|
bay_attr='node_addresses')
|
||||||
|
self.add_output('discovery_url',
|
||||||
|
bay_attr='discovery_url')
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_public_token():
|
||||||
|
token_id = requests.post(cfg.CONF.bay.public_swarm_discovery_url).text
|
||||||
|
return 'token://%s' % token_id
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def parse_discovery_url(bay):
|
||||||
|
strings = dict(bay_id=bay.id, bay_uuid=bay.uuid)
|
||||||
|
return cfg.CONF.bay.swarm_discovery_url_format % strings
|
||||||
|
|
||||||
|
def get_discovery_url(self, bay):
|
||||||
|
if hasattr(bay, 'discovery_url') and bay.discovery_url:
|
||||||
|
discovery_url = bay.discovery_url
|
||||||
|
elif cfg.CONF.bay.public_swarm_discovery:
|
||||||
|
discovery_url = self.get_public_token()
|
||||||
|
else:
|
||||||
|
discovery_url = self.parse_discovery_url(bay)
|
||||||
|
|
||||||
|
return discovery_url
|
||||||
|
|
||||||
|
def get_params(self, baymodel, bay, extra_params=None):
|
||||||
|
if not extra_params:
|
||||||
|
extra_params = dict()
|
||||||
|
|
||||||
|
extra_params['discovery_url'] = self.get_discovery_url(bay)
|
||||||
|
|
||||||
|
return super(AtomicSwarmTemplateDefinition,
|
||||||
|
self).get_params(baymodel, bay, extra_params=extra_params)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def template_path(self):
|
||||||
|
return cfg.CONF.bay.swarm_atomic_template_path
|
||||||
|
@ -0,0 +1,31 @@
|
|||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
"""add-discovery-url-to-bay
|
||||||
|
|
||||||
|
Revision ID: 4ea34a59a64c
|
||||||
|
Revises: 456126c6c9e9
|
||||||
|
Create Date: 2015-04-14 18:56:03.440329
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = '4ea34a59a64c'
|
||||||
|
down_revision = '456126c6c9e9'
|
||||||
|
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
op.add_column('bay',
|
||||||
|
sa.Column('discovery_url', sa.String(length=255),
|
||||||
|
nullable=True))
|
@ -129,6 +129,7 @@ class Bay(Base):
|
|||||||
node_addresses = Column(JSONEncodedList)
|
node_addresses = Column(JSONEncodedList)
|
||||||
node_count = Column(Integer())
|
node_count = Column(Integer())
|
||||||
status = Column(String(20), nullable=True)
|
status = Column(String(20), nullable=True)
|
||||||
|
discovery_url = Column(String(255))
|
||||||
|
|
||||||
|
|
||||||
class BayLock(Base):
|
class BayLock(Base):
|
||||||
|
@ -52,7 +52,8 @@ class Bay(base.MagnumObject):
|
|||||||
'status': obj_utils.str_or_none,
|
'status': obj_utils.str_or_none,
|
||||||
'api_address': obj_utils.str_or_none,
|
'api_address': obj_utils.str_or_none,
|
||||||
'node_addresses': obj_utils.list_or_none,
|
'node_addresses': obj_utils.list_or_none,
|
||||||
'node_count': obj_utils.int_or_none
|
'node_count': obj_utils.int_or_none,
|
||||||
|
'discovery_url': obj_utils.str_or_none,
|
||||||
}
|
}
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -40,7 +40,7 @@ your environment:
|
|||||||
external_network_id: 028d70dd-67b8-4901-8bdd-0c62b06cce2d
|
external_network_id: 028d70dd-67b8-4901-8bdd-0c62b06cce2d
|
||||||
dns_nameserver: 192.168.200.1
|
dns_nameserver: 192.168.200.1
|
||||||
server_image: fedora-21-atomic
|
server_image: fedora-21-atomic
|
||||||
swarm_token: d8cdfe5128af6e1075b34aa06ff1cc2c
|
discovery_url: token://d8cdfe5128af6e1075b34aa06ff1cc2c
|
||||||
|
|
||||||
And then create the stack, referencing that environment file:
|
And then create the stack, referencing that environment file:
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ You must provide values for:
|
|||||||
- `ssh_key_name`
|
- `ssh_key_name`
|
||||||
- `external_network_id`
|
- `external_network_id`
|
||||||
- `server_image`
|
- `server_image`
|
||||||
- `swarm_token`
|
- `discovery_url`
|
||||||
|
|
||||||
## Interacting with Swarm
|
## Interacting with Swarm
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ write_files:
|
|||||||
ExecStartPre=-/usr/bin/docker kill swarm-agent
|
ExecStartPre=-/usr/bin/docker kill swarm-agent
|
||||||
ExecStartPre=-/usr/bin/docker rm swarm-agent
|
ExecStartPre=-/usr/bin/docker rm swarm-agent
|
||||||
ExecStartPre=/usr/bin/docker pull swarm
|
ExecStartPre=/usr/bin/docker pull swarm
|
||||||
ExecStart=/usr/bin/docker run --name swarm-agent swarm join --addr $NODE_IP:2375 token://$SWARM_TOKEN
|
ExecStart=/usr/bin/docker run --name swarm-agent swarm join --addr $NODE_IP:2375 $DISCOVERY_URL
|
||||||
ExecStop=/usr/bin/docker stop swarm-agent
|
ExecStop=/usr/bin/docker stop swarm-agent
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
|
@ -15,7 +15,7 @@ write_files:
|
|||||||
ExecStartPre=-/usr/bin/docker kill swarm-manager
|
ExecStartPre=-/usr/bin/docker kill swarm-manager
|
||||||
ExecStartPre=-/usr/bin/docker rm swarm-manager
|
ExecStartPre=-/usr/bin/docker rm swarm-manager
|
||||||
ExecStartPre=/usr/bin/docker pull swarm
|
ExecStartPre=/usr/bin/docker pull swarm
|
||||||
ExecStart=/usr/bin/docker run --name swarm-manager -p 2376:2375 swarm manage -H tcp://0.0.0.0:2375 token://$SWARM_TOKEN
|
ExecStart=/usr/bin/docker run --name swarm-manager -p 2376:2375 swarm manage -H tcp://0.0.0.0:2375 $DISCOVERY_URL
|
||||||
ExecStop=/usr/bin/docker stop swarm-manager
|
ExecStop=/usr/bin/docker stop swarm-manager
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
|
@ -21,9 +21,9 @@ parameters:
|
|||||||
type: string
|
type: string
|
||||||
description: uuid of a network to use for floating ip addresses
|
description: uuid of a network to use for floating ip addresses
|
||||||
|
|
||||||
swarm_token:
|
discovery_url:
|
||||||
type: string
|
type: string
|
||||||
description: identifier of swarm cluster to build
|
description: url provided for node discovery
|
||||||
|
|
||||||
#
|
#
|
||||||
# OPTIONAL PARAMETERS
|
# OPTIONAL PARAMETERS
|
||||||
@ -174,7 +174,7 @@ resources:
|
|||||||
template: {get_file: fragments/write-swarm-agent-service.yaml}
|
template: {get_file: fragments/write-swarm-agent-service.yaml}
|
||||||
params:
|
params:
|
||||||
"$NODE_IP": {get_attr: [swarm_manager_eth0, fixed_ips, 0, ip_address]}
|
"$NODE_IP": {get_attr: [swarm_manager_eth0, fixed_ips, 0, ip_address]}
|
||||||
"$SWARM_TOKEN": {get_param: swarm_token}
|
"$DISCOVERY_URL": {get_param: discovery_url}
|
||||||
|
|
||||||
write_swarm_manager_service:
|
write_swarm_manager_service:
|
||||||
type: "OS::Heat::SoftwareConfig"
|
type: "OS::Heat::SoftwareConfig"
|
||||||
@ -184,7 +184,7 @@ resources:
|
|||||||
str_replace:
|
str_replace:
|
||||||
template: {get_file: fragments/write-swarm-manager-service.yaml}
|
template: {get_file: fragments/write-swarm-manager-service.yaml}
|
||||||
params:
|
params:
|
||||||
"$SWARM_TOKEN": {get_param: swarm_token}
|
"$DISCOVERY_URL": {get_param: discovery_url}
|
||||||
|
|
||||||
enable_services:
|
enable_services:
|
||||||
type: "OS::Heat::SoftwareConfig"
|
type: "OS::Heat::SoftwareConfig"
|
||||||
@ -282,7 +282,7 @@ resources:
|
|||||||
fixed_network_id: {get_resource: fixed_network}
|
fixed_network_id: {get_resource: fixed_network}
|
||||||
fixed_subnet_id: {get_resource: fixed_subnet}
|
fixed_subnet_id: {get_resource: fixed_subnet}
|
||||||
external_network_id: {get_param: external_network_id}
|
external_network_id: {get_param: external_network_id}
|
||||||
swarm_token: {get_param: swarm_token}
|
discovery_url: {get_param: discovery_url}
|
||||||
|
|
||||||
outputs:
|
outputs:
|
||||||
|
|
||||||
@ -294,3 +294,6 @@ outputs:
|
|||||||
|
|
||||||
swarm_nodes_external:
|
swarm_nodes_external:
|
||||||
value: {get_attr: [swarm_nodes, swarm_node_external_ip]}
|
value: {get_attr: [swarm_nodes, swarm_node_external_ip]}
|
||||||
|
|
||||||
|
discovery_url:
|
||||||
|
value: {get_param: discovery_url}
|
||||||
|
@ -34,9 +34,9 @@ parameters:
|
|||||||
type: string
|
type: string
|
||||||
description: Subnet from which to allocate fixed addresses.
|
description: Subnet from which to allocate fixed addresses.
|
||||||
|
|
||||||
swarm_token:
|
discovery_url:
|
||||||
type: string
|
type: string
|
||||||
description: token of swarm cluster to build
|
description: url provided for node discovery
|
||||||
|
|
||||||
resources:
|
resources:
|
||||||
|
|
||||||
@ -118,7 +118,7 @@ resources:
|
|||||||
template: {get_file: fragments/write-swarm-agent-service.yaml}
|
template: {get_file: fragments/write-swarm-agent-service.yaml}
|
||||||
params:
|
params:
|
||||||
"$NODE_IP": {get_attr: [swarm_node_eth0, fixed_ips, 0, ip_address]}
|
"$NODE_IP": {get_attr: [swarm_node_eth0, fixed_ips, 0, ip_address]}
|
||||||
"$SWARM_TOKEN": {get_param: swarm_token}
|
"$DISCOVERY_URL": {get_param: discovery_url}
|
||||||
|
|
||||||
enable_services:
|
enable_services:
|
||||||
type: "OS::Heat::SoftwareConfig"
|
type: "OS::Heat::SoftwareConfig"
|
||||||
|
@ -604,3 +604,81 @@ class TestHandler(db_base.DbTestCase):
|
|||||||
# The bay has been destroyed
|
# The bay has been destroyed
|
||||||
self.assertRaises(exception.BayNotFound,
|
self.assertRaises(exception.BayNotFound,
|
||||||
objects.Bay.get, self.context, self.bay.uuid)
|
objects.Bay.get, self.context, self.bay.uuid)
|
||||||
|
|
||||||
|
|
||||||
|
class TestBayK8sHeatSwarm(base.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
super(TestBayK8sHeatSwarm, self).setUp()
|
||||||
|
self.baymodel_dict = {
|
||||||
|
'image_id': 'image_id',
|
||||||
|
'flavor_id': 'flavor_id',
|
||||||
|
'keypair_id': 'keypair_id',
|
||||||
|
'dns_nameserver': 'dns_nameserver',
|
||||||
|
'external_network_id': 'external_network_id',
|
||||||
|
'fixed_network': '10.2.0.0/22'
|
||||||
|
}
|
||||||
|
self.bay_dict = {
|
||||||
|
'id': 1,
|
||||||
|
'uuid': 'some_uuid',
|
||||||
|
'baymodel_id': 'xx-xx-xx-xx',
|
||||||
|
'name': 'bay1',
|
||||||
|
'stack_id': 'xx-xx-xx-xx',
|
||||||
|
'api_address': '172.17.2.3',
|
||||||
|
'node_addresses': ['172.17.2.4'],
|
||||||
|
'node_count': 1,
|
||||||
|
'discovery_url': 'token://39987da72f8386e0d0225ae8929e7cb4',
|
||||||
|
}
|
||||||
|
|
||||||
|
@patch('magnum.objects.BayModel.get_by_uuid')
|
||||||
|
def test_extract_template_definition_all_values(self,
|
||||||
|
mock_objects_baymodel_get_by_uuid):
|
||||||
|
cfg.CONF.set_override('cluster_coe', 'swarm', group='k8s_heat')
|
||||||
|
baymodel = objects.BayModel(self.context, **self.baymodel_dict)
|
||||||
|
mock_objects_baymodel_get_by_uuid.return_value = baymodel
|
||||||
|
bay = objects.Bay(self.context, **self.bay_dict)
|
||||||
|
|
||||||
|
(template_path,
|
||||||
|
definition) = bay_k8s_heat._extract_template_definition(self.context,
|
||||||
|
bay)
|
||||||
|
|
||||||
|
expected = {
|
||||||
|
'ssh_key_name': 'keypair_id',
|
||||||
|
'external_network_id': 'external_network_id',
|
||||||
|
'dns_nameserver': 'dns_nameserver',
|
||||||
|
'server_image': 'image_id',
|
||||||
|
'server_flavor': 'flavor_id',
|
||||||
|
'number_of_nodes': '1',
|
||||||
|
'fixed_network_cidr': '10.2.0.0/22',
|
||||||
|
'discovery_url': 'token://39987da72f8386e0d0225ae8929e7cb4'
|
||||||
|
}
|
||||||
|
self.assertEqual(expected, definition)
|
||||||
|
|
||||||
|
@patch('magnum.objects.BayModel.get_by_uuid')
|
||||||
|
def test_extract_template_definition_only_required(self,
|
||||||
|
mock_objects_baymodel_get_by_uuid):
|
||||||
|
cfg.CONF.set_override('cluster_coe', 'swarm', group='k8s_heat')
|
||||||
|
cfg.CONF.set_override('public_swarm_discovery', False, group='bay')
|
||||||
|
cfg.CONF.set_override('swarm_discovery_url_format',
|
||||||
|
'test_discovery', group='bay')
|
||||||
|
|
||||||
|
not_required = ['image_id', 'flavor_id', 'dns_nameserver',
|
||||||
|
'fixed_network']
|
||||||
|
for key in not_required:
|
||||||
|
self.baymodel_dict[key] = None
|
||||||
|
self.bay_dict['discovery_url'] = None
|
||||||
|
|
||||||
|
baymodel = objects.BayModel(self.context, **self.baymodel_dict)
|
||||||
|
mock_objects_baymodel_get_by_uuid.return_value = baymodel
|
||||||
|
bay = objects.Bay(self.context, **self.bay_dict)
|
||||||
|
|
||||||
|
(template_path,
|
||||||
|
definition) = bay_k8s_heat._extract_template_definition(self.context,
|
||||||
|
bay)
|
||||||
|
|
||||||
|
expected = {
|
||||||
|
'ssh_key_name': 'keypair_id',
|
||||||
|
'external_network_id': 'external_network_id',
|
||||||
|
'number_of_nodes': '1',
|
||||||
|
'discovery_url': 'test_discovery'
|
||||||
|
}
|
||||||
|
self.assertEqual(expected, definition)
|
||||||
|
@ -48,6 +48,13 @@ class TemplateDefinitionTestCase(base.TestCase):
|
|||||||
self.assertIsInstance(definition,
|
self.assertIsInstance(definition,
|
||||||
tdef.CoreOSK8sTemplateDefinition)
|
tdef.CoreOSK8sTemplateDefinition)
|
||||||
|
|
||||||
|
def test_get_vm_atomic_swarm_definition(self):
|
||||||
|
definition = tdef.TemplateDefinition.get_template_definition('vm',
|
||||||
|
'fedora-atomic', 'swarm')
|
||||||
|
|
||||||
|
self.assertIsInstance(definition,
|
||||||
|
tdef.AtomicSwarmTemplateDefinition)
|
||||||
|
|
||||||
def test_get_definition_not_supported(self):
|
def test_get_definition_not_supported(self):
|
||||||
self.assertRaises(exception.BayTypeNotSupported,
|
self.assertRaises(exception.BayTypeNotSupported,
|
||||||
tdef.TemplateDefinition.get_template_definition,
|
tdef.TemplateDefinition.get_template_definition,
|
||||||
@ -69,3 +76,61 @@ class TemplateDefinitionTestCase(base.TestCase):
|
|||||||
|
|
||||||
self.assertRaises(exception.RequiredParameterNotProvided,
|
self.assertRaises(exception.RequiredParameterNotProvided,
|
||||||
param.set_param, {}, mock_baymodel, None)
|
param.set_param, {}, mock_baymodel, None)
|
||||||
|
|
||||||
|
@mock.patch('requests.post')
|
||||||
|
def test_swarm_discovery_url_public_token(self, mock_post):
|
||||||
|
|
||||||
|
mock_resp = mock.MagicMock()
|
||||||
|
mock_resp.text = 'some_token'
|
||||||
|
mock_post.return_value = mock_resp
|
||||||
|
|
||||||
|
mock_bay = mock.MagicMock()
|
||||||
|
mock_bay.discovery_url = None
|
||||||
|
mock_bay.id = 1
|
||||||
|
mock_bay.uuid = 'some_uuid'
|
||||||
|
|
||||||
|
swarm_def = tdef.AtomicSwarmTemplateDefinition()
|
||||||
|
actual_url = swarm_def.get_discovery_url(mock_bay)
|
||||||
|
|
||||||
|
self.assertEqual('token://some_token', actual_url)
|
||||||
|
|
||||||
|
def test_swarm_discovery_url_format_bay_id(self):
|
||||||
|
cfg.CONF.set_override('public_swarm_discovery', False, group='bay')
|
||||||
|
cfg.CONF.set_override('swarm_discovery_url_format',
|
||||||
|
'etcd://test.com/bay-%(bay_id)s', group='bay')
|
||||||
|
|
||||||
|
mock_bay = mock.MagicMock()
|
||||||
|
mock_bay.discovery_url = None
|
||||||
|
mock_bay.id = 1
|
||||||
|
mock_bay.uuid = 'some_uuid'
|
||||||
|
|
||||||
|
swarm_def = tdef.AtomicSwarmTemplateDefinition()
|
||||||
|
actual_url = swarm_def.get_discovery_url(mock_bay)
|
||||||
|
|
||||||
|
self.assertEqual('etcd://test.com/bay-1', actual_url)
|
||||||
|
|
||||||
|
def test_swarm_discovery_url_format_bay_uuid(self):
|
||||||
|
cfg.CONF.set_override('public_swarm_discovery', False, group='bay')
|
||||||
|
cfg.CONF.set_override('swarm_discovery_url_format',
|
||||||
|
'etcd://test.com/bay-%(bay_uuid)s', group='bay')
|
||||||
|
|
||||||
|
mock_bay = mock.MagicMock()
|
||||||
|
mock_bay.discovery_url = None
|
||||||
|
mock_bay.id = 1
|
||||||
|
mock_bay.uuid = 'some_uuid'
|
||||||
|
|
||||||
|
swarm_def = tdef.AtomicSwarmTemplateDefinition()
|
||||||
|
actual_url = swarm_def.get_discovery_url(mock_bay)
|
||||||
|
|
||||||
|
self.assertEqual('etcd://test.com/bay-some_uuid', actual_url)
|
||||||
|
|
||||||
|
def test_swarm_discovery_url_from_bay(self):
|
||||||
|
mock_bay = mock.MagicMock()
|
||||||
|
mock_bay.discovery_url = 'token://some_token'
|
||||||
|
mock_bay.id = 1
|
||||||
|
mock_bay.uuid = 'some_uuid'
|
||||||
|
|
||||||
|
swarm_def = tdef.AtomicSwarmTemplateDefinition()
|
||||||
|
actual_url = swarm_def.get_discovery_url(mock_bay)
|
||||||
|
|
||||||
|
self.assertEqual(mock_bay.discovery_url, actual_url)
|
||||||
|
@ -53,6 +53,7 @@ def get_test_bay(**kw):
|
|||||||
'id': kw.get('id', 42),
|
'id': kw.get('id', 42),
|
||||||
'uuid': kw.get('uuid', '5d12f6fd-a196-4bf0-ae4c-1f639a523a52'),
|
'uuid': kw.get('uuid', '5d12f6fd-a196-4bf0-ae4c-1f639a523a52'),
|
||||||
'name': kw.get('name', 'bay1'),
|
'name': kw.get('name', 'bay1'),
|
||||||
|
'discovery_url': kw.get('discovery_url', None),
|
||||||
'project_id': kw.get('project_id', 'fake_project'),
|
'project_id': kw.get('project_id', 'fake_project'),
|
||||||
'user_id': kw.get('user_id', 'fake_user'),
|
'user_id': kw.get('user_id', 'fake_user'),
|
||||||
'baymodel_id': kw.get('baymodel_id',
|
'baymodel_id': kw.get('baymodel_id',
|
||||||
|
@ -56,6 +56,7 @@ oslo.config.opts =
|
|||||||
magnum.template_definitions =
|
magnum.template_definitions =
|
||||||
magnum_vm_atomic_k8s = magnum.conductor.template_definition:AtomicK8sTemplateDefinition
|
magnum_vm_atomic_k8s = magnum.conductor.template_definition:AtomicK8sTemplateDefinition
|
||||||
magnum_vm_coreos_k8s = magnum.conductor.template_definition:CoreOSK8sTemplateDefinition
|
magnum_vm_coreos_k8s = magnum.conductor.template_definition:CoreOSK8sTemplateDefinition
|
||||||
|
magnum_vm_atomic_swarm = magnum.conductor.template_definition:AtomicSwarmTemplateDefinition
|
||||||
|
|
||||||
[wheel]
|
[wheel]
|
||||||
universal = 1
|
universal = 1
|
||||||
|
Loading…
Reference in New Issue
Block a user