diff --git a/errors.go b/errors.go index f896c8b95..91f4b92f9 100644 --- a/errors.go +++ b/errors.go @@ -6,10 +6,10 @@ import ( // Generic errors applicable to all resources. var ( - // ErrUnauthorized is returned when a receiving a 401. + // ErrUnauthorized is returned when receiving a 401. ErrUnauthorized = errors.New("unauthorized") - // ErrResourceNotFound is returned when a receiving a 404. + // ErrResourceNotFound is returned when receiving a 404. ErrResourceNotFound = errors.New("resource not found") // ErrRequiredName is returned when a name option is not present. diff --git a/run.go b/run.go index 690d672d1..c7a21760e 100644 --- a/run.go +++ b/run.go @@ -106,6 +106,7 @@ type Run struct { Status RunStatus `jsonapi:"attr,status"` StatusTimestamps *RunStatusTimestamps `jsonapi:"attr,status-timestamps"` TargetAddrs []string `jsonapi:"attr,target-addrs,omitempty"` + Variables []*RunVariable `jsonapi:"attr,variables"` // Relations Apply *Apply `jsonapi:"relation,apply"` @@ -164,6 +165,14 @@ type RunListOptions struct { Include *string `url:"include"` } +// RunVariable represents a variable that can be applied to a run. All values must be expressed as an HCL literal +// in the same syntax you would use when writing terraform code. See https://www.terraform.io/docs/language/expressions/types.html#types +// for more details. +type RunVariable struct { + Key string `jsonapi:"attr,key"` + Value string `jsonapi:"attr,value"` +} + // List all the runs of the given workspace. func (s *runs) List(ctx context.Context, workspaceID string, options RunListOptions) (*RunList, error) { if !validStringID(&workspaceID) { @@ -237,6 +246,10 @@ type RunCreateOptions struct { // AutoApply determines if the run should be applied automatically without // user confirmation. It defaults to the Workspace.AutoApply setting. AutoApply *bool `jsonapi:"attr,auto-apply,omitempty"` + + // RunVariables allows you to specify terraform input variables for + // a particular run, prioritized over variables defined on the workspace. + Variables []*RunVariable `jsonapi:"attr,variables,omitempty"` } func (o RunCreateOptions) valid() error { diff --git a/run_integration_test.go b/run_integration_test.go index d093ece67..2dcb8b806 100644 --- a/run_integration_test.go +++ b/run_integration_test.go @@ -180,6 +180,41 @@ func TestRunsCreate(t *testing.T) { assert.Equal(t, *options.Refresh, r.Refresh) assert.Equal(t, options.ReplaceAddrs, r.ReplaceAddrs) assert.Equal(t, options.TargetAddrs, r.TargetAddrs) + assert.Nil(t, r.Variables) + }) + + t.Run("with variables", func(t *testing.T) { + vars := []*RunVariable{ + { + Key: "test_variable", + Value: "Hello, World!", + }, + { + Key: "test_foo", + Value: "Hello, Foo!", + }, + } + + options := RunCreateOptions{ + Message: String("yo"), + Workspace: wTest, + Variables: vars, + } + + r, err := client.Runs.Create(ctx, options) + require.NoError(t, err) + assert.NotNil(t, r.Variables) + assert.Equal(t, len(vars), len(r.Variables)) + + for _, v := range r.Variables { + if v.Key == "test_foo" { + assert.Equal(t, v.Value, "Hello, Foo!") + } else if v.Key == "test_variable" { + assert.Equal(t, v.Value, "Hello, World!") + } else { + t.Fatalf("Unexpected variable key: %s", v.Key) + } + } }) }