Note
Fleet Management is currently in public preview. Grafana Labs offers limited support, and breaking changes might occur prior to the feature being made generally available.
The Collector API
API usage
NOTE TO SELF: CONTENT DUMP NO EDITS YET
Collector API
The collector
API is pretty straightforward for CRUD operations on individual collectors. In case of success, it returns an empty payload with 200 - OK status code. Otherwise, an explanatory error message is returned instead.
--- create-collector.json ---
{
"collector": {
"id": "karasu",
"attribute_overrides": {"mycustomattr": "mycustomval"},
"name": "raven",
"enabled": true
}
}
--- update-collector.json ---
{
"collector": {
"id": "karasu",
"attribute_overrides": {"mycustomattr": "mynewcustomval"},
"enabled": true
}
}
--- get-collector.json ---
{
"id": "karasu"
}
--- delete-collector.json ---
{
"id": "karasu"
}
Here’s how the requests look like using the above payloads
$ curl -q \
-d @create-collector.json \
-u "user:pass" \
--header "Content-Type: application/json" \
-X POST https://fleet-management-dev-001.grafana-dev.net/collector.v1.CollectorService/CreateCollector
{}%
$ curl -q \
-d @create-collector.json \
-u "user:pass" \
--header "Content-Type: application/json" \
-X POST https://fleet-management-dev-001.grafana-dev.net/collector.v1.CollectorService/CreateCollector
{}%
$ curl -q \
-d @get-collector.json \
-u "user:pass" \
--header "Content-Type: application/json" \
-X POST https://fleet-management-dev-001.grafana-dev.net/collector.v1.CollectorService/GetCollector
{"attributeOverrides":{"mycustomattr":"mynewcustomval"}, "createdAt":"2024-09-02T14:59:13Z", "updatedAt":"2024-09-02T16:18:38Z", "attributes":{"cluster":"dev", "collector.os":"linux", "collector.version":"v1.4.0-devel+wip", "namespace":"team-c"}, "enabled":true}
$ curl -q \
-d @delete-collector.json \
-u "user:pass" \
--header "Content-Type: application/json" \
-X POST https://fleet-management-dev-001.grafana-dev.net/collector.v1.CollectorService/DeleteCollector
{}%
$ curl -q \
-d '{}' \
-u "user:pass" \
--header "Content-Type: application/json" \
-X POST https://fleet-management-dev-001.grafana-dev.net/collector.v1.CollectorService/ListCollectors
$ curl -q \
-d '{"matchers": ["collector.os=linux"]}' \
-u "user:pass" \
--header "Content-Type: application/json" \
-X POST https://fleet-management-dev-001.grafana-dev.net/collector.v1.CollectorService/ListCollectors
Pipeline API
The pipeline
API requires some more handling because requests and responses are generally longer and require proper escaping of the pipeline contents. For this reason, some use of jq
is helpful. Let’s say that the contents of the pipeline are saved in a file named config.alloy.
--- config.alloy ---
prometheus.exporter.self "alloy" { }
prometheus.scrape "alloy" {
targets = prometheus.exporter.self.alloy.targets
forward_to = [prometheus.remote_write.grafanacloud.receiver]
scrape_interval = "60s"
}
prometheus.remote_write "grafanacloud" {
// Must match the uniquely-identifiable ID set up in the remotecfg block.
external_labels = {"collector_id" = constants.hostname}
endpoint {
url = "https://prometheus-dev-01-dev-us-central-0.grafana-dev.net/api/prom/push"
basic_auth {
username = "20191"
password_file = "/var/secrets/fleet-management-creds/api-user"
}
}
}
To build a payload for the CreatePipeline and UpsertPipeline requests with properly-escaped content, the following command is a good starting point:
jq --arg contents "$(cat config.alloy)" \
--arg name "myname" \
--argjson matchers '["collector.os=linux", "team!=team-a"]' \
--argjson enabled true \
'.pipeline = {name: $name, contents: $contents, matchers: $matchers, enabled: $enabled}' \
<<< '{}' > create-pipeline.json
Here, it is redirected to a create-pipeline.json
file for easier handling.
The CreatePipeline call response verifies what was created, and also lists the unique ID for this pipeline.
curl -q \
-d @create-pipeline.json \
-u "user:pass" \
--header "Content-Type: application/json" \
-X POST https://fleet-management-dev-001.grafana-dev.net/pipeline.v1.PipelineService/CreatePipeline
{
"name": "myname",
"contents": " ... pipeline contents ...",
"matchers": [
"collector.os=\"linux\"",
"team!=\"team-a\""
],
"enabled": true,
"id": "22234"
}
The ListPipelines takes an empty payload and returns all available pipelines.
$ curl -q \
-d '{}' \
-u "user:pass" \
--header "Content-Type: application/json" \
-X POST https://fleet-management-dev-001.grafana-dev.net/pipeline.v1.PipelineService/ListPipelines
{
"pipelines": [
{
"name": "pipeline_1",
"contents": " ... pipeline contents ...",
"matchers": [
"team=\"team-a\""
],
"createdAt": "2024-09-02T12:31:47Z",
"updatedAt": "2024-09-02T14:08:10Z",
"enabled": false,
"id": "22231"
},
{
"name": "pipeline_2",
"contents": " ... pipeline contents ...",
"matchers": [
"collector.os=\"linux\"",
"team!=\"team-a\""
],
"createdAt": "2024-09-02T16:42:26Z",
"updatedAt": "2024-09-02T16:42:26Z",
"enabled": true,
"id": "22234"
}
]
}
We can use a similar jq
command to build an UpdatePipeline command, by adding the unique pipeline ID
jq --arg contents "$(cat self.alloy)" \
--arg id "22234" \
--arg name "myname" \
--argjson matchers '["collector.os=linux", "team!=team-a"]' \
--argjson enabled true \
'.pipeline = {id: $id, name: $name, contents: $contents, matchers: $matchers, enabled: $enabled}' \
<<< '{}' > update-pipeline.json
{
"name": "myname",
"contents": " ... new pipeline contents ...",
"matchers": [
"collector.os=\"linux\"",
"team!=\"team-a\""
],
"enabled": true,
"id": "22234"
}
Finally, the GetPipeline and DeletePipeline calls are simpler and only require an ID.
curl -q \
-d '{"id": "22234"}' \
-u "user:pass" \
--header "Content-Type: application/json" \
-X POST https://fleet-management-dev-001.grafana-dev.net/pipeline.v1.PipelineService/GetPipeline
{
"name": "myname",
"contents": "... pipeline contents ...",
"matchers": [
"collector.os=\"linux\"",
"team!=\"team-a\""
],
"createdAt": "2024-09-02T16:42:26Z",
"updatedAt": "2024-09-02T16:42:26Z",
"enabled": true,
"id": "22234"
}
curl -q \
-d '{"id": "22234"}' \
-u "user:pass" \
--header "Content-Type: application/json" \
-X POST https://fleet-management-dev-001.grafana-dev.net/pipeline.v1.PipelineService/DeletePipeline
{}