blob: 1726beb07f58d60dea9b8f23d6df683cb72af9f8 [file] [log] [blame]
Matthew Treinish1f7b33d2013-10-21 18:07:02 +00001#!/usr/bin/env python
Matthew Treinish1f7b33d2013-10-21 18:07:02 +00002
3# Copyright 2013 IBM Corp.
4#
5# Licensed under the Apache License, Version 2.0 (the "License"); you may
6# not use this file except in compliance with the License. You may obtain
7# a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14# License for the specific language governing permissions and limitations
15# under the License.
16
Matthew Treinish4f30eb82014-01-07 21:04:49 +000017import json
Matthew Treinish1f7b33d2013-10-21 18:07:02 +000018import sys
Matthew Treinish864fe072014-03-02 03:47:26 +000019import urlparse
Matthew Treinish1f7b33d2013-10-21 18:07:02 +000020
Matthew Treinish4f30eb82014-01-07 21:04:49 +000021import httplib2
22
Matthew Treinish1f7b33d2013-10-21 18:07:02 +000023from tempest import clients
24from tempest import config
25
26
Sean Dague86bd8422013-12-20 09:56:44 -050027CONF = config.CONF
Matthew Treinish4f30eb82014-01-07 21:04:49 +000028RAW_HTTP = httplib2.Http()
Matthew Treinish1f7b33d2013-10-21 18:07:02 +000029
Matthew Treinish1f7b33d2013-10-21 18:07:02 +000030
Matthew Treinish99afd072013-10-22 18:03:06 +000031def verify_glance_api_versions(os):
32 # Check glance api versions
33 __, versions = os.image_client.get_versions()
34 if CONF.image_feature_enabled.api_v1 != ('v1.1' in versions or 'v1.0' in
35 versions):
Sean Dague6b447882013-12-02 11:09:58 -050036 print('Config option image api_v1 should be change to: %s' % (
37 not CONF.image_feature_enabled.api_v1))
Matthew Treinish99afd072013-10-22 18:03:06 +000038 if CONF.image_feature_enabled.api_v2 != ('v2.0' in versions):
Sean Dague6b447882013-12-02 11:09:58 -050039 print('Config option image api_v2 should be change to: %s' % (
40 not CONF.image_feature_enabled.api_v2))
Matthew Treinish99afd072013-10-22 18:03:06 +000041
42
Matthew Treinish864fe072014-03-02 03:47:26 +000043def _get_api_versions(os, service):
44 client_dict = {
45 'nova': os.servers_client,
46 'keystone': os.identity_client,
Matthew Treinish2e439632014-03-05 21:53:33 +000047 'cinder': os.volumes_client,
Matthew Treinish864fe072014-03-02 03:47:26 +000048 }
49 client_dict[service].skip_path()
Matthew Treinish1722f0b2014-04-11 20:09:17 +000050 endpoint_parts = urlparse.urlparse(client_dict[service].base_url)
51 endpoint = endpoint_parts.scheme + '://' + endpoint_parts.netloc
Matthew Treinisha5080812014-02-11 15:49:04 +000052 __, body = RAW_HTTP.request(endpoint, 'GET')
Matthew Treinish864fe072014-03-02 03:47:26 +000053 client_dict[service].reset_path()
Matthew Treinish4f30eb82014-01-07 21:04:49 +000054 body = json.loads(body)
Matthew Treinish864fe072014-03-02 03:47:26 +000055 if service == 'keystone':
56 versions = map(lambda x: x['id'], body['versions']['values'])
57 else:
58 versions = map(lambda x: x['id'], body['versions'])
59 return versions
60
61
62def verify_keystone_api_versions(os):
63 # Check keystone api versions
64 versions = _get_api_versions(os, 'keystone')
65 if CONF.identity_feature_enabled.api_v2 != ('v2.0' in versions):
66 print('Config option identity api_v2 should be change to %s' % (
67 not CONF.identity_feature_enabled.api_v2))
68 if CONF.identity_feature_enabled.api_v3 != ('v3.0' in versions):
69 print('Config option identity api_v3 should be change to %s' % (
70 not CONF.identity_feature_enabled.api_v3))
71
72
73def verify_nova_api_versions(os):
74 versions = _get_api_versions(os, 'nova')
Matthew Treinish4f30eb82014-01-07 21:04:49 +000075 if CONF.compute_feature_enabled.api_v3 != ('v3.0' in versions):
76 print('Config option compute api_v3 should be change to: %s' % (
77 not CONF.compute_feature_enabled.api_v3))
78
79
Matthew Treinish2e439632014-03-05 21:53:33 +000080def verify_cinder_api_versions(os):
81 # Check cinder api versions
82 versions = _get_api_versions(os, 'cinder')
83 if CONF.volume_feature_enabled.api_v1 != ('v1.0' in versions):
84 print('Config option volume api_v2 should be change to: %s' % (
85 not CONF.volume_feature_enabled.api_v1))
86 if CONF.volume_feature_enabled.api_v2 != ('v2.0' in versions):
87 print('Config option volume api_v2 should be change to: %s' % (
88 not CONF.volume_feature_enabled.api_v2))
89
90
Matthew Treinish8b006d22014-01-07 15:37:20 +000091def get_extension_client(os, service):
92 extensions_client = {
93 'nova': os.extensions_client,
94 'nova_v3': os.extensions_v3_client,
95 'cinder': os.volumes_extension_client,
Matthew Treinish8c6706d2014-01-07 19:28:18 +000096 'neutron': os.network_client,
Matthew Treinishc0120ba2014-01-31 20:10:19 +000097 'swift': os.account_client,
Matthew Treinish8b006d22014-01-07 15:37:20 +000098 }
99 if service not in extensions_client:
100 print('No tempest extensions client for %s' % service)
101 exit(1)
102 return extensions_client[service]
103
104
105def get_enabled_extensions(service):
106 extensions_options = {
107 'nova': CONF.compute_feature_enabled.api_extensions,
108 'nova_v3': CONF.compute_feature_enabled.api_v3_extensions,
109 'cinder': CONF.volume_feature_enabled.api_extensions,
Matthew Treinish8c6706d2014-01-07 19:28:18 +0000110 'neutron': CONF.network_feature_enabled.api_extensions,
Matthew Treinishc0120ba2014-01-31 20:10:19 +0000111 'swift': CONF.object_storage_feature_enabled.discoverable_apis,
Matthew Treinish8b006d22014-01-07 15:37:20 +0000112 }
113 if service not in extensions_options:
114 print('No supported extensions list option for %s' % service)
115 exit(1)
116 return extensions_options[service]
117
118
119def verify_extensions(os, service, results):
120 extensions_client = get_extension_client(os, service)
Matthew Treinish1f7b33d2013-10-21 18:07:02 +0000121 __, resp = extensions_client.list_extensions()
Matthew Treinish8b006d22014-01-07 15:37:20 +0000122 if isinstance(resp, dict):
Matthew Treinish8c6706d2014-01-07 19:28:18 +0000123 # Neutron's extension 'name' field has is not a single word (it has
124 # spaces in the string) Since that can't be used for list option the
125 # api_extension option in the network-feature-enabled group uses alias
126 # instead of name.
127 if service == 'neutron':
128 extensions = map(lambda x: x['alias'], resp['extensions'])
Matthew Treinishc0120ba2014-01-31 20:10:19 +0000129 elif service == 'swift':
130 # Remove Swift general information from extensions list
131 resp.pop('swift')
132 extensions = resp.keys()
Matthew Treinish8c6706d2014-01-07 19:28:18 +0000133 else:
134 extensions = map(lambda x: x['name'], resp['extensions'])
135
Matthew Treinish8b006d22014-01-07 15:37:20 +0000136 else:
137 extensions = map(lambda x: x['name'], resp)
138 if not results.get(service):
139 results[service] = {}
140 extensions_opt = get_enabled_extensions(service)
141 if extensions_opt[0] == 'all':
142 results[service]['extensions'] = 'all'
143 return results
144 # Verify that all configured extensions are actually enabled
145 for extension in extensions_opt:
146 results[service][extension] = extension in extensions
147 # Verify that there aren't additional extensions enabled that aren't
148 # specified in the config list
149 for extension in extensions:
150 if extension not in extensions_opt:
151 results[service][extension] = False
Matthew Treinish1f7b33d2013-10-21 18:07:02 +0000152 return results
153
154
155def display_results(results):
Matthew Treinish8b006d22014-01-07 15:37:20 +0000156 for service in results:
157 # If all extensions are specified as being enabled there is no way to
158 # verify this so we just assume this to be true
159 if results[service].get('extensions'):
160 continue
161 extension_list = get_enabled_extensions(service)
162 for extension in results[service]:
163 if not results[service][extension]:
164 if extension in extension_list:
165 print("%s extension: %s should not be included in the list"
166 " of enabled extensions" % (service, extension))
167 else:
168 print("%s extension: %s should be included in the list of "
169 "enabled extensions" % (service, extension))
Matthew Treinish1f7b33d2013-10-21 18:07:02 +0000170
171
Matthew Treinish221bd7f2014-02-07 21:16:09 +0000172def check_service_availability(os):
173 services = []
174 avail_services = []
175 codename_match = {
176 'volume': 'cinder',
177 'network': 'neutron',
178 'image': 'glance',
179 'object_storage': 'swift',
180 'compute': 'nova',
181 'orchestration': 'heat',
182 'metering': 'ceilometer',
183 'telemetry': 'ceilometer',
Matthew Treinish42d50f62014-04-11 19:47:13 +0000184 'data_processing': 'sahara',
Matthew Treinish221bd7f2014-02-07 21:16:09 +0000185 'baremetal': 'ironic',
Matthew Treinish42d50f62014-04-11 19:47:13 +0000186 'identity': 'keystone',
187 'queuing': 'marconi',
188 'database': 'trove'
Matthew Treinish221bd7f2014-02-07 21:16:09 +0000189 }
190 # Get catalog list for endpoints to use for validation
191 __, endpoints = os.endpoints_client.list_endpoints()
192 for endpoint in endpoints:
193 __, service = os.service_client.get_service(endpoint['service_id'])
194 services.append(service['type'])
195 # Pull all catalog types from config file and compare against endpoint list
196 for cfgname in dir(CONF._config):
197 cfg = getattr(CONF, cfgname)
198 catalog_type = getattr(cfg, 'catalog_type', None)
199 if not catalog_type:
200 continue
201 else:
202 if cfgname == 'identity':
203 # Keystone is a required service for tempest
204 continue
205 if catalog_type not in services:
206 if getattr(CONF.service_available, codename_match[cfgname]):
207 print('Endpoint type %s not found either disable service '
208 '%s or fix the catalog_type in the config file' % (
209 catalog_type, codename_match[cfgname]))
210 else:
211 if not getattr(CONF.service_available,
212 codename_match[cfgname]):
213 print('Endpoint type %s is available, service %s should be'
214 ' set as available in the config file.' % (
215 catalog_type, codename_match[cfgname]))
216 else:
217 avail_services.append(codename_match[cfgname])
218 return avail_services
Matthew Treinishd44fe032014-01-31 20:07:24 +0000219
220
Matthew Treinish1f7b33d2013-10-21 18:07:02 +0000221def main(argv):
Matthew Treinish8b006d22014-01-07 15:37:20 +0000222 print('Running config verification...')
Matthew Treinish1f7b33d2013-10-21 18:07:02 +0000223 os = clients.ComputeAdminManager(interface='json')
Matthew Treinish221bd7f2014-02-07 21:16:09 +0000224 services = check_service_availability(os)
Matthew Treinish8b006d22014-01-07 15:37:20 +0000225 results = {}
Matthew Treinishc0120ba2014-01-31 20:10:19 +0000226 for service in ['nova', 'nova_v3', 'cinder', 'neutron', 'swift']:
Matthew Treinish221bd7f2014-02-07 21:16:09 +0000227 if service == 'nova_v3' and 'nova' not in services:
228 continue
229 elif service not in services:
Matthew Treinishd44fe032014-01-31 20:07:24 +0000230 continue
Matthew Treinish8b006d22014-01-07 15:37:20 +0000231 results = verify_extensions(os, service, results)
Matthew Treinish864fe072014-03-02 03:47:26 +0000232 verify_keystone_api_versions(os)
Matthew Treinish99afd072013-10-22 18:03:06 +0000233 verify_glance_api_versions(os)
Matthew Treinish4f30eb82014-01-07 21:04:49 +0000234 verify_nova_api_versions(os)
Matthew Treinish2e439632014-03-05 21:53:33 +0000235 verify_cinder_api_versions(os)
Matthew Treinish1f7b33d2013-10-21 18:07:02 +0000236 display_results(results)
237
238
239if __name__ == "__main__":
240 main(sys.argv)