gleis 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +674 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/exe/gleis +7 -0
- data/lib/gleis/addon.rb +41 -0
- data/lib/gleis/api.rb +45 -0
- data/lib/gleis/application.rb +198 -0
- data/lib/gleis/authentication.rb +47 -0
- data/lib/gleis/cli/addon.rb +23 -0
- data/lib/gleis/cli/app.rb +73 -0
- data/lib/gleis/cli/auth.rb +21 -0
- data/lib/gleis/cli/db.rb +48 -0
- data/lib/gleis/cli/domain.rb +23 -0
- data/lib/gleis/cli/management.rb +16 -0
- data/lib/gleis/cli/sharing.rb +23 -0
- data/lib/gleis/cli/storage.rb +28 -0
- data/lib/gleis/config.rb +21 -0
- data/lib/gleis/database.rb +126 -0
- data/lib/gleis/domain.rb +39 -0
- data/lib/gleis/main.rb +36 -0
- data/lib/gleis/management.rb +42 -0
- data/lib/gleis/params.rb +9 -0
- data/lib/gleis/sharing.rb +38 -0
- data/lib/gleis/ssh.rb +36 -0
- data/lib/gleis/storage.rb +69 -0
- data/lib/gleis/token.rb +21 -0
- data/lib/gleis/utils.rb +105 -0
- data/lib/gleis/version.rb +3 -0
- data/lib/gleis.rb +29 -0
- metadata +188 -0
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'gleis'
|
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/gleis
ADDED
data/lib/gleis/addon.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
module Gleis
|
2
|
+
# The class implements the methods required to manage the add-ons of a gleis app
|
3
|
+
class Addon
|
4
|
+
def self.add(app_name, name)
|
5
|
+
token = Token.check
|
6
|
+
body = API.request('post', 'addons', token, 'name': app_name, 'addon': name)
|
7
|
+
if body['success'] == 1
|
8
|
+
puts "Successfully added #{name} add-on to #{app_name}."
|
9
|
+
else
|
10
|
+
puts "Failed to add add-on: #{body['message']}"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.list(app_name)
|
15
|
+
token = Token.check
|
16
|
+
body = API.request('get', "addons/#{app_name}", token)
|
17
|
+
addons = body ['data']
|
18
|
+
if addons.any?
|
19
|
+
puts "List of available add-ons:\n\n"
|
20
|
+
printf("\t%-30s %-15s %s\n", 'ADD-ON NAME', 'VERSION', 'CATEGORY')
|
21
|
+
printf("\t%s\n\n", 'DESCRIPTION')
|
22
|
+
addons.each do |addon|
|
23
|
+
printf("\t%-30s %-15s %s\n", addon['name'], addon['version'], addon['category'])
|
24
|
+
puts "\t#{addon['description']}\n"
|
25
|
+
end
|
26
|
+
else
|
27
|
+
puts 'No add-ons avaialble.'
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.remove(app_name, name)
|
32
|
+
token = Token.check
|
33
|
+
body = API.request('delete', "addons/#{app_name}/#{name}", token)
|
34
|
+
if body['success'] == 1
|
35
|
+
puts "Successfully removed #{name} add-on from #{app_name}."
|
36
|
+
else
|
37
|
+
puts "Failed to remove add-on: #{body['message']}"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/gleis/api.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'rest-client'
|
2
|
+
|
3
|
+
module Gleis
|
4
|
+
# This class uses REST over HTTPS to communicate with the API server
|
5
|
+
class API
|
6
|
+
def self.request(method, action, token = nil, body = {})
|
7
|
+
url = Config::API_URL + Config::API_VERSION + '/cli/' + action
|
8
|
+
# Support legacy rest-client (<2.0) which does not have RestClient::NotFound
|
9
|
+
notfound_exception = defined?(RestClient::ResourceNotFound) ? RestClient::ResourceNotFound : RestClient::NotFound
|
10
|
+
begin
|
11
|
+
case method
|
12
|
+
when 'get', 'delete'
|
13
|
+
resp = RestClient.send(method, url, 'X-Gleis-Token': token, content_type: :json, accept: :json)
|
14
|
+
when 'post', 'put'
|
15
|
+
if token
|
16
|
+
resp =
|
17
|
+
RestClient.send(method, url, body.to_json, 'X-Gleis-Token': token, content_type: :json, accept: :json)
|
18
|
+
else
|
19
|
+
resp = RestClient.send(method, url, body.to_json, content_type: :json, accept: :json)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
rescue RestClient::BadRequest
|
23
|
+
abort('Authentication failed.')
|
24
|
+
rescue RestClient::Unauthorized
|
25
|
+
abort('Not authenticated, please login first.')
|
26
|
+
rescue RestClient::Forbidden
|
27
|
+
abort('You do not have the required permissions, please contact the app owner.')
|
28
|
+
rescue notfound_exception
|
29
|
+
abort('Application not found.')
|
30
|
+
rescue RestClient::InternalServerError
|
31
|
+
abort('An error occured on the platform. Please contact support if this problem persists.')
|
32
|
+
rescue StandardError # (e.g. SocketError, Errno::ECONNREFUSED, RestClient::BadGateway, ...)
|
33
|
+
abort('There was an issue connecting to the Gleis API server.')
|
34
|
+
else
|
35
|
+
if resp.body.empty?
|
36
|
+
# If there is no body return whole response object
|
37
|
+
resp
|
38
|
+
else
|
39
|
+
# Return Ruby data structure of the JSON parsed body
|
40
|
+
JSON.parse(resp.body)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,198 @@
|
|
1
|
+
module Gleis
|
2
|
+
# The class implements the methods required to manage gleis applications
|
3
|
+
class Application
|
4
|
+
def self.config(app_name, env_var)
|
5
|
+
token = Token.check
|
6
|
+
if env_var.end_with? '='
|
7
|
+
# Delete variable
|
8
|
+
var_name = env_var.split('=')[0]
|
9
|
+
response = API.request('delete', "config/#{app_name}/#{var_name}", token)
|
10
|
+
puts "Deleted environment variable #{var_name}" if response.code == 204
|
11
|
+
elsif env_var.include? '='
|
12
|
+
# Update or create variable
|
13
|
+
var_value = env_var.split('=')
|
14
|
+
response = API.request('post', 'config', token, 'name': app_name, 'var': var_value[0], 'value': var_value[1])
|
15
|
+
puts "Sucessfully created environment variable #{var_value[0]}" if response.code == 201
|
16
|
+
puts "Sucessfully updated environment variable #{var_value[0]}" if response.code == 200
|
17
|
+
else
|
18
|
+
config_body = Config.get_env_vars(app_name, token)
|
19
|
+
Utils.output_config_env_vars(config_body['env_vars'], app_name)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.create(app_name)
|
24
|
+
token = Token.check
|
25
|
+
print "Creating new app named #{app_name}, you should be ready to go in about 10 seconds ... "
|
26
|
+
body = API.request('post', 'create', token, 'name': app_name)
|
27
|
+
# Check status of project creation in Gitlab
|
28
|
+
if body['success'] == 1
|
29
|
+
puts "done!\n"
|
30
|
+
git_ssh_url_to_repo = body['ssh_url_to_repo']
|
31
|
+
# Add git remote if .git/config file is detected
|
32
|
+
if Utils.add_remote_to_git_config(git_ssh_url_to_repo) == false
|
33
|
+
puts "Now add the gleis git remote to your app using: git remote add gleis #{git_ssh_url_to_repo}"
|
34
|
+
else
|
35
|
+
puts 'Git remote gleis added to your git config'
|
36
|
+
end
|
37
|
+
puts 'When ready to deploy your app, push it to the gleis git remote with: git push gleis master'
|
38
|
+
puts "You can then access your app using the URL https://#{body['dns_name']}" if body.key? 'dns_name'
|
39
|
+
else
|
40
|
+
puts 'failed!'
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.deployments(app_name)
|
45
|
+
token = Token.check
|
46
|
+
action = 'deployment/' + app_name
|
47
|
+
body = API.request('get', action, token)
|
48
|
+
if body['deployments'].any?
|
49
|
+
body['deployments'].reverse_each do |d|
|
50
|
+
puts "v#{d['version']} | #{d['commit'][0, 7]} | #{d['email']} | #{d['subject']}\n" \
|
51
|
+
"deployed by #{d['name']} on #{Time.parse(d['created_at']).strftime('%c')}\n\n"
|
52
|
+
end
|
53
|
+
else
|
54
|
+
puts 'No deployments found, please deploy your app first.'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.destroy(app_name)
|
59
|
+
token = Token.check
|
60
|
+
if Utils.prompt_confirmation("Are you sure you want to destroy the #{app_name} app?")
|
61
|
+
# Delete everything related to project/app
|
62
|
+
body = API.request('post', 'delete', token, 'name': app_name)
|
63
|
+
if body['success'] == 1
|
64
|
+
puts 'App destroyed successfully'
|
65
|
+
else
|
66
|
+
puts 'Failed to destroy app: ' + body['message']
|
67
|
+
end
|
68
|
+
else
|
69
|
+
puts 'Command cancelled'
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.exec(app_name, command)
|
74
|
+
token = Token.check
|
75
|
+
config_body = Config.get_env_vars(app_name, token)
|
76
|
+
# Get storage and generate Docker mount parameter
|
77
|
+
mount_param = Utils.generate_docker_cmd_mount(API.request('get', "storage/#{app_name}", token), app_name)
|
78
|
+
# Get deployments and commit from last deployment
|
79
|
+
dp_body = API.request('get', "deployment/#{app_name}", token)
|
80
|
+
if dp_body['deployments'].any?
|
81
|
+
# Get CLI parameters from API server
|
82
|
+
p = Params.get_cli_parameters(token)
|
83
|
+
system("ssh -t -q -o 'StrictHostKeyChecking=no' \
|
84
|
+
-p #{p['run_port']} \
|
85
|
+
#{p['run_username']}@#{p['run_server']} \
|
86
|
+
'#{Utils.generate_docker_cmd_env_vars(config_body['env_vars'])} #{mount_param} \
|
87
|
+
#{p['registry_server']}/#{dp_body['namespace']}/#{app_name}:#{dp_body['deployments'].last['commit'][0..6]} \
|
88
|
+
#{command}'")
|
89
|
+
else
|
90
|
+
puts 'No deployments found, please deploy your app first.'
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def self.git(app_name)
|
95
|
+
token = Token.check
|
96
|
+
action = 'git/' + app_name
|
97
|
+
body = API.request('get', action, token)
|
98
|
+
if body['success'] == 1
|
99
|
+
puts "The URL to the git repo of the #{app_name} app is: #{body['data']}"
|
100
|
+
else
|
101
|
+
puts 'Failed to fetch git URL for app.'
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def self.logs(app_name)
|
106
|
+
token = Token.check
|
107
|
+
action = 'logs/' + app_name
|
108
|
+
body = API.request('get', action, token)
|
109
|
+
if body['log'].nil? || body['log'].empty?
|
110
|
+
puts 'No log entries found yet.'
|
111
|
+
else
|
112
|
+
puts "Last 100 lines of consolidated log output for #{app_name}:"
|
113
|
+
puts
|
114
|
+
puts body['log']
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def self.restart(app_name)
|
119
|
+
token = Token.check
|
120
|
+
body = API.request('post', 'restart', token, 'name': app_name)
|
121
|
+
if body['success'] == 1
|
122
|
+
puts 'Successfully restarted app using rolling update'
|
123
|
+
else
|
124
|
+
puts 'Failed to restart app: ' + body['error_text']
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def self.scale(app_name, replica)
|
129
|
+
token = Token.check
|
130
|
+
count = Utils.validate_scale_count(replica)
|
131
|
+
body = API.request('post', 'scale', token, 'name': app_name, 'count': count)
|
132
|
+
if body['success'] == 1
|
133
|
+
puts "Successfully scaled app to #{count} replica"
|
134
|
+
if body['message']
|
135
|
+
puts 'Note that your app is currently not running, hence scaling will take effect as soon as you start it'
|
136
|
+
end
|
137
|
+
else
|
138
|
+
puts "Failed to scale app: #{body['message']}"
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def self.start(app_name)
|
143
|
+
token = Token.check
|
144
|
+
body = API.request('post', 'start', token, 'name': app_name)
|
145
|
+
if body['success'] == 1
|
146
|
+
puts 'Successfully started app'
|
147
|
+
else
|
148
|
+
puts 'Failed to start app: ' + body['message']
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def self.ps(app_name)
|
153
|
+
token = Token.check
|
154
|
+
body = API.request('get', "ps/#{app_name}", token)
|
155
|
+
puts 'Failed to get processes.' unless body['success'] == 1
|
156
|
+
if body['data']&.size&.positive?
|
157
|
+
body['data'].each_with_index do |service, index|
|
158
|
+
puts "=== #{service[0]}: `#{service[1]['command']}`"
|
159
|
+
if service[1]['tasks'].empty?
|
160
|
+
puts 'No processes running'
|
161
|
+
else
|
162
|
+
Utils.output_tasks(service[1]['tasks'], service[1]['type'])
|
163
|
+
end
|
164
|
+
puts '' if index != body['data'].size - 1
|
165
|
+
end
|
166
|
+
else
|
167
|
+
puts 'No deployments found, please deploy your app first.'
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
def self.status(app_name)
|
172
|
+
token = Token.check
|
173
|
+
action = 'status/' + app_name
|
174
|
+
body = API.request('get', action, token)
|
175
|
+
puts "Status of app #{app_name}:\n\n"
|
176
|
+
if body['success'] == 1
|
177
|
+
status = body['status']
|
178
|
+
puts "\tStatus:\t\trunning\n" \
|
179
|
+
"\tStarted at:\t#{Time.parse(status['createdat']).localtime.strftime('%c')}\n" \
|
180
|
+
"\tUpdated at:\t#{Time.parse(status['updatedat']).localtime.strftime('%c')}\n" \
|
181
|
+
"\tUpdate count:\t#{status['forceupdate']}\n" \
|
182
|
+
"\tReplicas:\t#{status['replicas']}"
|
183
|
+
else
|
184
|
+
puts "\tStatus:\t\tnot running"
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
def self.stop(app_name)
|
189
|
+
token = Token.check
|
190
|
+
body = API.request('post', 'stop', token, 'name': app_name)
|
191
|
+
if body['success'] == 1
|
192
|
+
puts 'Succesfully stopped app'
|
193
|
+
else
|
194
|
+
puts 'Failed to stop app: ' + body['message']
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Gleis
|
2
|
+
# This class implements all authentication related commands of the CLI
|
3
|
+
class Authentication
|
4
|
+
def self.login(username)
|
5
|
+
puts 'Login to Gleis'
|
6
|
+
username = username.downcase
|
7
|
+
password = Utils.prompt_password
|
8
|
+
|
9
|
+
body = API.request('post', 'login', nil, 'username': username, 'password': password)
|
10
|
+
token = body['token']
|
11
|
+
|
12
|
+
Token.save(token)
|
13
|
+
puts 'Authentication successful'
|
14
|
+
puts "\nNEWS: #{body['data']}\n\n" unless body['data'].nil?
|
15
|
+
# Generate SSH key pair if not found and upload pub key
|
16
|
+
ssh_key_filename = Config::SSH_KEY_FILE_BASE + '_' + Utils.convert_username_to_filename(username)
|
17
|
+
upload_ssh_public_key(ssh_key_filename, token) if SSH.generate_key(ssh_key_filename, username)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.whoami
|
21
|
+
token = Token.check
|
22
|
+
body = API.request('get', 'whoami', token)
|
23
|
+
puts "You are currently logged in as #{body['data']}"
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.logout
|
27
|
+
token = Token.check
|
28
|
+
puts 'Logout of Gleis'
|
29
|
+
API.request('post', 'logout', token, {})
|
30
|
+
Token.delete
|
31
|
+
puts 'Logout successful'
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.upload_ssh_public_key(filename, token)
|
35
|
+
ssh_public_key = SSH.load_public_key(filename)
|
36
|
+
body = API.request('post', 'upload_ssh_pub_key', token, 'ssh_public_key' => ssh_public_key)
|
37
|
+
if body['success'] == 1
|
38
|
+
puts "Successfully uploaded your SSH public key #{filename}.pub"
|
39
|
+
# Get run server name
|
40
|
+
params = Params.get_cli_parameters(token)
|
41
|
+
SSH.add_host_to_config(body['git_server'], params['run_server'], filename)
|
42
|
+
else
|
43
|
+
puts "Failed to upload SSH public key: #{body['message']}"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Gleis
|
2
|
+
module CLI
|
3
|
+
# Add-ons-related CLI commands
|
4
|
+
class Addon < Thor
|
5
|
+
class_option :app, aliases: :a, type: :string, default: Utils.app_name
|
6
|
+
|
7
|
+
desc 'add ADDON', 'Add add-on to app'
|
8
|
+
def add(name)
|
9
|
+
Gleis::Addon.add(options[:app], name)
|
10
|
+
end
|
11
|
+
|
12
|
+
desc 'list', 'List available add-ons on Gleis and add-ons used by app'
|
13
|
+
def list
|
14
|
+
Gleis::Addon.list(options[:app])
|
15
|
+
end
|
16
|
+
|
17
|
+
desc 'remove ADDON', 'Add add-on to app'
|
18
|
+
def remove(name)
|
19
|
+
Gleis::Addon.remove(options[:app], name)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module Gleis
|
2
|
+
module CLI
|
3
|
+
# Application-related CLI commands
|
4
|
+
class App < Thor
|
5
|
+
class_option :app, aliases: :a, type: :string, default: Utils.app_name
|
6
|
+
|
7
|
+
desc 'config [VAR=value]', 'Show, set or delete environment variables'
|
8
|
+
def config(env_var = '')
|
9
|
+
Application.config(options[:app], env_var)
|
10
|
+
end
|
11
|
+
|
12
|
+
desc 'create', 'Create new application'
|
13
|
+
def create
|
14
|
+
Application.create(options[:app])
|
15
|
+
end
|
16
|
+
|
17
|
+
desc 'destroy', 'Destroy application'
|
18
|
+
def destroy
|
19
|
+
Application.destroy(options[:app])
|
20
|
+
end
|
21
|
+
|
22
|
+
desc 'deployments', 'List all deployments'
|
23
|
+
def deployments
|
24
|
+
Application.deployments(options[:app])
|
25
|
+
end
|
26
|
+
|
27
|
+
desc 'exec COMMAND', 'Execute a one-time-command (e.g. rails db:migrate)'
|
28
|
+
def exec(command)
|
29
|
+
Application.exec(options[:app], command)
|
30
|
+
end
|
31
|
+
|
32
|
+
desc 'git', 'Show URL of git repository'
|
33
|
+
def git
|
34
|
+
Application.git(options[:app])
|
35
|
+
end
|
36
|
+
|
37
|
+
desc 'logs', 'View last log entries'
|
38
|
+
def logs
|
39
|
+
Application.logs(options[:app])
|
40
|
+
end
|
41
|
+
|
42
|
+
desc 'ps', 'Show running processes'
|
43
|
+
def ps
|
44
|
+
Application.ps(options[:app])
|
45
|
+
end
|
46
|
+
|
47
|
+
desc 'restart', 'Restart application (rolling update)'
|
48
|
+
def restart
|
49
|
+
Application.restart(options[:app])
|
50
|
+
end
|
51
|
+
|
52
|
+
desc 'scale #REPLICA', 'Scale up or down (horizontal scaling)'
|
53
|
+
def scale(replica)
|
54
|
+
Application.scale(options[:app], replica)
|
55
|
+
end
|
56
|
+
|
57
|
+
desc 'start', 'Start application'
|
58
|
+
def start
|
59
|
+
Application.start(options[:app])
|
60
|
+
end
|
61
|
+
|
62
|
+
desc 'status', 'Status of application'
|
63
|
+
def status
|
64
|
+
Application.status(options[:app])
|
65
|
+
end
|
66
|
+
|
67
|
+
desc 'stop', 'Stop application'
|
68
|
+
def stop
|
69
|
+
Application.stop(options[:app])
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Gleis
|
2
|
+
module CLI
|
3
|
+
# Authentication-related CLI commands
|
4
|
+
class Auth < Thor
|
5
|
+
desc 'login USERNAME', 'Login into Gleis'
|
6
|
+
def login(username)
|
7
|
+
Authentication.login(username)
|
8
|
+
end
|
9
|
+
|
10
|
+
desc 'logout', 'Logout of Gleis'
|
11
|
+
def logout
|
12
|
+
Authentication.logout
|
13
|
+
end
|
14
|
+
|
15
|
+
desc 'whoami', 'Info on current login'
|
16
|
+
def whoami
|
17
|
+
Authentication.whoami
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/gleis/cli/db.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
module Gleis
|
2
|
+
module CLI
|
3
|
+
# Database-related CLI subcommands
|
4
|
+
class Db < Thor
|
5
|
+
class_option :app, aliases: :a, type: :string, default: Utils.app_name
|
6
|
+
|
7
|
+
desc 'backup', 'Backup locally database DATABASE_URL'
|
8
|
+
def backup
|
9
|
+
Gleis::Database.backup(options[:app])
|
10
|
+
end
|
11
|
+
|
12
|
+
desc 'delete DB_ENV_VAR', 'Delete database configured at variable name'
|
13
|
+
def delete(env_var_name)
|
14
|
+
Gleis::Database.delete(options[:app], env_var_name)
|
15
|
+
end
|
16
|
+
|
17
|
+
desc 'info', 'Information about database DATABASE_URL'
|
18
|
+
def info
|
19
|
+
Gleis::Database.info(options[:app])
|
20
|
+
end
|
21
|
+
|
22
|
+
desc 'new', 'Create new database'
|
23
|
+
def new
|
24
|
+
Gleis::Database.new(options[:app])
|
25
|
+
end
|
26
|
+
|
27
|
+
desc 'promote DB_ENV_VAR', 'Promote database to app using variable name (e.g. DATABASE1_URL)'
|
28
|
+
def promote(env_var_name)
|
29
|
+
Gleis::Database.promote(options[:app], env_var_name)
|
30
|
+
end
|
31
|
+
|
32
|
+
desc 'psql', 'Connect to PostgreSQL database DATABASE_URL'
|
33
|
+
def psql
|
34
|
+
Gleis::Database.psql(options[:app])
|
35
|
+
end
|
36
|
+
|
37
|
+
desc 'push LOCAL_DB_NAME', 'Copy local database to remote database DATABASE_URL'
|
38
|
+
def push(local_name)
|
39
|
+
Gleis::Database.push(options[:app], local_name)
|
40
|
+
end
|
41
|
+
|
42
|
+
desc 'reset DB_ENV_VAR', 'Reset database configured at variable name'
|
43
|
+
def reset(env_var_name)
|
44
|
+
Gleis::Database.reset(options[:app], env_var_name)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Gleis
|
2
|
+
module CLI
|
3
|
+
# Domain-related CLI commands
|
4
|
+
class Domain < Thor
|
5
|
+
class_option :app, aliases: :a, type: :string, default: Utils.app_name
|
6
|
+
|
7
|
+
desc 'add DOMAIN', 'Add domain name to app'
|
8
|
+
def add(name)
|
9
|
+
Gleis::Domain.add(options[:app], name)
|
10
|
+
end
|
11
|
+
|
12
|
+
desc 'list', 'List existing domain names for app'
|
13
|
+
def list
|
14
|
+
Gleis::Domain.list(options[:app])
|
15
|
+
end
|
16
|
+
|
17
|
+
desc 'remove DOMAIN', 'Remove domain name from app'
|
18
|
+
def remove(name)
|
19
|
+
Gleis::Domain.remove(options[:app], name)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Gleis
|
2
|
+
module CLI
|
3
|
+
# Management-related CLI commands
|
4
|
+
class Management < Thor
|
5
|
+
desc 'apps', 'List all apps for organisation'
|
6
|
+
def apps
|
7
|
+
Gleis::Management.apps
|
8
|
+
end
|
9
|
+
|
10
|
+
desc 'license', 'Display short license info'
|
11
|
+
def license
|
12
|
+
Gleis::Management.license
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Gleis
|
2
|
+
module CLI
|
3
|
+
# Sharing-related CLI commands
|
4
|
+
class Sharing < Thor
|
5
|
+
class_option :app, aliases: :a, type: :string, default: Utils.app_name
|
6
|
+
|
7
|
+
desc 'add EMAIL ROLE', 'Allow user to access app (roles: collaborator, owner)'
|
8
|
+
def add(email, role)
|
9
|
+
Gleis::Sharing.add(options[:app], email, role)
|
10
|
+
end
|
11
|
+
|
12
|
+
desc 'list', 'Show access list of application'
|
13
|
+
def list
|
14
|
+
Gleis::Sharing.list(options[:app])
|
15
|
+
end
|
16
|
+
|
17
|
+
desc 'remove EMAIL', 'Remove user access to app'
|
18
|
+
def remove(email)
|
19
|
+
Gleis::Sharing.remove(options[:app], email)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Gleis
|
2
|
+
module CLI
|
3
|
+
# Storage-related CLI commands
|
4
|
+
class Storage < Thor
|
5
|
+
class_option :app, aliases: :a, type: :string, default: Utils.app_name
|
6
|
+
|
7
|
+
desc 'add TYPE', 'Add storage to app'
|
8
|
+
def add(type)
|
9
|
+
Gleis::Storage.add(options[:app], type)
|
10
|
+
end
|
11
|
+
|
12
|
+
desc 'attach DIRECTORY', 'Attach storage to directory (e.g. /usr/src/app/public)'
|
13
|
+
def attach(dir)
|
14
|
+
Gleis::Storage.attach(options[:app], dir)
|
15
|
+
end
|
16
|
+
|
17
|
+
desc 'list', 'List available storage types'
|
18
|
+
def list
|
19
|
+
Gleis::Storage.list(options[:app])
|
20
|
+
end
|
21
|
+
|
22
|
+
desc 'sync DIRECTORY', 'Synchronise local directory with remote storage'
|
23
|
+
def sync(dir)
|
24
|
+
Gleis::Storage.sync(options[:app], dir)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/gleis/config.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
module Gleis
|
2
|
+
# Global parameters of gleis gem and app config env variables
|
3
|
+
class Config
|
4
|
+
# Override default API URL if GLEIS_API_URL env variable is set
|
5
|
+
API_URL = ENV['GLEIS_API_URL'].nil? ? 'https://api.basel.gleis.one/' : ENV['GLEIS_API_URL']
|
6
|
+
API_VERSION = 'v0'.freeze
|
7
|
+
SSH_KEY_FILE_BASE = Dir.home + '/.ssh/gleis'
|
8
|
+
TOKEN_FILE = Dir.home + '/.gleis-token'
|
9
|
+
|
10
|
+
def self.get_env_vars(app_name, token)
|
11
|
+
body = API.request('get', "config/#{app_name}", token)
|
12
|
+
abort("Failed to get app environment variables: #{body['error_text']}") if body['success'] != 1
|
13
|
+
body
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.get_env_var(app_name, token, var_name)
|
17
|
+
body = API.request('get', "config/#{app_name}/#{var_name}", token)
|
18
|
+
return body['data'] if body['success'] == 1
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|