blob: aa92c0b432430d2f7b2a76bbb1b6e887bd972d45 [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
19
Matthew Treinish4f30eb82014-01-07 21:04:49 +000020import httplib2
21
Matthew Treinish1f7b33d2013-10-21 18:07:02 +000022from tempest import clients
23from tempest import config
24
25
Sean Dague86bd8422013-12-20 09:56:44 -050026CONF = config.CONF
Matthew Treinish4f30eb82014-01-07 21:04:49 +000027RAW_HTTP = httplib2.Http()
Matthew Treinish1f7b33d2013-10-21 18:07:02 +000028
Matthew Treinish1f7b33d2013-10-21 18:07:02 +000029
Matthew Treinish99afd072013-10-22 18:03:06 +000030def verify_glance_api_versions(os):
31 # Check glance api versions
32 __, versions = os.image_client.get_versions()
33 if CONF.image_feature_enabled.api_v1 != ('v1.1' in versions or 'v1.0' in
34 versions):
Sean Dague6b447882013-12-02 11:09:58 -050035 print('Config option image api_v1 should be change to: %s' % (
36 not CONF.image_feature_enabled.api_v1))
Matthew Treinish99afd072013-10-22 18:03:06 +000037 if CONF.image_feature_enabled.api_v2 != ('v2.0' in versions):
Sean Dague6b447882013-12-02 11:09:58 -050038 print('Config option image api_v2 should be change to: %s' % (
39 not CONF.image_feature_enabled.api_v2))
Matthew Treinish99afd072013-10-22 18:03:06 +000040
41
Matthew Treinish4f30eb82014-01-07 21:04:49 +000042def verify_nova_api_versions(os):
Andrea Frittoli8bbdb162014-01-06 11:06:13 +000043 # Check nova api versions - only get base URL without PATH
44 os.servers_client.skip_path = True
Matthew Treinisha5080812014-02-11 15:49:04 +000045 # The nova base endpoint url includes the version but to get the versions
46 # list the unversioned endpoint is needed
47 v2_endpoint = os.servers_client.base_url
48 v2_endpoint_parts = v2_endpoint.split('/')
49 endpoint = v2_endpoint_parts[0] + '//' + v2_endpoint_parts[2]
50 __, body = RAW_HTTP.request(endpoint, 'GET')
Matthew Treinish4f30eb82014-01-07 21:04:49 +000051 body = json.loads(body)
Andrea Frittoli8bbdb162014-01-06 11:06:13 +000052 # Restore full base_url
53 os.servers_client.skip_path = False
Matthew Treinish4f30eb82014-01-07 21:04:49 +000054 versions = map(lambda x: x['id'], body['versions'])
55 if CONF.compute_feature_enabled.api_v3 != ('v3.0' in versions):
56 print('Config option compute api_v3 should be change to: %s' % (
57 not CONF.compute_feature_enabled.api_v3))
58
59
Matthew Treinish8b006d22014-01-07 15:37:20 +000060def get_extension_client(os, service):
61 extensions_client = {
62 'nova': os.extensions_client,
63 'nova_v3': os.extensions_v3_client,
64 'cinder': os.volumes_extension_client,
Matthew Treinish8c6706d2014-01-07 19:28:18 +000065 'neutron': os.network_client,
Matthew Treinishc0120ba2014-01-31 20:10:19 +000066 'swift': os.account_client,
Matthew Treinish8b006d22014-01-07 15:37:20 +000067 }
68 if service not in extensions_client:
69 print('No tempest extensions client for %s' % service)
70 exit(1)
71 return extensions_client[service]
72
73
74def get_enabled_extensions(service):
75 extensions_options = {
76 'nova': CONF.compute_feature_enabled.api_extensions,
77 'nova_v3': CONF.compute_feature_enabled.api_v3_extensions,
78 'cinder': CONF.volume_feature_enabled.api_extensions,
Matthew Treinish8c6706d2014-01-07 19:28:18 +000079 'neutron': CONF.network_feature_enabled.api_extensions,
Matthew Treinishc0120ba2014-01-31 20:10:19 +000080 'swift': CONF.object_storage_feature_enabled.discoverable_apis,
Matthew Treinish8b006d22014-01-07 15:37:20 +000081 }
82 if service not in extensions_options:
83 print('No supported extensions list option for %s' % service)
84 exit(1)
85 return extensions_options[service]
86
87
88def verify_extensions(os, service, results):
89 extensions_client = get_extension_client(os, service)
Matthew Treinish1f7b33d2013-10-21 18:07:02 +000090 __, resp = extensions_client.list_extensions()
Matthew Treinish8b006d22014-01-07 15:37:20 +000091 if isinstance(resp, dict):
Matthew Treinish8c6706d2014-01-07 19:28:18 +000092 # Neutron's extension 'name' field has is not a single word (it has
93 # spaces in the string) Since that can't be used for list option the
94 # api_extension option in the network-feature-enabled group uses alias
95 # instead of name.
96 if service == 'neutron':
97 extensions = map(lambda x: x['alias'], resp['extensions'])
Matthew Treinishc0120ba2014-01-31 20:10:19 +000098 elif service == 'swift':
99 # Remove Swift general information from extensions list
100 resp.pop('swift')
101 extensions = resp.keys()
Matthew Treinish8c6706d2014-01-07 19:28:18 +0000102 else:
103 extensions = map(lambda x: x['name'], resp['extensions'])
104
Matthew Treinish8b006d22014-01-07 15:37:20 +0000105 else:
106 extensions = map(lambda x: x['name'], resp)
107 if not results.get(service):
108 results[service] = {}
109 extensions_opt = get_enabled_extensions(service)
110 if extensions_opt[0] == 'all':
111 results[service]['extensions'] = 'all'
112 return results
113 # Verify that all configured extensions are actually enabled
114 for extension in extensions_opt:
115 results[service][extension] = extension in extensions
116 # Verify that there aren't additional extensions enabled that aren't
117 # specified in the config list
118 for extension in extensions:
119 if extension not in extensions_opt:
120 results[service][extension] = False
Matthew Treinish1f7b33d2013-10-21 18:07:02 +0000121 return results
122
123
124def display_results(results):
Matthew Treinish8b006d22014-01-07 15:37:20 +0000125 for service in results:
126 # If all extensions are specified as being enabled there is no way to
127 # verify this so we just assume this to be true
128 if results[service].get('extensions'):
129 continue
130 extension_list = get_enabled_extensions(service)
131 for extension in results[service]:
132 if not results[service][extension]:
133 if extension in extension_list:
134 print("%s extension: %s should not be included in the list"
135 " of enabled extensions" % (service, extension))
136 else:
137 print("%s extension: %s should be included in the list of "
138 "enabled extensions" % (service, extension))
Matthew Treinish1f7b33d2013-10-21 18:07:02 +0000139
140
Matthew Treinish221bd7f2014-02-07 21:16:09 +0000141def check_service_availability(os):
142 services = []
143 avail_services = []
144 codename_match = {
145 'volume': 'cinder',
146 'network': 'neutron',
147 'image': 'glance',
148 'object_storage': 'swift',
149 'compute': 'nova',
150 'orchestration': 'heat',
151 'metering': 'ceilometer',
152 'telemetry': 'ceilometer',
153 'data_processing': 'savanna',
154 'baremetal': 'ironic',
155 'identity': 'keystone'
156
157 }
158 # Get catalog list for endpoints to use for validation
159 __, endpoints = os.endpoints_client.list_endpoints()
160 for endpoint in endpoints:
161 __, service = os.service_client.get_service(endpoint['service_id'])
162 services.append(service['type'])
163 # Pull all catalog types from config file and compare against endpoint list
164 for cfgname in dir(CONF._config):
165 cfg = getattr(CONF, cfgname)
166 catalog_type = getattr(cfg, 'catalog_type', None)
167 if not catalog_type:
168 continue
169 else:
170 if cfgname == 'identity':
171 # Keystone is a required service for tempest
172 continue
173 if catalog_type not in services:
174 if getattr(CONF.service_available, codename_match[cfgname]):
175 print('Endpoint type %s not found either disable service '
176 '%s or fix the catalog_type in the config file' % (
177 catalog_type, codename_match[cfgname]))
178 else:
179 if not getattr(CONF.service_available,
180 codename_match[cfgname]):
181 print('Endpoint type %s is available, service %s should be'
182 ' set as available in the config file.' % (
183 catalog_type, codename_match[cfgname]))
184 else:
185 avail_services.append(codename_match[cfgname])
186 return avail_services
Matthew Treinishd44fe032014-01-31 20:07:24 +0000187
188
Matthew Treinish1f7b33d2013-10-21 18:07:02 +0000189def main(argv):
Matthew Treinish8b006d22014-01-07 15:37:20 +0000190 print('Running config verification...')
Matthew Treinish1f7b33d2013-10-21 18:07:02 +0000191 os = clients.ComputeAdminManager(interface='json')
Matthew Treinish221bd7f2014-02-07 21:16:09 +0000192 services = check_service_availability(os)
Matthew Treinish8b006d22014-01-07 15:37:20 +0000193 results = {}
Matthew Treinishc0120ba2014-01-31 20:10:19 +0000194 for service in ['nova', 'nova_v3', 'cinder', 'neutron', 'swift']:
Matthew Treinish221bd7f2014-02-07 21:16:09 +0000195 if service == 'nova_v3' and 'nova' not in services:
196 continue
197 elif service not in services:
Matthew Treinishd44fe032014-01-31 20:07:24 +0000198 continue
Matthew Treinish8b006d22014-01-07 15:37:20 +0000199 results = verify_extensions(os, service, results)
Matthew Treinish99afd072013-10-22 18:03:06 +0000200 verify_glance_api_versions(os)
Matthew Treinish4f30eb82014-01-07 21:04:49 +0000201 verify_nova_api_versions(os)
Matthew Treinish1f7b33d2013-10-21 18:07:02 +0000202 display_results(results)
203
204
205if __name__ == "__main__":
206 main(sys.argv)