tdi 0.1.6 → 0.1.7

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.
@@ -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