SlideShare a Scribd company logo
1 of 56
Download to read offline
The worst code I ever wrote (maybe)
Tomas Doran
@bobtfish
tdoran@yelp.com
15/11/2013
Key lessons
!

•‘Working’ != ‘done’
– I’m a terrible person
– Working now doesn’t mean you can maintain it

•Functions for reuse
– and my horrible propensity for inline templating

•exec {} abuse
– Lets fit an entire shell script in the command => “…”

•Looping
– Hacks you have probably used.
– Doing it sanely with puppet >= 3.2

tl;dl: This talk is about bad puppet code, and how and why to do it better. The worst code I ever wrote is a
lie ;)
We’re going to concentrate on 2 main topics - functions and looping, with a nod to exec abuse.
Managing ssh keys - gitolite
!

• Legacy user management code
–Old non-modular code
–Have to fit in
–Can’t change everything

• Built in sshkey {}
– Not suitable for our requirements

We’re rapidly updating our puppet codebase, but the user management code is one of the most complex
parts, so we wanted to be minimally invasive.. We needed to generate a very custom authorized keys files to
integrate gitolite authentication into our current model.
sshkey resource

The built in sshkey {} isn’t perfect for everyone.
Most of the solutions on forge aren’t generic
http://forge.puppetlabs.com/hetzeneckerl/ssh_authorized_key

These are the core issues.
But this code didn’t work for me.
http://forge.puppetlabs.com/nightfly/ssh_keys
!

• Legacy user management code
!

–Old non-modular code
–Have to fit in

• Almost
– But not quite suitable for our requirements

Doing it myself as a concat {} seemed sane, especially given other people’s evidence..
Managing ssh keys - gitolite
!

• Legacy user management code

!

–Old non-modular code
–Have to fit in
–Can’t change everything

• Built in sshkey {}
– Not suitable for our requirements
!

• Hack what we want
with define
So, we’re gonna use a bunch of defines and concat {}, easy?
Inputs and outputs
!

gitolite::user { ‘tdoran’:
key_source => $key_source;
}
– Add in current user management code
– $keysource = puppet:///files/
users/tdoran/authorized_keys

/etc/authorized_keys.d/git.pub
– Use concat
– Multiple gitolite instances!

- API for creating a key we drop into our current user management path
- Eventual generated file, from a concat {} resource
- Note we can have multiple gitolite instances on one box, that makes everything much harder.
So how does it work?
First, get an array of key lines, with names prepended

$864
Split the key into an array

$864

We split the file of keys into an array of lines.
We remove comments, whitespace only lines etc
We capture the entire key passed in.
Split the key into an array

$864

We interpolate the username in front of that key, space separating them
Split the key into an array

$864

End up with an array of strings which are username and key joined by a space
We then abuse a define as a loop by calling it with the array of lines as $title
Prepend instance name
!

Add user to every instance
– [“${username} ${restofkey}”]
– [“${instance} “]
– [“${instance} ${username} ${restofkey}”]
– Use this as $name in a define to iterate
– ssh/authorized_keys.d/${instance}.pub

We then have an array of instances, and an array of users/keys.
Our array_prefix function makes the product of both lists.
Complexity due to iterating over two lists $key_lines and $instances
Prepend instance name
!

Add user to every instance
– [“${username} ${restofkey}”]
– [“${instance} “]
– [“${instance} ${username} ${restofkey}”]
– Use this as $name in a define to iterate
– ssh/authorized_keys.d/${instance}.pub

We then have an array of instances, and an array of users/keys.
Our array_prefix function makes the product of both lists.
Complexity due to iterating over two lists $key_lines and $instances
Prepend instance name
!

Add user to every instance
– [“${username} ${restofkey}”]
– [“${instance} “]
– [“${instance} ${username} ${restofkey}”]
– Use this as $name in a define to iterate
– ssh/authorized_keys.d/${instance}.pub

We then have an array of instances, and an array of users/keys.
Our array_prefix function makes the product of both lists.
Complexity due to iterating over two lists $key_lines and $instances
Prepend instance name
!

Add user to every instance
– [“${username} ${restofkey}”]
– [“${instance} “]
– [“${instance} ${username} ${restofkey}”]
– Use this as $name in a define to iterate
– ssh/authorized_keys.d/${instance}.pub

We then have an array of instances, and an array of users/keys.
Our array_prefix function makes the product of both lists.
Complexity due to iterating over two lists $key_lines and $instances
Prepend instance name
!

Add user to every instance
– [“${username} ${restofkey}”]
– [“${instance} “]
– [“${instance} ${username} ${restofkey}”]
– Use this as $name in a define to iterate
– ssh/authorized_keys.d/${instance}.pub

This is gross
We then have an array of instances, and an array of users/keys.
Our array_prefix function makes the product of both lists.
Complexity due to iterating over two lists $key_lines and $instances
My original next code
Stare in horror!

$864

This was hideous. Whilst looping without define abuse is hard, there’s just no excuse for this.
Sins

LOL??

Hideous abuse of define - one $name for
each $key_lines

$864

We then split the line back up.
Sins

$864

Shift the user name off the array.
Lol, who knew you could do that?
Use the remaining data joined back up

LOL??

Hideous abuse of variables
Sins
Hideous abuse of interpolation

LOL??
LOL??

$864

So, here, I have a double quoted string containing erb, and I’m then using double quote (not erb)
interpolation.. Niiice.
Sins
Hideous abuse of quoting

EVERY TYPE OF QUOTES!!!

LOL??

LOL??

LOL??

$864
Sins
Hideous abuse of quoting

$864

LOL??

LOL??
Sins
Hideous abuse of bash

LOL??
$864

ssh-keygen can’t be fed from stdin without disgusting trickery (modern bash specific)
Sins
So complex I’m tempting the template!

LOL??
$864

LOL??

And yes, it’s so complex I template the thing I’m interpolating into a template..
I am a bad person
LOL?

$864
I am a bad person
LOL?

$864
I am a bad person
LOL?

$864

Thankfully
I am a bad person
LOL?

$864

Someone stopped me ;)
Don’t abuse inline_template()
!

• Please?
– I’m a terrible person
– Working now doesn’t mean you can maintain it

• Functions for reuse
– Full power of ruby
– Composable
– There should be more libraries of functions

Do what I’m saying, not what I do :)
More sane

Except each user can have multiple keys, and we want to prevent any key being reused by multiple
users.
Issues with functions
!

• What functions do I even have?
– Hard to know what functions you have imported
– stdlib, builtins, ….your $modulepath here…

• What do these even do?
– Often need to read the code to determine
– Lots of functions packaged with modules - don’t do
this!

• Millions of twisty little functions, all alike
• Millions of twisty little functions, all different
– You know what this reminds me of?
Everyone’s favorite language

If all you have is a hammer, everything looks like a nail
has a few functions

Unfortunately, there are no consistent naming conventions
arguably

And it’s hard to work out which function you actually want
a few too many..

The problem is, functions in a global namespace aren’t all that modular/composable.
You can call functions from functions - but dependency hell
we’re almost half way through….

Shall I stop now? :)
puppet problem is worse than this - what functions you have depends on what modules are in your codebase.
Get docs for project’s functions

I wrote a thing to help with this - this will document _your_ functions for you. gist at end of talk.
gitolite group file generation
!

• /etc/groups on system
!

• gitolite groups have a different
format:
@admins = tdoran joebloggs!
!

• Use exec {… add mess here … }

This is another great example of what not to do.
exec {} abuse
Syntax highlighting won’t save you now puny human!

$864

This. DO NOT DO THIS.
Please?
exec {} abuse
Syntax highlighting won’t save you now puny human!

$864
exec {} abuse
Syntax highlighting won’t save you now puny human!

$864
exec {} abuse
Syntax highlighting won’t save you now puny human!

$864

Arggh, the backslashes!
This madness actually worked
LOL?

$864
This madness actually worked
LOL?

!

•exec {} abuse

– Lets fit an entire shell script in the 

command => “…”
– Don’t do it! :)
– Drop a perl/python/ruby script (or two)
instead, call them from the exec.
$864
– Think about writing a type/provider

– Lots of examples of parsedfile available
Which would you rather have to debug?

$864
OR THIS!?!

$864
Which one’s going to stay debugged?

$864
OR THIS?!?

$864
Looping sanely

!

This would work fine.
Need multiple instances :(
—parser future
—parser future

$864
—parser future
!

• Can’t do this at Yelp
(yet)

• Still using 2.7, because
$864
variable scope
Hypocrisy avoidance
!

”There should be more libraries
of functions”
- Me, about 5m ago

– https://github.com/bobtfish/puppetsshkey_utilities
– https://github.com/bobtfish/puppet-better_file
– https://gist.github.com/bobtfish/7403811
– Whole module to follow (eventually)
That’s all folks
!

• Where was that code?
– https://github.com/bobtfish/puppet-sshkey_utilities
– https://github.com/bobtfish/puppet-better_file

• Did you say you were hiring?
– YES
– Hamburg.
– London.
– San Francisco.

• Questions?

More Related Content

What's hot

Perl: Hate it for the Right Reasons
Perl: Hate it for the Right ReasonsPerl: Hate it for the Right Reasons
Perl: Hate it for the Right ReasonsMatt Follett
 
Rails workshop for Java people (September 2015)
Rails workshop for Java people (September 2015)Rails workshop for Java people (September 2015)
Rails workshop for Java people (September 2015)Andre Foeken
 
Nedap Rails Workshop
Nedap Rails WorkshopNedap Rails Workshop
Nedap Rails WorkshopAndre Foeken
 
NYPHP March 2009 Presentation
NYPHP March 2009 PresentationNYPHP March 2009 Presentation
NYPHP March 2009 Presentationbrian_dailey
 
Getfilestruct zbksh(1)
Getfilestruct zbksh(1)Getfilestruct zbksh(1)
Getfilestruct zbksh(1)Ben Pope
 
Accelerated Native Mobile Development with the Ti gem
Accelerated Native Mobile Development with the Ti gemAccelerated Native Mobile Development with the Ti gem
Accelerated Native Mobile Development with the Ti gemWynn Netherland
 
Going crazy with Node.JS and CakePHP
Going crazy with Node.JS and CakePHPGoing crazy with Node.JS and CakePHP
Going crazy with Node.JS and CakePHPMariano Iglesias
 
DBIx::Class beginners
DBIx::Class beginnersDBIx::Class beginners
DBIx::Class beginnersleo lapworth
 
Koajs as an alternative to Express - OdessaJs'16
Koajs as an alternative to Express - OdessaJs'16Koajs as an alternative to Express - OdessaJs'16
Koajs as an alternative to Express - OdessaJs'16Nikolay Kozhukharenko
 
Introduction to CoffeeScript
Introduction to CoffeeScriptIntroduction to CoffeeScript
Introduction to CoffeeScriptStalin Thangaraj
 
AnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time webAnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time webclkao
 
ISUCONアプリを Pythonで書いてみた
ISUCONアプリを Pythonで書いてみたISUCONアプリを Pythonで書いてみた
ISUCONアプリを Pythonで書いてみたmemememomo
 
WordPress London 16 May 2012 - You don’t know query
WordPress London 16 May 2012 - You don’t know queryWordPress London 16 May 2012 - You don’t know query
WordPress London 16 May 2012 - You don’t know queryl3rady
 
DBIx::Class introduction - 2010
DBIx::Class introduction - 2010DBIx::Class introduction - 2010
DBIx::Class introduction - 2010leo lapworth
 
Dealing with Legacy Perl Code - Peter Scott
Dealing with Legacy Perl Code - Peter ScottDealing with Legacy Perl Code - Peter Scott
Dealing with Legacy Perl Code - Peter ScottO'Reilly Media
 

What's hot (19)

Perl: Hate it for the Right Reasons
Perl: Hate it for the Right ReasonsPerl: Hate it for the Right Reasons
Perl: Hate it for the Right Reasons
 
Rails workshop for Java people (September 2015)
Rails workshop for Java people (September 2015)Rails workshop for Java people (September 2015)
Rails workshop for Java people (September 2015)
 
Nedap Rails Workshop
Nedap Rails WorkshopNedap Rails Workshop
Nedap Rails Workshop
 
NYPHP March 2009 Presentation
NYPHP March 2009 PresentationNYPHP March 2009 Presentation
NYPHP March 2009 Presentation
 
Getfilestruct zbksh(1)
Getfilestruct zbksh(1)Getfilestruct zbksh(1)
Getfilestruct zbksh(1)
 
Modern Perl
Modern PerlModern Perl
Modern Perl
 
Accelerated Native Mobile Development with the Ti gem
Accelerated Native Mobile Development with the Ti gemAccelerated Native Mobile Development with the Ti gem
Accelerated Native Mobile Development with the Ti gem
 
Going crazy with Node.JS and CakePHP
Going crazy with Node.JS and CakePHPGoing crazy with Node.JS and CakePHP
Going crazy with Node.JS and CakePHP
 
DBIx::Class beginners
DBIx::Class beginnersDBIx::Class beginners
DBIx::Class beginners
 
Koajs as an alternative to Express - OdessaJs'16
Koajs as an alternative to Express - OdessaJs'16Koajs as an alternative to Express - OdessaJs'16
Koajs as an alternative to Express - OdessaJs'16
 
Your JavaScript Library
Your JavaScript LibraryYour JavaScript Library
Your JavaScript Library
 
Introduction to CoffeeScript
Introduction to CoffeeScriptIntroduction to CoffeeScript
Introduction to CoffeeScript
 
AnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time webAnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time web
 
ISUCONアプリを Pythonで書いてみた
ISUCONアプリを Pythonで書いてみたISUCONアプリを Pythonで書いてみた
ISUCONアプリを Pythonで書いてみた
 
Symfony2 meets propel 1.5
Symfony2 meets propel 1.5Symfony2 meets propel 1.5
Symfony2 meets propel 1.5
 
WordPress London 16 May 2012 - You don’t know query
WordPress London 16 May 2012 - You don’t know queryWordPress London 16 May 2012 - You don’t know query
WordPress London 16 May 2012 - You don’t know query
 
DBIx::Class introduction - 2010
DBIx::Class introduction - 2010DBIx::Class introduction - 2010
DBIx::Class introduction - 2010
 
Dealing with Legacy Perl Code - Peter Scott
Dealing with Legacy Perl Code - Peter ScottDealing with Legacy Perl Code - Peter Scott
Dealing with Legacy Perl Code - Peter Scott
 
Symfony 2.0 on PHP 5.3
Symfony 2.0 on PHP 5.3Symfony 2.0 on PHP 5.3
Symfony 2.0 on PHP 5.3
 

Viewers also liked

Wintry smoothie with grapefruits, pears and cashewnuts
Wintry smoothie with grapefruits, pears and cashewnutsWintry smoothie with grapefruits, pears and cashewnuts
Wintry smoothie with grapefruits, pears and cashewnutsTastymania
 
Webapp security testing
Webapp security testingWebapp security testing
Webapp security testingTomas Doran
 
TWI Summit Europe 2015 program
TWI Summit Europe 2015 program  TWI Summit Europe 2015 program
TWI Summit Europe 2015 program John Vellema
 
Evolucion de la deuda publica por entidad federativa desde 1993 hasta 2006
Evolucion de la deuda publica por entidad federativa desde 1993 hasta 2006Evolucion de la deuda publica por entidad federativa desde 1993 hasta 2006
Evolucion de la deuda publica por entidad federativa desde 1993 hasta 2006Froylan Angel Hernandez Ochoa
 
Marketing using social media
Marketing using social mediaMarketing using social media
Marketing using social mediaHeather Hurley
 
Challenges Chemoinformatics Tool Contest Award Presentation
Challenges Chemoinformatics Tool Contest Award PresentationChallenges Chemoinformatics Tool Contest Award Presentation
Challenges Chemoinformatics Tool Contest Award Presentationmdpi_ch
 
Hindustan Times HT Cafe- Cinema Promotes Pop Art
Hindustan Times HT Cafe- Cinema Promotes Pop ArtHindustan Times HT Cafe- Cinema Promotes Pop Art
Hindustan Times HT Cafe- Cinema Promotes Pop Artarchana jhangiani
 
Tendex - онлайн площадка для проведения электронных торгов
Tendex - онлайн площадка для проведения электронных торговTendex - онлайн площадка для проведения электронных торгов
Tendex - онлайн площадка для проведения электронных торговE-COM UA
 
Social media strategies instead of tools
Social media strategies instead of toolsSocial media strategies instead of tools
Social media strategies instead of toolsViệt Long Plaza
 
欧赛斯外星人探秘嘉年华网络公关营销提案
欧赛斯外星人探秘嘉年华网络公关营销提案欧赛斯外星人探秘嘉年华网络公关营销提案
欧赛斯外星人探秘嘉年华网络公关营销提案qoolupeter
 
Sitting on the bench? Don't blame the recruiter
Sitting on the bench? Don't blame the recruiterSitting on the bench? Don't blame the recruiter
Sitting on the bench? Don't blame the recruiterStephanie Hain
 
.NET Core Internals. O que é o .NET Platform Standard?
.NET Core Internals. O que é o .NET Platform Standard?.NET Core Internals. O que é o .NET Platform Standard?
.NET Core Internals. O que é o .NET Platform Standard?Victor Cavalcante
 
Delivering Happiness, The New Secret Ingredient by Sunny Grosso
Delivering Happiness, The New Secret Ingredient by Sunny GrossoDelivering Happiness, The New Secret Ingredient by Sunny Grosso
Delivering Happiness, The New Secret Ingredient by Sunny GrossoAudienceView
 
Nutrition and Food Products
Nutrition and Food ProductsNutrition and Food Products
Nutrition and Food ProductsMay Wee
 
Run a Smart SaaS Company
Run a Smart SaaS CompanyRun a Smart SaaS Company
Run a Smart SaaS CompanyTotango
 
The long and winding road to chemical information
The long and winding road to chemical informationThe long and winding road to chemical information
The long and winding road to chemical informationEngelbert Zass
 

Viewers also liked (20)

Wintry smoothie with grapefruits, pears and cashewnuts
Wintry smoothie with grapefruits, pears and cashewnutsWintry smoothie with grapefruits, pears and cashewnuts
Wintry smoothie with grapefruits, pears and cashewnuts
 
Webapp security testing
Webapp security testingWebapp security testing
Webapp security testing
 
TWI Summit Europe 2015 program
TWI Summit Europe 2015 program  TWI Summit Europe 2015 program
TWI Summit Europe 2015 program
 
Evolucion de la deuda publica por entidad federativa desde 1993 hasta 2006
Evolucion de la deuda publica por entidad federativa desde 1993 hasta 2006Evolucion de la deuda publica por entidad federativa desde 1993 hasta 2006
Evolucion de la deuda publica por entidad federativa desde 1993 hasta 2006
 
Marketing using social media
Marketing using social mediaMarketing using social media
Marketing using social media
 
Challenges Chemoinformatics Tool Contest Award Presentation
Challenges Chemoinformatics Tool Contest Award PresentationChallenges Chemoinformatics Tool Contest Award Presentation
Challenges Chemoinformatics Tool Contest Award Presentation
 
Hindustan Times HT Cafe- Cinema Promotes Pop Art
Hindustan Times HT Cafe- Cinema Promotes Pop ArtHindustan Times HT Cafe- Cinema Promotes Pop Art
Hindustan Times HT Cafe- Cinema Promotes Pop Art
 
Tendex - онлайн площадка для проведения электронных торгов
Tendex - онлайн площадка для проведения электронных торговTendex - онлайн площадка для проведения электронных торгов
Tendex - онлайн площадка для проведения электронных торгов
 
Social media strategies instead of tools
Social media strategies instead of toolsSocial media strategies instead of tools
Social media strategies instead of tools
 
欧赛斯外星人探秘嘉年华网络公关营销提案
欧赛斯外星人探秘嘉年华网络公关营销提案欧赛斯外星人探秘嘉年华网络公关营销提案
欧赛斯外星人探秘嘉年华网络公关营销提案
 
Sitting on the bench? Don't blame the recruiter
Sitting on the bench? Don't blame the recruiterSitting on the bench? Don't blame the recruiter
Sitting on the bench? Don't blame the recruiter
 
.NET Core Internals. O que é o .NET Platform Standard?
.NET Core Internals. O que é o .NET Platform Standard?.NET Core Internals. O que é o .NET Platform Standard?
.NET Core Internals. O que é o .NET Platform Standard?
 
Much ado about...documents
Much ado about...documentsMuch ado about...documents
Much ado about...documents
 
Bioclipse
BioclipseBioclipse
Bioclipse
 
Delivering Happiness, The New Secret Ingredient by Sunny Grosso
Delivering Happiness, The New Secret Ingredient by Sunny GrossoDelivering Happiness, The New Secret Ingredient by Sunny Grosso
Delivering Happiness, The New Secret Ingredient by Sunny Grosso
 
Nutrition and Food Products
Nutrition and Food ProductsNutrition and Food Products
Nutrition and Food Products
 
Nash 2013 liliana
Nash 2013 lilianaNash 2013 liliana
Nash 2013 liliana
 
Run a Smart SaaS Company
Run a Smart SaaS CompanyRun a Smart SaaS Company
Run a Smart SaaS Company
 
The long and winding road to chemical information
The long and winding road to chemical informationThe long and winding road to chemical information
The long and winding road to chemical information
 
TWI Summit 2013: TWI on a Global Scale
TWI Summit 2013: TWI on a Global Scale TWI Summit 2013: TWI on a Global Scale
TWI Summit 2013: TWI on a Global Scale
 

Similar to "The worst code I ever wrote"

What we Learned Implementing Puppet at Backstop
What we Learned Implementing Puppet at BackstopWhat we Learned Implementing Puppet at Backstop
What we Learned Implementing Puppet at BackstopPuppet
 
PuppetConf 2014 Killer R10K Workflow With Notes
PuppetConf 2014 Killer R10K Workflow With NotesPuppetConf 2014 Killer R10K Workflow With Notes
PuppetConf 2014 Killer R10K Workflow With NotesPhil Zimmerman
 
Elegant Solutions For Everyday Python Problems - Nina Zakharenko
Elegant Solutions For Everyday Python Problems - Nina ZakharenkoElegant Solutions For Everyday Python Problems - Nina Zakharenko
Elegant Solutions For Everyday Python Problems - Nina ZakharenkoNina Zakharenko
 
Twig: Friendly Curly Braces Invade Your Templates!
Twig: Friendly Curly Braces Invade Your Templates!Twig: Friendly Curly Braces Invade Your Templates!
Twig: Friendly Curly Braces Invade Your Templates!Ryan Weaver
 
Write your Ruby in Style
Write your Ruby in StyleWrite your Ruby in Style
Write your Ruby in StyleBhavin Javia
 
Gearman and CodeIgniter
Gearman and CodeIgniterGearman and CodeIgniter
Gearman and CodeIgniterErik Giberti
 
PuppetDB: Sneaking Clojure into Operations
PuppetDB: Sneaking Clojure into OperationsPuppetDB: Sneaking Clojure into Operations
PuppetDB: Sneaking Clojure into Operationsgrim_radical
 
Drupal 8: A story of growing up and getting off the island
Drupal 8: A story of growing up and getting off the islandDrupal 8: A story of growing up and getting off the island
Drupal 8: A story of growing up and getting off the islandAngela Byron
 
Work Queues
Work QueuesWork Queues
Work Queuesciconf
 
Debugging and Testing ES Systems
Debugging and Testing ES SystemsDebugging and Testing ES Systems
Debugging and Testing ES SystemsChris Birchall
 
Solid And Sustainable Development in Scala
Solid And Sustainable Development in ScalaSolid And Sustainable Development in Scala
Solid And Sustainable Development in ScalaKazuhiro Sera
 
Solid and Sustainable Development in Scala
Solid and Sustainable Development in ScalaSolid and Sustainable Development in Scala
Solid and Sustainable Development in Scalascalaconfjp
 
Php Code Audits (PHP UK 2010)
Php Code Audits (PHP UK 2010)Php Code Audits (PHP UK 2010)
Php Code Audits (PHP UK 2010)Damien Seguy
 
Building Cloud Castles
Building Cloud CastlesBuilding Cloud Castles
Building Cloud CastlesBen Scofield
 
How I Learned to Stop Worrying and Love Legacy Code - Ox:Agile 2018
How I Learned to Stop Worrying and Love Legacy Code - Ox:Agile 2018How I Learned to Stop Worrying and Love Legacy Code - Ox:Agile 2018
How I Learned to Stop Worrying and Love Legacy Code - Ox:Agile 2018Mike Harris
 
A Recovering Java Developer Learns to Go
A Recovering Java Developer Learns to GoA Recovering Java Developer Learns to Go
A Recovering Java Developer Learns to GoMatt Stine
 
Guide to Destroying Codebases The Demise of Clever Code
Guide to Destroying Codebases   The Demise of Clever CodeGuide to Destroying Codebases   The Demise of Clever Code
Guide to Destroying Codebases The Demise of Clever CodeGabor Varadi
 

Similar to "The worst code I ever wrote" (20)

What we Learned Implementing Puppet at Backstop
What we Learned Implementing Puppet at BackstopWhat we Learned Implementing Puppet at Backstop
What we Learned Implementing Puppet at Backstop
 
PuppetConf 2014 Killer R10K Workflow With Notes
PuppetConf 2014 Killer R10K Workflow With NotesPuppetConf 2014 Killer R10K Workflow With Notes
PuppetConf 2014 Killer R10K Workflow With Notes
 
Elegant Solutions For Everyday Python Problems - Nina Zakharenko
Elegant Solutions For Everyday Python Problems - Nina ZakharenkoElegant Solutions For Everyday Python Problems - Nina Zakharenko
Elegant Solutions For Everyday Python Problems - Nina Zakharenko
 
Twig: Friendly Curly Braces Invade Your Templates!
Twig: Friendly Curly Braces Invade Your Templates!Twig: Friendly Curly Braces Invade Your Templates!
Twig: Friendly Curly Braces Invade Your Templates!
 
Write your Ruby in Style
Write your Ruby in StyleWrite your Ruby in Style
Write your Ruby in Style
 
Conf orm - explain
Conf orm - explainConf orm - explain
Conf orm - explain
 
Gearman and CodeIgniter
Gearman and CodeIgniterGearman and CodeIgniter
Gearman and CodeIgniter
 
PuppetDB: Sneaking Clojure into Operations
PuppetDB: Sneaking Clojure into OperationsPuppetDB: Sneaking Clojure into Operations
PuppetDB: Sneaking Clojure into Operations
 
Drupal 8: A story of growing up and getting off the island
Drupal 8: A story of growing up and getting off the islandDrupal 8: A story of growing up and getting off the island
Drupal 8: A story of growing up and getting off the island
 
Work Queues
Work QueuesWork Queues
Work Queues
 
Debugging and Testing ES Systems
Debugging and Testing ES SystemsDebugging and Testing ES Systems
Debugging and Testing ES Systems
 
Django at Scale
Django at ScaleDjango at Scale
Django at Scale
 
Solid And Sustainable Development in Scala
Solid And Sustainable Development in ScalaSolid And Sustainable Development in Scala
Solid And Sustainable Development in Scala
 
Solid and Sustainable Development in Scala
Solid and Sustainable Development in ScalaSolid and Sustainable Development in Scala
Solid and Sustainable Development in Scala
 
Php Code Audits (PHP UK 2010)
Php Code Audits (PHP UK 2010)Php Code Audits (PHP UK 2010)
Php Code Audits (PHP UK 2010)
 
Building Cloud Castles
Building Cloud CastlesBuilding Cloud Castles
Building Cloud Castles
 
How I Learned to Stop Worrying and Love Legacy Code - Ox:Agile 2018
How I Learned to Stop Worrying and Love Legacy Code - Ox:Agile 2018How I Learned to Stop Worrying and Love Legacy Code - Ox:Agile 2018
How I Learned to Stop Worrying and Love Legacy Code - Ox:Agile 2018
 
Automate Yo' Self
Automate Yo' SelfAutomate Yo' Self
Automate Yo' Self
 
A Recovering Java Developer Learns to Go
A Recovering Java Developer Learns to GoA Recovering Java Developer Learns to Go
A Recovering Java Developer Learns to Go
 
Guide to Destroying Codebases The Demise of Clever Code
Guide to Destroying Codebases   The Demise of Clever CodeGuide to Destroying Codebases   The Demise of Clever Code
Guide to Destroying Codebases The Demise of Clever Code
 

More from Tomas Doran

Empowering developers to deploy their own data stores
Empowering developers to deploy their own data storesEmpowering developers to deploy their own data stores
Empowering developers to deploy their own data storesTomas Doran
 
Dockersh and a brief intro to the docker internals
Dockersh and a brief intro to the docker internalsDockersh and a brief intro to the docker internals
Dockersh and a brief intro to the docker internalsTomas Doran
 
Sensu and Sensibility - Puppetconf 2014
Sensu and Sensibility - Puppetconf 2014Sensu and Sensibility - Puppetconf 2014
Sensu and Sensibility - Puppetconf 2014Tomas Doran
 
Steamlining your puppet development workflow
Steamlining your puppet development workflowSteamlining your puppet development workflow
Steamlining your puppet development workflowTomas Doran
 
Building a smarter application stack - service discovery and wiring for Docker
Building a smarter application stack - service discovery and wiring for DockerBuilding a smarter application stack - service discovery and wiring for Docker
Building a smarter application stack - service discovery and wiring for DockerTomas Doran
 
Chasing AMI - Building Amazon machine images with Puppet, Packer and Jenkins
Chasing AMI - Building Amazon machine images with Puppet, Packer and JenkinsChasing AMI - Building Amazon machine images with Puppet, Packer and Jenkins
Chasing AMI - Building Amazon machine images with Puppet, Packer and JenkinsTomas Doran
 
Deploying puppet code at light speed
Deploying puppet code at light speedDeploying puppet code at light speed
Deploying puppet code at light speedTomas Doran
 
Thinking through puppet code layout
Thinking through puppet code layoutThinking through puppet code layout
Thinking through puppet code layoutTomas Doran
 
Docker puppetcamp london 2013
Docker puppetcamp london 2013Docker puppetcamp london 2013
Docker puppetcamp london 2013Tomas Doran
 
Test driven infrastructure development (2 - puppetconf 2013 edition)
Test driven infrastructure development (2 - puppetconf 2013 edition)Test driven infrastructure development (2 - puppetconf 2013 edition)
Test driven infrastructure development (2 - puppetconf 2013 edition)Tomas Doran
 
Test driven infrastructure development
Test driven infrastructure developmentTest driven infrastructure development
Test driven infrastructure developmentTomas Doran
 
London devops - orc
London devops - orcLondon devops - orc
London devops - orcTomas Doran
 
London devops logging
London devops loggingLondon devops logging
London devops loggingTomas Doran
 
Message:Passing - lpw 2012
Message:Passing - lpw 2012Message:Passing - lpw 2012
Message:Passing - lpw 2012Tomas Doran
 
Webapp security testing
Webapp security testingWebapp security testing
Webapp security testingTomas Doran
 
Dates aghhhh!!?!?!?!
Dates aghhhh!!?!?!?!Dates aghhhh!!?!?!?!
Dates aghhhh!!?!?!?!Tomas Doran
 
Messaging, interoperability and log aggregation - a new framework
Messaging, interoperability and log aggregation - a new frameworkMessaging, interoperability and log aggregation - a new framework
Messaging, interoperability and log aggregation - a new frameworkTomas Doran
 
Cooking a rabbit pie
Cooking a rabbit pieCooking a rabbit pie
Cooking a rabbit pieTomas Doran
 
High scale flavour
High scale flavourHigh scale flavour
High scale flavourTomas Doran
 

More from Tomas Doran (20)

Empowering developers to deploy their own data stores
Empowering developers to deploy their own data storesEmpowering developers to deploy their own data stores
Empowering developers to deploy their own data stores
 
Dockersh and a brief intro to the docker internals
Dockersh and a brief intro to the docker internalsDockersh and a brief intro to the docker internals
Dockersh and a brief intro to the docker internals
 
Sensu and Sensibility - Puppetconf 2014
Sensu and Sensibility - Puppetconf 2014Sensu and Sensibility - Puppetconf 2014
Sensu and Sensibility - Puppetconf 2014
 
Steamlining your puppet development workflow
Steamlining your puppet development workflowSteamlining your puppet development workflow
Steamlining your puppet development workflow
 
Building a smarter application stack - service discovery and wiring for Docker
Building a smarter application stack - service discovery and wiring for DockerBuilding a smarter application stack - service discovery and wiring for Docker
Building a smarter application stack - service discovery and wiring for Docker
 
Chasing AMI - Building Amazon machine images with Puppet, Packer and Jenkins
Chasing AMI - Building Amazon machine images with Puppet, Packer and JenkinsChasing AMI - Building Amazon machine images with Puppet, Packer and Jenkins
Chasing AMI - Building Amazon machine images with Puppet, Packer and Jenkins
 
Deploying puppet code at light speed
Deploying puppet code at light speedDeploying puppet code at light speed
Deploying puppet code at light speed
 
Thinking through puppet code layout
Thinking through puppet code layoutThinking through puppet code layout
Thinking through puppet code layout
 
Docker puppetcamp london 2013
Docker puppetcamp london 2013Docker puppetcamp london 2013
Docker puppetcamp london 2013
 
Test driven infrastructure development (2 - puppetconf 2013 edition)
Test driven infrastructure development (2 - puppetconf 2013 edition)Test driven infrastructure development (2 - puppetconf 2013 edition)
Test driven infrastructure development (2 - puppetconf 2013 edition)
 
Test driven infrastructure development
Test driven infrastructure developmentTest driven infrastructure development
Test driven infrastructure development
 
London devops - orc
London devops - orcLondon devops - orc
London devops - orc
 
London devops logging
London devops loggingLondon devops logging
London devops logging
 
Message:Passing - lpw 2012
Message:Passing - lpw 2012Message:Passing - lpw 2012
Message:Passing - lpw 2012
 
Webapp security testing
Webapp security testingWebapp security testing
Webapp security testing
 
Dates aghhhh!!?!?!?!
Dates aghhhh!!?!?!?!Dates aghhhh!!?!?!?!
Dates aghhhh!!?!?!?!
 
Messaging, interoperability and log aggregation - a new framework
Messaging, interoperability and log aggregation - a new frameworkMessaging, interoperability and log aggregation - a new framework
Messaging, interoperability and log aggregation - a new framework
 
Zero mq logs
Zero mq logsZero mq logs
Zero mq logs
 
Cooking a rabbit pie
Cooking a rabbit pieCooking a rabbit pie
Cooking a rabbit pie
 
High scale flavour
High scale flavourHigh scale flavour
High scale flavour
 

Recently uploaded

DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Wonjun Hwang
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
The Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfThe Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfSeasiaInfotech2
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostZilliz
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesZilliz
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 

Recently uploaded (20)

E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
The Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfThe Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdf
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector Databases
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 

"The worst code I ever wrote"

  • 1.
  • 2. The worst code I ever wrote (maybe) Tomas Doran @bobtfish tdoran@yelp.com 15/11/2013
  • 3. Key lessons ! •‘Working’ != ‘done’ – I’m a terrible person – Working now doesn’t mean you can maintain it •Functions for reuse – and my horrible propensity for inline templating •exec {} abuse – Lets fit an entire shell script in the command => “…” •Looping – Hacks you have probably used. – Doing it sanely with puppet >= 3.2 tl;dl: This talk is about bad puppet code, and how and why to do it better. The worst code I ever wrote is a lie ;) We’re going to concentrate on 2 main topics - functions and looping, with a nod to exec abuse.
  • 4. Managing ssh keys - gitolite ! • Legacy user management code –Old non-modular code –Have to fit in –Can’t change everything • Built in sshkey {} – Not suitable for our requirements We’re rapidly updating our puppet codebase, but the user management code is one of the most complex parts, so we wanted to be minimally invasive.. We needed to generate a very custom authorized keys files to integrate gitolite authentication into our current model.
  • 5. sshkey resource The built in sshkey {} isn’t perfect for everyone. Most of the solutions on forge aren’t generic
  • 6. http://forge.puppetlabs.com/hetzeneckerl/ssh_authorized_key These are the core issues. But this code didn’t work for me.
  • 7. http://forge.puppetlabs.com/nightfly/ssh_keys ! • Legacy user management code ! –Old non-modular code –Have to fit in • Almost – But not quite suitable for our requirements Doing it myself as a concat {} seemed sane, especially given other people’s evidence..
  • 8. Managing ssh keys - gitolite ! • Legacy user management code ! –Old non-modular code –Have to fit in –Can’t change everything • Built in sshkey {} – Not suitable for our requirements ! • Hack what we want with define So, we’re gonna use a bunch of defines and concat {}, easy?
  • 9. Inputs and outputs ! gitolite::user { ‘tdoran’: key_source => $key_source; } – Add in current user management code – $keysource = puppet:///files/ users/tdoran/authorized_keys /etc/authorized_keys.d/git.pub – Use concat – Multiple gitolite instances! - API for creating a key we drop into our current user management path - Eventual generated file, from a concat {} resource - Note we can have multiple gitolite instances on one box, that makes everything much harder.
  • 10. So how does it work? First, get an array of key lines, with names prepended $864
  • 11. Split the key into an array $864 We split the file of keys into an array of lines. We remove comments, whitespace only lines etc We capture the entire key passed in.
  • 12. Split the key into an array $864 We interpolate the username in front of that key, space separating them
  • 13. Split the key into an array $864 End up with an array of strings which are username and key joined by a space We then abuse a define as a loop by calling it with the array of lines as $title
  • 14. Prepend instance name ! Add user to every instance – [“${username} ${restofkey}”] – [“${instance} “] – [“${instance} ${username} ${restofkey}”] – Use this as $name in a define to iterate – ssh/authorized_keys.d/${instance}.pub We then have an array of instances, and an array of users/keys. Our array_prefix function makes the product of both lists. Complexity due to iterating over two lists $key_lines and $instances
  • 15. Prepend instance name ! Add user to every instance – [“${username} ${restofkey}”] – [“${instance} “] – [“${instance} ${username} ${restofkey}”] – Use this as $name in a define to iterate – ssh/authorized_keys.d/${instance}.pub We then have an array of instances, and an array of users/keys. Our array_prefix function makes the product of both lists. Complexity due to iterating over two lists $key_lines and $instances
  • 16. Prepend instance name ! Add user to every instance – [“${username} ${restofkey}”] – [“${instance} “] – [“${instance} ${username} ${restofkey}”] – Use this as $name in a define to iterate – ssh/authorized_keys.d/${instance}.pub We then have an array of instances, and an array of users/keys. Our array_prefix function makes the product of both lists. Complexity due to iterating over two lists $key_lines and $instances
  • 17. Prepend instance name ! Add user to every instance – [“${username} ${restofkey}”] – [“${instance} “] – [“${instance} ${username} ${restofkey}”] – Use this as $name in a define to iterate – ssh/authorized_keys.d/${instance}.pub We then have an array of instances, and an array of users/keys. Our array_prefix function makes the product of both lists. Complexity due to iterating over two lists $key_lines and $instances
  • 18. Prepend instance name ! Add user to every instance – [“${username} ${restofkey}”] – [“${instance} “] – [“${instance} ${username} ${restofkey}”] – Use this as $name in a define to iterate – ssh/authorized_keys.d/${instance}.pub This is gross We then have an array of instances, and an array of users/keys. Our array_prefix function makes the product of both lists. Complexity due to iterating over two lists $key_lines and $instances
  • 19. My original next code Stare in horror! $864 This was hideous. Whilst looping without define abuse is hard, there’s just no excuse for this.
  • 20. Sins LOL?? Hideous abuse of define - one $name for each $key_lines $864 We then split the line back up.
  • 21. Sins $864 Shift the user name off the array. Lol, who knew you could do that? Use the remaining data joined back up LOL?? Hideous abuse of variables
  • 22. Sins Hideous abuse of interpolation LOL?? LOL?? $864 So, here, I have a double quoted string containing erb, and I’m then using double quote (not erb) interpolation.. Niiice.
  • 23. Sins Hideous abuse of quoting EVERY TYPE OF QUOTES!!! LOL?? LOL?? LOL?? $864
  • 24. Sins Hideous abuse of quoting $864 LOL?? LOL??
  • 25. Sins Hideous abuse of bash LOL?? $864 ssh-keygen can’t be fed from stdin without disgusting trickery (modern bash specific)
  • 26. Sins So complex I’m tempting the template! LOL?? $864 LOL?? And yes, it’s so complex I template the thing I’m interpolating into a template..
  • 27. I am a bad person LOL? $864
  • 28. I am a bad person LOL? $864
  • 29. I am a bad person LOL? $864 Thankfully
  • 30. I am a bad person LOL? $864 Someone stopped me ;)
  • 31. Don’t abuse inline_template() ! • Please? – I’m a terrible person – Working now doesn’t mean you can maintain it • Functions for reuse – Full power of ruby – Composable – There should be more libraries of functions Do what I’m saying, not what I do :)
  • 32. More sane Except each user can have multiple keys, and we want to prevent any key being reused by multiple users.
  • 33. Issues with functions ! • What functions do I even have? – Hard to know what functions you have imported – stdlib, builtins, ….your $modulepath here… • What do these even do? – Often need to read the code to determine – Lots of functions packaged with modules - don’t do this! • Millions of twisty little functions, all alike • Millions of twisty little functions, all different – You know what this reminds me of?
  • 34. Everyone’s favorite language If all you have is a hammer, everything looks like a nail
  • 35. has a few functions Unfortunately, there are no consistent naming conventions
  • 36. arguably And it’s hard to work out which function you actually want
  • 37. a few too many.. The problem is, functions in a global namespace aren’t all that modular/composable. You can call functions from functions - but dependency hell
  • 38. we’re almost half way through…. Shall I stop now? :) puppet problem is worse than this - what functions you have depends on what modules are in your codebase.
  • 39. Get docs for project’s functions I wrote a thing to help with this - this will document _your_ functions for you. gist at end of talk.
  • 40. gitolite group file generation ! • /etc/groups on system ! • gitolite groups have a different format: @admins = tdoran joebloggs! ! • Use exec {… add mess here … } This is another great example of what not to do.
  • 41. exec {} abuse Syntax highlighting won’t save you now puny human! $864 This. DO NOT DO THIS. Please?
  • 42. exec {} abuse Syntax highlighting won’t save you now puny human! $864
  • 43. exec {} abuse Syntax highlighting won’t save you now puny human! $864
  • 44. exec {} abuse Syntax highlighting won’t save you now puny human! $864 Arggh, the backslashes!
  • 45. This madness actually worked LOL? $864
  • 46. This madness actually worked LOL? ! •exec {} abuse – Lets fit an entire shell script in the 
 command => “…” – Don’t do it! :) – Drop a perl/python/ruby script (or two) instead, call them from the exec. $864 – Think about writing a type/provider – Lots of examples of parsedfile available
  • 47. Which would you rather have to debug? $864
  • 49. Which one’s going to stay debugged? $864
  • 51. Looping sanely ! This would work fine. Need multiple instances :(
  • 54. —parser future ! • Can’t do this at Yelp (yet) • Still using 2.7, because $864 variable scope
  • 55. Hypocrisy avoidance ! ”There should be more libraries of functions” - Me, about 5m ago – https://github.com/bobtfish/puppetsshkey_utilities – https://github.com/bobtfish/puppet-better_file – https://gist.github.com/bobtfish/7403811 – Whole module to follow (eventually)
  • 56. That’s all folks ! • Where was that code? – https://github.com/bobtfish/puppet-sshkey_utilities – https://github.com/bobtfish/puppet-better_file • Did you say you were hiring? – YES – Hamburg. – London. – San Francisco. • Questions?