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): def _collect_rabbitmq_data(self, client):
process = self._find_process(client, 'beam.smp') process = self._find_process(client, 'beam.smp')
if not process: if not process:
return None process = self._find_process(client, 'beam')
if not process:
return None
if ' '.join(process).find('rabbit') == -1: if ' '.join(process).find('rabbit') == -1:
return None return None
@@ -632,6 +634,24 @@ class OpenstackDiscovery(object):
rabbitmq = RabbitMqComponent() rabbitmq = RabbitMqComponent()
rabbitmq.version = 'unknown' 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 return rabbitmq
def _collect_neutron_server_data(self, client): def _collect_neutron_server_data(self, client):
@@ -673,4 +693,4 @@ class OpenstackDiscovery(object):
swift_proxy_server.config_files.append( swift_proxy_server.config_files.append(
self._collect_file(client, config_path)) self._collect_file(client, config_path))
return swift_proxy_server return swift_proxy_server

View File

@@ -1,7 +1,7 @@
from itertools import groupby from itertools import groupby
import logging 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_formats import IniConfigParser
from rubick.config_model import Configuration from rubick.config_model import Configuration
from rubick.schema import ConfigSchemaRegistry, TypeValidatorRegistry from rubick.schema import ConfigSchemaRegistry, TypeValidatorRegistry
@@ -346,6 +346,22 @@ class MysqlComponent(Service):
class RabbitMqComponent(Service): class RabbitMqComponent(Service):
name = 'rabbitmq' 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): class GlanceApiComponent(OpenstackComponent):
component = 'glance' component = 'glance'

View File

@@ -1,4 +1,5 @@
from contextlib import contextmanager from contextlib import contextmanager
import re
from rubick.common import Issue, MarkedIssue, Mark, Version, find, index from rubick.common import Issue, MarkedIssue, Mark, Version, find, index
from rubick.exceptions import RubickException 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) return validate_integer(s, min=min, max=max)
@type_validator('string_list') def validate_list(s, element_type):
def validate_list(s, element_type='string'):
element_type_validator = TypeValidatorRegistry.get_validator(element_type) element_type_validator = TypeValidatorRegistry.get_validator(element_type)
if not element_type_validator: if not element_type_validator:
return SchemaIssue('Invalid element type "%s"' % element_type) return SchemaIssue('Invalid element type "%s"' % element_type)
@@ -456,16 +456,29 @@ def validate_list(s, element_type='string'):
return result return result
values = s.split(',') values = s.split(',')
for value in values: while len(values) > 0:
validated_value = element_type_validator.validate(value.strip()) value = values.pop(0)
if isinstance(validated_value, Issue): while True:
# TODO: provide better position reporting validated_value = element_type_validator.validate(value.strip())
return validated_value 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) result.append(validated_value)
return result return result
@type_validator('string_list')
def validate_string_list(s):
return validate_list(s, element_type='string')
@type_validator('string_dict') @type_validator('string_dict')
def validate_dict(s, element_type='string'): def validate_dict(s, element_type='string'):
element_type_validator = TypeValidatorRegistry.get_validator(element_type) element_type_validator = TypeValidatorRegistry.get_validator(element_type)
@@ -501,3 +514,41 @@ def validate_dict(s, element_type='string'):
return validated_value return validated_value
result[key] = validated_value result[key] = validated_value
return result 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.neutron
import rubick.schemas.nova import rubick.schemas.nova
import rubick.schemas.swift 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): class TypeValidatorTestHelper(object):
def setUp(self): def setUp(self):
super(TypeValidatorTestHelper, self).setUp() super(TypeValidatorTestHelper, self).setUp()
self.validator = TypeValidatorRegistry.get_validator(self.type_name) self.validator = TypeValidatorRegistry.get_validator(self.type_name)
@@ -14,7 +13,8 @@ class TypeValidatorTestHelper(object):
self.assertNotIsInstance(self.validator.validate(value), Issue) self.assertNotIsInstance(self.validator.validate(value), Issue)
def assertInvalid(self, value): def assertInvalid(self, value):
self.assertIsInstance(self.validator.validate(value), Issue) self.assertIsInstance(
self.validator.validate(value), Issue)
class StringTypeValidatorTests(TypeValidatorTestHelper, unittest.TestCase): class StringTypeValidatorTests(TypeValidatorTestHelper, unittest.TestCase):
@@ -277,5 +277,47 @@ class StringDictTypeValidatorTests(TypeValidatorTestHelper, unittest.TestCase):
self.assertEqual(2, len(v)) 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__': if __name__ == '__main__':
unittest.main() unittest.main()