blob: 30785c4d4f36f7451c8dfd6c781f6f597e7c43f3 [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,
47 }
48 client_dict[service].skip_path()
49 endpoint_parts = urlparse.urlparse(client_dict[service])
50 endpoint = endpoint_parts.scheme + '//' + endpoint_parts.netloc
Matthew Treinisha5080812014-02-11 15:49:04 +000051 __, body = RAW_HTTP.request(endpoint, 'GET')
Matthew Treinish864fe072014-03-02 03:47:26 +000052 client_dict[service].reset_path()
Matthew Treinish4f30eb82014-01-07 21:04:49 +000053 body = json.loads(body)
Matthew Treinish864fe072014-03-02 03:47:26 +000054 if service == 'keystone':
55 versions = map(lambda x: x['id'], body['versions']['values'])
56 else:
57 versions = map(lambda x: x['id'], body['versions'])
58 return versions
59
60
61def verify_keystone_api_versions(os):
62 # Check keystone api versions
63 versions = _get_api_versions(os, 'keystone')
64 if CONF.identity_feature_enabled.api_v2 != ('v2.0' in versions):
65 print('Config option identity api_v2 should be change to %s' % (
66 not CONF.identity_feature_enabled.api_v2))
67 if CONF.identity_feature_enabled.api_v3 != ('v3.0' in versions):
68 print('Config option identity api_v3 should be change to %s' % (
69 not CONF.identity_feature_enabled.api_v3))
70
71
72def verify_nova_api_versions(os):
73 versions = _get_api_versions(os, 'nova')
Matthew Treinish4f30eb82014-01-07 21:04:49 +000074 if CONF.compute_feature_enabled.api_v3 != ('v3.0' in versions):
75 print('Config option compute api_v3 should be change to: %s' % (
76 not CONF.compute_feature_enabled.api_v3))
77
78
Matthew Treinish8b006d22014-01-07 15:37:20 +000079def get_extension_client(os, service):
80 extensions_client = {
81 'nova': os.extensions_client,
82 'nova_v3': os.extensions_v3_client,
83 'cinder': os.volumes_extension_client,
Matthew Treinish8c6706d2014-01-07 19:28:18 +000084 'neutron': os.network_client,
Matthew Treinishc0120ba2014-01-31 20:10:19 +000085 'swift': os.account_client,
Matthew Treinish8b006d22014-01-07 15:37:20 +000086 }
87 if service not in extensions_client:
88 print('No tempest extensions client for %s' % service)
89 exit(1)
90 return extensions_client[service]
91
92
93def get_enabled_extensions(service):
94 extensions_options = {
95 'nova': CONF.compute_feature_enabled.api_extensions,
96 'nova_v3': CONF.compute_feature_enabled.api_v3_extensions,
97 'cinder': CONF.volume_feature_enabled.api_extensions,
Matthew Treinish8c6706d2014-01-07 19:28:18 +000098 'neutron': CONF.network_feature_enabled.api_extensions,
Matthew Treinishc0120ba2014-01-31 20:10:19 +000099 'swift': CONF.object_storage_feature_enabled.discoverable_apis,
Matthew Treinish8b006d22014-01-07 15:37:20 +0000100 }
101 if service not in extensions_options:
102 print('No supported extensions list option for %s' % service)
103 exit(1)
104 return extensions_options[service]
105
106
107def verify_extensions(os, service, results):
108 extensions_client = get_extension_client(os, service)
Matthew Treinish1f7b33d2013-10-21 18:07:02 +0000109 __, resp = extensions_client.list_extensions()
Matthew Treinish8b006d22014-01-07 15:37:20 +0000110 if isinstance(resp, dict):
Matthew Treinish8c6706d2014-01-07 19:28:18 +0000111 # Neutron's extension 'name' field has is not a single word (it has
112 # spaces in the string) Since that can't be used for list option the
113 # api_extension option in the network-feature-enabled group uses alias
114 # instead of name.
115 if service == 'neutron':
116 extensions = map(lambda x: x['alias'], resp['extensions'])
Matthew Treinishc0120ba2014-01-31 20:10:19 +0000117 elif service == 'swift':
118 # Remove Swift general information from extensions list
119 resp.pop('swift')
120 extensions = resp.keys()
Matthew Treinish8c6706d2014-01-07 19:28:18 +0000121 else:
122 extensions = map(lambda x: x['name'], resp['extensions'])
123
Matthew Treinish8b006d22014-01-07 15:37:20 +0000124 else:
125 extensions = map(lambda x: x['name'], resp)
126 if not results.get(service):
127 results[service] = {}
128 extensions_opt = get_enabled_extensions(service)
129 if extensions_opt[0] == 'all':
130 results[service]['extensions'] = 'all'
131 return results
132 # Verify that all configured extensions are actually enabled
133 for extension in extensions_opt:
134 results[service][extension] = extension in extensions
135 # Verify that there aren't additional extensions enabled that aren't
136 # specified in the config list
137 for extension in extensions:
138 if extension not in extensions_opt:
139 results[service][extension] = False
Matthew Treinish1f7b33d2013-10-21 18:07:02 +0000140 return results
141
142
143def display_results(results):
Matthew Treinish8b006d22014-01-07 15:37:20 +0000144 for service in results:
145 # If all extensions are specified as being enabled there is no way to
146 # verify this so we just assume this to be true
147 if results[service].get('extensions'):
148 continue
149 extension_list = get_enabled_extensions(service)
150 for extension in results[service]:
151 if not results[service][extension]:
152 if extension in extension_list:
153 print("%s extension: %s should not be included in the list"
154 " of enabled extensions" % (service, extension))
155 else:
156 print("%s extension: %s should be included in the list of "
157 "enabled extensions" % (service, extension))
Matthew Treinish1f7b33d2013-10-21 18:07:02 +0000158
159
Matthew Treinish221bd7f2014-02-07 21:16:09 +0000160def check_service_availability(os):
161 services = []
162 avail_services = []
163 codename_match = {
164 'volume': 'cinder',
165 'network': 'neutron',
166 'image': 'glance',
167 'object_storage': 'swift',
168 'compute': 'nova',
169 'orchestration': 'heat',
170 'metering': 'ceilometer',
171 'telemetry': 'ceilometer',
172 'data_processing': 'savanna',
173 'baremetal': 'ironic',
174 'identity': 'keystone'
175
176 }
177 # Get catalog list for endpoints to use for validation
178 __, endpoints = os.endpoints_client.list_endpoints()
179 for endpoint in endpoints:
180 __, service = os.service_client.get_service(endpoint['service_id'])
181 services.append(service['type'])
182 # Pull all catalog types from config file and compare against endpoint list
183 for cfgname in dir(CONF._config):
184 cfg = getattr(CONF, cfgname)
185 catalog_type = getattr(cfg, 'catalog_type', None)
186 if not catalog_type:
187 continue
188 else:
189 if cfgname == 'identity':
190 # Keystone is a required service for tempest
191 continue
192 if catalog_type not in services:
193 if getattr(CONF.service_available, codename_match[cfgname]):
194 print('Endpoint type %s not found either disable service '
195 '%s or fix the catalog_type in the config file' % (
196 catalog_type, codename_match[cfgname]))
197 else:
198 if not getattr(CONF.service_available,
199 codename_match[cfgname]):
200 print('Endpoint type %s is available, service %s should be'
201 ' set as available in the config file.' % (
202 catalog_type, codename_match[cfgname]))
203 else:
204 avail_services.append(codename_match[cfgname])
205 return avail_services
Matthew Treinishd44fe032014-01-31 20:07:24 +0000206
207
Matthew Treinish1f7b33d2013-10-21 18:07:02 +0000208def main(argv):
Matthew Treinish8b006d22014-01-07 15:37:20 +0000209 print('Running config verification...')
Matthew Treinish1f7b33d2013-10-21 18:07:02 +0000210 os = clients.ComputeAdminManager(interface='json')
Matthew Treinish221bd7f2014-02-07 21:16:09 +0000211 services = check_service_availability(os)
Matthew Treinish8b006d22014-01-07 15:37:20 +0000212 results = {}
Matthew Treinishc0120ba2014-01-31 20:10:19 +0000213 for service in ['nova', 'nova_v3', 'cinder', 'neutron', 'swift']:
Matthew Treinish221bd7f2014-02-07 21:16:09 +0000214 if service == 'nova_v3' and 'nova' not in services:
215 continue
216 elif service not in services:
Matthew Treinishd44fe032014-01-31 20:07:24 +0000217 continue
Matthew Treinish8b006d22014-01-07 15:37:20 +0000218 results = verify_extensions(os, service, results)
Matthew Treinish864fe072014-03-02 03:47:26 +0000219 verify_keystone_api_versions(os)
Matthew Treinish99afd072013-10-22 18:03:06 +0000220 verify_glance_api_versions(os)
Matthew Treinish4f30eb82014-01-07 21:04:49 +0000221 verify_nova_api_versions(os)
Matthew Treinish1f7b33d2013-10-21 18:07:02 +0000222 display_results(results)
223
224
225if __name__ == "__main__":
226 main(sys.argv)