kafo 0.3.17 → 0.4.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 +4 -4
- data/README.md +79 -6
- data/bin/kafofy +49 -13
- data/config/kafo.yaml.example +5 -1
- data/lib/kafo/color_scheme.rb +63 -0
- data/lib/kafo/configuration.rb +14 -17
- data/lib/kafo/exceptions.rb +0 -6
- data/lib/kafo/help_builders/base.rb +8 -1
- data/lib/kafo/kafo_configure.rb +14 -27
- data/lib/kafo/puppet_command.rb +1 -1
- data/lib/kafo/puppet_module.rb +2 -2
- data/lib/kafo/version.rb +1 -1
- data/lib/kafo/wizard.rb +13 -30
- data/modules/kafo_configure/lib/puppet/parser/functions/dump_values.rb +2 -5
- metadata +23 -10
- data/lib/kafo/doc_parser.rb +0 -129
- data/lib/kafo/puppet_module_parser.rb +0 -78
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cec1cec4f897c23ed85f473caca2b1e9fc7feea7
|
4
|
+
data.tar.gz: 5cd2bb6b161e2fdbf71e42425df0179cad53226b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ad300f9ee839582ea0b81b26861f75347280f9ab746bcf7c70130141c430f7dcf5da98e62671912053c5bb4e0fe98b4feb8020af63468288dbee5681909643e7
|
7
|
+
data.tar.gz: 7ea593a6fda67a94dbb9daaa88ac9138086e974d7fec9c62737c76145445334e8ef783dae6ffab8a99f3253525e4f45bed55640a9b1a9e4d8c81aa5d6d79ae35
|
data/README.md
CHANGED
@@ -62,28 +62,51 @@ Now we run ```kafofy``` script which will prepare directory structure and
|
|
62
62
|
optionally create a bin script according to first parameter.
|
63
63
|
|
64
64
|
```bash
|
65
|
-
kafofy foreman-installer
|
65
|
+
kafofy -n foreman-installer
|
66
66
|
```
|
67
67
|
|
68
68
|
You can see that it created modules directory where your puppet modules
|
69
|
-
should live. It also created config and bin directories. If you
|
70
|
-
argument (foreman-installer in this case) a script in
|
69
|
+
should live. It also created config and bin directories. If you specify
|
70
|
+
argument --name (or -n for short, foreman-installer in this case) a script in
|
71
|
+
bin is created.
|
72
|
+
|
71
73
|
It's the script you can use to run installer. If you did not specify any
|
72
|
-
you can run your installer by ```kafo-configure``` which is
|
74
|
+
you can run your installer by ```kafo-configure``` which is the default.
|
73
75
|
All configuration related files are to be found in config directory.
|
74
76
|
|
77
|
+
You can supply custom locations for you configuration and answers files using
|
78
|
+
options:
|
79
|
+
|
80
|
+
```kafofy --help
|
81
|
+
Usage: kafofy [options]
|
82
|
+
-a, --answer_file FILE location of the answer file
|
83
|
+
-c, --config_file FILE location of the configuration file
|
84
|
+
-n, --name NAME your installer name
|
85
|
+
```
|
86
|
+
|
87
|
+
Configuration file will be created by default template. It's the configuration
|
88
|
+
of you installer (so you can setup log level, path to puppet modules etc).
|
89
|
+
On the other hand, answer file must be created manually. Answer file defines
|
90
|
+
which modules should be used and hold all values for puppet class parameters.
|
91
|
+
|
92
|
+
|
75
93
|
So for example to install foreman you want to
|
76
94
|
```bash
|
77
95
|
cd foreman-installer/modules
|
78
96
|
git clone https://github.com/theforeman/puppet-foreman/ foreman
|
79
97
|
```
|
80
|
-
|
98
|
+
You must also download any dependant modules.
|
81
99
|
Then you need to tell kafo it's going to use foreman module.
|
82
100
|
```bash
|
83
101
|
cd ..
|
84
102
|
echo "foreman: true" > config/answers.yaml
|
85
103
|
```
|
86
|
-
|
104
|
+
|
105
|
+
Alternatively you can use librarian-puppet project to manage all deps for you.
|
106
|
+
You just create a Puppetfile and call librarian to install your modules. See
|
107
|
+
https://github.com/rodjek/librarian-puppet for more details.
|
108
|
+
|
109
|
+
When you have your modules in-place, fire the installer with -h argument
|
87
110
|
```bash
|
88
111
|
bin/foreman-installer -h
|
89
112
|
```
|
@@ -501,6 +524,56 @@ You can register as many hooks as you need. They are executed in unspecified ord
|
|
501
524
|
must have a unique name. In a very similar way you can register :post hooks that are executed
|
502
525
|
right after puppet run is over.
|
503
526
|
|
527
|
+
## Colors
|
528
|
+
|
529
|
+
Everybody loves colors right? In case you don't you can disable them using ```--no-colors```
|
530
|
+
argument or disallow them in installer config file (search for ```colors:``` key and set
|
531
|
+
it to false). If you don't touch this setting, kafo will try to detect whether colors
|
532
|
+
are supported and will enable/disable it accordingly.
|
533
|
+
|
534
|
+
Kafo supports two sets of colors, one for terminals with bright and one for dark backround.
|
535
|
+
You can specify your installer default scheme in installer config file (```color_of_background```
|
536
|
+
key). Or user can override this default setting by ```--color-of-background``` argument.
|
537
|
+
Possible values are ```dark``` and ```bright```.
|
538
|
+
|
539
|
+
You can reuse kafo color schema in your custom hooks (so you can reuse dark/bright logic).
|
540
|
+
Look at this example in bin/foreman-installer
|
541
|
+
```ruby
|
542
|
+
#!/usr/bin/env ruby
|
543
|
+
|
544
|
+
# Run the install
|
545
|
+
@result = Kafo::KafoConfigure.run
|
546
|
+
exit 0 if @result.nil? # --help invocation
|
547
|
+
|
548
|
+
# Puppet status codes say 0 for unchanged, 2 for changed succesfully
|
549
|
+
if [0,2].include?(@result.exit_code)
|
550
|
+
say " <%= color('Success!', :good) %>"
|
551
|
+
|
552
|
+
if module_enabled? 'foreman'
|
553
|
+
say " * <%= color('Foreman', :info) %> is running at <%= color('#{get_param('foreman','foreman_url')}', :info) %>"
|
554
|
+
say " Default credentials are '<%= color('admin:changeme', :info) %>'"e
|
555
|
+
end
|
556
|
+
end
|
557
|
+
```
|
558
|
+
|
559
|
+
As you can see you can use HighLine helpers (e.g. say) with colors. Look at kafo/color_schema.rb for
|
560
|
+
supported color identifiers. We can guarantee that there will always be at least :good, :bad, :info.
|
561
|
+
|
562
|
+
Methods like module_enabled? and get_param are just helpers defined in the same file. If you find
|
563
|
+
them useful, here's the definition
|
564
|
+
|
565
|
+
```ruby
|
566
|
+
def module_enabled?(name)
|
567
|
+
mod = @result.module(name)
|
568
|
+
return false if mod.nil?
|
569
|
+
mod.enabled?
|
570
|
+
end
|
571
|
+
|
572
|
+
def get_param(mod, name)
|
573
|
+
@result.param(mod, name).value
|
574
|
+
end
|
575
|
+
```
|
576
|
+
|
504
577
|
## Custom paths
|
505
578
|
|
506
579
|
Usually when you package your installer you want to load files from specific
|
data/bin/kafofy
CHANGED
@@ -1,6 +1,33 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
+
$LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
|
4
|
+
|
3
5
|
require 'fileutils'
|
6
|
+
require 'optparse'
|
7
|
+
require 'yaml'
|
8
|
+
require 'kafo/configuration'
|
9
|
+
|
10
|
+
|
11
|
+
# Option Parsing
|
12
|
+
options = {}
|
13
|
+
OptionParser.new do |opts|
|
14
|
+
opts.banner = "Usage: kafofy"
|
15
|
+
options[:answer_file] = './config/answers.yaml'
|
16
|
+
opts.on("-a", "--answer_file FILE", "location of the answer file") do |answer_file|
|
17
|
+
options[:answer_file] = answer_file
|
18
|
+
end
|
19
|
+
opts.on("-c", "--config_file FILE", "location of the configuration file") do |config_file|
|
20
|
+
options[:config_file] = config_file
|
21
|
+
end
|
22
|
+
opts.on("-n", "--name NAME", "installer name") do |name|
|
23
|
+
options[:name] = name
|
24
|
+
end
|
25
|
+
end.parse!
|
26
|
+
|
27
|
+
config = Kafo::Configuration::DEFAULT
|
28
|
+
options[:answer_file] ||= config[:answer_file]
|
29
|
+
options[:name] ||= "kafo-configure"
|
30
|
+
options[:config_file] ||= "./config/#{options[:name]}.yaml"
|
4
31
|
|
5
32
|
# Create directory structure
|
6
33
|
%w(bin config modules).each do |dir|
|
@@ -13,27 +40,36 @@ src = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
|
13
40
|
FileUtils.cp src + "/config/#{file}", 'config/'
|
14
41
|
end
|
15
42
|
|
16
|
-
|
17
|
-
#
|
18
|
-
if
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
43
|
+
# Create default config file
|
44
|
+
puts "using #{options[:config_file]} as default config file"
|
45
|
+
if !File.exists?(options[:config_file])
|
46
|
+
puts "... creating config file #{options[:config_file]}"
|
47
|
+
FileUtils.touch options[:config_file]
|
48
|
+
File.chmod 0600, options[:config_file]
|
49
|
+
FileUtils.cp('config/kafo.yaml.example', options[:config_file])
|
50
|
+
if options[:answer_file]
|
51
|
+
`sed -i 's/^# :answer_file.*$/:answer_file: #{options[:answer_file].gsub('/', '\/')}/' #{options[:config_file]}`
|
52
|
+
`sed -i 's/^# :name.*$/:name: #{options[:name]}/' #{options[:config_file]}`
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Installer script
|
57
|
+
script_name = "bin/#{options[:name]}"
|
58
|
+
puts "... creating #{script_name}"
|
59
|
+
content = <<EOS
|
23
60
|
#!/usr/bin/env ruby
|
24
61
|
require 'rubygems'
|
62
|
+
CONFIG_FILE = '#{options[:config_file]}'
|
25
63
|
require 'kafo'
|
26
|
-
CONFIG_FILE = "/etc/#{name}/#{name}.yaml"
|
27
64
|
result = Kafo::KafoConfigure.run
|
28
65
|
exit result.nil? ? 0 : result.exit_code
|
29
66
|
EOS
|
30
|
-
|
31
|
-
|
32
|
-
end
|
67
|
+
File.open(script_name, 'w') { |file| file.write(content) }
|
68
|
+
FileUtils.chmod 0755, script_name
|
33
69
|
|
34
70
|
puts "Your directory was kafofied"
|
35
71
|
|
36
72
|
puts "Now you should:"
|
37
73
|
puts " 1. upload your puppet modules to modules directory (you can use librarian-puppet project)"
|
38
|
-
puts " 2. create default
|
39
|
-
puts " 3. run #{script_name}"
|
74
|
+
puts " 2. create default #{options[:answer_file]} or modify #{options[:config_file]} to load another answer file"
|
75
|
+
puts " 3. run #{script_name} to install your modules"
|
data/config/kafo.yaml.example
CHANGED
@@ -6,13 +6,17 @@
|
|
6
6
|
# Your project name
|
7
7
|
# :name: Kafo
|
8
8
|
# Path to answer file, if the file does not exist a $pwd/config/answers.yaml is used as a fallback
|
9
|
-
# :answer_file: /etc/kafo/
|
9
|
+
# :answer_file: /etc/kafo/answers.yaml
|
10
10
|
# Custom installer path
|
11
11
|
# :installer_dir: /usr/share/kafo/
|
12
12
|
# Uncomment if you want to load puppet modules from a specific path, $pwd/modules is used by default
|
13
13
|
# :modules_dir: /usr/share/kafo/modules
|
14
14
|
# Similar as modules_dir but for kafo internal modules, leave nil if you don't need to change it
|
15
15
|
# :kafo_modules_dir:
|
16
|
+
# Enable colors? If you don't touch this, we'll autodetect terminal capabilities
|
17
|
+
# :colors: true
|
18
|
+
# Color scheme, we support :bright and :dark (first is better for white background, dark for black background)
|
19
|
+
# :color_of_background: :dark
|
16
20
|
|
17
21
|
## Kafo tuning, customization of core functionality
|
18
22
|
# :no_prefix: false
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'highline/import'
|
2
|
+
|
3
|
+
module Kafo
|
4
|
+
class ColorScheme
|
5
|
+
def initialize(config)
|
6
|
+
@config = config
|
7
|
+
end
|
8
|
+
|
9
|
+
def setup
|
10
|
+
if @config.app[:colors]
|
11
|
+
HighLine.color_scheme = build_color_scheme
|
12
|
+
HighLine.use_color = true
|
13
|
+
else
|
14
|
+
HighLine.use_color = false
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def build_color_scheme
|
21
|
+
HighLine::ColorScheme.new do |cs|
|
22
|
+
color_hash.keys.each do |key|
|
23
|
+
cs[key] = color_hash[key]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def color_hash
|
29
|
+
@color_hash ||= {
|
30
|
+
:headline => build_color(:yellow),
|
31
|
+
:horizontal_line => build_color(:white),
|
32
|
+
:important => build_color(:white),
|
33
|
+
:question => build_color(:green),
|
34
|
+
:info => build_color(:cyan),
|
35
|
+
:cancel => build_color(:red),
|
36
|
+
:run => build_color(:green),
|
37
|
+
|
38
|
+
:bad => build_color(:red),
|
39
|
+
:good => build_color(:green),
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
def build_color(color)
|
44
|
+
bright = @config.app[:color_of_background].to_s == 'bright'
|
45
|
+
color = convert_bright_to_dark(color) if bright
|
46
|
+
|
47
|
+
attributes = [ color ]
|
48
|
+
attributes.unshift :bold unless bright
|
49
|
+
attributes
|
50
|
+
end
|
51
|
+
|
52
|
+
def convert_bright_to_dark(color)
|
53
|
+
case color
|
54
|
+
when :white
|
55
|
+
:black
|
56
|
+
when :cyan
|
57
|
+
:blue
|
58
|
+
else
|
59
|
+
color
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
data/lib/kafo/configuration.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
require 'yaml'
|
3
|
-
require 'tmpdir'
|
4
3
|
require 'kafo/puppet_module'
|
5
4
|
require 'kafo/password_manager'
|
6
5
|
|
@@ -13,16 +12,17 @@ module Kafo
|
|
13
12
|
end
|
14
13
|
|
15
14
|
DEFAULT = {
|
16
|
-
:log_dir
|
17
|
-
:log_name
|
18
|
-
:log_level
|
19
|
-
:no_prefix
|
20
|
-
:mapping
|
21
|
-
:answer_file
|
22
|
-
:installer_dir
|
23
|
-
:modules_dir
|
24
|
-
:default_values_dir
|
25
|
-
:colors
|
15
|
+
:log_dir => '/var/log/kafo',
|
16
|
+
:log_name => 'configuration.log',
|
17
|
+
:log_level => 'info',
|
18
|
+
:no_prefix => false,
|
19
|
+
:mapping => {},
|
20
|
+
:answer_file => './config/answers.yaml',
|
21
|
+
:installer_dir => '.',
|
22
|
+
:modules_dir => './modules',
|
23
|
+
:default_values_dir => '/tmp',
|
24
|
+
:colors => Configuration.colors_possible?,
|
25
|
+
:color_of_background => :dark
|
26
26
|
}
|
27
27
|
|
28
28
|
def initialize(file, persist = true)
|
@@ -35,7 +35,7 @@ module Kafo
|
|
35
35
|
begin
|
36
36
|
@data = YAML.load_file(@answer_file)
|
37
37
|
rescue Errno::ENOENT => e
|
38
|
-
puts "No
|
38
|
+
puts "No answer file at #{@answer_file} found, can not continue"
|
39
39
|
KafoConfigure.exit(:no_answer_file)
|
40
40
|
end
|
41
41
|
|
@@ -75,11 +75,8 @@ module Kafo
|
|
75
75
|
|
76
76
|
def params_default_values
|
77
77
|
@params_default_values ||= begin
|
78
|
-
@logger.debug "Creating tmp dir within #{app[:default_values_dir]}..."
|
79
|
-
temp_dir = Dir.mktmpdir(nil, app[:default_values_dir])
|
80
|
-
KafoConfigure.register_cleanup_path temp_dir
|
81
78
|
@logger.info "Parsing default values from puppet modules..."
|
82
|
-
command = PuppetCommand.new("
|
79
|
+
command = PuppetCommand.new("#{includes} dump_values(#{params})").append('2>&1').command
|
83
80
|
@logger.debug `#{command}`
|
84
81
|
unless $?.exitstatus == 0
|
85
82
|
log = app[:log_dir] + '/' + app[:log_name]
|
@@ -88,7 +85,7 @@ module Kafo
|
|
88
85
|
KafoConfigure.exit(:defaults_error)
|
89
86
|
end
|
90
87
|
@logger.info "... finished"
|
91
|
-
YAML.load_file(File.join(
|
88
|
+
YAML.load_file(File.join(KafoConfigure.config.app[:default_values_dir], 'default_values.yaml'))
|
92
89
|
end
|
93
90
|
end
|
94
91
|
|
data/lib/kafo/exceptions.rb
CHANGED
@@ -19,7 +19,7 @@ module Kafo
|
|
19
19
|
puts "\n#{heading}:"
|
20
20
|
|
21
21
|
data = by_module(items)
|
22
|
-
data.
|
22
|
+
sorted_keys(data).each do |section|
|
23
23
|
if section == 'Generic'
|
24
24
|
add_list(header(1, section), data[section])
|
25
25
|
else
|
@@ -33,6 +33,13 @@ module Kafo
|
|
33
33
|
|
34
34
|
private
|
35
35
|
|
36
|
+
# sorts modules by name with leaving Generic as first one
|
37
|
+
def sorted_keys(modules_hash)
|
38
|
+
keys = modules_hash.keys
|
39
|
+
keys.reject! { |k| k == DEFAULT_MODULE_NAME }
|
40
|
+
[ DEFAULT_MODULE_NAME ] + keys.sort
|
41
|
+
end
|
42
|
+
|
36
43
|
def add_module(name, items)
|
37
44
|
raise NotImplementedError, 'add module not defined'
|
38
45
|
end
|
data/lib/kafo/kafo_configure.rb
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
# encoding: UTF-8
|
2
|
-
|
2
|
+
|
3
|
+
# First of all we have to store ENV variable, requiring facter can override them
|
4
|
+
module Kafo
|
5
|
+
module ENV
|
6
|
+
LANG = ::ENV['LANG']
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
3
10
|
require 'pty'
|
4
11
|
require 'clamp'
|
5
12
|
require 'kafo/exceptions'
|
@@ -17,15 +24,12 @@ module Kafo
|
|
17
24
|
class KafoConfigure < Clamp::Command
|
18
25
|
include StringHelper
|
19
26
|
|
27
|
+
|
20
28
|
class << self
|
21
29
|
attr_accessor :config, :root_dir, :config_file, :gem_root, :temp_config_file,
|
22
30
|
:modules_dir, :kafo_modules_dir, :verbose, :app_options, :logger
|
23
31
|
attr_writer :hooking
|
24
32
|
|
25
|
-
def cleanup_paths
|
26
|
-
@cleanup_paths ||= []
|
27
|
-
end
|
28
|
-
|
29
33
|
def hooking
|
30
34
|
@hooking ||= Hooking.new
|
31
35
|
end
|
@@ -51,6 +55,7 @@ module Kafo
|
|
51
55
|
parse clamp_app_arguments
|
52
56
|
parse_app_arguments
|
53
57
|
Logger.setup
|
58
|
+
ColorScheme.new(config).setup
|
54
59
|
|
55
60
|
set_parameters # here the params gets parsed and we need app config populated
|
56
61
|
set_options
|
@@ -108,7 +113,6 @@ module Kafo
|
|
108
113
|
end
|
109
114
|
|
110
115
|
def self.exit(code)
|
111
|
-
cleanup
|
112
116
|
@exit_code = translate_exit_code(code)
|
113
117
|
throw :exit
|
114
118
|
end
|
@@ -132,26 +136,6 @@ module Kafo
|
|
132
136
|
end
|
133
137
|
end
|
134
138
|
|
135
|
-
def self.cleanup
|
136
|
-
# make sure default values are removed from /tmp
|
137
|
-
(self.cleanup_paths + ['/tmp/default_values.yaml']).each do |file|
|
138
|
-
logger.debug "Cleaning #{file}"
|
139
|
-
FileUtils.rm_rf(file)
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
def self.register_cleanup_path(path)
|
144
|
-
self.cleanup_paths<< path
|
145
|
-
end
|
146
|
-
|
147
|
-
def register_cleanup_path(path)
|
148
|
-
self.class.register_cleanup_path(path)
|
149
|
-
end
|
150
|
-
|
151
|
-
def cleanup_paths
|
152
|
-
self.class.cleanup_paths
|
153
|
-
end
|
154
|
-
|
155
139
|
def help
|
156
140
|
self.class.help(invocation_path, self)
|
157
141
|
end
|
@@ -171,7 +155,7 @@ module Kafo
|
|
171
155
|
|
172
156
|
def params
|
173
157
|
@params ||= modules.map(&:params).flatten
|
174
|
-
rescue ModuleName => e
|
158
|
+
rescue KafoParsers::ModuleName => e
|
175
159
|
puts e
|
176
160
|
exit(:unknown_module)
|
177
161
|
end
|
@@ -210,6 +194,8 @@ module Kafo
|
|
210
194
|
def set_app_options
|
211
195
|
self.class.app_option ['--[no-]colors'], :flag, 'Use color output on STDOUT',
|
212
196
|
:default => !!config.app[:colors]
|
197
|
+
self.class.app_option ['--color-of-background'], 'COLOR', 'Your terminal background is :bright or :dark',
|
198
|
+
:default => config.app[:color_of_background]
|
213
199
|
self.class.app_option ['-d', '--dont-save-answers'], :flag, 'Skip saving answers to answers.yaml?',
|
214
200
|
:default => !!config.app[:dont_save_answers]
|
215
201
|
self.class.app_option '--ignore-undocumented', :flag, 'Ignore inconsistent parameter documentation',
|
@@ -380,6 +366,7 @@ module Kafo
|
|
380
366
|
def config_file
|
381
367
|
return CONFIG_FILE if defined?(CONFIG_FILE) && File.exists?(CONFIG_FILE)
|
382
368
|
return '/etc/kafo/kafo.yaml' if File.exists?('/etc/kafo/kafo.yaml')
|
369
|
+
return "#{::RbConfig::CONFIG['sysconfdir']}/kafo/kafo.yaml" if File.exists?("#{::RbConfig::CONFIG['sysconfdir']}/kafo/kafo.yaml")
|
383
370
|
File.join(Dir.pwd, 'config', 'kafo.yaml')
|
384
371
|
end
|
385
372
|
|
data/lib/kafo/puppet_command.rb
CHANGED
@@ -23,7 +23,7 @@ module Kafo
|
|
23
23
|
result = [
|
24
24
|
"echo '$kafo_config_file=\"#{KafoConfigure.config_file}\" #{custom_answer_file} #{add_progress} #{@command}'",
|
25
25
|
'|',
|
26
|
-
"RUBYLIB=#{["#{KafoConfigure.gem_root}/modules", ENV['RUBYLIB']].join(File::PATH_SEPARATOR)}",
|
26
|
+
"RUBYLIB=#{["#{KafoConfigure.gem_root}/modules", ::ENV['RUBYLIB']].join(File::PATH_SEPARATOR)}",
|
27
27
|
"puppet apply #{@options.join(' ')} #{@suffix}",
|
28
28
|
].join(' ')
|
29
29
|
@logger.debug result
|
data/lib/kafo/puppet_module.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
require 'kafo/param'
|
3
3
|
require 'kafo/param_builder'
|
4
|
-
require '
|
4
|
+
require 'kafo_parsers/puppet_module_parser'
|
5
5
|
require 'kafo/validator'
|
6
6
|
|
7
7
|
module Kafo
|
@@ -11,7 +11,7 @@ module Kafo
|
|
11
11
|
attr_reader :name, :identifier, :params, :dir_name, :class_name, :manifest_name, :manifest_path,
|
12
12
|
:groups
|
13
13
|
|
14
|
-
def initialize(identifier, parser = PuppetModuleParser)
|
14
|
+
def initialize(identifier, parser = KafoParsers::PuppetModuleParser)
|
15
15
|
@identifier = identifier
|
16
16
|
@name = get_name
|
17
17
|
@dir_name = get_dir_name
|
data/lib/kafo/version.rb
CHANGED
data/lib/kafo/wizard.rb
CHANGED
@@ -1,15 +1,22 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
require 'highline/import'
|
3
|
+
require 'kafo/color_scheme'
|
3
4
|
require 'yaml'
|
4
5
|
|
5
6
|
module Kafo
|
6
7
|
class Wizard
|
8
|
+
def self.utf_support?
|
9
|
+
Kafo::ENV::LANG =~ /UTF-8\z/
|
10
|
+
end
|
11
|
+
|
12
|
+
OK = utf_support? ? '✓' : 'y'
|
13
|
+
NO = utf_support? ? '✗' : 'n'
|
14
|
+
|
7
15
|
def initialize(kafo)
|
8
16
|
@kafo = kafo
|
9
17
|
@config = kafo.config
|
10
18
|
@name = @config.app[:name] || 'Kafo'
|
11
19
|
setup_terminal
|
12
|
-
setup_colors
|
13
20
|
end
|
14
21
|
|
15
22
|
def run
|
@@ -39,8 +46,10 @@ END
|
|
39
46
|
say("\n" + HighLine.color('Main Config Menu', :headline))
|
40
47
|
choose do |menu|
|
41
48
|
menu.prompt = 'Choose an option from the menu... '
|
49
|
+
menu.select_by = :index
|
50
|
+
|
42
51
|
@config.modules.each do |mod|
|
43
|
-
menu.choice "[#{mod.enabled? ? HighLine.color(
|
52
|
+
menu.choice "[#{mod.enabled? ? HighLine.color(OK, :run) : HighLine.color(NO, :cancel)}] Configure #{mod.name}" do
|
44
53
|
configure_module(mod)
|
45
54
|
end
|
46
55
|
end
|
@@ -69,6 +78,8 @@ END
|
|
69
78
|
say("\n" + HighLine.color("Module #{mod.name} configuration", :headline))
|
70
79
|
choose do |menu|
|
71
80
|
menu.prompt = 'Choose an option from the menu... '
|
81
|
+
menu.select_by = :index
|
82
|
+
|
72
83
|
menu.choice("Enable/disable #{mod.name} module, current value: #{HighLine.color(mod.enabled?.to_s, :info)}") { turn_module(mod) }
|
73
84
|
if mod.enabled?
|
74
85
|
render_params(mod.primary_parameter_group.params, menu)
|
@@ -149,33 +160,5 @@ END
|
|
149
160
|
$terminal.wrap_at = data.first > 80 ? 80 : data.first if data.first
|
150
161
|
$terminal.page_at = data.last if data.last
|
151
162
|
end
|
152
|
-
|
153
|
-
def color_hash
|
154
|
-
@color_hash ||= {
|
155
|
-
:headline => [:bold, :yellow, :on_black],
|
156
|
-
:horizontal_line => [:bold, :white, :on_black],
|
157
|
-
:important => [:bold, :white, :on_black],
|
158
|
-
:question => [:bold, :green, :on_black],
|
159
|
-
:info => [:bold, :cyan, :on_black],
|
160
|
-
:cancel => [:bold, :red, :on_black],
|
161
|
-
:run => [:bold, :green, :on_black],
|
162
|
-
}
|
163
|
-
end
|
164
|
-
|
165
|
-
# setup colour scheme for prompts
|
166
|
-
def setup_colors
|
167
|
-
colors = HighLine::ColorScheme.new do |cs|
|
168
|
-
color_hash.keys.each do |key|
|
169
|
-
cs[key] = color_hash[key]
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
|
-
nocolors = HighLine::ColorScheme.new do |cs|
|
174
|
-
color_hash.keys.each { |k| cs[k.to_sym] = [] }
|
175
|
-
end
|
176
|
-
|
177
|
-
HighLine.color_scheme = @config.app[:colors] ? colors : nocolors
|
178
|
-
end
|
179
|
-
|
180
163
|
end
|
181
164
|
end
|
@@ -9,10 +9,7 @@ module Puppet::Parser::Functions
|
|
9
9
|
[arg, found_value.nil? ? arg : found_value]
|
10
10
|
end
|
11
11
|
data = Hash[data]
|
12
|
-
|
13
|
-
dump_dir
|
14
|
-
file_name = "#{dump_dir}/default_values.yaml"
|
15
|
-
|
16
|
-
File.open(file_name, File::WRONLY|File::CREAT|File::EXCL, 0600) { |file| file.write(YAML.dump(data)) }
|
12
|
+
dump_dir = YAML.load_file(lookupvar('kafo_config_file'))[:default_values_dir]
|
13
|
+
File.open("#{dump_dir}/default_values.yaml", 'w') { |file| file.write(YAML.dump(data)) }
|
17
14
|
end
|
18
15
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kafo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marek Hulan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-03-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - '>='
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: kafo_parsers
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: minitest
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -81,7 +95,7 @@ dependencies:
|
|
81
95
|
- !ruby/object:Gem::Version
|
82
96
|
version: '0'
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
98
|
+
name: kafo_parsers
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
86
100
|
requirements:
|
87
101
|
- - '>='
|
@@ -95,19 +109,19 @@ dependencies:
|
|
95
109
|
- !ruby/object:Gem::Version
|
96
110
|
version: '0'
|
97
111
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
112
|
+
name: puppet
|
99
113
|
requirement: !ruby/object:Gem::Requirement
|
100
114
|
requirements:
|
101
115
|
- - '>='
|
102
116
|
- !ruby/object:Gem::Version
|
103
|
-
version:
|
117
|
+
version: '0'
|
104
118
|
type: :runtime
|
105
119
|
prerelease: false
|
106
120
|
version_requirements: !ruby/object:Gem::Requirement
|
107
121
|
requirements:
|
108
122
|
- - '>='
|
109
123
|
- !ruby/object:Gem::Version
|
110
|
-
version:
|
124
|
+
version: '0'
|
111
125
|
- !ruby/object:Gem::Dependency
|
112
126
|
name: logging
|
113
127
|
requirement: !ruby/object:Gem::Requirement
|
@@ -142,14 +156,14 @@ dependencies:
|
|
142
156
|
requirements:
|
143
157
|
- - '>='
|
144
158
|
- !ruby/object:Gem::Version
|
145
|
-
version:
|
159
|
+
version: 1.6.21
|
146
160
|
type: :runtime
|
147
161
|
prerelease: false
|
148
162
|
version_requirements: !ruby/object:Gem::Requirement
|
149
163
|
requirements:
|
150
164
|
- - '>='
|
151
165
|
- !ruby/object:Gem::Version
|
152
|
-
version:
|
166
|
+
version: 1.6.21
|
153
167
|
- !ruby/object:Gem::Dependency
|
154
168
|
name: powerbar
|
155
169
|
requirement: !ruby/object:Gem::Requirement
|
@@ -181,8 +195,6 @@ files:
|
|
181
195
|
- config/config_header.txt
|
182
196
|
- lib/kafo/condition.rb
|
183
197
|
- lib/kafo/puppet_module.rb
|
184
|
-
- lib/kafo/puppet_module_parser.rb
|
185
|
-
- lib/kafo/doc_parser.rb
|
186
198
|
- lib/kafo/password_manager.rb
|
187
199
|
- lib/kafo/configuration.rb
|
188
200
|
- lib/kafo/validator.rb
|
@@ -205,6 +217,7 @@ files:
|
|
205
217
|
- lib/kafo/hooking.rb
|
206
218
|
- lib/kafo/string_helper.rb
|
207
219
|
- lib/kafo/logger.rb
|
220
|
+
- lib/kafo/color_scheme.rb
|
208
221
|
- lib/kafo/param_group.rb
|
209
222
|
- lib/kafo/progress_bars/colored.rb
|
210
223
|
- lib/kafo/progress_bars/black_white.rb
|
data/lib/kafo/doc_parser.rb
DELETED
@@ -1,129 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
require 'rdoc'
|
3
|
-
require 'rdoc/markup' # required for RDoc < 0.9.5
|
4
|
-
require 'rdoc/markup/parser' # required for RDoc < 0.9.5
|
5
|
-
|
6
|
-
module Kafo
|
7
|
-
class DocParser
|
8
|
-
ATTRIBUTE_LINE = /^(condition|type)\s*:\s*(.*)/
|
9
|
-
HEADER_CONDITION = /\A(.+)\s*condition:\s*(.+)\Z/
|
10
|
-
|
11
|
-
def initialize(text)
|
12
|
-
@text = text
|
13
|
-
@nesting_buffer = []
|
14
|
-
@docs = {}
|
15
|
-
@groups = {}
|
16
|
-
@conditions = {}
|
17
|
-
@types = Hash.new('string')
|
18
|
-
@rdoc = rdoc_parser.parse(@text)
|
19
|
-
end
|
20
|
-
|
21
|
-
attr_reader :docs, :groups, :types, :conditions
|
22
|
-
|
23
|
-
# items is array of RDoc::Markup::* on one level
|
24
|
-
def parse(items = @rdoc.parts)
|
25
|
-
items.each do |item|
|
26
|
-
if item.is_a?(RDoc::Markup::Heading)
|
27
|
-
parse_header(item)
|
28
|
-
elsif item.is_a?(RDoc::Markup::List) && item.respond_to?(:items)
|
29
|
-
parse(item.items)
|
30
|
-
elsif item.is_a?(RDoc::Markup::ListItem)
|
31
|
-
parse_paragraph(item)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
self
|
35
|
-
end
|
36
|
-
|
37
|
-
private
|
38
|
-
|
39
|
-
def parse_paragraph(para)
|
40
|
-
# Skip rdoc paras that aren't paragraphs
|
41
|
-
return unless (para.parts.to_s.scan("RDoc::Markup::Paragraph") == ["RDoc::Markup::Paragraph"])
|
42
|
-
# RDoc (>= 4) makes label an array
|
43
|
-
label = para.label.is_a?(Array) ? para.label.first : para.label
|
44
|
-
# Documentation must be a list - if there's no label then skip
|
45
|
-
return if label.nil?
|
46
|
-
key = label.gsub(/[^A-Za-z0-9_-]/, '')
|
47
|
-
@groups[key] = current_groups
|
48
|
-
text_parts = para.parts.first.parts.map!(&:strip)
|
49
|
-
attributes, docs = text_parts.partition { |line| line =~ ATTRIBUTE_LINE }
|
50
|
-
parse_attributes(key, attributes)
|
51
|
-
@docs[key] = docs
|
52
|
-
end
|
53
|
-
|
54
|
-
def parse_attributes(parameter, attributes)
|
55
|
-
condition = nil
|
56
|
-
attributes.each do |attribute|
|
57
|
-
data = attribute.match(ATTRIBUTE_LINE)
|
58
|
-
name, value = data[1], data[2]
|
59
|
-
|
60
|
-
case name
|
61
|
-
when 'type'
|
62
|
-
@types[parameter] = value
|
63
|
-
when 'condition'
|
64
|
-
if condition.nil?
|
65
|
-
condition = value
|
66
|
-
else
|
67
|
-
raise DocParseError, "Two or more conditions defined for #{name}"
|
68
|
-
end
|
69
|
-
else
|
70
|
-
raise DocParseError, "Unknown attribute #{name}"
|
71
|
-
end
|
72
|
-
|
73
|
-
end
|
74
|
-
condition = [current_condition, condition].compact.join(' && ')
|
75
|
-
@conditions[parameter] = condition.empty? ? nil : condition
|
76
|
-
end
|
77
|
-
|
78
|
-
def parse_header(heading)
|
79
|
-
if heading.level > current_level
|
80
|
-
@nesting_buffer.push nesting(heading)
|
81
|
-
elsif heading.level == current_level
|
82
|
-
@nesting_buffer.pop
|
83
|
-
@nesting_buffer.push nesting(heading)
|
84
|
-
else
|
85
|
-
while current_level >= heading.level do
|
86
|
-
@nesting_buffer.pop
|
87
|
-
end
|
88
|
-
@nesting_buffer.push nesting(heading)
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
def nesting(heading)
|
93
|
-
if heading.text =~ HEADER_CONDITION
|
94
|
-
text, condition = $1, $2
|
95
|
-
else
|
96
|
-
text, condition = heading.text, nil
|
97
|
-
end
|
98
|
-
Nesting.new(text.strip, heading.level, condition)
|
99
|
-
end
|
100
|
-
|
101
|
-
def current_groups
|
102
|
-
@nesting_buffer.map(&:name)
|
103
|
-
end
|
104
|
-
|
105
|
-
def current_level
|
106
|
-
current_nesting.nil? ? 0 : current_nesting.level
|
107
|
-
end
|
108
|
-
|
109
|
-
def current_condition
|
110
|
-
condition = @nesting_buffer.map(&:condition).select { |c| !c.nil? }.join(' && ')
|
111
|
-
condition.empty? ? nil : condition
|
112
|
-
end
|
113
|
-
|
114
|
-
def current_nesting
|
115
|
-
@nesting_buffer.last
|
116
|
-
end
|
117
|
-
|
118
|
-
def rdoc_parser
|
119
|
-
if RDoc::Markup.respond_to?(:parse)
|
120
|
-
RDoc::Markup
|
121
|
-
else # RDoc < 3.10.0
|
122
|
-
RDoc::Markup::Parser
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
class Nesting < Struct.new(:name, :level, :condition);
|
127
|
-
end
|
128
|
-
end
|
129
|
-
end
|
@@ -1,78 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
require 'puppet'
|
3
|
-
require 'kafo/doc_parser'
|
4
|
-
|
5
|
-
module Kafo
|
6
|
-
# Based on ideas from puppet-parse by Johan van den Dorpe
|
7
|
-
# we don't build any tree structure since e.g. params from doc does not
|
8
|
-
# have to be defined in puppet DSL and vice versa, we just gather all info
|
9
|
-
# we can read from the whole manifest
|
10
|
-
class PuppetModuleParser
|
11
|
-
def self.parse(file)
|
12
|
-
content = new(file)
|
13
|
-
docs = content.docs
|
14
|
-
|
15
|
-
data = {
|
16
|
-
:values => content.values,
|
17
|
-
:validations => content.validations
|
18
|
-
}
|
19
|
-
data[:parameters] = data[:values].keys
|
20
|
-
data.merge!(docs)
|
21
|
-
data
|
22
|
-
end
|
23
|
-
|
24
|
-
def initialize(file)
|
25
|
-
@file = file
|
26
|
-
raise ModuleName, "File not found #{file}, check you answer file" unless File.exists?(file)
|
27
|
-
Puppet.settings[:confdir] ||= '/' # just some stubbing
|
28
|
-
if Puppet::Node::Environment.respond_to?(:create)
|
29
|
-
env = Puppet::Node::Environment.create(:production, [], '')
|
30
|
-
else
|
31
|
-
env = Puppet::Node::Environment.new(:production)
|
32
|
-
end
|
33
|
-
parser = Puppet::Parser::Parser.new(env)
|
34
|
-
parser.import(@file)
|
35
|
-
|
36
|
-
# Find object corresponding to class defined in init.pp in list of hostclasses
|
37
|
-
parser.environment.known_resource_types.hostclasses.each do |ast_objects|
|
38
|
-
ast_type = ast_objects.last
|
39
|
-
@object = ast_type if ast_type.file == file
|
40
|
-
end
|
41
|
-
|
42
|
-
parser
|
43
|
-
end
|
44
|
-
|
45
|
-
# TODO - store parsed object type (Puppet::Parser::AST::Variable must be dumped later)
|
46
|
-
def values
|
47
|
-
parameters = {}
|
48
|
-
arguments = @object.respond_to?(:arguments) ? @object.arguments : {}
|
49
|
-
arguments.each { |k, v| parameters[k] = v.respond_to?(:value) ? v.value : nil }
|
50
|
-
parameters
|
51
|
-
end
|
52
|
-
|
53
|
-
def validations(param = nil)
|
54
|
-
@object.code.select { |stmt| stmt.is_a?(Puppet::Parser::AST::Function) && stmt.name =~ /^validate_/ }
|
55
|
-
end
|
56
|
-
|
57
|
-
# returns data in following form
|
58
|
-
# {
|
59
|
-
# :docs => { $param1 => 'documentation without types and conditions'}
|
60
|
-
# :types => { $param1 => 'boolean'},
|
61
|
-
# :groups => { $param1 => ['Parameters', 'Advanced']},
|
62
|
-
# :conditions => { $param1 => '$db_type == "mysql"'},
|
63
|
-
# }
|
64
|
-
def docs
|
65
|
-
data = { :docs => {}, :types => {}, :groups => {}, :conditions => {} }
|
66
|
-
if @object.nil?
|
67
|
-
raise DocParseError, "no documentation found for manifest #{@file}, parsing error?"
|
68
|
-
elsif !@object.doc.nil?
|
69
|
-
parser = DocParser.new(@object.doc).parse
|
70
|
-
data[:docs] = parser.docs
|
71
|
-
data[:groups] = parser.groups
|
72
|
-
data[:types] = parser.types
|
73
|
-
data[:conditions] = parser.conditions
|
74
|
-
end
|
75
|
-
data
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|