Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to create workspace (wrong VCS settings marshal) #202

Closed
SkYNewZ opened this issue Apr 9, 2021 · 5 comments
Closed

Unable to create workspace (wrong VCS settings marshal) #202

SkYNewZ opened this issue Apr 9, 2021 · 5 comments

Comments

@SkYNewZ
Copy link

SkYNewZ commented Apr 9, 2021

I'm unable to create a workspace with VCS settings: missing required vcs creation params
Simple code snippet:

package main

import (
	"context"
	"github.com/hashicorp/go-tfe"
	"log"
)

func main() {
	client, err := tfe.NewClient(&tfe.Config{Token: "[redacted]"})
	if err != nil {
		log.Fatalln(err)
	}

	_, err = client.Workspaces.Create(context.Background(), "[redacted]", tfe.WorkspaceCreateOptions{
		AllowDestroyPlan:     tfe.Bool(true),
		AutoApply:            tfe.Bool(true),
		Description:          tfe.String("testing"),
		ExecutionMode:        tfe.String("remote"),
		MigrationEnvironment: nil,
		Name:                 tfe.String("quentin-testing-go-tfe"),
		TerraformVersion:     tfe.String("0.14.7"),
		VCSRepo:              &tfe.VCSRepoOptions{
			Branch:            tfe.String("master"),
			Identifier:        tfe.String("[redacted]"),
			OAuthTokenID:      tfe.String("[redacted]"),
			IngressSubmodules:  tfe.Bool(false),
		},
	})

	log.Fatalln(err)
}

Digging into the code, I think the error comes from jsonapi which does not marshal nested objects (and here the VCSRepo object).

I have reproduced https://github.com/hashicorp/go-tfe/blob/master/tfe.go#L551

package main

import (
	"fmt"
	"github.com/hashicorp/go-tfe"
	"github.com/hashicorp/jsonapi"
	"os"
)

func main() {
	onlyVCSSettings := &tfe.VCSRepoOptions{
		Branch:            tfe.String("master"),
		Identifier:        tfe.String("[redacted]"),
		OAuthTokenID:      tfe.String("[redacted]"),
		IngressSubmodules:  tfe.Bool(false),
	}

	entireObject := &tfe.WorkspaceCreateOptions{
		AllowDestroyPlan:     tfe.Bool(true),
		AutoApply:            tfe.Bool(true),
		Description:          tfe.String("testing"),
		ExecutionMode:        tfe.String("remote"),
		MigrationEnvironment: nil,
		Name:                 tfe.String("quentin-testing-go-tfe"),
		TerraformVersion:     tfe.String("0.14.7"),
		VCSRepo:              onlyVCSSettings,
	}

	_ = jsonapi.MarshalPayloadWithoutIncluded(os.Stdout, onlyVCSSettings)
	fmt.Println("----------")
	_ = jsonapi.MarshalPayloadWithoutIncluded(os.Stdout, entireObject)
}

Outputs:

{"data":{"type":"","attributes":{"branch":"master","identifier":"[redacted]","ingress-submodules":false,"oauth-token-id":"[redacted]"}}}
----------
{"data":{"type":"workspaces","attributes":{"allow-destroy-plan":true,"auto-apply":true,"description":"testing","execution-mode":"remote","name":"quentin-testing-go-tfe","terraform-version":"0.14.7","vcs-repo":{"Branch":"master","Identifier":"[redacted]","IngressSubmodules":false,"OAuthTokenID":"[redacted]"}}}}
@omarismail
Copy link
Contributor

Thanks for the issue submission @SkYNewZ , we'll take a look at this and fix it!

@SkYNewZ
Copy link
Author

SkYNewZ commented Apr 9, 2021

I'm currently using go-tfe v0.13.1

@SkYNewZ
Copy link
Author

SkYNewZ commented Apr 9, 2021

I have made to simple files to test and reproduce this issue without any link to go-tfe:

main.go
// main.go
package main

import (
	"bytes"

	"github.com/google/jsonapi"
)

// Nested describes a nested object
type Nested struct {
	Name *string `jsonapi:"attr,name"`
}

// Object is the main example object
type Object struct {
	Type         string  `jsonapi:"primary,object"`
	Color        *string `jsonapi:"attr,color"`
	Enable       *bool   `jsonapi:"attr,enable"`
	NestedObject *Nested `jsonapi:"attr,nested-object"`
}

func MarshalNestedObject() (string, error) {
	n := new(Nested)
	n.Name = toStringPtr("foo")

	var b bytes.Buffer
	err := jsonapi.MarshalPayload(&b, n)
	return b.String(), err
}

func MarshalObject() (string, error) {
	n := new(Nested)
	n.Name = toStringPtr("foo")

	o := &Object{
		Color:        toStringPtr("blue"),
		Enable:       toBoolPtr(true),
		NestedObject: n,
	}

	var b bytes.Buffer
	err := jsonapi.MarshalPayload(&b, o)
	return b.String(), err
}

func toStringPtr(in string) (out *string) {
	out = &in
	return
}

func toBoolPtr(in bool) (out *bool) {
	out = &in
	return
}
main_test.go
// main_test.go
package main

import (
	"reflect"
	"testing"
)

func TestMarshalNestedObject(t *testing.T) {
	tests := []struct {
		name    string
		want    string
		wantErr bool
	}{
		{
			name: "expected",
			want: `{"data":{"type":"","attributes":{"name":"foo"}}}
`,
			wantErr: false,
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			got, err := MarshalNestedObject()
			if (err != nil) != tt.wantErr {
				t.Errorf("MarshalNestedObject() error = %v, wantErr %v", err, tt.wantErr)
				return
			}
			if !reflect.DeepEqual(got, tt.want) {
				t.Errorf("MarshalNestedObject() got = %v, want %v", got, tt.want)
			}
		})
	}
}

func TestMarshalObject(t *testing.T) {
	tests := []struct {
		name    string
		want    string
		wantErr bool
	}{
		{
			name: "expected",
			want: `{"data":{"type":"object","attributes":{"color":"blue","enable":true,"nested-object":{"name":"foo"}}}}
`,
			wantErr: false,
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			got, err := MarshalObject()
			if (err != nil) != tt.wantErr {
				t.Errorf("MarshalObject() error = %v, wantErr %v", err, tt.wantErr)
				return
			}

			if !reflect.DeepEqual(got, tt.want) {
				t.Errorf("MarshalObject() got = %v, want %v", got, tt.want)
			}
		})
	}
}

@SkYNewZ
Copy link
Author

SkYNewZ commented Apr 12, 2021

Hello! Commit 094a293 from @radditude fix my issue. Waiting to be on master

@radditude
Copy link
Member

radditude commented Apr 12, 2021

This should be fixed as of https://github.com/hashicorp/go-tfe/releases/tag/v0.13.2 - thank you for reporting and for the detailed repro!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants