Yardstick API refactor
[yardstick.git] / api / resources / env_action.py
1 ##############################################################################
2 # Copyright (c) 2016 Huawei Technologies Co.,Ltd and others.
3 #
4 # All rights reserved. This program and the accompanying materials
5 # are made available under the terms of the Apache License, Version 2.0
6 # which accompanies this distribution, and is available at
7 # http://www.apache.org/licenses/LICENSE-2.0
8 ##############################################################################
9 import logging
10 import threading
11 import subprocess
12 import time
13 import json
14 import os
15 import errno
16
17 from docker import Client
18
19 from yardstick.common import constants as config
20 from yardstick.common import utils as yardstick_utils
21 from yardstick.common.httpClient import HttpClient
22 from api import conf as api_conf
23 from api.utils import influx
24 from api.utils.common import result_handler
25
26 logger = logging.getLogger(__name__)
27
28
29 def createGrafanaContainer(args):
30     thread = threading.Thread(target=_create_grafana)
31     thread.start()
32     return result_handler('success', [])
33
34
35 def _create_grafana():
36     client = Client(base_url=config.DOCKER_URL)
37
38     try:
39         if not _check_image_exist(client, '%s:%s' % (config.GRAFANA_IMAGE,
40                                                      config.GRAFANA_TAGS)):
41             client.pull(config.GRAFANA_IMAGE, config.GRAFANA_TAGS)
42
43         _create_grafana_container(client)
44
45         time.sleep(5)
46
47         _create_data_source()
48
49         _create_dashboard()
50     except Exception as e:
51         logger.debug('Error: %s', e)
52
53
54 def _create_dashboard():
55     url = 'http://admin:admin@%s:3000/api/dashboards/db' % api_conf.GATEWAY_IP
56     with open('../dashboard/ping_dashboard.json') as dashboard_json:
57         data = json.load(dashboard_json)
58     HttpClient().post(url, data)
59
60
61 def _create_data_source():
62     url = 'http://admin:admin@%s:3000/api/datasources' % api_conf.GATEWAY_IP
63     data = {
64         "name": "yardstick",
65         "type": "influxdb",
66         "access": "proxy",
67         "url": "http://%s:8086" % api_conf.GATEWAY_IP,
68         "password": "root",
69         "user": "root",
70         "database": "yardstick",
71         "basicAuth": True,
72         "basicAuthUser": "admin",
73         "basicAuthPassword": "admin",
74         "isDefault": False,
75     }
76     HttpClient().post(url, data)
77
78
79 def _create_grafana_container(client):
80     ports = [3000]
81     port_bindings = {k: k for k in ports}
82     host_config = client.create_host_config(port_bindings=port_bindings)
83
84     container = client.create_container(image='%s:%s' % (config.GRAFANA_IMAGE,
85                                                          config.GRAFANA_TAGS),
86                                         ports=ports,
87                                         detach=True,
88                                         tty=True,
89                                         host_config=host_config)
90     client.start(container)
91
92
93 def _check_image_exist(client, t):
94     return any(t in a['RepoTags'][0] for a in client.images() if a['RepoTags'])
95
96
97 def createInfluxDBContainer(args):
98     thread = threading.Thread(target=_create_influxdb)
99     thread.start()
100     return result_handler('success', [])
101
102
103 def _create_influxdb():
104     client = Client(base_url=config.DOCKER_URL)
105
106     try:
107         _config_output_file()
108
109         if not _check_image_exist(client, '%s:%s' % (config.INFLUXDB_IMAGE,
110                                                      config.INFLUXDB_TAG)):
111             client.pull(config.INFLUXDB_IMAGE, tag=config.INFLUXDB_TAG)
112
113         _create_influxdb_container(client)
114
115         time.sleep(5)
116
117         _config_influxdb()
118     except Exception as e:
119         logger.debug('Error: %s', e)
120
121
122 def _create_influxdb_container(client):
123
124     ports = [8083, 8086]
125     port_bindings = {k: k for k in ports}
126     host_config = client.create_host_config(port_bindings=port_bindings)
127
128     container = client.create_container(image='%s:%s' % (config.INFLUXDB_IMAGE,
129                                                          config.INFLUXDB_TAG),
130                                         ports=ports,
131                                         detach=True,
132                                         tty=True,
133                                         host_config=host_config)
134     client.start(container)
135
136
137 def _config_influxdb():
138     try:
139         client = influx.get_data_db_client()
140         client.create_user(config.USER, config.PASSWORD, config.DATABASE)
141         client.create_database(config.DATABASE)
142         logger.info('Success to config influxDB')
143     except Exception as e:
144         logger.debug('Failed to config influxDB: %s', e)
145
146
147 def _config_output_file():
148     yardstick_utils.makedirs(config.YARDSTICK_CONFIG_DIR)
149     with open(config.YARDSTICK_CONFIG_FILE, 'w') as f:
150         f.write("""\
151 [DEFAULT]
152 debug = False
153 dispatcher = influxdb
154
155 [dispatcher_file]
156 file_path = /tmp/yardstick.out
157
158 [dispatcher_http]
159 timeout = 5
160 # target = http://127.0.0.1:8000/results
161
162 [dispatcher_influxdb]
163 timeout = 5
164 target = http://%s:8086
165 db_name = yardstick
166 username = root
167 password = root
168 """
169                 % api_conf.GATEWAY_IP)
170
171
172 def prepareYardstickEnv(args):
173     thread = threading.Thread(target=_prepare_env_daemon)
174     thread.start()
175     return result_handler('success', [])
176
177
178 def _prepare_env_daemon():
179
180     installer_ip = os.environ.get('INSTALLER_IP', 'undefined')
181     installer_type = os.environ.get('INSTALLER_TYPE', 'undefined')
182
183     _check_variables(installer_ip, installer_type)
184
185     _create_directories()
186
187     rc_file = config.OPENSTACK_RC_FILE
188
189     _get_remote_rc_file(rc_file, installer_ip, installer_type)
190
191     _source_file(rc_file)
192
193     _append_external_network(rc_file)
194
195     # update the external_network
196     _source_file(rc_file)
197
198     _load_images()
199
200
201 def _check_variables(installer_ip, installer_type):
202
203     if installer_ip == 'undefined':
204         raise SystemExit('Missing INSTALLER_IP')
205
206     if installer_type == 'undefined':
207         raise SystemExit('Missing INSTALLER_TYPE')
208     elif installer_type not in config.INSTALLERS:
209         raise SystemExit('INSTALLER_TYPE is not correct')
210
211
212 def _create_directories():
213     yardstick_utils.makedirs(config.YARDSTICK_CONFIG_DIR)
214
215
216 def _source_file(rc_file):
217     yardstick_utils.source_env(rc_file)
218
219
220 def _get_remote_rc_file(rc_file, installer_ip, installer_type):
221
222     os_fetch_script = os.path.join(config.RELENG_DIR, config.OS_FETCH_SCRIPT)
223
224     try:
225         cmd = [os_fetch_script, '-d', rc_file, '-i', installer_type,
226                '-a', installer_ip]
227         p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
228         p.communicate()[0]
229
230         if p.returncode != 0:
231             logger.debug('Failed to fetch credentials from installer')
232     except OSError as e:
233         if e.errno != errno.EEXIST:
234             raise
235
236
237 def _append_external_network(rc_file):
238     neutron_client = yardstick_utils.get_neutron_client()
239     networks = neutron_client.list_networks()['networks']
240     try:
241         ext_network = next(n['name'] for n in networks if n['router:external'])
242     except StopIteration:
243         logger.warning("Can't find external network")
244     else:
245         cmd = 'export EXTERNAL_NETWORK=%s' % ext_network
246         try:
247             with open(rc_file, 'a') as f:
248                 f.write(cmd + '\n')
249         except OSError as e:
250             if e.errno != errno.EEXIST:
251                 raise
252
253
254 def _load_images():
255     cmd = [config.LOAD_IMAGES_SCRIPT]
256     p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
257                          cwd=config.YARDSTICK_REPOS_DIR)
258     output = p.communicate()[0]
259     logger.debug('The result is: %s', output)