dtk-node-agent 0.5.10

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 (62) hide show
  1. checksums.yaml +15 -0
  2. data/Gemfile +4 -0
  3. data/Gemfile.lock +18 -0
  4. data/README.md +42 -0
  5. data/bin/dtk-node-agent +16 -0
  6. data/dtk-node-agent.gemspec +38 -0
  7. data/lib/config/install.config +12 -0
  8. data/lib/dtk-node-agent/installer.rb +142 -0
  9. data/lib/dtk-node-agent/version.rb +3 -0
  10. data/mcollective_additions/plugins/README.md +1 -0
  11. data/mcollective_additions/plugins/v1.2/agent/discovery.rb +39 -0
  12. data/mcollective_additions/plugins/v1.2/agent/get_log_fragment.ddl +15 -0
  13. data/mcollective_additions/plugins/v1.2/agent/get_log_fragment.rb +79 -0
  14. data/mcollective_additions/plugins/v1.2/agent/git_access.ddl +9 -0
  15. data/mcollective_additions/plugins/v1.2/agent/git_access.rb +79 -0
  16. data/mcollective_additions/plugins/v1.2/agent/netstat.ddl +9 -0
  17. data/mcollective_additions/plugins/v1.2/agent/netstat.rb +34 -0
  18. data/mcollective_additions/plugins/v1.2/agent/puppet_apply.ddl +9 -0
  19. data/mcollective_additions/plugins/v1.2/agent/puppet_apply.rb +630 -0
  20. data/mcollective_additions/plugins/v1.2/agent/rpcutil.ddl +204 -0
  21. data/mcollective_additions/plugins/v1.2/agent/rpcutil.rb +101 -0
  22. data/mcollective_additions/plugins/v1.2/facts/pbuilder_facts.rb +35 -0
  23. data/mcollective_additions/plugins/v2.2/agent/dev_manager.ddl +9 -0
  24. data/mcollective_additions/plugins/v2.2/agent/dev_manager.rb +69 -0
  25. data/mcollective_additions/plugins/v2.2/agent/discovery.rb +39 -0
  26. data/mcollective_additions/plugins/v2.2/agent/dtk_node_agent_git_client.rb +94 -0
  27. data/mcollective_additions/plugins/v2.2/agent/execute_tests.ddl +9 -0
  28. data/mcollective_additions/plugins/v2.2/agent/execute_tests.rb +64 -0
  29. data/mcollective_additions/plugins/v2.2/agent/get_log_fragment.ddl +15 -0
  30. data/mcollective_additions/plugins/v2.2/agent/get_log_fragment.rb +79 -0
  31. data/mcollective_additions/plugins/v2.2/agent/git_access.ddl +9 -0
  32. data/mcollective_additions/plugins/v2.2/agent/git_access.rb +72 -0
  33. data/mcollective_additions/plugins/v2.2/agent/netstat.ddl +9 -0
  34. data/mcollective_additions/plugins/v2.2/agent/netstat.rb +34 -0
  35. data/mcollective_additions/plugins/v2.2/agent/ps.ddl +9 -0
  36. data/mcollective_additions/plugins/v2.2/agent/ps.rb +37 -0
  37. data/mcollective_additions/plugins/v2.2/agent/puppet_apply.ddl +9 -0
  38. data/mcollective_additions/plugins/v2.2/agent/puppet_apply.rb +633 -0
  39. data/mcollective_additions/plugins/v2.2/agent/puppet_cancel.ddl +10 -0
  40. data/mcollective_additions/plugins/v2.2/agent/puppet_cancel.rb +78 -0
  41. data/mcollective_additions/plugins/v2.2/agent/rpcutil.ddl +204 -0
  42. data/mcollective_additions/plugins/v2.2/agent/rpcutil.rb +101 -0
  43. data/mcollective_additions/plugins/v2.2/agent/sync_agent_code.ddl +10 -0
  44. data/mcollective_additions/plugins/v2.2/agent/sync_agent_code.rb +85 -0
  45. data/mcollective_additions/plugins/v2.2/agent/tail.ddl +11 -0
  46. data/mcollective_additions/plugins/v2.2/agent/tail.rb +67 -0
  47. data/mcollective_additions/plugins/v2.2/connector/r8stomp.rb +238 -0
  48. data/mcollective_additions/plugins/v2.2/connector/stomp.rb +349 -0
  49. data/mcollective_additions/plugins/v2.2/connector/stomp_em.rb +191 -0
  50. data/mcollective_additions/plugins/v2.2/facts/pbuilder_facts.rb +35 -0
  51. data/mcollective_additions/plugins/v2.2/security/sshkey.ddl +9 -0
  52. data/mcollective_additions/plugins/v2.2/security/sshkey.rb +362 -0
  53. data/mcollective_additions/server.cfg +22 -0
  54. data/puppet_additions/modules/r8/lib/puppet/type/r8_export_file.rb +53 -0
  55. data/puppet_additions/modules/r8/manifests/export_variable.rb +10 -0
  56. data/puppet_additions/puppet_lib_base/puppet/indirector/catalog/r8_storeconfig_backend.rb +48 -0
  57. data/puppet_additions/puppet_lib_base/puppet/indirector/r8_storeconfig_backend.rb +4 -0
  58. data/puppet_additions/puppet_lib_base/puppet/indirector/resource/r8_storeconfig_backend.rb +72 -0
  59. data/src/etc/init.d/ec2-run-user-data +95 -0
  60. data/src/etc/logrotate.d/mcollective +10 -0
  61. data/src/etc/logrotate.d/puppet +7 -0
  62. metadata +189 -0
@@ -0,0 +1,94 @@
1
+ require 'grit'
2
+ module DTK
3
+ module NodeAgent
4
+ class GitClient
5
+ def initialize(repo_dir,opts={})
6
+ @repo_dir = repo_dir
7
+ @grit_repo = (opts[:create] ? ::Grit::Repo.init(repo_dir) : ::Grit::Repo.new(repo_dir))
8
+ end
9
+
10
+ def clone_branch(remote_repo,branch,opts={})
11
+ git_command__remote_add(remote_repo,branch)
12
+ git_command__checkout(opts[:sha]||branch)
13
+ end
14
+
15
+ def pull_and_checkout_branch?(branch,opts={})
16
+ sha = opts[:sha]
17
+ #shortcut
18
+ return if sha and (sha == current_branch_or_head())
19
+
20
+ unless remote_branch_exists?(branch)
21
+ git_command__remote_branch_add(branch)
22
+ git_command__fetch()
23
+ end
24
+
25
+ if branch_exists?(branch)
26
+ git_command__pull(branch)
27
+ git_command__checkout(sha) if sha
28
+ else
29
+ git_command__checkout(sha||branch)
30
+ end
31
+ end
32
+
33
+ private
34
+ def git_command__remote_add(remote_repo,branch,remote_name=nil)
35
+ remote_name ||= default_remote()
36
+ git_command().remote(git_command_opts(),"add","-t", branch, "-f", remote_name, remote_repo)
37
+ end
38
+
39
+ def git_command__remote_branch_add(branch,remote_name=nil)
40
+ remote_name ||= default_remote()
41
+ git_command().remote(git_command_opts(),"set-branches", "--add", remote_name, branch)
42
+ end
43
+
44
+ def git_command__checkout(ref)
45
+ unless current_branch_or_head() == ref
46
+ git_command().checkout(git_command_opts(),ref)
47
+ end
48
+ end
49
+
50
+ def git_command__fetch(remote_name=nil)
51
+ remote_name ||= default_remote()
52
+ git_command().fetch(git_command_opts(),remote_name)
53
+ end
54
+
55
+ def git_command__pull(branch,remote_name=nil)
56
+ remote_name ||= default_remote()
57
+ git_command().pull(git_command_opts(),remote_name,branch)
58
+ end
59
+
60
+ def branch_exists?(branch)
61
+ @grit_repo.heads.find{|h|h.name == branch} ? true : nil
62
+ end
63
+
64
+ def remote_branch_exists?(branch,remote_name=nil)
65
+ remote_name ||= default_remote()
66
+ remote_branch = "#{remote_name}/#{branch}"
67
+ @grit_repo.remotes.find{|h|h.name == remote_branch} ? true : nil
68
+ end
69
+
70
+ def current_branch_or_head()
71
+ #this returns sha when detached head
72
+ if @grit_repo.head
73
+ @grit_repo.head.name
74
+ elsif @grit_repo.commit('HEAD')
75
+ @grit_repo.commit('HEAD').id
76
+ end
77
+ end
78
+
79
+ def default_remote()
80
+ 'origin'
81
+ end
82
+
83
+ def git_command_opts(opts={})
84
+ ret = {:raise => true, :timeout => 60}
85
+ ret.merge!(:chdir => @repo_dir) unless opts[:no_chdir]
86
+ end
87
+
88
+ def git_command()
89
+ @grit_repo.git
90
+ end
91
+ end
92
+ end
93
+ end
94
+
@@ -0,0 +1,9 @@
1
+ metadata :name => "component module tests executor",
2
+ :description => "Agent to executing component module infrastructure tests",
3
+ :author => "Reactor8",
4
+ :license => "",
5
+ :version => "",
6
+ :url => "",
7
+ :timeout => 10
8
+ action "execute_tests", :description => "execute all component module infrastructure tests" do
9
+ end
@@ -0,0 +1,64 @@
1
+ module MCollective
2
+ module Agent
3
+ class Execute_tests < RPC::Agent
4
+ def initialize()
5
+ super()
6
+ @log = Log.instance
7
+ end
8
+
9
+ action "execute_tests" do
10
+ #Get list of component modules that have spec tests
11
+ list_output=`ls /etc/puppet/modules/*/dtk/serverspec/spec/localhost/*/*_spec.rb`
12
+ regex_pattern=/modules\/(.+)\/dtk\/serverspec\/spec\/localhost\/(.+)\//
13
+ ModuleInfo = Struct.new(:module_name, :component_name)
14
+ modules_info = []
15
+
16
+ components = []
17
+ request[:components].each do |c|
18
+ if c.include? "::"
19
+ components << c.split("::").last
20
+ elsif c.include? "/"
21
+ components << c.split("/").last
22
+ else
23
+ components << c
24
+ end
25
+ end
26
+
27
+ list_output.each do |line|
28
+ match = line.match(regex_pattern)
29
+ components.each do |c|
30
+ if c.eql? match[2]
31
+ modules_info << ModuleInfo.new(match[1],match[2])
32
+ end
33
+ end
34
+ end
35
+
36
+ all_spec_results = []
37
+ #filter out redundant module info if any
38
+ modules_info = modules_info.uniq
39
+ modules_info.each do |module_info|
40
+ component_module = module_info[:module_name]
41
+ component = module_info[:component_name]
42
+
43
+ spec_results=`/opt/puppet-omnibus/embedded/bin/rspec /etc/puppet/modules/#{component_module}/dtk/serverspec/spec/localhost/#{component}/*_spec.rb --format j`
44
+ @log.info("Executing serverspec test: /etc/puppet/modules/#{component_module}/tests/serverspec/spec/localhost/#{component}/*_spec.rb")
45
+
46
+ spec_results_json = JSON.parse(spec_results)
47
+
48
+ spec_results_json['examples'].each do |spec|
49
+ spec_result = {}
50
+ spec_result.store(:module_name, component_module)
51
+ spec_result.store(:component_name, component)
52
+ spec_result.store(:test_result, spec['full_description'])
53
+ spec_result.store(:status, spec['status'])
54
+ all_spec_results << spec_result
55
+ end
56
+ end
57
+
58
+ reply[:data] = all_spec_results
59
+ reply[:pbuilderid] = Facts["pbuilderid"]
60
+ reply[:status] = :ok
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,15 @@
1
+ metadata :name => "get log fragment",
2
+ :description => "get log fragment",
3
+ :author => "Reactor8",
4
+ :license => "",
5
+ :version => "",
6
+ :url => "",
7
+ :timeout => 20
8
+ action "get", :description => "get log data fragment" do
9
+ display :always
10
+ %w{status error data pbuilderid}.each do |k|
11
+ output k.to_sym,
12
+ :description => k.capitalize,
13
+ :display_as => k.capitalize
14
+ end
15
+ end
@@ -0,0 +1,79 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+
4
+ module MCollective
5
+ #TODO: shoudl go in common area
6
+ LogFileHandles = {:task_id => Hash.new, :top_task_id => Hash.new}
7
+
8
+ module Agent
9
+ class Get_log_fragment < RPC::Agent
10
+ metadata :name => "get log fragment",
11
+ :description => "get log fragment",
12
+ :author => "Reactor8",
13
+ :license => "",
14
+ :version => "",
15
+ :url => "",
16
+ :timeout => 20
17
+ def initialize()
18
+ super()
19
+ @log = Log.instance
20
+ end
21
+ def get_action()
22
+ validate :key, String
23
+ validate :value, String
24
+ log_file_dir = "/var/log/puppet"
25
+ key = request[:key]
26
+ value = request[:value]
27
+ lines = get_log_fragment(log_file_dir,key,value)
28
+ pbuilderid = Facts["pbuilderid"]
29
+ if lines.nil?
30
+ error_msg = "Cannot find log fragment matching #{key}=#{value}"
31
+ error_response = {
32
+ :status => :failed,
33
+ :error => {
34
+ :message => error_msg
35
+ },
36
+ :pbuilderid => pbuilderid
37
+ }
38
+ @log.error(error_msg)
39
+ reply.data = error_response
40
+ else
41
+ ok_response = {
42
+ :status => :ok,
43
+ :data => lines,
44
+ :pbuilderid => pbuilderid
45
+ }
46
+ reply.data = ok_response
47
+ end
48
+ end
49
+ private
50
+ def get_log_fragment(log_file_dir,key,value)
51
+ #flush file if it is open
52
+ if file_handle = (LogFileHandles[key.to_sym]||{})[value]
53
+ file_handle.flush
54
+ end
55
+
56
+ delim = key.to_sym == :top_task_id ? "\\." : ":"
57
+ string_key = "#{key}:#{value.to_s}#{delim}"
58
+ ret = Array.new
59
+ matches = Dir["#{log_file_dir}/*.log"].grep(Regexp.new(string_key))
60
+ if matches.size == 0
61
+ return nil
62
+ end
63
+ matching_file = matches.size == 1 ?
64
+ matches.first :
65
+ #this finds teh most recent file
66
+ matches.map{|file|[file,File.mtime(file)]}.sort{|a,b|b[1]<=>a[1]}.first[0]
67
+ begin
68
+ f = File.open(matching_file)
69
+ until f.eof
70
+ ret << f.readline.chop
71
+ end
72
+ ensure
73
+ f.close
74
+ end
75
+ ret
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,9 @@
1
+ metadata :name => "git access",
2
+ :description => "Agent to enable git access",
3
+ :author => "Reactor8",
4
+ :license => "",
5
+ :version => "",
6
+ :url => "",
7
+ :timeout => 20
8
+ action "add_rsa_info", :description => "add ssh rsa info" do
9
+ end
@@ -0,0 +1,72 @@
1
+ module MCollective
2
+ module Agent
3
+ class Git_access < RPC::Agent
4
+ action "add_rsa_info" do
5
+ ssh_folder_path = '/root/.ssh'
6
+ rsa_path = "#{ssh_folder_path}/id_rsa"
7
+ rsa_pub_path = "#{ssh_folder_path}/id_rsa.pub"
8
+ known_hosts = "#{ssh_folder_path}/known_hosts"
9
+
10
+ begin
11
+ # validate request
12
+ validate_request(request)
13
+
14
+ #create private rsa file if needed
15
+ unless donot_create_file?(:private,rsa_path,request[:agent_ssh_key_private])
16
+ File.open(rsa_path,"w",0600){|f|f.print request[:agent_ssh_key_private]}
17
+ end
18
+
19
+ #create public rsa file if needed
20
+ unless donot_create_file?(:public,rsa_pub_path,request[:agent_ssh_key_public])
21
+ File.open(rsa_pub_path,"w"){|f|f.print request[:agent_ssh_key_public]}
22
+ end
23
+
24
+ #create or append if key not there
25
+ skip = nil
26
+ fp = request[:server_ssh_rsa_fingerprint]
27
+ if File.exists?(known_hosts)
28
+ fp_key = (fp =~ Regexp.new("^[|]1[|]([^=]+)=");$1)
29
+ if fp_key
30
+ fp_key_regexp = Regexp.new("^.1.#{fp_key}")
31
+ skip = !!File.open(known_hosts){|f|f.find{|line|line =~ fp_key_regexp}}
32
+ end
33
+ end
34
+ unless skip
35
+ File.open(known_hosts,"a"){|f|f.print request[:server_ssh_rsa_fingerprint]}
36
+ end
37
+
38
+ reply.data = { :status => :succeeded}
39
+ rescue Exception => e
40
+ reply.data = { :status => :failed, :error => {:message => e.message}}
41
+ end
42
+ end
43
+
44
+ #TODO: move to using mcollective vallidation on ddl
45
+ def validate_request(req)
46
+ required_params = [:agent_ssh_key_public, :agent_ssh_key_private, :server_ssh_rsa_fingerprint]
47
+ missing_params = []
48
+ required_params.each do |param|
49
+ missing_params << param if req[param].nil?
50
+ end
51
+
52
+ unless missing_params.empty?
53
+ raise "Request is missing required param(s): #{missing_params.join(',')} please review your request."
54
+ end
55
+ end
56
+
57
+ def donot_create_file?(type,path,content)
58
+ # raises exception if these files already exists and content differs
59
+ if File.exists?(path)
60
+ existing = File.open(path).read
61
+ if existing == content
62
+ true
63
+ else
64
+ raise "RSA #{type} key already exists and differs from one in payload"
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+
72
+
@@ -0,0 +1,9 @@
1
+ metadata :name => "netstat info",
2
+ :description => "Agent to get netstat info",
3
+ :author => "Reactor8",
4
+ :license => "",
5
+ :version => "",
6
+ :url => "",
7
+ :timeout => 2
8
+ action "get_tcp_udp", :description => "get tcp and udp info" do
9
+ end
@@ -0,0 +1,34 @@
1
+ module MCollective
2
+ module Agent
3
+ class Netstat < RPC::Agent
4
+ metadata :name => "netstat info",
5
+ :description => "Agent to get netstat info",
6
+ :author => "Reactor8",
7
+ :license => "",
8
+ :version => "",
9
+ :url => "",
10
+ :timeout => 2
11
+ action "get_tcp_udp" do
12
+ output = `netstat -nltpu`
13
+ results = output.scan(/(^[a-z0-9]+)\s+(\d)\s+(\d)\s+([0-9:.*]+)\s+([0-9:.*]+)\s+(LISTEN)?\s+([0-9a-zA-Z\/\-: ]+)/m)
14
+
15
+ netstat_result = []
16
+ results.each do |result|
17
+ netstat_packet = {}
18
+ netstat_packet.store(:protocol, result[0])
19
+ netstat_packet.store(:recv_q, result[1])
20
+ netstat_packet.store(:send_q, result[2])
21
+ netstat_packet.store(:local, result[3])
22
+ netstat_packet.store(:foreign, result[4])
23
+ netstat_packet.store(:state, result[5])
24
+ netstat_packet.store(:program, result[6].strip)
25
+ netstat_result << netstat_packet
26
+ end
27
+
28
+ reply[:data] = netstat_result
29
+ reply[:pbuilderid] = Facts["pbuilderid"]
30
+ reply[:status] = :ok
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,9 @@
1
+ metadata :name => "ps info",
2
+ :description => "Agent to get ps info (running processes)",
3
+ :author => "Reactor8",
4
+ :license => "",
5
+ :version => "",
6
+ :url => "",
7
+ :timeout => 2
8
+ action "get_ps", :description => "get running processes via ps" do
9
+ end
@@ -0,0 +1,37 @@
1
+ module MCollective
2
+ module Agent
3
+ class Ps < RPC::Agent
4
+ metadata :name => "ps info",
5
+ :description => "Agent to get ps info (running processes)",
6
+ :author => "Reactor8",
7
+ :license => "",
8
+ :version => "",
9
+ :url => "",
10
+ :timeout => 2
11
+ action "get_ps" do
12
+ output=`ps -ef`
13
+ output.gsub!(/^.+\]$/,'')
14
+ results = output.scan(/(\S+)[\s].*?(\S+)[\s].*?(\S+)[\s].*?(\S+)[\s].*?(\S+)[\s].*?(\S+)[\s].*?(\S+)[\s].*?(.+)/)
15
+ results.shift
16
+ ps_result = []
17
+ results.each do |result|
18
+ ps_packet = {}
19
+ ps_packet.store(:uid, result[0])
20
+ ps_packet.store(:pid, result[1])
21
+ ps_packet.store(:ppid, result[2])
22
+ ps_packet.store(:cpu, result[3])
23
+ ps_packet.store(:start_time, result[4])
24
+ ps_packet.store(:tty, result[5])
25
+ ps_packet.store(:time, result[6])
26
+ result[7] = (result[7][0...60].strip + '...') if result[7].strip.length > 60
27
+ ps_packet.store(:command, result[7])
28
+ ps_result << ps_packet
29
+ end
30
+
31
+ reply[:data] = ps_result
32
+ reply[:pbuilderid] = Facts["pbuilderid"]
33
+ reply[:status] = :ok
34
+ end
35
+ end
36
+ end
37
+ end