aboutsummaryrefslogtreecommitdiffstats
path: root/os_net_config/objects.py
diff options
context:
space:
mode:
authorDan Prince <dprince@redhat.com>2014-07-01 13:59:18 -0400
committerDan Prince <dprince@redhat.com>2014-07-01 13:59:18 -0400
commita58503a27b67571b8a534b43fc7e614b5557b64e (patch)
tree7abe039c9b298a29056807e81d4fb3502326bf06 /os_net_config/objects.py
parent2c18d75b41199ae673d07df8c0ee3e53d6ba9863 (diff)
Implement object json parsing functions.
Adds a from_json static method to all objects. Also adds a top level object_from_json function that can be used for all the interface and bridge types. (everything except addresses and routes). This should be useful for wiring processing JSON from the CLI.
Diffstat (limited to 'os_net_config/objects.py')
-rw-r--r--os_net_config/objects.py127
1 files changed, 121 insertions, 6 deletions
diff --git a/os_net_config/objects.py b/os_net_config/objects.py
index 45824de..10f3060 100644
--- a/os_net_config/objects.py
+++ b/os_net_config/objects.py
@@ -13,12 +13,34 @@
# under the License.
import netaddr
+from openstack.common import strutils
-class NetworkObjectException(Exception):
+class InvalidConfigException(ValueError):
pass
+def object_from_json(json):
+ obj_type = json.get("type")
+ if obj_type == "interface":
+ return Interface.from_json(json)
+ elif obj_type == "vlan":
+ return Vlan.from_json(json)
+ elif obj_type == "ovs_bridge":
+ return OvsBridge.from_json(json)
+ elif obj_type == "ovs_bond":
+ return OvsBond.from_json(json)
+
+
+def _get_required_field(json, name, object_name):
+ field = json.get(name)
+ if not field:
+ msg = '%s JSON objects require \'%s\' to be configured.' \
+ % (object_name, name)
+ raise InvalidConfigException(msg)
+ return field
+
+
class Route(object):
"""Base class for network routes."""
@@ -27,17 +49,28 @@ class Route(object):
self.ip_netmask = ip_netmask
self.default = default
+ @staticmethod
+ def from_json(json):
+ next_hop = _get_required_field(json, 'next_hop', 'Route')
+ ip_netmask = json.get('ip_netmask', "")
+ default = strutils.bool_from_string(str(json.get('default', False)))
+ return Route(next_hop, ip_netmask, default)
+
class Address(object):
"""Base class for network addresses."""
- def __init__(self, ip_netmask, routes=[]):
+ def __init__(self, ip_netmask):
self.ip_netmask = ip_netmask
ip_nw = netaddr.IPNetwork(self.ip_netmask)
self.ip = str(ip_nw.ip)
self.netmask = str(ip_nw.netmask)
self.version = ip_nw.version
- self.routes = routes
+
+ @staticmethod
+ def from_json(json):
+ ip_netmask = _get_required_field(json, 'ip_netmask', 'Address')
+ return Address(ip_netmask)
class _BaseOpts(object):
@@ -70,6 +103,37 @@ class _BaseOpts(object):
return v6_addresses
+ @staticmethod
+ def base_opts_from_json(json):
+ use_dhcp = strutils.bool_from_string(str(json.get('use_dhcp', False)))
+ use_dhcpv6 = strutils.bool_from_string(str(json.get('use_dhcpv6',
+ False)))
+ mtu = json.get('mtu', 1500)
+ addresses = []
+ routes = []
+
+ # addresses
+ addresses_json = json.get('addresses')
+ if addresses_json:
+ if isinstance(addresses_json, list):
+ for address in addresses_json:
+ addresses.append(Address.from_json(address))
+ else:
+ msg = 'Addresses must be a list.'
+ raise InvalidConfigException(msg)
+
+ # routes
+ routes_json = json.get('routes')
+ if routes_json:
+ if isinstance(routes_json, list):
+ for route in routes_json:
+ routes.append(Route.from_json(route))
+ else:
+ msg = 'Routes must be a list.'
+ raise InvalidConfigException(msg)
+
+ return (use_dhcp, use_dhcpv6, addresses, routes, mtu)
+
class Interface(_BaseOpts):
"""Base class for network interfaces."""
@@ -79,11 +143,17 @@ class Interface(_BaseOpts):
super(Interface, self).__init__(name, use_dhcp, use_dhcpv6, addresses,
routes, mtu)
+ @staticmethod
+ def from_json(json):
+ name = _get_required_field(json, 'name', 'Interface')
+ opts = _BaseOpts.base_opts_from_json(json)
+ return Interface(name, *opts)
+
class Vlan(_BaseOpts):
"""Base class for VLANs.
- NOTE: the name parameter must be formated w/ vlan#### where ####
+ NOTE: the name parameter must be formated w/ vlan<num> where <num>
matches the vlan ID being used. Example: vlan5
"""
@@ -95,12 +165,19 @@ class Vlan(_BaseOpts):
self.vlan_id = int(vlan_id)
self.device = device
+ @staticmethod
+ def from_json(json):
+ device = _get_required_field(json, 'device', 'Vlan')
+ vlan_id = _get_required_field(json, 'vlan_id', 'Vlan')
+ opts = _BaseOpts.base_opts_from_json(json)
+ return Vlan(device, vlan_id, *opts)
+
class OvsBridge(_BaseOpts):
"""Base class for OVS bridges."""
def __init__(self, name, use_dhcp=False, use_dhcpv6=False, addresses=[],
- routes=[], members=[], mtu=1500, ovs_options=None):
+ routes=[], mtu=1500, members=[], ovs_options=None):
super(OvsBridge, self).__init__(name, use_dhcp, use_dhcpv6, addresses,
routes, mtu)
self.members = members
@@ -109,13 +186,51 @@ class OvsBridge(_BaseOpts):
member.bridge_name = name
member.ovs_port = True
+ @staticmethod
+ def from_json(json):
+ name = _get_required_field(json, 'name', 'OvsBridge')
+ opts = _BaseOpts.base_opts_from_json(json)
+ ovs_options = json.get('ovs_options')
+ members = []
+
+ # members
+ members_json = json.get('members')
+ if members_json:
+ if isinstance(members_json, list):
+ for member in members_json:
+ members.append(object_from_json(member))
+ else:
+ msg = 'Members must be a list.'
+ raise InvalidConfigException(msg)
+
+ return OvsBridge(name, *opts, members=members, ovs_options=ovs_options)
+
class OvsBond(_BaseOpts):
"""Base class for OVS bonds."""
def __init__(self, name, use_dhcp=False, use_dhcpv6=False, addresses=[],
- routes=[], members=[], mtu=1500, ovs_options=None):
+ routes=[], mtu=1500, members=[], ovs_options=None):
super(OvsBond, self).__init__(name, use_dhcp, use_dhcpv6, addresses,
routes, mtu)
self.members = members
self.ovs_options = ovs_options
+
+ @staticmethod
+ def from_json(json):
+ name = _get_required_field(json, 'name', 'OvsBond')
+ opts = _BaseOpts.base_opts_from_json(json)
+ ovs_options = json.get('ovs_options')
+ members = []
+
+ # members
+ members_json = json.get('members')
+ if members_json:
+ if isinstance(members_json, list):
+ for member in members_json:
+ members.append(object_from_json(member))
+ else:
+ msg = 'Members must be a list.'
+ raise InvalidConfigException(msg)
+
+ return OvsBond(name, *opts, members=members, ovs_options=ovs_options)