0
puppetconf.com #puppetconf
Loops and Unicorns
Future of the Puppet Language
Henrik Lindberg
Consulting Engineer | Puppet Labs
@hel
puppetconf.com #puppetconf
•  New parser
•  New Language Features
•  New approach
– Opt in to New/Experimental Features
– ...
New Parser
The future is already here…
puppetconf.com #puppetconf
•  Rewritten from the ground up
•  Removes quirky grammar constraints
•  Improves error message...
puppetconf.com #puppetconf
De-Quirk
"This is a random number: ${fqdn_rand()}"
join([1,2,3])
$a = 0x0EH
$b = 0778
Interpola...
puppetconf.com #puppetconf
Array & Hash
$a = [1,2,3]
$b = [4,5,6]
$c = $a + $b
Concatenate Arrays:
Append to Array:
Merge ...
puppetconf.com #puppetconf
Misc
unless $something { . . .}
else { . . . }
Unless Else:
Assignment is an expression:
Expres...
puppetconf.com #puppetconf
Error Reporting
Error: Could not parse for environment production:
Syntax error at 'node' at li...
New Approach
puppetconf.com #puppetconf
•  Forgiving Grammar
•  Validation is separate
– Can validate a particular language version
– L...
New Language Features
puppetconf.com #puppetconf
puppetconf.com #puppetconf
puppetconf.com #puppetconf
puppetconf.com #puppetconf
puppetconf.com #puppetconf
•  Iteration & Lambdas
•  Puppet Bindings
•  Heredoc support
•  Puppet Templates
New Language F...
Iteration & Lambdas
puppetconf.com #puppetconf
Concepts
each($foo) |$x| { notice $x }
The lambda:
Inline call:
$foo.each |$x| { notice $x }
ea...
puppetconf.com #puppetconf
•  each
•  select – reject
•  collect
•  reduce
•  slice
Custom functions can take a lambda!
It...
puppetconf.com #puppetconf
Each - Array
$a = ['a', 'b', 'c']
$a.each |$value| { notice $value }
Iterating over an array:
P...
puppetconf.com #puppetconf
Each – Array (with index)
$a = ['a', 'b', 'c']
$a.each |$index, $value| { notice "$index = $val...
puppetconf.com #puppetconf
Each - Hash
$a = {a => 10, b => 20, c => 30}
$a.each |$key, $value| { notice "$key = $value" }
...
puppetconf.com #puppetconf
Each – Hash (elements)
$a = {a => 10, b => 20, c => 30}
$a.each |$elem| { notice "${elem[0]} = ...
puppetconf.com #puppetconf
Select / Reject
$a = [1, 2, 3]
notice $a.select |$value| { $v == 2 }
notice $a.reject |$value| ...
puppetconf.com #puppetconf
Collect
$a = [1, 2, 3]
notice $a.collect |$value| { $v * 10 }
Transform each element with colle...
puppetconf.com #puppetconf
Reduce
$a = [1, 2, 3]
notice $a.reduce |$memo, $value| { $memo + $value }
Reduce all elements i...
puppetconf.com #puppetconf
Examples
$usernames.each |$x| {
file { "/home/$x/.somerc":
owner => $x
}
}
Set ownership of som...
puppetconf.com #puppetconf
Examples
$a.select |$x| { $x =~ /com$/ }.each |$x| {
file { "/somewhere/$x":
owner => $x
}
}
Fi...
puppetconf.com #puppetconf
Custom Function (Ruby)
pp_block = args[-1]
Lambda always last argument:
Was it given?
Call it:
...
puppetconf.com #puppetconf
•  http://links.puppetlabs.com/arm2-iteration
•  http://links.puppetlabs.com/arm2-examples
ARM ...
Heredoc
Not yet on master branch
https://github.com/puppetlabs/puppet/pull/1659
puppetconf.com #puppetconf
Heredoc - Syntax
@( ["]<endtag>["] [:<syntax>] [/<escapes>] )
<text>
[|][-] <endtag>
ENDS-­‐HER...
puppetconf.com #puppetconf
Heredoc – example
Example:
#.........1.........2.........3.........4.........5....
$a = @(END)
...
puppetconf.com #puppetconf
Heredoc – example
multiple on same line:
#.........1.........2.........3.........4.........5......
puppetconf.com #puppetconf
For more examples and details
•  http://links.puppetlabs.com/arm4-heredoc
ARM-4 Heredoc
Puppet Templates
Not yet on master branch
https://github.com/puppetlabs/puppet/pull/1660
puppetconf.com #puppetconf
•  Embedded Puppet (EPP) - like ERB
•  Same tags
§  <%, <%=, <%-, <%%, <%#
§  %>,-%>
•  Expre...
puppetconf.com #puppetconf
Use by calling
epptemplate(<name> [,<params_hash>])
inline_epptemplate(<text>[,<params_hash>])
...
puppetconf.com #puppetconf
•  Parameterized
– declare parameters
– set default values
– parameter without value and no def...
puppetconf.com #puppetconf
For more examples and details
•  http://links.puppetlabs.com/arm3-
puppet_templates
ARM-3 Puppe...
Puppet Bindings / Data in Modules
puppetconf.com #puppetconf
•  More powerful data bindings
•  For both Data, and Puppet Extensions
•  Composes Hiera2 data ...
puppetconf.com #puppetconf
•  Default:
– All hiera-2 data (in default location) and all
(default) ruby bindings from all m...
puppetconf.com #puppetconf
•  Composable
•  Interpolation using Puppet DSL expressions
•  Changed hiera.yaml syntax (for v...
puppetconf.com #puppetconf
Minimal opt-in (in a module)
---
version: 2
hiera.yaml:
data/common.yaml:
data/${osfamily}.yaml...
puppetconf.com #puppetconf
For more examples and details
•  http://links.puppetlabs.com/arm8-
puppet_bindings
•  http://li...
Thank You
Henrik Lindberg
Consulting Engineer | Puppet Labs
@hel
Collaborate. Automate. Ship.
Follow us on Twitter @puppetlabs
youtube.com/puppetlabsinc
slideshare.net/puppetlabs
Collaborate. Automate. Ship.
Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013
Upcoming SlideShare
Loading in...5
×

Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013

5,505

Published on

"Loops and Unicorns - The Future of the Puppet Language" by Henrik Lindberg, Platform Engineer, Puppet Labs.

Presentation Overview: Loops, Unicorns and other magical animals lives in your puppet since Puppet 3.2. This is the first version to ship with the future just a setting away! In this talk you will see the new features at work; we are talking loops, lambdas, puppet templates and other unicorns! In addition to learning how loops work, we will present the background to the new parser and the future capabilities this enables such as being able to support multiple language compliance levels, provide better error messages, and much more. Parts of this talk will touch on advanced topics such has to use lambdas in your custom functions.

Speaker Bio: Henrik has 30 years of experience architecting and developing software. Past positions include CTO of Cloudsmith Inc, leadership of BEA’s Java Run-Time Group (JRockit) and CTO and/or technical founder of several publicly and privately held software companies. Henrik works on the Platform team at Puppet Labs with special focus on the Puppet Language. He is also a committer and leader of several Eclipse projects, and leads the Puppet IDE Geppetto project.

Published in: Technology, Spiritual
0 Comments
6 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
5,505
On Slideshare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
47
Comments
0
Likes
6
Embeds 0
No embeds

No notes for slide

Transcript of "Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013"

  1. 1. puppetconf.com #puppetconf
  2. 2. Loops and Unicorns Future of the Puppet Language Henrik Lindberg Consulting Engineer | Puppet Labs @hel
  3. 3. puppetconf.com #puppetconf •  New parser •  New Language Features •  New approach – Opt in to New/Experimental Features – Maintaining Backwards Compatibility Introduction
  4. 4. New Parser The future is already here…
  5. 5. puppetconf.com #puppetconf •  Rewritten from the ground up •  Removes quirky grammar constraints •  Improves error messages •  Enabler for: – opt-in to new and experimental features – backwards compatibility •  Use on command line, or in settings New Parser puppet apply –-parser future ...
  6. 6. puppetconf.com #puppetconf De-Quirk "This is a random number: ${fqdn_rand()}" join([1,2,3]) $a = 0x0EH $b = 0778 Interpolation and functions work: Literal Array / Hash as argument in calls works: Numbers must now be valid:
  7. 7. puppetconf.com #puppetconf Array & Hash $a = [1,2,3] $b = [4,5,6] $c = $a + $b Concatenate Arrays: Append to Array: Merge Hash: $d = $a << 4 $a = {name => 'mary'} $b = {has => 'a little lamb'} $c = $a + $b
  8. 8. puppetconf.com #puppetconf Misc unless $something { . . .} else { . . . } Unless Else: Assignment is an expression: Expression separator ';' : $a = $b = 10 fqdn_rand($seed = 30) $a = $x[1][1] $a = $x[1];[1]
  9. 9. puppetconf.com #puppetconf Error Reporting Error: Could not parse for environment production: Syntax error at 'node' at line 1 on node kermit.example.com puppet apply -e '$a = node "a+b" { }' Then: Now: Error: Invalid use of expression. A Node Definition does not produce a value at line 1:6 Error: The hostname 'a+b' contains illegal characters (only letters, digits, '_', '-', and '.' are allowed) at line 1:11 Error: Classes, definitions, and nodes may only appear at toplevel or inside other classes at line 1:6 Error: Could not parse for environment production: Found 3 errors. Giving up on node kermit.example.com
  10. 10. New Approach
  11. 11. puppetconf.com #puppetconf •  Forgiving Grammar •  Validation is separate – Can validate a particular language version – Language version != Puppet version •  Evaluation is separate – Can evaluate a particular language version way – Language version != Puppet version Separation of Language Concerns
  12. 12. New Language Features
  13. 13. puppetconf.com #puppetconf
  14. 14. puppetconf.com #puppetconf
  15. 15. puppetconf.com #puppetconf
  16. 16. puppetconf.com #puppetconf
  17. 17. puppetconf.com #puppetconf •  Iteration & Lambdas •  Puppet Bindings •  Heredoc support •  Puppet Templates New Language Features
  18. 18. Iteration & Lambdas
  19. 19. puppetconf.com #puppetconf Concepts each($foo) |$x| { notice $x } The lambda: Inline call: $foo.each |$x| { notice $x } each($foo) |$x| { notice $x }
  20. 20. puppetconf.com #puppetconf •  each •  select – reject •  collect •  reduce •  slice Custom functions can take a lambda! Iterating Functions
  21. 21. puppetconf.com #puppetconf Each - Array $a = ['a', 'b', 'c'] $a.each |$value| { notice $value } Iterating over an array: Produces: Notice: Scope(Class[main]): a Notice: Scope(Class[main]): b Notice: Scope(Class[main]): c
  22. 22. puppetconf.com #puppetconf Each – Array (with index) $a = ['a', 'b', 'c'] $a.each |$index, $value| { notice "$index = $value" } Iterating over an array – with index: Produces: Notice: Scope(Class[main]): 0 = a Notice: Scope(Class[main]): 1 = b Notice: Scope(Class[main]): 2 = c
  23. 23. puppetconf.com #puppetconf Each - Hash $a = {a => 10, b => 20, c => 30} $a.each |$key, $value| { notice "$key = $value" } Iterating over a hash – with key and value: Produces: Notice: Scope(Class[main]): a = 10 Notice: Scope(Class[main]): b = 20 Notice: Scope(Class[main]): c = 30
  24. 24. puppetconf.com #puppetconf Each – Hash (elements) $a = {a => 10, b => 20, c => 30} $a.each |$elem| { notice "${elem[0]} = ${elem[1]}" } Iterating over a hash elements: Produces: Notice: Scope(Class[main]): a = 10 Notice: Scope(Class[main]): b = 20 Notice: Scope(Class[main]): c = 30
  25. 25. puppetconf.com #puppetconf Select / Reject $a = [1, 2, 3] notice $a.select |$value| { $v == 2 } notice $a.reject |$value| { $v == 2 } Select and Reject elements: Produces: Notice: Scope(Class[main]): 2 Notice: Scope(Class[main]): 1 3
  26. 26. puppetconf.com #puppetconf Collect $a = [1, 2, 3] notice $a.collect |$value| { $v * 10 } Transform each element with collect: Produces: Notice: Scope(Class[main]): 10 20 30
  27. 27. puppetconf.com #puppetconf Reduce $a = [1, 2, 3] notice $a.reduce |$memo, $value| { $memo + $value } Reduce all elements into one: Produces: Notice: Scope(Class[main]): 6
  28. 28. puppetconf.com #puppetconf Examples $usernames.each |$x| { file { "/home/$x/.somerc": owner => $x } } Set ownership of some "rc-file" for each user: Setting 'owner' and 'mode' from a Hash: $users_with_mode = ['fred' => 0666, 'mary' => 0777 ] $users_with_mode.each |$user, $mode| { file {"/home/$user/.somerc": owner => $user, mode => $mode } }
  29. 29. puppetconf.com #puppetconf Examples $a.select |$x| { $x =~ /com$/ }.each |$x| { file { "/somewhere/$x": owner => $x } } Filter and create resources: Include classes based on array of roles: $roles.each |$x| { include "role_$x" }
  30. 30. puppetconf.com #puppetconf Custom Function (Ruby) pp_block = args[-1] Lambda always last argument: Was it given? Call it: pp_block.is_a? Puppet::Parser::AST::Lambda # in a custom function, self is scope) pp_block.call(self, 'hello', 'world')
  31. 31. puppetconf.com #puppetconf •  http://links.puppetlabs.com/arm2-iteration •  http://links.puppetlabs.com/arm2-examples ARM 2 - Iteration
  32. 32. Heredoc Not yet on master branch https://github.com/puppetlabs/puppet/pull/1659
  33. 33. puppetconf.com #puppetconf Heredoc - Syntax @( ["]<endtag>["] [:<syntax>] [/<escapes>] ) <text> [|][-] <endtag> ENDS-­‐HERE   anything  not  in  <text>     "ENDS-­‐HERE"   with  interpola2on   :json   syntax  check  result   /tsrn$L    turns  on  escape   /      turns  on  all   |   set  le7  margin   -­‐   trim  trailing   t  tab   s  space   r  return   n  new-­‐line   $  $   L  <end  of  line>  
  34. 34. puppetconf.com #puppetconf Heredoc – example Example: #.........1.........2.........3.........4.........5.... $a = @(END) This is indented 2 spaces in the source, but produces a result flush left with the initial 'T' This line is thus indented 2 spaces. | END
  35. 35. puppetconf.com #puppetconf Heredoc – example multiple on same line: #.........1.........2.........3.........4.........5.... foo(@(FIRST), @(SECOND)) This is the text for the first heredoc FIRST This is the text for the second SECOND
  36. 36. puppetconf.com #puppetconf For more examples and details •  http://links.puppetlabs.com/arm4-heredoc ARM-4 Heredoc
  37. 37. Puppet Templates Not yet on master branch https://github.com/puppetlabs/puppet/pull/1660
  38. 38. puppetconf.com #puppetconf •  Embedded Puppet (EPP) - like ERB •  Same tags §  <%, <%=, <%-, <%%, <%# §  %>,-%> •  Expressions are Puppet DSL •  Parameterized •  .epp file extension (by convention) Puppet Templates
  39. 39. puppetconf.com #puppetconf Use by calling epptemplate(<name> [,<params_hash>]) inline_epptemplate(<text>[,<params_hash>]) Puppet Templates $x = 'human' inline_epptemplate('This is not the <%= $x %> you are looking for.', { 'x' => 'droid'}) # => 'This is not the droid you are looking for.'
  40. 40. puppetconf.com #puppetconf •  Parameterized – declare parameters – set default values – parameter without value and no default = error Puppet Templates <%- ($x = 'human') -%> This is not the <%= $x %> you are looking for.
  41. 41. puppetconf.com #puppetconf For more examples and details •  http://links.puppetlabs.com/arm3- puppet_templates ARM-3 Puppet Templates
  42. 42. Puppet Bindings / Data in Modules
  43. 43. puppetconf.com #puppetconf •  More powerful data bindings •  For both Data, and Puppet Extensions •  Composes Hiera2 data in modules and environment + Hiera1 •  Bindings in Ruby •  Opt in on command line or in settings Puppet Binder puppet apply --binder puppet apply –-parser future ...
  44. 44. puppetconf.com #puppetconf •  Default: – All hiera-2 data (in default location) and all (default) ruby bindings from all modules on module path composed – Site level hiera-2 data and ruby bindings override contributions from modules. •  Customize – include alternatives, exclude bindings – add / reorganize overriding "layers" Configuration
  45. 45. puppetconf.com #puppetconf •  Composable •  Interpolation using Puppet DSL expressions •  Changed hiera.yaml syntax (for version 2) Hiera 2
  46. 46. puppetconf.com #puppetconf Minimal opt-in (in a module) --- version: 2 hiera.yaml: data/common.yaml: data/${osfamily}.yaml: --- myclass::myparam: '1.2.3' --- myclass::myparam: '2.4.6'
  47. 47. puppetconf.com #puppetconf For more examples and details •  http://links.puppetlabs.com/arm8- puppet_bindings •  http://links.puppetlabs.com/arm9- data_in_modules ARM-8 & 9
  48. 48. Thank You Henrik Lindberg Consulting Engineer | Puppet Labs @hel Collaborate. Automate. Ship.
  49. 49. Follow us on Twitter @puppetlabs youtube.com/puppetlabsinc slideshare.net/puppetlabs Collaborate. Automate. Ship.
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×