Skip to content

Instantly share code, notes, and snippets.

@codeout
Last active January 17, 2016 12:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save codeout/20bc799560b6efe7b2be to your computer and use it in GitHub Desktop.
Save codeout/20bc799560b6efe7b2be to your computer and use it in GitHub Desktop.
Hubot script to manage gobgpd
# Description:
# Allow Hubot to originate flowspec routes with gobgpd
#
# Commands:
# hubot flowspec add <expression> - Originate a flowspec route. <expression> must be in gobgp format - See https://github.com/osrg/gobgp/blob/master/docs/sources/flowspec.md
# hubot flowspec del <expression> - Withdraw a flowspec route. <expression> must be in gobgp format - See https://github.com/osrg/gobgp/blob/master/docs/sources/flowspec.md
# hubot flowspec list - Show flowspec routes.
# hubot route <host address> - Show the best matched prefix in gobgpd
#
# Author:
# Shintaro Kojima <goodies@codeout.net>
Gobgp = require('gobgp')
gobgp = new Gobgp('localhost:50051')
module.exports = (robot) ->
resolvePrefix = (addr, callback) ->
gobgp.getRib family: 'ipv4-unicast', destinations: [prefix: addr], (err, table) ->
if table.destinations.length == 0
callback "#{addr} not in table"
else
callback null, table.destinations[0].prefix
robot.respond /flowspec (add|del) (.*)/i, (res) ->
switch res.match[1]
when 'add'
withdraw = false
description = 'originated'
when 'del'
withdraw = true
description = 'withdrawn'
else
return
expression = res.match[2]
originate = (expression) ->
gobgp.modPath family: 'ipv4-flowspec', withdraw: withdraw, expression, (err, response) ->
return res.send('Invalid expression') if err
res.send "Flowspec route #{description}"
matched = expression.match(/source (\S+)\/\?/)
if matched
resolvePrefix matched[1], (err, prefix) ->
return res.send(err) if err
originate expression.replace("source #{matched[1]}/?", "source #{prefix}")
else
originate expression
robot.respond /flowspec list/i, (res) ->
gobgp.getRib family: 'ipv4-flowspec', (err, table) ->
if table.destinations.length == 0
res.send 'Network not in table'
else
prefixes = table.destinations.map (destination) ->
destination.prefix
res.send prefixes.join("\n")
robot.respond /route (\S+)/i, (res) ->
addr = res.match[1]
resolvePrefix addr, (err, prefix) ->
return res.send(err) if err
res.send prefix
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment