fly_io 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/CHANGELOG.md +15 -0
- data/CONTRIBUTING.md +14 -0
- data/LICENSE +21 -0
- data/README.md +239 -0
- data/Rakefile +30 -0
- data/contracts/additional_rest/network_policies.json +94 -0
- data/contracts/additional_rest/prometheus.json +103 -0
- data/contracts/graphql/fly_go_operations.json +948 -0
- data/contracts/graphql/flyctl_named_operations.graphql +316 -0
- data/contracts/graphql/flyctl_operations.json +336 -0
- data/contracts/graphql/official_examples.json +75 -0
- data/contracts/graphql/schema.graphql +10995 -0
- data/contracts/graphql/source.json +29 -0
- data/contracts/machines/openapi.headers +9 -0
- data/contracts/machines/openapi.json +1 -0
- data/contracts/machines/source.json +20 -0
- data/contracts/public_surface_inventory.json +164 -0
- data/contracts/research_metadata.json +17 -0
- data/contracts/sources/metrics.html.md +474 -0
- data/contracts/sources/network-policies.html.markerb +142 -0
- data/docs/API.md +149 -0
- data/docs/SURFACES.md +60 -0
- data/lib/fly_io/client.rb +52 -0
- data/lib/fly_io/configuration.rb +115 -0
- data/lib/fly_io/errors.rb +45 -0
- data/lib/fly_io/generated/additional_operations.json +123 -0
- data/lib/fly_io/generated/graphql_operations.json +1658 -0
- data/lib/fly_io/generated/operations.json +6130 -0
- data/lib/fly_io/generated/prometheus_operations.json +503 -0
- data/lib/fly_io/generated/schemas.json +4237 -0
- data/lib/fly_io/graphql_client.rb +103 -0
- data/lib/fly_io/model.rb +65 -0
- data/lib/fly_io/operation_registry.rb +79 -0
- data/lib/fly_io/redactor.rb +34 -0
- data/lib/fly_io/resources/base.rb +68 -0
- data/lib/fly_io/resources.rb +30 -0
- data/lib/fly_io/response.rb +45 -0
- data/lib/fly_io/schema_registry.rb +89 -0
- data/lib/fly_io/schema_validator.rb +56 -0
- data/lib/fly_io/transport.rb +282 -0
- data/lib/fly_io/version.rb +5 -0
- data/lib/fly_io.rb +23 -0
- data/script/check_api_coverage +60 -0
- data/script/fetch_openapi +18 -0
- data/script/generate_api +302 -0
- metadata +197 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 4dd8c23a72b3368728387726a4f9c0f549f964c73031fd210f8a452e0b635fed
|
|
4
|
+
data.tar.gz: 5c7cde4c9562e3a5e422b31c253f62eaa27de501e4ee80ef2a045c4934444f46
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 537aacc7de6c237c6acfb03107d96c4244ba0e94338e819ec5ac9bd16ca2af122b25abcc143f9e58eee2eeb43d35f70b990f120546266c1db87417ab9eb142a3
|
|
7
|
+
data.tar.gz: 18fb6ba50789303ed0b90154dd650822accbd1c21d4852afbd3bec80876b21167e5597e2f2b5c714c8acff081c17145c46038897eac192d6b1ed2f38a753b2fe
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes follow [Keep a Changelog](https://keepachangelog.com/) and Semantic Versioning.
|
|
4
|
+
|
|
5
|
+
## [Unreleased]
|
|
6
|
+
|
|
7
|
+
## [0.1.0] - 2026-08-26
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- Complete generated coverage of the Fly Machines OpenAPI contract: 98 operations and 173 schemas.
|
|
12
|
+
- Documentation-derived Network Policies client.
|
|
13
|
+
- Seven-family Fly Prometheus compatibility client.
|
|
14
|
+
- Raw GraphQL client and explicitly experimental flyctl/fly-go/official operation inventory.
|
|
15
|
+
- Typed responses, redaction, bounded safe retries, contract drift gates, offline tests, and packaging/CI workflows.
|
data/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Use Ruby 4.0.6 for development. Run `bundle install`, then `bundle exec rake` before opening a change.
|
|
4
|
+
|
|
5
|
+
API changes start from committed evidence, not handwritten endpoint lists:
|
|
6
|
+
|
|
7
|
+
1. Run `bundle exec rake api:fetch_check` to detect Machines OpenAPI drift.
|
|
8
|
+
2. Review upstream changes and update the relevant snapshot plus provenance/hash.
|
|
9
|
+
3. Run `bundle exec rake api:generate`.
|
|
10
|
+
4. Add readable behavior coverage when semantics or risk changes.
|
|
11
|
+
5. Run `bundle exec rake`, `bundle exec bundle-audit check --update`, and the install smoke test.
|
|
12
|
+
|
|
13
|
+
Do not add undocumented flyctl calls to the stable namespace. GraphQL evidence stays experimental. Never commit tokens,
|
|
14
|
+
live response cassettes, credentials, or unredacted debug output.
|
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Vito Botta
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
# fly_io
|
|
2
|
+
|
|
3
|
+
`fly_io` is a contract-driven Ruby client for Fly.io’s documented platform APIs. It covers every operation in the
|
|
4
|
+
Machines REST OpenAPI contract, the documentation-only Network Policies endpoints, Fly’s Prometheus compatibility
|
|
5
|
+
endpoint, and Fly’s explicitly unstable control-plane GraphQL boundary.
|
|
6
|
+
|
|
7
|
+
The Ruby namespace is `FlyIO`. The gem name was unclaimed on RubyGems when checked on 2026-08-26; see
|
|
8
|
+
[`contracts/research_metadata.json`](contracts/research_metadata.json). This repository is not published by or
|
|
9
|
+
affiliated with Fly.io.
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
Add the gem to your bundle:
|
|
14
|
+
|
|
15
|
+
```ruby
|
|
16
|
+
gem "fly_io", "~> 0.1"
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Then run `bundle install`. Ruby 3.2 or newer is supported. Development and the primary CI job use Ruby 4.0.6, the
|
|
20
|
+
latest stable release verified from ruby-lang.org on the contract retrieval date.
|
|
21
|
+
|
|
22
|
+
The sole runtime dependency is Faraday 2.x. It provides a maintained, adapter-injectable HTTP foundation; retries,
|
|
23
|
+
redaction, contract mapping, and model coercion are implemented in this gem so their behavior remains explicit.
|
|
24
|
+
|
|
25
|
+
## Quickstart
|
|
26
|
+
|
|
27
|
+
```ruby
|
|
28
|
+
require "fly_io"
|
|
29
|
+
|
|
30
|
+
client = FlyIO::Client.new(token: ENV.fetch("FLY_API_TOKEN"))
|
|
31
|
+
|
|
32
|
+
apps = client.apps.list(org_slug: "personal")
|
|
33
|
+
machine = client.machines.create(
|
|
34
|
+
app_name: "my-app",
|
|
35
|
+
body: {
|
|
36
|
+
region: "iad",
|
|
37
|
+
config: {
|
|
38
|
+
image: "registry.example.com/my-image:latest",
|
|
39
|
+
guest: {cpu_kind: "shared", cpus: 1, memory_mb: 512}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
client.machines.start(app_name: "my-app", machine_id: machine.id)
|
|
45
|
+
client.machines.wait(app_name: "my-app", machine_id: machine.id, state: "started", timeout: 60)
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Resource methods return `FlyIO::Response`. `response.body` is coerced to the documented `FlyIO::Models::*` class (or
|
|
49
|
+
an array/primitive where the contract says so), while response methods delegate to a model for concise code such as
|
|
50
|
+
`machine.id`. Models keep unknown fields and preserve exact wire keys for forward compatibility.
|
|
51
|
+
|
|
52
|
+
All named endpoint inputs are keyword arguments. JSON request bodies use `body:` because this gives every generated
|
|
53
|
+
operation one consistent signature. The generated [complete API reference](docs/API.md) maps each Ruby method to the
|
|
54
|
+
official operation ID, method, and path.
|
|
55
|
+
|
|
56
|
+
## Authentication
|
|
57
|
+
|
|
58
|
+
The official Machines guide and current examples use `Authorization: Bearer <token>`. The generated reference also
|
|
59
|
+
contains contradictory `FlyV1` prose. Consequently, a raw token uses `Bearer` by default and preformatted values are
|
|
60
|
+
explicit:
|
|
61
|
+
|
|
62
|
+
```ruby
|
|
63
|
+
FlyIO::Client.new(token: ENV.fetch("FLY_API_TOKEN"))
|
|
64
|
+
FlyIO::Client.new(authorization: "FlyV1 #{ENV.fetch("FLY_MACAROON")}")
|
|
65
|
+
FlyIO::Client.new(token: ENV.fetch("FLY_MACAROON"), authorization_mode: :fly_v1)
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
A token passed to `token:` must be raw, so `Bearer Bearer ...` cannot be produced accidentally. Authorization values,
|
|
69
|
+
tokens, secrets, passwords, credentials, private keys, and certificates are filtered from logs, request metadata, and
|
|
70
|
+
exceptions.
|
|
71
|
+
|
|
72
|
+
## Configuration and transport behavior
|
|
73
|
+
|
|
74
|
+
```ruby
|
|
75
|
+
configuration = FlyIO::Configuration.new(
|
|
76
|
+
token: ENV.fetch("FLY_API_TOKEN"),
|
|
77
|
+
base_url: "https://api.machines.dev", # or http://_api.internal:4280 on the Fly private network
|
|
78
|
+
graphql_url: "https://api.fly.io/graphql",
|
|
79
|
+
metrics_url: "https://api.fly.io",
|
|
80
|
+
open_timeout: 10,
|
|
81
|
+
read_timeout: 30,
|
|
82
|
+
write_timeout: 30,
|
|
83
|
+
request_timeout: 45,
|
|
84
|
+
proxy: ENV["HTTPS_PROXY"],
|
|
85
|
+
user_agent: "my-service/1.0 fly_io/#{FlyIO::VERSION}",
|
|
86
|
+
max_retries: 2,
|
|
87
|
+
base_retry_interval: 0.25,
|
|
88
|
+
max_retry_interval: 5,
|
|
89
|
+
retry_jitter: 0.25,
|
|
90
|
+
logger: Logger.new($stderr)
|
|
91
|
+
)
|
|
92
|
+
client = FlyIO::Client.new(configuration)
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
TLS verification is always enabled by the HTTP adapter. The client parses JSON only when the response content type is
|
|
96
|
+
JSON, represents 204 as a nil body, preserves 202 responses, and safely returns text, binary, empty, or malformed JSON
|
|
97
|
+
bodies. `FlyIO::Response` includes status, headers, parsed body, raw body, safe request metadata, and Fly’s request ID.
|
|
98
|
+
|
|
99
|
+
GET/HEAD/OPTIONS requests retry bounded transient connection failures and 408, 429, 500, 502, 503, and 504 responses.
|
|
100
|
+
`Retry-After` is honored; otherwise delay uses capped exponential backoff with jitter. Unsafe methods are never retried
|
|
101
|
+
unless a caller passes `retry_unsafe: true` to that request or deliberately enables it globally. Fly’s limits are
|
|
102
|
+
per-action and per-resource, so this gem does not pretend a single client-wide throttle is correct.
|
|
103
|
+
|
|
104
|
+
Configuration and resource objects are immutable. All request state is local, making a client safe to share between
|
|
105
|
+
threads. An object responding to `call(method:, url:, headers:, body:, timeout:)` can be supplied as `adapter:` for
|
|
106
|
+
dependency injection; a Faraday adapter symbol is also accepted.
|
|
107
|
+
|
|
108
|
+
## Errors
|
|
109
|
+
|
|
110
|
+
All failures inherit `FlyIO::Error`. HTTP failures use `FlyIO::APIError` and its typed subclasses:
|
|
111
|
+
|
|
112
|
+
- `AuthenticationError` / `AuthorizationError`
|
|
113
|
+
- `NotFoundError`
|
|
114
|
+
- `ValidationError`
|
|
115
|
+
- `RateLimitError`
|
|
116
|
+
- `RequestTimeoutError`
|
|
117
|
+
- `TransportError`
|
|
118
|
+
- `ServerError`
|
|
119
|
+
- `GraphQLError`
|
|
120
|
+
|
|
121
|
+
API errors retain status, safe headers, redacted parsed details, request ID, and redacted request metadata.
|
|
122
|
+
|
|
123
|
+
## Raw REST and operation-ID access
|
|
124
|
+
|
|
125
|
+
Use a path template when values are dynamic so every component is escaped independently:
|
|
126
|
+
|
|
127
|
+
```ruby
|
|
128
|
+
client.request(
|
|
129
|
+
method: :get,
|
|
130
|
+
path: "/v1/apps/{app_name}/machines",
|
|
131
|
+
path_params: {app_name: "my-app"},
|
|
132
|
+
query: {state: "started"}
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
client.operation("Machines_start", app_name: "my-app", machine_id: "machine-id")
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
The low-level API validates the method, rejects path traversal and URL-shaped paths, supports repeated query values,
|
|
139
|
+
and returns the same response/errors as resource methods. The upstream duplicate `Machines_update_metadata` ID must be
|
|
140
|
+
disambiguated with `method:` and `path:`.
|
|
141
|
+
|
|
142
|
+
## Network Policies
|
|
143
|
+
|
|
144
|
+
Fly officially documents three Network Policies operations that are missing from its OpenAPI document:
|
|
145
|
+
|
|
146
|
+
```ruby
|
|
147
|
+
client.network_policies.upsert(
|
|
148
|
+
app_name: "my-app",
|
|
149
|
+
body: {
|
|
150
|
+
name: "web-egress",
|
|
151
|
+
selector: {metadata: {role: "web"}},
|
|
152
|
+
rules: [{action: "allow", direction: "egress", ports: [{protocol: "tcp", port: 443}]}]
|
|
153
|
+
}
|
|
154
|
+
)
|
|
155
|
+
client.network_policies.list(app_name: "my-app")
|
|
156
|
+
client.network_policies.delete(app_name: "my-app", policy_id: "policy-id")
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
The guide does not document response statuses or schemas. Responses therefore remain forward-compatible raw values;
|
|
160
|
+
the body input is checked only against fields and constraints the guide actually states.
|
|
161
|
+
|
|
162
|
+
## Prometheus metrics
|
|
163
|
+
|
|
164
|
+
Fly documents seven Prometheus-compatible endpoint families at `https://api.fly.io/prometheus/<org>/`. They are a
|
|
165
|
+
stable observability/data API, not control-plane operations, but are included so the platform-surface audit is honest:
|
|
166
|
+
|
|
167
|
+
```ruby
|
|
168
|
+
client.metrics.query(org_slug: "personal", query: 'sum(rate(fly_edge_http_responses_count[5m]))')
|
|
169
|
+
client.metrics.query_range(org_slug: "personal", query: "up", start: "-1h", end: "now", step: "60s")
|
|
170
|
+
client.metrics.series(org_slug: "personal", match: ['{__name__="up"}'])
|
|
171
|
+
client.metrics.labels(org_slug: "personal")
|
|
172
|
+
client.metrics.label_values(org_slug: "personal", label_name: "app")
|
|
173
|
+
client.metrics.tsdb(org_slug: "personal")
|
|
174
|
+
client.metrics.federate(org_slug: "personal", match: ["up"])
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
The JSON envelope becomes `FlyIO::Models::PrometheusAPIResponse`; federation remains text. Endpoint semantics are
|
|
178
|
+
delegated to the stable Prometheus HTTP API and Fly’s stated VictoriaMetrics compatibility.
|
|
179
|
+
|
|
180
|
+
## GraphQL: experimental and unstable
|
|
181
|
+
|
|
182
|
+
Fly explicitly documents `https://api.fly.io/graphql` as an internal flyctl interface with no stability guarantees.
|
|
183
|
+
It can change without notice. Prefer REST or flyctl where possible. Nothing in this gem presents GraphQL fields as a
|
|
184
|
+
stable public contract.
|
|
185
|
+
|
|
186
|
+
Raw documents, variables, operation names, response parsing, errors, timeouts, and opt-in retries are first class:
|
|
187
|
+
|
|
188
|
+
```ruby
|
|
189
|
+
graphql = client.graphql
|
|
190
|
+
response = graphql.query(
|
|
191
|
+
document: "query App($name: String!) { app(name: $name) { id name } }",
|
|
192
|
+
variables: {name: "my-app"},
|
|
193
|
+
operation_name: "App"
|
|
194
|
+
)
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Schema introspection is double opt-in: construct configuration with `introspection: true`, then call
|
|
198
|
+
`graphql.introspect(document: ...)`. The committed flyctl schema is evidence only.
|
|
199
|
+
|
|
200
|
+
The experimental adapter inventories 29 current flyctl documents, 85 fly-go v0.9.8 documents, and 3 official unstable
|
|
201
|
+
examples. Execute one with `graphql.experimental.execute("flyctl.GetApp", variables: ...)`. Arbitrary raw GraphQL
|
|
202
|
+
documents remain available when Fly adds fields before this gem releases.
|
|
203
|
+
|
|
204
|
+
## Contracts, development, and tests
|
|
205
|
+
|
|
206
|
+
The [surface inventory](docs/SURFACES.md) records every selected/excluded surface, provenance, hashes, revisions,
|
|
207
|
+
counts, stability, and gaps. Contract artifacts live under `contracts/`; generated runtime metadata is under
|
|
208
|
+
`lib/fly_io/generated/`.
|
|
209
|
+
|
|
210
|
+
```shell
|
|
211
|
+
bundle install
|
|
212
|
+
bundle exec rake api:check # offline snapshot/ref/mapping/generated-drift checks
|
|
213
|
+
bundle exec rspec # offline; WebMock disables all network access
|
|
214
|
+
bundle exec rubocop
|
|
215
|
+
bundle exec bundle-audit check --update
|
|
216
|
+
bundle exec rake build
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
For an isolated `--install-dir` smoke under RubyGems 4, use `--ignore-dependencies` for the target gem and include the
|
|
220
|
+
already audited Bundler gem path when requiring it. RubyGems otherwise attempts to rediscover Faraday in a local gem
|
|
221
|
+
repository even when it is already installed. CI performs this install plus a packaged-gem require check.
|
|
222
|
+
|
|
223
|
+
`bundle exec rake api:fetch_check` is the explicit networked upstream-drift check. `script/generate_api` regenerates
|
|
224
|
+
operation/model metadata and [docs/API.md](docs/API.md). Generated code is included in coverage because the small
|
|
225
|
+
runtime generator boundary is exercised by contract-derived RSpec examples; JSON metadata itself has no executable
|
|
226
|
+
lines to exclude.
|
|
227
|
+
|
|
228
|
+
Live tests require `FLY_IO_LIVE_TESTS=1`, `FLY_API_TOKEN`, and `FLY_IO_TEST_APP`. Destructive live work additionally
|
|
229
|
+
requires `FLY_IO_DESTRUCTIVE_LIVE_TESTS=1`; ordinary CI never has network access or credentials.
|
|
230
|
+
|
|
231
|
+
## Versioning
|
|
232
|
+
|
|
233
|
+
The gem follows Semantic Versioning for its own stable Ruby API. Machines contract changes are reviewed through the
|
|
234
|
+
drift gate. Experimental GraphQL changes may ship in any release and are called out in the changelog because Fly gives
|
|
235
|
+
that upstream interface no compatibility guarantee.
|
|
236
|
+
|
|
237
|
+
## License
|
|
238
|
+
|
|
239
|
+
MIT. See [LICENSE](LICENSE).
|
data/Rakefile
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "bundler/gem_tasks"
|
|
4
|
+
require "rspec/core/rake_task"
|
|
5
|
+
require "rubocop/rake_task"
|
|
6
|
+
|
|
7
|
+
RSpec::Core::RakeTask.new(:spec)
|
|
8
|
+
RuboCop::RakeTask.new(:rubocop) do |task|
|
|
9
|
+
task.options = ["--cache-root", "tmp/rubocop_cache", "--no-server"]
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
namespace :api do
|
|
13
|
+
desc "Verify generated API coverage and committed contract outputs"
|
|
14
|
+
task :check do
|
|
15
|
+
sh RbConfig.ruby, "script/check_api_coverage"
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
desc "Fetch the upstream OpenAPI and fail if it differs from the snapshot"
|
|
19
|
+
task :fetch_check do
|
|
20
|
+
sh RbConfig.ruby, "script/fetch_openapi"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
desc "Regenerate API metadata and documentation"
|
|
24
|
+
task :generate do
|
|
25
|
+
sh RbConfig.ruby, "script/generate_api"
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
desc "Run offline quality checks"
|
|
30
|
+
task default: ["api:check", :spec, :rubocop]
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
{
|
|
2
|
+
"surface": "network_policies_rest",
|
|
3
|
+
"stability": "stable_documented",
|
|
4
|
+
"base_url": "https://api.machines.dev",
|
|
5
|
+
"documentation_url": "https://fly.io/docs/machines/guides-examples/network-policies/",
|
|
6
|
+
"source_repository": "https://github.com/superfly/docs",
|
|
7
|
+
"source_revision": "1e8cac5f0fd7a82e66e3b01ece3a10a8ecb2b7e3",
|
|
8
|
+
"source_path": "machines/guides-examples/network-policies.html.markerb",
|
|
9
|
+
"source_sha256": "fa64b69db56beb1da2de60e3ff91820b628a1238a120d103c2f3bae16e2fcc1f",
|
|
10
|
+
"retrieved_at": "2026-08-26T21:00:00Z",
|
|
11
|
+
"limitations": [
|
|
12
|
+
"This official guide is not represented in the Machines OpenAPI document.",
|
|
13
|
+
"The guide documents methods, paths, authentication, and request shape, but no response status or schema."
|
|
14
|
+
],
|
|
15
|
+
"schemas": {
|
|
16
|
+
"NetworkPolicyPort": {
|
|
17
|
+
"type": "object",
|
|
18
|
+
"required": ["protocol", "port"],
|
|
19
|
+
"properties": {"protocol": {"type": "string"}, "port": {"type": "integer"}}
|
|
20
|
+
},
|
|
21
|
+
"NetworkPolicyRule": {
|
|
22
|
+
"type": "object",
|
|
23
|
+
"required": ["action", "direction", "ports"],
|
|
24
|
+
"properties": {
|
|
25
|
+
"action": {"type": "string", "enum": ["allow"]},
|
|
26
|
+
"direction": {"type": "string", "enum": ["ingress", "egress"]},
|
|
27
|
+
"ports": {"type": "array", "items": {"$ref": "#/additional/schemas/NetworkPolicyPort"}}
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"NetworkPolicySelector": {
|
|
31
|
+
"type": "object",
|
|
32
|
+
"properties": {
|
|
33
|
+
"all": {"type": "boolean"},
|
|
34
|
+
"machines": {"type": "array", "items": {"type": "object", "required": ["id"], "properties": {"id": {"type": "string"}}}},
|
|
35
|
+
"metadata": {"type": "object", "additionalProperties": {"type": "string"}}
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
"NetworkPolicyRequest": {
|
|
39
|
+
"type": "object",
|
|
40
|
+
"required": ["name", "selector", "rules"],
|
|
41
|
+
"properties": {
|
|
42
|
+
"id": {"type": "string"},
|
|
43
|
+
"name": {"type": "string"},
|
|
44
|
+
"selector": {"$ref": "#/additional/schemas/NetworkPolicySelector"},
|
|
45
|
+
"rules": {"type": "array", "items": {"$ref": "#/additional/schemas/NetworkPolicyRule"}}
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
"NetworkPolicy": {
|
|
49
|
+
"type": "object",
|
|
50
|
+
"additionalProperties": true,
|
|
51
|
+
"properties": {
|
|
52
|
+
"id": {"type": "string"},
|
|
53
|
+
"name": {"type": "string"},
|
|
54
|
+
"selector": {"$ref": "#/additional/schemas/NetworkPolicySelector"},
|
|
55
|
+
"rules": {"type": "array", "items": {"$ref": "#/additional/schemas/NetworkPolicyRule"}}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
"operations": [
|
|
60
|
+
{
|
|
61
|
+
"identity": "POST /v1/apps/{app_name}/network_policies NetworkPolicies_upsert",
|
|
62
|
+
"operation_id": "NetworkPolicies_upsert",
|
|
63
|
+
"method": "post",
|
|
64
|
+
"path": "/v1/apps/{app_name}/network_policies",
|
|
65
|
+
"summary": "Create or update a network policy",
|
|
66
|
+
"parameters": [{"name": "app_name", "ruby_name": "app_name", "in": "path", "required": true, "schema": {"type": "string"}}],
|
|
67
|
+
"request_body": {"required": true, "content_types": ["application/json"], "schema": {"$ref": "#/additional/schemas/NetworkPolicyRequest"}},
|
|
68
|
+
"responses": {}
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"identity": "GET /v1/apps/{app_name}/network_policies/ NetworkPolicies_list",
|
|
72
|
+
"operation_id": "NetworkPolicies_list",
|
|
73
|
+
"method": "get",
|
|
74
|
+
"path": "/v1/apps/{app_name}/network_policies/",
|
|
75
|
+
"summary": "List network policies",
|
|
76
|
+
"parameters": [{"name": "app_name", "ruby_name": "app_name", "in": "path", "required": true, "schema": {"type": "string"}}],
|
|
77
|
+
"request_body": null,
|
|
78
|
+
"responses": {}
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"identity": "DELETE /v1/apps/{app_name}/network_policies/{policy_id} NetworkPolicies_delete",
|
|
82
|
+
"operation_id": "NetworkPolicies_delete",
|
|
83
|
+
"method": "delete",
|
|
84
|
+
"path": "/v1/apps/{app_name}/network_policies/{policy_id}",
|
|
85
|
+
"summary": "Delete a network policy",
|
|
86
|
+
"parameters": [
|
|
87
|
+
{"name": "app_name", "ruby_name": "app_name", "in": "path", "required": true, "schema": {"type": "string"}},
|
|
88
|
+
{"name": "policy_id", "ruby_name": "policy_id", "in": "path", "required": true, "schema": {"type": "string"}}
|
|
89
|
+
],
|
|
90
|
+
"request_body": null,
|
|
91
|
+
"responses": {}
|
|
92
|
+
}
|
|
93
|
+
]
|
|
94
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
{
|
|
2
|
+
"surface": "prometheus_metrics",
|
|
3
|
+
"stability": "stable_standard_api_with_qualified_compatibility",
|
|
4
|
+
"base_url": "https://api.fly.io",
|
|
5
|
+
"documentation_url": "https://fly.io/docs/monitoring/metrics",
|
|
6
|
+
"source_repository": "https://github.com/superfly/docs",
|
|
7
|
+
"source_revision": "1e8cac5f0fd7a82e66e3b01ece3a10a8ecb2b7e3",
|
|
8
|
+
"source_path": "monitoring/metrics.html.md",
|
|
9
|
+
"source_sha256": "e22d7b34406b16c2ea75eed6cd92c51ec07d166963155623557295ef24f67e9f",
|
|
10
|
+
"retrieved_at": "2026-08-26T21:00:00Z",
|
|
11
|
+
"limitations": [
|
|
12
|
+
"This is an observability data API, not a control-plane API.",
|
|
13
|
+
"Fly documents support for most common Prometheus query endpoints and delegates their parameter/response contracts to Prometheus/VictoriaMetrics."
|
|
14
|
+
],
|
|
15
|
+
"schemas": {
|
|
16
|
+
"PrometheusAPIResponse": {
|
|
17
|
+
"type": "object",
|
|
18
|
+
"required": ["status"],
|
|
19
|
+
"additionalProperties": true,
|
|
20
|
+
"properties": {
|
|
21
|
+
"status": {"type": "string", "enum": ["success", "error"]},
|
|
22
|
+
"data": {"type": "object", "additionalProperties": true},
|
|
23
|
+
"errorType": {"type": "string"},
|
|
24
|
+
"error": {"type": "string"},
|
|
25
|
+
"warnings": {"type": "array", "items": {"type": "string"}},
|
|
26
|
+
"infos": {"type": "array", "items": {"type": "string"}}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"operations": [
|
|
31
|
+
{
|
|
32
|
+
"operation_id": "Prometheus_query", "method": "get", "path": "/prometheus/{org_slug}/api/v1/query",
|
|
33
|
+
"summary": "Run an instant Prometheus query",
|
|
34
|
+
"parameters": [
|
|
35
|
+
{"name": "org_slug", "ruby_name": "org_slug", "in": "path", "required": true, "schema": {"type": "string"}},
|
|
36
|
+
{"name": "query", "ruby_name": "query", "in": "query", "required": true, "schema": {"type": "string"}},
|
|
37
|
+
{"name": "time", "ruby_name": "time", "in": "query", "required": false, "schema": {"type": "string"}},
|
|
38
|
+
{"name": "timeout", "ruby_name": "timeout", "in": "query", "required": false, "schema": {"type": "string"}}
|
|
39
|
+
]
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"operation_id": "Prometheus_query_range", "method": "get", "path": "/prometheus/{org_slug}/api/v1/query_range",
|
|
43
|
+
"summary": "Run a range Prometheus query",
|
|
44
|
+
"parameters": [
|
|
45
|
+
{"name": "org_slug", "ruby_name": "org_slug", "in": "path", "required": true, "schema": {"type": "string"}},
|
|
46
|
+
{"name": "query", "ruby_name": "query", "in": "query", "required": true, "schema": {"type": "string"}},
|
|
47
|
+
{"name": "start", "ruby_name": "start", "in": "query", "required": true, "schema": {"type": "string"}},
|
|
48
|
+
{"name": "end", "ruby_name": "end", "in": "query", "required": true, "schema": {"type": "string"}},
|
|
49
|
+
{"name": "step", "ruby_name": "step", "in": "query", "required": true, "schema": {"type": "string"}},
|
|
50
|
+
{"name": "timeout", "ruby_name": "timeout", "in": "query", "required": false, "schema": {"type": "string"}}
|
|
51
|
+
]
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"operation_id": "Prometheus_series", "method": "get", "path": "/prometheus/{org_slug}/api/v1/series",
|
|
55
|
+
"summary": "Find series by label matchers",
|
|
56
|
+
"parameters": [
|
|
57
|
+
{"name": "org_slug", "ruby_name": "org_slug", "in": "path", "required": true, "schema": {"type": "string"}},
|
|
58
|
+
{"name": "match[]", "ruby_name": "match", "in": "query", "required": true, "schema": {"type": "array", "items": {"type": "string"}}},
|
|
59
|
+
{"name": "start", "ruby_name": "start", "in": "query", "required": false, "schema": {"type": "string"}},
|
|
60
|
+
{"name": "end", "ruby_name": "end", "in": "query", "required": false, "schema": {"type": "string"}}
|
|
61
|
+
]
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"operation_id": "Prometheus_labels", "method": "get", "path": "/prometheus/{org_slug}/api/v1/labels",
|
|
65
|
+
"summary": "Get label names",
|
|
66
|
+
"parameters": [
|
|
67
|
+
{"name": "org_slug", "ruby_name": "org_slug", "in": "path", "required": true, "schema": {"type": "string"}},
|
|
68
|
+
{"name": "match[]", "ruby_name": "match", "in": "query", "required": false, "schema": {"type": "array", "items": {"type": "string"}}},
|
|
69
|
+
{"name": "start", "ruby_name": "start", "in": "query", "required": false, "schema": {"type": "string"}},
|
|
70
|
+
{"name": "end", "ruby_name": "end", "in": "query", "required": false, "schema": {"type": "string"}}
|
|
71
|
+
]
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
"operation_id": "Prometheus_label_values", "method": "get", "path": "/prometheus/{org_slug}/api/v1/label/{label_name}/values",
|
|
75
|
+
"summary": "Get values for a label",
|
|
76
|
+
"parameters": [
|
|
77
|
+
{"name": "org_slug", "ruby_name": "org_slug", "in": "path", "required": true, "schema": {"type": "string"}},
|
|
78
|
+
{"name": "label_name", "ruby_name": "label_name", "in": "path", "required": true, "schema": {"type": "string"}},
|
|
79
|
+
{"name": "match[]", "ruby_name": "match", "in": "query", "required": false, "schema": {"type": "array", "items": {"type": "string"}}},
|
|
80
|
+
{"name": "start", "ruby_name": "start", "in": "query", "required": false, "schema": {"type": "string"}},
|
|
81
|
+
{"name": "end", "ruby_name": "end", "in": "query", "required": false, "schema": {"type": "string"}}
|
|
82
|
+
]
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"operation_id": "Prometheus_tsdb", "method": "get", "path": "/prometheus/{org_slug}/api/v1/status/tsdb",
|
|
86
|
+
"summary": "Get TSDB statistics",
|
|
87
|
+
"parameters": [
|
|
88
|
+
{"name": "org_slug", "ruby_name": "org_slug", "in": "path", "required": true, "schema": {"type": "string"}},
|
|
89
|
+
{"name": "limit", "ruby_name": "limit", "in": "query", "required": false, "schema": {"type": "integer"}},
|
|
90
|
+
{"name": "match[]", "ruby_name": "match", "in": "query", "required": false, "schema": {"type": "array", "items": {"type": "string"}}}
|
|
91
|
+
]
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"operation_id": "Prometheus_federate", "method": "get", "path": "/prometheus/{org_slug}/federate",
|
|
95
|
+
"summary": "Federate selected metrics",
|
|
96
|
+
"parameters": [
|
|
97
|
+
{"name": "org_slug", "ruby_name": "org_slug", "in": "path", "required": true, "schema": {"type": "string"}},
|
|
98
|
+
{"name": "match[]", "ruby_name": "match", "in": "query", "required": true, "schema": {"type": "array", "items": {"type": "string"}}}
|
|
99
|
+
],
|
|
100
|
+
"response_content_type": "text/plain"
|
|
101
|
+
}
|
|
102
|
+
]
|
|
103
|
+
}
|