deis_deploy 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0a57435f77ae92b00838d768f60061cccf920521
4
+ data.tar.gz: f0e6faa2afb1d9ced144a619f69bb6a7a7f7dce4
5
+ SHA512:
6
+ metadata.gz: 9ef4db92538d47ce0afdfc5f5c1bc2855b1377d0f696591ccc8fafbcc611fabe8f8ef6252b0db7285282d229a7cda559e5d08d7ea86d0fa6b3dc8d4f0b1088ce
7
+ data.tar.gz: 316c93427808d327e6357ef06dc7837a51bdf6061cd529d8b245bc43d535af95709eebee7e4da468f99bcc6413c2fdeecd3e9adaa8623cc43712e4d8be22dd24
@@ -0,0 +1 @@
1
+ *.gem
@@ -0,0 +1 @@
1
+ 2.1.2
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
@@ -0,0 +1,22 @@
1
+ # DEIS DEPLOYMENT #
2
+
3
+ Gem to make deploying to deis much easier.
4
+
5
+ ## Install & Setup ##
6
+
7
+ <code>gem install deis_deploy</code>
8
+
9
+ ## Usage ##
10
+
11
+ <code>cd $REPO_DIR</code>
12
+ <code>deisConfig name</code>
13
+ this will give you app a name, optional
14
+ <code>deisConfig set $ENV $VARNAME $VALUE</code>
15
+ sets a variable for this application
16
+ <code>deisConfig list</code>
17
+ this will show all config values
18
+ <code>deisConfig domain $ENV $DOMAIN</code>
19
+ <code>deisConfig domains $ENV</code>
20
+ lists all domains
21
+ <code>deisDeploy staging</code>
22
+ deploys to staging cluster
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+ lib = File.expand_path(File.dirname(__FILE__) + '/../lib')
4
+ $LOAD_PATH.unshift(lib) if File.directory?(lib) && !$LOAD_PATH.include?(lib)
5
+
6
+ require "deis_deploy"
7
+ DEIS::Config.start(ARGV)
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+ lib = File.expand_path(File.dirname(__FILE__) + '/../lib')
4
+ $LOAD_PATH.unshift(lib) if File.directory?(lib) && !$LOAD_PATH.include?(lib)
5
+
6
+ require "deis_deploy"
7
+ DEIS::Deploy.start(ARGV)
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "deis_deploy/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "deis_deploy"
8
+ spec.version = DEIS::VERSION
9
+ spec.authors = ["Charles Marshall"]
10
+ spec.email = ["cm56marshall@gmail.com"]
11
+ spec.summary = %q{ }
12
+ spec.description = %q{ }
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+ spec.required_ruby_version = '>= 2.0'
20
+
21
+ spec.add_dependency "colorize", "~> 0.7"
22
+ spec.add_dependency "bundler", "~> 1.5"
23
+ spec.add_dependency "thor", "~> 0.19"
24
+ spec.add_dependency "faker", "~> 1.4"
25
+ spec.add_dependency "net-ssh", "~> 2.9"
26
+
27
+ spec.post_install_message = ""
28
+
29
+ end
@@ -0,0 +1,27 @@
1
+ require "deis_deploy/version"
2
+ require "utils"
3
+ require "ssh"
4
+ require "deis_deploy/strings"
5
+
6
+ module DEIS
7
+ require "thor"
8
+ require "faker"
9
+ require 'fileutils'
10
+ require 'json'
11
+ # utils
12
+
13
+ require "deis_deploy/git"
14
+ require "deis_deploy/file_locations"
15
+ require "deis_deploy/validations"
16
+
17
+ # thor
18
+ require "deis_deploy/deploy"
19
+ require "deis_deploy/config"
20
+ # formatting vars
21
+ FORMAT_OK = "\e[0;32m%#-40s\t%5s\e[0m\n"
22
+ FORMAT_ERROR = "\e[33;40m%#-40s\t%5s\e[0m\n"
23
+ FORMAT_FATAL = "\e[0;31m%#-40s\t%5s\e[0m\n"
24
+
25
+ end
26
+
27
+ String::log_level = ENV['DEIS_GEM_LOG_LEVEL'].to_i if ! ENV['DEIS_GEM_LOG_LEVEL'].nil?
@@ -0,0 +1,280 @@
1
+ module DEIS
2
+
3
+ class Config < Thor
4
+ extend Utils
5
+ include Utils
6
+
7
+ desc "set <env> <varname> <value>", "Set <var> to <value> for <env>"
8
+ def set(env, varname, value)
9
+ DEIS::Validations.config
10
+ stored = DEIS::Config.data
11
+ current = if stored.nil? then {} else stored end
12
+ name = DEIS::Config.full_name(env)
13
+ "Setting #{varname} to #{value} in #{env}".info
14
+ "Using name: #{name}".log
15
+ sub_config = if !current[name].nil? && !current[name]["config"].nil? then current[name]["config"] else {:RACK_EV => env, :RAILS_ENV => env} end
16
+ sub_config[varname] = value
17
+ current[name] = {
18
+ :deis_name => "#{name}",
19
+ :dir => "#{name}-#{Time.now.to_i}",
20
+ :remote => DEIS::Git.remote,
21
+ :repo => DEIS::Git.repo,
22
+ :env => env,
23
+ :config => sub_config,
24
+ :removed_config => []
25
+ }
26
+ # log output
27
+ DEIS::Config.save(current)
28
+ "Complete (run 'deisDeploy #{env}' to deploy changes)".important
29
+ end
30
+
31
+ desc "domain <env> <domain_without_schema>", "Add a custom domain"
32
+ def domain(env="staging", domain)
33
+ DEIS::Validations.config
34
+ stored = DEIS::Config.data
35
+ current = if stored.nil? then {} else stored end
36
+ name = DEIS::Config.full_name(env)
37
+ "Adding domain #{domain} to #{env}".info
38
+ "Using name: #{name}".log
39
+ if current.has_key?(name)
40
+ current[name]["url"] = {} if current[name]["url"].nil?
41
+ current[name]["url"][env] = [] if current[name]["url"][env].nil?
42
+ current[name]["url"][env].push(domain)
43
+ DEIS::Config.save(current)
44
+ "Complete (run 'deisDeploy #{env}' to deploy changes)".important
45
+ else
46
+ "No config values set, create those first".fatal
47
+ exit 1
48
+ end
49
+ end
50
+
51
+ desc "domains <env>", "List all domains in <env>"
52
+ def domains(env="staging")
53
+ DEIS::Validations.config
54
+ stored = DEIS::Config.data
55
+ name = DEIS::Config.full_name(env)
56
+ current = if stored.nil? then {} else stored end
57
+ "Listing domains in #{env}..".info
58
+ if current.has_key?(name) && current[name].has_key?("url") && current[name]["url"].has_key?(env)
59
+ "Found domains".log
60
+ printf(DEIS::FORMAT_OK, "Domain", "")
61
+ printf(DEIS::FORMAT_OK, "-------------------------------", "")
62
+ current[name]["url"][env].each{|v| printf(DEIS::FORMAT_OK, "#{v}", "") }
63
+ else
64
+ "No domains found".info
65
+ end
66
+ "Complete".important
67
+ end
68
+
69
+ desc "list <env>", "List all config vars in <env>"
70
+ def list(env="staging")
71
+ DEIS::Validations.config
72
+ stored = DEIS::Config.data
73
+ name = DEIS::Config.full_name(env)
74
+ "Getting config data for #{name}\n".info
75
+ if !stored.nil? && !name.nil? && !stored[name].nil? && !stored[name]["config"].nil?
76
+ "Found data for #{name}".log
77
+ printf(DEIS::FORMAT_OK, "Name", "Value")
78
+ printf(DEIS::FORMAT_OK, "-------------------------------", "---------")
79
+ stored[name]['config'].each {|k,v| printf(DEIS::FORMAT_OK, "#{k}", "#{v}") }
80
+ else
81
+ "No data".info
82
+ end
83
+ "checking for config data that will be removed..".log
84
+ if !stored.nil? && !name.nil? && !stored[name].nil? && !stored[name]["removed_config"].nil? && stored[name]["removed_config"].size > 0
85
+ "\nThe following config items are waiting to be removed".info
86
+ printf(DEIS::FORMAT_OK, "Name", "Value")
87
+ printf(DEIS::FORMAT_OK, "-------------------------------", "---------")
88
+ stored[name]['removed_config'].each {|r| printf(DEIS::FORMAT_OK, "#{r['k']}", "#{r['v']}") }
89
+ end
90
+
91
+ "Complete".important
92
+ end
93
+
94
+ desc "rm <env> <varname>", "Remove the <varname> from the config"
95
+ def rm(env, varname)
96
+ DEIS::Validations.config
97
+ "Removing #{varname} from #{env}".info
98
+ stored = DEIS::Config.data
99
+ if !stored.nil?
100
+ name = DEIS::Config.full_name(env)
101
+ "Found data store for #{name}".log
102
+ if !stored[name].nil? && !stored[name]["config"].nil? && stored[name]["config"].has_key?(varname)
103
+ value = stored[name]["config"][varname]
104
+ "Value was #{value}".log
105
+ stored[name]["removed_config"] = [] if ! stored[name].has_key?("removed_config")
106
+ stored[name]["removed_config"].push( {:k => varname, :v => value} )
107
+ stored[name]["config"].tap{|r| r.delete(varname) }
108
+ DEIS::Config.save(stored)
109
+ end
110
+ end
111
+ "Complete (run 'deisDeploy deis_unset_config #{env}' to deploy changes)".important
112
+ end
113
+
114
+
115
+ desc "name <name>", "set the name of the app if its not been done before"
116
+ def name(name)
117
+ DEIS::Validations.config
118
+ file = DEIS::Config.name_storage+DEIS::Git.repo+".json"
119
+ if File.exists?(file)
120
+ "Cannot set name, use rename instead".fatal
121
+ exit
122
+ end
123
+ data = [ {:name => name, :active => true} ].to_json
124
+ File.open(file, "w") {|f| f.write( data ) }
125
+ "Complete".important
126
+ end
127
+
128
+ desc "names", "View all names used for this repo"
129
+ def names
130
+ DEIS::Validations.config
131
+ file = DEIS::Config.name_storage+DEIS::Git.repo+".json"
132
+ printf(DEIS::FORMAT_OK, "Name", "")
133
+ printf(DEIS::FORMAT_OK, "-------------------------------", "")
134
+ JSON.parse( File.open(file, "r"){|f| f.read} ).each{ |row| printf(DEIS::FORMAT_OK, row['name'], "")}
135
+ end
136
+
137
+ # fetch all names
138
+ def self.names(repo=nil)
139
+ repo = DEIS::Git.repo if repo.nil?
140
+ file = DEIS::Config.name_storage+repo+".json"
141
+ if File.exists?(file)
142
+ return JSON.parse( File.open(file, "r"){|f| f.read} )
143
+ else
144
+ return []
145
+ end
146
+ end
147
+
148
+ def self.save_names(names, repo=nil)
149
+ repo = DEIS::Git.repo if repo.nil?
150
+ file = DEIS::Config.name_storage+repo+".json"
151
+ if names.class == Array
152
+ names = names.to_json
153
+ end
154
+ File.open(file, "w") {|f| f.write( names ) }
155
+ end
156
+
157
+ desc "rename <env> <new_name>", "generate a new name"
158
+ def rename(env, newname=nil)
159
+ DEIS::Validations.config
160
+ repo = DEIS::Git.repo
161
+ "Warning, this may break deployed versions of this app.".warning
162
+ newname = DEIS::Config.new_name(repo) if newname.nil?
163
+ # find the current name
164
+ currentname = DEIS::Config.full_name(env)
165
+ current_short_name = DEIS::Config.name
166
+ "#{currentname}".log
167
+ names = DEIS::Config.names(repo)
168
+ exists = names.select{ |row| row['name'] == newname}
169
+ if exists.nil? || exists.size == 0
170
+ "Renaming #{current_short_name} to #{newname}".log
171
+ # adjust the name file
172
+ names = names.select!{|row| row['name'] != current_short_name}
173
+ names = [] if names.nil?
174
+ names = names.push({:name => newname, :active => true})
175
+ # adjust config file
176
+ stored = DEIS::Config.data
177
+ if stored.has_key?(currentname)
178
+ key = DEIS::Config.full_name(env, repo, newname)
179
+ stored[key] = stored[currentname]
180
+ stored[key]['deis_name'] = newname
181
+ stored.delete(currentname)
182
+ DEIS::Config.save(stored)
183
+ DEIS::Config.save_names(names.to_json, repo)
184
+ "Renamed to #{newname}".info
185
+ "Complete".important
186
+ end
187
+ else
188
+ "Cannot rename, #{newname} has already been used".fatal
189
+ end
190
+ end
191
+
192
+ # save the config array to a file
193
+ def self.save(array)
194
+ file = DEIS::Config.config_storage+"#{DEIS::Git.repo}.json"
195
+ data = array.to_json
196
+ File.open(file, "w") {|f| f.write( data ) }
197
+ end
198
+
199
+ #
200
+ def self.deis_end_point
201
+ self.target_host("deis_router_end_point")
202
+ end
203
+
204
+ # check for / generate a name and store that name in the config file
205
+ def self.name
206
+ repo = DEIS::Git.repo
207
+ names = DEIS::Config.names(repo)
208
+ if names.size > 0
209
+ name = DEIS::Config.existing_name(repo)
210
+ "Found existing name: #{name}".log
211
+ else
212
+ name = DEIS::Config.generate_name(repo)
213
+ "Created name: #{name}".log
214
+ end
215
+ return name
216
+ end
217
+
218
+ def self.existing_name(repo=nil)
219
+ repo = DEIS::Git.repo if repo.nil?
220
+ names = DEIS::Config.names(repo)
221
+ name = nil
222
+ if names && names.size > 0
223
+ content = names.select{|r| r["active"]}
224
+ name = if !content.nil? then content.first["name"] end
225
+ end
226
+ name
227
+ end
228
+
229
+ def self.new_name(repo=nil)
230
+ Faker::App.name.downcase.gsub(" ", "-")
231
+ end
232
+ def self.generate_name(repo)
233
+ name = DEIS::Config.new_name(repo)
234
+ names = DEIS::Config.names(repo)
235
+ data = names.push({:name => name, :active => true} ).to_json
236
+ DEIS::Config.save_names(data, repo)
237
+ name
238
+ end
239
+
240
+ def self.full_name(env="staging", repo=nil, name=nil)
241
+ repo = DEIS::Git.repo if repo.nil?
242
+ name = self.name if name.nil?
243
+ repo+"-"+name+"-"+env
244
+ end
245
+
246
+ def self.name_storage
247
+ self.file_store(DEIS::NAMES_STORE)
248
+ end
249
+ # make and return the directory path for data storage
250
+ def self.config_storage
251
+ self.file_store(DEIS::CONFIG_STORE)
252
+ end
253
+
254
+ # fetch & parse json file containing the data for this app
255
+ def self.data
256
+ self.config_data
257
+ end
258
+
259
+
260
+ # find and return current config
261
+ def self.current(env="staging")
262
+ name = DEIS::Config.full_name(env)
263
+ "found config name: #{name}".log
264
+ if DEIS::Config.data.has_key?(name)
265
+ return DEIS::Config.data[name]
266
+ end
267
+ return nil
268
+ end
269
+
270
+ def self.save_current(env, config, name=nil)
271
+ name = DEIS::Config.full_name(env) if name.nil?
272
+ stored = DEIS::Config.data
273
+ current = if stored.nil? then {} else stored end
274
+ current[name] = config
275
+ DEIS::Config.save(current)
276
+ end
277
+
278
+ end
279
+
280
+ end
@@ -0,0 +1,172 @@
1
+ module DEIS
2
+
3
+ class Deploy < Thor
4
+ extend Utils
5
+ include Utils
6
+
7
+ desc "staging", "Deploy to staging"
8
+ def staging
9
+ env = "staging"
10
+ name = DEIS::Config.name
11
+ host = self.target_host(env)
12
+ "Deploying '#{name}' to '#{env}' on '#{host}'".info
13
+ # fetch config data for this name
14
+ config = DEIS::Config.current(env)
15
+ # run validations
16
+ DEIS::Validations.deploy(env, host, config)
17
+ if ! config.nil?
18
+ # clone repo to $HOME/APPS/$FULL_NAME (swap if exists - add to saved config data)
19
+ # fetch
20
+ # checkout to matching branch
21
+ self.checkout(env,host, config)
22
+ # deis create $name
23
+ self.deis_create(env, host, config)
24
+ # add domain
25
+ self.deis_domain(env, host, config)
26
+ # create deis config command and run it
27
+ self.deis_unset_config(env, host, config)
28
+ self.deis_config(env, host, config)
29
+
30
+ # git push deis $branch
31
+ self.push(env, host, config)
32
+ end
33
+ end
34
+
35
+ desc "push <env> <host> <config>", "Push to deis for building"
36
+ def push(env, host=nil, config=nil)
37
+ host = self.target_host(env) if host.nil?
38
+ config = DEIS::Config.current(env) if config.nil? || config.class != Hash
39
+ "Deploying..".info
40
+ ssh = SSH.new({:host => host, :user => nil})
41
+ location = "#{DEIS::REMOTE_APP_DIR}#{config['dir']}"
42
+ ref = DEIS::Git.ref
43
+ branch = DEIS::Git.branch
44
+ # actually deploys it
45
+ res = ssh.exec!("cd #{location} && git push deis #{branch}:#{ref}")
46
+ "Failed to deploy".fatal if res == false
47
+ up = ssh.exec!("cd #{location} && deis scale web=1 | grep 'web\..* up' | wc -l").to_i if res != false
48
+ "Complete".important if ! up.nil? && up > 0
49
+ ssh.close
50
+ end
51
+
52
+ desc "deis_domain <env> <host> <config>", "Set a domain on the app"
53
+ def deis_domain(env, host=nil, config=nil)
54
+ host = self.target_host(env) if host.nil?
55
+ config = DEIS::Config.current(env) if config.nil? || config.class != Hash
56
+ "Adding domain..".info
57
+ ssh = SSH.new({:host => host, :user => nil})
58
+ location = "#{DEIS::REMOTE_APP_DIR}#{config['dir']}"
59
+ if config.has_key?("url") && config["url"].has_key?(env)
60
+ domains = config['url'][env]
61
+ domains.each do |domain|
62
+ exists = ssh.exec!("cd #{location} && deis domains | grep #{domain} -o | wc -l").to_i
63
+ res = ssh.exec!("cd #{location} && deis domains:add #{domain} | grep 400 | wc -l").to_i if exists == 0
64
+ "Domain #{domain} already in use".warning if ! res.nil? && res > 0
65
+ "Added #{domain}".info if ! res.nil? && res == 0
66
+ end
67
+ else
68
+ "No custom url to add".info
69
+ end
70
+ ssh.close
71
+
72
+ end
73
+
74
+ desc "deis_unset_config <env> <host> <config>", "Remove a series of values from deis app data"
75
+ def deis_unset_config(env, host=nil, config=nil)
76
+ host = self.target_host(env) if host.nil?
77
+ config = DEIS::Config.current(env) if config.nil? || config.class != Hash
78
+ name = DEIS::Config.full_name(env)
79
+ "Checking for old config data to remove..".info
80
+ ssh = SSH.new({:host => host, :user => nil})
81
+ location = "#{DEIS::REMOTE_APP_DIR}#{config['dir']}"
82
+ # run the unset calls
83
+ config['removed_config'].each{|r| ssh.exec!( "cd #{location} && deis config:unset #{r['k']}" ) }
84
+ ssh.close
85
+ config['removed_config'] = []
86
+ DEIS::Config.save_current(env, config, name)
87
+ "Removed".info
88
+ end
89
+
90
+ desc "deis_config <env> <host> <config>", "Sets config on deis for this app"
91
+ def deis_config(env, host=nil, config=nil)
92
+ host = self.target_host(env) if host.nil?
93
+ config = DEIS::Config.current(env) if config.nil? || config.class != Hash
94
+ "Setting config data..".info
95
+ # presume you have a working ssh config so we dont need to worry about the ssh user
96
+ ssh = SSH.new({:host => host, :user => nil})
97
+ location = "#{DEIS::REMOTE_APP_DIR}#{config['dir']}"
98
+ # generate deis config string from the config data
99
+ config_cmd = self.data_to_deis_config_set(config['config'])
100
+ res = ssh.exec!("cd #{location} && #{config_cmd}") unless config_cmd.nil?
101
+ ssh.close
102
+ if res.nil? && ! config_cmd.nil?
103
+ "Config command failed".fatal
104
+ exit 1
105
+ elsif config_cmd.nil?
106
+ "No config data to set".info
107
+ end
108
+ end
109
+
110
+ desc "deis create <env> <host> <config>", "Tries to create a deis application based on the data"
111
+ def deis_create(env, host=nil, config=nil)
112
+ host = self.target_host(env) if host.nil?
113
+ config = DEIS::Config.current(env) if config.nil? || config.class != Hash
114
+
115
+ "Creating deis app".info
116
+ # presume you have a working ssh config so we dont need to worry about the ssh user
117
+ ssh = SSH.new({:host => host, :user => nil})
118
+ location = "#{DEIS::REMOTE_APP_DIR}#{config['dir']}"
119
+ # check if already created the app
120
+ app_exists = ssh.exec!("deis apps | grep #{config['deis_name']} | wc -l").to_i
121
+ creation_failed = 0
122
+ # if the app does exist, create it
123
+ if app_exists == 0
124
+ creation_failed = ssh.exec!("cd #{location} && deis create #{config['deis_name']} --cluster=#{config['env']} | grep 400 | wc -l").to_i
125
+ else
126
+ "Application alrady exists..".info
127
+ end
128
+ # if creation failed, die
129
+ if creation_failed >= 1
130
+ "Failed to create deis app".fatal
131
+ "\nThis could be due to cluster being missing, the application name may be in use or other issues.".warning
132
+ exit 1
133
+ end
134
+ # make sure this dir uses this app name
135
+ matches = ssh.exec!("sleep 1; cd #{location} && deis info | grep '#{config['deis_name']} Application' -o | wc -l").to_i
136
+ if matches != 1
137
+ "Application names do not match".fatal
138
+ exit 1
139
+ end
140
+ ssh.close
141
+
142
+ end
143
+
144
+ desc "checkout <env> <host> <config>", "runs a git clone, fetch & checkout"
145
+ def checkout(env, host=nil, config=nil)
146
+ host = self.target_host(env) if host.nil?
147
+ config = DEIS::Config.current(env) if config.nil? || config.class != Hash
148
+ # presume you have a working ssh config so we dont need to worry about the ssh user
149
+ ssh = SSH.new({:host => host, :user => nil})
150
+ # check base location exists
151
+ base = ssh.exec!("ls -lart #{DEIS::REMOTE_APP_DIR} | wc -l").to_i
152
+ # create if it doesnt
153
+ ssh.exec!("mkdir -p #{DEIS::REMOTE_APP_DIR}") if base == 0
154
+ # check location
155
+ location = ssh.exec!("ls -lart #{DEIS::REMOTE_APP_DIR}#{config['dir']} | wc -l").to_i
156
+ # clone if it doesn't exist
157
+ ssh.exec!("cd #{DEIS::REMOTE_APP_DIR} && git clone #{config['remote']} #{config['deis_name']}") if location == 0
158
+ # find current ref head
159
+ ref = DEIS::Git.branch
160
+ "current git ref: #{ref}".log
161
+ # checkout to that ref head
162
+ res = nil
163
+ res = ssh.exec!("cd #{DEIS::REMOTE_APP_DIR}#{config['dir']} && git fetch && git checkout #{ref}") unless ref.nil?
164
+ ssh.close
165
+ res
166
+ end
167
+
168
+
169
+
170
+ end
171
+
172
+ end
@@ -0,0 +1,7 @@
1
+ module DEIS
2
+ CONFIG_STORE = "#{ENV['HOME']}/.deis/Gem/config/"
3
+ NAMES_STORE = "#{ENV['HOME']}/.deis/Gem/names/"
4
+ HOSTS_STORE = "#{ENV['HOME']}/.deis/Gem/hosts/"
5
+ # remote locations
6
+ REMOTE_APP_DIR = "$HOME/APPS/"
7
+ end
@@ -0,0 +1,33 @@
1
+ module DEIS
2
+ class Git
3
+
4
+ def self.is_git?
5
+ res = `git status 2>&1 | grep 'fatal: Not a git' | wc -l`.to_i
6
+ "is git: #{res} (#{res.class})".log
7
+ if res == 0 then true else false end
8
+ end
9
+
10
+ def self.repo
11
+ remote = DEIS::Git.remote
12
+ "remote: #{remote}".log
13
+ if remote.nil? || remote.length == 0
14
+ return "na"
15
+ else
16
+ `echo #{remote} | grep "/.*\.git" -o | sed -E "s#/##" | sed -E "s#.git##" 2>/dev/null`.strip
17
+ end
18
+ end
19
+
20
+ def self.remote
21
+ `c=$(git remote show | wc -l ) ; if [ "$c" -gt 0 ]; then git remote show -n origin | grep " Fetch URL:" | grep ": .*" -o | sed -E "s#: ##" 2>/dev/null ; fi`.strip
22
+ end
23
+
24
+ def self.ref
25
+ `git rev-parse --verify HEAD 2>/dev/null`.strip
26
+ end
27
+
28
+ def self.branch
29
+ `git rev-parse --abbrev-ref HEAD`.strip
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,55 @@
1
+ require 'colorize'
2
+ class String
3
+ ##
4
+ # data logging
5
+ ##
6
+
7
+ # add a log level value to string class for output handling
8
+ # 0 = fatal only
9
+ # 1 = fatal & warnings
10
+ # 2 = fatal, warnings & important
11
+ # 3 = fatal, warnings, important & info
12
+ # 4 = fatal, warnings, important, info & log
13
+ @@log_level = 3
14
+ def self.log_level
15
+ return @@log_level
16
+ end
17
+ def self.log_level=(lvl)
18
+ @@log_level = lvl.to_i
19
+ end
20
+
21
+ # functions to output various log types
22
+ def log
23
+ if @@log_level >= 4
24
+ puts "\e[2m[#{Time.now}]: #{self}\e[22m"
25
+ end
26
+ end
27
+
28
+ def info
29
+ if @@log_level >= 3
30
+ puts self.colorize(:green)
31
+ end
32
+ end
33
+
34
+ def important
35
+ if @@log_level >= 2
36
+ puts ""
37
+ puts self.colorize(:blue)
38
+ puts ""
39
+ end
40
+ end
41
+
42
+ def warning
43
+ if @@log_level >= 1
44
+ puts self.colorize(:red)
45
+ end
46
+ end
47
+
48
+ def fatal
49
+ if @@log_level >= 0
50
+ puts self.colorize(:background => :red, :color => :white)
51
+ end
52
+ end
53
+
54
+
55
+ end
@@ -0,0 +1,33 @@
1
+ module DEIS
2
+ class Validations
3
+
4
+ def self.config
5
+ DEIS::Validations.git
6
+ end
7
+
8
+ def self.deploy(env, host, config)
9
+ # make sure a cluster exists
10
+ DEIS::Validations.cluster(env, host)
11
+ end
12
+
13
+ def self.cluster(env, host)
14
+ ssh = SSH.new({:host => host, :user => nil})
15
+ cluster = ssh.exec!("deis clusters | grep #{env} | wc -l").to_i
16
+ ssh.close
17
+ if cluster == 1 then true else false end
18
+ end
19
+
20
+ def self.git
21
+ if ! DEIS::Git.is_git?
22
+ "Not a git repository, exiting".fatal
23
+ exit 1
24
+ end
25
+ if DEIS::Git.remote.nil?
26
+ "Git remote could not be found, exiting".fatal
27
+ exit 1
28
+ end
29
+ end
30
+
31
+
32
+ end
33
+ end
@@ -0,0 +1,3 @@
1
+ module DEIS
2
+ VERSION="0.0.1"
3
+ end
@@ -0,0 +1,51 @@
1
+ require 'net/ssh'
2
+ class SSH
3
+
4
+ def initialize(config)
5
+ @config = config
6
+ "SSH: #{@config[:user]}@#{@config[:host]}".log
7
+ @ssh = Net::SSH.start(@config[:host], @config[:user])
8
+ end
9
+
10
+ def exec!(command)
11
+ # I am not awesome enough to have made this method myself
12
+ # I've just modified it a bit
13
+ # Originally submitted by 'flitzwald' over here: http://stackoverflow.com/a/3386375
14
+ stdout_data = ""
15
+ stderr_data = ""
16
+ exit_code = nil
17
+ "#{command.strip}".log
18
+ @ssh.open_channel do |channel|
19
+ channel.exec(command) do |ch, success|
20
+ unless success
21
+ abort "FAILED: couldn't execute command (ssh.channel.exec)"
22
+ end
23
+ channel.on_data do |ch,data|
24
+ stdout_data+=data
25
+ end
26
+
27
+ channel.on_extended_data do |ch,type,data|
28
+ stderr_data+=data
29
+ end
30
+
31
+ channel.on_request("exit-status") do |ch,data|
32
+ exit_code = data.read_long
33
+ end
34
+ end
35
+ end
36
+ @ssh.loop
37
+ stdout_data.strip.log
38
+ stderr_data.strip.log
39
+ if exit_code > 0
40
+ return false
41
+ else
42
+ return stdout_data.strip
43
+ end
44
+ end
45
+
46
+
47
+ def close
48
+ @ssh.close
49
+ end
50
+
51
+ end
@@ -0,0 +1,41 @@
1
+ module Utils
2
+ require "thor"
3
+ include Thor::Shell
4
+
5
+ def target_host(env)
6
+ file = DEIS::HOSTS_STORE+env
7
+ if ! File.exists?(file)
8
+ host = ask "Hostname / IP for #{env}: ".colorize(:yellow)
9
+ self.file_store(DEIS::HOSTS_STORE)
10
+ File.open(file, "w"){|f| f.write(host) }
11
+ end
12
+ File.read(file)
13
+ end
14
+
15
+ def file_store(dir)
16
+ FileUtils.mkdir_p(dir) unless Dir.exists?(dir)
17
+ dir
18
+ end
19
+
20
+ def config_data
21
+ "looking for data file".log
22
+ name = DEIS::Git.repo
23
+ file = DEIS::Config.config_storage+"#{name}.json"
24
+ "data file: #{file}".log
25
+ if File.exists?(file) && ( content = File.read(file) ) && (json = JSON.parse(content))
26
+ return json
27
+ end
28
+ return nil
29
+ end
30
+
31
+
32
+ def data_to_deis_config_set(config)
33
+ if config.length > 0
34
+ string = "deis config:set "
35
+ config.each{|k,v| string += "#{k}=\"#{v.strip}\" "}
36
+ return string.strip
37
+ end
38
+ nil
39
+ end
40
+
41
+ end
metadata ADDED
@@ -0,0 +1,133 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: deis_deploy
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Charles Marshall
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-10-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: colorize
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.7'
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'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.5'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.5'
41
+ - !ruby/object:Gem::Dependency
42
+ name: thor
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.19'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.19'
55
+ - !ruby/object:Gem::Dependency
56
+ name: faker
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.4'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.4'
69
+ - !ruby/object:Gem::Dependency
70
+ name: net-ssh
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '2.9'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '2.9'
83
+ description: " "
84
+ email:
85
+ - cm56marshall@gmail.com
86
+ executables:
87
+ - deisConfig
88
+ - deisDeploy
89
+ extensions: []
90
+ extra_rdoc_files: []
91
+ files:
92
+ - ".gitignore"
93
+ - ".ruby-version"
94
+ - Gemfile
95
+ - README.md
96
+ - bin/deisConfig
97
+ - bin/deisDeploy
98
+ - deis_deploy.gemspec
99
+ - lib/deis_deploy.rb
100
+ - lib/deis_deploy/config.rb
101
+ - lib/deis_deploy/deploy.rb
102
+ - lib/deis_deploy/file_locations.rb
103
+ - lib/deis_deploy/git.rb
104
+ - lib/deis_deploy/strings.rb
105
+ - lib/deis_deploy/validations.rb
106
+ - lib/deis_deploy/version.rb
107
+ - lib/ssh.rb
108
+ - lib/utils.rb
109
+ homepage: ''
110
+ licenses:
111
+ - MIT
112
+ metadata: {}
113
+ post_install_message: ''
114
+ rdoc_options: []
115
+ require_paths:
116
+ - lib
117
+ required_ruby_version: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ version: '2.0'
122
+ required_rubygems_version: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ requirements: []
128
+ rubyforge_project:
129
+ rubygems_version: 2.2.2
130
+ signing_key:
131
+ specification_version: 4
132
+ summary: ''
133
+ test_files: []