simnos 0.1.0.beta4 → 0.1.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 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