choria-mcorpc-support 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/bin/mco +64 -0
- data/lib/mcollective.rb +63 -0
- data/lib/mcollective/agent.rb +5 -0
- data/lib/mcollective/agents.rb +149 -0
- data/lib/mcollective/aggregate.rb +85 -0
- data/lib/mcollective/aggregate/average.ddl +33 -0
- data/lib/mcollective/aggregate/average.rb +29 -0
- data/lib/mcollective/aggregate/base.rb +40 -0
- data/lib/mcollective/aggregate/result.rb +9 -0
- data/lib/mcollective/aggregate/result/base.rb +25 -0
- data/lib/mcollective/aggregate/result/collection_result.rb +19 -0
- data/lib/mcollective/aggregate/result/numeric_result.rb +13 -0
- data/lib/mcollective/aggregate/sum.ddl +33 -0
- data/lib/mcollective/aggregate/sum.rb +18 -0
- data/lib/mcollective/aggregate/summary.ddl +33 -0
- data/lib/mcollective/aggregate/summary.rb +53 -0
- data/lib/mcollective/application.rb +365 -0
- data/lib/mcollective/application/completion.rb +104 -0
- data/lib/mcollective/application/describe_filter.rb +87 -0
- data/lib/mcollective/application/facts.rb +62 -0
- data/lib/mcollective/application/find.rb +23 -0
- data/lib/mcollective/application/help.rb +28 -0
- data/lib/mcollective/application/inventory.rb +344 -0
- data/lib/mcollective/application/ping.rb +82 -0
- data/lib/mcollective/application/plugin.rb +369 -0
- data/lib/mcollective/application/rpc.rb +111 -0
- data/lib/mcollective/applications.rb +134 -0
- data/lib/mcollective/cache.rb +145 -0
- data/lib/mcollective/client.rb +353 -0
- data/lib/mcollective/config.rb +245 -0
- data/lib/mcollective/connector.rb +18 -0
- data/lib/mcollective/connector/base.rb +26 -0
- data/lib/mcollective/data.rb +91 -0
- data/lib/mcollective/data/agent_data.ddl +22 -0
- data/lib/mcollective/data/agent_data.rb +17 -0
- data/lib/mcollective/data/base.rb +67 -0
- data/lib/mcollective/data/collective_data.ddl +20 -0
- data/lib/mcollective/data/collective_data.rb +9 -0
- data/lib/mcollective/data/fact_data.ddl +28 -0
- data/lib/mcollective/data/fact_data.rb +55 -0
- data/lib/mcollective/data/fstat_data.ddl +89 -0
- data/lib/mcollective/data/fstat_data.rb +56 -0
- data/lib/mcollective/data/result.rb +45 -0
- data/lib/mcollective/ddl.rb +113 -0
- data/lib/mcollective/ddl/agentddl.rb +253 -0
- data/lib/mcollective/ddl/base.rb +217 -0
- data/lib/mcollective/ddl/dataddl.rb +56 -0
- data/lib/mcollective/ddl/discoveryddl.rb +52 -0
- data/lib/mcollective/ddl/validatorddl.rb +6 -0
- data/lib/mcollective/discovery.rb +143 -0
- data/lib/mcollective/discovery/flatfile.ddl +11 -0
- data/lib/mcollective/discovery/flatfile.rb +48 -0
- data/lib/mcollective/discovery/mc.ddl +11 -0
- data/lib/mcollective/discovery/mc.rb +30 -0
- data/lib/mcollective/discovery/stdin.ddl +11 -0
- data/lib/mcollective/discovery/stdin.rb +68 -0
- data/lib/mcollective/exceptions.rb +28 -0
- data/lib/mcollective/facts.rb +39 -0
- data/lib/mcollective/facts/base.rb +100 -0
- data/lib/mcollective/facts/yaml_facts.rb +65 -0
- data/lib/mcollective/generators.rb +7 -0
- data/lib/mcollective/generators/agent_generator.rb +51 -0
- data/lib/mcollective/generators/base.rb +46 -0
- data/lib/mcollective/generators/data_generator.rb +51 -0
- data/lib/mcollective/generators/templates/action_snippet.erb +13 -0
- data/lib/mcollective/generators/templates/data_input_snippet.erb +7 -0
- data/lib/mcollective/generators/templates/ddl.erb +8 -0
- data/lib/mcollective/generators/templates/plugin.erb +7 -0
- data/lib/mcollective/log.rb +118 -0
- data/lib/mcollective/logger.rb +5 -0
- data/lib/mcollective/logger/base.rb +77 -0
- data/lib/mcollective/logger/console_logger.rb +61 -0
- data/lib/mcollective/logger/file_logger.rb +53 -0
- data/lib/mcollective/logger/syslog_logger.rb +53 -0
- data/lib/mcollective/matcher.rb +224 -0
- data/lib/mcollective/matcher/parser.rb +128 -0
- data/lib/mcollective/matcher/scanner.rb +241 -0
- data/lib/mcollective/message.rb +248 -0
- data/lib/mcollective/monkey_patches.rb +152 -0
- data/lib/mcollective/optionparser.rb +197 -0
- data/lib/mcollective/pluginmanager.rb +180 -0
- data/lib/mcollective/pluginpackager.rb +98 -0
- data/lib/mcollective/pluginpackager/agent_definition.rb +94 -0
- data/lib/mcollective/pluginpackager/debpackage_packager.rb +237 -0
- data/lib/mcollective/pluginpackager/modulepackage_packager.rb +127 -0
- data/lib/mcollective/pluginpackager/ospackage_packager.rb +59 -0
- data/lib/mcollective/pluginpackager/rpmpackage_packager.rb +180 -0
- data/lib/mcollective/pluginpackager/standard_definition.rb +69 -0
- data/lib/mcollective/pluginpackager/templates/debian/Makefile.erb +7 -0
- data/lib/mcollective/pluginpackager/templates/debian/changelog.erb +5 -0
- data/lib/mcollective/pluginpackager/templates/debian/compat.erb +1 -0
- data/lib/mcollective/pluginpackager/templates/debian/control.erb +15 -0
- data/lib/mcollective/pluginpackager/templates/debian/copyright.erb +8 -0
- data/lib/mcollective/pluginpackager/templates/debian/rules.erb +6 -0
- data/lib/mcollective/pluginpackager/templates/module/Modulefile.erb +5 -0
- data/lib/mcollective/pluginpackager/templates/module/README.md.erb +37 -0
- data/lib/mcollective/pluginpackager/templates/module/_manifest.pp.erb +9 -0
- data/lib/mcollective/pluginpackager/templates/redhat/rpm_spec.erb +63 -0
- data/lib/mcollective/registration/base.rb +91 -0
- data/lib/mcollective/rpc.rb +182 -0
- data/lib/mcollective/rpc/actionrunner.rb +158 -0
- data/lib/mcollective/rpc/agent.rb +374 -0
- data/lib/mcollective/rpc/audit.rb +38 -0
- data/lib/mcollective/rpc/client.rb +1066 -0
- data/lib/mcollective/rpc/helpers.rb +321 -0
- data/lib/mcollective/rpc/progress.rb +63 -0
- data/lib/mcollective/rpc/reply.rb +87 -0
- data/lib/mcollective/rpc/request.rb +86 -0
- data/lib/mcollective/rpc/result.rb +90 -0
- data/lib/mcollective/rpc/stats.rb +294 -0
- data/lib/mcollective/runnerstats.rb +90 -0
- data/lib/mcollective/security.rb +26 -0
- data/lib/mcollective/security/base.rb +244 -0
- data/lib/mcollective/shell.rb +126 -0
- data/lib/mcollective/ssl.rb +285 -0
- data/lib/mcollective/util.rb +579 -0
- data/lib/mcollective/validator.rb +85 -0
- data/lib/mcollective/validator/array_validator.ddl +7 -0
- data/lib/mcollective/validator/array_validator.rb +9 -0
- data/lib/mcollective/validator/ipv4address_validator.ddl +7 -0
- data/lib/mcollective/validator/ipv4address_validator.rb +16 -0
- data/lib/mcollective/validator/ipv6address_validator.ddl +7 -0
- data/lib/mcollective/validator/ipv6address_validator.rb +16 -0
- data/lib/mcollective/validator/length_validator.ddl +7 -0
- data/lib/mcollective/validator/length_validator.rb +11 -0
- data/lib/mcollective/validator/regex_validator.ddl +7 -0
- data/lib/mcollective/validator/regex_validator.rb +9 -0
- data/lib/mcollective/validator/shellsafe_validator.ddl +7 -0
- data/lib/mcollective/validator/shellsafe_validator.rb +13 -0
- data/lib/mcollective/validator/typecheck_validator.ddl +7 -0
- data/lib/mcollective/validator/typecheck_validator.rb +28 -0
- metadata +215 -0
@@ -0,0 +1,11 @@
|
|
1
|
+
metadata :name => "flatfile",
|
2
|
+
:description => "Flatfile based discovery for node identities",
|
3
|
+
:author => "R.I.Pienaar <rip@devco.net>",
|
4
|
+
:license => "ASL 2.0",
|
5
|
+
:version => "0.1",
|
6
|
+
:url => "https://docs.puppetlabs.com/mcollective/",
|
7
|
+
:timeout => 0
|
8
|
+
|
9
|
+
discovery do
|
10
|
+
capabilities :identity
|
11
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# discovers against a flatfile instead of the traditional network discovery
|
2
|
+
# the flat file must have a node name per line which should match identities
|
3
|
+
# as configured
|
4
|
+
module MCollective
|
5
|
+
class Discovery
|
6
|
+
class Flatfile
|
7
|
+
def self.discover(filter, timeout, limit=0, client=nil)
|
8
|
+
unless client.options[:discovery_options].empty?
|
9
|
+
file = client.options[:discovery_options].first
|
10
|
+
else
|
11
|
+
raise "The flatfile discovery method needs a path to a text file"
|
12
|
+
end
|
13
|
+
|
14
|
+
raise "Cannot read the file %s specified as discovery source" % file unless File.readable?(file)
|
15
|
+
|
16
|
+
discovered = []
|
17
|
+
hosts = []
|
18
|
+
|
19
|
+
File.readlines(file).each do |host|
|
20
|
+
host = host.chomp.strip
|
21
|
+
if host.empty? || host.match(/^#/)
|
22
|
+
next
|
23
|
+
end
|
24
|
+
raise 'Identities can only match /^[\w\.\-]+$/' unless host.match(/^[\w\.\-]+$/)
|
25
|
+
hosts << host
|
26
|
+
end
|
27
|
+
|
28
|
+
# this plugin only supports identity filters, do regex matches etc against
|
29
|
+
# the list found in the flatfile
|
30
|
+
if !(filter["identity"].empty?)
|
31
|
+
filter["identity"].each do |identity|
|
32
|
+
identity = Regexp.new(identity.gsub("\/", "")) if identity.match("^/")
|
33
|
+
|
34
|
+
if identity.is_a?(Regexp)
|
35
|
+
discovered = hosts.grep(identity)
|
36
|
+
elsif hosts.include?(identity)
|
37
|
+
discovered << identity
|
38
|
+
end
|
39
|
+
end
|
40
|
+
else
|
41
|
+
discovered = hosts
|
42
|
+
end
|
43
|
+
|
44
|
+
discovered
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
metadata :name => "mc",
|
2
|
+
:description => "MCollective Broadcast based discovery",
|
3
|
+
:author => "R.I.Pienaar <rip@devco.net>",
|
4
|
+
:license => "ASL 2.0",
|
5
|
+
:version => "0.1",
|
6
|
+
:url => "https://docs.puppetlabs.com/mcollective/",
|
7
|
+
:timeout => 2
|
8
|
+
|
9
|
+
discovery do
|
10
|
+
capabilities [:classes, :facts, :identity, :agents, :compound]
|
11
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module MCollective
|
2
|
+
class Discovery
|
3
|
+
class Mc
|
4
|
+
def self.discover(filter, timeout, limit, client)
|
5
|
+
begin
|
6
|
+
hosts = []
|
7
|
+
Timeout.timeout(timeout) do
|
8
|
+
reqid = client.sendreq("ping", "discovery", filter)
|
9
|
+
Log.debug("Waiting #{timeout} seconds for discovery replies to request #{reqid}")
|
10
|
+
|
11
|
+
loop do
|
12
|
+
reply = client.receive(reqid)
|
13
|
+
Log.debug("Got discovery reply from #{reply.payload[:senderid]}")
|
14
|
+
hosts << reply.payload[:senderid]
|
15
|
+
|
16
|
+
return hosts if limit > 0 && hosts.size == limit
|
17
|
+
end
|
18
|
+
end
|
19
|
+
rescue Timeout::Error => e
|
20
|
+
rescue Exception => e
|
21
|
+
raise
|
22
|
+
ensure
|
23
|
+
client.unsubscribe("discovery", :reply)
|
24
|
+
end
|
25
|
+
|
26
|
+
hosts
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
metadata :name => "stdin",
|
2
|
+
:description => "STDIN based discovery for node identities",
|
3
|
+
:author => "Tomas Doran <bobtfish@bobtfish.net.net>",
|
4
|
+
:license => "ASL 2.0",
|
5
|
+
:version => "0.1",
|
6
|
+
:url => "https://docs.puppetlabs.com/mcollective/",
|
7
|
+
:timeout => 0
|
8
|
+
|
9
|
+
discovery do
|
10
|
+
capabilities :identity
|
11
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# discovers against stdin instead of the traditional network discovery
|
2
|
+
# the input must be a flat file with a node name per line which should match identities as configured,
|
3
|
+
# or it should be a json string as output by the -j option of mco rpc
|
4
|
+
require 'mcollective/rpc/helpers'
|
5
|
+
|
6
|
+
module MCollective
|
7
|
+
class Discovery
|
8
|
+
class Stdin
|
9
|
+
def self.discover(filter, timeout, limit=0, client=nil)
|
10
|
+
unless client.options[:discovery_options].empty?
|
11
|
+
type = client.options[:discovery_options].first.downcase
|
12
|
+
else
|
13
|
+
type = 'auto'
|
14
|
+
end
|
15
|
+
|
16
|
+
discovered = []
|
17
|
+
|
18
|
+
file = STDIN.read
|
19
|
+
|
20
|
+
if file =~ /^\s*$/
|
21
|
+
raise("data piped on STDIN contained only whitespace - could not discover hosts from it.")
|
22
|
+
end
|
23
|
+
|
24
|
+
if type == 'auto'
|
25
|
+
if file =~ /^\s*\[/
|
26
|
+
type = 'json'
|
27
|
+
else
|
28
|
+
type = 'text'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
Log.debug("Parsing STDIN input as type %s" % type)
|
33
|
+
|
34
|
+
if type == 'json'
|
35
|
+
hosts = RPC::Helpers.extract_hosts_from_json(file)
|
36
|
+
elsif type == 'text'
|
37
|
+
hosts = file.split("\n")
|
38
|
+
else
|
39
|
+
raise("stdin discovery plugin only knows the types auto/text/json, not \"#{type}\"")
|
40
|
+
end
|
41
|
+
|
42
|
+
hosts.map do |host|
|
43
|
+
raise 'Identities can only match /\w\.\-/' unless host.match(/^[\w\.\-]+$/)
|
44
|
+
host
|
45
|
+
end
|
46
|
+
|
47
|
+
# this plugin only supports identity filters, do regex matches etc against
|
48
|
+
# the list found in the flatfile
|
49
|
+
unless filter["identity"].empty?
|
50
|
+
filter["identity"].each do |identity|
|
51
|
+
identity = Regexp.new(identity.gsub("\/", "")) if identity.match("^/")
|
52
|
+
|
53
|
+
if identity.is_a?(Regexp)
|
54
|
+
discovered = hosts.grep(identity)
|
55
|
+
elsif hosts.include?(identity)
|
56
|
+
discovered << identity
|
57
|
+
end
|
58
|
+
end
|
59
|
+
else
|
60
|
+
discovered = hosts
|
61
|
+
end
|
62
|
+
|
63
|
+
discovered
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module MCollective
|
2
|
+
# Exceptions for the RPC system
|
3
|
+
class DDLValidationError<RuntimeError;end
|
4
|
+
class ValidatorError<RuntimeError; end
|
5
|
+
class ClientTimeoutError<RuntimeError; end
|
6
|
+
class MsgDoesNotMatchRequestID < RuntimeError; end
|
7
|
+
class MsgTTLExpired<RuntimeError;end
|
8
|
+
class NotTargettedAtUs<RuntimeError;end
|
9
|
+
class RPCError<StandardError;end
|
10
|
+
class SecurityValidationFailed<RuntimeError;end
|
11
|
+
|
12
|
+
class BackoffSuggestion<StandardError
|
13
|
+
attr_reader :backoff
|
14
|
+
|
15
|
+
def initialize(backoff = nil)
|
16
|
+
@backoff = backoff
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class MessageNotReceived<BackoffSuggestion; end
|
21
|
+
class UnexpectedMessageType<BackoffSuggestion; end
|
22
|
+
|
23
|
+
class InvalidRPCData<RPCError;end
|
24
|
+
class MissingRPCData<RPCError;end
|
25
|
+
class RPCAborted<RPCError;end
|
26
|
+
class UnknownRPCAction<RPCError;end
|
27
|
+
class UnknownRPCError<RPCError;end
|
28
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module MCollective
|
2
|
+
# This is a class that gives access to the configured fact provider
|
3
|
+
# such as MCollectives::Facts::Facter that uses Reductive Labs facter
|
4
|
+
#
|
5
|
+
# The actual provider is pluggable and configurable using the 'factsource'
|
6
|
+
# configuration option.
|
7
|
+
#
|
8
|
+
# To develop a new factsource simply create a class under MCollective::Facts::
|
9
|
+
# and provide the following classes:
|
10
|
+
#
|
11
|
+
# self.get_fact(fact)
|
12
|
+
# self.has_fact?(fact)
|
13
|
+
#
|
14
|
+
# You can also just inherit from MCollective::Facts::Base and provide just the
|
15
|
+
#
|
16
|
+
# self.get_facts
|
17
|
+
#
|
18
|
+
# method that should return a hash of facts.
|
19
|
+
module Facts
|
20
|
+
require "mcollective/facts/base"
|
21
|
+
|
22
|
+
@@config = nil
|
23
|
+
|
24
|
+
# True if we know of a specific fact else false
|
25
|
+
def self.has_fact?(fact, value)
|
26
|
+
PluginManager["facts_plugin"].get_fact(fact) == value ? true : false
|
27
|
+
end
|
28
|
+
|
29
|
+
# Get the value of a fact
|
30
|
+
def self.get_fact(fact)
|
31
|
+
PluginManager["facts_plugin"].get_fact(fact)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Get the value of a fact
|
35
|
+
def self.[](fact)
|
36
|
+
PluginManager["facts_plugin"].get_fact(fact)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
module MCollective
|
2
|
+
module Facts
|
3
|
+
# A base class for fact providers, to make a new fully functional fact provider
|
4
|
+
# inherit from this and simply provide a self.get_facts method that returns a
|
5
|
+
# hash like:
|
6
|
+
#
|
7
|
+
# {"foo" => "bar",
|
8
|
+
# "bar" => "baz"}
|
9
|
+
class Base
|
10
|
+
def initialize
|
11
|
+
@mutex = Mutex.new
|
12
|
+
@facts = {}
|
13
|
+
@last_good_facts = {}
|
14
|
+
@last_facts_load = 0
|
15
|
+
end
|
16
|
+
|
17
|
+
# Registers new fact sources into the plugin manager
|
18
|
+
def self.inherited(klass)
|
19
|
+
PluginManager << {:type => "facts_plugin", :class => klass.to_s}
|
20
|
+
end
|
21
|
+
|
22
|
+
# Returns the value of a single fact
|
23
|
+
def get_fact(fact=nil)
|
24
|
+
config = Config.instance
|
25
|
+
|
26
|
+
cache_time = config.fact_cache_time || 300
|
27
|
+
|
28
|
+
@mutex.synchronize do
|
29
|
+
begin
|
30
|
+
if (Time.now.to_i - @last_facts_load > cache_time.to_i ) || force_reload?
|
31
|
+
Log.debug("Resetting facter cache, now: #{Time.now.to_i} last-known-good: #{@last_facts_load}")
|
32
|
+
|
33
|
+
tfacts = load_facts_from_source
|
34
|
+
|
35
|
+
# Force reset to last known good state on empty facts
|
36
|
+
raise "Got empty facts" if tfacts.empty?
|
37
|
+
|
38
|
+
@facts = normalize_facts(tfacts)
|
39
|
+
|
40
|
+
@last_good_facts = @facts.clone
|
41
|
+
@last_facts_load = Time.now.to_i
|
42
|
+
else
|
43
|
+
Log.debug("Using cached facts now: #{Time.now.to_i} last-known-good: #{@last_facts_load}")
|
44
|
+
end
|
45
|
+
rescue Exception => e
|
46
|
+
Log.error("Failed to load facts: #{e.class}: #{e}")
|
47
|
+
|
48
|
+
# Avoid loops where failing fact loads cause huge CPU
|
49
|
+
# loops, this way it only retries once every cache_time
|
50
|
+
# seconds
|
51
|
+
@last_facts_load = Time.now.to_i
|
52
|
+
|
53
|
+
# Revert to last known good state
|
54
|
+
@facts = @last_good_facts.clone
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
# If you do not supply a specific fact all facts will be returned
|
60
|
+
if fact.nil?
|
61
|
+
return @facts
|
62
|
+
else
|
63
|
+
@facts.include?(fact) ? @facts[fact] : nil
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# Returns all facts
|
68
|
+
def get_facts
|
69
|
+
get_fact(nil)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Returns true if we know about a specific fact, false otherwise
|
73
|
+
def has_fact?(fact)
|
74
|
+
get_fact(nil).include?(fact)
|
75
|
+
end
|
76
|
+
|
77
|
+
# Plugins can override this to provide forced fact invalidation
|
78
|
+
def force_reload?
|
79
|
+
false
|
80
|
+
end
|
81
|
+
|
82
|
+
private
|
83
|
+
|
84
|
+
def normalize_facts(value)
|
85
|
+
case value
|
86
|
+
when Array
|
87
|
+
return value.map { |v| normalize_facts(v) }
|
88
|
+
when Hash
|
89
|
+
new_hash = {}
|
90
|
+
value.each do |k,v|
|
91
|
+
new_hash[k.to_s] = normalize_facts(v)
|
92
|
+
end
|
93
|
+
return new_hash
|
94
|
+
else
|
95
|
+
return value.to_s
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module MCollective
|
2
|
+
module Facts
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
# A factsource that reads a hash of facts from a YAML file
|
6
|
+
#
|
7
|
+
# Multiple files can be specified seperated with a : in the
|
8
|
+
# config file, they will be merged with later files overriding
|
9
|
+
# earlier ones in the list.
|
10
|
+
class Yaml_facts<Base
|
11
|
+
def initialize
|
12
|
+
@yaml_file_mtimes = {}
|
13
|
+
|
14
|
+
super
|
15
|
+
end
|
16
|
+
|
17
|
+
def load_facts_from_source
|
18
|
+
config = Config.instance
|
19
|
+
|
20
|
+
fact_files = config.pluginconf["yaml"].split(File::PATH_SEPARATOR)
|
21
|
+
facts = {}
|
22
|
+
|
23
|
+
fact_files.each do |file|
|
24
|
+
begin
|
25
|
+
if File.exist?(file)
|
26
|
+
if YAML.respond_to? :safe_load
|
27
|
+
facts.merge!(YAML.safe_load(File.read(file)))
|
28
|
+
else
|
29
|
+
facts.merge!(YAML.load(File.read(file))) # rubocop:disable Security/YAMLLoad
|
30
|
+
end
|
31
|
+
else
|
32
|
+
raise("Can't find YAML file to load: #{file}")
|
33
|
+
end
|
34
|
+
rescue Exception => e
|
35
|
+
Log.error("Failed to load yaml facts from #{file}: #{e.class}: #{e}")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
facts
|
40
|
+
end
|
41
|
+
|
42
|
+
# force fact reloads when the mtime on the yaml file change
|
43
|
+
def force_reload?
|
44
|
+
config = Config.instance
|
45
|
+
|
46
|
+
fact_files = config.pluginconf["yaml"].split(File::PATH_SEPARATOR)
|
47
|
+
|
48
|
+
fact_files.each do |file|
|
49
|
+
@yaml_file_mtimes[file] ||= File.stat(file).mtime
|
50
|
+
mtime = File.stat(file).mtime
|
51
|
+
|
52
|
+
if mtime > @yaml_file_mtimes[file]
|
53
|
+
@yaml_file_mtimes[file] = mtime
|
54
|
+
|
55
|
+
Log.debug("Forcing fact reload due to age of #{file}")
|
56
|
+
|
57
|
+
return true
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
false
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module MCollective
|
2
|
+
module Generators
|
3
|
+
class AgentGenerator<Base
|
4
|
+
|
5
|
+
attr_accessor :ddl, :content
|
6
|
+
|
7
|
+
def initialize(plugin_name, actions = [], name = nil, description = nil, author = nil ,
|
8
|
+
license = nil, version = nil, url = nil, timeout = nil)
|
9
|
+
|
10
|
+
super(name, description, author, license, version, url, timeout)
|
11
|
+
@plugin_name = plugin_name
|
12
|
+
@actions = actions || []
|
13
|
+
@ddl = create_ddl
|
14
|
+
@mod_name = "Agent"
|
15
|
+
@pclass = "RPC::Agent"
|
16
|
+
@content = create_plugin_content
|
17
|
+
@plugin = create_plugin_string
|
18
|
+
write_plugins
|
19
|
+
end
|
20
|
+
|
21
|
+
def create_ddl
|
22
|
+
action_text = ""
|
23
|
+
@actions.each_with_index do |action, i|
|
24
|
+
action_text += "action \"#{action}\", :description => \"%ACTIONDESCRIPTION%\" do\n"
|
25
|
+
action_text += action_help if i == 0
|
26
|
+
action_text += "end\n"
|
27
|
+
action_text += "\n" unless @actions.size == (i + 1)
|
28
|
+
end
|
29
|
+
# Use inherited method to create metadata part of the ddl
|
30
|
+
create_metadata_string + action_text
|
31
|
+
end
|
32
|
+
|
33
|
+
def create_plugin_content
|
34
|
+
content_text = ""
|
35
|
+
|
36
|
+
# Add actions to agent file
|
37
|
+
@actions.each_with_index do |action, i|
|
38
|
+
content_text += "%6s%s" % [" ", "action \"#{action}\" do\n"]
|
39
|
+
content_text += "%6s%s" % [" ", "end\n"]
|
40
|
+
content_text += "\n" unless @actions.size == (i + 1)
|
41
|
+
end
|
42
|
+
content_text
|
43
|
+
end
|
44
|
+
|
45
|
+
def action_help
|
46
|
+
action_snippet = File.read(File.join(File.dirname(__FILE__), "templates", "action_snippet.erb"))
|
47
|
+
ERB.new(action_snippet).result
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|