-
Notifications
You must be signed in to change notification settings - Fork 60
feat(telemetry link): Onboarding TelemetryLink #1456
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
Merged
Fyusel
merged 47 commits into
stackitcloud:main
from
ozanichkovsky:feature/telemetrylink
Jun 1, 2026
Merged
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
db12dc1
chore: lint fix
a5447dd
Merge remote-tracking branch 'origin/main' into feature/telemetrylink
a085795
chore: renamed stackit_telemetrylink link to stackit_telemetrylink
4213072
chore: rename "TelemetryLink Link" to "TelemetryLink"
6d6d309
chore: sorted schema by required then optional
e573f59
chore: sorted schema fields by required then optional
d38ccae
chore: review comments fixed
9db81c2
chore: moved error handling out of the switch statement
a5f01a5
chore: partial update
648da00
chore: LinkLink renamed to Link
3955797
chore: telemetryLinkInstanceResource to telemetryLinkResource
79e8ba0
Merge remote-tracking branch 'origin/main' into feature/telemetrylink
3b7f608
Merge remote-tracking branch 'origin/main' into feature/telemetrylink
b4903ef
feat: use waiter when deleting acceptance test resources
caccee4
feat: telemetry router resources deletion in acceptance tests
c61fcfe
feat: delete telemetry router resources in acceptance tests
b854951
chore: use real telemetry router for telemetry link in acceptance tests
5de9c3b
fix: fixed acceptance test
94b2a2b
chore: improvements
6413bd8
Merge branch 'main' into feature/telemetrylink
ozanichkovsky 634d8e9
chore: lint fix
9b65448
chore; improvements
aa72ff9
chore: adjusted update and delete
5535910
Update stackit/internal/services/telemetrylink/link/datasource.go
ozanichkovsky f5e9a84
chore: code review fixes
afee88c
chore: fixed tests
97bb747
chore: Import state fields
85ccd64
Merge remote-tracking branch 'origin/main' into feature/telemetrylink
83c8279
chore: code review fixes
0975b3a
chore: acc test fix
85f96f8
chore: code review and generated docs
277a80d
Update stackit/internal/services/telemetrylink/link/resource.go
ozanichkovsky 6941406
chore: code review fix
8c05f2f
chore: code review fix
3b58622
Update stackit/internal/services/telemetrylink/link/datasource.go
ozanichkovsky 9a9797c
chore: moved telemetrylink import as requested
8f4b384
chore: link ID is always returned from the API
a98c241
chore: removed link_id since it is not actually used for resource ide…
564ad9c
chore: updated docs
c07944d
chore: fixed resource cleanup in acceptance test
b378e61
chore: link_id cleanup
0fcd7c0
feat: use CreateOrUpdate... for update instead of PartialUpdate...
e045455
chore: code review fixes
79e189e
chore: code review fix
20d50a0
chore: code review fix
67c35f3
chore: code review fix
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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`. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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" | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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}" | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
201 changes: 201 additions & 0 deletions
201
stackit/internal/services/telemetrylink/link/datasource.go
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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{ | ||
| 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) | ||
|
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 | ||
| } | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.