Merge branch 'master' of github.com:MirantisLabs/openstack-config-validator
* 'master' of github.com:MirantisLabs/openstack-config-validator: [doc] Add proposal document and update architecture model Added minimal support for running Lettuce-based inspections Added minimal RabbitMq service info collection [doc] Add configuration validator proposal document [doc] Move .dot image sources to images/src dir
This commit is contained in:
commit
71e4f7d08e
@ -4,7 +4,7 @@ from itertools import groupby
|
||||
from ostack_validator.common import Issue, MarkedIssue, Inspection
|
||||
from ostack_validator.model import OpenstackComponent
|
||||
from ostack_validator.discovery import OpenstackDiscovery
|
||||
from ostack_validator.inspections import KeystoneAuthtokenSettingsInspection, KeystoneEndpointsInspection
|
||||
from ostack_validator.inspections import KeystoneAuthtokenSettingsInspection, KeystoneEndpointsInspection, LettuceRunnerInspection
|
||||
|
||||
def indent_prefix(indent=0):
|
||||
s = ''
|
||||
@ -62,7 +62,7 @@ def main():
|
||||
|
||||
openstack = discovery.discover(['172.18.65.179'], 'root', private_key=private_key)
|
||||
|
||||
all_inspections = [KeystoneAuthtokenSettingsInspection, KeystoneEndpointsInspection]
|
||||
all_inspections = [KeystoneAuthtokenSettingsInspection, KeystoneEndpointsInspection, LettuceRunnerInspection]
|
||||
for inspection in all_inspections:
|
||||
x = inspection()
|
||||
x.inspect(openstack)
|
||||
|
@ -2,16 +2,20 @@
|
||||
ARCHITECTURE DATA MODEL
|
||||
=======================
|
||||
|
||||
--------
|
||||
Overview
|
||||
--------
|
||||
|
||||
Architecture data model produced by Joker could be consumed by configuration
|
||||
validator tool (Dark Knight), by architecture graph (Stencil) and others.
|
||||
We want to introduce unified data structure which contains all information
|
||||
necessary to inspect, analyze, describe and visualize OpenStack architecture.
|
||||
|
||||
At some point it should be made convertible into format accepted by deployment
|
||||
systems (e.g. Fuel or TripleO) which will allow to effectively 'clone' OpenStack
|
||||
clouds using different deployment applications.
|
||||
This Architecture data model could be consumed and processed by configuration
|
||||
analysis and diagnostics tool (**Dark Knight**) and by architecture visualizer
|
||||
(**Stencil**).
|
||||
|
||||
Arhictecture data model must include all information necessary to deployment
|
||||
systems (e.g. **Fuel** or **TripleO**). We will implement simple conversion tools which
|
||||
will allow to configure these deployment systems and effectively support
|
||||
'portable' clouds.
|
||||
|
||||
This model could be reused by Rally project to compare benchmarking results for
|
||||
different architectures.
|
||||
@ -24,11 +28,10 @@ support contract pricing purposes.
|
||||
The model could be used to perform automated/guided hardening of OpenStack
|
||||
architecture and configuration.
|
||||
|
||||
-----------
|
||||
Data Format
|
||||
-----------
|
||||
|
||||
This section proposes data model format which allows to describe any OpenStack
|
||||
This section proposes data model format which allows to describe an OpenStack
|
||||
installation. The model includes data regarding physical infrastructure, logical
|
||||
topology of services and mapping between the two.
|
||||
|
||||
|
68
doc/configuration_validator.rst
Normal file
68
doc/configuration_validator.rst
Normal file
@ -0,0 +1,68 @@
|
||||
OPENSTACK DIAGNOSTICS PROPOSAL
|
||||
==============================
|
||||
|
||||
Project Name
|
||||
------------
|
||||
|
||||
**Official:** OpenStack Diagnostics
|
||||
**Codename:** Dark Knight
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
OpenStack cloud operators usually rely on deploymnet tools to configure all the
|
||||
platform components correctly and efficiently upfront. However, after initial
|
||||
deployment platform configurations and operational conditions start to change.
|
||||
We propose a project that allows to analyze OpenStack architecture and diagnose
|
||||
existing and potential problems using flexible set of rules.
|
||||
|
||||
Mission
|
||||
---------
|
||||
|
||||
Diagnostics project mission is to **provide OpenStack cloud operators with
|
||||
flexible way to inspect, analyze and diagnose architecture of the cloud and
|
||||
configuration of components of the platform**.
|
||||
|
||||
User Stories
|
||||
------------
|
||||
|
||||
As a **cloud operator**, I want to be able to automatically extract
|
||||
configuration parameters from all OpenStack components to verify their
|
||||
correctness, consistency and integrity.
|
||||
As a **cloud architect**, I want to make sure that my OpenStack architecture and
|
||||
configuration are compliant to 'best practices'.
|
||||
As a **cloud operator**, I want automatic diagnostics tool which can tell me
|
||||
what problems does my OpenStack architecture and/or configuration have or might
|
||||
potentially have (e.g. at scale or if some component or node failed).
|
||||
As a **cloud operator**, I want to be able to define rules used to inspect and
|
||||
verify configuration of OpenStack components and store them to use for
|
||||
verification of future configuration changes.
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
TBD
|
||||
|
||||
Scope
|
||||
-----
|
||||
|
||||
As an MVP1, we create a service that includes:
|
||||
|
||||
1. Rules engine with grammatic analysis capabilities
|
||||
1. Extensible implementation of rules
|
||||
1. REST API for running inspections
|
||||
1. Storage back-end implementation for OpenStack platform architecture and
|
||||
configuration data
|
||||
|
||||
Assumptions
|
||||
-----------
|
||||
|
||||
We assume that we must reuse as much as possible from OpenStack Deployment
|
||||
program in terms of platform configuration and architecture definitions (i.e.
|
||||
TripleO Heat and configuration files templates).
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
|
||||
Design
|
||||
------
|
@ -408,5 +408,8 @@ class OpenstackDiscovery(object):
|
||||
if ' '.join(process).find('rabbit') == -1:
|
||||
return None
|
||||
|
||||
return None
|
||||
rabbitmq = RabbitMqComponent()
|
||||
rabbitmq.version = 'unknown'
|
||||
|
||||
return rabbitmq
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
from ostack_validator.inspections.keystone_authtoken import KeystoneAuthtokenSettingsInspection
|
||||
from ostack_validator.inspections.keystone_endpoints import KeystoneEndpointsInspection
|
||||
from ostack_validator.inspections.lettuce_runner import LettuceRunnerInspection
|
||||
|
||||
|
8
ostack_validator/inspections/lettuce/sample.feature
Normal file
8
ostack_validator/inspections/lettuce/sample.feature
Normal file
@ -0,0 +1,8 @@
|
||||
Feature: Configuration consistency
|
||||
|
||||
Scenario: Nova has proper Keystone host
|
||||
Given I use OpenStack 2013.1
|
||||
And Nova has "auth_strategy" equal to "keystone"
|
||||
And Keystone addresses are @X
|
||||
Then Nova should have "keystone_authtoken.auth_host" in "$X"
|
||||
|
67
ostack_validator/inspections/lettuce/steps.py
Normal file
67
ostack_validator/inspections/lettuce/steps.py
Normal file
@ -0,0 +1,67 @@
|
||||
import string
|
||||
from lettuce import *
|
||||
|
||||
from ostack_validator.common import Issue, Version, find
|
||||
from ostack_validator.model import *
|
||||
|
||||
def get_variable(name):
|
||||
if not hasattr(world, 'variables'):
|
||||
return None
|
||||
|
||||
return world.variables.get(name)
|
||||
|
||||
def set_variable(name, value):
|
||||
if not hasattr(world, 'variables'):
|
||||
world.variables = {}
|
||||
|
||||
world.variables[name] = value
|
||||
|
||||
def subst(template):
|
||||
if not hasattr(world, 'variables'):
|
||||
return template
|
||||
|
||||
tmpl = string.Template(template)
|
||||
return tmpl.safe_substitute(world.variables)
|
||||
|
||||
def stop():
|
||||
assert False, "stop"
|
||||
|
||||
@step(r'I use OpenStack (\w+)')
|
||||
def use_openstack_version(step, version):
|
||||
version = Version(version)
|
||||
for component in [c for c in world.openstack.components if isinstance(c, OpenstackComponent)]:
|
||||
if not Version(component.version) >= version: stop()
|
||||
|
||||
@step(r'Nova has "(.+)" equal to "(.*)"')
|
||||
def nova_has_property(step, name, value):
|
||||
name = subst(name)
|
||||
value = subst(value)
|
||||
|
||||
for nova in [c for c in world.openstack.components if c.name.startswith('nova')]:
|
||||
if not nova.config[name] == value: stop()
|
||||
|
||||
@step(r'Keystone addresses are @(\w+)')
|
||||
def keystone_addresses(self, variable):
|
||||
keystone = find(world.openstack.components, lambda c: c.name == 'keystone')
|
||||
|
||||
if keystone.config['bind_host'] == '0.0.0.0':
|
||||
addresses = filter(lambda ip: not ip.startswith('127.'), keystone.host.network_addresses)
|
||||
else:
|
||||
addresses = [keystone.config['bind_host']]
|
||||
|
||||
set_variable(variable, addresses)
|
||||
|
||||
@step(r'Nova should have "(.+)" in "(.*)"')
|
||||
def nova_property_assertion(self, name, values):
|
||||
name = subst(name)
|
||||
values = subst(values)
|
||||
|
||||
if not values:
|
||||
return
|
||||
|
||||
for nova in [c for c in world.openstack.components if c.name.startswith('nova')]:
|
||||
nova_value = nova.config[name]
|
||||
|
||||
if not (nova_value and nova_value in values):
|
||||
nova.report_issue(Issue(Issue.ERROR, 'Nova should have "%s" in %s' % (name, values)))
|
||||
|
20
ostack_validator/inspections/lettuce_runner.py
Normal file
20
ostack_validator/inspections/lettuce_runner.py
Normal file
@ -0,0 +1,20 @@
|
||||
import os.path
|
||||
import lettuce
|
||||
|
||||
from ostack_validator.common import Inspection, Issue
|
||||
|
||||
class LettuceRunnerInspection(Inspection):
|
||||
def inspect(self, openstack):
|
||||
runner = lettuce.Runner(
|
||||
base_path=os.path.join(os.path.dirname(__file__), 'lettuce')
|
||||
)
|
||||
|
||||
lettuce.world.openstack = openstack
|
||||
result = runner.run()
|
||||
del lettuce.world.openstack
|
||||
|
||||
for feature_result in result.feature_results:
|
||||
for scenario_result in [s for s in feature_result.scenario_results if not s.passed]:
|
||||
for step in scenario_result.steps_undefined:
|
||||
openstack.report_issue(Issue(Issue.ERROR, 'Undefined step "%s"' % step.sentence))
|
||||
|
@ -270,7 +270,7 @@ class MysqlComponent(Service):
|
||||
name = 'mysql'
|
||||
|
||||
class RabbitMqComponent(Service):
|
||||
pass
|
||||
name = 'rabbitmq'
|
||||
|
||||
class FileResource(IssueReporter):
|
||||
def __init__(self, path, contents, owner, group, permissions):
|
||||
|
Loading…
x
Reference in New Issue
Block a user