Removed fuel from Genesis master since fuel has moved to repo fuel.
[genesis.git] / compass / deploy / status_callback.py
1 # (C) 2012, Michael DeHaan, <michael.dehaan@gmail.com>
2
3 # This file is part of Ansible
4 #
5 # Ansible is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation, either version 3 of the License, or
8 # (at your option) any later version.
9 #
10 # Ansible is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
17
18 import httplib
19 import json
20 import sys
21 import logging
22
23 def task_error(host, data):
24     logging.info("task_error: host=%s,data=%s" % (host, data))
25
26     if type(data) == dict:
27         invocation = data.pop('invocation', {})
28
29     notify_host("localhost", host, "failed")
30
31 class CallbackModule(object):
32     """
33     logs playbook results, per host, in /var/log/ansible/hosts
34     """
35
36     def on_any(self, *args, **kwargs):
37         pass
38
39     def runner_on_failed(self, host, res, ignore_errors=False):
40         task_error(host, res)
41
42     def runner_on_ok(self, host, res):
43         pass
44
45     def runner_on_skipped(self, host, item=None):
46         pass
47
48     def runner_on_unreachable(self, host, res):
49         pass
50
51     def runner_on_no_hosts(self):
52         pass
53
54     def runner_on_async_poll(self, host, res, jid, clock):
55         pass
56
57     def runner_on_async_ok(self, host, res, jid):
58         pass
59
60     def runner_on_async_failed(self, host, res, jid):
61         task_error(host, res)
62
63     def playbook_on_start(self):
64         pass
65
66     def playbook_on_notify(self, host, handler):
67         pass
68
69     def playbook_on_no_hosts_matched(self):
70         pass
71
72     def playbook_on_no_hosts_remaining(self):
73         pass
74
75     def playbook_on_task_start(self, name, is_conditional):
76         pass
77
78     def playbook_on_vars_prompt(self, varname, private=True, prompt=None, encrypt=None, confirm=False, salt_size=None, salt=None, default=None):
79         pass
80
81     def playbook_on_setup(self):
82         pass
83
84     def playbook_on_import_for_host(self, host, imported_file):
85         pass
86
87     def playbook_on_not_import_for_host(self, host, missing_file):
88         pass
89
90     def playbook_on_play_start(self, name):
91         pass
92
93     def playbook_on_stats(self, stats):
94         logging.info("playbook_on_stats enter")
95         hosts = sorted(stats.processed.keys())
96         host_vars = self.playbook.inventory.get_variables(hosts[0])
97         cluster_name = host_vars['cluster_name']
98         failures = False
99         unreachable = False
100
101         for host in hosts:
102             summary = stats.summarize(host)
103
104             if summary['failures'] > 0:
105                 failures = True
106             if summary['unreachable'] > 0:
107                 unreachable = True
108
109         if failures or unreachable:
110             for host in hosts:
111                 notify_host("localhost", host, "error")
112             return
113
114         for host in hosts:
115             clusterhost_name = host + "." + cluster_name
116             notify_host("localhost", clusterhost_name, "succ")
117
118
119 def raise_for_status(resp):
120     if resp.status < 200 or resp.status > 300:
121         raise RuntimeError("%s, %s, %s" % (resp.status, resp.reason, resp.read()))
122
123 def auth(conn):
124     credential = {}
125     credential['email'] = "admin@huawei.com"
126     credential['password'] = "admin"
127     url = "/api/users/token"
128     headers = {"Content-type": "application/json",
129                "Accept": "*/*"}
130     conn.request("POST", url, json.dumps(credential), headers)
131     resp = conn.getresponse()
132
133     raise_for_status(resp)
134     return json.loads(resp.read())["token"]
135
136 def notify_host(compass_host, host, status):
137     if status == "succ":
138         body = {"ready": True}
139         url = "/api/clusterhosts/%s/state_internal" % host
140     elif status == "error":
141         body = {"state": "ERROR"}
142         host = host.strip("host")
143         url = "/api/clusterhosts/%s/state" % host
144     else:
145         logging.error("notify_host: host %s with status %s is not supported" \
146                 % (host, status))
147         return
148
149     headers = {"Content-type": "application/json",
150                "Accept": "*/*"}
151
152     conn = httplib.HTTPConnection(compass_host, 80)
153     token = auth(conn)
154     headers["X-Auth-Token"] = token
155     logging.info("host=%s,url=%s,body=%s,headers=%s" % (compass_host,url,json.dumps(body),headers))
156     conn.request("POST", url, json.dumps(body), headers)
157     resp = conn.getresponse()
158     try:
159         raise_for_status(resp)
160         logging.info("notify host status success!!! status=%s, body=%s" % (resp.status, resp.read()))
161     except Exception as e:
162         logging.error("http request failed %s" % str(e))
163         raise
164     finally:
165         conn.close()
166
167 if __name__ == "__main__":
168     if len(sys.argv) != 3:
169         logging.error("params: host, status is need")
170         sys.exit(1)
171
172     host = sys.argv[1]
173     status = sys.argv[2]
174     notify_host(host, status)