of_config: sample test code to use ofconfig capable_switch
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp> Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
This commit is contained in:
parent
e2566bbd70
commit
3cfb6fa6e9
229
ryu/tests/integrated/test_of_config.py
Normal file
229
ryu/tests/integrated/test_of_config.py
Normal file
@ -0,0 +1,229 @@
|
||||
# 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.netconf import constants as nc_consts
|
||||
from ryu.lib import of_config
|
||||
from ryu.lib.of_config import capable_switch
|
||||
from ryu.lib.of_config import constants as ofc_consts
|
||||
|
||||
|
||||
# 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.OFCapableSwitch(
|
||||
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)
|
||||
|
||||
return tree
|
||||
|
||||
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 _print_ports(self, tree, ns):
|
||||
for port in tree.findall('{%s}%s/{%s}%s' % (ns, ofc_consts.RESOURCES,
|
||||
ns, ofc_consts.PORT)):
|
||||
print(lxml.etree.tostring(port, pretty_print=True))
|
||||
|
||||
def _set_ports_down(self):
|
||||
"""try to set all ports down with etree operation"""
|
||||
tree = self._do_get()
|
||||
print lxml.etree.tostring(tree, pretty_print=True)
|
||||
|
||||
qname = lxml.etree.QName(tree.tag)
|
||||
ns = qname.namespace
|
||||
self._print_ports(tree, ns)
|
||||
|
||||
switch_id = tree.find('{%s}%s' % (ns, ofc_consts.ID))
|
||||
resources = tree.find('{%s}%s' % (ns, ofc_consts.RESOURCES))
|
||||
configuration = tree.find(
|
||||
'{%s}%s/{%s}%s/{%s}%s' % (ns, ofc_consts.RESOURCES,
|
||||
ns, ofc_consts.PORT,
|
||||
ns, ofc_consts.CONFIGURATION))
|
||||
admin_state = tree.find(
|
||||
'{%s}%s/{%s}%s/{%s}%s/{%s}%s' % (ns, ofc_consts.RESOURCES,
|
||||
ns, ofc_consts.PORT,
|
||||
ns, ofc_consts.CONFIGURATION,
|
||||
ns, ofc_consts.ADMIN_STATE))
|
||||
|
||||
config_ = lxml.etree.Element(
|
||||
'{%s}%s' % (ncclient.xml_.BASE_NS_1_0, nc_consts.CONFIG))
|
||||
capable_switch_ = lxml.etree.SubElement(config_, tree.tag)
|
||||
switch_id_ = lxml.etree.SubElement(capable_switch_, switch_id.tag)
|
||||
switch_id_.text = switch_id.text
|
||||
resources_ = lxml.etree.SubElement(capable_switch_,
|
||||
resources.tag)
|
||||
for port in tree.findall(
|
||||
'{%s}%s/{%s}%s' % (ns, ofc_consts.RESOURCES,
|
||||
ns, ofc_consts.PORT)):
|
||||
resource_id = port.find('{%s}%s' % (ns, ofc_consts.RESOURCE_ID))
|
||||
|
||||
port_ = lxml.etree.SubElement(resources_, port.tag)
|
||||
resource_id_ = lxml.etree.SubElement(port_, resource_id.tag)
|
||||
resource_id_.text = resource_id.text
|
||||
configuration_ = lxml.etree.SubElement(port_, configuration.tag)
|
||||
configuration_.set(ofc_consts.OPERATION, nc_consts.MERGE)
|
||||
admin_state_ = lxml.etree.SubElement(configuration_,
|
||||
admin_state.tag)
|
||||
admin_state_.text = ofc_consts.DOWN
|
||||
self._do_edit_config(lxml.etree.tostring(config_, pretty_print=True))
|
||||
|
||||
tree = self._do_get()
|
||||
self._print_ports(tree, ns)
|
||||
|
||||
def _do_of_config(self):
|
||||
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()
|
||||
|
||||
# use raw XML format
|
||||
self._do_edit_config(SWITCH_PORT_DOWN)
|
||||
self._do_edit_config(SWITCH_ADVERTISED)
|
||||
self._do_edit_config(SWITCH_CONTROLLER)
|
||||
|
||||
self._set_ports_down()
|
||||
|
||||
self.switch.close_session()
|
Loading…
Reference in New Issue
Block a user