Signed-off-by: Isaku Yamahata <[email protected]> --- ryu/tests/integrated/test_of_config.py | 170 ++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 ryu/tests/integrated/test_of_config.py
diff --git a/ryu/tests/integrated/test_of_config.py b/ryu/tests/integrated/test_of_config.py new file mode 100644 index 0000000..9c74ec6 --- /dev/null +++ b/ryu/tests/integrated/test_of_config.py @@ -0,0 +1,170 @@ +# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation. +# Copyright (C) 2013 Isaku Yamahata <yamahata at private email ne jp> +# +# Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 +# +# 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. + +import gevent +import traceback + +import lxml.etree +import ncclient + +from ryu.base import app_manager +from ryu.lib import of_config +from ryu.lib.of_config import capable_switch + + +# Change those depending on switch configuration +HOST = '127.0.0.1' +PORT = 1830 +USERNAME = 'linc' +PASSWORD = 'linc' + +CAPABLE_SWITCH_ID = 'CapableSwitch0' +LOGICAL_SWITCH = 'LogicalSwitch0' +PORT_ID = 'LogicalSwitch0-Port2' +CONTROLLER_ID = 'Switch0-DefaultController' + +PORT_DICT = { + 'capable_switch': CAPABLE_SWITCH_ID, + 'port_id': PORT_ID, + 'logical_switch': LOGICAL_SWITCH, + 'controller_id': CONTROLLER_ID, + 'ip': HOST, +} + +SWITCH_PORT_DOWN = ''' +<nc:config xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> + <capable-switch xmlns="urn:onf:of111:config:yang"> + <id>%(capable_switch)s</id> + <resources> + <port> + <resource-id>%(port_id)s</resource-id> + <configuration operation="merge"> + <admin-state>down</admin-state> + <no-receive>false</no-receive> + <no-forward>false</no-forward> + <no-packet-in>false</no-packet-in> + </configuration> + </port> + </resources> + </capable-switch> +</nc:config> +''' % PORT_DICT + +SWITCH_ADVERTISED = ''' +<nc:config xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> + <capable-switch xmlns="urn:onf:of111:config:yang"> + <id>%(capable_switch)s</id> + <resources> + <port> + <resource-id>%(port_id)s</resource-id> + <features> + <advertised operation="merge"> + <rate>10Mb-FD</rate> + <auto-negotiate>true</auto-negotiate> + <medium>copper</medium> + <pause>unsupported</pause> + </advertised> + </features> + </port> + </resources> + </capable-switch> +</nc:config> +''' % PORT_DICT + +SWITCH_CONTROLLER = ''' +<nc:config xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> + <capable-switch xmlns="urn:onf:of111:config:yang"> + <id>%(capable_switch)s</id> + <logical-switches> + <switch> + <id>%(logical_switch)s</id> + <controllers> + <controller operation="merge"> + <id>%(controller_id)s</id> + <role>master</role> + <ip-address>%(ip)s</ip-address> + <port>6633</port> + <protocol>tcp</protocol> + </controller> + </controllers> + </switch> + </logical-switches> + </capable-switch> +</nc:config> +''' % PORT_DICT + + +def _get_schema(): + # file_name = of_config.OF_CONFIG_1_0_XSD + # file_name = of_config.OF_CONFIG_1_1_XSD + file_name = of_config.OF_CONFIG_1_1_1_XSD + return lxml.etree.XMLSchema(file=file_name) + + +class OFConfigClient(app_manager.RyuApp): + def __init__(self, *args, **kwargs): + super(OFConfigClient, self).__init__(*args, **kwargs) + self.switch = capable_switch.CapableSwitch( + host=HOST, port=PORT, username=USERNAME, password=PASSWORD) + gevent.spawn(self._do_of_config) + + def _validate(self, tree): + xmlschema = _get_schema() + try: + xmlschema.assertValid(tree) + except: + traceback.print_exc() + + def _do_get(self): + data_xml = self.switch.get() + + tree = lxml.etree.fromstring(data_xml) + # print(lxml.etree.tostring(tree, pretty_print=True)) + self._validate(tree) + + name_spaces = set() + for e in tree.getiterator(): + name_spaces.add(capable_switch.get_ns_tag(e.tag)[0]) + print(name_spaces) + + def _do_get_config(self, source): + print('source = %s' % source) + config_xml = self.switch.get_config(source) + + tree = lxml.etree.fromstring(config_xml) + # print(lxml.etree.tostring(tree, pretty_print=True)) + self._validate(tree) + + def _do_edit_config(self, config): + tree = lxml.etree.fromstring(config) + self._validate(tree) + self.switch.edit_config(target='running', config=config) + + def _do_of_config(self): + self.switch.connect() + self._do_get() + self._do_get_config('running') + self._do_get_config('startup') + + # LINC doesn't support 'candidate' datastore + try: + self._do_get_config('candidate') + except ncclient.NCClientError: + traceback.print_exc() + + self._do_edit_config(SWITCH_PORT_DOWN) + self._do_edit_config(SWITCH_ADVERTISED) + self._do_edit_config(SWITCH_CONTROLLER) -- 1.7.10.4 ------------------------------------------------------------------------------ Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the endpoint security space. For insight on selecting the right partner to tackle endpoint security challenges, access the full report. http://p.sf.net/sfu/symantec-dev2dev _______________________________________________ Ryu-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/ryu-devel
