2017-07-31 64 views
0

我們的服務器邏輯結構是基於「集羣」和「實例」的概念。羣集是Weblogic和/或Karaf和/或Apache和/或Nginx和/或Jboss的一組實例。實例「可以或不可以」分佈在多個主機上。可以在一個模塊內創建/調用AnsibleModule的多個實例嗎?

一個經典的集羣將是:在A,B 實例: 主機tst13的Apache,tst13-WebLogic的ECOM,tst13-WebLogic的履行 實例上B:tst13-karaf靜止總線,tst13 -karf-rest-svcs,tst13-nginx-cache

我創建了超類模塊(myMod)和5個子類(myApache,myNginx,myJboss,myKaraf,myWeblogic)。 「實例」信息(庫存變量)保存在ldap數據庫中。這些實例不在主機上的rc.d目錄中「註冊」。每個服務器都有用於啓動apache實例和weblogic實例以及JBoss實例的「通用腳本」,以及「實例名稱」,因此調用諸如「httpd」之類的Ansible模塊並不實際。

我的模塊將用於針對實例列表進行「停止,開始,狀態,殺死等」(動作)。

理想情況下,我想創建一個到目標主機的ssh連接,以便在目標主機上運行的每個軟件實例(我相信這意味着每個服務器實例的模塊實例)需要採取措施的軟件);然而,到目前爲止,它似乎是可靠的,使得每個目標「主機」1個SSH連接。由於「主機」可以運行不同類型軟件的許多實例(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) 

目前,我只得到背面的「out」和「警告」和第一個獲取「process」的模塊的「err」。其他模塊不執行或未報告。我期待exit_json「退出整個Ansible運行」而不僅僅是「當前模塊」。

我正確嗎?有沒有我不知道的遊戲概念?這裏最好的改變是確保運行結束時的「報告」顯示「所有實例的所有輸出」?

回答

0

對於每個任務Ansible在將模塊發送到通過SSH執行之前,將所有必需的庫和參數打包。所以你的主模塊(包裝)應該在一次運行中完成所有的工作。

exit_json方法stops整個過程與sys.exit(0),所以當你第一次調用這個方法時,你的模塊的運行完成。

我建議你製作一個AnsibleModule類和一組返回數據到你的父模塊的幫助器。然後,您只需將所有助手的結果合併到單個對象中並將其刷新到stdout(使用exit_json)。

+0

謝謝康斯坦丁,我同意。有兩種可能的方法。 1)建立一個模塊,按照建議將它們聚合到標準輸出中,2)將這些助手分解成它們自己的模塊(基本上將ctl.py的內容複製到每個助手類的尾端,並將助手類移入modules目錄,而不是將它們都放在module_utils中。我會嘗試並與用戶一起審查。 – nverkland

相關問題