barbeque 0.3.0 → 0.4.0
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 +4 -4
- data/app/controllers/barbeque/sns_subscriptions_controller.rb +139 -0
- data/app/models/barbeque/job_queue.rb +2 -0
- data/app/models/barbeque/sns_subscription.rb +11 -0
- data/app/views/barbeque/sns_subscriptions/_form.html.haml +39 -0
- data/app/views/barbeque/sns_subscriptions/edit.html.haml +3 -0
- data/app/views/barbeque/sns_subscriptions/index.html.haml +24 -0
- data/app/views/barbeque/sns_subscriptions/new.html.haml +3 -0
- data/app/views/barbeque/sns_subscriptions/show.html.haml +28 -0
- data/app/views/layouts/barbeque/_sidebar.html.haml +4 -0
- data/app/views/layouts/barbeque/application.html.haml +1 -1
- data/config/routes.rb +2 -0
- data/db/migrate/20170420030157_create_barbeque_sns_subscriptions.rb +11 -0
- data/lib/barbeque/message.rb +1 -0
- data/lib/barbeque/message/job_execution.rb +2 -2
- data/lib/barbeque/message/notification.rb +28 -0
- data/lib/barbeque/message_handler.rb +1 -0
- data/lib/barbeque/message_handler/notification.rb +21 -0
- data/lib/barbeque/version.rb +1 -1
- metadata +13 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 234d0202835f94f4ecb493933e9805c1302148a2
|
4
|
+
data.tar.gz: cac682927dfc758791fcebf8e30a4d37daf98d76
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 76e7a70a6bffa609ce74dbb90783a7835da3876c34e75c19f711bad301d6b517b01e7bc7c2b6a614ec71c6297921cf36c49b01ecc8d5a072a2606cdb29ca99d0
|
7
|
+
data.tar.gz: 5ab873c9a336c285af66b758931628eaa604e05266454960c4a2974a6ddaa9ab0bcd9e87866c3b2cc8d47bafd0a913ab56fe06675949770667976eae0fcd67f5
|
@@ -0,0 +1,139 @@
|
|
1
|
+
class Barbeque::SnsSubscriptionsController < Barbeque::ApplicationController
|
2
|
+
def index
|
3
|
+
@sns_subscriptions = Barbeque::SNSSubscription.all
|
4
|
+
end
|
5
|
+
|
6
|
+
def show
|
7
|
+
@sns_subscription = Barbeque::SNSSubscription.find(params[:id])
|
8
|
+
end
|
9
|
+
|
10
|
+
def new
|
11
|
+
@sns_topic_arns = fetch_sns_topic_arns
|
12
|
+
@sns_subscription = Barbeque::SNSSubscription.new
|
13
|
+
end
|
14
|
+
|
15
|
+
def edit
|
16
|
+
@sns_subscription = Barbeque::SNSSubscription.find(params[:id])
|
17
|
+
end
|
18
|
+
|
19
|
+
def create
|
20
|
+
@sns_subscription = Barbeque::SNSSubscription.new(params.require(:sns_subscription).permit(:topic_arn, :job_queue_id, :job_definition_id))
|
21
|
+
|
22
|
+
if @sns_subscription.save
|
23
|
+
update_sqs_policy!
|
24
|
+
subscribe_topic!
|
25
|
+
redirect_to @sns_subscription, notice: 'SNS subscription was successfully created.'
|
26
|
+
else
|
27
|
+
render :new
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def update
|
32
|
+
@sns_subscription = Barbeque::SNSSubscription.find(params[:id])
|
33
|
+
if @sns_subscription.update(params.require(:sns_subscription).permit(:job_definition_id))
|
34
|
+
update_sqs_policy!
|
35
|
+
redirect_to @sns_subscription, notice: 'SNS subscription was successfully updated.'
|
36
|
+
else
|
37
|
+
render :edit
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def destroy
|
42
|
+
@sns_subscription = Barbeque::SNSSubscription.find(params[:id])
|
43
|
+
@sns_subscription.destroy
|
44
|
+
update_sqs_policy!
|
45
|
+
unsubscribe_topic!
|
46
|
+
redirect_to sns_subscriptions_path, notice: 'SNS subscription was successfully destroyed.'
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def fetch_sns_topic_arns
|
52
|
+
sns_client.list_topics.topics.map(&:topic_arn)
|
53
|
+
end
|
54
|
+
|
55
|
+
def update_sqs_policy!
|
56
|
+
attrs = sqs_client.get_queue_attributes(
|
57
|
+
queue_url: @sns_subscription.job_queue.queue_url,
|
58
|
+
attribute_names: ['QueueArn'],
|
59
|
+
)
|
60
|
+
queue_arn = attrs.attributes['QueueArn']
|
61
|
+
topic_arns = @sns_subscription.job_queue.sns_subscriptions.map(&:topic_arn)
|
62
|
+
|
63
|
+
if topic_arns.present?
|
64
|
+
policy = generate_policy(queue_arn: queue_arn, topic_arns: topic_arns)
|
65
|
+
else
|
66
|
+
policy = '' # Be blank when there're no subscriptions.
|
67
|
+
end
|
68
|
+
|
69
|
+
sqs_client.set_queue_attributes(
|
70
|
+
queue_url: @sns_subscription.job_queue.queue_url,
|
71
|
+
attributes: { 'Policy' => policy },
|
72
|
+
)
|
73
|
+
end
|
74
|
+
|
75
|
+
# @paaram [String] queue_arn
|
76
|
+
# @param [Array<String>] topic_arns
|
77
|
+
# @return [String] JSON formatted policy
|
78
|
+
def generate_policy(queue_arn:, topic_arns:)
|
79
|
+
{
|
80
|
+
'Version' => '2012-10-17',
|
81
|
+
'Statement' => [
|
82
|
+
'Effect' => 'Allow',
|
83
|
+
'Principal' => '*',
|
84
|
+
'Action' => 'sqs:SendMessage',
|
85
|
+
'Resource' => queue_arn,
|
86
|
+
'Condition' => {
|
87
|
+
'ArnEquals' => {
|
88
|
+
'aws:SourceArn' => topic_arns,
|
89
|
+
}
|
90
|
+
}
|
91
|
+
]
|
92
|
+
}.to_json
|
93
|
+
end
|
94
|
+
|
95
|
+
def subscribe_topic!
|
96
|
+
sns_client.subscribe(
|
97
|
+
topic_arn: @sns_subscription.topic_arn,
|
98
|
+
protocol: 'sqs',
|
99
|
+
endpoint: queue_arn
|
100
|
+
)
|
101
|
+
end
|
102
|
+
|
103
|
+
def unsubscribe_topic!
|
104
|
+
sqs_attrs = sqs_client.get_queue_attributes(
|
105
|
+
queue_url: @sns_subscription.job_queue.queue_url,
|
106
|
+
attribute_names: ['QueueArn'],
|
107
|
+
)
|
108
|
+
queue_arn = sqs_attrs.attributes['QueueArn']
|
109
|
+
|
110
|
+
subscriptions = sns_client.list_subscriptions_by_topic(
|
111
|
+
topic_arn: @sns_subscription.topic_arn,
|
112
|
+
)
|
113
|
+
subscription_arn = subscriptions.subscriptions.find {|subscription| subscription.endpoint == queue_arn }.try!(:subscription_arn)
|
114
|
+
|
115
|
+
if subscription_arn
|
116
|
+
sns_client.unsubscribe(
|
117
|
+
subscription_arn: subscription_arn,
|
118
|
+
)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def sqs_client
|
123
|
+
@sqs_client ||= Aws::SQS::Client.new
|
124
|
+
end
|
125
|
+
|
126
|
+
def sns_client
|
127
|
+
@sns_client ||= Aws::SNS::Client.new
|
128
|
+
end
|
129
|
+
|
130
|
+
def queue_arn
|
131
|
+
return @queue_arn if @queue_arn
|
132
|
+
|
133
|
+
sqs_attrs = sqs_client.get_queue_attributes(
|
134
|
+
queue_url: @sns_subscription.job_queue.queue_url,
|
135
|
+
attribute_names: ['QueueArn'],
|
136
|
+
)
|
137
|
+
@queue_arn = sqs_attrs.attributes['QueueArn']
|
138
|
+
end
|
139
|
+
end
|
@@ -2,6 +2,8 @@ class Barbeque::JobQueue < Barbeque::ApplicationRecord
|
|
2
2
|
SQS_NAME_PREFIX = ENV['BARBEQUE_SQS_NAME_PREFIX'] || 'Barbeque-'
|
3
3
|
SQS_NAME_MAX_LENGTH = 80
|
4
4
|
|
5
|
+
has_many :sns_subscriptions, class_name: 'SNSSubscription', dependent: :destroy
|
6
|
+
|
5
7
|
# All SQS queues' "ReceiveMessageWaitTimeSeconds" are configured to be 20s (maximum).
|
6
8
|
# This should be as large as possible to reduce API-calling cost by long polling.
|
7
9
|
# http://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_CreateQueue.html#API_CreateQueue_RequestParameters
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module Barbeque
|
2
|
+
class SNSSubscription < ApplicationRecord
|
3
|
+
belongs_to :job_queue
|
4
|
+
belongs_to :job_definition
|
5
|
+
has_one :app, through: :job_definition
|
6
|
+
|
7
|
+
validates :topic_arn,
|
8
|
+
uniqueness: { scope: :job_queue, message: 'should be set with only one queue' },
|
9
|
+
presence: true
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
.box.box-primary
|
2
|
+
.box-header
|
3
|
+
%h3.box-title.with_padding
|
4
|
+
#{action_name.capitalize} SNS Subscription
|
5
|
+
|
6
|
+
.box-body
|
7
|
+
= form_for @sns_subscription do |f|
|
8
|
+
- if @sns_subscription.errors.any?
|
9
|
+
%strong #{pluralize(@sns_subscription.errors.count, 'error')} prohibited this SNS subscription from being saved:
|
10
|
+
%ul
|
11
|
+
- @sns_subscription.errors.full_messages.each do |msg|
|
12
|
+
%li= msg
|
13
|
+
|
14
|
+
.row.form-group
|
15
|
+
.col-md-8
|
16
|
+
= f.label :topic_arn
|
17
|
+
- if @sns_subscription.persisted?
|
18
|
+
.sns_subscription_topic_arn= @sns_subscription.topic_arn
|
19
|
+
- else
|
20
|
+
= f.collection_select :topic_arn, @sns_topic_arns.map {|t| [t] }, :first, :first,
|
21
|
+
{ prompt: true }, class: 'form-control'
|
22
|
+
|
23
|
+
.row.form-group
|
24
|
+
.col-md-4
|
25
|
+
= f.label :job_queue_id
|
26
|
+
- if @sns_subscription.persisted?
|
27
|
+
.sns_subscription_job_queue_id= link_to @sns_subscription.job_queue.name, @sns_subscription.job_queue
|
28
|
+
- else
|
29
|
+
= f.collection_select :job_queue_id, Barbeque::JobQueue.pluck(:id, :name), :first, :second,
|
30
|
+
{ prompt: true }, class: 'form-control'
|
31
|
+
|
32
|
+
.row.form-group
|
33
|
+
.col-md-4
|
34
|
+
= f.label :job_definition_id
|
35
|
+
= f.collection_select :job_definition_id, Barbeque::JobDefinition.pluck(:id, :job), :first, :second,
|
36
|
+
{ prompt: true }, class: 'form-control'
|
37
|
+
|
38
|
+
.form-group
|
39
|
+
= f.submit 'Save', class: 'btn btn-primary'
|
@@ -0,0 +1,24 @@
|
|
1
|
+
.box.box-primary
|
2
|
+
.box-header
|
3
|
+
%h3.box-title.with_padding
|
4
|
+
All SNS Subscriptions
|
5
|
+
= link_to new_sns_subscription_path, class: 'btn btn-primary pull-right' do
|
6
|
+
New SNS Subscriptions
|
7
|
+
|
8
|
+
.box-body
|
9
|
+
%table.table.table-bordered
|
10
|
+
%thead
|
11
|
+
%tr
|
12
|
+
%th topic_arn
|
13
|
+
%th Job Queue
|
14
|
+
%th Job Definition
|
15
|
+
%th
|
16
|
+
|
17
|
+
%tbody
|
18
|
+
- @sns_subscriptions.each do |sns_subscription|
|
19
|
+
%tr
|
20
|
+
%td= sns_subscription.topic_arn
|
21
|
+
%td= sns_subscription.job_queue.name
|
22
|
+
%td= sns_subscription.job_definition.job
|
23
|
+
%td
|
24
|
+
= link_to 'View Details', sns_subscription, class: 'btn btn-default btn-sm'
|
@@ -0,0 +1,28 @@
|
|
1
|
+
.row
|
2
|
+
.col-sm-7
|
3
|
+
.box.box-primary
|
4
|
+
.box-header
|
5
|
+
%h3.box-title.with_padding
|
6
|
+
SNS Subscription Details
|
7
|
+
|
8
|
+
.box-body
|
9
|
+
%p#notice= notice
|
10
|
+
|
11
|
+
%table.table.table-bordered
|
12
|
+
%tbody
|
13
|
+
%tr
|
14
|
+
%th topic_arn
|
15
|
+
%td= @sns_subscription.topic_arn
|
16
|
+
%tr
|
17
|
+
%th Job Queue
|
18
|
+
%td= link_to @sns_subscription.job_queue.name, @sns_subscription.job_queue
|
19
|
+
%tr
|
20
|
+
%th Job Defenition
|
21
|
+
%td= link_to @sns_subscription.job_definition.job, @sns_subscription.job_definition
|
22
|
+
%tr
|
23
|
+
|
24
|
+
= link_to 'Edit', edit_sns_subscription_path(@sns_subscription), class: 'btn btn-primary'
|
25
|
+
= link_to 'Destroy', sns_subscription_path(@sns_subscription),
|
26
|
+
class: 'btn', method: :delete, data: { confirm: 'Are you sure to delete SNS subscription?' }
|
27
|
+
|
28
|
+
= link_to 'Back', sns_subscriptions_path
|
@@ -14,6 +14,10 @@
|
|
14
14
|
= link_to job_queues_path do
|
15
15
|
%i.fa.fa-cubes
|
16
16
|
%span Queues
|
17
|
+
%li{ class: ('active' if controller_path == 'barbeque/sns_subscriptions') }
|
18
|
+
= link_to sns_subscriptions_path do
|
19
|
+
%i.fa.fa-calendar-plus-o
|
20
|
+
%span SNS Subscriptions
|
17
21
|
%li{ class: ('active' if controller_path == 'barbeque/monitors') }
|
18
22
|
= link_to monitors_path do
|
19
23
|
%i.fa.fa-tachometer
|
@@ -6,7 +6,7 @@
|
|
6
6
|
%title Barbeque
|
7
7
|
%meta{ content: 'width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no', name: 'viewport' }
|
8
8
|
-# FIXME: Don't rely on others' CDN
|
9
|
-
%link{ href: 'https://maxcdn.bootstrapcdn.com/font-awesome/4.
|
9
|
+
%link{ href: 'https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css', rel: 'stylesheet', type: 'text/css' }
|
10
10
|
%link{ href: 'https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css', rel: 'stylesheet', type: 'text/css' }
|
11
11
|
= stylesheet_link_tag 'barbeque/application', media: 'all'
|
12
12
|
= javascript_include_tag 'barbeque/application'
|
data/config/routes.rb
CHANGED
@@ -0,0 +1,11 @@
|
|
1
|
+
class CreateBarbequeSnsSubscriptions < ActiveRecord::Migration[5.0]
|
2
|
+
def change
|
3
|
+
create_table :barbeque_sns_subscriptions do |t|
|
4
|
+
t.string :topic_arn, null: false
|
5
|
+
t.integer :job_queue_id, null: false
|
6
|
+
t.integer :job_definition_id, null: false
|
7
|
+
|
8
|
+
t.timestamps
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
data/lib/barbeque/message.rb
CHANGED
@@ -4,8 +4,8 @@ module Barbeque
|
|
4
4
|
module Message
|
5
5
|
class JobExecution < Base
|
6
6
|
attr_reader :body # [Object] free-format JSON
|
7
|
-
attr_reader :application # [String] To specify `job_definitions.
|
8
|
-
attr_reader :job # [String] To specify `job_definitions.
|
7
|
+
attr_reader :application # [String] To specify `job_definitions.app.name`
|
8
|
+
attr_reader :job # [String] To specify `job_definitions.job`
|
9
9
|
|
10
10
|
private
|
11
11
|
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'barbeque/message/base'
|
2
|
+
|
3
|
+
module Barbeque
|
4
|
+
module Message
|
5
|
+
class Notification < Base
|
6
|
+
attr_reader :body # [Object] free-format JSON
|
7
|
+
attr_reader :topic_arn # [String] To specify `subscription.topic_arn`
|
8
|
+
attr_reader :application # [String] To specify `job_definitions.app.name`
|
9
|
+
attr_reader :job # [String] To specify `job_definitions.job`
|
10
|
+
|
11
|
+
# @param [Barneque::SNSSubscription] subscription
|
12
|
+
# @return [Barbeque::Message::Notification]
|
13
|
+
def set_params_from_subscription(subscription)
|
14
|
+
@application = subscription.app.name
|
15
|
+
@job = subscription.job_definition.job
|
16
|
+
self
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def assign_body(message_body)
|
22
|
+
super
|
23
|
+
@topic_arn = message_body['TopicArn']
|
24
|
+
@body = message_body['Message']
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'barbeque/docker_image'
|
2
|
+
require 'barbeque/execution_log'
|
3
|
+
require 'barbeque/runner'
|
4
|
+
require 'barbeque/slack_client'
|
5
|
+
require 'barbeque/message_handler/job_execution'
|
6
|
+
|
7
|
+
module Barbeque
|
8
|
+
module MessageHandler
|
9
|
+
class Notification < JobExecution
|
10
|
+
# @param [Barbeque::Message::Notification] message
|
11
|
+
# @param [Barbeque::JobQueue] job_queue
|
12
|
+
def initialize(message:, job_queue:)
|
13
|
+
@message = message
|
14
|
+
@job_queue = job_queue
|
15
|
+
|
16
|
+
subscription = SNSSubscription.find_by!(topic_arn: @message.topic_arn, job_queue_id: @job_queue.id)
|
17
|
+
@message.set_params_from_subscription(subscription)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/barbeque/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: barbeque
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Takashi Kokubun
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-04-
|
11
|
+
date: 2017-04-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: adminlte2-rails
|
@@ -289,6 +289,7 @@ files:
|
|
289
289
|
- app/controllers/barbeque/job_queues_controller.rb
|
290
290
|
- app/controllers/barbeque/job_retries_controller.rb
|
291
291
|
- app/controllers/barbeque/monitors_controller.rb
|
292
|
+
- app/controllers/barbeque/sns_subscriptions_controller.rb
|
292
293
|
- app/helpers/barbeque/application_helper.rb
|
293
294
|
- app/helpers/barbeque/job_definitions_helper.rb
|
294
295
|
- app/helpers/barbeque/job_executions_helper.rb
|
@@ -305,6 +306,7 @@ files:
|
|
305
306
|
- app/models/barbeque/job_queue.rb
|
306
307
|
- app/models/barbeque/job_retry.rb
|
307
308
|
- app/models/barbeque/slack_notification.rb
|
309
|
+
- app/models/barbeque/sns_subscription.rb
|
308
310
|
- app/services/barbeque/message_enqueuing_service.rb
|
309
311
|
- app/services/barbeque/message_retrying_service.rb
|
310
312
|
- app/views/barbeque/apps/_form.html.haml
|
@@ -327,6 +329,11 @@ files:
|
|
327
329
|
- app/views/barbeque/job_queues/show.html.haml
|
328
330
|
- app/views/barbeque/job_retries/show.html.haml
|
329
331
|
- app/views/barbeque/monitors/index.html.haml
|
332
|
+
- app/views/barbeque/sns_subscriptions/_form.html.haml
|
333
|
+
- app/views/barbeque/sns_subscriptions/edit.html.haml
|
334
|
+
- app/views/barbeque/sns_subscriptions/index.html.haml
|
335
|
+
- app/views/barbeque/sns_subscriptions/new.html.haml
|
336
|
+
- app/views/barbeque/sns_subscriptions/show.html.haml
|
330
337
|
- app/views/layouts/barbeque/_header.html.haml
|
331
338
|
- app/views/layouts/barbeque/_sidebar.html.haml
|
332
339
|
- app/views/layouts/barbeque/application.html.haml
|
@@ -347,6 +354,7 @@ files:
|
|
347
354
|
- db/migrate/20160509041452_add_job_queue_id_to_job_executions.rb
|
348
355
|
- db/migrate/20160516041710_create_job_retries.rb
|
349
356
|
- db/migrate/20160829023237_prefix_barbeque_to_tables.rb
|
357
|
+
- db/migrate/20170420030157_create_barbeque_sns_subscriptions.rb
|
350
358
|
- lib/barbeque.rb
|
351
359
|
- lib/barbeque/config.rb
|
352
360
|
- lib/barbeque/docker_image.rb
|
@@ -358,9 +366,11 @@ files:
|
|
358
366
|
- lib/barbeque/message/invalid_message.rb
|
359
367
|
- lib/barbeque/message/job_execution.rb
|
360
368
|
- lib/barbeque/message/job_retry.rb
|
369
|
+
- lib/barbeque/message/notification.rb
|
361
370
|
- lib/barbeque/message_handler.rb
|
362
371
|
- lib/barbeque/message_handler/job_execution.rb
|
363
372
|
- lib/barbeque/message_handler/job_retry.rb
|
373
|
+
- lib/barbeque/message_handler/notification.rb
|
364
374
|
- lib/barbeque/message_queue.rb
|
365
375
|
- lib/barbeque/runner.rb
|
366
376
|
- lib/barbeque/runner/docker.rb
|
@@ -390,7 +400,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
390
400
|
version: '0'
|
391
401
|
requirements: []
|
392
402
|
rubyforge_project:
|
393
|
-
rubygems_version: 2.6.
|
403
|
+
rubygems_version: 2.6.11
|
394
404
|
signing_key:
|
395
405
|
specification_version: 4
|
396
406
|
summary: Job queue system to run job with Docker
|