kafo_parsers 0.1.5 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/README.md +83 -17
- data/lib/kafo_parsers/doc_parser.rb +10 -26
- data/lib/kafo_parsers/param_doc_parser.rb +42 -0
- data/lib/kafo_parsers/parsers.rb +1 -2
- data/lib/kafo_parsers/puppet_strings_module_parser.rb +52 -21
- data/lib/kafo_parsers/version.rb +1 -1
- metadata +22 -24
- data/lib/kafo_parsers/puppet_module_parser.rb +0 -138
- data/lib/kafo_parsers/validation.rb +0 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: e59aa9f14c8c8c6888b69b88521c9fcd589dfe122d7dc0a1bc9d3df32262969a
|
4
|
+
data.tar.gz: 99682f87e85a3c3994313f50d4942ae1f4f51a22564532af2e78c0ee48bf869a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 04e1546703475de823ed9a40fa9e05515c9bdc7a39c20e7cddfaf180f64a6771813539f9264f145664ae0d50a653e2474cc9313dcd76ab1bd573fa68fd377813
|
7
|
+
data.tar.gz: ea384ebd11d468bfc8e8c81f126483481273a34abdb9acec94f6cfe9a5bfeb535eb84ed323a4fa0a55ac5e90a2cdc742a4379f6c88d4abb3d22751946b13ba82
|
data/README.md
CHANGED
@@ -44,33 +44,99 @@ KafoParsers::Parsers.find_available(:logger => logger)
|
|
44
44
|
|
45
45
|
To load a specific parser:
|
46
46
|
```ruby
|
47
|
-
require 'kafo_parsers/
|
48
|
-
hash = KafoParsers::
|
47
|
+
require 'kafo_parsers/puppet_strings_module_parser'
|
48
|
+
hash = KafoParsers::PuppetStringsModuleParser.parse('/puppet/module/manifests/init.pp')
|
49
49
|
```
|
50
50
|
|
51
|
-
#### PuppetModuleParser
|
52
|
-
|
53
|
-
The standard PuppetModuleParser loads Puppet as a regular library or gem, so it
|
54
|
-
must be installed in the same Ruby that's running kafo_parsers.
|
55
|
-
|
56
|
-
Only Puppet versions 2.6.x, 2.7.x and 3.x are supported.
|
57
|
-
|
58
|
-
Add `gem 'puppet', '< 4'` to your application's Gemfile to use this.
|
59
|
-
|
60
51
|
#### PuppetStringsModuleParser
|
61
52
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
Puppet AIO installation.
|
53
|
+
Leverage puppet-strings to parse puppet manifests. This requires puppet-strings
|
54
|
+
1.2.0 or higher and may be installed either as a gem in the same environment,
|
55
|
+
or in a Puppet AIO installation.
|
66
56
|
|
67
57
|
```ruby
|
68
58
|
require 'kafo_parsers/puppet_strings_module_parser'
|
69
59
|
hash = KafoParsers::PuppetStringsModuleParser.parse('/puppet/module/manifests/init.pp')
|
70
60
|
```
|
71
61
|
|
72
|
-
|
73
|
-
|
62
|
+
## Documentation syntax
|
63
|
+
|
64
|
+
### RDoc syntax
|
65
|
+
|
66
|
+
Classes and defined types should be prefixed with a comment section with an RDoc
|
67
|
+
block, containing a description, headings for different parameter groups and
|
68
|
+
parameters laid out as shown below:
|
69
|
+
|
70
|
+
```puppet
|
71
|
+
# Example class that installs Example
|
72
|
+
#
|
73
|
+
# Supports version 1 to 3.
|
74
|
+
#
|
75
|
+
# === Parameters::
|
76
|
+
#
|
77
|
+
# $foo:: Sets the value of foo in the Example config
|
78
|
+
#
|
79
|
+
# === Advanced parameters::
|
80
|
+
#
|
81
|
+
# $bar:: Sets the value of bar in the advanced config
|
82
|
+
```
|
83
|
+
|
84
|
+
Parameters may have multi-line descriptions and can have extra attributes
|
85
|
+
defined on new lines below them. Supports:
|
86
|
+
|
87
|
+
```puppet
|
88
|
+
# $foo:: Sets the value of foo in the Example config
|
89
|
+
# condition: $bar == 'use_foo'
|
90
|
+
# type: Optional[String]
|
91
|
+
```
|
92
|
+
|
93
|
+
Supports:
|
94
|
+
|
95
|
+
* `condition:` an expression to determine if the parameter is used
|
96
|
+
* `type:` the data type of the parameter
|
97
|
+
|
98
|
+
Used by:
|
99
|
+
|
100
|
+
* `PuppetStringsModuleParser` (but deprecated, prefer YARD)
|
101
|
+
|
102
|
+
### YARD syntax
|
103
|
+
|
104
|
+
Classes and defined types should be prefixed with a comment section in YARD
|
105
|
+
following the Puppet Strings documentation standard, as shown below:
|
106
|
+
|
107
|
+
```puppet
|
108
|
+
# Example class that installs Example
|
109
|
+
#
|
110
|
+
# Supports version 1 to 3.
|
111
|
+
#
|
112
|
+
# @param foo Sets the value of foo in the Example config
|
113
|
+
# @param bar Sets the value of bar in the advanced config
|
114
|
+
# group: Advanced parameters
|
115
|
+
```
|
116
|
+
|
117
|
+
Parameters may have multi-line descriptions and can have extra attributes
|
118
|
+
defined on new lines below them. Supports:
|
119
|
+
|
120
|
+
```puppet
|
121
|
+
# @param foo Sets the value of foo in the Example config
|
122
|
+
# condition: $bar == 'use_foo'
|
123
|
+
```
|
124
|
+
|
125
|
+
Supports:
|
126
|
+
|
127
|
+
* `condition:` an expression to determine if the parameter is used
|
128
|
+
* `group:` comma-separated list of groups, increasing in specificity
|
129
|
+
|
130
|
+
Data types are given in the parameter list of the class, or can be given inline
|
131
|
+
for Puppet 3 compatibility:
|
132
|
+
|
133
|
+
```puppet
|
134
|
+
# @param foo [Integer] Sets the value of foo in the Example config
|
135
|
+
```
|
136
|
+
|
137
|
+
Used by:
|
138
|
+
|
139
|
+
* `PuppetStringsModuleParser`
|
74
140
|
|
75
141
|
# License
|
76
142
|
|
@@ -3,6 +3,7 @@ require 'rdoc'
|
|
3
3
|
require 'rdoc/markup' # required for RDoc < 0.9.5
|
4
4
|
require 'rdoc/markup/parser' # required for RDoc < 0.9.5
|
5
5
|
require 'kafo_parsers/exceptions'
|
6
|
+
require 'kafo_parsers/param_doc_parser'
|
6
7
|
|
7
8
|
module KafoParsers
|
8
9
|
class DocParser
|
@@ -15,7 +16,7 @@ module KafoParsers
|
|
15
16
|
@docs = {}
|
16
17
|
@groups = {}
|
17
18
|
@conditions = {}
|
18
|
-
@types =
|
19
|
+
@types = {}
|
19
20
|
@rdoc = rdoc_parser.parse(@text)
|
20
21
|
end
|
21
22
|
|
@@ -46,34 +47,17 @@ module KafoParsers
|
|
46
47
|
return if label.nil?
|
47
48
|
key = label.gsub(/[^A-Za-z0-9_-]/, '')
|
48
49
|
@groups[key] = current_groups
|
49
|
-
text_parts = para.parts.first.parts
|
50
|
-
attributes, docs = text_parts.partition { |line| line =~ ATTRIBUTE_LINE }
|
51
|
-
parse_attributes(key, attributes)
|
52
|
-
@docs[key] = docs
|
53
|
-
end
|
50
|
+
text_parts = para.parts.first.parts
|
54
51
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
name, value = data[1], data[2]
|
60
|
-
|
61
|
-
case name
|
62
|
-
when 'type'
|
63
|
-
@types[parameter] = value
|
64
|
-
when 'condition'
|
65
|
-
if condition.nil?
|
66
|
-
condition = value
|
67
|
-
else
|
68
|
-
raise KafoParsers::DocParseError, "Two or more conditions defined for #{name}"
|
69
|
-
end
|
70
|
-
else
|
71
|
-
raise KafoParsers::DocParseError, "Unknown attribute #{name}"
|
72
|
-
end
|
52
|
+
param_parser = ParamDocParser.new(key, text_parts)
|
53
|
+
@docs[key] = param_parser.doc
|
54
|
+
parse_attributes(key, param_parser)
|
55
|
+
end
|
73
56
|
|
74
|
-
|
75
|
-
condition = [current_condition, condition].compact.join(' && ')
|
57
|
+
def parse_attributes(parameter, parser)
|
58
|
+
condition = [current_condition, parser.condition].compact.join(' && ')
|
76
59
|
@conditions[parameter] = condition.empty? ? nil : condition
|
60
|
+
@types[parameter] = parser.type unless parser.type.nil?
|
77
61
|
end
|
78
62
|
|
79
63
|
def parse_header(heading)
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'kafo_parsers/exceptions'
|
2
|
+
|
3
|
+
module KafoParsers
|
4
|
+
class ParamDocParser
|
5
|
+
ATTRIBUTE_LINE = /^(condition|group|type)\s*:\s*(.*)/
|
6
|
+
|
7
|
+
def initialize(param, text)
|
8
|
+
@param = param
|
9
|
+
@metadata = {}
|
10
|
+
parse_paragraph([text].flatten)
|
11
|
+
end
|
12
|
+
|
13
|
+
attr_reader :param, :doc
|
14
|
+
[:condition, :group, :type].each do |attr|
|
15
|
+
define_method(attr) do
|
16
|
+
@metadata[attr]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def parse_paragraph(text)
|
23
|
+
text_parts = text.map(&:strip)
|
24
|
+
attributes, docs = text_parts.partition { |line| line =~ ATTRIBUTE_LINE }
|
25
|
+
parse_attributes(attributes)
|
26
|
+
@doc = docs
|
27
|
+
end
|
28
|
+
|
29
|
+
def parse_attributes(attributes)
|
30
|
+
attributes.each do |attribute|
|
31
|
+
data = attribute.match(ATTRIBUTE_LINE)
|
32
|
+
name, value = data[1], data[2]
|
33
|
+
raise KafoParsers::DocParseError, "Two or more #{name} lines defined for #{param}" if @metadata.key?(name)
|
34
|
+
@metadata[name.to_sym] = value
|
35
|
+
end
|
36
|
+
|
37
|
+
if @metadata.key?(:group)
|
38
|
+
@metadata[:group] = @metadata[:group].split(/\s*,\s*/)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/kafo_parsers/parsers.rb
CHANGED
@@ -1,10 +1,9 @@
|
|
1
|
-
require 'kafo_parsers/puppet_module_parser.rb'
|
2
1
|
require 'kafo_parsers/puppet_strings_module_parser.rb'
|
3
2
|
|
4
3
|
module KafoParsers
|
5
4
|
module Parsers
|
6
5
|
def self.all
|
7
|
-
[
|
6
|
+
[ PuppetStringsModuleParser ]
|
8
7
|
end
|
9
8
|
|
10
9
|
def self.find_available(options = {})
|
@@ -1,6 +1,9 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
require 'json'
|
3
|
+
require 'open3'
|
4
|
+
|
3
5
|
require 'kafo_parsers/doc_parser'
|
6
|
+
require 'kafo_parsers/param_doc_parser'
|
4
7
|
|
5
8
|
module KafoParsers
|
6
9
|
class PuppetStringsModuleParser
|
@@ -24,25 +27,25 @@ module KafoParsers
|
|
24
27
|
end
|
25
28
|
|
26
29
|
def self.available?
|
27
|
-
|
28
|
-
if
|
30
|
+
_stdout, _stderr, status = run_puppet(['help', 'strings'])
|
31
|
+
if status.success?
|
29
32
|
return true
|
30
33
|
else
|
31
|
-
raise KafoParsers::ParserNotAvailable.new("#{puppet_bin} does not have strings module installed")
|
34
|
+
raise KafoParsers::ParserNotAvailable.new("#{puppet_bin} does not have strings module installed.")
|
32
35
|
end
|
33
36
|
end
|
34
37
|
|
35
38
|
def initialize(file)
|
36
39
|
@file = file = File.expand_path(file)
|
37
|
-
raise KafoParsers::ModuleName, "File not found #{file}, check your answer file" unless File.
|
40
|
+
raise KafoParsers::ModuleName, "File not found #{file}, check your answer file" unless File.exist?(file)
|
41
|
+
|
42
|
+
command = ['strings', 'generate', '--format', 'json', file]
|
43
|
+
@raw_json, stderr, status = self.class.run_puppet(command)
|
38
44
|
|
39
|
-
|
40
|
-
|
41
|
-
unless $?.success?
|
42
|
-
raise KafoParsers::ParseError, "'#{command}' returned error\n#{@raw_json}"
|
45
|
+
unless status.success?
|
46
|
+
raise KafoParsers::ParseError, "'#{command}' returned error:\n #{@raw_json}\n #{stderr}"
|
43
47
|
end
|
44
48
|
|
45
|
-
Encoding.default_external = Encoding::UTF_8 if defined?(Encoding)
|
46
49
|
begin
|
47
50
|
@complete_hash = ::JSON.parse(@raw_json)
|
48
51
|
rescue ::JSON::ParserError => e
|
@@ -91,7 +94,7 @@ module KafoParsers
|
|
91
94
|
|
92
95
|
# returns data in following form
|
93
96
|
# {
|
94
|
-
# :docs => { $param1 => 'documentation without types and conditions'}
|
97
|
+
# :docs => { $param1 => ['documentation without types and conditions']}
|
95
98
|
# :types => { $param1 => 'boolean'},
|
96
99
|
# :groups => { $param1 => ['Parameters', 'Advanced']},
|
97
100
|
# :conditions => { $param1 => '$db_type == "mysql"'},
|
@@ -101,19 +104,52 @@ module KafoParsers
|
|
101
104
|
if @parsed_hash.nil?
|
102
105
|
raise KafoParsers::DocParseError, "no documentation found for manifest #{@file}, parsing error?"
|
103
106
|
elsif !@parsed_hash['docstring'].nil? && !@parsed_hash['docstring']['text'].nil?
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
107
|
+
# Lowest precedence: types given in the strings hash from class definition
|
108
|
+
tag_params.each do |param|
|
109
|
+
data[:types][param['name']] = param['types'][0] unless param['types'].nil?
|
110
|
+
end
|
111
|
+
|
112
|
+
# Next: types and other data from RDoc parser
|
113
|
+
rdoc_parser = DocParser.new(@parsed_hash['docstring']['text']).parse
|
114
|
+
data[:docs] = rdoc_parser.docs
|
115
|
+
data[:groups] = rdoc_parser.groups
|
116
|
+
data[:conditions] = rdoc_parser.conditions
|
117
|
+
data[:types].merge! rdoc_parser.types
|
118
|
+
|
119
|
+
# Highest precedence: data in YARD @param stored in the 'text' field
|
120
|
+
tag_params.each do |param|
|
121
|
+
param_name = param['name']
|
122
|
+
unless param['text'].nil? || param['text'].empty?
|
123
|
+
param_parser = ParamDocParser.new(param_name, param['text'].split($/))
|
124
|
+
data[:docs][param_name] = param_parser.doc if param_parser.doc
|
125
|
+
data[:groups][param_name] = param_parser.group if param_parser.group
|
126
|
+
data[:conditions][param_name] = param_parser.condition if param_parser.condition
|
127
|
+
data[:types][param_name] = param_parser.type if param_parser.type
|
128
|
+
end
|
129
|
+
end
|
109
130
|
end
|
110
131
|
data
|
111
132
|
end
|
112
133
|
|
113
134
|
private
|
114
135
|
|
136
|
+
def self.run_puppet(command)
|
137
|
+
env_vars = self.puppet_bin.start_with?('/opt/puppetlabs') ? clean_env_vars : ::ENV
|
138
|
+
command = command.unshift(self.puppet_bin)
|
139
|
+
Open3.capture3(env_vars, *command, :unsetenv_others => true)
|
140
|
+
end
|
141
|
+
|
142
|
+
def self.clean_env_vars
|
143
|
+
# Cleaning ENV vars and keeping required vars only because,
|
144
|
+
# When using SCL it adds GEM_HOME and GEM_PATH ENV vars.
|
145
|
+
whitelisted_vars = %w[HOME USER LANG]
|
146
|
+
|
147
|
+
cleaned_env = ::ENV.select { |var| whitelisted_vars.include?(var) || var.start_with?('LC_') }
|
148
|
+
cleaned_env['PATH'] = '/sbin:/bin:/usr/sbin:/usr/bin:/opt/puppetlabs/bin'
|
149
|
+
cleaned_env
|
150
|
+
end
|
151
|
+
|
115
152
|
# default values using puppet strings includes $ symbol, e.g. "$::foreman::params::ssl"
|
116
|
-
# to keep the same API we strip $ if it's present
|
117
153
|
#
|
118
154
|
# values are reported as strings which is issue especially for :under
|
119
155
|
# strings are double quoted
|
@@ -122,16 +158,11 @@ module KafoParsers
|
|
122
158
|
if (value.start_with?("'") && value.end_with?("'")) || (value.start_with?('"') && value.end_with?('"'))
|
123
159
|
value = value[1..-2]
|
124
160
|
end
|
125
|
-
value = value[1..-1] if value.start_with?('$')
|
126
161
|
value = :undef if value == 'undef'
|
127
162
|
|
128
163
|
value
|
129
164
|
end
|
130
165
|
|
131
|
-
def merge_doc_types(types)
|
132
|
-
Hash[tag_params.select { |param| !param['types'].nil? }.map { |param| [ param['name'], param['types'].first ] }].merge(types)
|
133
|
-
end
|
134
|
-
|
135
166
|
def tag_params
|
136
167
|
if @parsed_hash['docstring']['tags']
|
137
168
|
@parsed_hash['docstring']['tags'].select { |tag| tag['tag_name'] == 'param' }
|
data/lib/kafo_parsers/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kafo_parsers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marek Hulan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-08-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -28,58 +28,58 @@ dependencies:
|
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: minitest
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - "
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - "
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
54
|
+
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: simplecov
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - "
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '0
|
61
|
+
version: '0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - "
|
66
|
+
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '0
|
68
|
+
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: ci_reporter_minitest
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - "
|
73
|
+
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
75
|
+
version: '0'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- - "
|
80
|
+
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
82
|
+
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: rdoc
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -122,14 +122,13 @@ files:
|
|
122
122
|
- lib/kafo_parsers.rb
|
123
123
|
- lib/kafo_parsers/doc_parser.rb
|
124
124
|
- lib/kafo_parsers/exceptions.rb
|
125
|
+
- lib/kafo_parsers/param_doc_parser.rb
|
125
126
|
- lib/kafo_parsers/parsers.rb
|
126
|
-
- lib/kafo_parsers/puppet_module_parser.rb
|
127
127
|
- lib/kafo_parsers/puppet_strings_module_parser.rb
|
128
|
-
- lib/kafo_parsers/validation.rb
|
129
128
|
- lib/kafo_parsers/version.rb
|
130
129
|
homepage: https://github.com/theforeman/kafo_parsers
|
131
130
|
licenses:
|
132
|
-
-
|
131
|
+
- GPL-3.0+
|
133
132
|
metadata: {}
|
134
133
|
post_install_message:
|
135
134
|
rdoc_options: []
|
@@ -146,8 +145,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
146
145
|
- !ruby/object:Gem::Version
|
147
146
|
version: '0'
|
148
147
|
requirements: []
|
149
|
-
|
150
|
-
rubygems_version: 2.4.5
|
148
|
+
rubygems_version: 3.1.2
|
151
149
|
signing_key:
|
152
150
|
specification_version: 4
|
153
151
|
summary: Puppet module parsers
|
@@ -1,138 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
require 'kafo_parsers/doc_parser'
|
3
|
-
require 'kafo_parsers/validation'
|
4
|
-
|
5
|
-
module KafoParsers
|
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
|
-
@@puppet_initialized = false
|
12
|
-
|
13
|
-
def self.available?
|
14
|
-
require 'puppet'
|
15
|
-
[2, 3].include?(Puppet::PUPPETVERSION.to_i)
|
16
|
-
rescue LoadError => e
|
17
|
-
raise KafoParsers::ParserNotAvailable.new(e)
|
18
|
-
end
|
19
|
-
|
20
|
-
# You can call this method to get all supported information from a given manifest
|
21
|
-
#
|
22
|
-
# @param [ String ] manifest file path to parse
|
23
|
-
# @return [ Hash ] hash containing values, validations, documentation, types, groups and conditions
|
24
|
-
def self.parse(file)
|
25
|
-
content = new(file)
|
26
|
-
docs = content.docs
|
27
|
-
|
28
|
-
data = {
|
29
|
-
:values => content.values,
|
30
|
-
:validations => content.validations
|
31
|
-
}
|
32
|
-
data[:parameters] = data[:values].keys
|
33
|
-
data.merge!(docs)
|
34
|
-
data
|
35
|
-
end
|
36
|
-
|
37
|
-
def initialize(file)
|
38
|
-
called_before_each_test = false
|
39
|
-
|
40
|
-
@file = file = File.expand_path(file)
|
41
|
-
raise KafoParsers::ModuleName, "File not found #{file}, check your answer file" unless File.exists?(file)
|
42
|
-
|
43
|
-
unless @@puppet_initialized
|
44
|
-
require 'puppet'
|
45
|
-
if Puppet::PUPPETVERSION.to_i >= 3
|
46
|
-
require 'puppet/test/test_helper'
|
47
|
-
if Puppet::Test::TestHelper.respond_to?(:initialize) # 3.1+
|
48
|
-
Puppet::Test::TestHelper.initialize
|
49
|
-
end
|
50
|
-
Puppet::Test::TestHelper.before_all_tests
|
51
|
-
else
|
52
|
-
Puppet.parse_config
|
53
|
-
end
|
54
|
-
Encoding.default_external = Encoding::UTF_8 if defined?(Encoding)
|
55
|
-
@@puppet_initialized = true
|
56
|
-
end
|
57
|
-
|
58
|
-
if Puppet::PUPPETVERSION.to_i >= 3
|
59
|
-
Puppet::Test::TestHelper.before_each_test
|
60
|
-
called_before_each_test = true
|
61
|
-
end
|
62
|
-
|
63
|
-
env = Puppet::Node::Environment.new
|
64
|
-
parser = Puppet::Parser::Parser.new(env)
|
65
|
-
parser.import(@file)
|
66
|
-
|
67
|
-
# Find object corresponding to class defined in init.pp in list of hostclasses
|
68
|
-
ast_types = parser.environment.known_resource_types.hostclasses.map(&:last)
|
69
|
-
@object = ast_types.find { |ast_type| ast_type.file == file }
|
70
|
-
|
71
|
-
# Find object in list of definitions if not found among hostclasses
|
72
|
-
if @object.nil?
|
73
|
-
ast_types = parser.environment.known_resource_types.definitions.map(&:last)
|
74
|
-
@object = ast_types.find { |ast_type| ast_type.file == file }
|
75
|
-
end
|
76
|
-
|
77
|
-
parser
|
78
|
-
ensure
|
79
|
-
Puppet::Test::TestHelper.after_each_test if called_before_each_test
|
80
|
-
end
|
81
|
-
|
82
|
-
# TODO - store parsed object type (Puppet::Parser::AST::Variable must be dumped later)
|
83
|
-
def values
|
84
|
-
parameters = {}
|
85
|
-
arguments = @object.respond_to?(:arguments) ? @object.arguments : {}
|
86
|
-
arguments.each { |k, v| parameters[k] = v.respond_to?(:value) ? v.value : nil }
|
87
|
-
parameters
|
88
|
-
end
|
89
|
-
|
90
|
-
def validations(param = nil)
|
91
|
-
return [] if @object.code.nil?
|
92
|
-
@object.code.select { |stmt| stmt.is_a?(Puppet::Parser::AST::Function) && stmt.name =~ /^validate_/ }.map do |v|
|
93
|
-
Validation.new(v.name, interpret_validation_args(v.arguments))
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
# returns data in following form
|
98
|
-
# {
|
99
|
-
# :docs => { $param1 => 'documentation without types and conditions'}
|
100
|
-
# :types => { $param1 => 'boolean'},
|
101
|
-
# :groups => { $param1 => ['Parameters', 'Advanced']},
|
102
|
-
# :conditions => { $param1 => '$db_type == "mysql"'},
|
103
|
-
# :object_type => 'hostclass' # or definition
|
104
|
-
# }
|
105
|
-
def docs
|
106
|
-
data = { :docs => {}, :types => {}, :groups => {}, :conditions => {}, :object_type => '' }
|
107
|
-
if @object.nil?
|
108
|
-
raise KafoParsers::DocParseError, "no documentation found for manifest #{@file}, parsing error?"
|
109
|
-
elsif !@object.doc.nil?
|
110
|
-
parser = DocParser.new(@object.doc).parse
|
111
|
-
data[:docs] = parser.docs
|
112
|
-
data[:groups] = parser.groups
|
113
|
-
data[:types] = parser.types
|
114
|
-
data[:conditions] = parser.conditions
|
115
|
-
data[:object_type] = @object.type.to_s
|
116
|
-
end
|
117
|
-
data
|
118
|
-
end
|
119
|
-
|
120
|
-
private
|
121
|
-
|
122
|
-
def interpret_validation_args(args)
|
123
|
-
args.map do |arg|
|
124
|
-
if arg.is_a?(Puppet::Parser::AST::Variable)
|
125
|
-
arg.to_s
|
126
|
-
elsif arg.is_a?(Puppet::Parser::AST::ASTArray)
|
127
|
-
interpret_validation_args(arg.to_a)
|
128
|
-
elsif arg.is_a?(Puppet::Parser::AST::Concat)
|
129
|
-
interpret_validation_args(arg.value).join
|
130
|
-
elsif arg.respond_to? :value
|
131
|
-
arg.value
|
132
|
-
else
|
133
|
-
arg
|
134
|
-
end
|
135
|
-
end
|
136
|
-
end
|
137
|
-
end
|
138
|
-
end
|