Project

General

Profile

Parameterized class development Ofavre analysis » History » Version 1

Olivier Favre, 06/27/2012 06:24 AM
ofavre: Thoughts on parameterized classes support

1 1 Olivier Favre
h1. Parameterized class development - Ofavre's analysis
2
3
h2. Puppet classes parameters and smart variables
4
5
h3. Making the smart-proxy return the parameters
6
7
Puppet classes parameters are given by the smart-proxy:
8
The current answer of smart-proxies are:
9
<pre>
10
[
11
  {
12
    "amodule::aclass" : 
13
    {
14
      "module" : "amodule",
15
      "name" : "aclass"
16
    }
17
  },
18
  ...
19
]
20
</pre>
21
I've extended it to give the extracted parameters, using the "@Puppet::Parser@":https://github.com/puppetlabs/puppet/blob/master/lib/puppet/parser:
22
<pre>
23
[
24
  {
25
    "amodule::aclass" : 
26
    {
27
      "module" : "amodule",
28
      "name" : "aclass",
29
      "params" : {}   # no parameters
30
    }
31
  },
32
  {
33
    "amodule::aparameterizedclass" : 
34
    {
35
      "module" : "amodule",
36
      "name" : "aparameterizedclass",
37
      "params" : {
38
        "mandatoryParam" : null,
39
        "optionalNumericParam" : "42",
40
        "optionalStringParam" : "\"foo\""
41
        "optionalConcatParam" : "company@$::hostname"
42
      }
43
    }
44
  },
45
  ...
46
]
47
</pre>
48
The values of the parameters are either @null@ if there is none, or the string representation of the @AST::Leaf@ (see "lib/puppet/parser/ast/leaf.rb":https://github.com/puppetlabs/puppet/blob/master/lib/puppet/parser/ast/leaf.rb).
49
Its likely not perfect yet.
50
51
h3. Storing the parameters in the db
52
53
We can do multiple things to represent the parameters in the database, but we need to know what we want to do with them before choosing the right representation.
54
We want to:
55
* Be able to sync the db when importing puppet classes.
56
  This means addition, deletion of puppet classes __and__ parameters.
57
* Control the value of the parameter using a smart-variable, with a potentially complex set of matchers.
58
  We never want to loose this complex configuration.
59
60
So we can directly:
61
* Create a new smart-variable for each new {puppetclass, parameter} couple on importing
62
* But we need not to delete a smart-variable for an obsolete {puppetclass, parameter} couple.
63
  (We could do it automatically if and only if the description and default value were left intact, and there is no matchers).
64
65
But this will not be very practical:
66
* New mandatory parameters would need their smart-variable configured, or it will generate errors.
67
  Hence we need to make this visible somehow.
68
* An old smart-variable, no longer attached to a valid {puppetclass, parameter} couple cannot easily be reassigned to a new, valid couple, without erasing an existing (automatically created) smart-variable.
69
  This makes it __impractical__ for the user interface. __But note that it__ is __feasible.__
70
* Note that puppetclass or parameter renames __cannot__, generally speaking, be detected. Hence we can only to add/delete.
71
72
So we would need to separate puppetclass parameters from the eventual smart-variables that will control them.
73
That way:
74
* We can show the obsolete smart-variables (no longer bound to a value {puppetclass, parameter} couple).
75
* We can show uncontrolled parameters: puppetclass parameters without a bound smart-variable.
76
  We can visually separate mandatory uncontrolled parameters from optional ones (which have a default value, hence won't raise errors).
77
* Provide a way to rebind an obsolete smart-variable to a yet unbound {puppetclass, parameter} couple.
78
* Provide a way to create a smart-variable for an uncontrolled parameter, presenting a form for the necessary configuration.
79
* Additionally provide an easy way to automatically create a noop smart-variable for an optional parameter.
80
81
So we need to easily see the mapping between smart-variables and puppetclasses parameters.
82
We can either:
83
* Store a serialized hash into a new parameters column of the puppetclasses table.
84
  But this would mean parsing them all to see which are not controlled by a smart-variable.
85
* Create an entry in the parameters __table__ of type @PuppetClassParameter@, filling the name and value from the smart-proxy's output and binding it to the corresponding puppetclass.
86
87
I favor the second solution. Do you see any other?
88
89
h2. Supporting non uniform classes across environments
90
91
In puppet, classes are totally separate from an environment to another.
92
Hence it is possible that classes have the same name in two environments while having different parameters.
93
Currently puppetclasses are linked to environments with an __n-n__ relation.
94
This need to be changed to a __n-1__ relation (envs. having many classes, a class belonging to a single env.).
95
96
However, in order to reduce redundancy in the configuration, we may need to bind a smart-variable to multiple environments, ie. to same-named puppet classes across different environments.