13 November 2018

Del The Funky Robosapien

by mo


At work we use HipChat for our chat system. A little while back I wanted to be able to deploy code via HipChat commands so I built a couple of tools to make this possible. Some of the tools are for internal use only.

The tools are:

  • pidge CLI: is a CLI application that allows you to perform various operations against the services that our team owns.
  • pidge-bot: is a HipChat bot that listens for instructions and performs requested actions.
  • del: XMPP compatible bot client/server for interacting with a HipChat server.

Pidge

The pidge CLI offers commands such as:

も pidge
pidge commands:
  pidge castle          # manage the castle application
  pidge chef            # query chef server
  pidge coran           # manage the coran application
  pidge github          # interact with github API
  pidge help [COMMAND]  # Describe available commands or one specific command
  pidge maintenance     # allow taking up/down maintenance
  pidge shiro           # manage the shiro application
  pidge standup         # standup
  pidge update          # Update pidge to the latest version
  pidge version         # Display the current version

I work on team Voltron and our services have codenames named after various characters from the show. One of the services that we ship is named Shiro. To perform operations against Shiro hosts you can use Pidge.

Some of these operations include:

  • taking down a specific node for maintenance.
  • bootstrapping a single node.
  • running database migrations
  • deploying a specific version of code to a specific environment.
も pidge shiro
Commands:
  pidge shiro boostrap <host> <git_hash>       # Deploy the `shiro` package to a specific host
  pidge shiro chef_status                      # Display the chef status for each node
  pidge shiro deploy <environment>             # Deploy the `shiro` package to a specific environment
  pidge shiro help [COMMAND]                   # Describe subcommands or one specific subcommand
  pidge shiro migrate <environment>            # Run the migrations.
  pidge shiro version <environment>            # Display the version of `shiro` deployed to each host in an environment.

Options:
  [--debug=DEBUG]
  [--ruby-version=RUBY-VERSION]
                                 # Default: 2.5.3

To deploy shiro you can specify a specific git hash or branch to deploy.

も pidge shiro help deploy
Usage:
  pidge shiro deploy <environment>

Options:
  [--git-hash=GIT-HASH]          # The git SHA1 hash of the commit to deploy. A branch name can be used in place of a SHA1.
                                 # Default: master
  [--check], [--no-check]        # run a check
  [--debug=DEBUG]                
  [--ruby-version=RUBY-VERSION]  
                                 # Default: 2.5.3

Deploy the `shiro` package to a specific environment

Pidge Bot

This bot runs on a dedicated host with VPN access to different environments. It enlists in different HipChat rooms to listen for specific commands. You can also issue commands directly to it, as if you were chatting with another HipChat user. The bot itself is packaged as a docker image.

Del

This is an XMPP client. It has a server mode that starts a daemon and listens for incoming messages from a HipChat room or for commands via the client CLI.

Setup

To run the daemon you will need to provide del with some configuration.

も gem install del
も del setup # follow the prompts

del stores it’s configuration in ~/.delrc. For a privately hosted HipChat server, a configuration might look like:

---
host: hipchat.example.org
jid: 1@chat.btf.hipchat.com
muc_domain: conf.btf.hipchat.com
full_name: Katie "Pidge" Holt
password: "secret"
rooms:
  - 1_voltron

Daemon

With this configuration in place you can now start the del client daemon.

も del server
I, [2018-11-12T11:35:54.446164 #18370]  INFO -- : 🔥🔥🔥

Client

With the daemon running, you can now issue commands to it.

E.g.

も del whoami | jq '.'
{
  "xmlns": "jabber:iq:roster",
  "jid": "1@chat.btf.hipchat.com",
  "name": "Katie &quot;Pidge&quot; Holt",
  "email": "<snip>",
  "mention_name": "pidge",
  "version": "",
  "photo_url": "https://hipchat.example.org/files/photos/1/1.png",
  "id": "1",
  "subscription": "both"
}

del offers a few other friendly commands like:

  • message: send a message to a specific user.
  • status: change your status and supply a message.
  • users: view the full roster of users
  • whois: view the info of a specific user.

See del help for more info.

Routing

The del server can also be configured to use a configuration file that is very similar to the Ruby on Rails routes.rb file.

E.g.

# routes.rb

Del.configure do |x|
  x.router.register(/^[Hh]ello/) do |message|
    message.reply('Oh, Hai!')
  end
end

To use a custom routes.rb file you can start del with the path to the file.

も del server routes.rb
Registering custom routes.
I, [2018-11-12T11:43:57.294248 #20621]  INFO -- : 🔥🔥🔥

With the above routes registered, and the daemon running, the del bot will auto respond to any messages that match the registered routes.

E.g.

With a custom routes file, you can create a bot to respond to different commands.

E.g.

If I wanted my bot to respond to:

@pidge deploy shiro:master to staging

I could register the following command in my routes.rb.

# routes.rb
Del.configure do |x|
  pattern = /^deploy ([a-z-]+):?([a-zA-Z0-9]*) to (\bstaging\b|\bproduction\b)$/
  router.register(pattern) do |message, match_data|
    application = match_data[1]
    git_hash = match_data[2]
    chef_env = match_data[3]
    message.execute_shell([
      'pidge',
      application,
      'deploy',
      chef_env,
      "--git-hash=#{git_hash}"
    ])
  end
end

Give it a try on GitHub. Or go listen to one of my favourite artists.

Peace, 🤖 and Ruby!

💎