the placement (ryu/tests/bin) was suggested by FUJITA Tomonori.

Signed-off-by: YAMAMOTO Takashi <[email protected]>
---
 ryu/cmd/of_config_cli.py    | 473 ++++++++++++++++++++++++++++++++++++++++++++
 ryu/tests/bin/of-config-cli |  20 ++
 2 files changed, 493 insertions(+)
 create mode 100755 ryu/cmd/of_config_cli.py
 create mode 100755 ryu/tests/bin/of-config-cli

diff --git a/ryu/cmd/of_config_cli.py b/ryu/cmd/of_config_cli.py
new file mode 100755
index 0000000..1803849
--- /dev/null
+++ b/ryu/cmd/of_config_cli.py
@@ -0,0 +1,473 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation.
+# Copyright (C) 2013 YAMAMOTO Takashi <yamamoto at valinux co 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.
+
+# a simple command line OF-CONFIG client
+#
+# a usage example:
+#     % PYTHONPATH=. ./bin/of_config_cli \
+#      --peers=sw1=localhost:1830:username:password
+#     (Cmd) raw_get sw1
+
+import ryu.contrib
+
+from oslo.config import cfg
+
+import cmd
+import sys
+import lxml.etree as ET
+
+from ryu.lib import of_config
+from ryu.lib.of_config import capable_switch
+from ryu.lib.of_config import constants as consts
+from ncclient.operations.rpc import RPCError
+import ryu.lib.of_config.classes as ofc
+
+
+CONF = cfg.CONF
+CONF.register_cli_opts([
+    cfg.ListOpt('peers', default=[], help='list of peers')
+])
+
+
+class Peer(capable_switch.OFCapableSwitch):
+    def __init__(self, name, host, port, username, password):
+        self._name = name
+        super(Peer, self).__init__(
+            host=host, port=port, username=username, password=password,
+            unknown_host_cb=lambda host, fingeprint: True)
+
+
+peers = {}
+
+
+def add_peer(name, host, port, username, password):
+    peers[name] = Peer(name, host, port, username, password)
+
+
+def et_tostring_pp(tree):
+    # pretty_print is an lxml feature, not available in ElementTree
+    try:
+        return ET.tostring(tree, pretty_print=True)
+    except TypeError:
+        return ET.tostring(tree)
+
+
+def validate(tree):
+    schema = ET.XMLSchema(file=of_config.OF_CONFIG_1_1_1_XSD)
+    if not schema(tree):
+        print schema.error_log
+
+
+def _pythonify(name):
+    # XXX code duplication
+    return name.replace('-', '_')
+
+
+class Cmd(cmd.Cmd):
+    def __init__(self, *args, **kwargs):
+        self._in_onecmd = False
+        cmd.Cmd.__init__(self, *args, **kwargs)
+
+    def _request(self, line, f):
+        args = line.split()
+        try:
+            peer = args[0]
+        except:
+            print "argument error"
+            return
+        try:
+            p = peers[peer]
+        except KeyError:
+            print "unknown peer", peer
+            return
+        try:
+            f(p, args[1:])
+        except RPCError, e:
+            print "RPC Error", e
+        except EOFError:
+            print "disconnected"
+
+    def _complete_peer(self, text, line, _begidx, _endidx):
+        if len((line + 'x').split()) >= 3:
+            return []
+        return [name for name in peers if name.startswith(text)]
+
+    def do_list_cap(self, line):
+        """list_cap <peer>
+        """
+
+        def f(p, args):
+            for i in p.netconf.server_capabilities:
+                print i
+
+        self._request(line, f)
+
+    def do_raw_get(self, line):
+        """raw_get <peer>
+        """
+
+        def f(p, args):
+            result = p.raw_get()
+            tree = ET.fromstring(result)
+            validate(tree)
+            print et_tostring_pp(tree)
+
+        self._request(line, f)
+
+    def do_raw_get_config(self, line):
+        """raw_get_config <peer> <source>
+        """
+
+        def f(p, args):
+            try:
+                source = args[0]
+            except:
+                print "argument error"
+                return
+            result = p.raw_get_config(source)
+            tree = ET.fromstring(result)
+            validate(tree)
+            print et_tostring_pp(tree)
+
+        self._request(line, f)
+
+    def do_get(self, line):
+        """get <peer>
+        eg. get_config sw1
+        """
+
+        def f(p, args):
+            print p.get()
+
+        self._request(line, f)
+
+    def do_get_config(self, line):
+        """get_config <peer> <source>
+        eg. get_config sw1 startup
+        """
+
+        def f(p, args):
+            try:
+                source = args[0]
+            except:
+                print "argument error"
+                return
+            print p.get_config(source)
+
+        self._request(line, f)
+
+    def do_list_port(self, line):
+        """list_port <peer>
+        """
+
+        def f(p, args):
+            o = p.get()
+            for p in o.resources.port:
+                print p.resource_id, p.name, p.number
+
+        self._request(line, f)
+
+    _port_settings = [
+        'admin-state',
+        'no-forward',
+        'no-packet-in',
+        'no-receive',
+    ]
+
+    def do_get_port_config(self, line):
+        """get_config_port <peer> <source> <port>
+        eg. get_port_config sw1 running LogicalSwitch7-Port2
+        """
+
+        def f(p, args):
+            try:
+                source, port = args
+            except:
+                print "argument error"
+                return
+            o = p.get_config(source)
+            for p in o.resources.port:
+                if p.resource_id != port:
+                    continue
+                print p.resource_id
+                conf = p.configuration
+                for k in self._port_settings:
+                    try:
+                        v = getattr(conf, _pythonify(k))
+                    except AttributeError:
+                        continue
+                    print k, v
+
+        self._request(line, f)
+
+    def do_set_port_config(self, line):
+        """set_port_config <peer> <target> <port> <key> <value>
+        eg. set_port_config sw1 running LogicalSwitch7-Port2 admin-state down
+        eg. set_port_config sw1 running LogicalSwitch7-Port2 no-forward false
+        """
+
+        def f(p, args):
+            try:
+                target, port, key, value = args
+            except:
+                print "argument error"
+                print args
+                return
+
+            # get switch id
+            o = p.get()
+            capable_switch_id = o.id
+
+            try:
+                capable_switch = ofc.OFCapableSwitchType(
+                    id=capable_switch_id,
+                    resources=ofc.OFCapableSwitchResourcesType(
+                        port=[
+                            ofc.OFPortType(
+                                resource_id=port,
+                                configuration=ofc.OFPortConfigurationType(
+                                    **{_pythonify(key): value}))
+                        ]
+                    )
+                )
+            except TypeError:
+                print "argument error"
+                return
+            try:
+                p.edit_config(target, capable_switch)
+            except Exception, e:
+                print e
+
+        self._request(line, f)
+
+    def do_list_queue(self, line):
+        """list_queue <peer>
+        """
+
+        def f(p, args):
+            o = p.get()
+            if o.resources.queue:
+                for q in o.resources.queue:
+                    print q.resource_id, q.port
+
+        self._request(line, f)
+
+    _queue_settings = [
+        'max-rate',
+        'min-rate',
+        'experimenter',
+    ]
+
+    def do_get_queue_config(self, line):
+        """get_queue_port <peer> <source> <queue>
+        eg. get_queue_config sw1 running LogicalSwitch7-Port1-Queue922
+        """
+
+        def f(p, args):
+            try:
+                source, queue = args
+            except:
+                print "argument error"
+                return
+            o = p.get_config(source)
+            for q in o.resources.queue:
+                if q.resource_id != queue:
+                    continue
+                print q.resource_id
+                conf = q.properties
+                for k in self._queue_settings:
+                    try:
+                        v = getattr(conf, _pythonify(k))
+                    except AttributeError:
+                        continue
+                    print k, v
+
+        self._request(line, f)
+
+    def do_set_queue_config(self, line):
+        """set_queue_config <peer> <target> <queue> <key> <value>
+        eg. set_queue_config sw1 running LogicalSwitch7-Port1-Queue922 \
+max-rate 100
+        """
+
+        def f(p, args):
+            try:
+                target, queue, key, value = args
+            except:
+                print "argument error"
+                print args
+                return
+
+            # get switch id
+            o = p.get()
+            capable_switch_id = o.id
+
+            try:
+                capable_switch = ofc.OFCapableSwitchType(
+                    id=capable_switch_id,
+                    resources=ofc.OFCapableSwitchResourcesType(
+                        queue=[
+                            ofc.OFQueueType(
+                                resource_id=queue,
+                                properties=ofc.OFQueuePropertiesType(
+                                    **{_pythonify(key): value})),
+                        ]
+                    )
+                )
+            except TypeError:
+                print "argument error"
+                return
+            try:
+                p.edit_config(target, capable_switch)
+            except Exception, e:
+                print e
+
+        self._request(line, f)
+
+    def do_list_logical_switch(self, line):
+        """list_logical_switch <peer>
+        """
+
+        def f(p, args):
+            o = p.get()
+            for s in o.logical_switches.switch:
+                print s.id, s.datapath_id
+
+        self._request(line, f)
+
+    def do_show_logical_switch(self, line):
+        """show_logical_switch <peer> <logical switch>
+        """
+
+        def f(p, args):
+            try:
+                (lsw,) = args
+            except:
+                print "argument error"
+                return
+            o = p.get()
+            for s in o.logical_switches.switch:
+                if s.id != lsw:
+                    continue
+                print s.id
+                print 'datapath-id', s.datapath_id
+                if s.resources.queue:
+                    print 'queues:'
+                    for q in s.resources.queue:
+                        print '\t', q
+                if s.resources.port:
+                    print 'ports:'
+                    for p in s.resources.port:
+                        print '\t', p
+
+        self._request(line, f)
+
+    _lsw_settings = [
+        'lost-connection-behavior',
+    ]
+
+    def do_get_logical_switch_config(self, line):
+        """get_logical_switch_config <peer> <source> <logical switch>
+        """
+
+        def f(p, args):
+            try:
+                source, lsw = args
+            except:
+                print "argument error"
+                return
+            o = p.get_config(source)
+            for l in o.logical_switches.switch:
+                if l.id != lsw:
+                    continue
+                print l.id
+                for k in self._lsw_settings:
+                    try:
+                        v = getattr(l, _pythonify(k))
+                    except AttributeError:
+                        continue
+                    print k, v
+
+        self._request(line, f)
+
+    def do_set_logical_switch_config(self, line):
+        """set_logical_switch_config <peer> <logical switch> <key> <value>
+        eg. set_logical_switch_config sw1 running LogicalSwitch7 \
+lost-connection-behavior failStandaloneMode
+        """
+
+        def f(p, args):
+            try:
+                target, lsw, key, value = args
+            except:
+                print "argument error"
+                return
+
+            # get switch id
+            o = p.get_config(target)
+            capable_switch_id = o.id
+
+            try:
+                capable_switch = ofc.OFCapableSwitchType(
+                    id=capable_switch_id,
+                    logical_switches=ofc.OFCapableSwitchLogicalSwitchesType(
+                        switch=[ofc.OFLogicalSwitchType(
+                            id=lsw,
+                            **{_pythonify(key): value}
+                        )]
+                    )
+                )
+            except TypeError:
+                print "argument error"
+                return
+            try:
+                p.edit_config(target, capable_switch)
+            except Exception, e:
+                print e
+
+        self._request(line, f)
+
+    completedefault = _complete_peer
+
+    def complete_EOF(self, _text, _line, _begidx, _endidx):
+        return []
+
+    def do_EOF(self, _line):
+        sys.exit(0)
+
+    def onecmd(self, string):
+        self._in_onecmd = True
+        try:
+            return cmd.Cmd.onecmd(self, string)
+        finally:
+            self._in_onecmd = False
+
+
+def main():
+    CONF(project='of-config-cli', version='of-config-cli')
+
+    for p_str in CONF.peers:
+        name, addr = p_str.split('=')
+        host, port, username, password = addr.rsplit(':', 3)
+        add_peer(name, host, port, username, password)
+
+    Cmd().cmdloop()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/ryu/tests/bin/of-config-cli b/ryu/tests/bin/of-config-cli
new file mode 100755
index 0000000..c076ee8
--- /dev/null
+++ b/ryu/tests/bin/of-config-cli
@@ -0,0 +1,20 @@
+#!/usr/bin/env python
+
+# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation.
+# Copyright (C) 2013 YAMAMOTO Takashi <yamamoto at valinux co 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.
+
+from ryu.cmd.of_config_cli import main
+main()
-- 
1.8.3.1


------------------------------------------------------------------------------
Rapidly troubleshoot problems before they affect your business. Most IT 
organizations don't have a clear picture of how application performance 
affects their revenue. With AppDynamics, you get 100% visibility into your 
Java,.NET, & PHP application. Start your 15-day FREE TRIAL of AppDynamics Pro!
http://pubads.g.doubleclick.net/gampad/clk?id=84349831&iu=/4140/ostg.clktrk
_______________________________________________
Ryu-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to