handsome_fencer-circle_c_i 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +28 -0
- data/Rakefile +27 -0
- data/lib/generators/handsome_fencer.rb +3 -0
- data/lib/generators/handsome_fencer/circle_c_i/deploy_key_generator.rb +18 -0
- data/lib/generators/handsome_fencer/circle_c_i/exposed_env_files_generator.rb +15 -0
- data/lib/generators/handsome_fencer/circle_c_i/install_generator.rb +28 -0
- data/lib/generators/handsome_fencer/circle_c_i/obfuscated_env_files_generator.rb +15 -0
- data/lib/generators/handsome_fencer/circle_c_i/templates/circleci/circle.env +9 -0
- data/lib/generators/handsome_fencer/circle_c_i/templates/circleci/config.yml +62 -0
- data/lib/generators/handsome_fencer/circle_c_i/templates/circleci/containers/app/Dockerfile +11 -0
- data/lib/generators/handsome_fencer/circle_c_i/templates/circleci/containers/app/development.env +9 -0
- data/lib/generators/handsome_fencer/circle_c_i/templates/circleci/containers/app/production.env +9 -0
- data/lib/generators/handsome_fencer/circle_c_i/templates/circleci/containers/database/development.env +2 -0
- data/lib/generators/handsome_fencer/circle_c_i/templates/circleci/containers/web/production.env +9 -0
- data/lib/generators/handsome_fencer/circle_c_i/templates/circleci/expose_env.rb +3 -0
- data/lib/generators/handsome_fencer/circle_c_i/templates/circleci/obfuscate_env.rb +3 -0
- data/lib/generators/handsome_fencer/circle_c_i/templates/docker-compose.yml +77 -0
- data/lib/generators/handsome_fencer/circle_c_i/templates/lib/tasks/deploy.rake +99 -0
- data/lib/handsome_fencer/circle_c_i.rb +8 -0
- data/lib/handsome_fencer/circle_c_i/crypto.rb +93 -0
- data/lib/handsome_fencer/circle_c_i/railtie.rb +9 -0
- data/lib/handsome_fencer/circle_c_i/version.rb +5 -0
- data/lib/tasks/handsome_fencer/circle_c_i_tasks.rake +17 -0
- metadata +139 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 7f1b79823feff3fab032cdd6fd7d10e0638454b4adb5d872427061e774dd804b
|
4
|
+
data.tar.gz: f119c0cec97a44590213de00d00f731a2104f9113fa4fb709ae3d061fa707c57
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d25c45549f31e162fa7e3ed44b054afb6dfeb74787128b8031857ad2e237191ec7256c3a840e6db1e356b352ccef3653571404b57e540188fbbd30e59a12161c
|
7
|
+
data.tar.gz: 970a3754ef7d647b9bbc3d693dcc78c58f39b13ec5e2698877514388c31a9cd72f8b4f84bb4ea3387c9927f89c5653ae0cde8f4697d67f3dbc61d4f4af694d6b
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2018 schadenfred
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# HandsomeFencer::CircleCI
|
2
|
+
Short description and motivation.
|
3
|
+
|
4
|
+
## Usage
|
5
|
+
How to use my plugin.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
gem 'handsome_fencer-circle_c_i'
|
12
|
+
```
|
13
|
+
|
14
|
+
And then execute:
|
15
|
+
```bash
|
16
|
+
$ bundle
|
17
|
+
```
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
```bash
|
21
|
+
$ gem install handsome_fencer-circle_c_i
|
22
|
+
```
|
23
|
+
|
24
|
+
## Contributing
|
25
|
+
Contribution directions go here.
|
26
|
+
|
27
|
+
## License
|
28
|
+
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,27 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'HandsomeFencer::CircleCI'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.md')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
require 'bundler/gem_tasks'
|
18
|
+
|
19
|
+
require 'rake/testtask'
|
20
|
+
|
21
|
+
Rake::TestTask.new(:test) do |t|
|
22
|
+
t.libs << 'test'
|
23
|
+
t.pattern = 'test/**/*_test.rb'
|
24
|
+
t.verbose = false
|
25
|
+
end
|
26
|
+
|
27
|
+
task default: :test
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'handsome_fencer/circle_c_i/crypto'
|
2
|
+
module HandsomeFencer
|
3
|
+
module CircleCI
|
4
|
+
|
5
|
+
class DeployKeyGenerator < Rails::Generators::Base
|
6
|
+
source_root File.expand_path('templates', __dir__)
|
7
|
+
desc "generate deploy key"
|
8
|
+
|
9
|
+
def generate_deploy_key
|
10
|
+
@cipher = OpenSSL::Cipher.new 'AES-128-CBC'
|
11
|
+
@salt = '8 octets'
|
12
|
+
@new_key = @cipher.random_key
|
13
|
+
|
14
|
+
create_file ".circleci/deploy.key", Base64.encode64(@new_key)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'handsome_fencer/circle_c_i/crypto'
|
2
|
+
module HandsomeFencer
|
3
|
+
module CircleCI
|
4
|
+
|
5
|
+
class ExposedEnvFilesGenerator < Rails::Generators::Base
|
6
|
+
source_root File.expand_path('templates', __dir__)
|
7
|
+
desc "expose .env files inside .circleci directory"
|
8
|
+
|
9
|
+
def expose_env_files
|
10
|
+
@cipher = HandsomeFencer::CircleCI::Crypto.new
|
11
|
+
@cipher.expose
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'handsome_fencer/circle_c_i/crypto'
|
2
|
+
module HandsomeFencer
|
3
|
+
module CircleCI
|
4
|
+
|
5
|
+
class InstallGenerator < Rails::Generators::Base
|
6
|
+
source_root File.expand_path('templates', __dir__)
|
7
|
+
desc "Sets up some necessary files for continuous deployments using docker and CircleCI"
|
8
|
+
|
9
|
+
def copy_circle_templates
|
10
|
+
directory "circleci", ".circleci", recursive: true
|
11
|
+
end
|
12
|
+
|
13
|
+
def copy_deploy_task
|
14
|
+
directory 'lib/', 'lib', recursive: true
|
15
|
+
end
|
16
|
+
|
17
|
+
def copy_docker_compose
|
18
|
+
copy_file "docker-compose.yml", "docker-compose.yml"
|
19
|
+
end
|
20
|
+
|
21
|
+
def insert_gitignores
|
22
|
+
create_file '.gitignore' if File.exist? '.gitignore'
|
23
|
+
append_to_file '.gitignore', "\n.circleci/**/*.env"
|
24
|
+
append_to_file '.gitignore', "\n.circleci/**/*.key"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'handsome_fencer/circle_c_i/crypto'
|
2
|
+
module HandsomeFencer
|
3
|
+
module CircleCI
|
4
|
+
|
5
|
+
class ObfuscatedEnvFilesGenerator < Rails::Generators::Base
|
6
|
+
source_root File.expand_path('templates', __dir__)
|
7
|
+
desc "obfuscate .env files inside .circleci directory"
|
8
|
+
|
9
|
+
def obfuscate_env_files
|
10
|
+
@cipher = HandsomeFencer::CircleCI::Crypto.new
|
11
|
+
@cipher.obfuscate
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
export DOCKERHUB_PASS="set me"
|
2
|
+
export DOCKERHUB_EMAIL="set me"
|
3
|
+
export DOCKERHUB_USER="set me"
|
4
|
+
export PUSH_DEPLOY_TAG=${CIRCLE_PREVIOUS_BUILD_NUM}_${CIRCLE_SHA1:0:7}
|
5
|
+
export DEPLOY_TAG=${CIRCLE_BUILD_NUM}_${CIRCLE_SHA1:0:7}
|
6
|
+
export DEPLOY_PATH="name of our app"
|
7
|
+
export SERVER_HOST="server ip address"
|
8
|
+
export SERVER_USER="probably root"
|
9
|
+
export SERVER_PORT="probably 22"
|
@@ -0,0 +1,62 @@
|
|
1
|
+
defaults: &defaults
|
2
|
+
working_directory: /tmp
|
3
|
+
|
4
|
+
version: 2
|
5
|
+
|
6
|
+
jobs:
|
7
|
+
|
8
|
+
build:
|
9
|
+
machine: true
|
10
|
+
steps:
|
11
|
+
- checkout
|
12
|
+
- run: gem install handsomefencer-environment
|
13
|
+
- run: ruby expose_env.rb
|
14
|
+
- run: docker-compose build dev_app database
|
15
|
+
- run: docker-compose run dev_app bin/rails db:create db:migrate test
|
16
|
+
|
17
|
+
push:
|
18
|
+
docker:
|
19
|
+
- image: circleci/ruby:2.5.1-node-browsers
|
20
|
+
environment:
|
21
|
+
BASH_ENV: .env/circle/deploy.env
|
22
|
+
steps:
|
23
|
+
- checkout
|
24
|
+
- setup_remote_docker
|
25
|
+
- run: gem install handsomefencer-environment
|
26
|
+
- run: ruby expose_env.rb
|
27
|
+
- run: docker-compose up -d --build
|
28
|
+
- run:
|
29
|
+
name: Tag web image
|
30
|
+
command: docker tag $(docker images | grep project_web | awk '{ print $3 }') rennmappe/bacchanal_web:$DEPLOY_TAG
|
31
|
+
- run: docker login -u $DOCKERHUB_USER -p $DOCKERHUB_PASS
|
32
|
+
- run: docker push rennmappe/bacchanal_web:$DEPLOY_TAG
|
33
|
+
|
34
|
+
deploy:
|
35
|
+
docker:
|
36
|
+
- image: circleci/ruby:2.5.1-node-browsers
|
37
|
+
environment:
|
38
|
+
BASH_ENV: .env/circle/deploy.env
|
39
|
+
steps:
|
40
|
+
- checkout
|
41
|
+
- add_ssh_keys
|
42
|
+
- run: bundle install --without production
|
43
|
+
- run: ruby expose_env.rb
|
44
|
+
- run: bin/rails docker:deploy
|
45
|
+
|
46
|
+
workflows:
|
47
|
+
version: 2
|
48
|
+
build-and-deploy:
|
49
|
+
jobs:
|
50
|
+
- build
|
51
|
+
- push:
|
52
|
+
requires:
|
53
|
+
- build
|
54
|
+
filters:
|
55
|
+
branches:
|
56
|
+
only: master
|
57
|
+
- deploy:
|
58
|
+
requires:
|
59
|
+
- push
|
60
|
+
filters:
|
61
|
+
branches:
|
62
|
+
only: master
|
@@ -0,0 +1,11 @@
|
|
1
|
+
FROM ruby:2.5-alpine
|
2
|
+
|
3
|
+
LABEL maintainer="your-email-here@gmail.com"
|
4
|
+
|
5
|
+
RUN apk add --no-cache --update build-base linux-headers \
|
6
|
+
postgresql-dev nodejs tzdata libxml2-dev libxslt-dev
|
7
|
+
|
8
|
+
COPY Gemfile* /usr/src/app/
|
9
|
+
WORKDIR /usr/src/app
|
10
|
+
RUN bundle install
|
11
|
+
COPY . /usr/src/app/
|
data/lib/generators/handsome_fencer/circle_c_i/templates/circleci/containers/app/development.env
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
export DOCKERHUB_PASS="set me"
|
2
|
+
export DOCKERHUB_EMAIL="set me"
|
3
|
+
export DOCKERHUB_USER="set me"
|
4
|
+
export PUSH_DEPLOY_TAG=${CIRCLE_PREVIOUS_BUILD_NUM}_${CIRCLE_SHA1:0:7}
|
5
|
+
export DEPLOY_TAG=${CIRCLE_BUILD_NUM}_${CIRCLE_SHA1:0:7}
|
6
|
+
export DEPLOY_PATH="name of our app"
|
7
|
+
export SERVER_HOST="server ip address"
|
8
|
+
export SERVER_USER="probably root"
|
9
|
+
export SERVER_PORT="probably 22"
|
data/lib/generators/handsome_fencer/circle_c_i/templates/circleci/containers/app/production.env
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
export DOCKERHUB_PASS="set me"
|
2
|
+
export DOCKERHUB_EMAIL="set me"
|
3
|
+
export DOCKERHUB_USER="set me"
|
4
|
+
export PUSH_DEPLOY_TAG=${CIRCLE_PREVIOUS_BUILD_NUM}_${CIRCLE_SHA1:0:7}
|
5
|
+
export DEPLOY_TAG=${CIRCLE_BUILD_NUM}_${CIRCLE_SHA1:0:7}
|
6
|
+
export DEPLOY_PATH="name of our app"
|
7
|
+
export SERVER_HOST="server ip address"
|
8
|
+
export SERVER_USER="probably root"
|
9
|
+
export SERVER_PORT="probably 22"
|
data/lib/generators/handsome_fencer/circle_c_i/templates/circleci/containers/web/production.env
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
export DOCKERHUB_PASS="set me"
|
2
|
+
export DOCKERHUB_EMAIL="set me"
|
3
|
+
export DOCKERHUB_USER="set me"
|
4
|
+
export PUSH_DEPLOY_TAG=${CIRCLE_PREVIOUS_BUILD_NUM}_${CIRCLE_SHA1:0:7}
|
5
|
+
export DEPLOY_TAG=${CIRCLE_BUILD_NUM}_${CIRCLE_SHA1:0:7}
|
6
|
+
export DEPLOY_PATH="name of our app"
|
7
|
+
export SERVER_HOST="server ip address"
|
8
|
+
export SERVER_USER="probably root"
|
9
|
+
export SERVER_PORT="probably 22"
|
@@ -0,0 +1,77 @@
|
|
1
|
+
version: '3.1'
|
2
|
+
|
3
|
+
services:
|
4
|
+
|
5
|
+
dev_app:
|
6
|
+
build:
|
7
|
+
context: .
|
8
|
+
dockerfile: ./docker/app/Dockerfile
|
9
|
+
|
10
|
+
depends_on:
|
11
|
+
- database
|
12
|
+
ports:
|
13
|
+
- "35729:35729"
|
14
|
+
- "3000:3000"
|
15
|
+
volumes:
|
16
|
+
- .:/usr/src/app
|
17
|
+
- gem_cache:/gems
|
18
|
+
env_file:
|
19
|
+
- .env/development/database.env
|
20
|
+
- .env/development/app.env
|
21
|
+
command: [ "bin/rails", "s" ]
|
22
|
+
|
23
|
+
stdin_open: true
|
24
|
+
tty: true
|
25
|
+
secrets:
|
26
|
+
- host_ssh_key
|
27
|
+
|
28
|
+
app:
|
29
|
+
|
30
|
+
build:
|
31
|
+
context: .
|
32
|
+
dockerfile: ./docker/app/Dockerfile
|
33
|
+
|
34
|
+
depends_on:
|
35
|
+
- database
|
36
|
+
ports:
|
37
|
+
- "3000:3000"
|
38
|
+
volumes:
|
39
|
+
- .:/usr/src/app
|
40
|
+
- gem_cache:/gems
|
41
|
+
environment:
|
42
|
+
- RAILS_ENV=production
|
43
|
+
env_file:
|
44
|
+
- .env/development/database.env
|
45
|
+
- .env/development/app.env
|
46
|
+
|
47
|
+
command: [ "bundle", "exec", "puma", "-C", "config/puma.rb" ]
|
48
|
+
|
49
|
+
secrets:
|
50
|
+
- host_ssh_key
|
51
|
+
|
52
|
+
web:
|
53
|
+
build:
|
54
|
+
context: .
|
55
|
+
dockerfile: ./docker/web/Dockerfile
|
56
|
+
command: [ "nginx", "-g", "daemon off;" ]
|
57
|
+
|
58
|
+
depends_on:
|
59
|
+
- app
|
60
|
+
expose:
|
61
|
+
- 80
|
62
|
+
|
63
|
+
database:
|
64
|
+
image: postgres
|
65
|
+
env_file:
|
66
|
+
- .env/development/database.env
|
67
|
+
|
68
|
+
volumes:
|
69
|
+
- db-data:/var/lib/postgresql/data
|
70
|
+
|
71
|
+
volumes:
|
72
|
+
db-data:
|
73
|
+
gem_cache:
|
74
|
+
|
75
|
+
secrets:
|
76
|
+
host_ssh_key:
|
77
|
+
file: ~/.ssh/id_rsa
|
@@ -0,0 +1,99 @@
|
|
1
|
+
# use SSHKit directly instead of Capistrano
|
2
|
+
require 'sshkit'
|
3
|
+
require 'sshkit/dsl'
|
4
|
+
include SSHKit::DSL
|
5
|
+
|
6
|
+
deploy_tag = ENV['DEPLOY_TAG']
|
7
|
+
hostname = ENV['SERVER_HOST']
|
8
|
+
user = ENV['SERVER_USER']
|
9
|
+
dockerhub_user = ENV['DOCKERHUB_USER']
|
10
|
+
dockerhub_pass = ENV['DOCKERHUB_PASS']
|
11
|
+
port = ENV['SERVER_PORT']
|
12
|
+
deploy_env = ENV['DEPLOY_ENV'] || :production
|
13
|
+
deploy_path = ENV['DEPLOY_PATH']
|
14
|
+
|
15
|
+
server = SSHKit::Host.new(hostname: hostname, port: port, user: user)
|
16
|
+
|
17
|
+
namespace :deploy do
|
18
|
+
|
19
|
+
desc 'copy to server files needed to run and manage Docker containers'
|
20
|
+
|
21
|
+
task :configs do
|
22
|
+
|
23
|
+
on server do
|
24
|
+
within deploy_path do
|
25
|
+
upload! File.expand_path('../../config/containers/docker-compose.yml', __dir__), '.'
|
26
|
+
upload! File.expand_path('../../.env', __dir__), '.', recursive: true
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
namespace :docker do
|
34
|
+
|
35
|
+
desc 'logs into Docker Hub for pushing and pulling'
|
36
|
+
|
37
|
+
task :login do
|
38
|
+
on server do
|
39
|
+
execute "mkdir -p #{deploy_path}"
|
40
|
+
within deploy_path do
|
41
|
+
execute 'docker', 'login', '-u', dockerhub_user, '-p', dockerhub_pass
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
desc 'stops all Docker containers via Docker Compose'
|
47
|
+
|
48
|
+
task stop: 'deploy:configs' do
|
49
|
+
on server do
|
50
|
+
within deploy_path do
|
51
|
+
with rails_env: deploy_env, deploy_tag: deploy_tag do
|
52
|
+
execute 'docker-compose', 'stop'
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
desc 'starts all Docker containers via Docker Compose'
|
60
|
+
|
61
|
+
task start: 'deploy:configs' do
|
62
|
+
on server do
|
63
|
+
within deploy_path do
|
64
|
+
with rails_env: deploy_env, deploy_tag: deploy_tag do
|
65
|
+
execute 'docker-compose', 'up', '-d'
|
66
|
+
execute 'echo', deploy_tag , '>', 'deploy.tag'
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
desc 'pulls images from Docker Hub'
|
73
|
+
|
74
|
+
task pull: 'docker:login' do
|
75
|
+
on server do
|
76
|
+
within deploy_path do
|
77
|
+
["#{deploy_path}_app", "#{deploy_path}_web"].each do |image_name|
|
78
|
+
execute 'docker', 'pull', "rennmappe/#{image_name}:#{deploy_tag}"
|
79
|
+
end
|
80
|
+
execute 'docker', 'pull', 'postgres:9.4.5'
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
|
86
|
+
desc 'runs database migrations in application container via Docker Compose'
|
87
|
+
task migrate: 'deploy:configs' do
|
88
|
+
on server do
|
89
|
+
within deploy_path do
|
90
|
+
with rails_env: deploy_env, deploy_tag: deploy_tag do
|
91
|
+
execute 'docker-compose', 'run', 'app', "bin/rails", 'db:create', 'db:migrate'
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
desc 'pulls images, stops old containers, updates the database, and starts new containers'
|
98
|
+
task deploy: %w{docker:pull docker:stop docker:migrate docker:start }
|
99
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require 'base64'
|
3
|
+
require 'byebug'
|
4
|
+
|
5
|
+
module HandsomeFencer
|
6
|
+
module CircleCI
|
7
|
+
class Crypto
|
8
|
+
|
9
|
+
DeployKeyError = Class.new(StandardError)
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@cipher = OpenSSL::Cipher.new 'AES-128-CBC'
|
13
|
+
@salt = '8 octets'
|
14
|
+
@pass_phrase = get_deploy_key
|
15
|
+
end
|
16
|
+
|
17
|
+
def get_deploy_key
|
18
|
+
case
|
19
|
+
when ENV['DEPLOY_KEY'].nil? && !File.exist?(dkfile)
|
20
|
+
raise DeployKeyError, "No deploy key set. Please generate a deploy key using '$ bin/rails generate handsome_fencer:circle_c_i:deploy_key' or set it using '$ export ENV['DEPLOY_KEY'] = some-complicated-key'"
|
21
|
+
when ENV['DEPLOY_KEY'].present?
|
22
|
+
Base64.decode64(ENV['DEPLOY_KEY'])
|
23
|
+
when File.exist?(dkfile)
|
24
|
+
Base64.decode64(File.read(dkfile))
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def read_deploy_key
|
29
|
+
File.exist?(dkfile) ? File.read(dkfile) : save_deploy_key
|
30
|
+
end
|
31
|
+
|
32
|
+
def save_deploy_key
|
33
|
+
|
34
|
+
@new_key = @cipher.random_key
|
35
|
+
|
36
|
+
write_to_file Base64.encode64(@new_key), dkfile
|
37
|
+
# ignore_sensitive_files
|
38
|
+
read_deploy_key
|
39
|
+
end
|
40
|
+
|
41
|
+
def ignore_sensitive_files
|
42
|
+
if File.exist? '.gitignore'
|
43
|
+
["/#{dkfile}", "/.env/*"].each do |pattern|
|
44
|
+
unless File.read('.gitignore').match pattern
|
45
|
+
open('.gitignore', 'a') { |f| f << pattern }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def encrypt(file)
|
52
|
+
file = Rails.root.join(file).to_s
|
53
|
+
@cipher.encrypt.pkcs5_keyivgen @pass_phrase, @salt
|
54
|
+
encrypted = @cipher.update(File.read file) + @cipher.final
|
55
|
+
write_to_file(Base64.encode64(encrypted), file + '.enc')
|
56
|
+
end
|
57
|
+
|
58
|
+
def decrypt(file)
|
59
|
+
encrypted = Base64.decode64 File.read(file.to_s)
|
60
|
+
@cipher.decrypt.pkcs5_keyivgen @pass_phrase, @salt
|
61
|
+
decrypted = @cipher.update(encrypted) + @cipher.final
|
62
|
+
decrypted_file = file.split('.enc').first
|
63
|
+
write_to_file decrypted, decrypted_file
|
64
|
+
end
|
65
|
+
|
66
|
+
def source_files(directory=nil, extension=nil)
|
67
|
+
Dir.glob(directory + "/**/*#{extension}")
|
68
|
+
end
|
69
|
+
|
70
|
+
def obfuscate(directory=nil, extension=nil)
|
71
|
+
extension = extension || '.env'
|
72
|
+
directory = directory || '.circleci'
|
73
|
+
source_files(directory, extension).each { |file| encrypt file }
|
74
|
+
end
|
75
|
+
|
76
|
+
def expose(directory=nil, extension=nil)
|
77
|
+
extension = extension || '.env.enc'
|
78
|
+
directory = directory || '.circleci'
|
79
|
+
source_files(directory, extension).each { |file| decrypt(file) }
|
80
|
+
end
|
81
|
+
|
82
|
+
private
|
83
|
+
|
84
|
+
def dkfile
|
85
|
+
".circleci/deploy.key"
|
86
|
+
end
|
87
|
+
|
88
|
+
def write_to_file(data, filename)
|
89
|
+
File.open(filename, "w") { |io| io.write data }
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
namespace "handsome_fencer" do
|
2
|
+
|
3
|
+
# namespace "circleci" do
|
4
|
+
#
|
5
|
+
# @cipher = HandsomeFencer::CircleCI::Crypto.new
|
6
|
+
#
|
7
|
+
# desc "obfuscate .circleci variables"
|
8
|
+
# task :obfuscate do
|
9
|
+
# @cipher.obfuscate
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
# desc "expose .circleci variables"
|
13
|
+
# task :expose do
|
14
|
+
# @cipher.expose
|
15
|
+
# end
|
16
|
+
# end
|
17
|
+
end
|
metadata
ADDED
@@ -0,0 +1,139 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: handsome_fencer-circle_c_i
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.5
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- schadenfred
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-09-26 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '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'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: sshkit
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: sqlite3
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: minitest-given
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: byebug
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description: Obfuscate sensitive data in source control, expose it again for circle
|
84
|
+
and then deploy
|
85
|
+
email:
|
86
|
+
- fred.schoeneman@gmail.com
|
87
|
+
executables: []
|
88
|
+
extensions: []
|
89
|
+
extra_rdoc_files: []
|
90
|
+
files:
|
91
|
+
- MIT-LICENSE
|
92
|
+
- README.md
|
93
|
+
- Rakefile
|
94
|
+
- lib/generators/handsome_fencer.rb
|
95
|
+
- lib/generators/handsome_fencer/circle_c_i/deploy_key_generator.rb
|
96
|
+
- lib/generators/handsome_fencer/circle_c_i/exposed_env_files_generator.rb
|
97
|
+
- lib/generators/handsome_fencer/circle_c_i/install_generator.rb
|
98
|
+
- lib/generators/handsome_fencer/circle_c_i/obfuscated_env_files_generator.rb
|
99
|
+
- lib/generators/handsome_fencer/circle_c_i/templates/circleci/circle.env
|
100
|
+
- lib/generators/handsome_fencer/circle_c_i/templates/circleci/config.yml
|
101
|
+
- lib/generators/handsome_fencer/circle_c_i/templates/circleci/containers/app/Dockerfile
|
102
|
+
- lib/generators/handsome_fencer/circle_c_i/templates/circleci/containers/app/development.env
|
103
|
+
- lib/generators/handsome_fencer/circle_c_i/templates/circleci/containers/app/production.env
|
104
|
+
- lib/generators/handsome_fencer/circle_c_i/templates/circleci/containers/database/development.env
|
105
|
+
- lib/generators/handsome_fencer/circle_c_i/templates/circleci/containers/web/production.env
|
106
|
+
- lib/generators/handsome_fencer/circle_c_i/templates/circleci/expose_env.rb
|
107
|
+
- lib/generators/handsome_fencer/circle_c_i/templates/circleci/obfuscate_env.rb
|
108
|
+
- lib/generators/handsome_fencer/circle_c_i/templates/docker-compose.yml
|
109
|
+
- lib/generators/handsome_fencer/circle_c_i/templates/lib/tasks/deploy.rake
|
110
|
+
- lib/handsome_fencer/circle_c_i.rb
|
111
|
+
- lib/handsome_fencer/circle_c_i/crypto.rb
|
112
|
+
- lib/handsome_fencer/circle_c_i/railtie.rb
|
113
|
+
- lib/handsome_fencer/circle_c_i/version.rb
|
114
|
+
- lib/tasks/handsome_fencer/circle_c_i_tasks.rake
|
115
|
+
homepage: https://github.com/schadenfred/handsomefencer-environment
|
116
|
+
licenses:
|
117
|
+
- MIT
|
118
|
+
metadata: {}
|
119
|
+
post_install_message:
|
120
|
+
rdoc_options: []
|
121
|
+
require_paths:
|
122
|
+
- lib
|
123
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
124
|
+
requirements:
|
125
|
+
- - ">="
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
version: '0'
|
128
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
129
|
+
requirements:
|
130
|
+
- - ">="
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: '0'
|
133
|
+
requirements: []
|
134
|
+
rubyforge_project:
|
135
|
+
rubygems_version: 2.7.7
|
136
|
+
signing_key:
|
137
|
+
specification_version: 4
|
138
|
+
summary: Handsome deployment of Rails apps using Circle and Docker
|
139
|
+
test_files: []
|