summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAlan Quillin <alanquillin@gmail.com>2016-05-03 12:54:28 -0400
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2016-05-10 05:31:24 +0900
commit7db022bf71fe3de9f6e7d4550e017c6d1cd70c10 (patch)
tree35091ac1cfacf73825765540ecb243d70902ae36
parentdbe67437428da79506f9d08050a81f8b28ac4699 (diff)
Enable filtering the OVSDB schema tables/columns
Adds the ability to filter the OVSDB scheme to only include specified tables from the config as well as filter out (exclude) specific table columns. If neither of the values are defined in the config, then the discovered schema is used unchanged. The is needed to calm down noise with unused tables/columns to help with scale problems on hosts with a large number of bridges and interfaces. Signed-off-by: Alan Quillin <alanquillin@gmail.com> Acked-By: Jason Kölker <jason@koelker.net> Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
-rw-r--r--ryu/services/protocols/ovsdb/client.py70
-rw-r--r--ryu/services/protocols/ovsdb/manager.py23
2 files changed, 90 insertions, 3 deletions
diff --git a/ryu/services/protocols/ovsdb/client.py b/ryu/services/protocols/ovsdb/client.py
index 7c20eb2a..0f62f86e 100644
--- a/ryu/services/protocols/ovsdb/client.py
+++ b/ryu/services/protocols/ovsdb/client.py
@@ -15,6 +15,7 @@
import collections
import errno
+import six
import uuid
from ovs import jsonrpc
@@ -132,6 +133,68 @@ def discover_system_id(idl):
return system_id
+def _filter_schemas(schemas, schema_tables, exclude_table_columns):
+ """Wrapper method for _filter_schema to filter multiple schemas."""
+ return [_filter_schema(s, schema_tables, exclude_table_columns)
+ for s in schemas]
+
+
+def _filter_schema(schema, schema_tables, exclude_table_columns):
+ """Filters a schema to only include the specified tables in the
+ schema_tables parameter. This will also filter out any colums for
+ included tables that reference tables that are not included
+ in the schema_tables parameter
+
+ :param schema: Schema dict to be filtered
+ :param schema_tables: List of table names to filter on.
+ EX: ['Bridge', 'Controller', 'Interface']
+ NOTE: This list is case sensitive.
+ :return: Schema dict:
+ filtered if the schema_table parameter contains table names,
+ else the original schema dict
+ """
+
+ tables = {}
+ for tbl_name, tbl_data in schema['tables'].iteritems():
+ if not schema_tables or tbl_name in schema_tables:
+ columns = {}
+
+ exclude_columns = exclude_table_columns.get(tbl_name, [])
+ for col_name, col_data in tbl_data['columns'].iteritems():
+ if col_name in exclude_columns:
+ continue
+
+ # NOTE(Alan Quillin) Needs to check and remove
+ # and columns that have references to tables that
+ # are not to be configured
+ type_ = col_data.get('type')
+ if type_:
+ if type_ and isinstance(type_, dict):
+ key = type_.get('key')
+ if key and isinstance(key, dict):
+ ref_tbl = key.get('refTable')
+ if ref_tbl and isinstance(ref_tbl,
+ six.string_types):
+ if ref_tbl not in schema_tables:
+ continue
+ value = type_.get('value')
+ if value and isinstance(value, dict):
+ ref_tbl = value.get('refTable')
+ if ref_tbl and isinstance(ref_tbl,
+ six.string_types):
+ if ref_tbl not in schema_tables:
+ continue
+
+ columns[col_name] = col_data
+
+ tbl_data['columns'] = columns
+ tables[tbl_name] = tbl_data
+
+ schema['tables'] = tables
+
+ return schema
+
+
# NOTE(jkoelker) Wrap ovs's Idl to accept an existing session, and
# trigger callbacks on changes
class Idl(idl.Idl):
@@ -218,7 +281,8 @@ class RemoteOvsdb(app_manager.RyuApp):
@classmethod
def factory(cls, sock, address, probe_interval=None, min_backoff=None,
- max_backoff=None, *args, **kwargs):
+ max_backoff=None, schema_tables=None,
+ schema_exclude_columns={}, *args, **kwargs):
ovs_stream = stream.Stream(sock, None, None)
connection = jsonrpc.Connection(ovs_stream)
schemas = discover_schemas(connection)
@@ -226,6 +290,10 @@ class RemoteOvsdb(app_manager.RyuApp):
if not schemas:
return
+ if schema_tables or schema_exclude_columns:
+ schemas = _filter_schemas(schemas, schema_tables,
+ schema_exclude_columns)
+
fsm = reconnect.Reconnect(now())
fsm.set_name('%s:%s' % address)
fsm.enable(now())
diff --git a/ryu/services/protocols/ovsdb/manager.py b/ryu/services/protocols/ovsdb/manager.py
index a2b8a7e2..86a2d1ff 100644
--- a/ryu/services/protocols/ovsdb/manager.py
+++ b/ryu/services/protocols/ovsdb/manager.py
@@ -36,7 +36,14 @@ opts = (cfg.StrOpt('address', default='0.0.0.0', help='OVSDB address'),
cfg.StrOpt('mngr-privkey', default=None, help='manager private key'),
cfg.StrOpt('mngr-cert', default=None, help='manager certificate'),
cfg.ListOpt('whitelist', default=[],
- help='Whitelist of address to allow to connect'))
+ help='Whitelist of address to allow to connect'),
+ cfg.ListOpt('schema-tables', default=[],
+ help='Tables in the OVSDB schema to configure'),
+ cfg.ListOpt('schema-exclude-columns', default=[],
+ help='Table columns in the OVSDB schema to filter out. '
+ 'Values should be in the format: <table>.<column>.'
+ 'Ex: Bridge.netflow,Interface.statistics')
+ )
cfg.CONF.register_opts(opts, 'ovsdb')
@@ -119,10 +126,22 @@ class OVSDB(app_manager.RyuApp):
return self.send_event(client_name, ev)
def _start_remote(self, sock, client_address):
+ schema_tables = cfg.CONF.ovsdb.schema_tables
+ schema_ex_col = {}
+ if cfg.CONF.ovsdb.schema_exclude_columns:
+ for c in cfg.CONF.ovsdb.schema_exclude_columns:
+ tbl, col = c.split('.')
+ if tbl in schema_ex_col:
+ schema_ex_col[tbl].append(col)
+ else:
+ schema_ex_col[tbl] = [col]
+
app = client.RemoteOvsdb.factory(sock, client_address,
probe_interval=self._probe_interval,
min_backoff=self._min_backoff,
- max_backoff=self._max_backoff)
+ max_backoff=self._max_backoff,
+ schema_tables=schema_tables,
+ schema_exclude_columns=schema_ex_col)
if app:
self._clients[app.name] = app