Книга: Automation and Monitoring with Hubot: For DevOps and Developers
Назад: Building And Deploying With Hubot And Jenkins
Дальше: There Are No Limits

Invoking Chef’s Knife With Hubot

is one of most popular weapons of choice for managing IT infrastructure as code. And what could be better than controlling chef directly from your chat using Hubot? In this chapter we will write a custom Hubot script that will be running commands for you.

Configuring Knife

To begin the integration, you have to get knife command to work on your bot server. For that you need to install chef gem and .

You have a couple of options here, one is to make knife work from any directory by placing the configuration at /etc/chef, other is to have your *.pem and knife.rb in some directory from where knife command will work without being available globally. Our example script will be running knife from /home/hubot/knife directory.

Hubot Chef Script

Here is a quick example of Hubot script with one, yet very powerful chef’s knife command:

scripts/chef.coffee


 1 # Description  2 #   Hubot script that runs Chef's knife  3 #  4 # Commands:  5 #   hubot knife <command> - execute knife command  6 #  7 # Author:  8 #   spajus  9  10 module.exports = (robot) -> 11   knife_opts = { cwd: '/home/hubot/knife' } 12   cp = require 'child_process' 13   robot.respond /knife (.*)/i, (msg) -> 14     cp.exec "knife #{msg.match[1]}", knife_opts, (error, stdout, stderr) -> 15       msg.send stdout if stdout 16       msg.send "Error: #{stderr}" if stderr 

If your knife command works globally, you may set knife_opts to {}.

This script is written using the technique explained in “Hubot Scripting” chapter - see the calendar script in “Reacting To Messages In Chatroom” section for explanation how invoking shell commands works with Hubot scripts.

Example of this script in action:

Tomas V.  hubot knife role list | grep jobs$ Hubot     analytics-jobs           core-jobs 

Yes, even pipe works. This script is so powerfull, that you MUST take precautions to secure it properly, or somebody can can do devastating things not only to hubot’s machine, but to all your servers. A good way is to execute cp.exec only when it’s invoked in devops or admins room or by small set of trusted users. See “Roles And Authentication” chapter to see how it can be done, and use it at your own risk.

Advanced Hubot Chef Script

While the script we’ve written is very powerful already, we may want to make our lives easier and let Hubot do the thinking. This is especially helpful if you want to expose a set of secure commands for your developers to perform actions without getting to know how chef and knife works. Behold, the advanced chef integration script, that includes hubot knife command.

scripts/chef.coffee


 1 # Description  2 #   Hubot script that runs Chef's knife  3 #  4 # Commands:  5 #   hubot knife <command> - execute knife command (only in devops chat)  6 #   hubot server list - list all our servers registered with chef  7 #   hubot server list <pattern> - list our servers registered with chef match\  8 ing a pattern  9 #   hubot server search <pattern> - search for servers matching chef role (* \ 10 works) 11 #   hubot servers <pattern> - search for servers matching '*-<pattern>' chef \ 12 role 13 #   hubot server roles - list all chef roles 14 #   hubot server roles <pattern> - list chef roles matching a pattern 15 # 16 # Author: 17 #   spajus 18  19 module.exports = (robot) -> 20  21   cp = require 'child_process' 22   knife_opts = { cwd: '/home/hubot/knife' } 23  24   handle_response = (msg) -> 25     (error, stdout, stderr) -> 26       msg.send stdout if stdout 27       msg.send "Error: #{stderr}" if stderr 28  29   robot.respond /knife (.*)/i, (msg) -> 30     if msg.message.room != '<insert devops room id>' 31       msg.send "Do it in devops room please" 32       return 33     cp.exec "knife #{msg.match[1]}", 34       knife_opts, handle_response(msg) 35  36   robot.respond /server list$/i, (msg) -> 37     cp.exec "knife node list", 38       knife_opts, handle_response(msg) 39  40   robot.respond /server list (.*)/i, (msg) -> 41     cp.exec "knife node list | grep #{msg.match[1]}", 42       knife_opts, handle_response(msg) 43  44   robot.respond /server roles?$/i, (msg) -> 45     cp.exec "knife role list", 46       knife_opts, handle_response(msg) 47  48   robot.respond /server roles? (.*)/i, (msg) -> 49     cp.exec "knife role list | grep #{msg.match[1]}$", 50       knife_opts, handle_response(msg) 51  52   robot.respond /server search (.*)/i, (msg) -> 53     cp.exec "knife search node 'roles:#{msg.match[1]}' -a run_list", 54       knife_opts, handle_response(msg) 55  56   robot.respond /servers (.*)/i, (msg) -> 57     cp.exec "knife search node 'roles:*-#{msg.match[1]}' -i", 58       knife_opts, handle_response(msg) 

You can find this script at .

Script in action:

Tomas V.  hubot help server Hubot     hubot server list - list all our servers registered with chef           hubot server list <pattern> - list our servers registered with chef\  matching a pattern           hubot server roles - list all chef roles           hubot server roles <pattern> - list chef roles matching a pattern           hubot server search <pattern> - search for servers matching chef ro\ le (* works)           hubot servers <pattern> - search for servers matching '*-<pattern>'\  chef role Tomas V.  hubot server list indexer Hubot     indexer.botserv.org Tomas V.  hubot server list redis Hubot     redis1.botserv.org Tomas V.  hubot server list static Hubot     static1.botserv.org           static2.botserv.org           static-x1.botserv.org           static-x2.botserv.org           static11.botserv.org           static12.botserv.org           static13.botserv.org           static14.botserv.org Tomas V.  hubot server roles redis Hubot     core-redis           redis Tomas V.  hubot server search core-redis Hubot     2 items found           db3.botserv.org:             run_list: role[machine], role[core-redis]           redis1.botserv.org:             run_list: role[machine], role[redis], role[core-redis] Tomas V.  hubot servers uk Hubot     14 items found           indexer.botserv.org           static2.botserv.org           front2.botserv.org           app4.botserv.org           jobs9.botserv.org           db4.botserv.org           app1.botserv.org           search2.botserv.org           front1.botserv.org           app2.botserv.org           db1.botserv.org           static1.botserv.org           db2.botserv.org           search1.botserv.org 

Tune this script and add shortcuts to your favorite knife commands.

Third Party Hubot Chef Scripts

There are Hubot scripts out there that work nearly the same. For example, this package at GitHub: . It may be a good alternative if you want something working right out of the box, however, I believe Hubot Chef integration is too important, you can’t just throw something in and expect it will suit your needs. You should write every bit of it yourself, add safety precautions, enrich it with shorthands for most often used commands. By getting very intimate with this integration script you will be sure it does all you want, and you will be able to sleep at night knowing that you built it in a way that nobody can do any harm to your infrastructure.

Hubot With Puppet, Ansible, Or Something Else

This book will not cover these, however you can use same techniques that were used in Chef’s integration to write yourself a custom integration with any infrastructure management tool. Just make sure you follow through the chapter and understand how chef.coffee works.

Назад: Building And Deploying With Hubot And Jenkins
Дальше: There Are No Limits