Fix metadata computation for empty bundle (#939)

## Changes
This PR fixes metadata computation for empty bundle. Before we would
error because the `terraform.Load()` mutator errors on a empty / no
state file.

## Tests
Failing integration tests now pass.
This commit is contained in:
shreyas-goenka 2023-11-02 12:00:30 +01:00 committed by GitHub
parent d70d7445c4
commit b6aa4631f1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 23 additions and 8 deletions

View File

@ -213,6 +213,11 @@ func BundleToTerraform(config *config.Root) *schema.Root {
} }
func TerraformToBundle(state *tfjson.State, config *config.Root) error { func TerraformToBundle(state *tfjson.State, config *config.Root) error {
// This is a no-op if the state is empty.
if state.Values == nil || state.Values.RootModule == nil {
return nil
}
for _, resource := range state.Values.RootModule.Resources { for _, resource := range state.Values.RootModule.Resources {
// Limit to resources. // Limit to resources.
if resource.Mode != tfjson.ManagedResourceMode { if resource.Mode != tfjson.ManagedResourceMode {

View File

@ -3,13 +3,20 @@ package terraform
import ( import (
"context" "context"
"fmt" "fmt"
"slices"
"github.com/databricks/cli/bundle" "github.com/databricks/cli/bundle"
"github.com/hashicorp/terraform-exec/tfexec" "github.com/hashicorp/terraform-exec/tfexec"
tfjson "github.com/hashicorp/terraform-json" tfjson "github.com/hashicorp/terraform-json"
) )
type load struct{} type loadMode int
const ErrorOnEmptyState loadMode = 0
type load struct {
modes []loadMode
}
func (l *load) Name() string { func (l *load) Name() string {
return "terraform.Load" return "terraform.Load"
@ -31,7 +38,7 @@ func (l *load) Apply(ctx context.Context, b *bundle.Bundle) error {
return err return err
} }
err = ValidateState(state) err = l.validateState(state)
if err != nil { if err != nil {
return err return err
} }
@ -45,10 +52,13 @@ func (l *load) Apply(ctx context.Context, b *bundle.Bundle) error {
return nil return nil
} }
func ValidateState(state *tfjson.State) error { func (l *load) validateState(state *tfjson.State) error {
if state.Values == nil { if state.Values == nil {
if slices.Contains(l.modes, ErrorOnEmptyState) {
return fmt.Errorf("no deployment state. Did you forget to run 'databricks bundle deploy'?") return fmt.Errorf("no deployment state. Did you forget to run 'databricks bundle deploy'?")
} }
return nil
}
if state.Values.RootModule == nil { if state.Values.RootModule == nil {
return fmt.Errorf("malformed terraform state: RootModule not set") return fmt.Errorf("malformed terraform state: RootModule not set")
@ -57,6 +67,6 @@ func ValidateState(state *tfjson.State) error {
return nil return nil
} }
func Load() bundle.Mutator { func Load(modes ...loadMode) bundle.Mutator {
return &load{} return &load{modes: modes}
} }

View File

@ -34,7 +34,7 @@ func TestLoadWithNoState(t *testing.T) {
err = bundle.Apply(context.Background(), b, bundle.Seq( err = bundle.Apply(context.Background(), b, bundle.Seq(
Initialize(), Initialize(),
Load(), Load(ErrorOnEmptyState),
)) ))
require.ErrorContains(t, err, "Did you forget to run 'databricks bundle deploy'") require.ErrorContains(t, err, "Did you forget to run 'databricks bundle deploy'")

View File

@ -38,7 +38,7 @@ func newRunCommand() *cobra.Command {
terraform.Interpolate(), terraform.Interpolate(),
terraform.Write(), terraform.Write(),
terraform.StatePull(), terraform.StatePull(),
terraform.Load(), terraform.Load(terraform.ErrorOnEmptyState),
)) ))
if err != nil { if err != nil {
return err return err