Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
a39fce3
feat: TelemetryLink resources and datasources
May 11, 2026
db12dc1
chore: lint fix
May 11, 2026
a5447dd
Merge remote-tracking branch 'origin/main' into feature/telemetrylink
May 14, 2026
a085795
chore: renamed stackit_telemetrylink link to stackit_telemetrylink
May 14, 2026
4213072
chore: rename "TelemetryLink Link" to "TelemetryLink"
May 14, 2026
6d6d309
chore: sorted schema by required then optional
May 14, 2026
e573f59
chore: sorted schema fields by required then optional
May 14, 2026
d38ccae
chore: review comments fixed
May 14, 2026
9db81c2
chore: moved error handling out of the switch statement
May 14, 2026
a5f01a5
chore: partial update
May 14, 2026
648da00
chore: LinkLink renamed to Link
May 19, 2026
3955797
chore: telemetryLinkInstanceResource to telemetryLinkResource
May 19, 2026
79e8ba0
Merge remote-tracking branch 'origin/main' into feature/telemetrylink
May 22, 2026
3b7f608
Merge remote-tracking branch 'origin/main' into feature/telemetrylink
May 25, 2026
b4903ef
feat: use waiter when deleting acceptance test resources
May 25, 2026
caccee4
feat: telemetry router resources deletion in acceptance tests
May 25, 2026
c61fcfe
feat: delete telemetry router resources in acceptance tests
May 25, 2026
b854951
chore: use real telemetry router for telemetry link in acceptance tests
May 25, 2026
5de9c3b
fix: fixed acceptance test
May 27, 2026
94b2a2b
chore: improvements
May 28, 2026
6413bd8
Merge branch 'main' into feature/telemetrylink
ozanichkovsky May 28, 2026
634d8e9
chore: lint fix
May 28, 2026
9b65448
chore; improvements
May 28, 2026
aa72ff9
chore: adjusted update and delete
May 29, 2026
5535910
Update stackit/internal/services/telemetrylink/link/datasource.go
ozanichkovsky May 29, 2026
f5e9a84
chore: code review fixes
May 29, 2026
afee88c
chore: fixed tests
May 29, 2026
97bb747
chore: Import state fields
May 29, 2026
85ccd64
Merge remote-tracking branch 'origin/main' into feature/telemetrylink
May 29, 2026
83c8279
chore: code review fixes
May 29, 2026
0975b3a
chore: acc test fix
May 29, 2026
85f96f8
chore: code review and generated docs
Jun 1, 2026
277a80d
Update stackit/internal/services/telemetrylink/link/resource.go
ozanichkovsky Jun 1, 2026
6941406
chore: code review fix
Jun 1, 2026
8c05f2f
chore: code review fix
Jun 1, 2026
3b58622
Update stackit/internal/services/telemetrylink/link/datasource.go
ozanichkovsky Jun 1, 2026
9a9797c
chore: moved telemetrylink import as requested
Jun 1, 2026
8f4b384
chore: link ID is always returned from the API
Jun 1, 2026
a98c241
chore: removed link_id since it is not actually used for resource ide…
Jun 1, 2026
564ad9c
chore: updated docs
Jun 1, 2026
c07944d
chore: fixed resource cleanup in acceptance test
Jun 1, 2026
b378e61
chore: link_id cleanup
Jun 1, 2026
0fcd7c0
feat: use CreateOrUpdate... for update instead of PartialUpdate...
Jun 1, 2026
e045455
chore: code review fixes
Jun 1, 2026
79e189e
chore: code review fix
Jun 1, 2026
20d50a0
chore: code review fix
Jun 1, 2026
67c35f3
chore: code review fix
Jun 1, 2026
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
42 changes: 42 additions & 0 deletions docs/data-sources/telemetrylink.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "stackit_telemetrylink Data Source - stackit"
subcategory: ""
description: |-
TelemetryLink data source schema. Uses the default_region specified in the provider configuration as a fallback in case no region is defined on datasource level.
---

# stackit_telemetrylink (Data Source)

TelemetryLink data source schema. Uses the `default_region` specified in the provider configuration as a fallback in case no `region` is defined on datasource level.

## Example Usage

```terraform
data "stackit_telemetrylink" "link" {
resource_type = "project"
resource_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
region = "eu01"
}
```

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

### Required

- `resource_id` (String) STACKIT project ID, folder ID, or organization ID associated with the Telemetry Link resource.
- `resource_type` (String) The resource type of the TelemetryLink resource, possible values: Possible values are: `organization`, `folder`, `project`.

### Optional

- `region` (String) STACKIT region name the resource is located in. If not defined, the provider region is used.

### Read-Only

- `create_time` (String) The time the Telemetry Link was created.
- `description` (String) The description of the Telemetry Link resource.
- `display_name` (String) The displayed name of the Telemetry Link resource.
- `id` (String) Terraform's internal resource identifier. It is structured as "`resource_type`, `resource_id`,`region`".
- `status` (String) The status of the TelemetryLink, possible values: Possible values are: `active`, `inactive`, `failed`, `reconciling`, `deleting`.
- `telemetry_router_id` (String) The Telemetry Router ID.
1 change: 1 addition & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ Note: AWS specific checks must be skipped as they do not work on STACKIT. For de
- `sfs_custom_endpoint` (String) Custom endpoint for the Stackit Filestorage API
- `ske_custom_endpoint` (String) Custom endpoint for the Kubernetes Engine (SKE) service
- `sqlserverflex_custom_endpoint` (String) Custom endpoint for the SQL Server Flex service
- `telemetrylink_custom_endpoint` (String) Custom endpoint for the Telemetry Link service
- `telemetryrouter_custom_endpoint` (String) Custom endpoint for the Telemetry Router service
- `token_custom_endpoint` (String) Custom endpoint for the token API, which is used to request access tokens when using the key flow
- `use_oidc` (Boolean) Enables OIDC for Authentication. This can also be sourced from the `STACKIT_USE_OIDC` Environment Variable. Defaults to `false`.
62 changes: 62 additions & 0 deletions docs/resources/telemetrylink.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "stackit_telemetrylink Resource - stackit"
subcategory: ""
description: |-
TelemetryLink instance resource schema. Uses the default_region specified in the provider configuration as a fallback in case no region is defined on resource level.
---

# stackit_telemetrylink (Resource)

TelemetryLink instance resource schema. Uses the `default_region` specified in the provider configuration as a fallback in case no `region` is defined on resource level.

## Example Usage

```terraform
resource "stackit_telemetrylink" "link" {
resource_type = "project"
resource_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
region = "eu01"
display_name = "telemetrylink-example"
access_token = "eyJxxx"
telemetry_router_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

resource "stackit_telemetrylink" "link2" {
resource_type = "project"
resource_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
region = "eu01"
display_name = "telemetrylink-example"
description = "telemetrylink description"
access_token = "eyJxxx"
telemetry_router_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

# Only use the import statement, if you want to import an existing TelemetryLink
import {
to = stackit_telemetrylink.import-example
id = "${var.resource_type},${var.resource_id},${var.region}"
}
```

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

### Required

- `display_name` (String) The displayed name of the Telemetry Link resource.
- `resource_id` (String) STACKIT project ID, folder ID, or organization ID associated with the Telemetry Link resource.
- `resource_type` (String) The resource type of the TelemetryLink resource, possible values: Possible values are: `organization`, `folder`, `project`.
- `telemetry_router_id` (String) The Telemetry Router ID.

### Optional

- `access_token` (String, Sensitive) The access token of the Telemetry Router instance.
- `description` (String) The description of the Telemetry Link resource.
- `region` (String) STACKIT region name the resource is located in. If not defined, the provider region is used.

### Read-Only

- `create_time` (String) The time the Telemetry Link was created.
- `id` (String) Terraform's internal resource identifier. It is structured as "`resource_type`, `resource_id`,`region`".
- `status` (String) The status of the TelemetryLink, possible values: Possible values are: `active`, `inactive`, `failed`, `reconciling`, `deleting`.
5 changes: 5 additions & 0 deletions examples/data-sources/stackit_telemetrylink/data-source.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
data "stackit_telemetrylink" "link" {
resource_type = "project"
resource_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
region = "eu01"
}
24 changes: 24 additions & 0 deletions examples/resources/stackit_telemetrylink/resource.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
resource "stackit_telemetrylink" "link" {
resource_type = "project"
resource_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
region = "eu01"
display_name = "telemetrylink-example"
access_token = "eyJxxx"
telemetry_router_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

resource "stackit_telemetrylink" "link2" {
resource_type = "project"
resource_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
region = "eu01"
display_name = "telemetrylink-example"
description = "telemetrylink description"
access_token = "eyJxxx"
telemetry_router_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

# Only use the import statement, if you want to import an existing TelemetryLink
import {
to = stackit_telemetrylink.import-example
id = "${var.resource_type},${var.resource_id},${var.region}"
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ require (
github.com/stackitcloud/stackit-sdk-go/services/sfs v0.10.1
github.com/stackitcloud/stackit-sdk-go/services/ske v1.15.0
github.com/stackitcloud/stackit-sdk-go/services/sqlserverflex v1.11.0
github.com/stackitcloud/stackit-sdk-go/services/telemetrylink v0.2.0
github.com/stackitcloud/stackit-sdk-go/services/telemetryrouter v0.3.0
github.com/teambition/rrule-go v1.8.2
golang.org/x/mod v0.36.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -734,6 +734,8 @@ github.com/stackitcloud/stackit-sdk-go/services/ske v1.15.0 h1:sSuwbqAvh89jUUX2R
github.com/stackitcloud/stackit-sdk-go/services/ske v1.15.0/go.mod h1:TbqmZhLMofmfl+HhVl6oHYcI3zvXTm1vRjN3A/fOkM4=
github.com/stackitcloud/stackit-sdk-go/services/sqlserverflex v1.11.0 h1:PwjQeupEnXxhu+uWCUzO/hUfL4yqNblOcZbP2jvaQtU=
github.com/stackitcloud/stackit-sdk-go/services/sqlserverflex v1.11.0/go.mod h1:AiUoMAqQcOlMgDtkVJlqI7P/VGD5xjN3dYjERGnwN/M=
github.com/stackitcloud/stackit-sdk-go/services/telemetrylink v0.2.0 h1:U1mQoCk0TXc8NsSc/Sl9PKMdEyJpWNU2zLnsqmx6wEc=
github.com/stackitcloud/stackit-sdk-go/services/telemetrylink v0.2.0/go.mod h1:hgw8janWmDfP2bnuZensxqcAePr49BX5ug8Rq85o+h8=
github.com/stackitcloud/stackit-sdk-go/services/telemetryrouter v0.3.0 h1:MEvzGItcbig+9A4JvK2E5W6/mqXDPafiGkDZ1BprBAI=
github.com/stackitcloud/stackit-sdk-go/services/telemetryrouter v0.3.0/go.mod h1:WUmgKtwpe90Yq3YbgNxc2clTTULVxCu0ha6lMTjUnII=
github.com/stbenjam/no-sprintf-host-port v0.3.1 h1:AyX7+dxI4IdLBPtDbsGAyqiTSLpCP9hWRrXQDU4Cm/g=
Expand Down
1 change: 1 addition & 0 deletions stackit/internal/core/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ type ProviderData struct {
ServiceEnablementCustomEndpoint string
SfsCustomEndpoint string
ServiceAccountCustomEndpoint string
TelemetryLinkCustomEndpoint string
TelemetryRouterCustomEndpoint string
EnableBetaResources bool
Experiments []string
Expand Down
201 changes: 201 additions & 0 deletions stackit/internal/services/telemetrylink/link/datasource.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
package link

import (
"context"
"fmt"
"net/http"
"time"

"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-log/tflog"
telemetrylink "github.com/stackitcloud/stackit-sdk-go/services/telemetrylink/v1betaapi"

"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/conversion"
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/core"
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/services/telemetrylink/utils"
tfutils "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/utils"
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/validate"
)

var (
_ datasource.DataSource = &telemetryLinkDataSource{}
)

func NewTelemetryLinkDataSource() datasource.DataSource {
return &telemetryLinkDataSource{}
}

type DataSourceModel struct {
ID types.String `tfsdk:"id"` // Required by Terraform
Region types.String `tfsdk:"region"`
ResourceType types.String `tfsdk:"resource_type"`
ResourceID types.String `tfsdk:"resource_id"`
DisplayName types.String `tfsdk:"display_name"`
Description types.String `tfsdk:"description"`
TelemetryRouterID types.String `tfsdk:"telemetry_router_id"`
CreateTime types.String `tfsdk:"create_time"`
Status types.String `tfsdk:"status"`
}

type telemetryLinkDataSource struct {
client *telemetrylink.APIClient
providerData core.ProviderData
}

func (d *telemetryLinkDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_telemetrylink"
}

func (d *telemetryLinkDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
providerData, ok := conversion.ParseProviderData(ctx, req.ProviderData, &resp.Diagnostics)
if !ok {
return
}
d.providerData = providerData

apiClient := utils.ConfigureClient(ctx, &providerData, &resp.Diagnostics)
if resp.Diagnostics.HasError() {
return
}
d.client = apiClient
tflog.Info(ctx, "TelemetryLink client configured")
}

func (d *telemetryLinkDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
Description: fmt.Sprintf("TelemetryLink data source schema. %s", core.DatasourceRegionFallbackDocstring),
Attributes: map[string]schema.Attribute{
"id": schema.StringAttribute{
Description: schemaDescriptions["id"],
Computed: true,
},
"resource_type": schema.StringAttribute{
Description: schemaDescriptions["resource_type"],
Required: true,
Validators: []validator.String{
stringvalidator.OneOf(resourceTypes...),
validate.NoSeparator(),
},
},
"resource_id": schema.StringAttribute{
Comment thread
ozanichkovsky marked this conversation as resolved.
Description: schemaDescriptions["resource_id"],
Required: true,
Validators: []validator.String{
validate.UUID(),
validate.NoSeparator(),
},
},
"region": schema.StringAttribute{
Description: schemaDescriptions["region"],
// the region cannot be found, so it has to be passed
Optional: true,
},
"display_name": schema.StringAttribute{
Description: schemaDescriptions["display_name"],
Computed: true,
},
"description": schema.StringAttribute{
Description: schemaDescriptions["description"],
Computed: true,
},
"telemetry_router_id": schema.StringAttribute{
Description: schemaDescriptions["telemetry_router_id"],
Computed: true,
},
"create_time": schema.StringAttribute{
Description: schemaDescriptions["create_time"],
Computed: true,
},
"status": schema.StringAttribute{
Description: schemaDescriptions["status"],
Computed: true,
},
},
}
}

func (d *telemetryLinkDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { // nolint:gocritic // function signature required by Terraform
var model DataSourceModel
diags := req.Config.Get(ctx, &model)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}

ctx = core.InitProviderContext(ctx)

resourceType := model.ResourceType.ValueString()
resourceID := model.ResourceID.ValueString()
region := d.providerData.GetRegionWithOverride(model.Region)

ctx = tflog.SetField(ctx, "resource_type", resourceType)
ctx = tflog.SetField(ctx, "resource_id", resourceID)
ctx = tflog.SetField(ctx, "region", region)

var response *telemetrylink.TelemetryLinkResponse
var err error
switch resourceType {
case resourceTypeOrganization:
response, err = d.client.DefaultAPI.GetOrganizationTelemetryLink(ctx, resourceID, region).Execute()
case resourceTypeFolder:
response, err = d.client.DefaultAPI.GetFolderTelemetryLink(ctx, resourceID, region).Execute()
case resourceTypeProject:
response, err = d.client.DefaultAPI.GetProjectTelemetryLink(ctx, resourceID, region).Execute()
default:
core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading TelemetryLink", fmt.Sprintf("Unsupported resource type: %s", resourceType))
return
}
if err != nil {
tfutils.LogError(
ctx,
&resp.Diagnostics,
err,
"Error reading TelemetryLink",
fmt.Sprintf("TelemetryLink for resource type %q and resource ID %q does not exist.", resourceType, resourceID),
map[int]string{
http.StatusForbidden: fmt.Sprintf("Resource with type %q ID %q not found or forbidden access", resourceType, resourceID),
},
)
resp.State.RemoveResource(ctx)
return
}
ctx = core.LogResponse(ctx)

err = mapDataSourceFields(ctx, response, &model, region)
if err != nil {
core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading TelemetryLink", fmt.Sprintf("Processing response: %v", err))
return
}
diags = resp.State.Set(ctx, model)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
tflog.Info(ctx, "TelemetryLink read", map[string]interface{}{
"resource_type": resourceType,
"resource_id": resourceID,
})
}

func mapDataSourceFields(_ context.Context, link *telemetrylink.TelemetryLinkResponse, model *DataSourceModel, region string) error {
if link == nil {
return fmt.Errorf("link is nil")
}
if model == nil {
return fmt.Errorf("model is nil")
}

model.ID = tfutils.BuildInternalTerraformId(model.ResourceType.ValueString(), model.ResourceID.ValueString(), region)
Comment thread
ozanichkovsky marked this conversation as resolved.
model.Region = types.StringValue(region)
model.DisplayName = types.StringValue(link.DisplayName)
model.Description = types.StringPointerValue(link.Description)
model.TelemetryRouterID = types.StringValue(link.TelemetryRouterId)
model.CreateTime = types.StringValue(link.CreateTime.Format(time.RFC3339))
model.Status = types.StringValue(string(link.Status))

return nil
}
Loading
Loading