constancy 0.1.5 → 0.2.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
- SHA1:
3
- metadata.gz: 7f2b5ae0525b88e9fc9b56f9d5bdcd4d84c143a3
4
- data.tar.gz: 6350e6dec7a606733ba292e002bc423dff8634af
2
+ SHA256:
3
+ metadata.gz: 65a3785bc8276043c12dd3a82fc0da2f23db508f8ccb9de6e074ef3fb34a0c01
4
+ data.tar.gz: 6f83ec7f19dfe57f28ae56b9179c3c34b9b5419c1bfc8c3f7f4338d08564675b
5
5
  SHA512:
6
- metadata.gz: 213832240c59baf7d8289a27cc5829d66c7cc6e61a072eaf9a25b20d54d6929f21c8b85a76ac6c0f76cd704dbe180d21a30e0d1adc58564f3d964d58f15e80b7
7
- data.tar.gz: c013397a8786af4f9f309a80217440b069c0459f7d71a8c072d1de34c366abbc2f2e4f2c69a31f960f560589e2c681bbe291e40310ff37cf2bba426913661093
6
+ metadata.gz: 6b4a9af5164674a87cc132d026fd7b7a1205f30ed94d255e37fa43d0ac46922235ab665836c7158f862441106947e3792bcd5d2338ca76f8ceb3cf4c22738c7b
7
+ data.tar.gz: 3b589b72c830dd07283e5fc5a19c5feb9f7404e4d3f949fa20915a44e9bf91a7fb03b9409e9d66805bb7343dbcdf9d33542bdb69373bc55020f5c82ee26900de
data/README.md CHANGED
@@ -112,6 +112,29 @@ required. An example `constancy.yml` is below including explanatory comments:
112
112
  # something other than the datacenter of the Consul agent.
113
113
  datacenter: dc1
114
114
 
115
+ # token_source - defaults to 'none'
116
+ # 'none': expect no Consul token (although env vars will be used if they are set)
117
+ # 'env': expect Consul token to be set in CONSUL_TOKEN or CONSUL_HTTP_TOKEN
118
+ # 'vault': read Consul token from Vault based on settings in the 'vault' section
119
+
120
+ # the vault section is only necessary if consul.token_source is set to 'vault'
121
+ vault:
122
+ # url - defaults to the value of VAULT_ADDR
123
+ # The REST API endpoint of your Vault server
124
+ url: https://your.vault.example
125
+
126
+ # path - the path to the endpoint from which to read the Consul token
127
+ # The Vault URI path to the Consul token - can be either the Consul
128
+ # dynamic backend or a KV endpoint with a static value. If the dynamic
129
+ # backend is used, the lease will be automatically revoked when
130
+ # constancy exits.
131
+ path: consul/creds/my-role
132
+
133
+ # field - name of the field in which the Consul token is stored
134
+ # Defaults to 'token' which is the field used by the dynamic backend
135
+ # but can be set to something else for static values.
136
+ field: token
137
+
115
138
  sync:
116
139
  # sync is an array of hashes of sync target configurations
117
140
  # Fields:
@@ -184,13 +207,11 @@ Constancy may be partially configured using environment variables:
184
207
  is given to `CONSUL_HTTP_TOKEN`) to set an explicit Consul token to use when
185
208
  interacting with the API. Otherwise, by default the agent's `acl_token`
186
209
  setting is used implicitly.
187
-
188
-
189
- ## Automation
190
-
191
- For version 0.1, Constancy does not fully support running non-interactively.
192
- This is primarily to ensure human observation of any changes being made while
193
- the software matures. Later versions will allow for full automation.
210
+ * `VAULT_ADDR` and `VAULT_TOKEN` - if `consul.token_source` is set to `vault`
211
+ these variables are used to authenticate to Vault. If `VAULT_TOKEN` is not
212
+ set, Constancy will attempt to read a token from `~/.vault-token`. If the
213
+ `url` field is set, it will take priority over the `VAULT_ADDR` environment
214
+ variable, but one or the other must be set.
194
215
 
195
216
 
196
217
  ## Roadmap
@@ -203,10 +224,10 @@ Constancy is very new software. There's more to be done. Some ideas:
203
224
  * Git awareness (branches, commit state, etc)
204
225
  * Automated tests
205
226
  * Logging of changes to files, syslog, other services
206
- * Allowing other means of providing a Consul token
207
227
  * Pull mode to sync from Consul to local filesystem
208
228
  * Using CAS to verify the key has not changed in the interim before updating/deleting
209
229
  * Submitting changes in batches using transactions
230
+ * Optional expansion of YAML or JSON files into multiple keys
210
231
 
211
232
 
212
233
  ## Contributing
data/constancy.gemspec CHANGED
@@ -26,4 +26,5 @@ Gem::Specification.new do |s|
26
26
 
27
27
  s.add_dependency 'imperium', '~>0.3'
28
28
  s.add_dependency 'diffy', '~>3.2'
29
+ s.add_dependency 'vault', '~>0.12'
29
30
  end
data/lib/constancy/cli.rb CHANGED
@@ -86,6 +86,15 @@ USAGE
86
86
  end
87
87
  STDERR.puts " #{e}"
88
88
  exit 1
89
+
90
+ rescue Constancy::ConsulTokenRequired => e
91
+ STDERR.puts "constancy: ERROR: No Consul token could be found: #{e}"
92
+ exit 1
93
+
94
+ rescue Constancy::VaultConfigInvalid => e
95
+ STDERR.puts "constancy: ERROR: Vault configuration invalid: #{e}"
96
+ exit 1
97
+
89
98
  end
90
99
 
91
100
  if Constancy.config.sync_targets.count < 1
@@ -3,13 +3,18 @@
3
3
  class Constancy
4
4
  class ConfigFileNotFound < RuntimeError; end
5
5
  class ConfigFileInvalid < RuntimeError; end
6
+ class ConsulTokenRequired < RuntimeError; end
7
+ class VaultConfigInvalid < RuntimeError; end
6
8
 
7
9
  class Config
8
10
  CONFIG_FILENAMES = %w( constancy.yml )
9
- VALID_CONFIG_KEYS = %w( sync consul constancy )
10
- VALID_CONSUL_CONFIG_KEYS = %w( url datacenter )
11
+ VALID_CONFIG_KEYS = %w( sync consul vault constancy )
12
+ VALID_CONSUL_CONFIG_KEYS = %w( url datacenter token_source )
13
+ VALID_VAULT_CONFIG_KEYS = %w( url path field )
11
14
  VALID_CONSTANCY_CONFIG_KEYS = %w( verbose chomp delete color )
12
15
  DEFAULT_CONSUL_URL = "http://localhost:8500"
16
+ DEFAULT_CONSUL_TOKEN_SOURCE = "none"
17
+ DEFAULT_VAULT_FIELD = "token"
13
18
 
14
19
  attr_accessor :config_file, :base_dir, :consul, :sync_targets, :target_whitelist
15
20
 
@@ -97,7 +102,83 @@ class Constancy
97
102
  end
98
103
 
99
104
  consul_url = raw['consul']['url'] || Constancy::Config::DEFAULT_CONSUL_URL
105
+
106
+ # start with a token from the environment, regardless of the token_source setting
100
107
  consul_token = ENV['CONSUL_HTTP_TOKEN'] || ENV['CONSUL_TOKEN']
108
+
109
+ case raw['consul']['token_source'] || Constancy::Config::DEFAULT_CONSUL_TOKEN_SOURCE
110
+ when "none"
111
+ # nothing to do
112
+
113
+ when "env"
114
+ if consul_token.nil? or consul_token == ""
115
+ raise Constancy::ConsulTokenRequired.new("Consul token_source is set to 'env' but neither CONSUL_TOKEN nor CONSUL_HTTP_TOKEN is set")
116
+ end
117
+
118
+ when "vault"
119
+ require 'vault'
120
+
121
+ raw['vault'] ||= {}
122
+ if not raw['vault'].is_a? Hash
123
+ raise Constancy::ConfigFileInvalid.new("'vault' must be a hash")
124
+ end
125
+
126
+ if (raw['vault'].keys - Constancy::Config::VALID_VAULT_CONFIG_KEYS) != []
127
+ raise Constancy::ConfigFileInvalid.new("Only the following keys are valid in the vault config: #{Constancy::Config::VALID_VAULT_CONFIG_KEYS.join(", ")}")
128
+ end
129
+
130
+ vault_path = raw['vault']['path']
131
+ if vault_path.nil? or vault_path == ""
132
+ raise Constancy::ConfigFileInvalid.new("vault.path must be specified to use vault as a token source")
133
+ end
134
+
135
+ # prioritize the config file over environment variables for vault address
136
+ vault_addr = raw['vault']['url'] || ENV['VAULT_ADDR']
137
+ if vault_addr.nil? or vault_addr == ""
138
+ raise Constancy::VaultConfigInvalid.new("Vault address must be set in vault.url or VAULT_ADDR")
139
+ end
140
+
141
+ vault_token = ENV['VAULT_TOKEN']
142
+ if vault_token.nil? or vault_token == ""
143
+ vault_token_file = File.expand_path("~/.vault-token")
144
+ if File.exist?(vault_token_file)
145
+ vault_token = File.read(vault_token_file)
146
+ else
147
+ raise Constancy::VaultConfigInvalid.new("Vault token must be set in ~/.vault-token or VAULT_TOKEN")
148
+ end
149
+ end
150
+
151
+ vault_field = raw['vault']['field'] || Constancy::Config::DEFAULT_VAULT_FIELD
152
+
153
+ ENV['VAULT_ADDR'] = vault_addr
154
+ ENV['VAULT_TOKEN'] = vault_token
155
+
156
+ begin
157
+ response = Vault.logical.read(vault_path)
158
+ consul_token = response.data[vault_field.to_sym]
159
+
160
+ if response.lease_id
161
+ at_exit {
162
+ begin
163
+ Vault.sys.revoke(response.lease_id)
164
+ rescue => e
165
+ # this is fine
166
+ end
167
+ }
168
+ end
169
+
170
+ rescue => e
171
+ raise Constancy::VaultConfigInvalid.new("Are you logged in to Vault?\n\n#{e}")
172
+ end
173
+
174
+ if consul_token.nil? or consul_token == ""
175
+ raise Constancy::VaultConfigInvalid.new("Could not acquire a Consul token from Vault")
176
+ end
177
+
178
+ else
179
+ raise Constancy::ConfigFileInvalid.new("Only the following values are valid for token_source: none, env, vault")
180
+ end
181
+
101
182
  self.consul = Imperium::Configuration.new(url: consul_url, token: consul_token)
102
183
 
103
184
  raw['constancy'] ||= {}
@@ -1,5 +1,5 @@
1
1
  # This software is public domain. No rights are reserved. See LICENSE for more information.
2
2
 
3
3
  class Constancy
4
- VERSION = "0.1.5"
4
+ VERSION = "0.2.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: constancy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Adams
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-11-29 00:00:00.000000000 Z
11
+ date: 2018-12-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: imperium
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '3.2'
41
+ - !ruby/object:Gem::Dependency
42
+ name: vault
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.12'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.12'
41
55
  description: Syncs content from the filesystem to the Consul KV store.
42
56
  email: daveadams@gmail.com
43
57
  executables:
@@ -77,7 +91,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
77
91
  version: '0'
78
92
  requirements: []
79
93
  rubyforge_project:
80
- rubygems_version: 2.6.13
94
+ rubygems_version: 2.7.6
81
95
  signing_key:
82
96
  specification_version: 4
83
97
  summary: Simple filesystem-to-Consul KV synchronization