Add coe attribute to BayModel
Add the Container Orchestration Engine (coe) attribute to the BayModel API, model, and DB objects to be used by the Heat Conductor Handler when creating a Bay. 1) Add coe attribute to BayModel models 2) Use coe attribute in heat handler's get_template_definition(...) calls Partially implements: bp multiple-bay-templates Change-Id: I15078c4327373df8fc6ebff8ad9a3d0cacdae572
This commit is contained in:
parent
5dfb30721c
commit
2ea49688c1
2
.gitignore
vendored
2
.gitignore
vendored
@ -51,4 +51,4 @@ ChangeLog
|
||||
# Editors
|
||||
*~
|
||||
.*.swp
|
||||
.*sw?
|
||||
.*sw?
|
@ -175,7 +175,7 @@ Magnum in which way to construct a bay.::
|
||||
--keypair-id testkey \
|
||||
--external-network-id $NIC_ID \
|
||||
--dns-nameserver 8.8.8.8 --flavor-id m1.small \
|
||||
--docker-volume-size 5
|
||||
--docker-volume-size 5 --coe kubernetes
|
||||
|
||||
Next create a bay. Use the baymodel UUID as a template for bay creation.
|
||||
This bay will result in one master kubernetes node and two minion nodes.::
|
||||
@ -264,25 +264,16 @@ replicating data between one another.
|
||||
|
||||
Building and using a Swarm bay
|
||||
==============================
|
||||
|
||||
First, we will need to reconfigure Magnum. We need to set 'cluster_coe' in
|
||||
the 'k8s_heat' 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.::
|
||||
Create a baymodel. It is very similar to the Kubernetes baymodel,
|
||||
it is only missing some Kubernetes specific arguments and uses 'swarm' as the
|
||||
coe. ::
|
||||
|
||||
NIC_ID=$(neutron net-show public | awk '/ id /{print $4}')
|
||||
magnum baymodel-create --name swarmbaymodel --image-id fedora-21-atomic-3 \
|
||||
--keypair-id testkey \
|
||||
--external-network-id $NIC_ID \
|
||||
--dns-nameserver 8.8.8.8 --flavor-id m1.small
|
||||
--dns-nameserver 8.8.8.8 --flavor-id m1.small \
|
||||
--coe swarm
|
||||
|
||||
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
|
||||
|
@ -42,12 +42,26 @@ class BayModel(base.APIBase):
|
||||
between the internal object model and the API representation of a baymodel.
|
||||
"""
|
||||
|
||||
_coe = None
|
||||
|
||||
def _get_coe(self):
|
||||
return self._coe
|
||||
|
||||
def _set_coe(self, value):
|
||||
if value and self._coe != value:
|
||||
self._coe = value
|
||||
elif value == wtypes.Unset:
|
||||
self._coe = wtypes.Unset
|
||||
|
||||
uuid = types.uuid
|
||||
"""Unique UUID for this baymodel"""
|
||||
|
||||
name = wtypes.text
|
||||
"""The name of the bay model"""
|
||||
|
||||
coe = wsme.wsproperty(wtypes.text, _get_coe, _set_coe, mandatory=True)
|
||||
"""The Container Orchestration Engine for this bay model"""
|
||||
|
||||
image_id = wtypes.text
|
||||
"""The image name or UUID to use as a base image for this baymodel"""
|
||||
|
||||
@ -97,7 +111,7 @@ class BayModel(base.APIBase):
|
||||
def _convert_with_links(baymodel, url, expand=True):
|
||||
if not expand:
|
||||
baymodel.unset_fields_except(['uuid', 'name', 'image_id',
|
||||
'apiserver_port'])
|
||||
'apiserver_port', 'coe'])
|
||||
|
||||
baymodel.links = [link.Link.make_link('self', url,
|
||||
'baymodels', baymodel.uuid),
|
||||
@ -128,6 +142,7 @@ class BayModel(base.APIBase):
|
||||
docker_volume_size=25,
|
||||
cluster_distro='fedora-atomic',
|
||||
ssh_authorized_key='ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAB',
|
||||
coe='kubernetes',
|
||||
created_at=datetime.datetime.utcnow(),
|
||||
updated_at=datetime.datetime.utcnow())
|
||||
return cls._convert_with_links(sample, 'http://localhost:9511', expand)
|
||||
|
@ -29,10 +29,6 @@ from magnum.openstack.common import loopingcall
|
||||
|
||||
|
||||
k8s_heat_opts = [
|
||||
cfg.StrOpt('cluster_coe',
|
||||
default='kubernetes',
|
||||
help=_('Container Orchestration Environments are '
|
||||
'kubernetes or swarm. ')),
|
||||
cfg.IntOpt('max_attempts',
|
||||
default=2000,
|
||||
help=('Number of attempts to query the Heat stack for '
|
||||
@ -57,12 +53,16 @@ cfg.CONF.register_opts(k8s_heat_opts, group='k8s_heat')
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _extract_template_definition(context, bay):
|
||||
def _get_baymodel(context, bay):
|
||||
baymodel = objects.BayModel.get_by_uuid(context, bay.baymodel_id)
|
||||
return baymodel
|
||||
|
||||
|
||||
def _extract_template_definition(context, bay):
|
||||
baymodel = _get_baymodel(context, bay)
|
||||
cluster_distro = baymodel.cluster_distro
|
||||
cluster_coe = cfg.CONF.k8s_heat.cluster_coe
|
||||
definition = TDef.get_template_definition('vm',
|
||||
cluster_distro,
|
||||
cluster_coe = baymodel.coe
|
||||
definition = TDef.get_template_definition('vm', cluster_distro,
|
||||
cluster_coe)
|
||||
return definition.extract_definition(baymodel, bay)
|
||||
|
||||
@ -107,11 +107,10 @@ def _update_stack(context, osc, bay):
|
||||
|
||||
|
||||
def _update_stack_outputs(context, stack, bay):
|
||||
baymodel = objects.BayModel.get_by_uuid(context, bay.baymodel_id)
|
||||
baymodel = _get_baymodel(context, bay)
|
||||
cluster_distro = baymodel.cluster_distro
|
||||
cluster_coe = cfg.CONF.k8s_heat.cluster_coe
|
||||
definition = TDef.get_template_definition('vm',
|
||||
cluster_distro,
|
||||
cluster_coe = baymodel.coe
|
||||
definition = TDef.get_template_definition('vm', cluster_distro,
|
||||
cluster_coe)
|
||||
return definition.update_outputs(stack, bay)
|
||||
|
||||
@ -222,6 +221,7 @@ class HeatPoller(object):
|
||||
raise loopingcall.LoopingCallDone()
|
||||
if (stack.stack_status in ['CREATE_COMPLETE', 'UPDATE_COMPLETE']):
|
||||
_update_stack_outputs(self.context, stack, self.bay)
|
||||
|
||||
self.bay.status = stack.stack_status
|
||||
self.bay.save()
|
||||
raise loopingcall.LoopingCallDone()
|
||||
|
@ -0,0 +1,52 @@
|
||||
# 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 coe column to BayModel
|
||||
|
||||
Revision ID: 592131657ca1
|
||||
Revises: 4956f03cabad
|
||||
Create Date: 2015-04-17 14:20:17.620995
|
||||
|
||||
"""
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '592131657ca1'
|
||||
down_revision = '4956f03cabad'
|
||||
|
||||
from alembic import op
|
||||
from oslo_config import cfg
|
||||
import sqlalchemy as sa
|
||||
|
||||
from magnum.openstack.common._i18n import _
|
||||
|
||||
|
||||
k8s_heat_opts = [
|
||||
cfg.StrOpt('cluster_coe',
|
||||
default='kubernetes',
|
||||
help=_('Container Orchestration Environments are '
|
||||
'kubernetes or swarm. ')),
|
||||
]
|
||||
|
||||
cfg.CONF.register_opts(k8s_heat_opts, group='k8s_heat')
|
||||
|
||||
|
||||
def upgrade():
|
||||
op.add_column('baymodel', sa.Column('coe', sa.String(length=255),
|
||||
nullable=True))
|
||||
|
||||
baymodel = sa.sql.table('baymodel',
|
||||
sa.sql.column('coe', sa.String(length=255)))
|
||||
op.execute(
|
||||
baymodel.update().values({'coe':
|
||||
op.inline_literal(
|
||||
cfg.CONF.k8s_heat.cluster_coe)})
|
||||
)
|
@ -169,6 +169,7 @@ class BayModel(Base):
|
||||
docker_volume_size = Column(Integer())
|
||||
ssh_authorized_key = Column(Text)
|
||||
cluster_distro = Column(String(255))
|
||||
coe = Column(String(255))
|
||||
|
||||
|
||||
class Container(Base):
|
||||
|
@ -43,6 +43,7 @@ class BayModel(base.MagnumObject):
|
||||
'docker_volume_size': obj_utils.int_or_none,
|
||||
'ssh_authorized_key': obj_utils.str_or_none,
|
||||
'cluster_distro': obj_utils.str_or_none,
|
||||
'coe': obj_utils.str_or_none,
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
|
@ -67,6 +67,7 @@ class TestListBayModel(api_base.FunctionalTest):
|
||||
self.assertIn('fixed_network', response)
|
||||
self.assertIn('docker_volume_size', response)
|
||||
self.assertIn('ssh_authorized_key', response)
|
||||
self.assertIn('coe', response)
|
||||
|
||||
def test_get_one_by_name(self):
|
||||
baymodel = obj_utils.create_test_baymodel(self.context)
|
||||
@ -79,6 +80,7 @@ class TestListBayModel(api_base.FunctionalTest):
|
||||
self.assertIn('external_network_id', response)
|
||||
self.assertIn('fixed_network', response)
|
||||
self.assertIn('docker_volume_size', response)
|
||||
self.assertIn('coe', response)
|
||||
|
||||
def test_get_one_by_name_not_found(self):
|
||||
response = self.get_json('/baymodels/not_found',
|
||||
@ -110,6 +112,7 @@ class TestListBayModel(api_base.FunctionalTest):
|
||||
self.assertIn('fixed_network', response['baymodels'][0])
|
||||
self.assertIn('docker_volume_size', response['baymodels'][0])
|
||||
self.assertIn('ssh_authorized_key', response['baymodels'][0])
|
||||
self.assertIn('coe', response['baymodels'][0])
|
||||
|
||||
def test_detail_against_single(self):
|
||||
baymodel = obj_utils.create_test_baymodel(self.context)
|
||||
@ -177,7 +180,8 @@ class TestPatch(api_base.FunctionalTest):
|
||||
'DYucqbeuM7nmJi+8Hb55y1xWoOZI'
|
||||
'KMa71G5/4EOQxuQ/sgW965OOO2Hq'
|
||||
'X8vjlQUnTK0HijrbSTLxp/9kazWW'
|
||||
'FrfsdB8RtZBN digambar@magnum'
|
||||
'FrfsdB8RtZBN digambar@magnum',
|
||||
coe='swarm'
|
||||
)
|
||||
|
||||
def test_update_not_found(self):
|
||||
@ -219,6 +223,8 @@ class TestPatch(api_base.FunctionalTest):
|
||||
response['docker_volume_size'])
|
||||
self.assertEqual(self.baymodel.ssh_authorized_key,
|
||||
response['ssh_authorized_key'])
|
||||
self.assertEqual(self.baymodel.coe,
|
||||
response['coe'])
|
||||
|
||||
def test_remove_singular(self):
|
||||
baymodel = obj_utils.create_test_baymodel(self.context,
|
||||
@ -243,6 +249,8 @@ class TestPatch(api_base.FunctionalTest):
|
||||
response['docker_volume_size'])
|
||||
self.assertEqual(self.baymodel.ssh_authorized_key,
|
||||
response['ssh_authorized_key'])
|
||||
self.assertEqual(self.baymodel.coe,
|
||||
response['coe'])
|
||||
|
||||
def test_remove_non_existent_property_fail(self):
|
||||
response = self.patch_json('/baymodels/%s' % self.baymodel.uuid,
|
||||
@ -268,6 +276,8 @@ class TestPatch(api_base.FunctionalTest):
|
||||
response['apiserver_port'])
|
||||
self.assertEqual(self.baymodel.docker_volume_size,
|
||||
response['docker_volume_size'])
|
||||
self.assertEqual(self.baymodel.coe,
|
||||
response['coe'])
|
||||
|
||||
def test_add_root_non_existent(self):
|
||||
response = self.patch_json('/baymodels/%s' % self.baymodel.uuid,
|
||||
@ -307,6 +317,8 @@ class TestPatch(api_base.FunctionalTest):
|
||||
response['docker_volume_size'])
|
||||
self.assertEqual(self.baymodel.ssh_authorized_key,
|
||||
response['ssh_authorized_key'])
|
||||
self.assertEqual(self.baymodel.coe,
|
||||
response['coe'])
|
||||
|
||||
def test_remove_uuid(self):
|
||||
response = self.patch_json('/baymodels/%s' % self.baymodel.uuid,
|
||||
|
@ -41,6 +41,7 @@ class TestBayK8sHeat(base.TestCase):
|
||||
'docker_volume_size': 20,
|
||||
'cluster_distro': 'fedora-atomic',
|
||||
'ssh_authorized_key': 'ssh_authorized_key',
|
||||
'coe': 'kubernetes',
|
||||
'token': None,
|
||||
}
|
||||
self.bay_dict = {
|
||||
@ -52,6 +53,15 @@ class TestBayK8sHeat(base.TestCase):
|
||||
'node_count': 1,
|
||||
}
|
||||
|
||||
@patch('magnum.objects.BayModel.get_by_uuid')
|
||||
def test_get_baymodel(self, mock_objects_baymodel_get_by_uuid):
|
||||
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)
|
||||
|
||||
fetched_baymodel = bay_k8s_heat._get_baymodel(self.context, bay)
|
||||
self.assertEqual(baymodel, fetched_baymodel)
|
||||
|
||||
@patch('magnum.objects.BayModel.get_by_uuid')
|
||||
def test_extract_template_definition(self,
|
||||
mock_objects_baymodel_get_by_uuid):
|
||||
@ -167,7 +177,7 @@ class TestBayK8sHeat(base.TestCase):
|
||||
'master_flavor': 'master_flavor_id',
|
||||
'number_of_minions': '1',
|
||||
'fixed_network': 'private',
|
||||
'docker_volume_size': 20
|
||||
'docker_volume_size': 20,
|
||||
}
|
||||
self.assertEqual(expected, definition)
|
||||
|
||||
@ -192,7 +202,7 @@ class TestBayK8sHeat(base.TestCase):
|
||||
'master_flavor': 'master_flavor_id',
|
||||
'number_of_minions': '1',
|
||||
'fixed_network': 'private',
|
||||
'docker_volume_size': 20
|
||||
'docker_volume_size': 20,
|
||||
}
|
||||
self.assertEqual(expected, definition)
|
||||
|
||||
@ -700,6 +710,9 @@ class TestHandler(db_base.DbTestCase):
|
||||
def setUp(self):
|
||||
super(TestHandler, self).setUp()
|
||||
self.handler = bay_k8s_heat.Handler()
|
||||
baymodel_dict = utils.get_test_baymodel()
|
||||
self.baymodel = objects.BayModel(self.context, **baymodel_dict)
|
||||
self.baymodel.create()
|
||||
bay_dict = utils.get_test_bay(node_count=1)
|
||||
self.bay = objects.Bay(self.context, **bay_dict)
|
||||
self.bay.create()
|
||||
@ -775,6 +788,7 @@ class TestBayK8sHeatSwarm(base.TestCase):
|
||||
'external_network_id': 'external_network_id',
|
||||
'fixed_network': '10.2.0.0/22',
|
||||
'cluster_distro': 'fedora-atomic',
|
||||
'coe': 'swarm'
|
||||
}
|
||||
self.bay_dict = {
|
||||
'id': 1,
|
||||
@ -791,7 +805,6 @@ class TestBayK8sHeatSwarm(base.TestCase):
|
||||
@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)
|
||||
@ -815,7 +828,6 @@ class TestBayK8sHeatSwarm(base.TestCase):
|
||||
@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')
|
||||
|
@ -44,6 +44,7 @@ def get_test_baymodel(**kw):
|
||||
'KMa71G5/4EOQxuQ/sgW965OOO2Hq'
|
||||
'X8vjlQUnTK0HijrbSTLxp/9kazWW'
|
||||
'FrfsdB8RtZBN digambar@magnum'),
|
||||
'coe': kw.get('coe', 'swarm'),
|
||||
'created_at': kw.get('created_at'),
|
||||
'updated_at': kw.get('updated_at'),
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user