Add Policy Based Routing Support to os-net-config
Add support for routing tables and rules, as well as a property to specify a routing table for each route to the impl_ifcfg implementation. This change adds a new top-level object in the network_config with type "route_table" to specify which route table IDs and names should be added to the /etc/iproute2/rt_table file. This change adds a "table" property to routes for each interface type, that allows the selection of which routing table to apply the route to. This change also adds a "rules" property to each interface type, which can be used to specify a list of rules. Each rule contains a rule string and an optional comment, both of which will be added to the /etc/sysconfig/network-scripts/rule-<iface> file. This change includes tests and changes to the schema for validation. Note that this change was based on the abandoned patch https://review.openstack.org/#/c/575712 and was recreated when that patch diverged too far from master branch. Change-Id: I6906d3b6923845af177faba6579fa255a2195bec Closes-bug: #1783297
This commit is contained in:
parent
0607a2ac29
commit
35832347e1
|
@ -0,0 +1,52 @@
|
|||
network_config:
|
||||
-
|
||||
type: route_table
|
||||
name: custom
|
||||
table_id: 200
|
||||
-
|
||||
type: route_table
|
||||
name: alternate
|
||||
table_id: 201
|
||||
-
|
||||
type: interface
|
||||
name: em1
|
||||
use_dhcp: false
|
||||
addresses:
|
||||
-
|
||||
ip_netmask: 192.0.2.1/24
|
||||
routes:
|
||||
-
|
||||
ip_netmask: 10.1.3.0/24
|
||||
next_hop: 192.0.2.5
|
||||
route_options: "metric 10"
|
||||
table: 200 # Use table ID or table name
|
||||
-
|
||||
ip_netmask: 0.0.0.0/0
|
||||
next_hop: 192.0.2.254
|
||||
default: true
|
||||
table: 200
|
||||
rules:
|
||||
- rule: "iif em1 table 200"
|
||||
comment: "Route incoming traffic to em1 with table 200"
|
||||
- rule: "from 192.0.2.0/24 table 200"
|
||||
comment: "Route all traffic from 192.0.2.0/24 with table 200"
|
||||
- rule: "add blackhole from 172.19.40.0/24 table 200"
|
||||
- rule: "add unreachable iif em1 from 192.168.1.0/24"
|
||||
-
|
||||
type: interface
|
||||
name: em2
|
||||
use_dhcp: false
|
||||
addresses:
|
||||
- ip_netmask: 10.0.2.1/24
|
||||
routes:
|
||||
-
|
||||
ip_netmask: 10.1.3.0/24
|
||||
next_hop: 10.0.2.253
|
||||
table: alternate # Use table ID or table name
|
||||
-
|
||||
default: true
|
||||
next_hop: 10.0.3.254
|
||||
route_options: "table alternate"
|
||||
rules:
|
||||
- rule: "iif em2 table alternate"
|
||||
- rule: "from 10.0.2.0/24 table alternate"
|
|
@ -50,6 +50,8 @@ class NetConfig(object):
|
|||
|
||||
:param obj: The object to add.
|
||||
"""
|
||||
if isinstance(obj, objects.RouteTable):
|
||||
self.add_route_table(obj)
|
||||
if isinstance(obj, objects.Interface):
|
||||
self.add_interface(obj)
|
||||
elif isinstance(obj, objects.Vlan):
|
||||
|
@ -115,6 +117,13 @@ class NetConfig(object):
|
|||
elif isinstance(obj, objects.ContrailVrouterDpdk):
|
||||
self.add_contrail_vrouter_dpdk(obj)
|
||||
|
||||
def add_route_table(self, route_table):
|
||||
"""Add a route table object to the net config object.
|
||||
|
||||
:param route_table: The RouteTable object to add.
|
||||
"""
|
||||
raise NotImplementedError("add_route_table is not implemented.")
|
||||
|
||||
def add_interface(self, interface):
|
||||
"""Add an Interface object to the net config object.
|
||||
|
||||
|
|
|
@ -235,8 +235,9 @@ def main(argv=sys.argv):
|
|||
return 1
|
||||
|
||||
for iface_json in iface_array:
|
||||
iface_json.update({'nic_mapping': iface_mapping})
|
||||
iface_json.update({'persist_mapping': persist_mapping})
|
||||
if iface_json.get('type') != 'route_table':
|
||||
iface_json.update({'nic_mapping': iface_mapping})
|
||||
iface_json.update({'persist_mapping': persist_mapping})
|
||||
|
||||
validation_errors = validator.validate_config(iface_array)
|
||||
if validation_errors:
|
||||
|
|
|
@ -31,6 +31,17 @@ logger = logging.getLogger(__name__)
|
|||
# Import the raw NetConfig object so we can call its methods
|
||||
netconfig = os_net_config.NetConfig()
|
||||
|
||||
_ROUTE_TABLE_DEFAULT = """# reserved values
|
||||
#
|
||||
255\tlocal
|
||||
254\tmain
|
||||
253\tdefault
|
||||
0\tunspec
|
||||
#
|
||||
# local
|
||||
#
|
||||
#1\tinr.ruhep\n"""
|
||||
|
||||
|
||||
def ifcfg_config_path(name):
|
||||
return "/etc/sysconfig/network-scripts/ifcfg-%s" % name
|
||||
|
@ -68,6 +79,14 @@ def route6_config_path(name):
|
|||
return "/etc/sysconfig/network-scripts/route6-%s" % name
|
||||
|
||||
|
||||
def route_rule_config_path(name):
|
||||
return "/etc/sysconfig/network-scripts/rule-%s" % name
|
||||
|
||||
|
||||
def route_table_config_path():
|
||||
return "/etc/iproute2/rt_tables"
|
||||
|
||||
|
||||
def cleanup_pattern():
|
||||
return "/etc/sysconfig/network-scripts/ifcfg-*"
|
||||
|
||||
|
@ -117,6 +136,8 @@ class IfcfgNetConfig(os_net_config.NetConfig):
|
|||
self.vlan_data = {}
|
||||
self.route_data = {}
|
||||
self.route6_data = {}
|
||||
self.route_table_data = {}
|
||||
self.rule_data = {}
|
||||
self.bridge_data = {}
|
||||
self.linuxbridge_data = {}
|
||||
self.linuxbond_data = {}
|
||||
|
@ -594,33 +615,62 @@ class IfcfgNetConfig(os_net_config.NetConfig):
|
|||
first_line6 = ""
|
||||
for route in routes:
|
||||
options = ""
|
||||
table = ""
|
||||
if route.route_options:
|
||||
options = " %s" % (route.route_options)
|
||||
options = " %s" % route.route_options
|
||||
if route.route_table:
|
||||
if route.route_options.find('table ') == -1:
|
||||
table = " table %s" % route.route_table
|
||||
if ":" not in route.next_hop:
|
||||
# Route is an IPv4 route
|
||||
if route.default:
|
||||
first_line = "default via %s dev %s%s\n" % (
|
||||
first_line = "default via %s dev %s%s%s\n" % (
|
||||
route.next_hop, interface_name,
|
||||
options)
|
||||
table, options)
|
||||
else:
|
||||
data += "%s via %s dev %s%s\n" % (
|
||||
data += "%s via %s dev %s%s%s\n" % (
|
||||
route.ip_netmask, route.next_hop,
|
||||
interface_name, options)
|
||||
interface_name, table, options)
|
||||
else:
|
||||
# Route is an IPv6 route
|
||||
if route.default:
|
||||
first_line6 = "default via %s dev %s%s\n" % (
|
||||
first_line6 = "default via %s dev %s%s%s\n" % (
|
||||
route.next_hop, interface_name,
|
||||
options)
|
||||
table, options)
|
||||
else:
|
||||
data6 += "%s via %s dev %s%s\n" % (
|
||||
data6 += "%s via %s dev %s%s%s\n" % (
|
||||
route.ip_netmask, route.next_hop,
|
||||
interface_name, options)
|
||||
interface_name, table, options)
|
||||
self.route_data[interface_name] = first_line + data
|
||||
self.route6_data[interface_name] = first_line6 + data6
|
||||
logger.debug('route data: %s' % self.route_data[interface_name])
|
||||
logger.debug('ipv6 route data: %s' % self.route6_data[interface_name])
|
||||
|
||||
def _add_rules(self, interface, rules):
|
||||
"""Add RouteRule objects to an interface.
|
||||
|
||||
:param interface: the name of the interface to apply rules.
|
||||
:param rules: the list of rules to apply to the interface.
|
||||
"""
|
||||
logger.info('adding route rules for interface: %s' % interface)
|
||||
data = ""
|
||||
first_line = "# This file is autogenerated by os-net-config\n"
|
||||
for rule in rules:
|
||||
if rule.comment:
|
||||
data += "# %s\n" % rule.comment
|
||||
data += "%s\n" % rule.rule
|
||||
self.rule_data[interface] = first_line + data
|
||||
logger.debug('rules for interface: %s' % self.rule_data[interface])
|
||||
|
||||
def add_route_table(self, route_table):
|
||||
"""Add a RouteTable object to the net config object.
|
||||
|
||||
:param route_table: the RouteTable object to add.
|
||||
"""
|
||||
logger.info('adding route table: %s %s' % (route_table.table_id,
|
||||
route_table.name))
|
||||
self.route_table_data[int(route_table.table_id)] = route_table.name
|
||||
|
||||
def add_interface(self, interface):
|
||||
"""Add an Interface object to the net config object.
|
||||
|
||||
|
@ -632,6 +682,8 @@ class IfcfgNetConfig(os_net_config.NetConfig):
|
|||
self.interface_data[interface.name] = data
|
||||
if interface.routes:
|
||||
self._add_routes(interface.name, interface.routes)
|
||||
if interface.rules:
|
||||
self._add_rules(interface.name, interface.rules)
|
||||
|
||||
if interface.renamed:
|
||||
logger.info("Interface %s being renamed to %s"
|
||||
|
@ -649,6 +701,8 @@ class IfcfgNetConfig(os_net_config.NetConfig):
|
|||
self.vlan_data[vlan.name] = data
|
||||
if vlan.routes:
|
||||
self._add_routes(vlan.name, vlan.routes)
|
||||
if vlan.rules:
|
||||
self._add_rules(vlan.name, vlan.rules)
|
||||
|
||||
def add_ivs_interface(self, ivs_interface):
|
||||
"""Add a ivs_interface object to the net config object.
|
||||
|
@ -661,6 +715,8 @@ class IfcfgNetConfig(os_net_config.NetConfig):
|
|||
self.ivsinterface_data[ivs_interface.name] = data
|
||||
if ivs_interface.routes:
|
||||
self._add_routes(ivs_interface.name, ivs_interface.routes)
|
||||
if ivs_interface.rules:
|
||||
self._add_rules(ivs_interface.name, ivs_interface.rules)
|
||||
|
||||
def add_nfvswitch_internal(self, nfvswitch_internal):
|
||||
"""Add a nfvswitch_internal interface object to the net config object.
|
||||
|
@ -674,6 +730,8 @@ class IfcfgNetConfig(os_net_config.NetConfig):
|
|||
self.nfvswitch_intiface_data[iface_name] = data
|
||||
if nfvswitch_internal.routes:
|
||||
self._add_routes(iface_name, nfvswitch_internal.routes)
|
||||
if nfvswitch_internal.rules:
|
||||
self._add_rules(iface_name, nfvswitch_internal.rules)
|
||||
|
||||
def add_bridge(self, bridge):
|
||||
"""Add an OvsBridge object to the net config object.
|
||||
|
@ -686,6 +744,8 @@ class IfcfgNetConfig(os_net_config.NetConfig):
|
|||
self.bridge_data[bridge.name] = data
|
||||
if bridge.routes:
|
||||
self._add_routes(bridge.name, bridge.routes)
|
||||
if bridge.routes:
|
||||
self._add_rules(bridge.name, bridge.rules)
|
||||
|
||||
def add_ovs_user_bridge(self, bridge):
|
||||
"""Add an OvsUserBridge object to the net config object.
|
||||
|
@ -698,6 +758,8 @@ class IfcfgNetConfig(os_net_config.NetConfig):
|
|||
self.bridge_data[bridge.name] = data
|
||||
if bridge.routes:
|
||||
self._add_routes(bridge.name, bridge.routes)
|
||||
if bridge.rules:
|
||||
self._add_rules(bridge.name, bridge.rules)
|
||||
|
||||
def add_linux_bridge(self, bridge):
|
||||
"""Add a LinuxBridge object to the net config object.
|
||||
|
@ -710,6 +772,8 @@ class IfcfgNetConfig(os_net_config.NetConfig):
|
|||
self.linuxbridge_data[bridge.name] = data
|
||||
if bridge.routes:
|
||||
self._add_routes(bridge.name, bridge.routes)
|
||||
if bridge.rules:
|
||||
self._add_rules(bridge.name, bridge.rules)
|
||||
|
||||
def add_ivs_bridge(self, bridge):
|
||||
"""Add a IvsBridge object to the net config object.
|
||||
|
@ -744,6 +808,8 @@ class IfcfgNetConfig(os_net_config.NetConfig):
|
|||
self.interface_data[bond.name] = data
|
||||
if bond.routes:
|
||||
self._add_routes(bond.name, bond.routes)
|
||||
if bond.rules:
|
||||
self._add_rules(bond.name, bond.rules)
|
||||
|
||||
def add_linux_bond(self, bond):
|
||||
"""Add a LinuxBond object to the net config object.
|
||||
|
@ -756,6 +822,8 @@ class IfcfgNetConfig(os_net_config.NetConfig):
|
|||
self.linuxbond_data[bond.name] = data
|
||||
if bond.routes:
|
||||
self._add_routes(bond.name, bond.routes)
|
||||
if bond.rules:
|
||||
self._add_rules(bond.name, bond.rules)
|
||||
|
||||
def add_linux_team(self, team):
|
||||
"""Add a LinuxTeam object to the net config object.
|
||||
|
@ -768,6 +836,8 @@ class IfcfgNetConfig(os_net_config.NetConfig):
|
|||
self.linuxteam_data[team.name] = data
|
||||
if team.routes:
|
||||
self._add_routes(team.name, team.routes)
|
||||
if team.rules:
|
||||
self._add_rules(team.name, team.rules)
|
||||
|
||||
def add_ovs_tunnel(self, tunnel):
|
||||
"""Add a OvsTunnel object to the net config object.
|
||||
|
@ -800,6 +870,8 @@ class IfcfgNetConfig(os_net_config.NetConfig):
|
|||
self.ib_interface_data[ib_interface.name] = data
|
||||
if ib_interface.routes:
|
||||
self._add_routes(ib_interface.name, ib_interface.routes)
|
||||
if ib_interface.rules:
|
||||
self._add_rules(ib_interface.name, ib_interface.rules)
|
||||
|
||||
if ib_interface.renamed:
|
||||
logger.info("InfiniBand interface %s being renamed to %s"
|
||||
|
@ -847,6 +919,8 @@ class IfcfgNetConfig(os_net_config.NetConfig):
|
|||
self.interface_data[ovs_dpdk_bond.name] = data
|
||||
if ovs_dpdk_bond.routes:
|
||||
self._add_routes(ovs_dpdk_bond.name, ovs_dpdk_bond.routes)
|
||||
if ovs_dpdk_bond.rules:
|
||||
self._add_rules(ovs_dpdk_bond.name, ovs_dpdk_bond.rules)
|
||||
|
||||
def add_sriov_pf(self, sriov_pf):
|
||||
"""Add a SriovPF object to the net config object
|
||||
|
@ -872,6 +946,8 @@ class IfcfgNetConfig(os_net_config.NetConfig):
|
|||
self.interface_data[sriov_vf.name] = data
|
||||
if sriov_vf.routes:
|
||||
self._add_routes(sriov_vf.name, sriov_vf.routes)
|
||||
if sriov_vf.rules:
|
||||
self._add_rules(sriov_vf.name, sriov_vf.rules)
|
||||
|
||||
def add_vpp_interface(self, vpp_interface):
|
||||
"""Add a VppInterface object to the net config object
|
||||
|
@ -917,8 +993,9 @@ class IfcfgNetConfig(os_net_config.NetConfig):
|
|||
logger.debug('contrail data: %s' % data)
|
||||
self.interface_data[contrail_vrouter.name] = data
|
||||
if contrail_vrouter.routes:
|
||||
self._add_routes(contrail_vrouter.name,
|
||||
contrail_vrouter.routes)
|
||||
self._add_routes(contrail_vrouter.name, contrail_vrouter.routes)
|
||||
if contrail_vrouter.rules:
|
||||
self._add_rules(contrail_vrouter.name, contrail_vrouter.rules)
|
||||
|
||||
def add_contrail_vrouter_dpdk(self, contrail_vrouter_dpdk):
|
||||
"""Add a ContraiVrouterDpdk object to the net config object
|
||||
|
@ -947,6 +1024,9 @@ class IfcfgNetConfig(os_net_config.NetConfig):
|
|||
if contrail_vrouter_dpdk.routes:
|
||||
self._add_routes(contrail_vrouter_dpdk.name,
|
||||
contrail_vrouter_dpdk.routes)
|
||||
if contrail_vrouter_dpdk.rules:
|
||||
self._add_rules(contrail_vrouter_dpdk.name,
|
||||
contrail_vrouter_dpdk.rules)
|
||||
|
||||
def generate_ivs_config(self, ivs_uplinks, ivs_interfaces):
|
||||
"""Generate configuration content for ivs."""
|
||||
|
@ -991,6 +1071,56 @@ class IfcfgNetConfig(os_net_config.NetConfig):
|
|||
data = "SETUP_ARGS=\"%s%s%s\"" % (options_str, iface_str, internal_str)
|
||||
return data
|
||||
|
||||
def generate_route_table_config(self, route_tables):
|
||||
"""Generate configuration content for routing tables.
|
||||
|
||||
This method first extracts the existing route table definitions. If
|
||||
any non-default tables exist, they will be kept unless they conflict
|
||||
with new tables defined in the route_tables dict.
|
||||
|
||||
:param route_tables: A dict of RouteTable objects
|
||||
"""
|
||||
|
||||
custom_tables = {}
|
||||
res_ids = ['0', '253', '254', '255']
|
||||
res_names = ['unspec', 'default', 'main', 'local']
|
||||
rt_config = utils.get_file_data(route_table_config_path()).split('\n')
|
||||
rt_defaults = _ROUTE_TABLE_DEFAULT.split("\n")
|
||||
data = _ROUTE_TABLE_DEFAULT
|
||||
for line in (line for line in rt_config if line not in rt_defaults):
|
||||
# Leave non-standard comments intact in file
|
||||
if line.startswith('#') and not line.strip() in rt_defaults:
|
||||
data += "%s\n" % line
|
||||
# Ignore old managed entries, will be added back if in new config.
|
||||
elif line.find("# os-net-config managed table") == -1:
|
||||
id_name = line.split()
|
||||
# Keep custom tables if there is no conflict with new tables.
|
||||
if id_name[0].isdigit() and len(id_name) > 1:
|
||||
if not id_name[0] in res_ids:
|
||||
if not id_name[1] in res_names:
|
||||
if not int(id_name[0]) in route_tables:
|
||||
if not id_name[1] in route_tables.values():
|
||||
# Replicate line with any comments appended
|
||||
custom_tables[id_name[0]] = id_name[1]
|
||||
data += "%s\n" % line
|
||||
if custom_tables:
|
||||
logger.debug("Existing route tables: %s" % custom_tables)
|
||||
for id in sorted(route_tables):
|
||||
if str(id) in res_ids:
|
||||
message = "Table %s(%s) conflicts with reserved table %s(%s)" \
|
||||
% (route_tables[id], id,
|
||||
res_names[res_ids.index(str(id))], id)
|
||||
raise os_net_config.ConfigurationError(message)
|
||||
elif route_tables[id] in res_names:
|
||||
message = "Table %s(%s) conflicts with reserved table %s(%s)" \
|
||||
% (route_tables[id], id, route_tables[id],
|
||||
res_ids[res_names.index(route_tables[id])])
|
||||
raise os_net_config.ConfigurationError(message)
|
||||
else:
|
||||
data += "%s\t%s # os-net-config managed table\n" \
|
||||
% (id, route_tables[id])
|
||||
return data
|
||||
|
||||
def apply(self, cleanup=False, activate=True):
|
||||
"""Apply the network configuration.
|
||||
|
||||
|
@ -1031,9 +1161,11 @@ class IfcfgNetConfig(os_net_config.NetConfig):
|
|||
for interface_name, iface_data in self.interface_data.items():
|
||||
route_data = self.route_data.get(interface_name, '')
|
||||
route6_data = self.route6_data.get(interface_name, '')
|
||||
rule_data = self.rule_data.get(interface_name, '')
|
||||
interface_path = self.root_dir + ifcfg_config_path(interface_name)
|
||||
route_path = self.root_dir + route_config_path(interface_name)
|
||||
route6_path = self.root_dir + route6_config_path(interface_name)
|
||||
rule_path = self.root_dir + route_rule_config_path(interface_name)
|
||||
all_file_names.append(interface_path)
|
||||
all_file_names.append(route_path)
|
||||
all_file_names.append(route6_path)
|
||||
|
@ -1066,16 +1198,21 @@ class IfcfgNetConfig(os_net_config.NetConfig):
|
|||
update_files[route6_path] = route6_data
|
||||
if interface_name not in restart_interfaces:
|
||||
apply_routes.append((interface_name, route6_data))
|
||||
if utils.diff(rule_path, rule_data):
|
||||
update_files[rule_path] = rule_data
|
||||
|
||||
for interface_name, iface_data in self.ivsinterface_data.items():
|
||||
route_data = self.route_data.get(interface_name, '')
|
||||
route6_data = self.route6_data.get(interface_name, '')
|
||||
rule_data = self.rule_data.get(interface_name, '')
|
||||
interface_path = self.root_dir + ifcfg_config_path(interface_name)
|
||||
route_path = self.root_dir + route_config_path(interface_name)
|
||||
route6_path = self.root_dir + route6_config_path(interface_name)
|
||||
rule_path = self.root_dir + route_rule_config_path(interface_name)
|
||||
all_file_names.append(interface_path)
|
||||
all_file_names.append(route_path)
|
||||
all_file_names.append(route6_path)
|
||||
all_file_names.append(rule_path)
|
||||
ivs_interfaces.append(interface_name)
|
||||
if utils.diff(interface_path, iface_data):
|
||||
if self.ifcfg_requires_restart(interface_path, iface_data):
|
||||
|
@ -1095,16 +1232,21 @@ class IfcfgNetConfig(os_net_config.NetConfig):
|
|||
update_files[route6_path] = route6_data
|
||||
if interface_name not in restart_interfaces:
|
||||
apply_routes.append((interface_name, route6_data))
|
||||
if utils.diff(rule_path, rule_data):
|
||||
update_files[rule_path] = rule_data
|
||||
|
||||
for iface_name, iface_data in self.nfvswitch_intiface_data.items():
|
||||
route_data = self.route_data.get(iface_name, '')
|
||||
route6_data = self.route6_data.get(iface_name, '')
|
||||
rule_data = self.rule_data.get(iface_name, '')
|
||||
iface_path = self.root_dir + ifcfg_config_path(iface_name)
|
||||
route_path = self.root_dir + route_config_path(iface_name)
|
||||
route6_path = self.root_dir + route6_config_path(iface_name)
|
||||
rule_path = self.root_dir + route_rule_config_path(iface_name)
|
||||
all_file_names.append(iface_path)
|
||||
all_file_names.append(route_path)
|
||||
all_file_names.append(route6_path)
|
||||
all_file_names.append(rule_path)
|
||||
nfvswitch_internal_ifaces.append(iface_name)
|
||||
if utils.diff(iface_path, iface_data):
|
||||
if self.ifcfg_requires_restart(iface_path, iface_data):
|
||||
|
@ -1124,16 +1266,21 @@ class IfcfgNetConfig(os_net_config.NetConfig):
|
|||
update_files[route6_path] = route6_data
|
||||
if iface_name not in restart_interfaces:
|
||||
apply_routes.append((iface_name, route6_data))
|
||||
if utils.diff(rule_path, rule_data):
|
||||
update_files[rule_path] = rule_data
|
||||
|
||||
for bridge_name, bridge_data in self.bridge_data.items():
|
||||
route_data = self.route_data.get(bridge_name, '')
|
||||
route6_data = self.route6_data.get(bridge_name, '')
|
||||
rule_data = self.rule_data.get(bridge_name, '')
|
||||
bridge_path = self.root_dir + bridge_config_path(bridge_name)
|
||||
br_route_path = self.root_dir + route_config_path(bridge_name)
|
||||
br_route6_path = self.root_dir + route6_config_path(bridge_name)
|
||||
br_rule_path = self.root_dir + route_rule_config_path(bridge_name)
|
||||
all_file_names.append(bridge_path)
|
||||
all_file_names.append(br_route_path)
|
||||
all_file_names.append(br_route6_path)
|
||||
all_file_names.append(br_rule_path)
|
||||
if utils.diff(bridge_path, bridge_data):
|
||||
if self.ifcfg_requires_restart(bridge_path, bridge_data):
|
||||
restart_bridges.append(bridge_name)
|
||||
|
@ -1156,16 +1303,21 @@ class IfcfgNetConfig(os_net_config.NetConfig):
|
|||
update_files[br_route6_path] = route6_data
|
||||
if bridge_name not in restart_interfaces:
|
||||
apply_routes.append((bridge_name, route6_data))
|
||||
if utils.diff(br_rule_path, rule_data):
|
||||
update_files[br_rule_path] = rule_data
|
||||
|
||||
for bridge_name, bridge_data in self.linuxbridge_data.items():
|
||||
route_data = self.route_data.get(bridge_name, '')
|
||||
route6_data = self.route6_data.get(bridge_name, '')
|
||||
rule_data = self.rule_data.get(bridge_name, '')
|
||||
bridge_path = self.root_dir + bridge_config_path(bridge_name)
|
||||
br_route_path = self.root_dir + route_config_path(bridge_name)
|
||||
br_route6_path = self.root_dir + route6_config_path(bridge_name)
|
||||
br_rule_path = self.root_dir + route_rule_config_path(bridge_name)
|
||||
all_file_names.append(bridge_path)
|
||||
all_file_names.append(br_route_path)
|
||||
all_file_names.append(br_route6_path)
|
||||
all_file_names.append(br_rule_path)
|
||||
if utils.diff(bridge_path, bridge_data):
|
||||
if self.ifcfg_requires_restart(bridge_path, bridge_data):
|
||||
restart_bridges.append(bridge_name)
|
||||
|
@ -1188,16 +1340,21 @@ class IfcfgNetConfig(os_net_config.NetConfig):
|
|||
update_files[route6_path] = route6_data
|
||||
if bridge_name not in restart_bridges:
|
||||
apply_routes.append((bridge_name, route6_data))
|
||||
if utils.diff(br_rule_path, rule_data):
|
||||
update_files[br_rule_path] = rule_data
|
||||
|
||||
for team_name, team_data in self.linuxteam_data.items():
|
||||
route_data = self.route_data.get(team_name, '')
|
||||
route6_data = self.route6_data.get(team_name, '')
|
||||
rule_data = self.rule_data.get(team_name, '')
|
||||
team_path = self.root_dir + bridge_config_path(team_name)
|
||||
team_route_path = self.root_dir + route_config_path(team_name)
|
||||
team_route6_path = self.root_dir + route6_config_path(team_name)
|
||||
team_rule_path = self.root_dir + route_rule_config_path(team_name)
|
||||
all_file_names.append(team_path)
|
||||
all_file_names.append(team_route_path)
|
||||
all_file_names.append(team_route6_path)
|
||||
all_file_names.append(team_rule_path)
|
||||
if utils.diff(team_path, team_data):
|
||||
if self.ifcfg_requires_restart(team_path, team_data):
|
||||
restart_linux_teams.append(team_name)
|
||||
|
@ -1221,16 +1378,21 @@ class IfcfgNetConfig(os_net_config.NetConfig):
|
|||
update_files[team_route6_path] = route6_data
|
||||
if team_name not in restart_linux_teams:
|
||||
apply_routes.append((team_name, route6_data))
|
||||
if utils.diff(team_rule_path, rule_data):
|
||||
update_files[team_rule_path] = rule_data
|
||||
|
||||
for bond_name, bond_data in self.linuxbond_data.items():
|
||||
route_data = self.route_data.get(bond_name, '')
|
||||
route6_data = self.route6_data.get(bond_name, '')
|
||||
rule_data = self.rule_data.get(bond_name, '')
|
||||
bond_path = self.root_dir + bridge_config_path(bond_name)
|
||||
bond_route_path = self.root_dir + route_config_path(bond_name)
|
||||
bond_route6_path = self.root_dir + route6_config_path(bond_name)
|
||||
bond_rule_path = self.root_dir + route_rule_config_path(bond_name)
|
||||
all_file_names.append(bond_path)
|
||||
all_file_names.append(bond_route_path)
|
||||
all_file_names.append(bond_route6_path)
|
||||
all_file_names.append(bond_rule_path)
|
||||
if utils.diff(bond_path, bond_data):
|
||||
if self.ifcfg_requires_restart(bond_path, bond_data):
|
||||
restart_linux_bonds.append(bond_name)
|
||||
|
@ -1254,17 +1416,22 @@ class IfcfgNetConfig(os_net_config.NetConfig):
|
|||
update_files[bond_route6_path] = route6_data
|
||||
if bond_name not in restart_linux_bonds:
|
||||
apply_routes.append((bond_name, route6_data))
|
||||
if utils.diff(bond_rule_path, rule_data):
|
||||
update_files[bond_rule_path] = rule_data
|
||||
|
||||
# Infiniband interfaces are handled similarly to Ethernet interfaces
|
||||
for interface_name, iface_data in self.ib_interface_data.items():
|
||||
route_data = self.route_data.get(interface_name, '')
|
||||
route6_data = self.route6_data.get(interface_name, '')
|
||||
rule_data = self.rule_data.get(interface_name, '')
|
||||
interface_path = self.root_dir + ifcfg_config_path(interface_name)
|
||||
route_path = self.root_dir + route_config_path(interface_name)
|
||||
route6_path = self.root_dir + route6_config_path(interface_name)
|
||||
rule_path = self.root_dir + route_rule_config_path(interface_name)
|
||||
all_file_names.append(interface_path)
|
||||
all_file_names.append(route_path)
|
||||
all_file_names.append(route6_path)
|
||||
all_file_names.append(rule_path)
|
||||
# TODO(dsneddon) determine if InfiniBand can be used with IVS
|
||||
if "IVS_BRIDGE" in iface_data:
|
||||
ivs_uplinks.append(interface_name)
|
||||
|
@ -1286,18 +1453,23 @@ class IfcfgNetConfig(os_net_config.NetConfig):
|
|||
update_files[route6_path] = route6_data
|
||||
if interface_name not in restart_interfaces:
|
||||
apply_routes.append((interface_name, route6_data))
|
||||
if utils.diff(rule_path, rule_data):
|
||||
update_files[rule_path] = rule_data
|
||||
|
||||
# NOTE(hjensas): Process the VLAN's last so that we know if the vlan's
|
||||
# parent interface is being restarted.
|
||||
for vlan_name, vlan_data in self.vlan_data.items():
|
||||
route_data = self.route_data.get(vlan_name, '')
|
||||
route6_data = self.route6_data.get(vlan_name, '')
|
||||
rule_data = self.rule_data.get(vlan_name, '')
|
||||
vlan_path = self.root_dir + ifcfg_config_path(vlan_name)
|
||||
vlan_route_path = self.root_dir + route_config_path(vlan_name)
|
||||
vlan_route6_path = self.root_dir + route6_config_path(vlan_name)
|
||||
vlan_rule_path = self.root_dir + route_rule_config_path(vlan_name)
|
||||
all_file_names.append(vlan_path)
|
||||
all_file_names.append(vlan_route_path)
|
||||
all_file_names.append(vlan_route6_path)
|
||||
all_file_names.append(vlan_rule_path)
|
||||
restarts_concatenated = itertools.chain(restart_interfaces,
|
||||
restart_bridges,
|
||||
restart_linux_bonds,
|
||||
|
@ -1325,6 +1497,8 @@ class IfcfgNetConfig(os_net_config.NetConfig):
|
|||
update_files[vlan_route6_path] = route6_data
|
||||
if vlan_name not in restart_vlans:
|
||||
apply_routes.append((vlan_name, route6_data))
|
||||
if utils.diff(vlan_rule_path, rule_data):
|
||||
update_files[vlan_rule_path] = rule_data
|
||||
|
||||
if self.vpp_interface_data or self.vpp_bond_data:
|
||||
vpp_path = self.root_dir + vpp_config_path()
|
||||
|
@ -1432,6 +1606,11 @@ class IfcfgNetConfig(os_net_config.NetConfig):
|
|||
for location, data in update_files.items():
|
||||
self.write_config(location, data)
|
||||
|
||||
if self.route_table_data:
|
||||
location = route_table_config_path()
|
||||
data = self.generate_route_table_config(self.route_table_data)
|
||||
self.write_config(location, data)
|
||||
|
||||
if ivs_uplinks or ivs_interfaces:
|
||||
location = ivs_config_path()
|
||||
data = self.generate_ivs_config(ivs_uplinks, ivs_interfaces)
|
||||
|
|
|
@ -39,6 +39,10 @@ class InvalidConfigException(ValueError):
|
|||
|
||||
def object_from_json(json):
|
||||
obj_type = json.get("type")
|
||||
if obj_type == "route_table":
|
||||
return RouteTable.from_json(json)
|
||||
if obj_type == "route_rule":
|
||||
return RouteRule.from_json(json)
|
||||
if obj_type == "interface":
|
||||
return Interface.from_json(json)
|
||||
elif obj_type == "vlan":
|
||||
|
@ -222,11 +226,12 @@ class Route(object):
|
|||
"""Base class for network routes."""
|
||||
|
||||
def __init__(self, next_hop, ip_netmask="", default=False,
|
||||
route_options=""):
|
||||
route_options="", route_table=None):
|
||||
self.next_hop = next_hop
|
||||
self.ip_netmask = ip_netmask
|
||||
self.default = default
|
||||
self.route_options = route_options
|
||||
self.route_table = route_table
|
||||
|
||||
@staticmethod
|
||||
def from_json(json):
|
||||
|
@ -249,7 +254,9 @@ class Route(object):
|
|||
ip_netmask = json.get('ip_netmask', json.get('destination', ""))
|
||||
route_options = json.get('route_options', "")
|
||||
default = strutils.bool_from_string(str(json.get('default', False)))
|
||||
return Route(next_hop, ip_netmask, default, route_options)
|
||||
route_options = json.get('route_options', "")
|
||||
route_table = json.get('table', "")
|
||||
return Route(next_hop, ip_netmask, default, route_options, route_table)
|
||||
|
||||
|
||||
class Address(object):
|
||||
|
@ -269,15 +276,56 @@ class Address(object):
|
|||
return Address(ip_netmask)
|
||||
|
||||
|
||||
class RouteRule(object):
|
||||
"""Base class for route rules."""
|
||||
|
||||
def __init__(self, rule, comment=""):
|
||||
self.rule = rule
|
||||
self.comment = comment
|
||||
|
||||
@staticmethod
|
||||
def from_json(json):
|
||||
rule = _get_required_field(json, 'rule', 'RouteRule')
|
||||
comment = json.get('comment', "")
|
||||
return RouteRule(rule, comment)
|
||||
|
||||
|
||||
class RouteTable(object):
|
||||
"""Base class for route tables for policy-based routing."""
|
||||
|
||||
def __init__(self, name, table_id):
|
||||
self.name = name
|
||||
self.table_id = table_id
|
||||
|
||||
@staticmethod
|
||||
def from_json(json):
|
||||
name = _get_required_field(json, 'name', 'RouteTable')
|
||||
table_id = _get_required_field(json, 'table_id', 'RouteTable')
|
||||
reserved_ids = [0, 253, 254, 255]
|
||||
reserved_names = ['unspec', 'default', 'main', 'local']
|
||||
if table_id in reserved_ids:
|
||||
msg = 'Route table "%s" conflicts with reserved table "%s %s"'\
|
||||
% (table_id, table_id,
|
||||
reserved_names[reserved_ids.index(table_id)])
|
||||
raise InvalidConfigException(msg)
|
||||
elif name in reserved_names:
|
||||
msg = 'Route table "%s" conflicts with reserved table "%s %s"'\
|
||||
% (name, reserved_ids[reserved_names.index(name)], name)
|
||||
raise InvalidConfigException(msg)
|
||||
return RouteTable(name, table_id)
|
||||
|
||||
|
||||
class _BaseOpts(object):
|
||||
"""Base abstraction for logical port options."""
|
||||
|
||||
def __init__(self, name, use_dhcp=False, use_dhcpv6=False, addresses=None,
|
||||
routes=None, mtu=None, primary=False, nic_mapping=None,
|
||||
persist_mapping=False, defroute=True, dhclient_args=None,
|
||||
dns_servers=None, nm_controlled=False, onboot=True):
|
||||
routes=None, rules=None, mtu=None, primary=False,
|
||||
nic_mapping=None, persist_mapping=False, defroute=True,
|
||||
dhclient_args=None, dns_servers=None, nm_controlled=False,
|
||||
onboot=True):
|
||||
addresses = addresses or []
|
||||
routes = routes or []
|
||||
rules = rules or []
|
||||
dns_servers = dns_servers or []
|
||||
mapped_nic_names = mapped_nics(nic_mapping)
|
||||
self.hwaddr = None
|
||||
|
@ -307,6 +355,7 @@ class _BaseOpts(object):
|
|||
self.use_dhcpv6 = use_dhcpv6
|
||||
self.addresses = addresses
|
||||
self.routes = routes
|
||||
self.rules = rules
|
||||
self.primary = primary
|
||||
self.defroute = defroute
|
||||
self.dhclient_args = dhclient_args
|
||||
|
@ -355,6 +404,7 @@ class _BaseOpts(object):
|
|||
primary = strutils.bool_from_string(str(json.get('primary', False)))
|
||||
addresses = []
|
||||
routes = []
|
||||
rules = []
|
||||
|
||||
# addresses
|
||||
addresses_json = json.get('addresses')
|
||||
|
@ -376,15 +426,25 @@ class _BaseOpts(object):
|
|||
msg = 'Routes must be a list.'
|
||||
raise InvalidConfigException(msg)
|
||||
|
||||
# rules
|
||||
rules_json = json.get('rules')
|
||||
if rules_json:
|
||||
if isinstance(rules_json, list):
|
||||
for rule in rules_json:
|
||||
rules.append(RouteRule.from_json(rule))
|
||||
else:
|
||||
msg = 'Routes must be a list.'
|
||||
raise InvalidConfigException(msg)
|
||||
|
||||
nic_mapping = json.get('nic_mapping')
|
||||
persist_mapping = json.get('persist_mapping')
|
||||
|
||||
if include_primary:
|
||||
return (use_dhcp, use_dhcpv6, addresses, routes, mtu, primary,
|
||||
nic_mapping, persist_mapping, defroute, dhclient_args,
|
||||
dns_servers, nm_controlled, onboot)
|
||||
return (use_dhcp, use_dhcpv6, addresses, routes, rules, mtu,
|
||||
primary, nic_mapping, persist_mapping, defroute,
|
||||
dhclient_args, dns_servers, nm_controlled, onboot)
|
||||
else:
|
||||
return (use_dhcp, use_dhcpv6, addresses, routes, mtu,
|
||||
return (use_dhcp, use_dhcpv6, addresses, routes, rules, mtu,
|
||||
nic_mapping, persist_mapping, defroute, dhclient_args,
|
||||
dns_servers, nm_controlled, onboot)
|
||||
|
||||
|
@ -393,16 +453,17 @@ class Interface(_BaseOpts):
|
|||
"""Base class for network interfaces."""
|
||||
|
||||
def __init__(self, name, use_dhcp=False, use_dhcpv6=False, addresses=None,
|
||||
routes=None, mtu=None, primary=False, nic_mapping=None,
|
||||
persist_mapping=False, defroute=True, dhclient_args=None,
|
||||
dns_servers=None, nm_controlled=False, onboot=True,
|
||||
ethtool_opts=None, hotplug=False):
|
||||
routes=None, rules=None, mtu=None, primary=False,
|
||||
nic_mapping=None, persist_mapping=False, defroute=True,
|
||||
dhclient_args=None, dns_servers=None, nm_controlled=False,
|
||||
onboot=True, ethtool_opts=None, hotplug=False):
|
||||
addresses = addresses or []
|
||||
routes = routes or []
|
||||
rules = rules or []
|
||||
dns_servers = dns_servers or []
|
||||
super(Interface, self).__init__(name, use_dhcp, use_dhcpv6, addresses,
|
||||
routes, mtu, primary, nic_mapping,
|
||||
persist_mapping, defroute,
|
||||
routes, rules, mtu, primary,
|
||||
nic_mapping, persist_mapping, defroute,
|
||||
dhclient_args, dns_servers,
|
||||
nm_controlled, onboot)
|
||||
self.ethtool_opts = ethtool_opts
|
||||
|
@ -426,16 +487,17 @@ class Vlan(_BaseOpts):
|
|||
"""
|
||||
|
||||
def __init__(self, device, vlan_id, use_dhcp=False, use_dhcpv6=False,
|
||||
addresses=None, routes=None, mtu=None, primary=False,
|
||||
nic_mapping=None, persist_mapping=False, defroute=True,
|
||||
dhclient_args=None, dns_servers=None, nm_controlled=False,
|
||||
onboot=True):
|
||||
addresses=None, routes=None, rules=None, mtu=None,
|
||||
primary=False, nic_mapping=None, persist_mapping=False,
|
||||
defroute=True, dhclient_args=None, dns_servers=None,
|
||||
nm_controlled=False, onboot=True):
|
||||
addresses = addresses or []
|
||||
routes = routes or []
|
||||
rules = rules or []
|
||||
dns_servers = dns_servers or []
|
||||
name = 'vlan%i' % vlan_id
|
||||
super(Vlan, self).__init__(name, use_dhcp, use_dhcpv6, addresses,
|
||||
routes, mtu, primary, nic_mapping,
|
||||
routes, rules, mtu, primary, nic_mapping,
|
||||
persist_mapping, defroute, dhclient_args,
|
||||
dns_servers, nm_controlled, onboot)
|
||||
self.vlan_id = int(vlan_id)
|
||||
|
@ -458,20 +520,21 @@ class IvsInterface(_BaseOpts):
|
|||
"""Base class for ivs interfaces."""
|
||||
|
||||
def __init__(self, vlan_id, name='ivs', use_dhcp=False, use_dhcpv6=False,
|
||||
addresses=None, routes=None, mtu=1500, primary=False,
|
||||
nic_mapping=None, persist_mapping=False, defroute=True,
|
||||
dhclient_args=None, dns_servers=None, nm_controlled=False,
|
||||
onboot=True):
|
||||
addresses=None, routes=None, rules=None, mtu=1500,
|
||||
primary=False, nic_mapping=None, persist_mapping=False,
|
||||
defroute=True, dhclient_args=None, dns_servers=None,
|
||||
nm_controlled=False, onboot=True):
|
||||
addresses = addresses or []
|
||||
routes = routes or []
|
||||
rules = rules or []
|
||||
dns_servers = dns_servers or []
|
||||
name_vlan = '%s%i' % (name, vlan_id)
|
||||
super(IvsInterface, self).__init__(name_vlan, use_dhcp, use_dhcpv6,
|
||||
addresses, routes, mtu, primary,
|
||||
nic_mapping, persist_mapping,
|
||||
defroute, dhclient_args,
|
||||
dns_servers, nm_controlled,
|
||||
onboot)
|
||||
addresses, routes, rules, mtu,
|
||||
primary, nic_mapping,
|
||||
persist_mapping, defroute,
|
||||
dhclient_args, dns_servers,
|
||||
nm_controlled, onboot)
|
||||
self.vlan_id = int(vlan_id)
|
||||
|
||||
@staticmethod
|
||||
|
@ -486,20 +549,22 @@ class NfvswitchInternal(_BaseOpts):
|
|||
"""Base class for nfvswitch internal interfaces."""
|
||||
|
||||
def __init__(self, vlan_id, name='nfvswitch', use_dhcp=False,
|
||||
use_dhcpv6=False, addresses=None, routes=None, mtu=1500,
|
||||
primary=False, nic_mapping=None, persist_mapping=False,
|
||||
defroute=True, dhclient_args=None, dns_servers=None,
|
||||
nm_controlled=False, onboot=True):
|
||||
use_dhcpv6=False, addresses=None, routes=None, rules=None,
|
||||
mtu=1500, primary=False, nic_mapping=None,
|
||||
persist_mapping=False, defroute=True, dhclient_args=None,
|
||||
dns_servers=None, nm_controlled=False, onboot=True):
|
||||
addresses = addresses or []
|
||||
routes = routes or []
|
||||
rules = rules or []
|
||||
dns_servers = dns_servers or []
|
||||
name_vlan = '%s%i' % (name, vlan_id)
|
||||
super(NfvswitchInternal, self).__init__(name_vlan, use_dhcp,
|
||||
use_dhcpv6, addresses, routes,
|
||||
mtu, primary, nic_mapping,
|
||||
persist_mapping, defroute,
|
||||
dhclient_args, dns_servers,
|
||||
nm_controlled, onboot)
|
||||
rules, mtu, primary,
|
||||
nic_mapping, persist_mapping,
|
||||
defroute, dhclient_args,
|
||||
dns_servers, nm_controlled,
|
||||
onboot)
|
||||
self.vlan_id = int(vlan_id)
|
||||
|
||||
@staticmethod
|
||||
|
@ -514,19 +579,21 @@ class OvsBridge(_BaseOpts):
|
|||
"""Base class for OVS bridges."""
|
||||
|
||||
def __init__(self, name, use_dhcp=False, use_dhcpv6=False, addresses=None,
|
||||
routes=None, mtu=None, members=None, ovs_options=None,
|
||||
ovs_extra=None, nic_mapping=None, persist_mapping=False,
|
||||
defroute=True, dhclient_args=None, dns_servers=None,
|
||||
nm_controlled=False, onboot=True, fail_mode=None):
|
||||
routes=None, rules=None, mtu=None, members=None,
|
||||
ovs_options=None, ovs_extra=None, nic_mapping=None,
|
||||
persist_mapping=False, defroute=True, dhclient_args=None,
|
||||
dns_servers=None, nm_controlled=False, onboot=True,
|
||||
fail_mode=None):
|
||||
|
||||
check_ovs_installed(self.__class__.__name__)
|
||||
|
||||
addresses = addresses or []
|
||||
routes = routes or []
|
||||
rules = rules or []
|
||||
members = members or []
|
||||
dns_servers = dns_servers or []
|
||||
super(OvsBridge, self).__init__(name, use_dhcp, use_dhcpv6, addresses,
|
||||
routes, mtu, False, nic_mapping,
|
||||
routes, rules, mtu, False, nic_mapping,
|
||||
persist_mapping, defroute,
|
||||
dhclient_args, dns_servers,
|
||||
nm_controlled, onboot)
|
||||
|
@ -574,9 +641,8 @@ class OvsBridge(_BaseOpts):
|
|||
@staticmethod
|
||||
def from_json(json):
|
||||
name = _get_required_field(json, 'name', 'OvsBridge')
|
||||
(use_dhcp, use_dhcpv6, addresses, routes, mtu, nic_mapping,
|
||||
persist_mapping, defroute,
|
||||
dhclient_args, dns_servers,
|
||||
(use_dhcp, use_dhcpv6, addresses, routes, rules, mtu, nic_mapping,
|
||||
persist_mapping, defroute, dhclient_args, dns_servers,
|
||||
nm_controlled, onboot) = _BaseOpts.base_opts_from_json(
|
||||
json, include_primary=False)
|
||||
ovs_options = json.get('ovs_options')
|
||||
|
@ -588,8 +654,8 @@ class OvsBridge(_BaseOpts):
|
|||
members = _update_members(json, nic_mapping, persist_mapping)
|
||||
|
||||
return OvsBridge(name, use_dhcp=use_dhcp, use_dhcpv6=use_dhcpv6,
|
||||
addresses=addresses, routes=routes, mtu=mtu,
|
||||
members=members, ovs_options=ovs_options,
|
||||
addresses=addresses, routes=routes, rules=rules,
|
||||
mtu=mtu, members=members, ovs_options=ovs_options,
|
||||
ovs_extra=ovs_extra, nic_mapping=nic_mapping,
|
||||
persist_mapping=persist_mapping, defroute=defroute,
|
||||
dhclient_args=dhclient_args, dns_servers=dns_servers,
|
||||
|
@ -601,19 +667,20 @@ class OvsUserBridge(_BaseOpts):
|
|||
"""Base class for OVS User bridges."""
|
||||
|
||||
def __init__(self, name, use_dhcp=False, use_dhcpv6=False, addresses=None,
|
||||
routes=None, mtu=None, members=None, ovs_options=None,
|
||||
ovs_extra=None, nic_mapping=None, persist_mapping=False,
|
||||
defroute=True, dhclient_args=None, dns_servers=None,
|
||||
nm_controlled=False, onboot=True, fail_mode=None):
|
||||
routes=None, rules=None, mtu=None, members=None,
|
||||
ovs_options=None, ovs_extra=None, nic_mapping=None,
|
||||
persist_mapping=False, defroute=True, dhclient_args=None,
|
||||
dns_servers=None, nm_controlled=False, onboot=True,
|
||||
fail_mode=None):
|
||||
|
||||
check_ovs_installed(self.__class__.__name__)
|
||||
|
||||
super(OvsUserBridge, self).__init__(name, use_dhcp, use_dhcpv6,
|
||||
addresses, routes, mtu, False,
|
||||
nic_mapping, persist_mapping,
|
||||
defroute, dhclient_args,
|
||||
dns_servers, nm_controlled,
|
||||
onboot)
|
||||
addresses, routes, rules, mtu,
|
||||
False, nic_mapping,
|
||||
persist_mapping, defroute,
|
||||
dhclient_args, dns_servers,
|
||||
nm_controlled, onboot)
|
||||
self.members = members or []
|
||||
self.ovs_options = ovs_options
|
||||
ovs_extra = ovs_extra or []
|
||||
|
@ -638,9 +705,8 @@ class OvsUserBridge(_BaseOpts):
|
|||
@staticmethod
|
||||
def from_json(json):
|
||||
name = _get_required_field(json, 'name', 'OvsUserBridge')
|
||||
(use_dhcp, use_dhcpv6, addresses, routes, mtu, nic_mapping,
|
||||
persist_mapping, defroute,
|
||||
dhclient_args, dns_servers,
|
||||
(use_dhcp, use_dhcpv6, addresses, routes, rules, mtu, nic_mapping,
|
||||
persist_mapping, defroute, dhclient_args, dns_servers,
|
||||
nm_controlled, onboot) = _BaseOpts.base_opts_from_json(
|
||||
json, include_primary=False)
|
||||
ovs_options = json.get('ovs_options')
|
||||
|
@ -652,8 +718,8 @@ class OvsUserBridge(_BaseOpts):
|
|||
members = _update_members(json, nic_mapping, persist_mapping)
|
||||
|
||||
return OvsUserBridge(name, use_dhcp=use_dhcp, use_dhcpv6=use_dhcpv6,
|
||||
addresses=addresses, routes=routes, mtu=mtu,
|
||||
members=members, ovs_options=ovs_options,
|
||||
addresses=addresses, routes=routes, rules=rules,
|
||||
mtu=mtu, members=members, ovs_options=ovs_options,
|
||||
ovs_extra=ovs_extra, nic_mapping=nic_mapping,
|
||||
persist_mapping=persist_mapping,
|
||||
defroute=defroute, dhclient_args=dhclient_args,
|
||||
|
@ -666,15 +732,17 @@ class LinuxBridge(_BaseOpts):
|
|||
"""Base class for Linux bridges."""
|
||||
|
||||
def __init__(self, name, use_dhcp=False, use_dhcpv6=False, addresses=None,
|
||||
routes=None, mtu=None, members=None, nic_mapping=None,
|
||||
persist_mapping=False, defroute=True, dhclient_args=None,
|
||||
dns_servers=None, nm_controlled=False, onboot=True):
|
||||
routes=None, rules=None, mtu=None, members=None,
|
||||
nic_mapping=None, persist_mapping=False, defroute=True,
|
||||
dhclient_args=None, dns_servers=None, nm_controlled=False,
|
||||
onboot=True):
|
||||
addresses = addresses or []
|
||||
routes = routes or []
|
||||
rules = rules or []
|
||||
members = members or []
|
||||
dns_servers = dns_servers or []
|
||||
super(LinuxBridge, self).__init__(name, use_dhcp, use_dhcpv6,
|
||||
addresses, routes, mtu, False,
|
||||
addresses, routes, rules, mtu, False,
|
||||
nic_mapping, persist_mapping,
|
||||
defroute, dhclient_args, dns_servers,
|
||||
nm_controlled, onboot)
|
||||
|
@ -694,16 +762,15 @@ class LinuxBridge(_BaseOpts):
|
|||
@staticmethod
|
||||
def from_json(json):
|
||||
name = _get_required_field(json, 'name', 'LinuxBridge')
|
||||
(use_dhcp, use_dhcpv6, addresses, routes, mtu, nic_mapping,
|
||||
persist_mapping, defroute, dhclient_args,
|
||||
dns_servers, nm_controlled, onboot) = _BaseOpts.base_opts_from_json(
|
||||
json, include_primary=False)
|
||||
(use_dhcp, use_dhcpv6, addresses, routes, rules, mtu, nic_mapping,
|
||||
persist_mapping, defroute, dhclient_args, dns_servers, nm_controlled,
|
||||
onboot) = _BaseOpts.base_opts_from_json(json, include_primary=False)
|
||||
|
||||
members = _update_members(json, nic_mapping, persist_mapping)
|
||||
|
||||
return LinuxBridge(name, use_dhcp=use_dhcp, use_dhcpv6=use_dhcpv6,
|
||||
addresses=addresses, routes=routes, mtu=mtu,
|
||||
members=members, nic_mapping=nic_mapping,
|
||||
addresses=addresses, routes=routes, rules=rules,
|
||||
mtu=mtu, members=members, nic_mapping=nic_mapping,
|
||||
persist_mapping=persist_mapping, defroute=defroute,
|
||||
dhclient_args=dhclient_args,
|
||||
dns_servers=dns_servers,
|
||||
|
@ -724,16 +791,17 @@ class IvsBridge(_BaseOpts):
|
|||
"""
|
||||
|
||||
def __init__(self, name='ivs', use_dhcp=False, use_dhcpv6=False,
|
||||
addresses=None, routes=None, mtu=1500, members=None,
|
||||
nic_mapping=None, persist_mapping=False, defroute=True,
|
||||
dhclient_args=None, dns_servers=None, nm_controlled=False,
|
||||
onboot=True):
|
||||
addresses=None, rules=None, routes=None,
|
||||
mtu=1500, members=None, nic_mapping=None,
|
||||
persist_mapping=False, defroute=True, dhclient_args=None,
|
||||
dns_servers=None, nm_controlled=False, onboot=True):
|
||||
addresses = addresses or []
|
||||
routes = routes or []
|
||||
rules = rules or []
|
||||
members = members or []
|
||||
dns_servers = dns_servers or []
|
||||
super(IvsBridge, self).__init__(name, use_dhcp, use_dhcpv6,
|
||||
addresses, routes, mtu, False,
|
||||
addresses, routes, rules, mtu, False,
|
||||
nic_mapping, persist_mapping,
|
||||
defroute, dhclient_args, dns_servers,
|
||||
nm_controlled, onboot)
|
||||
|
@ -749,16 +817,15 @@ class IvsBridge(_BaseOpts):
|
|||
@staticmethod
|
||||
def from_json(json):
|
||||
name = 'ivs'
|
||||
(use_dhcp, use_dhcpv6, addresses, routes, mtu, nic_mapping,
|
||||
persist_mapping, defroute, dhclient_args,
|
||||
dns_servers, nm_controlled, onboot) = _BaseOpts.base_opts_from_json(
|
||||
json, include_primary=False)
|
||||
(use_dhcp, use_dhcpv6, addresses, routes, rules, mtu, nic_mapping,
|
||||
persist_mapping, defroute, dhclient_args, dns_servers, nm_controlled,
|
||||
onboot) = _BaseOpts.base_opts_from_json(json, include_primary=False)
|
||||
|
||||
members = _update_members(json, nic_mapping, persist_mapping)
|
||||
|
||||
return IvsBridge(name, use_dhcp=use_dhcp, use_dhcpv6=use_dhcpv6,
|
||||
addresses=addresses, routes=routes, mtu=mtu,
|
||||
members=members, nic_mapping=nic_mapping,
|
||||
addresses=addresses, routes=routes, rules=rules,
|
||||
mtu=mtu, members=members, nic_mapping=nic_mapping,
|
||||
persist_mapping=persist_mapping, defroute=defroute,
|
||||
dhclient_args=dhclient_args,
|
||||
dns_servers=dns_servers, nm_controlled=nm_controlled,
|
||||
|
@ -774,20 +841,21 @@ class NfvswitchBridge(_BaseOpts):
|
|||
"""
|
||||
|
||||
def __init__(self, name='nfvswitch', use_dhcp=False, use_dhcpv6=False,
|
||||
addresses=None, routes=None, mtu=1500, members=None,
|
||||
nic_mapping=None, persist_mapping=False, defroute=True,
|
||||
dhclient_args=None, dns_servers=None, nm_controlled=False,
|
||||
onboot=True, options=""):
|
||||
addresses=None, routes=None, rules=None, mtu=1500,
|
||||
members=None, nic_mapping=None, persist_mapping=False,
|
||||
defroute=True, dhclient_args=None, dns_servers=None,
|
||||
nm_controlled=False, onboot=True, options=""):
|
||||
addresses = addresses or []
|
||||
routes = routes or []
|
||||
rules = rules or []
|
||||
members = members or []
|
||||
dns_servers = dns_servers or []
|
||||
super(NfvswitchBridge, self).__init__(name, use_dhcp, use_dhcpv6,
|
||||
addresses, routes, mtu, False,
|
||||
nic_mapping, persist_mapping,
|
||||
defroute, dhclient_args,
|
||||
dns_servers, nm_controlled,
|
||||
onboot)
|
||||
addresses, routes, rules, mtu,
|
||||
False, nic_mapping,
|
||||
persist_mapping, defroute,
|
||||
dhclient_args, dns_servers,
|
||||
nm_controlled, onboot)
|
||||
self.options = options
|
||||
self.members = members
|
||||
for member in self.members:
|
||||
|
@ -801,10 +869,9 @@ class NfvswitchBridge(_BaseOpts):
|
|||
@staticmethod
|
||||
def from_json(json):
|
||||
name = 'nfvswitch'
|
||||
(use_dhcp, use_dhcpv6, addresses, routes, mtu, nic_mapping,
|
||||
persist_mapping, defroute, dhclient_args,
|
||||
dns_servers, nm_controlled, onboot) = _BaseOpts.base_opts_from_json(
|
||||
json, include_primary=False)
|
||||
(use_dhcp, use_dhcpv6, addresses, routes, rules, mtu, nic_mapping,
|
||||
persist_mapping, defroute, dhclient_args, dns_servers, nm_controlled,
|
||||
onboot) = _BaseOpts.base_opts_from_json(json, include_primary=False)
|
||||
|
||||
members = _update_members(json, nic_mapping, persist_mapping)
|
||||
|
||||
|
@ -814,8 +881,9 @@ class NfvswitchBridge(_BaseOpts):
|
|||
raise InvalidConfigException(msg)
|
||||
|
||||
return NfvswitchBridge(name, use_dhcp=use_dhcp, use_dhcpv6=use_dhcpv6,
|
||||
addresses=addresses, routes=routes, mtu=mtu,
|
||||
members=members, nic_mapping=nic_mapping,
|
||||
addresses=addresses, routes=routes, rules=rules,
|
||||
mtu=mtu, members=members,
|
||||
nic_mapping=nic_mapping,
|
||||
persist_mapping=persist_mapping,
|
||||
defroute=defroute, dhclient_args=dhclient_args,
|
||||
dns_servers=dns_servers,
|
||||
|
@ -827,17 +895,18 @@ class LinuxTeam(_BaseOpts):
|
|||
"""Base class for Linux bonds using teamd."""
|
||||
|
||||
def __init__(self, name, use_dhcp=False, use_dhcpv6=False, addresses=None,
|
||||
routes=None, mtu=None, primary=False, members=None,
|
||||
bonding_options=None, nic_mapping=None, persist_mapping=False,
|
||||
defroute=True, dhclient_args=None, dns_servers=None,
|
||||
nm_controlled=False, onboot=True):
|
||||
routes=None, rules=None, mtu=None, primary=False,
|
||||
members=None, bonding_options=None, nic_mapping=None,
|
||||
persist_mapping=False, defroute=True, dhclient_args=None,
|
||||
dns_servers=None, nm_controlled=False, onboot=True):
|
||||
addresses = addresses or []
|
||||
routes = routes or []
|
||||
rules = rules or []
|
||||
members = members or []
|
||||
dns_servers = dns_servers or []
|
||||
super(LinuxTeam, self).__init__(name, use_dhcp, use_dhcpv6, addresses,
|
||||
routes, mtu, primary, nic_mapping,
|
||||
persist_mapping, defroute,
|
||||
routes, rules, mtu, primary,
|
||||
nic_mapping, persist_mapping, defroute,
|
||||
dhclient_args, dns_servers,
|
||||
nm_controlled, onboot)
|
||||
self.members = members
|
||||
|
@ -856,17 +925,17 @@ class LinuxTeam(_BaseOpts):
|
|||
@staticmethod
|
||||
def from_json(json):
|
||||
name = _get_required_field(json, 'name', 'LinuxTeam')
|
||||
(use_dhcp, use_dhcpv6, addresses, routes, mtu, nic_mapping,
|
||||
persist_mapping, defroute, dhclient_args,
|
||||
dns_servers, nm_controlled, onboot) = _BaseOpts.base_opts_from_json(
|
||||
json, include_primary=False)
|
||||
bonding_options = json.get('bonding_options')
|
||||
(use_dhcp, use_dhcpv6, addresses, routes, rules, mtu, nic_mapping,
|
||||
persist_mapping, defroute, dhclient_args, dns_servers, nm_controlled,
|
||||
onboot) = _BaseOpts.base_opts_from_json(json, include_primary=False)
|
||||
|
||||
bonding_options = json.get('bonding_options')
|
||||
members = _update_members(json, nic_mapping, persist_mapping)
|
||||
|
||||
return LinuxTeam(name, use_dhcp=use_dhcp, use_dhcpv6=use_dhcpv6,
|
||||
addresses=addresses, routes=routes, mtu=mtu,
|
||||
members=members, bonding_options=bonding_options,
|
||||
addresses=addresses, routes=routes, rules=rules,
|
||||
mtu=mtu, members=members,
|
||||
bonding_options=bonding_options,
|
||||
nic_mapping=nic_mapping,
|
||||
persist_mapping=persist_mapping, defroute=defroute,
|
||||
dhclient_args=dhclient_args, dns_servers=dns_servers,
|
||||
|
@ -877,17 +946,18 @@ class LinuxBond(_BaseOpts):
|
|||
"""Base class for Linux bonds."""
|
||||
|
||||
def __init__(self, name, use_dhcp=False, use_dhcpv6=False, addresses=None,
|
||||
routes=None, mtu=None, primary=False, members=None,
|
||||
bonding_options=None, nic_mapping=None, persist_mapping=False,
|
||||
defroute=True, dhclient_args=None, dns_servers=None,
|
||||
nm_controlled=False, onboot=True):
|
||||
routes=None, rules=None, mtu=None, primary=False,
|
||||
members=None, bonding_options=None, nic_mapping=None,
|
||||
persist_mapping=False, defroute=True, dhclient_args=None,
|
||||
dns_servers=None, nm_controlled=False, onboot=True):
|
||||
addresses = addresses or []
|
||||
routes = routes or []
|
||||
rules = rules or []
|
||||
members = members or []
|
||||
dns_servers = dns_servers or []
|
||||
super(LinuxBond, self).__init__(name, use_dhcp, use_dhcpv6, addresses,
|
||||
routes, mtu, primary, nic_mapping,
|
||||
persist_mapping, defroute,
|
||||
routes, rules, mtu, primary,
|
||||
nic_mapping, persist_mapping, defroute,
|
||||
dhclient_args, dns_servers,
|
||||
nm_controlled, onboot)
|
||||
self.members = members
|
||||
|
@ -928,7 +998,7 @@ class LinuxBond(_BaseOpts):
|
|||
@staticmethod
|
||||
def from_json(json):
|
||||
name = _get_required_field(json, 'name', 'LinuxBond')
|
||||
(use_dhcp, use_dhcpv6, addresses, routes, mtu, nic_mapping,
|
||||
(use_dhcp, use_dhcpv6, addresses, routes, rules, mtu, nic_mapping,
|
||||
persist_mapping, defroute, dhclient_args,
|
||||
dns_servers, nm_controlled, onboot) = _BaseOpts.base_opts_from_json(
|
||||
json, include_primary=False)
|
||||
|
@ -937,8 +1007,9 @@ class LinuxBond(_BaseOpts):
|
|||
members = _update_members(json, nic_mapping, persist_mapping)
|
||||
|
||||
return LinuxBond(name, use_dhcp=use_dhcp, use_dhcpv6=use_dhcpv6,
|
||||
addresses=addresses, routes=routes, mtu=mtu,
|
||||
members=members, bonding_options=bonding_options,
|
||||
addresses=addresses, routes=routes, rules=rules,
|
||||
mtu=mtu, members=members,
|
||||
bonding_options=bonding_options,
|
||||
nic_mapping=nic_mapping,
|
||||
persist_mapping=persist_mapping, defroute=defroute,
|
||||
dhclient_args=dhclient_args, dns_servers=dns_servers,
|
||||
|
@ -949,19 +1020,21 @@ class OvsBond(_BaseOpts):
|
|||
"""Base class for OVS bonds."""
|
||||
|
||||
def __init__(self, name, use_dhcp=False, use_dhcpv6=False, addresses=None,
|
||||
routes=None, mtu=None, primary=False, members=None,
|
||||
ovs_options=None, ovs_extra=None, nic_mapping=None,
|
||||
persist_mapping=False, defroute=True, dhclient_args=None,
|
||||
dns_servers=None, nm_controlled=False, onboot=True):
|
||||
routes=None, rules=None, mtu=None, primary=False,
|
||||
members=None, ovs_options=None, ovs_extra=None,
|
||||
nic_mapping=None, persist_mapping=False, defroute=True,
|
||||
dhclient_args=None, dns_servers=None, nm_controlled=False,
|
||||
onboot=True):
|
||||
|
||||
check_ovs_installed(self.__class__.__name__)
|
||||
|
||||
addresses = addresses or []
|
||||
routes = routes or []
|
||||
rules = rules or []
|
||||
members = members or []
|
||||
dns_servers = dns_servers or []
|
||||
super(OvsBond, self).__init__(name, use_dhcp, use_dhcpv6, addresses,
|
||||
routes, mtu, primary, nic_mapping,
|
||||
routes, rules, mtu, primary, nic_mapping,
|
||||
persist_mapping, defroute, dhclient_args,
|
||||
dns_servers, nm_controlled, onboot)
|
||||
self.members = members
|
||||
|
@ -1006,7 +1079,7 @@ class OvsBond(_BaseOpts):
|
|||
@staticmethod
|
||||
def from_json(json):
|
||||
name = _get_required_field(json, 'name', 'OvsBond')
|
||||
(use_dhcp, use_dhcpv6, addresses, routes, mtu, nic_mapping,
|
||||
(use_dhcp, use_dhcpv6, addresses, routes, rules, mtu, nic_mapping,
|
||||
persist_mapping, defroute, dhclient_args,
|
||||
dns_servers, nm_controlled, onboot) = _BaseOpts.base_opts_from_json(
|
||||
json, include_primary=False)
|
||||
|
@ -1018,8 +1091,8 @@ class OvsBond(_BaseOpts):
|
|||
members = _update_members(json, nic_mapping, persist_mapping)
|
||||
|
||||
return OvsBond(name, use_dhcp=use_dhcp, use_dhcpv6=use_dhcpv6,
|
||||
addresses=addresses, routes=routes, mtu=mtu,
|
||||
members=members, ovs_options=ovs_options,
|
||||
addresses=addresses, routes=routes, rules=rules,
|
||||
mtu=mtu, members=members, ovs_options=ovs_options,
|
||||
ovs_extra=ovs_extra, nic_mapping=nic_mapping,
|
||||
persist_mapping=persist_mapping, defroute=defroute,
|
||||
dhclient_args=dhclient_args, dns_servers=dns_servers,
|
||||
|
@ -1030,19 +1103,21 @@ class OvsTunnel(_BaseOpts):
|
|||
"""Base class for OVS Tunnels."""
|
||||
|
||||
def __init__(self, name, use_dhcp=False, use_dhcpv6=False, addresses=None,
|
||||
routes=None, mtu=None, primary=False, nic_mapping=None,
|
||||
persist_mapping=False, defroute=True, dhclient_args=None,
|
||||
dns_servers=None, nm_controlled=False, onboot=True,
|
||||
tunnel_type=None, ovs_options=None, ovs_extra=None):
|
||||
routes=None, rules=None, mtu=None, primary=False,
|
||||
nic_mapping=None, persist_mapping=False, defroute=True,
|
||||
dhclient_args=None, dns_servers=None, nm_controlled=False,
|
||||
onboot=True, tunnel_type=None, ovs_options=None,
|
||||
ovs_extra=None):
|
||||
|
||||
check_ovs_installed(self.__class__.__name__)
|
||||
|
||||
addresses = addresses or []
|
||||
routes = routes or []
|
||||
rules = rules or []
|
||||
dns_servers = dns_servers or []
|
||||
super(OvsTunnel, self).__init__(name, use_dhcp, use_dhcpv6, addresses,
|
||||
routes, mtu, primary, nic_mapping,
|
||||
persist_mapping, defroute,
|
||||
routes, rules, mtu, primary,
|
||||
nic_mapping, persist_mapping, defroute,
|
||||
dhclient_args, dns_servers,
|
||||
nm_controlled, onboot)
|
||||
self.tunnel_type = tunnel_type
|
||||
|
@ -1067,22 +1142,24 @@ class OvsPatchPort(_BaseOpts):
|
|||
"""Base class for OVS Patch Ports."""
|
||||
|
||||
def __init__(self, name, use_dhcp=False, use_dhcpv6=False, addresses=None,
|
||||
routes=None, mtu=None, primary=False, nic_mapping=None,
|
||||
persist_mapping=False, defroute=True, dhclient_args=None,
|
||||
dns_servers=None, nm_controlled=False, onboot=True,
|
||||
bridge_name=None, peer=None, ovs_options=None,
|
||||
routes=None, rules=None, mtu=None, primary=False,
|
||||
nic_mapping=None, persist_mapping=False, defroute=True,
|
||||
dhclient_args=None, dns_servers=None, nm_controlled=False,
|
||||
onboot=True, bridge_name=None, peer=None, ovs_options=None,
|
||||
ovs_extra=None):
|
||||
|
||||
check_ovs_installed(self.__class__.__name__)
|
||||
|
||||
addresses = addresses or []
|
||||
routes = routes or []
|
||||
rules = rules or []
|
||||
dns_servers = dns_servers or []
|
||||
super(OvsPatchPort, self).__init__(name, use_dhcp, use_dhcpv6,
|
||||
addresses, routes, mtu, primary,
|
||||
nic_mapping, persist_mapping,
|
||||
defroute, dhclient_args,
|
||||
dns_servers, nm_controlled, onboot)
|
||||
addresses, routes, rules, mtu,
|
||||
primary, nic_mapping,
|
||||
persist_mapping, defroute,
|
||||
dhclient_args, dns_servers,
|
||||
nm_controlled, onboot)
|
||||
self.bridge_name = bridge_name
|
||||
self.peer = peer
|
||||
self.ovs_options = ovs_options or []
|
||||
|
@ -1107,17 +1184,19 @@ class IbInterface(_BaseOpts):
|
|||
"""Base class for InfiniBand network interfaces."""
|
||||
|
||||
def __init__(self, name, use_dhcp=False, use_dhcpv6=False, addresses=None,
|
||||
routes=None, mtu=None, primary=False, nic_mapping=None,
|
||||
persist_mapping=False, defroute=True, dhclient_args=None,
|
||||
dns_servers=None, nm_controlled=False, onboot=True,
|
||||
ethtool_opts=None):
|
||||
routes=None, rules=None, mtu=None, primary=False,
|
||||
nic_mapping=None, persist_mapping=False, defroute=True,
|
||||
dhclient_args=None, dns_servers=None, nm_controlled=False,
|
||||
onboot=True, ethtool_opts=None):
|
||||
addresses = addresses or []
|
||||
routes = routes or []
|
||||
rules = rules or []
|
||||
dns_servers = dns_servers or []
|
||||
super(IbInterface, self).__init__(name, use_dhcp, use_dhcpv6,
|
||||
addresses, routes, mtu, primary,
|
||||
nic_mapping, persist_mapping,
|
||||
defroute, dhclient_args, dns_servers,
|
||||
addresses, routes, rules, mtu,
|
||||
primary, nic_mapping,
|
||||
persist_mapping, defroute,
|
||||
dhclient_args, dns_servers,
|
||||
nm_controlled, onboot)
|
||||
self.ethtool_opts = ethtool_opts
|
||||
|
||||
|
@ -1133,19 +1212,20 @@ class OvsDpdkPort(_BaseOpts):
|
|||
"""Base class for OVS Dpdk Ports."""
|
||||
|
||||
def __init__(self, name, use_dhcp=False, use_dhcpv6=False, addresses=None,
|
||||
routes=None, mtu=None, primary=False, nic_mapping=None,
|
||||
persist_mapping=False, defroute=True, dhclient_args=None,
|
||||
dns_servers=None, nm_controlled=False, onboot=True,
|
||||
members=None, driver='vfio-pci', ovs_options=None,
|
||||
ovs_extra=None, rx_queue=None):
|
||||
routes=None, rules=None, mtu=None, primary=False,
|
||||
nic_mapping=None, persist_mapping=False, defroute=True,
|
||||
dhclient_args=None, dns_servers=None, nm_controlled=False,
|
||||
onboot=True, members=None, driver='vfio-pci',
|
||||
ovs_options=None, ovs_extra=None, rx_queue=None):
|
||||
|
||||
check_ovs_installed(self.__class__.__name__)
|
||||
|
||||
super(OvsDpdkPort, self).__init__(name, use_dhcp, use_dhcpv6,
|
||||
addresses, routes, mtu, primary,
|
||||
nic_mapping, persist_mapping,
|
||||
defroute, dhclient_args,
|
||||
dns_servers, nm_controlled, onboot)
|
||||
addresses, routes, rules, mtu,
|
||||
primary, nic_mapping,
|
||||
persist_mapping, defroute,
|
||||
dhclient_args, dns_servers,
|
||||
nm_controlled, onboot)
|
||||
self.members = members or []
|
||||
self.ovs_options = ovs_options or []
|
||||
self.ovs_extra = format_ovs_extra(self, ovs_extra)
|
||||
|
@ -1175,8 +1255,8 @@ class OvsDpdkPort(_BaseOpts):
|
|||
def from_json(json):
|
||||
name = _get_required_field(json, 'name', 'OvsDpdkPort')
|
||||
# driver name by default will be 'vfio-pci' if not specified
|
||||
(use_dhcp, use_dhcpv6, addresses, routes, mtu, primary, nic_mapping,
|
||||
persist_mapping, defroute, dhclient_args,
|
||||
(use_dhcp, use_dhcpv6, addresses, routes, rules, mtu, primary,
|
||||
nic_mapping, persist_mapping, defroute, dhclient_args,
|
||||
dns_servers, nm_controlled,
|
||||
onboot) = _BaseOpts.base_opts_from_json(json)
|
||||
|
||||
|
@ -1223,8 +1303,8 @@ class OvsDpdkPort(_BaseOpts):
|
|||
if not isinstance(ovs_extra, list):
|
||||
ovs_extra = [ovs_extra]
|
||||
return OvsDpdkPort(name, use_dhcp=use_dhcp, use_dhcpv6=use_dhcpv6,
|
||||
addresses=addresses, routes=routes, mtu=mtu,
|
||||
primary=primary, nic_mapping=nic_mapping,
|
||||
addresses=addresses, routes=routes, rules=rules,
|
||||
mtu=mtu, primary=primary, nic_mapping=nic_mapping,
|
||||
persist_mapping=persist_mapping, defroute=defroute,
|
||||
dhclient_args=dhclient_args,
|
||||
dns_servers=dns_servers,
|
||||
|
@ -1238,13 +1318,15 @@ class SriovVF(_BaseOpts):
|
|||
"""Base class for SR-IOV VF."""
|
||||
|
||||
def __init__(self, device, vfid, use_dhcp=False, use_dhcpv6=False,
|
||||
addresses=None, routes=None, mtu=None, primary=False,
|
||||
nic_mapping=None, persist_mapping=False, defroute=True,
|
||||
dhclient_args=None, dns_servers=None, nm_controlled=False,
|
||||
onboot=True, vlan_id=0, qos=0, spoofcheck=None,
|
||||
trust=None, state=None, macaddr=None, promisc=None):
|
||||
addresses=None, routes=None, rules=None, mtu=None,
|
||||
primary=False, nic_mapping=None, persist_mapping=False,
|
||||
defroute=True, dhclient_args=None, dns_servers=None,
|
||||
nm_controlled=False, onboot=True, vlan_id=0, qos=0,
|
||||
spoofcheck=None, trust=None, state=None, macaddr=None,
|
||||
promisc=None):
|
||||
addresses = addresses or []
|
||||
routes = routes or []
|
||||
rules = rules or []
|
||||
dns_servers = dns_servers or []
|
||||
mapped_nic_names = mapped_nics(nic_mapping)
|
||||
if device in mapped_nic_names:
|
||||
|
@ -1254,7 +1336,7 @@ class SriovVF(_BaseOpts):
|
|||
# (device) and the VF id.
|
||||
name = utils.get_vf_devname(device, vfid)
|
||||
super(SriovVF, self).__init__(name, use_dhcp, use_dhcpv6, addresses,
|
||||
routes, mtu, primary, nic_mapping,
|
||||
routes, rules, mtu, primary, nic_mapping,
|
||||
persist_mapping, defroute,
|
||||
dhclient_args, dns_servers,
|
||||
nm_controlled, onboot)
|
||||
|
@ -1314,15 +1396,16 @@ class SriovPF(_BaseOpts):
|
|||
"""Base class for SR-IOV PF."""
|
||||
|
||||
def __init__(self, name, numvfs, use_dhcp=False, use_dhcpv6=False,
|
||||
addresses=None, routes=None, mtu=None, primary=False,
|
||||
nic_mapping=None, persist_mapping=False, defroute=True,
|
||||
dhclient_args=None, dns_servers=None, nm_controlled=False,
|
||||
onboot=True, members=None, promisc=None):
|
||||
addresses=None, routes=None, rules=None, mtu=None,
|
||||
primary=False, nic_mapping=None, persist_mapping=False,
|
||||
defroute=True, dhclient_args=None, dns_servers=None,
|
||||
nm_controlled=False, onboot=True, members=None, promisc=None):
|
||||
addresses = addresses or []
|
||||
routes = routes or []
|
||||
rules = rules or []
|
||||
dns_servers = dns_servers or []
|
||||
super(SriovPF, self).__init__(name, use_dhcp, use_dhcpv6, addresses,
|
||||
routes, mtu, primary, nic_mapping,
|
||||
routes, rules, mtu, primary, nic_mapping,
|
||||
persist_mapping, defroute,
|
||||
dhclient_args, dns_servers,
|
||||
nm_controlled, onboot)
|
||||
|
@ -1358,18 +1441,19 @@ class OvsDpdkBond(_BaseOpts):
|
|||
"""Base class for OVS DPDK bonds."""
|
||||
|
||||
def __init__(self, name, use_dhcp=False, use_dhcpv6=False, addresses=None,
|
||||
routes=None, mtu=None, primary=False, members=None,
|
||||
ovs_options=None, ovs_extra=None, nic_mapping=None,
|
||||
persist_mapping=False, defroute=True, dhclient_args=None,
|
||||
dns_servers=None, nm_controlled=False, onboot=True,
|
||||
rx_queue=None):
|
||||
routes=None, rules=None, mtu=None, primary=False,
|
||||
members=None, ovs_options=None, ovs_extra=None,
|
||||
nic_mapping=None, persist_mapping=False, defroute=True,
|
||||
dhclient_args=None, dns_servers=None, nm_controlled=False,
|
||||
onboot=True, rx_queue=None):
|
||||
|
||||
check_ovs_installed(self.__class__.__name__)
|
||||
|
||||
super(OvsDpdkBond, self).__init__(name, use_dhcp, use_dhcpv6,
|
||||
addresses, routes, mtu, primary,
|
||||
nic_mapping, persist_mapping,
|
||||
defroute, dhclient_args, dns_servers,
|
||||
addresses, routes, rules, mtu,
|
||||
primary, nic_mapping,
|
||||
persist_mapping, defroute,
|
||||
dhclient_args, dns_servers,
|
||||
nm_controlled, onboot)
|
||||
self.members = members or []
|
||||
self.ovs_options = ovs_options
|
||||
|
@ -1393,7 +1477,7 @@ class OvsDpdkBond(_BaseOpts):
|
|||
@staticmethod
|
||||
def from_json(json):
|
||||
name = _get_required_field(json, 'name', 'OvsDpdkBond')
|
||||
(use_dhcp, use_dhcpv6, addresses, routes, mtu, nic_mapping,
|
||||
(use_dhcp, use_dhcpv6, addresses, routes, rules, mtu, nic_mapping,
|
||||
persist_mapping, defroute, dhclient_args,
|
||||
dns_servers, nm_controlled, onboot) = _BaseOpts.base_opts_from_json(
|
||||
json, include_primary=False)
|
||||
|
@ -1423,8 +1507,8 @@ class OvsDpdkBond(_BaseOpts):
|
|||
raise InvalidConfigException(msg)
|
||||
|
||||
return OvsDpdkBond(name, use_dhcp=use_dhcp, use_dhcpv6=use_dhcpv6,
|
||||
addresses=addresses, routes=routes, mtu=mtu,
|
||||
members=members, ovs_options=ovs_options,
|
||||
addresses=addresses, routes=routes, rules=rules,
|
||||
mtu=mtu, members=members, ovs_options=ovs_options,
|
||||
ovs_extra=ovs_extra, nic_mapping=nic_mapping,
|
||||
persist_mapping=persist_mapping,
|
||||
defroute=defroute, dhclient_args=dhclient_args,
|
||||
|
@ -1458,17 +1542,20 @@ class VppInterface(_BaseOpts):
|
|||
subsequent runs of os-net-config.
|
||||
"""
|
||||
def __init__(self, name, use_dhcp=False, use_dhcpv6=False, addresses=None,
|
||||
routes=None, mtu=None, primary=False, nic_mapping=None,
|
||||
persist_mapping=False, defroute=True, dhclient_args=None,
|
||||
dns_servers=None, nm_controlled=False, onboot=True,
|
||||
uio_driver='vfio-pci', options=None):
|
||||
routes=None, rules=None, mtu=None, primary=False,
|
||||
nic_mapping=None, persist_mapping=False, defroute=True,
|
||||
dhclient_args=None, dns_servers=None, nm_controlled=False,
|
||||
onboot=True, uio_driver='vfio-pci', options=None):
|
||||
addresses = addresses or []
|
||||
routes = routes or []
|
||||
rules = rules or []
|
||||
|
||||
super(VppInterface, self).__init__(name, use_dhcp, use_dhcpv6,
|
||||
addresses, routes, mtu, primary,
|
||||
nic_mapping, persist_mapping,
|
||||
defroute, dhclient_args,
|
||||
dns_servers, nm_controlled, onboot)
|
||||
addresses, routes, rules, mtu,
|
||||
primary, nic_mapping,
|
||||
persist_mapping, defroute,
|
||||
dhclient_args, dns_servers,
|
||||
nm_controlled, onboot)
|
||||
self.uio_driver = uio_driver
|
||||
self.options = options
|
||||
# pci_dev contains pci address for the interface, it will be populated
|
||||
|
@ -1490,15 +1577,17 @@ class VppInterface(_BaseOpts):
|
|||
class VppBond(_BaseOpts):
|
||||
"""Base class for VPP Bond."""
|
||||
def __init__(self, name, use_dhcp=False, use_dhcpv6=False, addresses=None,
|
||||
routes=None, mtu=None, primary=False, nic_mapping=None,
|
||||
persist_mapping=False, defroute=True, dhclient_args=None,
|
||||
dns_servers=None, nm_controlled=False, onboot=True,
|
||||
members=None, bonding_options=None):
|
||||
routes=None, rules=None, mtu=None, primary=False,
|
||||
nic_mapping=None, persist_mapping=False, defroute=True,
|
||||
dhclient_args=None, dns_servers=None, nm_controlled=False,
|
||||
onboot=True, members=None, bonding_options=None):
|
||||
addresses = addresses or []
|
||||
members = members or []
|
||||
routes = routes or []
|
||||
rules = rules or []
|
||||
|
||||
super(VppBond, self).__init__(name, use_dhcp, use_dhcpv6,
|
||||
addresses, routes, mtu, primary,
|
||||
addresses, routes, rules, mtu, primary,
|
||||
nic_mapping, persist_mapping,
|
||||
defroute, dhclient_args,
|
||||
dns_servers, nm_controlled, onboot)
|
||||
|
@ -1510,10 +1599,9 @@ class VppBond(_BaseOpts):
|
|||
name = _get_required_field(json, 'name', 'VppBond')
|
||||
bonding_options = json.get('bonding_options', '')
|
||||
|
||||
(use_dhcp, use_dhcpv6, addresses, routes, mtu, nic_mapping,
|
||||
persist_mapping, defroute, dhclient_args,
|
||||
dns_servers, nm_controlled, onboot) = _BaseOpts.base_opts_from_json(
|
||||
json, include_primary=False)
|
||||
(use_dhcp, use_dhcpv6, addresses, routes, rules, mtu, nic_mapping,
|
||||
persist_mapping, defroute, dhclient_args, dns_servers, nm_controlled,
|
||||
onboot) = _BaseOpts.base_opts_from_json(json, include_primary=False)
|
||||
|
||||
members = []
|
||||
members_json = json.get('members', None)
|
||||
|
@ -1534,8 +1622,8 @@ class VppBond(_BaseOpts):
|
|||
raise InvalidConfigException(msg)
|
||||
|
||||
return VppBond(name, use_dhcp=use_dhcp, use_dhcpv6=use_dhcpv6,
|
||||
addresses=addresses, routes=routes, mtu=mtu,
|
||||
members=members, nic_mapping=nic_mapping,
|
||||
addresses=addresses, routes=routes, rules=rules,
|
||||
mtu=mtu, members=members, nic_mapping=nic_mapping,
|
||||
persist_mapping=persist_mapping,
|
||||
defroute=defroute, dhclient_args=dhclient_args,
|
||||
dns_servers=dns_servers, nm_controlled=nm_controlled,
|
||||
|
@ -1552,14 +1640,14 @@ class ContrailVrouter(_BaseOpts):
|
|||
- members: List of sole interface to use by vhost0
|
||||
"""
|
||||
def __init__(self, name, use_dhcp=False, use_dhcpv6=False, addresses=None,
|
||||
routes=None, mtu=None, primary=False, nic_mapping=None,
|
||||
persist_mapping=False, defroute=True, dhclient_args=None,
|
||||
dns_servers=None, nm_controlled=False, onboot=True,
|
||||
members=None):
|
||||
routes=None, rules=None, mtu=None, primary=False,
|
||||
nic_mapping=None, persist_mapping=False, defroute=True,
|
||||
dhclient_args=None, dns_servers=None, nm_controlled=False,
|
||||
onboot=True, members=None):
|
||||
addresses = addresses or []
|
||||
|
||||
super(ContrailVrouter, self).__init__(name, use_dhcp, use_dhcpv6,
|
||||
addresses, routes, mtu,
|
||||
addresses, routes, rules, mtu,
|
||||
primary, nic_mapping,
|
||||
persist_mapping, defroute,
|
||||
dhclient_args, dns_servers,
|
||||
|
@ -1570,7 +1658,7 @@ class ContrailVrouter(_BaseOpts):
|
|||
def from_json(json):
|
||||
name = _get_required_field(json, 'name', 'ContrailVrouter')
|
||||
|
||||
(_use_dhcp, _use_dhcpv6, _addresses, _routes, _mtu, _primary,
|
||||
(_use_dhcp, _use_dhcpv6, _addresses, _routes, _rules, _mtu, _primary,
|
||||
nic_mapping, persist_mapping, _defroute, _dhclient_args, _dns_servers,
|
||||
_nm_controlled, _onboot) = opts = _BaseOpts.base_opts_from_json(json)
|
||||
members = _update_members(json, nic_mapping, persist_mapping)
|
||||
|
@ -1592,16 +1680,16 @@ class ContrailVrouterDpdk(_BaseOpts):
|
|||
- vlan_id:
|
||||
"""
|
||||
def __init__(self, name, use_dhcp=False, use_dhcpv6=False, addresses=None,
|
||||
routes=None, mtu=None, primary=False, nic_mapping=None,
|
||||
persist_mapping=False, defroute=True, dhclient_args=None,
|
||||
dns_servers=None, nm_controlled=False, onboot=True,
|
||||
members=None, bond_mode=None, bond_policy=None,
|
||||
routes=None, rules=None, mtu=None, primary=False,
|
||||
nic_mapping=None, persist_mapping=False, defroute=True,
|
||||
dhclient_args=None, dns_servers=None, nm_controlled=False,
|
||||
onboot=True, members=None, bond_mode=None, bond_policy=None,
|
||||
driver=None, cpu_list='0-31', vlan_id=None):
|
||||
addresses = addresses or []
|
||||
|
||||
super(ContrailVrouterDpdk, self).__init__(name, use_dhcp, use_dhcpv6,
|
||||
addresses, routes, mtu,
|
||||
primary, nic_mapping,
|
||||
addresses, routes, rules,
|
||||
mtu, primary, nic_mapping,
|
||||
persist_mapping, defroute,
|
||||
dhclient_args, dns_servers,
|
||||
nm_controlled, onboot)
|
||||
|
@ -1622,7 +1710,7 @@ class ContrailVrouterDpdk(_BaseOpts):
|
|||
cpu_list = json.get('cpu_list', '0-31')
|
||||
vlan_id = json.get('vlan_id', '')
|
||||
|
||||
(_use_dhcp, _use_dhcpv6, _addresses, _routes, _mtu, _primary,
|
||||
(_use_dhcp, _use_dhcpv6, _addresses, _routes, _rules, _mtu, _primary,
|
||||
nic_mapping, persist_mapping, _defroute, _dhclient_args, _dns_servers,
|
||||
_nm_controlled, _onboot) = opts = _BaseOpts.base_opts_from_json(json)
|
||||
members = _update_members(json, nic_mapping, persist_mapping)
|
||||
|
|
|
@ -135,6 +135,10 @@ definitions:
|
|||
$ref: "#/definitions/bool_or_param"
|
||||
route_options:
|
||||
$ref: "#/definitions/string_or_param"
|
||||
table:
|
||||
oneOf:
|
||||
- $ref: "#/definitions/string_or_param"
|
||||
- $ref: "#/definitions/int_or_param"
|
||||
requires:
|
||||
- next_hop
|
||||
additionalProperties: False
|
||||
|
@ -147,6 +151,10 @@ definitions:
|
|||
$ref: "#/definitions/bool_or_param"
|
||||
route_options:
|
||||
$ref: "#/definitions/string_or_param"
|
||||
table:
|
||||
oneOf:
|
||||
- $ref: "#/definitions/string_or_param"
|
||||
- $ref: "#/definitions/int_or_param"
|
||||
requires:
|
||||
- nexthop
|
||||
additionalProperties: False
|
||||
|
@ -156,6 +164,22 @@ definitions:
|
|||
$ref: "#/definitions/route"
|
||||
minItems: 0
|
||||
|
||||
route_rule:
|
||||
type: object
|
||||
properties:
|
||||
rule:
|
||||
$ref: "#/definitions/string_or_param"
|
||||
comment:
|
||||
$ref: "#/definitions/string_or_param"
|
||||
required:
|
||||
- rule
|
||||
additionalProperties: False
|
||||
list_of_rule:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/definitions/route_rule"
|
||||
minItems: 1
|
||||
|
||||
nic_mapping:
|
||||
type: ["object", "null"]
|
||||
|
||||
|
@ -230,6 +254,8 @@ definitions:
|
|||
$ref: "#/definitions/list_of_address"
|
||||
routes:
|
||||
$ref: "#/definitions/list_of_route"
|
||||
rules:
|
||||
$ref: "#/definitions/list_of_rule"
|
||||
mtu:
|
||||
$ref: "#/definitions/int_or_param"
|
||||
nic_mapping:
|
||||
|
@ -251,6 +277,23 @@ definitions:
|
|||
- name
|
||||
additionalProperties: False
|
||||
|
||||
route_table:
|
||||
type: object
|
||||
properties:
|
||||
type:
|
||||
enum: ["route_table"]
|
||||
name:
|
||||
$ref: "#/definitions/string_or_param"
|
||||
table_id:
|
||||
oneOf:
|
||||
- $ref: "#/definitions/int_or_param"
|
||||
- $ref: "#/definitions/string_or_param"
|
||||
required:
|
||||
- type
|
||||
- name
|
||||
- table_id
|
||||
additionalProperties: False
|
||||
|
||||
sriov_pf:
|
||||
type: object
|
||||
properties:
|
||||
|
@ -275,6 +318,8 @@ definitions:
|
|||
$ref: "#/definitions/list_of_address"
|
||||
routes:
|
||||
$ref: "#/definitions/list_of_route"
|
||||
rules:
|
||||
$ref: "#/definitions/list_of_rule"
|
||||
mtu:
|
||||
$ref: "#/definitions/int_or_param"
|
||||
nic_mapping:
|
||||
|
@ -333,6 +378,8 @@ definitions:
|
|||
$ref: "#/definitions/list_of_address"
|
||||
routes:
|
||||
$ref: "#/definitions/list_of_route"
|
||||
rules:
|
||||
$ref: "#/definitions/list_of_rule"
|
||||
mtu:
|
||||
$ref: "#/definitions/int_or_param"
|
||||
nic_mapping:
|
||||
|
@ -375,6 +422,8 @@ definitions:
|
|||
$ref: "#/definitions/list_of_address"
|
||||
routes:
|
||||
$ref: "#/definitions/list_of_route"
|
||||
rules:
|
||||
$ref: "#/definitions/list_of_rule"
|
||||
mtu:
|
||||
$ref: "#/definitions/int_or_param"
|
||||
nic_mapping:
|
||||
|
@ -429,6 +478,8 @@ definitions:
|
|||
$ref: "#/definitions/list_of_address"
|
||||
routes:
|
||||
$ref: "#/definitions/list_of_route"
|
||||
rules:
|
||||
$ref: "#/definitions/list_of_rule"
|
||||
mtu:
|
||||
$ref: "#/definitions/int_or_param"
|
||||
nic_mapping:
|
||||
|
@ -484,6 +535,8 @@ definitions:
|
|||
$ref: "#/definitions/list_of_address"
|
||||
routes:
|
||||
$ref: "#/definitions/list_of_route"
|
||||
rules:
|
||||
$ref: "#/definitions/list_of_rule"
|
||||
mtu:
|
||||
$ref: "#/definitions/int_or_param"
|
||||
nic_mapping:
|
||||
|
@ -534,6 +587,8 @@ definitions:
|
|||
$ref: "#/definitions/list_of_address"
|
||||
routes:
|
||||
$ref: "#/definitions/list_of_route"
|
||||
rules:
|
||||
$ref: "#/definitions/list_of_rule"
|
||||
mtu:
|
||||
$ref: "#/definitions/int_or_param"
|
||||
nic_mapping:
|
||||
|
@ -582,6 +637,8 @@ definitions:
|
|||
$ref: "#/definitions/list_of_address"
|
||||
routes:
|
||||
$ref: "#/definitions/list_of_route"
|
||||
rules:
|
||||
$ref: "#/definitions/list_of_rule"
|
||||
mtu:
|
||||
$ref: "#/definitions/int_or_param"
|
||||
nic_mapping:
|
||||
|
@ -629,6 +686,8 @@ definitions:
|
|||
$ref: "#/definitions/list_of_address"
|
||||
routes:
|
||||
$ref: "#/definitions/list_of_route"
|
||||
rules:
|
||||
$ref: "#/definitions/list_of_rule"
|
||||
mtu:
|
||||
$ref: "#/definitions/int_or_param"
|
||||
nic_mapping:
|
||||
|
@ -677,6 +736,8 @@ definitions:
|
|||
$ref: "#/definitions/list_of_address"
|
||||
routes:
|
||||
$ref: "#/definitions/list_of_route"
|
||||
rules:
|
||||
$ref: "#/definitions/list_of_rule"
|
||||
mtu:
|
||||
$ref: "#/definitions/int_or_param"
|
||||
nic_mapping:
|
||||
|
@ -733,6 +794,8 @@ definitions:
|
|||
$ref: "#/definitions/list_of_address"
|
||||
routes:
|
||||
$ref: "#/definitions/list_of_route"
|
||||
rules:
|
||||
$ref: "#/definitions/list_of_rule"
|
||||
mtu:
|
||||
$ref: "#/definitions/int_or_param"
|
||||
nic_mapping:
|
||||
|
@ -775,6 +838,8 @@ definitions:
|
|||
$ref: "#/definitions/list_of_address"
|
||||
routes:
|
||||
$ref: "#/definitions/list_of_route"
|
||||
rules:
|
||||
$ref: "#/definitions/list_of_rule"
|
||||
mtu:
|
||||
$ref: "#/definitions/int_or_param"
|
||||
nic_mapping:
|
||||
|
@ -816,6 +881,8 @@ definitions:
|
|||
$ref: "#/definitions/list_of_address"
|
||||
routes:
|
||||
$ref: "#/definitions/list_of_route"
|
||||
rules:
|
||||
$ref: "#/definitions/list_of_rule"
|
||||
mtu:
|
||||
$ref: "#/definitions/int_or_param"
|
||||
nic_mapping:
|
||||
|
@ -869,6 +936,8 @@ definitions:
|
|||
$ref: "#/definitions/list_of_address"
|
||||
routes:
|
||||
$ref: "#/definitions/list_of_route"
|
||||
rules:
|
||||
$ref: "#/definitions/list_of_rule"
|
||||
mtu:
|
||||
$ref: "#/definitions/int_or_param"
|
||||
nic_mapping:
|
||||
|
@ -926,6 +995,8 @@ definitions:
|
|||
$ref: "#/definitions/list_of_address"
|
||||
routes:
|
||||
$ref: "#/definitions/list_of_route"
|
||||
rules:
|
||||
$ref: "#/definitions/list_of_rule"
|
||||
mtu:
|
||||
$ref: "#/definitions/int_or_param"
|
||||
nic_mapping:
|
||||
|
@ -969,6 +1040,8 @@ definitions:
|
|||
$ref: "#/definitions/list_of_address"
|
||||
routes:
|
||||
$ref: "#/definitions/list_of_route"
|
||||
rules:
|
||||
$ref: "#/definitions/list_of_rule"
|
||||
mtu:
|
||||
$ref: "#/definitions/int_or_param"
|
||||
nic_mapping:
|
||||
|
@ -1016,6 +1089,8 @@ definitions:
|
|||
$ref: "#/definitions/list_of_address"
|
||||
routes:
|
||||
$ref: "#/definitions/list_of_route"
|
||||
rules:
|
||||
$ref: "#/definitions/list_of_rule"
|
||||
mtu:
|
||||
$ref: "#/definitions/int_or_param"
|
||||
nic_mapping:
|
||||
|
@ -1062,6 +1137,8 @@ definitions:
|
|||
$ref: "#/definitions/list_of_address"
|
||||
routes:
|
||||
$ref: "#/definitions/list_of_route"
|
||||
rules:
|
||||
$ref: "#/definitions/list_of_rule"
|
||||
mtu:
|
||||
$ref: "#/definitions/int_or_param"
|
||||
nic_mapping:
|
||||
|
@ -1104,6 +1181,8 @@ definitions:
|
|||
$ref: "#/definitions/list_of_address"
|
||||
routes:
|
||||
$ref: "#/definitions/list_of_route"
|
||||
rules:
|
||||
$ref: "#/definitions/list_of_rule"
|
||||
mtu:
|
||||
$ref: "#/definitions/int_or_param"
|
||||
nic_mapping:
|
||||
|
@ -1145,6 +1224,8 @@ definitions:
|
|||
$ref: "#/definitions/list_of_address"
|
||||
routes:
|
||||
$ref: "#/definitions/list_of_route"
|
||||
rules:
|
||||
$ref: "#/definitions/list_of_rule"
|
||||
mtu:
|
||||
$ref: "#/definitions/int_or_param"
|
||||
nic_mapping:
|
||||
|
@ -1189,6 +1270,8 @@ definitions:
|
|||
$ref: "#/definitions/list_of_address"
|
||||
routes:
|
||||
$ref: "#/definitions/list_of_route"
|
||||
rules:
|
||||
$ref: "#/definitions/list_of_rule"
|
||||
mtu:
|
||||
$ref: "#/definitions/int_or_param"
|
||||
nic_mapping:
|
||||
|
@ -1231,6 +1314,8 @@ definitions:
|
|||
$ref: "#/definitions/list_of_address"
|
||||
routes:
|
||||
$ref: "#/definitions/list_of_route"
|
||||
rules:
|
||||
$ref: "#/definitions/list_of_rule"
|
||||
mtu:
|
||||
$ref: "#/definitions/int_or_param"
|
||||
nic_mapping:
|
||||
|
@ -1272,6 +1357,8 @@ definitions:
|
|||
$ref: "#/definitions/list_of_address"
|
||||
routes:
|
||||
$ref: "#/definitions/list_of_route"
|
||||
rules:
|
||||
$ref: "#/definitions/list_of_rule"
|
||||
mtu:
|
||||
$ref: "#/definitions/int_or_param"
|
||||
nic_mapping:
|
||||
|
@ -1297,6 +1384,7 @@ type: array
|
|||
items:
|
||||
oneOf:
|
||||
- $ref: "#/definitions/interface"
|
||||
- $ref: "#/definitions/route_table"
|
||||
- $ref: "#/definitions/sriov_pf"
|
||||
- $ref: "#/definitions/sriov_vf"
|
||||
- $ref: "#/definitions/vlan"
|
||||
|
|
|
@ -194,6 +194,33 @@ _ROUTES = """default via 192.168.1.1 dev em1 metric 10
|
|||
172.20.0.0/24 via 192.168.1.5 dev em1 metric 100
|
||||
"""
|
||||
|
||||
_ROUTES_WITH_TABLES = """172.19.0.0/24 via 192.168.1.1 dev em1 table table1
|
||||
172.20.0.0/24 via 192.168.1.1 dev em1 table 201
|
||||
172.21.0.0/24 via 192.168.1.1 dev em1 table 200
|
||||
"""
|
||||
|
||||
_ROUTE_RULES = """# This file is autogenerated by os-net-config
|
||||
# test comment
|
||||
from 192.0.2.0/24 table 200
|
||||
"""
|
||||
|
||||
_RT_DEFAULT = """# reserved values
|
||||
#
|
||||
255\tlocal
|
||||
254\tmain
|
||||
253\tdefault
|
||||
0\tunspec
|
||||
#
|
||||
# local
|
||||
#
|
||||
#1\tinr.ruhep\n"""
|
||||
|
||||
_RT_CUSTOM = _RT_DEFAULT + "# Custom\n10\tcustom # Custom table\n20\ttable1\n"
|
||||
|
||||
_RT_FULL = _RT_DEFAULT + """# Custom
|
||||
10\tcustom # os-net-config managed table
|
||||
200\ttable1 # os-net-config managed table\n"""
|
||||
|
||||
_ROUTES_V6 = """default via 2001:db8::1 dev em1
|
||||
2001:db8:dead:beef:cafe::/56 via fd00:fd00:2000::1 dev em1
|
||||
2001:db8:dead:beff::/64 via fd00:fd00:2000::1 dev em1 metric 100
|
||||
|
@ -554,6 +581,12 @@ class TestIfcfgNetConfig(base.TestCase):
|
|||
def get_route_config(self, name='em1'):
|
||||
return self.provider.route_data.get(name, '')
|
||||
|
||||
def get_route_table_config(self, name='custom', table_id=200):
|
||||
return self.provider.route_table_data.get(name, table_id)
|
||||
|
||||
def get_rule_config(self, name='em1'):
|
||||
return self.provider.rule_data.get(name)
|
||||
|
||||
def get_route6_config(self, name='em1'):
|
||||
return self.provider.route6_data.get(name, '')
|
||||
|
||||
|
@ -569,6 +602,35 @@ class TestIfcfgNetConfig(base.TestCase):
|
|||
if 'em1' in ifname:
|
||||
return "0000:00:01.0"
|
||||
|
||||
def test_add_route_table(self):
|
||||
route_table1 = objects.RouteTable('table1', 200)
|
||||
route_table2 = objects.RouteTable('table2', '201')
|
||||
self.provider.add_route_table(route_table1)
|
||||
self.provider.add_route_table(route_table2)
|
||||
self.assertEqual("table1", self.get_route_table_config(200))
|
||||
self.assertEqual("table2", self.get_route_table_config(201))
|
||||
|
||||
def test_add_route_with_table(self):
|
||||
route_rule1 = objects.RouteRule('from 192.0.2.0/24 table 200',
|
||||
'test comment')
|
||||
# Test route table by name
|
||||
route1 = objects.Route('192.168.1.1', '172.19.0.0/24', False,
|
||||
route_table="table1")
|
||||
# Test that table specified in route_options takes precedence
|
||||
route2 = objects.Route('192.168.1.1', '172.20.0.0/24', False,
|
||||
'table 201', route_table=200)
|
||||
# Test route table specified by integer ID
|
||||
route3 = objects.Route('192.168.1.1', '172.21.0.0/24', False,
|
||||
route_table=200)
|
||||
v4_addr = objects.Address('192.168.1.2/24')
|
||||
interface = objects.Interface('em1', addresses=[v4_addr],
|
||||
routes=[route1, route2, route3],
|
||||
rules=[route_rule1])
|
||||
self.provider.add_interface(interface)
|
||||
self.assertEqual(_V4_IFCFG, self.get_interface_config())
|
||||
self.assertEqual(_ROUTES_WITH_TABLES, self.get_route_config())
|
||||
self.assertEqual(_ROUTE_RULES, self.get_rule_config())
|
||||
|
||||
def test_add_base_interface(self):
|
||||
interface = objects.Interface('em1')
|
||||
self.provider.add_interface(interface)
|
||||
|
@ -1637,6 +1699,8 @@ class TestIfcfgNetConfigApply(base.TestCase):
|
|||
self.temp_bond_file = tempfile.NamedTemporaryFile()
|
||||
self.temp_route_file = tempfile.NamedTemporaryFile()
|
||||
self.temp_route6_file = tempfile.NamedTemporaryFile()
|
||||
self.temp_route_table_file = tempfile.NamedTemporaryFile()
|
||||
self.temp_rule_file = tempfile.NamedTemporaryFile()
|
||||
self.temp_bridge_file = tempfile.NamedTemporaryFile()
|
||||
self.temp_cleanup_file = tempfile.NamedTemporaryFile(delete=False)
|
||||
self.ifup_interface_names = []
|
||||
|
@ -1666,6 +1730,18 @@ class TestIfcfgNetConfigApply(base.TestCase):
|
|||
self.stub_out(
|
||||
'os_net_config.impl_ifcfg.route6_config_path', test_routes6_path)
|
||||
|
||||
def test_rules_path(name):
|
||||
return self.temp_rule_file.name
|
||||
self.stub_out(
|
||||
'os_net_config.impl_ifcfg.route_rule_config_path', test_rules_path)
|
||||
|
||||
def test_route_table_path():
|
||||
return self.temp_route_table_file.name
|
||||
self.stub_out(
|
||||
'os_net_config.impl_ifcfg.route_table_config_path',
|
||||
test_route_table_path)
|
||||
utils.write_config(self.temp_route_table_file.name, _RT_CUSTOM)
|
||||
|
||||
def test_bridge_path(name):
|
||||
return self.temp_bridge_file.name
|
||||
self.stub_out(
|
||||
|
@ -1707,6 +1783,40 @@ class TestIfcfgNetConfigApply(base.TestCase):
|
|||
self.temp_cleanup_file.close()
|
||||
super(TestIfcfgNetConfigApply, self).tearDown()
|
||||
|
||||
def test_route_table_apply(self):
|
||||
# Test overriding an existing route table
|
||||
route_table1 = objects.RouteTable('custom', 10)
|
||||
self.provider.add_route_table(route_table1)
|
||||
route_table2 = objects.RouteTable('table1', 200)
|
||||
self.provider.add_route_table(route_table2)
|
||||
|
||||
def test_route_table_path():
|
||||
return self.temp_route_table_file.name
|
||||
self.stub_out(
|
||||
'os_net_config.impl_ifcfg.route_table_config_path',
|
||||
test_route_table_path)
|
||||
utils.write_config(self.temp_route_table_file.name, _RT_CUSTOM)
|
||||
|
||||
self.provider.apply()
|
||||
|
||||
route_table_data = utils.get_file_data(
|
||||
self.temp_route_table_file.name)
|
||||
self.assertEqual(_RT_FULL, route_table_data)
|
||||
|
||||
def test_reserved_route_table_id(self):
|
||||
route_table1 = objects.RouteTable('table1', 253)
|
||||
self.provider.add_route_table(route_table1)
|
||||
|
||||
self.assertRaises(os_net_config.ConfigurationError,
|
||||
self.provider.apply)
|
||||
|
||||
def test_reserved_route_table_name(self):
|
||||
route_table2 = objects.RouteTable('default', 200)
|
||||
self.provider.add_route_table(route_table2)
|
||||
|
||||
self.assertRaises(os_net_config.ConfigurationError,
|
||||
self.provider.apply)
|
||||
|
||||
def test_network_apply(self):
|
||||
route1 = objects.Route('192.168.1.1', default=True,
|
||||
route_options="metric 10")
|
||||
|
|
|
@ -30,12 +30,13 @@ class TestRoute(base.TestCase):
|
|||
|
||||
def test_from_json(self):
|
||||
data = '{"next_hop": "172.19.0.1", "ip_netmask": "172.19.0.0/24", ' \
|
||||
'"route_options": "metric 10"}'
|
||||
'"route_options": "metric 10", "table": "200"}'
|
||||
route = objects.Route.from_json(json.loads(data))
|
||||
self.assertEqual("172.19.0.1", route.next_hop)
|
||||
self.assertEqual("172.19.0.0/24", route.ip_netmask)
|
||||
self.assertFalse(route.default)
|
||||
self.assertEqual("metric 10", route.route_options)
|
||||
self.assertEqual("200", route.route_table)
|
||||
|
||||
def test_from_json_default_route(self):
|
||||
data = '{"next_hop": "172.19.0.1", "ip_netmask": "172.19.0.0/24", ' \
|
||||
|
@ -73,6 +74,45 @@ class TestRoute(base.TestCase):
|
|||
objects.Route.from_json, data)
|
||||
|
||||
|
||||
class TestRouteTable(base.TestCase):
|
||||
|
||||
def test_from_json(self):
|
||||
data = '{"type": "route_table", "name": "custom", "table_id": 200}'
|
||||
route_table = objects.RouteTable.from_json(json.loads(data))
|
||||
self.assertEqual("custom", route_table.name)
|
||||
self.assertEqual(200, route_table.table_id)
|
||||
|
||||
def test_from_json_invalid(self):
|
||||
self.assertRaises(objects.InvalidConfigException,
|
||||
objects.RouteTable.from_json,
|
||||
{})
|
||||
|
||||
data = '{"type": "route_table", "table_id": 200}'
|
||||
json_data = json.loads(data)
|
||||
self.assertRaises(objects.InvalidConfigException,
|
||||
objects.RouteTable.from_json,
|
||||
json_data)
|
||||
|
||||
data = '{"type": "route_table", "name": "custom"}'
|
||||
json_data = json.loads(data)
|
||||
self.assertRaises(objects.InvalidConfigException,
|
||||
objects.RouteTable.from_json,
|
||||
json_data)
|
||||
|
||||
|
||||
class TestRouteRule(base.TestCase):
|
||||
|
||||
def test_rule(self):
|
||||
rule1 = objects.RouteRule('from 192.0.2.0/24 table 200 prio 1000')
|
||||
self.assertEqual('from 192.0.2.0/24 table 200 prio 1000', rule1.rule)
|
||||
|
||||
def test_rule_from_json(self):
|
||||
data = '{"rule":"from 172.19.0.0/24 table 200", "comment":"test"}'
|
||||
route_rule = objects.RouteRule.from_json(json.loads(data))
|
||||
self.assertEqual("from 172.19.0.0/24 table 200", route_rule.rule)
|
||||
self.assertEqual("test", route_rule.comment)
|
||||
|
||||
|
||||
class TestAddress(base.TestCase):
|
||||
|
||||
def test_ipv4_address(self):
|
||||
|
|
|
@ -200,6 +200,28 @@ class TestDerivedTypes(base.TestCase):
|
|||
self.assertFalse(v.is_valid([]))
|
||||
self.assertFalse(v.is_valid(None))
|
||||
|
||||
def test_route_table(self):
|
||||
schema = validator.get_schema_for_defined_type("route_table")
|
||||
v = jsonschema.Draft4Validator(schema)
|
||||
data = {"type": "route_table", "name": "custom", "table_id": "20"}
|
||||
self.assertTrue(v.is_valid(data))
|
||||
data["unkown_property"] = "value"
|
||||
self.assertFalse(v.is_valid(data))
|
||||
self.assertFalse(v.is_valid({}))
|
||||
self.assertFalse(v.is_valid([]))
|
||||
self.assertFalse(v.is_valid(None))
|
||||
|
||||
def test_route_rule(self):
|
||||
schema = validator.get_schema_for_defined_type("route_rule")
|
||||
v = jsonschema.Draft4Validator(schema)
|
||||
data = {"rule": "iif em2 table 20"}
|
||||
self.assertTrue(v.is_valid(data))
|
||||
data["unkown_property"] = "value"
|
||||
self.assertFalse(v.is_valid(data))
|
||||
self.assertFalse(v.is_valid({}))
|
||||
self.assertFalse(v.is_valid([]))
|
||||
self.assertFalse(v.is_valid(None))
|
||||
|
||||
|
||||
class TestDeviceTypes(base.TestCase):
|
||||
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
features:
|
||||
- |
|
||||
Support for configuring policy-based routing has been added. A new
|
||||
top-level object "route_table" has been added, which allows the user to
|
||||
add tables to the system route table at /etc/iproute2/rt_tables. Routes
|
||||
have a new "table" property for specifying which table to apply the route.
|
||||
Interfaces now have a "rules" property that allows the user to add
|
||||
arbitrary rules for when the system should use a particular routing table,
|
||||
such as input interface or source IP address.
|
Loading…
Reference in New Issue