Skip to content

Commit

Permalink
internal/resource: Add Prometheus metrics configuration capability to…
Browse files Browse the repository at this point in the history
… `definednet_lighthouse` resource (#60)

Enable metrics collection capability on `definednet_lighthouse` instances. The configuration is exposed via `metrics` block providing

- `listen` - a hostport for the metrics server (default `127.0.0.1:8080`),
- `path` - a path for serving Prometheus metrics endpoint (default `/metrics`),
- `namespace` - Prometheus' metrics namespace (default `nebula`),
- `subsystem` - Prometheus' metrics subsystem (default `host`), and
- `enable_extra_metrics` - enable lighthouse metrics (default `false`).
  • Loading branch information
janartodesk authored Nov 28, 2024
1 parent 4c215dd commit e3b96ee
Show file tree
Hide file tree
Showing 8 changed files with 397 additions and 0 deletions.
44 changes: 44 additions & 0 deletions docs/resources/lighthouse.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,37 @@ resource "definednet_lighthouse" "example" {
static_addresses = ["84.123.10.1"]
tags = ["service:app"]
}
resource "definednet_lighthouse" "metrics_minimal" {
name = "example.defined.test"
network_id = "network-7P81MCS2TVAY9XJWQTNJ3PWYPD"
role_id = "role-WSG78880Z655TQJVQFL5CZ405B"
listen_port = 4242
static_addresses = ["84.123.10.1"]
tags = ["service:app"]
metrics {
enabled = true
}
}
resource "definednet_lighthouse" "metrics" {
name = "example.defined.test"
network_id = "network-7P81MCS2TVAY9XJWQTNJ3PWYPD"
role_id = "role-WSG78880Z655TQJVQFL5CZ405B"
listen_port = 4242
static_addresses = ["84.123.10.1"]
tags = ["service:app"]
metrics {
enabled = true
listen = "127.0.0.1:9100"
path = "/-/metrics"
namespace = "infra"
subsystem = "nebula"
enable_extra_metrics = true
}
}
```

<!-- schema generated by tfplugindocs -->
Expand All @@ -55,6 +86,7 @@ resource "definednet_lighthouse" "example" {

### Optional

- `metrics` (Block, Optional) Host's metrics exporter configuration (see [below for nested schema](#nestedblock--metrics))
- `role_id` (String) Lighthouse's role ID on Defined.net
- `tags` (List of String) Lighthouse's tags on Defined.net

Expand All @@ -63,3 +95,15 @@ resource "definednet_lighthouse" "example" {
- `enrollment_code` (String, Sensitive) Lighthouse's enrollment code
- `id` (String) Lighthouse's ID
- `ip_address` (String) Lighthouse's IP address on Defined.net overlay network

<a id="nestedblock--metrics"></a>
### Nested Schema for `metrics`

Optional:

- `enable_extra_metrics` (Boolean) Enable extra metrics
- `enabled` (Boolean) Enable metrics exporter
- `listen` (String) Host-port for Prometheus metrics exporter listener
- `namespace` (String) Prometheus metrics' namespace
- `path` (String) Prometheus metrics exporter's HTTP path
- `subsystem` (String) Prometheus metrics' subsystem
31 changes: 31 additions & 0 deletions examples/resources/definednet_lighthouse/resource.tf
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,34 @@ resource "definednet_lighthouse" "example" {
static_addresses = ["84.123.10.1"]
tags = ["service:app"]
}

resource "definednet_lighthouse" "metrics_minimal" {
name = "example.defined.test"
network_id = "network-7P81MCS2TVAY9XJWQTNJ3PWYPD"
role_id = "role-WSG78880Z655TQJVQFL5CZ405B"
listen_port = 4242
static_addresses = ["84.123.10.1"]
tags = ["service:app"]

metrics {
enabled = true
}
}

resource "definednet_lighthouse" "metrics" {
name = "example.defined.test"
network_id = "network-7P81MCS2TVAY9XJWQTNJ3PWYPD"
role_id = "role-WSG78880Z655TQJVQFL5CZ405B"
listen_port = 4242
static_addresses = ["84.123.10.1"]
tags = ["service:app"]

metrics {
enabled = true
listen = "127.0.0.1:9100"
path = "/-/metrics"
namespace = "infra"
subsystem = "nebula"
enable_extra_metrics = true
}
}
30 changes: 30 additions & 0 deletions internal/resource/lighthouse/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,21 @@ func (r *Resource) Create(ctx context.Context, req resource.CreateRequest, resp
IsLighthouse: true,
IsRelay: false,
Tags: tags,
ConfigOverrides: func() []definednet.ConfigOverride {
if lo.IsNil(state.Metrics) || !state.Metrics.Enabled.ValueBool() {
return nil
}

return []definednet.ConfigOverride{
{Key: "stats.type", Value: "prometheus"},
{Key: "stats.listen", Value: state.Metrics.Listen.ValueString()},
{Key: "stats.path", Value: state.Metrics.Path.ValueString()},
{Key: "stats.namespace", Value: state.Metrics.Namespace.ValueString()},
{Key: "stats.subsystem", Value: state.Metrics.Subsystem.ValueString()},
{Key: "stats.lighthouse_metrics", Value: state.Metrics.EnableExtraMetrics.ValueBool()},
{Key: "stats.interval", Value: "60s"},
}
}(),
})

if err != nil {
Expand Down Expand Up @@ -189,6 +204,21 @@ func (r *Resource) Update(ctx context.Context, req resource.UpdateRequest, resp
}),
ListenPort: int(state.ListenPort.ValueInt32()),
Tags: tags,
ConfigOverrides: func() []definednet.ConfigOverride {
if lo.IsNil(state.Metrics) || !state.Metrics.Enabled.ValueBool() {
return nil
}

return []definednet.ConfigOverride{
{Key: "stats.type", Value: "prometheus"},
{Key: "stats.listen", Value: state.Metrics.Listen.ValueString()},
{Key: "stats.path", Value: state.Metrics.Path.ValueString()},
{Key: "stats.namespace", Value: state.Metrics.Namespace.ValueString()},
{Key: "stats.subsystem", Value: state.Metrics.Subsystem.ValueString()},
{Key: "stats.lighthouse_metrics", Value: state.Metrics.EnableExtraMetrics.ValueBool()},
{Key: "stats.interval", Value: "60s"},
}
}(),
})

if err != nil {
Expand Down
105 changes: 105 additions & 0 deletions internal/resource/lighthouse/resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -252,3 +252,108 @@ var _ = DescribeTable("lighthouse resource management",
},
),
)

var _ = DescribeTable("host metrics exporter configuration management",
func(steps ...resource.TestStep) {
resource.Test(GinkgoT(), resource.TestCase{
Steps: lo.Map(steps, func(step resource.TestStep, _ int) resource.TestStep {
step.ProtoV6ProviderFactories = map[string]func() (tfprotov6.ProviderServer, error){
"definednet": providerserver.NewProtocol6WithError(providerFactory()),
}

return step
}),
})
},
Entry("assert enabling metrics configures default metrics exporter",
resource.TestStep{
ConfigFile: config.StaticFile("testdata/lighthouse_metrics_defaults.tf"),
ConfigStateChecks: []statecheck.StateCheck{
statecheck.ExpectKnownValue("definednet_lighthouse.metrics_default_test", tfjsonpath.New("metrics").AtMapKey("listen"), knownvalue.StringExact("127.0.0.1:8080")),
statecheck.ExpectKnownValue("definednet_lighthouse.metrics_default_test", tfjsonpath.New("metrics").AtMapKey("path"), knownvalue.StringExact("/metrics")),
statecheck.ExpectKnownValue("definednet_lighthouse.metrics_default_test", tfjsonpath.New("metrics").AtMapKey("namespace"), knownvalue.StringExact("nebula")),
statecheck.ExpectKnownValue("definednet_lighthouse.metrics_default_test", tfjsonpath.New("metrics").AtMapKey("subsystem"), knownvalue.StringExact("host")),
statecheck.ExpectKnownValue("definednet_lighthouse.metrics_default_test", tfjsonpath.New("metrics").AtMapKey("enable_extra_metrics"), knownvalue.Bool(false)),
},
},
),
Entry("assert metrics exporter is configurable",
resource.TestStep{
ConfigFile: config.StaticFile("testdata/lighthouse_metrics.tf"),
ConfigVariables: config.Variables{
"metrics_listen": config.StringVariable("100.64.0.1:9100"),
"metrics_path": config.StringVariable("/-/metrics"),
"metrics_namespace": config.StringVariable("test"),
"metrics_subsystem": config.StringVariable("configurable_host"),
"metrics_enable_extra": config.BoolVariable(true),
},
ConfigStateChecks: []statecheck.StateCheck{
statecheck.ExpectKnownValue("definednet_lighthouse.metrics_test", tfjsonpath.New("metrics").AtMapKey("listen"), knownvalue.StringExact("100.64.0.1:9100")),
statecheck.ExpectKnownValue("definednet_lighthouse.metrics_test", tfjsonpath.New("metrics").AtMapKey("path"), knownvalue.StringExact("/-/metrics")),
statecheck.ExpectKnownValue("definednet_lighthouse.metrics_test", tfjsonpath.New("metrics").AtMapKey("namespace"), knownvalue.StringExact("test")),
statecheck.ExpectKnownValue("definednet_lighthouse.metrics_test", tfjsonpath.New("metrics").AtMapKey("subsystem"), knownvalue.StringExact("configurable_host")),
statecheck.ExpectKnownValue("definednet_lighthouse.metrics_test", tfjsonpath.New("metrics").AtMapKey("enable_extra_metrics"), knownvalue.Bool(true)),
},
},
),
Entry("assert metrics configuration updates are executed in-place",
resource.TestStep{
ConfigFile: config.StaticFile("testdata/lighthouse_metrics.tf"),
ConfigVariables: config.Variables{
"metrics_listen": config.StringVariable("127.0.0.1:8080"),
"metrics_path": config.StringVariable("/metrics"),
"metrics_namespace": config.StringVariable("nebula"),
"metrics_subsystem": config.StringVariable("host"),
"metrics_enable_extra": config.BoolVariable(false),
},
},
resource.TestStep{
ConfigFile: config.StaticFile("testdata/lighthouse_metrics.tf"),
ConfigVariables: config.Variables{
"metrics_listen": config.StringVariable("100.64.0.1:9100"),
"metrics_path": config.StringVariable("/-/metrics"),
"metrics_namespace": config.StringVariable("test"),
"metrics_subsystem": config.StringVariable("configurable_host"),
"metrics_enable_extra": config.BoolVariable(true),
},
ConfigPlanChecks: resource.ConfigPlanChecks{
PreApply: []plancheck.PlanCheck{
plancheck.ExpectResourceAction("definednet_lighthouse.metrics_test", plancheck.ResourceActionUpdate),
},
},
ConfigStateChecks: []statecheck.StateCheck{
statecheck.ExpectKnownValue("definednet_lighthouse.metrics_test", tfjsonpath.New("metrics").AtMapKey("listen"), knownvalue.StringExact("100.64.0.1:9100")),
statecheck.ExpectKnownValue("definednet_lighthouse.metrics_test", tfjsonpath.New("metrics").AtMapKey("path"), knownvalue.StringExact("/-/metrics")),
statecheck.ExpectKnownValue("definednet_lighthouse.metrics_test", tfjsonpath.New("metrics").AtMapKey("namespace"), knownvalue.StringExact("test")),
statecheck.ExpectKnownValue("definednet_lighthouse.metrics_test", tfjsonpath.New("metrics").AtMapKey("subsystem"), knownvalue.StringExact("configurable_host")),
statecheck.ExpectKnownValue("definednet_lighthouse.metrics_test", tfjsonpath.New("metrics").AtMapKey("enable_extra_metrics"), knownvalue.Bool(true)),
},
},
),
Entry("assert host import populates metrics configuration",
resource.TestStep{
ConfigFile: config.StaticFile("testdata/lighthouse_metrics.tf"),
ConfigVariables: config.Variables{
"metrics_listen": config.StringVariable("100.64.0.1:9100"),
"metrics_path": config.StringVariable("/-/metrics"),
"metrics_namespace": config.StringVariable("test"),
"metrics_subsystem": config.StringVariable("configurable_host"),
"metrics_enable_extra": config.BoolVariable(true),
},
},
resource.TestStep{
ConfigFile: config.StaticFile("testdata/lighthouse_metrics.tf"),
ConfigVariables: config.Variables{
"metrics_listen": config.StringVariable("100.64.0.1:9100"),
"metrics_path": config.StringVariable("/-/metrics"),
"metrics_namespace": config.StringVariable("test"),
"metrics_subsystem": config.StringVariable("configurable_host"),
"metrics_enable_extra": config.BoolVariable(true),
},
ResourceName: "definednet_lighthouse.metrics_test",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"enrollment_code"},
},
),
)
57 changes: 57 additions & 0 deletions internal/resource/lighthouse/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import (
"github.com/hashicorp/terraform-plugin-framework-validators/listvalidator"
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/boolplanmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
"github.com/hashicorp/terraform-plugin-framework/types"
Expand Down Expand Up @@ -80,6 +82,61 @@ var Schema = schema.Schema{
},
},
},
Blocks: map[string]schema.Block{
"metrics": schema.SingleNestedBlock{
Description: "Host's metrics exporter configuration",
Attributes: map[string]schema.Attribute{
"enabled": schema.BoolAttribute{
Description: "Enable metrics exporter",
Optional: true,
},
"listen": schema.StringAttribute{
Description: "Host-port for Prometheus metrics exporter listener",
Optional: true,
Computed: true,
Default: stringdefault.StaticString("127.0.0.1:8080"),
PlanModifiers: []planmodifier.String{
stringplanmodifier.UseStateForUnknown(),
},
},
"path": schema.StringAttribute{
Description: "Prometheus metrics exporter's HTTP path",
Optional: true,
Computed: true,
Default: stringdefault.StaticString("/metrics"),
PlanModifiers: []planmodifier.String{
stringplanmodifier.UseStateForUnknown(),
},
},
"namespace": schema.StringAttribute{
Description: "Prometheus metrics' namespace",
Optional: true,
Computed: true,
Default: stringdefault.StaticString("nebula"),
PlanModifiers: []planmodifier.String{
stringplanmodifier.UseStateForUnknown(),
},
},
"subsystem": schema.StringAttribute{
Description: "Prometheus metrics' subsystem",
Optional: true,
Computed: true,
Default: stringdefault.StaticString("host"),
PlanModifiers: []planmodifier.String{
stringplanmodifier.UseStateForUnknown(),
},
},
"enable_extra_metrics": schema.BoolAttribute{
Description: "Enable extra metrics",
Optional: true,
Computed: true,
PlanModifiers: []planmodifier.Bool{
boolplanmodifier.UseStateForUnknown(),
},
},
},
},
},
}

//go:embed docs/resource.md
Expand Down
Loading

0 comments on commit e3b96ee

Please sign in to comment.