Adds network_driver Support of Container Network Model

Adds network_driver to the following:
  1. api baymodel attribute
  2. conductor template definitions and entrypoints
  3. a new column to the baymodel db
  4. objects. Note: Updates baymodel object version
  5. Tests

Partially-Implements: blueprint extend-api-network-attributes
Partially-Implements: blueprint extend-baymodel-net-attributes
Partially-Implements: blueprint conductor-template-net-update

Change-Id: I312ec863919543aa8ca5d215a028d3a44a9003c9
This commit is contained in:
Daneyon Hansen 2015-08-20 00:26:42 +00:00
parent c18c10bed1
commit c0ad7c376e
9 changed files with 107 additions and 6 deletions

View File

@ -87,6 +87,9 @@ class BayModel(base.APIBase):
fixed_network = wtypes.StringType(min_length=1, max_length=255)
"""The fixed network name to attach the Bay"""
network_driver = wtypes.StringType(min_length=1, max_length=255)
"""The name of the driver used for instantiating container networks"""
apiserver_port = wtypes.IntegerType(minimum=1024, maximum=65535)
"""The API server port for k8s"""
@ -155,6 +158,7 @@ class BayModel(base.APIBase):
keypair_id='keypair1',
external_network_id='ffc44e4a-2319-4062-bce0-9ae1c38b05ba',
fixed_network='private',
network_driver='libnetwork',
apiserver_port=8080,
docker_volume_size=25,
cluster_distro='fedora-atomic',

View File

@ -375,6 +375,8 @@ class AtomicK8sTemplateDefinition(BaseTemplateDefinition):
self.add_parameter('external_network',
baymodel_attr='external_network_id',
required=True)
self.add_parameter('network_driver',
baymodel_attr='network_driver')
# TODO(yuanying): Add below lines if apiserver_port parameter
# is supported
# self.add_parameter('apiserver_port',

View File

@ -0,0 +1,34 @@
# Copyright 2015 OpenStack Foundation
# All Rights Reserved.
#
# 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_network_driver_baymodel_column
Revision ID: 3be65537a94a
Revises: 4e263f236334
Create Date: 2015-09-03 20:51:54.229436
"""
# revision identifiers, used by Alembic.
revision = '3be65537a94a'
down_revision = '4e263f236334'
from alembic import op
import sqlalchemy as sa
def upgrade():
op.add_column('baymodel', sa.Column('network_driver',
sa.String(length=255), nullable=True))

View File

@ -160,6 +160,7 @@ class BayModel(Base):
keypair_id = Column(String(255))
external_network_id = Column(String(255))
fixed_network = Column(String(255))
network_driver = Column(String(255))
dns_nameserver = Column(String(255))
apiserver_port = Column(Integer())
docker_volume_size = Column(Integer())

View File

@ -26,7 +26,8 @@ class BayModel(base.MagnumPersistentObject, base.MagnumObject,
base.MagnumObjectDictCompat):
# Version 1.0: Initial version
# Version 1.1: Add 'registry_enabled' field
VERSION = '1.1'
# Version 1.2: Added 'network_driver' field
VERSION = '1.2'
dbapi = dbapi.get_instance()
@ -43,6 +44,7 @@ class BayModel(base.MagnumPersistentObject, base.MagnumObject,
'dns_nameserver': fields.StringField(nullable=True),
'external_network_id': fields.StringField(nullable=True),
'fixed_network': fields.StringField(nullable=True),
'network_driver': fields.StringField(nullable=True),
'apiserver_port': fields.IntegerField(nullable=True),
'docker_volume_size': fields.IntegerField(nullable=True),
'ssh_authorized_key': fields.StringField(nullable=True),

View File

@ -55,6 +55,7 @@ class TestListBayModel(api_base.FunctionalTest):
self.assertNotIn('keypair_id', response['baymodels'][0])
self.assertNotIn('external_network_id', response['baymodels'][0])
self.assertNotIn('fixed_network', response['baymodels'][0])
self.assertNotIn('network_driver', response['baymodels'][0])
self.assertNotIn('docker_volume_size', response['baymodels'][0])
self.assertNotIn('ssh_authorized_key', response['baymodels'][0])
self.assertNotIn('http_proxy', response['baymodels'][0])
@ -71,6 +72,7 @@ class TestListBayModel(api_base.FunctionalTest):
self.assertIn('keypair_id', response)
self.assertIn('external_network_id', response)
self.assertIn('fixed_network', response)
self.assertIn('network_driver', response)
self.assertIn('docker_volume_size', response)
self.assertIn('ssh_authorized_key', response)
self.assertIn('coe', response)
@ -88,6 +90,7 @@ class TestListBayModel(api_base.FunctionalTest):
self.assertIn('keypair_id', response)
self.assertIn('external_network_id', response)
self.assertIn('fixed_network', response)
self.assertIn('network_driver', response)
self.assertIn('docker_volume_size', response)
self.assertIn('coe', response)
self.assertIn('http_proxy', response)
@ -136,7 +139,8 @@ class TestListBayModel(api_base.FunctionalTest):
for key in ("flavor_id", "master_flavor_id", "dns_nameserver",
"keypair_id", "external_network_id", "fixed_network",
"docker_volume_size", "ssh_authorized_key", "coe",
"http_proxy", "https_proxy", "no_proxy"):
"http_proxy", "https_proxy", "no_proxy",
"network_driver"):
self.assertIn(key, response['baymodels'][0])
def test_detail_with_pagination_marker(self):
@ -153,7 +157,8 @@ class TestListBayModel(api_base.FunctionalTest):
self.assertEqual(bm_list[-1].uuid, response['baymodels'][0]['uuid'])
for key in ("flavor_id", "master_flavor_id", "dns_nameserver",
"keypair_id", "external_network_id", "fixed_network",
"docker_volume_size", "ssh_authorized_key", "coe"):
"network_driver", "docker_volume_size",
"ssh_authorized_key", "coe"):
self.assertIn(key, response['baymodels'][0])
self.assertIn('flavor_id', response['baymodels'][0])
self.assertIn('master_flavor_id', response['baymodels'][0])
@ -229,6 +234,7 @@ class TestPatch(api_base.FunctionalTest):
image_id='nerdherd',
apiserver_port=8080,
fixed_network='private',
network_driver='fake_driver',
docker_volume_size=20,
ssh_authorized_key='ssh-rsa AAAAB3NzaC1ycEAAAADA'
'v0XRqg3tm+jlsOKGO81lPDH+KaSJ'
@ -275,6 +281,8 @@ class TestPatch(api_base.FunctionalTest):
response['apiserver_port'])
self.assertEqual(self.baymodel.fixed_network,
response['fixed_network'])
self.assertEqual(self.baymodel.network_driver,
response['network_driver'])
self.assertEqual(self.baymodel.docker_volume_size,
response['docker_volume_size'])
self.assertEqual(self.baymodel.ssh_authorized_key,
@ -307,6 +315,8 @@ class TestPatch(api_base.FunctionalTest):
self.assertEqual(baymodel.apiserver_port, response['apiserver_port'])
self.assertEqual(self.baymodel.fixed_network,
response['fixed_network'])
self.assertEqual(self.baymodel.network_driver,
response['network_driver'])
self.assertEqual(self.baymodel.docker_volume_size,
response['docker_volume_size'])
self.assertEqual(self.baymodel.ssh_authorized_key,
@ -343,6 +353,8 @@ class TestPatch(api_base.FunctionalTest):
self.assertEqual(self.baymodel.image_id, response['image_id'])
self.assertEqual(self.baymodel.apiserver_port,
response['apiserver_port'])
self.assertEqual(self.baymodel.network_driver,
response['network_driver'])
self.assertEqual(self.baymodel.docker_volume_size,
response['docker_volume_size'])
self.assertEqual(self.baymodel.coe,
@ -383,6 +395,8 @@ class TestPatch(api_base.FunctionalTest):
response['apiserver_port'])
self.assertEqual(self.baymodel.fixed_network,
response['fixed_network'])
self.assertEqual(self.baymodel.network_driver,
response['network_driver'])
self.assertEqual(self.baymodel.docker_volume_size,
response['docker_volume_size'])
self.assertEqual(self.baymodel.ssh_authorized_key,
@ -487,7 +501,7 @@ class TestPost(api_base.FunctionalTest):
"dns_nameserver", "keypair_id", "external_network_id",
"cluster_distro", "fixed_network", "apiserver_port",
"docker_volume_size", "http_proxy", "https_proxy",
"no_proxy"]
"no_proxy", "network_driver"]
for field in fields:
self._create_baymodel_raises_app_error(**{field: 'i' * 256})
@ -496,7 +510,7 @@ class TestPost(api_base.FunctionalTest):
"dns_nameserver", "keypair_id", "external_network_id",
"cluster_distro", "fixed_network", "apiserver_port",
"docker_volume_size", "ssh_authorized_key",
"http_proxy", "https_proxy", "no_proxy"]
"http_proxy", "https_proxy", "no_proxy", "network_driver"]
for field in fields:
self._create_baymodel_raises_app_error(**{field: ''})
@ -542,6 +556,42 @@ class TestPost(api_base.FunctionalTest):
mock_keypair_exists,
mock_image_data):
mock_keypair_exists.return_value = None
@mock.patch.object(api_baymodel.BayModelsController, '_get_image_data')
@mock.patch.object(api_baymodel.BayModelsController,
'check_keypair_exists')
def test_create_baymodel_with_network_driver(self, mock_keypair_exists,
mock_image_data):
mock_keypair_exists.return_value = None
with mock.patch.object(self.dbapi, 'create_baymodel',
wraps=self.dbapi.create_baymodel) as cc_mock:
mock_keypair_exists.return_value = None
mock_image_data.return_value = {'name': 'mock_name',
'os_distro': 'fedora-atomic'}
bdict = apiutils.baymodel_post_data(network_driver='libnetwork')
response = self.post_json('/baymodels', bdict)
self.assertEqual(bdict['network_driver'],
response.json['network_driver'])
cc_mock.assert_called_once_with(mock.ANY)
self.assertNotIn('id', cc_mock.call_args[0][0])
@mock.patch.object(api_baymodel.BayModelsController, '_get_image_data')
@mock.patch.object(api_baymodel.BayModelsController,
'check_keypair_exists')
def test_create_baymodel_with_no_network_driver(self, mock_keypair_exists,
mock_image_data):
mock_keypair_exists.return_value = None
with mock.patch.object(self.dbapi, 'create_baymodel',
wraps=self.dbapi.create_baymodel) as cc_mock:
mock_image_data.return_value = {'name': 'mock_name',
'os_distro': 'fedora-atomic'}
bdict = apiutils.baymodel_post_data()
response = self.post_json('/baymodels', bdict)
self.assertEqual(bdict['network_driver'],
response.json['network_driver'])
cc_mock.assert_called_once_with(mock.ANY)
self.assertNotIn('id', cc_mock.call_args[0][0])
mock_image_data.return_value = {'name': 'mock_name',
'os_distro': 'fedora-atomic'}
bdict = apiutils.baymodel_post_data()

View File

@ -39,6 +39,7 @@ class TestBayConductorWithK8s(base.TestCase):
'dns_nameserver': 'dns_nameserver',
'external_network_id': 'external_network_id',
'fixed_network': '10.20.30.0/24',
'network_driver': 'network_driver',
'docker_volume_size': 20,
'cluster_distro': 'fedora-atomic',
'ssh_authorized_key': 'ssh_authorized_key',
@ -91,6 +92,7 @@ class TestBayConductorWithK8s(base.TestCase):
'flavor_id': 'minion_flavor',
'docker_volume_size': 'docker_volume_size',
'fixed_network': 'fixed_network_cidr',
'network_driver': 'network_driver',
'master_flavor_id': 'master_flavor',
'apiserver_port': '',
'node_count': 'number_of_minions',
@ -103,6 +105,7 @@ class TestBayConductorWithK8s(base.TestCase):
expected = {
'ssh_key_name': 'keypair_id',
'external_network': 'external_network_id',
'network_driver': 'network_driver',
'dns_nameserver': 'dns_nameserver',
'server_image': 'image_id',
'minion_flavor': 'flavor_id',
@ -152,6 +155,7 @@ class TestBayConductorWithK8s(base.TestCase):
'number_of_minions': '1',
'number_of_masters': '1',
'fixed_network_cidr': '10.20.30.0/24',
'network_driver': 'network_driver',
'docker_volume_size': 20,
'ssh_authorized_key': 'ssh_authorized_key',
'token': 'h3',
@ -193,6 +197,7 @@ class TestBayConductorWithK8s(base.TestCase):
'number_of_minions': '1',
'number_of_masters': '1',
'fixed_network_cidr': '10.20.30.0/24',
'network_driver': 'network_driver',
'docker_volume_size': 20,
'ssh_authorized_key': 'ssh_authorized_key',
'token': 'ba3d1866282848ddbedc76112110c208',
@ -276,6 +281,7 @@ class TestBayConductorWithK8s(base.TestCase):
'number_of_minions': '1',
'number_of_masters': '1',
'fixed_network_cidr': '10.20.30.0/24',
'network_driver': 'network_driver',
'docker_volume_size': 20,
'discovery_url': 'https://discovery.etcd.io/test',
'http_proxy': 'http_proxy',
@ -342,6 +348,7 @@ class TestBayConductorWithK8s(base.TestCase):
'number_of_minions': '1',
'number_of_masters': '1',
'fixed_network_cidr': '10.20.30.0/24',
'network_driver': 'network_driver',
'docker_volume_size': 20,
'discovery_url': 'https://address/token',
'http_proxy': 'http_proxy',

View File

@ -32,6 +32,7 @@ def get_test_baymodel(**kw):
'external_network_id': kw.get('external_network_id',
'd1f02cfb-d27f-4068-9332-84d907cb0e2e'),
'fixed_network': kw.get('fixed_network', 'private'),
'network_driver': kw.get('network_driver', 'fake_driver'),
'dns_nameserver': kw.get('dns_nameserver', '8.8.1.1'),
'apiserver_port': kw.get('apiserver_port', 8080),
'docker_volume_size': kw.get('docker_volume_size', 20),

View File

@ -426,7 +426,7 @@ class _TestObject(object):
object_data = {
'Bay': '1.0-35edde13ad178e9419e7ea8b6d580bcd',
'BayLock': '1.0-7d1eb08cf2070523bd210369c7a2e076',
'BayModel': '1.1-0ada1b67f847f673ccbdb59a20eefae9',
'BayModel': '1.2-b08e888342cc84d7c709193529b92c6f',
'Certificate': '1.0-2aff667971b85c1edf8d15684fd7d5e2',
'Container': '1.0-e12affbba5f8a748882a3ae98aced282',
'MyObj': '1.0-b43567e512438205e32f4e95ca616697',