### Create CollectorServiceClient Source: https://context7.com/grafana/fleet-management-api/llms.txt Constructs a CollectorServiceClient for the Connect protocol. Use connect.WithGRPC() or connect.WithGRPCWeb() to switch transport protocols. This example demonstrates listing all collectors. ```go package main import ( "context" "fmt" "log" "net/http" "connectrpc.com/connect" collectorv1 "github.com/grafana/fleet-management-api/api/gen/proto/go/collector/v1" "github.com/grafana/fleet-management-api/api/gen/proto/go/collector/v1/collectorv1connect" ) func main() { client := collectorv1connect.NewCollectorServiceClient( http.DefaultClient, "https://fleet-management-prod-001.grafana.net", connect.WithGRPC(), // optional: use gRPC transport instead of Connect ) ctx := context.Background() // List all collectors listResp, err := client.ListCollectors(ctx, connect.NewRequest(&collectorv1.ListCollectorsRequest{})) if err != nil { log.Fatalf("list collectors: %v", err) } for _, c := range listResp.Msg.Collectors { fmt.Printf("collector id=%s name=%s enabled=%v\n", c.Id, c.Name, c.GetEnabled()) } } ``` -------------------------------- ### ListPipelineRevisions / GetPipelineRevision Source: https://context7.com/grafana/fleet-management-api/llms.txt Audit the history of a pipeline. Every create, update, and delete operation creates an immutable `PipelineRevision` snapshot. Use `ListPipelinesRevisions` to get all revisions across all pipelines, `ListPipelineRevisions` for revisions of a single pipeline, and `GetPipelineRevision` to fetch a specific snapshot. ```APIDOC ## ListPipelineRevisions / GetPipelineRevision ### Description Audit the history of a pipeline. Every create, update, and delete operation creates an immutable `PipelineRevision` snapshot. Use `ListPipelinesRevisions` to get all revisions across all pipelines, `ListPipelineRevisions` for revisions of a single pipeline, and `GetPipelineRevision` to fetch a specific snapshot. ### Method GET ### Endpoint - `ListPipelineRevisions`: `/v1/pipelines/{pipeline_id}/revisions` - `GetPipelineRevision`: `/v1/pipelineRevisions/{revision_id}` ### Parameters #### ListPipelineRevisions ##### Path Parameters - **pipeline_id** (string) - Required - The ID of the pipeline to list revisions for. #### GetPipelineRevision ##### Path Parameters - **revision_id** (string) - Required - The ID of the pipeline revision to fetch. ### Request Example ```json // Get all revisions for a specific pipeline GET /v1/pipelines/01HXYZ123456/revisions // Fetch a specific revision snapshot GET /v1/pipelineRevisions/01HREV000042 ``` ### Response #### Success Response (200) ##### ListPipelineRevisions - **pipeline_revisions** (array) - A list of pipeline revisions. - **revision_id** (string) - The ID of the revision. - **operation** (string) - The operation performed (e.g., CREATE, UPDATE, DELETE). - **created_at** (timestamp) - The timestamp when the revision was created. ##### GetPipelineRevision - **snapshot** (PipelineRevisionSnapshot) - The pipeline revision snapshot. - **name** (string) - The name of the pipeline. - **contents** (string) - The pipeline configuration content. - **matchers** (array) - A list of matchers associated with the pipeline. - **config_type** (ConfigType) - The configuration type of the pipeline. - **enabled** (bool) - The enabled state of the pipeline. - **updated_at** (timestamp) - The timestamp when the pipeline was last updated. #### Response Example ```json // ListPipelineRevisions response example { "pipeline_revisions": [ { "revision_id": "01HREV000042", "operation": "UPDATE", "created_at": "2023-10-27T09:55:00Z" } ] } // GetPipelineRevision response example { "snapshot": { "name": "prod-metrics-pipeline", "contents": "/* updated Alloy config */", "matchers": [ "{env=\"production\"}" ], "config_type": "CONFIG_TYPE_ALLOY", "enabled": true, "updated_at": "2023-10-27T09:55:00Z" } } ``` ``` -------------------------------- ### Get Pipeline by ID or Name Source: https://context7.com/grafana/fleet-management-api/llms.txt Retrieves a pipeline by its server-assigned ID or resolves a human-readable name to its ID. Use `GetPipelineID` first if only the name is known. ```go // Resolve name → ID idResp, err := pipelineClient.GetPipelineID(ctx, connect.NewRequest(&pipelinev1.GetPipelineIDRequest{ Name: "prod-metrics-pipeline", })) if err != nil { log.Fatalf("get pipeline id: %v", err) } pipelineID := idResp.Msg.Id // Fetch full pipeline by ID getResp, err := pipelineClient.GetPipeline(ctx, connect.NewRequest(&pipelinev1.GetPipelineRequest{ Id: pipelineID, })) if err != nil { log.Fatalf("get pipeline: %v", err) } p := getResp.Msg fmt.Printf("name=%s enabled=%v matchers=%v\n", p.Name, p.GetEnabled(), p.Matchers) fmt.Printf("config_type=%s\ncontents:\n%s\n", p.ConfigType, p.Contents) ``` -------------------------------- ### Audit Pipeline Revisions Source: https://context7.com/grafana/fleet-management-api/llms.txt Retrieve historical snapshots of pipelines using `ListPipelineRevisions` for a specific pipeline or `GetPipelineRevision` for a single revision by ID. `ListPipelinesRevisions` gets all revisions across all pipelines. Each operation creates an immutable `PipelineRevision`. ```go // Get all revisions for a specific pipeline revisionsResp, err := pipelineClient.ListPipelineRevisions(ctx, connect.NewRequest(&pipelinev1.ListPipelineRevisionsRequest{ Id: "01HXYZ123456", })) if err != nil { log.Fatalf("list pipeline revisions: %v", err) } for _, rev := range revisionsResp.Msg.PipelineRevisions { fmt.Printf("revision_id=%s op=%s at=%v\n", rev.RevisionId, rev.Operation, rev.CreatedAt.AsTime()) } // Fetch a specific revision snapshot revResp, err := pipelineClient.GetPipelineRevision(ctx, connect.NewRequest(&pipelinev1.GetPipelineRevisionRequest{ RevisionId: "01HREV000042", })) if err != nil { log.Fatalf("get pipeline revision: %v", err) } fmt.Printf("snapshot name=%s contents:\n%s\n", revResp.Msg.Snapshot.Name, revResp.Msg.Snapshot.Contents) ``` -------------------------------- ### Bootstrap Initial Alloy Pipelines Source: https://context7.com/grafana/fleet-management-api/llms.txt Internal convenience RPC for provisioning default Alloy pipelines. Intended for service-level automation, not end-user calls. Requires Mimir and Loki endpoint details. ```go resp, err := pipelineClient.CreateAlloyPipelines(ctx, connect.NewRequest(&pipelinev1.CreateAlloyPipelinesRequest{ MimirUrl: "https://prometheus-prod-10-prod-us-central-0.grafana.net/api/prom/push", MimirUsername: "123456", LokiUrl: "https://logs-prod-006.grafana.net/loki/api/v1/push", LokiUsername: "654321", })) if err != nil { log.Fatalf("create alloy pipelines: %v", err) } for _, p := range resp.Msg.Pipelines.Pipelines { fmt.Printf("bootstrapped pipeline: %s\n", p.Name) } ``` -------------------------------- ### List Pipelines by Attributes and Type Source: https://context7.com/grafana/fleet-management-api/llms.txt Query pipelines based on local and remote attributes, and filter by configuration type (Alloy/OTel) and enabled state. Ensure the `pipelineClient` is initialized. ```go resp, err := pipelineClient.ListPipelines(ctx, connect.NewRequest(&pipelinev1.ListPipelinesRequest{ LocalAttributes: map[string]string{ "env": "production", "region": "us-east-1", }, RemoteAttributes: map[string]string{ "team": "platform", }, ConfigType: func() *pipelinev1.ConfigType { ct := pipelinev1.ConfigType_CONFIG_TYPE_ALLOY return &ct }(), Enabled: proto.Bool(true), })) if err != nil { log.Fatalf("list pipelines: %v", err) } for _, p := range resp.Msg.Pipelines { fmt.Printf("pipeline %s (id=%s) matchers=%v\n", p.Name, p.GetId(), p.Matchers) } ``` -------------------------------- ### Build Docker Container for Protobuf Generation Source: https://github.com/grafana/fleet-management-api/blob/main/README.md Run this command to build the container with necessary dependencies for Protobuf code generation. ```bash make build-container ``` -------------------------------- ### Create Pipeline Source: https://context7.com/grafana/fleet-management-api/llms.txt Defines a new configuration pipeline with specified contents, matchers, and configuration type. Use `validate_only: true` for dry-runs. ```go import pipelinev1 "github.com/grafana/fleet-management-api/api/gen/proto/go/pipeline/v1" resp, err := pipelineClient.CreatePipeline(ctx, connect.NewRequest(&pipelinev1.CreatePipelineRequest{ Pipeline: &pipelinev1.Pipeline{ Name: "prod-metrics-pipeline", Contents: " prometheus.scrape \"node\" { targets = [{"__address__" = "localhost:9100"}] forward_to = [prometheus.remote_write.mimir.receiver] } prometheus.remote_write \"mimir\" { endpoint { url = \"https://mimir.example.grafana.net/api/prom/push\" } }", Matchers: []string{ `{env="production"}`, `{team="platform"}`, }, ConfigType: pipelinev1.ConfigType_CONFIG_TYPE_ALLOY, Enabled: proto.Bool(true), }, ValidateOnly: false, })) if err != nil { log.Fatalf("create pipeline: %v", err) } fmt.Printf("created pipeline id=%s name=%s\n", resp.Msg.GetId(), resp.Msg.Name) ``` -------------------------------- ### CollectorService Client Source: https://context7.com/grafana/fleet-management-api/llms.txt Demonstrates how to create a typed Go client for the CollectorService using the Connect protocol. ```APIDOC ## NewCollectorServiceClient ### Description `NewCollectorServiceClient` constructs a `CollectorServiceClient` backed by the Connect protocol. Pass `connect.WithGRPC()` or `connect.WithGRPCWeb()` to switch transport protocols. ### Usage ```go package main import ( "context" "fmt" "log" "net/http" "connectrpc.com/connect" collectorv1 "github.com/grafana/fleet-management-api/api/gen/proto/go/collector/v1" "github.com/grafana/fleet-management-api/api/gen/proto/go/collector/v1/collectorv1connect" ) func main() { client := collectorv1connect.NewCollectorServiceClient( http.DefaultClient, "https://fleet-management-prod-001.grafana.net", connect.WithGRPC(), // optional: use gRPC transport instead of Connect ) ctx := context.Background() // List all collectors listResp, err := client.ListCollectors(ctx, connect.NewRequest(&collectorv1.ListCollectorsRequest{})) if err != nil { log.Fatalf("list collectors: %v", err) } for _, c := range listResp.Msg.Collectors { fmt.Printf("collector id=%s name=%s enabled=%v\n", c.Id, c.Name, c.GetEnabled()) } } ``` ``` -------------------------------- ### NewPipelineServiceClient Source: https://context7.com/grafana/fleet-management-api/llms.txt Create a typed Go client for PipelineService. ```APIDOC ## NewPipelineServiceClient — Create a typed Go client for PipelineService ```go client := pipelinev1connect.NewPipelineServiceClient( http.DefaultClient, "https://fleet-management-prod-001.grafana.net", ) ``` ``` -------------------------------- ### Create PipelineServiceClient Source: https://context7.com/grafana/fleet-management-api/llms.txt Creates a typed Go client for the PipelineService. Ensure the client uses the correct HTTP client and endpoint. ```go client := pipelinev1connect.NewPipelineServiceClient( http.DefaultClient, "https://fleet-management-prod-001.grafana.net", ) ``` -------------------------------- ### Generate Go Code from Protobuf Definitions Source: https://github.com/grafana/fleet-management-api/blob/main/README.md Execute this command within the Docker container to regenerate Go client code based on updated Protobuf definitions. ```bash make buf-generate ``` -------------------------------- ### Synchronize Pipelines Declaratively Source: https://context7.com/grafana/fleet-management-api/llms.txt Apply a desired set of pipelines from an external source like Git or Terraform. Pipelines not present in the sync payload but sharing the same source type and namespace will be deleted, enabling GitOps-style management. ```go _, err = pipelineClient.SyncPipelines(ctx, connect.NewRequest(&pipelinev1.SyncPipelinesRequest{ Source: &pipelinev1.PipelineSource{ Type: pipelinev1.PipelineSource_SOURCE_TYPE_GIT, Namespace: "github.com/myorg/observability-config/production", }, Pipelines: []*pipelinev1.Pipeline{ { Name: "prod-metrics-pipeline", Contents: `/* alloy config */`, Matchers: []string{`{env="production"}`}, ConfigType: pipelinev1.ConfigType_CONFIG_TYPE_ALLOY, Enabled: proto.Bool(true), }, { Name: "prod-logs-pipeline", Contents: `/* alloy logs config */`, Matchers: []string{`{env="production"}`, `{logs="enabled"}`}, ConfigType: pipelinev1.ConfigType_CONFIG_TYPE_ALLOY, Enabled: proto.Bool(true), }, }, })) if err != nil { log.Fatalf("sync pipelines: %v", err) } fmt.Println("sync complete — pipelines not in payload were removed") ``` -------------------------------- ### Update Pipeline Configuration Source: https://context7.com/grafana/fleet-management-api/llms.txt Perform a full replacement update on an existing pipeline. Fields not provided will be cleared. Returns `NOT_FOUND` if the pipeline ID does not exist. Ensure `proto.String` and `proto.Bool` are imported. ```go resp, err := pipelineClient.UpdatePipeline(ctx, connect.NewRequest(&pipelinev1.UpdatePipelineRequest{ Pipeline: &pipelinev1.Pipeline{ Id: proto.String("01HXYZ123456"), Name: "prod-metrics-pipeline", Contents: `/* updated Alloy config */`, Matchers: []string{`{env="production"}`, `{region="us-east-1"}`}, ConfigType: pipelinev1.ConfigType_CONFIG_TYPE_ALLOY, Enabled: proto.Bool(true), }, ValidateOnly: false, })) if err != nil { log.Fatalf("update pipeline: %v", err) } fmt.Printf("updated pipeline at %v\n", resp.Msg.UpdatedAt.AsTime()) ``` -------------------------------- ### CreatePipeline Source: https://context7.com/grafana/fleet-management-api/llms.txt Define a new configuration pipeline. Creates a named pipeline with a configuration snippet and matchers. Set `validate_only: true` to dry-run without persisting. ```APIDOC ## CreatePipeline — Define a new configuration pipeline Creates a named pipeline with a configuration snippet (Alloy or OTel format) and Prometheus-style matchers that determine which collectors receive it. Set `validate_only: true` to dry-run without persisting. ```go import pipelinev1 "github.com/grafana/fleet-management-api/api/gen/proto/go/pipeline/v1" resp, err := pipelineClient.CreatePipeline(ctx, connect.NewRequest(&pipelinev1.CreatePipelineRequest{ Pipeline: &pipelinev1.Pipeline{ Name: "prod-metrics-pipeline", Contents: ` prometheus.scrape "node" { targets = [{"__address__" = "localhost:9100"}] forward_to = [prometheus.remote_write.mimir.receiver] } prometheus.remote_write "mimir" { endpoint { url = "https://mimir.example.grafana.net/api/prom/push" } }`, Matchers: []string{ `{env="production"}`, `{team="platform"}`, }, ConfigType: pipelinev1.ConfigType_CONFIG_TYPE_ALLOY, Enabled: proto.Bool(true), }, ValidateOnly: false, })) if err != nil { log.Fatalf("create pipeline: %v", err) } fmt.Printf("created pipeline id=%s name=%s\n", resp.Msg.GetId(), resp.Msg.Name) ``` ``` -------------------------------- ### SyncPipelines Source: https://context7.com/grafana/fleet-management-api/llms.txt Declarative sync from an external source (GitOps/Terraform). Applies a desired set of pipelines from a named source (Git or Terraform). Any pipelines sharing the same `source.type` and `source.namespace` that are NOT in the sync payload are deleted, enabling fully declarative management. ```APIDOC ## SyncPipelines ### Description Declarative sync from an external source (GitOps/Terraform). Applies a desired set of pipelines from a named source (Git or Terraform). Any pipelines sharing the same `source.type` and `source.namespace` that are NOT in the sync payload are deleted, enabling fully declarative management. ### Method POST ### Endpoint `/v1/pipelines:sync` ### Parameters #### Request Body - **source** (PipelineSource) - Required - The source of the pipelines to sync. - **type** (PipelineSourceType) - Required - The type of the source (e.g., Git, Terraform). - **namespace** (string) - Required - The namespace of the source. - **pipelines** (array) - Required - A list of pipelines to sync. - **name** (string) - Required - The name of the pipeline. - **contents** (string) - Required - The pipeline configuration content. - **matchers** (array) - Optional - A list of matchers for the pipeline. - **config_type** (ConfigType) - Required - The configuration type of the pipeline. - **enabled** (bool) - Required - The enabled state of the pipeline. ### Request Example ```json { "source": { "type": "SOURCE_TYPE_GIT", "namespace": "github.com/myorg/observability-config/production" }, "pipelines": [ { "name": "prod-metrics-pipeline", "contents": "/* alloy config */", "matchers": [ "{env=\"production\"}" ], "config_type": "CONFIG_TYPE_ALLOY", "enabled": true }, { "name": "prod-logs-pipeline", "contents": "/* alloy logs config */", "matchers": [ "{env=\"production\"}", "{logs=\"enabled\"}" ], "config_type": "CONFIG_TYPE_ALLOY", "enabled": true } ] } ``` ### Response #### Success Response (200) - **message** (string) - Confirmation message indicating the sync operation is complete. #### Response Example ```json { "message": "Sync complete — pipelines not in payload were removed" } ``` ``` -------------------------------- ### Upsert Pipeline Source: https://context7.com/grafana/fleet-management-api/llms.txt Creates or overwrites a pipeline by name idempotently. This is useful for GitOps workflows where the desired state is declared and applied repeatedly. Ensure the `basic_auth` or other credentials are correctly configured if needed. ```go resp, err := pipelineClient.UpsertPipeline(ctx, connect.NewRequest(&pipelinev1.UpsertPipelineRequest{ Pipeline: &pipelinev1.Pipeline{ Name: "prod-metrics-pipeline", Contents: " prometheus.scrape \"node\" { targets = [{"__address__" = "localhost:9100"}] forward_to = [prometheus.remote_write.mimir.receiver] } prometheus.remote_write \"mimir\" { endpoint { url = \"https://mimir.example.grafana.net/api/prom/push\" basic_auth { username = \"123456\" password_file = \"/etc/grafana/token\" } } }", Matchers: []string{`{env="production"}`}, ConfigType: pipelinev1.ConfigType_CONFIG_TYPE_ALLOY, Enabled: proto.Bool(true), }, })) if err != nil { log.Fatalf("upsert pipeline: %v", err) } fmt.Printf("upserted pipeline id=%s\n", resp.Msg.GetId()) ``` -------------------------------- ### Delete Single and Bulk Pipelines Source: https://context7.com/grafana/fleet-management-api/llms.txt Remove pipelines using either `DeletePipeline` for a single pipeline by ID or `BulkDeletePipelines` for atomic deletion of multiple pipelines. The bulk delete operation is transactional. ```go // Single delete _, err = pipelineClient.DeletePipeline(ctx, connect.NewRequest(&pipelinev1.DeletePipelineRequest{ Id: "01HXYZ123456", })) if err != nil { log.Fatalf("delete pipeline: %v", err) } // Bulk delete _, err = pipelineClient.BulkDeletePipelines(ctx, connect.NewRequest(&pipelinev1.BulkDeletePipelinesRequest{ Ids: []string{"01HXYZ000001", "01HXYZ000002", "01HXYZ000003"}, })) if err != nil { log.Fatalf("bulk delete pipelines: %v", err) } ``` -------------------------------- ### Mount CollectorService Server Source: https://context7.com/grafana/fleet-management-api/llms.txt Registers CollectorService RPCs as an HTTP handler. Supports Connect, gRPC, and gRPC-Web protocols. ```go package main import ( "context" "net/http" "connectrpc.com/connect" collectorv1 "github.com/grafana/fleet-management-api/api/gen/proto/go/collector/v1" "github.com/grafana/fleet-management-api/api/gen/proto/go/collector/v1/collectorv1connect" "golang.org/x/net/http2" "golang.org/x/net/http2/h2c" ) type myCollectorService struct { collectorv1connect.UnimplementedCollectorServiceHandler } func (s *myCollectorService) GetCollector( ctx context.Context, req *connect.Request[collectorv1.GetCollectorRequest], ) (*connect.Response[collectorv1.Collector], error) { return connect.NewResponse(&collectorv1.Collector{ Id: req.Msg.Id, Name: "example", }), nil } func main() { mux := http.NewServeMux() path, handler := collectorv1connect.NewCollectorServiceHandler(&myCollectorService{}) mux.Handle(path, handler) http.ListenAndServe(":8080", h2c.NewHandler(mux, &http2.Server{})) } ``` -------------------------------- ### ListPipelines Source: https://context7.com/grafana/fleet-management-api/llms.txt Query pipelines by attribute and type filters. Returns pipelines whose matchers match the provided local and/or remote attribute sets. Optionally filter by `config_type` (Alloy vs OTel) and `enabled` state. ```APIDOC ## ListPipelines ### Description Query pipelines by attribute and type filters. Returns pipelines whose matchers match the provided local and/or remote attribute sets. Optionally filter by `config_type` (Alloy vs OTel) and `enabled` state. ### Method POST ### Endpoint `/v1/pipelines:list` ### Parameters #### Request Body - **local_attributes** (map[string]string) - Optional - A map of local attributes to filter pipelines by. - **remote_attributes** (map[string]string) - Optional - A map of remote attributes to filter pipelines by. - **config_type** (ConfigType) - Optional - Filters pipelines by their configuration type (e.g., Alloy, OTel). - **enabled** (bool) - Optional - Filters pipelines based on their enabled state. ### Request Example ```json { "local_attributes": { "env": "production", "region": "us-east-1" }, "remote_attributes": { "team": "platform" }, "config_type": "CONFIG_TYPE_ALLOY", "enabled": true } ``` ### Response #### Success Response (200) - **pipelines** (array) - A list of pipelines matching the filter criteria. - **id** (string) - The unique identifier of the pipeline. - **name** (string) - The name of the pipeline. - **matchers** (array) - A list of matchers associated with the pipeline. - **config_type** (ConfigType) - The configuration type of the pipeline. - **enabled** (bool) - The enabled state of the pipeline. - **updated_at** (timestamp) - The timestamp when the pipeline was last updated. #### Response Example ```json { "pipelines": [ { "id": "01HXYZ123456", "name": "prod-metrics-pipeline", "matchers": [ "{env=\"production\"}" ], "config_type": "CONFIG_TYPE_ALLOY", "enabled": true, "updated_at": "2023-10-27T10:00:00Z" } ] } ``` ``` -------------------------------- ### UpdatePipeline Source: https://context7.com/grafana/fleet-management-api/llms.txt Replace an existing pipeline's contents and matchers. Fields not provided are cleared. Returns `NOT_FOUND` if the pipeline does not exist. ```APIDOC ## UpdatePipeline ### Description Replace an existing pipeline's contents and matchers. Fields not provided are cleared. Returns `NOT_FOUND` if the pipeline does not exist. ### Method PUT ### Endpoint `/v1/pipelines/{pipeline_id}` ### Parameters #### Path Parameters - **pipeline_id** (string) - Required - The ID of the pipeline to update. #### Request Body - **pipeline** (Pipeline) - Required - The updated pipeline object. - **id** (string) - Required - The ID of the pipeline. - **name** (string) - Required - The name of the pipeline. - **contents** (string) - Required - The pipeline configuration content. - **matchers** (array) - Optional - A list of matchers for the pipeline. - **config_type** (ConfigType) - Required - The configuration type of the pipeline. - **enabled** (bool) - Required - The enabled state of the pipeline. - **validate_only** (bool) - Optional - If true, the update will be validated but not applied. ### Request Example ```json { "pipeline": { "id": "01HXYZ123456", "name": "prod-metrics-pipeline", "contents": "/* updated Alloy config */", "matchers": [ "{env=\"production\"}", "{region=\"us-east-1\"}" ], "config_type": "CONFIG_TYPE_ALLOY", "enabled": true }, "validate_only": false } ``` ### Response #### Success Response (200) - **updated_at** (timestamp) - The timestamp when the pipeline was updated. #### Response Example ```json { "updated_at": "2023-10-27T10:05:00Z" } ``` ``` -------------------------------- ### ListCollectorAttributes - Enumerate Attribute Keys and Values Source: https://context7.com/grafana/fleet-management-api/llms.txt Returns maps of all `local_attributes` and `remote_attributes` keys along with their distinct values currently in use across all collectors. This is useful for building matcher UIs or auditing label usage. ```go resp, err := client.ListCollectorAttributes(ctx, connect.NewRequest(&collectorv1.ListCollectorAttributesRequest{})) if err != nil { log.Fatalf("list collector attributes: %v", err) } fmt.Println("Remote attribute keys and values:") for key, attrs := range resp.Msg.RemoteAttributes { vals := make([]string, 0, len(attrs.Values)) for _, v := range attrs.Values { vals = append(vals, v.Value) } fmt.Printf(" %s: %v\n", key, vals) } // Output example: // Remote attribute keys and values: // env: [production staging] // region: [us-east-1 eu-west-1] // team: [platform infra] ``` -------------------------------- ### UpsertPipeline Source: https://context7.com/grafana/fleet-management-api/llms.txt Create or overwrite a pipeline by name. Idempotently creates or fully replaces a pipeline, useful for GitOps workflows. ```APIDOC ## UpsertPipeline — Create or overwrite a pipeline by name Idempotently creates or fully replaces a pipeline. Useful for GitOps workflows where the desired state is declared and applied repeatedly. ```go resp, err := pipelineClient.UpsertPipeline(ctx, connect.NewRequest(&pipelinev1.UpsertPipelineRequest{ Pipeline: &pipelinev1.Pipeline{ Name: "prod-metrics-pipeline", Contents: ` prometheus.scrape "node" { targets = [{"__address__" = "localhost:9100"}] forward_to = [prometheus.remote_write.mimir.receiver] } prometheus.remote_write "mimir" { endpoint { url = "https://mimir.example.grafana.net/api/prom/push" basic_auth { username = "123456" password_file = "/etc/grafana/token" } } }`, Matchers: []string{`{env="production"}`}, ConfigType: pipelinev1.ConfigType_CONFIG_TYPE_ALLOY, Enabled: proto.Bool(true), }, })) if err != nil { log.Fatalf("upsert pipeline: %v", err) } fmt.Printf("upserted pipeline id=%s\n", resp.Msg.GetId()) ``` ``` -------------------------------- ### DeleteCollector and BulkDeleteCollectors - Remove Collectors Source: https://context7.com/grafana/fleet-management-api/llms.txt Use `DeleteCollector` to remove a single collector and `BulkDeleteCollectors` to atomically remove a list of collectors. The bulk delete operation is all-or-nothing; if any ID is missing, the entire request fails. ```go // Single delete _, err = client.DeleteCollector(ctx, connect.NewRequest(&collectorv1.DeleteCollectorRequest{ Id: "alloy-decommissioned-01", })) if err != nil { log.Fatalf("delete collector: %v", err) } // Bulk delete _, err = client.BulkDeleteCollectors(ctx, connect.NewRequest(&collectorv1.BulkDeleteCollectorsRequest{ Ids: []string{"alloy-old-01", "alloy-old-02", "alloy-old-03"}, })) if err != nil { log.Fatalf("bulk delete collectors: %v", err) } fmt.Println("collectors deleted") ``` -------------------------------- ### UpdateCollector - Full Collector Replacement Source: https://context7.com/grafana/fleet-management-api/llms.txt Use this to replace all fields of a collector. Omitted fields will be removed, so this is not a partial update. ```go resp, err := client.UpdateCollector(ctx, connect.NewRequest(&collectorv1.UpdateCollectorRequest{ Collector: &collectorv1.Collector{ Id: "alloy-prod-us-east-01", Name: "Production US-East Alloy Node 01 (updated)", RemoteAttributes: map[string]string{ "env": "production", "region": "us-east-1", "team": "platform", "tier": "critical", // added attribute }, CollectorType: collectorv1.CollectorType_COLLECTOR_TYPE_ALLOY, Enabled: proto.Bool(true), }, })) if err != nil { log.Fatalf("update collector: %v", err) } fmt.Printf("updated name=%s attributes=%v\n", resp.Msg.Name, resp.Msg.RemoteAttributes) ``` -------------------------------- ### ListCollectors - Filter by Attribute Matchers Source: https://context7.com/grafana/fleet-management-api/llms.txt Retrieves all collectors that match the provided Prometheus Alertmanager-style matchers. If no matchers are provided, all collectors are returned. ```go resp, err := client.ListCollectors(ctx, connect.NewRequest(&collectorv1.ListCollectorsRequest{ Matchers: []string{ `{env="production"}`, `{region=~"us-.*"}`, }, })) if err != nil { log.Fatalf("list collectors: %v", err) } fmt.Printf("found %d collectors\n", len(resp.Msg.Collectors)) for _, c := range resp.Msg.Collectors { fmt.Printf(" %s (%s)\n", c.Id, c.Name) } ``` -------------------------------- ### CreateCollector Source: https://context7.com/grafana/fleet-management-api/llms.txt Registers a new collector in the Fleet Management service, seeding server-side labels for pipeline matching. ```APIDOC ## CreateCollector ### Description Creates a collector record in the Fleet Management service. The `id` field uniquely identifies the collector. `remote_attributes` seed the server-side labels used for pipeline matching. ### Method `CreateCollector` ### Request Body - **Collector** (Collector) - Required - The collector object to create. - **Id** (string) - Required - The unique identifier for the collector. - **Name** (string) - Required - The display name for the collector. - **RemoteAttributes** (map[string]string) - Optional - Server-side attributes to associate with the collector for matching. - **CollectorType** (CollectorType) - Required - The type of the collector (e.g., ALLOY, OPENTELEMETRY). - **Enabled** (bool) - Optional - Whether the collector should be enabled upon creation. ### Request Example ```go resp, err := client.CreateCollector(ctx, connect.NewRequest(&collectorv1.CreateCollectorRequest{ Collector: &collectorv1.Collector{ Id: "alloy-prod-us-east-01", Name: "Production US-East Alloy Node 01", RemoteAttributes: map[string]string{ "env": "production", "region": "us-east-1", "team": "platform", }, CollectorType: collectorv1.CollectorType_COLLECTOR_TYPE_ALLOY, Enabled: proto.Bool(true), }, })) ``` ### Response #### Success Response (200) - **Id** (string) - The unique identifier of the created collector. ``` -------------------------------- ### CreateCollector - Register a new collector Source: https://context7.com/grafana/fleet-management-api/llms.txt Creates a collector record in the Fleet Management service. The `id` field must be unique, and `remote_attributes` are used for server-side label matching with pipelines. The collector type and enabled state can also be set. ```go resp, err := client.CreateCollector(ctx, connect.NewRequest(&collectorv1.CreateCollectorRequest{ Collector: &collectorv1.Collector{ Id: "alloy-prod-us-east-01", Name: "Production US-East Alloy Node 01", RemoteAttributes: map[string]string{ "env": "production", "region": "us-east-1", "team": "platform", }, CollectorType: collectorv1.CollectorType_COLLECTOR_TYPE_ALLOY, Enabled: proto.Bool(true), }, })) if err != nil { log.Fatalf("create collector: %v", err) } fmt.Printf("created collector id=%s\n", resp.Msg.Id) ``` -------------------------------- ### GetPipeline / GetPipelineID Source: https://context7.com/grafana/fleet-management-api/llms.txt Retrieve a pipeline by ID or resolve a name to an ID. `GetPipeline` fetches the full pipeline by server-assigned ID; `GetPipelineID` resolves a pipeline name to its ID. ```APIDOC ## GetPipeline / GetPipelineID — Retrieve a pipeline by ID or resolve a name to an ID `GetPipeline` fetches the full pipeline by server-assigned ID; `GetPipelineID` resolves a pipeline name to its ID (useful when only the human-readable name is known). ```go // Resolve name → ID idResp, err := pipelineClient.GetPipelineID(ctx, connect.NewRequest(&pipelinev1.GetPipelineIDRequest{ Name: "prod-metrics-pipeline", })) if err != nil { log.Fatalf("get pipeline id: %v", err) } pipelineID := idResp.Msg.Id // Fetch full pipeline by ID getResp, err := pipelineClient.GetPipeline(ctx, connect.NewRequest(&pipelinev1.GetPipelineRequest{ Id: pipelineID, })) if err != nil { log.Fatalf("get pipeline: %v", err) } p := getResp.Msg fmt.Printf("name=%s enabled=%v matchers=%v\n", p.Name, p.GetEnabled(), p.Matchers) fmt.Printf("config_type=%s\ncontents:\n%s\n", p.ConfigType, p.Contents) ``` ``` -------------------------------- ### GetCollector - Retrieve a single collector by ID Source: https://context7.com/grafana/fleet-management-api/llms.txt Retrieves full details for a specific collector, including its attributes, timestamps, type, and enabled state. Handles the case where the collector is not found. ```go resp, err := client.GetCollector(ctx, connect.NewRequest(&collectorv1.GetCollectorRequest{ Id: "alloy-prod-us-east-01", })) if err != nil { var connectErr *connect.Error if errors.As(err, &connectErr) && connectErr.Code() == connect.CodeNotFound { log.Println("collector not found") return } log.Fatalf("get collector: %v", err) } c := resp.Msg fmt.Printf("id=%s name=%s type=%s\n", c.Id, c.Name, c.CollectorType) fmt.Printf("local_attributes=%v\n", c.LocalAttributes) fmt.Printf("remote_attributes=%v\n", c.RemoteAttributes) fmt.Printf("created_at=%v updated_at=%v\n", c.CreatedAt.AsTime(), c.UpdatedAt.AsTime()) ``` -------------------------------- ### ListCollectors Source: https://context7.com/grafana/fleet-management-api/llms.txt Filters and returns collectors based on provided Prometheus Alertmanager matchers. If no matchers are provided, all collectors are returned. ```APIDOC ## ListCollectors — Filter collectors by attribute matchers ### Description Returns all collectors matching the provided Prometheus Alertmanager matchers. Omitting matchers returns all collectors. ### Method GET ### Endpoint (Not explicitly defined, but implies a list operation) ### Parameters #### Query Parameters - **Matchers** (array[string]) - Optional - A list of Prometheus Alertmanager-style matchers to filter collectors. ### Request Example ```go client.ListCollectors(ctx, connect.NewRequest(&collectorv1.ListCollectorsRequest{ Matchers: []string{ `{env="production"}`, `{region=~"us-.*"}`, }, })) ``` ### Response #### Success Response (200) - **Collectors** (array[object]) - A list of collectors matching the specified criteria. - **Id** (string) - The unique identifier of the collector. - **Name** (string) - The name of the collector. - **RemoteAttributes** (map[string]string) - The remote attributes of the collector. - **CollectorType** (string) - The type of the collector. - **Enabled** (boolean) - Whether the collector is enabled. ### Response Example ``` found 2 collectors alloy-prod-us-east-01 (Production US-East Alloy Node 01) alloy-prod-us-west-01 (Production US-West Alloy Node 01) ``` ``` -------------------------------- ### ListCollectorAttributes Source: https://context7.com/grafana/fleet-management-api/llms.txt Enumerates all attribute keys and their distinct values currently in use across all collectors for both local and remote attributes. ```APIDOC ## ListCollectorAttributes — Enumerate all attribute keys and values in use ### Description Returns maps of all `local_attributes` and `remote_attributes` keys together with the distinct values currently in use across all collectors — useful for building matcher UIs or auditing label usage. ### Method GET ### Endpoint (Not explicitly defined, but implies a list operation for attributes) ### Parameters #### Request Body (No parameters required for this operation) ### Request Example ```go client.ListCollectorAttributes(ctx, connect.NewRequest(&collectorv1.ListCollectorAttributesRequest{})) ``` ### Response #### Success Response (200) - **RemoteAttributes** (map[string]object) - A map where keys are attribute names and values contain attribute details. - **Values** (array[object]) - A list of distinct values for the attribute. - **Value** (string) - The distinct value of the attribute. - **LocalAttributes** (map[string]object) - Similar structure for local attributes. ### Response Example ``` Remote attribute keys and values: env: [production staging] region: [us-east-1 eu-west-1] team: [platform infra] ``` ``` -------------------------------- ### BulkUpdateCollectors - Atomic Remote Attribute Updates Source: https://context7.com/grafana/fleet-management-api/llms.txt Atomically applies JSON-patch-style operations to the remote attributes of multiple collectors. Any error during the process will roll back all changes. ```go resp, err := client.BulkUpdateCollectors(ctx, connect.NewRequest(&collectorv1.BulkUpdateCollectorsRequest{ Ids: []string{ "alloy-prod-us-east-01", "alloy-prod-us-east-02", "alloy-prod-us-east-03", }, Ops: []*collectorv1.Operation{ { Op: collectorv1.Operation_ADD, Path: "remoteAttributes.maintenance", Value: proto.String("true"), }, { Op: collectorv1.Operation_REPLACE, Path: "remoteAttributes.tier", // selective replace: only replaces if current value matches oldValue OldValue: proto.String("standard"), Value: proto.String("critical"), }, { Op: collectorv1.Operation_REMOVE, Path: "remoteAttributes.deprecated_label", }, }, })) if err != nil { log.Fatalf("bulk update collectors: %v", err) } // HTTP 200 / empty response body signals success _ = resp fmt.Println("bulk update applied successfully") ``` -------------------------------- ### NewCollectorServiceHandler Source: https://context7.com/grafana/fleet-management-api/llms.txt Registers all CollectorService RPCs as an HTTP handler, supporting Connect, gRPC, and gRPC-Web protocols. ```APIDOC ## NewCollectorServiceHandler — Mount a CollectorService server Registers all CollectorService RPCs as an HTTP handler. Supports Connect, gRPC, and gRPC-Web protocols out of the box. ```go package main import ( "context" "net/http" "connectrpc.com/connect" collectorv1 "github.com/grafana/fleet-management-api/api/gen/proto/go/collector/v1" "github.com/grafana/fleet-management-api/api/gen/proto/go/collector/v1/collectorv1connect" "golang.org/x/net/http2" "golang.org/x/net/http2/h2c" ) type myCollectorService struct { collectorv1connect.UnimplementedCollectorServiceHandler } func (s *myCollectorService) GetCollector( ctx context.Context, req *connect.Request[collectorv1.GetCollectorRequest], ) (*connect.Response[collectorv1.Collector], error) { return connect.NewResponse(&collectorv1.Collector{ Id: req.Msg.Id, Name: "example", }), nil } func main() { mux := http.NewServeMux() path, handler := collectorv1connect.NewCollectorServiceHandler(&myCollectorService{}) mux.Handle(path, handler) http.ListenAndServe(":8080", h2c.NewHandler(mux, &http2.Server{})) } ``` ``` -------------------------------- ### DeleteCollector / BulkDeleteCollectors Source: https://context7.com/grafana/fleet-management-api/llms.txt Removes one or more collectors. `DeleteCollector` removes a single collector, while `BulkDeleteCollectors` atomically removes a list of collectors. ```APIDOC ## DeleteCollector / BulkDeleteCollectors — Remove one or many collectors ### Description `DeleteCollector` removes a single collector; `BulkDeleteCollectors` atomically removes a list (all-or-nothing — if any ID is missing the whole request fails). ### Method (Implied DELETE based on operation) ### Endpoint (Not explicitly defined, but implies delete operations) ### Parameters #### DeleteCollector ##### Request Body - **Id** (string) - Required - The ID of the collector to delete. #### BulkDeleteCollectors ##### Request Body - **Ids** (array[string]) - Required - A list of collector IDs to delete. ### Request Example ```go // Single delete client.DeleteCollector(ctx, connect.NewRequest(&collectorv1.DeleteCollectorRequest{ Id: "alloy-decommissioned-01", })) // Bulk delete client.BulkDeleteCollectors(ctx, connect.NewRequest(&collectorv1.BulkDeleteCollectorsRequest{ Ids: []string{"alloy-old-01", "alloy-old-02", "alloy-old-03"}, })) ``` ### Response #### Success Response (200) (Response details not explicitly specified, but implies success upon deletion) ``` -------------------------------- ### DeletePipeline / BulkDeletePipelines Source: https://context7.com/grafana/fleet-management-api/llms.txt Remove one or many pipelines. `DeletePipeline` removes a single pipeline by ID; `BulkDeletePipelines` is atomic — all specified IDs must exist or the entire operation is rolled back. ```APIDOC ## DeletePipeline / BulkDeletePipelines ### Description Remove one or many pipelines. `DeletePipeline` removes a single pipeline by ID; `BulkDeletePipelines` is atomic — all specified IDs must exist or the entire operation is rolled back. ### Method DELETE ### Endpoint - `DeletePipeline`: `/v1/pipelines/{pipeline_id}` - `BulkDeletePipelines`: `/v1/pipelines:bulkDelete` ### Parameters #### DeletePipeline ##### Path Parameters - **pipeline_id** (string) - Required - The ID of the pipeline to delete. #### BulkDeletePipelines ##### Request Body - **ids** (array) - Required - A list of pipeline IDs to delete. ### Request Example ```json // Single delete { "id": "01HXYZ123456" } // Bulk delete { "ids": [ "01HXYZ000001", "01HXYZ000002", "01HXYZ000003" ] } ``` ### Response #### Success Response (200) - **message** (string) - Confirmation message indicating the pipelines were deleted. #### Response Example ```json { "message": "Pipelines deleted successfully." } ``` ```