simnos 0.1.0.beta4 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9e73c37a3d3496d3566b8f5d6ef17f52cacef62a
4
- data.tar.gz: 4a9ae23753a4879f3f0ff2d24560d378a959d31e
3
+ metadata.gz: 38020c8fa6b7c99e9aa74293b2835ba3c2c1b004
4
+ data.tar.gz: 5f0d61084dc248763ec1c6704196d7c0b6757710
5
5
  SHA512:
6
- metadata.gz: 787cc521de2adbdcb594f385f1ea95328c90ee2148a6bc6a74985a001cee7e8fb1fca45192dfeb3f3edc7285353a69bddc83f9193f4a16f52d3353636d23d6fd
7
- data.tar.gz: '0989e8dc63a28b094fdd3f1f2b3f484b48143b224f967c7188db5ed4717175b911aadb0555cbcb82a6ed28de546c1740191b2e966c8c8922663c9cc5327ae464'
6
+ metadata.gz: f849048fb5de7f875206640e220117bd8b8abafb758aa32b8de1f15dc828c9bdec3f15affb0bbdde3b0521536da059baf45cb3ba8b0a75520633574a7e9ca7b6
7
+ data.tar.gz: 5abcc2a81d5f4ed434ad1d652cf21e0aec9f130dbd3052e3d6ceed1275e0f361d112d8d773c40b1f598fafffa95cf049d7b0b88a93aa7db5a03820943494c332
data/README.md CHANGED
@@ -25,7 +25,7 @@ Or install it yourself as:
25
25
  export AWS_ACCESS_KEY_ID='...'
26
26
  export AWS_SECRET_ACCESS_KEY='...'
27
27
  export AWS_REGION='ap-northeast-1'
28
- simnos -e -o SNSfile # export SNS topic
28
+ simnos -e -f SNSfile # export SNS topic
29
29
  vi SNSfile
30
30
  simnos -a --dry-run
31
31
  simnos -a # apply `SNSfile` to SNS
@@ -35,8 +35,8 @@ simnos -a # apply `SNSfile` to SNS
35
35
 
36
36
  ```
37
37
  Usage: simnos [options]
38
- -h, --help Show help
39
- -v, --debug Show debug log
38
+ -h, --help show help
39
+ -v, --debug show debug log
40
40
  -a, --apply apply DSL
41
41
  -e, --export export to DSL
42
42
  -n, --dry-run dry run
@@ -44,6 +44,8 @@ Usage: simnos [options]
44
44
  -s, --split split export DSL file to 1 per topic
45
45
  --no-color
46
46
  no color
47
+ --with-subscriptions
48
+ manage subscriptions
47
49
  -i, --include-names NAMES include SNS names
48
50
  -x, --exclude-names NAMES exclude SNS names by regex
49
51
  ```
@@ -79,6 +81,13 @@ sns "ap-northeast-1" do
79
81
  "Resource"=>"arn:aws:sns:ap-northeast-1:XXXXXXXXXXXX:test-topic",
80
82
  "Condition"=>{"StringEquals"=>{"AWS:SourceOwner"=>"XXXXXXXXXXXX"}}}]}
81
83
  end
84
+
85
+ subscriptions opt_out: false do
86
+ subscription protocol: "https", endpoint: "https://your.awesome.site/"
87
+ subscription protocol: "email", endpoint: "simnos@example.com"
88
+ subscription protocol: "email-json", endpoint: "simnos@example.com"
89
+ subscription protocol: "sqs", endpoint: "arn:aws:sqs:ap-northeast-1:XXXXXXXXXXXX:test-queue"
90
+ end
82
91
  end
83
92
  end
84
93
  ```
data/lib/simnos/cli.rb CHANGED
@@ -35,14 +35,15 @@ module Simnos
35
35
  def parser
36
36
  @parser ||= OptionParser.new do |opts|
37
37
  opts.version = VERSION
38
- opts.on('-h', '--help', 'Show help') { @help = true }
39
- opts.on('-v', '--debug', 'Show debug log') { Simnos.logger.level = Logger::DEBUG }
38
+ opts.on('-h', '--help', 'show help') { @help = true }
39
+ opts.on('-v', '--debug', 'show debug log') { Simnos.logger.level = Logger::DEBUG }
40
40
  opts.on('-a', '--apply', 'apply DSL') { @apply = true }
41
41
  opts.on('-e', '--export', 'export to DSL') { @export = true }
42
42
  opts.on('-n', '--dry-run', 'dry run') { @options[:dry_run] = true }
43
43
  opts.on('-f', '--file FILE', 'use selected DSL file') { |v| @filepath = v }
44
44
  opts.on('-s', '--split', 'split export DSL file to 1 per topic') { @options[:split] = true }
45
45
  opts.on('', '--no-color', 'no color') { @options[:color] = false }
46
+ opts.on('', '--with-subscriptions', 'manage subscriptions') { @options[:with_subscriptions] = true }
46
47
  opts.on('-i', '--include-names NAMES', 'include SNS names', Array) { |v| @options[:includes] = v }
47
48
  opts.on('-x', '--exclude-names NAMES', 'exclude SNS names by regex', Array) do |v|
48
49
  @options[:excludes] = v.map! do |name|
data/lib/simnos/client.rb CHANGED
@@ -33,6 +33,13 @@ module Simnos
33
33
  Simnos.logger.info("Exporting...#{@options[:dry_run] ? ' [dry-run]' : ''}")
34
34
 
35
35
  topics_by_name = client.topics
36
+
37
+ if @options[:with_subscriptions]
38
+ topics_by_name.each do |name, topic|
39
+ Simnos.logger.debug("exporting subscriptions of #{topic[:topic].topic_arn}")
40
+ topic[:subscriptions] = client.subscriptions_by_topic(topic_arn: topic[:topic].topic_arn)
41
+ end
42
+ end
36
43
  region = client.region
37
44
 
38
45
  path = Pathname.new(@filepath)
@@ -63,11 +70,43 @@ module Simnos
63
70
 
64
71
  private
65
72
 
73
+ def traverse_subscriptions(aws_topic, dsl_subscriptions, aws_subscriptions)
74
+ dsl_sub_by_key = dsl_subscriptions.each_with_object({}) { |dsl_sub, h| h[[dsl_sub.protocol, dsl_sub.endpoint]] = dsl_sub }
75
+ aws_sub_by_key = aws_subscriptions.each_with_object({}) { |aws_sub, h| h[[aws_sub.protocol, aws_sub.endpoint]] = aws_sub }
76
+ # create
77
+ dsl_sub_by_key.reject { |key, _| aws_sub_by_key[key] }.each do |key, dsl_sub|
78
+ dsl_sub.aws_topic(aws_topic).create
79
+ end
80
+
81
+ dsl_sub_by_key.each do |key, dsl_sub|
82
+ aws_sub_by_key.delete(key)
83
+ end
84
+
85
+ # delete
86
+ aws_sub_by_key.each do |key, aws_sub|
87
+ Simnos.logger.info("Delete Topic(#{aws_topic[:topic].topic_arn.split(':').last}) Subscription. protocol: #{key[0].inspect}, endpoint: #{key[1].inspect}.#{@options[:dry_run] ? ' [dry-run]' : ''}")
88
+ if aws_sub.subscription_arn.split(':').length < 6
89
+ Simnos.logger.warn("Can not delete Subscription `#{aws_sub.subscription_arn}`")
90
+ next
91
+ end
92
+ next if @options[:dry_run]
93
+
94
+ client.unsubscribe(subscription_arn: aws_sub.subscription_arn)
95
+ end
96
+ end
97
+
66
98
  def traverse_topics(dsl_topics_all, aws_topics_by_name)
67
99
  dsl_topics = dsl_topics_all.select { |t| target?(t.name) }
68
100
  # create
69
101
  dsl_topics.reject { |t| aws_topics_by_name[t.name] }.each do |dsl_topic|
70
- aws_topics_by_name[dsl_topic.name] = dsl_topic.create
102
+ aws_topic = dsl_topic.create
103
+
104
+ unless @options[:dry_run]
105
+ aws_topics_by_name[dsl_topic.name] = aws_topic
106
+ end
107
+ if @options[:with_subscriptions] && !dsl_topic.opt_out_subscriptions
108
+ traverse_subscriptions(aws_topic, dsl_topic.subscriptions, [])
109
+ end
71
110
  end
72
111
 
73
112
  # modify
@@ -75,11 +114,16 @@ module Simnos
75
114
  next unless aws_topic = aws_topics_by_name.delete(dsl_topic.name)
76
115
 
77
116
  dsl_topic.aws(aws_topic).modify
117
+
118
+ if @options[:with_subscriptions] && !dsl_topic.opt_out_subscriptions
119
+ aws_subscriptions = client.subscriptions_by_topic(topic_arn: aws_topic[:topic].topic_arn)
120
+ traverse_subscriptions(aws_topic, dsl_topic.subscriptions, aws_subscriptions)
121
+ end
78
122
  end
79
123
 
80
124
  # delete
81
125
  aws_topics_by_name.each do |name, aws_topic|
82
- Simnos.logger.info("Delete Topic #{name}")
126
+ Simnos.logger.info("Delete Topic #{name}.#{@options[:dry_run] ? ' [dry-run]' : ''}")
83
127
  next if @options[:dry_run]
84
128
 
85
129
  client.delete_topic(topic_arn: aws_topic[:topic].topic_arn)
@@ -7,7 +7,7 @@ module Simnos
7
7
  extend Forwardable
8
8
  include Filterable
9
9
 
10
- def_delegators :@client, *%i/delete_topic get_topic_attributes create_topic set_topic_attributes set_subscription_attributes/
10
+ def_delegators :@client, *%i/delete_topic get_topic_attributes create_topic set_topic_attributes set_subscription_attributes subscribe unsubscribe/
11
11
 
12
12
  def initialize(options)
13
13
  @options = options
@@ -40,6 +40,17 @@ module Simnos
40
40
  results
41
41
  end
42
42
 
43
+ def subscriptions_by_topic(topic_arn: )
44
+ results = []
45
+ next_token = nil
46
+ begin
47
+ resp = @client.list_subscriptions_by_topic(topic_arn: topic_arn, next_token: next_token)
48
+ results.concat(resp.subscriptions)
49
+ next_token = resp.next_token
50
+ end while next_token
51
+ results
52
+ end
53
+
43
54
  def region
44
55
  @client.config.region
45
56
  end
@@ -0,0 +1,41 @@
1
+ require 'simnos/utils'
2
+
3
+ module Simnos
4
+ class DSL
5
+ class Subscription
6
+ include Simnos::TemplateHelper
7
+
8
+ def create
9
+ Simnos.logger.info("Create Topic(#{@aws_topic[:topic].topic_arn.split(':').last}) Subscription. protocol: #{protocol.inspect}, endpoint: #{endpoint.inspect}#{@options[:dry_run] ? ' [dry-run]' : ''}")
10
+ return if @options[:dry_run]
11
+
12
+ client.subscribe(
13
+ topic_arn: @aws_topic[:topic].topic_arn,
14
+ protocol: protocol,
15
+ endpoint: endpoint,
16
+ )
17
+ end
18
+
19
+ def aws_topic(aws_topic)
20
+ @aws_topic = aws_topic
21
+ self
22
+ end
23
+
24
+ def initialize(context, topic: , protocol: , endpoint: )
25
+ @context = context
26
+ @options = @context.options
27
+ @topic = topic
28
+ @protocol = protocol
29
+ @endpoint = endpoint
30
+ end
31
+
32
+ attr_reader :topic, :protocol, :endpoint
33
+
34
+ private
35
+
36
+ def client
37
+ @client ||= Simnos::ClientWrapper.new(@context)
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,27 @@
1
+ require 'simnos/utils'
2
+ require 'simnos/dsl/subscription'
3
+
4
+ module Simnos
5
+ class DSL
6
+ class Subscriptions
7
+ include Simnos::TemplateHelper
8
+
9
+ def initialize(context, topic, &block)
10
+ @context = context
11
+ @topic = topic
12
+
13
+ @result = []
14
+
15
+ instance_eval(&block)
16
+ end
17
+
18
+ attr_reader :result
19
+
20
+ private
21
+
22
+ def subscription(protocol: , endpoint: )
23
+ @result << Subscription.new(@context, topic: @topic, protocol: protocol, endpoint: endpoint)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -1,4 +1,5 @@
1
1
  require 'simnos/utils'
2
+ require 'simnos/dsl/subscriptions'
2
3
 
3
4
  module Simnos
4
5
  class DSL
@@ -6,12 +7,13 @@ module Simnos
6
7
  include Simnos::TemplateHelper
7
8
 
8
9
  class Result
9
- ATTRIBUTES = %i/name display_name subscriptions_pending subscriptions_confirmed subscriptions_deleted effective_delivery_policy policy/
10
+ ATTRIBUTES = %i/name display_name subscriptions_pending subscriptions_confirmed subscriptions_deleted effective_delivery_policy policy topic_arn subscriptions aws_topic opt_out_subscriptions/
10
11
  attr_accessor *ATTRIBUTES
11
12
 
12
13
  def initialize(context)
13
14
  @context = context
14
15
  @options = context.options
16
+ @subscriptions = []
15
17
  end
16
18
 
17
19
  def to_h
@@ -24,10 +26,12 @@ module Simnos
24
26
  end
25
27
 
26
28
  def create
27
- Simnos.logger.info("Create Topic #{name}")
28
- return if @options[:dry_run]
29
+ Simnos.logger.info("Create Topic #{name}.#{@options[:dry_run] ? ' [dry-run]' : ''}")
30
+ return { topic: Hashie::Mash.new(topic_arn: 'not yet created') } if @options[:dry_run]
29
31
 
30
32
  resp = client.create_topic(name: name)
33
+ # save topic_arn
34
+ topic_arn = resp.topic_arn
31
35
  {
32
36
  topic: resp,
33
37
  attrs: client.topic_attrs(topic_arn: resp.topic_arn)
@@ -68,7 +72,7 @@ module Simnos
68
72
  Simnos.logger.debug(@aws_topic[:attrs].attributes.pretty_inspect)
69
73
  Simnos.logger.debug('--- dsl ---')
70
74
  Simnos.logger.debug(dsl_val)
71
- Simnos.logger.info("Modify Topic `#{name}` #{attr_name} attributes")
75
+ Simnos.logger.info("Modify Topic `#{name}` #{attr_name} attributes.#{@options[:dry_run] ? ' [dry-run]' : ''}")
72
76
  dsl_attrs = {
73
77
  attribute_name: attr_name,
74
78
  attribute_value: dsl_val,
@@ -88,7 +92,7 @@ module Simnos
88
92
  def modify_attr_hash(dsl_val, attr_name)
89
93
  aws_val = JSON.parse(@aws_topic[:attrs].attributes[attr_name])
90
94
  return if dsl_val == aws_val
91
- Simnos.logger.info("Modify Topic `#{name}` #{attr_name} attributes")
95
+ Simnos.logger.info("Modify Topic `#{name}` #{attr_name} attributes.#{@options[:dry_run] ? ' [dry-run]' : ''}")
92
96
  dsl_attrs = {
93
97
  attribute_name: attr_name,
94
98
  attribute_value: dsl_val,
@@ -166,6 +170,14 @@ module Simnos
166
170
  def policy
167
171
  @result.policy = yield
168
172
  end
173
+
174
+ def subscriptions(opt_out: false, &block)
175
+ if opt_out
176
+ @result.opt_out_subscriptions = true
177
+ return
178
+ end
179
+ @result.subscriptions = Subscriptions.new(@context, self, &block).result
180
+ end
169
181
  end
170
182
  end
171
183
  end
@@ -10,6 +10,14 @@ sns <%= region.inspect %> do
10
10
  policy do
11
11
  <%= JSON.parse(topic[:attrs].attributes['Policy']).pretty_inspect.gsub(/^/, ' ') -%>
12
12
  end
13
+ <%- if topic[:subscriptions] -%>
14
+
15
+ subscriptions do
16
+ <%- (topic[:subscriptions] || []).each do |subscription| -%>
17
+ subscription protocol: <%= subscription.protocol.inspect %>, endpoint: <%= subscription.endpoint.inspect %>
18
+ <%- end -%>
19
+ end
20
+ <%- end -%>
13
21
  end
14
22
  <%- if topics_by_name.keys.last != name -%>
15
23
 
@@ -1,3 +1,3 @@
1
1
  module Simnos
2
- VERSION = "0.1.0.beta4"
2
+ VERSION = "0.1.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simnos
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.beta4
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - wata
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-08-23 00:00:00.000000000 Z
11
+ date: 2017-10-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk
@@ -161,6 +161,8 @@ files:
161
161
  - lib/simnos/converter.rb
162
162
  - lib/simnos/dsl.rb
163
163
  - lib/simnos/dsl/sns.rb
164
+ - lib/simnos/dsl/subscription.rb
165
+ - lib/simnos/dsl/subscriptions.rb
164
166
  - lib/simnos/dsl/topic.rb
165
167
  - lib/simnos/filterable.rb
166
168
  - lib/simnos/output_topic.erb
@@ -183,12 +185,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
183
185
  version: '0'
184
186
  required_rubygems_version: !ruby/object:Gem::Requirement
185
187
  requirements:
186
- - - ">"
188
+ - - ">="
187
189
  - !ruby/object:Gem::Version
188
- version: 1.3.1
190
+ version: '0'
189
191
  requirements: []
190
192
  rubyforge_project:
191
- rubygems_version: 2.6.11
193
+ rubygems_version: 2.6.13
192
194
  signing_key:
193
195
  specification_version: 4
194
196
  summary: Codenize AWS SNS