Add support for updating the config file

This commit adds a new flag to the verify_tempest_config.py script,
'-u' that will update the config file from values found during the
verification process.

Partially implements bp config-verification

Change-Id: I20b8bca7d3368b56da0a0496ed7aa3c1a6eacc9e
This commit is contained in:
Matthew Treinish 2014-04-11 20:08:53 +00:00 committed by Matthew Treinish
parent e3a663bca1
commit f09717137a
1 changed files with 142 additions and 36 deletions

View File

@ -14,11 +14,14 @@
# License for the specific language governing permissions and limitations
# under the License.
import argparse
import json
import os
import sys
import urlparse
import httplib2
from six.moves import configparser
from tempest import clients
from tempest import config
@ -26,18 +29,50 @@ from tempest import config
CONF = config.CONF
RAW_HTTP = httplib2.Http()
CONF_FILE = None
OUTFILE = sys.stdout
def verify_glance_api_versions(os):
def _get_config_file():
default_config_dir = os.path.join(os.path.abspath(
os.path.dirname(os.path.dirname(__file__))), "etc")
default_config_file = "tempest.conf"
conf_dir = os.environ.get('TEMPEST_CONFIG_DIR', default_config_dir)
conf_file = os.environ.get('TEMPEST_CONFIG', default_config_file)
path = os.path.join(conf_dir, conf_file)
fd = open(path, 'rw')
return fd
def change_option(option, group, value):
config_parse = configparser.SafeConfigParser()
config_parse.optionxform = str
config_parse.readfp(CONF_FILE)
if not config_parse.has_section(group):
config_parse.add_section(group)
config_parse.set(group, option, str(value))
global OUTFILE
config_parse.write(OUTFILE)
def print_and_or_update(option, group, value, update):
print('Config option %s in group %s should be changed to: %s'
% (option, group, value))
if update:
change_option(option, group, value)
def verify_glance_api_versions(os, update):
# Check glance api versions
__, versions = os.image_client.get_versions()
if CONF.image_feature_enabled.api_v1 != ('v1.1' in versions or 'v1.0' in
versions):
print('Config option image api_v1 should be change to: %s' % (
not CONF.image_feature_enabled.api_v1))
print_and_or_update('api_v1', 'image_feature_enabled',
not CONF.image_feature_enabled.api_v1, update)
if CONF.image_feature_enabled.api_v2 != ('v2.0' in versions):
print('Config option image api_v2 should be change to: %s' % (
not CONF.image_feature_enabled.api_v2))
print_and_or_update('api_v2', 'image_feature_enabled',
not CONF.image_feature_enabled.api_v2, update)
def _get_api_versions(os, service):
@ -59,33 +94,33 @@ def _get_api_versions(os, service):
return versions
def verify_keystone_api_versions(os):
def verify_keystone_api_versions(os, update):
# Check keystone api versions
versions = _get_api_versions(os, 'keystone')
if CONF.identity_feature_enabled.api_v2 != ('v2.0' in versions):
print('Config option identity api_v2 should be change to %s' % (
not CONF.identity_feature_enabled.api_v2))
print_and_or_update('api_v2', 'identity_feature_enabled',
not CONF.identity_feature_enabled.api_v2, update)
if CONF.identity_feature_enabled.api_v3 != ('v3.0' in versions):
print('Config option identity api_v3 should be change to %s' % (
not CONF.identity_feature_enabled.api_v3))
print_and_or_update('api_v3', 'identity_feature_enabled',
not CONF.identity_feature_enabled.api_v3, update)
def verify_nova_api_versions(os):
def verify_nova_api_versions(os, update):
versions = _get_api_versions(os, 'nova')
if CONF.compute_feature_enabled.api_v3 != ('v3.0' in versions):
print('Config option compute api_v3 should be change to: %s' % (
not CONF.compute_feature_enabled.api_v3))
print_and_or_update('api_v3', 'compute_feature_enabled',
not CONF.compute_feature_enabled.api_v3, update)
def verify_cinder_api_versions(os):
def verify_cinder_api_versions(os, update):
# Check cinder api versions
versions = _get_api_versions(os, 'cinder')
if CONF.volume_feature_enabled.api_v1 != ('v1.0' in versions):
print('Config option volume api_v2 should be change to: %s' % (
not CONF.volume_feature_enabled.api_v1))
print_and_or_update('api_v1', 'volume_feature_enabled',
not CONF.volume_feature_enabled.api_v1, update)
if CONF.volume_feature_enabled.api_v2 != ('v2.0' in versions):
print('Config option volume api_v2 should be change to: %s' % (
not CONF.volume_feature_enabled.api_v2))
print_and_or_update('api_v2', 'volume_feature_enabled',
not CONF.volume_feature_enabled.api_v2, update)
def get_extension_client(os, service):
@ -139,7 +174,7 @@ def verify_extensions(os, service, results):
results[service] = {}
extensions_opt = get_enabled_extensions(service)
if extensions_opt[0] == 'all':
results[service]['extensions'] = 'all'
results[service]['extensions'] = extensions
return results
# Verify that all configured extensions are actually enabled
for extension in extensions_opt:
@ -152,24 +187,54 @@ def verify_extensions(os, service, results):
return results
def display_results(results):
def display_results(results, update, replace):
update_dict = {
'swift': 'object-storage-feature-enabled',
'nova': 'compute-feature-enabled',
'nova_v3': 'compute-feature-enabled',
'cinder': 'volume-feature-enabled',
'neutron': 'network-feature-enabled',
}
for service in results:
# If all extensions are specified as being enabled there is no way to
# verify this so we just assume this to be true
if results[service].get('extensions'):
continue
extension_list = get_enabled_extensions(service)
for extension in results[service]:
if not results[service][extension]:
if extension in extension_list:
print("%s extension: %s should not be included in the list"
" of enabled extensions" % (service, extension))
if replace:
output_list = results[service].get('extensions')
else:
output_list = ['all']
else:
extension_list = get_enabled_extensions(service)
output_list = []
for extension in results[service]:
if not results[service][extension]:
if extension in extension_list:
print("%s extension: %s should not be included in the "
"list of enabled extensions" % (service,
extension))
else:
print("%s extension: %s should be included in the list"
" of enabled extensions" % (service, extension))
output_list.append(extension)
else:
print("%s extension: %s should be included in the list of "
"enabled extensions" % (service, extension))
output_list.append(extension)
if update:
# Sort List
output_list.sort()
# Convert list to a string
output_string = ', '.join(output_list)
if service == 'swift':
change_option('discoverable_apis', update_dict[service],
output_string)
elif service == 'nova_v3':
change_option('api_v3_extensions', update_dict[service],
output_string)
else:
change_option('api_extensions', update_dict[service],
output_string)
def check_service_availability(os):
def check_service_availability(os, update):
services = []
avail_services = []
codename_match = {
@ -207,21 +272,59 @@ def check_service_availability(os):
print('Endpoint type %s not found either disable service '
'%s or fix the catalog_type in the config file' % (
catalog_type, codename_match[cfgname]))
if update:
change_option(codename_match[cfgname],
'service_available', False)
else:
if not getattr(CONF.service_available,
codename_match[cfgname]):
print('Endpoint type %s is available, service %s should be'
' set as available in the config file.' % (
catalog_type, codename_match[cfgname]))
if update:
change_option(codename_match[cfgname],
'service_available', True)
else:
avail_services.append(codename_match[cfgname])
return avail_services
def parse_args():
parser = argparse.ArgumentParser()
parser.add_argument('-u', '--update', action='store_true',
help='Update the config file with results from api '
'queries. This assumes whatever is set in the '
'config file is incorrect. In the case of '
'endpoint checks where it could either be the '
'incorrect catalog type or the service available '
'option the service available option is assumed '
'to be incorrect and is thus changed')
parser.add_argument('-o', '--output',
help="Output file to write an updated config file to. "
"This has to be a separate file from the "
"original config file. If one isn't specified "
"with -u the new config file will be printed to "
"STDOUT")
parser.add_argument('-r', '--replace-ext', action='store_true',
help="If specified the all option will be replaced "
"with a full list of extensions")
args = parser.parse_args()
return args
def main(argv):
print('Running config verification...')
opts = parse_args()
update = opts.update
replace = opts.replace_ext
global CONF_FILE
global OUTFILE
if update:
CONF_FILE = _get_config_file()
if opts.output:
OUTFILE = open(opts.output, 'w+')
os = clients.ComputeAdminManager(interface='json')
services = check_service_availability(os)
services = check_service_availability(os, update)
results = {}
for service in ['nova', 'nova_v3', 'cinder', 'neutron', 'swift']:
if service == 'nova_v3' and 'nova' not in services:
@ -229,11 +332,14 @@ def main(argv):
elif service not in services:
continue
results = verify_extensions(os, service, results)
verify_keystone_api_versions(os)
verify_glance_api_versions(os)
verify_nova_api_versions(os)
verify_cinder_api_versions(os)
display_results(results)
verify_keystone_api_versions(os, update)
verify_glance_api_versions(os, update)
verify_nova_api_versions(os, update)
verify_cinder_api_versions(os, update)
display_results(results, update, replace)
if CONF_FILE:
CONF_FILE.close()
OUTFILE.close()
if __name__ == "__main__":