Source code for confab.model

"""
Functions for interacting with the defined :term:`hosts<host>`,
:term:`environments<environment>`, and :term:`roles<role>`.
"""
from fabric.api import env
from confab.files import _import
from os.path import join


def _keys():
    """
    Get the model's environment keys.
    """
    return ["environmentdefs", "roledefs", "componentdefs"]


[docs]def load_model_from_dir(dir_name, module_name='settings'): """ Load model data (environments, roles, hosts) from settings module. """ settings = _import(module_name, dir_name) for key in _keys(): env[key] = getattr(settings, key, {})
[docs]def load_model_from_dict(settings): """ Load model data (environments, roles, hosts) from settings dictionary. """ for key in _keys(): env[key] = settings.get(key, {})
[docs]def get_roles_for_host(host): """ Get all roles that a host belongs to. Delegates to Fabric's env roledefs. """ return [role for (role, hosts) in env.roledefs.iteritems() if host in hosts]
[docs]def get_hosts_for_environment(environment): """ Get all hosts for an environment. Assumes an environmentsdef structure in Fabric's env. """ try: return env.environmentdefs[environment] except AttributeError: raise Exception("No environments are defined") except KeyError: raise Exception("Environment '{}' is not defined".format(environment))
[docs]def get_components_for_role(role): """ Get all component paths for the given role. """ if role not in env.roledefs: raise Exception("Role '{}' is not defined".format(role)) if 'componentdefs' not in env or role not in env.componentdefs: return [] return _expand_components(role, '', {})
def _expand_components(component, path, seen): """ Recursively expand component paths rooted at the given component based on componentdefs. Raises an exception if a cycle is discovered in component definitions or if a component leaf exists in multiple paths. :param component: A component name. :param path: The component path being built. :param seen: Dictionary of visited components and their paths. """ component_path = join(path, component) if component in seen: raise Exception("Detected cycle or multiple paths with role/component '{}'" " ('{}' and '{}')".format(component, seen[component], component_path)) seen[component] = component_path if component not in env.componentdefs: return [component_path] components = [] for c in env.componentdefs.get(component): components += _expand_components(c, component_path, seen) return components