choria-mcorpc-support 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (133) hide show
  1. checksums.yaml +7 -0
  2. data/bin/mco +64 -0
  3. data/lib/mcollective.rb +63 -0
  4. data/lib/mcollective/agent.rb +5 -0
  5. data/lib/mcollective/agents.rb +149 -0
  6. data/lib/mcollective/aggregate.rb +85 -0
  7. data/lib/mcollective/aggregate/average.ddl +33 -0
  8. data/lib/mcollective/aggregate/average.rb +29 -0
  9. data/lib/mcollective/aggregate/base.rb +40 -0
  10. data/lib/mcollective/aggregate/result.rb +9 -0
  11. data/lib/mcollective/aggregate/result/base.rb +25 -0
  12. data/lib/mcollective/aggregate/result/collection_result.rb +19 -0
  13. data/lib/mcollective/aggregate/result/numeric_result.rb +13 -0
  14. data/lib/mcollective/aggregate/sum.ddl +33 -0
  15. data/lib/mcollective/aggregate/sum.rb +18 -0
  16. data/lib/mcollective/aggregate/summary.ddl +33 -0
  17. data/lib/mcollective/aggregate/summary.rb +53 -0
  18. data/lib/mcollective/application.rb +365 -0
  19. data/lib/mcollective/application/completion.rb +104 -0
  20. data/lib/mcollective/application/describe_filter.rb +87 -0
  21. data/lib/mcollective/application/facts.rb +62 -0
  22. data/lib/mcollective/application/find.rb +23 -0
  23. data/lib/mcollective/application/help.rb +28 -0
  24. data/lib/mcollective/application/inventory.rb +344 -0
  25. data/lib/mcollective/application/ping.rb +82 -0
  26. data/lib/mcollective/application/plugin.rb +369 -0
  27. data/lib/mcollective/application/rpc.rb +111 -0
  28. data/lib/mcollective/applications.rb +134 -0
  29. data/lib/mcollective/cache.rb +145 -0
  30. data/lib/mcollective/client.rb +353 -0
  31. data/lib/mcollective/config.rb +245 -0
  32. data/lib/mcollective/connector.rb +18 -0
  33. data/lib/mcollective/connector/base.rb +26 -0
  34. data/lib/mcollective/data.rb +91 -0
  35. data/lib/mcollective/data/agent_data.ddl +22 -0
  36. data/lib/mcollective/data/agent_data.rb +17 -0
  37. data/lib/mcollective/data/base.rb +67 -0
  38. data/lib/mcollective/data/collective_data.ddl +20 -0
  39. data/lib/mcollective/data/collective_data.rb +9 -0
  40. data/lib/mcollective/data/fact_data.ddl +28 -0
  41. data/lib/mcollective/data/fact_data.rb +55 -0
  42. data/lib/mcollective/data/fstat_data.ddl +89 -0
  43. data/lib/mcollective/data/fstat_data.rb +56 -0
  44. data/lib/mcollective/data/result.rb +45 -0
  45. data/lib/mcollective/ddl.rb +113 -0
  46. data/lib/mcollective/ddl/agentddl.rb +253 -0
  47. data/lib/mcollective/ddl/base.rb +217 -0
  48. data/lib/mcollective/ddl/dataddl.rb +56 -0
  49. data/lib/mcollective/ddl/discoveryddl.rb +52 -0
  50. data/lib/mcollective/ddl/validatorddl.rb +6 -0
  51. data/lib/mcollective/discovery.rb +143 -0
  52. data/lib/mcollective/discovery/flatfile.ddl +11 -0
  53. data/lib/mcollective/discovery/flatfile.rb +48 -0
  54. data/lib/mcollective/discovery/mc.ddl +11 -0
  55. data/lib/mcollective/discovery/mc.rb +30 -0
  56. data/lib/mcollective/discovery/stdin.ddl +11 -0
  57. data/lib/mcollective/discovery/stdin.rb +68 -0
  58. data/lib/mcollective/exceptions.rb +28 -0
  59. data/lib/mcollective/facts.rb +39 -0
  60. data/lib/mcollective/facts/base.rb +100 -0
  61. data/lib/mcollective/facts/yaml_facts.rb +65 -0
  62. data/lib/mcollective/generators.rb +7 -0
  63. data/lib/mcollective/generators/agent_generator.rb +51 -0
  64. data/lib/mcollective/generators/base.rb +46 -0
  65. data/lib/mcollective/generators/data_generator.rb +51 -0
  66. data/lib/mcollective/generators/templates/action_snippet.erb +13 -0
  67. data/lib/mcollective/generators/templates/data_input_snippet.erb +7 -0
  68. data/lib/mcollective/generators/templates/ddl.erb +8 -0
  69. data/lib/mcollective/generators/templates/plugin.erb +7 -0
  70. data/lib/mcollective/log.rb +118 -0
  71. data/lib/mcollective/logger.rb +5 -0
  72. data/lib/mcollective/logger/base.rb +77 -0
  73. data/lib/mcollective/logger/console_logger.rb +61 -0
  74. data/lib/mcollective/logger/file_logger.rb +53 -0
  75. data/lib/mcollective/logger/syslog_logger.rb +53 -0
  76. data/lib/mcollective/matcher.rb +224 -0
  77. data/lib/mcollective/matcher/parser.rb +128 -0
  78. data/lib/mcollective/matcher/scanner.rb +241 -0
  79. data/lib/mcollective/message.rb +248 -0
  80. data/lib/mcollective/monkey_patches.rb +152 -0
  81. data/lib/mcollective/optionparser.rb +197 -0
  82. data/lib/mcollective/pluginmanager.rb +180 -0
  83. data/lib/mcollective/pluginpackager.rb +98 -0
  84. data/lib/mcollective/pluginpackager/agent_definition.rb +94 -0
  85. data/lib/mcollective/pluginpackager/debpackage_packager.rb +237 -0
  86. data/lib/mcollective/pluginpackager/modulepackage_packager.rb +127 -0
  87. data/lib/mcollective/pluginpackager/ospackage_packager.rb +59 -0
  88. data/lib/mcollective/pluginpackager/rpmpackage_packager.rb +180 -0
  89. data/lib/mcollective/pluginpackager/standard_definition.rb +69 -0
  90. data/lib/mcollective/pluginpackager/templates/debian/Makefile.erb +7 -0
  91. data/lib/mcollective/pluginpackager/templates/debian/changelog.erb +5 -0
  92. data/lib/mcollective/pluginpackager/templates/debian/compat.erb +1 -0
  93. data/lib/mcollective/pluginpackager/templates/debian/control.erb +15 -0
  94. data/lib/mcollective/pluginpackager/templates/debian/copyright.erb +8 -0
  95. data/lib/mcollective/pluginpackager/templates/debian/rules.erb +6 -0
  96. data/lib/mcollective/pluginpackager/templates/module/Modulefile.erb +5 -0
  97. data/lib/mcollective/pluginpackager/templates/module/README.md.erb +37 -0
  98. data/lib/mcollective/pluginpackager/templates/module/_manifest.pp.erb +9 -0
  99. data/lib/mcollective/pluginpackager/templates/redhat/rpm_spec.erb +63 -0
  100. data/lib/mcollective/registration/base.rb +91 -0
  101. data/lib/mcollective/rpc.rb +182 -0
  102. data/lib/mcollective/rpc/actionrunner.rb +158 -0
  103. data/lib/mcollective/rpc/agent.rb +374 -0
  104. data/lib/mcollective/rpc/audit.rb +38 -0
  105. data/lib/mcollective/rpc/client.rb +1066 -0
  106. data/lib/mcollective/rpc/helpers.rb +321 -0
  107. data/lib/mcollective/rpc/progress.rb +63 -0
  108. data/lib/mcollective/rpc/reply.rb +87 -0
  109. data/lib/mcollective/rpc/request.rb +86 -0
  110. data/lib/mcollective/rpc/result.rb +90 -0
  111. data/lib/mcollective/rpc/stats.rb +294 -0
  112. data/lib/mcollective/runnerstats.rb +90 -0
  113. data/lib/mcollective/security.rb +26 -0
  114. data/lib/mcollective/security/base.rb +244 -0
  115. data/lib/mcollective/shell.rb +126 -0
  116. data/lib/mcollective/ssl.rb +285 -0
  117. data/lib/mcollective/util.rb +579 -0
  118. data/lib/mcollective/validator.rb +85 -0
  119. data/lib/mcollective/validator/array_validator.ddl +7 -0
  120. data/lib/mcollective/validator/array_validator.rb +9 -0
  121. data/lib/mcollective/validator/ipv4address_validator.ddl +7 -0
  122. data/lib/mcollective/validator/ipv4address_validator.rb +16 -0
  123. data/lib/mcollective/validator/ipv6address_validator.ddl +7 -0
  124. data/lib/mcollective/validator/ipv6address_validator.rb +16 -0
  125. data/lib/mcollective/validator/length_validator.ddl +7 -0
  126. data/lib/mcollective/validator/length_validator.rb +11 -0
  127. data/lib/mcollective/validator/regex_validator.ddl +7 -0
  128. data/lib/mcollective/validator/regex_validator.rb +9 -0
  129. data/lib/mcollective/validator/shellsafe_validator.ddl +7 -0
  130. data/lib/mcollective/validator/shellsafe_validator.rb +13 -0
  131. data/lib/mcollective/validator/typecheck_validator.ddl +7 -0
  132. data/lib/mcollective/validator/typecheck_validator.rb +28 -0
  133. 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,7 @@
1
+ module MCollective
2
+ module Generators
3
+ require "mcollective/generators/base.rb"
4
+ require "mcollective/generators/data_generator.rb"
5
+ require "mcollective/generators/agent_generator.rb"
6
+ end
7
+ 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