trixie 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: d9fb9e4a817416d5df9d692a6da48f03afc54c429b1956e6b74724739253776e
4
+ data.tar.gz: f0cbfc84bccc590573c633fe8a36ee00762fd4d6a94748c928ebb55668730d64
5
+ SHA512:
6
+ metadata.gz: d897d133563fc5ce764cb7dda155f58b9822191ae74d24113736626cab6a172acbc15cd316d18d9c43cc2b473a7d1dbf93c0b655acfb7373bf09ec6d67120eda
7
+ data.tar.gz: 41c803e3e23ba1a91d2c523b98e95e053ef8a5a00c72f4cbfee3427aa73f7e8a577c57ac5abc72fcc4ca3e9836069c8479a3da016305fe98276a6520f559dd9f
@@ -0,0 +1,25 @@
1
+ name: Ruby
2
+
3
+ on:
4
+ push:
5
+ branches: [ master ]
6
+ pull_request:
7
+
8
+ jobs:
9
+ build:
10
+ runs-on: ubuntu-latest
11
+ strategy:
12
+ matrix:
13
+ ruby-version: ['2.7', '3.0', '3.1']
14
+
15
+ steps:
16
+ - uses: actions/checkout@v2
17
+ - name: Set up Ruby
18
+ uses: ruby/setup-ruby@v1
19
+ with:
20
+ ruby-version: ${{ matrix.ruby-version }}
21
+ - name: Run the default task
22
+ run: |
23
+ gem install bundler -v 2.2.7
24
+ bundle install
25
+ bundle exec rake
data/.gitignore ADDED
@@ -0,0 +1,12 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
12
+ /.trixie.yml
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,17 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.4
3
+
4
+ Style/StringLiterals:
5
+ Enabled: true
6
+ EnforcedStyle: double_quotes
7
+
8
+ Style/StringLiteralsInInterpolation:
9
+ Enabled: true
10
+ EnforcedStyle: double_quotes
11
+
12
+ Layout/LineLength:
13
+ Max: 120
14
+
15
+ Metrics/BlockLength:
16
+ Exclude:
17
+ - spec/**/*
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 3.0.4
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ # Specify your gem's dependencies in trixie.gemspec
6
+ gemspec
7
+
8
+ gem "rake", "~> 13.0"
9
+
10
+ gem "rspec", "~> 3.0"
11
+
12
+ gem "rubocop", "~> 1.7"
13
+
14
+ gem "pry-byebug"
data/Gemfile.lock ADDED
@@ -0,0 +1,69 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ trixie (0.1.1)
5
+ dry-cli (~> 0.7.0)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ ast (2.4.2)
11
+ byebug (11.1.3)
12
+ coderay (1.1.3)
13
+ diff-lcs (1.5.0)
14
+ dry-cli (0.7.0)
15
+ json (2.6.2)
16
+ method_source (1.0.0)
17
+ parallel (1.22.1)
18
+ parser (3.1.2.1)
19
+ ast (~> 2.4.1)
20
+ pry (0.14.1)
21
+ coderay (~> 1.1)
22
+ method_source (~> 1.0)
23
+ pry-byebug (3.10.1)
24
+ byebug (~> 11.0)
25
+ pry (>= 0.13, < 0.15)
26
+ rainbow (3.1.1)
27
+ rake (13.0.6)
28
+ regexp_parser (2.5.0)
29
+ rexml (3.2.5)
30
+ rspec (3.11.0)
31
+ rspec-core (~> 3.11.0)
32
+ rspec-expectations (~> 3.11.0)
33
+ rspec-mocks (~> 3.11.0)
34
+ rspec-core (3.11.0)
35
+ rspec-support (~> 3.11.0)
36
+ rspec-expectations (3.11.0)
37
+ diff-lcs (>= 1.2.0, < 2.0)
38
+ rspec-support (~> 3.11.0)
39
+ rspec-mocks (3.11.1)
40
+ diff-lcs (>= 1.2.0, < 2.0)
41
+ rspec-support (~> 3.11.0)
42
+ rspec-support (3.11.0)
43
+ rubocop (1.35.0)
44
+ json (~> 2.3)
45
+ parallel (~> 1.10)
46
+ parser (>= 3.1.2.1)
47
+ rainbow (>= 2.2.2, < 4.0)
48
+ regexp_parser (>= 1.8, < 3.0)
49
+ rexml (>= 3.2.5, < 4.0)
50
+ rubocop-ast (>= 1.20.1, < 2.0)
51
+ ruby-progressbar (~> 1.7)
52
+ unicode-display_width (>= 1.4.0, < 3.0)
53
+ rubocop-ast (1.21.0)
54
+ parser (>= 3.1.1.0)
55
+ ruby-progressbar (1.11.0)
56
+ unicode-display_width (2.2.0)
57
+
58
+ PLATFORMS
59
+ x86_64-linux
60
+
61
+ DEPENDENCIES
62
+ pry-byebug
63
+ rake (~> 13.0)
64
+ rspec (~> 3.0)
65
+ rubocop (~> 1.7)
66
+ trixie!
67
+
68
+ BUNDLED WITH
69
+ 2.2.33
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2022 Toptal
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
13
+ all 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
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,89 @@
1
+ # Trixie
2
+
3
+ Trixie let you load 1password secrets as ENVs for your development environment
4
+
5
+ ## Usage
6
+
7
+ Initialize a `.trixie.yml` config file with:
8
+
9
+ ```sh
10
+ trixie init
11
+ ```
12
+
13
+ Then update it with a URI for you secret as `op://<vault>/<item>[/<section>]/<field>`, and the ENV your want, eg:
14
+
15
+ ```yaml
16
+ secrets:
17
+ - env: 'NPM_TOKEN'
18
+ value: "{{ op://Developers/NPM_TOKEN/SETUP_SECRET/value }}"
19
+ ```
20
+
21
+ Then you can run `trixie load > .env.secrets` to update your env file with the `NPM_TOKEN`
22
+
23
+ ### Groups
24
+
25
+ If you have multiple secrets you can declare groups, eg:
26
+
27
+ ```yaml
28
+ secrets:
29
+ - env: 'NPM_TOKEN'
30
+ value: "{{ op://Developers/NPM_TOKEN/SETUP_SECRET/value }}"
31
+ groups: [ dev ]
32
+ - env: 'MY_API_TOKEN'
33
+ value: "{{ op://Developers/MY_API_TOKEN/SETUP_SECRET/password }}"
34
+ groups: [ api ]
35
+ - env: 'MY_TEST_API_TOKEN'
36
+ value: "{{ op://Developers/MY_TEST_API_TOKEN/SETUP_SECRET/password }}"
37
+ groups: [ test ]
38
+ ```
39
+
40
+ Then you could run `trixie load --groups GROUP_NAME` to select which group you want to fetch, eg: `trixie load --groups api,test`
41
+
42
+ ### Formats
43
+
44
+ Trixie also supports other formats as the output as json, pretty_json and sh (ENVs with export), eg:
45
+
46
+ ```sh
47
+ # Load envs in the current shell session
48
+ eval $(trixie load --format sh)
49
+
50
+ # Handle your ENVs in JSON format
51
+ trixie load --format json | jq '.[0].value'
52
+ ```
53
+
54
+ ## Installation
55
+
56
+ Add this line to your application's Gemfile:
57
+
58
+ ```ruby
59
+ gem 'trixie'
60
+ ```
61
+
62
+ And then execute:
63
+
64
+ $ bundle install
65
+
66
+ Or install it yourself as:
67
+
68
+ $ gem install trixie
69
+
70
+ ## TODO IDEAS
71
+
72
+ 1. Support Multiple Backends/Password Managers, Trixie::Loader can be refactored to be an adapter for the op CLI
73
+ 2. Allow specific Backend options, eg: trixie load --backend op --backend-options '{ "email": "bar@foo.com", "address": "foo.1password.com"}'
74
+ 3. Validate the `.trixie.yml`, check if we have the required values for trixie to run
75
+ 4. Add a load --cache option, so fetched secrets could be retained for a while without using the Password Manager Backend
76
+
77
+ ## Development
78
+
79
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
80
+
81
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
82
+
83
+ ## Contributing
84
+
85
+ Bug reports and pull requests are welcome on GitHub at https://github.com/toptal/trixie.
86
+
87
+ ## License
88
+
89
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ require "rubocop/rake_task"
9
+
10
+ RuboCop::RakeTask.new
11
+
12
+ task default: %i[spec rubocop]
data/bin/console ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "trixie"
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require "irb"
15
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/exe/trixie ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require_relative "../lib/trixie"
5
+
6
+ begin
7
+ Dry::CLI.new(Trixie::CLI).call
8
+ rescue Trixie::Error => e
9
+ puts e
10
+ warn "Exiting trixie..."
11
+ end
data/lib/trixie/cli.rb ADDED
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Trixie
4
+ class CLI # rubocop:disable Style/Documentation
5
+ extend Dry::CLI::Registry
6
+
7
+ class Init < Dry::CLI::Command # rubocop:disable Style/Documentation
8
+ desc "Creates an initial .trixie.yml"
9
+
10
+ option :output, type: :string, default: ".trixie.yml", desc: "Output File", aliases: ["-o"]
11
+ option :template, type: :string, default: "default", desc: "Template to be used", aliases: ["-t"]
12
+
13
+ def call(template:, output:)
14
+ warn "Creating trixie secrets file to #{output}"
15
+ Template.render(template, to: output)
16
+ end
17
+ end
18
+
19
+ class Load < Dry::CLI::Command # rubocop:disable Style/Documentation
20
+ desc "Load envs"
21
+ option :file, type: :string, default: ".trixie.yml", desc: "Secrets file", aliases: ["-f"]
22
+ option :groups, type: :array, default: [], desc: "Secrets groups to consider", aliases: ["-g"]
23
+ option :format, type: :string, default: "env", desc: "Format to output (env, sh, json, pretty_json)"
24
+
25
+ def call(**options)
26
+ puts Trixie::Load.new(**options).call
27
+ end
28
+ end
29
+
30
+ class Version < Dry::CLI::Command # rubocop:disable Style/Documentation
31
+ desc "Prints trixie version"
32
+
33
+ def call(*)
34
+ puts Trixie::VERSION
35
+ end
36
+ end
37
+
38
+ register "--version", Version, aliases: ["-v"]
39
+ register "load", Load, aliases: ["l"]
40
+ register "init", Init, aliases: ["i"]
41
+ end
42
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Trixie
4
+ # Inlcludes the possible formats to output the secrets and the main entrypoint with Formatter.for(format)
5
+ class Formatter
6
+ FORMATTERS = {
7
+ "env" => ->(secrets) { secrets.map { |secret| "#{secret["env"]}=#{secret["value"]}" }.join("\n") },
8
+ "sh" => ->(secrets) { secrets.map { |secret| "export #{secret["env"]}=#{secret["value"]}" }.join("\n") },
9
+ "json" => ->(secrets) { secrets.to_json },
10
+ "pretty_json" => ->(secrets) { JSON.pretty_generate(secrets) }
11
+ }.freeze
12
+
13
+ def self.for(format)
14
+ FORMATTERS[format]
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Trixie
4
+ # Fetches the specified secrets with op cli and returns them formatted
5
+ class Load
6
+ OP_NOT_INSTALLED = "op cli is not installed please download and install at https://developer.1password.com/docs/cli/get-started#install"
7
+
8
+ def initialize(file:, groups: [], format: "env")
9
+ @file = file
10
+ @groups = groups
11
+ @formatter = Formatter.for(format)
12
+ end
13
+
14
+ def call
15
+ verify_op_installed!
16
+
17
+ create_account unless account_is_configured?
18
+
19
+ fetch_secrets
20
+ end
21
+
22
+ def verify_op_installed!
23
+ raise Trixie::OpCLINotInstalled, OP_NOT_INSTALLED unless system("which op > /dev/null")
24
+ end
25
+
26
+ def account_is_configured?
27
+ !Open3.capture2("op account list").first.empty?
28
+ end
29
+
30
+ def create_account
31
+ warn "* Configuring 1password Account"
32
+ warn "To get the Secret Key take a look at https://support.1password.com/secret-key/"
33
+
34
+ `op account add`
35
+ end
36
+
37
+ def fetch_secrets
38
+ `eval $(op signin) && echo '#{formatted_secrets}' | op inject`
39
+ end
40
+
41
+ def secrets_config
42
+ @secrets_config ||= YAML.load_file(@file)
43
+ end
44
+
45
+ def filtered_secrets
46
+ return secrets_config["secrets"] if @groups.empty?
47
+
48
+ secrets_config["secrets"].select { |secret| secret["groups"].any? { |group| @groups.include?(group) } }
49
+ end
50
+
51
+ def formatted_secrets
52
+ @formatter.call(filtered_secrets)
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Trixie
4
+ # Render templates in lib/templates folder to a custom path
5
+ class Template
6
+ def self.render(template_name, to:)
7
+ new(template_name).render(to: to)
8
+ end
9
+
10
+ def initialize(template_name)
11
+ @template_name = template_name
12
+ end
13
+
14
+ def render(to:)
15
+ path = Pathname.new(to)
16
+ path.write(template_content)
17
+ end
18
+
19
+ private
20
+
21
+ def template_content
22
+ @template_content = template_path.join(@template_name).read
23
+ end
24
+
25
+ def template_path
26
+ Trixie.root_path.join("lib/trixie/templates")
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,8 @@
1
+ ---
2
+ secrets:
3
+ - env: 'MY_SECRET1'
4
+ value: "{{ op://Developers/MySecret1/SETUP_SECRET/value }}"
5
+ groups: [group1]
6
+ - env: 'MY_SECRET2'
7
+ value: "{{ op://Developers/MySecret2/SETUP_SECRET/value }}"
8
+ groups: [group2]
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Trixie
4
+ VERSION = "0.1.1"
5
+ end
data/lib/trixie.rb ADDED
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "open3"
4
+ require "yaml"
5
+ require "json"
6
+ require "pathname"
7
+ require "dry/cli"
8
+
9
+ require_relative "trixie/version"
10
+ require_relative "trixie/template"
11
+ require_relative "trixie/formatter"
12
+ require_relative "trixie/load"
13
+ require_relative "trixie/cli"
14
+
15
+ module Trixie # rubocop:disable Style/Documentation
16
+ class Error < StandardError; end
17
+ class OpCLINotInstalled < Error; end
18
+
19
+ class << self
20
+ def root_path
21
+ Pathname.new File.expand_path("#{__dir__}/..")
22
+ end
23
+ end
24
+ end
data/trixie.gemspec ADDED
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/trixie/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "trixie"
7
+ spec.version = Trixie::VERSION
8
+ spec.authors = ["Toptal, LLC"]
9
+ spec.email = ["open-source@toptal.com", "carlos.atkinson@toptal.com", "dalibor.kezele@toptal.com",
10
+ "tiago.melo@toptal.com"]
11
+
12
+ spec.summary = "CLI tool to fetch secrets in development"
13
+ spec.homepage = "https://github.com/toptal/trixie"
14
+ spec.license = "MIT"
15
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.4.0")
16
+
17
+ spec.metadata["homepage_uri"] = spec.homepage
18
+ spec.metadata["source_code_uri"] = "https://github.com/toptal/trixie"
19
+
20
+ # Specify which files should be added to the gem when it is released.
21
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
22
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
23
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
24
+ end
25
+ spec.bindir = "exe"
26
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
27
+ spec.require_paths = ["lib"]
28
+
29
+ # Uncomment to register a new dependency of your gem
30
+ # spec.add_dependency "example-gem", "~> 1.0"
31
+
32
+ # For more information and examples about making a new gem, checkout our
33
+ # guide at: https://bundler.io/guides/creating_gem.html
34
+ spec.add_dependency "dry-cli", "~> 0.7.0"
35
+ end
metadata ADDED
@@ -0,0 +1,84 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: trixie
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Toptal, LLC
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2022-08-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: dry-cli
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.7.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.7.0
27
+ description:
28
+ email:
29
+ - open-source@toptal.com
30
+ - carlos.atkinson@toptal.com
31
+ - dalibor.kezele@toptal.com
32
+ - tiago.melo@toptal.com
33
+ executables:
34
+ - trixie
35
+ extensions: []
36
+ extra_rdoc_files: []
37
+ files:
38
+ - ".github/workflows/main.yml"
39
+ - ".gitignore"
40
+ - ".rspec"
41
+ - ".rubocop.yml"
42
+ - ".ruby-version"
43
+ - Gemfile
44
+ - Gemfile.lock
45
+ - LICENSE.txt
46
+ - README.md
47
+ - Rakefile
48
+ - bin/console
49
+ - bin/setup
50
+ - exe/trixie
51
+ - lib/trixie.rb
52
+ - lib/trixie/cli.rb
53
+ - lib/trixie/formatter.rb
54
+ - lib/trixie/load.rb
55
+ - lib/trixie/template.rb
56
+ - lib/trixie/templates/default
57
+ - lib/trixie/version.rb
58
+ - trixie.gemspec
59
+ homepage: https://github.com/toptal/trixie
60
+ licenses:
61
+ - MIT
62
+ metadata:
63
+ homepage_uri: https://github.com/toptal/trixie
64
+ source_code_uri: https://github.com/toptal/trixie
65
+ post_install_message:
66
+ rdoc_options: []
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: 2.4.0
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ requirements: []
80
+ rubygems_version: 3.2.33
81
+ signing_key:
82
+ specification_version: 4
83
+ summary: CLI tool to fetch secrets in development
84
+ test_files: []