pogo 2.31.2
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.
- data/README.md +73 -0
- data/bin/pogo +22 -0
- data/data/cacert.pem +3988 -0
- data/lib/heroku.rb +22 -0
- data/lib/heroku/auth.rb +320 -0
- data/lib/heroku/cli.rb +38 -0
- data/lib/heroku/client.rb +764 -0
- data/lib/heroku/client/heroku_postgresql.rb +111 -0
- data/lib/heroku/client/pgbackups.rb +113 -0
- data/lib/heroku/client/rendezvous.rb +105 -0
- data/lib/heroku/client/ssl_endpoint.rb +25 -0
- data/lib/heroku/command.rb +273 -0
- data/lib/heroku/command/account.rb +23 -0
- data/lib/heroku/command/accounts.rb +34 -0
- data/lib/heroku/command/addons.rb +305 -0
- data/lib/heroku/command/apps.rb +311 -0
- data/lib/heroku/command/auth.rb +86 -0
- data/lib/heroku/command/base.rb +230 -0
- data/lib/heroku/command/certs.rb +148 -0
- data/lib/heroku/command/config.rb +137 -0
- data/lib/heroku/command/db.rb +218 -0
- data/lib/heroku/command/domains.rb +85 -0
- data/lib/heroku/command/drains.rb +46 -0
- data/lib/heroku/command/git.rb +65 -0
- data/lib/heroku/command/help.rb +163 -0
- data/lib/heroku/command/keys.rb +115 -0
- data/lib/heroku/command/labs.rb +161 -0
- data/lib/heroku/command/logs.rb +98 -0
- data/lib/heroku/command/maintenance.rb +61 -0
- data/lib/heroku/command/pg.rb +277 -0
- data/lib/heroku/command/pgbackups.rb +289 -0
- data/lib/heroku/command/plugins.rb +110 -0
- data/lib/heroku/command/ps.rb +232 -0
- data/lib/heroku/command/releases.rb +124 -0
- data/lib/heroku/command/run.rb +179 -0
- data/lib/heroku/command/sharing.rb +89 -0
- data/lib/heroku/command/ssl.rb +61 -0
- data/lib/heroku/command/stack.rb +62 -0
- data/lib/heroku/command/status.rb +51 -0
- data/lib/heroku/command/update.rb +47 -0
- data/lib/heroku/command/version.rb +23 -0
- data/lib/heroku/deprecated.rb +5 -0
- data/lib/heroku/deprecated/help.rb +38 -0
- data/lib/heroku/distribution.rb +9 -0
- data/lib/heroku/helpers.rb +517 -0
- data/lib/heroku/helpers/heroku_postgresql.rb +104 -0
- data/lib/heroku/plugin.rb +161 -0
- data/lib/heroku/updater.rb +158 -0
- data/lib/heroku/version.rb +3 -0
- data/lib/vendor/heroku/okjson.rb +598 -0
- data/spec/helper/legacy_help.rb +16 -0
- data/spec/heroku/auth_spec.rb +246 -0
- data/spec/heroku/client/heroku_postgresql_spec.rb +34 -0
- data/spec/heroku/client/pgbackups_spec.rb +43 -0
- data/spec/heroku/client/rendezvous_spec.rb +62 -0
- data/spec/heroku/client/ssl_endpoint_spec.rb +48 -0
- data/spec/heroku/client_spec.rb +564 -0
- data/spec/heroku/command/addons_spec.rb +585 -0
- data/spec/heroku/command/apps_spec.rb +351 -0
- data/spec/heroku/command/auth_spec.rb +38 -0
- data/spec/heroku/command/base_spec.rb +109 -0
- data/spec/heroku/command/certs_spec.rb +178 -0
- data/spec/heroku/command/config_spec.rb +144 -0
- data/spec/heroku/command/db_spec.rb +110 -0
- data/spec/heroku/command/domains_spec.rb +87 -0
- data/spec/heroku/command/drains_spec.rb +34 -0
- data/spec/heroku/command/git_spec.rb +116 -0
- data/spec/heroku/command/help_spec.rb +93 -0
- data/spec/heroku/command/keys_spec.rb +120 -0
- data/spec/heroku/command/labs_spec.rb +99 -0
- data/spec/heroku/command/logs_spec.rb +60 -0
- data/spec/heroku/command/maintenance_spec.rb +51 -0
- data/spec/heroku/command/pg_spec.rb +223 -0
- data/spec/heroku/command/pgbackups_spec.rb +280 -0
- data/spec/heroku/command/plugins_spec.rb +104 -0
- data/spec/heroku/command/ps_spec.rb +195 -0
- data/spec/heroku/command/releases_spec.rb +130 -0
- data/spec/heroku/command/run_spec.rb +86 -0
- data/spec/heroku/command/sharing_spec.rb +59 -0
- data/spec/heroku/command/ssl_spec.rb +32 -0
- data/spec/heroku/command/stack_spec.rb +46 -0
- data/spec/heroku/command/status_spec.rb +48 -0
- data/spec/heroku/command/version_spec.rb +16 -0
- data/spec/heroku/command_spec.rb +211 -0
- data/spec/heroku/helpers/heroku_postgresql_spec.rb +109 -0
- data/spec/heroku/helpers_spec.rb +48 -0
- data/spec/heroku/plugin_spec.rb +172 -0
- data/spec/heroku/updater_spec.rb +44 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +209 -0
- data/spec/support/display_message_matcher.rb +49 -0
- data/spec/support/openssl_mock_helper.rb +8 -0
- metadata +220 -0
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
require "heroku/command/base"
|
|
2
|
+
|
|
3
|
+
# authentication (login, logout)
|
|
4
|
+
#
|
|
5
|
+
class Heroku::Command::Auth < Heroku::Command::Base
|
|
6
|
+
|
|
7
|
+
# auth
|
|
8
|
+
#
|
|
9
|
+
# Authenticate, display token and current user
|
|
10
|
+
def index
|
|
11
|
+
validate_arguments!
|
|
12
|
+
|
|
13
|
+
Heroku::Command::Help.new.send(:help_for_command, current_command)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# auth:login
|
|
17
|
+
#
|
|
18
|
+
# log in with your heroku credentials
|
|
19
|
+
#
|
|
20
|
+
#Example:
|
|
21
|
+
#
|
|
22
|
+
# $ heroku auth:login
|
|
23
|
+
# Enter your Heroku credentials:
|
|
24
|
+
# Email: email@example.com
|
|
25
|
+
# Password (typing will be hidden):
|
|
26
|
+
# Authentication successful.
|
|
27
|
+
#
|
|
28
|
+
def login
|
|
29
|
+
validate_arguments!
|
|
30
|
+
|
|
31
|
+
Heroku::Auth.login
|
|
32
|
+
display "Authentication successful."
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
alias_command "login", "auth:login"
|
|
36
|
+
|
|
37
|
+
# auth:logout
|
|
38
|
+
#
|
|
39
|
+
# clear local authentication credentials
|
|
40
|
+
#
|
|
41
|
+
#Example:
|
|
42
|
+
#
|
|
43
|
+
# $ heroku auth:logout
|
|
44
|
+
# Local credentials cleared.
|
|
45
|
+
#
|
|
46
|
+
def logout
|
|
47
|
+
validate_arguments!
|
|
48
|
+
|
|
49
|
+
Heroku::Auth.logout
|
|
50
|
+
display "Local credentials cleared."
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
alias_command "logout", "auth:logout"
|
|
54
|
+
|
|
55
|
+
# auth:token
|
|
56
|
+
#
|
|
57
|
+
# display your api token
|
|
58
|
+
#
|
|
59
|
+
#Example:
|
|
60
|
+
#
|
|
61
|
+
# $ heroku auth:token
|
|
62
|
+
# ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCD
|
|
63
|
+
#
|
|
64
|
+
def token
|
|
65
|
+
validate_arguments!
|
|
66
|
+
|
|
67
|
+
display Heroku::Auth.api_key
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# auth:whoami
|
|
71
|
+
#
|
|
72
|
+
# display your heroku email address
|
|
73
|
+
#
|
|
74
|
+
#Example:
|
|
75
|
+
#
|
|
76
|
+
# $ heroku auth:whoami
|
|
77
|
+
# email@example.com
|
|
78
|
+
#
|
|
79
|
+
def whoami
|
|
80
|
+
validate_arguments!
|
|
81
|
+
|
|
82
|
+
display Heroku::Auth.user
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
end
|
|
86
|
+
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
require "fileutils"
|
|
2
|
+
require "heroku/auth"
|
|
3
|
+
require "heroku/client/rendezvous"
|
|
4
|
+
require "heroku/command"
|
|
5
|
+
|
|
6
|
+
class Heroku::Command::Base
|
|
7
|
+
include Heroku::Helpers
|
|
8
|
+
|
|
9
|
+
def self.namespace
|
|
10
|
+
self.to_s.split("::").last.downcase
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
attr_reader :args
|
|
14
|
+
attr_reader :options
|
|
15
|
+
|
|
16
|
+
def initialize(args=[], options={})
|
|
17
|
+
@args = args
|
|
18
|
+
@options = options
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def app
|
|
22
|
+
@app ||= if options[:confirm].is_a?(String)
|
|
23
|
+
if options[:app] && (options[:app] != options[:confirm])
|
|
24
|
+
error("Mismatch between --app and --confirm")
|
|
25
|
+
end
|
|
26
|
+
options[:confirm]
|
|
27
|
+
elsif options[:app].is_a?(String)
|
|
28
|
+
options[:app]
|
|
29
|
+
elsif ENV.has_key?('HEROKU_APP')
|
|
30
|
+
ENV['HEROKU_APP']
|
|
31
|
+
elsif app_from_dir = extract_app_in_dir(Dir.pwd)
|
|
32
|
+
app_from_dir
|
|
33
|
+
else
|
|
34
|
+
# raise instead of using error command to enable rescuing when app is optional
|
|
35
|
+
raise Heroku::Command::CommandFailed.new("No app specified.\nRun this command from an app folder or specify which app to use with --app APP.")
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def api
|
|
40
|
+
Heroku::Auth.api
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def heroku
|
|
44
|
+
Heroku::Auth.client
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
protected
|
|
48
|
+
|
|
49
|
+
def self.inherited(klass)
|
|
50
|
+
unless klass == Heroku::Command::Base
|
|
51
|
+
help = extract_help_from_caller(caller.first)
|
|
52
|
+
|
|
53
|
+
Heroku::Command.register_namespace(
|
|
54
|
+
:name => klass.namespace,
|
|
55
|
+
:description => help.first
|
|
56
|
+
)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def self.method_added(method)
|
|
61
|
+
return if self == Heroku::Command::Base
|
|
62
|
+
return if private_method_defined?(method)
|
|
63
|
+
return if protected_method_defined?(method)
|
|
64
|
+
|
|
65
|
+
help = extract_help_from_caller(caller.first)
|
|
66
|
+
resolved_method = (method.to_s == "index") ? nil : method.to_s
|
|
67
|
+
command = [ self.namespace, resolved_method ].compact.join(":")
|
|
68
|
+
banner = extract_banner(help) || command
|
|
69
|
+
|
|
70
|
+
Heroku::Command.register_command(
|
|
71
|
+
:klass => self,
|
|
72
|
+
:method => method,
|
|
73
|
+
:namespace => self.namespace,
|
|
74
|
+
:command => command,
|
|
75
|
+
:banner => banner.strip,
|
|
76
|
+
:help => help.join("\n"),
|
|
77
|
+
:summary => extract_summary(help),
|
|
78
|
+
:description => extract_description(help),
|
|
79
|
+
:options => extract_options(help)
|
|
80
|
+
)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def self.alias_command(new, old)
|
|
84
|
+
raise "no such command: #{old}" unless Heroku::Command.commands[old]
|
|
85
|
+
Heroku::Command.command_aliases[new] = old
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def extract_app
|
|
89
|
+
output_with_bang "Command::Base#extract_app has been deprecated. Please use Command::Base#app instead. #{caller.first}"
|
|
90
|
+
app
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
#
|
|
94
|
+
# Parse the caller format and identify the file and line number as identified
|
|
95
|
+
# in : http://www.ruby-doc.org/core/classes/Kernel.html#M001397. This will
|
|
96
|
+
# look for a colon followed by a digit as the delimiter. The biggest
|
|
97
|
+
# complication is windows paths, which have a color after the drive letter.
|
|
98
|
+
# This regex will match paths as anything from the beginning to a colon
|
|
99
|
+
# directly followed by a number (the line number).
|
|
100
|
+
#
|
|
101
|
+
# Examples of the caller format :
|
|
102
|
+
# * c:/Ruby192/lib/.../lib/heroku/command/addons.rb:8:in `<module:Command>'
|
|
103
|
+
# * c:/Ruby192/lib/.../heroku-2.0.1/lib/heroku/command/pg.rb:96:in `<class:Pg>'
|
|
104
|
+
# * /Users/ph7/...../xray-1.1/lib/xray/thread_dump_signal_handler.rb:9
|
|
105
|
+
#
|
|
106
|
+
def self.extract_help_from_caller(line)
|
|
107
|
+
# pull out of the caller the information for the file path and line number
|
|
108
|
+
if line =~ /^(.+?):(\d+)/
|
|
109
|
+
extract_help($1, $2)
|
|
110
|
+
else
|
|
111
|
+
raise("unable to extract help from caller: #{line}")
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def self.extract_help(file, line_number)
|
|
116
|
+
buffer = []
|
|
117
|
+
lines = Heroku::Command.files[file]
|
|
118
|
+
|
|
119
|
+
(line_number.to_i-2).downto(0) do |i|
|
|
120
|
+
line = lines[i]
|
|
121
|
+
case line[0..0]
|
|
122
|
+
when ""
|
|
123
|
+
when "#"
|
|
124
|
+
buffer.unshift(line[1..-1])
|
|
125
|
+
else
|
|
126
|
+
break
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
buffer
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def self.extract_banner(help)
|
|
134
|
+
help.first
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def self.extract_summary(help)
|
|
138
|
+
extract_description(help).split("\n")[2].to_s.split("\n").first
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def self.extract_description(help)
|
|
142
|
+
help.reject do |line|
|
|
143
|
+
line =~ /^\s+-(.+)#(.+)/
|
|
144
|
+
end.join("\n")
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def self.extract_options(help)
|
|
148
|
+
help.select do |line|
|
|
149
|
+
line =~ /^\s+-(.+)#(.+)/
|
|
150
|
+
end.inject([]) do |options, line|
|
|
151
|
+
args = line.split('#', 2).first
|
|
152
|
+
args = args.split(/,\s*/).map {|arg| arg.strip}.sort.reverse
|
|
153
|
+
name = args.last.split(' ', 2).first[2..-1]
|
|
154
|
+
options << { :name => name, :args => args }
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def current_command
|
|
159
|
+
Heroku::Command.current_command
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def extract_option(key)
|
|
163
|
+
options[key.dup.gsub('-','_').to_sym]
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def invalid_arguments
|
|
167
|
+
Heroku::Command.invalid_arguments
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def shift_argument
|
|
171
|
+
Heroku::Command.shift_argument
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def validate_arguments!
|
|
175
|
+
Heroku::Command.validate_arguments!
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def extract_app_in_dir(dir)
|
|
179
|
+
return unless remotes = git_remotes(dir)
|
|
180
|
+
|
|
181
|
+
if remote = options[:remote]
|
|
182
|
+
remotes[remote]
|
|
183
|
+
elsif remote = extract_app_from_git_config
|
|
184
|
+
remotes[remote]
|
|
185
|
+
else
|
|
186
|
+
apps = remotes.values.uniq
|
|
187
|
+
if apps.size == 1
|
|
188
|
+
apps.first
|
|
189
|
+
else
|
|
190
|
+
raise(Heroku::Command::CommandFailed, "Multiple apps in folder and no app specified.\nSpecify app with --app APP.")
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
def extract_app_from_git_config
|
|
196
|
+
remote = git("config heroku.remote")
|
|
197
|
+
remote == "" ? nil : remote
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def git_remotes(base_dir=Dir.pwd)
|
|
201
|
+
remotes = {}
|
|
202
|
+
original_dir = Dir.pwd
|
|
203
|
+
Dir.chdir(base_dir)
|
|
204
|
+
|
|
205
|
+
return unless File.exists?(".git")
|
|
206
|
+
git("remote -v").split("\n").each do |remote|
|
|
207
|
+
name, url, method = remote.split(/\s/)
|
|
208
|
+
if url =~ /^git@#{Heroku::Auth.git_host}:([\w\d-]+)\.git$/
|
|
209
|
+
remotes[name] = $1
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
Dir.chdir(original_dir)
|
|
214
|
+
if remotes.empty?
|
|
215
|
+
nil
|
|
216
|
+
else
|
|
217
|
+
remotes
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
def escape(value)
|
|
222
|
+
heroku.escape(value)
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
module Heroku::Command
|
|
227
|
+
unless const_defined?(:BaseWithApp)
|
|
228
|
+
BaseWithApp = Base
|
|
229
|
+
end
|
|
230
|
+
end
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
require "heroku/command/base"
|
|
2
|
+
|
|
3
|
+
# manage ssl endpoints for an app
|
|
4
|
+
#
|
|
5
|
+
class Heroku::Command::Certs < Heroku::Command::Base
|
|
6
|
+
|
|
7
|
+
# certs
|
|
8
|
+
#
|
|
9
|
+
# list ssl endpoints for an app
|
|
10
|
+
#
|
|
11
|
+
def index
|
|
12
|
+
endpoints = heroku.ssl_endpoint_list(app)
|
|
13
|
+
|
|
14
|
+
if endpoints.empty?
|
|
15
|
+
display "#{app} has no SSL Endpoints."
|
|
16
|
+
display "Use `heroku certs:add PEM KEY` to add one."
|
|
17
|
+
else
|
|
18
|
+
endpoints.map! do |endpoint|
|
|
19
|
+
{
|
|
20
|
+
'cname' => endpoint['cname'],
|
|
21
|
+
'domains' => endpoint['ssl_cert']['cert_domains'].join(', '),
|
|
22
|
+
'expires_at' => format_date(endpoint['ssl_cert']['expires_at']),
|
|
23
|
+
'ca_signed?' => endpoint['ssl_cert']['ca_signed?'].to_s.capitalize
|
|
24
|
+
}
|
|
25
|
+
end
|
|
26
|
+
display_table(
|
|
27
|
+
endpoints,
|
|
28
|
+
%w( cname domains expires_at ca_signed? ),
|
|
29
|
+
[ "Endpoint", "Common Name(s)", "Expires", "Trusted" ]
|
|
30
|
+
)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# certs:add PEM KEY
|
|
35
|
+
#
|
|
36
|
+
# add an ssl endpoint to an app
|
|
37
|
+
#
|
|
38
|
+
def add
|
|
39
|
+
fail("Usage: heroku certs:add PEM KEY\nMust specify PEM and KEY to add cert.") if args.size < 2
|
|
40
|
+
pem = File.read(args[0]) rescue error("Unable to read #{args[0]} PEM")
|
|
41
|
+
key = File.read(args[1]) rescue error("Unable to read #{args[1]} KEY")
|
|
42
|
+
|
|
43
|
+
endpoint = action("Adding SSL Endpoint to #{app}") do
|
|
44
|
+
heroku.ssl_endpoint_add(app, pem, key)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
display_warnings(endpoint)
|
|
48
|
+
display "#{app} now served by #{endpoint['cname']}"
|
|
49
|
+
display "Certificate details:"
|
|
50
|
+
display_certificate_info(endpoint)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# certs:info
|
|
54
|
+
#
|
|
55
|
+
# show certificate information for an ssl endpoint
|
|
56
|
+
#
|
|
57
|
+
def info
|
|
58
|
+
cname = options[:endpoint] || current_endpoint
|
|
59
|
+
endpoint = action("Fetching SSL Endpoint #{cname} info for #{app}") do
|
|
60
|
+
heroku.ssl_endpoint_info(app, cname)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
display "Certificate details:"
|
|
64
|
+
display_certificate_info(endpoint)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# certs:remove
|
|
68
|
+
#
|
|
69
|
+
# remove an SSL Endpoint from an app
|
|
70
|
+
#
|
|
71
|
+
def remove
|
|
72
|
+
cname = options[:endpoint] || current_endpoint
|
|
73
|
+
action("Removing SSL Endpoint #{cname} from #{app}") do
|
|
74
|
+
heroku.ssl_endpoint_remove(app, cname)
|
|
75
|
+
end
|
|
76
|
+
display "NOTE: Billing is still active. Remove SSL Endpoint add-on to stop billing."
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# certs:update PEM KEY
|
|
80
|
+
#
|
|
81
|
+
# update an SSL Endpoint on an app
|
|
82
|
+
#
|
|
83
|
+
def update
|
|
84
|
+
fail("Usage: heroku certs:update PEM KEY\nMust specify PEM and KEY to update cert.") if args.size < 2
|
|
85
|
+
pem = File.read(args[0]) rescue error("Unable to read #{args[0]} PEM")
|
|
86
|
+
key = File.read(args[1]) rescue error("Unable to read #{args[1]} KEY")
|
|
87
|
+
app = self.app
|
|
88
|
+
cname = options[:endpoint] || current_endpoint
|
|
89
|
+
|
|
90
|
+
endpoint = action("Updating SSL Endpoint #{cname} for #{app}") do
|
|
91
|
+
heroku.ssl_endpoint_update(app, cname, pem, key)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
display_warnings(endpoint)
|
|
95
|
+
display "Updated certificate details:"
|
|
96
|
+
display_certificate_info(endpoint)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# certs:rollback
|
|
100
|
+
#
|
|
101
|
+
# rollback an SSL Endpoint for an app
|
|
102
|
+
#
|
|
103
|
+
def rollback
|
|
104
|
+
cname = options[:endpoint] || current_endpoint
|
|
105
|
+
|
|
106
|
+
endpoint = action("Rolling back SSL Endpoint #{cname} for #{app}") do
|
|
107
|
+
heroku.ssl_endpoint_rollback(app, cname)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
display "New active certificate details:"
|
|
111
|
+
display_certificate_info(endpoint)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
private
|
|
115
|
+
|
|
116
|
+
def current_endpoint
|
|
117
|
+
endpoint = heroku.ssl_endpoint_list(app).first || error("#{app} has no SSL Endpoints.")
|
|
118
|
+
endpoint["cname"]
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def display_certificate_info(endpoint)
|
|
122
|
+
data = {
|
|
123
|
+
'Common Name(s)' => endpoint['ssl_cert']['cert_domains'],
|
|
124
|
+
'Expires At' => format_date(endpoint['ssl_cert']['expires_at']),
|
|
125
|
+
'Issuer' => endpoint['ssl_cert']['issuer'],
|
|
126
|
+
'Starts At' => format_date(endpoint['ssl_cert']['starts_at']),
|
|
127
|
+
'Subject' => endpoint['ssl_cert']['subject']
|
|
128
|
+
}
|
|
129
|
+
styled_hash(data)
|
|
130
|
+
|
|
131
|
+
if endpoint["ssl_cert"]["ca_signed?"]
|
|
132
|
+
display "SSL certificate is verified by a root authority."
|
|
133
|
+
elsif endpoint["issuer"] == endpoint["subject"]
|
|
134
|
+
display "SSL certificate is self signed."
|
|
135
|
+
else
|
|
136
|
+
display "SSL certificate is not trusted."
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def display_warnings(endpoint)
|
|
141
|
+
if endpoint["warnings"]
|
|
142
|
+
endpoint["warnings"].each do |field, warning|
|
|
143
|
+
display "WARNING: #{field} #{warning}"
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
end
|