from ostack_validator.common import Inspection, Issue, find KEYSTONE_AUTHTOKEN_FILTER_FACTORY = 'keystoneclient.middleware.auth_token:filter_factory' class KeystoneAuthtokenSettingsInspection(Inspection): name = 'Keystone auth' description = 'Validate correctness of keystone settings' def inspect(self, openstack): components = [] for host in openstack.hosts: components.extend(host.components) keystones = [c for c in components if c.name == 'keystone'] if len(keystones) == 0: openstack.report_issue( Issue(Issue.FATAL, 'No keystone service found')) return keystone = keystones[0] keystone_addresses = [keystone.config['bind_host']] if keystone_addresses == ['0.0.0.0']: keystone_addresses = keystone.host.network_addresses for nova in [c for c in components if c.name == 'nova-api']: if nova.config['auth_strategy'] != 'keystone': continue (authtoken_section, _) = find( nova.paste_config.items(), lambda name_values: name_values[0].startswith('filter:') and name_values[ 1].get('paste.filter_factory') == KEYSTONE_AUTHTOKEN_FILTER_FACTORY ) if not authtoken_section: continue authtoken_settings = nova.paste_config.section(authtoken_section) def get_value(name): return ( authtoken_settings[ name] or nova.config[ 'keystone_authtoken.%s' % name] ) auth_host = get_value('auth_host') auth_port = get_value('auth_port') auth_protocol = get_value('auth_protocol') admin_user = get_value('admin_user') admin_password = get_value('admin_password') admin_tenant_name = get_value('admin_tenant_name') admin_token = get_value('admin_token') msg_prefix = 'Service "%s" on host "%s"' % ( nova.name, nova.host.name) if not auth_host: nova.report_issue( Issue( Issue.ERROR, msg_prefix + ' miss "auth_host" setting in keystone authtoken config')) elif not auth_host in keystone_addresses: nova.report_issue( Issue( Issue.ERROR, msg_prefix + ' has incorrect "auth_host" setting in keystone authtoken config')) if not auth_port: nova.report_issue( Issue( Issue.ERROR, msg_prefix + ' miss "auth_port" setting in keystone authtoken config')) elif auth_port != keystone.config['admin_port']: nova.report_issue( Issue( Issue.ERROR, msg_prefix + ' has incorrect "auth_port" setting in keystone authtoken config')) if not auth_protocol: nova.report_issue( Issue( Issue.ERROR, msg_prefix + ' miss "auth_protocol" setting in keystone authtoken config')) elif not auth_protocol in ['http', 'https']: nova.report_issue( Issue( Issue.ERROR, msg_prefix + ' has incorrect "auth_protocol" setting in keystone authtoken config')) if not admin_user: nova.report_issue( Issue( Issue.ERROR, msg_prefix + ' miss "admin_user" setting in keystone authtoken config')) else: user = find( keystone.db['users'], lambda u: u['name'] == admin_user) if not user: nova.report_issue( Issue( Issue.ERROR, msg_prefix + ' has "admin_user" that is missing in Keystone catalog')) if not admin_tenant_name: nova.report_issue( Issue( Issue.ERROR, msg_prefix + ' miss "admin_tenant_name" setting in keystone authtoken config')) else: tenant = find( keystone.db['tenants'], lambda t: t['name'] == admin_tenant_name) if not tenant: nova.report_issue( Issue( Issue.ERROR, msg_prefix + ' has "admin_tenant_name" that is missing in Keystone catalog')) if admin_token: nova.report_issue( Issue( Issue.WARNING, msg_prefix + ' uses insecure admin_token for authentication'))