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.
Files changed (93) hide show
  1. data/README.md +73 -0
  2. data/bin/pogo +22 -0
  3. data/data/cacert.pem +3988 -0
  4. data/lib/heroku.rb +22 -0
  5. data/lib/heroku/auth.rb +320 -0
  6. data/lib/heroku/cli.rb +38 -0
  7. data/lib/heroku/client.rb +764 -0
  8. data/lib/heroku/client/heroku_postgresql.rb +111 -0
  9. data/lib/heroku/client/pgbackups.rb +113 -0
  10. data/lib/heroku/client/rendezvous.rb +105 -0
  11. data/lib/heroku/client/ssl_endpoint.rb +25 -0
  12. data/lib/heroku/command.rb +273 -0
  13. data/lib/heroku/command/account.rb +23 -0
  14. data/lib/heroku/command/accounts.rb +34 -0
  15. data/lib/heroku/command/addons.rb +305 -0
  16. data/lib/heroku/command/apps.rb +311 -0
  17. data/lib/heroku/command/auth.rb +86 -0
  18. data/lib/heroku/command/base.rb +230 -0
  19. data/lib/heroku/command/certs.rb +148 -0
  20. data/lib/heroku/command/config.rb +137 -0
  21. data/lib/heroku/command/db.rb +218 -0
  22. data/lib/heroku/command/domains.rb +85 -0
  23. data/lib/heroku/command/drains.rb +46 -0
  24. data/lib/heroku/command/git.rb +65 -0
  25. data/lib/heroku/command/help.rb +163 -0
  26. data/lib/heroku/command/keys.rb +115 -0
  27. data/lib/heroku/command/labs.rb +161 -0
  28. data/lib/heroku/command/logs.rb +98 -0
  29. data/lib/heroku/command/maintenance.rb +61 -0
  30. data/lib/heroku/command/pg.rb +277 -0
  31. data/lib/heroku/command/pgbackups.rb +289 -0
  32. data/lib/heroku/command/plugins.rb +110 -0
  33. data/lib/heroku/command/ps.rb +232 -0
  34. data/lib/heroku/command/releases.rb +124 -0
  35. data/lib/heroku/command/run.rb +179 -0
  36. data/lib/heroku/command/sharing.rb +89 -0
  37. data/lib/heroku/command/ssl.rb +61 -0
  38. data/lib/heroku/command/stack.rb +62 -0
  39. data/lib/heroku/command/status.rb +51 -0
  40. data/lib/heroku/command/update.rb +47 -0
  41. data/lib/heroku/command/version.rb +23 -0
  42. data/lib/heroku/deprecated.rb +5 -0
  43. data/lib/heroku/deprecated/help.rb +38 -0
  44. data/lib/heroku/distribution.rb +9 -0
  45. data/lib/heroku/helpers.rb +517 -0
  46. data/lib/heroku/helpers/heroku_postgresql.rb +104 -0
  47. data/lib/heroku/plugin.rb +161 -0
  48. data/lib/heroku/updater.rb +158 -0
  49. data/lib/heroku/version.rb +3 -0
  50. data/lib/vendor/heroku/okjson.rb +598 -0
  51. data/spec/helper/legacy_help.rb +16 -0
  52. data/spec/heroku/auth_spec.rb +246 -0
  53. data/spec/heroku/client/heroku_postgresql_spec.rb +34 -0
  54. data/spec/heroku/client/pgbackups_spec.rb +43 -0
  55. data/spec/heroku/client/rendezvous_spec.rb +62 -0
  56. data/spec/heroku/client/ssl_endpoint_spec.rb +48 -0
  57. data/spec/heroku/client_spec.rb +564 -0
  58. data/spec/heroku/command/addons_spec.rb +585 -0
  59. data/spec/heroku/command/apps_spec.rb +351 -0
  60. data/spec/heroku/command/auth_spec.rb +38 -0
  61. data/spec/heroku/command/base_spec.rb +109 -0
  62. data/spec/heroku/command/certs_spec.rb +178 -0
  63. data/spec/heroku/command/config_spec.rb +144 -0
  64. data/spec/heroku/command/db_spec.rb +110 -0
  65. data/spec/heroku/command/domains_spec.rb +87 -0
  66. data/spec/heroku/command/drains_spec.rb +34 -0
  67. data/spec/heroku/command/git_spec.rb +116 -0
  68. data/spec/heroku/command/help_spec.rb +93 -0
  69. data/spec/heroku/command/keys_spec.rb +120 -0
  70. data/spec/heroku/command/labs_spec.rb +99 -0
  71. data/spec/heroku/command/logs_spec.rb +60 -0
  72. data/spec/heroku/command/maintenance_spec.rb +51 -0
  73. data/spec/heroku/command/pg_spec.rb +223 -0
  74. data/spec/heroku/command/pgbackups_spec.rb +280 -0
  75. data/spec/heroku/command/plugins_spec.rb +104 -0
  76. data/spec/heroku/command/ps_spec.rb +195 -0
  77. data/spec/heroku/command/releases_spec.rb +130 -0
  78. data/spec/heroku/command/run_spec.rb +86 -0
  79. data/spec/heroku/command/sharing_spec.rb +59 -0
  80. data/spec/heroku/command/ssl_spec.rb +32 -0
  81. data/spec/heroku/command/stack_spec.rb +46 -0
  82. data/spec/heroku/command/status_spec.rb +48 -0
  83. data/spec/heroku/command/version_spec.rb +16 -0
  84. data/spec/heroku/command_spec.rb +211 -0
  85. data/spec/heroku/helpers/heroku_postgresql_spec.rb +109 -0
  86. data/spec/heroku/helpers_spec.rb +48 -0
  87. data/spec/heroku/plugin_spec.rb +172 -0
  88. data/spec/heroku/updater_spec.rb +44 -0
  89. data/spec/spec.opts +1 -0
  90. data/spec/spec_helper.rb +209 -0
  91. data/spec/support/display_message_matcher.rb +49 -0
  92. data/spec/support/openssl_mock_helper.rb +8 -0
  93. 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