heroku-api-postgres 0.13.1 → 0.14.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/CHANGELOG.md +12 -0
- data/README.md +7 -7
- data/docs/services.md +7 -49
- data/lib/heroku/api/postgres/backups.rb +8 -17
- data/lib/heroku/api/postgres/client.rb +9 -30
- data/lib/heroku/api/postgres/credentials.rb +2 -7
- data/lib/heroku/api/postgres/databases.rb +4 -10
- data/lib/heroku/api/postgres/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c3e288c214dd07ce53ec130af58ba3c9ecb29fde19862f80f6ede9e1d8b844ff
|
|
4
|
+
data.tar.gz: 6ffb07ca048f339b2563e8e07b2611589d1785ff0ba51e12f5f543753d0f078d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8e543d935c8f2bf2412894ff8eae50cdc33a18ca725b87a59f32f05b8ff9f859c0817f201c759509f7c35df5557eab3e58bd9d413bb64487ee810aad76d88c93
|
|
7
|
+
data.tar.gz: 9ac5dcc55c561c545d9ae74e1274f2c6c2574d7692c52a7928642312a99fdb4004461ac46f763ff752cf22cf590f4f5b727bad43e6b929f3093033e64a8132c0
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
## 0.14.0
|
|
2
|
+
|
|
3
|
+
* [#24](https://github.com/coorasse/heroku-api-postgres/pull/24): **Breaking change**: Remove `app_id` from the following methods ([@hunchr]):
|
|
4
|
+
* `client.backups.capture(database_id)`
|
|
5
|
+
* `client.backups.restore(database_id, backup_url)`
|
|
6
|
+
* `client.backups.schedule(database_id)`
|
|
7
|
+
* `client.backups.schedules(database_id)`
|
|
8
|
+
* `client.credentials.rotate(database_id)`
|
|
9
|
+
* `client.databases.info(database_id)`
|
|
10
|
+
* `client.databases.wait(database_id)`
|
|
11
|
+
|
|
1
12
|
## 0.13.0
|
|
2
13
|
|
|
3
14
|
* Update of dependencies and minimum ruby version set to 3.2.7. ([@coorasse][])
|
|
@@ -13,4 +24,5 @@
|
|
|
13
24
|
[@avokhmin]: https://github.com/avokhmin
|
|
14
25
|
[@deepakmahakale]: https://github.com/deepakmahakale
|
|
15
26
|
[@louism517]: https://github.com/louism517
|
|
27
|
+
[@hunchr]: https://github.com/hunchr
|
|
16
28
|
[@coorasse]: https://github.com/coorasse
|
data/README.md
CHANGED
|
@@ -60,7 +60,7 @@ databases_client = postgres_api_client.databases
|
|
|
60
60
|
---
|
|
61
61
|
|
|
62
62
|
```ruby
|
|
63
|
-
database_info = databases_client.info(
|
|
63
|
+
database_info = databases_client.info(database_id)
|
|
64
64
|
```
|
|
65
65
|
|
|
66
66
|
returns a [Database](docs/models.md#database).
|
|
@@ -68,7 +68,7 @@ returns a [Database](docs/models.md#database).
|
|
|
68
68
|
---
|
|
69
69
|
|
|
70
70
|
```ruby
|
|
71
|
-
database = postgres_api_client.databases.wait(
|
|
71
|
+
database = postgres_api_client.databases.wait(database_id, wait_interval: 5)
|
|
72
72
|
```
|
|
73
73
|
|
|
74
74
|
Waits for the given database to be ready.
|
|
@@ -84,7 +84,7 @@ credentials_client = postgres_api_client.credentials
|
|
|
84
84
|
---
|
|
85
85
|
|
|
86
86
|
```ruby
|
|
87
|
-
credentials_client.rotate(
|
|
87
|
+
credentials_client.rotate(database_id)
|
|
88
88
|
```
|
|
89
89
|
|
|
90
90
|
Rotate the database credentials.
|
|
@@ -121,7 +121,7 @@ To retrieve the APP_ID and DATABASE_ID needed to run the tests you can use the n
|
|
|
121
121
|
---
|
|
122
122
|
|
|
123
123
|
```ruby
|
|
124
|
-
schedules = backups_client.schedules(
|
|
124
|
+
schedules = backups_client.schedules(database_id)
|
|
125
125
|
```
|
|
126
126
|
|
|
127
127
|
Returns all the backup schedules associated with the database.
|
|
@@ -131,7 +131,7 @@ Returns an array of [Schedule](docs/models.md#schedule)
|
|
|
131
131
|
---
|
|
132
132
|
|
|
133
133
|
```ruby
|
|
134
|
-
schedule = backups_client.schedule(
|
|
134
|
+
schedule = backups_client.schedule(database_id)
|
|
135
135
|
```
|
|
136
136
|
|
|
137
137
|
Schedules the backups at 00:00 UTC.
|
|
@@ -142,7 +142,7 @@ Returns a [Schedule](docs/models.md#schedule)
|
|
|
142
142
|
|
|
143
143
|
|
|
144
144
|
```ruby
|
|
145
|
-
backup = backups_client.capture(
|
|
145
|
+
backup = backups_client.capture(database_id)
|
|
146
146
|
```
|
|
147
147
|
Captures a new backup for the given database
|
|
148
148
|
|
|
@@ -160,7 +160,7 @@ Returns a [BackupUrl](docs/models.md#backup_url)
|
|
|
160
160
|
---
|
|
161
161
|
|
|
162
162
|
```ruby
|
|
163
|
-
backup = backups_client.restore(
|
|
163
|
+
backup = backups_client.restore(database_id, dump_url)
|
|
164
164
|
```
|
|
165
165
|
Restores a dump from a public URL.
|
|
166
166
|
|
data/docs/services.md
CHANGED
|
@@ -3,98 +3,56 @@
|
|
|
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(
|
|
7
|
-
|
|
6
|
+
- [x] pg --> `client.databases.info(database_id)`
|
|
8
7
|
- [x] pg:backups --> `client.backups.list(app_id)`
|
|
9
|
-
|
|
10
8
|
- [ ] pg:backups:cancel
|
|
11
|
-
|
|
12
|
-
- [x] pg:backups:capture ---> `client.backups.capture(app_id, database_id)`
|
|
9
|
+
- [x] pg:backups:capture ---> `client.backups.capture(database_id)`
|
|
13
10
|
The command returns immediately, without waiting for the capture to be completed.
|
|
14
11
|
`--wait-interval` not implemented. `--snapshot` not implemented.
|
|
15
12
|
|
|
16
13
|
- [ ] pg:backups:delete
|
|
17
|
-
|
|
18
14
|
- [ ] pg:backups:download
|
|
19
|
-
|
|
20
15
|
- [x] pg:backups:info --> `client.backups.info(app_id, backup_id)`
|
|
21
|
-
|
|
22
|
-
- [x] pg:backups:restore --> `client.backups.restore(app_id, database_id, dump_url)`
|
|
16
|
+
- [x] pg:backups:restore --> `client.backups.restore(database_id, backup_url)`
|
|
23
17
|
The command works only with public URLs. It does not support all the features of the original
|
|
24
18
|
`heroku pg:backups:restore` command, like restoring directly from another database.
|
|
25
19
|
The command returns immediately, without waiting for the capture to be completed.
|
|
26
20
|
You can use the command `client.backups.wait(app_id, restore[:num])` to wait for it to be ready.
|
|
27
21
|
|
|
28
|
-
- [x] pg:backups:schedule --> `client.backups.schedule(
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
- [x] pg:backups:schedules --> `client.backups.schedules(app_id, database_id)`
|
|
32
|
-
|
|
22
|
+
- [x] pg:backups:schedule --> `client.backups.schedule(database_id)`
|
|
23
|
+
- [x] pg:backups:schedules --> `client.backups.schedules(database_id)`
|
|
33
24
|
- [ ] pg:backups:unschedule
|
|
34
|
-
|
|
35
25
|
- [x] pg:backups:url --> `client.backups.url(app_id, backup_num)`
|
|
36
|
-
|
|
37
26
|
- [ ] pg:connection-pooling:attach
|
|
38
|
-
|
|
39
27
|
- [ ] pg:copy
|
|
40
|
-
|
|
41
28
|
- [ ] pg:credentials
|
|
42
|
-
|
|
43
29
|
- [ ] pg:credentials:create
|
|
44
|
-
|
|
45
30
|
- [ ] pg:credentials:destroy
|
|
46
|
-
|
|
47
31
|
- [ ] pg:credentials:repair-default
|
|
48
|
-
|
|
49
|
-
- [x] pg:credentials:rotate --> `client.credentials.rotate(app_id, database_id)`
|
|
50
|
-
|
|
32
|
+
- [x] pg:credentials:rotate --> `client.credentials.rotate(database_id)`
|
|
51
33
|
- [ ] pg:credentials:url
|
|
52
|
-
|
|
53
34
|
- [ ] pg:diagnose
|
|
54
|
-
|
|
55
|
-
- [x] pg:info --> `client.databases.info(app_id, database_id)`
|
|
56
|
-
|
|
35
|
+
- [x] pg:info --> `client.databases.info(database_id)`
|
|
57
36
|
- [ ] pg:kill
|
|
58
|
-
|
|
59
37
|
- [ ] pg:killall
|
|
60
|
-
|
|
61
38
|
- [ ] pg:links
|
|
62
|
-
|
|
63
39
|
- [ ] pg:links:create
|
|
64
|
-
|
|
65
40
|
- [ ] pg:links:destroy
|
|
66
|
-
|
|
67
41
|
- [ ] pg:maintenance
|
|
68
|
-
|
|
69
42
|
- [ ] pg:maintenance:run
|
|
70
|
-
|
|
71
43
|
- [ ] pg:maintenance:window
|
|
72
|
-
|
|
73
44
|
- [ ] pg:outliers
|
|
74
|
-
|
|
75
45
|
- [ ] pg:promote
|
|
76
|
-
|
|
77
46
|
- [ ] pg:ps
|
|
78
|
-
|
|
79
47
|
- [ ] pg:psql
|
|
80
|
-
|
|
81
48
|
- [ ] pg:pull
|
|
82
|
-
|
|
83
49
|
- [ ] pg:push
|
|
84
|
-
|
|
85
50
|
- [ ] pg:reset
|
|
86
|
-
|
|
87
51
|
- [ ] pg:settings
|
|
88
|
-
|
|
89
52
|
- [ ] pg:settings:log-lock-waits
|
|
90
|
-
|
|
91
53
|
- [ ] pg:settings:log-min-duration-statement
|
|
92
|
-
|
|
93
54
|
- [ ] pg:settings:log-statement
|
|
94
|
-
|
|
95
55
|
- [ ] pg:unfollow
|
|
96
|
-
|
|
97
56
|
- [ ] pg:upgrade
|
|
98
|
-
|
|
99
57
|
- [x] pg:wait --> `client.wait(app_id, database_id)`
|
|
100
58
|
Waits for a database to be ready.
|
|
@@ -23,22 +23,19 @@ module Heroku
|
|
|
23
23
|
@client.perform_get_request("/client/v11/apps/#{app_id}/transfers/#{backup_id}")
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
-
def schedules(
|
|
27
|
-
@client.perform_get_request("/client/v11/databases/#{database_id}/transfer-schedules"
|
|
28
|
-
host: db_host(app_id, database_id))
|
|
26
|
+
def schedules(database_id)
|
|
27
|
+
@client.perform_get_request("/client/v11/databases/#{database_id}/transfer-schedules")
|
|
29
28
|
end
|
|
30
29
|
|
|
31
|
-
def schedule(
|
|
30
|
+
def schedule(database_id, hour: 0, timezone: 'UTC')
|
|
32
31
|
@client.perform_post_request("/client/v11/databases/#{database_id}/transfer-schedules",
|
|
33
32
|
{ hour: hour,
|
|
34
33
|
timezone: timezone,
|
|
35
|
-
schedule_name: 'DATABASE_URL' }
|
|
34
|
+
schedule_name: 'DATABASE_URL' })
|
|
36
35
|
end
|
|
37
36
|
|
|
38
|
-
def capture(
|
|
39
|
-
@client.perform_post_request("/client/v11/databases/#{database_id}/backups",
|
|
40
|
-
options,
|
|
41
|
-
host: db_host(app_id, database_id))
|
|
37
|
+
def capture(database_id, options = {})
|
|
38
|
+
@client.perform_post_request("/client/v11/databases/#{database_id}/backups", options)
|
|
42
39
|
end
|
|
43
40
|
|
|
44
41
|
def url(app_id, backup_num = nil)
|
|
@@ -64,15 +61,9 @@ module Heroku
|
|
|
64
61
|
backup
|
|
65
62
|
end
|
|
66
63
|
|
|
67
|
-
def restore(
|
|
64
|
+
def restore(database_id, backup_url)
|
|
68
65
|
@client.perform_post_request("/client/v11/databases/#{database_id}/restores",
|
|
69
|
-
{ backup_url: backup_url }
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
private
|
|
73
|
-
|
|
74
|
-
def db_host(app_id, database_id)
|
|
75
|
-
@client.db_host(app_id, database_id)
|
|
66
|
+
{ backup_url: backup_url })
|
|
76
67
|
end
|
|
77
68
|
end
|
|
78
69
|
end
|
|
@@ -4,26 +4,24 @@ module Heroku
|
|
|
4
4
|
module Api
|
|
5
5
|
module Postgres
|
|
6
6
|
def self.connect(api_key = ENV.fetch('HEROKU_API_KEY', nil))
|
|
7
|
-
Client.new
|
|
7
|
+
Client.new.tap do |c|
|
|
8
|
+
c.api_key = api_key
|
|
8
9
|
c.heroku_client = PlatformAPI.connect(api_key)
|
|
9
10
|
end
|
|
10
11
|
end
|
|
11
12
|
|
|
12
13
|
def self.connect_oauth(oauth_client_key = ENV.fetch('HEROKU_OAUTH_TOKEN', nil))
|
|
13
|
-
Client.new
|
|
14
|
+
Client.new.tap do |c|
|
|
15
|
+
c.oauth_client_key = oauth_client_key
|
|
14
16
|
c.heroku_client = PlatformAPI.connect_oauth(oauth_client_key)
|
|
15
17
|
end
|
|
16
18
|
end
|
|
17
19
|
|
|
18
20
|
class Client
|
|
19
|
-
|
|
20
|
-
PRO_HOST = 'https://postgres-api.heroku.com'
|
|
21
|
+
attr_accessor :api_key, :api_host, :oauth_client_key, :heroku_client
|
|
21
22
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
def initialize(client_key)
|
|
25
|
-
@client_key = client_key
|
|
26
|
-
@basic_url = STARTER_HOST
|
|
23
|
+
def initialize
|
|
24
|
+
@api_host = 'https://postgres-api.heroku.com'
|
|
27
25
|
end
|
|
28
26
|
|
|
29
27
|
def backups
|
|
@@ -38,17 +36,6 @@ module Heroku
|
|
|
38
36
|
@credentials ||= Credentials.new(self)
|
|
39
37
|
end
|
|
40
38
|
|
|
41
|
-
# the database id matches the field `id` in pro plans and the field addon_service.id in free plans
|
|
42
|
-
def db_host(app_id, database_id)
|
|
43
|
-
all_addons = heroku_client.addon.list_by_app(app_id)
|
|
44
|
-
database_json = all_addons.find do |addon|
|
|
45
|
-
[addon['id'], addon['addon_service']['id']].include?(database_id)
|
|
46
|
-
end
|
|
47
|
-
return STARTER_HOST if database_json.nil?
|
|
48
|
-
|
|
49
|
-
host_for(database_json)
|
|
50
|
-
end
|
|
51
|
-
|
|
52
39
|
def perform_get_request(path, options = {})
|
|
53
40
|
url = build_uri(path, **options)
|
|
54
41
|
req = Net::HTTP::Get.new(url)
|
|
@@ -68,21 +55,13 @@ module Heroku
|
|
|
68
55
|
|
|
69
56
|
private
|
|
70
57
|
|
|
71
|
-
def
|
|
72
|
-
starter_plan?(database_json) ? STARTER_HOST : PRO_HOST
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
def starter_plan?(database)
|
|
76
|
-
database['plan']['name'].match(/(dev|basic)$/)
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
def build_uri(path, host: @basic_url)
|
|
58
|
+
def build_uri(path, host: api_host)
|
|
80
59
|
URI.join(host, path)
|
|
81
60
|
end
|
|
82
61
|
|
|
83
62
|
def add_auth_headers(req)
|
|
84
63
|
req['Accept'] = 'application/vnd.heroku+json; version=3'
|
|
85
|
-
req.basic_auth '', @
|
|
64
|
+
req.basic_auth '', @oauth_client_key
|
|
86
65
|
end
|
|
87
66
|
|
|
88
67
|
def start_request(req, url)
|
|
@@ -17,16 +17,11 @@ module Heroku
|
|
|
17
17
|
# @param app_id [String] the application name.
|
|
18
18
|
# @param database_id [String] the database UUID.
|
|
19
19
|
# @param name [String] the credential name to be rotated (default: `default`).
|
|
20
|
-
def rotate(
|
|
20
|
+
def rotate(database_id, name: 'default')
|
|
21
21
|
path = "/postgres/v0/databases/#{database_id}/credentials" \
|
|
22
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
23
|
|
|
28
|
-
|
|
29
|
-
@client.db_host(app_id, database_id)
|
|
24
|
+
@client.perform_post_request(path, {})
|
|
30
25
|
end
|
|
31
26
|
end
|
|
32
27
|
end
|
|
@@ -13,10 +13,10 @@ module Heroku
|
|
|
13
13
|
|
|
14
14
|
# original call returns simply a database object, therefore I call the info API.
|
|
15
15
|
# perform_get_request "/client/v11/databases/#{database_id}/wait_status"
|
|
16
|
-
def wait(
|
|
16
|
+
def wait(database_id, options = { wait_interval: 3 })
|
|
17
17
|
waiting = true
|
|
18
18
|
while waiting
|
|
19
|
-
database = info(
|
|
19
|
+
database = info(database_id)
|
|
20
20
|
break unless database[:waiting?]
|
|
21
21
|
|
|
22
22
|
sleep(options[:wait_interval])
|
|
@@ -24,14 +24,8 @@ module Heroku
|
|
|
24
24
|
database
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
-
def info(
|
|
28
|
-
@client.perform_get_request("/client/v11/databases/#{database_id}"
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
private
|
|
32
|
-
|
|
33
|
-
def db_host(app_id, database_id)
|
|
34
|
-
@client.db_host(app_id, database_id)
|
|
27
|
+
def info(database_id)
|
|
28
|
+
@client.perform_get_request("/client/v11/databases/#{database_id}")
|
|
35
29
|
end
|
|
36
30
|
end
|
|
37
31
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
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.14.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Alessandro Rodi
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2026-02-12 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: platform-api
|