Skip to content

Commit 268a157

Browse files
authored
feat: Fleet Resources (BPOP-5000) (#212)
* add terraform support for managing fleets * add docs for bindplane_fleet resources * fix lint * fix bundle for CI * try and account for integraiton test deprecated component * one more revert of parse_timestamp change * simplify configuration of the fleet resource * ForceNew on agent_type and Platform * fix fleets configuration reference
1 parent 8610002 commit 268a157

5 files changed

Lines changed: 430 additions & 2 deletions

File tree

client/client.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,36 @@ func (i *BindPlane) DeleteExtension(name string) error {
250250
return nil
251251
}
252252

253+
// Fleet takes a name and returns the matching fleet
254+
func (i *BindPlane) Fleet(name string) (*model.Fleet, error) {
255+
r, err := i.Client.Resource(context.Background(), model.KindFleet, name)
256+
if err != nil {
257+
// Do not return an error if the resource is not found. Terraform
258+
// will understand that the resource does not exist when it receives
259+
// a nil value, and will instead offer to create the resource.
260+
if isNotFoundError(err) {
261+
return nil, nil
262+
}
263+
return nil, fmt.Errorf("failed to get fleet with name %s: %w", name, err)
264+
}
265+
266+
switch f := r.(type) {
267+
case *model.Fleet:
268+
return f, nil
269+
default:
270+
return nil, fmt.Errorf("unexpected response from bindplane, expected fleet, got %T, this is a bug that should be reported", f)
271+
}
272+
}
273+
274+
// DeleteFleet will delete a BindPlane fleet
275+
func (i *BindPlane) DeleteFleet(name string) error {
276+
err := i.Client.DeleteResource(context.Background(), model.KindFleet, name)
277+
if err != nil {
278+
return fmt.Errorf("error while deleting fleet with name %s: %w", name, err)
279+
}
280+
return nil
281+
}
282+
253283
// Delete will delete a Bindplane resource
254284
func (i *BindPlane) Delete(k model.Kind, name string) error {
255285
switch k {
@@ -265,6 +295,8 @@ func (i *BindPlane) Delete(k model.Kind, name string) error {
265295
return i.DeleteExtension(name)
266296
case model.KindConnector:
267297
return i.DeleteConnector(name)
298+
case model.KindFleet:
299+
return i.DeleteFleet(name)
268300
default:
269301
return fmt.Errorf("Delete does not support bindplane kind '%s'", k)
270302
}

docs/resources/bindplane_fleet.md

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
---
2+
subcategory: "Fleet Management"
3+
description: |-
4+
A Fleet manages a collection of agents that are deployed and configured by Bindplane.
5+
---
6+
7+
# bindplane_fleet
8+
9+
The `bindplane_fleet` resource creates a Bindplane fleet that manages a collection of agents.
10+
A fleet defines which [configuration](./bindplane_configuration.md) is assigned to a group of agents,
11+
and uses a selector to match agents to the fleet based on labels.
12+
13+
## Options
14+
15+
| Option | Type | Default | Description |
16+
| --------------- | ------ | -------- | ------------------------------------------------------------------------------------------ |
17+
| `name` | string | required | The resource name for the fleet. Used internally and cannot be changed after creation. |
18+
| `display_name` | string | optional | A user-friendly name for the fleet. Can be changed anytime. |
19+
| `agent_type` | string | optional | The collector agent type for agents in this fleet. |
20+
| `platform` | string | optional | The platform (OS/architecture) for agents in this fleet. |
21+
| `configuration` | string | optional | Name of the configuration assigned to the fleet. |
22+
23+
## Examples
24+
25+
### Basic Fleet with Agent Type and Platform
26+
27+
This example creates a fleet with collector type and platform. The selector is automatically generated to match agents with the fleet name label.
28+
29+
```hcl
30+
resource "bindplane_configuration" "example" {
31+
name = "my-config"
32+
platform = "linux"
33+
# ... configuration sources, destinations, etc.
34+
}
35+
36+
resource "bindplane_fleet" "production" {
37+
name = "us-east"
38+
display_name = "US East"
39+
agent_type = "observiq-otel-collector"
40+
platform = "linux"
41+
configuration = bindplane_configuration.example.name
42+
}
43+
```
44+
45+
### Fleet with Configuration
46+
47+
This example creates a fleet and assigns a configuration to it.
48+
49+
```hcl
50+
resource "bindplane_fleet" "staging" {
51+
name = "staging-fleet"
52+
display_name = "Staging Fleet"
53+
agent_type = "observiq-otel-collector"
54+
platform = "linux"
55+
configuration = "my-existing-config"
56+
}
57+
```
58+
59+
### Minimal Fleet
60+
61+
This example creates a fleet with minimal required fields.
62+
63+
```hcl
64+
resource "bindplane_fleet" "development" {
65+
name = "development-fleet"
66+
display_name = "Development"
67+
}
68+
```
69+
70+
## Configuration Dependency
71+
72+
When you reference a configuration from another resource using its name attribute (e.g., `bindplane_configuration.example.name`),
73+
Terraform automatically establishes a dependency. The configuration will be created before the fleet, ensuring the referenced
74+
configuration exists when the fleet is created.
75+
76+
If you hardcode a configuration name as a string literal, the provider validates that the configuration exists at creation time
77+
and returns an error if it doesn't:
78+
79+
```hcl
80+
# This will fail if "missing-config" doesn't exist
81+
resource "bindplane_fleet" "example" {
82+
name = "my-fleet"
83+
configuration = "missing-config" # ← Error: configuration 'missing-config' does not exist
84+
}
85+
```
86+
87+
## Using Fleets
88+
89+
After applying the configuration with `terraform apply`, you can view the fleet with the `bindplane get fleet` commands:
90+
91+
```bash
92+
bindplane get fleet
93+
```
94+
95+
```yaml
96+
# bindplane get fleet us-east -o yaml
97+
apiVersion: bindplane.observiq.com/v1
98+
kind: Fleet
99+
metadata:
100+
id: us-east
101+
name: us-east
102+
displayName: US East
103+
labels:
104+
agent-type: observiq-otel-collector
105+
platform: linux
106+
version: 1
107+
dateModified: 2024-05-05T10:30:00Z
108+
spec:
109+
configuration: my-config
110+
selector:
111+
matchLabels:
112+
fleet: us-east
113+
```
114+
115+
## Import
116+
117+
When using the [terraform import command](https://developer.hashicorp.com/terraform/cli/commands/import),
118+
fleets can be imported by name. For example:
119+
120+
```bash
121+
terraform import bindplane_fleet.production production-fleet
122+
```

provider/provider.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,10 +127,11 @@ func Configure() *schema.Provider {
127127
"bindplane_configuration": resourceConfiguration(),
128128
"bindplane_configuration_v2": resourceConfigurationV2(),
129129
"bindplane_destination": resourceDestination(),
130-
"bindplane_source": resourceSource(),
130+
"bindplane_extension": resourceExtension(),
131+
"bindplane_fleet": resourceFleet(),
131132
"bindplane_processor": resourceProcessor(),
132133
"bindplane_processor_bundle": resourceProcessorBundle(),
133-
"bindplane_extension": resourceExtension(),
134+
"bindplane_source": resourceSource(),
134135
},
135136
}
136137
}

0 commit comments

Comments
 (0)