dtk-node-agent 0.5.10

Sign up to get free protection for your applications and to get access to all the features.
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