Added RabbitMQ info descovery

This commit is contained in:
Maxim Kulkin 2013-10-31 16:38:35 +04:00
parent 94ebe4a1bb
commit 1347022cc9
7 changed files with 170 additions and 12 deletions

View File

@ -624,7 +624,9 @@ class OpenstackDiscovery(object):
def _collect_rabbitmq_data(self, client):
process = self._find_process(client, 'beam.smp')
if not process:
return None
process = self._find_process(client, 'beam')
if not process:
return None
if ' '.join(process).find('rabbit') == -1:
return None
@ -632,6 +634,24 @@ class OpenstackDiscovery(object):
rabbitmq = RabbitMqComponent()
rabbitmq.version = 'unknown'
env_file = '/etc/rabbitmq/rabbitmq-env.conf'
env_vars = {}
result = client.run(['bash', '-c', 'source %s && printenv' % env_file])
if result.return_code == 0:
lines = result.output.split("\n")
env_vars = dict((k, v) for k, v in lines.split('=', 1))
rabbitmq_env_vars = \
dict((key.replace('RABBITMQ_', ''), value)
for key, value in env_vars if key.startswith('RABBITMQ_'))
for key, value in rabbitmq_env_vars:
rabbitmq.config.set_env(key, value)
for i, s in enumerate(process):
if s == '-rabbit' and i + 2 <= len(process):
rabbitmq.config.set_cli(process[i + 1], process[i + 2])
return rabbitmq
def _collect_neutron_server_data(self, client):
@ -673,4 +693,4 @@ class OpenstackDiscovery(object):
swift_proxy_server.config_files.append(
self._collect_file(client, config_path))
return swift_proxy_server
return swift_proxy_server

View File

@ -1,7 +1,7 @@
from itertools import groupby
import logging
from rubick.common import Mark, Issue, MarkedIssue
from rubick.common import Mark, Issue, MarkedIssue, Version
from rubick.config_formats import IniConfigParser
from rubick.config_model import Configuration
from rubick.schema import ConfigSchemaRegistry, TypeValidatorRegistry
@ -346,6 +346,22 @@ class MysqlComponent(Service):
class RabbitMqComponent(Service):
name = 'rabbitmq'
@property
@memoized
def config(self):
config = Configuration()
schema = ConfigSchemaRegistry.get_schema('rabbitmq', Version(1000000))
if schema:
for parameter in schema.parameters:
if not parameter.default:
continue
config.set_default(parameter.name, parameter.default)
else:
print("RabbitMQ schema not found")
return config
class GlanceApiComponent(OpenstackComponent):
component = 'glance'

View File

@ -1,4 +1,5 @@
from contextlib import contextmanager
import re
from rubick.common import Issue, MarkedIssue, Mark, Version, find, index
from rubick.exceptions import RubickException
@ -443,8 +444,7 @@ def validate_port(s, min=1, max=65535):
return validate_integer(s, min=min, max=max)
@type_validator('string_list')
def validate_list(s, element_type='string'):
def validate_list(s, element_type):
element_type_validator = TypeValidatorRegistry.get_validator(element_type)
if not element_type_validator:
return SchemaIssue('Invalid element type "%s"' % element_type)
@ -456,16 +456,29 @@ def validate_list(s, element_type='string'):
return result
values = s.split(',')
for value in values:
validated_value = element_type_validator.validate(value.strip())
if isinstance(validated_value, Issue):
# TODO: provide better position reporting
return validated_value
while len(values) > 0:
value = values.pop(0)
while True:
validated_value = element_type_validator.validate(value.strip())
if not isinstance(validated_value, Issue):
break
if len(values) == 0:
# TODO: provide better position reporting
return validated_value
value += ',' + values.pop()
result.append(validated_value)
return result
@type_validator('string_list')
def validate_string_list(s):
return validate_list(s, element_type='string')
@type_validator('string_dict')
def validate_dict(s, element_type='string'):
element_type_validator = TypeValidatorRegistry.get_validator(element_type)
@ -501,3 +514,41 @@ def validate_dict(s, element_type='string'):
return validated_value
result[key] = validated_value
return result
@type_validator('rabbitmq_bind')
def validate_rabbitmq_bind(s):
m = re.match('\d+', s)
if m:
port = validate_port(s)
if isinstance(port, Issue):
return port
return ('0.0.0.0', port)
m = re.match('{\s*\"(.+)\"\s*,\s*(\d+)\s*}', s)
if m:
host = validate_host_address(m.group(1))
port = validate_port(m.group(2))
if isinstance(host, Issue):
return host
if isinstance(port, Issue):
return port
return (host, port)
return SchemaIssue("Unrecognized bind format")
def validate_rabbitmq_list(s, element_type):
if not (s.startswith('[') and s.endswith(']')):
return SchemaIssue('List should be surrounded by [ and ]')
return validate_list(s[1:-1], element_type=element_type)
@type_validator('rabbitmq_bind_list')
def validate_rabbitmq_bind_list(s):
return validate_rabbitmq_list(s, element_type='rabbitmq_bind')

View File

@ -4,3 +4,4 @@ import rubick.schemas.keystone
import rubick.schemas.neutron
import rubick.schemas.nova
import rubick.schemas.swift
import rubick.schemas.rabbitmq

View File

@ -0,0 +1 @@
import rubick.schemas.rabbitmq.v3_0_0

View File

@ -0,0 +1,27 @@
from rubick.schema import ConfigSchemaRegistry
rabbitmq = ConfigSchemaRegistry.register_schema(project='rabbitmq')
with rabbitmq.version('3.0.0', checkpoint=True) as cfg:
cfg.param(
'tcp_listeners', type='rabbitmq_bind_list', default=[5672],
description="List of ports on which to listen for AMQP connections (without SSL)")
cfg.param(
'ssl_listeners', type='rabbitmq_bind_list', default=[],
description="List of ports on which to listen for AMQP connections (SSL)")
cfg.param('ssl_options', type='string_list', default=[])
cfg.param('vm_memory_high_watermark', type='float', default=0.4)
cfg.param('vm_memory_high_watermark_paging_ratio',
type='float', default=0.5)
cfg.param('disk_free_limit', type='integer', default='50000000')
cfg.param('log_levels', type='string_list', default=['{connection, info}'])
cfg.param('frame_max', type='integer', default=131072)
cfg.param('heartbeat', type='integer', default=600)
cfg.param('default_vhost', type='string', default='/')
cfg.param('default_user', type='string', default='guest')
cfg.param('default_pass', type='string', default='guest')

View File

@ -5,7 +5,6 @@ import unittest
class TypeValidatorTestHelper(object):
def setUp(self):
super(TypeValidatorTestHelper, self).setUp()
self.validator = TypeValidatorRegistry.get_validator(self.type_name)
@ -14,7 +13,8 @@ class TypeValidatorTestHelper(object):
self.assertNotIsInstance(self.validator.validate(value), Issue)
def assertInvalid(self, value):
self.assertIsInstance(self.validator.validate(value), Issue)
self.assertIsInstance(
self.validator.validate(value), Issue)
class StringTypeValidatorTests(TypeValidatorTestHelper, unittest.TestCase):
@ -277,5 +277,47 @@ class StringDictTypeValidatorTests(TypeValidatorTestHelper, unittest.TestCase):
self.assertEqual(2, len(v))
class RabbitmqBindValidatorTest(TypeValidatorTestHelper, unittest.TestCase):
type_name = 'rabbitmq_bind'
def test_empty_value_is_an_error(self):
self.assertInvalid('')
def test_integer(self):
v = self.validator.validate('123')
self.assertEqual(('0.0.0.0', 123), v)
def test_integer_outside_port_range(self):
self.assertInvalid('65536')
def test_host_port(self):
v = self.validator.validate('{"127.0.0.1",8080}')
self.assertEqual(('127.0.0.1', 8080), v)
class RabbitmqListValidatorTest(TypeValidatorTestHelper, unittest.TestCase):
type_name = 'rabbitmq_bind_list'
def test_empty(self):
self.assertInvalid('')
def test_empty_list(self):
v = self.validator.validate('[]')
self.assertEqual([], v)
def test_single_entry(self):
v = self.validator.validate('[123]')
self.assertEqual([('0.0.0.0', 123)], v)
def test_multiple_entries(self):
v = self.validator.validate('[1080,{"localhost",8080}]')
self.assertEqual([('0.0.0.0', 1080), ('localhost', 8080)], v)
if __name__ == '__main__':
unittest.main()