subspace 0.2.1 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/README.md +5 -9
- data/ansible/playbooks/local_template.yml +13 -0
- data/ansible/roles/common/templates/motd +3 -1
- data/ansible/roles/letsencrypt/tasks/main.yml +1 -3
- data/ansible/roles/rails/tasks/main.yml +15 -1
- data/lib/subspace/cli.rb +9 -5
- data/lib/subspace/commands/ansible.rb +1 -1
- data/lib/subspace/commands/base.rb +22 -0
- data/lib/subspace/commands/init.rb +16 -1
- data/lib/subspace/commands/vars.rb +39 -2
- data/lib/subspace/version.rb +1 -1
- data/subspace.gemspec +2 -1
- data/template/provision/templates/application.yml.template +27 -0
- metadata +20 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 57b55c6f99d2144073f2601463e9945b60842550
|
4
|
+
data.tar.gz: 93c40a9e919c5c8a49745310ad042de16f54bf1f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b67b94db7a8c7d5e70352f927bd944099f0abfe2a71bd51b6670af6b693976253d902f5054a56feea5ff8e200b17234ef5300f5a3500584c5d5add70d1a9a72c
|
7
|
+
data.tar.gz: 5a98c46e5f8547dd596fb55260ea9ab17156847854375585f7c0fd1834a16643213199d2b529a33ee1f7682c30c6732a3b16bbebfdd86e4e1ad835db18086e90
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -21,18 +21,10 @@ Add this line to your application's Gemfile:
|
|
21
21
|
gem 'subspace'
|
22
22
|
```
|
23
23
|
|
24
|
-
And then execute:
|
25
|
-
|
26
|
-
$ bundle
|
27
|
-
|
28
24
|
Or install it yourself as:
|
29
25
|
|
30
26
|
$ gem install subspace
|
31
27
|
|
32
|
-
Then run
|
33
|
-
|
34
|
-
subspace init
|
35
|
-
|
36
28
|
## Usage
|
37
29
|
|
38
30
|
* `subspace init`
|
@@ -97,11 +89,15 @@ This role should almost always be there. It ties a bunch of stuff together, run
|
|
97
89
|
|
98
90
|
Note: we grant the deploy user limited sudo access to run `service xyz restart` and also add it to the `adm` group so it can view logs in `/var/log`.
|
99
91
|
|
92
|
+
# Roles
|
93
|
+
|
94
|
+
This is a description of all the roles that are included by installing subspace, along with their configuration.
|
95
|
+
|
100
96
|
## apache
|
101
97
|
|
102
98
|
## collectd
|
103
99
|
|
104
|
-
|
100
|
+
## common
|
105
101
|
|
106
102
|
## delayed_job
|
107
103
|
|
@@ -5,8 +5,10 @@ This server brought to you by:
|
|
5
5
|
___) | |_| | |_) |__) | |_) | (_| | (_| __/
|
6
6
|
|____/ \__,_|_.__/____/| .__/ \__,_|\___\___|
|
7
7
|
|_|
|
8
|
-
|
9
8
|
~~~ https://github.com/tenforwardconsulting/subspace ~~~
|
10
9
|
|
11
10
|
If you need to make configuration changes to the server, please modify the
|
12
11
|
config/provision directory in the app or risk the changes dissapearing.
|
12
|
+
|
13
|
+
Last subspace run: {{ansible_date_time.iso8601}}
|
14
|
+
|
@@ -25,7 +25,7 @@
|
|
25
25
|
file:
|
26
26
|
path: "{{certbot_dir}}"
|
27
27
|
state: directory
|
28
|
-
mode:
|
28
|
+
mode: 0755
|
29
29
|
|
30
30
|
- name: Get certbot
|
31
31
|
become: true
|
@@ -37,8 +37,6 @@
|
|
37
37
|
- name: Run default
|
38
38
|
become: true
|
39
39
|
command: "{{certbot_dir}}/certbot-auto certonly --email {{letsencrypt_email}} --domains {{([server_name] + server_aliases) | join(',')}} --apache --agree-tos --expand --non-interactive"
|
40
|
-
args:
|
41
|
-
creates: /etc/letsencrypt/live/{{server_name}}/cert.pem
|
42
40
|
|
43
41
|
- name: Enable mod_rewrite
|
44
42
|
become: true
|
@@ -28,9 +28,23 @@
|
|
28
28
|
become: true
|
29
29
|
become_user: "{{deploy_user}}"
|
30
30
|
|
31
|
-
- name: Create application.yml
|
31
|
+
- name: Create application.yml (legacy)
|
32
|
+
when: appyml is defined
|
32
33
|
template:
|
33
34
|
src: application.yml
|
34
35
|
dest: /u/apps/{{project_name}}/shared/config/application.yml
|
35
36
|
become: true
|
36
37
|
become_user: "{{deploy_user}}"
|
38
|
+
|
39
|
+
- debug:
|
40
|
+
msg: "Warning: Using legacy appyml for variable configuration. Consider switching to application.yml.template"
|
41
|
+
verbosity: 0
|
42
|
+
when: appyml is defined
|
43
|
+
|
44
|
+
- name: Create application.yml
|
45
|
+
when: appyml is not defined
|
46
|
+
template:
|
47
|
+
src: application.yml.template
|
48
|
+
dest: /u/apps/{{project_name}}/shared/config/application.yml
|
49
|
+
owner: "{{deploy_user}}"
|
50
|
+
|
data/lib/subspace/cli.rb
CHANGED
@@ -23,10 +23,11 @@ class Subspace::Cli
|
|
23
23
|
program :description, 'Ansible-backed server provisioning tool for rails'
|
24
24
|
|
25
25
|
command :init do |c|
|
26
|
-
c.syntax = 'subspace init [
|
27
|
-
c.summary = ''
|
28
|
-
c.description = ''
|
29
|
-
c.example '
|
26
|
+
c.syntax = 'subspace init [vars]'
|
27
|
+
c.summary = 'Run without options to initialize subspace.'
|
28
|
+
c.description = 'Some initialization routines can be run indiviaully, useful for upgrading'
|
29
|
+
c.example 'init a new project', 'subspace init'
|
30
|
+
c.example 'create the new style application.yml vars template', 'subspace init vars'
|
30
31
|
c.when_called Subspace::Commands::Init
|
31
32
|
end
|
32
33
|
|
@@ -73,8 +74,11 @@ class Subspace::Cli
|
|
73
74
|
command :vars do |c, args|
|
74
75
|
c.syntax = 'subspace vars [environment]'
|
75
76
|
c.summary = 'View or edit the encrypted variables for an environment'
|
76
|
-
c.description =
|
77
|
+
c.description = """By default, this will simply show the variables for a specific environemnt.
|
78
|
+
You can also edit variables, and we expect the functionality here to grow in the future.
|
79
|
+
Running `subspace vars development --create` is usually a great way to bootstrap a new development environment."""
|
77
80
|
c.option '--edit', "Edit the variables instead of view"
|
81
|
+
c.option '--create', "Create config/application.yml with the variables from the specified environment"
|
78
82
|
c.when_called Subspace::Commands::Vars
|
79
83
|
end
|
80
84
|
|
@@ -8,6 +8,10 @@ module Subspace
|
|
8
8
|
load "config/provision.rb"
|
9
9
|
end
|
10
10
|
|
11
|
+
def playbook_dir
|
12
|
+
File.join(gem_path, 'ansible', 'playbooks')
|
13
|
+
end
|
14
|
+
|
11
15
|
def template_dir
|
12
16
|
File.join(gem_path, 'template', 'provision')
|
13
17
|
end
|
@@ -16,11 +20,21 @@ module Subspace
|
|
16
20
|
File.expand_path '../../../..', __FILE__
|
17
21
|
end
|
18
22
|
|
23
|
+
def project_path
|
24
|
+
Dir.pwd # TODO make sure this is correct if they for whatever reason aren't running subspace from the project root??
|
25
|
+
end
|
26
|
+
|
19
27
|
def dest_dir
|
20
28
|
"config/provision"
|
21
29
|
end
|
22
30
|
|
23
31
|
def template(src, dest = nil, render_binding = nil)
|
32
|
+
return unless confirm_overwrite File.join(dest_dir, dest || src)
|
33
|
+
template! src, dest, render_binding
|
34
|
+
say "Wrote #{dest}"
|
35
|
+
end
|
36
|
+
|
37
|
+
def template!(src, dest = nil, render_binding = nil)
|
24
38
|
dest ||= src
|
25
39
|
template = ERB.new File.read(File.join(template_dir, "#{src}.erb")), nil, '-'
|
26
40
|
File.write File.join(dest_dir, dest), template.result(render_binding || binding)
|
@@ -28,7 +42,15 @@ module Subspace
|
|
28
42
|
|
29
43
|
def copy(src, dest = nil)
|
30
44
|
dest ||= src
|
45
|
+
return unless confirm_overwrite File.join(dest_dir, dest)
|
31
46
|
FileUtils.cp File.join(template_dir, src), File.join(dest_dir, dest)
|
47
|
+
say "Wrote #{dest}"
|
48
|
+
end
|
49
|
+
|
50
|
+
def confirm_overwrite(file_path)
|
51
|
+
return true unless File.exists? file_path
|
52
|
+
answer = ask "#{file_path} already exists. Reply 'y' to overwrite: [no] "
|
53
|
+
return answer.downcase.start_with? "y"
|
32
54
|
end
|
33
55
|
|
34
56
|
end
|
@@ -3,10 +3,19 @@ require 'erb'
|
|
3
3
|
require 'securerandom'
|
4
4
|
class Subspace::Commands::Init < Subspace::Commands::Base
|
5
5
|
def initialize(args, options)
|
6
|
-
|
6
|
+
if args.first == "vars"
|
7
|
+
init_vars
|
8
|
+
else
|
9
|
+
run
|
10
|
+
end
|
7
11
|
end
|
8
12
|
|
9
13
|
def run
|
14
|
+
if File.exists? dest_dir
|
15
|
+
answer = ask "Subspace appears to be initialized. Reply 'yes' to continue anyway: [no] "
|
16
|
+
abort unless answer.chomp == "yes"
|
17
|
+
end
|
18
|
+
|
10
19
|
FileUtils.mkdir_p File.join dest_dir, "group_vars"
|
11
20
|
FileUtils.mkdir_p File.join dest_dir, "host_vars"
|
12
21
|
FileUtils.mkdir_p File.join dest_dir, "vars"
|
@@ -27,6 +36,7 @@ class Subspace::Commands::Init < Subspace::Commands::Base
|
|
27
36
|
create_vars_file_for_env env
|
28
37
|
template "playbook.yml", "#{env}.yml"
|
29
38
|
end
|
39
|
+
create_vars_file_for_env "development"
|
30
40
|
|
31
41
|
puts """
|
32
42
|
1. Create a server.
|
@@ -48,6 +58,11 @@ class Subspace::Commands::Init < Subspace::Commands::Base
|
|
48
58
|
|
49
59
|
end
|
50
60
|
|
61
|
+
def init_vars
|
62
|
+
FileUtils.mkdir_p File.join dest_dir, "templates"
|
63
|
+
copy "templates/application.yml.template"
|
64
|
+
end
|
65
|
+
|
51
66
|
private
|
52
67
|
|
53
68
|
def project_name
|
@@ -1,11 +1,48 @@
|
|
1
1
|
class Subspace::Commands::Vars < Subspace::Commands::Base
|
2
2
|
def initialize(args, options)
|
3
3
|
@environment = args.first
|
4
|
-
@action = options.edit
|
4
|
+
@action = if options.edit
|
5
|
+
"edit"
|
6
|
+
elsif options.create
|
7
|
+
"create"
|
8
|
+
else
|
9
|
+
"view"
|
10
|
+
end
|
11
|
+
|
5
12
|
run
|
6
13
|
end
|
7
14
|
|
8
15
|
def run
|
9
|
-
|
16
|
+
case @action
|
17
|
+
when "create"
|
18
|
+
create_local
|
19
|
+
when "view", "edit"
|
20
|
+
ansible_command "ansible-vault", @action, "vars/#{@environment}.yml"
|
21
|
+
else
|
22
|
+
abort "Invalid vars command"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def create_local
|
27
|
+
if File.exists? File.join(project_path, "config/application.yml")
|
28
|
+
answer = ask "config/application.yml already exists. Reply 'yes' to overwrite: [no] "
|
29
|
+
abort unless answer == "yes"
|
30
|
+
end
|
31
|
+
src = application_yml_template
|
32
|
+
dest = "config/application.yml"
|
33
|
+
vars_file = File.join(project_path, "config/provision/vars/#{@environment}.yml")
|
34
|
+
extra_vars = "project_path=#{project_path} vars_file=#{vars_file} src=#{src} dest=#{dest}"
|
35
|
+
ansible_command "ansible-playbook", File.join(playbook_dir, "local_template.yml"), "--extra-vars", extra_vars
|
36
|
+
say "File created at config/application.yml with #{@environment} secrets"
|
37
|
+
say "-------------------------------------------------------------------\n"
|
38
|
+
|
39
|
+
system "cat", "config/application.yml"
|
10
40
|
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def application_yml_template
|
45
|
+
"config/provision/templates/application.yml.template"
|
46
|
+
end
|
47
|
+
|
11
48
|
end
|
data/lib/subspace/version.rb
CHANGED
data/subspace.gemspec
CHANGED
@@ -31,5 +31,6 @@ Gem::Specification.new do |spec|
|
|
31
31
|
spec.add_development_dependency "rake", "~> 10.0"
|
32
32
|
spec.add_development_dependency "rspec", "~> 3.0"
|
33
33
|
|
34
|
-
spec.add_runtime_dependency "commander", "~>4.
|
34
|
+
spec.add_runtime_dependency "commander", "~>4.2"
|
35
|
+
spec.add_runtime_dependency "figaro", "~>1.0"
|
35
36
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# This file defines the environment variables available to the application at runtime
|
2
|
+
# We use the figaro gem to load environment variables from application.yml.
|
3
|
+
|
4
|
+
# These environment variables are available to all environments, and can be secret or not:
|
5
|
+
|
6
|
+
# These are secret and can be changed per environment easily by using subspace vars <env> --edit
|
7
|
+
SECRET_KEY_BASE: {{secret_key_base}}
|
8
|
+
AWS_SECRET_KEY: {{aws_secret_key}}
|
9
|
+
|
10
|
+
# These are not secret, and have the same value for all environments
|
11
|
+
ENABLE_SOME_FEATURE: false
|
12
|
+
MAX_USER_INVITES: 20
|
13
|
+
DEFAULT_EMAIL_ADDRESS: test@example.com
|
14
|
+
|
15
|
+
|
16
|
+
# These variable are not secret, but have different, static values for all environments
|
17
|
+
development:
|
18
|
+
INSECURE_VARIABLE: "this isn't secret"
|
19
|
+
AWS_BUCKET: my-app-development
|
20
|
+
|
21
|
+
dev:
|
22
|
+
INSECURE_VARIABLE: "but it changes"
|
23
|
+
AWS_BUCKET: my-app-dev
|
24
|
+
|
25
|
+
production:
|
26
|
+
INSECURE_VARIABLE: "on different servers"
|
27
|
+
AWS_BUCKET: my-app-production
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: subspace
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brian Samson
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-05-
|
11
|
+
date: 2017-05-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -58,14 +58,28 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '4.
|
61
|
+
version: '4.2'
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '4.
|
68
|
+
version: '4.2'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: figaro
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.0'
|
69
83
|
description: WIP -- don't use this :)
|
70
84
|
email:
|
71
85
|
- brian@tenforwardconsulting.com
|
@@ -85,6 +99,7 @@ files:
|
|
85
99
|
- README.md
|
86
100
|
- Rakefile
|
87
101
|
- TODO
|
102
|
+
- ansible/playbooks/local_template.yml
|
88
103
|
- ansible/roles/apache/defaults/main.yml
|
89
104
|
- ansible/roles/apache/handlers/main.yml
|
90
105
|
- ansible/roles/apache/tasks/main.yml
|
@@ -223,6 +238,7 @@ files:
|
|
223
238
|
- template/provision/host_vars/template.erb
|
224
239
|
- template/provision/hosts.erb
|
225
240
|
- template/provision/playbook.yml.erb
|
241
|
+
- template/provision/templates/application.yml.template
|
226
242
|
- template/provision/vars/template.erb
|
227
243
|
homepage: https://github.com/tenforwardconsulting/subspace
|
228
244
|
licenses:
|