simnos 0.1.1.beta1 → 0.1.1.beta2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|