可以在一个模块内创建/调用AnsibleModule的多个实例吗?

时间:2017-07-31 22:01:04

标签: python python-2.7 ansible ansible-2.x

我们的服务器逻辑结构基于" cluster"的概念。和"实例"。集群是Weblogic和/或Karaf和/或Apache和/或Nginx和/或Jboss的一组实例。实例" MAY或MAY-NOT"分散在多个主机上。

经典集群将是: 主持人:a,b 实例:a:tst13-apache,tst13-weblogic-ecom,tst13-weblogic-fulfill b上的实例:tst13-karaf-rest-bus,tst13-karf-rest-svcs,tst13-nginx-cache

我创建了一个超类模块(myMod)和5个子类(myApache,myNginx,myJboss,myKaraf,myWeblogic)。 "实例"信息(库存变量)保存在ldap数据库中。实例没有注册"在主机上的rc.d目录中。每个服务器都有"通用脚本"用于启动apache实例和weblogic实例以及JBoss实例,并通过"实例名称"所以调用Ansible模块,例如" httpd"不实用。

我的模块将用于"停止,开始,状态,杀死等等#34; (行动)针对实例列表。

理想情况下,我想创建一个到目的地"主机"的ssh连接。对于要在目标主机上执行的每个软件实例(我认为这意味着每个需要采取措施的服务器软件实例的模块实例);然而,到目前为止,似乎ansible每个目的地1 ssh连接" host"。

由于"主持人"可以运行不同类型软件的许多实例(2个apache实例,4个weblogic实例和3个karaf实例都可以在1个主机上);创建我的" myMod"似乎很实用。如下:

#####
## <ANSIBLE_HOME>/modules/controller.py    
#####
    import socket
    from ansible.module_utils.ldapData import ldapData
    from ansible.module_utils.myMod import myMod
    from ansible.module_utils.myModules import myApache, myNginx, myWeblogic, myKaraf, myJboss

    def main():

        arg_spec = dict(
                action = dict(default='status', choices=['start', 'stop', 'kill', 'status', 'warm', 'startsession', 'stopsession']),
                instances = dict(default='@', required=False, type='str'),
            )

        host = socket.gethostname()

        serverdata = ldapData()
        cluster = serverdata.hosts[host]["cluster"]
        clusterData = serverdata.clusters[cluster]
        hostData = serverdata.hosts[host]

        classList = list(myMod.__subclasses__())

        for classType in classList:
            localMod = classType(arg_spec, hostData, clusterData)
            localMod.process()

    if __name__ == '__main__':
        main()

myMod中的处理方法如下所示:

#####
## <ANSIBLE_HOME>/module_utils/myMod.py
#####
    def process(self):
        fPointers = {
                'start': self.start,
                'stop': self.stop,
                'kill': self.kill,
                'status': self.status,
                'stopsession': self.stopsession,
                'startsesson': self.startsession,
                'warm': self.warm
        }
        act = self.params['action']
        for inst in self.instances:
                if fPointers[act]:
                        fPointers[act](inst)
                else:
                        undefined(inst)
        self.exit_json(changed=self.changed, msg=self.out, warnings=self.warn, errors=self.err)

目前,我只是回到了&#34; out&#34;和#34;警告&#34;并且&#34;错误&#34;得到&#34;进程&#34;的第一个模块调用。其他模块未执行或未报告。我期待exit_json退出整个Ansible运行&#34;而不只是&#34;当前模块&#34;。

我说错了吗?是否有一个我不知道的游戏概念?这里最好的变化是什么,以确保ansible&#34;报告&#34;在运行结束时显示&#34;所有实例的所有输出&#34;?

1 个答案:

答案 0 :(得分:0)

对于每个任务,在通过SSH将模块发送到执行之前,Ansible将模块包含所有必需的库和参数。因此,您的主模块(包装器)应该在一次运行中完成所有工作。

exit_json方法stops使用sys.exit(0)的整个过程,因此当您第一次运行模块时调用此方法。

我建议您创建一个AnsibleModule类和一组将数据返回到父模块的帮助程序。然后,您只需将所有帮助器的结果合并到单个对象中,然后将其刷新到stdout(使用exit_json)。