Пример #1
0
def generate2(targetFilePath, tmpl, model):
    ensureFolder(os.path.dirname(targetFilePath))
    if isinstance(tmpl, jinja2.Template):
        try:
            result = tmpl.render(m=model)
        except jinja2.exceptions.TemplateRuntimeError as err:
            print '---------------------------------------------------------'
            traceback.print_exc(file=sys.stdout)
            print '---------------------------------------------------------'
            ERROR("Error in '{0}' file generation: {1}".format(
                targetFilePath, err.message))
    else:
        result = tmpl
    with open(targetFilePath, "w") as f:
        f.write(result)
    if targetFilePath.endswith(".sh"):
        cp = stat.S_IMODE(os.lstat(targetFilePath).st_mode)
        os.chmod(
            targetFilePath,
            cp | stat.S_IXUSR | (stat.S_IXGRP if cp & stat.S_IRGRP else 0) |
            (stat.S_IXOTH if cp & stat.S_IROTH else 0))
        logger.info("File '{0}' successfully generated as executable".format(
            targetFilePath))
    else:
        logger.info("File '{0}' successfully generated".format(targetFilePath))
Пример #2
0
 def dumpTmpl(self, fileName, tmplType, string):
     fname = os.path.join(self.folder, "tmpls", fileName + "." + tmplType)
     misc.ensureFolder(os.path.dirname(fname))
     with open(fname, "w") as f:
         f.write(string)
Пример #3
0
 def __init__(self, location, unsafe):
     self.folder = os.path.join(location, "dump")
     self.unsafe = unsafe
     misc.ensureFolder(self.folder)
Пример #4
0
def main():
    global vaultFactory

    mydir = os.path.dirname(os.path.realpath(__file__))

    parser = argparse.ArgumentParser()
    parser.add_argument('--src', required=True)
    parser.add_argument('--mark', choices=["none", "both", "start", "end"])
    parser.add_argument('--dump', action='store_true')
    parser.add_argument('--dumpPasswords', action='store_true')
    parser.add_argument('--out')  # Generate a file to set some variable

    param = parser.parse_args()

    loggingConfFile = os.path.join(mydir, "./logging.yml")
    logging.config.dictConfig(
        yaml.load(open(loggingConfFile), Loader=yaml.SafeLoader))

    sourceFile = os.path.normpath(os.path.abspath(param.src))
    if not os.path.isfile(sourceFile):
        ERROR("File '{}' does not exists".format(sourceFile))
    logger.info("Will handle '{}'".format(sourceFile))
    sourceFileDir = os.path.dirname(sourceFile)

    cluster = yaml.load(open(sourceFile), Loader=yaml.SafeLoader)
    targetFolder = misc.appendPath(
        sourceFileDir,
        cluster["build_folder"] if "build_folder" in cluster else "build")
    misc.ensureFolder(targetFolder)
    logger.info("Build folder: '{}'".format(targetFolder))

    if "config_file" in cluster:
        baseConfigFile = cluster["config_file"]
    else:
        baseConfigFile = "ezconfig.yml"
    config, configFile = buildConfig(sourceFileDir, baseConfigFile)

    plugins = []
    plugins.append(Plugin("core", misc.appendPath(mydir, "../plugins/core")))
    logger.debug("Plugins path:'{}'".format(config[PLUGINS_PATH]))
    appendPlugins(plugins, cluster, config[PLUGINS_PATH])

    schema = buildSchema(mydir, plugins)
    configSchema, safeConfigSchema = buildConfigSchema(mydir,
                                                       config[PLUGINS_PATH])

    if param.dump:
        dumper = Dumper(targetFolder, param.dumpPasswords)
        dumper.dump("schema.json", schema)
        dumper.dump("config-schema.json", configSchema)
        dumper.dump("safe-config-schema.json", safeConfigSchema)
    else:
        dumper = None

    k = kwalify(source_data=cluster, schema_data=schema)
    k.validate(raise_exception=False)
    if len(k.errors) != 0:
        ERROR("Problem {0}: {1}".format(sourceFile, k.errors))

    k = kwalify(source_data=config, schema_data=configSchema)
    k.validate(raise_exception=False)
    if len(k.errors) != 0:
        ERROR("Configuration problem {0}: {1}".format(configFile, k.errors))

    data = {}
    data['sourceFileDir'] = sourceFileDir
    data["targetFolder"] = targetFolder
    data['ezclusterHome'] = misc.appendPath(mydir, "..")
    data["rolePaths"] = set()
    data["configFile"] = configFile

    model = {}
    model['cluster'] = cluster
    model["config"] = config
    model['data'] = data

    initVault(model)

    if SAFE_CONFIG in model and safeConfigSchema != None:
        k = kwalify(source_data=model[SAFE_CONFIG],
                    schema_data=safeConfigSchema)
        k.validate(raise_exception=False)
        if len(k.errors) != 0:
            ERROR("Configuration problem {0}: {1}".format(
                model["data"][_SAFE_CONFIG_FILE_], k.errors))

    for plugin in plugins:
        plugin.groom(model)

    for plugin in plugins:
        plugin.groom2(model)

    targetFileByName = buildTargetFileByName(plugins)

    if param.dump:
        dumper.dump("cluster.json", model['cluster'])
        dumper.dump("data.json", model['data'])
        dumper.dump("targetFileByName.json", targetFileByName)
        dumper.dump("config.json", config)
        if SAFE_CONFIG in model and dumper.unsafe:
            dumper.dump("safeConfig.json", model[SAFE_CONFIG])

        for plugin in plugins:
            plugin.dump(model, dumper)

    generate(targetFileByName, targetFolder, model, param.mark, dumper)

    if "out" in param:
        f = open(param.out, "w+")
        f.write("# Generated by ezcluster:\n")
        if "buildScript" in model["data"]:
            f.write('BUILD_SCRIPT="{}"\n'.format(model["data"]["buildScript"]))
        f.close()
Пример #5
0
def main():
    mydir =  os.path.dirname(os.path.realpath(__file__)) 
    parser = argparse.ArgumentParser()
    parser.add_argument('--src', nargs='*', required=True)
    parser.add_argument('--action', required=True)
    parser.add_argument('--scope', nargs='*', required=False)
    parser.add_argument('--noScope', nargs='*', required=False)
    parser.add_argument('--yamlLoggingConf', help="Logging configuration as a yaml file", required=False)
    parser.add_argument('--workingFolder', help="Where to store working context", required=True)

    param = parser.parse_args()

    if param.yamlLoggingConf != None:
        loggingConfFile = param.yamlLoggingConf
    else:
        loggingConfFile = os.path.join(mydir, "conf/logging.yml")
        
    if not os.path.isfile(loggingConfFile):
        misc.ERROR("'{0}' is not a readable file!".format(loggingConfFile))    

    logging.config.dictConfig(yaml.load(open(loggingConfFile)))
    
    logger.debug("mydir:" + mydir)
    logger.debug("param.src:" + str(param.src))
    
    workingFolder = param.workingFolder
    if not os.path.isdir(workingFolder):
        misc.ERROR("{0} must be an existing folder".format(workingFolder))
    if len(os.listdir(workingFolder)) > 0:
        misc.ERROR("{0} must be an existing EMPTY folder".format(workingFolder))
    
    # ----- We must make a first read of the file, with only the 'master' plugin to fetch plugins list and path
    masterPluginPath = os.path.abspath(os.path.join(mydir, "."))
    context = Context(workingFolder)
    context.loadPlugin("master", [masterPluginPath])
    handleSourceFiles(param.src, context, None)
    context.groom()
    
    # --------------------------------------------- included scope handling
    context.includedScopes = handleCliScopes(param.scope)
    if len(context.includedScopes) == 0 and INCLUDED_SCOPES in context.model[SRC]:
        context.includedScopes = set(context.model[SRC][INCLUDED_SCOPES])
    if len(context.includedScopes) > 0:
        print("Scope limited to  {0}".format(str(list(context.includedScopes))))
    # -------------------------------------------- Excluded scope handling
    context.excludedScopes = handleCliScopes(param.noScope)
    if EXCLUDED_SCOPES in context.model[SRC]:
        context.excludedScopes = context.excludedScopes.union(context.model[SRC][EXCLUDED_SCOPES])
    if len(context.excludedScopes) > 0:
        print("Scope excluded: {0}".format(str(list(context.excludedScopes))))
    
    # Now, we must have the effective PLUGINS list and PLUGINS_PATHS in the context. We can load all plugins
    for plName in context.model[SRC][PLUGINS]:
            context.loadPlugin(plName, context.model[SRC][PLUGINS_PATHS])
    # And reload source files, with now all plugins activated
    fileByVariable = {} if param.action == "dumpvars" else None        
    handleSourceFiles(param.src, context, fileByVariable)
    if 'include' in context.model[SRC]:
        del(context.model[SRC]['include'])  # Must remove, as not part of the schema

    # Now, build the schema for source validation, by merge of all schema plugin
    theSchema = context.getSchema()
    dump.dumpSchema(context, theSchema)
    #dump.dumpModel(context)
    # And validate against this schema
    schema.validate(context.model[SRC], theSchema)

    # And groom all plugins
    context.groom()

    dump.dumpModel(context)

    # Check scopes validity
    # NB: We perform this after grooming, even if grooming can rely on scope. Aims is only to detect scopes with typo. 
    supportedScopes = context.getAllSupportedScopes()
    scopesToTest = context.excludedScopes.union(context.includedScopes)
    for scope in scopesToTest:
        if scope != "all" and scope != "none" and not context.checkScope(scope) and scope not in supportedScopes:   # checkScope(): Scope for target file/folders (hosts and hostgroups)
            misc.ERROR("Scope '{0}' is not supported!".format(scope))
    
    templator = Templator([os.path.join(mydir, './templates'), context.workingFolder], context.model)
    actions = context.getAllSupportedActions()
    logger.debug("Supported actions: {0}".format(actions))
    action = param.action
    if action == "none":
        for action in actions:
            pluginExts = context.getPluginExtForAction(action)
            logger.debug("Action: {0} -> plugins: {1}".format(action, pluginExts))
            context.buildTemplate(action, pluginExts)
            context.builRolesPath(action, pluginExts)
            context.generateAuxTemplates(action, pluginExts)
            templator.generate("{0}.yml.jj2".format(action), os.path.join(context.workingFolder, "{0}.yml".format(action)))
    elif action == "dumpvars":
        if SRC in context.model and VARS in context.model[SRC]:
            print("---")
            variables = context.model[SRC][VARS]
            for name in sorted(variables):
                x = yaml.dump(variables[name], default_flow_style=True, default_style=None, explicit_end=False)
                p = x.find("\n...\n")
                if p > 0:
                    x = x[:-5]
                p = x.find("\n")
                if p > 0:
                    x = x[:-1]
                print("{}: {}   ({})".format(name, x, fileByVariable[name] if name in fileByVariable else "??"))
            print("---")
            #txt = yaml.dump(context.model[SRC][VARS], default_flow_style=False, default_style=None)
            return
    else: 
        if not action in actions:
            misc.ERROR("Action {0} not supported. Current configuration only supports {1}".format(action, str(actions)))
        pluginExts = context.getPluginExtForAction(action)
        logger.debug("Action: {0} -> plugins: {1}".format(action, pluginExts))
        context.buildTemplate(action, pluginExts)
        context.builRolesPath(action, pluginExts)
        context.generateAuxTemplates(action, pluginExts)
        templator.generate("{0}.yml.jj2".format(action), os.path.join(context.workingFolder, "{0}.yml".format(action)))
        

    templator.generate("inventory.jj2", os.path.join(context.workingFolder, "inventory"))
    templator.generate("ansible.cfg.jj2", os.path.join(context.workingFolder, "ansible.cfg"))
    misc.ensureFolder(os.path.join(context.workingFolder, "group_vars"))
    templator.generate("group_vars_all.jj2", os.path.join(context.workingFolder, "group_vars/all"))