From aa036e5eef9fbf587a232c9d4e396c7eca159ccb Mon Sep 17 00:00:00 2001 From: miton18 Date: Tue, 20 Jan 2026 17:10:04 +0100 Subject: [PATCH] feat: env vars warning on invalid values --- go.mod | 6 ++--- go.sum | 7 ++++++ pkg/resources/application/create.go | 37 ++++++++++++++++++++++++++++- pkg/resources/application/update.go | 2 +- pkg/tmp/app.go | 6 ++++- 5 files changed, 52 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index a318a2ba..b52cd6f5 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( github.com/hashicorp/terraform-plugin-testing v1.13.3 github.com/minio/minio-go/v7 v7.0.95 github.com/miton18/helper v0.0.3 - go.clever-cloud.dev/client v0.1.4 + go.clever-cloud.dev/client v0.1.6 go.clever-cloud.dev/sdk v0.0.5 golang.org/x/exp v0.0.0-20251017212417-90e834f514db ) @@ -136,7 +136,7 @@ require ( github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect github.com/shirou/gopsutil/v4 v4.25.6 // indirect github.com/shopspring/decimal v1.3.1 // indirect - github.com/sirupsen/logrus v1.9.3 // indirect + github.com/sirupsen/logrus v1.9.4 // indirect github.com/skeema/knownhosts v1.3.1 // indirect github.com/spf13/cast v1.5.0 // indirect github.com/tinylib/msgp v1.3.0 // indirect @@ -164,7 +164,7 @@ require ( golang.org/x/net v0.46.0 // indirect golang.org/x/oauth2 v0.30.0 // indirect golang.org/x/sync v0.17.0 // indirect - golang.org/x/sys v0.39.0 // indirect + golang.org/x/sys v0.40.0 // indirect golang.org/x/term v0.36.0 // indirect golang.org/x/text v0.30.0 // indirect golang.org/x/tools v0.38.0 // indirect diff --git a/go.sum b/go.sum index 784c7756..aa36bde6 100644 --- a/go.sum +++ b/go.sum @@ -402,6 +402,7 @@ github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyY github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -1072,6 +1073,8 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w= +github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g= github.com/skeema/knownhosts v1.3.1 h1:X2osQ+RAjK76shCbvhHHHVl3ZlgDm8apHEHFqRjnBY8= github.com/skeema/knownhosts v1.3.1/go.mod h1:r7KTdC8l4uxWRyK2TpQZ/1o5HaSzh06ePQNxPwTcfiY= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= @@ -1170,6 +1173,8 @@ go.abhg.dev/goldmark/frontmatter v0.2.0 h1:P8kPG0YkL12+aYk2yU3xHv4tcXzeVnN+gU0tJ go.abhg.dev/goldmark/frontmatter v0.2.0/go.mod h1:XqrEkZuM57djk7zrlRUB02x8I5J0px76YjkOzhB4YlU= go.clever-cloud.dev/client v0.1.4 h1:WnDBRgFHwxNxj+NCzEUFakBrPBVhWJBANzm/Yd8smJY= go.clever-cloud.dev/client v0.1.4/go.mod h1:FbR9HINkEq3ilZoKOTWOLgtv5JdNZEggW8cGuRjtODc= +go.clever-cloud.dev/client v0.1.6 h1:lsmCAkcmSNqvjgeU6PirQ/9f79IOkDCjTSytkuFHOuw= +go.clever-cloud.dev/client v0.1.6/go.mod h1:FbR9HINkEq3ilZoKOTWOLgtv5JdNZEggW8cGuRjtODc= go.clever-cloud.dev/sdk v0.0.5 h1:xoLR3/limOTZYhHP3q242BQmi7ha0qb1zU2w5FWDqms= go.clever-cloud.dev/sdk v0.0.5/go.mod h1:wTbSUEQLKgbBohz9OMya7bcjBrdoutdaC5JQM7LrXPE= go.einride.tech/aip v0.67.1/go.mod h1:ZGX4/zKw8dcgzdLsrvpOOGxfxI2QSk12SlP7d6c0/XI= @@ -1637,6 +1642,8 @@ golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= +golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= diff --git a/pkg/resources/application/create.go b/pkg/resources/application/create.go index fa91fc9f..76096799 100644 --- a/pkg/resources/application/create.go +++ b/pkg/resources/application/create.go @@ -93,7 +93,7 @@ func CreateApp(ctx context.Context, req CreateReq) (*CreateRes, diag.Diagnostics res.Application = *appRes.Payload() // Environment - envRes := tmp.UpdateAppEnv(ctx, req.Client, req.Organization, res.Application.ID, req.Environment) + envRes := UpdateAppEnv(ctx, req.Client, req.Organization, res.Application.ID, req.Environment, &diags) if envRes.HasError() { diags.AddError("failed to configure application environment", envRes.Error().Error()) } @@ -167,3 +167,38 @@ func Create[T RuntimePlan](ctx context.Context, resource RuntimeResource, plan T return diags } + +// this version of UpdateAppEnv first try with Env var validation reports warning +// and perform the update without validation in order to not break anything +// diag parameter only reports warnings, no error +// +// { +// "id":557, +// "message":"Application environment is invalid", +// "type":"error", +// "fields":{ +// "CC_TROUBLESHOOT":"must be one of: [troubleshoot, true, 1, yes, enable, enabled, on] (= true) or [off, disable, no, false, disabled, 0] (= false)" +// } +// } +func UpdateAppEnv(ctx context.Context, cc *client.Client, organisationID, applicationID string, envs map[string]string, diags *diag.Diagnostics) client.Response[any] { + res := tmp.UpdateAppEnv(ctx, cc, organisationID, applicationID, envs, true) + if !res.HasError() { + return res + } + + tflog.Info(ctx, "DEBUG") + // report errors + if apiErr, ok := res.Error().(*client.APIError); res.StatusCode() == 400 && ok { + tflog.Info(ctx, "ERR", map[string]any{"err": apiErr}) + for key, value := range apiErr.Context { + if key == "type" { + continue + } + + diags.AddWarning( + fmt.Sprintf("Invalid value for %s", key), fmt.Sprintf("%v", value)) + } + } + + return tmp.UpdateAppEnv(ctx, cc, organisationID, applicationID, envs, false) +} diff --git a/pkg/resources/application/update.go b/pkg/resources/application/update.go index 1a9d7d97..2045a6bc 100644 --- a/pkg/resources/application/update.go +++ b/pkg/resources/application/update.go @@ -42,7 +42,7 @@ func UpdateApp(ctx context.Context, req UpdateReq) (*CreateRes, diag.Diagnostics res.Application = *appRes.Payload() // Environment - envRes := tmp.UpdateAppEnv(ctx, req.Client, req.Organization, res.Application.ID, req.Environment) + envRes := UpdateAppEnv(ctx, req.Client, req.Organization, res.Application.ID, req.Environment, &diags) if envRes.HasError() { diags.AddError("failed to configure application environment", envRes.Error().Error()) return res, diags diff --git a/pkg/tmp/app.go b/pkg/tmp/app.go index 69a876f2..c2969593 100644 --- a/pkg/tmp/app.go +++ b/pkg/tmp/app.go @@ -246,8 +246,12 @@ func GetAppEnv(ctx context.Context, cc *client.Client, organisationID string, ap return client.Get[[]Env](ctx, cc, path) } -func UpdateAppEnv(ctx context.Context, cc *client.Client, organisationID string, applicationID string, envs map[string]string) client.Response[any] { +func UpdateAppEnv(ctx context.Context, cc *client.Client, organisationID string, applicationID string, envs map[string]string, enforceValidation bool) client.Response[any] { path := fmt.Sprintf("/v2/organisations/%s/applications/%s/env", organisationID, applicationID) + if enforceValidation { + path = fmt.Sprintf("%s?check=true", path) + } + return client.Put[any](ctx, cc, path, envs) }