Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Go Remote Control

Go Remote Control

Introducing Go Remote Control, a daemon that can be used to control multiple remote nodes from a single location.


Anthony Eden

October 10, 2014


  1. Go Remote Control Anthony Eden of DNSimple

  2. How do you easily operate 40 nodes remotely?

  3. You could SSH

  4. OR

  5. You can Go Remote Control

  6. Small Go Service on each node

  7. Hubot calls HTTPS endpoints

  8. Go invokes scripts on the node

  9. deploy nameserver srv1-iad

  10. Executing update on ns1a-srv1-iad - this may take some time

    Executing update on ns3a-srv1-iad - this may take some time Executing update on ns2a-srv1-iad - this may take some time Executing update on ns4a-srv1-iad - this may take some time
  11. Result of update on ns4a-srv1-iad: Silencing Sensu sensu silenced for

    ns4a.srv1.iad.dnsimple.com Stopping exabgp exabgp stopped Stopping erldnsimple erldnsimple stopped Running chef client Chef client exit status: 0 chef client run completed erldnsimple started Starting exabgp exabgp started Unsilencing Sensu sensu unsilenced for ns4a.srv1.iad.dnsimple.com
  12. callGoRemoteControl = (msg, host, action, callback) -> baseUrl = "https://#{host}.example.com:9876"

    actionUrl = "#{baseUrl}/#{action}" httpAuthToken = "<auth token>" msg.http(baseUrl) .headers 'Authorization': httpAuthToken .get() (err, res, body) -> if err msg.send "Failed to connect to node: #{err}" else msg.send "Executing #{action} on #{host} - this may take some time" msg.http(actionUrl) .headers 'Authorization': httpAuthToken .get() (err, res, body) -> if callback callback(host, action, body) else message = "Result of #{action} on #{host}:\n" message += body msg.send(message)
  13. module.exports = (robot) -> # Stop a DNSimple name server,

    run chef-client and start it back up robot.respond /deploy nameserver (\w+-\w+-\w+)$/i, (msg) -> host = msg.match[1] callGoRemoteControl(msg, host, 'update')
  14. #!/usr/bin/env ruby require 'open3' require_relative 'stop' require_relative 'start' require_relative 'status'

    def run_chef_client puts "Running chef client" o, e, s = Open3.capture3("chef-client") puts "Chef client exit status: #{s.exitstatus}" if s.exitstatus == 0 notify("chef client run completed", true) else notify("chef client run failed: #{e}", false) end end def main silence stop_exabgp stop_erldnsimple remove_erldnsimple_run_file run_chef_client || return while !erldnsimple_started? sleep 3 end if name_server_answering? puts "erldnsimple started" start_exabgp || return unsilence else puts "erldnsimple failed to start properly" end end if __FILE__==$0 main end
  15. https://github.com/aetrion/go-remote-control

  16. https://gist.github.com/aeden/4435503566665b8cc267