#!/usr/bin/env python # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you 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 getopt import sys import socket import os from qpid import qmfconsole def Usage (): print "Usage: qpid-route [OPTIONS] link add " print " qpid-route [OPTIONS] link del " print " qpid-route [OPTIONS] link list []" print print " qpid-route [OPTIONS] route add [tag] [exclude-list]" print " qpid-route [OPTIONS] route del " print " qpid-route [OPTIONS] route list []" print " qpid-route [OPTIONS] route flush []" print print "Options:" print " -v [ --verbose ] Verbose output" print " -q [ --quiet ] Quiet output, don't print duplicate warnings" print " -d [ --durable ] Added configuration shall be durable" print " -e [ --del-empty-link ] Delete link after deleting last route on the link" print print " dest-broker and src-broker are in the form: [username/password@] hostname | ip-address [:]" print " ex: localhost, 10.1.1.7:10000, broker-host:10000, guest/guest@localhost" print sys.exit (1) _verbose = False _quiet = False _durable = False _dellink = False class RouteManager: def __init__ (self, destBroker): self.dest = qmfconsole.BrokerURL(destBroker) self.src = None self.qmf = qmfconsole.Session() self.broker = self.qmf.addBroker(destBroker) def Disconnect (self): self.qmf.delBroker(self.broker) def getLink (self): links = self.qmf.getObjects(_class="link") for link in links: if "%s:%d" % (link.host, link.port) == self.src.name (): return link return None def AddLink (self, srcBroker): self.src = qmfconsole.BrokerURL(srcBroker) if self.dest.name() == self.src.name(): print "Linking broker to itself is not permitted" sys.exit(1) brokers = self.qmf.getObjects(_class="broker") broker = brokers[0] link = self.getLink() if link != None: raise Exception("Link already exists") if self.src.authName == "anonymous": mech = "ANONYMOUS" else: mech = "PLAIN" res = broker.connect(self.src.host, self.src.port, False, _durable, mech, self.src.authName, self.src.authPass) if _verbose: print "Connect method returned:", res.status, res.text link = self.getLink() def DelLink (self, srcBroker): self.src = qmfconsole.BrokerURL(srcBroker) brokers = self.qmf.getObjects(_class="broker") broker = brokers[0] link = self.getLink() if link == None: raise Exception("Link not found") res = link.close() if _verbose: print "Close method returned:", res.status, res.text def ListLinks (self): links = self.qmf.getObjects(_class="link") if len(links) == 0: print "No Links Found" else: print print "Host Port Durable State Last Error" print "===================================================================" for link in links: print "%-16s%-8d %c %-18s%s" % \ (link.host, link.port, YN(link.durable), link.state, link.lastError) def AddRoute (self, srcBroker, exchange, routingKey, tag, excludes): self.src = qmfconsole.BrokerURL(srcBroker) if self.dest.name() == self.src.name(): raise Exception("Linking broker to itself is not permitted") brokers = self.qmf.getObjects(_class="broker") broker = brokers[0] link = self.getLink() if link == None: if _verbose: print "Inter-broker link not found, creating..." if self.src.authName == "anonymous": mech = "ANONYMOUS" else: mech = "PLAIN" res = broker.connect(self.src.host, self.src.port, False, _durable, mech, self.src.authName, self.src.authPass) if _verbose: print "Connect method returned:", res.status, res.text link = self.getLink() if link == None: raise Exception("Protocol Error - Missing link ID") bridges = self.qmf.getObjects(_class="bridge") for bridge in bridges: if bridge.linkRef == link.getObjectId() and \ bridge.dest == exchange and bridge.key == routingKey: if not _quiet: raise Exception("Duplicate Route - ignoring: %s(%s)" % (exchange, routingKey)) sys.exit (0) if _verbose: print "Creating inter-broker binding..." res = link.bridge(_durable, exchange, exchange, routingKey, tag, excludes, 0, 0) if res.status == 4: raise Exception("Can't create a durable route on a non-durable link") if _verbose: print "Bridge method returned:", res.status, res.text def DelRoute (self, srcBroker, exchange, routingKey): self.src = qmfconsole.BrokerURL(srcBroker) link = self.getLink() if link == None: if not _quiet: raise Exception("No link found from %s to %s" % (self.src.name(), self.dest.name())) sys.exit (0) bridges = self.qmf.getObjects(_class="bridge") for bridge in bridges: if bridge.linkRef == link.getObjectId() and bridge.dest == exchange and bridge.key == routingKey: if _verbose: print "Closing bridge..." res = bridge.close() if res.status != 0: raise Exception("Error closing bridge: %d - %s" % (res.status, res.text)) if len (bridges) == 1 and _dellink: link = self.getLink () if link == None: sys.exit (0) if _verbose: print "Last bridge on link, closing link..." res = link.close() if res.status != 0: raise Exception("Error closing link: %d - %s" % (res.status, res.text)) sys.exit (0) if not _quiet: raise Exception("Route not found") def ListRoutes (self): links = self.qmf.getObjects(_class="link") bridges = self.qmf.getObjects(_class="bridge") for bridge in bridges: myLink = None for link in links: if bridge.linkRef == link.getObjectId(): myLink = link break if myLink != None: print "%s %s:%d %s %s" % (self.dest.name(), myLink.host, myLink.port, bridge.dest, bridge.key) def ClearAllRoutes (self): links = self.qmf.getObjects(_class="link") bridges = self.qmf.getObjects(_class="bridge") for bridge in bridges: if _verbose: myLink = None for link in links: if bridge.linkRef == link.getObjectId(): myLink = link break if myLink != None: print "Deleting Bridge: %s:%d %s %s... " % (myLink.host, myLink.port, bridge.dest, bridge.key), res = bridge.close() if res.status != 0: print "Error: %d - %s" % (res.status, res.text) elif _verbose: print "Ok" if _dellink: links = self.qmf.getObjects(_class="link") for link in links: if _verbose: print "Deleting Link: %s:%d... " % (link.host, link.port), res = link.close() if res.status != 0: print "Error: %d - %s" % (res.status, res.text) elif _verbose: print "Ok" def YN(val): if val == 1: return 'Y' return 'N' ## ## Main Program ## try: longOpts = ("verbose", "quiet", "durable", "del-empty-link") (optlist, cargs) = getopt.gnu_getopt (sys.argv[1:], "vqde", longOpts) except: Usage () for opt in optlist: if opt[0] == "-v" or opt[0] == "--verbose": _verbose = True if opt[0] == "-q" or opt[0] == "--quiet": _quiet = True if opt[0] == "-d" or opt[0] == "--durable": _durable = True if opt[0] == "-e" or opt[0] == "--del-empty-link": _dellink = True nargs = len (cargs) if nargs < 2: Usage () if nargs == 2: destBroker = "localhost" else: destBroker = cargs[2] group = cargs[0] cmd = cargs[1] try: rm = RouteManager (destBroker) if group == "link": if cmd == "add": if nargs != 4: Usage() rm.AddLink (cargs[3]) elif cmd == "del": if nargs != 4: Usage() rm.DelLink (cargs[3]) elif cmd == "list": rm.ListLinks () elif group == "route": if cmd == "add": if nargs < 6 or nargs > 8: Usage () tag = "" excludes = "" if nargs > 6: tag = cargs[6] if nargs > 7: excludes = cargs[7] rm.AddRoute (cargs[3], cargs[4], cargs[5], tag, excludes) elif cmd == "del": if nargs != 6: Usage () else: rm.DelRoute (cargs[3], cargs[4], cargs[5]) else: if cmd == "list": rm.ListRoutes () elif cmd == "flush": rm.ClearAllRoutes () else: Usage () except Exception,e: print "Failed:", e.message sys.exit(1) rm.Disconnect ()