yle-newrelic_api_v2 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9151a614abbee9d5c5f34c66570b1a4d8601b528
4
+ data.tar.gz: 25aacb884bc37810b8cad27979887879a915ed5c
5
+ SHA512:
6
+ metadata.gz: 712a889db5bb3a5534c288918945dd0d48875da5074dda022cde892fe63611ed2b7ed45624bb397407692881b8c39c22b30f7f44c62f81eefbbbec6efb9b05d1
7
+ data.tar.gz: 43c1d5fa0bd08e93cc84278f457eb33897644f968be2826eae208b04991f762e776b634b8028c1c166afad961dac2dd5699a99f00ca739e7fe2dc214bf35fe36
@@ -0,0 +1,102 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'net/http'
4
+ require 'json'
5
+ require 'yaml'
6
+
7
+ require_relative 'yle-newrelic_api_v2/yle-newrelic_api_v2_user'
8
+ require_relative 'yle-newrelic_api_v2/yle-newrelic_api_v2_notification_channel'
9
+ require_relative 'yle-newrelic_api_v2/yle-newrelic_api_v2_alert_policy'
10
+ require_relative 'yle-newrelic_api_v2/yle-newrelic_api_v2_servers'
11
+
12
+ module Yle
13
+ module NewRelicApi
14
+ def get(params = {})
15
+ @endpoint.query = URI.encode_www_form(params)
16
+ Net::HTTP.start(@endpoint.host, @endpoint.port,
17
+ use_ssl: @endpoint.scheme == 'https') do |http|
18
+ request = Net::HTTP::Get.new @endpoint
19
+ request.add_field('X-Api-Key', @api_key)
20
+ response = http.request request
21
+ # raise HTTP Error, if response code is not 2XX
22
+ response.value
23
+ process_response_body(response)
24
+ end
25
+ end
26
+
27
+ def get_all_pages(params = {})
28
+ count = pages(params)
29
+ page = 1
30
+ while page <= count do
31
+ params['page'] = page
32
+ get(params)
33
+ page += 1
34
+ end
35
+ end
36
+
37
+ def pages(params = {})
38
+ response = nil
39
+ @endpoint.query = URI.encode_www_form(params)
40
+ Net::HTTP.start(@endpoint.host, @endpoint.port,
41
+ use_ssl: @endpoint.scheme == 'https') do |http|
42
+ request = Net::HTTP::Get.new @endpoint
43
+ request.add_field('X-Api-Key', @api_key)
44
+ response = http.request request
45
+ # raise HTTP Error, if response code is not 2XX
46
+ response.value
47
+ end
48
+ last_page(response)
49
+ end
50
+
51
+ def put(params, endpoint)
52
+ uri = URI("https://api.newrelic.com/v2/#{endpoint}.json")
53
+ Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
54
+ request = Net::HTTP::Put.new uri
55
+ request.add_field('X-Api-Key', @api_key)
56
+ request.add_field('Content-Type', 'application/json')
57
+ request.body = params.to_json
58
+ response = http.request request
59
+ # raise HTTP Error, if response code is not 2XX
60
+ response.value
61
+ end
62
+ end
63
+
64
+ def clear
65
+ @data.clear
66
+ end
67
+
68
+ def last_page(response)
69
+ return 1 unless response.key?('Link')
70
+ m = response['Link'].match(/<http.*\?page=(\d+)>; rel="last"/)
71
+ return 1 unless m
72
+ m[1].to_i
73
+ end
74
+
75
+ def get_next_page_number(response)
76
+ m = response['Link'].match(/<http.*\?page=(\d+)>; rel="next"/)
77
+ m[1].to_i
78
+ end
79
+
80
+ def delete(endpoint)
81
+ uri = URI(endpoint)
82
+ Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
83
+ request = Net::HTTP::Delete.new uri
84
+ request.add_field('X-Api-Key', @api_key)
85
+ response = http.request request
86
+ # raise HTTP Error, if response code is not 2XX
87
+ response.value
88
+ end
89
+ end
90
+
91
+ private
92
+
93
+ def process_response_body(response)
94
+ # check that response has a body
95
+ if response.class.body_permitted?
96
+ @data << response.body
97
+ else
98
+ raise "Empty response from New Relic API:\n\n #{response}"
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,118 @@
1
+ require_relative '../yle-newrelic_api_v2'
2
+ require_relative 'yle-newrelic_api_v2_notification_channel'
3
+
4
+ module Yle
5
+ module NewRelicApi
6
+ class AlertPolicy
7
+ include Yle::NewRelicApi
8
+
9
+ def initialize(api_key)
10
+ @api_key = api_key
11
+ @data = []
12
+ @endpoint = URI('https://api.newrelic.com/v2/alert_policies.json')
13
+ end
14
+
15
+ def get_alert_policy_id(name)
16
+ hits = []
17
+ @data.each do |d|
18
+ j = JSON.parse(d)
19
+ matches = j['alert_policies'].select { |policy| policy['name'] == name }
20
+ hits << matches unless matches.empty?
21
+ end
22
+ hits[0][0]['id']
23
+ end
24
+
25
+ def get_alert_policy(policy_id)
26
+ hits = []
27
+ @data.each do |d|
28
+ j = JSON.parse(d)
29
+ matches = j['alert_policies'].select { |policy| policy['id'] == policy_id }
30
+ hits << matches unless matches.empty?
31
+ end
32
+ hits[0][0]
33
+ end
34
+
35
+ def generate_alert_policy(config, policy_id)
36
+ policy = get_alert_policy(policy_id)
37
+
38
+ config['conditions'].each do |item|
39
+ policy['conditions'].each do |alert|
40
+ update_alert(item, alert)
41
+ end
42
+ end
43
+
44
+ update_notification_channel(policy, config)
45
+ policy
46
+ end
47
+
48
+ private
49
+
50
+ def update_alert(item, alert)
51
+ type = item[0]
52
+
53
+ if alert['type'] == 'server_downtime' && type == 'server_downtime'
54
+ downtime = item[1]['downtime']
55
+ alert['trigger_minutes'] = downtime['trigger_minutes']
56
+ alert['enabled'] = downtime['enabled']
57
+ elsif alert['type'] == type
58
+ critical = item[1]['critical']
59
+ caution = item[1]['caution']
60
+
61
+ if alert['severity'] == 'critical'
62
+ alert['threshold'] = critical['threshold']
63
+ alert['trigger_minutes'] = critical['trigger_minutes']
64
+ elsif alert['severity'] == 'caution'
65
+ alert['threshold'] = caution['threshold']
66
+ alert['trigger_minutes'] = caution['trigger_minutes']
67
+ else
68
+ raise "Unknown severity level #{alert['severity']}"
69
+ end
70
+ end
71
+ end
72
+
73
+ def update_notification_channel(policy, config)
74
+ notification_channels_params = { 'format' => 'JSON' }
75
+ channel_client = Yle::NewRelicApi::NotificationChannel.new(@api_key)
76
+ channel_client.get_all_pages(notification_channels_params)
77
+
78
+ # empty notification channels
79
+ policy['links']['notification_channels'].clear
80
+
81
+ config['notification_channels'].each do |item|
82
+ type = item[0]
83
+ values = item[1]
84
+
85
+ case type
86
+ when 'email'
87
+ values.each do |v|
88
+ policy['links']['notification_channels'] << channel_client.get_email_id(v)
89
+ end
90
+ when 'webhook'
91
+ values.each do |v|
92
+ policy['links']['notification_channels'] << channel_client.get_webhook_id(v)
93
+ end
94
+ when 'notification_group'
95
+ values.each do |v|
96
+ policy['links']['notification_channels'] << channel_client.get_group_id(v)
97
+ end
98
+ when 'pager_duty'
99
+ values.each do |v|
100
+ policy['links']['notification_channels'] << channel_client.get_pager_duty_id(v)
101
+ end
102
+ when 'hipchat'
103
+ values.each do |v|
104
+ policy['links']['notification_channels'] << channel_client.get_hipchat_id(v)
105
+ end
106
+ when 'user'
107
+ values.each do |v|
108
+ policy['links']['notification_channels'] << channel_client.get_user_id(v)
109
+ end
110
+ else
111
+ raise "Unknown notification channel type #{type}"
112
+ end
113
+ end
114
+ policy
115
+ end
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,132 @@
1
+ require_relative '../yle-newrelic_api_v2'
2
+ require_relative 'yle-newrelic_api_v2_user'
3
+
4
+ module Yle
5
+ module NewRelicApi
6
+ class NotificationChannel
7
+ include Yle::NewRelicApi
8
+
9
+ def initialize(api_key)
10
+ @api_key = api_key
11
+ @data = []
12
+ @endpoint = URI('https://api.newrelic.com/v2/notification_channels.json')
13
+ end
14
+
15
+ def get_group_id(name)
16
+ matches = get_id(name)
17
+ if matches.nil?
18
+ raise "Did not find any notification groups with name #{name}"
19
+ elsif matches.length > 1
20
+ raise "Found multiple matches for notification group name: #{matches}"
21
+ else
22
+ return matches[0]['id']
23
+ end
24
+ end
25
+
26
+ def get_email_id(name)
27
+ matches = get_id_for_email(name)
28
+ if matches.empty?
29
+ raise "Did not find any emails with name #{name}"
30
+ elsif matches.length > 1
31
+ raise "Found multiple matches for email: #{matches}"
32
+ else
33
+ return matches[0]['id']
34
+ end
35
+ end
36
+
37
+ def get_webhook_id(name)
38
+ matches = get_id(name)
39
+ if matches.nil?
40
+ raise "Did not find any webhooks with name #{name}"
41
+ elsif matches.length > 1
42
+ raise "Found multiple matches for webhook: #{matches}"
43
+ else
44
+ return matches[0]['id']
45
+ end
46
+ end
47
+
48
+ def get_pager_duty_id(name)
49
+ matches = get_id_for_pagerduty(name)
50
+ if matches.nil?
51
+ raise "Did not find any PagerDuty channels with name #{name}"
52
+ elsif matches.length > 1
53
+ raise "Found multiple matches for PagerDuty: #{matches}"
54
+ else
55
+ return matches[0]['id']
56
+ end
57
+ end
58
+
59
+ def get_hipchat_id(name)
60
+ matches = get_id(name)
61
+ if matches.nil?
62
+ raise "Did not find any HipChat channels with name #{name}"
63
+ elsif matches.length > 1
64
+ raise "Found multiple matches for HipChat: #{matches}"
65
+ else
66
+ return matches[0]['id']
67
+ end
68
+ end
69
+
70
+ def get_user_id(email)
71
+ params = {
72
+ 'filter[email]' => email,
73
+ 'format' => 'JSON'
74
+ }
75
+
76
+ client = Yle::NewRelicApi::User.new(@api_key)
77
+ client.get(params)
78
+ user_id = client.get_user_id(email)
79
+ user_notification_channel_id = get_id_for_user(user_id)
80
+ user_notification_channel_id
81
+ end
82
+
83
+ private
84
+
85
+ def get_id(name)
86
+ hits = []
87
+ @data.each do |d|
88
+ j = JSON.parse(d)
89
+ matches = j['notification_channels'].select { |group| group['name'] == name }
90
+ hits << matches unless matches.empty?
91
+ end
92
+ hits[0]
93
+ end
94
+
95
+ def get_id_for_email(email)
96
+ hits = []
97
+ @data.each do |d|
98
+ j = JSON.parse(d)
99
+ matches = j['notification_channels'].select { |group| group['email'] == email }
100
+ hits << matches unless matches.empty?
101
+ end
102
+ hits[0]
103
+ end
104
+
105
+ def get_id_for_pagerduty(service)
106
+ hits = []
107
+ @data.each do |d|
108
+ j = JSON.parse(d)
109
+ matches = j['notification_channels'].select { |group| group['service'] == service }
110
+ hits << matches unless matches.empty?
111
+ end
112
+ hits[0]
113
+ end
114
+
115
+ def get_id_for_user(user_id)
116
+ @data.each do |d|
117
+ j = JSON.parse(d)
118
+ j['notification_channels'].each do |c|
119
+ if c.key?('links')
120
+ if c['links'].key?('user')
121
+ if c['links']['user'] == user_id
122
+ # found user id, return notification channel id
123
+ return c['id']
124
+ end
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,74 @@
1
+ require 'logger'
2
+
3
+ require_relative '../yle-newrelic_api_v2'
4
+
5
+ module Yle
6
+ module NewRelicApi
7
+ class Servers
8
+ include Yle::NewRelicApi
9
+
10
+ def initialize(api_key)
11
+ @api_key = api_key
12
+ @data = []
13
+ @endpoint = URI('https://api.newrelic.com/v2/servers.json')
14
+ @pages = nil
15
+ end
16
+
17
+ def servers
18
+ servers = []
19
+ @data.each do |d|
20
+ j = JSON.parse(d)
21
+ j['servers'].each do |s|
22
+ servers << s['id']
23
+ end
24
+ end
25
+ servers
26
+ end
27
+
28
+ def healthy?(server_id)
29
+ @data.each do |d|
30
+ j = JSON.parse(d)
31
+ j['servers'].each do |s|
32
+ return s['reporting'] if s['id'] == server_id
33
+ end
34
+ end
35
+ end
36
+
37
+ def delete_non_reporting(server_id)
38
+ if !healthy?(server_id)
39
+ endpoint = "https://api.newrelic.com/v2/servers/#{server_id}.json"
40
+ if hostname(server_id).start_with?('ip-10-')
41
+ puts "Deleting #{hostname(server_id)}"
42
+ delete(endpoint)
43
+ else
44
+ require 'time'
45
+ now = Time.new
46
+ not_reported_for = ((now - Time.parse(last_reported(server_id))) / 60 / 60 / 24).round
47
+ if not_reported_for > 5
48
+ puts "Deleting #{hostname(server_id)} - not reported for #{not_reported_for} days"
49
+ delete(endpoint)
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ def last_reported(server_id)
56
+ @data.each do |d|
57
+ j = JSON.parse(d)
58
+ j['servers'].each do |s|
59
+ return s['last_reported_at'] if s['id'] == server_id
60
+ end
61
+ end
62
+ end
63
+
64
+ def hostname(server_id)
65
+ @data.each do |d|
66
+ j = JSON.parse(d)
67
+ j['servers'].each do |s|
68
+ return s['host'] if s['id'] == server_id
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,36 @@
1
+ require_relative '../yle-newrelic_api_v2'
2
+
3
+ module Yle
4
+ module NewRelicApi
5
+ class User
6
+ include Yle::NewRelicApi
7
+
8
+ def initialize(api_key)
9
+ @api_key = api_key
10
+ @data = []
11
+ @endpoint = URI('https://api.newrelic.com/v2/users.json')
12
+ end
13
+
14
+ def get_user_id(email)
15
+ matches = get_id_by_email(email)
16
+ if matches.empty?
17
+ raise "Did not find any users with email #{email}"
18
+ elsif matches.length > 1
19
+ raise "Found multiple matches for email: #{matches}"
20
+ else
21
+ return matches[0]['id']
22
+ end
23
+ end
24
+
25
+ private
26
+
27
+ def get_id_by_email(email)
28
+ @data.each do |d|
29
+ j = JSON.parse(d)
30
+ matches = j['users'].select { |user| user['email'] == email }
31
+ return matches
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
metadata ADDED
@@ -0,0 +1,48 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: yle-newrelic_api_v2
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Aki Hänninen
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-05-26 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description:
14
+ email:
15
+ - aki.hanninen@affecto.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/yle-newrelic_api_v2.rb
21
+ - lib/yle-newrelic_api_v2/yle-newrelic_api_v2_alert_policy.rb
22
+ - lib/yle-newrelic_api_v2/yle-newrelic_api_v2_notification_channel.rb
23
+ - lib/yle-newrelic_api_v2/yle-newrelic_api_v2_servers.rb
24
+ - lib/yle-newrelic_api_v2/yle-newrelic_api_v2_user.rb
25
+ homepage:
26
+ licenses: []
27
+ metadata: {}
28
+ post_install_message:
29
+ rdoc_options: []
30
+ require_paths:
31
+ - lib
32
+ required_ruby_version: !ruby/object:Gem::Requirement
33
+ requirements:
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: '0'
37
+ required_rubygems_version: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ requirements: []
43
+ rubyforge_project:
44
+ rubygems_version: 2.4.5.1
45
+ signing_key:
46
+ specification_version: 4
47
+ summary: New Relic API v2 implementation for Ruby
48
+ test_files: []