diff --git a/ostack_validator/discovery.py b/ostack_validator/discovery.py index a42e75c..5b8a89d 100644 --- a/ostack_validator/discovery.py +++ b/ostack_validator/discovery.py @@ -202,7 +202,8 @@ class OpenstackDiscovery(object): keystone = KeystoneComponent() keystone.version = self._find_python_package_version(client, 'keystone') - keystone.config_file = self._collect_file(client, config_path) + keystone.config_files = [] + keystone.config_files.append(self._collect_file(client, config_path)) token = keystone.config['admin_token'] host = keystone.config['bind_host'] @@ -236,7 +237,8 @@ class OpenstackDiscovery(object): nova_api = NovaApiComponent() nova_api.version = self._find_python_package_version(client, 'nova') - nova_api.config_file = self._collect_file(client, config_path) + nova_api.config_files = [] + nova_api.config_files.append(self._collect_file(client, config_path)) paste_config_path = path_relative_to(nova_api.config['api_paste_config'], os.path.dirname(config_path)) nova_api.paste_config_file = self._collect_file(client, paste_config_path) @@ -256,7 +258,8 @@ class OpenstackDiscovery(object): nova_compute = NovaComputeComponent() nova_compute.version = self._find_python_package_version(client, 'nova') - nova_compute.config_file = self._collect_file(client, config_path) + nova_compute.config_files = [] + nova_compute.config_files.append(self._collect_file(client, config_path)) return nova_compute @@ -273,7 +276,8 @@ class OpenstackDiscovery(object): nova_scheduler = NovaSchedulerComponent() nova_scheduler.version = self._find_python_package_version(client, 'nova') - nova_scheduler.config_file = self._collect_file(client, config_path) + nova_scheduler.config_files = [] + nova_scheduler.config_files.append(self._collect_file(client, config_path)) return nova_scheduler @@ -290,7 +294,8 @@ class OpenstackDiscovery(object): glance_api = GlanceApiComponent() glance_api.version = self._find_python_package_version(client, 'glance') - glance_api.config_file = self._collect_file(client, config_path) + glance_api.config_files = [] + glance_api.config_files.append(self._collect_file(client, config_path)) return glance_api @@ -307,7 +312,8 @@ class OpenstackDiscovery(object): glance_registry = GlanceRegistryComponent() glance_registry.version = self._find_python_package_version(client, 'glance') - glance_registry.config_file = self._collect_file(client, config_path) + glance_registry.config_files = [] + glance_registry.config_files.append(self._collect_file(client, config_path)) return glance_registry @@ -324,7 +330,8 @@ class OpenstackDiscovery(object): cinder_api = CinderApiComponent() cinder_api.version = self._find_python_package_version(client, 'cinder') - cinder_api.config_file = self._collect_file(client, config_path) + cinder_api.config_files = [] + cinder_api.config_files.append(self._collect_file(client, config_path)) paste_config_path = path_relative_to(cinder_api.config['api_paste_config'], os.path.dirname(config_path)) cinder_api.paste_config_file = self._collect_file(client, paste_config_path) @@ -344,7 +351,8 @@ class OpenstackDiscovery(object): cinder_volume = CinderVolumeComponent() cinder_volume.version = self._find_python_package_version(client, 'cinder') - cinder_volume.config_file = self._collect_file(client, config_path) + cinder_volume.config_files = [] + cinder_volume.config_files.append(self._collect_file(client, config_path)) rootwrap_config_path = path_relative_to(cinder_volume.config['rootwrap_config'], os.path.dirname(config_path)) cinder_volume.rootwrap_config = self._collect_file(client, rootwrap_config_path) @@ -364,7 +372,8 @@ class OpenstackDiscovery(object): cinder_scheduler = CinderSchedulerComponent() cinder_scheduler.version = self._find_python_package_version(client, 'cinder') - cinder_scheduler.config_file = self._collect_file(client, config_path) + cinder_scheduler.config_files = [] + cinder_scheduler.config_files.append(self._collect_file(client, config_path)) return cinder_scheduler diff --git a/ostack_validator/model.py b/ostack_validator/model.py index 3506175..01cd574 100644 --- a/ostack_validator/model.py +++ b/ostack_validator/model.py @@ -101,8 +101,8 @@ class Service(IssueReporter): def all_issues(self): result = super(Service, self).all_issues - if hasattr(self, 'config_file') and self.config_file: - result.extend(self.config_file.all_issues) + if hasattr(self, 'config_files') and self.config_files: + [result.extend(config_file.all_issues) for config_file in self.config_files] return result @@ -122,30 +122,32 @@ class OpenstackComponent(Service): self.logger.debug('No schema for component "%s" main config version %s. Skipping it' % (self.component, self.version)) return None - return self._parse_config_resource(self.config_file, schema) + return self._parse_config_resources(self.config_files, schema) - def _parse_config_resource(self, resource, schema=None): - return self._parse_config_file(Mark(resource.path), resource.contents, schema, issue_reporter=resource) + def _parse_config_resources(self, resources, schema=None): + config = Configuration() - def _parse_config_file(self, base_mark, config_contents, schema=None, issue_reporter=None): + # Apply defaults + if schema: + for parameter in filter(lambda p: p.default, schema.parameters): + if parameter.section == 'DEFAULT': + config.set_default(parameter.name, parameter.default) + else: + config.set_default('%s.%s' % (parameter.section, parameter.name), parameter.default) + + for resource in reversed(resources): + self._parse_config_file(Mark(resource.path), resource.contents, config, schema, issue_reporter=resource) + + return config + + def _parse_config_file(self, base_mark, config_contents, config=Configuration(), schema=None, issue_reporter=None): if issue_reporter: def report_issue(issue): issue_reporter.report_issue(issue) else: def report_issue(issue): pass - _config = Configuration() - - # Apply defaults - if schema: - for parameter in filter(lambda p: p.default, schema.parameters): - if parameter.section == 'DEFAULT': - _config.set_default(parameter.name, parameter.default) - else: - _config.set_default('%s.%s' % (parameter.section, parameter.name), parameter.default) - # Parse config file - config_parser = IniConfigParser() parsed_config = config_parser.parse('', base_mark, config_contents) for error in parsed_config.errors: @@ -197,19 +199,20 @@ class OpenstackComponent(Service): type_validation_result.message = 'Property "%s" in section "%s": %s' % (parameter.name.text, section_name, type_validation_result.message) report_issue(type_validation_result) + config.set(parameter_fullname, parameter.value.text) else: value = type_validation_result - _config.set(parameter_fullname, value) + config.set(parameter_fullname, value) # if value == parameter_schema.default: # report_issue(MarkedIssue(Issue.INFO, 'Explicit value equals default: section "%s" parameter "%s"' % (section_name, parameter.name.text), parameter.start_mark)) if parameter_schema.deprecation_message: report_issue(MarkedIssue(Issue.WARNING, 'Deprecated parameter: section "%s" name "%s". %s' % (section_name, parameter.name.text, parameter_schema.deprecation_message), parameter.start_mark)) else: - _config.set(parameter_fullname, parameter.value.text) + config.set(parameter_fullname, parameter.value.text) - return _config + return config class KeystoneComponent(OpenstackComponent): @@ -231,7 +234,7 @@ class NovaApiComponent(OpenstackComponent): @property @memoized def paste_config(self): - return self._parse_config_resource(self.paste_config_file) + return self._parse_config_resources([self.paste_config_file]) @property def all_issues(self): @@ -266,12 +269,6 @@ class MysqlComponent(Service): component = 'mysql' name = 'mysql' - @property - def config_file(self): - if len(self.config_files) == 0: - return None - return self.config_files[0] - class RabbitMqComponent(Service): pass