choria-mcorpc-support 0.0.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 (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