cloud66_agent 1.3.1 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 51ef1d2f57617cdc1d773ba203a52f105f47437e
4
- data.tar.gz: 76ef024511f59e0182a94eb39e4466cb38a0070e
2
+ SHA256:
3
+ metadata.gz: c38dc8b98765dbcd9303528cc6ff8c57013613c1908b259e73c0b17d5f1327c7
4
+ data.tar.gz: 930f568ce197cf07f061f026af19231b6050486769450f617049449451b44e50
5
5
  SHA512:
6
- metadata.gz: dc9c0e1e78b71b067235a022b776d68122e03f6d412e4c1b7b9c2d9c3e0a559c6044a7544b7281993921b7811ad94a3da70121247a8a4a597d77c7de351793f9
7
- data.tar.gz: cb8c05474defa7dc3901c8dcb6dbeed028d1f7ee6f8ea52f59149ef602064bf22eaa74006adaf45b097228e2d7c85233b0880013744e5aa0972c9a18f6ac32aa
6
+ metadata.gz: 00c8fa84e68deea570a160aa7aa9eca9286312c35dad0b44e7700a7cb793f753a03f99f1a311be63aa666b918c1c9a1c42f7fc2d174386f9a6482f399cdd47fa
7
+ data.tar.gz: affeb9cb1ef085b1db0f8ff18e366b4e7e7af408c6fed305eb637587a46b315a22a9d7b9353288ed6fd741fda2331b16bb2eb7db7f00fb783339772f606c5854
data/.gitignore CHANGED
@@ -15,3 +15,4 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
+ .idea
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- ruby-2.4.4
1
+ ruby-2.4.5
@@ -7,7 +7,7 @@ Gem::Specification.new do |gem|
7
7
  gem.name = "cloud66_agent"
8
8
  gem.version = Cloud66::Utils::Version.current
9
9
  gem.platform = Gem::Platform::RUBY
10
- gem.date = '2018-04-10'
10
+ gem.date = '2019-03-27'
11
11
  gem.authors = ["Cloud 66"]
12
12
  gem.email = ['hello@cloud66.com']
13
13
  gem.licenses = ['MIT']
@@ -3,48 +3,54 @@ require 'cloud66_agent/utils/version'
3
3
  require 'cloud66_agent/utils/server'
4
4
 
5
5
  module Cloud66
6
- module Commands
7
- class Configure
8
- def self.perform(server_uid, cloud)
9
- begin
10
- if cloud.nil? || cloud.empty?
11
- # try figure it out
12
- $config.is_aws = Utils::VitalSigns.is_aws?
6
+ module Commands
7
+ class Configure
8
+ def self.perform(server_uid, cloud)
9
+ begin
10
+ if cloud.nil? || cloud.empty?
11
+ # try figure it out
12
+ $config.is_aws = Utils::VitalSigns.is_aws?
13
13
 
14
- if $config.is_aws
15
- $config.is_gc = false
16
- else
17
- # try figure it out
18
- $config.is_gc = Utils::VitalSigns.is_gc?
19
- end
20
- else
21
- # use the passed in value
22
- $config.is_aws = (cloud == 'aws')
14
+ if $config.is_aws
15
+ $config.is_gc = false
16
+ else
17
+ # try figure it out
18
+ $config.is_gc = Utils::VitalSigns.is_gc?
19
+ end
20
+ else
21
+ # use the passed in value
22
+ $config.is_aws = (cloud == 'aws')
23
23
 
24
- # use the passed in value
25
- $config.is_gc = (cloud == 'googlecloud')
26
- end
27
- data = {
28
- :timezone => Time.new.zone,
29
- :server_uid => server_uid,
30
- :version => Utils::Version.current,
31
- :system => Utils::VitalSigns.system_info }
24
+ # use the passed in value
25
+ $config.is_gc = (cloud == 'googlecloud')
26
+ end
27
+ data = {
28
+ :timezone => Time.new.zone,
29
+ :server_uid => server_uid,
30
+ :version => Utils::Version.current,
31
+ :system => Utils::VitalSigns.system_info}
32
32
 
33
- address_info = Utils::VitalSigns.address_info
34
- data = data.merge(address_info)
35
- rescue => exc
36
- data = { error: exc.message }
37
- end
38
- result = Utils::Server.send_configure data
39
- $config.agent_uid = result['agent_uid']
40
- $config.disabled = false
41
- $config.save
42
- exit 0
43
- rescue => exc
44
- $logger.error "Command \"configure\" failed: #{exc.message}"
45
- exit -1
46
- end
33
+ address_info = Utils::VitalSigns.address_info
34
+ data = data.merge(address_info)
35
+ rescue => exc
36
+ data = {error: exc.message}
37
+ end
38
+ result = Utils::Server.send_configure data
39
+ $config.agent_uid = result['agent_uid']
47
40
 
48
- end
49
- end
41
+ disk_warning_percent = result['disk_warning_percent']
42
+ $config.disk_warning_percent = disk_warning_percent.to_i unless disk_warning_percent.nil?
43
+ disk_critical_percent = result['disk_critical_percent']
44
+ $config.disk_critical_percent = disk_critical_percent.to_i unless disk_critical_percent.nil?
45
+
46
+ $config.disabled = false
47
+ $config.save
48
+ exit 0
49
+ rescue => exc
50
+ $logger.error "Command \"configure\" failed: #{exc.message}"
51
+ exit -1
52
+ end
53
+
54
+ end
55
+ end
50
56
  end
@@ -6,11 +6,11 @@ module Cloud66
6
6
  class Vitals
7
7
  def self.perform
8
8
  begin
9
- data = Utils::VitalSigns.vitals_info
9
+ data = Utils::VitalSigns.vitals_alerts
10
10
  rescue => exc
11
11
  data = { error: exc.message }
12
12
  end
13
- Utils::Server.send_vitals data
13
+ Utils::Server.send_vitals(data) if !data.nil? && !data.empty?
14
14
  exit 0
15
15
  rescue => exc
16
16
  $logger.error "Command \"vitals\" failed: #{exc.message}"
@@ -1,115 +1,125 @@
1
1
  require 'cloud66_agent/utils/vital_signs'
2
2
 
3
3
  module Cloud66
4
- module Utils
5
- class Config
6
-
7
- # default conf dir
8
- CONFIG_PATH = "/etc/cloud66/cloud66_agent.yml"
9
-
10
- attr_accessor :api_url,
11
- :api_key,
12
- :secret_key,
13
- :agent_uid,
14
- :disabled,
15
- :is_aws,
16
- :is_gc,
17
- :log,
18
- :log_level
19
-
20
- # load up the config at startup
21
- def initialize
22
- load if File.exists?(CONFIG_PATH)
23
-
24
- # set defaults
25
- @log = @log.nil? ? "/var/log/cloud66_agent.log" : @log == "STDOUT" ? STDOUT : @log
26
- @log_level ||= 2
27
- @api_url ||= 'https://api.cloud66.com'
28
- @disabled ||= false
29
- @is_aws ||= false
30
- @is_gc ||= false
31
- end
32
-
33
- def is_agent_configured?
34
- return !@agent_uid.nil? && !@agent_uid.empty?
35
- end
36
-
37
- def save
38
- Dir.mkdir(CONFIG_PATH) if !FileTest::directory?(File.dirname(CONFIG_PATH))
39
-
40
- File.open(CONFIG_PATH, 'w+') do |out|
41
- data = {
42
- 'api_url' => @api_url,
43
- 'api_key' => @api_key,
44
- 'secret_key' => @secret_key,
45
- 'agent_uid' => @agent_uid,
46
- 'disabled' => @disabled,
47
- 'is_aws' => @is_aws,
48
- 'is_gc' => @is_gc,
49
- 'log' => @log == STDOUT ? "STDOUT" : @log,
50
- 'log_level' => @log_level,
51
- }
52
- out.puts to_cust_yaml(data)
53
- end
54
- end
55
-
56
- def delete
57
- File.delete(CONFIG_PATH) if File.exists?(CONFIG_PATH)
58
- end
59
-
60
- private
61
-
62
- def load
63
- raise "config not found" unless File.exists?(CONFIG_PATH)
64
- config = from_cust_yaml(IO.read(CONFIG_PATH))
65
- @api_url = config['api_url']
66
- @api_key = config['api_key']
67
- @secret_key = config['secret_key']
68
- @agent_uid = config['agent_uid']
69
- @disabled = config['disabled']
70
- @is_aws = config['is_aws']
71
- @is_gc = config['is_gc']
72
- @log = config['log']
73
- @log_level = config['log_level']
74
- rescue
75
- # we can't load the file
76
- end
77
-
78
- # temporary measure to handle psych dependency errors
79
- def to_cust_yaml(hash)
80
- yaml_output = ''
81
- hash.each do |key, value|
82
- if !!value == value || value.is_a?(Integer)
83
- yaml_output += "#{key}: #{value.to_s}\n"
84
- else
85
- yaml_output += "#{key}: \"#{value.to_s}\"\n"
86
- end
87
- end
88
- return yaml_output
89
- end
90
-
91
- # temporary measure to handle psych dependency errors
92
- def from_cust_yaml(yaml)
93
- hash = {}
94
- yaml.lines.each do |line|
95
- next if line.nil? || !line.include?(':')
96
- key = line.split(':', 2)[0].strip
97
- value = line.split(':', 2)[1].strip
98
- next if value.empty?
99
-
100
- if value =~ /^(true|false)$/
101
- value = true if value == 'true'
102
- value = false if value == 'false'
103
- elsif value =~ /^[0-9]+$/
104
- value = value.to_i
105
- elsif value =~ /^".*"$/
106
- value = value.gsub(/^"/, '').gsub(/"$/,'')
107
- end
108
- hash[key] = value
109
- end
110
- return hash
111
- end
112
-
113
- end
114
- end
4
+ module Utils
5
+ class Config
6
+
7
+ # default conf dir
8
+ CONFIG_PATH = "/etc/cloud66/cloud66_agent.yml"
9
+
10
+ attr_accessor :api_url,
11
+ :api_key,
12
+ :secret_key,
13
+ :agent_uid,
14
+ :disabled,
15
+ :is_aws,
16
+ :is_gc,
17
+ :log,
18
+ :log_level,
19
+ :disk_warning_percent,
20
+ :disk_critical_percent
21
+
22
+ # load up the config at startup
23
+ def initialize
24
+ load if File.exists?(CONFIG_PATH)
25
+
26
+ # set defaults
27
+ @log = @log.nil? ? "/var/log/cloud66_agent.log" : @log == "STDOUT" ? STDOUT : @log
28
+ @log_level ||= 2
29
+ @api_url ||= 'https://api.cloud66.com'
30
+ @disabled ||= false
31
+ @is_aws ||= false
32
+ @is_gc ||= false
33
+
34
+ # defaults
35
+ @disk_warning_percent = 80
36
+ @disk_critical_percent = 90
37
+ end
38
+
39
+ def is_agent_configured?
40
+ return !@agent_uid.nil? && !@agent_uid.empty?
41
+ end
42
+
43
+ def save
44
+ Dir.mkdir(CONFIG_PATH) if !FileTest::directory?(File.dirname(CONFIG_PATH))
45
+
46
+ File.open(CONFIG_PATH, 'w+') do |out|
47
+ data = {
48
+ 'api_url' => @api_url,
49
+ 'api_key' => @api_key,
50
+ 'secret_key' => @secret_key,
51
+ 'agent_uid' => @agent_uid,
52
+ 'disabled' => @disabled,
53
+ 'is_aws' => @is_aws,
54
+ 'is_gc' => @is_gc,
55
+ 'log' => @log == STDOUT ? "STDOUT" : @log,
56
+ 'log_level' => @log_level,
57
+ 'disk_warning_percent' => @disk_warning_percent,
58
+ 'disk_critical_percent' => @disk_critical_percent,
59
+ }
60
+ out.puts to_cust_yaml(data)
61
+ end
62
+ end
63
+
64
+ def delete
65
+ File.delete(CONFIG_PATH) if File.exists?(CONFIG_PATH)
66
+ end
67
+
68
+ private
69
+
70
+ def load
71
+ raise "config not found" unless File.exists?(CONFIG_PATH)
72
+ config = from_cust_yaml(IO.read(CONFIG_PATH))
73
+ @api_url = config['api_url']
74
+ @api_key = config['api_key']
75
+ @secret_key = config['secret_key']
76
+ @agent_uid = config['agent_uid']
77
+ @disabled = config['disabled']
78
+ @is_aws = config['is_aws']
79
+ @is_gc = config['is_gc']
80
+ @log = config['log']
81
+ @log_level = config['log_level']
82
+ @disk_warning_percent = config['disk_warning_percent'].to_i if config['disk_warning_percent']
83
+ @disk_critical_percent = config['disk_critical_percent'].to_i if config['disk_critical_percent']
84
+ rescue
85
+ # we can't load the file
86
+ end
87
+
88
+ # temporary measure to handle psych dependency errors
89
+ def to_cust_yaml(hash)
90
+ yaml_output = ''
91
+ hash.each do |key, value|
92
+ if !!value == value || value.is_a?(Integer)
93
+ yaml_output += "#{key}: #{value.to_s}\n"
94
+ else
95
+ yaml_output += "#{key}: \"#{value.to_s}\"\n"
96
+ end
97
+ end
98
+ return yaml_output
99
+ end
100
+
101
+ # temporary measure to handle psych dependency errors
102
+ def from_cust_yaml(yaml)
103
+ hash = {}
104
+ yaml.lines.each do |line|
105
+ next if line.nil? || !line.include?(':')
106
+ key = line.split(':', 2)[0].strip
107
+ value = line.split(':', 2)[1].strip
108
+ next if value.empty?
109
+
110
+ if value =~ /^(true|false)$/
111
+ value = true if value == 'true'
112
+ value = false if value == 'false'
113
+ elsif value =~ /^[0-9]+$/
114
+ value = value.to_i
115
+ elsif value =~ /^".*"$/
116
+ value = value.gsub(/^"/, '').gsub(/"$/, '')
117
+ end
118
+ hash[key] = value
119
+ end
120
+ return hash
121
+ end
122
+
123
+ end
124
+ end
115
125
  end
@@ -2,92 +2,92 @@ require 'httparty'
2
2
  require 'json'
3
3
 
4
4
  module Cloud66
5
- module Utils
5
+ module Utils
6
6
 
7
- class Server
8
- include HTTParty
9
- # set the default request timeout to 45 seconds
10
- # this sets the open_timeout and the read_timeout
11
- default_timeout 45
7
+ class Server
8
+ include HTTParty
9
+ # set the default request timeout to 45 seconds
10
+ # this sets the open_timeout and the read_timeout
11
+ default_timeout 45
12
12
 
13
- def self.send_configure(data)
14
- process(do_request(:post, '/server/configure.json', build_content(data)))
15
- end
13
+ def self.send_configure(data)
14
+ process(do_request(:post, '/server/configure.json', build_content(data)))
15
+ end
16
16
 
17
- def self.send_pulse
18
- process(do_request(:get, "/server/#{$config.agent_uid}/pulse.json", build_content))
19
- end
17
+ def self.send_pulse
18
+ process(do_request(:get, "/server/#{$config.agent_uid}/pulse.json", build_content))
19
+ end
20
20
 
21
- def self.send_address(data)
22
- process(do_request(:post, "/server/#{$config.agent_uid}/address.json", build_content(data)))
23
- end
21
+ def self.send_address(data)
22
+ process(do_request(:post, "/server/#{$config.agent_uid}/address.json", build_content(data)))
23
+ end
24
24
 
25
- def self.send_vitals(data)
26
- process(do_request(:post, "/server/#{$config.agent_uid}/vitals.json", build_content(data)))
27
- end
25
+ def self.send_vitals(data)
26
+ process(do_request(:post, "/server/#{$config.agent_uid}/vitals_alerts.json", build_content(data)))
27
+ end
28
28
 
29
- def self.send_job_start(job_uid)
30
- process(do_request(:get, "/job/#{job_uid}/start.json", build_content))
31
- end
29
+ def self.send_job_start(job_uid)
30
+ process(do_request(:get, "/job/#{job_uid}/start.json", build_content))
31
+ end
32
32
 
33
- def self.send_job_end(job_uid, data)
34
- process(do_request(:post, "/job/#{job_uid}/end.json", build_content(data)))
35
- end
33
+ def self.send_job_end(job_uid, data)
34
+ process(do_request(:post, "/job/#{job_uid}/end.json", build_content(data)))
35
+ end
36
36
 
37
- def self.send_fail2ban(data)
38
- process(do_request(:post, "/server/#{$config.agent_uid}/fail2ban.json", build_content(data)))
39
- end
37
+ def self.send_fail2ban(data)
38
+ process(do_request(:post, "/server/#{$config.agent_uid}/fail2ban.json", build_content(data)))
39
+ end
40
40
 
41
- def self.send_message(data)
42
- #puts data
43
- process(do_request(:post, "/server/#{$config.agent_uid}/message.json", build_content(data)))
44
- end
41
+ def self.send_message(data)
42
+ #puts data
43
+ process(do_request(:post, "/server/#{$config.agent_uid}/message.json", build_content(data)))
44
+ end
45
45
 
46
- private
46
+ private
47
47
 
48
- def self.process(response)
49
- $logger.debug "Received response!"
50
- if response.code != 200
51
- $logger.debug "Response code: #{response.code}"
52
- $logger.debug "Response body: #{response.body}"
53
- raise response.body
54
- else
55
- parsed_response = response.parsed_response
56
- unless parsed_response['ok']
57
- if parsed_response['shut_down']
58
- $config.disabled = true
59
- $config.save
60
- exit 86
61
- elsif parsed_response.has_key?('error')
62
- raise parsed_response['error']
63
- else
64
- raise "unidentified error"
65
- end
66
- end
67
- $logger.debug "Parsed response: #{parsed_response}"
68
- parsed_response['data']
69
- end
70
- end
48
+ def self.process(response)
49
+ $logger.debug "Received response!"
50
+ if response.code != 200
51
+ $logger.debug "Response code: #{response.code}"
52
+ $logger.debug "Response body: #{response.body}"
53
+ raise response.body
54
+ else
55
+ parsed_response = response.parsed_response
56
+ unless parsed_response['ok']
57
+ if parsed_response['shut_down']
58
+ $config.disabled = true
59
+ $config.save
60
+ exit 86
61
+ elsif parsed_response.has_key?('error')
62
+ raise parsed_response['error']
63
+ else
64
+ raise "unidentified error"
65
+ end
66
+ end
67
+ $logger.debug "Parsed response: #{parsed_response}"
68
+ parsed_response['data']
69
+ end
70
+ end
71
71
 
72
- def self.do_request(verb, url, content)
73
- $logger.debug "Sending (#{verb}) request..."
74
- $logger.debug "Request url: #{url}"
75
- $logger.debug "Request content: #{content}"
76
- base_uri $config.api_url
77
- self.send verb, url, content
78
- end
72
+ def self.do_request(verb, url, content)
73
+ $logger.debug "Sending (#{verb}) request..."
74
+ $logger.debug "Request url: #{url}"
75
+ $logger.debug "Request content: #{content}"
76
+ base_uri $config.api_url
77
+ self.send verb, url, content
78
+ end
79
79
 
80
- def self.build_content(data = nil)
81
- time = Time.now.utc.to_i
82
- hash = Digest::SHA1.hexdigest("#{$config.api_key}#{$config.secret_key}#{time}").downcase
83
- if data.nil?
84
- content = { :headers => { 'api-key' => $config.api_key, 'hash' => hash, 'time' => time.to_s } }
85
- else
86
- content = { :headers => { 'api-key' => $config.api_key, 'hash' => hash, 'time' => time.to_s, 'Content-Type' => 'application/json' }, :body => { data: data }.to_json }
87
- end
88
- content
89
- end
80
+ def self.build_content(data = nil)
81
+ time = Time.now.utc.to_i
82
+ hash = Digest::SHA1.hexdigest("#{$config.api_key}#{$config.secret_key}#{time}").downcase
83
+ if data.nil?
84
+ content = {:headers => {'api-key' => $config.api_key, 'hash' => hash, 'time' => time.to_s}}
85
+ else
86
+ content = {:headers => {'api-key' => $config.api_key, 'hash' => hash, 'time' => time.to_s, 'Content-Type' => 'application/json'}, :body => {data: data}.to_json}
87
+ end
88
+ content
89
+ end
90
90
 
91
- end
92
- end
91
+ end
92
+ end
93
93
  end
@@ -13,7 +13,7 @@ module Cloud66
13
13
  # Defines the minor version
14
14
  # PATCH:
15
15
  # Defines the patch version
16
- MAJOR, MINOR, PATCH = 1, 3, 1
16
+ MAJOR, MINOR, PATCH = 1, 4, 0
17
17
 
18
18
  #ie. PRERELEASE_MODIFIER = 'beta1' or nil
19
19
  PRERELEASE_MODIFIER = nil
@@ -1,97 +1,123 @@
1
1
  module Cloud66
2
- module Utils
3
- class VitalSigns
2
+ module Utils
3
+ class VitalSigns
4
4
 
5
- IP_BLOCK_REGEX = /\d{,2}|1\d{2}|2[0-4]\d|25[0-5]/
6
- IP_REGEX = /\A#{IP_BLOCK_REGEX}\.#{IP_BLOCK_REGEX}\.#{IP_BLOCK_REGEX}\.#{IP_BLOCK_REGEX}\z/
5
+ IP_BLOCK_REGEX = /\d{,2}|1\d{2}|2[0-4]\d|25[0-5]/
6
+ IP_REGEX = /\A#{IP_BLOCK_REGEX}\.#{IP_BLOCK_REGEX}\.#{IP_BLOCK_REGEX}\.#{IP_BLOCK_REGEX}\z/
7
7
 
8
- def self.system_info
9
- # system info
10
- return parse_data(`facter`)
11
- end
12
8
 
13
- def self.address_info
14
- result = {}
15
- # AWS special case
16
- if $config.is_aws
17
- reported_ip = `/usr/bin/curl -s http://169.254.169.254/latest/meta-data/public-ipv4`
18
- result[:ext_ipv4] = reported_ip if reported_ip =~ /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/
19
- reported_ip = `/usr/bin/curl -s http://169.254.169.254/latest/meta-data/local-ipv4`
20
- result[:int_ipv4] = reported_ip if reported_ip =~ /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/
21
- # GC special case
22
- elsif $config.is_gc
23
- external_ip = `/usr/bin/curl -s -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/instance/network-interfaces/0/access-configs/0/external-ip`
24
- result[:ext_ipv4] = external_ip if external_ip =~ /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/
25
- internal_ip = `/usr/bin/curl -s -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/instance/network-interfaces/0/ip`
26
- result[:int_ipv4] = internal_ip if internal_ip =~ /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/
27
- else
28
- interfaces_raw = `facter interfaces`.strip
29
- interfaces = interfaces_raw.split(',').select { |interface| interface !~ /^lo/ }
30
- # don't have any ip address info
31
- unless interfaces.empty?
32
- # return all interface information
33
- facter_command = "facter #{interfaces.map { |interface| "ipaddress_#{interface} ipaddress6_#{interface}" }.join(' ')}"
34
- raw_data = `#{facter_command}`.strip
35
- result = parse_data(raw_data) rescue {}
36
- end
37
- end
38
- normalised_hash = {}
39
- result.each do |key, value|
40
- if value =~ IP_REGEX && value != '127.0.0.1' && value != '127.0.1.1'
41
- normalised_hash[key] = value
42
- end
43
- end
44
- return normalised_hash
45
- end
9
+ def self.system_info
10
+ # system info
11
+ return parse_data(`facter`)
12
+ end
46
13
 
47
- def self.is_aws?
48
- # 6 seconds to find out if this is a AWS image or not!
49
- instance = `/usr/bin/curl --connect-timeout 6 -s http://169.254.169.254/latest/meta-data/instance-id` rescue nil
50
- return false if instance.nil? || instance.empty?
14
+ def self.vitals_alerts
15
+ vitals_alerts = {}
16
+ space_alerts = calculate_space_alerts($config.disk_warning_percent, $config.disk_critical_percent)
17
+ vitals_alerts[:disk] = space_alerts if space_alerts.present?
18
+ return vitals_alerts
19
+ end
51
20
 
52
- # now check the external ip to make sure we're not just being routed
53
- reported_ip = `/usr/bin/curl -s http://169.254.169.254/latest/meta-data/public-ipv4` rescue nil
54
- return false if reported_ip.nil? || reported_ip.empty?
55
- return false unless reported_ip =~ /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/
21
+ def self.address_info
22
+ result = {}
23
+ # AWS special case
24
+ if $config.is_aws
25
+ reported_ip = `/usr/bin/curl -s http://169.254.169.254/latest/meta-data/public-ipv4`
26
+ result[:ext_ipv4] = reported_ip if reported_ip =~ /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/
27
+ reported_ip = `/usr/bin/curl -s http://169.254.169.254/latest/meta-data/local-ipv4`
28
+ result[:int_ipv4] = reported_ip if reported_ip =~ /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/
29
+ # GC special case
30
+ elsif $config.is_gc
31
+ external_ip = `/usr/bin/curl -s -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/instance/network-interfaces/0/access-configs/0/external-ip`
32
+ result[:ext_ipv4] = external_ip if external_ip =~ /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/
33
+ internal_ip = `/usr/bin/curl -s -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/instance/network-interfaces/0/ip`
34
+ result[:int_ipv4] = internal_ip if internal_ip =~ /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/
35
+ else
36
+ interfaces_raw = `facter interfaces`.strip
37
+ interfaces = interfaces_raw.split(',').select {|interface| interface !~ /^lo/}
38
+ # don't have any ip address info
39
+ unless interfaces.empty?
40
+ # return all interface information
41
+ facter_command = "facter #{interfaces.map {|interface| "ipaddress_#{interface} ipaddress6_#{interface}"}.join(' ')}"
42
+ raw_data = `#{facter_command}`.strip
43
+ result = parse_data(raw_data) rescue {}
44
+ end
45
+ end
46
+ normalised_hash = {}
47
+ result.each do |key, value|
48
+ if value =~ IP_REGEX && value != '127.0.0.1' && value != '127.0.1.1'
49
+ normalised_hash[key] = value
50
+ end
51
+ end
52
+ return normalised_hash
53
+ end
56
54
 
57
- # it is aws
58
- return true
59
- rescue => exc
60
- return false
61
- end
55
+ def self.is_aws?
56
+ # 6 seconds to find out if this is a AWS image or not!
57
+ instance = `/usr/bin/curl --connect-timeout 6 -s http://169.254.169.254/latest/meta-data/instance-id` rescue nil
58
+ return false if instance.nil? || instance.empty?
62
59
 
63
- def self.is_gc?
64
- # 6 seconds to find out if this is a AWS image or not!
65
- external_ip = `/usr/bin/curl --connect-timeout 6 -s -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/instance/network-interfaces/0/access-configs/0/external-ip` rescue nil
66
- return false if external_ip.nil? || external_ip.empty?
67
- return false unless external_ip =~ /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/
60
+ # now check the external ip to make sure we're not just being routed
61
+ reported_ip = `/usr/bin/curl -s http://169.254.169.254/latest/meta-data/public-ipv4` rescue nil
62
+ return false if reported_ip.nil? || reported_ip.empty?
63
+ return false unless reported_ip =~ /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/
68
64
 
69
- # it is google cloud
70
- return true
71
- rescue => exc
72
- return false
73
- end
65
+ # it is aws
66
+ return true
67
+ rescue => exc
68
+ return false
69
+ end
74
70
 
75
- private
71
+ def self.is_gc?
72
+ # 6 seconds to find out if this is a AWS image or not!
73
+ external_ip = `/usr/bin/curl --connect-timeout 6 -s -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/instance/network-interfaces/0/access-configs/0/external-ip` rescue nil
74
+ return false if external_ip.nil? || external_ip.empty?
75
+ return false unless external_ip =~ /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/
76
76
 
77
- # parse the data, not using YAML due to YAML parsing issues and JSON output not always working
78
- def self.parse_data(data)
79
- hash = {}
80
- data.lines.each do |line|
81
- split = line.split('=>')
82
- if split.size == 2
83
- key = split[0].strip rescue ''
84
- value = split[1].strip rescue ''
85
- if !value.nil? && value != 'nil'
86
- # exclude empty or long results (like ssh keys)
87
- if !value.empty? && value.size < 100
88
- hash[key] = value
89
- end
90
- end
91
- end
92
- end
93
- return hash
94
- end
95
- end
96
- end
77
+ # it is google cloud
78
+ return true
79
+ rescue => exc
80
+ return false
81
+ end
82
+
83
+ def self.calculate_space_alerts(warning_threshold, critical_threshold)
84
+ space_alerts = []
85
+ return space_alerts if warning_threshold == 0 || critical_threshold == 0
86
+ # get the df output (linux only)
87
+ df_output = `sudo df -h | grep -v /var/lib/docker | grep -v /var/lib/kubelet | grep -v Use% | awk '{print $1"|"$6"|"$5}'`
88
+ df_output.lines.each do |df_line|
89
+ parts = df_line.split('|')
90
+ next unless parts.size == 3
91
+ filesystem = parts[0].strip
92
+ mounted = parts[1].strip
93
+ percentage = parts[2].strip.gsub(/%/, '').to_i
94
+ if percentage >= critical_threshold
95
+ space_alerts << {level: :critical, filesystem: filesystem, mounted: mounted, percentage: percentage}
96
+ elsif percentage > warning_threshold
97
+ space_alerts << {level: :warning, filesystem: filesystem, mounted: mounted, percentage: percentage}
98
+ end
99
+ end
100
+ return space_alerts
101
+ end
102
+
103
+ # parse the data, not using YAML due to YAML parsing issues and JSON output not always working
104
+ def self.parse_data(data)
105
+ hash = {}
106
+ data.lines.each do |line|
107
+ split = line.split('=>')
108
+ if split.size == 2
109
+ key = split[0].strip rescue ''
110
+ value = split[1].strip rescue ''
111
+ if !value.nil? && value != 'nil'
112
+ # exclude empty or long results (like ssh keys)
113
+ if !value.empty? && value.size < 100
114
+ hash[key] = value
115
+ end
116
+ end
117
+ end
118
+ end
119
+ return hash
120
+ end
121
+ end
122
+ end
97
123
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cloud66_agent
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.1
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cloud 66
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-04-10 00:00:00.000000000 Z
11
+ date: 2019-03-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mime-types
@@ -160,7 +160,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
160
160
  version: '0'
161
161
  requirements: []
162
162
  rubyforge_project:
163
- rubygems_version: 2.6.14.1
163
+ rubygems_version: 2.7.9
164
164
  signing_key:
165
165
  specification_version: 4
166
166
  summary: Cloud 66 server component