yle-newrelic_api_v2 0.0.2

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,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: []