diff --git a/rubick/discovery.py b/rubick/discovery.py index 81ddf0d..e9cffe8 100644 --- a/rubick/discovery.py +++ b/rubick/discovery.py @@ -260,6 +260,8 @@ class OpenstackDiscovery(object): host.add_component(self._collect_cinder_scheduler_data(client)) host.add_component(self._collect_mysql_data(client)) host.add_component(self._collect_rabbitmq_data(client)) + host.add_component(self._collect_neutron_server_data(client)) + host.add_component(self._collect_swift_proxy_server_data(client)) return host @@ -631,3 +633,44 @@ class OpenstackDiscovery(object): rabbitmq.version = 'unknown' return rabbitmq + + def _collect_neutron_server_data(self, client): + process = self._find_python_process(client, 'neutron-server') + if not process: + return None + + p = index(process, lambda s: s == '--config-file') + if p != -1 and p + 1 < len(process): + config_path = process[p + 1] + else: + config_path = '/etc/neutron/neutron.conf' + + neutron_server = NeutronServerComponent() + neutron_server.version = self._find_python_package_version( + client, 'neutron') + neutron_server.config_files = [] + neutron_server.config_files.append( + self._collect_file(client, config_path)) + + return neutron_server + + + def _collect_swift_proxy_server_data(self, client): + process = self._find_python_process(client, 'swift-proxy-server') + if not process: + return None + + p = index(process, lambda s: 'swift-proxy-server' in s) + if p != -1 and p + 1 < len(process): + config_path = process[p + 1] + else: + config_path = '/etc/swift/proxy-server.conf' + + swift_proxy_server = SwiftProxyServerComponent() + swift_proxy_server.version = self._find_python_package_version( + client, 'swift') + swift_proxy_server.config_files = [] + swift_proxy_server.config_files.append( + self._collect_file(client, config_path)) + + return swift_proxy_server \ No newline at end of file diff --git a/rubick/inspections/lettuce/sample.feature b/rubick/inspections/lettuce/sample.feature index 0e91111..8f985d6 100644 --- a/rubick/inspections/lettuce/sample.feature +++ b/rubick/inspections/lettuce/sample.feature @@ -15,7 +15,5 @@ Feature: Configuration consistency Given I use OpenStack 2013.1 And Controller addresses are @X Then "nova" component have "novncproxy_base_url" parameter equal to "$X" + And "nova" component must have "sql_connection" parameter - Scenario: Nova has proper settings for NoVNC - Given I use OpenStack 2013.1 - Then "nova" component must have "sql_connection" parameter diff --git a/rubick/inspections/lettuce/sample_havana.feature b/rubick/inspections/lettuce/sample_havana.feature new file mode 100644 index 0000000..9664e6d --- /dev/null +++ b/rubick/inspections/lettuce/sample_havana.feature @@ -0,0 +1,22 @@ +Feature: Configuration consistency + + Scenario: Nova has proper Keystone host + Given I use OpenStack 2013.2.1 + And Nova has "auth_strategy" equal to "keystone" + And Keystone addresses are @X + Then Nova should have keystone authtoken filter's "auth_host" in "$X" + + Scenario: Nova has proper fixed_range settings for Grizzly release + Given I use OpenStack 2013.2.1 + And Nova has "fixed_range" equal to "" + Then "nova" component have "fixed_range" parameter equal to "" + + Scenario: Nova has proper settings for NoVNC + Given I use OpenStack 2013.2.1 + And Controller addresses are @X + Then "nova" component have "novncproxy_base_url" parameter equal to "$X" + And "nova" component must have "sql_connection" parameter + + Scenario: Neutron check + Given I use OpenStack 2013.2.1 + Then "neutron" component must have "sql_connection" parameter \ No newline at end of file diff --git a/rubick/inspections/lettuce/steps.py b/rubick/inspections/lettuce/steps.py index 087dbc7..c507825 100644 --- a/rubick/inspections/lettuce/steps.py +++ b/rubick/inspections/lettuce/steps.py @@ -97,7 +97,7 @@ def nova_property_assertion(self, name, values): if not (nova_value and nova_value in values): nova.report_issue( Issue(Issue.ERROR, 'Nova should have "%s" in %s' % - (name, values))) + (name, values))) @step(r"Nova should have keystone authtoken filter's \"(.+)\" in \"(.*)\"") @@ -114,14 +114,14 @@ def nova_authtoken_property_assertion(self, name, values): (authtoken_section, _) = find( nova.paste_config.items(), lambda name_values: name_values[0].startswith('filter:') and - name_values[1].get( - 'paste.filter_factory') == AUTHTOKEN_FILTER_FACTORY + name_values[1].get( + 'paste.filter_factory') == AUTHTOKEN_FILTER_FACTORY ) if not authtoken_section: nova.report_issue( Issue(Issue.ERROR, 'Nova has keystone "auth" strategy ' - 'configured, but doesnt have authtoken paste filter')) + 'configured, but doesnt have authtoken paste filter')) continue authtoken_settings = nova.paste_config.section(authtoken_section) @@ -132,26 +132,30 @@ def nova_authtoken_property_assertion(self, name, values): if not (param_value and param_value in values): nova.report_issue( Issue(Issue.ERROR, 'Nova should have "%s" in %s, ' - 'actual value is "%s"' % (name, values, param_value))) + 'actual value is "%s"' % ( + name, values, param_value))) +# Common steps section @step(r'"(.+)" component must have "(.+)" parameter') -def nova_has_non_none_property(step, component_name, parameter_name): +def component_has_non_none_property(step, component_name, parameter_name): component_name = subst(component_name) parameter_name = subst(parameter_name) for component in [c for c in world.openstack.components - if c.component.startswith('%s' % component_name)]: + if c.name.startswith('%s' % component_name)]: component_value = component.config[parameter_name] if component_value is None: component.report_issue( - Issue(Issue.ERROR, '"%s" should have parameter "%s"' % - (component_name, parameter_name))) + Issue(Issue.ERROR, + '"%s" must have parameter "%s - version %s"' % + (c.name, parameter_name, component.version))) @step(r'"(.+)" component have "(.+)" parameter equal to "(.*)"') -def nova_has_property_with_value(step, component_name, parameter_name, value): +def component_has_property_with_value(step, component_name, parameter_name, + value): component_name = subst(component_name) parameter_name = subst(parameter_name) value = subst(value) @@ -166,3 +170,11 @@ def nova_has_property_with_value(step, component_name, parameter_name, value): '"%s" should have parameter "%s" equals "%s"' 'now its "%s"' % (component_name, parameter_name, component_value, value))) + + +@step(r'Which package version do I use?') +def component_versions_list(self): + for component in world.openstack.components: + component.report_issue(Issue(Issue.INFO, "%s component has % version" % + ( + component.name, component.version))) \ No newline at end of file diff --git a/rubick/inspections/lettuce/version.feature b/rubick/inspections/lettuce/version.feature new file mode 100644 index 0000000..5fe2dce --- /dev/null +++ b/rubick/inspections/lettuce/version.feature @@ -0,0 +1,4 @@ +Feature: OpenStack component version finding + + Scenario: All component version finding + Then Which package version do I use? \ No newline at end of file diff --git a/rubick/model.py b/rubick/model.py index 1e39d16..0b44ced 100644 --- a/rubick/model.py +++ b/rubick/model.py @@ -347,6 +347,46 @@ class RabbitMqComponent(Service): name = 'rabbitmq' +class GlanceApiComponent(OpenstackComponent): + component = 'glance' + name = 'glance-api' + + +class GlanceRegistryComponent(OpenstackComponent): + component = 'glance' + name = 'glance-registry' + + +class NeutronServerComponent(OpenstackComponent): + component = 'neutron' + name = 'neutron-server' + + +class NeutronOpenvswitchAgentComponent(OpenstackComponent): + component = 'neutron' + name = 'neutron-openvswitch-agent' + + +class NeutronDhcpAgentComponent(OpenstackComponent): + component = 'neutron' + name = 'neutron-dhcp-agent' + + +class NeutronL3AgentComponent(OpenstackComponent): + component = 'neutron' + name = 'neutron-l3-agent' + + +class NeutronMetadataAgentComponent(OpenstackComponent): + component = 'neutron' + name = 'neutron-metadata-agent' + + +class SwiftProxyServerComponent(OpenstackComponent): + component = 'swift' + name = 'swift-proxy-server' + + class FileResource(IssueReporter): def __init__(self, path, contents, owner, group, permissions):