From 06717afc5390b53ad61c6a709e66e6bb9451e955 Mon Sep 17 00:00:00 2001 From: Jakub Gruszecki Date: Thu, 22 Aug 2024 14:26:18 +0200 Subject: [PATCH 01/10] make value optional --- examples/resources/nobl9_slo/resource.tf | 1 - nobl9/resource_slo.go | 13 +++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/examples/resources/nobl9_slo/resource.tf b/examples/resources/nobl9_slo/resource.tf index a346e23c..31e2392d 100644 --- a/examples/resources/nobl9_slo/resource.tf +++ b/examples/resources/nobl9_slo/resource.tf @@ -144,7 +144,6 @@ resource "nobl9_slo" "composite_slo" { display_name = "OK" name = "tf-objective-1" target = 0.8 - value = 1 composite { max_delay = "45m" components { diff --git a/nobl9/resource_slo.go b/nobl9/resource_slo.go index 2b53ee41..4f5eac01 100644 --- a/nobl9/resource_slo.go +++ b/nobl9/resource_slo.go @@ -144,7 +144,7 @@ func resourceObjective() *schema.Resource { }, "value": { Type: schema.TypeFloat, - Required: true, + Optional: false, Description: "Value.", }, "name": { @@ -545,7 +545,10 @@ func marshalObjectives(d *schema.ResourceData) ([]v1alphaSLO.Objective, diag.Dia objectives := make([]v1alphaSLO.Objective, len(objectivesSchema)) for i, o := range objectivesSchema { objective := o.(map[string]interface{}) - value := objective["value"].(float64) + var valuePtr *float64 + if value, ok := objective["value"].(float64); ok { + valuePtr = &value + } target := objective["target"].(float64) timeSliceTarget := objective["time_slice_target"].(float64) var timeSliceTargetPtr *float64 @@ -562,7 +565,7 @@ func marshalObjectives(d *schema.ResourceData) ([]v1alphaSLO.Objective, diag.Dia objectives[i] = v1alphaSLO.Objective{ ObjectiveBase: v1alphaSLO.ObjectiveBase{ DisplayName: objective["display_name"].(string), - Value: &value, + Value: valuePtr, Name: objective["name"].(string), }, BudgetTarget: &target, @@ -803,7 +806,9 @@ func unmarshalObjectives(d *schema.ResourceData, spec v1alphaSLO.Spec) error { objectiveTF["name"] = objective.Name objectiveTF["display_name"] = objective.DisplayName objectiveTF["op"] = objective.Operator - objectiveTF["value"] = objective.Value + if objective.Value != nil { + objectiveTF["value"] = objective.Value + } objectiveTF["target"] = objective.BudgetTarget objectiveTF["time_slice_target"] = objective.TimeSliceTarget objectiveTF["primary"] = objective.Primary From 4b46a1ef9bcf064b43d4113e7f5f5db6d3ea93de Mon Sep 17 00:00:00 2001 From: Jakub Gruszecki Date: Thu, 22 Aug 2024 16:11:48 +0200 Subject: [PATCH 02/10] value is optional --- nobl9/resource_slo.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nobl9/resource_slo.go b/nobl9/resource_slo.go index 4f5eac01..c61008d8 100644 --- a/nobl9/resource_slo.go +++ b/nobl9/resource_slo.go @@ -144,7 +144,7 @@ func resourceObjective() *schema.Resource { }, "value": { Type: schema.TypeFloat, - Optional: false, + Optional: true, Description: "Value.", }, "name": { From c50644ce2c124a043ddbe0cab7d021ae24a5e79c Mon Sep 17 00:00:00 2001 From: Jakub Gruszecki Date: Thu, 22 Aug 2024 16:12:12 +0200 Subject: [PATCH 03/10] generated docs --- docs/resources/slo.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/resources/slo.md b/docs/resources/slo.md index 70a3402b..efc5136e 100644 --- a/docs/resources/slo.md +++ b/docs/resources/slo.md @@ -164,7 +164,6 @@ resource "nobl9_slo" "composite_slo" { display_name = "OK" name = "tf-objective-1" target = 0.8 - value = 1 composite { max_delay = "45m" components { @@ -225,7 +224,6 @@ resource "nobl9_slo" "composite_slo" { Required: - `target` (Number) Designated value. -- `value` (Number) Value. Optional: @@ -237,6 +235,7 @@ Optional: - `primary` (Boolean) Is objective marked as primary. - `raw_metric` (Block Set) Raw data is used to compare objective values. (see [below for nested schema](#nestedblock--objective--raw_metric)) - `time_slice_target` (Number) Designated value for slice. +- `value` (Number) Value. ### Nested Schema for `objective.composite` From fb79f039f0bc5f7ea8b654410b28af7b70f3e080 Mon Sep 17 00:00:00 2001 From: Jakub Gruszecki Date: Fri, 23 Aug 2024 12:52:40 +0200 Subject: [PATCH 04/10] omitting value using sentinel --- nobl9/resource_slo.go | 25 ++++++++++++++++++------- nobl9/resource_slo_test.go | 2 -- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/nobl9/resource_slo.go b/nobl9/resource_slo.go index c61008d8..6df4b72b 100644 --- a/nobl9/resource_slo.go +++ b/nobl9/resource_slo.go @@ -5,6 +5,7 @@ import ( "encoding/json" "errors" "fmt" + "math" "reflect" "regexp" "sort" @@ -21,6 +22,8 @@ import ( "github.com/nobl9/nobl9-go/manifest" ) +const sloSpecObjectiveValueNotSetSentinel = math.SmallestNonzeroFloat64 + func resourceSLO() *schema.Resource { return &schema.Resource{ Schema: schemaSLO(), @@ -143,8 +146,13 @@ func resourceObjective() *schema.Resource { Description: "Designated value for slice.", }, "value": { - Type: schema.TypeFloat, - Optional: true, + Type: schema.TypeFloat, + Optional: true, + // This is a sentinel value which is used to determine if the value was set or not. It is set to nil + // in Nobl9 SDK. In Terraform SDKv2 this is the only way to determine if the value was set or not: + // https://discuss.hashicorp.com/t/how-to-tell-if-sub-structure-attributes-are-set-in-the-resource/46491 + // This will become easier to handle when migrating to Terraform Framework. + Default: sloSpecObjectiveValueNotSetSentinel, Description: "Value.", }, "name": { @@ -340,8 +348,7 @@ func resourceSLOApply(ctx context.Context, d *schema.ResourceData, meta interfac resultSlo := manifest.SetDefaultProject([]manifest.Object{slo}, config.Project) if err := retry.RetryContext(ctx, d.Timeout(schema.TimeoutCreate)-time.Minute, func() *retry.RetryError { - err := client.Objects().V1().Apply(ctx, resultSlo) - if err != nil { + if err := client.Objects().V1().Apply(ctx, resultSlo); err != nil { if errors.Is(err, errConcurrencyIssue) { return retry.RetryableError(err) } @@ -541,12 +548,14 @@ func marshalIndicator(d *schema.ResourceData) *v1alphaSLO.Indicator { } func marshalObjectives(d *schema.ResourceData) ([]v1alphaSLO.Objective, diag.Diagnostics) { - objectivesSchema := d.Get("objective").(*schema.Set).List() + objectivesSchemaSet := d.Get("objective").(*schema.Set) + objectivesSchema := objectivesSchemaSet.List() objectives := make([]v1alphaSLO.Objective, len(objectivesSchema)) for i, o := range objectivesSchema { objective := o.(map[string]interface{}) var valuePtr *float64 - if value, ok := objective["value"].(float64); ok { + value := objective["value"].(float64) + if value != sloSpecObjectiveValueNotSetSentinel { valuePtr = &value } target := objective["target"].(float64) @@ -806,7 +815,9 @@ func unmarshalObjectives(d *schema.ResourceData, spec v1alphaSLO.Spec) error { objectiveTF["name"] = objective.Name objectiveTF["display_name"] = objective.DisplayName objectiveTF["op"] = objective.Operator - if objective.Value != nil { + if objective.Value == nil { + objectiveTF["value"] = sloSpecObjectiveValueNotSetSentinel + } else { objectiveTF["value"] = objective.Value } objectiveTF["target"] = objective.BudgetTarget diff --git a/nobl9/resource_slo_test.go b/nobl9/resource_slo_test.go index f37daa8d..13461daa 100644 --- a/nobl9/resource_slo_test.go +++ b/nobl9/resource_slo_test.go @@ -1027,7 +1027,6 @@ resource "nobl9_slo" ":name" { display_name = "obj1" name = "tf-objective-1" target = 0.7 - value = 1 composite { max_delay = "45m" components { @@ -1089,7 +1088,6 @@ resource "nobl9_slo" ":name" { display_name = "obj1" name = "tf-objective-1" target = 0.7 - value = 1 time_slice_target = 0.7 composite { max_delay = "45m" From 608c943f9948eebc631513e6cdb7ff052101e046 Mon Sep 17 00:00:00 2001 From: Jakub Gruszecki Date: Fri, 23 Aug 2024 16:01:35 +0200 Subject: [PATCH 05/10] temporarily pin nobl9 sdk to unreleased version from branch PC-13893-composite-value --- go.mod | 2 ++ go.sum | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index a493ae3b..8a548077 100644 --- a/go.mod +++ b/go.mod @@ -12,6 +12,8 @@ require ( github.com/teambition/rrule-go v1.8.2 ) +replace github.com/nobl9/nobl9-go => github.com/nobl9/nobl9-go v0.84.0-rc4.0.20240823121412-63f033ee794d + require ( github.com/BurntSushi/toml v1.4.0 // indirect github.com/Kunde21/markdownfmt/v3 v3.1.0 // indirect diff --git a/go.sum b/go.sum index e31a49e9..2d27ce0d 100644 --- a/go.sum +++ b/go.sum @@ -178,8 +178,8 @@ github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zx github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/nobl9/go-yaml v1.0.1 h1:Aj1kSaYdRQTKlvS6ihvXzQJhCpoHhtf9nfA95zqWH4Q= github.com/nobl9/go-yaml v1.0.1/go.mod h1:t7vCO8ctYdBweZxU5lUgxzAw31+ZcqJYeqRtrv+5RHI= -github.com/nobl9/nobl9-go v0.83.0 h1:2In5WdZh/GiChSIRLoxhMJf5DKdKCS492bURQJC7my8= -github.com/nobl9/nobl9-go v0.83.0/go.mod h1:Fx4m7n32rq+f0N+ezgx8+JbhGg89T6TikiGC/QlRE14= +github.com/nobl9/nobl9-go v0.84.0-rc4.0.20240823121412-63f033ee794d h1:jtZFc/8ebLw43Y65cCXqrsEzQ8BpS41XUSntDVB6NLw= +github.com/nobl9/nobl9-go v0.84.0-rc4.0.20240823121412-63f033ee794d/go.mod h1:Jq840pSewkS1xvbwOENjqvNKugs3p3ZAdZG+iWZksGQ= github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= From d19b784110255bf549bb4fca51796aee9f50a4c7 Mon Sep 17 00:00:00 2001 From: Jakub Gruszecki Date: Fri, 23 Aug 2024 16:17:39 +0200 Subject: [PATCH 06/10] updated description for `value` --- docs/resources/slo.md | 2 +- nobl9/resource_slo.go | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/resources/slo.md b/docs/resources/slo.md index efc5136e..5807c753 100644 --- a/docs/resources/slo.md +++ b/docs/resources/slo.md @@ -235,7 +235,7 @@ Optional: - `primary` (Boolean) Is objective marked as primary. - `raw_metric` (Block Set) Raw data is used to compare objective values. (see [below for nested schema](#nestedblock--objective--raw_metric)) - `time_slice_target` (Number) Designated value for slice. -- `value` (Number) Value. +- `value` (Number) Value. Should be omitted for objectives using `composite` section. Can be omitted for objectives using `count_metrics` section. Is required for objectives using `raw_metric` section. Must be unique in a scope of SLO if that SLO has multiple objectives. ### Nested Schema for `objective.composite` diff --git a/nobl9/resource_slo.go b/nobl9/resource_slo.go index 6df4b72b..21e33df3 100644 --- a/nobl9/resource_slo.go +++ b/nobl9/resource_slo.go @@ -152,8 +152,10 @@ func resourceObjective() *schema.Resource { // in Nobl9 SDK. In Terraform SDKv2 this is the only way to determine if the value was set or not: // https://discuss.hashicorp.com/t/how-to-tell-if-sub-structure-attributes-are-set-in-the-resource/46491 // This will become easier to handle when migrating to Terraform Framework. - Default: sloSpecObjectiveValueNotSetSentinel, - Description: "Value.", + Default: sloSpecObjectiveValueNotSetSentinel, + Description: "Value. Should be omitted for objectives using `composite` section. Can be omitted for" + + " objectives using `count_metrics` section. Is required for objectives using `raw_metric` section." + + " Must be unique in a scope of SLO if that SLO has multiple objectives.", }, "name": { Type: schema.TypeString, From 9b821ccf7398042d7a65351d6c045c997f0e2631 Mon Sep 17 00:00:00 2001 From: Jakub Gruszecki Date: Tue, 10 Sep 2024 11:12:18 +0200 Subject: [PATCH 07/10] updated nobl9-go reference --- go.mod | 23 ++++++++++++----------- go.sum | 46 ++++++++++++++++++++++++---------------------- 2 files changed, 36 insertions(+), 33 deletions(-) diff --git a/go.mod b/go.mod index 90861a28..25e359e2 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/teambition/rrule-go v1.8.2 ) -replace github.com/nobl9/nobl9-go => github.com/nobl9/nobl9-go v0.84.0-rc4.0.20240823121412-63f033ee794d +replace github.com/nobl9/nobl9-go => github.com/nobl9/nobl9-go v0.84.1-0.20240909142431-e1b671f98ae4 require ( github.com/BurntSushi/toml v1.4.0 // indirect @@ -26,7 +26,7 @@ require ( github.com/agext/levenshtein v1.2.3 // indirect github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect github.com/armon/go-radix v1.0.0 // indirect - github.com/aws/aws-sdk-go v1.54.17 // indirect + github.com/aws/aws-sdk-go v1.55.5 // indirect github.com/bgentry/speakeasy v0.1.0 // indirect github.com/bmatcuk/doublestar/v4 v4.6.1 // indirect github.com/cloudflare/circl v1.3.7 // indirect @@ -68,6 +68,7 @@ require ( github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/nobl9/go-yaml v1.0.1 // indirect + github.com/nobl9/govy v0.1.1 // indirect github.com/oklog/run v1.1.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect @@ -81,15 +82,15 @@ require ( github.com/yuin/goldmark-meta v1.1.0 // indirect github.com/zclconf/go-cty v1.14.4 // indirect go.abhg.dev/goldmark/frontmatter v0.2.0 // indirect - golang.org/x/crypto v0.24.0 // indirect - golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8 // indirect - golang.org/x/mod v0.18.0 // indirect - golang.org/x/net v0.26.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.21.0 // indirect - golang.org/x/text v0.16.0 // indirect - golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.22.0 // indirect + golang.org/x/crypto v0.26.0 // indirect + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.23.0 // indirect + golang.org/x/text v0.18.0 // indirect + golang.org/x/time v0.6.0 // indirect + golang.org/x/tools v0.24.0 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect google.golang.org/appengine v1.6.8 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de // indirect diff --git a/go.sum b/go.sum index a816b1a0..ad9f2a6a 100644 --- a/go.sum +++ b/go.sum @@ -25,8 +25,8 @@ github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/aws/aws-sdk-go v1.54.17 h1:ZV/qwcCIhMHgsJ6iXXPVYI0s1MdLT+5LW28ClzCUPeI= -github.com/aws/aws-sdk-go v1.54.17/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= +github.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU= +github.com/aws/aws-sdk-go v1.55.5/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bmatcuk/doublestar/v4 v4.6.1 h1:FH9SifrbvJhnlQpztAx++wlkk70QBf0iBWDwNy7PA4I= @@ -178,8 +178,10 @@ github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zx github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/nobl9/go-yaml v1.0.1 h1:Aj1kSaYdRQTKlvS6ihvXzQJhCpoHhtf9nfA95zqWH4Q= github.com/nobl9/go-yaml v1.0.1/go.mod h1:t7vCO8ctYdBweZxU5lUgxzAw31+ZcqJYeqRtrv+5RHI= -github.com/nobl9/nobl9-go v0.84.0 h1:2mwwegUx/gAltbNmx4STq5A4iVahGVLZ7UI6QZepu0U= -github.com/nobl9/nobl9-go v0.84.0/go.mod h1:Jq840pSewkS1xvbwOENjqvNKugs3p3ZAdZG+iWZksGQ= +github.com/nobl9/govy v0.1.1 h1:l5UVwLuYhDhDFdmofH+SpE63Ta9IMTusFwY2MeJlCx4= +github.com/nobl9/govy v0.1.1/go.mod h1:MIhQelE3P6Ty7oqXef5ObzsxAo50+RiXmrywNy9ZRRw= +github.com/nobl9/nobl9-go v0.84.1-0.20240909142431-e1b671f98ae4 h1:3Nb3cyvvEy+eaGAzv118ptpC4r/6VQCh+AiNTln21AM= +github.com/nobl9/nobl9-go v0.84.1-0.20240909142431-e1b671f98ae4/go.mod h1:prAsgIuSyMUYbtQTh+o5prg8gykeEU3tfaU3gouOJBs= github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= @@ -234,25 +236,25 @@ go.abhg.dev/goldmark/frontmatter v0.2.0/go.mod h1:XqrEkZuM57djk7zrlRUB02x8I5J0px golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= -golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= -golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= -golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8 h1:LoYXNGAShUG3m/ehNk4iFctuhGX/+R1ZpfJ4/ia80JM= -golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= +golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI= +golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= -golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= -golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= -golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -266,8 +268,8 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= +golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= @@ -277,15 +279,15 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= -golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= -golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= +golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA= -golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= From 75a259911648b0fb3e9957b30a20792922113b8f Mon Sep 17 00:00:00 2001 From: Jakub Gruszecki Date: Wed, 11 Sep 2024 13:21:46 +0200 Subject: [PATCH 08/10] updated nobl9-go --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 25e359e2..c5ff0981 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/teambition/rrule-go v1.8.2 ) -replace github.com/nobl9/nobl9-go => github.com/nobl9/nobl9-go v0.84.1-0.20240909142431-e1b671f98ae4 +replace github.com/nobl9/nobl9-go => github.com/nobl9/nobl9-go v0.84.1-rc4.0.20240911111359-063d013bdffa require ( github.com/BurntSushi/toml v1.4.0 // indirect diff --git a/go.sum b/go.sum index ad9f2a6a..a4f45c15 100644 --- a/go.sum +++ b/go.sum @@ -180,8 +180,8 @@ github.com/nobl9/go-yaml v1.0.1 h1:Aj1kSaYdRQTKlvS6ihvXzQJhCpoHhtf9nfA95zqWH4Q= github.com/nobl9/go-yaml v1.0.1/go.mod h1:t7vCO8ctYdBweZxU5lUgxzAw31+ZcqJYeqRtrv+5RHI= github.com/nobl9/govy v0.1.1 h1:l5UVwLuYhDhDFdmofH+SpE63Ta9IMTusFwY2MeJlCx4= github.com/nobl9/govy v0.1.1/go.mod h1:MIhQelE3P6Ty7oqXef5ObzsxAo50+RiXmrywNy9ZRRw= -github.com/nobl9/nobl9-go v0.84.1-0.20240909142431-e1b671f98ae4 h1:3Nb3cyvvEy+eaGAzv118ptpC4r/6VQCh+AiNTln21AM= -github.com/nobl9/nobl9-go v0.84.1-0.20240909142431-e1b671f98ae4/go.mod h1:prAsgIuSyMUYbtQTh+o5prg8gykeEU3tfaU3gouOJBs= +github.com/nobl9/nobl9-go v0.84.1-rc4.0.20240911111359-063d013bdffa h1:jqK6DcewxWw+rCnz4mJAw/a3SPhdSIrT9YO58J4j/yw= +github.com/nobl9/nobl9-go v0.84.1-rc4.0.20240911111359-063d013bdffa/go.mod h1:prAsgIuSyMUYbtQTh+o5prg8gykeEU3tfaU3gouOJBs= github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= From cb9b7cd45fee21f9f3620aa8c05f26671731b651 Mon Sep 17 00:00:00 2001 From: Jakub Gruszecki Date: Fri, 13 Sep 2024 12:50:09 +0200 Subject: [PATCH 09/10] unit test for zaro value backward compatibility --- nobl9/resource_slo_test.go | 74 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/nobl9/resource_slo_test.go b/nobl9/resource_slo_test.go index 13461daa..0d7ba03c 100644 --- a/nobl9/resource_slo_test.go +++ b/nobl9/resource_slo_test.go @@ -32,6 +32,7 @@ func TestAcc_Nobl9SLO(t *testing.T) { {"test-composite-time-slices-deprecated", testCompositeSLOTimeSlicesDeprecated}, {"test-composite-occurrences", testCompositeSLOOccurrences}, {"test-composite-time-slices", testCompositeSLOTimeSlices}, + {"test-composite-with-value", testCompositeSLOValueZeroBackwardCompatibility}, {"test-datadog", testDatadogSLO}, {"test-dynatrace", testDynatraceSLO}, {"test-grafanaloki", testGrafanaLokiSLO}, @@ -1128,6 +1129,79 @@ resource "nobl9_slo" ":name" { return config } +func testCompositeSLOValueZeroBackwardCompatibility(name string) string { + var serviceName = name + "-tf-service" + var agentName = name + "-tf-agent" + var sloDependencyName = name + "-dependency-slo-1" + config := + testService(serviceName) + + testPrometheusAgent(agentName) + + testCompositeDependencySLO(serviceName, agentName, sloDependencyName) + ` +resource "nobl9_slo" ":name" { + name = ":name" + display_name = ":name" + project = ":project" + service = nobl9_service.:serviceName.name + + + depends_on = [nobl9_slo.:sloDependencyName] + + label { + key = "team" + values = ["green","sapphire"] + } + + label { + key = "env" + values = ["dev", "staging", "prod"] + } + + budgeting_method = "Occurrences" + + objective { + display_name = "obj1" + name = "tf-objective-1" + target = 0.7 + value = 0 + composite { + max_delay = "45m" + components { + objectives { + composite_objective { + project = ":project" + slo = ":sloDependencyName" + objective = "objective-1" + weight = 0.8 + when_delayed = "CountAsGood" + } + composite_objective { + project = ":project" + slo = ":sloDependencyName" + objective = "objective-2" + weight = 1.0 + when_delayed = "CountAsBad" + } + } + } + } + } + + time_window { + count = 10 + is_rolling = true + unit = "Minute" + } +} +` + config = strings.ReplaceAll(config, ":name", name) + config = strings.ReplaceAll(config, ":serviceName", serviceName) + config = strings.ReplaceAll(config, ":agentName", agentName) + config = strings.ReplaceAll(config, ":project", testProject) + config = strings.ReplaceAll(config, ":sloDependencyName", sloDependencyName) + + return config +} + func testDatadogSLO(name string) string { var serviceName = name + "-tf-service" var agentName = name + "-tf-agent" From 207743cb83c5c31d27f1131f13d38bd90b507366 Mon Sep 17 00:00:00 2001 From: Jakub Gruszecki Date: Fri, 13 Sep 2024 12:50:36 +0200 Subject: [PATCH 10/10] used simple default zero instead of sentinel --- nobl9/resource_slo.go | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/nobl9/resource_slo.go b/nobl9/resource_slo.go index 400bdbae..39ae1bbc 100644 --- a/nobl9/resource_slo.go +++ b/nobl9/resource_slo.go @@ -5,7 +5,6 @@ import ( "encoding/json" "errors" "fmt" - "math" "reflect" "regexp" "sort" @@ -22,8 +21,6 @@ import ( "github.com/nobl9/nobl9-go/manifest" ) -const sloSpecObjectiveValueNotSetSentinel = math.SmallestNonzeroFloat64 - func resourceSLO() *schema.Resource { return &schema.Resource{ Schema: schemaSLO(), @@ -149,11 +146,7 @@ func resourceObjective() *schema.Resource { "value": { Type: schema.TypeFloat, Optional: true, - // This is a sentinel value which is used to determine if the value was set or not. It is set to nil - // in Nobl9 SDK. In Terraform SDKv2 this is the only way to determine if the value was set or not: - // https://discuss.hashicorp.com/t/how-to-tell-if-sub-structure-attributes-are-set-in-the-resource/46491 - // This will become easier to handle when migrating to Terraform Framework. - Default: sloSpecObjectiveValueNotSetSentinel, + Default: 0, Description: "Value. Should be omitted for objectives using `composite` section. Can be omitted for" + " objectives using `count_metrics` section. Is required for objectives using `raw_metric` section." + " Must be unique in a scope of SLO if that SLO has multiple objectives.", @@ -556,11 +549,6 @@ func marshalObjectives(d *schema.ResourceData) ([]v1alphaSLO.Objective, diag.Dia objectives := make([]v1alphaSLO.Objective, len(objectivesSchema)) for i, o := range objectivesSchema { objective := o.(map[string]interface{}) - var valuePtr *float64 - value := objective["value"].(float64) - if value != sloSpecObjectiveValueNotSetSentinel { - valuePtr = &value - } target := objective["target"].(float64) timeSliceTarget := objective["time_slice_target"].(float64) var timeSliceTargetPtr *float64 @@ -573,7 +561,12 @@ func marshalObjectives(d *schema.ResourceData) ([]v1alphaSLO.Objective, diag.Dia if err != nil { return nil, diag.FromErr(err) } - + var valuePtr *float64 + value := objective["value"].(float64) + valuePtr = &value + if value == 0 && compositeSpec != nil { + valuePtr = nil + } objectives[i] = v1alphaSLO.Objective{ ObjectiveBase: v1alphaSLO.ObjectiveBase{ DisplayName: objective["display_name"].(string), @@ -818,9 +811,7 @@ func unmarshalObjectives(d *schema.ResourceData, spec v1alphaSLO.Spec) error { objectiveTF["name"] = objective.Name objectiveTF["display_name"] = objective.DisplayName objectiveTF["op"] = objective.Operator - if objective.Value == nil { - objectiveTF["value"] = sloSpecObjectiveValueNotSetSentinel - } else { + if objective.Value != nil && (*objective.Value != 0 || objective.Composite == nil) { objectiveTF["value"] = objective.Value } objectiveTF["target"] = objective.BudgetTarget