Skip to content

Conversation

@devanshcache
Copy link

Description

This PR onboards the new STACKIT Intake (ticket) service into the Terraform provider.

Intake is composed of three components:

  • Intake Runners: dedicated, isolated runtime data ingestion environment
  • Intake: a specific data stream or topic within an Intake Runner
  • Intake Users: provides secure access credentials for your applications to connect to your Intake

This PR contains the Intake Runners part only to make a quicker and less overwhelming review.

Checklist

  • Issue was linked above
  • Code format was applied: make fmt
  • Examples were added / adjusted (see examples/ directory)
  • Docs are up-to-date: make generate-docs (will be checked by CI)
  • Unit tests got implemented or updated
  • Acceptance tests got implemented or updated (see e.g. here)
  • Unit tests are passing: make test (will be checked by CI)
  • No linter issues: make lint (will be checked by CI)

@devanshcache devanshcache requested a review from a team as a code owner December 8, 2025 08:08
@devanshcache devanshcache changed the title onboarding(1/3): Intake Runner Onboarding Intake(1/3): Intake Runner Dec 8, 2025
@@ -0,0 +1,160 @@
package runner_test
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you move this file please to stackit/internal/services/intake/intake_acc_test.go please?

We have one acc test for each service usually. See https://github.com/stackitcloud/terraform-provider-stackit/blob/da2bb41b1e1c702e8aa53ae5221f5a49bd6a9251/stackit/internal/services/git/git_acc_test.go for reference 😅

}

func testAccIntakeRunnerConfigFull(name, description string, maxKib, maxPerHour int) string {
return fmt.Sprintf(`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please specify the test config as a terraform file and embed it into the test like we have it in most places:

//go:embed testdata/resource-min.tf
var resourceMin string
//go:embed testdata/resource-max.tf
var resourceMax string

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can then specify your test variables like that:

var testConfigVarsMin = config.Variables{
"project_id": config.StringVariable(testutil.ProjectId),
"name": config.StringVariable(nameMin),
}
var testConfigVarsMax = config.Variables{
"project_id": config.StringVariable(testutil.ProjectId),
"name": config.StringVariable(nameMax),
"acl": config.StringVariable("192.168.0.0/16"),
"flavor": config.StringVariable("git-100"),
}

resource.TestCheckResourceAttr(intakeRunnerResource, "description", ""),
resource.TestCheckResourceAttr(intakeRunnerResource, "labels.%", "0"),
),
},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also test the datasource within your acc test, see

// Data source
{
ConfigVariables: testConfigVarsMin,
Config: fmt.Sprintf(`
%s
data "stackit_git" "git" {
project_id = stackit_git.git.project_id
instance_id = stackit_git.git.instance_id
}
`, testutil.GitProviderConfig()+resourceMin,
),
Check: resource.ComposeAggregateTestCheckFunc(
// Instance
resource.TestCheckResourceAttr("data.stackit_git.git", "project_id", testutil.ConvertConfigVariable(testConfigVarsMin["project_id"])),
resource.TestCheckResourceAttrPair(
"stackit_git.git", "project_id",
"data.stackit_git.git", "project_id",
),
resource.TestCheckResourceAttrPair(
"stackit_git.git", "instance_id",
"data.stackit_git.git", "instance_id",
),
resource.TestCheckResourceAttrPair(
"stackit_git.git", "name",
"data.stackit_git.git", "name",
),
resource.TestCheckResourceAttrPair(
"stackit_git.git", "url",
"data.stackit_git.git", "url",
),
resource.TestCheckResourceAttrPair(
"stackit_git.git", "version",
"data.stackit_git.git", "version",
),
resource.TestCheckResourceAttrPair(
"stackit_git.git", "created",
"data.stackit_git.git", "created",
),
resource.TestCheckResourceAttrPair(
"stackit_git.git", "consumed_object_storage",
"data.stackit_git.git", "consumed_object_storage",
),
resource.TestCheckResourceAttrPair(
"stackit_git.git", "consumed_disk",
"data.stackit_git.git", "consumed_disk",
),
resource.TestCheckResourceAttrPair(
"stackit_git.git", "flavor",
"data.stackit_git.git", "flavor",
),
for reference

@@ -0,0 +1,34 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "stackit_intake_runner Resource - stackit"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

docs and examples for the datasource are missing

stringplanmodifier.RequiresReplace(),
},
Validators: []validator.String{
stringvalidator.OneOf("eu01"), // Currently Intake supports only EU01 region
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This won't prevent the default_region in the provider configuration to not be eu02 😉

model.Labels = labels
}

if runnerResp.Id != nil && *runnerResp.Id == "" {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if runnerResp.Id != nil && *runnerResp.Id == "" {
if runnerResp.Id != nil || *runnerResp.Id == "" {

}
model.Name = types.StringPointerValue(runnerResp.DisplayName)
if runnerResp.Description == nil {
model.Description = types.StringValue("")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This whole condition shouldn't be needed. The following line should be enough

model.Description = types.StringPointerValue(runnerResp.Description)

return nil
}

// Build CreateBarPayload from provider's model
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Build CreateBarPayload from provider's model
// Build CreateIntakeRunnerPayload from provider's model

either adjust the example comments from the contribution guide or remove them 😅

// Handle optional fields
if !model.Description.IsUnknown() || model.Description.IsNull() {
if model.Description.IsNull() {
payload.Description = sdkUtils.Ptr("")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the point of this? Sending an empty string? Just leave it out of the payload, it's optional 😄


payload := &intake.UpdateIntakeRunnerPayload{}

if !model.Name.IsUnknown() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if !model.Name.IsUnknown() {

I would leave this out. Display name is marked as required for the create request, you'll always have to send it.

payload.DisplayName = conversion.StringValueToPointer(model.Name)
}

if !model.MaxMessageSizeKiB.IsUnknown() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

payload.MaxMessageSizeKiB = conversion.Int64ValueToPointer(model.MaxMessageSizeKiB)
}

if !model.MaxMessagesPerHour.IsUnknown() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

if !model.Labels.IsUnknown() {
if model.Labels.IsNull() {
labels = map[string]string{}
payload.Labels = &labels
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

labels are optional, just leave them out of the payload...

},
"intake_custom_endpoint": schema.StringAttribute{
Optional: true,
Description: descriptions["intake_custom_endpoint"],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You will have to add your description to the descriptions slice...

},
"region": schema.StringAttribute{
Description: descriptions["region"],
Required: true,
Copy link
Member

@rubenhoenle rubenhoenle Jan 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is the region required? It should use the default_region value from the provider configuration as a fallback value, just as all our datasource implementations do.

// Try to find the runner
_, err := client.GetIntakeRunner(ctx, rs.Primary.Attributes["project_id"], rs.Primary.Attributes["region"], rs.Primary.Attributes["runner_id"]).Execute()
if err == nil {
return fmt.Errorf("intake runner with ID %s still exists", rs.Primary.ID)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it still exists, delete it 😉

err := client.DeleteInstance(ctx, testutil.ProjectId, *gitInstances[i].Id).Execute()

var err error
if testutil.IntakeCustomEndpoint == "" {
client, err = intake.NewAPIClient(
sdkConfig.WithRegion("eu01"),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
sdkConfig.WithRegion("eu01"),

This shouldn't be needed. It's only needed because you have two region parameters in your API URLs:

https://intake.api.eu01.stackit.cloud/v1beta/projects/{projectId}/regions/{regionId}/intake-runners

One in the hostname and one in the URL path. The one in the hostname is redundant and shouldn't be there 😅

Devansh Thakur and others added 4 commits January 22, 2026 11:14
# Conflicts:
#	go.mod
#	go.sum
#	stackit/internal/testutil/testutil.go
#	stackit/provider.go
Yago Carlos Fernandez Gou and others added 2 commits January 22, 2026 11:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants