lyra 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.github/workflows/unit_tests.yml +22 -0
- data/.gitignore +40 -0
- data/.ruby-version +1 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +62 -0
- data/LICENSE +21 -0
- data/README.md +143 -0
- data/Rakefile +10 -0
- data/exe/lyra +4 -0
- data/lib/lyra.rb +85 -0
- data/lib/lyra/client.rb +29 -0
- data/lib/lyra/client_config.rb +15 -0
- data/lib/lyra/config.rb +26 -0
- data/lib/lyra/item.rb +16 -0
- data/lib/lyra/logger.rb +16 -0
- data/lib/lyra/secret.rb +14 -0
- data/lib/lyra/template.rb +25 -0
- data/lib/lyra/version.rb +3 -0
- data/lyra.gemspec +41 -0
- metadata +207 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: fc3addb9ee2340c0fedb44a82abb5886656c47ee889ab82cddd6b540a3d30026
|
4
|
+
data.tar.gz: 9dbd0d75abd6c75c5fb1a64b3e3fde0b1c78f6c375b31953eddafe3d979a4d86
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ec43997f86032a06fde828947f64d6da1f1ac5973440eae633e6405f3d2da191ed6e059d08d2242367a965efd820a3daa7f0d0f57859d0d91a7a28faef67386b
|
7
|
+
data.tar.gz: 71e6e0c8cab567b7a5d7f9426c04745ec4f6947f6ea31606cd41a482fb187365eca5f4c805e0bce1330eaced839cd732abf9a691bd5494307363662ff3225c39
|
@@ -0,0 +1,22 @@
|
|
1
|
+
name: Unit Test
|
2
|
+
|
3
|
+
on: [push, pull_request]
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
tests:
|
7
|
+
runs-on: ubuntu-latest
|
8
|
+
steps:
|
9
|
+
- uses: actions/checkout@v2
|
10
|
+
- uses: actions/setup-ruby@v1
|
11
|
+
with:
|
12
|
+
ruby-version: '2.6'
|
13
|
+
- name: Bundle Install
|
14
|
+
run: gem install bundler:2.1.4 && bundle install
|
15
|
+
- name: Unit Tests
|
16
|
+
run: rake test
|
17
|
+
- name: Upload coverage results
|
18
|
+
uses: actions/upload-artifact@master
|
19
|
+
if: always()
|
20
|
+
with:
|
21
|
+
name: coverage-report
|
22
|
+
path: coverage
|
data/.gitignore
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
/.config
|
4
|
+
/coverage/
|
5
|
+
/InstalledFiles
|
6
|
+
/pkg/
|
7
|
+
/spec/reports/
|
8
|
+
/spec/examples.txt
|
9
|
+
/test/tmp/
|
10
|
+
/test/version_tmp/
|
11
|
+
/tmp/
|
12
|
+
|
13
|
+
# Used by dotenv library to load environment variables.
|
14
|
+
# .env
|
15
|
+
|
16
|
+
## Documentation cache and generated files:
|
17
|
+
/.yardoc/
|
18
|
+
/_yardoc/
|
19
|
+
/doc/
|
20
|
+
/rdoc/
|
21
|
+
|
22
|
+
## Environment normalization:
|
23
|
+
/.bundle/
|
24
|
+
/vendor/bundle
|
25
|
+
/lib/bundler/man/
|
26
|
+
|
27
|
+
# for a library or gem, you might want to ignore these files since the code is
|
28
|
+
# intended to run in multiple environments; otherwise, check them in:
|
29
|
+
# Gemfile.lock
|
30
|
+
# .ruby-version
|
31
|
+
# .ruby-gemset
|
32
|
+
|
33
|
+
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
34
|
+
.rvmrc
|
35
|
+
.DS_Store
|
36
|
+
|
37
|
+
# Jetbrains
|
38
|
+
.idea/
|
39
|
+
.rakeTasks
|
40
|
+
test/tests/.tmp
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.7.0
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
lyra (0.1.0)
|
5
|
+
aws-sdk-secretsmanager (~> 1.32.0)
|
6
|
+
json (~> 2.3.0)
|
7
|
+
rainbow (~> 3.0.0)
|
8
|
+
terminal-table (~> 1.8.0)
|
9
|
+
thor (~> 0.20.3)
|
10
|
+
|
11
|
+
GEM
|
12
|
+
remote: https://rubygems.org/
|
13
|
+
specs:
|
14
|
+
aws-eventstream (1.0.3)
|
15
|
+
aws-partitions (1.281.0)
|
16
|
+
aws-sdk-core (3.91.0)
|
17
|
+
aws-eventstream (~> 1.0, >= 1.0.2)
|
18
|
+
aws-partitions (~> 1, >= 1.239.0)
|
19
|
+
aws-sigv4 (~> 1.1)
|
20
|
+
jmespath (~> 1.0)
|
21
|
+
aws-sdk-secretsmanager (1.32.0)
|
22
|
+
aws-sdk-core (~> 3, >= 3.71.0)
|
23
|
+
aws-sigv4 (~> 1.1)
|
24
|
+
aws-sigv4 (1.1.1)
|
25
|
+
aws-eventstream (~> 1.0, >= 1.0.2)
|
26
|
+
byebug (11.1.1)
|
27
|
+
coderay (1.1.2)
|
28
|
+
docile (1.3.2)
|
29
|
+
jmespath (1.4.0)
|
30
|
+
json (2.3.0)
|
31
|
+
method_source (0.9.2)
|
32
|
+
minitest (5.14.0)
|
33
|
+
pry (0.12.2)
|
34
|
+
coderay (~> 1.1.0)
|
35
|
+
method_source (~> 0.9.0)
|
36
|
+
pry-byebug (3.7.0)
|
37
|
+
byebug (~> 11.0)
|
38
|
+
pry (~> 0.10)
|
39
|
+
rainbow (3.0.0)
|
40
|
+
rake (13.0.1)
|
41
|
+
simplecov (0.18.5)
|
42
|
+
docile (~> 1.1)
|
43
|
+
simplecov-html (~> 0.11)
|
44
|
+
simplecov-html (0.12.2)
|
45
|
+
terminal-table (1.8.0)
|
46
|
+
unicode-display_width (~> 1.1, >= 1.1.1)
|
47
|
+
thor (0.20.3)
|
48
|
+
unicode-display_width (1.7.0)
|
49
|
+
|
50
|
+
PLATFORMS
|
51
|
+
ruby
|
52
|
+
|
53
|
+
DEPENDENCIES
|
54
|
+
bundler (~> 2.0)
|
55
|
+
lyra!
|
56
|
+
minitest (~> 5.0)
|
57
|
+
pry-byebug (~> 3.7.0)
|
58
|
+
rake (~> 13.0)
|
59
|
+
simplecov (~> 0.18)
|
60
|
+
|
61
|
+
BUNDLED WITH
|
62
|
+
2.1.4
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2019 Mat Cartmill
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,143 @@
|
|
1
|
+
# Lyra
|
2
|
+
|
3
|
+
![Unit Test](https://github.com/HelloMustard/lyra/workflows/Unit%20Test/badge.svg?branch=master)
|
4
|
+
|
5
|
+
Lyra is a Ruby gem that fetches your application's passwords from AWS Secrets Manager and builds a file containing them using a `Templatefile` as the guide. This results in a simple and platform-agnostic approach to rendering your application password in to a compilable file.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
`gem install lyra`
|
10
|
+
|
11
|
+
## Usage
|
12
|
+
|
13
|
+
Once the gem is installed, simply running `lyra exec` is enough to get you started. However, should you want to pass in specific command line options instead of specifying values in your `Lyrafile`, you can do that as well.
|
14
|
+
|
15
|
+
```
|
16
|
+
--access_key_id [String] Your AWS Access Key ID
|
17
|
+
```
|
18
|
+
```
|
19
|
+
--secret_access_key [String] Your AWS Secret Access Key
|
20
|
+
```
|
21
|
+
```
|
22
|
+
--aws_region [String] Your AWS Region
|
23
|
+
```
|
24
|
+
```
|
25
|
+
--environment [String] Your specified secret environment
|
26
|
+
```
|
27
|
+
```
|
28
|
+
--config [String] Path to your Lyrafile
|
29
|
+
```
|
30
|
+
|
31
|
+
**Note**: Parameters passed in via CLI take precedence over those listed in your `Lyrafile`.
|
32
|
+
|
33
|
+
## Lyrafile
|
34
|
+
|
35
|
+
The Lyrafile is used to tell Lyra what to do. It is a YAML file with a basic structure and contains the following properties:
|
36
|
+
|
37
|
+
1. **access_key_id**
|
38
|
+
The environment variable that your `AWS_ACCESS_KEY_ID` is associated with. Do **not** commit your actual access key ID to the Lyrafile
|
39
|
+
2. **secret_access_key**
|
40
|
+
The environment variable that your `AWS_SECRET_ACCESS_KEY` is associated with. Do **not** commit your actual secret access key to the Lyrafile
|
41
|
+
3. **aws_region**
|
42
|
+
The AWS region that your Secrets Manager instance is in. Eg: `us-east-2`
|
43
|
+
4. **template_path**
|
44
|
+
The relative path from the project root to the file containing your template
|
45
|
+
5. **output_path**
|
46
|
+
The relative path from the project root to the desired location of the file containing your application's passwords
|
47
|
+
6. **environment**
|
48
|
+
Optional. If you've given your passwords an environment in Secrets Manager, add the environment here. Eg: `prod/someProvider`, enter `prod`. This will prefix **all** searches in Secrets Manager with the environment value and a trailing slash.
|
49
|
+
7. **secrets**
|
50
|
+
An array of secrets from Secrets Manager, and the item mapping for your template
|
51
|
+
|
52
|
+
As an example, an `Lyrafile` could similar to this:
|
53
|
+
|
54
|
+
```yml
|
55
|
+
access_key_id: MY_AWS_KEY_ENV_VAR
|
56
|
+
secret_access_key: MY_AWS_SECRET_ENV_VAR
|
57
|
+
aws_region: us-east-2
|
58
|
+
template_path: .lyra/Templatefile
|
59
|
+
output_path: Keys.swift
|
60
|
+
environment: prod
|
61
|
+
secrets:
|
62
|
+
- name: ProviderA
|
63
|
+
items:
|
64
|
+
- key: apiKey
|
65
|
+
property_name: apiKey
|
66
|
+
- key: apiSecret
|
67
|
+
property_name: apiSecret
|
68
|
+
- name: ProviderB
|
69
|
+
items:
|
70
|
+
- key: some.longer.key.from.aws.secretmanager.password
|
71
|
+
property_name: password
|
72
|
+
```
|
73
|
+
|
74
|
+
For more information about the `secrets` portion of the `Lyrafile`, see below.
|
75
|
+
|
76
|
+
## Templatefile
|
77
|
+
|
78
|
+
The Templatefile contains your template rendering code, written in Ruby, and is customizable however you want, as long as it remains valid syntax for use with `ERB`.
|
79
|
+
|
80
|
+
As an example, a `Templatefile` could look similar to this if we were adding secrets to a Swift application:
|
81
|
+
|
82
|
+
```ruby
|
83
|
+
enum Keys {
|
84
|
+
<% @secrets.each do |secret| %>
|
85
|
+
enum <%= secret.name %> {
|
86
|
+
<% secret.items.each do |item| %>
|
87
|
+
static let <%= item.property_name %> = <%= item.value %>
|
88
|
+
<% end %>
|
89
|
+
}
|
90
|
+
<% end %>
|
91
|
+
}
|
92
|
+
```
|
93
|
+
|
94
|
+
This very simple template could translate to
|
95
|
+
|
96
|
+
```swift
|
97
|
+
enum Keys {
|
98
|
+
enum ProviderA {
|
99
|
+
static let apiKey = "someApiKeyForProviderA"
|
100
|
+
static let apiSecret = "someApiSecretForProviderA"
|
101
|
+
}
|
102
|
+
enum ProviderB {
|
103
|
+
static let password = "somePasswordForProviderB"
|
104
|
+
}
|
105
|
+
}
|
106
|
+
```
|
107
|
+
|
108
|
+
## Secret Mapping
|
109
|
+
|
110
|
+
AWS Secrets Manager allows users to combine multiple key-value pairs under a single `secret name`. For example, in Secrets Manager you could create the following (*schema for information purposes only*):
|
111
|
+
|
112
|
+
```
|
113
|
+
{
|
114
|
+
secret_name: "prod/ProviderA"
|
115
|
+
secret_values: [
|
116
|
+
{
|
117
|
+
"key": "apiKey",
|
118
|
+
"value": "s0m3R3@a1LySt120nG@P1K3y!"
|
119
|
+
},
|
120
|
+
{
|
121
|
+
"key": "apiSecret",
|
122
|
+
"value": "s0m3R3@a1LySt120nG$3cR37!"
|
123
|
+
}
|
124
|
+
]
|
125
|
+
}
|
126
|
+
```
|
127
|
+
|
128
|
+
In the `Lyrafile` we would use the `secret_name` as the parent secret name, and the individual `secret_values` would be `item`s for that `secret`. As an example, the above would translate to the following `Lyrafile` format:
|
129
|
+
|
130
|
+
```yml
|
131
|
+
environment: prod
|
132
|
+
secrets:
|
133
|
+
- name: ProviderA
|
134
|
+
items:
|
135
|
+
- key: apiKey
|
136
|
+
property_name: apiKey
|
137
|
+
- key: apiSecret
|
138
|
+
property_name: apiSecret
|
139
|
+
```
|
140
|
+
|
141
|
+
The `property_name` attribute of the `item` only pertains to how the item is rendered in the template. Specifically, it is the name of the property that will be used to hold the secret value. You can give the `property_name` attribute any value you would like.
|
142
|
+
|
143
|
+
**Remember**: try to prefix all of your secrets with your environment in Secrets Manager, and use the `environment` attribute of the `Lyrafile` / CLI param to automatically append the `environment` to every secret fetch.
|
data/Rakefile
ADDED
data/exe/lyra
ADDED
data/lib/lyra.rb
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'rainbow'
|
2
|
+
require 'lyra/client'
|
3
|
+
require 'lyra/client_config'
|
4
|
+
require 'lyra/config'
|
5
|
+
require 'lyra/item'
|
6
|
+
require 'lyra/logger'
|
7
|
+
require 'lyra/secret'
|
8
|
+
require 'lyra/template'
|
9
|
+
require 'lyra/version'
|
10
|
+
require 'terminal-table'
|
11
|
+
require 'thor'
|
12
|
+
|
13
|
+
module Lyra
|
14
|
+
class Error < StandardError; end
|
15
|
+
|
16
|
+
class CLI < Thor
|
17
|
+
class_option :verbose, aliases: :v, type: :boolean, default: false
|
18
|
+
|
19
|
+
desc 'exec --access_key_id <aws access key id> --secret_access_key <aws secret access key> --config <path to Lyrafile>', 'Pulls the secrets from your AWS Secrets Manager instance and builds a file from template'
|
20
|
+
option :access_key_id, aliases: :b, type: :string
|
21
|
+
option :secret_access_key, aliases: :s, type: :string
|
22
|
+
option :aws_region, aliases: :r, type: :string
|
23
|
+
option :environment, aliases: :e, type: :string
|
24
|
+
option :config, aliases: :c, type: :string, default: "#{ENV['PWD']}/Lyrafile"
|
25
|
+
option :working_directory, aliases: :d, type: :string, default: '.'
|
26
|
+
def exec
|
27
|
+
configure_logger(verbose: options[:verbose])
|
28
|
+
|
29
|
+
raise Thor::Error, Rainbow("Cannot find Lyrafile at #{@options[:config]}").red unless File.exist?(@options[:config])
|
30
|
+
|
31
|
+
@config = Lyra::Config.new(path: @options[:config])
|
32
|
+
|
33
|
+
access_key_id = @options[:access_key_id] || ENV[@config.access_key_id]
|
34
|
+
raise Thor::Error, Rainbow("access_key_id cannot be nil").red if access_key_id.nil?
|
35
|
+
raise Thor::Error, Rainbow("access_key_id cannot be empty").red if access_key_id.empty?
|
36
|
+
|
37
|
+
secret_access_key = @options[:secret_access_key] || ENV[@config.secret_access_key]
|
38
|
+
raise Thor::Error, Rainbow("secret_access_key cannot be nil").red if secret_access_key.nil?
|
39
|
+
raise Thor::Error, Rainbow("secret_access_key cannot be empty").red if secret_access_key.empty?
|
40
|
+
|
41
|
+
aws_region = @options[:aws_region] || @config.aws_region
|
42
|
+
raise Thor::Error, Rainbow("aws_region cannot be nil").red if aws_region.nil?
|
43
|
+
raise Thor::Error, Rainbow("aws_region cannot be empty").red if aws_region.empty?
|
44
|
+
|
45
|
+
environment = @options[:environment] || @config.environment
|
46
|
+
|
47
|
+
client_config = Lyra::ClientConfig.new(access_key_id: access_key_id,
|
48
|
+
secret_access_key: secret_access_key,
|
49
|
+
aws_region: aws_region,
|
50
|
+
environment: environment)
|
51
|
+
@client = Lyra::Client.new(config: client_config)
|
52
|
+
|
53
|
+
secret_list = []
|
54
|
+
|
55
|
+
secrets = @config.secrets
|
56
|
+
secrets.each do |s|
|
57
|
+
secret = Lyra::Secret.new(hash: s)
|
58
|
+
item_list = []
|
59
|
+
|
60
|
+
remote_values = JSON.parse(@client.fetch_secret(secret_name: secret.name))
|
61
|
+
secret.items.each do |i|
|
62
|
+
item = Lyra::Item.new(hash: i)
|
63
|
+
|
64
|
+
raise Thor::Error, Rainbow("Could not retrieve value for item #{item.name}").red if remote_values[item.key].nil?
|
65
|
+
|
66
|
+
item.value = remote_values[item.key]
|
67
|
+
item_list.append(item)
|
68
|
+
end
|
69
|
+
|
70
|
+
secret.items = item_list
|
71
|
+
secret_list.append(secret)
|
72
|
+
end
|
73
|
+
|
74
|
+
template = Lyra::Template.new(secrets: secret_list, template_path: @config.template_path)
|
75
|
+
template.generate(output_path: @config.output_path)
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
def configure_logger(verbose: Boolean)
|
81
|
+
log.level = verbose ? Logger::DEBUG : Logger::INFO
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
data/lib/lyra/client.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'aws-sdk-secretsmanager'
|
2
|
+
|
3
|
+
module Lyra
|
4
|
+
class Client
|
5
|
+
|
6
|
+
def initialize(config: Lyra::ClientConfig)
|
7
|
+
@config = config
|
8
|
+
credentials = Aws::Credentials.new(@config.access_key_id, @config.secret_access_key)
|
9
|
+
@client = Aws::SecretsManager::Client.new(credentials: credentials, region: @config.aws_region)
|
10
|
+
end
|
11
|
+
|
12
|
+
def fetch_secret(secret_name: String)
|
13
|
+
response = @client.get_secret_value({
|
14
|
+
secret_id: make_secret_name(from: secret_name)
|
15
|
+
})
|
16
|
+
|
17
|
+
response.secret_string
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def make_secret_name(from: String)
|
23
|
+
environment_prefix = ''
|
24
|
+
environment_prefix = "#{@config.environment}/" unless @config.environment.nil? || @config.environment.empty?
|
25
|
+
"#{environment_prefix}#{from}"
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Lyra
|
2
|
+
class ClientConfig
|
3
|
+
attr_reader :access_key_id
|
4
|
+
attr_reader :secret_access_key
|
5
|
+
attr_reader :aws_region
|
6
|
+
attr_reader :environment
|
7
|
+
|
8
|
+
def initialize(access_key_id: String, secret_access_key: String, aws_region: String, environment: String)
|
9
|
+
@access_key_id = access_key_id
|
10
|
+
@secret_access_key = secret_access_key
|
11
|
+
@aws_region = aws_region
|
12
|
+
@environment = environment
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/lyra/config.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module Lyra
|
4
|
+
|
5
|
+
class Config
|
6
|
+
attr_reader :access_key_id
|
7
|
+
attr_reader :secret_access_key
|
8
|
+
attr_reader :aws_region
|
9
|
+
attr_reader :environment
|
10
|
+
attr_reader :output_path
|
11
|
+
attr_reader :secrets
|
12
|
+
attr_reader :template_path
|
13
|
+
|
14
|
+
def initialize(path: 'Lyrafile')
|
15
|
+
config = YAML::load_file(path).transform_keys(&:to_sym)
|
16
|
+
@access_key_id = config[:access_key_id]
|
17
|
+
@secret_access_key = config[:secret_access_key]
|
18
|
+
@aws_region = config[:aws_region]
|
19
|
+
@environment = config[:environment]
|
20
|
+
@output_path = config[:output_path]
|
21
|
+
@secrets = config[:secrets]
|
22
|
+
@template_path = config[:template_path]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
data/lib/lyra/item.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
module Lyra
|
2
|
+
|
3
|
+
class Item
|
4
|
+
attr_reader :key
|
5
|
+
attr_reader :property_name
|
6
|
+
attr_accessor :value
|
7
|
+
|
8
|
+
def initialize(hash: Hash)
|
9
|
+
hash = hash.transform_keys(&:to_sym)
|
10
|
+
@key = hash[:key]
|
11
|
+
@property_name = hash[:property_name]
|
12
|
+
@value = ''
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
data/lib/lyra/logger.rb
ADDED
data/lib/lyra/secret.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'erb'
|
2
|
+
|
3
|
+
module Lyra
|
4
|
+
class Template
|
5
|
+
attr_reader :secrets
|
6
|
+
attr_reader :template_path
|
7
|
+
attr_reader :output_path
|
8
|
+
|
9
|
+
def initialize(secrets: Array, template_path: String)
|
10
|
+
@secrets = secrets
|
11
|
+
@template_path = template_path
|
12
|
+
end
|
13
|
+
|
14
|
+
def render
|
15
|
+
ERB.new(File.read(@template_path), trim_mode: '<>').result(binding)
|
16
|
+
end
|
17
|
+
|
18
|
+
def generate(output_path: String)
|
19
|
+
File.open(output_path, 'w+') do |f|
|
20
|
+
f.write(render)
|
21
|
+
f.close
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/lyra/version.rb
ADDED
data/lyra.gemspec
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
lib = File.expand_path('lib', __dir__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require 'lyra/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = 'lyra'
|
7
|
+
spec.version = Lyra::VERSION
|
8
|
+
spec.authors = ['Mat Cartmill']
|
9
|
+
spec.email = ['mat@hellomustard.com']
|
10
|
+
|
11
|
+
spec.summary = %q{A gem for pulling secrets from AWS Secrets Manager.}
|
12
|
+
spec.description = %q{Retrieves secrets to from AWS Secrets Manager and creates a file matching your template with your secrets populated.}
|
13
|
+
spec.homepage = 'https://github.com/HelloMustard/lyra'
|
14
|
+
spec.license = 'MIT'
|
15
|
+
|
16
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
17
|
+
spec.metadata['source_code_uri'] = 'https://github.com/HelloMustard/lyra'
|
18
|
+
spec.metadata['changelog_uri'] = 'https://github.com/HelloMustard/lyra'
|
19
|
+
|
20
|
+
spec.required_ruby_version = '>= 2.6'
|
21
|
+
|
22
|
+
# Specify which files should be added to the gem when it is released.
|
23
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
24
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
25
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
26
|
+
end
|
27
|
+
spec.bindir = 'exe'
|
28
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
29
|
+
spec.require_paths = ['lib']
|
30
|
+
|
31
|
+
spec.add_development_dependency 'bundler', '~> 2.0'
|
32
|
+
spec.add_development_dependency 'minitest', '~> 5.0'
|
33
|
+
spec.add_development_dependency 'pry-byebug', '~> 3.7.0'
|
34
|
+
spec.add_development_dependency 'rake', '~> 13.0'
|
35
|
+
spec.add_development_dependency 'simplecov', '~> 0.18'
|
36
|
+
spec.add_runtime_dependency 'aws-sdk-secretsmanager', '~> 1.32.0'
|
37
|
+
spec.add_runtime_dependency 'json', '~> 2.3.0'
|
38
|
+
spec.add_runtime_dependency 'rainbow', '~> 3.0.0'
|
39
|
+
spec.add_runtime_dependency 'terminal-table', '~> 1.8.0'
|
40
|
+
spec.add_runtime_dependency 'thor', '~> 0.20.3'
|
41
|
+
end
|
metadata
ADDED
@@ -0,0 +1,207 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: lyra
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Mat Cartmill
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-03-16 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: minitest
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '5.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '5.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: pry-byebug
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 3.7.0
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 3.7.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '13.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '13.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: simplecov
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0.18'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0.18'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: aws-sdk-secretsmanager
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 1.32.0
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 1.32.0
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: json
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 2.3.0
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 2.3.0
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rainbow
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 3.0.0
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 3.0.0
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: terminal-table
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: 1.8.0
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: 1.8.0
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: thor
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: 0.20.3
|
146
|
+
type: :runtime
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: 0.20.3
|
153
|
+
description: Retrieves secrets to from AWS Secrets Manager and creates a file matching
|
154
|
+
your template with your secrets populated.
|
155
|
+
email:
|
156
|
+
- mat@hellomustard.com
|
157
|
+
executables:
|
158
|
+
- lyra
|
159
|
+
extensions: []
|
160
|
+
extra_rdoc_files: []
|
161
|
+
files:
|
162
|
+
- ".github/workflows/unit_tests.yml"
|
163
|
+
- ".gitignore"
|
164
|
+
- ".ruby-version"
|
165
|
+
- Gemfile
|
166
|
+
- Gemfile.lock
|
167
|
+
- LICENSE
|
168
|
+
- README.md
|
169
|
+
- Rakefile
|
170
|
+
- exe/lyra
|
171
|
+
- lib/lyra.rb
|
172
|
+
- lib/lyra/client.rb
|
173
|
+
- lib/lyra/client_config.rb
|
174
|
+
- lib/lyra/config.rb
|
175
|
+
- lib/lyra/item.rb
|
176
|
+
- lib/lyra/logger.rb
|
177
|
+
- lib/lyra/secret.rb
|
178
|
+
- lib/lyra/template.rb
|
179
|
+
- lib/lyra/version.rb
|
180
|
+
- lyra.gemspec
|
181
|
+
homepage: https://github.com/HelloMustard/lyra
|
182
|
+
licenses:
|
183
|
+
- MIT
|
184
|
+
metadata:
|
185
|
+
homepage_uri: https://github.com/HelloMustard/lyra
|
186
|
+
source_code_uri: https://github.com/HelloMustard/lyra
|
187
|
+
changelog_uri: https://github.com/HelloMustard/lyra
|
188
|
+
post_install_message:
|
189
|
+
rdoc_options: []
|
190
|
+
require_paths:
|
191
|
+
- lib
|
192
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
193
|
+
requirements:
|
194
|
+
- - ">="
|
195
|
+
- !ruby/object:Gem::Version
|
196
|
+
version: '2.6'
|
197
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
198
|
+
requirements:
|
199
|
+
- - ">="
|
200
|
+
- !ruby/object:Gem::Version
|
201
|
+
version: '0'
|
202
|
+
requirements: []
|
203
|
+
rubygems_version: 3.1.2
|
204
|
+
signing_key:
|
205
|
+
specification_version: 4
|
206
|
+
summary: A gem for pulling secrets from AWS Secrets Manager.
|
207
|
+
test_files: []
|