vagrant + rouster at salesforce.com - puppetconf 2013
DESCRIPTION
"Vagrant + Rouster at salesforce.com" by Conor Horan-Kates Senior Member of the Technical Staff, Quality Engineering, salesforce.com. Speaker Presentation: Rouster is an abstraction layer between you and Vagrant. At salesforce.com, we're using it to assist in running functional tests of the Puppet code we've written. While RSpec is significantly faster, it really only tells you whether the catalog contains what you expect it to - not whether those things can/will be applied successfully - and that's where Rouster comes in. Currently the library contains many hooks for system level testing and information gathering (is_file?(), is_user_in_group?(), is_service?()) and puppet related functionality (get_catalog(), parse_catalog(), run_puppet()), but we're looking to expand. Speaker Bio: Conor Horan-Kates is a Senior Member of the Technical Staff in the Quality Engineering organization supporting Data Center Automation. In this role, Conor has planned and implemented test environments, created testing and development best practices and developed applications, automated tests, and test frameworks. Most recently, Rouster, an abstraction layer for Vagrant. At salesforce.com, Conor has been involved in many aspects of building the infrastructure, from initial contributions to a CMDB, testing of switch/load balancer/ACL creation automation and now, bringing the build and maintenance lifecycle into Puppet. Additionally, he has written a testing framework that interfaces with salesforce.com records, Test::More::Salesforce, and a learn-by-testing project called Perl::Koans. Prior to salesforce.com, Conor worked in QA at the antimalware company Webroot.TRANSCRIPT
Vagrant + Rouster at salesforce.com
Conor Horan-Kates Senior Member of the Technical Staff,
Quality Engineering
@chorankates
/usr/bin/whoami
• most recently as a tester in quality assurance for a Windows based antimalware solution
• started as a traditional quality engineer in a Data Center Automation group, moved towards developer and systems engineer, riding the DevOps wave
Rouster
basic instantiation
require 'rouster'
# the value for the 'name' attribute should be a name in `vagrant status`
app = Rouster.new(:name => 'app')
# equivalent to `vagrant up app`
app.up()
# STD(OUT|ERR) of this is available in app.get_output()
app.run('cat /etc/hosts')
app.put('new-‐foo', '/tmp/foo')
app.get('/tmp/foo')
app.destroy()
http://tipmra.com/new_tipmra/new_cop_pic/old_cop_time_1a.gif
Where did we start?
• Team composition • 6 engineers – 3 system engineers, 2 QE and 1 developer
• Very little Ruby experience, mostly Perl and Shell
• Education • Pro Puppet, Puppet 2.7 Cookbook, Puppet Types and Providers • Puppet Intro and Puppet Developers (now Advanced) classes
from PuppetLabs
• Tools • RSpec, rspec-puppet
• puppet-lint
Where have we been?
• get out of perforce and into git • local git-commit hooks
• puppet-lint
• RSpec, rspec-puppet
• Vagrantfile: 39 lines • piab -> ‘Puppet in a box’
• Supports base images for roles in SFDC stack
Where are we now?
• Jenkins – relatively small installation • RSpec, rspec-puppet – for catalog validation of
manifests, some unit testing
• test-unit – for unit tests of custom functions
• Test::More – for unit/functional tests of ENC
• built mock racadm for type/provider testing
• Vagrantfile: 237 lines • Supports base images for ~every host in production
Where are we now? (pt. 2)
• Salesforce::piab – for functional validation of catalogs –the precursor to Rouster • Perl abstraction layer to Vagrant machines, shelled out to
vagrant faces, created a new pseudo-TTY connection for each run() command
• Relies on external project, deltas, to power the get_(groups|packages|services|users)
• Supports a subset of is_* tests
• To accomplish isolation, large portions of code in role_*.t is duplicated for each test
Where are we going?
• Rouster • Porting existing Salesforce::piab tests
• Resolve issues and TODOs in codebase
• Moving from all Vagrant VMs to include physical hardware environment
http://www.hostgator.com/images/d8.jpg
puppet-y methods
require 'rouster'
require 'rouster/puppet'
ppm = Rouster.new(:name => 'ppm')
p (ppm.methods – Object.methods).sort
[
:get_catalog, :get_puppet_errors, :get_puppet_notices,:parse_catalog, :remove_existing_certs, :run_puppet
]
testing methods
require 'rouster'
require 'rouster/testing'
ppm = Rouster.new(:name => 'ppm')
p (ppm.methods – Object.methods).sort
[
:is_dir?, :is_executable?, :is_file?, :is_group?, :is_in_file?, :is_in_path?, :is_package?, :is_port_active?, :is_port_open?, :is_process_running?, :is_readable?, :is_service?, :is_service_running?, :is_user?, :is_user_in_group?, :is_writeable?
]
Rouster - demo
Where is Rouster going?
• SFDC is going all RHEL, most of our time will be devoted to supporting that OS
• Object model – no more shelling out • Vagrant
• Puppet
• Passthrough implementation
• Better/more • Documentation • Tests
• What does the community need?
http://www.skyanalytics.com/Portals/171866/images/roadmap.jpg
Want to help?
• Testing • do our tests work in your environment? how can we make them
more generic? • how does Rouster work with providers other than VirtualBox?
• Support for • other system configuration tools – Chef? Ansible?
$whatevercomesnext?
• other operating systems
• TODO hunting – at last count, more than 30
• New tests/convenience methods
• Most importantly, need an awesome logo
Questions for the audience
• How are you accomplishing test isolation? • How are you handling credential management?
• How are you testing code against non-server puppet agents?
• How are you handling negative testing?
Conor Horan-Kates SMTS, QE github.com/chorankates/rouster @chorankates