Load plugins from conf file

Change-Id: I4f262620abbee1b10088b2b0c789c9b4a054c384
This commit is contained in:
Noam Bloom 2016-03-08 13:48:15 +00:00
parent f077648548
commit 9382bb4293
36 changed files with 312 additions and 370 deletions

View File

@ -2,6 +2,7 @@
output_file = etc/vitrage/vitrage.conf
wrap_width = 79
namespace = vitrage
namespace = plugins
namespace = oslo.db
namespace = oslo.log
namespace = oslo.middleware

View File

@ -28,6 +28,7 @@ console_scripts =
oslo.config.opts =
vitrage = vitrage.opts:list_opts
plugins = vitrage.opts:plugins_opts
vitrage.transformers =
nova.instance = vitrage.entity_graph.transformer.nova_transformer.instance_transformer.InstanceTransformer

View File

@ -65,7 +65,7 @@ class EntityType(object):
NOVA_INSTANCE = 'nova.instance'
NOVA_HOST = 'nova.host'
NOVA_ZONE = 'nova.zone'
SWITCH = 'switch'
STATIC_PHYSICAL = 'static_physical'
NAGIOS = 'nagios'
VITRAGE = 'vitrage'

View File

@ -17,6 +17,7 @@
# License for the specific language governing permissions and limitations
# under the License.
from oslo_config import cfg
import six
@ -28,3 +29,10 @@ def recursive_keypairs(d, separator='.'):
yield ('%s%s%s' % (name, separator, subname), subvalue)
else:
yield name, value
def oslo_config_opt_exists(conf_parent, opt):
try:
return conf_parent[opt]
except cfg.NoSuchOptError:
return False

View File

@ -19,10 +19,12 @@ from oslo_utils import importutils
from vitrage.common.constants import EntityType
from vitrage.common.constants import SynchronizerProperties as SyncProps
from vitrage.common.exception import VitrageTransformerError
from vitrage.common.utils import oslo_config_opt_exists
from vitrage.evaluator.actions.evaluator_event_transformer import \
EvaluatorEventTransformer
LOG = logging.getLogger(__name__)
ENTITIES = 'entities'
class TransformerManager(object):
@ -35,9 +37,13 @@ class TransformerManager(object):
transformers = {}
for plugin in conf.synchronizer_plugins.plugin_type:
transformers[plugin] = importutils.import_object(
conf.synchronizer_plugins[plugin]['transformer'],
transformers)
transformers[plugin] = importutils.import_object(
conf[plugin].transformer,
transformers)
if oslo_config_opt_exists(conf[plugin], ENTITIES):
for entity in conf[plugin].entities:
transformers[entity] = importutils.import_object(
conf[plugin].transformer, transformers)
transformers[EntityType.VITRAGE] = importutils.import_object(
"%s.%s" % (EvaluatorEventTransformer.__module__,

View File

@ -13,6 +13,11 @@
# License for the specific language governing permissions and limitations
# under the License.
from oslo_config import cfg
from oslo_log import log
from oslo_policy import opts as policy_opts
from oslo_utils import importutils
import vitrage.api
import vitrage.entity_graph.consistency
import vitrage.evaluator
@ -20,6 +25,8 @@ import vitrage.rpc
import vitrage.synchronizer
import vitrage.synchronizer.plugins
PLUGINS_PATH = 'vitrage.synchronizer.plugins.'
def list_opts():
return [
@ -31,3 +38,18 @@ def list_opts():
('entity_graph', vitrage.entity_graph.OPTS),
('DEFAULT', vitrage.rpc.OPTS)
]
# This is made for documentation and configuration purposes
def plugins_opts():
conf = cfg.ConfigOpts()
log.register_options(conf)
policy_opts.set_defaults(conf)
for group, options in list_opts():
conf.register_opts(list(options),
group=None if group == 'DEFAULT' else group)
return [(plugin_name, importutils.import_module(PLUGINS_PATH + plugin_name)
.OPTS)
for plugin_name in conf.synchronizer_plugins.plugin_type]

View File

@ -16,9 +16,11 @@ import logging
from oslo_config import cfg
from oslo_log import log
from oslo_policy import opts as policy_opts
from oslo_utils import importutils
from vitrage import opts
PLUGINS_PATH = 'vitrage.synchronizer.plugins.'
LOG = log.getLogger(__name__)
@ -35,8 +37,16 @@ def prepare_service(args=None, default_opts=None, conf=None):
for opt, value, group in default_opts or []:
conf.set_default(opt, value, group)
for plugin_name in conf.synchronizer_plugins.plugin_type:
load_plugin(conf, plugin_name)
conf(args, project='vitrage', validate_default_values=True)
log.setup(conf, 'vitrage')
conf.log_opt_values(LOG, logging.DEBUG)
return conf
def load_plugin(conf, name):
opt = importutils.import_module(PLUGINS_PATH + name).OPTS
conf.register_opts(list(opt), group=None if name == 'DEFAULT' else name)

View File

@ -19,13 +19,4 @@ OPTS = [
default=600,
min=10,
help='interval between full snapshots'),
cfg.IntOpt('nagios_changes_interval',
default=30,
min=30,
help='interval between checking changes in nagios plugin'),
cfg.IntOpt('static_physical_changes_interval',
default=30,
min=30,
help='interval between checking changes in the configuration '
'files of the physical topology plugin'),
]

View File

@ -15,20 +15,14 @@
from oslo_log import log
from oslo_service import service as os_service
from oslo_utils import importutils
from services import ChangesService
from services import SnapshotsService
from vitrage.synchronizer.plugins.nagios.synchronizer import NagiosSynchronizer
from vitrage.synchronizer.plugins.nova.host.synchronizer import \
HostSynchronizer
from vitrage.synchronizer.plugins.nova.instance.synchronizer import \
InstanceSynchronizer
from vitrage.synchronizer.plugins.nova.zone.synchronizer import \
ZoneSynchronizer
from vitrage.synchronizer.plugins.static_physical.synchronizer import \
StaticPhysicalSynchronizer
from vitrage.common.utils import oslo_config_opt_exists
LOG = log.getLogger(__name__)
CHANGES_INTERVAL = 'changes_interval'
def create_send_to_queue_callback(queue):
@ -53,29 +47,15 @@ class Launcher(object):
launcher.launch_service(service, 1)
def _register_snapshot_plugins(self):
version = 2.0
user = 'admin'
password = 'password'
project = 'admin'
auth_url = "http://localhost:5000/v2.0/"
registered_plugins = \
[ZoneSynchronizer(version, user, password, project, auth_url),
HostSynchronizer(version, user, password, project, auth_url),
InstanceSynchronizer(version, user, password, project, auth_url),
NagiosSynchronizer(self.conf),
StaticPhysicalSynchronizer(self.conf)]
return registered_plugins
return {plugin: importutils.import_object
(self.conf[plugin].synchronizer, self.conf)
for plugin
in self.conf.synchronizer_plugins.plugin_type}
def _register_services(self):
nagios_changes_interval = self.conf.synchronizer.\
nagios_changes_interval
static_physical_changes_interval = self.conf.synchronizer.\
static_physical_changes_interval
return [SnapshotsService(self.conf, self.snapshot_plugins),
ChangesService(self.conf,
[NagiosSynchronizer(self.conf)],
nagios_changes_interval),
ChangesService(self.conf,
[StaticPhysicalSynchronizer(self.conf)],
static_physical_changes_interval)]
return [SnapshotsService(self.conf, self.snapshot_plugins)] + \
[ChangesService(self.conf,
[self.snapshot_plugins[plugin]],
self.conf[plugin].changes_interval)
for plugin in self.conf.synchronizer_plugins.plugin_type
if oslo_config_opt_exists(self.conf[plugin], CHANGES_INTERVAL)]

View File

@ -22,101 +22,6 @@ OPTS = [
'nova.host',
'nova.instance',
'nova.zone',
'switch'],
'static_physical'],
help='Names of supported plugins'),
cfg.DictOpt('nagios',
default={
'synchronizer':
'vitrage.synchronizer.plugins.nagios.synchronizer'
'.NagiosSynchronizer',
'transformer': 'vitrage.synchronizer.plugins'
'.nagios.transformer.NagiosTransformer',
'user': '',
'password': '',
'url': '',
'config_file': '/etc/vitrage/nagios_conf.yaml'},
help='synchronizer:synchronizer path,\n'
'transformer:transformer path,\n'
'user:Nagios user,\n'
'password:Nagios password,\n'
'url:Nagios url for querying the data. Example: '
'http://<ip>/monitoring/nagios/cgi-bin/status.cgi\n'
'config_file:Nagios configuration file'
),
cfg.DictOpt('nova.host',
default={
'synchronizer':
'vitrage.synchronizer.plugins.nova.host.synchronizer'
'.HostSynchronizer',
'transformer': 'vitrage.synchronizer.plugins'
'.nova.host.transformer.HostTransformer',
'user': '',
'password': '',
'url': '',
'version': '2.0',
'project': 'admin'},
help='synchronizer:synchronizer path,\n'
'transformer:transformer path,\n'
'user:nova.host user,\n'
'password:nova.host password,\n'
'url:nova authentication url for querying the data'
'version: nova version\n'
'project: nova project'),
cfg.DictOpt('nova.instance',
default={
'synchronizer':
'vitrage.synchronizer.plugins.nova.instance'
'.synchronizer.InstanceSynchronizer',
'transformer':
'vitrage.synchronizer.plugins'
'.nova.instance.transformer.InstanceTransformer',
'user': '',
'password': '',
'url': '',
'version': '2.0',
'project': 'admin'},
help='synchronizer:synchronizer path,\n'
'transformer:transformer path,\n'
'user:nova.instance user,\n'
'password:nova.instance password,\n'
'url:nova authentication url for querying the data'
'version: nova version\n'
'project: nova project'),
cfg.DictOpt('nova.zone',
default={
'synchronizer':
'vitrage.synchronizer.plugins.nova.zone.synchronizer'
'.ZoneSynchronizer',
'transformer': 'vitrage.synchronizer.plugins'
'.nova.zone.transformer.ZoneTransformer',
'user': '',
'password': '',
'url': '',
'version': '2.0',
'project': 'admin'},
help='synchronizer:synchronizer path,\n'
'transformer:transformer path,\n'
'user:nova.zone user,\n'
'password:nova.zone password,\n'
'url:nova authentication url for querying the data'
'version: nova version\n'
'project: nova project'),
cfg.DictOpt('switch',
default={
'synchronizer':
'vitrage.synchronizer.plugins.static_physical'
'.synchronizer.StaticPhysicalSynchronizer',
'transformer':
'vitrage.synchronizer.plugins.static_physical.'
'transformer.StaticPhysicalTransformer',
'dir': '/etc/vitrage/static_plugins'},
help='synchronizer:synchronizer path,\n'
'transformer:transformer path,\n'
'dir: A path for the static plugins for the '
'synchronizer'),
]

View File

@ -12,4 +12,29 @@
# License for the specific language governing permissions and limitations
# under the License.
__author__ = 'stack'
from oslo_config import cfg
OPTS = [
cfg.StrOpt('transformer',
default='vitrage.synchronizer.plugins.nagios.'
'transformer.NagiosTransformer',
help='Nagios plugin transformer class path',
required=True),
cfg.StrOpt('synchronizer',
default='vitrage.synchronizer.plugins.nagios.synchronizer'
'.NagiosSynchronizer',
help='Nagios plugin synchronizer class path',
required=True),
cfg.IntOpt('changes_interval',
default=30,
min=30,
help='interval between checking changes in nagios plugin',
required=True),
cfg.StrOpt('user', default='nagiosadmin',
help='Nagios user name'),
cfg.StrOpt('password', default='nagiosadmin',
help='Nagios user password'),
cfg.StrOpt('url', default='', help='Nagios url'),
cfg.StrOpt('config_file', default='/etc/vitrage/nagios_conf.yaml',
help='Nagios configuration file'),
]

View File

@ -29,8 +29,7 @@ NAME = 'name'
class NagiosConfig(object):
def __init__(self, conf):
try:
nagios_config_file = conf.synchronizer_plugins\
.nagios['config_file']
nagios_config_file = conf.nagios['config_file']
nagios_config = file_utils.load_yaml_file(nagios_config_file)
nagios = nagios_config[NAGIOS] # nagios root in the yaml file

View File

@ -65,9 +65,9 @@ class NagiosSynchronizer(SynchronizerBase):
NagiosSynchronizer._filter_get_changes)
def _get_services_from_nagios(self):
nagios_user = self.conf.synchronizer_plugins.nagios['user']
nagios_password = self.conf.synchronizer_plugins.nagios['password']
nagios_url = self.conf.synchronizer_plugins.nagios['url']
nagios_user = self.conf.nagios.user
nagios_password = self.conf.nagios.password
nagios_url = self.conf.nagios.url
if not nagios_user:
return []

View File

@ -12,4 +12,23 @@
# License for the specific language governing permissions and limitations
# under the License.
__author__ = 'stack'
from oslo_config import cfg
OPTS = [
cfg.StrOpt('transformer',
default='vitrage.synchronizer.plugins.nova.host.'
'transformer.HostTransformer',
help='Nova host transformer class path',
required=True),
cfg.StrOpt('synchronizer',
default='vitrage.synchronizer.plugins.nova.host.synchronizer'
'.HostSynchronizer',
help='Nova host synchronizer class path',
required=True),
cfg.StrOpt('user', default='admin', help='Nova user name'),
cfg.StrOpt('password', default='password', help='Nova user password'),
cfg.StrOpt('url', default='http://localhost:5000/v2.0/',
help='Nova authentication url'),
cfg.FloatOpt('version', default='2.0', help='Nova version'),
cfg.StrOpt('project', default='admin', help='Nova project'),
]

View File

@ -18,12 +18,18 @@ from vitrage.synchronizer.plugins.nova.base import NovaBase
class HostSynchronizer(NovaBase):
def __init__(self, version, user, password, project, auth_url):
def __init__(self, conf):
version = conf[EntityType.NOVA_HOST].version
user = conf[EntityType.NOVA_HOST].user
password = conf[EntityType.NOVA_HOST].password
project = conf[EntityType.NOVA_HOST].project
auth_url = conf[EntityType.NOVA_HOST].url
super(HostSynchronizer, self).__init__(version,
user,
password,
project,
auth_url)
self.conf = conf
@staticmethod
def filter_none_compute_hosts(entities):

View File

@ -12,4 +12,23 @@
# License for the specific language governing permissions and limitations
# under the License.
__author__ = 'stack'
from oslo_config import cfg
OPTS = [
cfg.StrOpt('transformer',
default='vitrage.synchronizer.plugins.nova.instance.'
'transformer.InstanceTransformer',
help='Nova instance transformer class path',
required=True),
cfg.StrOpt('synchronizer',
default='vitrage.synchronizer.plugins.nova.instance'
'.synchronizer.InstanceSynchronizer',
help='Nova instance synchronizer class path',
required=True),
cfg.StrOpt('user', default='admin', help='Nova user name'),
cfg.StrOpt('password', default='password', help='Nova user password'),
cfg.StrOpt('url', default='http://localhost:5000/v2.0/',
help='Nova authentication url'),
cfg.FloatOpt('version', default='2.0', help='Nova version'),
cfg.StrOpt('project', default='admin', help='Nova project'),
]

View File

@ -17,12 +17,18 @@ from vitrage.synchronizer.plugins.nova.base import NovaBase
class InstanceSynchronizer(NovaBase):
def __init__(self, version, user, password, project, auth_url):
def __init__(self, conf):
version = conf[EntityType.NOVA_INSTANCE].version
user = conf[EntityType.NOVA_INSTANCE].user
password = conf[EntityType.NOVA_INSTANCE].password
project = conf[EntityType.NOVA_INSTANCE].project
auth_url = conf[EntityType.NOVA_INSTANCE].url
super(InstanceSynchronizer, self).__init__(version,
user,
password,
project,
auth_url)
self.conf = conf
@staticmethod
def filter_instances(instances):

View File

@ -12,4 +12,23 @@
# License for the specific language governing permissions and limitations
# under the License.
__author__ = 'stack'
from oslo_config import cfg
OPTS = [
cfg.StrOpt('transformer',
default='vitrage.synchronizer.plugins.nova.zone.'
'transformer.ZoneTransformer',
help='Nova zone transformer class path',
required=True),
cfg.StrOpt('synchronizer',
default='vitrage.synchronizer.plugins.nova.zone.synchronizer'
'.ZoneSynchronizer',
help='Nova zone synchronizer class path',
required=True),
cfg.StrOpt('user', default='admin', help='Nova user name'),
cfg.StrOpt('password', default='password', help='Nova user password'),
cfg.StrOpt('url', default='http://localhost:5000/v2.0/',
help='Nova authentication url'),
cfg.FloatOpt('version', default='2.0', help='Nova version'),
cfg.StrOpt('project', default='admin', help='Nova project'),
]

View File

@ -17,12 +17,18 @@ from vitrage.synchronizer.plugins.nova.base import NovaBase
class ZoneSynchronizer(NovaBase):
def __init__(self, version, user, password, project, auth_url):
def __init__(self, conf):
version = conf[EntityType.NOVA_ZONE].version
user = conf[EntityType.NOVA_ZONE].user
password = conf[EntityType.NOVA_ZONE].password
project = conf[EntityType.NOVA_ZONE].project
auth_url = conf[EntityType.NOVA_ZONE].url
super(ZoneSynchronizer, self).__init__(version,
user,
password,
project,
auth_url)
self.conf = conf
@staticmethod
def filter_internal_zone(zones):

View File

@ -12,4 +12,28 @@
# License for the specific language governing permissions and limitations
# under the License.
__author__ = 'stack'
from oslo_config import cfg
OPTS = [
cfg.StrOpt('transformer',
default='vitrage.synchronizer.plugins.static_physical.'
'transformer.StaticPhysicalTransformer',
help='Static physical transformer class path',
required=True),
cfg.StrOpt('synchronizer',
default='vitrage.synchronizer.plugins.static_physical'
'.synchronizer.StaticPhysicalSynchronizer',
help='Static physical synchronizer class path',
required=True),
cfg.IntOpt('changes_interval',
default=30,
min=30,
help='interval between checking changes in the configuration'
'files of the physical topology plugin',
required=True),
cfg.StrOpt('directory', default='/etc/vitrage/static_plugins',
help='Static physical plugins directory'),
cfg.ListOpt('entities',
default=['switch'],
help='Static physical entity types list')
]

View File

@ -32,23 +32,23 @@ class StaticPhysicalSynchronizer(SynchronizerBase):
def get_all(self, sync_mode):
return self.make_pickleable(self._get_all_entities(),
EntityType.SWITCH,
EntityType.STATIC_PHYSICAL,
sync_mode)
def get_changes(self, sync_mode):
return self.make_pickleable(self._get_changes_entities(),
EntityType.SWITCH,
EntityType.STATIC_PHYSICAL,
sync_mode)
def _get_all_entities(self):
static_entities = []
if os.path.isdir(self.cfg.synchronizer_plugins.switch['dir']):
if os.path.isdir(self.cfg.static_physical.directory):
files = file_utils.load_files(
self.cfg.synchronizer_plugins.switch['dir'], '.yaml')
self.cfg.static_physical.directory, '.yaml')
for file in files:
full_path = self.cfg.synchronizer_plugins.switch['dir'] \
full_path = self.cfg.static_physical.directory \
+ '/' + file
static_entities += self._get_entities_from_file(file,
full_path)
@ -71,10 +71,10 @@ class StaticPhysicalSynchronizer(SynchronizerBase):
entities_updates = []
files = file_utils.load_files(
self.cfg.synchronizer_plugins.switch['dir'], '.yaml')
self.cfg.static_physical.directory, '.yaml')
for file in files:
full_path = self.cfg.synchronizer_plugins.switch['dir'] +\
full_path = self.cfg.static_physical.directory +\
'/' + file
config = file_utils.load_yaml_file(full_path)
if config:

View File

@ -31,6 +31,7 @@ class StaticPhysicalTransformer(transformer_base.TransformerBase):
RELATION_TYPE = 'relation_type'
RELATIONSHIPS_SECTION = 'relationships'
SWITCH = 'switch'
def __init__(self, transformers):
self.transformers = transformers
@ -159,8 +160,8 @@ class StaticPhysicalTransformer(transformer_base.TransformerBase):
def _register_relations_direction(self):
self.relation_direction = {}
relationship = (EntityType.SWITCH, EntityType.NOVA_HOST)
relationship = (self.SWITCH, EntityType.NOVA_HOST)
self.relation_direction[relationship] = True
relationship = (EntityType.SWITCH, EntityType.SWITCH)
relationship = (self.SWITCH, self.SWITCH)
self.relation_direction[relationship] = True

View File

@ -59,7 +59,7 @@ class SnapshotsService(SynchronizerService):
if self.first_time else SyncMode.SNAPSHOT
LOG.debug("start get all with sync mode %s" % sync_mode)
for plugin in self.registered_plugins:
for plugin in self.registered_plugins.values():
entities_dictionaries = plugin.get_all(sync_mode)
for entity in entities_dictionaries:
self.callback_function(entity)

View File

@ -51,6 +51,7 @@ class TestConsistencyFunctional(TestEntityGraphFunctionalBase):
self.conf.register_opts(self.PROCESSOR_OPTS, group='entity_graph')
self.conf.register_opts(self.PLUGINS_OPTS,
group='synchronizer_plugins')
self.load_plugins(self.conf)
self.processor = Processor(self.conf, self.initialization_status)
self.consistency_enforcer = ConsistencyEnforcer(
self.conf, self.processor.entity_graph, self.initialization_status)

View File

@ -34,6 +34,7 @@ class TestProcessorFunctional(TestEntityGraphFunctionalBase):
self.conf.register_opts(self.PROCESSOR_OPTS, group='entity_graph')
self.conf.register_opts(self.PLUGINS_OPTS,
group='synchronizer_plugins')
self.load_plugins(self.conf)
def test_create_entity_graph(self):
processor = self._create_processor_with_graph(self.conf)
@ -41,7 +42,6 @@ class TestProcessorFunctional(TestEntityGraphFunctionalBase):
# check number of entities
num_vertices = len(processor.entity_graph)
self.assertEqual(self._num_total_expected_vertices(), num_vertices)
# TODO(Alexey): add this check and to check also the number of edges
# check all entities create a tree and no free floating vertices exists
# it will be done only after we will have zone plugin

View File

@ -34,6 +34,7 @@ class TestStateManagerFunctional(TestEntityGraphFunctionalBase):
self.conf.register_opts(self.PROCESSOR_OPTS, group='entity_graph')
self.conf.register_opts(self.PLUGINS_OPTS,
group='synchronizer_plugins')
self.load_plugins(self.conf)
def test_state_on_update(self):
# setup

View File

@ -12,6 +12,7 @@
# License for the specific language governing permissions and limitations
# under the License.
import multiprocessing
from oslo_config import cfg
from oslo_log import log as logging
@ -23,6 +24,7 @@ from vitrage.evaluator.actions.base import ActionMode
from vitrage.evaluator.actions.base import ActionType
from vitrage.evaluator.template import ActionSpecs
from vitrage.evaluator.template_fields import TemplateFields as TFields
from vitrage.service import load_plugin
from vitrage.tests.functional.entity_graph.base import \
TestEntityGraphFunctionalBase
@ -37,6 +39,8 @@ class TestActionExecutor(TestEntityGraphFunctionalBase):
cls.conf.register_opts(cls.PROCESSOR_OPTS, group='entity_graph')
cls.conf.register_opts(cls.PLUGINS_OPTS,
group='synchronizer_plugins')
for plugin_name in cls.conf.synchronizer_plugins.plugin_type:
load_plugin(cls.conf, plugin_name)
def test_execute_update_vertex(self):

View File

@ -21,6 +21,7 @@ from vitrage.common.datetime_utils import utcnow
from vitrage.entity_graph.initialization_status import InitializationStatus
from vitrage.entity_graph.processor import processor as proc
import vitrage.graph.utils as graph_utils
from vitrage.service import load_plugin
from vitrage.tests import base
from vitrage.tests.mocks import mock_syncronizer as mock_sync
from vitrage.tests.mocks import utils
@ -32,71 +33,24 @@ class TestEntityGraphUnitBase(base.BaseTest):
cfg.StrOpt('states_plugins_dir',
default=utils.get_resources_dir() + '/states_plugins'),
]
PLUGINS_OPTS = [
PLUGINS_OPTS = [
cfg.ListOpt('plugin_type',
default=['nagios',
'nova.host',
'nova.instance',
'nova.zone'],
help='Names of supported synchronizer plugins'),
cfg.DictOpt('nagios',
default={
'synchronizer':
'vitrage.synchronizer.plugins.nagios.synchronizer',
'transformer': 'vitrage.synchronizer.plugins'
'.nagios.transformer.NagiosTransformer',
'user': '',
'password': '',
'url': '',
'config_file': '/etc/vitrage/nagios_conf.yaml'},),
cfg.DictOpt('nova.host',
default={
'synchronizer':
'vitrage.synchronizer.plugins.nova.host'
'.synchronizer',
'transformer': 'vitrage.synchronizer.plugins.nova'
'.host.transformer.HostTransformer',
'user': '',
'password': '',
'url': '',
'version': '2.0',
'project': 'admin'},),
cfg.DictOpt('nova.instance',
default={
'synchronizer':
'vitrage.synchronizer.plugins.nova.instance'
'.synchronizer',
'transformer':
'vitrage.synchronizer.plugins'
'.nova.instance.transformer.InstanceTransformer',
'user': '',
'password': '',
'url': '',
'version': '2.0',
'project': 'admin'},),
cfg.DictOpt('nova.zone',
default={
'synchronizer':
'vitrage.synchronizer.plugins.nova.zone'
'.synchronizer',
'transformer': 'vitrage.synchronizer.plugins.nova'
'.zone.transformer.ZoneTransformer',
'user': '',
'password': '',
'url': '',
'version': '2.0',
'project': 'admin'},),
]
NUM_NODES = 1
NUM_ZONES = 2
NUM_HOSTS = 4
NUM_INSTANCES = 16
def load_plugins(self, conf):
for plugin_name in conf.synchronizer_plugins.plugin_type:
load_plugin(self.conf, plugin_name)
def _create_processor_with_graph(self, conf, processor=None):
events = self._create_mock_events()

View File

@ -27,6 +27,7 @@ class TestBaseProcessor(TestEntityGraphUnitBase):
self.conf = cfg.ConfigOpts()
self.conf.register_opts(self.PLUGINS_OPTS,
group='synchronizer_plugins')
self.load_plugins(self.conf)
self.transform = transformer_manager.TransformerManager(self.conf)
@staticmethod

View File

@ -45,6 +45,7 @@ class TestProcessor(TestEntityGraphUnitBase):
self.conf.register_opts(self.PROCESSOR_OPTS, group='entity_graph')
self.conf.register_opts(self.PLUGINS_OPTS,
group='synchronizer_plugins')
self.load_plugins(self.conf)
# TODO(Alexey): un skip this test when instance transformer update is ready
@unittest.skip('Not ready yet')

View File

@ -15,9 +15,9 @@
from oslo_config import cfg
from vitrage.common.constants import EntityType
from vitrage.entity_graph.states.resource_state import NormalizedResourceState
from vitrage.entity_graph.states.state_manager import StateManager
from vitrage.service import load_plugin
from vitrage.tests import base
from vitrage.tests.mocks import utils
@ -28,73 +28,28 @@ class TestStateManager(base.BaseTest):
cfg.StrOpt('states_plugins_dir',
default=utils.get_resources_dir() + '/states_plugins'),
]
PLUGINS_OPTS = [
PLUGINS_OPTS = [
cfg.ListOpt('plugin_type',
default=['nagios',
'nova.host',
'nova.instance',
'nova.zone'],
help='Names of supported synchronizer plugins'),
cfg.DictOpt('nagios',
default={
'synchronizer':
'vitrage.synchronizer.plugins.nagios.synchronizer',
'transformer': 'vitrage.synchronizer.plugins'
'.nagios.transformer.NagiosTransformer',
'user': '',
'password': '',
'url': '',
'config_file': '/etc/vitrage/nagios_conf.yaml'},),
cfg.DictOpt('nova.host',
default={
'synchronizer':
'vitrage.synchronizer.plugins.nova.host'
'.synchronizer',
'transformer': 'vitrage.synchronizer.plugins.nova'
'.host.transformer.HostTransformer',
'user': '',
'password': '',
'url': '',
'version': '2.0',
'project': 'admin'},),
cfg.DictOpt('nova.instance',
default={
'synchronizer':
'vitrage.synchronizer.plugins.nova.instance'
'.synchronizer',
'transformer':
'vitrage.synchronizer.plugins'
'.nova.instance.transformer.InstanceTransformer',
'user': '',
'password': '',
'url': '',
'version': '2.0',
'project': 'admin'},),
cfg.DictOpt('nova.zone',
default={
'synchronizer':
'vitrage.synchronizer.plugins.nova.zone'
'.synchronizer',
'transformer': 'vitrage.synchronizer.plugins.nova'
'.zone.transformer.ZoneTransformer',
'user': '',
'password': '',
'url': '',
'version': '2.0',
'project': 'admin'},),
]
@staticmethod
def _load_plugins(conf):
for plugin_name in conf.synchronizer_plugins.plugin_type:
load_plugin(conf, plugin_name)
def setUp(self):
super(TestStateManager, self).setUp()
self.conf = cfg.ConfigOpts()
self.conf.register_opts(self.ENTITY_GRAPH_OPTS, group='entity_graph')
self.conf.register_opts(self.PLUGINS_OPTS,
group='synchronizer_plugins')
self._load_plugins(self.conf)
def test_load_state_plugins_without_errors(self):
# action
@ -114,6 +69,7 @@ class TestStateManager(base.BaseTest):
conf = cfg.ConfigOpts()
conf.register_opts(entity_graph_opts, group='entity_graph')
conf.register_opts(self.PLUGINS_OPTS, group='synchronizer_plugins')
self._load_plugins(conf)
# action
state_manager = StateManager(conf)

View File

@ -45,7 +45,7 @@ HOST = EntityType.NOVA_HOST
INSTANCE = EntityType.NOVA_INSTANCE
OPENSTACK_NODE = EntityType.OPENSTACK_NODE
TEST = 'TEST'
SWITCH = EntityType.SWITCH
SWITCH = 'switch'
ALARM_ON_VM = 'ALARM_ON_VM'
ALARM_ON_HOST = 'ALARM_ON_HOST'
TEST_ON_HOST = 'TEST_ON_HOST'

View File

@ -25,19 +25,31 @@ LOG = logging.getLogger(__name__)
class TestNagiosConfig(base.BaseTest):
OPTS = [
cfg.DictOpt('nagios',
default={
'synchronizer':
'vitrage.synchronizer.plugins.nagios.synchronizer'
'.NagiosSynchronizer',
'transformer': 'vitrage.synchronizer.plugins'
'.nagios.transformer.NagiosTransformer',
'user': '',
'password': '',
'url': '',
'config_file': utils.get_resources_dir() +
'/nagios/nagios_conf.yaml'},)
]
cfg.StrOpt('transformer',
default='vitrage.synchronizer.plugins.nagios.'
'transformer.NagiosTransformer',
help='Nagios plugin transformer class path',
required=True),
cfg.StrOpt('synchronizer',
default='vitrage.synchronizer.plugins.nagios.synchronizer'
'.NagiosSynchronizer',
help='Nagios plugin synchronizer class path',
required=True),
cfg.IntOpt('changes_interval',
default=30,
min=30,
help='interval between checking changes in nagios plugin',
required=True),
cfg.StrOpt('user', default='nagiosadmin',
help='Nagios user name'),
cfg.StrOpt('password', default='nagiosadmin',
help='Nagios user password'),
cfg.StrOpt('url', default='', help='Nagios url'),
cfg.StrOpt('config_file',
default=utils.get_resources_dir() +
'/nagios/nagios_conf.yaml',
help='Nagios configuration file'),
]
# the mappings match the ones in nagios_conf.yaml
MAPPING_1 = NagiosHostMapping('compute-1', 'nova.host', 'compute-1')
@ -60,7 +72,7 @@ class TestNagiosConfig(base.BaseTest):
@classmethod
def setUpClass(cls):
cls.conf = cfg.ConfigOpts()
cls.conf.register_opts(cls.OPTS, group='synchronizer_plugins')
cls.conf.register_opts(cls.OPTS, group='nagios')
def test_nagios_configuration_loading(self):
# Action

View File

@ -33,46 +33,59 @@ LOG = logging.getLogger(__name__)
class TestStaticPhysicalSynchronizer(base.BaseTest):
SWITCH = 'switch'
STATIC_PHYSICAL = EntityType.STATIC_PHYSICAL
OPTS = [
cfg.DictOpt('switch',
default={
'synchronizer':
'vitrage.synchronizer.plugins.static_physical'
'.synchronizer.StaticPhysicalSynchronizer',
'transformer':
'vitrage.synchronizer.plugins.static_physical.'
'transformer.StaticPhysicalTransformer',
'dir': utils.get_resources_dir() + '/static_plugins'},)
cfg.StrOpt('transformer',
default='vitrage.synchronizer.plugins.static_physical.'
'transformer.StaticPhysicalTransformer'),
cfg.StrOpt('synchronizer',
default='vitrage.synchronizer.plugins.static_physical'
'.synchronizer.StaticPhysicalTransformer'),
cfg.IntOpt('changes_interval',
default=30,
min=30,
help='interval between checking changes in the '
'configuration files of the physical topology plugin'),
cfg.StrOpt('directory',
default=utils.get_resources_dir() + '/static_plugins'),
cfg.ListOpt('entities',
default=['switch'])
]
CHANGES_OPTS = [
cfg.DictOpt('switch',
default={
'synchronizer':
'vitrage.synchronizer.plugins.static_physical'
'.synchronizer.StaticPhysicalSynchronizer',
'transformer':
'vitrage.synchronizer.plugins.static_physical.'
'transformer.StaticPhysicalTransformer',
'dir': utils.get_resources_dir() + '/static_plugins/'
'changes_plugins'},)
cfg.StrOpt('transformer',
default='vitrage.synchronizer.plugins.static_physical.'
'transformer.StaticPhysicalTransformer'),
cfg.StrOpt('synchronizer',
default='vitrage.synchronizer.plugins.static_physical'
'.synchronizer.StaticPhysicalTransformer'),
cfg.IntOpt('changes_interval',
default=30,
min=30,
help='interval between checking changes in the '
'configuration files of the physical topology plugin'),
cfg.StrOpt('directory',
default=utils.get_resources_dir() +
'/static_plugins/changes_plugins'),
]
def setUp(self):
super(TestStaticPhysicalSynchronizer, self).setUp()
self.conf = cfg.ConfigOpts()
self.conf.register_opts(self.OPTS, group='synchronizer_plugins')
self.conf.register_opts(self.OPTS, group=self.STATIC_PHYSICAL)
self.static_physical_synchronizer = \
synchronizer.StaticPhysicalSynchronizer(self.conf)
def test_static_plugins_loader(self):
# Setup
total_static_plugins = \
os.listdir(self.conf.synchronizer_plugins.switch['dir'])
os.listdir(self.conf.static_physical.directory)
# Action
static_configs = file_utils.load_yaml_files(
self.conf.synchronizer_plugins.switch['dir'])
self.conf.static_physical.directory)
# Test assertions
# -1 is because there are 2 files and a folder in static_plugins_dir
@ -93,7 +106,7 @@ class TestStaticPhysicalSynchronizer(base.BaseTest):
self.conf = cfg.ConfigOpts()
self.conf.register_opts(self.CHANGES_OPTS,
group='synchronizer_plugins')
group=self.STATIC_PHYSICAL)
self.static_physical_synchronizer.cfg = self.conf
# Action
@ -101,24 +114,24 @@ class TestStaticPhysicalSynchronizer(base.BaseTest):
EventAction.UPDATE_ENTITY)
# Test Assertions
status = any(change[VProps.TYPE] == EntityType.SWITCH and
status = any(change[VProps.TYPE] == self.SWITCH and
change[VProps.ID] == '12345' for change in changes)
self.assertEqual(False, status)
status = any(change[VProps.TYPE] == EntityType.SWITCH and
status = any(change[VProps.TYPE] == self.SWITCH and
change[VProps.ID] == '23456' and
change[SyncProps.EVENT_TYPE] == EventAction.DELETE_ENTITY
for change in changes)
self.assertEqual(True, status)
status = any(change[VProps.TYPE] == EntityType.SWITCH and
status = any(change[VProps.TYPE] == self.SWITCH and
change[VProps.ID] == '34567' for change in changes)
self.assertEqual(True, status)
status = any(change[VProps.TYPE] == EntityType.SWITCH and
status = any(change[VProps.TYPE] == self.SWITCH and
change[VProps.ID] == '45678' for change in changes)
self.assertEqual(True, status)
status = any(change[VProps.TYPE] == EntityType.SWITCH and
status = any(change[VProps.TYPE] == self.SWITCH and
change[VProps.ID] == '56789' for change in changes)
self.assertEqual(True, status)

View File

@ -40,7 +40,7 @@ class TestStaticPhysicalTransformer(base.BaseTest):
host_transformer = HostTransformer(self.transformers)
static_transformer = StaticPhysicalTransformer(self.transformers)
self.transformers[EntityType.NOVA_HOST] = host_transformer
self.transformers[EntityType.SWITCH] = static_transformer
self.transformers[EntityType.STATIC_PHYSICAL] = static_transformer
def test_create_placeholder_vertex(self):
@ -48,7 +48,7 @@ class TestStaticPhysicalTransformer(base.BaseTest):
'vertex')
# Test setup
switch_type = EntityType.SWITCH
switch_type = EntityType.STATIC_PHYSICAL
switch_name = 'switch-1'
timestamp = datetime.datetime.utcnow()
static_transformer = StaticPhysicalTransformer(self.transformers)
@ -88,7 +88,7 @@ class TestStaticPhysicalTransformer(base.BaseTest):
LOG.debug('Static Physical transformer test: get key values')
# Test setup
switch_type = EntityType.SWITCH
switch_type = EntityType.STATIC_PHYSICAL
switch_name = 'switch-1'
static_transformer = StaticPhysicalTransformer(self.transformers)
@ -99,7 +99,7 @@ class TestStaticPhysicalTransformer(base.BaseTest):
# Test assertions
self.assertEqual(EntityCategory.RESOURCE, observed_key_fields[0])
self.assertEqual(EntityType.SWITCH, observed_key_fields[1])
self.assertEqual(EntityType.STATIC_PHYSICAL, observed_key_fields[1])
self.assertEqual(switch_name, observed_key_fields[2])
def test_snapshot_transform(self):

View File

@ -17,6 +17,7 @@ from oslo_log import log as logging
from vitrage.common.constants import EntityType
from vitrage.entity_graph.transformer_manager import TransformerManager
from vitrage.service import load_plugin
from vitrage.synchronizer.plugins.nagios.transformer import \
NagiosTransformer
from vitrage.synchronizer.plugins.nova.host.transformer import \
@ -33,70 +34,20 @@ LOG = logging.getLogger(__name__)
class TransformerManagerTest(base.BaseTest):
OPTS = [
cfg.ListOpt('plugin_type',
default=['nagios',
'nova.host',
'nova.instance',
'nova.zone'],
help='Names of supported synchronizer plugins'),
cfg.DictOpt('nagios',
default={
'synchronizer':
'vitrage.synchronizer.plugins.nagios.synchronizer',
'transformer': 'vitrage.synchronizer.plugins'
'.nagios.transformer.NagiosTransformer',
'user': '',
'password': '',
'url': '',
'config_file': '/etc/vitrage/nagios_conf.yaml'},),
cfg.DictOpt('nova.host',
default={
'synchronizer':
'vitrage.synchronizer.plugins.nova.host'
'.synchronizer',
'transformer': 'vitrage.synchronizer.plugins.nova'
'.host.transformer.HostTransformer',
'user': '',
'password': '',
'url': '',
'version': '2.0',
'project': 'admin'},),
cfg.DictOpt('nova.instance',
default={
'synchronizer':
'vitrage.synchronizer.plugins.nova.instance'
'.synchronizer',
'transformer':
'vitrage.synchronizer.plugins'
'.nova.instance.transformer.InstanceTransformer',
'user': '',
'password': '',
'url': '',
'version': '2.0',
'project': 'admin'},),
cfg.DictOpt('nova.zone',
default={
'synchronizer':
'vitrage.synchronizer.plugins.nova.zone'
'.synchronizer',
'transformer': 'vitrage.synchronizer.plugins.nova'
'.zone.transformer.ZoneTransformer',
'user': '',
'password': '',
'url': '',
'version': '2.0',
'project': 'admin'},),
]
@classmethod
def setUpClass(cls):
cls.conf = cfg.ConfigOpts()
cls.conf.register_opts(cls.OPTS, group='synchronizer_plugins')
for plugin_name in cls.conf.synchronizer_plugins.plugin_type:
load_plugin(cls.conf, plugin_name)
cls.manager = TransformerManager(cls.conf)
def test_transformer_registration_nagios(self):