fluent-plugin-slack-stakater 0.6.8
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 +7 -0
- data/.gitignore +8 -0
- data/.travis.yml +11 -0
- data/CHANGELOG.md +95 -0
- data/Gemfile +3 -0
- data/Gemfile.fluentd.0.12 +4 -0
- data/README.md +126 -0
- data/Rakefile +16 -0
- data/VERSION +1 -0
- data/example.conf +18 -0
- data/fluent-plugin-slack.gemspec +28 -0
- data/lib/fluent/plugin/out_buffered_slack.rb +1 -0
- data/lib/fluent/plugin/out_slack.rb +382 -0
- data/lib/fluent/plugin/slack_client.rb +289 -0
- data/lib/fluent/plugin/slack_client/error.rb +24 -0
- data/test.sh +2 -0
- data/test/plugin/test_out_slack.rb +566 -0
- data/test/plugin/test_slack_client.rb +282 -0
- data/test/test_helper.rb +32 -0
- metadata +176 -0
@@ -0,0 +1,282 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
require 'fluent/plugin/slack_client'
|
3
|
+
require 'time'
|
4
|
+
require 'dotenv'
|
5
|
+
require 'webrick'
|
6
|
+
require 'webrick/httpproxy'
|
7
|
+
|
8
|
+
# HOW TO RUN
|
9
|
+
#
|
10
|
+
# Create .env file with contents as:
|
11
|
+
#
|
12
|
+
# WEBHOOK_URL=https://hooks.slack.com/services/XXXX/YYYY/ZZZZ
|
13
|
+
# SLACKBOt_URL=https://xxxx.slack.com/services/hooks/slackbot?token=XXXX
|
14
|
+
# SLACK_API_TOKEN=XXXXX
|
15
|
+
#
|
16
|
+
Dotenv.load
|
17
|
+
if ENV['WEBHOOK_URL'] and ENV['SLACKBOT_URL'] and ENV['SLACK_API_TOKEN']
|
18
|
+
|
19
|
+
class TestProxyServer
|
20
|
+
def initialize
|
21
|
+
@proxy = WEBrick::HTTPProxyServer.new(
|
22
|
+
:BindAddress => '127.0.0.1',
|
23
|
+
:Port => unused_port,
|
24
|
+
)
|
25
|
+
end
|
26
|
+
|
27
|
+
def proxy_url
|
28
|
+
"https://127.0.0.1:#{unused_port}"
|
29
|
+
end
|
30
|
+
|
31
|
+
def start
|
32
|
+
@thread = Thread.new do
|
33
|
+
@proxy.start
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def shutdown
|
38
|
+
@proxy.shutdown
|
39
|
+
end
|
40
|
+
|
41
|
+
def unused_port
|
42
|
+
return @unused_port if @unused_port
|
43
|
+
s = TCPServer.open(0)
|
44
|
+
port = s.addr[1]
|
45
|
+
s.close
|
46
|
+
@unused_port = port
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class SlackClientTest < Test::Unit::TestCase
|
51
|
+
class << self
|
52
|
+
attr_reader :proxy
|
53
|
+
|
54
|
+
def startup
|
55
|
+
@proxy = TestProxyServer.new.tap {|proxy| proxy.start }
|
56
|
+
end
|
57
|
+
|
58
|
+
def shutdown
|
59
|
+
@proxy.shutdown
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def setup
|
64
|
+
super
|
65
|
+
@incoming = Fluent::SlackClient::IncomingWebhook.new(ENV['WEBHOOK_URL'])
|
66
|
+
@slackbot = Fluent::SlackClient::Slackbot.new(ENV['SLACKBOT_URL'])
|
67
|
+
@api = Fluent::SlackClient::WebApi.new
|
68
|
+
|
69
|
+
proxy_url = self.class.proxy.proxy_url
|
70
|
+
@incoming_proxy = Fluent::SlackClient::IncomingWebhook.new(ENV['WEBHOOK_URL'], proxy_url)
|
71
|
+
@slackbot_proxy = Fluent::SlackClient::Slackbot.new(ENV['SLACKBOT_URL'], proxy_url)
|
72
|
+
@api_proxy = Fluent::SlackClient::WebApi.new(nil, proxy_url)
|
73
|
+
|
74
|
+
@icon_url = 'http://www.google.com/s2/favicons?domain=www.google.de'
|
75
|
+
end
|
76
|
+
|
77
|
+
def token(client)
|
78
|
+
client.is_a?(Fluent::SlackClient::IncomingWebhook) ? {} : {token: ENV['SLACK_API_TOKEN']}
|
79
|
+
end
|
80
|
+
|
81
|
+
def default_payload(client)
|
82
|
+
{
|
83
|
+
channel: '#general',
|
84
|
+
mrkdwn: true,
|
85
|
+
link_names: true,
|
86
|
+
}.merge!(token(client))
|
87
|
+
end
|
88
|
+
|
89
|
+
def default_attachment
|
90
|
+
{
|
91
|
+
mrkdwn_in: %w[text fields]
|
92
|
+
}
|
93
|
+
end
|
94
|
+
|
95
|
+
def valid_utf8_encoded_string
|
96
|
+
"#general \xE3\x82\xA4\xE3\x83\xB3\xE3\x82\xB9\xE3\x83\x88\xE3\x83\xBC\xE3\x83\xAB\n"
|
97
|
+
end
|
98
|
+
|
99
|
+
def invalid_ascii8bit_encoded_utf8_string
|
100
|
+
str = "#general \xE3\x82\xA4\xE3\x83\xB3\xE3\x82\xB9\xE3\x83\x88\xE3\x83\xBC\xE3\x83\xAB\x81\n"
|
101
|
+
str.force_encoding(Encoding::ASCII_8BIT)
|
102
|
+
end
|
103
|
+
|
104
|
+
# Notification via Mention works for all three with plain text payload
|
105
|
+
def test_post_message_plain_payload_mention
|
106
|
+
[@incoming, @slackbot, @api].each do |slack|
|
107
|
+
assert_nothing_raised do
|
108
|
+
slack.post_message(default_payload(slack).merge({
|
109
|
+
text: "#general @everyone\n",
|
110
|
+
}))
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# Notification via Highlight Words works with only Slackbot with plain text payload
|
116
|
+
# NOTE: Please add `sowawa1` to Highlight Words
|
117
|
+
def test_post_message_plain_payload_highlight_words
|
118
|
+
[@incoming, @slackbot, @api].each do |slack|
|
119
|
+
assert_nothing_raised do
|
120
|
+
slack.post_message(default_payload(slack).merge({
|
121
|
+
text: "sowawa1\n",
|
122
|
+
}))
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
# Notification via Mention does not work for attachments
|
128
|
+
def test_post_message_color_payload
|
129
|
+
[@incoming, @slackbot, @api].each do |slack|
|
130
|
+
assert_nothing_raised do
|
131
|
+
slack.post_message(default_payload(slack).merge({
|
132
|
+
attachments: [default_attachment.merge({
|
133
|
+
color: 'good',
|
134
|
+
fallback: "sowawa1\n@everyone\n",
|
135
|
+
text: "sowawa1\n@everyone\n",
|
136
|
+
})]
|
137
|
+
}))
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
# Notification via Mention does not work for attachments
|
143
|
+
def test_post_message_fields_payload
|
144
|
+
[@incoming, @slackbot, @api].each do |slack|
|
145
|
+
assert_nothing_raised do
|
146
|
+
slack.post_message(default_payload(slack).merge({
|
147
|
+
attachments: [default_attachment.merge({
|
148
|
+
color: 'good',
|
149
|
+
fallback: 'test1 test2',
|
150
|
+
fields: [
|
151
|
+
{
|
152
|
+
title: 'test1',
|
153
|
+
value: "[07:00:00] sowawa1\n[07:00:00] @everyone\n",
|
154
|
+
},
|
155
|
+
{
|
156
|
+
title: 'test2',
|
157
|
+
value: "[07:00:00] sowawa1\n[07:00:00] @everyone\n",
|
158
|
+
},
|
159
|
+
],
|
160
|
+
})]
|
161
|
+
}))
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def test_post_via_proxy
|
167
|
+
[@incoming_proxy, @slackbot_proxy, @api_proxy].each do |slack|
|
168
|
+
assert_nothing_raised do
|
169
|
+
slack.post_message(default_payload(slack).merge({
|
170
|
+
attachments: [default_attachment.merge({
|
171
|
+
color: 'good',
|
172
|
+
fallback: "sowawa1\n@everyone\n",
|
173
|
+
text: "sowawa1\n@everyone\n",
|
174
|
+
})]
|
175
|
+
}))
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
def test_post_message_username
|
181
|
+
[@incoming, @api].each do |slack|
|
182
|
+
assert_nothing_raised do
|
183
|
+
slack.post_message(default_payload(slack).merge({
|
184
|
+
username: 'fluentd',
|
185
|
+
text: "#general @everyone\n",
|
186
|
+
}))
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
def test_post_message_icon_url
|
192
|
+
[@incoming, @api].each do |slack|
|
193
|
+
assert_nothing_raised do
|
194
|
+
slack.post_message(default_payload(slack).merge({
|
195
|
+
icon_url: @icon_url,
|
196
|
+
attachments: [default_attachment.merge({
|
197
|
+
color: 'good',
|
198
|
+
fallback: "sowawa1\n@everyone\n",
|
199
|
+
text: "sowawa1\n@everyone\n",
|
200
|
+
})]
|
201
|
+
}))
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
# Hmm, I need to delete channels to test repeatedly,
|
207
|
+
# but slack does not provide channels.delete API
|
208
|
+
def test_channels_create
|
209
|
+
begin
|
210
|
+
@api.channels_create(token(@api).merge({
|
211
|
+
name: '#test_channels_create',
|
212
|
+
}))
|
213
|
+
rescue Fluent::SlackClient::NameTakenError
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
# Hmm, I need to delete channels to test repeatedly,
|
218
|
+
# but slack does not provide channels.delete API
|
219
|
+
def test_auto_channels_create
|
220
|
+
assert_nothing_raised do
|
221
|
+
@api.post_message(default_payload(@api).merge(
|
222
|
+
{
|
223
|
+
channel: '#test_auto_api',
|
224
|
+
text: "bar\n",
|
225
|
+
}),
|
226
|
+
{
|
227
|
+
auto_channels_create: true,
|
228
|
+
}
|
229
|
+
)
|
230
|
+
end
|
231
|
+
|
232
|
+
assert_nothing_raised do
|
233
|
+
@slackbot.post_message(default_payload(@slackbot).merge(
|
234
|
+
{
|
235
|
+
channel: '#test_auto_slackbot',
|
236
|
+
text: "bar\n",
|
237
|
+
}),
|
238
|
+
{
|
239
|
+
auto_channels_create: true,
|
240
|
+
}
|
241
|
+
)
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
# IncomingWebhook posts "#general インストール"
|
246
|
+
def test_post_message_utf8_encoded_text
|
247
|
+
[@incoming].each do |slack|
|
248
|
+
assert_nothing_raised do
|
249
|
+
slack.post_message(default_payload(slack).merge({
|
250
|
+
text: valid_utf8_encoded_string,
|
251
|
+
}))
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
# IncomingWebhook posts "#general インストール?"
|
257
|
+
def test_post_message_ascii8bit_encoded_utf8_text
|
258
|
+
[@incoming].each do |slack|
|
259
|
+
assert_nothing_raised do
|
260
|
+
slack.post_message(default_payload(slack).merge({
|
261
|
+
text: invalid_ascii8bit_encoded_utf8_string,
|
262
|
+
}))
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
# IncomingWebhook and API posts "#general インストール?"
|
268
|
+
def test_post_message_ascii8bit_encoded_utf8_attachments
|
269
|
+
[@incoming, @api].each do |slack|
|
270
|
+
assert_nothing_raised do
|
271
|
+
slack.post_message(default_payload(slack).merge({
|
272
|
+
attachments: [default_attachment.merge({
|
273
|
+
color: 'good',
|
274
|
+
fallback: invalid_ascii8bit_encoded_utf8_string,
|
275
|
+
text: invalid_ascii8bit_encoded_utf8_string,
|
276
|
+
})]
|
277
|
+
}))
|
278
|
+
end
|
279
|
+
end
|
280
|
+
end
|
281
|
+
end
|
282
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
|
4
|
+
begin
|
5
|
+
Bundler.setup(:default, :development)
|
6
|
+
rescue Bundler::BundlerError => e
|
7
|
+
$stderr.puts e.message
|
8
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
9
|
+
exit e.status_code
|
10
|
+
end
|
11
|
+
require 'test/unit'
|
12
|
+
require 'test/unit/rr'
|
13
|
+
|
14
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
15
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
16
|
+
require 'fluent/test'
|
17
|
+
unless ENV.has_key?('VERBOSE')
|
18
|
+
nulllogger = Object.new
|
19
|
+
nulllogger.instance_eval {|obj|
|
20
|
+
def method_missing(method, *args)
|
21
|
+
# pass
|
22
|
+
end
|
23
|
+
}
|
24
|
+
$log = nulllogger
|
25
|
+
end
|
26
|
+
|
27
|
+
def with_timezone(tz)
|
28
|
+
oldtz, ENV['TZ'] = ENV['TZ'], tz
|
29
|
+
yield
|
30
|
+
ensure
|
31
|
+
ENV['TZ'] = oldtz
|
32
|
+
end
|
metadata
ADDED
@@ -0,0 +1,176 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fluent-plugin-slack-stakater
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.6.8
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Keisuke SOGAWA
|
8
|
+
- Naotoshi Seo
|
9
|
+
- stakater
|
10
|
+
autorequire:
|
11
|
+
bindir: bin
|
12
|
+
cert_chain: []
|
13
|
+
date: 2018-06-25 00:00:00.000000000 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: fluentd
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
|
+
requirements:
|
19
|
+
- - ">="
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.12.0
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
version: 0.12.0
|
29
|
+
- !ruby/object:Gem::Dependency
|
30
|
+
name: rake
|
31
|
+
requirement: !ruby/object:Gem::Requirement
|
32
|
+
requirements:
|
33
|
+
- - ">="
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: 10.1.1
|
36
|
+
type: :development
|
37
|
+
prerelease: false
|
38
|
+
version_requirements: !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: 10.1.1
|
43
|
+
- !ruby/object:Gem::Dependency
|
44
|
+
name: rr
|
45
|
+
requirement: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: 1.0.0
|
50
|
+
type: :development
|
51
|
+
prerelease: false
|
52
|
+
version_requirements: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: 1.0.0
|
57
|
+
- !ruby/object:Gem::Dependency
|
58
|
+
name: pry
|
59
|
+
requirement: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '0'
|
64
|
+
type: :development
|
65
|
+
prerelease: false
|
66
|
+
version_requirements: !ruby/object:Gem::Requirement
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '0'
|
71
|
+
- !ruby/object:Gem::Dependency
|
72
|
+
name: pry-nav
|
73
|
+
requirement: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
type: :development
|
79
|
+
prerelease: false
|
80
|
+
version_requirements: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '0'
|
85
|
+
- !ruby/object:Gem::Dependency
|
86
|
+
name: test-unit
|
87
|
+
requirement: !ruby/object:Gem::Requirement
|
88
|
+
requirements:
|
89
|
+
- - "~>"
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: 3.0.2
|
92
|
+
type: :development
|
93
|
+
prerelease: false
|
94
|
+
version_requirements: !ruby/object:Gem::Requirement
|
95
|
+
requirements:
|
96
|
+
- - "~>"
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: 3.0.2
|
99
|
+
- !ruby/object:Gem::Dependency
|
100
|
+
name: test-unit-rr
|
101
|
+
requirement: !ruby/object:Gem::Requirement
|
102
|
+
requirements:
|
103
|
+
- - "~>"
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: 1.0.3
|
106
|
+
type: :development
|
107
|
+
prerelease: false
|
108
|
+
version_requirements: !ruby/object:Gem::Requirement
|
109
|
+
requirements:
|
110
|
+
- - "~>"
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: 1.0.3
|
113
|
+
- !ruby/object:Gem::Dependency
|
114
|
+
name: dotenv
|
115
|
+
requirement: !ruby/object:Gem::Requirement
|
116
|
+
requirements:
|
117
|
+
- - ">="
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
version: '0'
|
120
|
+
type: :development
|
121
|
+
prerelease: false
|
122
|
+
version_requirements: !ruby/object:Gem::Requirement
|
123
|
+
requirements:
|
124
|
+
- - ">="
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
version: '0'
|
127
|
+
description: fluent Slack plugin
|
128
|
+
email:
|
129
|
+
- hello@stakater.com
|
130
|
+
executables: []
|
131
|
+
extensions: []
|
132
|
+
extra_rdoc_files: []
|
133
|
+
files:
|
134
|
+
- ".gitignore"
|
135
|
+
- ".travis.yml"
|
136
|
+
- CHANGELOG.md
|
137
|
+
- Gemfile
|
138
|
+
- Gemfile.fluentd.0.12
|
139
|
+
- README.md
|
140
|
+
- Rakefile
|
141
|
+
- VERSION
|
142
|
+
- example.conf
|
143
|
+
- fluent-plugin-slack.gemspec
|
144
|
+
- lib/fluent/plugin/out_buffered_slack.rb
|
145
|
+
- lib/fluent/plugin/out_slack.rb
|
146
|
+
- lib/fluent/plugin/slack_client.rb
|
147
|
+
- lib/fluent/plugin/slack_client/error.rb
|
148
|
+
- test.sh
|
149
|
+
- test/plugin/test_out_slack.rb
|
150
|
+
- test/plugin/test_slack_client.rb
|
151
|
+
- test/test_helper.rb
|
152
|
+
homepage: https://github.com/stakater/fluent-plugin-slack
|
153
|
+
licenses:
|
154
|
+
- Apache-2.0
|
155
|
+
metadata: {}
|
156
|
+
post_install_message:
|
157
|
+
rdoc_options: []
|
158
|
+
require_paths:
|
159
|
+
- lib
|
160
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
161
|
+
requirements:
|
162
|
+
- - ">="
|
163
|
+
- !ruby/object:Gem::Version
|
164
|
+
version: '0'
|
165
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
166
|
+
requirements:
|
167
|
+
- - ">="
|
168
|
+
- !ruby/object:Gem::Version
|
169
|
+
version: '0'
|
170
|
+
requirements: []
|
171
|
+
rubyforge_project:
|
172
|
+
rubygems_version: 2.5.2.1
|
173
|
+
signing_key:
|
174
|
+
specification_version: 4
|
175
|
+
summary: fluent Slack plugin
|
176
|
+
test_files: []
|