It simplifies the implementation of different types of flows by creating the concept of Section (e.g: match, action) and automatic accessors for all the provided Sections
Signed-off-by: Adrian Moreno <amore...@redhat.com> --- python/automake.mk | 1 + python/ovs/flows/flow.py | 125 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 126 insertions(+) create mode 100644 python/ovs/flows/flow.py diff --git a/python/automake.mk b/python/automake.mk index 5f7a44518..b7debfbd9 100644 --- a/python/automake.mk +++ b/python/automake.mk @@ -28,6 +28,7 @@ ovs_pyfiles = \ python/ovs/fcntl_win.py \ python/ovs/flows/__init__.py \ python/ovs/flows/decoders.py \ + python/ovs/flows/flow.py \ python/ovs/flows/kv.py \ python/ovs/flows/list.py \ python/ovs/json.py \ diff --git a/python/ovs/flows/flow.py b/python/ovs/flows/flow.py new file mode 100644 index 000000000..2456d5f87 --- /dev/null +++ b/python/ovs/flows/flow.py @@ -0,0 +1,125 @@ +""" Defines the Flow class. +""" + + +class Section(object): + """A flow can be seen as composed of different sections, e.g: + + [info] [match] actions=[actions] + + This class represents each of those sections. + + A section is basically a set of Key-Value pairs. Typically, they can be + expressed as a dictionary, for instance the "match" part of a flow can be + expressed as: + { + "nw_src": "192.168.1.1", + "nw_dst": "192.168.1.2", + } + However, some of them must be expressed as a list which allows for + duplicated keys. For instance, the "actions" section could be: + [ + { + "output": 32 + }, + { + "output": 33 + } + ] + + The is_list flag is used to discriminate this. + + Attributes: + name (str): Name of the section. + pos (int): Position within the overall flow string. + string (str): Section string. + data (list[KeyValue]): Parsed data of the section. + is_list (bool): Whether the key-values shall be expressed as a list + (i.e: it allows repeated keys). + """ + + def __init__(self, name, pos, string, data, is_list=False): + self.name = name + self.pos = pos + self.string = string + self.data = data + self.is_list = is_list + + def __str__(self): + return "{} (at {}): {}".format(self.name, self.pos, self.string) + + def __repr__(self): + return "%s('%s')" % (self.__class__.__name__, self) + + def dict(self): + return {self.name: self.format_data()} + + def format_data(self): + """Returns the section's key-values formatted in a dictionary or list + depending on the value of is_list flag. + """ + if self.is_list: + return [{item.key: item.value} for item in self.data] + else: + return {item.key: item.value for item in self.data} + + +class Flow(object): + """The Flow class is a base class for other types of concrete flows + (such as OFproto Flows or DPIF Flows). + + A flow is basically comprised of a number of sections. + For each section named {section_name}, the flow object will have the + following attributes: + - {section_name} will return the sections data in a formatted way. + - {section_name}_kv will return the sections data as a list of KeyValues. + + Args: + sections (list[Section]): List of sections that comprise the flow + orig (str): Original flow string. + id (Any): Optional; identifier that clients can use to uniqely identify + this flow. + """ + + def __init__(self, sections, orig="", id=None): + self._sections = sections + self._orig = orig + self._id = id + for section in sections: + setattr( + self, section.name, self.section(section.name).format_data() + ) + setattr( + self, + "{}_kv".format(section.name), + self.section(section.name).data, + ) + + def section(self, name): + """Return the section by name.""" + return next( + (sect for sect in self._sections if sect.name == name), None + ) + + @property + def id(self): + """Return the Flow ID.""" + return self._id + + @property + def sections(self): + """Return the all the sections in a list.""" + return self._sections + + @property + def orig(self): + """Return the original flow string.""" + return self._orig + + def dict(self): + """Returns the Flow information in a dictionary.""" + flow_dict = {"orig": self.orig} + for section in self.sections: + flow_dict.update(section.dict()) + + return flow_dict -- 2.34.1 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev