meroku 0.0.0 → 0.1.28
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/exe/meroku +5 -0
- data/lib/meroku/app/collaborator.rb +18 -0
- data/lib/meroku/app.rb +12 -0
- data/lib/meroku/application_record.rb +8 -0
- data/lib/meroku/apps_controller.rb +112 -0
- data/lib/meroku/cli/certs.rb +30 -0
- data/lib/meroku/cli/certs.rb~ +14 -0
- data/lib/meroku/cli/cli.rb +97 -0
- data/lib/meroku/cli/config.rb +111 -0
- data/lib/meroku/cli/domains.rb +69 -0
- data/lib/meroku/cli/keys.rb +38 -0
- data/lib/meroku/cli/remote.rb +13 -0
- data/lib/meroku/cli/remote.rb~ +12 -0
- data/lib/meroku/cli/server.rb +159 -0
- data/lib/meroku/cli/server.rb~ +4 -0
- data/lib/meroku/cli.rb +8 -0
- data/lib/meroku/config.rb +6 -0
- data/lib/meroku/configs_controller.rb +62 -0
- data/lib/meroku/core_ext.rb +30 -0
- data/lib/meroku/domain.rb +6 -0
- data/lib/meroku/domains_controller.rb +83 -0
- data/lib/meroku/error.rb +6 -0
- data/lib/meroku/key.rb +11 -0
- data/lib/meroku/keys_controller.rb +82 -0
- data/lib/meroku/sanitychecks.rb +19 -0
- data/lib/meroku/user.rb +23 -0
- data/lib/meroku/util.rb +416 -0
- data/lib/meroku/version.rb +3 -0
- data/lib/meroku.rb +20 -4
- metadata +170 -46
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 49c5433cbce12e5cfa8b9e3cac3b41d2e8af0f9f
|
4
|
+
data.tar.gz: 49d6a9a8b5fc2a57349d33fff57e5153fdc9f2ba
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d0f969eb23f7da5db69bba1cbc398341eb0f4522a31b0ec82dee32d38e25ef7b88c105066b41b12d5397fad8dc0496e3fde68da23fe102c994d88f5971341068
|
7
|
+
data.tar.gz: da17716cb9ffa9d8b7cb8fc6172d9498469a5049ae99fa0f68d8f7a8bdd5fbf946ae7ff6088204df51c1143c7b18f207867655d5a94fb46c80a50c57902fc23f
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "meroku"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/exe/meroku
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
class Meroku::App::Collaborator < Meroku::ApplicationRecord
|
2
|
+
include Meroku::Util
|
3
|
+
self.table_name = "meroku_app_collaborators"
|
4
|
+
|
5
|
+
validates :user_id, presence: true, allow_nil: false
|
6
|
+
validates :app_id, presence: true, allow_nil: false
|
7
|
+
validates_uniqueness_of :user_id, :scope => "app_id"
|
8
|
+
|
9
|
+
after_create :setup_repo
|
10
|
+
after_create :add_mysql_user
|
11
|
+
after_create :create_empty_mysql_db
|
12
|
+
after_create :add_mysql_grants
|
13
|
+
after_create :add_pg_user
|
14
|
+
after_create :create_empty_pg_db
|
15
|
+
after_create :add_pg_grants
|
16
|
+
end
|
17
|
+
|
18
|
+
|
data/lib/meroku/app.rb
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
module Meroku
|
2
|
+
|
3
|
+
class AppsController < ApplicationController
|
4
|
+
#before_action :set_app, only: [:show, :edit, :update, :destroy]
|
5
|
+
skip_before_action :verify_authenticity_token, only: [:create, :update, :additional_env_vars]
|
6
|
+
before_action :authenticate, only: [:create, :update, :additional_env_vars]
|
7
|
+
|
8
|
+
## GET /apps
|
9
|
+
## GET /apps.json
|
10
|
+
#def index
|
11
|
+
# @apps = App.all
|
12
|
+
#end
|
13
|
+
#
|
14
|
+
## GET /apps/1
|
15
|
+
## GET /apps/1.json
|
16
|
+
#def show
|
17
|
+
#end
|
18
|
+
#
|
19
|
+
## GET /apps/new
|
20
|
+
#def new
|
21
|
+
# @app = App.new
|
22
|
+
#end
|
23
|
+
#
|
24
|
+
## GET /apps/1/edit
|
25
|
+
#def edit
|
26
|
+
#end
|
27
|
+
#
|
28
|
+
# POST /apps
|
29
|
+
# POST /apps.json
|
30
|
+
def create
|
31
|
+
@app = Meroku::App.new(app_params)
|
32
|
+
app_saved = @app.save
|
33
|
+
collaborator_saved = nil
|
34
|
+
if app_saved
|
35
|
+
@collaborator = Meroku::App::Collaborator.new(
|
36
|
+
app_id: @app.id,
|
37
|
+
user_id: @user.id
|
38
|
+
)
|
39
|
+
collaborator_saved = @collaborator.save
|
40
|
+
Meroku::Util.nginx_rebuild()
|
41
|
+
end
|
42
|
+
|
43
|
+
respond_to do |format|
|
44
|
+
if app_saved && collaborator_saved
|
45
|
+
format.json { render json: @app }
|
46
|
+
else
|
47
|
+
format.json {
|
48
|
+
if @app.errors
|
49
|
+
render json: { :errors => @app.errors }, :status => :unprocessable_entity
|
50
|
+
elsif @collaborator.errors
|
51
|
+
render json: { :errors => @collaborator.errors }, :status => :unprocessable_entity
|
52
|
+
end
|
53
|
+
}
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
#
|
58
|
+
# PATCH/PUT /apps/1
|
59
|
+
# PATCH/PUT /apps/1.json
|
60
|
+
def update
|
61
|
+
respond_to do |format|
|
62
|
+
if @app_.update(app_params)
|
63
|
+
format.json {
|
64
|
+
Meroku::Util.nginx_rebuild()
|
65
|
+
render json: @app_
|
66
|
+
}
|
67
|
+
else
|
68
|
+
format.json { render json: @app_.errors, status: :unprocessable_entity }
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
#
|
73
|
+
## DELETE /apps/1
|
74
|
+
## DELETE /apps/1.json
|
75
|
+
#def destroy
|
76
|
+
# @app.destroy
|
77
|
+
# respond_to do |format|
|
78
|
+
# format.html { redirect_to apps_url, notice: 'App was successfully destroyed.' }
|
79
|
+
# format.json { head :no_content }
|
80
|
+
# end
|
81
|
+
#end
|
82
|
+
|
83
|
+
|
84
|
+
# POST /?
|
85
|
+
def additional_env_vars
|
86
|
+
if params[:dbtype] == "mysql"
|
87
|
+
database_url = %Q[export DATABASE_URL=mysql2://u#{@user.id}:#{@user.database_password}@localhost/#{@app_.name}?socket=/opt/bitnami/mysql/tmp/mysql.sock]
|
88
|
+
else
|
89
|
+
database_url = %Q[export DATABASE_URL=postgres://u#{@user.id}:#{@user.database_password}@localhost/#{@app_.name}]
|
90
|
+
end
|
91
|
+
|
92
|
+
respond_to do |format|
|
93
|
+
Rails.logger.debug "DB8 #{"export RAILS_ENV=production export PORT=#{3000+@app_.id} #{database_url}"}"
|
94
|
+
format.json { render json: { :data => "export RAILS_ENV=production export PORT=#{3000+@app_.id} #{database_url} "} }
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
private
|
99
|
+
# Use callbacks to share common setup or constraints between actions.
|
100
|
+
#def set_app
|
101
|
+
# @app = App.find(params[:id])
|
102
|
+
#end
|
103
|
+
|
104
|
+
# Never trust parameters from the scary internet, only allow the white list through.
|
105
|
+
def app_params
|
106
|
+
params.fetch(:app, {}).permit(:name, :server_crt, :server_key)
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Meroku
|
2
|
+
module CLI
|
3
|
+
require 'action_view'
|
4
|
+
include ActionView::Helpers::TextHelper
|
5
|
+
|
6
|
+
class Certs < Thor
|
7
|
+
include Meroku::Util
|
8
|
+
|
9
|
+
desc "add server.crt server.key", "Upload domain certificate and key"
|
10
|
+
def add(cert, key)
|
11
|
+
require 'rest-client'
|
12
|
+
require 'active_support/all'
|
13
|
+
require 'rack'
|
14
|
+
require 'action_view'
|
15
|
+
server_crt = IO.read(cert)
|
16
|
+
server_key = IO.read(key)
|
17
|
+
resp = RestClient.put 'https://www.meroku.com/meroku/apps/0.json', { app: { server_crt: server_crt, server_key: server_key }, authentication: { token: cli_token, app_name: app_name } }
|
18
|
+
puts "Added. (#{resp.code} #{Rack::Utils::HTTP_STATUS_CODES[resp.code]})"
|
19
|
+
rescue RestClient::Exception => e
|
20
|
+
abort e.to_s if e.response.code != 200
|
21
|
+
out_str = "ERROR"
|
22
|
+
if valid_json?(e.response) && JSON.parse(e.response)["errors"].size >= 1
|
23
|
+
out_str += " "
|
24
|
+
out_str += JSON.parse(e.response)["errors"].map { |e| e.join(' ') }.to_sentence
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Meroku
|
2
|
+
module CLI
|
3
|
+
require 'action_view'
|
4
|
+
include ActionView::Helpers::TextHelper
|
5
|
+
|
6
|
+
class Certs < Thor
|
7
|
+
include Meroku::Util
|
8
|
+
|
9
|
+
desc "add 'DOMAIN'", "Remove DOMAIN"
|
10
|
+
def remove(domain)
|
11
|
+
require 'rest-client'
|
12
|
+
require 'active_support/all'
|
13
|
+
require 'rack'
|
14
|
+
require 'action_view'
|
@@ -0,0 +1,97 @@
|
|
1
|
+
module Meroku
|
2
|
+
module CLI
|
3
|
+
require 'action_view'
|
4
|
+
include ActionView::Helpers::TextHelper
|
5
|
+
|
6
|
+
class Cli < Thor
|
7
|
+
include Meroku::Util
|
8
|
+
register(Meroku::CLI::Server, 'server', 'server <command>', 'Administer infrastructure')
|
9
|
+
register(Remote, 'remote', 'remote <command>', '')
|
10
|
+
register(Keys, 'keys', 'keys <command>', '')
|
11
|
+
register(Domains,'domains','domains <command>', '')
|
12
|
+
register(Certs ,'certs','certs <command>', '')
|
13
|
+
register(Config ,'config','config <command>', '')
|
14
|
+
|
15
|
+
desc "_run 'COMMAND'", "Run a command on the server"
|
16
|
+
def _run(command)
|
17
|
+
user_id = `cat /tmp/meroku.id`.chomp
|
18
|
+
server = "u#{user_id}@www.meroku.com"
|
19
|
+
name = app_name
|
20
|
+
if IO.read("Gemfile") =~ /^[^\#]*gem ["']mysql/
|
21
|
+
dbtype="mysql"
|
22
|
+
else
|
23
|
+
dbtype="postgres"
|
24
|
+
end
|
25
|
+
|
26
|
+
_additional_env_vars = additional_env_vars(name,dbtype)
|
27
|
+
if command == "bash"
|
28
|
+
exec "ssh -t -o StrictHostKeyChecking=no #{server} '#{_additional_env_vars} ;echo INFO: Type exit quit this remote shell; cd #{name}; bash --login'"
|
29
|
+
end
|
30
|
+
abort "ERROR: Unexpected output for \"git remote -v\"" if name.blank?
|
31
|
+
require 'open3'
|
32
|
+
stdout, stderr, exit_status = Open3.capture3(%Q[ssh -o 'StrictHostKeyChecking=no' #{server} 'export PATH=$PATH:/opt/bitnami/nodejs/bin; source ~/.rvm/scripts/rvm; cd #{name}; #{_additional_env_vars} ; #{command}'])
|
33
|
+
puts stdout if !stdout.empty?
|
34
|
+
puts stderr if !stderr.empty?
|
35
|
+
puts "meroku run finished with exit code #{exit_status.exitstatus}" if exit_status.exitstatus != 0
|
36
|
+
end
|
37
|
+
|
38
|
+
desc "create NAME", "Create an app named NAME on meroku"
|
39
|
+
def create(name)
|
40
|
+
require 'rest-client'
|
41
|
+
require 'rack'
|
42
|
+
|
43
|
+
return if !cli_logged_in?
|
44
|
+
resp = RestClient.post 'https://www.meroku.com/meroku/apps.json', { :"app[name]" => name, authentication: { app: name, token: cli_token} }
|
45
|
+
puts "Created #{JSON.parse(resp)["name"]}! (#{resp.code} #{Rack::Utils::HTTP_STATUS_CODES[resp.code]})"
|
46
|
+
`git remote remove meroku 2>&1 >/dev/null`
|
47
|
+
`git remote add meroku u#{cli_user_id}@www.meroku.com:#{name}.git 2>&1 >/dev/null`
|
48
|
+
puts "Added git remote meroku ( u#{cli_user_id}@www.meroku.com:#{name}.git )"
|
49
|
+
rescue RestClient::Exception => e
|
50
|
+
abort e.to_s if e == RestClient::ServerBrokeConnection
|
51
|
+
out_str = "ERROR"
|
52
|
+
if valid_json?(e.response) && JSON.parse(e.response)["errors"].size >= 1
|
53
|
+
out_str += " "
|
54
|
+
out_str += JSON.parse(e.response)["errors"].map { |e| e.join(' ') }.to_sentence
|
55
|
+
end
|
56
|
+
out_str += " (#{e.to_s}) "
|
57
|
+
puts out_str
|
58
|
+
end
|
59
|
+
|
60
|
+
option :email, :required => true
|
61
|
+
option :password, :required => true
|
62
|
+
desc "login", "Login to meroku"
|
63
|
+
def login()
|
64
|
+
require 'rest-client'
|
65
|
+
require 'rack'
|
66
|
+
resp = RestClient.post 'https://www.meroku.com/users/sign_in.json', {:"user[email]" => options[:email], :"user[password]" => options[:password] }
|
67
|
+
puts "Logged in! (#{resp.code} #{Rack::Utils::HTTP_STATUS_CODES[resp.code]})"
|
68
|
+
IO.write("/tmp/meroku.token", JSON.parse(resp)["encrypted_password"])
|
69
|
+
IO.write("/tmp/meroku.id", JSON.parse(resp)["id"])
|
70
|
+
rescue RestClient::Exception => e
|
71
|
+
abort e.to_s if e.response.code == 500 || e.response.code == 404
|
72
|
+
out_str = "ERROR"
|
73
|
+
if JSON.parse(e.response)["errors"].is_a? Array
|
74
|
+
out_str += " "
|
75
|
+
out_str += JSON.parse(e.response)["errors"].map { |e| e.join(' ') }.to_sentence
|
76
|
+
end
|
77
|
+
out_str += " (#{e.to_s}) "
|
78
|
+
puts out_str
|
79
|
+
end
|
80
|
+
|
81
|
+
option :email, :required => true
|
82
|
+
option :password, :required => true
|
83
|
+
desc "signup", "Sign up for a free meroku account"
|
84
|
+
def signup()
|
85
|
+
require 'rest-client'
|
86
|
+
require 'rack'
|
87
|
+
resp = RestClient.post 'https://www.meroku.com/users.json', {:"user[email]" => options[:email], :"user[password]" => options[:password], :"user[password_confirmation]" => options[:password] }
|
88
|
+
puts "Signed up #{JSON.parse(resp)["email"]}! (#{resp.code} #{Rack::Utils::HTTP_STATUS_CODES[resp.code]})"
|
89
|
+
rescue RestClient::Exception => e
|
90
|
+
abort e.to_s if e.response.code == 500 || e.response.code == 404
|
91
|
+
puts "ERROR " +
|
92
|
+
JSON.parse(e.response)["errors"].map { |e| e.join(' ') }.to_sentence +
|
93
|
+
" (#{e.to_s})"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
module Meroku
|
2
|
+
module CLI
|
3
|
+
require 'action_view'
|
4
|
+
include ActionView::Helpers::TextHelper
|
5
|
+
|
6
|
+
class Config < Thor
|
7
|
+
include Meroku::Util
|
8
|
+
|
9
|
+
desc "list", "List environment variables"
|
10
|
+
def list
|
11
|
+
require 'rest-client'
|
12
|
+
#require 'active_support/all'
|
13
|
+
require 'rack'
|
14
|
+
require 'action_view'
|
15
|
+
resp = RestClient.get "https://www.meroku.com/meroku/configs.json?authentication_token=#{cli_token}&authentication_app_name=#{app_name}"
|
16
|
+
puts "#{JSON.parse(resp)["data"]}. (#{resp.code} #{Rack::Utils::HTTP_STATUS_CODES[resp.code]})"
|
17
|
+
rescue RestClient::Exception => e
|
18
|
+
out_str = "ERROR"
|
19
|
+
if valid_json?(e.response) && JSON.parse(e.response)["errors"].size >= 1
|
20
|
+
out_str += " "
|
21
|
+
out_str += JSON.parse(e.response)["errors"].map { |e| e.join(' ') }.to_sentence
|
22
|
+
end
|
23
|
+
out_str += " (#{e.to_s}) "
|
24
|
+
puts out_str
|
25
|
+
end
|
26
|
+
|
27
|
+
#desc "remove 'DOMAIN'", "Remove DOMAIN"
|
28
|
+
#def remove(domain)
|
29
|
+
# require 'rest-client'
|
30
|
+
# require 'active_support/all'
|
31
|
+
# require 'rack'
|
32
|
+
# require 'action_view'
|
33
|
+
# resp = RestClient.delete "https://www.meroku.com/meroku/domains/0.json?domain=#{domain}&authentication_token=#{cli_token}&authentication_app_name=#{app_name}"
|
34
|
+
# puts "Removed #{truncate(JSON.parse(resp)["data"]["domain"])}. (#{resp.code} #{Rack::Utils::HTTP_STATUS_CODES[resp.code]})"
|
35
|
+
#rescue RestClient::Exception => e
|
36
|
+
# abort e.to_s if e.response.code != 200
|
37
|
+
# out_str = "ERROR"
|
38
|
+
# if valid_json?(e.response) && JSON.parse(e.response)["errors"].size >= 1
|
39
|
+
# out_str += " "
|
40
|
+
# out_str += JSON.parse(e.response)["errors"].map { |e| e.join(' ') }.to_sentence
|
41
|
+
# end
|
42
|
+
# out_str += " (#{e.to_s}) "
|
43
|
+
# puts out_str
|
44
|
+
#end
|
45
|
+
#
|
46
|
+
#desc "list", "List domains associated with your app"
|
47
|
+
#def list
|
48
|
+
# require 'rest-client'
|
49
|
+
# require 'active_support/all'
|
50
|
+
# require 'rack'
|
51
|
+
# require 'action_view'
|
52
|
+
# resp = RestClient.get "https://www.meroku.com/meroku/domains.json?authentication_token=#{cli_token}&authentication_app_name=#{app_name}"
|
53
|
+
# puts "#{JSON.parse(resp)["data"]}. (#{resp.code} #{Rack::Utils::HTTP_STATUS_CODES[resp.code]})"
|
54
|
+
#rescue RestClient::Exception => e
|
55
|
+
# out_str = "ERROR"
|
56
|
+
# if valid_json?(e.response) && JSON.parse(e.response)["errors"].size >= 1
|
57
|
+
# out_str += " "
|
58
|
+
# out_str += JSON.parse(e.response)["errors"].map { |e| e.join(' ') }.to_sentence
|
59
|
+
# end
|
60
|
+
# out_str += " (#{e.to_s}) "
|
61
|
+
# puts out_str
|
62
|
+
#end
|
63
|
+
|
64
|
+
|
65
|
+
|
66
|
+
|
67
|
+
desc "unset FOO", "Set environment variable FOO"
|
68
|
+
def unset(name)
|
69
|
+
require 'rest-client'
|
70
|
+
require 'rack'
|
71
|
+
require 'action_view'
|
72
|
+
resp = RestClient.delete "https://www.meroku.com/meroku/configs/0.json?name=#{name}&authentication_token=#{cli_token}&authentication_app_name=#{app_name}"
|
73
|
+
puts "Removed #{truncate(JSON.parse(resp)["data"]["name"])}. (#{resp.code} #{Rack::Utils::HTTP_STATUS_CODES[resp.code]})"
|
74
|
+
rescue RestClient::Exception => e
|
75
|
+
abort e.to_s if e == RestClient::ServerBrokeConnection
|
76
|
+
out_str = "ERROR"
|
77
|
+
puts e.to_s
|
78
|
+
if valid_json?(e.response) && JSON.parse(e.response)["errors"].size >= 1
|
79
|
+
out_str += " "
|
80
|
+
out_str += JSON.parse(e.response)["errors"].map { |e| e.join(' ') }.to_sentence
|
81
|
+
end
|
82
|
+
out_str += " (#{e.to_s}) "
|
83
|
+
puts out_str
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
|
88
|
+
|
89
|
+
desc "set FOO baa", "Set environment variable FOO to baa"
|
90
|
+
def set(name, value)
|
91
|
+
require 'rest-client'
|
92
|
+
#require 'active_support/all'
|
93
|
+
require 'rack'
|
94
|
+
require 'action_view'
|
95
|
+
|
96
|
+
resp = RestClient.post 'https://www.meroku.com/meroku/configs.json', { name: name, value: value, authentication: { token: cli_token, app_name: app_name } }
|
97
|
+
puts "Added/Updated #{truncate(JSON.parse(resp)["data"]["name"])}. (#{resp.code} #{Rack::Utils::HTTP_STATUS_CODES[resp.code]})"
|
98
|
+
rescue RestClient::Exception => e
|
99
|
+
abort e.to_s if e == RestClient::ServerBrokeConnection
|
100
|
+
out_str = "ERROR"
|
101
|
+
puts e.to_s
|
102
|
+
if valid_json?(e.response) && JSON.parse(e.response)["errors"].size >= 1
|
103
|
+
out_str += " "
|
104
|
+
out_str += JSON.parse(e.response)["errors"].map { |e| e.join(' ') }.to_sentence
|
105
|
+
end
|
106
|
+
out_str += " (#{e.to_s}) "
|
107
|
+
puts out_str
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module Meroku
|
2
|
+
module CLI
|
3
|
+
require 'action_view'
|
4
|
+
include ActionView::Helpers::TextHelper
|
5
|
+
|
6
|
+
class Domains < Thor
|
7
|
+
include Meroku::Util
|
8
|
+
|
9
|
+
desc "remove 'DOMAIN'", "Remove DOMAIN"
|
10
|
+
def remove(domain)
|
11
|
+
require 'rest-client'
|
12
|
+
require 'active_support/all'
|
13
|
+
require 'rack'
|
14
|
+
require 'action_view'
|
15
|
+
resp = RestClient.delete "https://www.meroku.com/meroku/domains/0.json?domain=#{domain}&authentication_token=#{cli_token}&authentication_app_name=#{app_name}"
|
16
|
+
puts "Removed #{truncate(JSON.parse(resp)["data"]["domain"])}. (#{resp.code} #{Rack::Utils::HTTP_STATUS_CODES[resp.code]})"
|
17
|
+
rescue RestClient::Exception => e
|
18
|
+
abort e.to_s if e.response.code != 200
|
19
|
+
out_str = "ERROR"
|
20
|
+
if valid_json?(e.response) && JSON.parse(e.response)["errors"].size >= 1
|
21
|
+
out_str += " "
|
22
|
+
out_str += JSON.parse(e.response)["errors"].map { |e| e.join(' ') }.to_sentence
|
23
|
+
end
|
24
|
+
out_str += " (#{e.to_s}) "
|
25
|
+
puts out_str
|
26
|
+
end
|
27
|
+
|
28
|
+
desc "list", "List domains associated with your app"
|
29
|
+
def list
|
30
|
+
require 'rest-client'
|
31
|
+
require 'active_support/all'
|
32
|
+
require 'rack'
|
33
|
+
require 'action_view'
|
34
|
+
resp = RestClient.get "https://www.meroku.com/meroku/domains.json?authentication_token=#{cli_token}&authentication_app_name=#{app_name}"
|
35
|
+
puts "#{JSON.parse(resp)["data"]}. (#{resp.code} #{Rack::Utils::HTTP_STATUS_CODES[resp.code]})"
|
36
|
+
rescue RestClient::Exception => e
|
37
|
+
out_str = "ERROR"
|
38
|
+
if valid_json?(e.response) && JSON.parse(e.response)["errors"].size >= 1
|
39
|
+
out_str += " "
|
40
|
+
out_str += JSON.parse(e.response)["errors"].map { |e| e.join(' ') }.to_sentence
|
41
|
+
end
|
42
|
+
out_str += " (#{e.to_s}) "
|
43
|
+
puts out_str
|
44
|
+
end
|
45
|
+
|
46
|
+
desc "add 'DOMAIN'", "Associate DOMAIN with your app"
|
47
|
+
def add(domain)
|
48
|
+
require 'rest-client'
|
49
|
+
require 'active_support/all'
|
50
|
+
require 'rack'
|
51
|
+
require 'action_view'
|
52
|
+
|
53
|
+
resp = RestClient.post 'https://www.meroku.com/meroku/domains.json', { domain: domain, authentication: { token: cli_token, app_name: app_name } }
|
54
|
+
puts "Added #{truncate(JSON.parse(resp)["data"]["domain"])}. (#{resp.code} #{Rack::Utils::HTTP_STATUS_CODES[resp.code]})"
|
55
|
+
rescue RestClient::ServerBrokeConnection
|
56
|
+
raise
|
57
|
+
rescue RestClient::Exception => e
|
58
|
+
abort e.to_s if e == RestClient::ServerBrokeConnection
|
59
|
+
out_str = "ERROR"
|
60
|
+
if valid_json?(e.response) && JSON.parse(e.response)["errors"].size >= 1
|
61
|
+
out_str += " "
|
62
|
+
out_str += JSON.parse(e.response)["errors"].map { |e| e.join(' ') }.to_sentence
|
63
|
+
end
|
64
|
+
out_str += " (#{e.to_s}) "
|
65
|
+
puts out_str
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Meroku
|
2
|
+
module CLI
|
3
|
+
|
4
|
+
require 'action_view'
|
5
|
+
include ActionView::Helpers::TextHelper
|
6
|
+
class Keys < Thor
|
7
|
+
include Meroku::Util
|
8
|
+
include ActionView::Helpers::TextHelper
|
9
|
+
|
10
|
+
desc "add", "Upload your public key (~/.ssh/id_rsa.pub) to meroku"
|
11
|
+
def add
|
12
|
+
require 'rest-client'
|
13
|
+
require 'rack'
|
14
|
+
require 'action_view'
|
15
|
+
|
16
|
+
if !public_key_exists?
|
17
|
+
puts "Public key not found at ~/.ssh/id_rsa.pub"
|
18
|
+
puts "see https://git-scm.com/book/en/v2/Git-on-the-Server-Generating-Your-SSH-Public-Key"
|
19
|
+
return
|
20
|
+
end
|
21
|
+
key = IO.read("#{Dir.home}/.ssh/id_rsa.pub")
|
22
|
+
resp = RestClient.post 'https://www.meroku.com/meroku/keys.json', { key: key, authentication: { token: cli_token } }
|
23
|
+
puts "Added #{truncate(JSON.parse(resp)["data"]["key"])}. (#{resp.code} #{Rack::Utils::HTTP_STATUS_CODES[resp.code]})"
|
24
|
+
rescue RestClient::Exception => e
|
25
|
+
out_str = "ERROR"
|
26
|
+
|
27
|
+
if valid_json?(e.response) && JSON.parse(e.response)["errors"].size >= 1
|
28
|
+
out_str += " "
|
29
|
+
out_str += JSON.parse(e.response)["errors"].map { |e| e.join(' ') }.to_sentence
|
30
|
+
end
|
31
|
+
out_str += " (#{e.to_s}) "
|
32
|
+
puts out_str
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'action_view'
|
2
|
+
include ActionView::Helpers::TextHelper
|
3
|
+
|
4
|
+
class Remote < Thor
|
5
|
+
include ::Meroku::Util
|
6
|
+
|
7
|
+
desc "add APPNAME", "adds a git remote for app named APPNAME"
|
8
|
+
def add(name)
|
9
|
+
`git remote remove meroku 2>&1 >/dev/null`
|
10
|
+
`git remote add meroku u#{cli_user_id}@www.meroku.com:#{name}.git 2>&1 >/dev/null`
|
11
|
+
puts "Added git remote meroku ( u#{cli_user_id}@www.meroku.com:#{name}.git )"
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
class Remote < Thor
|
4
|
+
include ::Meroku::Util
|
5
|
+
|
6
|
+
desc "add APPNAME", "adds a git remote for app named APPNAME"
|
7
|
+
def add(name)
|
8
|
+
`git remote remove meroku 2>&1 >/dev/null`
|
9
|
+
`git remote add meroku u#{cli_user_id}@www.meroku.com:#{name}.git 2>&1 >/dev/null`
|
10
|
+
puts "Added git remote meroku ( u#{cli_user_id}@www.meroku.com:#{name}.git )"
|
11
|
+
end
|
12
|
+
end
|