lita-aws-cloudwatch 0.1.1

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: bd3b6f952230d48f6f56dc7745bcb2a9f33c2687
4
+ data.tar.gz: 101e2b55f44ecbc6564251c02c7fb4c6950f0c1e
5
+ SHA512:
6
+ metadata.gz: 81e6f1b04d7f80b68fb9158e909b6c6e6f4699e28006a60f9a2437417e5692338dc39392b25628f0de96ecd8bbefc12edfb1ac61748eefba3d6a436e3ce0cbfa
7
+ data.tar.gz: dc6728dbf2bb417220652346d33070b840b1183fbe3113705bd69b0e0a1e817ac6c516f019bb3951a008d03da2fb8474a5af23372b1cbcb2100dbb46f3fba241
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --colour
2
+ --profile
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ services:
5
+ - redis-server
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
data/README.md ADDED
@@ -0,0 +1,73 @@
1
+ # lita-aws-cloudwatch
2
+
3
+ [![Build Status](https://travis-ci.org/5fpro/lita-aws-cloudwatch.svg?branch=master)](https://travis-ci.org/5fpro/lita-aws-cloudwatch)
4
+
5
+ Receive AWS CloudWatch alarm from AWS SNS (Simple Notification Service), and messaging to room.
6
+
7
+ # Features
8
+
9
+ - Supporting multiple AWS accounts.
10
+ - Notify to different room for each AWS acount.
11
+ - Can reveice SNS confirmation data.
12
+ - Show `AWS AccountID` while receiving SNS confirmation data.
13
+
14
+ ## Installation
15
+
16
+ - Add lita-aws-cloudwatch to your Lita instance's Gemfile:
17
+ ``` ruby
18
+ gem "lita-aws-cloudwatch"
19
+ ```
20
+
21
+ - See <a href="#configuration">Configuration</a>.
22
+
23
+ - Restart lita.
24
+
25
+ (goto AWS web console...)
26
+
27
+ - Create `Topic` in AWS SNS.
28
+
29
+ - Create SNS `Subscription` from `Topic`
30
+ - choose Protocol to `HTTP`.
31
+ - set Endpoint to `http://123.123.123.123:8888/aws-cloudwatch/receive`
32
+ - You will receive confirmation link from lita notify (click the link to finish confirmation).
33
+
34
+ - Set CloudWatch notification to topic.
35
+
36
+ - Done :)
37
+
38
+ ## Configuration
39
+
40
+ - You must enable lita `http routing` and `redis` in `lita_config.rb`
41
+ ```
42
+ config.redis['host'] = "127.0.0.1"
43
+ config.redis['port'] = 6379
44
+
45
+ config.http.port = 8888
46
+ ```
47
+
48
+ - Default room name while account is not set yet.
49
+ ```
50
+ config.handlers.aws_cloudwatch.default_room = "general"
51
+ ```
52
+
53
+
54
+ ## Usage
55
+
56
+ - list all aws accounts. Including account id, name, room.
57
+ ```
58
+ aws account list
59
+ ```
60
+
61
+ - `aws account set [account id] [account name]` : set account name.
62
+ ```
63
+ aws account set 123123 5Fpro co. ltd.
64
+ ```
65
+
66
+ - `aws account set [account id] [room name]` : set notify room for account. If you use Slack, it need to invite lita robot to room.
67
+ ```
68
+ aws account set 123123 #server-state.
69
+ ```
70
+
71
+ ## License
72
+
73
+ [MIT](http://opensource.org/licenses/MIT)
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
@@ -0,0 +1,120 @@
1
+ module Lita
2
+ module Handlers
3
+ class AwsCloudwatch < Handler
4
+ config :default_room, type: String, default: "general"
5
+
6
+ route(/^aws account set ([0-9]+) (.+)$/, :set_account, command: true, help: { "aws account set [account id] [account name]" => "Set AWS account name" })
7
+ def set_account(response)
8
+ account_id = response.matches[0][0]
9
+ account_name = response.matches[0][1]
10
+ redis.hset(redis_key, account_id, account_name)
11
+ response.reply("AWS account: #{account_id} has been set name: #{account_name}")
12
+ end
13
+
14
+ route(/^aws account room ([0-9]+) ([^\s]+)$/, :set_account_room, command: true, help: { "aws account room [account id] [room_name]" => "Set room for AWS account" })
15
+ def set_account_room(response)
16
+ account_id = response.matches[0][0]
17
+ room_name = response.matches[0][1].gsub("#", "")
18
+ redis.hset(redis_key_for_room, account_id, room_name)
19
+ response.reply("AWS account: #{account_id} has set room to: ##{room_name} , please invite robot to the room.")
20
+ end
21
+
22
+ route(/^aws account list/, :list_accounts, command: true, help: { "aws account list" => "List all AWS accounts" })
23
+ def list_accounts(response)
24
+ message = accounts.keys.map{ |key| "#{key}: #{accounts[key]} ( ##{fetch_room(key)} )" }.join("\n")
25
+ response.reply(message)
26
+ end
27
+
28
+ http.post "/aws-cloudwatch/receive", :receive
29
+ def receive(request, response)
30
+ @request = request
31
+ case params_data["Type"]
32
+ when "SubscriptionConfirmation"
33
+ alert_confirmation!
34
+ when "Notification"
35
+ alert_notification!
36
+ else
37
+ alert_unknowtype!
38
+ end
39
+ response.write("ok")
40
+ end
41
+
42
+ private
43
+
44
+ def alert_confirmation!
45
+ message = params_data["Message"].gsub("SubscribeURL", params_data["SubscribeURL"])
46
+ account_id = params_data["TopicArn"].split(":")[-2]
47
+ room = fetch_room(account_id)
48
+ send_message_to_room(message, room)
49
+ unless accounts[account_id]
50
+ send_message_to_room("Your AWS Account ID is `#{account_id}`, type `aws account set #{account_id} [account name]` for sett name, and type `aws account room #{account_id} [room name]` to set reporting room", room)
51
+ end
52
+ end
53
+
54
+ def alert_unknowtype!
55
+ room = config.default_room
56
+ message = "unknow type: #{params_data["Type"].inspect} , send to robot.\n DEBUG: #{params_data.inspect}"
57
+ send_message_to_room(message, room)
58
+ end
59
+
60
+ def alert_notification!
61
+ data = JSON.parse(params_data["Message"])
62
+ account_id = data["AWSAccountId"]
63
+ name = data["AlarmName"]
64
+ state = data["NewStateValue"]
65
+ reason = data["NewStateReason"]
66
+ messages = []
67
+ messages << "Account: #{accounts[account_id] || account_id}"
68
+ messages << "State: #{state}"
69
+ messages << "Name: #{name}"
70
+ messages << "Reason: #{reason}"
71
+ room = fetch_room(account_id)
72
+ send_message_to_room(messages.join("\n"), room)
73
+ end
74
+
75
+ def redis_key_for_room
76
+ "aws-cloudwatch-accounts-room"
77
+ end
78
+
79
+ def redis_key
80
+ "aws-cloudwatch"
81
+ end
82
+
83
+ def accounts
84
+ @accounts ||= redis.hgetall(redis_key)
85
+ @accounts
86
+ end
87
+
88
+ def fetch_room(account_id)
89
+ @rooms ||= redis.hgetall(redis_key_for_room)
90
+ @rooms[account_id] || config.default_room
91
+ end
92
+
93
+ def params_data
94
+ @data ||= JSON.parse(@request.body.string)
95
+ @data
96
+ end
97
+
98
+ def send_message_to_room(message, room_name = nil)
99
+ room_name ||= config.default_room
100
+ target = Source.new(room: find_room_id_by_name(room_name))
101
+ robot.send_messages(target, message)
102
+ end
103
+
104
+ def find_room_id_by_name(room_name)
105
+ case robot.config.robot.adapter.to_s.to_sym
106
+ when :slack
107
+ if room = ::Lita::Room.find_by_name(room_name)
108
+ return room.id
109
+ else
110
+ ::Lita::Room.find_by_name("general").id
111
+ end
112
+ else
113
+ room_name
114
+ end
115
+ end
116
+
117
+ Lita.register_handler(self)
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,12 @@
1
+ require "lita"
2
+
3
+ Lita.load_locales Dir[File.expand_path(
4
+ File.join("..", "..", "locales", "*.yml"), __FILE__
5
+ )]
6
+
7
+ require "lita/handlers/aws_cloudwatch"
8
+
9
+ Lita::Handlers::AwsCloudwatch.template_root File.expand_path(
10
+ File.join("..", "..", "templates"),
11
+ __FILE__
12
+ )
@@ -0,0 +1,23 @@
1
+ Gem::Specification.new do |spec|
2
+ spec.name = "lita-aws-cloudwatch"
3
+ spec.version = "0.1.1"
4
+ spec.authors = ["marsz"]
5
+ spec.email = ["marsz330@gmail.com"]
6
+ spec.description = "Receive AWS CloudWatch alarm from AWS SNS (Simple Notification Service), and messaging to room."
7
+ spec.summary = "AWS CloudWatch integration with AWS SNS"
8
+ spec.homepage = "https://github.com/5fpro/lita-aws-cloudwatch"
9
+ spec.license = "MIT"
10
+ spec.metadata = { "lita_plugin_type" => "handler" }
11
+
12
+ spec.files = `git ls-files`.split($/)
13
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
14
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
15
+ spec.require_paths = ["lib"]
16
+
17
+ spec.add_runtime_dependency "lita", ">= 4"
18
+
19
+ spec.add_development_dependency "bundler", "~> 1.3"
20
+ spec.add_development_dependency "rake"
21
+ spec.add_development_dependency "rack-test"
22
+ spec.add_development_dependency "rspec", ">= 3.0.0"
23
+ end
data/locales/en.yml ADDED
@@ -0,0 +1,4 @@
1
+ en:
2
+ lita:
3
+ handlers:
4
+ aws_cloudwatch:
@@ -0,0 +1,86 @@
1
+ require "spec_helper"
2
+
3
+ describe Lita::Handlers::AwsCloudwatch, lita_handler: true do
4
+ it "#set_account" do
5
+ send_command "aws account set 1234 5Fpro HaHa"
6
+ expect(replies.size).to be > 0
7
+ send_command "aws account list"
8
+ expect(replies.last).to match("1234: 5Fpro HaHa")
9
+ end
10
+
11
+ it "#set_account_room" do
12
+ send_command "aws account set 1234 5Fpro HaHa"
13
+ send_command "aws account room 1234 #haha"
14
+ expect(replies.size).to be > 0
15
+ send_command "aws account list"
16
+ expect(replies.last).to match("1234: 5Fpro HaHa ( #haha )")
17
+ end
18
+
19
+ context "#receive" do
20
+ let(:account_id){ "863886017929" }
21
+ let(:body_confirmation){ '{"Type": "SubscriptionConfirmation", "MessageId": "cb304f8d-740d-4810-b9dd-7d47a1184eb8", "Token": "2336412f37fb687f5d51e6e241d7700bdc2fd74df0fbef7c6648870dee1c4c87ab59fe66548b509ff18165e81a2a4c6b4b5803444bf84a10365c1104202a9d010019385e91a7c871bf84959b919966358f3e2ced05bd9bc1d08a86ac8bae46a1420da82c2b308a395058cb4cad8ba00cdf5efada5812e150171241d95acd5153", "TopicArn": "arn:aws:sns:ap-northeast-1:863886017929:developers", "Message": "You have chosen to subscribe to the topic arn:aws:sns:ap-northeast-1:863886017929:developers.\nTo confirm the subscription, visit the SubscribeURL included in this message.", "SubscribeURL": "https://sns.ap-northeast-1.amazonaws.com/?Action=ConfirmSubscription&TopicArn=arn:aws:sns:ap-northeast-1:863886017929:developers&Token=2336412f37fb687f5d51e6e241d7700bdc2fd74df0fbef7c6648870dee1c4c87ab59fe66548b509ff18165e81a2a4c6b4b5803444bf84a10365c1104202a9d010019385e91a7c871bf84959b919966358f3e2ced05bd9bc1d08a86ac8bae46a1420da82c2b308a395058cb4cad8ba00cdf5efada5812e150171241d95acd5153", "Timestamp": "2015-12-06T07:13:41.370Z", "SignatureVersion": "1", "Signature": "bkvpfe9br6g41XQRJOgDg99C2evpXTGsXJ8lbLfZbmt4rfloORWO5Kw0Dh7QKIijd9y/QyvU6Yo80k8DXVWfJfj/vLysjplHOsrxSmvR1F7VMZil1cyoag3c/LNHJIq0WRSJxH8O6HkT1c5SNCSWfAiqz+4tw/brtCl8gK9vmGr0eGPOcFhT46xrz0Ucc+clFlwuhAjrRoK9vRRsIyTl4NEPgtC7HyRlB+Qm+ooXi7Bk0AUnGMdTKPYB/c1bCq+A0VKCzxLKjSzIme0i59n3lxFh4zSSygbX68gay7A2FRxYfl2j6/agH5gC0jsnQh1Xgry7Y/+z0fdUwzAZoWw5Ng==", "SigningCertURL": "https://sns.ap-northeast-1.amazonaws.com/SimpleNotificationService-bb750dd426d95ee9390147a5624348ee.pem"}' }
22
+ let(:body_notification){ '{"Type": "Notification", "MessageId": "f1cd789a-df69-5dc4-bd54-36419e0f72c4", "TopicArn": "arn:aws:sns:ap-northeast-1:863886017929:developers", "Subject": "ALARM: \"api-1 - Network In\" in APAC - Tokyo", "Message": "{\"AlarmName\":\"api-1 - Network In\",\"AlarmDescription\":null,\"AWSAccountId\":\"863886017929\",\"NewStateValue\":\"ALARM\",\"NewStateReason\":\"Threshold Crossed: 1 datapoint (2024818.75) was greater than or equal to the threshold (2000000.0).\",\"StateChangeTime\":\"2015-12-04T07:22:14.394+0000\",\"Region\":\"APAC - Tokyo\",\"OldStateValue\":\"OK\",\"Trigger\":{\"MetricName\":\"NetworkIn\",\"Namespace\":\"AWS/EC2\",\"Statistic\":\"AVERAGE\",\"Unit\":null,\"Dimensions\":[{\"name\":\"InstanceId\",\"value\":\"i-bc8dcaa5\"}],\"Period\":300,\"EvaluationPeriods\":1,\"ComparisonOperator\":\"GreaterThanOrEqualToThreshold\",\"Threshold\":2000000.0}}", "Timestamp": "2015-12-04T07:22:14.461Z", "SignatureVersion": "1", "Signature": "cW8eyf5k/+QaVZna/nhMh8HSnN7Y0BFR1fOvyYTG9seBsW4f6tGMj/wVK9aQVqVvEI3Vt54+OM0RSiiJHGOaanej2IxH+DiVo7k7VnN9uK25ejYbcp0pXusz7z7+VfzDr26QRCGF1qmq+TTx61q4PmfTIdigPZ9H9wUzQdujLxJy7vjRjJTLnhJ6fQtGCOyTfl0FTpYbVPeRT8/vu6G6XYw53hAa+sRbGiONmirwF0OzLQaW7M0FRO/Y/W8Yyr8GTNcT9egSIRED79fmkzWz2oxmEjVCJBUtvO6BBmjckCSsFB7oSDjuOKhGv5TNP29qSE36pwox0AoOnn6SoTnAlw==", "SigningCertURL": "https://sns.ap-northeast-1.amazonaws.com/SimpleNotificationService-bb750dd426d95ee9390147a5624348ee.pem", "UnsubscribeURL": "https://sns.ap-northeast-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:ap-northeast-1:863886017929:developers:dc2735b1-b160-4ec3-901e-393fd971a28a"}' }
23
+ context "no account name, no room" do
24
+ it "confirmation" do
25
+ response = http.post("/aws-cloudwatch/receive") do |req|
26
+ req.body = body_confirmation
27
+ end
28
+ expect( response.body ).to match("ok")
29
+ end
30
+ it "notification" do
31
+ response = http.post("/aws-cloudwatch/receive") do |req|
32
+ req.body = body_notification
33
+ end
34
+ expect( response.body ).to match("ok")
35
+ end
36
+ end
37
+ context "only account id" do
38
+ before{ send_command "aws account set #{account_id} 5Fpro" }
39
+ it "confirmation" do
40
+ response = http.post("/aws-cloudwatch/receive") do |req|
41
+ req.body = body_confirmation
42
+ end
43
+ expect( response.body ).to match("ok")
44
+ end
45
+ it "notification" do
46
+ response = http.post("/aws-cloudwatch/receive") do |req|
47
+ req.body = body_notification
48
+ end
49
+ expect( response.body ).to match("ok")
50
+ end
51
+ end
52
+
53
+ context "only room" do
54
+ before{ send_command "aws account room #{account_id} haha" }
55
+ it "confirmation" do
56
+ response = http.post("/aws-cloudwatch/receive") do |req|
57
+ req.body = body_confirmation
58
+ end
59
+ expect( response.body ).to match("ok")
60
+ end
61
+ it "notification" do
62
+ response = http.post("/aws-cloudwatch/receive") do |req|
63
+ req.body = body_notification
64
+ end
65
+ expect( response.body ).to match("ok")
66
+ end
67
+ end
68
+
69
+ context "both room and account_id" do
70
+ before{ send_command "aws account room #{account_id} haha" }
71
+ before{ send_command "aws account set #{account_id} 5Fpro" }
72
+ it "confirmation" do
73
+ response = http.post("/aws-cloudwatch/receive") do |req|
74
+ req.body = body_confirmation
75
+ end
76
+ expect( response.body ).to match("ok")
77
+ end
78
+ it "notification" do
79
+ response = http.post("/aws-cloudwatch/receive") do |req|
80
+ req.body = body_notification
81
+ end
82
+ expect( response.body ).to match("ok")
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,7 @@
1
+ require 'json'
2
+ require "lita-aws-cloudwatch"
3
+ require "lita/rspec"
4
+
5
+ # A compatibility mode is provided for older plugins upgrading from Lita 3. Since this plugin
6
+ # was generated with Lita 4, the compatibility mode should be left disabled.
7
+ Lita.version_3_compatibility_mode = false
File without changes
metadata ADDED
@@ -0,0 +1,131 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lita-aws-cloudwatch
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - marsz
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-12-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: lita
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '4'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '4'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.3'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rack-test
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: 3.0.0
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: 3.0.0
83
+ description: Receive AWS CloudWatch alarm from AWS SNS (Simple Notification Service),
84
+ and messaging to room.
85
+ email:
86
+ - marsz330@gmail.com
87
+ executables: []
88
+ extensions: []
89
+ extra_rdoc_files: []
90
+ files:
91
+ - ".gitignore"
92
+ - ".rspec"
93
+ - ".travis.yml"
94
+ - Gemfile
95
+ - README.md
96
+ - Rakefile
97
+ - lib/lita-aws-cloudwatch.rb
98
+ - lib/lita/handlers/aws_cloudwatch.rb
99
+ - lita-aws-cloudwatch.gemspec
100
+ - locales/en.yml
101
+ - spec/lita/handlers/aws_cloudwatch_spec.rb
102
+ - spec/spec_helper.rb
103
+ - templates/.gitkeep
104
+ homepage: https://github.com/5fpro/lita-aws-cloudwatch
105
+ licenses:
106
+ - MIT
107
+ metadata:
108
+ lita_plugin_type: handler
109
+ post_install_message:
110
+ rdoc_options: []
111
+ require_paths:
112
+ - lib
113
+ required_ruby_version: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ required_rubygems_version: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - ">="
121
+ - !ruby/object:Gem::Version
122
+ version: '0'
123
+ requirements: []
124
+ rubyforge_project:
125
+ rubygems_version: 2.4.6
126
+ signing_key:
127
+ specification_version: 4
128
+ summary: AWS CloudWatch integration with AWS SNS
129
+ test_files:
130
+ - spec/lita/handlers/aws_cloudwatch_spec.rb
131
+ - spec/spec_helper.rb