choria-mcorpc-support 2.21.1 → 2.23.1

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.
Files changed (145) hide show
  1. checksums.yaml +4 -4
  2. data/lib/mcollective.rb +1 -2
  3. data/lib/mcollective/agent/bolt_tasks.ddl +253 -0
  4. data/lib/mcollective/agent/bolt_tasks.json +365 -0
  5. data/lib/mcollective/agent/bolt_tasks.rb +178 -0
  6. data/lib/mcollective/agent/choria_util.ddl +152 -0
  7. data/lib/mcollective/agent/choria_util.json +244 -0
  8. data/lib/mcollective/agent/rpcutil.ddl +8 -4
  9. data/lib/mcollective/agent/rpcutil.json +333 -0
  10. data/lib/mcollective/agent/scout.ddl +169 -0
  11. data/lib/mcollective/agent/scout.json +224 -0
  12. data/lib/mcollective/agents.rb +7 -6
  13. data/lib/mcollective/aggregate.rb +4 -4
  14. data/lib/mcollective/aggregate/average.rb +2 -2
  15. data/lib/mcollective/aggregate/base.rb +2 -2
  16. data/lib/mcollective/aggregate/result.rb +3 -3
  17. data/lib/mcollective/aggregate/result/collection_result.rb +2 -2
  18. data/lib/mcollective/aggregate/result/numeric_result.rb +2 -2
  19. data/lib/mcollective/aggregate/sum.rb +2 -2
  20. data/lib/mcollective/aggregate/summary.rb +3 -4
  21. data/lib/mcollective/application.rb +57 -21
  22. data/lib/mcollective/application/choria.rb +189 -0
  23. data/lib/mcollective/application/completion.rb +6 -6
  24. data/lib/mcollective/application/facts.rb +11 -11
  25. data/lib/mcollective/application/federation.rb +237 -0
  26. data/lib/mcollective/application/find.rb +4 -4
  27. data/lib/mcollective/application/help.rb +3 -3
  28. data/lib/mcollective/application/inventory.rb +3 -341
  29. data/lib/mcollective/application/ping.rb +5 -51
  30. data/lib/mcollective/application/playbook.rb +207 -0
  31. data/lib/mcollective/application/plugin.rb +106 -106
  32. data/lib/mcollective/application/rpc.rb +3 -108
  33. data/lib/mcollective/application/tasks.rb +425 -0
  34. data/lib/mcollective/applications.rb +11 -10
  35. data/lib/mcollective/audit/choria.rb +33 -0
  36. data/lib/mcollective/cache.rb +2 -4
  37. data/lib/mcollective/client.rb +11 -10
  38. data/lib/mcollective/config.rb +21 -34
  39. data/lib/mcollective/connector/base.rb +2 -1
  40. data/lib/mcollective/connector/nats.ddl +9 -0
  41. data/lib/mcollective/connector/nats.rb +450 -0
  42. data/lib/mcollective/data.rb +8 -3
  43. data/lib/mcollective/data/agent_data.rb +1 -1
  44. data/lib/mcollective/data/base.rb +6 -5
  45. data/lib/mcollective/data/bolt_task_data.ddl +90 -0
  46. data/lib/mcollective/data/bolt_task_data.rb +32 -0
  47. data/lib/mcollective/data/collective_data.rb +1 -1
  48. data/lib/mcollective/data/fact_data.rb +6 -6
  49. data/lib/mcollective/data/fstat_data.rb +2 -4
  50. data/lib/mcollective/data/result.rb +7 -2
  51. data/lib/mcollective/ddl/agentddl.rb +5 -17
  52. data/lib/mcollective/ddl/base.rb +10 -13
  53. data/lib/mcollective/discovery.rb +24 -39
  54. data/lib/mcollective/discovery/choria.ddl +11 -0
  55. data/lib/mcollective/discovery/choria.rb +223 -0
  56. data/lib/mcollective/discovery/flatfile.rb +7 -8
  57. data/lib/mcollective/discovery/mc.rb +2 -2
  58. data/lib/mcollective/discovery/stdin.rb +17 -18
  59. data/lib/mcollective/exceptions.rb +13 -0
  60. data/lib/mcollective/facts/base.rb +9 -9
  61. data/lib/mcollective/facts/yaml_facts.rb +12 -12
  62. data/lib/mcollective/generators.rb +3 -3
  63. data/lib/mcollective/generators/agent_generator.rb +3 -4
  64. data/lib/mcollective/generators/base.rb +14 -15
  65. data/lib/mcollective/generators/data_generator.rb +5 -6
  66. data/lib/mcollective/log.rb +2 -2
  67. data/lib/mcollective/logger/base.rb +3 -2
  68. data/lib/mcollective/logger/console_logger.rb +10 -10
  69. data/lib/mcollective/logger/file_logger.rb +7 -7
  70. data/lib/mcollective/logger/syslog_logger.rb +11 -15
  71. data/lib/mcollective/message.rb +8 -39
  72. data/lib/mcollective/monkey_patches.rb +2 -4
  73. data/lib/mcollective/optionparser.rb +2 -1
  74. data/lib/mcollective/pluginmanager.rb +3 -5
  75. data/lib/mcollective/pluginpackager.rb +1 -3
  76. data/lib/mcollective/pluginpackager/agent_definition.rb +3 -8
  77. data/lib/mcollective/pluginpackager/forge_packager.rb +7 -9
  78. data/lib/mcollective/pluginpackager/standard_definition.rb +1 -2
  79. data/lib/mcollective/registration/base.rb +18 -16
  80. data/lib/mcollective/rpc.rb +2 -4
  81. data/lib/mcollective/rpc/actionrunner.rb +16 -18
  82. data/lib/mcollective/rpc/agent.rb +26 -43
  83. data/lib/mcollective/rpc/audit.rb +1 -0
  84. data/lib/mcollective/rpc/client.rb +67 -85
  85. data/lib/mcollective/rpc/helpers.rb +55 -62
  86. data/lib/mcollective/rpc/progress.rb +2 -2
  87. data/lib/mcollective/rpc/reply.rb +17 -19
  88. data/lib/mcollective/rpc/request.rb +7 -5
  89. data/lib/mcollective/rpc/result.rb +6 -8
  90. data/lib/mcollective/rpc/stats.rb +49 -58
  91. data/lib/mcollective/security/base.rb +13 -56
  92. data/lib/mcollective/security/choria.rb +765 -0
  93. data/lib/mcollective/shell.rb +9 -4
  94. data/lib/mcollective/signer/base.rb +28 -0
  95. data/lib/mcollective/signer/choria.rb +185 -0
  96. data/lib/mcollective/ssl.rb +8 -6
  97. data/lib/mcollective/util.rb +58 -55
  98. data/lib/mcollective/util/bolt_support.rb +176 -0
  99. data/lib/mcollective/util/bolt_support/plan_runner.rb +167 -0
  100. data/lib/mcollective/util/bolt_support/task_result.rb +94 -0
  101. data/lib/mcollective/util/bolt_support/task_results.rb +128 -0
  102. data/lib/mcollective/util/choria.rb +946 -0
  103. data/lib/mcollective/util/indifferent_hash.rb +12 -0
  104. data/lib/mcollective/util/natswrapper.rb +242 -0
  105. data/lib/mcollective/util/playbook.rb +435 -0
  106. data/lib/mcollective/util/playbook/data_stores.rb +201 -0
  107. data/lib/mcollective/util/playbook/data_stores/base.rb +99 -0
  108. data/lib/mcollective/util/playbook/data_stores/consul_data_store.rb +88 -0
  109. data/lib/mcollective/util/playbook/data_stores/environment_data_store.rb +33 -0
  110. data/lib/mcollective/util/playbook/data_stores/etcd_data_store.rb +42 -0
  111. data/lib/mcollective/util/playbook/data_stores/file_data_store.rb +106 -0
  112. data/lib/mcollective/util/playbook/data_stores/shell_data_store.rb +103 -0
  113. data/lib/mcollective/util/playbook/inputs.rb +265 -0
  114. data/lib/mcollective/util/playbook/nodes.rb +207 -0
  115. data/lib/mcollective/util/playbook/nodes/mcollective_nodes.rb +86 -0
  116. data/lib/mcollective/util/playbook/nodes/pql_nodes.rb +40 -0
  117. data/lib/mcollective/util/playbook/nodes/shell_nodes.rb +55 -0
  118. data/lib/mcollective/util/playbook/nodes/terraform_nodes.rb +65 -0
  119. data/lib/mcollective/util/playbook/nodes/yaml_nodes.rb +47 -0
  120. data/lib/mcollective/util/playbook/playbook_logger.rb +47 -0
  121. data/lib/mcollective/util/playbook/puppet_logger.rb +51 -0
  122. data/lib/mcollective/util/playbook/report.rb +152 -0
  123. data/lib/mcollective/util/playbook/task_result.rb +55 -0
  124. data/lib/mcollective/util/playbook/tasks.rb +196 -0
  125. data/lib/mcollective/util/playbook/tasks/base.rb +45 -0
  126. data/lib/mcollective/util/playbook/tasks/graphite_event_task.rb +64 -0
  127. data/lib/mcollective/util/playbook/tasks/mcollective_task.rb +356 -0
  128. data/lib/mcollective/util/playbook/tasks/shell_task.rb +93 -0
  129. data/lib/mcollective/util/playbook/tasks/slack_task.rb +105 -0
  130. data/lib/mcollective/util/playbook/tasks/webhook_task.rb +136 -0
  131. data/lib/mcollective/util/playbook/template_util.rb +98 -0
  132. data/lib/mcollective/util/playbook/uses.rb +169 -0
  133. data/lib/mcollective/util/tasks_support.rb +751 -0
  134. data/lib/mcollective/util/tasks_support/cli.rb +260 -0
  135. data/lib/mcollective/util/tasks_support/default_formatter.rb +138 -0
  136. data/lib/mcollective/util/tasks_support/json_formatter.rb +108 -0
  137. data/lib/mcollective/validator.rb +6 -1
  138. data/lib/mcollective/validator/bolt_task_name_validator.ddl +7 -0
  139. data/lib/mcollective/validator/bolt_task_name_validator.rb +11 -0
  140. data/lib/mcollective/validator/length_validator.rb +1 -3
  141. metadata +65 -6
  142. data/lib/mcollective/application/describe_filter.rb +0 -87
  143. data/lib/mcollective/matcher.rb +0 -220
  144. data/lib/mcollective/matcher/parser.rb +0 -128
  145. data/lib/mcollective/matcher/scanner.rb +0 -241
@@ -30,7 +30,7 @@ module MCollective
30
30
  end
31
31
 
32
32
  # Allows validation plugins to be called like module methods : Validator.validate()
33
- def self.method_missing(method, *args, &block) # rubocop:disable Style/MethodMissing
33
+ def self.method_missing(method, *args, &block)
34
34
  if has_validator?(method)
35
35
  Validator[method].validate(*args)
36
36
  else
@@ -38,6 +38,10 @@ module MCollective
38
38
  end
39
39
  end
40
40
 
41
+ def self.respond_to_missing?(method, *)
42
+ has_validator?(method)
43
+ end
44
+
41
45
  def self.has_validator?(validator)
42
46
  const_defined?(validator_class(validator))
43
47
  end
@@ -48,6 +52,7 @@ module MCollective
48
52
 
49
53
  def self.load_validators?
50
54
  return true if @last_load.nil?
55
+
51
56
  (@last_load - Time.now.to_i) > 300
52
57
  end
53
58
 
@@ -0,0 +1,7 @@
1
+ metadata :name => "bolt_task_name",
2
+ :description => "Validates that a string matches Bolt Task Name",
3
+ :author => "R.I.Pienaar <rip@devco.net>",
4
+ :license => "Apache-2.0",
5
+ :version => "0.19.0",
6
+ :url => "https://choria.io",
7
+ :timeout => 1
@@ -0,0 +1,11 @@
1
+ module MCollective
2
+ module Validator
3
+ class Bolt_task_nameValidator
4
+ def self.validate(name)
5
+ Validator.typecheck(name, :string)
6
+
7
+ raise("'%s' is not a valid Bolt Task name" % name) unless name =~ /\A([a-z][a-z0-9_]*)?(::[a-z][a-z0-9_]*)*\Z/
8
+ end
9
+ end
10
+ end
11
+ end
@@ -2,9 +2,7 @@ module MCollective
2
2
  module Validator
3
3
  class LengthValidator
4
4
  def self.validate(validator, length)
5
- if (validator.size > length) && (length > 0)
6
- raise ValidatorError, "Input string is longer than #{length} character(s)"
7
- end
5
+ raise ValidatorError, "Input string is longer than #{length} character(s)" if (validator.size > length) && (length > 0)
8
6
  end
9
7
  end
10
8
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: choria-mcorpc-support
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.21.1
4
+ version: 2.23.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - R.I.Pienaar
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-07-07 00:00:00.000000000 Z
11
+ date: 2021-01-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: systemu
@@ -54,7 +54,15 @@ files:
54
54
  - bin/mco
55
55
  - lib/mcollective.rb
56
56
  - lib/mcollective/agent.rb
57
+ - lib/mcollective/agent/bolt_tasks.ddl
58
+ - lib/mcollective/agent/bolt_tasks.json
59
+ - lib/mcollective/agent/bolt_tasks.rb
60
+ - lib/mcollective/agent/choria_util.ddl
61
+ - lib/mcollective/agent/choria_util.json
57
62
  - lib/mcollective/agent/rpcutil.ddl
63
+ - lib/mcollective/agent/rpcutil.json
64
+ - lib/mcollective/agent/scout.ddl
65
+ - lib/mcollective/agent/scout.json
58
66
  - lib/mcollective/agents.rb
59
67
  - lib/mcollective/aggregate.rb
60
68
  - lib/mcollective/aggregate/average.ddl
@@ -69,25 +77,33 @@ files:
69
77
  - lib/mcollective/aggregate/summary.ddl
70
78
  - lib/mcollective/aggregate/summary.rb
71
79
  - lib/mcollective/application.rb
80
+ - lib/mcollective/application/choria.rb
72
81
  - lib/mcollective/application/completion.rb
73
- - lib/mcollective/application/describe_filter.rb
74
82
  - lib/mcollective/application/facts.rb
83
+ - lib/mcollective/application/federation.rb
75
84
  - lib/mcollective/application/find.rb
76
85
  - lib/mcollective/application/help.rb
77
86
  - lib/mcollective/application/inventory.rb
78
87
  - lib/mcollective/application/ping.rb
88
+ - lib/mcollective/application/playbook.rb
79
89
  - lib/mcollective/application/plugin.rb
80
90
  - lib/mcollective/application/rpc.rb
91
+ - lib/mcollective/application/tasks.rb
81
92
  - lib/mcollective/applications.rb
93
+ - lib/mcollective/audit/choria.rb
82
94
  - lib/mcollective/cache.rb
83
95
  - lib/mcollective/client.rb
84
96
  - lib/mcollective/config.rb
85
97
  - lib/mcollective/connector.rb
86
98
  - lib/mcollective/connector/base.rb
99
+ - lib/mcollective/connector/nats.ddl
100
+ - lib/mcollective/connector/nats.rb
87
101
  - lib/mcollective/data.rb
88
102
  - lib/mcollective/data/agent_data.ddl
89
103
  - lib/mcollective/data/agent_data.rb
90
104
  - lib/mcollective/data/base.rb
105
+ - lib/mcollective/data/bolt_task_data.ddl
106
+ - lib/mcollective/data/bolt_task_data.rb
91
107
  - lib/mcollective/data/collective_data.ddl
92
108
  - lib/mcollective/data/collective_data.rb
93
109
  - lib/mcollective/data/fact_data.ddl
@@ -102,6 +118,8 @@ files:
102
118
  - lib/mcollective/ddl/discoveryddl.rb
103
119
  - lib/mcollective/ddl/validatorddl.rb
104
120
  - lib/mcollective/discovery.rb
121
+ - lib/mcollective/discovery/choria.ddl
122
+ - lib/mcollective/discovery/choria.rb
105
123
  - lib/mcollective/discovery/flatfile.ddl
106
124
  - lib/mcollective/discovery/flatfile.rb
107
125
  - lib/mcollective/discovery/mc.ddl
@@ -126,9 +144,6 @@ files:
126
144
  - lib/mcollective/logger/console_logger.rb
127
145
  - lib/mcollective/logger/file_logger.rb
128
146
  - lib/mcollective/logger/syslog_logger.rb
129
- - lib/mcollective/matcher.rb
130
- - lib/mcollective/matcher/parser.rb
131
- - lib/mcollective/matcher/scanner.rb
132
147
  - lib/mcollective/message.rb
133
148
  - lib/mcollective/monkey_patches.rb
134
149
  - lib/mcollective/optionparser.rb
@@ -158,12 +173,56 @@ files:
158
173
  - lib/mcollective/runnerstats.rb
159
174
  - lib/mcollective/security.rb
160
175
  - lib/mcollective/security/base.rb
176
+ - lib/mcollective/security/choria.rb
161
177
  - lib/mcollective/shell.rb
178
+ - lib/mcollective/signer/base.rb
179
+ - lib/mcollective/signer/choria.rb
162
180
  - lib/mcollective/ssl.rb
163
181
  - lib/mcollective/util.rb
182
+ - lib/mcollective/util/bolt_support.rb
183
+ - lib/mcollective/util/bolt_support/plan_runner.rb
184
+ - lib/mcollective/util/bolt_support/task_result.rb
185
+ - lib/mcollective/util/bolt_support/task_results.rb
186
+ - lib/mcollective/util/choria.rb
187
+ - lib/mcollective/util/indifferent_hash.rb
188
+ - lib/mcollective/util/natswrapper.rb
189
+ - lib/mcollective/util/playbook.rb
190
+ - lib/mcollective/util/playbook/data_stores.rb
191
+ - lib/mcollective/util/playbook/data_stores/base.rb
192
+ - lib/mcollective/util/playbook/data_stores/consul_data_store.rb
193
+ - lib/mcollective/util/playbook/data_stores/environment_data_store.rb
194
+ - lib/mcollective/util/playbook/data_stores/etcd_data_store.rb
195
+ - lib/mcollective/util/playbook/data_stores/file_data_store.rb
196
+ - lib/mcollective/util/playbook/data_stores/shell_data_store.rb
197
+ - lib/mcollective/util/playbook/inputs.rb
198
+ - lib/mcollective/util/playbook/nodes.rb
199
+ - lib/mcollective/util/playbook/nodes/mcollective_nodes.rb
200
+ - lib/mcollective/util/playbook/nodes/pql_nodes.rb
201
+ - lib/mcollective/util/playbook/nodes/shell_nodes.rb
202
+ - lib/mcollective/util/playbook/nodes/terraform_nodes.rb
203
+ - lib/mcollective/util/playbook/nodes/yaml_nodes.rb
204
+ - lib/mcollective/util/playbook/playbook_logger.rb
205
+ - lib/mcollective/util/playbook/puppet_logger.rb
206
+ - lib/mcollective/util/playbook/report.rb
207
+ - lib/mcollective/util/playbook/task_result.rb
208
+ - lib/mcollective/util/playbook/tasks.rb
209
+ - lib/mcollective/util/playbook/tasks/base.rb
210
+ - lib/mcollective/util/playbook/tasks/graphite_event_task.rb
211
+ - lib/mcollective/util/playbook/tasks/mcollective_task.rb
212
+ - lib/mcollective/util/playbook/tasks/shell_task.rb
213
+ - lib/mcollective/util/playbook/tasks/slack_task.rb
214
+ - lib/mcollective/util/playbook/tasks/webhook_task.rb
215
+ - lib/mcollective/util/playbook/template_util.rb
216
+ - lib/mcollective/util/playbook/uses.rb
217
+ - lib/mcollective/util/tasks_support.rb
218
+ - lib/mcollective/util/tasks_support/cli.rb
219
+ - lib/mcollective/util/tasks_support/default_formatter.rb
220
+ - lib/mcollective/util/tasks_support/json_formatter.rb
164
221
  - lib/mcollective/validator.rb
165
222
  - lib/mcollective/validator/array_validator.ddl
166
223
  - lib/mcollective/validator/array_validator.rb
224
+ - lib/mcollective/validator/bolt_task_name_validator.ddl
225
+ - lib/mcollective/validator/bolt_task_name_validator.rb
167
226
  - lib/mcollective/validator/ipv4address_validator.ddl
168
227
  - lib/mcollective/validator/ipv4address_validator.rb
169
228
  - lib/mcollective/validator/ipv6address_validator.ddl
@@ -1,87 +0,0 @@
1
- module MCollective
2
- class Application::Describe_filter<Application
3
- exclude_argument_sections "common", "rpc"
4
-
5
- description "Display human readable interpretation of filters"
6
-
7
- usage "mco describe_filter -S <filter> -F <filter> -C <filter>"
8
-
9
- def describe_s_filter(stack)
10
- indent = " "
11
- old_indent = " "
12
- puts "-S Query expands to the following instructions:"
13
- puts
14
- stack.each do |token|
15
- if token.keys[0] == "statement"
16
- if token.values[0] =~ /(<=|>=|=|=~|=)/
17
- op = $1
18
- k,v = token.values[0].split(op)
19
- puts indent + get_fact_string(k, v, op)
20
- else
21
- puts indent + get_class_string(token.values[0])
22
- end
23
- elsif token.keys[0] == "fstatement"
24
- v = token.values[0]
25
- result_string = indent + "Execute the Data Query '#{v["name"]}'"
26
- if v["params"]
27
- result_string += " with parameters (#{v["params"]})"
28
- end
29
- result_string += ". "
30
- result_string += "Check if the query's '#{v["value"]}' value #{v["operator"]} '#{v["r_compare"]}' "
31
- puts result_string
32
- elsif token.keys[0] == "("
33
- puts indent + "("
34
- old_indent = indent
35
- indent *= 2
36
- elsif token.keys[0] == ")"
37
- indent = old_indent
38
- puts indent + ")"
39
- else
40
- puts indent + token.keys[0].upcase
41
- end
42
- end
43
- end
44
-
45
- def describe_f_filter(facts)
46
- puts "-F filter expands to the following fact comparisons:"
47
- puts
48
- facts.each do |f|
49
- puts " " + get_fact_string(f[:fact], f[:value], f[:operator])
50
- end
51
- end
52
-
53
- def describe_c_filter(classes)
54
- puts "-C filter expands to the following class checks:"
55
- puts
56
- classes.each do |c|
57
- puts " " + get_class_string(c)
58
- end
59
- end
60
-
61
- def main
62
- if !(@options[:filter]["fact"].empty?)
63
- describe_f_filter(@options[:filter]["fact"])
64
- puts
65
- end
66
-
67
- if !(@options[:filter]["cf_class"].empty?)
68
- describe_c_filter(@options[:filter]["cf_class"])
69
- puts
70
- end
71
-
72
- if !(@options[:filter]["compound"].empty?)
73
- describe_s_filter(@options[:filter]["compound"][0])
74
- puts
75
- end
76
- end
77
-
78
- private
79
- def get_fact_string(fact, value, op)
80
- "Check if fact '#{fact}' #{op} '#{value}'"
81
- end
82
-
83
- def get_class_string(classname)
84
- "Check if class '#{classname}' is present on the host"
85
- end
86
- end
87
- end
@@ -1,220 +0,0 @@
1
- module MCollective
2
- # A parser and scanner that creates a stack machine for a simple
3
- # fact and class matching language used on the CLI to facilitate
4
- # a rich discovery language
5
- #
6
- # Language EBNF
7
- #
8
- # compound = ["("] expression [")"] {["("] expression [")"]}
9
- # expression = [!|not]statement ["and"|"or"] [!|not] statement
10
- # char = A-Z | a-z | < | > | => | =< | _ | - |* | / { A-Z | a-z | < | > | => | =< | _ | - | * | / | }
11
- # int = 0|1|2|3|4|5|6|7|8|9{|0|1|2|3|4|5|6|7|8|9|0}
12
- module Matcher
13
- require "mcollective/matcher/parser"
14
- require "mcollective/matcher/scanner"
15
-
16
- # Helper creates a hash from a function call string
17
- def self.create_function_hash(function_call)
18
- func_hash = {}
19
- f = ""
20
- func_parts = function_call.split(/(!=|>=|<=|<|>|=)/)
21
- func_hash["r_compare"] = func_parts.pop
22
- func_hash["operator"] = func_parts.pop
23
- func = func_parts.join
24
-
25
- # Deal with dots in function parameters and functions without dot values
26
- if func =~ /^.+\(.*\)$/
27
- f = func
28
- else
29
- func_parts = func.split(".")
30
- func_hash["value"] = func_parts.pop
31
- f = func_parts.join(".")
32
- end
33
-
34
- # Deal with regular expression matches
35
- if func_hash["r_compare"] =~ /^\/.*\/$/
36
- func_hash["operator"] = "=~" if func_hash["operator"] == "="
37
- func_hash["operator"] = "!=~" if func_hash["operator"] == "!="
38
- func_hash["r_compare"] = Regexp.new(func_hash["r_compare"].gsub(/^\/|\/$/, ""))
39
- # Convert = operators to == so they can be propperly evaluated
40
- elsif func_hash["operator"] == "="
41
- func_hash["operator"] = "=="
42
- end
43
-
44
- # Grab function name and parameters from left compare string
45
- func_hash["name"], func_hash["params"] = f.split("(")
46
- if func_hash["params"] == ")"
47
- func_hash["params"] = nil
48
- else
49
-
50
- # Walk the function parameters from the front and from the
51
- # back removing the first and last instances of single of
52
- # double qoutes. We do this to handle the case where params
53
- # contain escaped qoutes.
54
- func_hash["params"] = func_hash["params"].gsub(")", "")
55
- func_quotes = func_hash["params"].split(/('|")/)
56
-
57
- func_quotes.each_with_index do |item, i|
58
- if item =~ /'|"/
59
- func_quotes.delete_at(i)
60
- break
61
- end
62
- end
63
-
64
- func_quotes.reverse.each_with_index do |item, i|
65
- if item =~ /'|"/
66
- func_quotes.delete_at(func_quotes.size - i - 1)
67
- break
68
- end
69
- end
70
-
71
- func_hash["params"] = func_quotes.join
72
- end
73
-
74
- func_hash
75
- end
76
-
77
- # Returns the result of an executed function
78
- def self.execute_function(function_hash)
79
- # In the case where a data plugin isn't present there are two ways we can handle
80
- # the raised exception. The function result can either be false or the entire
81
- # expression can fail.
82
- #
83
- # In the case where we return the result as false it opens us op to unexpected
84
- # negation behavior.
85
- #
86
- # !foo('bar').name = bar
87
- #
88
- # In this case the user would expect discovery to match on all machines where
89
- # the name value of the foo function does not equal bar. If a non existent function
90
- # returns false then it is posible to match machines where the name value of the
91
- # foo function is bar.
92
- #
93
- # Instead we raise a DDLValidationError to prevent this unexpected behavior from
94
- # happening.
95
-
96
- result = Data.send(function_hash["name"], function_hash["params"])
97
-
98
- if function_hash["value"]
99
- begin
100
- eval_result = result.send(function_hash["value"])
101
- rescue
102
- # If data field has not been set we set the comparison result to nil
103
- eval_result = nil
104
- end
105
- return eval_result
106
- else
107
- return result
108
- end
109
- rescue NoMethodError
110
- Log.debug("cannot execute discovery function '#{function_hash['name']}'. data plugin not found")
111
- raise DDLValidationError
112
- end
113
-
114
- # Evaluates a compound statement
115
- def self.eval_compound_statement(expression)
116
- if expression.values.first =~ /^\//
117
- Util.has_cf_class?(expression.values.first)
118
- elsif expression.values.first =~ />=|<=|=|<|>/
119
- optype = expression.values.first.match(/>=|<=|=|<|>/)
120
- name, value = expression.values.first.split(optype[0])
121
- if value.split("")[0] == "/"
122
- optype = "=~"
123
- else
124
- optype[0] == "=" ? optype = "==" : optype = optype[0]
125
- end
126
-
127
- Util.has_fact?(name, value, optype).to_s
128
- else
129
- Util.has_cf_class?(expression.values.first)
130
- end
131
- end
132
-
133
- # Returns the result of an evaluated compound statement that
134
- # includes a function
135
- def self.eval_compound_fstatement(function_hash) # rubocop:disable Metrics/MethodLength
136
- l_compare = execute_function(function_hash)
137
- r_compare = function_hash["r_compare"]
138
- operator = function_hash["operator"]
139
-
140
- # Break out early and return false if the function returns nil
141
- return false if l_compare.nil?
142
-
143
- # Prevent unwanted discovery by limiting comparison operators
144
- # on Strings and Booleans
145
- if (l_compare.is_a?(String) || l_compare.is_a?(TrueClass) || l_compare.is_a?(FalseClass)) && function_hash["operator"].match(/<|>/)
146
- Log.debug("Cannot do > and < comparison on Booleans and Strings '#{l_compare} #{function_hash['operator']} #{function_hash['r_compare']}'")
147
- return false
148
- end
149
-
150
- # Prevent backticks in function parameters
151
- if function_hash["params"] =~ /`/
152
- Log.debug("Cannot use backticks in function parameters")
153
- return false
154
- end
155
-
156
- # Do a regex comparison if right compare string is a regex
157
- if operator =~ /(=~|!=~)/
158
- # Fail if left compare value isn't a string
159
- if l_compare.is_a?(String)
160
- result = l_compare.match(r_compare)
161
- # Flip return value for != operator
162
- if function_hash["operator"] == "!=~"
163
- return !result
164
- else
165
- return !!result
166
- end
167
- else
168
- Log.debug("Cannot do a regex check on a non string value.")
169
- return false
170
- end
171
- # Otherwise do a normal comparison while taking the type into account
172
- else
173
- if l_compare.is_a? String
174
- r_compare = r_compare.to_s
175
- elsif r_compare.is_a? String
176
- if l_compare.is_a? Numeric
177
- r_compare = r_compare.strip
178
- begin
179
- r_compare = Integer(r_compare)
180
- rescue ArgumentError # rubocop:disable Metrics/BlockNesting
181
- begin
182
- r_compare = Float(r_compare)
183
- rescue ArgumentError # rubocop:disable Metrics/BlockNesting
184
- raise(ArgumentError, "invalid numeric value: #{r_compare}")
185
- end
186
- end
187
- elsif l_compare.is_a?(TrueClass) || l_compare.is_a?(FalseClass)
188
- r_compare = r_compare.strip
189
- if r_compare == true.to_s # rubocop:disable Metrics/BlockNesting
190
- r_compare = true
191
- elsif r_compare == false.to_s # rubocop:disable Metrics/BlockNesting
192
- r_compare = false
193
- else
194
- raise(ArgumentError, "invalid boolean value: #{r_compare}")
195
- end
196
- end
197
- end
198
- operator = operator.strip
199
- if operator =~ /(?:(!=|<=|>=|<|>)|==?)/
200
- operator = $1 ? $1.to_sym : :==
201
- else
202
- raise(ArgumentError, "invalid operator: #{operator}")
203
- end
204
- result = l_compare.send(operator, r_compare)
205
- return result
206
- end
207
- end
208
-
209
- # Creates a callstack to be evaluated from a compound evaluation string
210
- def self.create_compound_callstack(call_string)
211
- callstack = Matcher::Parser.new(call_string).execution_stack
212
- callstack.each_with_index do |statement, i|
213
- if statement.keys.first == "fstatement"
214
- callstack[i]["fstatement"] = create_function_hash(statement.values.first)
215
- end
216
- end
217
- callstack
218
- end
219
- end
220
- end