heroku-api-postgres 0.9.1 → 0.12.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 +4 -4
- data/.example.env +2 -0
- data/.github/FUNDING.yml +1 -0
- data/.gitignore +1 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +10 -0
- data/Gemfile +2 -0
- data/README.md +39 -20
- data/Rakefile +2 -0
- data/bin/check +7 -0
- data/bin/console +1 -0
- data/docs/services.md +8 -8
- data/heroku-api-postgres.gemspec +12 -4
- data/lib/heroku/api/postgres/backups.rb +35 -13
- data/lib/heroku/api/postgres/client.rb +37 -14
- data/lib/heroku/api/postgres/credentials.rb +34 -0
- data/lib/heroku/api/postgres/databases.rb +14 -5
- data/lib/heroku/api/postgres/version.rb +3 -1
- data/lib/heroku/api/postgres.rb +3 -0
- metadata +50 -15
- data/Gemfile.lock +0 -67
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 33fc320b5b73a7a140e6af276b8f7f69b9ae4ef97170edf19e462fab253991db
|
4
|
+
data.tar.gz: 14d7757c4b7a78e5f9a5cc7da37143c808d83622374fd333303eebedeecbe5b5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bfaaa61d427515bec615afb3bc59dfe7950238654e497e9784fd6965a0bc4b5ca2fec3a9388648644fa94d7f9dd7a1bbee4e2c05b47f02bbc115fe965262beef
|
7
|
+
data.tar.gz: 5503f7c5feda7c5cddbad119efccba8370e2a90117ffa30101f90317871c04cb501b715febbdf1f3e215788d3850d0e888434b261c7605a0f39fa56386f8ac23
|
data/.example.env
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
HEROKU_OAUTH_TOKEN=a_valid_oauth_token
|
2
2
|
VALID_APP_ID_WITH_DATABASE=valid_app_id_with_database
|
3
3
|
VALID_DATABASE_ID_WITH_SCHEDULES=a_valid_database_id_with_a_schedule
|
4
|
+
VALID_APP_ID_WITH_DB_IN_PRO_PLAN=a_valid_app_id_with_database_in_pro_plan
|
5
|
+
VALID_DATABASE_ID_WITH_PRO_PLAN=a_valid_database_id_in_pro_plan
|
4
6
|
VALID_APP_ID=valid_app_id
|
5
7
|
VALID_DUMP_URL=valid_dump_public_url
|
data/.github/FUNDING.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
github: [coorasse]
|
data/.gitignore
CHANGED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.5.3
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
## 0.12.0
|
2
|
+
|
3
|
+
* [#18](https://github.com/coorasse/heroku-api-postgres/pull/18): Support ruby 3.0. ([@louism517][])
|
4
|
+
* [#15](https://github.com/coorasse/heroku-api-postgres/pull/15): Return latest backup if backup_num is not provided. ([@deepakmahakale][])
|
5
|
+
* [#14](https://github.com/coorasse/heroku-api-postgres/pull/14): Add support for rotating credentials. ([@avokhmin][])
|
6
|
+
* [#13](https://github.com/coorasse/heroku-api-postgres/pull/13): Allow to use hour and timezone when scheduling backups. ([@avokhmin][])
|
7
|
+
|
8
|
+
[@avokhmin]: https://github.com/avokhmin
|
9
|
+
[@deepakmahakale]: https://github.com/deepakmahakale
|
10
|
+
[@louism517]: https://github.com/louism517
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,7 +1,11 @@
|
|
1
1
|
# Heroku::Api::Postgres
|
2
2
|
|
3
|
+
**This gem has been extracted from https://db-backups.com.**
|
4
|
+
|
5
|
+
**Your "one click" backup solution for Heroku apps.**
|
6
|
+
|
3
7
|
Ruby library to invoke Heroku Postgres APIs.
|
4
|
-
An extension to the official [Platform API]() gem to introduce the missing APIs for Postgres.
|
8
|
+
An extension to the official [Platform API](https://github.com/heroku/platform-api) gem to introduce the missing APIs for Postgres.
|
5
9
|
|
6
10
|
[](https://travis-ci.org/coorasse/heroku-api-postgres)
|
7
11
|
[](https://codeclimate.com/github/coorasse/heroku-api-postgres/maintainability)
|
@@ -10,6 +14,7 @@ An extension to the official [Platform API]() gem to introduce the missing APIs
|
|
10
14
|
therefore is unrealistic that a breaking change in the APIs would break it, since it means it would break
|
11
15
|
both this gem and the official Heroku CLI.
|
12
16
|
|
17
|
+
|
13
18
|
Not all APIs are implemented at the moment but we are working hard on implementing all of them.
|
14
19
|
|
15
20
|
Please check the [list of implemented and not implemented services](docs/services.md).
|
@@ -34,20 +39,14 @@ Or install it yourself as:
|
|
34
39
|
|
35
40
|
## Usage
|
36
41
|
|
37
|
-
|
38
|
-
|
39
|
-
```ruby
|
40
|
-
# from platform api gem
|
41
|
-
platform_api_client = PlatformAPI.connect_oauth(ENV['HEROKU_OAUTH_TOKEN'])
|
42
|
-
```
|
43
|
-
|
44
|
-
this gem client needs to be instantiated as well in a similar way
|
42
|
+
This gem client needs to be instantiated in a similar way to the [PlatformAPI](https://github.com/heroku/platform-api).
|
43
|
+
You can use the same oauth key that you use for the PlatformAPI.
|
45
44
|
|
46
45
|
```ruby
|
47
46
|
postgres_api_client = Heroku::Api::Postgres.connect_oauth(ENV['HEROKU_OAUTH_TOKEN'])
|
48
47
|
```
|
49
48
|
|
50
|
-
Look into [Models](docs/models.
|
49
|
+
Look into [Models](docs/models.md) for a detailed description of the JSON objects returned by the APIs.
|
51
50
|
Those are the bare objects returned by the official Heroku API.
|
52
51
|
|
53
52
|
### Databases
|
@@ -59,7 +58,7 @@ databases_client = postgres_api_client.databases
|
|
59
58
|
---
|
60
59
|
|
61
60
|
```ruby
|
62
|
-
database_info = databases_client.info(database_id)
|
61
|
+
database_info = databases_client.info(app_id, database_id)
|
63
62
|
```
|
64
63
|
|
65
64
|
returns a [Database](docs/models.md#database).
|
@@ -67,12 +66,26 @@ returns a [Database](docs/models.md#database).
|
|
67
66
|
---
|
68
67
|
|
69
68
|
```ruby
|
70
|
-
database = postgres_api_client.databases.wait(database_id, wait_interval: 5)
|
69
|
+
database = postgres_api_client.databases.wait(app_id, database_id, wait_interval: 5)
|
71
70
|
```
|
71
|
+
|
72
72
|
Waits for the given database to be ready.
|
73
73
|
|
74
74
|
Polls every `wait_interval` seconds (default 3).
|
75
75
|
|
76
|
+
### Credentials
|
77
|
+
|
78
|
+
```ruby
|
79
|
+
credentials_client = postgres_api_client.credentials
|
80
|
+
```
|
81
|
+
|
82
|
+
---
|
83
|
+
|
84
|
+
```ruby
|
85
|
+
credentials_client.rotate(app_id, database_id)
|
86
|
+
```
|
87
|
+
|
88
|
+
Rotate the database credentials.
|
76
89
|
|
77
90
|
### Backups
|
78
91
|
|
@@ -103,7 +116,7 @@ The app_id can be either the name of your heroku app or the id.
|
|
103
116
|
---
|
104
117
|
|
105
118
|
```ruby
|
106
|
-
schedules = backups_client.schedules(database_id)
|
119
|
+
schedules = backups_client.schedules(app_id, database_id)
|
107
120
|
```
|
108
121
|
|
109
122
|
Returns all the backup schedules associated with the database.
|
@@ -113,7 +126,7 @@ Returns an array of [Schedule](docs/models.md#schedule)
|
|
113
126
|
---
|
114
127
|
|
115
128
|
```ruby
|
116
|
-
schedule = backups_client.schedule(database_id)
|
129
|
+
schedule = backups_client.schedule(app_id, database_id)
|
117
130
|
```
|
118
131
|
|
119
132
|
Schedules the backups at 00:00 UTC.
|
@@ -124,7 +137,7 @@ Returns a [Schedule](docs/models.md#schedule)
|
|
124
137
|
|
125
138
|
|
126
139
|
```ruby
|
127
|
-
backup = backups_client.capture(database_id)
|
140
|
+
backup = backups_client.capture(app_id, database_id)
|
128
141
|
```
|
129
142
|
Captures a new backup for the given database
|
130
143
|
|
@@ -142,7 +155,7 @@ Returns a [BackupUrl](docs/models.md#backup_url)
|
|
142
155
|
---
|
143
156
|
|
144
157
|
```ruby
|
145
|
-
backup = backups_client.restore(database_id, dump_url)
|
158
|
+
backup = backups_client.restore(app_id, database_id, dump_url)
|
146
159
|
```
|
147
160
|
Restores a dump from a public URL.
|
148
161
|
|
@@ -170,17 +183,23 @@ end
|
|
170
183
|
You can obtain a database id by calling the Heroku Platform API
|
171
184
|
|
172
185
|
```ruby
|
186
|
+
heroku = PlatformAPI.connect_oauth(ENV['HEROKU_OAUTH_TOKEN'])
|
173
187
|
addons = heroku.addon.list
|
174
188
|
databases = addons.select { |addon| addon['addon_service']['name'] == 'heroku-postgresql' }
|
175
189
|
databases_ids = databases.map{ |addon| addon['id'] }
|
176
190
|
```
|
177
191
|
|
178
|
-
Check also the [
|
192
|
+
Check also the [Official API](https://devcenter.heroku.com/articles/platform-api-reference#add-on)
|
179
193
|
|
180
194
|
## Development
|
181
195
|
|
182
196
|
After checking out the repo, run `bin/setup` to install dependencies.
|
183
|
-
Then, run `rake spec` to run the tests.
|
197
|
+
Then, run `rake spec` to run the tests.
|
198
|
+
You can run `bin/check` to run linter and the tests together.
|
199
|
+
You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
200
|
+
|
201
|
+
You need some app and database ids to run the tests and record the cassettes.
|
202
|
+
In particular you need an app with a postgres database on the free plan and one with a database on a pro plan.
|
184
203
|
|
185
204
|
To install this gem onto your local machine, run `bundle exec rake install`.
|
186
205
|
To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`,
|
@@ -199,5 +218,5 @@ The gem is available as open source under the terms of the [MIT License](https:/
|
|
199
218
|
|
200
219
|
## Code of Conduct
|
201
220
|
|
202
|
-
Everyone interacting in the Heroku::Api::Postgres project’s codebases, issue trackers, chat rooms and mailing lists is
|
203
|
-
expected to follow the [code of conduct](https://github.com/
|
221
|
+
Everyone interacting in the `Heroku::Api::Postgres` project’s codebases, issue trackers, chat rooms and mailing lists is
|
222
|
+
expected to follow the [code of conduct](https://github.com/coorasse/heroku-api-postgres/blob/master/CODE_OF_CONDUCT.md).
|
data/Rakefile
CHANGED
data/bin/check
ADDED
data/bin/console
CHANGED
data/docs/services.md
CHANGED
@@ -3,13 +3,13 @@
|
|
3
3
|
This list contains all postgres commands supported by the official CLI.
|
4
4
|
Source: https://devcenter.heroku.com/articles/heroku-cli-commands
|
5
5
|
|
6
|
-
- [x] pg --> `client.databases.info(database_id)`
|
6
|
+
- [x] pg --> `client.databases.info(app_id, database_id)`
|
7
7
|
|
8
8
|
- [x] pg:backups --> `client.backups.list(app_id)`
|
9
9
|
|
10
10
|
- [ ] pg:backups:cancel
|
11
11
|
|
12
|
-
- [x] pg:backups:capture ---> `client.backups.capture(database_id)`
|
12
|
+
- [x] pg:backups:capture ---> `client.backups.capture(app_id, database_id)`
|
13
13
|
The command returns immediately, without waiting for the capture to be completed.
|
14
14
|
`--wait-interval` not implemented. `--snapshot` not implemented.
|
15
15
|
|
@@ -19,16 +19,16 @@ The command returns immediately, without waiting for the capture to be completed
|
|
19
19
|
|
20
20
|
- [x] pg:backups:info --> `client.backups.info(app_id, backup_id)`
|
21
21
|
|
22
|
-
- [x] pg:backups:restore --> `client.backups.restore(database_id, dump_url)`
|
22
|
+
- [x] pg:backups:restore --> `client.backups.restore(app_id, database_id, dump_url)`
|
23
23
|
The command works only with public URLs. It does not support all the features of the original
|
24
24
|
`heroku pg:backups:restore` command, like restoring directly from another database.
|
25
25
|
The command returns immediately, without waiting for the capture to be completed.
|
26
26
|
You can use the command `client.backups.wait(app_id, restore[:num])` to wait for it to be ready.
|
27
27
|
|
28
|
-
- [x] pg:backups:schedule --> `client.backups.schedule(database_id)`
|
28
|
+
- [x] pg:backups:schedule --> `client.backups.schedule(app_id, database_id)`
|
29
29
|
|
30
30
|
|
31
|
-
- [x] pg:backups:schedules --> `client.backups.schedules(database_id)`
|
31
|
+
- [x] pg:backups:schedules --> `client.backups.schedules(app_id, database_id)`
|
32
32
|
|
33
33
|
- [ ] pg:backups:unschedule
|
34
34
|
|
@@ -46,13 +46,13 @@ You can use the command `client.backups.wait(app_id, restore[:num])` to wait for
|
|
46
46
|
|
47
47
|
- [ ] pg:credentials:repair-default
|
48
48
|
|
49
|
-
- [
|
49
|
+
- [x] pg:credentials:rotate --> `client.credentials.rotate(app_id, database_id)`
|
50
50
|
|
51
51
|
- [ ] pg:credentials:url
|
52
52
|
|
53
53
|
- [ ] pg:diagnose
|
54
54
|
|
55
|
-
- [x] pg:info --> `client.databases.info(database_id)`
|
55
|
+
- [x] pg:info --> `client.databases.info(app_id, database_id)`
|
56
56
|
|
57
57
|
- [ ] pg:kill
|
58
58
|
|
@@ -96,5 +96,5 @@ You can use the command `client.backups.wait(app_id, restore[:num])` to wait for
|
|
96
96
|
|
97
97
|
- [ ] pg:upgrade
|
98
98
|
|
99
|
-
- [x] pg:wait --> `client.wait(database_id)`
|
99
|
+
- [x] pg:wait --> `client.wait(app_id, database_id)`
|
100
100
|
Waits for a database to be ready.
|
data/heroku-api-postgres.gemspec
CHANGED
@@ -1,5 +1,6 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
|
2
|
-
lib = File.expand_path('
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
5
|
require 'heroku/api/postgres/version'
|
5
6
|
|
@@ -14,6 +15,11 @@ Gem::Specification.new do |spec|
|
|
14
15
|
spec.homepage = 'https://github.com/coorasse/heroku-api-postgres'
|
15
16
|
spec.license = 'MIT'
|
16
17
|
|
18
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
19
|
+
spec.metadata["source_code_uri"] = "https://github.com/coorasse/heroku-api-postgres"
|
20
|
+
spec.metadata["changelog_uri"] = "https://github.com/coorasse/heroku-api-postgres/blob/main/CHANGELOG.md"
|
21
|
+
spec.metadata["funding_uri"] = "https://github.com/sponsors/coorasse"
|
22
|
+
|
17
23
|
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
18
24
|
f.match(%r{^(test|spec|features)/})
|
19
25
|
end
|
@@ -21,11 +27,13 @@ Gem::Specification.new do |spec|
|
|
21
27
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
22
28
|
spec.require_paths = ['lib']
|
23
29
|
|
24
|
-
spec.
|
30
|
+
spec.add_dependency 'platform-api'
|
31
|
+
spec.add_development_dependency 'bundler', '~> 1.17'
|
25
32
|
spec.add_development_dependency 'dotenv'
|
26
|
-
spec.add_development_dependency '
|
33
|
+
spec.add_development_dependency 'pry'
|
34
|
+
spec.add_development_dependency 'rake', '~> 13.0'
|
27
35
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
28
|
-
spec.add_development_dependency 'rubocop', '0.
|
36
|
+
spec.add_development_dependency 'rubocop', '0.60.0'
|
29
37
|
spec.add_development_dependency 'vcr', '~> 4.0.0'
|
30
38
|
spec.add_development_dependency 'webmock', '~> 3.3.0'
|
31
39
|
end
|
@@ -1,5 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'net/http'
|
2
4
|
require 'json'
|
5
|
+
require 'platform-api'
|
3
6
|
|
4
7
|
module Heroku
|
5
8
|
module Api
|
@@ -20,37 +23,56 @@ module Heroku
|
|
20
23
|
@client.perform_get_request("/client/v11/apps/#{app_id}/transfers/#{backup_id}")
|
21
24
|
end
|
22
25
|
|
23
|
-
def schedules(database_id)
|
24
|
-
@client.perform_get_request("/client/v11/databases/#{database_id}/transfer-schedules"
|
26
|
+
def schedules(app_id, database_id)
|
27
|
+
@client.perform_get_request("/client/v11/databases/#{database_id}/transfer-schedules",
|
28
|
+
host: db_host(app_id, database_id))
|
25
29
|
end
|
26
30
|
|
27
|
-
def schedule(database_id)
|
31
|
+
def schedule(app_id, database_id, hour: 0o0, timezone: 'UTC')
|
28
32
|
@client.perform_post_request("/client/v11/databases/#{database_id}/transfer-schedules",
|
29
|
-
hour:
|
30
|
-
|
31
|
-
|
33
|
+
{ hour: hour,
|
34
|
+
timezone: timezone,
|
35
|
+
schedule_name: 'DATABASE_URL' }, host: db_host(app_id, database_id))
|
32
36
|
end
|
33
37
|
|
34
|
-
def capture(database_id)
|
35
|
-
@client.perform_post_request("/client/v11/databases/#{database_id}/backups"
|
38
|
+
def capture(app_id, database_id)
|
39
|
+
@client.perform_post_request("/client/v11/databases/#{database_id}/backups",
|
40
|
+
{},
|
41
|
+
host: db_host(app_id, database_id))
|
36
42
|
end
|
37
43
|
|
38
|
-
def url(app_id, backup_num)
|
44
|
+
def url(app_id, backup_num = nil)
|
45
|
+
unless backup_num
|
46
|
+
transfers = list(app_id)
|
47
|
+
last_transfer =
|
48
|
+
transfers.select { |t| t[:succeeded] && t[:to_type] == 'gof3r' }
|
49
|
+
.max_by { |t| t[:created_at] }
|
50
|
+
backup_num = last_transfer[:num]
|
51
|
+
end
|
39
52
|
@client.perform_post_request("/client/v11/apps/#{app_id}/transfers/#{backup_num}/actions/public-url")
|
40
53
|
end
|
41
54
|
|
42
55
|
def wait(app_id, backup_id, options = { wait_interval: 3 })
|
43
|
-
|
56
|
+
backup = nil
|
57
|
+
loop do
|
44
58
|
backup = info(app_id, backup_id)
|
45
59
|
yield(backup) if block_given?
|
46
|
-
break if backup[:finished_at]
|
60
|
+
break if backup[:finished_at]
|
61
|
+
|
47
62
|
sleep(options[:wait_interval])
|
48
63
|
end
|
49
64
|
backup
|
50
65
|
end
|
51
66
|
|
52
|
-
def restore(database_id, backup_url)
|
53
|
-
@client.perform_post_request("/client/v11/databases/#{database_id}/restores",
|
67
|
+
def restore(app_id, database_id, backup_url)
|
68
|
+
@client.perform_post_request("/client/v11/databases/#{database_id}/restores",
|
69
|
+
{ backup_url: backup_url }, host: db_host(app_id, database_id))
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def db_host(app_id, database_id)
|
75
|
+
@client.db_host(app_id, database_id)
|
54
76
|
end
|
55
77
|
end
|
56
78
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Heroku
|
2
4
|
module Api
|
3
5
|
module Postgres
|
@@ -6,9 +8,15 @@ module Heroku
|
|
6
8
|
end
|
7
9
|
|
8
10
|
class Client
|
11
|
+
STARTER_HOST = 'https://postgres-starter-api.heroku.com'
|
12
|
+
PRO_HOST = 'https://postgres-api.heroku.com'
|
13
|
+
|
14
|
+
attr_reader :oauth_client_key, :heroku_client
|
15
|
+
|
9
16
|
def initialize(oauth_client_key)
|
10
17
|
@oauth_client_key = oauth_client_key
|
11
|
-
@basic_url =
|
18
|
+
@basic_url = STARTER_HOST
|
19
|
+
@heroku_client = PlatformAPI.connect_oauth(oauth_client_key)
|
12
20
|
end
|
13
21
|
|
14
22
|
def backups
|
@@ -19,38 +27,53 @@ module Heroku
|
|
19
27
|
@databases ||= Databases.new(self)
|
20
28
|
end
|
21
29
|
|
22
|
-
def
|
23
|
-
|
30
|
+
def credentials
|
31
|
+
@credentials ||= Credentials.new(self)
|
32
|
+
end
|
33
|
+
|
34
|
+
# the database id matches the field `id` in pro plans and the field addon_service.id in free plans
|
35
|
+
def db_host(app_id, database_id)
|
36
|
+
all_addons = heroku_client.addon.list_by_app(app_id)
|
37
|
+
database_json = all_addons.find do |addon|
|
38
|
+
[addon['id'], addon['addon_service']['id']].include?(database_id)
|
39
|
+
end
|
40
|
+
return STARTER_HOST if database_json.nil?
|
41
|
+
|
42
|
+
host_for(database_json)
|
43
|
+
end
|
44
|
+
|
45
|
+
def perform_get_request(path, options = {})
|
46
|
+
url = build_uri(path, **options)
|
24
47
|
req = Net::HTTP::Get.new(url)
|
25
|
-
|
48
|
+
add_auth_headers(req)
|
26
49
|
response = start_request(req, url)
|
27
50
|
parse_response(response)
|
28
51
|
end
|
29
52
|
|
30
|
-
def perform_post_request(path, params = {})
|
31
|
-
url = build_uri(path)
|
53
|
+
def perform_post_request(path, params = {}, options = {})
|
54
|
+
url = build_uri(path, **options)
|
32
55
|
req = Net::HTTP::Post.new(url)
|
33
|
-
|
56
|
+
add_auth_headers(req)
|
34
57
|
req.body = params.to_json
|
35
58
|
response = start_request(req, url)
|
36
59
|
parse_response(response)
|
37
60
|
end
|
38
61
|
|
39
|
-
|
40
|
-
|
62
|
+
private
|
63
|
+
|
64
|
+
def host_for(database_json)
|
65
|
+
starter_plan?(database_json) ? STARTER_HOST : PRO_HOST
|
41
66
|
end
|
42
67
|
|
43
68
|
def starter_plan?(database)
|
44
|
-
database[
|
69
|
+
database['plan']['name'].match(/(dev|basic)$/)
|
45
70
|
end
|
46
71
|
|
47
|
-
private
|
48
|
-
|
49
72
|
def build_uri(path, host: @basic_url)
|
50
73
|
URI.join(host, path)
|
51
74
|
end
|
52
75
|
|
53
|
-
def
|
76
|
+
def add_auth_headers(req)
|
54
77
|
req['Accept'] = 'application/vnd.heroku+json; version=3'
|
55
78
|
req.basic_auth '', @oauth_client_key
|
56
79
|
end
|
@@ -58,7 +81,7 @@ module Heroku
|
|
58
81
|
def start_request(req, url)
|
59
82
|
http_new = Net::HTTP.new(url.hostname, url.port)
|
60
83
|
http_new.use_ssl = true
|
61
|
-
|
84
|
+
http_new.start { |http| http.request(req) }
|
62
85
|
end
|
63
86
|
|
64
87
|
def parse_response(response)
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'net/http'
|
4
|
+
require 'json'
|
5
|
+
require 'platform-api'
|
6
|
+
|
7
|
+
module Heroku
|
8
|
+
module Api
|
9
|
+
module Postgres
|
10
|
+
class Credentials
|
11
|
+
def initialize(client)
|
12
|
+
@client = client
|
13
|
+
end
|
14
|
+
|
15
|
+
# Public: Rotate the database credentials.
|
16
|
+
#
|
17
|
+
# @param app_id [String] the application name.
|
18
|
+
# @param database_id [String] the database UUID.
|
19
|
+
# @param name [String] the credential name to be rotated (default: `default`).
|
20
|
+
def rotate(app_id, database_id, name: 'default')
|
21
|
+
path = "/postgres/v0/databases/#{database_id}/credentials" \
|
22
|
+
"/#{URI.encode_www_form_component(name)}/credentials_rotation"
|
23
|
+
@client.perform_post_request(path, {}, host: db_host(app_id, database_id))
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def db_host(app_id, database_id)
|
29
|
+
@client.db_host(app_id, database_id)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'net/http'
|
2
4
|
require 'json'
|
3
5
|
|
@@ -11,18 +13,25 @@ module Heroku
|
|
11
13
|
|
12
14
|
# original call returns simply a database object, therefore I call the info API.
|
13
15
|
# perform_get_request "/client/v11/databases/#{database_id}/wait_status"
|
14
|
-
def wait(database_id, options = { wait_interval: 3 })
|
16
|
+
def wait(app_id, database_id, options = { wait_interval: 3 })
|
15
17
|
waiting = true
|
16
|
-
while waiting
|
17
|
-
database = info(database_id)
|
18
|
+
while waiting
|
19
|
+
database = info(app_id, database_id)
|
18
20
|
break unless database[:waiting?]
|
21
|
+
|
19
22
|
sleep(options[:wait_interval])
|
20
23
|
end
|
21
24
|
database
|
22
25
|
end
|
23
26
|
|
24
|
-
def info(database_id)
|
25
|
-
@client.perform_get_request("/client/v11/databases/#{database_id}")
|
27
|
+
def info(app_id, database_id)
|
28
|
+
@client.perform_get_request("/client/v11/databases/#{database_id}", host: db_host(app_id, database_id))
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def db_host(app_id, database_id)
|
34
|
+
@client.db_host(app_id, database_id)
|
26
35
|
end
|
27
36
|
end
|
28
37
|
end
|
data/lib/heroku/api/postgres.rb
CHANGED
metadata
CHANGED
@@ -1,29 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: heroku-api-postgres
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alessandro Rodi
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-11-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: platform-api
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: bundler
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
16
30
|
requirements:
|
17
31
|
- - "~>"
|
18
32
|
- !ruby/object:Gem::Version
|
19
|
-
version: '1.
|
33
|
+
version: '1.17'
|
20
34
|
type: :development
|
21
35
|
prerelease: false
|
22
36
|
version_requirements: !ruby/object:Gem::Requirement
|
23
37
|
requirements:
|
24
38
|
- - "~>"
|
25
39
|
- !ruby/object:Gem::Version
|
26
|
-
version: '1.
|
40
|
+
version: '1.17'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: dotenv
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -38,20 +52,34 @@ dependencies:
|
|
38
52
|
- - ">="
|
39
53
|
- !ruby/object:Gem::Version
|
40
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pry
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
41
69
|
- !ruby/object:Gem::Dependency
|
42
70
|
name: rake
|
43
71
|
requirement: !ruby/object:Gem::Requirement
|
44
72
|
requirements:
|
45
73
|
- - "~>"
|
46
74
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
75
|
+
version: '13.0'
|
48
76
|
type: :development
|
49
77
|
prerelease: false
|
50
78
|
version_requirements: !ruby/object:Gem::Requirement
|
51
79
|
requirements:
|
52
80
|
- - "~>"
|
53
81
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
82
|
+
version: '13.0'
|
55
83
|
- !ruby/object:Gem::Dependency
|
56
84
|
name: rspec
|
57
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -72,14 +100,14 @@ dependencies:
|
|
72
100
|
requirements:
|
73
101
|
- - '='
|
74
102
|
- !ruby/object:Gem::Version
|
75
|
-
version: 0.
|
103
|
+
version: 0.60.0
|
76
104
|
type: :development
|
77
105
|
prerelease: false
|
78
106
|
version_requirements: !ruby/object:Gem::Requirement
|
79
107
|
requirements:
|
80
108
|
- - '='
|
81
109
|
- !ruby/object:Gem::Version
|
82
|
-
version: 0.
|
110
|
+
version: 0.60.0
|
83
111
|
- !ruby/object:Gem::Dependency
|
84
112
|
name: vcr
|
85
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -116,16 +144,19 @@ extensions: []
|
|
116
144
|
extra_rdoc_files: []
|
117
145
|
files:
|
118
146
|
- ".example.env"
|
147
|
+
- ".github/FUNDING.yml"
|
119
148
|
- ".gitignore"
|
120
149
|
- ".rspec"
|
121
150
|
- ".rubocop.yml"
|
151
|
+
- ".ruby-version"
|
122
152
|
- ".travis.yml"
|
153
|
+
- CHANGELOG.md
|
123
154
|
- CODE_OF_CONDUCT.md
|
124
155
|
- Gemfile
|
125
|
-
- Gemfile.lock
|
126
156
|
- LICENSE.txt
|
127
157
|
- README.md
|
128
158
|
- Rakefile
|
159
|
+
- bin/check
|
129
160
|
- bin/console
|
130
161
|
- bin/setup
|
131
162
|
- docs/models.md
|
@@ -134,13 +165,18 @@ files:
|
|
134
165
|
- lib/heroku/api/postgres.rb
|
135
166
|
- lib/heroku/api/postgres/backups.rb
|
136
167
|
- lib/heroku/api/postgres/client.rb
|
168
|
+
- lib/heroku/api/postgres/credentials.rb
|
137
169
|
- lib/heroku/api/postgres/databases.rb
|
138
170
|
- lib/heroku/api/postgres/version.rb
|
139
171
|
homepage: https://github.com/coorasse/heroku-api-postgres
|
140
172
|
licenses:
|
141
173
|
- MIT
|
142
|
-
metadata:
|
143
|
-
|
174
|
+
metadata:
|
175
|
+
homepage_uri: https://github.com/coorasse/heroku-api-postgres
|
176
|
+
source_code_uri: https://github.com/coorasse/heroku-api-postgres
|
177
|
+
changelog_uri: https://github.com/coorasse/heroku-api-postgres/blob/main/CHANGELOG.md
|
178
|
+
funding_uri: https://github.com/sponsors/coorasse
|
179
|
+
post_install_message:
|
144
180
|
rdoc_options: []
|
145
181
|
require_paths:
|
146
182
|
- lib
|
@@ -155,9 +191,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
155
191
|
- !ruby/object:Gem::Version
|
156
192
|
version: '0'
|
157
193
|
requirements: []
|
158
|
-
|
159
|
-
|
160
|
-
signing_key:
|
194
|
+
rubygems_version: 3.3.10
|
195
|
+
signing_key:
|
161
196
|
specification_version: 4
|
162
197
|
summary: Ruby library to invoke Heroku Postgres APIs
|
163
198
|
test_files: []
|
data/Gemfile.lock
DELETED
@@ -1,67 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
heroku-api-postgres (0.9.0)
|
5
|
-
|
6
|
-
GEM
|
7
|
-
remote: https://rubygems.org/
|
8
|
-
specs:
|
9
|
-
addressable (2.5.2)
|
10
|
-
public_suffix (>= 2.0.2, < 4.0)
|
11
|
-
ast (2.4.0)
|
12
|
-
crack (0.4.3)
|
13
|
-
safe_yaml (~> 1.0.0)
|
14
|
-
diff-lcs (1.3)
|
15
|
-
dotenv (2.2.1)
|
16
|
-
hashdiff (0.3.7)
|
17
|
-
parallel (1.12.1)
|
18
|
-
parser (2.5.0.2)
|
19
|
-
ast (~> 2.4.0)
|
20
|
-
powerpack (0.1.1)
|
21
|
-
public_suffix (3.0.2)
|
22
|
-
rainbow (3.0.0)
|
23
|
-
rake (10.5.0)
|
24
|
-
rspec (3.7.0)
|
25
|
-
rspec-core (~> 3.7.0)
|
26
|
-
rspec-expectations (~> 3.7.0)
|
27
|
-
rspec-mocks (~> 3.7.0)
|
28
|
-
rspec-core (3.7.1)
|
29
|
-
rspec-support (~> 3.7.0)
|
30
|
-
rspec-expectations (3.7.0)
|
31
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
32
|
-
rspec-support (~> 3.7.0)
|
33
|
-
rspec-mocks (3.7.0)
|
34
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
35
|
-
rspec-support (~> 3.7.0)
|
36
|
-
rspec-support (3.7.1)
|
37
|
-
rubocop (0.52.1)
|
38
|
-
parallel (~> 1.10)
|
39
|
-
parser (>= 2.4.0.2, < 3.0)
|
40
|
-
powerpack (~> 0.1)
|
41
|
-
rainbow (>= 2.2.2, < 4.0)
|
42
|
-
ruby-progressbar (~> 1.7)
|
43
|
-
unicode-display_width (~> 1.0, >= 1.0.1)
|
44
|
-
ruby-progressbar (1.9.0)
|
45
|
-
safe_yaml (1.0.4)
|
46
|
-
unicode-display_width (1.3.0)
|
47
|
-
vcr (4.0.0)
|
48
|
-
webmock (3.3.0)
|
49
|
-
addressable (>= 2.3.6)
|
50
|
-
crack (>= 0.3.2)
|
51
|
-
hashdiff
|
52
|
-
|
53
|
-
PLATFORMS
|
54
|
-
ruby
|
55
|
-
|
56
|
-
DEPENDENCIES
|
57
|
-
bundler (~> 1.16)
|
58
|
-
dotenv
|
59
|
-
heroku-api-postgres!
|
60
|
-
rake (~> 10.0)
|
61
|
-
rspec (~> 3.0)
|
62
|
-
rubocop (= 0.52.1)
|
63
|
-
vcr (~> 4.0.0)
|
64
|
-
webmock (~> 3.3.0)
|
65
|
-
|
66
|
-
BUNDLED WITH
|
67
|
-
1.16.2
|