Compare commits

..

3 commits

Author SHA1 Message Date
635a9abf20
fix: disable shell color in runnerstats (#80)
Signed-off-by: marcel.henselin <marcel.henselin@stackit.cloud>

## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] 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](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #80
Co-authored-by: marcel.henselin <marcel.henselin@stackit.cloud>
Co-committed-by: marcel.henselin <marcel.henselin@stackit.cloud>
2026-02-27 10:25:10 +00:00
07458c5677
feat: add runner stats (#79)
Signed-off-by: marcel.henselin <marcel.henselin@stackit.cloud>

## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] 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](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #79
Co-authored-by: marcel.henselin <marcel.henselin@stackit.cloud>
Co-committed-by: marcel.henselin <marcel.henselin@stackit.cloud>
2026-02-27 10:20:02 +00:00
eb13630d2f
feat: test STACKIT runner (#78)
Signed-off-by: marcel.henselin <marcel.henselin@stackit.cloud>

## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] 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](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #78
Co-authored-by: marcel.henselin <marcel.henselin@stackit.cloud>
Co-committed-by: marcel.henselin <marcel.henselin@stackit.cloud>
2026-02-27 10:08:09 +00:00
20 changed files with 125 additions and 75 deletions

View file

@ -53,9 +53,9 @@ runs:
- name: Install Go ${{ inputs.go-version }}
uses: actions/setup-go@v6
with:
# go-version: ${{ env.GO_VERSION }}
go-version: ${{ inputs.go-version }}
check-latest: true
go-version-file: 'go.mod'
cache-dependency-path: "**/*.sum"
- name: Install go tools
shell: bash

View file

@ -26,9 +26,9 @@ runs:
- name: Install Go ${{ inputs.go-version }}
uses: actions/setup-go@v6
with:
# go-version: ${{ env.GO_VERSION }}
go-version: ${{ inputs.go-version }}
check-latest: true
go-version-file: 'go.mod'
cache-dependency-path: "**/*.sum"
- name: Install go tools
shell: bash

View file

@ -26,15 +26,11 @@ runs:
uses: https://code.forgejo.org/actions/setup-go@v6
id: go-version
with:
# go-version: ${{ inputs.go-version }}
# check-latest: true # Always check for the latest patch release
go-version: ${{ inputs.go-version }}
check-latest: true # Always check for the latest patch release
# go-version-file: "go.mod"
# do not cache dependencies, we do this manually
# cache: false
# go-version: ${{ env.GO_VERSION }}
go-version-file: 'go.mod'
cache-dependency-path: "**/*.sum"
cache: false
- name: "Get go environment information"
shell: bash

View file

@ -22,6 +22,39 @@ env:
CODE_COVERAGE_ARTIFACT_NAME: "code-coverage"
jobs:
runner_test:
name: "Test STACKIT runner"
runs-on: stackit-docker
steps:
- name: Install needed tools
run: |
apt-get -y -qq update
apt-get -y -qq install jq python3 python3-pip python-is-python3 s3cmd git make wget
- name: Setup Go
uses: actions/setup-go@v6
with:
go-version: ${{ env.GO_VERSION }}
- name: Install go tools
run: |
go install golang.org/x/tools/cmd/goimports@latest
go install github.com/hashicorp/terraform-plugin-codegen-framework/cmd/tfplugingen-framework@latest
go install github.com/hashicorp/terraform-plugin-codegen-openapi/cmd/tfplugingen-openapi@latest
- name: Setup JAVA
uses: actions/setup-java@v5
with:
distribution: 'temurin' # See 'Supported distributions' for available options
java-version: '21'
- name: Checkout
uses: actions/checkout@v6
- name: Run build pkg directory
run: |
go run cmd/main.go build
publish_test:
name: "Test readiness for publishing provider"
needs: config
@ -37,15 +70,10 @@ jobs:
apt-get -y -qq update
apt-get -y -qq install jq python3 python3-pip python-is-python3 s3cmd git make wget
- name: Checkout
uses: actions/checkout@v6
- name: Setup Go
uses: actions/setup-go@v6
with:
# go-version: ${{ env.GO_VERSION }}
go-version-file: 'go.mod'
cache-dependency-path: "**/*.sum"
go-version: ${{ env.GO_VERSION }}
- name: Install go tools
run: |
@ -59,6 +87,9 @@ jobs:
distribution: 'temurin' # See 'Supported distributions' for available options
java-version: '21'
- name: Checkout
uses: actions/checkout@v6
- name: Run build pkg directory
run: |
go run cmd/main.go build
@ -228,6 +259,7 @@ jobs:
# path: "stackit/${{ env.CODE_COVERAGE_FILE_NAME }}"
config:
if: ${{ github.event_name != 'schedule' }}
name: Check GoReleaser config
runs-on: ubuntu-latest
steps:

View file

@ -46,9 +46,7 @@ jobs:
- name: Setup Go
uses: actions/setup-go@v6
with:
# go-version: ${{ env.GO_VERSION }}
go-version-file: 'go.mod'
cache-dependency-path: "**/*.sum"
go-version: ${{ env.GO_VERSION }}
- name: Install go tools
run: |

View file

@ -22,11 +22,10 @@ jobs:
with:
# Allow goreleaser to access older tag information.
fetch-depth: 0
- uses: actions/setup-go@v6
- uses: actions/setup-go@v5
with:
# go-version: ${{ env.GO_VERSION }}
go-version-file: 'go.mod'
cache-dependency-path: "**/*.sum"
go-version-file: "go.mod"
cache: true
- name: Import GPG key
uses: crazy-max/ghaction-import-gpg@v6
id: import_gpg

29
.github/workflows/runnerstats.yaml vendored Normal file
View file

@ -0,0 +1,29 @@
name: Runner stats
on:
workflow_dispatch:
jobs:
stats-own:
name: "Get own runner stats"
runs-on: ubuntu-latest
steps:
- name: Install needed tools
run: |
apt-get -y -qq update
apt-get -y -qq install inxi
- name: Show stats
run: inxi -c 0
stats-stackit:
name: "Get STACKIT runner stats"
runs-on: stackit-docker
steps:
- name: Install needed tools
run: |
apt-get -y -qq update
apt-get -y -qq install inxi
- name: Show stats
run: inxi -c 0

View file

@ -14,7 +14,7 @@ import (
"github.com/stackitcloud/stackit-sdk-go/core/config"
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/conversion"
{{.PackageName}}PkgGen "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/{{.PackageName}}"
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/{{.PackageName}}"
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/core"
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/utils"
@ -35,12 +35,12 @@ func New{{.NamePascal}}Resource() resource.Resource {
}
type {{.NameCamel}}Resource struct{
client *{{.PackageName}}PkgGen.APIClient
client *{{.PackageName}}.APIClient
providerData core.ProviderData
}
// resourceModel represents the Terraform resource state
type resourceModel = {{.PackageName}}ResGen.{{.NamePascal}}Model
type resourceModel = {{.PackageName}}.{{.NamePascal}}Model
type {{.NamePascal}}ResourceIdentityModel struct {
ProjectID types.String `tfsdk:"project_id"`
@ -59,15 +59,15 @@ var modifiersFileByte []byte
// Schema loads the schema from generated files and adds plan modifiers
func (r *{{.NameCamel}}Resource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
schema := {{.PackageName}}ResGen.{{.NamePascal}}ResourceSchema(ctx)
schema = {{.PackageName}}ResGen.{{.NamePascal}}ResourceSchema(ctx)
fields, err := utils.ReadModifiersConfig(modifiersFileByte)
fields, err := {{.PackageName}}Utils.ReadModifiersConfig(modifiersFileByte)
if err != nil {
resp.Diagnostics.AddError("error during read modifiers config file", err.Error())
return
}
err = utils.AddPlanModifiersToResourceSchema(fields, &schema)
err = {{.PackageName}}Utils.AddPlanModifiersToResourceSchema(fields, &schema)
if err != nil {
resp.Diagnostics.AddError("error adding plan modifiers", err.Error())
return
@ -109,14 +109,12 @@ func (r *{{.NameCamel}}Resource) Configure(
config.WithCustomAuth(r.providerData.RoundTripper),
utils.UserAgentConfigOption(r.providerData.Version),
}
/*
if r.providerData.{{.PackageNamePascal}}CustomEndpoint != "" {
apiClientConfigOptions = append(apiClientConfigOptions, config.WithEndpoint(r.providerData.{{.PackageName}}CustomEndpoint))
} else {
apiClientConfigOptions = append(apiClientConfigOptions, config.WithRegion(r.providerData.GetRegion()))
}
*/
apiClient, err := {{.PackageName}}PkgGen.NewAPIClient(apiClientConfigOptions...)
apiClient, err := {{.PackageName}}.NewAPIClient(apiClientConfigOptions...)
if err != nil {
resp.Diagnostics.AddError(
"Error configuring API client",
@ -295,11 +293,18 @@ func (r *{{.NameCamel}}Resource) Read(ctx context.Context, req resource.ReadRequ
return
}
// Read identity data
var identityData {{.NamePascal}}ResourceIdentityModel
resp.Diagnostics.Append(req.Identity.Get(ctx, &identityData)...)
if resp.Diagnostics.HasError() {
return
}
ctx = core.InitProviderContext(ctx)
projectId := data.ProjectID.ValueString()
region := data.Region.ValueString()
projectId := identityData.ProjectID.ValueString()
region := identityData.Region.ValueString()
ctx = tflog.SetField(ctx, "project_id", projectId)
ctx = tflog.SetField(ctx, "region", region)
@ -325,6 +330,12 @@ func (r *{{.NameCamel}}Resource) Read(ctx context.Context, req resource.ReadRequ
func (r *{{.NameCamel}}Resource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
var data {{.PackageName}}ResGen.{{.NamePascal}}Model
// Read Terraform prior state data into the model
resp.Diagnostics.Append(req.State.Get(ctx, &data)...)
if resp.Diagnostics.HasError() {
return
}
ctx = core.InitProviderContext(ctx)
projectId := data.ProjectId.ValueString()

View file

@ -3,6 +3,7 @@ package testutils
import (
"fmt"
"log"
"log/slog"
"os"
"os/exec"
"path/filepath"
@ -77,10 +78,10 @@ func Setup() {
}
err = godotenv.Load(fmt.Sprintf("%s/.env", *root))
if err != nil {
log.Println("could not find .env file - not loading .env")
slog.Info("could not find .env file - not loading .env")
return
}
log.Println("loaded .env file", "path", *root)
slog.Info("loaded .env file", "path", *root)
}
func getRoot() (*string, error) {

View file

@ -7,7 +7,6 @@ import (
"math"
"net/http"
"strings"
"time"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/resource"
@ -245,9 +244,6 @@ func (r *instanceResource) Create(
}
waitResp, err := wait.CreateInstanceWaitHandler(ctx, r.client, projectId, region, instanceId).
// Sleep before wait is set because sometimes API returns 404 right after creation request
SetTimeout(90 * time.Minute).
SetSleepBeforeWait(30 * time.Second).
WaitWithContext(ctx)
if err != nil {
core.LogAndAddError(
@ -490,10 +486,7 @@ func (r *instanceResource) Update(
projectId,
region,
instanceId,
).
SetTimeout(45 * time.Minute).
SetSleepBeforeWait(30 * time.Second).
WaitWithContext(ctx)
).WaitWithContext(ctx)
if err != nil {
core.LogAndAddError(
ctx,

View file

@ -110,9 +110,6 @@ func TestMain(m *testing.M) {
}
func testAccPreCheck(t *testing.T) {
if _, ok := os.LookupEnv("TF_ACC"); !ok {
t.Skip("TF_ACC is not set")
}
if _, ok := os.LookupEnv("TF_ACC_PROJECT_ID"); !ok {
t.Fatalf("could not find env var TF_ACC_PROJECT_ID")
}

View file

@ -479,9 +479,7 @@ func (r *instanceResource) Delete(ctx context.Context, req resource.DeleteReques
ctx = core.LogResponse(ctx)
delResp, err := wait.DeleteInstanceWaitHandler(ctx, r.client, projectId, instanceId, region).
SetTimeout(30 * time.Minute).
WaitWithContext(ctx)
delResp, err := wait.DeleteInstanceWaitHandler(ctx, r.client, projectId, instanceId, region).WaitWithContext(ctx)
if err != nil {
core.LogAndAddError(
ctx,

View file

@ -468,8 +468,6 @@ func (r *userResource) Delete(
}
// Delete existing record set
_, err = sqlserverflexalphaWait.DeleteUserWaitHandler(ctx, r.client, projectId, region, instanceId, userId).
SetTimeout(15 * time.Minute).
SetSleepBeforeWait(15 * time.Second).
WaitWithContext(ctx)
if err != nil {
core.LogAndAddError(ctx, &resp.Diagnostics, "User Delete Error", fmt.Sprintf("Calling API: %v", err))

View file

@ -40,7 +40,6 @@ func Test_handleDSEncryption(t *testing.T) {
}
func Test_handleEncryption(t *testing.T) {
ctx := context.Background()
type args struct {
m *sqlserverflexbetaRs.InstanceModel
resp *sqlserverflexbetaPkgGen.GetInstanceResponse
@ -81,23 +80,19 @@ func Test_handleEncryption(t *testing.T) {
},
},
},
want: sqlserverflexbetaRs.NewEncryptionValueMust(
sqlserverflexbetaRs.EncryptionValue{}.AttributeTypes(ctx),
map[string]attr.Value{
"kek_key_id": types.StringValue("kek_key_id"),
"kek_key_ring_id": types.StringValue("kek_key_ring_id"),
"kek_key_version": types.StringValue("kek_key_version"),
"service_account": types.StringValue("kek_svc_acc"),
},
),
want: sqlserverflexbetaRs.EncryptionValue{
KekKeyId: types.StringValue("kek_key_id"),
KekKeyRingId: types.StringValue("kek_key_ring_id"),
KekKeyVersion: types.StringValue("kek_key_version"),
ServiceAccount: types.StringValue("kek_svc_acc"),
},
},
}
for _, tt := range tests {
t.Run(
tt.name, func(t *testing.T) {
got := handleEncryption(t.Context(), tt.args.m, tt.args.resp)
if diff := cmp.Diff(tt.want, got); diff != "" {
t.Errorf("string mismatch (-want +got):\n%s", diff)
if got := handleEncryption(t.Context(), tt.args.m, tt.args.resp); !reflect.DeepEqual(got, tt.want) {
t.Errorf("handleEncryption() = %v, want %v", got, tt.want)
}
},
)

View file

@ -473,9 +473,7 @@ func (r *instanceResource) Delete(ctx context.Context, req resource.DeleteReques
ctx = core.LogResponse(ctx)
delResp, err := wait.DeleteInstanceWaitHandler(ctx, r.client, projectId, instanceId, region).
SetTimeout(30 * time.Minute).
WaitWithContext(ctx)
delResp, err := wait.DeleteInstanceWaitHandler(ctx, r.client, projectId, instanceId, region).WaitWithContext(ctx)
if err != nil {
core.LogAndAddError(
ctx,

View file

@ -492,8 +492,6 @@ func (r *userResource) Delete(
}
// Delete existing record set
_, err = sqlserverflexbetaWait.DeleteUserWaitHandler(ctx, r.client, projectId, region, instanceId, userId).
SetTimeout(15 * time.Minute).
SetSleepBeforeWait(15 * time.Second).
WaitWithContext(ctx)
if err != nil {
core.LogAndAddError(ctx, &resp.Diagnostics, "User Delete Error", fmt.Sprintf("Calling API: %v", err))

View file

@ -173,7 +173,8 @@ func CreateInstanceWaitHandler(
return false, nil, nil
},
)
// Sleep before wait is set because sometimes API returns 404 right after creation request
handler.SetTimeout(90 * time.Minute).SetSleepBeforeWait(30 * time.Second)
return handler
}
@ -211,6 +212,7 @@ func PartialUpdateInstanceWaitHandler(
}
},
)
handler.SetTimeout(45 * time.Minute).SetSleepBeforeWait(30 * time.Second)
return handler
}

View file

@ -244,6 +244,7 @@ func DeleteInstanceWaitHandler(
return true, nil, nil
},
)
handler.SetTimeout(30 * time.Minute)
return handler
}
@ -385,5 +386,7 @@ func DeleteUserWaitHandler(
}
},
)
handler.SetTimeout(15 * time.Minute)
handler.SetSleepBeforeWait(15 * time.Second)
return handler
}

View file

@ -264,6 +264,7 @@ func DeleteInstanceWaitHandler(
return true, nil, nil
},
)
handler.SetTimeout(30 * time.Minute)
return handler
}
@ -405,5 +406,7 @@ func DeleteUserWaitHandler(
}
},
)
handler.SetTimeout(15 * time.Minute)
handler.SetSleepBeforeWait(15 * time.Second)
return handler
}

View file

@ -63,7 +63,6 @@ func TestMain(m *testing.M) {
}
func TestMshTest(t *testing.T) {
t.Skip("currently failing because of null pointer")
httpmock.Activate()
defer httpmock.DeactivateAndReset()
@ -75,7 +74,7 @@ func TestMshTest(t *testing.T) {
token := jwt.NewWithClaims(
jwt.SigningMethodHS256, jwt.MapClaims{
"foo": "bar",
"nbf": time.Date(2026, 12, 31, 12, 0, 0, 0, time.UTC).Unix(),
"nbf": time.Date(2015, 10, 10, 12, 0, 0, 0, time.UTC).Unix(),
},
)
// Sign and get the complete encoded token as a string using the secret
@ -86,7 +85,7 @@ func TestMshTest(t *testing.T) {
tR := clients.TokenResponseBody{
AccessToken: tokenString,
ExpiresIn: 36000,
ExpiresIn: 3600,
RefreshToken: "",
Scope: "",
TokenType: "",