Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Add metrics endpoint scrape job placeholder tests and examples #1818

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions docs/data-sources/connections_metrics_endpoint_scrape_job.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "grafana_connections_metrics_endpoint_scrape_job Data Source - terraform-provider-grafana"
subcategory: "Connections"
description: |-

---

# grafana_connections_metrics_endpoint_scrape_job (Data Source)





<!-- schema generated by tfplugindocs -->
## Schema

### Required

- `authentication_method` (String) Method to pass authentication credentials: basic or bearer.
- `name` (String) The name of the Metrics Endpoint Scrape Job. Part of the Terraform Resource ID.
- `stack_id` (String) The Stack ID of the Grafana Cloud instance. Part of the Terraform Resource ID.
- `url` (String) The url to scrape metrics.

### Optional

- `authentication_basic_password` (String, Sensitive) Password for basic authentication.
- `authentication_basic_username` (String) Username for basic authentication.
- `authentication_bearer_token` (String, Sensitive) Token for authentication bearer.

### Read-Only

- `enabled` (Boolean) Whether the Metrics Endpoint Scrape Job is enabled or not.
- `id` (String) The Terraform Resource ID. This has the format "{{ stack_id }}:{{ name }}".
- `scrape_interval_seconds` (Number) Frequency for scraping the metrics endpoint: 30, 60, or 120 seconds.
2 changes: 2 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,8 @@ resource "grafana_oncall_escalation" "example_notify_step" {
- `ca_cert` (String) Certificate CA bundle (file path or literal value) to use to verify the Grafana server's certificate. May alternatively be set via the `GRAFANA_CA_CERT` environment variable.
- `cloud_access_policy_token` (String, Sensitive) Access Policy Token for Grafana Cloud. May alternatively be set via the `GRAFANA_CLOUD_ACCESS_POLICY_TOKEN` environment variable.
- `cloud_api_url` (String) Grafana Cloud's API URL. May alternatively be set via the `GRAFANA_CLOUD_API_URL` environment variable.
- `connections_access_token` (String, Sensitive) A Grafana Connections API access token. May alternatively be set via the `GRAFANA_CONNECTIONS_ACCESS_TOKEN` environment variable.
- `connections_url` (String) A Grafana Connections API backend address. May alternatively be set via the `GRAFANA_CONNECTIONS_URL` environment variable.
- `http_headers` (Map of String, Sensitive) Optional. HTTP headers mapping keys to values used for accessing the Grafana and Grafana Cloud APIs. May alternatively be set via the `GRAFANA_HTTP_HEADERS` environment variable in JSON format.
- `insecure_skip_verify` (Boolean) Skip TLS certificate verification. May alternatively be set via the `GRAFANA_INSECURE_SKIP_VERIFY` environment variable.
- `oncall_access_token` (String, Sensitive) A Grafana OnCall access token. May alternatively be set via the `GRAFANA_ONCALL_ACCESS_TOKEN` environment variable.
Expand Down
54 changes: 54 additions & 0 deletions docs/resources/connections_metrics_endpoint_scrape_job.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "grafana_connections_metrics_endpoint_scrape_job Resource - terraform-provider-grafana"
subcategory: "Connections"
description: |-

---

# grafana_connections_metrics_endpoint_scrape_job (Resource)



## Example Usage

```terraform
resource "grafana_connections_metrics_endpoint_scrape_job" "test" {
stack_id = "test-stack-id"
name = "my-scrape-job"
authentication_method = "basic"
authentication_basic_username = "my_username"
authentication_basic_password = "my_password"
url = "https://dev.my-metrics-endpoint-url.com:9000/metrics"
}
```

<!-- schema generated by tfplugindocs -->
## Schema

### Required

- `authentication_method` (String) Method to pass authentication credentials: basic or bearer.
- `name` (String) The name of the Metrics Endpoint Scrape Job. Part of the Terraform Resource ID.
- `stack_id` (String) The Stack ID of the Grafana Cloud instance. Part of the Terraform Resource ID.
- `url` (String) The url to scrape metrics; a valid HTTPs URL is required.

### Optional

- `authentication_basic_password` (String, Sensitive) Password for basic authentication.
- `authentication_basic_username` (String) Username for basic authentication.
- `authentication_bearer_token` (String, Sensitive) Token for authentication bearer.
- `enabled` (Boolean) Whether the Metrics Endpoint Scrape Job is enabled or not.
- `scrape_interval_seconds` (Number) Frequency for scraping the metrics endpoint: 30, 60, or 120 seconds.

### Read-Only

- `id` (String) The Terraform Resource ID. This has the format "{{ stack_id }}:{{ name }}".

## Import

Import is supported using the following syntax:

```shell
terraform import grafana_connections_metrics_endpoint_scrape_job.name "{{ stack_id }}:{{ name }}"
```
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
data "grafana_connections_metrics_endpoint_scrape_job" "test" {}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
terraform import grafana_connections_metrics_endpoint_scrape_job.name "{{ stack_id }}:{{ name }}"
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
resource "grafana_connections_metrics_endpoint_scrape_job" "test" {
stack_id = "test-stack-id"
name = "my-scrape-job"
authentication_method = "basic"
authentication_basic_username = "my_username"
authentication_basic_password = "my_password"
url = "https://dev.my-metrics-endpoint-url.com:9000/metrics"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
resource "grafana_connections_metrics_endpoint_scrape_job" "test" {
stack_id = "test-stack-id"
name = "modified-scrape-job"
enabled = "false"
authentication_method = "bearer"
authentication_bearer_token = "test-token"
url = "https://www.modified-url.com:9000/metrics"
scrape_interval_seconds = "120"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package connections

import (
"context"

"github.com/grafana/terraform-provider-grafana/v3/internal/common"
"github.com/grafana/terraform-provider-grafana/v3/internal/common/connectionsapi"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
)

type datasourceMetricsEndpointScrapeJob struct {
client *connectionsapi.Client
}

func makeDatasourceMetricsEndpointScrapeJob() *common.DataSource {
return common.NewDataSource(
common.CategoryConnections,
resourceMetricsEndpointScrapeJobTerraformName,
&datasourceMetricsEndpointScrapeJob{},
)
}

func (r *datasourceMetricsEndpointScrapeJob) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
// Configure is called multiple times (sometimes when ProviderData is not yet available), we only want to configure once
if req.ProviderData == nil || r.client != nil {
return
}

client, err := withClientForDataSource(req, resp)
if err != nil {
return
}

r.client = client
}

func (r *datasourceMetricsEndpointScrapeJob) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = resourceMetricsEndpointScrapeJobTerraformName
}

func (r *datasourceMetricsEndpointScrapeJob) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
Attributes: map[string]schema.Attribute{
"id": schema.StringAttribute{
Description: "The Terraform Resource ID. This has the format \"{{ stack_id }}:{{ name }}\".",
Computed: true,
},
"stack_id": schema.StringAttribute{
Description: "The Stack ID of the Grafana Cloud instance. Part of the Terraform Resource ID.",
Required: true,
},
"name": schema.StringAttribute{
Description: "The name of the Metrics Endpoint Scrape Job. Part of the Terraform Resource ID.",
Required: true,
},
"enabled": schema.BoolAttribute{
Description: "Whether the Metrics Endpoint Scrape Job is enabled or not.",
Computed: true,
},
"authentication_method": schema.StringAttribute{
Description: "Method to pass authentication credentials: basic or bearer.",
Required: true,
},
"authentication_bearer_token": schema.StringAttribute{
Description: "Token for authentication bearer.",
Sensitive: true,
Optional: true,
},
"authentication_basic_username": schema.StringAttribute{
Description: "Username for basic authentication.",
Optional: true,
},
"authentication_basic_password": schema.StringAttribute{
Description: "Password for basic authentication.",
Sensitive: true,
Optional: true,
},
"url": schema.StringAttribute{
Description: "The url to scrape metrics.",
Required: true,
},
"scrape_interval_seconds": schema.Int64Attribute{
Description: "Frequency for scraping the metrics endpoint: 30, 60, or 120 seconds.",
Computed: true,
},
},
}
}

func (r *datasourceMetricsEndpointScrapeJob) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var dataTF metricsEndpointScrapeJobTFModel
diags := req.Config.Get(ctx, &dataTF)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}

job, err := r.client.GetMetricsEndpointScrapeJob(
ctx,
dataTF.StackID.ValueString(),
dataTF.Name.ValueString(),
)
if err != nil {
resp.Diagnostics.AddError("Failed to get metrics endpoint scrape job", err.Error())
return
}

resp.State.Set(ctx, convertClientModelToTFModel(dataTF.StackID.ValueString(), job))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package connections_test

import (
"testing"

"github.com/grafana/terraform-provider-grafana/v3/internal/testutils"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
)

func TestAcc_DataSourceMetricsEndpointScrapeJob(t *testing.T) {
// Run this test by removing t.Skip and set env variables TF_ACC=1;GRAFANA_CONNECTIONS_ACCESS_TOKEN=whatever
// in order to test the resource code "scaffolding".
// Expected result: test fails and the error message should be "failed to create metrics endpoint scrape job: failed to do request"
// because the Connections API is not yet available.

// t.Skip("will be enabled after Connections API is available in prod")

// testutils.CheckCloudInstanceTestsEnabled(t) // TODO: enable after Connections API is available
resource.ParallelTest(t, resource.TestCase{
ProtoV5ProviderFactories: testutils.ProtoV5ProviderFactories,
Steps: []resource.TestStep{
{
// Create this resource
Config: testutils.TestAccExample(t, "resources/grafana_connections_metrics_endpoint_scrape_job/resource.tf"),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("grafana_connections_metrics_endpoint_scrape_job.test", "stack_id", "test-stack-id"),
resource.TestCheckResourceAttr("grafana_connections_metrics_endpoint_scrape_job.test", "name", "my-scrape-job"),
resource.TestCheckResourceAttr("grafana_connections_metrics_endpoint_scrape_job.test", "enabled", "true"),
resource.TestCheckResourceAttr("grafana_connections_metrics_endpoint_scrape_job.test", "authentication_method", "basic"),
resource.TestCheckResourceAttr("grafana_connections_metrics_endpoint_scrape_job.test", "authentication_basic_username", "my_username"),
resource.TestCheckResourceAttr("grafana_connections_metrics_endpoint_scrape_job.test", "authentication_basic_password", "my_password"),
resource.TestCheckResourceAttr("grafana_connections_metrics_endpoint_scrape_job.test", "url", "https://dev.my-metrics-endpoint-url.com:9000/metrics"),
resource.TestCheckResourceAttr("grafana_connections_metrics_endpoint_scrape_job.test", "scrape_interval_seconds", "60"),
testutils.CheckLister("grafana_connections_metrics_endpoint_scrape_job.test"),
),
},
{
// Verifies that the created SLO Resource is read by the Datasource Read Method
// TODO: work on after other Test Step passes
// Config: testutils.TestAccExample(t, "data-sources/grafana_connections_metrics_endpoint_scrape_job/resource.tf"),
// RefreshState: true,
// Check: resource.ComposeTestCheckFunc(
// resource.TestCheckResourceAttrSet("data.grafana_connections_metrics_endpoint_scrape_job.test", "test.0.name"),
// ),
},
},
})
}
53 changes: 53 additions & 0 deletions internal/resources/connections/models.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package connections

import (
"github.com/grafana/terraform-provider-grafana/v3/internal/common/connectionsapi"
"github.com/hashicorp/terraform-plugin-framework/types"
)

type metricsEndpointScrapeJobTFModel struct {
ID types.String `tfsdk:"id"`
StackID types.String `tfsdk:"stack_id"`
Name types.String `tfsdk:"name"`
Enabled types.Bool `tfsdk:"enabled"`
AuthenticationMethod types.String `tfsdk:"authentication_method"`
AuthenticationBearerToken types.String `tfsdk:"authentication_bearer_token"`
AuthenticationBasicUsername types.String `tfsdk:"authentication_basic_username"`
AuthenticationBasicPassword types.String `tfsdk:"authentication_basic_password"`
URL types.String `tfsdk:"url"`
ScrapeIntervalSeconds types.Int64 `tfsdk:"scrape_interval_seconds"`
}

// convertJobTFModelToClientModel converts a metricsEndpointScrapeJobTFModel instance to a connectionsapi.MetricsEndpointScrapeJob instance.
// A special converter is needed because the TFModel uses special Terraform types that build upon their underlying Go types for
// supporting Terraform's state management/dependency analysis of the resource and its data.
func convertJobTFModelToClientModel(tfData metricsEndpointScrapeJobTFModel) connectionsapi.MetricsEndpointScrapeJob {
return connectionsapi.MetricsEndpointScrapeJob{
Name: tfData.Name.ValueString(),
Enabled: tfData.Enabled.ValueBool(),
AuthenticationMethod: tfData.AuthenticationMethod.ValueString(),
AuthenticationBearerToken: tfData.AuthenticationBearerToken.ValueString(),
AuthenticationBasicUsername: tfData.AuthenticationBasicUsername.ValueString(),
AuthenticationBasicPassword: tfData.AuthenticationBasicPassword.ValueString(),
URL: tfData.URL.ValueString(),
ScrapeIntervalSeconds: tfData.ScrapeIntervalSeconds.ValueInt64(),
}
}

// convertClientModelToTFModel converts a connectionsapi.MetricsEndpointScrapeJob instance to a metricsEndpointScrapeJobTFModel instance.
// A special converter is needed because the TFModel uses special Terraform types that build upon their underlying Go types for
// supporting Terraform's state management/dependency analysis of the resource and its data.
func convertClientModelToTFModel(stackID string, scrapeJobData connectionsapi.MetricsEndpointScrapeJob) metricsEndpointScrapeJobTFModel {
return metricsEndpointScrapeJobTFModel{
ID: types.StringValue(resourceMetricsEndpointScrapeJobTerraformID.Make(stackID, scrapeJobData.Name)),
StackID: types.StringValue(stackID),
Name: types.StringValue(scrapeJobData.Name),
Enabled: types.BoolValue(scrapeJobData.Enabled),
AuthenticationMethod: types.StringValue(scrapeJobData.AuthenticationMethod),
AuthenticationBearerToken: types.StringValue(scrapeJobData.AuthenticationBearerToken),
AuthenticationBasicUsername: types.StringValue(scrapeJobData.AuthenticationBasicUsername),
AuthenticationBasicPassword: types.StringValue(scrapeJobData.AuthenticationBasicPassword),
URL: types.StringValue(scrapeJobData.URL),
ScrapeIntervalSeconds: types.Int64Value(scrapeJobData.ScrapeIntervalSeconds),
}
}
Loading
Loading