diff --git a/go.sum b/go.sum index b93460350..a5d124db2 100644 --- a/go.sum +++ b/go.sum @@ -718,8 +718,6 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= -golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= diff --git a/integrationtest/fixtures/binding-cleanup/fake-bad-bind.tf b/integrationtest/fixtures/binding-cleanup/fake-bad-bind.tf index 9de1f243c..47edd5e47 100644 --- a/integrationtest/fixtures/binding-cleanup/fake-bad-bind.tf +++ b/integrationtest/fixtures/binding-cleanup/fake-bad-bind.tf @@ -1,4 +1,12 @@ // Fails as required "length" parameter is missing +terraform { + required_providers { + random = { + source = "registry.terraform.io/hashicorp/random" + } + } +} + resource "random_string" "random" {} output bind_output { value = random_string.random.result } \ No newline at end of file diff --git a/integrationtest/fixtures/binding-cleanup/fake-good-bind.tf b/integrationtest/fixtures/binding-cleanup/fake-good-bind.tf index fcbed15be..a214915a0 100644 --- a/integrationtest/fixtures/binding-cleanup/fake-good-bind.tf +++ b/integrationtest/fixtures/binding-cleanup/fake-good-bind.tf @@ -1,3 +1,11 @@ +terraform { + required_providers { + random = { + source = "registry.terraform.io/hashicorp/random" + } + } +} + resource "random_string" "random" { length = 10 } diff --git a/integrationtest/fixtures/binding-cleanup/fake-provision.tf b/integrationtest/fixtures/binding-cleanup/fake-provision.tf index adbe4074b..db12d4a33 100644 --- a/integrationtest/fixtures/binding-cleanup/fake-provision.tf +++ b/integrationtest/fixtures/binding-cleanup/fake-provision.tf @@ -1,3 +1,11 @@ +terraform { + required_providers { + random = { + source = "registry.terraform.io/hashicorp/random" + } + } +} + resource "random_uuid" "random" {} output provision_output { value = random_uuid.random.result } \ No newline at end of file diff --git a/integrationtest/fixtures/golden-path/fake-uuid-bind.tf b/integrationtest/fixtures/golden-path/fake-uuid-bind.tf index 3820163a0..7c92100ef 100644 --- a/integrationtest/fixtures/golden-path/fake-uuid-bind.tf +++ b/integrationtest/fixtures/golden-path/fake-uuid-bind.tf @@ -1,3 +1,11 @@ +terraform { + required_providers { + random = { + source = "registry.terraform.io/hashicorp/random" + } + } +} + resource "random_uuid" "random" {} output bind_output { value = random_uuid.random.result } \ No newline at end of file diff --git a/integrationtest/fixtures/golden-path/fake-uuid-provision.tf b/integrationtest/fixtures/golden-path/fake-uuid-provision.tf index adbe4074b..db12d4a33 100644 --- a/integrationtest/fixtures/golden-path/fake-uuid-provision.tf +++ b/integrationtest/fixtures/golden-path/fake-uuid-provision.tf @@ -1,3 +1,11 @@ +terraform { + required_providers { + random = { + source = "registry.terraform.io/hashicorp/random" + } + } +} + resource "random_uuid" "random" {} output provision_output { value = random_uuid.random.result } \ No newline at end of file diff --git a/integrationtest/fixtures/maintenance-info/fake-provision.tf b/integrationtest/fixtures/maintenance-info/fake-provision.tf index a815f8953..f3a9b7dd4 100644 --- a/integrationtest/fixtures/maintenance-info/fake-provision.tf +++ b/integrationtest/fixtures/maintenance-info/fake-provision.tf @@ -1,7 +1,7 @@ terraform { required_providers { random = { - source = "hashicorp/random" + source = "registry.terraform.io/hashicorp/random" version = "3.5.1" } } diff --git a/integrationtest/fixtures/osbapi/fake-provision.tf b/integrationtest/fixtures/osbapi/fake-provision.tf index 266b79568..364770813 100644 --- a/integrationtest/fixtures/osbapi/fake-provision.tf +++ b/integrationtest/fixtures/osbapi/fake-provision.tf @@ -1,4 +1,10 @@ -provider "random" { } +terraform { + required_providers { + random = { + source = "registry.terraform.io/hashicorp/random" + } + } +} resource "random_integer" "priority" { min = 1 diff --git a/integrationtest/fixtures/prevent-destroy-during-update/fake-provision.tf b/integrationtest/fixtures/prevent-destroy-during-update/fake-provision.tf index 27a2decb7..84864d59b 100644 --- a/integrationtest/fixtures/prevent-destroy-during-update/fake-provision.tf +++ b/integrationtest/fixtures/prevent-destroy-during-update/fake-provision.tf @@ -1,4 +1,10 @@ -provider "random" { } +terraform { + required_providers { + random = { + source = "registry.terraform.io/hashicorp/random" + } + } +} variable length { type = number } diff --git a/integrationtest/fixtures/provision-cleanup/fake-string-provision.tf b/integrationtest/fixtures/provision-cleanup/fake-string-provision.tf index c53142595..773443262 100644 --- a/integrationtest/fixtures/provision-cleanup/fake-string-provision.tf +++ b/integrationtest/fixtures/provision-cleanup/fake-string-provision.tf @@ -1,4 +1,12 @@ // Fails as required "length" parameter is missing +terraform { + required_providers { + random = { + source = "registry.terraform.io/hashicorp/random" + } + } +} + resource "random_string" "random" {} output provision_output { value = random_string.random.result } \ No newline at end of file diff --git a/integrationtest/fixtures/subsume/fake-string-service.yml b/integrationtest/fixtures/subsume/fake-string-service.yml index cddbf098f..108b71257 100644 --- a/integrationtest/fixtures/subsume/fake-string-service.yml +++ b/integrationtest/fixtures/subsume/fake-string-service.yml @@ -24,6 +24,7 @@ provision: import_parameters_to_delete: [ "random_string.random.id", "random_string.random.result" ] template_refs: main: fake-string-provision.tf + versions: versions.tf outputs: - field_name: provision_output type: string diff --git a/integrationtest/fixtures/subsume/fake-uuid-service.yml b/integrationtest/fixtures/subsume/fake-uuid-service.yml index 02ee298c6..ae1fe29be 100644 --- a/integrationtest/fixtures/subsume/fake-uuid-service.yml +++ b/integrationtest/fixtures/subsume/fake-uuid-service.yml @@ -21,6 +21,7 @@ provision: import_parameters_to_delete: [ "random_uuid.random.id" , "random_uuid.random.result" ] template_refs: main: fake-uuid-provision.tf + versions: versions.tf outputs: - field_name: provision_output type: string diff --git a/integrationtest/fixtures/subsume/versions.tf b/integrationtest/fixtures/subsume/versions.tf new file mode 100644 index 000000000..09be45e87 --- /dev/null +++ b/integrationtest/fixtures/subsume/versions.tf @@ -0,0 +1,7 @@ +terraform { + required_providers { + random = { + source = "registry.terraform.io/hashicorp/random" + } + } +} diff --git a/integrationtest/fixtures/termination-recovery/fake-uuid-bind.tf b/integrationtest/fixtures/termination-recovery/fake-uuid-bind.tf index 3820163a0..7c92100ef 100644 --- a/integrationtest/fixtures/termination-recovery/fake-uuid-bind.tf +++ b/integrationtest/fixtures/termination-recovery/fake-uuid-bind.tf @@ -1,3 +1,11 @@ +terraform { + required_providers { + random = { + source = "registry.terraform.io/hashicorp/random" + } + } +} + resource "random_uuid" "random" {} output bind_output { value = random_uuid.random.result } \ No newline at end of file diff --git a/integrationtest/fixtures/termination-recovery/fake-uuid-provision.tf b/integrationtest/fixtures/termination-recovery/fake-uuid-provision.tf index adbe4074b..db12d4a33 100644 --- a/integrationtest/fixtures/termination-recovery/fake-uuid-provision.tf +++ b/integrationtest/fixtures/termination-recovery/fake-uuid-provision.tf @@ -1,3 +1,11 @@ +terraform { + required_providers { + random = { + source = "registry.terraform.io/hashicorp/random" + } + } +} + resource "random_uuid" "random" {} output provision_output { value = random_uuid.random.result } \ No newline at end of file diff --git a/integrationtest/fixtures/terraform-block-action-before-upgrade-updated/fake-provision.tf b/integrationtest/fixtures/terraform-block-action-before-upgrade-updated/fake-provision.tf index a815f8953..f3a9b7dd4 100644 --- a/integrationtest/fixtures/terraform-block-action-before-upgrade-updated/fake-provision.tf +++ b/integrationtest/fixtures/terraform-block-action-before-upgrade-updated/fake-provision.tf @@ -1,7 +1,7 @@ terraform { required_providers { random = { - source = "hashicorp/random" + source = "registry.terraform.io/hashicorp/random" version = "3.5.1" } } diff --git a/integrationtest/fixtures/terraform-block-action-before-upgrade/fake-provision.tf b/integrationtest/fixtures/terraform-block-action-before-upgrade/fake-provision.tf index 266b79568..0934e7635 100644 --- a/integrationtest/fixtures/terraform-block-action-before-upgrade/fake-provision.tf +++ b/integrationtest/fixtures/terraform-block-action-before-upgrade/fake-provision.tf @@ -1,3 +1,11 @@ +terraform { + required_providers { + random = { + source = "registry.terraform.io/hashicorp/random" + } + } +} + provider "random" { } resource "random_integer" "priority" { diff --git a/integrationtest/fixtures/terraform-module-upgrade-updated/fake-provision.tf b/integrationtest/fixtures/terraform-module-upgrade-updated/fake-provision.tf index f495d310e..f3727e069 100644 --- a/integrationtest/fixtures/terraform-module-upgrade-updated/fake-provision.tf +++ b/integrationtest/fixtures/terraform-module-upgrade-updated/fake-provision.tf @@ -1,7 +1,7 @@ terraform { required_providers { random = { - source = "hashicorp/random" + source = "registry.terraform.io/hashicorp/random" version = "3.5.1" } } diff --git a/integrationtest/fixtures/terraform-module-upgrade/fake-provision.tf b/integrationtest/fixtures/terraform-module-upgrade/fake-provision.tf index 7f81ef008..902b2254d 100644 --- a/integrationtest/fixtures/terraform-module-upgrade/fake-provision.tf +++ b/integrationtest/fixtures/terraform-module-upgrade/fake-provision.tf @@ -1,4 +1,10 @@ -provider "random" { } +terraform { + required_providers { + random = { + source = "registry.terraform.io/hashicorp/random" + } + } +} resource "random_password" "password" { length = 5 diff --git a/integrationtest/fixtures/terraform-rename-provider/fake-provision.tf b/integrationtest/fixtures/terraform-rename-provider/fake-provision.tf index a0e2b6d3d..f4a462069 100644 --- a/integrationtest/fixtures/terraform-rename-provider/fake-provision.tf +++ b/integrationtest/fixtures/terraform-rename-provider/fake-provision.tf @@ -1,7 +1,7 @@ terraform { required_providers { random = { - source = "ContentSquare/random" + source = "registry.terraform.io/ContentSquare/random" version = "3.1.0" } } diff --git a/integrationtest/fixtures/terraform-upgrade-updated/fake-bind.tf b/integrationtest/fixtures/terraform-upgrade-updated/fake-bind.tf index f1a26f231..b110440d3 100644 --- a/integrationtest/fixtures/terraform-upgrade-updated/fake-bind.tf +++ b/integrationtest/fixtures/terraform-upgrade-updated/fake-bind.tf @@ -1,7 +1,7 @@ terraform { required_providers { random = { - source = "hashicorp/random" + source = "registry.terraform.io/hashicorp/random" version = "3.5.1" } } diff --git a/integrationtest/fixtures/terraform-upgrade-updated/fake-provision.tf b/integrationtest/fixtures/terraform-upgrade-updated/fake-provision.tf index 333608861..de374db86 100644 --- a/integrationtest/fixtures/terraform-upgrade-updated/fake-provision.tf +++ b/integrationtest/fixtures/terraform-upgrade-updated/fake-provision.tf @@ -1,7 +1,7 @@ terraform { required_providers { random = { - source = "hashicorp/random" + source = "registry.terraform.io/hashicorp/random" version = "3.5.1" } } diff --git a/integrationtest/fixtures/terraform-upgrade/fake-bind.tf b/integrationtest/fixtures/terraform-upgrade/fake-bind.tf index 6e2687d35..0ef2520a4 100644 --- a/integrationtest/fixtures/terraform-upgrade/fake-bind.tf +++ b/integrationtest/fixtures/terraform-upgrade/fake-bind.tf @@ -1,4 +1,10 @@ -provider "random" { } +terraform { + required_providers { + random = { + source = "registry.terraform.io/hashicorp/random" + } + } +} resource "random_integer" "priority" { min = 1 diff --git a/integrationtest/fixtures/terraform-upgrade/fake-provision.tf b/integrationtest/fixtures/terraform-upgrade/fake-provision.tf index 6e2687d35..0ef2520a4 100644 --- a/integrationtest/fixtures/terraform-upgrade/fake-provision.tf +++ b/integrationtest/fixtures/terraform-upgrade/fake-provision.tf @@ -1,4 +1,10 @@ -provider "random" { } +terraform { + required_providers { + random = { + source = "registry.terraform.io/hashicorp/random" + } + } +} resource "random_integer" "priority" { min = 1 diff --git a/integrationtest/fixtures/tf_attribute_skip/fake-provision.tf b/integrationtest/fixtures/tf_attribute_skip/fake-provision.tf index 2cd10bf80..145b86a3e 100644 --- a/integrationtest/fixtures/tf_attribute_skip/fake-provision.tf +++ b/integrationtest/fixtures/tf_attribute_skip/fake-provision.tf @@ -1,15 +1,5 @@ ## new versions of terraform fail with a different error to the one we want to trigger if this file is empty. ## adding some dummy terraform to test errors when a particular field is not present. - -terraform { - required_providers { - random = { - source = "hashicorp/random" - version = "3.5.1" - } - } -} - resource "random_integer" "priority" { min = 3 max = 4 diff --git a/integrationtest/fixtures/tf_attribute_skip/fake-service.yml b/integrationtest/fixtures/tf_attribute_skip/fake-service.yml index 15d9be5d2..ea3756800 100644 --- a/integrationtest/fixtures/tf_attribute_skip/fake-service.yml +++ b/integrationtest/fixtures/tf_attribute_skip/fake-service.yml @@ -20,6 +20,7 @@ plans: provision: template_refs: main: fake-provision.tf + versions: versions.tf user_inputs: - field_name: skip type: boolean diff --git a/integrationtest/fixtures/tf_attribute_skip/versions.tf b/integrationtest/fixtures/tf_attribute_skip/versions.tf new file mode 100644 index 000000000..577c5f6b9 --- /dev/null +++ b/integrationtest/fixtures/tf_attribute_skip/versions.tf @@ -0,0 +1,8 @@ +terraform { + required_providers { + random = { + source = "registry.terraform.io/hashicorp/random" + version = "3.5.1" + } + } +} diff --git a/integrationtest/subsume_test.go b/integrationtest/subsume_test.go index 997a89ade..7bdc463f5 100644 --- a/integrationtest/subsume_test.go +++ b/integrationtest/subsume_test.go @@ -31,7 +31,8 @@ var _ = Describe("Subsume", func() { It("can subsume a resource", func() { const serviceOfferingGUID = "547cad88-fa93-11eb-9f44-97feefe52547" const servicePlanGUID = "59624c68-fa93-11eb-9081-e79b0e1ab5ae" - broker.Provision(serviceOfferingGUID, servicePlanGUID, testdrive.WithProvisionParams(`{"value":"a97fd57a-fa94-11eb-8256-930255607a99"}`)) + _, err := broker.Provision(serviceOfferingGUID, servicePlanGUID, testdrive.WithProvisionParams(`{"value":"a97fd57a-fa94-11eb-8256-930255607a99"}`)) + Expect(err).NotTo(HaveOccurred()) }) It("cancels a subsume operation when a resource would be deleted", func() { diff --git a/internal/brokerpak/manifest/parser_test.go b/internal/brokerpak/manifest/parser_test.go index e4a66b246..2394658dc 100644 --- a/internal/brokerpak/manifest/parser_test.go +++ b/internal/brokerpak/manifest/parser_test.go @@ -320,9 +320,9 @@ var _ = Describe("Parser", func() { Expect(err).NotTo(HaveOccurred()) Expect(m.TerraformProviders[1].Provider.String()).To(Equal(expected)) }, - Entry("empty 'provider' field", "", "registry.opentofu.org/hashicorp/foo"), - Entry("just type", "lala", "registry.opentofu.org/hashicorp/lala"), - Entry("type and namespace", "mycorp/lala", "registry.opentofu.org/mycorp/lala"), + Entry("empty 'provider' field", "", "registry.terraform.io/hashicorp/foo"), + Entry("just type", "lala", "registry.terraform.io/hashicorp/lala"), + Entry("type and namespace", "mycorp/lala", "registry.terraform.io/mycorp/lala"), Entry("fully qualified", "mything.io/mycorp/lala", "mything.io/mycorp/lala"), ) diff --git a/internal/brokerpak/reader/reader.go b/internal/brokerpak/reader/reader.go index d4373d5e7..e9fa35796 100644 --- a/internal/brokerpak/reader/reader.go +++ b/internal/brokerpak/reader/reader.go @@ -19,6 +19,7 @@ import ( "archive/zip" "fmt" "io" + "log" "os" "path" "path/filepath" @@ -268,6 +269,11 @@ func (pak *BrokerPakReader) readBytes(name string) ([]byte, error) { func providerInstallPath(destination string, tfProvider manifest.TerraformProvider) string { plat := platform.CurrentPlatform() + log.Println("ProviderInstallPath:", filepath.Join( + destination, + tfProvider.Provider.String(), + tfProvider.Version.String(), + fmt.Sprintf("%s_%s", plat.Os, plat.Arch))) return filepath.Join( destination, tfProvider.Provider.String(), diff --git a/internal/brokerpak/reader/reader_test.go b/internal/brokerpak/reader/reader_test.go index d0dfee1f1..363884c72 100644 --- a/internal/brokerpak/reader/reader_test.go +++ b/internal/brokerpak/reader/reader_test.go @@ -35,6 +35,7 @@ var _ = Describe("reader", func() { withTerraform(binaryV160), withProvider("", "terraform-provider-google-beta", "1.19.0", "x4"), withProvider("other-namespace/google", "terraform-provider-google", "1.19.0", "x5"), + withProvider("custom.registry.org/other-namespace/custom", "terraform-provider-custom", "1.19.0", "x5"), ) pakReader, err := reader.OpenBrokerPak(pk) @@ -44,11 +45,15 @@ var _ = Describe("reader", func() { Expect(pakReader.ExtractPlatformBins(binOutput)).NotTo(HaveOccurred()) plat := fmt.Sprintf("%s_%s", runtime.GOOS, runtime.GOARCH) - hashicorpBinOutput := filepath.Join(binOutput, "registry.opentofu.org", "hashicorp") + hashicorpBinOutput := filepath.Join(binOutput, "registry.terraform.io", "hashicorp") Expect(filepath.Join(hashicorpBinOutput, "google-beta", "1.19.0", plat, "terraform-provider-google-beta_v1.19.0_x4")).To(BeAnExistingFile()) - otherNamespaceBinOutput := filepath.Join(binOutput, "registry.opentofu.org", "other-namespace") + otherNamespaceBinOutput := filepath.Join(binOutput, "registry.terraform.io", "other-namespace") Expect(filepath.Join(otherNamespaceBinOutput, "google", "1.19.0", plat, "terraform-provider-google_v1.19.0_x5")).To(BeAnExistingFile()) + + customDomainBinOutput := filepath.Join(binOutput, "custom.registry.org", "other-namespace") + Expect(filepath.Join(customDomainBinOutput, "custom", "1.19.0", plat, "terraform-provider-custom_v1.19.0_x5")).To(BeAnExistingFile()) + }) Context("single version of tofu", func() { diff --git a/internal/tfproviderfqn/tfproviderfqn.go b/internal/tfproviderfqn/tfproviderfqn.go index af01bd681..26ed9226d 100644 --- a/internal/tfproviderfqn/tfproviderfqn.go +++ b/internal/tfproviderfqn/tfproviderfqn.go @@ -5,7 +5,7 @@ import "fmt" const ( prefix = "terraform-provider-" - defaultRegistry = "registry.opentofu.org" + defaultRegistry = "registry.terraform.io" defaultNamespace = "hashicorp" ) diff --git a/internal/tfproviderfqn/tfproviderfqn_test.go b/internal/tfproviderfqn/tfproviderfqn_test.go index a5bc97d48..0959d951f 100644 --- a/internal/tfproviderfqn/tfproviderfqn_test.go +++ b/internal/tfproviderfqn/tfproviderfqn_test.go @@ -9,14 +9,14 @@ import ( "github.com/cloudfoundry/cloud-service-broker/internal/tfproviderfqn" ) -const defaultRegistrydomain = "registry.opentofu.org" +const defaultRegistryDomain = "registry.terraform.io" var _ = Describe("TfProviderFQN", func() { Context("from name", func() { It("can be created from a name", func() { n, err := tfproviderfqn.New("terraform-provider-mysql", "") Expect(err).NotTo(HaveOccurred()) - Expect(n.String()).To(Equal(fmt.Sprintf("%s/hashicorp/mysql", defaultRegistrydomain))) + Expect(n.String()).To(Equal(fmt.Sprintf("%s/hashicorp/mysql", defaultRegistryDomain))) }) When("the name has the wrong prefix", func() { @@ -32,13 +32,13 @@ var _ = Describe("TfProviderFQN", func() { It("can be created from the type", func() { n, err := tfproviderfqn.New("", "postgresql") Expect(err).NotTo(HaveOccurred()) - Expect(n.String()).To(Equal(fmt.Sprintf("%s/hashicorp/postgresql", defaultRegistrydomain))) + Expect(n.String()).To(Equal(fmt.Sprintf("%s/hashicorp/postgresql", defaultRegistryDomain))) }) It("can be created from the namespace and type", func() { n, err := tfproviderfqn.New("", "cyrilgdn/postgresql") Expect(err).NotTo(HaveOccurred()) - Expect(n.String()).To(Equal(fmt.Sprintf("%s/cyrilgdn/postgresql", defaultRegistrydomain))) + Expect(n.String()).To(Equal(fmt.Sprintf("%s/cyrilgdn/postgresql", defaultRegistryDomain))) }) It("can be created from the registry, namespace and type", func() { diff --git a/pkg/providers/tf/command/command.go b/pkg/providers/tf/command/command.go index 1e0aaf51c..ae1f32eb9 100644 --- a/pkg/providers/tf/command/command.go +++ b/pkg/providers/tf/command/command.go @@ -3,4 +3,5 @@ package command type TerraformCommand interface { Command() []string + Env() []string } diff --git a/pkg/providers/tf/command/terraform_command.go b/pkg/providers/tf/command/terraform_command.go index 37f5cb12b..accb176a3 100644 --- a/pkg/providers/tf/command/terraform_command.go +++ b/pkg/providers/tf/command/terraform_command.go @@ -16,11 +16,20 @@ func (cmd initCommand) Command() []string { return []string{"init", fmt.Sprintf("-plugin-dir=%s", cmd.pluginDir), "-no-color"} } +func (cmd initCommand) Env() []string { + return []string{} +} + type apply struct{} func NewApply() TerraformCommand { return apply{} } + +func (cmd apply) Env() []string { + return []string{} +} + func (apply) Command() []string { return []string{"apply", "-auto-approve", "-no-color"} } @@ -35,6 +44,10 @@ func (destroy) Command() []string { return []string{"destroy", "-auto-approve", "-no-color"} } +func (cmd destroy) Env() []string { + return []string{} +} + func NewShow() TerraformCommand { return show{} } @@ -45,6 +58,11 @@ func (show) Command() []string { return []string{"show", "-no-color"} } +func (cmd show) Env() []string { + // workaround for bug introduced by https://github.com/opentofu/opentofu/issues/1139 + return []string{"OPENTOFU_STATEFILE_PROVIDER_ADDRESS_TRANSLATION=0"} +} + func NewPlan() TerraformCommand { return plan{} } @@ -55,6 +73,10 @@ func (plan) Command() []string { return []string{"plan", "-no-color"} } +func (cmd plan) Env() []string { + return []string{} +} + func NewImport(addr, id string) TerraformCommand { return importCmd{Addr: addr, ID: id} } @@ -68,6 +90,10 @@ func (cmd importCmd) Command() []string { return []string{"import", cmd.Addr, cmd.ID} } +func (cmd importCmd) Env() []string { + return []string{} +} + type renameProvider struct { oldProviderName string newProviderName string @@ -80,3 +106,7 @@ func (cmd renameProvider) Command() []string { func NewRenameProvider(oldProviderName, newProviderName string) TerraformCommand { return renameProvider{oldProviderName: oldProviderName, newProviderName: newProviderName} } + +func (cmd renameProvider) Env() []string { + return []string{} +} diff --git a/pkg/providers/tf/command/terraform_command_test.go b/pkg/providers/tf/command/terraform_command_test.go index e124f54f2..6035fff91 100644 --- a/pkg/providers/tf/command/terraform_command_test.go +++ b/pkg/providers/tf/command/terraform_command_test.go @@ -11,20 +11,39 @@ var _ = Context("Terraform Commands", func() { It("calls init with the plugin directory", func() { initCommand := command.NewInit("plugindir") Expect(initCommand.Command()).To(Equal([]string{"init", "-plugin-dir=plugindir", "-no-color"})) + Expect(initCommand.Env()).To(BeEmpty()) }) }) Context("apply", func() { - It("calls init with the plugin directory", func() { + It("calls apply with the right options", func() { apply := command.NewApply() Expect(apply.Command()).To(Equal([]string{"apply", "-auto-approve", "-no-color"})) + Expect(apply.Env()).To(BeEmpty()) }) }) Context("Destroy", func() { - It("calls init with the plugin directory", func() { - apply := command.NewDestroy() - Expect(apply.Command()).To(Equal([]string{"destroy", "-auto-approve", "-no-color"})) + It("calls destroy with the right options", func() { + destroy := command.NewDestroy() + Expect(destroy.Command()).To(Equal([]string{"destroy", "-auto-approve", "-no-color"})) + Expect(destroy.Env()).To(BeEmpty()) + }) + }) + + Context("Show", func() { + It("calls show with the right env variables", func() { + show := command.NewShow() + Expect(show.Command()).To(Equal([]string{"show", "-no-color"})) + Expect(show.Env()).To(Equal([]string{"OPENTOFU_STATEFILE_PROVIDER_ADDRESS_TRANSLATION=0"})) + }) + }) + + Context("Plan", func() { + It("calls show with the right env variables", func() { + plan := command.NewPlan() + Expect(plan.Command()).To(Equal([]string{"plan", "-no-color"})) + Expect(plan.Env()).To(BeEmpty()) }) }) }) diff --git a/pkg/providers/tf/workspace/workspace.go b/pkg/providers/tf/workspace/workspace.go index 8b5b60aa6..d4e2da813 100644 --- a/pkg/providers/tf/workspace/workspace.go +++ b/pkg/providers/tf/workspace/workspace.go @@ -322,7 +322,7 @@ func (workspace *TerraformWorkspace) Execute(ctx context.Context, terraformExecu for _, cmd := range commands { c := exec.Command(binaryName, cmd.Command()...) - c.Env = os.Environ() + c.Env = append(os.Environ(), cmd.Env()...) c.Dir = workspace.dir lastExecutionOutput, err = terraformExecutor.Execute(ctx, c) diff --git a/pkg/providers/tf/workspace/workspace_test.go b/pkg/providers/tf/workspace/workspace_test.go index ae196c11a..1d01d19f5 100644 --- a/pkg/providers/tf/workspace/workspace_test.go +++ b/pkg/providers/tf/workspace/workspace_test.go @@ -213,6 +213,46 @@ func TestTerrafromWorkspace_StateTFVersion(t *testing.T) { }) } +func TestTerrafromWorkspace_Execute(t *testing.T) { + t.Parallel() + + t.Run("custom command env", func(t *testing.T) { + const definitionTfContents = "variable azure_tenant_id { type = string }" + ws, err := NewWorkspace(map[string]any{}, definitionTfContents, map[string]string{}, []ParameterMapping{}, []string{}, []ParameterMapping{}) + if err != nil { + t.Fatal(err) + } + + tExecutor := newTestExecutor(func(ctx context.Context, cmd *exec.Cmd) (executor.ExecutionOutput, error) { + if cmd.Env[len(cmd.Env)-1] != "OPENTOFU_STATEFILE_PROVIDER_ADDRESS_TRANSLATION=0" { + t.Fatalf("Custom command environment variable not set. Expected `OPENTOFU_STATEFILE_PROVIDER_ADDRESS_TRANSLATION=0` got %s", cmd.Env[len(cmd.Env)-1]) + } + return executor.ExecutionOutput{}, nil + }) + + ws.Execute(context.TODO(), tExecutor, command.NewShow()) + + }) + + t.Run("empty command env", func(t *testing.T) { + const definitionTfContents = "variable azure_tenant_id { type = string }" + ws, err := NewWorkspace(map[string]any{}, definitionTfContents, map[string]string{}, []ParameterMapping{}, []string{}, []ParameterMapping{}) + if err != nil { + t.Fatal(err) + } + + tExecutor := newTestExecutor(func(ctx context.Context, cmd *exec.Cmd) (executor.ExecutionOutput, error) { + if !reflect.DeepEqual(cmd.Env, os.Environ()) { + t.Fatalf("Unexpected env variable set. Expected %s got %s", os.Environ(), cmd.Env) + } + return executor.ExecutionOutput{}, nil + }) + + ws.Execute(context.TODO(), tExecutor, command.NewApply()) + + }) +} + func TestCustomEnvironmentExecutor(t *testing.T) { c := exec.Command("/path/to/terraform", "apply") c.Env = []string{"ORIGINAL=value"}