tdi 0.1.6 → 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,38 @@
1
+ {
2
+ "app": {
3
+ "desc": "Test role",
4
+ "http": {
5
+ "globoesporte.globo.com": {
6
+ "match": "<html"
7
+ },
8
+
9
+ "http://globoesporte.com": {
10
+ "code": 301,
11
+ "expect_header": "Location: http://globoesporte.globo.com/"
12
+ },
13
+
14
+ "http://api.sde.globo.com/docs": {
15
+ "code" : 301
16
+ },
17
+
18
+ "https://api.sde.globo.com/path/to/resource": {
19
+ "code" : 401
20
+ },
21
+
22
+ "doesnotexist.globo.com": {},
23
+
24
+ "https://api.cartola.globo.com/mercado/status.json": {},
25
+
26
+ "https://api.cartola.globo.com/wrong-url": {},
27
+
28
+ "http://g1.globo.com": {
29
+ "code": 301,
30
+ "match": "<html"
31
+ },
32
+
33
+ "http://g1.globo.com/index.html": {
34
+ "match": "<html"
35
+ }
36
+ }
37
+ }
38
+ }
data/doc/json/ssh.json ADDED
@@ -0,0 +1,16 @@
1
+ {
2
+ "app": {
3
+ "desc": "Test role",
4
+ "ssh": {
5
+ "timeout": 7,
6
+
7
+ "u_remote@localhost": {
8
+ "local_user": "u_local"
9
+ },
10
+
11
+ "u_remote2@localhost": {
12
+ "local_user": ["u_local", "u_local2"]
13
+ }
14
+ }
15
+ }
16
+ }
data/helper/acl.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright (C) 2013-2014 Globo.com
2
+ # Copyright (C) 2013-2015 Globo.com
3
3
  #
4
4
 
5
5
  # This file is part of TDI.
@@ -17,13 +17,14 @@
17
17
  # You should have received a copy of the GNU General Public License
18
18
  # along with TDI. If not, see <http://www.gnu.org/licenses/>.
19
19
 
20
+ require_relative '../lib/util'
20
21
  require 'socket'
21
22
  require 'timeout'
22
23
  require 'resolv'
23
24
 
24
25
  class TDIPlan < TDI
25
- def acl(plan)
26
- plan.select { |key, val|
26
+ def acl(role_name, plan_name, plan_content)
27
+ plan_content.select { |key, val|
27
28
  val.is_a?(Hash)
28
29
  }.each_pair do |case_name, case_content|
29
30
  # Parse.
@@ -36,26 +37,36 @@ class TDIPlan < TDI
36
37
 
37
38
  # ACL.
38
39
  ports.each do |port|
40
+ # Initialize vars.
41
+ addr = nil
42
+ res_str = "#{host}:#{port}"
43
+ res_dict = {host: host, addr: addr, port: port, origin_network: origin_network(host)}
44
+
39
45
  begin
46
+ addr = Resolv.getaddress(host)
47
+ res_str = "#{host}/#{addr}:#{port}"
48
+ res_dict = {host: host, addr: addr, port: port, origin_network: origin_network(host)}
49
+
40
50
  timeout(timeout_limit) do
41
51
  begin
42
-
43
- Resolv.getaddress(host)
44
- sock = TCPSocket.open(host, port)
52
+ sock = TCPSocket.open(addr, port)
45
53
  sock.close
46
- success "ACL (#{user}): #{host}:#{port}"
47
- rescue Errno::ECONNREFUSED
48
- warning "ACL (#{user}): #{host}:#{port}"
49
- rescue Errno::ECONNRESET, Errno::ETIMEDOUT
50
- failure "ACL (#{user}): Connection Refused #{host}:#{port}"
51
- rescue Resolv::ResolvError => re
52
- failure "ACL (#{user}): #{re.message}"
53
- rescue Resolv::ResolvTimeout => rt
54
- failure "ACL (#{user}): #{rt.message}"
54
+ res_msg = "ACL (#{user}): #{res_str}"
55
+ success role_name, plan_name, res_msg, res_dict
56
+ rescue Errno::ECONNREFUSED, Errno::ECONNRESET => e
57
+ res_msg = "ACL (#{user}): #{res_str} (#{e.message})"
58
+ warning role_name, plan_name, res_msg, res_dict
59
+ rescue => e
60
+ res_msg = "ACL (#{user}): #{res_str} (#{e.message})"
61
+ failure role_name, plan_name, res_msg, res_dict
55
62
  end
56
63
  end
57
- rescue Timeout::Error
58
- failure "ACL (#{user}): Timed out (#{timeout_limit}s) #{host}:#{port}"
64
+ rescue Timeout::Error => e
65
+ res_msg = "ACL (#{user}): #{res_str} (Timed out (#{timeout_limit}s) #{e.message})"
66
+ failure role_name, plan_name, res_msg, res_dict
67
+ rescue => e
68
+ res_msg = "ACL (#{user}): #{res_str} (#{e.message})"
69
+ failure role_name, plan_name, res_msg, res_dict
59
70
  end
60
71
  end
61
72
  end
data/helper/file.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright (C) 2013-2014 Globo.com
2
+ # Copyright (C) 2013-2015 Globo.com
3
3
  #
4
4
 
5
5
  # This file is part of TDI.
@@ -21,8 +21,8 @@ require 'fileutils'
21
21
  require 'etc'
22
22
 
23
23
  class TDIPlan < TDI
24
- def file(plan)
25
- plan.select { |key, val|
24
+ def file(role_name, plan_name, plan_content)
25
+ plan_content.select { |key, val|
26
26
  val.is_a?(Hash)
27
27
  }.each_pair do |case_name, case_content|
28
28
  # Parse.
@@ -51,7 +51,7 @@ class TDIPlan < TDI
51
51
  exit 1
52
52
  end
53
53
 
54
- # Apply the test to a
54
+ # Apply permissions test.
55
55
  def testPerm filename, perm, type
56
56
  # Perm.
57
57
  begin
@@ -89,8 +89,7 @@ class TDIPlan < TDI
89
89
  else
90
90
  df_path = path
91
91
  end
92
- fs_location_query_cmd = "df -P #{df_path} | tail -n 1 | awk '{print $1}'"
93
- device = `#{fs_location_query_cmd}`
92
+ device = %x(df -P #{df_path} | tail -n 1 | awk '{print $1}')
94
93
 
95
94
  case location
96
95
  when 'local'
@@ -103,10 +102,12 @@ class TDIPlan < TDI
103
102
  end
104
103
 
105
104
  # Verdict.
105
+ res_msg = "FILE (#{user}): #{path} => #{perm} #{type} #{location}"
106
+ res_dict = case_content
106
107
  if @flag_success
107
- success "FILE (#{user}): #{path} => #{perm} #{type} #{location}"
108
+ success role_name, plan_name, res_msg, res_dict
108
109
  else
109
- failure "FILE (#{user}): #{path} => #{perm} #{type} #{location}"
110
+ failure role_name, plan_name, res_msg, res_dict
110
111
  end
111
112
  end
112
113
 
data/helper/http.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright (C) 2013-2014 Globo.com
2
+ # Copyright (C) 2013-2015 Globo.com
3
3
  #
4
4
 
5
5
  # This file is part of TDI.
@@ -17,125 +17,125 @@
17
17
  # You should have received a copy of the GNU General Public License
18
18
  # along with TDI. If not, see <http://www.gnu.org/licenses/>.
19
19
 
20
+ require_relative '../lib/util'
20
21
  require 'net/http'
21
- require "net/https"
22
+ require 'net/https'
22
23
  require 'timeout'
23
24
  require 'uri'
24
25
  require 'resolv'
25
26
 
26
27
  class TDIPlan < TDI
27
-
28
- def _parse(uri,params)
29
-
30
- # Normalizing
28
+ def _parse(uri, params)
29
+ # Normalizing.
31
30
  if not uri =~ /^https?:\/\//
32
- uri = 'http://' + uri.to_s
31
+ uri = 'http://' + uri.to_s
33
32
  end
34
33
 
35
- # URI
34
+ # URI.
36
35
  _uri = URI(uri)
37
- ssl = _uri.scheme.eql?("https")
36
+ ssl = _uri.scheme.eql?('https')
38
37
  host = _uri.host
39
38
  port = _uri.port
40
39
  path = _uri.path.empty? ? '/' : _uri.path
41
40
 
42
- # Params
41
+ # Params.
43
42
  code = params['code'].nil? ? 200 : params['code'].to_i
44
43
  match = params['match']
45
44
  expect_header = params['expect_header']
46
45
  timeout_limit = params['timeout'].nil? ? 2 : params['timeout'].to_i
47
46
 
48
47
  if not params['proxy'].nil?
49
- proxy_addr, proxy_port = params['proxy'].split(/:/)
50
- proxy_port = 3128 unless not proxy_port.nil?
48
+ proxy, proxy_port = params['proxy'].split(/:/)
49
+ proxy_port = 3128 unless not proxy_port.nil?
51
50
  end
52
51
 
53
52
  if not params['expect_header'].nil?
54
- expect_header_key = params['expect_header'].split(':').first
55
- expect_header_value = nil
56
- if params['expect_header'].include?(':')
57
- expect_header_value = params['expect_header'][params['expect_header'].index(':')+1..-1].strip
58
- end
53
+ expect_header_key = params['expect_header'].split(':').first
54
+ expect_header_value = nil
55
+ if params['expect_header'].include?(':')
56
+ expect_header_value = params['expect_header'][params['expect_header'].index(':')+1..-1].strip
57
+ end
59
58
  end
60
59
 
61
- return host, port, path, proxy_addr, proxy_port, code, match, expect_header_key, expect_header_value, ssl, timeout_limit
60
+ return host, port, path, proxy, proxy_port, code, match, expect_header_key, expect_header_value, ssl, timeout_limit
62
61
  end
63
62
 
64
- def http(plan)
65
- plan.select { |key, val|
63
+ def http(role_name, plan_name, plan_content)
64
+ plan_content.select { |key, val|
66
65
  val.is_a?(Hash)
67
- }.each_pair do |case_name,case_content|
68
-
69
- host, port, path, proxy_addr, proxy_port, code, match, expect_header_key, expect_header_value, ssl, timeout_limit = _parse(case_name,case_content)
66
+ }.each_pair do |case_name, case_content|
67
+ # Parse params.
68
+ host, port, path, proxy, proxy_port, code, match, expect_header_key, expect_header_value, ssl, timeout_limit = _parse(case_name, case_content)
70
69
 
71
- # User
70
+ # User.
72
71
  user = Etc.getpwuid(Process.euid).name
73
72
 
73
+ # Initialize vars.
74
+ addr = nil
75
+ proxy_addr = nil
76
+ res_str = case_name
77
+ res_dict = {url: case_name, origin_network: origin_network(host)}
74
78
  response = nil
75
79
 
76
- if not proxy_addr.nil? and not proxy_port.nil?
77
- begin
78
- Resolv.getaddress(proxy_addr)
79
- http = Net::HTTP::Proxy(proxy_addr, proxy_port)
80
+ begin
81
+ addr = Resolv.getaddress(host)
80
82
 
83
+ if not proxy.nil? and not proxy_port.nil?
84
+ proxy_addr = Resolv.getaddress(proxy)
85
+ http = Net::HTTP::Proxy(proxy, proxy_port)
81
86
  timeout(timeout_limit) do
82
87
  begin
83
- Resolv.getaddress(host)
84
- http.start(host,port,:use_ssl => ssl, :verify_mode => OpenSSL::SSL::VERIFY_NONE) { |http|
88
+ http.start(host, port, use_ssl: ssl, verify_mode: OpenSSL::SSL::VERIFY_NONE) { |http|
85
89
  response = http.get(path)
86
90
  }
87
- rescue Errno::ECONNREFUSED, Errno::ECONNRESET
88
- warning "HTTP (#{user}): #{case_name} - Connection reset or refused."
91
+ rescue Errno::ECONNREFUSED, Errno::ECONNRESET => e
92
+ res_msg = "HTTP (#{user}): #{res_str} (#{e.message})"
93
+ warning role_name, plan_name, res_msg, res_dict
89
94
  end
90
95
  end
91
- rescue Resolv::ResolvError => re
92
- failure "HTTP (#{user}): #{re.message}"
93
- rescue Resolv::ResolvTimeout => rt
94
- failure "HTTP (#{user}): #{rt.message}"
95
- rescue Timeout::Error
96
- failure "HTTP (#{user}): #{case_name} - Timed out (#{timeout_limit}s)."
97
- end
98
96
 
99
- else
100
- begin
101
- Resolv.getaddress(host)
97
+ else
102
98
  http = Net::HTTP.new(host, port)
103
-
104
99
  if ssl
105
- http.use_ssl = true
106
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE
100
+ http.use_ssl = true
101
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
107
102
  end
108
-
109
103
  timeout(timeout_limit) do
110
104
  begin
111
105
  http.start() { |http|
112
106
  response = http.get(path)
113
107
  }
114
- rescue Errno::ECONNREFUSED, Errno::ECONNRESET
115
- warning "HTTP (#{user}): #{case_name} - Connection reset or refused."
108
+ rescue Errno::ECONNREFUSED, Errno::ECONNRESET => e
109
+ res_msg = "HTTP (#{user}): #{res_str} (#{e.message})"
110
+ warning role_name, plan_name, res_msg, res_dict
116
111
  end
117
112
  end
118
- rescue Resolv::ResolvError => re
119
- failure "HTTP (#{user}): #{re.message}"
120
- rescue Resolv::ResolvTimeout => rt
121
- failure "HTTP (#{user}): #{rt.message}"
122
- rescue Timeout::Error
123
- failure "HTTP (#{user}): #{case_name} - Timed out."
124
113
  end
114
+ rescue Timeout::Error => e
115
+ res_msg = "HTTP (#{user}): #{res_str} (Timed out (#{timeout_limit}s) #{e.message})"
116
+ failure role_name, plan_name, res_msg, res_dict
117
+ rescue => e
118
+ res_msg = "HTTP (#{user}): #{res_str} (#{e.message})"
119
+ failure role_name, plan_name, res_msg, res_dict
125
120
  end
126
121
 
127
122
  if not response.nil?
128
- if not match.nil? and not response.body.chomp.include?(match.chomp)
129
- failure "HTTP (#{user}): #{case_name} - Expected string '#{match.chomp}'"
130
- elsif not expect_header_key.nil? and not expect_header_value.nil? and not response[expect_header_key].eql?(expect_header_value)
131
- failure "HTTP (#{user}): #{case_name} - Expected header with content '#{expect_header_key}: #{expect_header_value}'"
132
- elsif not expect_header_key.nil? and response[expect_header_key].nil?
133
- failure "HTTP (#{user}): #{case_name} - Expected header '#{expect_header_key}'"
134
- elsif not code.nil? and (response.code.to_i != code)
135
- failure "HTTP (#{user}): #{case_name} - Expected HTTP #{code}"
136
- else
137
- success "HTTP (#{user}): #{case_name}"
138
- end
123
+ if not match.nil? and not response.body.chomp.include?(match.chomp)
124
+ res_msg = "HTTP (#{user}): #{res_str} (Expect string '#{match.chomp}')"
125
+ failure role_name, plan_name, res_msg, res_dict
126
+ elsif not expect_header_key.nil? and not expect_header_value.nil? and not response[expect_header_key].eql?(expect_header_value)
127
+ res_msg = "HTTP (#{user}): #{res_str} (Expect header with content '#{expect_header_key}: #{expect_header_value}')"
128
+ failure role_name, plan_name, res_msg, res_dict
129
+ elsif not expect_header_key.nil? and response[expect_header_key].nil?
130
+ res_msg = "HTTP (#{user}): #{res_str} (Expect header '#{expect_header_key}')"
131
+ failure role_name, plan_name, res_msg, res_dict
132
+ elsif not code.nil? and (response.code.to_i != code)
133
+ res_msg = "HTTP (#{user}): #{res_str} (Expect HTTP response code #{code})"
134
+ failure role_name, plan_name, res_msg, res_dict
135
+ else
136
+ res_msg = "HTTP (#{user}): #{res_str}"
137
+ success role_name, plan_name, res_msg, res_dict
138
+ end
139
139
  end
140
140
  end
141
141
  end
data/helper/ssh.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright (C) 2013-2014 Globo.com
2
+ # Copyright (C) 2013-2015 Globo.com
3
3
  #
4
4
 
5
5
  # This file is part of TDI.
@@ -17,12 +17,13 @@
17
17
  # You should have received a copy of the GNU General Public License
18
18
  # along with TDI. If not, see <http://www.gnu.org/licenses/>.
19
19
 
20
+ require_relative '../lib/util'
20
21
  require 'net/ssh'
21
22
  require 'resolv'
22
23
 
23
24
  class TDIPlan < TDI
24
- def ssh(plan)
25
- plan.select { |key, val|
25
+ def ssh(role_name, plan_name, plan_content)
26
+ plan_content.select { |key, val|
26
27
  val.is_a?(Hash)
27
28
  }.each_pair do |case_name, case_content|
28
29
  # Validate.
@@ -35,6 +36,7 @@ class TDIPlan < TDI
35
36
  remote_user = case_name.split('@').first
36
37
  host = case_name.split('@').last
37
38
  local_users = [case_content['local_user']].flatten
39
+ timeout_limit = case_content['timeout'].nil? ? 5 : case_content['timeout'].to_i
38
40
 
39
41
  # Users.
40
42
  local_users.each do |local_user|
@@ -57,21 +59,30 @@ class TDIPlan < TDI
57
59
  exit 1
58
60
  end
59
61
 
62
+ # Initialize vars.
63
+ addr = nil
64
+ res_str = "#{remote_user}@#{host}"
65
+ res_dict = {local_user: local_user, remote_user: remote_user, host: host, addr: addr, origin_network: origin_network(host)}
66
+
60
67
  begin
61
- timeout(5) do
62
- Resolv.getaddress(host)
68
+ addr = Resolv.getaddress(host)
69
+ res_str = "#{remote_user}@#{host}/#{addr}"
70
+ res_dict = {local_user: local_user, remote_user: remote_user, host: host, addr: addr, origin_network: origin_network(host)}
71
+
72
+ timeout(timeout_limit) do
63
73
  ssh_session = Net::SSH.start(host,
64
74
  remote_user,
65
- :auth_methods => ['publickey'])
75
+ auth_methods: ['publickey'])
66
76
  ssh_session.close
67
- success "SSH (#{local_user}): #{remote_user}@#{host}"
77
+ res_msg = "SSH (#{local_user}): #{res_str}"
78
+ success role_name, plan_name, res_msg, res_dict
68
79
  end
69
- rescue Resolv::ResolvError => re
70
- failure "SSH (#{local_user}): #{re.message}"
71
- rescue Resolv::ResolvTimeout => rt
72
- failure "SSH (#{local_user}): #{rt.message}"
80
+ rescue Timeout::Error => e
81
+ res_msg = "SSH (#{local_user}): #{res_str} (Timed out (#{timeout_limit}s) #{e.message})"
82
+ failure role_name, plan_name, res_msg, res_dict
73
83
  rescue => e
74
- failure "SSH (#{local_user}): #{remote_user}@#{host} (#{e.message})"
84
+ res_msg = "SSH (#{local_user}): #{res_str} (#{e.message})"
85
+ failure role_name, plan_name, res_msg, res_dict
75
86
  end
76
87
  end
77
88
  end