I've been carrying around the idea that it should be really easy to plug-in Chef's Knife command as a Rundeck node executor, and finally found the excuse to give it a whirl!
As part of doing a bit of a deep dive on alternatives to ssh for Windows command execution, I've been taking a look at
WinRM.
If your Rundeck server is on Windows itself, then it's possible to use the
WinRS command to issue remote commands. However, if your Rundeck server in
not on Windows, then you're looking for some cross-platform means of calling WinRM. One approach is Greg Schueler's excellent
dtolabs / rundeck-winrm-plugin which provides a Java plug-in based on Xebia Lab's
overthere project maintained by Vincent Partington.
Another approach, and the real subject of this posting, is that the Chef Knife command includes a WinRM plug-in that can also do the job.
Preparation
A
lot has been written about Chef
installation; enough for me to want to give a quick cheat-sheet here for anyone who just wants to get going with the least fuss and effort!
- Starting with a CentOS 6.2 "minimal server" install.
- Add the following additional packages to support installation of Opscode's Knife Windows plug-in:
[root@centos62-chef-server tmp]# yum install gcc gcc-c++ automake autoconf make curl dmidecode libxml2 libxml2-devel libxslt libxslt-devel
Loaded plugins: fastestmirror, security
.
.
.
Complete!
- There's no need to have a Chef server available to use "knife winrm" commands, but it does require and Chef client install using Ruby 1.9.1 or better, and so (on CentOS, at least) the best way to go is to use the Omnibus Chef Client installer:
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 5204 100 5204 0 0 5879 0 --:--:-- --:--:-- --:--:-- 5879
Downloading Chef 10.12.0-1 for el...
HTTP request sent, awaiting response... 200 OK
Length: 14709172 (14M) [audio/x-pn-realaudio-plugin]
Saving to: “/tmp/chef-full-10.12.0-1.x86_64.rpmâ€
100%[=============================================================================================================================================>] 14,709,172 1.25M/s in 27s
2012-08-02 04:23:01 (523 KB/s) - “/tmp/chef-full-10.12.0-1.x86_64.rpm†saved [14709172/14709172]
Installing Chef 10.12.0-1
Preparing... ########################################### [100%]
1:chef ########################################### [100%]
Thank you for installing Chef!
... done in a jiffy (less than 30 seconds)!
- Straight on to installing the Knife WinRM plug-in:
[root@centos62-chef-server opt]# /opt/chef/embedded/bin/gem install knife-windows
Fetching: eventmachine-1.0.0.beta.3.gem (100%)
Building native extensions. This could take a while...
Fetching: ffi-1.1.3.gem (100%)
Building native extensions. This could take a while...
Fetching: gssapi-1.0.3.gem (100%)
Fetching: nokogiri-1.5.5.gem (100%)
Building native extensions. This could take a while...
Fetching: httpclient-2.2.0.2.gem (100%)
Fetching: rubyntlm-0.1.1.gem (100%)
WARNING: rubyntlm-0.1.1 has an invalid nil value for @cert_chain
Fetching: builder-3.0.0.gem (100%)
Fetching: nori-1.1.3.gem (100%)
Fetching: rack-1.4.1.gem (100%)
Fetching: httpi-0.9.7.gem (100%)
Fetching: wasabi-1.0.0.gem (100%)
Fetching: gyoku-0.4.6.gem (100%)
Fetching: akami-1.2.0.gem (100%)
Fetching: savon-0.9.5.gem (100%)
Fetching: little-plugger-1.1.3.gem (100%)
Fetching: logging-1.6.2.gem (100%)
Fetching: winrm-1.0.6.gem (100%)
Fetching: em-winrm-0.5.2.gem (100%)
Fetching: knife-windows-0.5.8.gem (100%)
Successfully installed eventmachine-1.0.0.beta.3
Successfully installed ffi-1.1.3
Successfully installed gssapi-1.0.3
Successfully installed nokogiri-1.5.5
Successfully installed httpclient-2.2.0.2
Successfully installed rubyntlm-0.1.1
Successfully installed builder-3.0.0
Successfully installed nori-1.1.3
Successfully installed rack-1.4.1
Successfully installed httpi-0.9.7
Successfully installed wasabi-1.0.0
Successfully installed gyoku-0.4.6
Successfully installed akami-1.2.0
Successfully installed savon-0.9.5
Successfully installed little-plugger-1.1.3
Successfully installed logging-1.6.2
Successfully installed winrm-1.0.6
Successfully installed em-winrm-0.5.2
Successfully installed knife-windows-0.5.8
Installing ri documentation for eventmachine-1.0.0.beta.3...
Installing ri documentation for ffi-1.1.3...
Before reporting this, could you check that the file you're documenting
compiles cleanly--RDoc is not a full Ruby parser, and gets confused easily if
(ArgumentError) unknown encoding name - "UTF-8"?>
ERROR: While generating documentation for ffi-1.1.3
... MESSAGE: unknown encoding name - "UTF-8"?>
... RDOC args: --ri --op /opt/chef/embedded/lib/ruby/gems/1.9.1/doc/ffi-1.1.3/ri -x ext --main README.rdoc lib ext History.txt README.rdoc lib/ffi/platform/arm-linux/types.conf lib/ffi/platform/i386-darwin/types.conf lib/ffi/platform/i386-freebsd/types.conf lib/ffi/platform/i386-linux/types.conf lib/ffi/platform/i386-netbsd/types.conf lib/ffi/platform/i386-openbsd/types.conf lib/ffi/platform/i386-solaris/types.conf lib/ffi/platform/i386-windows/types.conf lib/ffi/platform/i486-gnu/types.conf lib/ffi/platform/ia64-linux/types.conf lib/ffi/platform/mips-linux/types.conf lib/ffi/platform/mipsel-linux/types.conf lib/ffi/platform/powerpc-aix/types.conf lib/ffi/platform/powerpc-darwin/types.conf lib/ffi/platform/powerpc-linux/types.conf lib/ffi/platform/s390-linux/types.conf lib/ffi/platform/s390x-linux/types.conf lib/ffi/platform/sparc-linux/types.conf lib/ffi/platform/sparc-solaris/types.conf lib/ffi/platform/sparcv9-solaris/types.conf lib/ffi/platform/x86_64-darwin/types.conf lib/ffi/platform/x86_64-freebsd/types.conf lib/ffi/platform/x86_64-linux/types.conf lib/ffi/platform/x86_64-netbsd/types.conf lib/ffi/platform/x86_64-openbsd/types.conf lib/ffi/platform/x86_64-solaris/types.conf lib/Lib.iml --title ffi-1.1.3 Documentation --quiet
... I assumed it was safe to ignore the documentation generation error which seemed to be due to the omnibus installer including a back-revved version of rdoc:
[root@centos62-chef-server opt]# /opt/chef/embedded/bin/rdoc --version
- If you don't have a Chef server, fake the Knife configuration to avoid warning messages as follows:
[root@centos62-chef-server ~]# mkdir ~/.chef
[root@centos62-chef-server ~]# touch ~/.chef/knife.rb
- Simple as that, we're ready to boogie:
[root@centos62-chef-server ~]# knife winrm -h
knife winrm QUERY COMMAND (options)
-a, --attribute ATTR The attribute to use for opening the connection - default is fqdn
-f CA_TRUST_FILE, The Certificate Authority (CA) trust file used for SSL transport
-s, --server-url URL Chef Server URL
-k, --key KEY API Client Key
--[no-]color Use colored output, defaults to enabled
-c, --config CONFIG The configuration file to use
--defaults Accept default values for all questions
-d, --disable-editing Do not open EDITOR, just accept the data as is
-e, --editor EDITOR Set the editor to use for interactive commands
-E, --environment ENVIRONMENT Set the Chef environment
-F, --format FORMAT Which format to use for output
--identity-file IDENTITY_FILE
The SSH identity file used for authentication
-i, --keytab-file KEYTAB_FILE The Kerberos keytab file used for authentication
-R KERBEROS_REALM, The Kerberos realm used for authentication
-S KERBEROS_SERVICE, The Kerberos service used for authentication
-m, --manual-list QUERY is a space separated list of servers
-u, --user USER API Client Username
--print-after Show the data after a destructive operation
-V, --verbose More verbose output. Use twice for max verbosity
-v, --version Show chef version
-P, --winrm-password PASSWORD The WinRM password
-p, --winrm-port PORT The WinRM port, by default this is 5985
-t, --winrm-transport TRANSPORT The WinRM transport type. valid choices are [ssl, plaintext]
-x, --winrm-user USERNAME The WinRM username
-y, --yes Say yes to all prompts for confirmation
-h, --help Show this message
Next step is to get WinRM itself going server-side and test Knife WinRM from the Linux client:
C:\Users\Administrator>winrs -u:administrator -p:!1qazxsw2@ -r:http://win2008 dir
Volume in drive C has no label.
Volume Serial Number is D0A0-E610
Directory of C:\Users\Administrator
08/02/2012 01:24 PM <DIR> .
08/02/2012 01:24 PM <DIR> ..
11/20/2010 05:20 PM <DIR> Contacts
07/27/2012 02:22 PM <DIR> Desktop
11/20/2010 05:20 PM <DIR> Documents
11/24/2010 11:53 AM <DIR> Downloads
11/20/2010 05:20 PM <DIR> Favorites
11/20/2010 05:20 PM <DIR> Links
11/20/2010 05:20 PM <DIR> Music
11/20/2010 05:20 PM <DIR> Pictures
11/20/2010 05:20 PM <DIR> Saved Games
11/20/2010 05:20 PM <DIR> Searches
07/27/2012 01:50 PM <DIR> src
11/20/2010 05:20 PM <DIR> Videos
08/02/2012 01:24 PM 0 winrs
11/24/2010 11:59 AM <DIR> workspace
15 Dir(s) 52,531,306,496 bytes free
... I went with the line of least resistance and setup a non-secure listener with out domain authentication.
- Test the Knife WinRM command-line from the CentOS box:
[anthony@centos62-chef-server ~]$ knife winrm -m win2008 -P '!1qazxsw2@' -p 80 -x Administrator dir
win2008 Volume in drive C has no label.
win2008 Volume Serial Number is D0A0-E610
win2008 Directory of C:\Users\Administrator
win2008 07/31/2012 03:19 PM <DIR> .
win2008 07/31/2012 03:19 PM <DIR> ..
win2008 11/20/2010 05:20 PM <DIR> Contacts
win2008 07/27/2012 02:22 PM <DIR> Desktop
win2008 11/20/2010 05:20 PM <DIR> Documents
win2008 11/24/2010 11:53 AM <DIR> Downloads
win2008 11/20/2010 05:20 PM <DIR> Favorites
win2008 11/20/2010 05:20 PM <DIR> Links
win2008 11/20/2010 05:20 PM <DIR> Music
win2008 11/20/2010 05:20 PM <DIR> Pictures
win2008 11/20/2010 05:20 PM <DIR> Saved Games
win2008 11/20/2010 05:20 PM <DIR> Searches
win2008 07/27/2012 01:50 PM <DIR> src
win2008 11/20/2010 05:20 PM <DIR> Videos
win2008 11/24/2010 11:59 AM <DIR> workspace
win2008 0 File(s) 0 bytes
win2008 15 Dir(s) 52,531,306,496 bytes free
The following Rundeck configuration steps were tested under 1.4.3:
- I setup a dedicated project in Rundeck called "knife-winrm" so that I could set project level properties (you can also selectively configure Knife WinRM at the node level in an existing project).
- Extended node attributes in the project XML to include everything needed to invoke Knife WinRM:
[rundeck@centos62-chef-server knife-winrm]$ cat etc/resources.xml
<?xml version="1.0" encoding="UTF-8"?>
<node name="localhost" description="Rundeck server node" tags="" hostname="localhost" osArch="amd64" osFamily="unix" osName="Linux" osVersion="2.6.32-220.el6.x86_64" username="rundeck"/>
<node name="win2008" description="Windows 2008 server node" tags="" hostname="win2008" osArch="Windows" osFamily="windows" osName="windows" osVersion="2008" username="Administrator" password="!1qazxsw2@" port="80"/>
... note that handling the password this way is a bit of a hack! It might better be passed thorough via a secure job option (but I do like to make sure the "run" tab continues to work too ...).
- Configured the project properties (via the project administration UI) to use the standard script execution plug-in as follows:
[rundeck@centos62-chef-server knife-winrm]$ cat etc/project.properties
#Project knife-winrm configuration, generated
#Thu Aug 02 05:47:39 PDT 2012
project.ssh-keypath=/var/lib/rundeck/.ssh/id_rsa
service.NodeExecutor.default.provider=script-exec
plugin.script-exec.default.command=knife winrm -m ${node.hostname} -P '${node.password}' -p ${node.port} -x ${node.username} ${exec.command}
project.resources.file=/var/rundeck/projects/knife-winrm/etc/resources.xml
plugin.script-exec.default.shell=/bin/bash -l -c
service.FileCopier.default.provider=jsch-scp
... note that it's critical to set bash to act as if it had been invoked as a login shell ("-l") in order to have the environment necessary for Knife to work.
Execution
With this configuration done, you can select the node using the run tab's filter and execute DOS (cmd.exe) commands from the Rundeck UI:
... sweet!
Anthony.