fuel-ccp/fuel_ccp/common/utils.py

188 lines
6.2 KiB
Python

import itertools
import logging
import os
import pkg_resources
import yaml
import fuel_ccp
from fuel_ccp.common import jinja_utils
from fuel_ccp import config
from fuel_ccp import kubernetes
CONF = config.CONF
LOG = logging.getLogger(__name__)
def get_ingress_host(ingress_name):
return '.'.join((ingress_name, CONF.configs.ingress.domain))
def get_ingress_domains(components=None):
components_map = get_deploy_components_info()
components = components or components_map.keys()
domains = []
for component in components:
service = components_map[component]["service_content"]["service"]
for port in service.get("ports", []):
if port.get("ingress"):
domains.append(get_ingress_host(port.get("ingress")))
return domains
def get_resource_path(path):
return pkg_resources.resource_filename(fuel_ccp.version_info.package, path)
def get_repositories_paths():
"""Get repositories paths.
:returns: list -- list of full repositories paths
"""
paths = []
for repo in CONF.repositories.repos:
paths.append(os.path.join(CONF.repositories.path, repo["name"]))
return paths
def get_config_paths():
paths = []
# Order does matter. At first we add global defaults.
for conf_path in ("resources/defaults.yaml", "resources/globals.yaml"):
paths.append(get_resource_path(conf_path))
# After we add component defaults.
for repo in get_repositories_paths():
paths.append(os.path.join(repo, "service", "files", "defaults.yaml"))
return paths
def address(service, port=None, external=False, with_scheme=False):
addr = None
service_name = service.split('-')[0]
enable_tls = CONF.configs.get(service_name, {}).get(
'tls', {}).get('enabled')
if enable_tls:
scheme = 'https'
else:
scheme = 'http'
if external:
if not port:
raise RuntimeError('Port config is required for external address')
if CONF.configs.ingress.enabled and port.get('ingress'):
scheme = 'https'
addr = "%s:%s" % (get_ingress_host(port['ingress']),
CONF.configs.ingress.port)
elif port.get('node'):
addr = '%s:%s' % (CONF.configs.k8s_external_ip, port['node'])
if addr is None:
addr = '.'.join((service, CONF.kubernetes.namespace, 'svc',
CONF.kubernetes.cluster_domain))
if port:
addr = '%s:%s' % (addr, port['cont'])
if with_scheme:
addr = "%s://%s" % (scheme, addr)
return addr
def get_repositories_exports():
"""Load shared templates from ./exports dirs of the repositories. """
exports = dict()
for repo in get_repositories_paths():
exports_dir = os.path.join(repo, 'exports')
if os.path.exists(exports_dir) and os.path.isdir(exports_dir):
for export_file in os.listdir(exports_dir):
# Due to k8s keys constraints we need to remove non-alpha
cm_key = ''.join([c for c in export_file if c.isalpha()])
path = os.path.join(exports_dir, export_file)
LOG.debug('Found shared jinja template file %s', path)
if cm_key not in exports:
exports[cm_key] = {'name': export_file, 'body': []}
with open(path) as f:
exports[cm_key]['body'].append(f.read())
for cm_key, cm in exports.items():
# Merge files with the same name
cm['body'] = '\n'.join(sorted(cm['body']))
return exports
def get_component_name_from_repo_path(path):
REPO_NAME_PREFIX = "fuel-ccp-"
name = os.path.basename(path)
if name.startswith(REPO_NAME_PREFIX):
name = name[len(REPO_NAME_PREFIX):]
return name
def get_deploy_components_info(rendering_context=None):
if rendering_context is None:
rendering_context = CONF.configs._dict
components_map = {}
for repo in get_repositories_paths():
service_dir = os.path.join(repo, "service")
if not os.path.isdir(service_dir):
continue
component_name = get_component_name_from_repo_path(repo)
component = {
"name": component_name,
"upgrades": {},
"service_dir": service_dir,
}
upgrade_dir = os.path.join(service_dir, "upgrade")
if os.path.isdir(upgrade_dir):
for upgrade_fname in os.listdir(upgrade_dir):
if not upgrade_fname.endswith('.yaml'):
continue
LOG.debug("Loading upgrade definition: %s", upgrade_fname)
with open(os.path.join(upgrade_dir, upgrade_fname)) as f:
upgrade_def = yaml.load(f)
key = upgrade_fname[:-len('.yaml')]
component['upgrades'][key] = upgrade_def
for service_file in os.listdir(service_dir):
if service_file.endswith('.yaml'):
LOG.debug("Rendering service definition: %s", service_file)
content = jinja_utils.jinja_render(
os.path.join(service_dir, service_file), rendering_context,
functions=[address]
)
LOG.debug("Parse service definition: %s", service_file)
service_definition = yaml.load(content)
service_name = service_definition['service']['name']
components_map[service_name] = {
'component': component,
'component_name': component_name,
'service_dir': service_dir,
'service_content': service_definition
}
return components_map
def get_deployed_components():
"""Returns set of deployed components."""
deployed_deployments = kubernetes.list_cluster_deployments()
deployed_statefulsets = kubernetes.list_cluster_statefulsets()
deployed_components = set(kubernetes.get_object_names(
itertools.chain(deployed_deployments, deployed_statefulsets))
)
return deployed_components
def get_nodes_config(nodes):
nodes_config = config._yaml.AttrDict()
for node in sorted(nodes):
if 'configs' in nodes[node]:
nodes_config[node] = nodes[node]['configs']
return nodes_config._json(sort_keys=True)