From 0d42f01f68cbe4e480c51b63271bd3bdb41d8021 Mon Sep 17 00:00:00 2001 From: Stan Lagun Date: Wed, 4 Feb 2015 03:39:49 +0300 Subject: [PATCH] Configurable environment's default network config Network configuration is extracted into a separate file. By default this is netconfig.yaml residing near murano.conf But the name and path can be changed in config file. Example of net-config can be found in etc/murano/netconfig.yaml.sample If no file present old behavior is kept Change-Id: I7b74eea69ee2ffe1c721b751e564b54252dcfbe3 Implements: blueprint configure-environment-network-defaults --- etc/murano/netconfig.yaml.samle | 8 +++ murano/common/config.py | 4 ++ murano/db/services/environments.py | 56 ++++++++++++++----- .../tests/unit/api/v1/test_env_templates.py | 15 +++++ murano/tests/unit/api/v1/test_environments.py | 8 +++ murano/tests/unit/api/v1/test_sessions.py | 9 +++ 6 files changed, 85 insertions(+), 15 deletions(-) create mode 100644 etc/murano/netconfig.yaml.samle diff --git a/etc/murano/netconfig.yaml.samle b/etc/murano/netconfig.yaml.samle new file mode 100644 index 000000000..3dcd10f58 --- /dev/null +++ b/etc/murano/netconfig.yaml.samle @@ -0,0 +1,8 @@ +environment: + ?: + type: io.murano.resources.ExistingNeutronNetwork + internalNetworkName: internal + # internalSubnetworkName: subnet1 + # externalNetworkName: ext_net + +flat: null diff --git a/murano/common/config.py b/murano/common/config.py index dec2a8e70..e37183189 100644 --- a/murano/common/config.py +++ b/murano/common/config.py @@ -176,6 +176,10 @@ networking_opts = [ cfg.BoolOpt('create_router', default=True, help='This option will create a router when one with ' '"router_name" does not exist'), + + cfg.StrOpt('network_config_file', default='netconfig.yaml', + help='If provided networking configuration will be taken ' + 'from this file') ] stats_opts = [ cfg.IntOpt('period', default=5, diff --git a/murano/db/services/environments.py b/murano/db/services/environments.py index 90f40ee59..8b10c8f34 100644 --- a/murano/db/services/environments.py +++ b/murano/db/services/environments.py @@ -12,6 +12,9 @@ # License for the specific language governing permissions and limitations # under the License. +import yaml + +from murano.common import config from murano.common import uuidutils from murano.db import models from murano.db.services import sessions @@ -19,10 +22,7 @@ from murano.db import session as db_session from murano.services import states -DEFAULT_NETWORKS = { - 'environment': 'io.murano.resources.NeutronNetwork', - # 'flat': 'io.murano.resources.ExistingNetworkConnector' -} +DEFAULT_NETWORK_TYPE = 'io.murano.resources.NeutronNetwork' class EnvironmentServices(object): @@ -91,8 +91,9 @@ class EnvironmentServices(object): 'id': uuidutils.generate_uuid(), }} objects.update(environment_params) - objects.update( - EnvironmentServices.generate_default_networks(objects['name'])) + if not objects.get('defaultNetworks'): + objects['defaultNetworks'] = \ + EnvironmentServices.generate_default_networks(objects['name']) objects['?']['type'] = 'io.murano.Environment' environment_params['tenant_id'] = tenant_id @@ -196,22 +197,29 @@ class EnvironmentServices(object): @staticmethod def generate_default_networks(env_name): + net_config = config.CONF.find_file( + config.CONF.networking.network_config_file) + if net_config: + with open(net_config) as f: + data = yaml.safe_load(f) + return EnvironmentServices._objectify(data, { + 'ENV': env_name + }) + # TODO(ativelkov): # This is a temporary workaround. Need to find a better way: # These objects have to be created in runtime when the environment is # deployed for the first time. Currently there is no way to persist # such changes, so we have to create the objects on the API side return { - 'defaultNetworks': { - 'environment': { - '?': { - 'id': uuidutils.generate_uuid(), - 'type': DEFAULT_NETWORKS['environment'] - }, - 'name': env_name + '-network' + 'environment': { + '?': { + 'id': uuidutils.generate_uuid(), + 'type': DEFAULT_NETWORK_TYPE }, - 'flat': None - } + 'name': env_name + '-network' + }, + 'flat': None } @staticmethod @@ -224,3 +232,21 @@ class EnvironmentServices(object): EnvironmentServices.remove(session.environment_id) else: sessions.SessionServices.deploy(session, environment, unit, token) + + @staticmethod + def _objectify(data, replacements): + if isinstance(data, dict): + if isinstance(data.get('?'), dict): + data['?']['id'] = uuidutils.generate_uuid() + result = {} + for key, value in data.iteritems(): + result[key] = EnvironmentServices._objectify( + value, replacements) + return result + elif isinstance(data, list): + return [EnvironmentServices._objectify(v, replacements) + for v in data] + elif isinstance(data, (str, unicode)): + for key, value in replacements.iteritems(): + data = data.replace('%' + key + '%', value) + return data diff --git a/murano/tests/unit/api/v1/test_env_templates.py b/murano/tests/unit/api/v1/test_env_templates.py index 4efc9be77..5d8c67e56 100644 --- a/murano/tests/unit/api/v1/test_env_templates.py +++ b/murano/tests/unit/api/v1/test_env_templates.py @@ -15,9 +15,11 @@ import json +from oslo.config import cfg from oslo.utils import timeutils from murano.api.v1 import templates +from murano.common import config from murano.db import models import murano.tests.unit.api.base as tb import murano.tests.unit.utils as test_utils @@ -422,6 +424,13 @@ class TestEnvTemplateApi(tb.ControllerTest, tb.MuranoApiTestCase): def test_create_environment(self): """Test that environment is created, session configured.""" + + opts = [ + cfg.StrOpt('config_dir'), + cfg.StrOpt('config_file', default='murano.conf'), + cfg.StrOpt('project', default='murano'), + ] + config.CONF.register_opts(opts) self._set_policy_rules( {'create_env_template': '@', 'create_environment': '@'} @@ -445,6 +454,12 @@ class TestEnvTemplateApi(tb.ControllerTest, tb.MuranoApiTestCase): """Test that environment is created and session with template without services. """ + opts = [ + cfg.StrOpt('config_dir'), + cfg.StrOpt('config_file', default='murano.conf'), + cfg.StrOpt('project', default='murano'), + ] + config.CONF.register_opts(opts) self._set_policy_rules( {'create_env_template': '@', 'create_environment': '@'} diff --git a/murano/tests/unit/api/v1/test_environments.py b/murano/tests/unit/api/v1/test_environments.py index e7e0b4692..293248449 100644 --- a/murano/tests/unit/api/v1/test_environments.py +++ b/murano/tests/unit/api/v1/test_environments.py @@ -15,9 +15,11 @@ import json +from oslo.config import cfg from oslo.utils import timeutils from murano.api.v1 import environments +from murano.common import config from murano.db import models import murano.tests.unit.api.base as tb import murano.tests.unit.utils as test_utils @@ -41,6 +43,12 @@ class TestEnvironmentApi(tb.ControllerTest, tb.MuranoApiTestCase): def test_create_environment(self): """Create an environment, test environment.show().""" + opts = [ + cfg.StrOpt('config_dir'), + cfg.StrOpt('config_file', default='murano.conf'), + cfg.StrOpt('project', default='murano'), + ] + config.CONF.register_opts(opts) self._set_policy_rules( {'list_environments': '@', 'create_environment': '@', diff --git a/murano/tests/unit/api/v1/test_sessions.py b/murano/tests/unit/api/v1/test_sessions.py index cb7572fd0..3d0421d14 100644 --- a/murano/tests/unit/api/v1/test_sessions.py +++ b/murano/tests/unit/api/v1/test_sessions.py @@ -15,8 +15,11 @@ import json +from oslo.config import cfg + from murano.api.v1 import environments from murano.api.v1 import sessions +from murano.common import config import murano.tests.unit.api.base as tb @@ -35,6 +38,12 @@ class TestSessionsApi(tb.ControllerTest, tb.MuranoApiTestCase): """ CREDENTIALS_1 = {'tenant': 'test_tenant_1', 'user': 'test_user_1'} CREDENTIALS_2 = {'tenant': 'test_tenant_2', 'user': 'test_user_2'} + opts = [ + cfg.StrOpt('config_dir'), + cfg.StrOpt('config_file', default='murano.conf'), + cfg.StrOpt('project', default='murano'), + ] + config.CONF.register_opts(opts) self._set_policy_rules( {'create_environment': '@'}