1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127 | #!/usr/bin/env python
# Dependencies:
# sudo apt-get install python-pip
# python-dev and libevent-dev may be needed.
# sudo pip install websocket-client pyyaml
# Usage:
# run this script passing the environment name, or nothing to connect to the
# default environment.
from __future__ import (
print_function,
unicode_literals,
)
import itertools
import json
import os
import pprint
import ssl
import subprocess
import sys
import websocket
import yaml
SSLOPT = {
'cert_reqs': ssl.CERT_NONE,
'ssl_version': ssl.PROTOCOL_TLSv1,
}
def start(ws, password):
counter = itertools.count()
def send(request):
request['RequestId'] = counter.next()
print(red('\n--> #{RequestId} {Type}:{Request}'.format(**request)))
pprint.pprint(request)
ws.send(json.dumps(request))
response = json.loads(ws.recv())
print(blue('<-- #{RequestId} Response'.format(**response)))
pprint.pprint(response)
print('\n{}'.format('-' * 80))
return response
# Log in.
send({
'Type': 'Admin',
'Request': 'Login',
'Params': {'AuthTag': 'user-admin', 'Password': password},
})
# Watch all.
response = send({
'Type': 'Client',
'Request': 'WatchAll',
'Params': {},
})
# Start watching.
whatcher_id = str(response['Response']['AllWatcherId'])
while True:
try:
send({
'Type': 'AllWatcher',
'Request': 'Next',
'Id': whatcher_id,
'Params': {},
})
except KeyboardInterrupt:
break
def blue(text):
return '\033[01;34m{}\033[00m'.format(text)
def red(text):
return '\033[01;31m{}\033[00m'.format(text)
def green(text):
return '\033[01;32m{}\033[00m'.format(text)
def get_default_env_name():
return subprocess.check_output(['juju', 'switch']).strip()
def get_env_info(env_name):
jenv_path = os.path.expanduser(
os.path.join('~', '.juju', 'environments', '{}.jenv'.format(env_name)))
while True:
with open(jenv_path) as stream:
data = yaml.safe_load(stream)
state_servers = data['state-servers']
if state_servers:
for state_server in state_servers:
if not state_server.startswith(':'):
return (state_server,
data['bootstrap-config']['admin-secret'])
raise ValueError('invalid state servers: {}'.format(state_servers))
print('State server not ready, retrying.')
# Calling status seems to set the state server info in the jenv.
subprocess.check_output(['juju', 'status', '-e', env_name])
def connect(url):
print(green('Connecting to {}.'.format(url)))
return websocket.create_connection(url, sslopt=SSLOPT)
def main(args):
env_name = args[0] if args else get_default_env_name()
host, password = get_env_info(env_name)
ws = connect('wss://{}'.format(host))
try:
start(ws, password)
finally:
print(green('\nClosing connection.'))
ws.close()
if __name__ == '__main__':
main(sys.argv[1:])
|