simnos 0.1.1.beta1 → 0.1.1.beta2
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/README.md +23 -0
- data/lib/simnos/cli.rb +2 -0
- data/lib/simnos/client.rb +25 -11
- data/lib/simnos/dsl/subscription.rb +23 -2
- data/lib/simnos/secret_expander.rb +75 -0
- data/lib/simnos/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 331d3fe90ec21685f9fa4a969c2e3d77436d88c3
|
4
|
+
data.tar.gz: e9053c2ad17c3d06fceef1097eed7066e8fc94ab
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 61869e91186323165f8ea9cba28e1a79c503b25f10dec59167fea025abca8b9735bc14b5d843151e947f983abb2a20fa399e968fcf7fa01b63652c25bcaa34c5
|
7
|
+
data.tar.gz: a3aec65e414b5cab557b9d2ca491ee84e3188f1b8f93c913aa4ba49ef2681b12d7b524b2b970e49510126173c0c7be5d2eb7951eca0340f82d39f5791f36f2e0
|
data/README.md
CHANGED
@@ -46,6 +46,10 @@ Usage: simnos [options]
|
|
46
46
|
no color
|
47
47
|
--with-subscriptions
|
48
48
|
manage subscriptions
|
49
|
+
--recreate-subscriptions
|
50
|
+
recreate subscriptions
|
51
|
+
--secret-provider NAME
|
52
|
+
use secret value expansion
|
49
53
|
-i, --include-names NAMES include SNS names
|
50
54
|
-x, --exclude-names NAMES exclude SNS names by regex
|
51
55
|
```
|
@@ -114,6 +118,25 @@ sns "ap-northeast-1" do
|
|
114
118
|
end
|
115
119
|
```
|
116
120
|
|
121
|
+
## Secret provider
|
122
|
+
|
123
|
+
If you don't want to commit your Basic authentication password, you can use SecretProvider.
|
124
|
+
Use --secret-provider option to select provider.(e.g. --secret-provider=vault)
|
125
|
+
Expression inside `${...}` is passed to provider.
|
126
|
+
|
127
|
+
```
|
128
|
+
subscriptions do
|
129
|
+
subscription protocol: "https", endpoint: "https://user:${password}your.awesome.site/"
|
130
|
+
end
|
131
|
+
```
|
132
|
+
|
133
|
+
## Subscriptions
|
134
|
+
|
135
|
+
There is no way to UPDATE subscription.
|
136
|
+
So if you want to recreate subscrptions, use --recreate-subscriptions option.
|
137
|
+
It is highly recommended to also path --include-names or exclude-names to select topics.
|
138
|
+
Because of Basic authentication password is not returned from API, recreation is needed to change password.
|
139
|
+
|
117
140
|
## Similar tools
|
118
141
|
|
119
142
|
* [Codenize.tools](http://codenize.tools/)
|
data/lib/simnos/cli.rb
CHANGED
@@ -44,6 +44,8 @@ module Simnos
|
|
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
46
|
opts.on('', '--with-subscriptions', 'manage subscriptions') { @options[:with_subscriptions] = true }
|
47
|
+
opts.on('', '--recreate-subscriptions', 'recreate subscriptions') { @options[:recreate_subscriptions] = true }
|
48
|
+
opts.on('', '--secret-provider NAME', 'use secret value expansion') { |v| @options[:secret_provider] = v }
|
47
49
|
opts.on('-i', '--include-names NAMES', 'include SNS names', Array) { |v| @options[:includes] = v }
|
48
50
|
opts.on('-x', '--exclude-names NAMES', 'exclude SNS names by regex', Array) do |v|
|
49
51
|
@options[:excludes] = v.map! do |name|
|
data/lib/simnos/client.rb
CHANGED
@@ -3,6 +3,7 @@ require 'simnos/client_wrapper'
|
|
3
3
|
require 'simnos/converter'
|
4
4
|
require 'simnos/dsl'
|
5
5
|
require 'simnos/filterable'
|
6
|
+
require 'simnos/secret_expander'
|
6
7
|
|
7
8
|
module Simnos
|
8
9
|
class Client
|
@@ -15,6 +16,7 @@ module Simnos
|
|
15
16
|
def initialize(filepath, options = {})
|
16
17
|
@filepath = filepath
|
17
18
|
@options = options
|
19
|
+
@options[:secret_expander] = SecretExpander.new(@options[:secret_provider]) if @options[:secret_provider]
|
18
20
|
end
|
19
21
|
|
20
22
|
def apply
|
@@ -70,29 +72,41 @@ module Simnos
|
|
70
72
|
|
71
73
|
private
|
72
74
|
|
75
|
+
def delete_subscriptions(aws_topic, aws_sub_by_key)
|
76
|
+
aws_sub_by_key.each do |key, aws_sub|
|
77
|
+
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]' : ''}")
|
78
|
+
if aws_sub.subscription_arn.split(':').length < 6
|
79
|
+
Simnos.logger.warn("Can not delete Subscription `#{aws_sub.subscription_arn}`")
|
80
|
+
next
|
81
|
+
end
|
82
|
+
next if @options[:dry_run]
|
83
|
+
|
84
|
+
client.unsubscribe(subscription_arn: aws_sub.subscription_arn)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
73
88
|
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.
|
89
|
+
dsl_sub_by_key = dsl_subscriptions.each_with_object({}) { |dsl_sub, h| h[[dsl_sub.protocol, dsl_sub.masked_endpoint]] = dsl_sub }
|
75
90
|
aws_sub_by_key = aws_subscriptions.each_with_object({}) { |aws_sub, h| h[[aws_sub.protocol, aws_sub.endpoint]] = aws_sub }
|
91
|
+
|
92
|
+
if @options[:recreate_subscriptions]
|
93
|
+
Simnos.logger.info("Subscription recreation flag is on.#{@options[:dry_run] ? ' [dry-run]' : ''}")
|
94
|
+
delete_subscriptions(aws_topic, aws_sub_by_key)
|
95
|
+
aws_sub_by_key = {}
|
96
|
+
end
|
97
|
+
|
76
98
|
# create
|
77
99
|
dsl_sub_by_key.reject { |key, _| aws_sub_by_key[key] }.each do |key, dsl_sub|
|
78
100
|
dsl_sub.aws_topic(aws_topic).create
|
79
101
|
end
|
80
102
|
|
103
|
+
# there is no way to update subscriptions
|
81
104
|
dsl_sub_by_key.each do |key, dsl_sub|
|
82
105
|
aws_sub_by_key.delete(key)
|
83
106
|
end
|
84
107
|
|
85
108
|
# delete
|
86
|
-
|
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
|
109
|
+
delete_subscriptions(aws_topic, aws_sub_by_key)
|
96
110
|
end
|
97
111
|
|
98
112
|
def traverse_topics(dsl_topics_all, aws_topics_by_name)
|
@@ -6,7 +6,7 @@ module Simnos
|
|
6
6
|
include Simnos::TemplateHelper
|
7
7
|
|
8
8
|
def create
|
9
|
-
Simnos.logger.info("Create Topic(#{@aws_topic[:topic].topic_arn.split(':').last}) Subscription. protocol: #{protocol.inspect}, endpoint: #{
|
9
|
+
Simnos.logger.info("Create Topic(#{@aws_topic[:topic].topic_arn.split(':').last}) Subscription. protocol: #{protocol.inspect}, endpoint: #{masked_endpoint.inspect}#{@options[:dry_run] ? ' [dry-run]' : ''}")
|
10
10
|
return if @options[:dry_run]
|
11
11
|
|
12
12
|
client.subscribe(
|
@@ -29,7 +29,28 @@ module Simnos
|
|
29
29
|
@endpoint = endpoint
|
30
30
|
end
|
31
31
|
|
32
|
-
attr_reader :topic, :protocol
|
32
|
+
attr_reader :topic, :protocol
|
33
|
+
|
34
|
+
# We have to mask endpoint because SNS returns masked endpoint from API
|
35
|
+
def masked_endpoint
|
36
|
+
if URI.extract(@endpoint, ['http', 'https']).empty?
|
37
|
+
return endpoint
|
38
|
+
end
|
39
|
+
uri = URI.parse(endpoint)
|
40
|
+
if md = uri.userinfo&.match(/(.*):(.*)/)
|
41
|
+
uri.userinfo = "#{md[1]}:****"
|
42
|
+
end
|
43
|
+
uri.to_s
|
44
|
+
end
|
45
|
+
|
46
|
+
def endpoint
|
47
|
+
secret_expander = @options[:secret_expander]
|
48
|
+
if secret_expander
|
49
|
+
secret_expander.expand(@endpoint)
|
50
|
+
else
|
51
|
+
@endpoint
|
52
|
+
end
|
53
|
+
end
|
33
54
|
|
34
55
|
private
|
35
56
|
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'strscan'
|
2
|
+
|
3
|
+
module Simnos
|
4
|
+
class ExpansionError < StandardError
|
5
|
+
end
|
6
|
+
|
7
|
+
class SecretExpander
|
8
|
+
Literal = Struct.new(:literal)
|
9
|
+
Variable = Struct.new(:name)
|
10
|
+
|
11
|
+
def initialize(provider_name)
|
12
|
+
@provider = load_provider(provider_name)
|
13
|
+
@asked_variables = {}
|
14
|
+
end
|
15
|
+
|
16
|
+
def expand(str)
|
17
|
+
tokens = parse(str)
|
18
|
+
variables = Set.new
|
19
|
+
tokens.each do |token|
|
20
|
+
if token.is_a?(Variable)
|
21
|
+
unless @asked_variables.include?(token.name)
|
22
|
+
variables << token.name
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
unless variables.empty?
|
28
|
+
@provider.ask(variables).each do |k, v|
|
29
|
+
@asked_variables[k] = v
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
tokens.map do |token|
|
34
|
+
case token
|
35
|
+
when Literal
|
36
|
+
token.literal
|
37
|
+
when Variable
|
38
|
+
@asked_variables.fetch(token.name)
|
39
|
+
else
|
40
|
+
raise ExpansionError.new("Unknown token type: #{token.class}")
|
41
|
+
end
|
42
|
+
end.join
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def parse(value)
|
48
|
+
s = StringScanner.new(value)
|
49
|
+
tokens = []
|
50
|
+
pos = 0
|
51
|
+
while s.scan_until(/\$\{(.*?)\}/)
|
52
|
+
pre = s.string.byteslice(pos...(s.pos - s.matched.size))
|
53
|
+
var = s[1]
|
54
|
+
unless pre.empty?
|
55
|
+
tokens << Literal.new(pre)
|
56
|
+
end
|
57
|
+
if var.empty?
|
58
|
+
raise ExpansionError.new('Empty interpolation is not allowed')
|
59
|
+
else
|
60
|
+
tokens << Variable.new(var)
|
61
|
+
end
|
62
|
+
pos = s.pos
|
63
|
+
end
|
64
|
+
unless s.rest.empty?
|
65
|
+
tokens << Literal.new(s.rest)
|
66
|
+
end
|
67
|
+
tokens
|
68
|
+
end
|
69
|
+
|
70
|
+
def load_provider(name)
|
71
|
+
require "simnos/secret_providers/#{name}"
|
72
|
+
Simnos::SecretProviders.const_get(name.split('_').map(&:capitalize).join('')).new
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
data/lib/simnos/version.rb
CHANGED
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.1.
|
4
|
+
version: 0.1.1.beta2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- wata
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-10-
|
11
|
+
date: 2017-10-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk
|
@@ -166,6 +166,7 @@ files:
|
|
166
166
|
- lib/simnos/dsl/topic.rb
|
167
167
|
- lib/simnos/filterable.rb
|
168
168
|
- lib/simnos/output_topic.erb
|
169
|
+
- lib/simnos/secret_expander.rb
|
169
170
|
- lib/simnos/template_helper.rb
|
170
171
|
- lib/simnos/utils.rb
|
171
172
|
- lib/simnos/version.rb
|