Thursday, September 4, 2014

Summary of Puppet 4 features and deprecations

PuppetLabs maintains a github repo where they manage documents regarding Puppet 4.x changes, deprecations and new features.
This article is a summary on planned and implemented changes.


New environment configuration pattern: environmentpath

Each environment directory
- can have environment.conf - overwrite defaults for this special env
- has manifests and modules

Within manifests directory all files are processed in alphabetical order

Catalog compile

1. initial evaluation
  - load global variables
  - set node definitions
2. selection of node definition
3. evaluation of node definition
4. catalog completion


In Puppet3 everything is visible to everything.
You can build references among different modules.

In Puppet4 visibility is limited:

- Puppet Runtime defines are visible to everything
- everything in an environment is visible to everything in the same environment
- modules without dependencies see all other modules
- modules with dependency see the module it depends on

Types, Values, Variables

Puppet Types
- Data Types
  - Integer
  - Float
  - Boolean
  - Regexp
  - String
  - Array
  - Hash
- Catalog Types
  - Resource
  - Class
- Abstract Types
  - Collection
  - Scalar
  - Numeric
  - CatalogEntry
  - Data
  - Tuple
  - Struct
  - Optional
  - Variant
  - Enum
  - Pattern
  - Any

Platform Types
  - Callable
  - Type
  - Runtime
  - Undef
  - Default


strict naming:
- start with lower case letter
- hyphen and period are no longer supported
- No upper case letter in initial position
- no underscore in initial position

Variable References
optional (configurable) strict variable lookup in Puppet 4 - will become mandatory in Puppet 5

Boolean conversion
‘’        -> true (false in Puppet 3 !!!)
undef    -> false
false        -> false
any other    -> true


- Top scope
- Class scope
- define scope
- lambda scope
- node scope

Access control (not yet implemented)

apply the keyword “private” to
- class
- define
- parameter
- variable

Private classes may only be
- included
- required
- instantiated (declared)
- inherited
- form relationship with private class
from the module where it is declared
References are possible

Private defines may only be
- instantiated (declared)
- form relationship
form the module where it is declared

Private parameters may only be
- referencing using variable syntax
- referencing parameter via catalog lookup and accessing its parameter

Private variable may only be
- available in the scope where declared
This is only useful for variables in top, node or class scope.
It is not visible to other scopes.

Lexical Stuff

Puppet reads ASCII files.
One may use Unicode escape mechanism (/uXXXX).
In the Future it may be possible to specify encoding for a file.

Reserved keywords:
- false
- true
- undef
- and
- case
- class
- default
- define
- else
- elsif
- if
- in
- inherits
- node
- or
- unless
Reserved for future:
- type
- function
- private
- attr
Reserved for types:
- any, Any
- hash, Hash
- array, Array
- integer, Integer
- float, Float
- collection, Collection
- scalar, Scalar
- resource, Resource
- string, String
- pattern, Pattern
- boolean, Boolean
- class, Class
- type, Type
- runtime, Runtime
- numeric, Numeric
- data, Data
- catalogentry, catalogEntry, CatalogEntry
- enum, Enum
- variant, Variant
- data, Data
 -struct, Struct
- tuple, Tuple
- optional, Optional
- undef, Undef
- default, Default


Node definition changes. Node inheritance will now raise an error.

Class definition remains as is

Resource definition remains as is

Resource defaults remain ss is


“class” is not a valid class name
Upper case variable names
Variables with underscore
- Local var may have underscore
- qualified var may not have an underscore in first position
Access to non existing variables
- turn on —strict-mode
Access to class using upper case name/title
+= and -= have den deprecated
hyphens in names
ruby dsl

Functions in Puppet

Autoloaded from Modules
<modulepath>/<modulename>/functions/<func name>.pp
e.g. function min in module test
function test::min ($a, $b) { … }

Unfold (match all elements of an array)
$a = [1,2,3]
foo(*$a) # same as foo(1, 2, 3)

case $something {
  *$a: { # matches 1 or 2 or 3

$b = [10, *$a, 20] # creates [10, 1, 2, 3, 20]

Puppet Function API

new API in Puppet 4.x
in Puppet 3.x:
- functions can not be private
- are defined in Puppet::Parser::Functions scope
- no automatic type checking

In Puppet 3.x API:
- name
- type
- arity
- doc

In Puppet 4.x API:

fix numer of arguments:
Puppet::Functions.create_function(:max) do
  def max(x,y)
    x >= y ? x : y

flexible number of arguments:
  def myfunc (a, b, c, *d)

Argument validation via dispatch (choose the proper method to use)
  dispatch :min do
    param 'Numeric', :a
    param 'Numeric', :b

  dispatch :min_s do
    param 'String', :s1
    param 'String', :s2
  def min(x,y)
    x <= y ? x : y

  def min_s(x,y)
    cmp = (x.downcase <=> y.downcase)
    cmp <= 0 ? x : y