Base net-virt CLI files on top of which ONOS specific changes will be done
diff --git a/cli/sdncon/controller/config.py b/cli/sdncon/controller/config.py
new file mode 100755
index 0000000..36dcd16
--- /dev/null
+++ b/cli/sdncon/controller/config.py
@@ -0,0 +1,284 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+from sdncon.rest.config import add_config_handler
+from sdncon.controller.models import Feature, GlobalConfig, Controller, \
+ ControllerInterface, ControllerDomainNameServer, \
+ FirewallRule, ControllerAlias, SnmpServerConfig, ImageDropUser
+from sdncon.controller.models import TacacsPlusConfig, TacacsPlusHost
+from oswrapper import exec_os_wrapper
+import os
+import re
+import sdncon
+from django.core import serializers
+
+# FIXME: Can probably get rid of default_id when the rest of the code is
+# in place for supporting multiple controller IDs. But what about
+# unit tests where we shouldn't rely on the boot-config file existing
+def get_local_controller_id(default_id='localhost'):
+ local_controller_id = default_id
+ f = None
+ try:
+ f = open("%s/run/boot-config" % sdncon.SDN_ROOT, 'r')
+ data = f.read()
+ match = re.search("^controller-id=([0-9a-zA-Z\-]*)$", data, re.MULTILINE)
+ if match:
+ local_controller_id = match.group(1)
+ except Exception, _e:
+ # If there was any error, then just leave the controller ID as the
+ # default value.
+ pass
+ finally:
+ if f:
+ f.close()
+ return local_controller_id
+
+
+# Add the config handlers here. Check the comments for add_config_handler in rest/config.py
+# for a description of the calling conventions for config handlers.
+
+def network_config_handler(op, old_instance, new_instance, modified_fields):
+ valid_instance = old_instance if (op == 'DELETE') else new_instance
+ if isinstance(valid_instance, Controller):
+ controller_node = valid_instance
+ controller_id = controller_node.id
+ if op == 'DELETE':
+ # no further configuration here
+ return
+ elif isinstance(valid_instance, ControllerDomainNameServer) \
+ or isinstance(valid_instance, ControllerInterface):
+ controller_id = valid_instance.controller_id
+ try:
+ controller_node = Controller.objects.get(pk=controller_id)
+ except Exception, _e:
+ # unknown controller node during delete, no need to
+ # do anything with any of these interfaces
+ return
+ else:
+ raise Exception('Unknown model change trigger network config handler')
+
+ if controller_id != get_local_controller_id():
+ return
+
+ if op == 'DELETE':
+ # don't reconfigure the interfaces during delete, since
+ # for deletes, the values of ip/netmask don't get updated
+ dns = ControllerDomainNameServer.objects.filter(
+ controller=controller_node).order_by('timestamp')
+ exec_os_wrapper('NetworkConfig', 'set',
+ [serializers.serialize("json", [controller_node]),
+ serializers.serialize("json", dns)])
+ else:
+ # op != 'DELETE'
+ #
+ # XXX what about HA?
+ # 'ifs' below isn't filtered by controller, the NetConfig
+ # target will only select interfaces assocaited with the
+ # controller-node 'localhost.
+ dns = ControllerDomainNameServer.objects.filter(
+ controller=controller_node).order_by('-priority')
+ ifs = ControllerInterface.objects.filter(controller=controller_node)
+ exec_os_wrapper('NetworkConfig', 'set',
+ [serializers.serialize("json", [controller_node]),
+ serializers.serialize("json", dns),
+ serializers.serialize("json", ifs)])
+
+def firewall_entry_handler(op, old_instance, new_instance, modified_fields=None):
+ #allow in on eth0 proto tcp from any to any port 80
+ print "XXX: firewall handler called-1"
+ command = ""
+ if op == "DELETE" and str(old_instance.interface.controller) == get_local_controller_id():
+ command += "delete "
+ instance = old_instance
+ elif (op == "INSERT" or op == "UPDATE") and str(new_instance.interface.controller) == get_local_controller_id():
+ instance = new_instance
+ else:
+ return
+
+ print instance.action
+ print instance.proto
+ print instance.port
+ print instance.src_ip
+ print instance.vrrp_ip
+ print "XXX: firewall handler called-2"
+ controller_interface = instance.interface
+ eth = 'eth' + str(controller_interface.number) #LOOK! Hardcoded to eth interface
+ proto_str = ""
+ if instance.proto != '' and instance.proto != 'vrrp':
+ proto_str = " proto " + instance.proto
+ action_str = instance.action
+ src_str = " from any"
+ if instance.src_ip != '':
+ src_str = " from " + instance.src_ip
+ dst_str = " to any"
+ if instance.vrrp_ip != '':
+ dst_str = " to " + instance.vrrp_ip
+ print "dst_str = ", dst_str
+ port_str = ""
+ if instance.port != 0:
+ port_str = " port " + str(instance.port)
+
+ command += (action_str + " in on " + eth + proto_str + src_str + dst_str + port_str)
+ print command
+
+ exec_os_wrapper('ExecuteUfwCommand', 'set', [command])
+ if instance.port == 6633 and action_str == 'reject' and op != 'DELETE':
+ exec_os_wrapper('RestartSDNPlatform', 'set', [])
+
+def ntp_config_handler(op, old_instance, new_instance, modified_fields=None):
+ if new_instance != None:
+ exec_os_wrapper("SetNtpServer", 'set', [new_instance.ntp_server])
+
+def tz_config_handler(op, old_instance, new_instance, modified_fields=None):
+ if op == "DELETE":
+ if str(old_instance.id) != get_local_controller_id():
+ return
+ exec_os_wrapper("UnsetTimezone", 'set')
+ elif op == "INSERT" or op == "UPDATE":
+ if str(new_instance.id) != get_local_controller_id():
+ return
+ if new_instance.time_zone != None and str(new_instance.time_zone) != "":
+ exec_os_wrapper("SetTimezone", 'set', [new_instance.time_zone])
+
+def logging_server_config_handler(op, old_instance, new_instance, modified_fields=None):
+ if op == "DELETE":
+ if str(old_instance.id) != get_local_controller_id():
+ return
+ exec_os_wrapper("UnsetSyslogServer", 'set',
+ [old_instance.logging_server, old_instance.logging_level])
+ elif op == "INSERT" or op == "UPDATE":
+ if str(new_instance.id) != get_local_controller_id():
+ return
+ if new_instance.logging_server != "" and new_instance.logging_enabled:
+ exec_os_wrapper("SetSyslogServer", 'set',
+ [new_instance.logging_server, new_instance.logging_level])
+ else:
+ exec_os_wrapper("UnsetSyslogServer", 'set',
+ [new_instance.logging_server, new_instance.logging_level])
+
+def vrrp_virtual_router_id_config_handle(op, old_instance, new_instance, modified_fields=None):
+ if op == "INSERT" or op == "UPDATE":
+ exec_os_wrapper("SetVrrpVirtualRouterId", 'set',
+ [new_instance.cluster_number])
+
+def netvirt_feature_config_handler(op, old_instance, new_instance, modified_fields=None):
+ if op == "INSERT" or op == "UPDATE":
+ if new_instance.netvirt_feature:
+ exec_os_wrapper("SetDefaultConfig", 'set', [new_instance.netvirt_feature])
+ else:
+ exec_os_wrapper("SetStaticFlowOnlyConfig", 'set', [new_instance.netvirt_feature])
+
+def controller_alias_config_handler(op, old_instance, new_instance, modified_fields=None):
+ if op == 'INSERT' or op == 'UPDATE':
+ if str(new_instance.controller) == get_local_controller_id():
+ exec_os_wrapper("SetHostname", 'set', [new_instance.alias])
+
+def tacacs_plus_config_handler(op, old_instance, new_instance, modified_fields=None):
+
+ if isinstance(old_instance, TacacsPlusConfig):
+ if op == 'DELETE':
+ # deleting the config singleton (presumably during shutdown?)
+ return
+
+ if isinstance(old_instance, TacacsPlusConfig):
+ config_id = old_instance.id
+ else:
+ config_id = 'tacacs'
+ try:
+ config = TacacsPlusConfig.objects.get(pk=config_id)
+ except TacacsPlusConfig.DoesNotExist:
+ # cons up a dummy config object, not necessary to save it
+ config = TacacsPlusConfig()
+
+ # get current list of hosts (op==DELETE ignored here)
+ ##hosts = TacacsPlusHost.objects.order_by('timestamp')
+ def timestampSort(h1, h2):
+ return cmp(h1.timestamp, h2.timestamp)
+ hosts = sorted(TacacsPlusHost.objects.all(), timestampSort)
+
+ # XXX roth -- config is passed as-is, not as a single-element list
+ cj = serializers.serialize("json", [config])
+ hj = serializers.serialize("json", hosts)
+ print "Calling oswrapper with:", [cj, hj]
+ exec_os_wrapper('TacacsPlusConfig', 'set', [cj, hj])
+
+def snmp_server_config_handler(op, old_instance, new_instance, modified_fields=None):
+ if op == 'DELETE':
+ exec_os_wrapper('UnsetSnmpServerConfig', 'set', [])
+ elif op == 'INSERT' or op == 'UPDATE':
+ # enable_changed is true if operation is INSERT, else compare with old instance
+ if (op == 'INSERT'):
+ enable_changed = (new_instance.server_enable is True) #since default is False
+ print 'operation= insert, enable_changed = ', enable_changed
+ else:
+ enable_changed = (new_instance.server_enable != old_instance.server_enable)
+ server_enable = new_instance.server_enable
+ community = '' if new_instance.community is None else new_instance.community
+ location = '' if new_instance.location is None else new_instance.location
+ contact = '' if new_instance.contact is None else new_instance.contact
+
+ print "Calling oswrapper with:", [server_enable, community, location, contact, enable_changed]
+ exec_os_wrapper('SetSnmpServerConfig', 'set',
+ [server_enable, community, location, contact, enable_changed])
+
+def test_config_handler(op, old_instance, new_instance, modified_fields=None):
+ pass
+
+def images_user_ssh_key_config_handler(op, old_instance, new_instance, modified_fields=None):
+ if op == 'INSERT' or op == 'UPDATE':
+ sshkey = "\"" + str(new_instance.images_user_ssh_key) + "\""
+ exec_os_wrapper('SetImagesUserSSHKey', 'set', [sshkey])
+
+def init_config():
+ #
+ # Associate the config handlers with specific callout for each of the fields
+ # Keep in mind that these are the django names, NOT the rest api names,
+ #
+ disabled_by_shell_variable = os.environ.get('SDNCON_CONFIG_HANDLERS_DISABLED', False)
+ disabled_by_file = os.path.exists("%s/sdncon_config_handlers_disabled" % sdncon.SDN_ROOT)
+ if not disabled_by_shell_variable and not disabled_by_file:
+ add_config_handler({Controller: ['ntp_server']}, ntp_config_handler)
+ add_config_handler({Controller: ['time_zone']}, tz_config_handler)
+ add_config_handler(
+ {
+ Controller: ['domain_lookups_enabled', 'domain_name', 'default_gateway'],
+ ControllerDomainNameServer: None,
+ ControllerInterface: ['ip', 'netmask', 'mode'],
+ }, network_config_handler)
+ add_config_handler({ControllerAlias: ['alias']}, controller_alias_config_handler)
+ add_config_handler({Controller: ['logging_enabled', 'logging_server', 'logging_level']}, logging_server_config_handler)
+ add_config_handler({Feature: ['netvirt_feature']}, netvirt_feature_config_handler)
+ add_config_handler({FirewallRule: None}, firewall_entry_handler)
+ add_config_handler({GlobalConfig: ['cluster_number']}, vrrp_virtual_router_id_config_handle)
+ add_config_handler({ TacacsPlusConfig: ["tacacs_plus_authn", "tacacs_plus_authz", "tacacs_plus_acct",
+ "local_authn", "local_authz",
+ "timeout", "key",],
+ TacacsPlusHost: ['ip', 'key'],
+ },
+ tacacs_plus_config_handler)
+ add_config_handler({SnmpServerConfig: ['server_enable', 'community', 'location', 'contact']}, snmp_server_config_handler)
+ add_config_handler({ImageDropUser: ['images_user_ssh_key']}, images_user_ssh_key_config_handler)
+ else:
+ add_config_handler(
+ {
+ Controller: ['domain_lookups_enabled', 'domain_name', 'default_gateway'],
+ ControllerDomainNameServer: None,
+ ControllerInterface: ['ip', 'netmask', 'mode'],
+ ControllerAlias: ['alias'],
+ FirewallRule: None,
+ Feature: None,
+ GlobalConfig: ['ha-enabled', 'cluster-number'],
+ }, test_config_handler)