Puppet Language 4.0 - PuppetConf 2014
-
Upload
puppet-labs -
Category
Technology
-
view
2.086 -
download
3
description
Transcript of Puppet Language 4.0 - PuppetConf 2014
Yamata no Orochi
Puppet Language 4.0
notice 1 => 1 notice 1 + 2 => syntax error notice(1 + 2) => 3 notice 1,2,3 => 1 2 3 notice [1,2,3] => 1 2 3 notice [1,2],3 => 1 2 3 notice 5 in [5] => true notice (4+1) in [5] => error, not a string notice 5 in [4+1] => false notice 5.0 in [5] => false notice(0xff =~ /5/) => false notice((0xfe+1) =~/5/) => true notice { a=>10 } => error, no title
Puppet 4.0
• Language Cleanup – Sanity, Principle of Least Surprise – Expressions, Expressions, Expressions
• Features – Misc enhancements – Resource Expression Features – IteraGon – Type System / OpGonal Typing – Embedded Puppet Templates (EPP) – Heredoc
Cleanup
• Language SpecificaGon – yes we have one – hQps://github.com/puppetlabs/puppet-‐specificaGons
• Numbers are Numbers • No magic to-‐string for =~ !~ in • Upper case bare words are Type References • Empty string is not undef (and thus "thruty") • InterpolaGon follows specified rules • +=, []= removed, no more mutaGon
Misc new features 1(7)
• Concatenate Arrays with + [1,2,3] + [4,5,6] => [1,2,3,4,5,6]
• Merge Hashes with + {a=>1} + {b=>2} => {a=>1, b=>2}
• Delete with -‐ [1,2,3] – [2, 3] => [1] {a=>1, b=>2, c=>3} – [a,c] => {b=>2}
Misc new features 2(7)
• Append to Array with << [1,2,3] << 4 => [1,2,3,4] [1,2,3] << [4,5,6] => [1,2,3,[4,5,6]]
Misc new features 3(7)
• Unfold with unary * $a = [2,3] $b = [1, *$a, 4] => [1,2,3,4]
• Unfold in case opGon, selector and call $a = [1,2,3] case 1 { *$a : { # 1 or 2 or 3
} } notice *$a => 1,2,3 notice $a => [1,2,3]
Misc new features 4(7)
• Substring in string 'cd' in "abcde" => true
• Substring with [] "xyzabcdef"[3,3] => "abc" "xyzabcdef"[3] => "a" "xyzabcdef"[3,-2] => "abcde"
Misc new features 5(7)
• Matches with Regexp in String form $a = "example.com" $url =~ "http://$a.*"
Misc new features 6(7)
• Detailed Error Messages – SemanGc validaGon unless lex or syntax errors
– Outputs posiGon on line – Can report more than one error
Expression Based Grammar 6(7)
• if, unless, case are expressions notice if 1 > 2 { true } else { false } # => false
$a = case 2 { 1, 2, 3: { yes } default: { no } } # => $a == yes
Resource Expression
Local Defaults
file { default: mode => '444', owner => 'admin';
title: . . . ; }
Unfold Hash
file { default: * => $defaults_hash;
'tmp/foo': mode => '666', * => $params_hash; }
Create Resources Equiv. in Puppet
Resource[$type] { default: * => $defaults_hash;
$titles: * => $params_hash; }
LOOOOOOOPS
• Iterate over: – Arrays – Hashes – Strings – Integer ranges
• Implemented as funcGons taking callable code blocks (lambdas) = open design
• Calls can now be expressed from leh to right using '.' notaGon
each
• Do something with each element • Returns LHS
[1,2,3].each |$x| { notice $x }
each([1,2,3]) |$x| { notice $x }
map
• Transform each element • Returns transformed result
[1,2,3].map |$x| { $x*10 }
=> [10,20,30]
filter
• Produces elements that match • Returns filtered result
[1,2,3].filter|$x| { $x >= 2 }
=> [2,3]
reduce
• Transforms / reduces many to one • Feeds seed/previous result into next iteraGon • Returns transformed result
[1,2,3].reduce |$result, $x| { $result + $x }
=> 6
And more
E-‐I-‐E-‐I-‐O
E-‐I-‐E-‐I-‐O
E-‐I-‐E-‐I-‐O
E-‐I-‐E-‐I-‐O
The Puppet Type System
Cow
Integer
Puppet Types
• Puppet Types are first order objects (they can be assigned and passed around in variables)
• Uses syntax familiar from Resource – i.e. Class, File, User, where [ ] applied to the type makes it more specific – e.g. File['foo']
Example Integer
# All integers Integer
# All integers >=42 Integer[42]
# All integers >=42 and <=142 Integer[42,142]
AutomaGc type checking!
define mytype(Integer[80,443] $port){ # port guaranteed to be integer # and between 80 and 443 # otherwise an error }
More advanced type checking!
define mytype($port) { assert_type(Integer[80,443], $port) |$expected, $got| { warn("Bad port $got, expected $expected. Using port 80.") 80 } }
• Code block called if given does not match • …do what you want, fail, warn, return default
OperaGons on Type
• Since a Type is a kind of PaQern… – Match with =~ and !~
– Match in case expression
• Since Types are defined in a hierarchy: – Compare types with <, <=, >, >=
# is $x an integer ? $x =~ Integer
# is $t more specific than Integer $t = Integer[80, 144] $t < Integer
Type Hierarchy Any |- Scalar | |- Numeric | | |- Integer[from, to] | | |- Float[from, to] | | | |- String[from, to] | | |- Enum[*strings] | | |- Pattern[*patterns] | | | |- Boolean | |- Regexp[pattern_string]
Type Hierarchy Any |- Collection | |- Array[T] | | |- Tuple[T*, from, to] | | | |- Hash[K, V] | | |- Struct[{ key => T, ...}] | |- Variant[T*] |- Optional[T] | |- Undef |- Default | |- Type[T]
Type Hierarchy Any |- CatalogEntry | |- Resource[type_name, title] | |- Class[class_name] | |- Undef |- Data | |- Scalar | |- Array[Data] | |- Hash[Scalar, Data] | |- Undef
EPP
EPP – Templates in Puppet
• Same template markup as ERB – Logic is Puppet instead of Ruby
AND • Can be parameterized ! • Use funcGons
epp(template) inline_epp(string)
• instead of template() inline_template()
Example EPP
$x = 'human' inline_epp('This is not the <%= $x %> you are looking for.', { 'x' => 'droid'})
# => 'This is not the droid you are looking for.'
<%- |$x = 'human'| -%> This is not the <%= $x %> you are looking for.
$x = 'human' inline_epp('This is not the <%= $x %> you are looking for.')
# => 'This is not the human you are looking for.'
Heredoc
Puppet Heredoc
• For more detailed control over a block of text • No, or selected set of escapes • InterpolaGon or no interpolaGon • Can be syntax checked by parser (JSon in core, can add plugin language support)
• Control over leh margin
Heredoc -‐ Syntax
@( ["]<endtag>["] [:<syntax>] [/<escapes>] ) <text> [|][-] <endtag>
ENDS-‐HERE anything not in <text>
"ENDS-‐HERE" with interpola:on
:json syntax check result
/tsrn$L turns on escape / turns on all
| set le= margin
-‐ trim trailing
t tab s space r return n new-‐line $ $ L <end of line>
Puppet Heredoc 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
#.........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
Ruby API
Ruby API
• 4x FuncGon API – type checked – dispatch to impl based on given types – more powerful – safer
• Binder – composable type safe injecGon – for plugins and data (e.g. syntax checkers)
Summary
• Language Cleanup • More strict • New Features • BeQer Error Messages • IteraGon • Type System • Puppet Templates – EPP • Heredoc
In pracGce
• Run now with –parser future • Fix deprecaGons and issues • Make backwards compaGble changes and conGnue in producGon on 3x
• Test carefully and conGnue running on what will be Puppet 4.0
• 4.0 expected release before end of the year
Links
• github/puppetlabs/puppet-‐specificaGons • hQp://puppet-‐on-‐the-‐edge.blogspot.com/
• TwiQer @hel
• IRC helindbe