From abb535c6cdc4761b6e9e8cf1c65e3a20a95decc6 Mon Sep 17 00:00:00 2001 From: Radek Simko Date: Wed, 11 Oct 2023 10:51:06 +0100 Subject: [PATCH] fix: Work around 'unreliable' input data for Registry modules --- internal/registry/module.go | 6 ++++-- internal/terraform/module/module_ops.go | 21 ++++++++++++++++++++- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/internal/registry/module.go b/internal/registry/module.go index 3bfa8a54a..b3932733d 100644 --- a/internal/registry/module.go +++ b/internal/registry/module.go @@ -11,6 +11,7 @@ import ( "net/http" "net/http/httptrace" "sort" + "time" "github.com/hashicorp/go-version" tfaddr "github.com/hashicorp/terraform-registry-address" @@ -21,8 +22,9 @@ import ( ) type ModuleResponse struct { - Version string `json:"version"` - Root ModuleRoot `json:"root"` + Version string `json:"version"` + PublishedAt time.Time `json:"published_at"` + Root ModuleRoot `json:"root"` } type ModuleRoot struct { diff --git a/internal/terraform/module/module_ops.go b/internal/terraform/module/module_ops.go index addd785ed..ad8d12cc0 100644 --- a/internal/terraform/module/module_ops.go +++ b/internal/terraform/module/module_ops.go @@ -1063,10 +1063,11 @@ func GetModuleDataFromRegistry(ctx context.Context, regClient registry.Client, m inputs := make([]tfregistry.Input, len(metaData.Root.Inputs)) for i, input := range metaData.Root.Inputs { + isRequired := isRegistryModuleInputRequired(metaData.PublishedAt, input) inputs[i] = tfregistry.Input{ Name: input.Name, Description: lang.Markdown(input.Description), - Required: input.Required, + Required: isRequired, } inputType := cty.DynamicPseudoType @@ -1123,3 +1124,21 @@ func GetModuleDataFromRegistry(ctx context.Context, regClient registry.Client, m return errs.ErrorOrNil() } + +// isRegistryModuleInputRequired checks whether the module input is required. +// It reflects the fact that modules ingested into the Registry +// may have used `default = null` (implying optional variable) which +// the Registry wasn't able to recognise until ~ 19th August 2022. +func isRegistryModuleInputRequired(publishTime time.Time, input registry.Input) bool { + fixTime := time.Date(2022, time.August, 20, 0, 0, 0, 0, time.UTC) + // Modules published after the date have "nullable" inputs + // (default = null) ingested as Required=false and Default="null". + // + // The same inputs ingested prior to the date make it impossible + // to distinguish variable with `default = null` and missing default. + if input.Required && input.Default == "" && publishTime.Before(fixTime) { + // To avoid false diagnostics, we safely assume the input is optional + return false + } + return input.Required +}