Merge "yardstick env influxdb/grafana cmd support centos"
[yardstick.git] / api / resources / v2 / openrcs.py
1 ##############################################################################
2 # Copyright (c) 2017 Huawei Technologies Co.,Ltd.
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 uuid
10 import logging
11 import re
12 import os
13
14 import yaml
15 from oslo_serialization import jsonutils
16
17 from api import ApiResource
18 from api.database.v2.handlers import V2OpenrcHandler
19 from api.database.v2.handlers import V2EnvironmentHandler
20 from yardstick.common import constants as consts
21 from yardstick.common.utils import result_handler
22 from yardstick.common.utils import makedirs
23 from yardstick.common.utils import source_env
24
25 LOG = logging.getLogger(__name__)
26 LOG.setLevel(logging.DEBUG)
27
28
29 class V2Openrcs(ApiResource):
30
31     def post(self):
32         return self._dispatch_post()
33
34     def upload_openrc(self, args):
35         try:
36             upload_file = args['file']
37         except KeyError:
38             return result_handler(consts.API_ERROR, 'file must be provided')
39
40         try:
41             environment_id = args['environment_id']
42         except KeyError:
43             return result_handler(consts.API_ERROR, 'environment_id must be provided')
44
45         try:
46             uuid.UUID(environment_id)
47         except ValueError:
48             return result_handler(consts.API_ERROR, 'invalid environment id')
49
50         LOG.info('writing openrc: %s', consts.OPENRC)
51         makedirs(consts.CONF_DIR)
52         upload_file.save(consts.OPENRC)
53         source_env(consts.OPENRC)
54
55         LOG.info('parsing openrc')
56         try:
57             openrc_data = self._get_openrc_dict()
58         except Exception:
59             LOG.exception('parse openrc failed')
60             return result_handler(consts.API_ERROR, 'parse openrc failed')
61
62         openrc_id = str(uuid.uuid4())
63         self._write_into_database(environment_id, openrc_id, openrc_data)
64
65         LOG.info('writing ansible cloud conf')
66         try:
67             self._generate_ansible_conf_file(openrc_data)
68         except Exception:
69             LOG.exception('write cloud conf failed')
70             return result_handler(consts.API_ERROR, 'genarate ansible conf failed')
71         LOG.info('finish writing ansible cloud conf')
72
73         return result_handler(consts.API_SUCCESS, {'openrc': openrc_data, 'uuid': openrc_id})
74
75     def update_openrc(self, args):
76         try:
77             openrc_vars = args['openrc']
78         except KeyError:
79             return result_handler(consts.API_ERROR, 'openrc must be provided')
80
81         try:
82             environment_id = args['environment_id']
83         except KeyError:
84             return result_handler(consts.API_ERROR, 'environment_id must be provided')
85
86         try:
87             uuid.UUID(environment_id)
88         except ValueError:
89             return result_handler(consts.API_ERROR, 'invalid environment id')
90
91         LOG.info('writing openrc: %s', consts.OPENRC)
92         makedirs(consts.CONF_DIR)
93
94         lines = ['export {}={}\n'.format(k, v) for k, v in openrc_vars.items()]
95         LOG.debug('writing: %s', ''.join(lines))
96         with open(consts.OPENRC, 'w') as f:
97             f.writelines(lines)
98         LOG.info('writing openrc: Done')
99
100         LOG.info('source openrc: %s', consts.OPENRC)
101         try:
102             source_env(consts.OPENRC)
103         except Exception:
104             LOG.exception('source openrc failed')
105             return result_handler(consts.API_ERROR, 'source openrc failed')
106         LOG.info('source openrc: Done')
107
108         openrc_id = str(uuid.uuid4())
109         self._write_into_database(environment_id, openrc_id, openrc_vars)
110
111         LOG.info('writing ansible cloud conf')
112         try:
113             self._generate_ansible_conf_file(openrc_vars)
114         except Exception:
115             LOG.exception('write cloud conf failed')
116             return result_handler(consts.API_ERROR, 'genarate ansible conf failed')
117         LOG.info('finish writing ansible cloud conf')
118
119         return result_handler(consts.API_SUCCESS, {'openrc': openrc_vars, 'uuid': openrc_id})
120
121     def _write_into_database(self, environment_id, openrc_id, openrc_data):
122         LOG.info('writing openrc to database')
123         openrc_handler = V2OpenrcHandler()
124         openrc_init_data = {
125             'uuid': openrc_id,
126             'environment_id': environment_id,
127             'content': jsonutils.dumps(openrc_data)
128         }
129         openrc_handler.insert(openrc_init_data)
130
131         LOG.info('binding openrc to environment: %s', environment_id)
132         environment_handler = V2EnvironmentHandler()
133         environment_handler.update_attr(environment_id, {'openrc_id': openrc_id})
134
135     def _get_openrc_dict(self):
136         with open(consts.OPENRC) as f:
137             content = f.readlines()
138
139         result = {}
140         for line in content:
141             m = re.search(r'(\ .*)=(.*)', line)
142             if m:
143                 try:
144                     value = os.environ[m.group(1).strip()]
145                 except KeyError:
146                     pass
147                 else:
148                     result.update({m.group(1).strip(): value})
149
150         return result
151
152     def _generate_ansible_conf_file(self, openrc_data):
153         ansible_conf = {
154             'clouds': {
155                 'opnfv': {
156                     'auth': {
157                     }
158                 }
159             }
160         }
161         black_list = ['OS_IDENTITY_API_VERSION', 'OS_IMAGE_API_VERSION']
162
163         for k, v in openrc_data.items():
164             if k.startswith('OS') and k not in black_list:
165                 key = k[3:].lower()
166                 ansible_conf['clouds']['opnfv']['auth'][key] = v
167
168         try:
169             value = openrc_data['OS_IDENTITY_API_VERSION']
170         except KeyError:
171             pass
172         else:
173             ansible_conf['clouds']['opnfv']['identity_api_version'] = value
174
175         makedirs(consts.OPENSTACK_CONF_DIR)
176         with open(consts.CLOUDS_CONF, 'w') as f:
177             yaml.dump(ansible_conf, f, default_flow_style=False)
178
179
180 class V2Openrc(ApiResource):
181
182     def get(self, openrc_id):
183         try:
184             uuid.UUID(openrc_id)
185         except ValueError:
186             return result_handler(consts.API_ERROR, 'invalid openrc id')
187
188         LOG.info('Geting openrc: %s', openrc_id)
189         openrc_handler = V2OpenrcHandler()
190         try:
191             openrc = openrc_handler.get_by_uuid(openrc_id)
192         except ValueError:
193             return result_handler(consts.API_ERROR, 'no such openrc id')
194
195         LOG.info('load openrc content')
196         content = jsonutils.loads(openrc.content)
197
198         return result_handler(consts.API_ERROR, {'openrc': content})
199
200     def delete(self, openrc_id):
201         try:
202             uuid.UUID(openrc_id)
203         except ValueError:
204             return result_handler(consts.API_ERROR, 'invalid openrc id')
205
206         LOG.info('Geting openrc: %s', openrc_id)
207         openrc_handler = V2OpenrcHandler()
208         try:
209             openrc = openrc_handler.get_by_uuid(openrc_id)
210         except ValueError:
211             return result_handler(consts.API_ERROR, 'no such openrc id')
212
213         LOG.info('update openrc in environment')
214         environment_handler = V2EnvironmentHandler()
215         environment_handler.update_attr(openrc.environment_id, {'openrc_id': None})
216
217         openrc_handler.delete_by_uuid(openrc_id)
218
219         return result_handler(consts.API_SUCCESS, {'openrc': openrc_id})