summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-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