Skip to content

Commit

Permalink
handle opentofu output when cleaning up terraform logs (#1467)
Browse files Browse the repository at this point in the history
* handle opentofu output when cleaning up terraform logs
  • Loading branch information
motatoes authored May 15, 2024
1 parent 2a5b48e commit 9e87e41
Show file tree
Hide file tree
Showing 2 changed files with 141 additions and 7 deletions.
22 changes: 15 additions & 7 deletions cli/pkg/core/execution/execution.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package execution

import (
"fmt"
"github.com/samber/lo"
"log"
"os"
"path"
Expand Down Expand Up @@ -443,7 +444,7 @@ func (d DiggerExecutor) Destroy() (bool, error) {
}

func cleanupTerraformOutput(nonEmptyOutput bool, planError error, stdout string, stderr string, regexStr *string) string {
var errorStr, start string
var errorStr string

// removes output of terraform -version command that terraform-exec executes on every run
i := strings.Index(stdout, "Initializing the backend...")
Expand All @@ -459,14 +460,21 @@ func cleanupTerraformOutput(nonEmptyOutput bool, planError error, stdout string,
errorStr = stdout
}
return errorStr
} else if nonEmptyOutput {
start = "Terraform will perform the following actions:"
} else {
start = "No changes. Your infrastructure matches the digger_config."
}

startPos := strings.Index(stdout, start)
if startPos == -1 {
delimiters := []string{
"Terraform will perform the following actions:",
"OpenTofu will perform the following actions:",
"No changes. Your infrastructure matches the configuration.",
}
indices := lo.FilterMap(delimiters, func(delimiter string, i int) (int, bool) {
index := strings.Index(stdout, delimiter)
return index, index > 0
})
var startPos int
if len(indices) > 0 {
startPos = indices[0]
} else {
startPos = 0
}

Expand Down
126 changes: 126 additions & 0 deletions cli/pkg/core/execution/execution_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,129 @@ Plan: 2 to add, 0 to change, 0 to destroy.
index := strings.Index(stdout, "Terraform will perform the following actions:")
assert.Equal(t, stdout[index:], res)
}

func TestCorrectCleanUpWithOpenTofuPlan(t *testing.T) {
stdout := `
Initializing the backend...
Initializing modules...
Initializing provider plugins...
- Reusing previous version of hashicorp/helm from the dependency lock file
- Reusing previous version of hashicorp/google-beta from the dependency lock file
- Reusing previous version of ns1-terraform/ns1 from the dependency lock file
- Reusing previous version of hashicorp/google from the dependency lock file
- Reusing previous version of hashicorp/time from the dependency lock file
- Reusing previous version of hashicorp/random from the dependency lock file
- Reusing previous version of integrations/github from the dependency lock file
- Reusing previous version of hashicorp/kubernetes from the dependency lock file
- Reusing previous version of hashicorp/tls from the dependency lock file
- Reusing previous version of hashicorp/vault from the dependency lock file
- Using previously-installed hashicorp/helm v2.10.1
- Using previously-installed ns1-terraform/ns1 v2.0.3
- Using previously-installed hashicorp/google v5.11.0
- Using previously-installed hashicorp/time v0.9.1
- Using previously-installed hashicorp/random v3.5.1
- Using previously-installed hashicorp/vault v3.15.2
- Using previously-installed hashicorp/google-beta v5.11.0
- Using previously-installed integrations/github v5.26.0
- Using previously-installed hashicorp/kubernetes v2.21.0
- Using previously-installed hashicorp/tls v4.0.4
OpenTofu has been successfully initialized!
data.vault_generic_secret.ns1_api_key_terraform: Reading...
data.vault_generic_secret.github_token: Reading...
data.vault_generic_secret.ns1_api_key_terraform: Read complete after 0s [id=zon/v1/ns1/api/terraform]
data.vault_generic_secret.github_token: Read complete after 0s [id=zon/v1/github/terraform/api-token]
data.google_project.project: Reading...
data.google_client_config.this: Reading...
module.infra_data.data.google_client_config.this: Reading...
module.infra_data.data.google_project.this: Reading...
data.google_client_config.this: Read complete after 1s [id=projects/"xxx"/regions/"europe-west3"/zones/"europe-west3-a"]
module.infra_data.data.google_client_config.this: Read complete after 1s [id=projects/"xxx"/regions/"europe-west3"/zones/"europe-west3-a"]
data.google_project.project: Read complete after 1s [id=projects/xxx]
module.infra_data.data.google_project.this: Read complete after 2s [id=projects/xxx]
module.infra_data.data.vault_kv_secrets_list.cloudsql_instances[0]: Reading...
module.infra_data.data.google_project.gke: Reading...
module.infra_data.data.vault_kv_secrets_list.cloudsql_instances[0]: Read complete after 0s [id=zon/v1/gcp/xxx/cloudsql/instances]
module.infra_data.data.google_sql_database_instance.this["xxx"]: Reading...
module.infra_data.data.google_sql_database_instance.this["xxx"]: Reading...
module.infra_data.data.google_sql_database_instance.this["xxx"]: Reading...
module.infra_data.data.google_sql_database_instance.this["xxx"]: Reading...
module.infra_data.data.google_sql_database_instance.this["xxx"]: Reading...
module.infra_data.data.google_sql_database_instance.this["xxx"]: Reading...
module.infra_data.data.google_sql_database_instance.this["xxx"]: Reading...
module.infra_data.data.google_sql_database_instance.this["xxx"]: Reading...
module.infra_data.data.google_sql_database_instance.this["xxx"]: Reading...
module.infra_data.data.google_sql_database_instance.this["xxx"]: Read complete after 0s [id=main-staging-pg14]
module.infra_data.data.google_sql_database_instance.this["xxx"]: Reading...
module.infra_data.data.google_sql_database_instance.this["xxx"]: Read complete after 0s [id=main-production-vivi-internal]
module.infra_data.data.google_sql_database_instance.this["xxx"]: Read complete after 0s [id=staging-9f9d9107]
module.infra_data.data.google_sql_database_instance.this["xxx"]: Read complete after 0s [id=devel-26e8a66a]
module.infra_data.data.google_sql_database_instance.this["xxx"]: Read complete after 0s [id=production-a31270fe]
module.infra_data.data.google_sql_database_instance.this["xxx"]: Reading...
module.infra_data.data.google_sql_database_instance.this["xxx"]: Reading...
module.infra_data.data.google_sql_database_instance.this["xxx"]: Read complete after 0s [id=main-production-pg14-rr]
module.infra_data.data.google_sql_database_instance.this["xxx"]: Read complete after 0s [id=production-pg13]
module.infra_data.data.google_sql_database_instance.this["xxx"]: Read complete after 0s [id=main-staging-pg15]
module.infra_data.data.google_sql_database_instance.this["xxx"]: Read complete after 0s [id=main-production-pg14]
module.infra_data.data.google_sql_database_instance.this["xxx"]: Read complete after 0s [id=main-devel-pg15]
module.infra_data.data.google_sql_database_instance.this["xxx"]: Read complete after 0s [id=main-devel-pg14]
module.infra_data.data.google_sql_database_instance.this["xxx"]: Read complete after 0s [id=staging-pg13]
module.infra_data.data.vault_generic_secret.cloudsql_credentials["xxx"]: Reading...
module.infra_data.data.vault_generic_secret.cloudsql_credentials["xxx"]: Reading...
module.infra_data.data.vault_generic_secret.cloudsql_credentials["xxx"]: Reading...
module.infra_data.data.vault_generic_secret.cloudsql_credentials["xxx"]: Reading...
module.infra_data.data.vault_generic_secret.cloudsql_credentials["xxx"]: Reading...
module.infra_data.data.vault_generic_secret.cloudsql_credentials["xxx"]: Reading...
module.infra_data.data.vault_generic_secret.cloudsql_credentials["xxx"]: Reading...
module.infra_data.data.vault_generic_secret.cloudsql_credentials["xxx"]: Read complete after 0s [id=zon/v1/gcp/xxx/cloudsql/instances/staging-pg13/instance-credentials]
module.infra_data.data.vault_generic_secret.cloudsql_credentials["xxx"]: Reading...
module.infra_data.data.vault_generic_secret.cloudsql_credentials["xxx"]: Read complete after 0s [id=zon/v1/gcp/xxx/cloudsql/instances/main-devel-pg15/instance-credentials]
module.infra_data.data.vault_generic_secret.cloudsql_credentials["xxx"]: Reading...
module.infra_data.data.vault_generic_secret.cloudsql_credentials["xxx"]: Read complete after 0s [id=zon/v1/gcp/xxx/cloudsql/instances/main-production-pg14-rr/instance-credentials]
module.infra_data.data.vault_generic_secret.cloudsql_credentials["xxx"]: Read complete after 0s [id=zon/v1/gcp/xxx/cloudsql/instances/staging-9f9d9107/instance-credentials]
module.infra_data.data.vault_generic_secret.cloudsql_credentials["xxx"]: Read complete after 0s [id=zon/v1/gcp/xxx/cloudsql/instances/devel-26e8a66a/instance-credentials]
module.infra_data.data.vault_generic_secret.cloudsql_credentials["xxx"]: Read complete after 0s [id=zon/v1/gcp/xxx/cloudsql/instances/main-devel-pg14/instance-credentials]
module.infra_data.data.vault_generic_secret.cloudsql_credentials["xxx"]: Read complete after 0s [id=zon/v1/gcp/xxx/cloudsql/instances/main-production-pg14/instance-credentials]
module.infra_data.data.vault_generic_secret.cloudsql_credentials["xxx"]: Read complete after 0s [id=zon/v1/gcp/xxx/cloudsql/instances/main-staging-pg15/instance-credentials]
module.infra_data.data.vault_generic_secret.cloudsql_credentials["xxx"]: Read complete after 0s [id=zon/v1/gcp/xxx/cloudsql/instances/production-a31270fe/instance-credentials]
module.infra_data.data.vault_generic_secret.cloudsql_credentials["xxx"]: Reading...
module.infra_data.data.vault_generic_secret.cloudsql_credentials["xxx"]: Reading...
module.infra_data.data.vault_generic_secret.cloudsql_credentials["xxx"]: Reading...
module.infra_data.data.vault_generic_secret.cloudsql_credentials["xxx"]: Read complete after 0s [id=zon/v1/gcp/xxx/cloudsql/instances/main-production-vivi-internal/instance-credentials]
module.infra_data.data.vault_generic_secret.cloudsql_credentials["xxx"]: Read complete after 0s [id=zon/v1/gcp/xxx/cloudsql/instances/production-pg13/instance-credentials]
module.infra_data.data.vault_generic_secret.cloudsql_credentials["xxx"]: Read complete after 0s [id=zon/v1/gcp/xxx/cloudsql/instances/main-staging-pg14/instance-credentials]
module.infra_data.data.google_project.gke: Read complete after 0s [id=projects/xxx]
module.infra_data.data.vault_generic_secret.cluster_credentials[0]: Reading...
module.infra_data.data.vault_generic_secret.cluster_credentials[0]: Read complete after 0s [id=zon/v1/gcp/xxx/gke/staging/cluster_credentials]
OpenTofu used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
+ create
OpenTofu will perform the following actions:
# google_storage_bucket.test1 will be created
+ resource "google_storage_bucket" "test1" {
+ effective_labels = {
+ "creator" = "terraform"
}
+ force_destroy = false
+ id = (known after apply)
+ labels = {
+ "creator" = "terraform"
}
+ location = "EUROPE-WEST3"
+ name = "digger-poc-staging-test1"
+ project = (known after apply)
+ public_access_prevention = (known after apply)
+ rpo = (known after apply)
+ self_link = (known after apply)
+ storage_class = "STANDARD"
+ terraform_labels = {
+ "creator" = "terraform"
}
+ uniform_bucket_level_access = true
+ url = (known after apply)
}
Plan: 1 to add, 0 to change, 0 to destroy.
`
res := cleanupTerraformPlan(true, nil, stdout, "")
index := strings.Index(stdout, "OpenTofu will perform the following actions:")
assert.Equal(t, stdout[index:], res)
}

0 comments on commit 9e87e41

Please sign in to comment.