kafo 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of kafo might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 172038c701a1e259a865a0315bb5d31a41797420
4
- data.tar.gz: c526c08e0df34742fd03fdfc0cac5c99595eb13a
3
+ metadata.gz: 7361c36d1938a0cb6e0aef8e7ba478e23f8f4af0
4
+ data.tar.gz: 828ffbb4779539427b3b40b1cb81db900e08820c
5
5
  SHA512:
6
- metadata.gz: 2a1c8d58ec05bba52eb9f190a9d6743d154b45ccc39dd33fc1aa830302c8a011e8255a4f1bce76365986b9a504c7318bbd0781015b12120fbd088f984d551adc
7
- data.tar.gz: 51e160a1ee3329136b0c36ae7492384d39506b9a64db76b5e2dcd9269b4074f2a496f9b48b6b3a2a485b8da740b405fdb3c08bb11f361dd21bda8a3561aced6a
6
+ metadata.gz: 11cf281c119c97541a028f364681fc00f7d93b86cb53123cec742b6530412bdf417d5bfc0f9a433e1a0eaf4ecdda1f857752d913a8df40e3fb59cf4c4a9675de
7
+ data.tar.gz: 872579a93ddff382ce44d83973a6b0eb0971a5fd7adee80733b5b3284416246e00b17ec1907aa006557639e142f0484cac4cf4582b68df648986e02921b43e8e
data/README.md CHANGED
@@ -168,6 +168,40 @@ class foreman (
168
168
  }
169
169
  ```
170
170
 
171
+ You can separate your parameters into groups like this.
172
+
173
+ Example - separating parameters into groups:
174
+ ```puppet
175
+ # Manage your foreman server
176
+ #
177
+ # === Parameters:
178
+ #
179
+ # $foreman_url:: URL on which foreman is going to run
180
+ #
181
+ # === Advanced parameters:
182
+ #
183
+ # $foreman_port:: Foreman listens on this port
184
+ #
185
+ # ==== MySQL:
186
+ #
187
+ # $mysql_host:: MySQL server address
188
+ ```
189
+
190
+ When you run the installer with ```--help``` argument it displays only
191
+ parameters specified in ```=== Parameters:``` group. If you don't specify
192
+ any group all parameters will be considered as Basic and will be displayed.
193
+
194
+ If you run installer with ```--full-help``` you'll receive help of all
195
+ parameters divided into groups. Note that only headers that include word
196
+ parameters are considered as parameter groups. Other headers are ignored.
197
+ Also note that you can nest parameter groups and the child has precedence.
198
+ Help output does not take header level into account though.
199
+
200
+ So in previous example, each parameter would be printed in one group even
201
+ though MySQL is a child of Advanced parameter. All groups in help would be
202
+ prefixed with second level (==). The first level is always a module to which
203
+ particular parameter belongs.
204
+
171
205
  ## Argument types
172
206
 
173
207
  By default all arguments that are parsed from puppet are treated as string.
@@ -237,6 +271,125 @@ bin/foreman-installer --puppetmaster-environments=development --puppetmaster-env
237
271
  In interactive mode you'll be prompted for another value until you specify
238
272
  blank line.
239
273
 
274
+ ## Grouping in interactive mode
275
+
276
+ If your module has too much parameters you may find useful grouping. Every
277
+ block in your documentation (prefixed by header) forms a group. Unlike for
278
+ help, all block are used in interactive mode. Suppose you have following
279
+ example:
280
+
281
+ ```puppet
282
+ # Testing class
283
+ #
284
+ # == Parameters:
285
+ #
286
+ # $one:: number one
287
+ #
288
+ # == Advanced parameters:
289
+ #
290
+ # $two:: number two
291
+ #
292
+ # === Advanced A:
293
+ #
294
+ # $two_a:: 2_a
295
+ #
296
+ # === Advanced 2_b
297
+ #
298
+ # $two_b:: 2_b
299
+ #
300
+ # == Extra parameters:
301
+ #
302
+ # $three:: number three
303
+ ```
304
+
305
+ When you enter Testing class module in interactive mode you see parameters
306
+ from Basic group and options to configure parameters which belongs to rest
307
+ of groups on same level, in this case Advanced and Extra parameters.
308
+
309
+ ```
310
+ Module foreman configuration
311
+ 1. Enable/disable foreman module, current value: true
312
+ 2. Set one, current value: '1'
313
+ 3. Configure Advanced parameters
314
+ 4. Configure Extra parameters
315
+ 5. Back to main menu
316
+ ```
317
+
318
+ When you enter Extra paramaters, you see only $three and option to get back
319
+ to parent. In Advanced you see $two and two more subgroups - Advanced A and
320
+ Advanced B. When you enter these subgroups, you see their parameters of
321
+ course. Nesting is unlimited. Also there's no naming rule. Just notice that
322
+ the main group must be called `Parameters` and it's parameters are always
323
+ displayed on first level of module configuration.
324
+
325
+ ```
326
+ Group Extra parameters (of module foreman)
327
+ 1. Set two_b, current value: '2b'
328
+ 2. Back to parent menu
329
+ ```
330
+
331
+ If there's no primary group a new one is created for you and it does not have
332
+ any parameter. This mean when user enters module configuration he or she will
333
+ see only subgroups in menu (no parameters until a particular subgroup is entered).
334
+ If there is no group in documentation a new primary group is created and it
335
+ holds all module parameters (there are no subgroups in module configuration).
336
+
337
+ ## Conditional parameters in interactive mode
338
+
339
+ You can also define conditions to parameter and their groups. These conditions
340
+ are evaluated in interactive mode and based on the result they are displayed
341
+ to the user. You can use this for example to hide mysql_* parameters when
342
+ $db_type is not set 'mysql'. Let's look at following example
343
+
344
+ ```puppet
345
+ # Testing class
346
+ #
347
+ # == Parameters:
348
+ #
349
+ # $use_db:: use database?
350
+ # type:boolean
351
+ #
352
+ # == Database parameters: condition: $use_db
353
+ #
354
+ # $database_type:: mysql/sqlite
355
+ #
356
+ # === MySQL: condition: $database_type == 'mysql'
357
+ #
358
+ # $remote:: use remote connection
359
+ # type:boolean
360
+ # $host server to connect to
361
+ # condition: $remote
362
+ # $socket server to connect to
363
+ # condition: !$remote
364
+ ```
365
+
366
+ Here you can see we defined several conditions on group and parameter level.
367
+ You can write condition in ruby language. All dollar-prefixed words are be
368
+ substituted by value of a particular puppet parameter.
369
+
370
+ Note that conditions are combined using ```&&``` when you nest them. So these
371
+ are facts based on example:
372
+
373
+ * $database_type, $remote, $host, $socket are displayed only when $use_db is set to true
374
+ * $remote, $host, $socket are displayed only when $database_type is set to 'mysql'
375
+ * $host is displayed only if $remote is set to true, $socket is displayed otherwise
376
+
377
+ Here's explanation how conditions are constructed
378
+
379
+ ```
380
+ -----------------------------------------------------------------------------
381
+ | parameter name | resulting condition |
382
+ -----------------------------------------------------------------------------
383
+ | $use_db | true |
384
+ | $database_type | true && $use_db |
385
+ | $remote | true && $use_db && $database_type == 'mysql' |
386
+ | $host | true && $use_db && $database_type == 'mysql' && $remote |
387
+ | $socket | true && $use_db && $database_type == 'mysql' && !$remote |
388
+ -----------------------------------------------------------------------------
389
+ ```
390
+ As already said you can use whatever ruby code, so you could leverage e.g.
391
+ parentheses, &&, ||, !, and, or
392
+
240
393
  ## Custom modules and manifest names
241
394
 
242
395
  By default Kafo expects a common module structure. For example if you add
@@ -290,6 +443,45 @@ bin/foreman-installer --foreman-db-password=UNDEF
290
443
 
291
444
  It also works in interactive mode.
292
445
 
446
+ ## Hooks
447
+
448
+ You may need to add new features to the installer. Kafo provides simple hook
449
+ mechanism that allows you to run custom code just before and after the puppet
450
+ is ran. Let's assume we want to add --reset-foreman-db option to our
451
+ foreman-installer. We add following lines to generated installer script
452
+
453
+ ```ruby
454
+ require 'kafo/hooking'
455
+
456
+ # functions specific to foreman installer
457
+ KafoConfigure.app_option '--reset-foreman-db',
458
+ :flag, 'Drop foreman database first? You will lose all data!', :default => false
459
+
460
+ KafoConfigure.hooking.register_pre(:reset_db) do |kafo|
461
+ if kafo.config.app[:reset_foreman_db] && !kafo.config.app[:noop]
462
+ `which foreman-rake > /dev/null 2>&1`
463
+ if $?.success?
464
+ KafoConfigure.logger.info 'Dropping database!'
465
+ output = `foreman-rake db:drop 2>&1`
466
+ KafoConfigure.logger.debug output.to_s
467
+ unless $?.success?
468
+ KafoConfigure.logger.warn "Unable to drop DB, ignoring since it's not fatal, output was: '#{output}''"
469
+ end
470
+ else
471
+ KafoConfigure.logger.warn 'Foreman not installed yet, can not drop database!'
472
+ end
473
+ end
474
+ end
475
+ ```
476
+
477
+ Note that we can access other installer options using ```kafo.config.app```. Since ```kafo``` is
478
+ KafoConfigure instance, you can even access puppet params values. Last but not least you have
479
+ access to logger.
480
+
481
+ You can register as many hooks as you need. They are executed in unspecified order. Every hook
482
+ must have a unique name. In a very similar way you can register :post hooks that are executed
483
+ right after puppet run is over.
484
+
293
485
  ## Custom paths
294
486
 
295
487
  Usually when you package your installer you want to load files from specific
data/bin/kafo-configure CHANGED
@@ -1,9 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- # TODO cover with tests
4
- # TODO validations: "puppet master --compile <fqdn>" compiles a catalog for a given host but it uses the global manifest/modules rather than stdin.. but by specifying --manifestdir you could get it to read a site.pp that contains the "include kafo_configure"
5
-
6
3
  $LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'kafo'))
7
4
  require 'kafo_configure'
8
- result = KafoConfigure.run
5
+ result = Kafo::KafoConfigure.run
9
6
  exit result.nil? ? 0 : result.exit_code
@@ -1,4 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'ostruct'
2
4
  require 'clamp'
3
5
  require 'logging'
4
6
  require 'kafo/string_helper'
@@ -8,97 +10,119 @@ require 'configuration'
8
10
 
9
11
  KafoConfigure = OpenStruct.new
10
12
 
11
- class KafoExportParams < Clamp::Command
12
- TYPES = %w(md html)
13
+ module Kafo
14
+ class KafoExportParams < Clamp::Command
15
+ TYPES = %w(md html asciidoc)
13
16
 
14
- option ['-c', '--config'], 'FILE', 'Config file for which should we generate params',
15
- :required => true
17
+ option ['-c', '--config'], 'FILE', 'Config file for which should we generate params',
18
+ :required => true
16
19
 
17
- option ['-f', '--format'], 'FORMAT',
18
- 'Config file for which should we generate params', :default => 'md' do |format|
19
- format = format.downcase
20
- raise ArgumentError unless TYPES.include?(format)
21
- format
22
- end
20
+ option ['-f', '--format'], 'FORMAT',
21
+ 'Config file for which should we generate params', :default => 'md' do |format|
22
+ format = format.downcase
23
+ raise ArgumentError unless TYPES.include?(format)
24
+ format
25
+ end
23
26
 
24
- def execute
25
- c = Configuration.new(config, false)
26
- KafoConfigure.config = c
27
- KafoConfigure.root_dir = File.expand_path(c.app[:installer_dir])
27
+ def execute
28
+ c = Configuration.new(config, false)
29
+ KafoConfigure.config = c
30
+ KafoConfigure.root_dir = File.expand_path(c.app[:installer_dir])
28
31
 
29
- exporter = self.class.const_get(format.capitalize).new(c)
30
- exporter.print_out
31
- end
32
+ exporter = self.class.const_get(format.capitalize).new(c)
33
+ exporter.print_out
34
+ end
32
35
 
33
- class Html
34
- include StringHelper
36
+ class Html
37
+ include StringHelper
35
38
 
36
- def initialize(config)
37
- @config = config
38
- end
39
+ def initialize(config)
40
+ @config = config
41
+ end
39
42
 
40
- def print_out
41
- puts '<div id="installer-options">'
42
- puts ' <table class="table table-bordered table-condensed">'
43
- header
44
- puts ' <tbody>'
45
-
46
- @config.modules.each do |mod|
47
- mod.params.each do |param|
48
- puts ' <tr>'
49
- puts " <td>#{parametrize(param)}</td>"
50
- puts " <td>#{param.doc.join(' ')}</td>"
51
- puts ' </tr>'
43
+ def print_out
44
+ puts '<div id="installer-options">'
45
+ puts ' <table class="table table-bordered table-condensed">'
46
+ header
47
+ puts ' <tbody>'
48
+
49
+ @config.modules.sort.each do |mod|
50
+ mod.params.sort.each do |param|
51
+ puts ' <tr>'
52
+ puts " <td style='white-space:nowrap'>#{parametrize(param)}</td>"
53
+ puts " <td>#{param.doc.join(' ')}</td>"
54
+ puts ' </tr>'
55
+ end
52
56
  end
57
+
58
+ puts ' </tbody>'
59
+ puts ' </table>'
60
+ puts '</div>'
53
61
  end
54
62
 
55
- puts ' </tbody>'
56
- puts ' </table>'
57
- puts '</div>'
63
+ private
64
+
65
+ def header
66
+ puts ' <thead>'
67
+ puts ' <tr>'
68
+ puts ' <th>Option</th>'
69
+ puts ' <th>Description</th>'
70
+ puts ' </tr>'
71
+ puts ' </thead>'
72
+ end
58
73
  end
59
74
 
60
- private
75
+ class Asciidoc
76
+ include StringHelper
77
+
78
+ def initialize(config)
79
+ @config = config
80
+ end
61
81
 
62
- def header
63
- puts ' <thead>'
64
- puts ' <tr>'
65
- puts ' <th>Option</th>'
66
- puts ' <th>Description</th>'
67
- puts ' </tr>'
68
- puts ' </thead>'
82
+ def print_out
83
+ @config.modules.sort.each do |mod|
84
+ puts "Parameters for '#{mod}'\n:"
85
+ mod.params.sort.each do |param|
86
+ puts "#{parametrize(param)}::"
87
+ puts param.doc.join("\n")
88
+ puts "\n"
89
+ end
90
+ puts "\n"
91
+ end
92
+ end
69
93
  end
70
- end
71
94
 
72
- class Md
73
- include StringHelper
95
+ class Md
96
+ include StringHelper
74
97
 
75
- def initialize(config)
76
- @config = config
77
- @max = max_description_length
78
- end
98
+ def initialize(config)
99
+ @config = config
100
+ @max = max_description_length
101
+ end
79
102
 
80
- def print_out
81
- puts "| #{('Parameter name').ljust(40)} | #{'Description'.ljust(@max)} |"
82
- puts "| #{'-'*40} | #{'-' * @max} |"
83
- @config.modules.each do |mod|
84
- mod.params.each do |param|
85
- puts "| #{parametrize(param).ljust(40)} | #{param.doc.join(' ').ljust(@max)} |"
103
+ def print_out
104
+ puts "| #{('Parameter name').ljust(40)} | #{'Description'.ljust(@max)} |"
105
+ puts "| #{'-'*40} | #{'-' * @max} |"
106
+ @config.modules.sort.each do |mod|
107
+ mod.params.sort.each do |param|
108
+ puts "| #{parametrize(param).ljust(40)} | #{param.doc.join(' ').ljust(@max)} |"
109
+ end
86
110
  end
87
111
  end
88
- end
89
112
 
90
- private
113
+ private
91
114
 
92
- def header
93
- @header ||= "| #{'-'*40} | #{'-' * @max} |"
94
- end
115
+ def header
116
+ @header ||= "| #{'-'*40} | #{'-' * @max} |"
117
+ end
95
118
 
96
- def max_description_length
97
- doc_lengths = @config.modules.map { |mod| mod.params.map { |param| param.doc.join(' ').length } }.flatten
98
- doc_lengths << 52
99
- doc_lengths.max
119
+ def max_description_length
120
+ doc_lengths = @config.modules.map { |mod| mod.params.map { |param| param.doc.join(' ').length } }.flatten
121
+ doc_lengths << 52
122
+ doc_lengths.max
123
+ end
100
124
  end
101
125
  end
102
126
  end
103
127
 
104
- KafoExportParams.run
128
+ Kafo::KafoExportParams.run
data/bin/kafofy CHANGED
@@ -24,7 +24,7 @@ if ARGV.size > 0
24
24
  require 'rubygems'
25
25
  require 'kafo'
26
26
  CONFIG_FILE = "/etc/#{name}/#{name}.yaml"
27
- result = KafoConfigure.run
27
+ result = Kafo::KafoConfigure.run
28
28
  exit result.nil? ? 0 : result.exit_code
29
29
  EOS
30
30
  File.open(script_name, 'w') { |file| file.write(content) }
@@ -0,0 +1,25 @@
1
+ # encoding: UTF-8
2
+ module Kafo
3
+ class Condition
4
+ VARIABLE_RE = /(\$\w+)/
5
+
6
+ def initialize(expression, context = [])
7
+ @expression = expression
8
+ @context = context
9
+ end
10
+
11
+ def evaluate
12
+ !!eval(substitute(@expression))
13
+ end
14
+
15
+ private
16
+
17
+ def substitute(expression)
18
+ expression.gsub(VARIABLE_RE) do |variable|
19
+ param = @context.detect { |p| p.name == $1.tr('$','') }
20
+ raise ConditionError, "can't substitute #{$1}, unknown parameter with such name" if param.nil?
21
+ variable.gsub!($1, param.condition_value)
22
+ end
23
+ end
24
+ end
25
+ end