diff --git a/fuel_ccp/action.py b/fuel_ccp/action.py index 86277405..2bc70f6b 100644 --- a/fuel_ccp/action.py +++ b/fuel_ccp/action.py @@ -75,6 +75,7 @@ class Action(object): CONF.configs._update(action_parameters=self._get_custom_parameters()) data = { "config": CONF.configs._json(sort_keys=True), + "secret-config": CONF.secret_configs._json(sort_keys=True), "nodes-config": utils.get_nodes_config(CONF.nodes), "workflow": self._get_workflow() } @@ -156,6 +157,10 @@ class Action(object): "key": "config", "path": "globals/globals.json" }, + { + "key": "secret-config", + "path": "global-secrets/global-secrets.json" + }, { "key": "nodes-config", "path": "nodes-config/nodes-config.json" @@ -356,8 +361,8 @@ def list_actions(): for filename in os.listdir(action_path): if filename.endswith(".yaml"): action_file = os.path.join(action_path, filename) - data = jinja_utils.jinja_render(action_file, - CONF.configs._dict) + conf = utils.get_rendering_config() + data = jinja_utils.jinja_render(action_file, conf._dict) for action_dict in yaml.load(data).get("actions", ()): actions.append(Action(component=component_name, component_dir=repo, diff --git a/fuel_ccp/cleanup.py b/fuel_ccp/cleanup.py index 1d8840b1..3a0d1221 100644 --- a/fuel_ccp/cleanup.py +++ b/fuel_ccp/cleanup.py @@ -206,5 +206,6 @@ def _cleanup_kubernetes_objects(): def cleanup(auth_url=None, skip_os_cleanup=False, verify=True): if not skip_os_cleanup: - _cleanup_openstack_environment(CONF.configs, auth_url, verify) + conf = utils.get_rendering_config() + _cleanup_openstack_environment(conf, auth_url, verify) _cleanup_kubernetes_objects() diff --git a/fuel_ccp/common/utils.py b/fuel_ccp/common/utils.py index 4a571630..4ae03b94 100644 --- a/fuel_ccp/common/utils.py +++ b/fuel_ccp/common/utils.py @@ -192,7 +192,7 @@ def extend_with_service_configs(service_name, config): def get_deploy_components_info(): - rendering_context = CONF.configs + rendering_context = get_rendering_config() service_definitions_map = get_service_definitions_map() services_map = {} custom_services_map = {} @@ -295,3 +295,9 @@ def get_nodes_config(nodes): if 'configs' in nodes[node]: nodes_config[node] = nodes[node]['configs'] return nodes_config._json(sort_keys=True) + + +def get_rendering_config(): + conf = copy.deepcopy(CONF.configs) + conf._merge(CONF.secret_configs) + return conf diff --git a/fuel_ccp/config/__init__.py b/fuel_ccp/config/__init__.py index 9af847d1..040fb7a6 100644 --- a/fuel_ccp/config/__init__.py +++ b/fuel_ccp/config/__init__.py @@ -76,7 +76,7 @@ def get_config_defaults(): 'urllib3=WARN' ] }) - for name in ['configs', 'nodes', 'roles', 'versions']: + for name in ['configs', 'secret_configs', 'nodes', 'roles', 'versions']: defaults[name] = _yaml.AttrDict() for module in CONFIG_MODULES: defaults._merge(module.DEFAULTS) @@ -102,7 +102,7 @@ def get_config_schema(): for name in ignore_opts: schema['properties'][name] = {} # Also for now don't validate sections that used to be in deploy config - for name in ['configs', 'nodes', 'roles', 'versions']: + for name in ['configs', 'secret_configs', 'nodes', 'roles', 'versions']: schema['properties'][name] = {'type': 'object'} return schema @@ -118,7 +118,7 @@ def load_component_defaults(): from fuel_ccp.common import utils sections = ['versions', 'sources', 'configs', 'nodes', 'roles', 'replicas', - 'url', 'files', 'services'] + 'url', 'files', 'services', 'secret_configs'] new_config = _yaml.AttrDict((k, _yaml.AttrDict()) for k in sections) for path in utils.get_config_paths(): if not os.path.exists(path): diff --git a/fuel_ccp/deploy.py b/fuel_ccp/deploy.py index ce0c738a..d0220127 100644 --- a/fuel_ccp/deploy.py +++ b/fuel_ccp/deploy.py @@ -121,8 +121,9 @@ def parse_role(component, topology, configmaps): if CONF.action.dry_run: cm_version = 'dry-run' else: + rendering_context = utils.get_rendering_config() cm_version = _get_configmaps_version( - configmaps, service_dir, files, CONF.configs._dict) + configmaps, service_dir, files, rendering_context._dict) for cont in service["containers"]: daemon_cmd = cont["daemon"] @@ -348,6 +349,13 @@ def _create_globals_configmap(config): return kubernetes.process_object(cm) +def _create_globals_secret(conf): + data = {templates.GLOBAL_SECRET_CONFIG: conf._json(sort_keys=True)} + secret = templates.serialize_secret( + templates.GLOBAL_SECRET_CONFIG, data=data) + return kubernetes.process_object(secret) + + def _create_nodes_configmap(nodes): nodes_config = utils.get_nodes_config(nodes) data = {templates.NODES_CONFIG: nodes_config} @@ -647,6 +655,7 @@ def deploy_components(components_map, components): _create_namespace(CONF.configs) _create_registry_secret() _create_globals_configmap(CONF.configs) + _create_globals_secret(CONF.secret_configs) _create_nodes_configmap(CONF.nodes) start_script_cm = create_start_script_configmap() @@ -697,4 +706,5 @@ def deploy_components(components_map, components): topology, exports_ctx) if 'keystone' in components: - _create_openrc(CONF.configs) + conf = utils.get_rendering_config() + _create_openrc(conf) diff --git a/fuel_ccp/kubernetes.py b/fuel_ccp/kubernetes.py index c8deb339..8e7ab001 100644 --- a/fuel_ccp/kubernetes.py +++ b/fuel_ccp/kubernetes.py @@ -16,6 +16,7 @@ UPDATABLE_OBJECTS = ( 'Service', 'Ingress', 'StatefulSet', + 'Secret', ) diff --git a/fuel_ccp/resources/defaults.yaml b/fuel_ccp/resources/defaults.yaml index 802fbc18..fdc9e913 100644 --- a/fuel_ccp/resources/defaults.yaml +++ b/fuel_ccp/resources/defaults.yaml @@ -8,6 +8,7 @@ configs: domain: external port: 8443 +secret_configs: security: tls: create_certificates: true diff --git a/fuel_ccp/templates.py b/fuel_ccp/templates.py index 70d7340b..eb25a2f1 100644 --- a/fuel_ccp/templates.py +++ b/fuel_ccp/templates.py @@ -9,6 +9,7 @@ from fuel_ccp.config import images CONF = config.CONF GLOBAL_CONFIG = "globals" +GLOBAL_SECRET_CONFIG = "global-secrets" NODES_CONFIG = "nodes-config" SERVICE_CONFIG = "service-config" SCRIPT_CONFIG = "start-script" @@ -61,6 +62,10 @@ def serialize_volume_mounts(container, for_job=None): "name": GLOBAL_CONFIG, "mountPath": "/etc/ccp/%s" % GLOBAL_CONFIG }, + { + "name": GLOBAL_SECRET_CONFIG, + "mountPath": "/etc/ccp/%s" % GLOBAL_SECRET_CONFIG + }, { "name": ROLE_CONFIG, "mountPath": "/etc/ccp/%s" % ROLE_CONFIG @@ -280,6 +285,14 @@ def serialize_volumes(service, for_job=None): "path": "globals.json"}] } }, + { + "name": GLOBAL_SECRET_CONFIG, + "secret": { + "secretName": GLOBAL_SECRET_CONFIG, + "items": [{"key": GLOBAL_SECRET_CONFIG, + "path": "%s.json" % GLOBAL_SECRET_CONFIG}] + } + }, { "name": SCRIPT_CONFIG, "configMap": { diff --git a/fuel_ccp/tests/test_templates.py b/fuel_ccp/tests/test_templates.py index 8c8584f1..c50b35bb 100644 --- a/fuel_ccp/tests/test_templates.py +++ b/fuel_ccp/tests/test_templates.py @@ -45,6 +45,8 @@ class TestDeploy(base.TestCase): ], "volumeMounts": [ {'mountPath': '/etc/ccp/globals', 'name': 'globals'}, + {'mountPath': '/etc/ccp/global-secrets', + 'name': 'global-secrets'}, {'mountPath': '/etc/ccp/role', 'name': 'role'}, {'mountPath': '/etc/ccp/meta', 'name': 'meta'}, {'mountPath': '/opt/ccp_start_script/bin',