ridoku 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/.gitignore +23 -0
- data/AUTHORS +3 -0
- data/Gemfile +24 -0
- data/Gemfile.lock +45 -0
- data/LICENSE.txt +23 -0
- data/README.md +271 -0
- data/Rakefile +1 -0
- data/bin/rid +3 -0
- data/bin/ridoku +350 -0
- data/lib/helpers.rb +13 -0
- data/lib/io-colorize.rb +35 -0
- data/lib/options.rb +142 -0
- data/lib/ridoku.rb +11 -0
- data/lib/ridoku/backup.rb +393 -0
- data/lib/ridoku/base.rb +717 -0
- data/lib/ridoku/config_wizard.rb +195 -0
- data/lib/ridoku/cook.rb +103 -0
- data/lib/ridoku/create.rb +101 -0
- data/lib/ridoku/cron.rb +227 -0
- data/lib/ridoku/db.rb +235 -0
- data/lib/ridoku/defaults.rb +68 -0
- data/lib/ridoku/deploy.rb +157 -0
- data/lib/ridoku/domain.rb +124 -0
- data/lib/ridoku/dump.rb +132 -0
- data/lib/ridoku/env.rb +118 -0
- data/lib/ridoku/list.rb +168 -0
- data/lib/ridoku/log.rb +77 -0
- data/lib/ridoku/maintenance.rb +76 -0
- data/lib/ridoku/packages.rb +93 -0
- data/lib/ridoku/rails_defaults.rb +160 -0
- data/lib/ridoku/run.rb +137 -0
- data/lib/ridoku/service.rb +158 -0
- data/lib/ridoku/services/postgres.rb +77 -0
- data/lib/ridoku/services/rabbitmq.rb +48 -0
- data/lib/ridoku/version.rb +5 -0
- data/lib/ridoku/workers.rb +138 -0
- data/ridoku.gemspec +32 -0
- metadata +211 -0
@@ -0,0 +1,124 @@
|
|
1
|
+
#
|
2
|
+
# Command: domain
|
3
|
+
#
|
4
|
+
|
5
|
+
require 'ridoku/base'
|
6
|
+
require 'json'
|
7
|
+
|
8
|
+
module Ridoku
|
9
|
+
register :domain
|
10
|
+
|
11
|
+
class Domain < Base
|
12
|
+
attr_accessor :domains
|
13
|
+
|
14
|
+
def run
|
15
|
+
clist = Base.config[:command]
|
16
|
+
command = clist.shift
|
17
|
+
sub_command = clist.shift
|
18
|
+
|
19
|
+
environment = load_environment
|
20
|
+
|
21
|
+
case sub_command
|
22
|
+
when 'list', nil
|
23
|
+
list
|
24
|
+
when 'set', 'add'
|
25
|
+
add
|
26
|
+
when 'delete', 'remove', 'rm'
|
27
|
+
delete
|
28
|
+
when 'push'
|
29
|
+
push_update
|
30
|
+
else
|
31
|
+
print_domain_help
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
protected
|
36
|
+
|
37
|
+
def load_environment
|
38
|
+
Base.fetch_app
|
39
|
+
self.domains = (Base.app[:domains] ||= [])
|
40
|
+
end
|
41
|
+
|
42
|
+
def print_domain_help
|
43
|
+
$stderr.puts <<-EOF
|
44
|
+
Command: domain
|
45
|
+
|
46
|
+
List/Modify the current app's associated domains.
|
47
|
+
domain[:list] lists the key value pairs
|
48
|
+
domain:add domain, e.g., http://app.example.com
|
49
|
+
domain:delete domain or index
|
50
|
+
domain:push push updated domains to the server
|
51
|
+
|
52
|
+
examples:
|
53
|
+
$ domain
|
54
|
+
No domains specified!
|
55
|
+
$ domain:add app.example.com
|
56
|
+
$ domain:list
|
57
|
+
Domains:
|
58
|
+
0: app.example.com
|
59
|
+
EOF
|
60
|
+
end
|
61
|
+
|
62
|
+
def list
|
63
|
+
if domains.length == 0
|
64
|
+
$stdout.puts 'No domains specified!'
|
65
|
+
else
|
66
|
+
$stdout.puts 'Domains:'
|
67
|
+
domains.each_index do |idx|
|
68
|
+
$stdout.puts " #{$stdout.colorize(idx.to_s, :bold)}: #{domains[idx]}"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def add
|
74
|
+
ARGV.each do |domain|
|
75
|
+
if domains.index(domain) == nil
|
76
|
+
domains << domain
|
77
|
+
$stdout.puts "Adding #{domain}."
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
Base.save_app(:domains)
|
82
|
+
end
|
83
|
+
|
84
|
+
def delete
|
85
|
+
ARGV.each do |domain|
|
86
|
+
if domain.match(/^[0-9]+$/)
|
87
|
+
value = domains.delete_at(domain.to_i)
|
88
|
+
else
|
89
|
+
value = domains.delete(domain)
|
90
|
+
end
|
91
|
+
$stdout.puts "Deleting domain: #{value}"
|
92
|
+
end
|
93
|
+
|
94
|
+
Base.save_app(:domains)
|
95
|
+
end
|
96
|
+
|
97
|
+
def push_update
|
98
|
+
if domains.length == 0
|
99
|
+
$stdout.puts 'No domains specified!'
|
100
|
+
$stderr.puts 'Please specify at least 1 domain and try again.'
|
101
|
+
return
|
102
|
+
end
|
103
|
+
|
104
|
+
unless Base.config[:quiet]
|
105
|
+
$stdout.puts "Pushing domains:"
|
106
|
+
|
107
|
+
domains.each_index do |idx|
|
108
|
+
$stdout.puts " #{$stdout.colorize(idx.to_s, :bold)}: #{domains[idx]}"
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
Base.standard_deploy('rails-app',
|
113
|
+
{
|
114
|
+
opsworks_custom_cookbooks: {
|
115
|
+
recipes: [
|
116
|
+
"deploy::domains"
|
117
|
+
]
|
118
|
+
}
|
119
|
+
}
|
120
|
+
)
|
121
|
+
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
data/lib/ridoku/dump.rb
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
#
|
2
|
+
# Command: dump
|
3
|
+
#
|
4
|
+
|
5
|
+
require 'ridoku/base'
|
6
|
+
|
7
|
+
module Ridoku
|
8
|
+
register :dump
|
9
|
+
|
10
|
+
class Dump < Base
|
11
|
+
|
12
|
+
def run
|
13
|
+
command = Base.config[:command]
|
14
|
+
sub_command = (command.length > 0 && command[1]) || nil
|
15
|
+
sub_sub_command = (command.length > 1 && command[2]) || nil
|
16
|
+
|
17
|
+
case sub_command
|
18
|
+
when 'stack'
|
19
|
+
dump_stack(sub_sub_command == 'all')
|
20
|
+
when 'custom'
|
21
|
+
dump_custom(sub_sub_command == 'all')
|
22
|
+
when 'app'
|
23
|
+
dump_app(sub_sub_command == 'all')
|
24
|
+
when 'layer'
|
25
|
+
dump_layer(sub_sub_command == 'all')
|
26
|
+
when 'instance'
|
27
|
+
dump_instance
|
28
|
+
else
|
29
|
+
print_dump_help
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
protected
|
34
|
+
|
35
|
+
def print_dump_help
|
36
|
+
$stderr.puts <<-EOF
|
37
|
+
Command: dump
|
38
|
+
|
39
|
+
List/Modify the current app's database configuration.
|
40
|
+
dump displays this list
|
41
|
+
dump:stack[:all] dump stack json or :all stack jsons
|
42
|
+
dump:custom[:all] dump stack's custom json only
|
43
|
+
dump:app[:all] dump app json or :all app jsons for specified stack
|
44
|
+
dump:layer[:all] dump layer json or :all layer jsons for specified stack
|
45
|
+
dump:instance dump instance json
|
46
|
+
EOF
|
47
|
+
end
|
48
|
+
|
49
|
+
def dump_custom(all = false)
|
50
|
+
Base.fetch_stack
|
51
|
+
|
52
|
+
if all
|
53
|
+
$stdout.print '['
|
54
|
+
Base.stack_list.each { |st| custom(st, true) }
|
55
|
+
$stdout.puts ']'
|
56
|
+
else
|
57
|
+
custom(Base.stack)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def dump_stack(all = false)
|
62
|
+
Base.fetch_stack
|
63
|
+
|
64
|
+
if all
|
65
|
+
$stdout.print '['
|
66
|
+
Base.stack_list.each { |st| stack(st, true) }
|
67
|
+
$stdout.puts ']'
|
68
|
+
else
|
69
|
+
stack(Base.stack)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def dump_app(all = false)
|
74
|
+
Base.fetch_app
|
75
|
+
|
76
|
+
if all
|
77
|
+
$stdout.print '['
|
78
|
+
Base.app_list.each { |ap| app(ap, true) }
|
79
|
+
$stdout.puts ']'
|
80
|
+
else
|
81
|
+
app(Base.app)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def dump_layer(all = false)
|
86
|
+
Base.fetch_layer(Base.config[:layer] || :all)
|
87
|
+
|
88
|
+
$stdout.print '['
|
89
|
+
if all
|
90
|
+
Base.layer_list.each { |ly| layer(ly) }
|
91
|
+
else
|
92
|
+
Base.layers.each { |ly| layer(ly) }
|
93
|
+
end
|
94
|
+
$stdout.puts ']'
|
95
|
+
end
|
96
|
+
|
97
|
+
def dump_instance
|
98
|
+
Base.fetch_instance
|
99
|
+
$stdout.print '['
|
100
|
+
Base.instances.each { |ist| instance(ist) }
|
101
|
+
$stdout.puts ']'
|
102
|
+
end
|
103
|
+
|
104
|
+
def stack(st, multiple = false)
|
105
|
+
$stdout.print JSON.generate(st.to_hash)
|
106
|
+
$stdout.print ',' if multiple
|
107
|
+
$stdout.puts
|
108
|
+
end
|
109
|
+
|
110
|
+
def custom(st, multiple = false)
|
111
|
+
$stdout.print st[:custom_json]
|
112
|
+
$stdout.print ',' if multiple
|
113
|
+
$stdout.puts
|
114
|
+
end
|
115
|
+
|
116
|
+
def app(ap, multiple = false)
|
117
|
+
$stdout.print ap.to_json
|
118
|
+
$stdout.print ',' if multiple
|
119
|
+
$stdout.puts
|
120
|
+
end
|
121
|
+
|
122
|
+
def layer(ly)
|
123
|
+
$stdout.print ly.to_json
|
124
|
+
$stdout.puts ','
|
125
|
+
end
|
126
|
+
|
127
|
+
def instance(ist)
|
128
|
+
$stdout.print ist.to_json
|
129
|
+
$stdout.puts ','
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
data/lib/ridoku/env.rb
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
#
|
2
|
+
# Command: env
|
3
|
+
# Description: List/Modify the current apps configuration.
|
4
|
+
# env - lists the key value pairs
|
5
|
+
# env:set KEY:VALUE [...]
|
6
|
+
# env:delete KEY
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'ridoku/base'
|
10
|
+
|
11
|
+
module Ridoku
|
12
|
+
register :env
|
13
|
+
|
14
|
+
class Env < Base
|
15
|
+
attr_accessor :environment
|
16
|
+
|
17
|
+
def run
|
18
|
+
command = Base.config[:command]
|
19
|
+
sub_command = (command.length > 0 && command[1]) || nil
|
20
|
+
|
21
|
+
environment = load_environment
|
22
|
+
|
23
|
+
case sub_command
|
24
|
+
when 'list', nil
|
25
|
+
list
|
26
|
+
when 'set', 'add'
|
27
|
+
set
|
28
|
+
when 'push'
|
29
|
+
push
|
30
|
+
when 'delete', 'remove', 'rm'
|
31
|
+
delete
|
32
|
+
else
|
33
|
+
print_env_help
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
protected
|
38
|
+
|
39
|
+
def load_environment
|
40
|
+
Base.fetch_stack
|
41
|
+
Base.fetch_app
|
42
|
+
self.environment =
|
43
|
+
Base.custom_json['deploy'][Base.app[:shortname]]['app_env']
|
44
|
+
end
|
45
|
+
|
46
|
+
def print_env_help
|
47
|
+
$stderr.puts <<-EOF
|
48
|
+
Command: env
|
49
|
+
|
50
|
+
List/Modify the current app's environment.
|
51
|
+
env lists the key value pairs
|
52
|
+
env:push push recipe changes
|
53
|
+
env:set KEY:VALUE [...]
|
54
|
+
env:delete KEY [...]
|
55
|
+
|
56
|
+
examples:
|
57
|
+
$ env
|
58
|
+
Environment Empty!
|
59
|
+
$ env:set AWS_ACCESS_KEY:'jas8dyfawenfi9f'
|
60
|
+
$ env:set AWS_SECRET_KEY:'SJHDF3HSDOFJS4DFJ3E'
|
61
|
+
$ env:delete AWS_SECRET_KEY
|
62
|
+
$ env
|
63
|
+
Environment:
|
64
|
+
AWS_ACCESS_KEY: 'jas8dyfawenfi9f'
|
65
|
+
EOF
|
66
|
+
end
|
67
|
+
|
68
|
+
def push
|
69
|
+
$stdout.puts "Pushing current environment..."
|
70
|
+
|
71
|
+
Base.standard_deploy(['rails-app','workers'],
|
72
|
+
{
|
73
|
+
opsworks_custom_cookbooks: {
|
74
|
+
recipes: [
|
75
|
+
"workers::default",
|
76
|
+
"deploy::environment"
|
77
|
+
]
|
78
|
+
}
|
79
|
+
}
|
80
|
+
)
|
81
|
+
end
|
82
|
+
|
83
|
+
def list
|
84
|
+
if environment.keys.length == 0
|
85
|
+
$stdout.puts 'Environment Empty!'
|
86
|
+
else
|
87
|
+
$stdout.puts 'Environment:'
|
88
|
+
environment.each do |key, value|
|
89
|
+
$stdout.puts " #{$stdout.colorize(key, :bold)}: '#{value}'"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def set
|
95
|
+
ARGV.each do |kvpair|
|
96
|
+
kvpair.match(%r((^[^:]+):(.*))) do |m|
|
97
|
+
key = m[1]
|
98
|
+
value = m[2]
|
99
|
+
|
100
|
+
update = environment.key?(key)
|
101
|
+
environment[key] = value
|
102
|
+
$stdout.puts "#{update && 'Updating' || 'Adding'}: #{key} as '#{value}'"
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
Base.save_stack
|
107
|
+
end
|
108
|
+
|
109
|
+
def delete
|
110
|
+
ARGV.each do |key|
|
111
|
+
value = environment.delete(key)
|
112
|
+
$stdout.puts "Deleting key: #{key}, '#{value}'"
|
113
|
+
end
|
114
|
+
|
115
|
+
Base.save_stack
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
data/lib/ridoku/list.rb
ADDED
@@ -0,0 +1,168 @@
|
|
1
|
+
#
|
2
|
+
# Command: list
|
3
|
+
# Description: Used to list all stacks on an AWS OpsStack account.
|
4
|
+
# The current selection is colorized green.
|
5
|
+
#
|
6
|
+
|
7
|
+
require 'ridoku/base'
|
8
|
+
|
9
|
+
module Ridoku
|
10
|
+
register :list
|
11
|
+
|
12
|
+
class List < Base
|
13
|
+
def run
|
14
|
+
command = Base.config[:command]
|
15
|
+
sub_command = (command.length > 0 && command[1]) || nil
|
16
|
+
|
17
|
+
case sub_command
|
18
|
+
when nil
|
19
|
+
return apps if Base.config[:stack]
|
20
|
+
stacks
|
21
|
+
|
22
|
+
when 'stacks'
|
23
|
+
stacks
|
24
|
+
|
25
|
+
when 'apps'
|
26
|
+
apps
|
27
|
+
|
28
|
+
when 'layers'
|
29
|
+
layers
|
30
|
+
|
31
|
+
when 'instances'
|
32
|
+
instances
|
33
|
+
|
34
|
+
when 'config'
|
35
|
+
config
|
36
|
+
|
37
|
+
when 'services'
|
38
|
+
services
|
39
|
+
|
40
|
+
else
|
41
|
+
print_list_help
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
protected
|
46
|
+
|
47
|
+
def print_list_help
|
48
|
+
$stderr.puts <<-EOF
|
49
|
+
Command: list
|
50
|
+
|
51
|
+
List/Modify the current app's database configuration.
|
52
|
+
list lists stacks or apps if stack is specified
|
53
|
+
list:config lists current configuration information (app, stack, etc)
|
54
|
+
list:stacks lists stacks by name
|
55
|
+
list:apps lists apps if stack is specified
|
56
|
+
list:layers lists layers if stack is specified
|
57
|
+
list:instances lists instances by layer
|
58
|
+
EOF
|
59
|
+
end
|
60
|
+
|
61
|
+
def config
|
62
|
+
config = [
|
63
|
+
'Current:',
|
64
|
+
" #{$stdout.colorize('Stack', :bold)}: #{Base.config[:stack]}",
|
65
|
+
" #{$stdout.colorize('App', :bold)}: #{Base.config[:app]}",
|
66
|
+
" #{$stdout.colorize('Shell User', :bold)}: #{Base.config[:shell_user]}",
|
67
|
+
" #{$stdout.colorize('Service ARN', :bold)}: #{Base.config[:service_arn]}",
|
68
|
+
" #{$stdout.colorize('Instance ARN', :bold)}: #{Base.config[:instance_arn]}",
|
69
|
+
" #{$stdout.colorize('Default SSH Key', :bold)}: #{Base.config[:ssh_key]}",
|
70
|
+
]
|
71
|
+
$stdout.puts config
|
72
|
+
end
|
73
|
+
|
74
|
+
def stacks
|
75
|
+
Base.fetch_stack(force: true)
|
76
|
+
|
77
|
+
stack_arr = Base.stack_list.map do |stack|
|
78
|
+
name = stack[:name]
|
79
|
+
(name == Base.config[:stack] && $stdout.colorize(name, :green)) || name
|
80
|
+
end
|
81
|
+
|
82
|
+
list = stack_arr.join(', ')
|
83
|
+
$stdout.puts 'Application stacks on your account:'
|
84
|
+
$stdout.puts " #{$stdout.colorize(list, :bold)}"
|
85
|
+
end
|
86
|
+
|
87
|
+
def apps
|
88
|
+
Base.fetch_app
|
89
|
+
|
90
|
+
app_arr = Base.app_list.map do |app|
|
91
|
+
name = app[:name]
|
92
|
+
(name == Base.config[:app] && $stdout.colorize(name, :green)) || name
|
93
|
+
end
|
94
|
+
|
95
|
+
list = app_arr.join(', ')
|
96
|
+
$stdout.puts "Application apps on stack " +
|
97
|
+
"#{$stdout.colorize(Base.stack[:name], [:green, :bold])}:"
|
98
|
+
$stdout.puts " #{$stdout.colorize(list, :bold)}"
|
99
|
+
end
|
100
|
+
|
101
|
+
def layers
|
102
|
+
Base.fetch_layer
|
103
|
+
|
104
|
+
max = 0
|
105
|
+
Base.layer_list.each do |layer|
|
106
|
+
shortname = $stdout.colorize(layer[:shortname], :bold)
|
107
|
+
max = shortname.length if max < shortname.length
|
108
|
+
end
|
109
|
+
|
110
|
+
layer_arr = Base.layer_list.map do |layer|
|
111
|
+
fmt = "%#{max}s"
|
112
|
+
shortname = sprintf(fmt, $stdout.colorize(layer[:shortname], :bold))
|
113
|
+
name = "[#{shortname}] #{layer[:name]}"
|
114
|
+
if layer[:shortname] == Base.config[:layer]
|
115
|
+
$stdout.colorize(name, :green)
|
116
|
+
else
|
117
|
+
name
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
$stdout.puts 'Layers on stack ' +
|
122
|
+
"#{$stdout.colorize(Base.stack[:name], [:bold, :green])}:"
|
123
|
+
$stdout.puts layer_arr
|
124
|
+
end
|
125
|
+
|
126
|
+
def instances
|
127
|
+
Base.fetch_layer
|
128
|
+
Base.fetch_instance
|
129
|
+
|
130
|
+
$stdout.puts 'Application instances on stack ' +
|
131
|
+
"#{$stdout.colorize(Base.stack[:name], [:bold, :green])}:"
|
132
|
+
|
133
|
+
Base.layer_list.each do |layer|
|
134
|
+
selected = Base.config[:instances]
|
135
|
+
|
136
|
+
linstances = Base.instances.select do |inst|
|
137
|
+
inst[:layer_ids].index(layer[:layer_id]) != nil
|
138
|
+
end
|
139
|
+
|
140
|
+
instance_arr = linstances.map do |instance|
|
141
|
+
name = " #{instance[:hostname]}: #{$stdout.colorize(
|
142
|
+
instance[:status], instance[:status] == 'online' ? :green : :red)}"
|
143
|
+
if selected && selected.index(instance[:hostname]) != nil
|
144
|
+
$stdout.colorize(name, :green)
|
145
|
+
else
|
146
|
+
name
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
name = "Layer: #{layer[:name]} [#{layer[:shortname]}]"
|
151
|
+
|
152
|
+
$stdout.puts (layer[:shortname] == Base.config[:layer] &&
|
153
|
+
$stdout.colorize(name, :green)) || name
|
154
|
+
|
155
|
+
if instance_arr.length
|
156
|
+
$stdout.puts instance_arr
|
157
|
+
else
|
158
|
+
$stdout.puts ' No instances in this layer.'
|
159
|
+
end
|
160
|
+
$stdout.puts
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
def services
|
165
|
+
Ridoku::Service.new.run(['list'])
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|