github.com/mponton/terratest@v0.44.0/modules/terraform/workspace.go (about) 1 package terraform 2 3 import ( 4 "fmt" 5 "regexp" 6 "strings" 7 8 "github.com/mponton/terratest/modules/testing" 9 "github.com/stretchr/testify/require" 10 ) 11 12 // WorkspaceSelectOrNew runs terraform workspace with the given options and the workspace name 13 // and returns a name of the current workspace. It tries to select a workspace with the given 14 // name, or it creates a new one if it doesn't exist. 15 func WorkspaceSelectOrNew(t testing.TestingT, options *Options, name string) string { 16 out, err := WorkspaceSelectOrNewE(t, options, name) 17 if err != nil { 18 t.Fatal(err) 19 } 20 return out 21 } 22 23 // WorkspaceSelectOrNewE runs terraform workspace with the given options and the workspace name 24 // and returns a name of the current workspace. It tries to select a workspace with the given 25 // name, or it creates a new one if it doesn't exist. 26 func WorkspaceSelectOrNewE(t testing.TestingT, options *Options, name string) (string, error) { 27 out, err := RunTerraformCommandE(t, options, "workspace", "list") 28 if err != nil { 29 return "", err 30 } 31 32 if isExistingWorkspace(out, name) { 33 _, err = RunTerraformCommandE(t, options, "workspace", "select", name) 34 } else { 35 _, err = RunTerraformCommandE(t, options, "workspace", "new", name) 36 } 37 if err != nil { 38 return "", err 39 } 40 41 return RunTerraformCommandE(t, options, "workspace", "show") 42 } 43 44 func isExistingWorkspace(out string, name string) bool { 45 workspaces := strings.Split(out, "\n") 46 for _, ws := range workspaces { 47 if nameMatchesWorkspace(name, ws) { 48 return true 49 } 50 } 51 return false 52 } 53 54 func nameMatchesWorkspace(name string, workspace string) bool { 55 // Regex for matching workspace should match for strings with optional leading asterisk "*" 56 // following optional white spaces following the workspace name. 57 // E.g. for the given name "terratest", following strings will match: 58 // 59 // "* terratest" 60 // " terratest" 61 match, _ := regexp.MatchString(fmt.Sprintf("^\\*?\\s*%s$", name), workspace) 62 return match 63 } 64 65 // WorkspaceDelete removes the specified terraform workspace with the given options. 66 // It returns the name of the current workspace AFTER deletion, and the returned error (that can be nil). 67 // If the workspace to delete is the current one, then it tries to switch to the "default" workspace. 68 // Deleting the workspace "default" is not supported. 69 func WorkspaceDeleteE(t testing.TestingT, options *Options, name string) (string, error) { 70 currentWorkspace, err := RunTerraformCommandE(t, options, "workspace", "show") 71 if err != nil { 72 return currentWorkspace, err 73 } 74 75 if name == "default" { 76 return currentWorkspace, &UnsupportedDefaultWorkspaceDeletion{} 77 } 78 79 out, err := RunTerraformCommandE(t, options, "workspace", "list") 80 if err != nil { 81 return currentWorkspace, err 82 } 83 if !isExistingWorkspace(out, name) { 84 return currentWorkspace, WorkspaceDoesNotExist(name) 85 } 86 87 // Switch workspace before deleting if it is the current 88 if currentWorkspace == name { 89 currentWorkspace, err = WorkspaceSelectOrNewE(t, options, "default") 90 if err != nil { 91 return currentWorkspace, err 92 } 93 } 94 95 // delete workspace 96 _, err = RunTerraformCommandE(t, options, "workspace", "delete", name) 97 98 return currentWorkspace, err 99 } 100 101 // WorkspaceDelete removes the specified terraform workspace with the given options. 102 // It returns the name of the current workspace AFTER deletion. 103 // If the workspace to delete is the current one, then it tries to switch to the "default" workspace. 104 // Deleting the workspace "default" is not supported and only return an empty string (to avoid a fatal error). 105 func WorkspaceDelete(t testing.TestingT, options *Options, name string) string { 106 out, err := WorkspaceDeleteE(t, options, name) 107 require.NoError(t, err) 108 return out 109 }