Giter VIP home page Giter VIP logo

go-tfe's Introduction

HCP Terraform and Terraform Enterprise Go Client

Tests GitHub license GoDoc Go Report Card GitHub issues

The official Go API client for HCP Terraform and Terraform Enterprise.

This client supports the HCP Terraform V2 API. As Terraform Enterprise is a self-hosted distribution of HCP Terraform, this client supports both HCP Terraform and Terraform Enterprise use cases. In all package documentation and API, the platform will always be stated as 'Terraform Enterprise' - but a feature will be explicitly noted as only supported in one or the other, if applicable (rare).

Version Information

Almost always, minor version changes will indicate backwards-compatible features and enhancements. Occasionally, function signature changes that reflect a bug fix may appear as a minor version change. Patch version changes will be used for bug fixes, performance improvements, and otherwise unimpactful changes.

Example Usage

Construct a new TFE client, then use the various endpoints on the client to access different parts of the Terraform Enterprise API. The following example lists all organizations.

(Recommended Approach) Using custom config to provide configuration details to the API client

import (
  "context"
  "log"

  "github.com/hashicorp/go-tfe"
)

config := &tfe.Config{
	Address: "https://tfe.local",
	Token: "insert-your-token-here",
  RetryServerErrors: true,
}

client, err := tfe.NewClient(config)
if err != nil {
	log.Fatal(err)
}

orgs, err := client.Organizations.List(context.Background(), nil)
if err != nil {
	log.Fatal(err)
}

Using the default config with env vars

The default configuration makes use of the TFE_ADDRESS and TFE_TOKEN environment variables.

  1. TFE_ADDRESS - URL of a HCP Terraform or Terraform Enterprise instance. Example: https://tfe.local
  2. TFE_TOKEN - An API token for the HCP Terraform or Terraform Enterprise instance.

Note: Alternatively, you can set TFE_HOSTNAME which serves as a fallback for TFE_ADDRESS. It will only be used if TFE_ADDRESS is not set and will resolve the host to an https scheme. Example: tfe.local => resolves to https://tfe.local

The environment variables are used as a fallback to configure TFE client if the Address or Token values are not provided as in the cases below:

Using the default configuration

import (
  "context"
  "log"

  "github.com/hashicorp/go-tfe"
)

// Passing nil to tfe.NewClient method will also use the default configuration
client, err := tfe.NewClient(tfe.DefaultConfig())
if err != nil {
	log.Fatal(err)
}

orgs, err := client.Organizations.List(context.Background(), nil)
if err != nil {
	log.Fatal(err)
}

When Address or Token has no value

import (
  "context"
  "log"

  "github.com/hashicorp/go-tfe"
)

config := &tfe.Config{
	Address: "",
	Token: "",
}

client, err := tfe.NewClient(config)
if err != nil {
	log.Fatal(err)
}

orgs, err := client.Organizations.List(context.Background(), nil)
if err != nil {
	log.Fatal(err)
}

Documentation

For complete usage of the API client, see the full package docs.

API Coverage

This API client covers most of the existing HCP Terraform API calls and is updated regularly to add new or missing endpoints.

  • Account
  • Agents
  • Agent Pools
  • Agent Tokens
  • Applies
  • Audit Trails
  • Changelog
  • Comments
  • Configuration Versions
  • Cost Estimation
  • Feature Sets
  • Invoices
  • IP Ranges
  • Notification Configurations
  • OAuth Clients
  • OAuth Tokens
  • Organizations
  • Organization Memberships
  • Organization Tags
  • Organization Tokens
  • Plan Exports
  • Plans
  • Policies
  • Policy Checks
  • Policy Sets
  • Policy Set Parameters
  • Private Registry
    • Modules
      • No-Code Modules
    • Providers
    • Provider Versions and Platforms
    • GPG Keys
  • Projects
  • Runs
  • Run Events
  • Run Tasks
  • Run Tasks Integration
  • Run Triggers
  • SSH Keys
  • Stability Policy
  • State Versions
  • State Version Outputs
  • Subscriptions
  • Team Access
  • Team Membership
  • Team Tokens
  • Teams
  • Test Runs
  • User Tokens
  • Users
  • Variable Sets
  • Variables
  • VCS Events
  • Workspaces
  • Workspace-Specific Variables
  • Workspace Resources
  • Admin
    • Module Sharing
    • Organizations
    • Runs
    • Settings
    • Terraform Versions
    • OPA Versions
    • Sentinel Versions
    • Users
    • Workspaces

Examples

See the examples directory.

Running tests

See TESTS.md.

Issues and Contributing

See CONTRIBUTING.md

Releases

See RELEASES.md

go-tfe's People

Contributors

annawinkler avatar barrettclark avatar brandonc avatar byronwolfman avatar chrisarcand avatar ctrombley avatar davidcelis avatar dependabot[bot] avatar dsa0x avatar glennsarti avatar hashicorp-copywrite[bot] avatar hashimoon avatar hs26gill avatar jarrettspiker avatar juliannatetreault avatar lafentres avatar laurenolivia avatar maed223 avatar mpminardi avatar mrinalirao avatar mwudka avatar netramali avatar nfagerlund avatar omarismail avatar radditude avatar ryanuber avatar sebasslash avatar thrashr888 avatar uk1288 avatar uturunku1 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

go-tfe's Issues

Teams.List API does not support pagination

Teams List API does not support pagination
// List all the teams of the given organization.
List(ctx context.Context, organization string, options TeamListOptions) (*TeamList, error)

    client.Teams.List(ctx, tfeOrgName, gotfe.TeamListOptions{
		ListOptions: gotfe.ListOptions{
			PageNumber: 10,
			PageSize:   10,
		},

It always return all the teams under the organization, however the same pagination works for the workspace List API

Checksum mismatch

When I run go mod vendor I have the following error

go: verifying github.com/hashicorp/[email protected]: checksum mismatch
	downloaded: h1:gekvezBc+9LwN3qC+lesrz0Qg36hhgge9z/an1FCHx4=
	go.sum:     h1:MVdZAkTmDsUi1AT+3NQDsn8n3ssnVSIHwiM6RcUHvE8=

Runs.Create occasionally fails with "invalid run parameters"

Hi!

I've created an action that uses go-tfe to create new runs on Terraform Cloud as part of our delivery pipeline. This works pretty well, but the execution of Runs.Create fails occasionally with a fairly cryptic error Invalid Attribute: invalid run parameters

Error in the context of GitHub Actions ๐Ÿ‘‡

Screenshot 2020-04-23 at 00 28 23

You can find the exact code I'm using here: https://github.com/kvrhdn/tfe-run/blob/master/main.go#L68

I haven't been able to pinpoint anything that could cause this:

  • it happens both on speculative and non-speculative runs
  • it happens both on runs that have changes and runs that don't have
  • the error is always caused by Runs.Create, I haven't seen any other error messages
  • re-triggering the job sometimes works, but I've also seen it fail multiple times after each other (over a span of 15+ minutes)

So I've been pretty puzzled ๐Ÿ˜• Maybe you recognize the error and provide some pointers? Is there anything I can do to log more trace data?

Thanks!

Unable to create workspace (wrong VCS settings marshal)

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]"}}}}

Variables.List doesn't take Organization anymore?

Hello

Firstly, thanks for the great library.

I'm upgrading from an ancient go-tfe version and observed in the commit[0] the ability to pass in Organisation Name was removed. The API seem to still support this.

How can I do the following?

		variables, err := client.Variables.List(ctx, tfe.VariableListOptions{
			Organization: &w.Organization.Name,
			Workspace:    &WorkspaceName,
		})

I feel as if I'm missing something obvious here. But see the partial patch below, by the looks of it it simply seems it was dropped and workspaceID was passed in as a parameter to List, but not organisation name.

I'm happy to create a PR and add it as a parameter to List function, however, any particular reason why it's not part of VariableListOptions anymore?

I feel it's better suited there.

Kind regards
Sam

[0]

commit 3c08ccf4d60964869dba86d89a0eec8c8c92ed98

...
 type Variables interface {
 	// List all the variables associated with the given workspace.
-	List(ctx context.Context, options VariableListOptions) (*VariableList, error)
+	List(ctx context.Context, workspaceID string, options VariableListOptions) (*VariableList, error)

...
 // VariableListOptions represents the options for listing variables.
 type VariableListOptions struct {
 	ListOptions
-	Organization *string `url:"filter[organization][name]"`
-	Workspace    *string `url:"filter[workspace][name]"`
 }

Request for Agent Information...

Hi,
Would like to request enhancement to list the Terraform Agent details within the agent Pool. The UI shows this detail but it is not available from the APIs.

thx
Murali

Support inclusion of related resources (include query param)

Hey there!

Thanks for creating the Golang API for TFE! I had a question about https://www.terraform.io/docs/enterprise/api/index.html#inclusion-of-related-resources and go-tfe's support of related resources.

I was looking through the documentation (https://godoc.org/github.com/hashicorp/go-tfe) and I didn't see an option in the ListOptions struct to pass in additional query parameters. I was specifically trying to identify how to return created-by in a workspace run which doesn't seem currently possible.

Thanks!

Should ConfigurationSource contants include ado for Azure DevOps?

In https://github.com/hashicorp/go-tfe/blob/master/configuration_version.go#L59 we list several ConfigurationSource strings including "tfe-api" for the TFE API, "terraform" (for the TFC UI?) and "bitbucket", "github", and "gitlab". But should we also include "ado" in case the VCS system is Azure DevOps Server or Azure DevOps Services? See https://www.terraform.io/docs/cloud/vcs/index.html#supported-vcs-providers

I'm asking because I am adding a new policy_set_version class and wonder if I should include "ado" there.

unauthorized only in container

Hi, I'm having an issue where, I have created a working go script that will create a workspace. When I attempt to run this script inside a golang container, with the same API token, I get unauthorized error. Is this anything you have come across before? My Dockerfile is below, and script

FROM golang:1.12.4

WORKDIR /go/src/app
ADD tfe-build.go tfe-build.go

RUN go get -d -v ./...
RUN go install -v ./...
package main

import (
	"context"
	"log"
	"os"
	"flag"

	tfe "github.com/hashicorp/go-tfe"
)

func main() {
	tfe_workspace_name := flag.String("tfe_workspace_name", "foo", "name of workspace to be created")
	tfe_version := flag.String("tfe_version", "0.11.1", "tfe version to use")
	tfe_working_dir := flag.String("tfe_working_dir", "", "working directory")

	flag.Parse()
	config := &tfe.Config{
		Token: "blahblah.atlasv1.blahblahblahblah",
	}
	client, err := tfe.NewClient(config)
	if err != nil {
		log.Print("cant make client")
		log.Print(config)
		log.Fatal(err)
	}
	log.Print(client)

	// Create a context
	ctx := context.Background()

	// Check is workspace exists
	r, err := client.Workspaces.Read(ctx, "dci", *tfe_workspace_name)
	if err == nil {
		log.Print(r.VCSRepo)
		log.Print("workspace already exists")
		os.Exit(0)
	}

	log.Print(err)
...```

Thanks

Ingress Attribute endpoint missing

It looks like there is an endpoint that is missing from the client, namely the ingress-attributes endpoint.

I can't seem to find direct documentation to it, although it is mentioned on the configuration versions API page in passing. However, it would be super useful to have this as it would allow us to work out when a run is associated to a PR or not

[Bug] Unlocking a Workspace that is locked by a Run returns the wrong error

Attempting to unlock a workspace that is locked by a Run errors, which is expected behavior, however the error returned is incorrect.

Setup

If the workspace is locked by a pending Run (i.e. "Needs Confirmation"), an attempt to unlock will fail as expected.

image

Expected Behavior

If calling via the API, the error response is "Unable to unlock workspace. The workspace is locked by ...".

Example:

$ curl \
--header "Authorization: Bearer $TOKEN" \
--header "Content-Type: application/vnd.api+json" \
--request POST \
https://firefly.tfe.rocks/api/v2/workspaces/ws-Trm11JYZz9dj46wT/actions/unlock | jq .


{
  "errors": [
    {
      "status": "409",
      "title": "conflict",
      "detail": "Unable to unlock workspace. The workspace is locked by Run run-t4AeTqyyWCxpkq4S and may not be unlocked except by them."
    }
  ]
}

It would be expected that the return message from Unlock() would return a message closer to the details of the API response.

Actual Behavior

When calling the Unlock function on that workspace:

Unlock()

ws, err := client.Workspaces.Unlock(ctx, w.ID)

The error response is "workspace already unlocked" which is not actually correct, since the workspace is locked.

I believe this message is being derivate here

Oauth object does not have "secret" and "uuid" fields

When TFE creates oauth connection (e.g. for the gh) it also providing secret and uuid as part of the config. It is currently missing in the go binding.

Sample request from TFE on oauth creation:

{
  "data": {
    "attributes": {
      "name": "Example GH",
      "created-at": null,
      "callback-url": null,
      "oauth-token-string": null,
      "connect-path": null,
      "key": "XXXXX",
      "secret": "XXXXXXXX",
      "rsa-public-key": null,
      "uuid": "82213e23-3d48-4061-8960-3c01ef3e2d6e",
      "service-provider": "github",
      "service-provider-display-name": null,
      "api-url": "https://api.github.com",
      "http-url": "https://github.com"
    },
    "relationships": {
      "organization": {
        "data": {
          "type": "organizations",
          "id": "sampl-org-gh"
        }
      }
    },
    "type": "oauth-clients"
  }
}

As these fields are missing it is not possible to automate VCS connection creation using go-tfe with github.com.

VCSRepo struct missing webhook-url attribute for Registry Modules

The VCS Repo struct should be like the following:

      "vcs-repo": {
        "branch": "",
        "ingress-submodules": true,
        "identifier": "lafentres/terraform-aws-my-module",
        "display-identifier": "lafentres/terraform-aws-my-module",
        "oauth-token-id": "ot-hmAyP66qk2AMVdbJ",
        "webhook-url": "https://app.terraform.io/webhooks/vcs/a12b3456..."
      },

documentation link: https://www.terraform.io/docs/cloud/api/modules.html#sample-response-3

Currently it is using the Workspace VCSRepo struct which lacks webhook-url

type VCSRepo struct {
	Branch            string `json:"branch"`
	DisplayIdentifier string `json:"display-identifier"`
	Identifier        string `json:"identifier"`
	IngressSubmodules bool   `json:"ingress-submodules"`
	OAuthTokenID      string `json:"oauth-token-id"`
}

I propose either creating a new struct specifically for Registry Modules, or adding a new attribute to the workspace VCSRepo. Probably this code should be moved out of Workspace.go if that is the case

Perhaps you would be interested in volatile tech's "null" module

Reading the function calls available you seem to be using pointers to objects as a way of allowing yourself to declare them null. While your approach is sufficient, and I understand golang's generic disprivilege, it might be more suitable to use a package like https://github.com/volatiletech/null which includes various primitive types along with a boolean "valid" or "not valid" tag. It may be more work, but it seems more appropriate instead of memory addressing everything.

StateVersionOutput fails to unmarshal

The tests

package controllers

import (
        "context"
        "fmt"
        "testing"

        "github.com/hashicorp/go-tfe"
)

func getClient() (*tfe.Client, error) {
        cfg := &tfe.Config{
                Token: token,
        }
        cli, err := tfe.NewClient(cfg)
        if err != nil {
                return nil, err
        }
        return cli, nil
}

func TestCurrent(t *testing.T) {

        cli, err := getClient()
        if err != nil {
                t.Fatal(err)
        }
        ctx := context.Background()

        ws, err := cli.Workspaces.Read(ctx, "myorg", "myworkspace")
        if err != nil {
                t.Fatal(err)
        }

        st, err := cli.StateVersions.Current(ctx, ws.ID)
        if err != nil {
                t.Fatal(err)
        }

        for _, o := range st.Outputs {
                fmt.Println(o)
        }
}

func TestCurrentOutputs(t *testing.T) {

        cli, err := getClient()
        if err != nil {
                t.Fatal(err)
        }

        ctx := context.Background()

        ws, err := cli.Workspaces.Read(ctx, "myorg", "myworkspace")
        if err != nil {
                t.Fatal(err)
        }

        st, err := cli.StateVersions.Current(ctx, ws.ID)
        if err != nil {
                t.Fatal(err)
        }

        for _, o := range st.Outputs {
                fmt.Println(o)
                out, err := cli.StateVersionOutputs.Read(ctx, o.ID)
                if err != nil {
                        t.Fatal(err)
                }
                fmt.Println(out)
        }
}

func TestCurrentWithOptions(t *testing.T) {

        cli, err := getClient()
        if err != nil {
                t.Fatal(err)
        }

        ctx := context.Background()

        ws, err := cli.Workspaces.Read(ctx, "myorg", "myworkspace")
        if err != nil {
                t.Fatal(err)
        }

        st, err := cli.StateVersions.CurrentWithOptions(ctx, ws.ID, &tfe.StateVersionCurrentOptions{
                Include: "outputs",
        })
        if err != nil {
                t.Fatal(err)
        }

        for _, o := range st.Outputs {
                fmt.Println(o)
        }
}

The output

=== RUN   TestCurrent
&{wsout-aaaa  false  }
&{wsout-bbbb false  }
--- PASS: TestCurrent (1.25s)
=== RUN   TestCurrentOutputs
&{wsout-aaaa false  }
    stateversionoutputs_test.go:69: Invalid type provided
--- FAIL: TestCurrentOutputs (1.47s)
=== RUN   TestCurrentWithOptions
    stateversionoutputs_test.go:94: Invalid type provided
--- FAIL: TestCurrentWithOptions (1.21s)
FAIL
exit status 1

After some debugging, I noticed that the server returns the response but unmarshalling fails.

I also tried to curl the 2 outputs with the same token and endpoint generated by go-tfe and it works.

curl --header "Authorization: Bearer $TOKEN" https://app.terraform.io/api/v2/state-version-outputs/wsout-aaaa
{
  "data": {
    "id": "wsout-aaaa",
    "type": "state-version-outputs",
    "attributes": {
      "name": "the_secret",
      "sensitive": true,
      "type": "object",
      "value": {
        ...
      }
    },
    "links": {
      "self": "/api/v2/state-version-outputs/wsout-aaaa"
    }
  }
}

Add ability to manage / read Workspace Tags

It does not appear to be possible to read the tags set against workspaces.

This would be handy as I have a tool that requires making changes to variables automatically and I would like to be able to filter with Workspaces it acts on via a workspace tag

Any CLI client using this library?

I am wondering if there is already a CLI client that leverages this library? Something like th-helper, but in Go?

If not is there any place to start such a project where we could contribute?

Workspaces Create error: Pointer type in struct is not supported

Hello,

I am trying to create a new workspace and I am getting the following error:

Pointer type in struct is not supported

This is the code I am using.

	config := &tfe.Config{
		Token: "ATLAS_TOKEN",
	}
	client, err := tfe.NewClient(config)
	if err != nil {
		log.Fatal(err)
	}
	ctx := context.Background()

	_, err = client.Workspaces.Create(ctx, "my-org", tfe.WorkspaceCreateOptions{
		Name:             tfe.String("workspace-name"),
		WorkingDirectory: tfe.String("directory"),
		VCSRepo: &tfe.VCSRepoOptions{
			Identifier:   tfe.String("org/repo-name"),
			OAuthTokenID: tfe.String("token"),
			Branch:       tfe.String("master"),
		},
	})

Any help you can provide would be greatly appreciated.

Thanks!

StateVersion has resources

Is there a way to figure out if the current state has resources or has output?

What I want is to check if the latest available state from the given workspace has resources or has output.

Policies.Create seems to ignore EnforcementMode

	opts := tfe.PolicyCreateOptions{
		Name: tfe.String("Required-Tags-Policy"),
		Enforce: []*tfe.EnforcementOptions{
			{
				Path: tfe.String("Required-Tags-Policy" + ".sentinel"),
				Mode: tfe.EnforcementMode(tfe.EnforcementSoft),
			},
		},
	}
	client.Policies.Create(ctx, "my_sweet_sweet_org", opts)
}

For me, it arrived in PTFE as "EnforcementHard"

RunStatusTimestamps are wrong/out of date

Hi, we are investigating using this API for a Terraform Enterprise installation and noticed some anomalies that we hope can be easily explained/solved.

The TFE API returns a status timestamp object as shown below, and the go-tfe API has different attributes, thus some are not populated (expected).
"status-timestamps": {
"applied-at": "2021-05-27T17:51:56+00:00",
"planned-at": "2021-05-27T17:45:06+00:00",
"applying-at": "2021-05-27T17:50:54+00:00",
"planning-at": "2021-05-27T17:44:18+00:00",
"confirmed-at": "2021-05-27T17:50:50+00:00",
"plan-queued-at": "2021-05-27T17:44:14+00:00",
"apply-queued-at": "2021-05-27T17:50:51+00:00",
"plan-queueable-at": "2021-05-27T17:44:12+00:00",
"policy-checked-at": "2021-05-27T17:45:16+00:00"
},

go-tfe returns timestamps such as QueuedAt, FinishedAt, ErroredAt. Our TFE version 202104-1 does not have these properties. Is this API coded against a specific version of Terraform Cloud?

Thanks

Don

GET /workspaces/:workspace_id/runs is missing include parameter

Hello folks,
According to the documentation: https://www.terraform.io/docs/cloud/api/run.html#list-runs-in-a-workspace, GET /workspaces/:workspace_id/runs is missing include parameter:

// RunListOptions represents the options for listing runs.
type RunListOptions struct {
	ListOptions
	Include *string `url:"include"` <-------------- This should be added
}

Can you please add it so we can query /runs endpoint with additional applies data. This can save us a lot of unnecessary additional HTTP requests!

Support upload of code not on filesystem in ConfigurationVersions.Upload

I would like to be able to provide a slice of bytes directly to the upload of the configuration versions instead of requiring that the terraform code be on disk. This would allow for hosting terraform code to run workspaces in cloud storage buckets and reading into memory for transient upload.

Propose a new method on ConfigurationVersions interface of ConfigurationVerions.UploadBytes()

New TFE Run Status?

Hey there!

We just updated to the latest version of TFE and noticed that there is a new status that is being returned by one of our workspaces via the API:

"status": "planned_and_finished",

Looking at the current set of RunStatus, I don't see a corresponding one for the returned status. Is that expected?

go-tfe/run.go

Line 50 in faae81b

const (

Thanks,
Glenn

List operations require pagination options but do not return pagination status

For example the organizations List function (https://github.com/hashicorp/go-tfe/blob/master/organization.go#L96) accepts an OrganizationListOptions which is simply a wrapper around ListOptions which primarily specifies pagination options.

This requires that consumers of the library manage pagination themselves. However, no pagination information is returned from the List calls forcing callers to create hacks to ensure all pages have been retrieved.

I see two possible fixes:

  1. Have the List calls handle pagination internally and return all possible items for each List call.
  2. Each List call returns a struct which includes pagination info for the caller to utilize. I utilized int pointers in the example below to account for the fact that occasionally certain pagination fields are null and wanted consistency among all fields.
type OrganizationsListResponse struct {
    Organizations []*Organization
    Pagination struct {
        CurrentPage *int
        NextPage *int
        PrevPage *int
        TotalCount *int
        TotalPages *int        
    }
}

Support account creation

Hi there,
I've read the documentation searching for a way to manage accounts via API. There are supported actions like updating account info or changing passwords, but couldn't find anything for account creation. Digging a bit in this repo I found [user.go] (https://github.com/hashicorp/go-tfe/blob/master/user.go) which looks like the place this could be defined, and seems there is no such thing.
I would expect something like:

POST /account/new

with a JSON payload containing the username, mail and password (which is exactly what /account/new requires when used from a browser)

So, am I missing something, is this supported at all?
If not, is there any particular reason for it?

Thanks in advance.

[Dev Request] Use mocking or go-vcr for testing

It would be nice if mocks or go-vcr could be used for the unit tests, as currently testing requires an internet connection, TFE/TF Cloud connection and token to run.

I did a quick spike and this seemed to work:

func getVCRRecorder(t *testing.T, cassetteName string) *recorder.Recorder {

	// Set recording responses with env variable RECORDING
	envRecording, ok := os.LookupEnv("RECORDING")

	mode := recorder.ModeReplaying

	if ok {
		switch envRecording {
		case "false":
			t.Logf("[VCR] - Replay mode enabled")
			mode = recorder.ModeReplaying
		case "disabled", "disable":
			t.Logf("[VCR] - VCR disabled")
			mode = recorder.ModeDisabled
		case "true":
			t.Logf("[VCR] - Recording enabled")
			mode = recorder.ModeRecording
		default:
			t.Logf("[VCR] - Recording enabled")
			mode = recorder.ModeRecording
		}
	}

	filename := fmt.Sprintf("fixtures/%s", cassetteName)

	transport := &http.Transport{	}

	rec, err := recorder.NewAsMode(
		filename,
		mode,
		transport,
	)
	if err != nil {
		t.Fatal(err)
	}
	return rec
}

func testVCRClient(t *testing.T) *Client {

       rec := getVCRRecorder(t, t.Name)
       defer rec.Stop()

      cfg := &Config{
	  HTTPClient: rec,
       }

       client, err := NewClient(cfg)

	if err != nil {
		t.Fatal(err)
	}

	return client
}

x509: certificate signed by unknown authority

Hi All,
I'm getting the following error when executing my CLI (in development) within a Docker container (ubuntu:18.04).

Get "https://app.terraform.io/api/v2/ping": x509: certificate signed by unknown authority 

Strangely enough, I don't get the same error when executing it from my MacBook. Any suggestions of how to solve this issue?

Thank you,
Valter.

Unable to destroy workspace

Is there a way to configure a workspace to be destroyable with this library, or a way to modify workspace permissions?

I see that a Workspace has CanQueueDestroyPlan, Actions.IsDestroyable, and Pemissions.CanQueueDestroy fields, but none of these are available to set in CreateWorkspaceOptions or UpdateWorkspaceOptions

As a result, a workspace appears to always have CanQueueDestoryPlan set as false, despite IsDestroyable set as true. And when creating a Run that is IsDestroy, I receive "resource not found".

StateVersionOutput expects all outputs to be strings, and fails when other output types exist

Terraform supports output types other than 'string'. For example, this Terraform declaration produces an output type of 'array':

output "instance_ips" {
  value = aws_instance.ubuntu.*.private_ip
}

resulting output:

instance_ips: [
  "10.1.2.3",
  "10.1.2.4",
  "10.1.2.5" 
]

This is why the State Output contains a "type" field, which will be "array" in this case.

However, the tfe-go library defines the State Version Output as:

type StateVersionOutput struct {
	ID        string `jsonapi:"primary,state-version-outputs"`
	Name      string `jsonapi:"attr,name"`
	Sensitive bool   `jsonapi:"attr,sensitive"`
	Type      string `jsonapi:"attr,type"`
	Value     string `jsonapi:"attr,value"`
}

Note that Value is 'string' only.

When .Read is called on an Output of type 'array', the Read call will fail with an error, as the jsonapi is not able to unmarshal the array value into this struct.

Here's an example API response from Terraform with an array:

{
  "data": {
    "id": "wsout-abcdef",
    "type": "state-version-outputs",
    "attributes": {
      "name": "instance_ips",
      "sensitive": false,
      "type": "array",
      "value": [
        "10.180.69.26",
        "10.180.69.11",
        "10.180.69.37"
      ]
    },
    "links": {
      "self": "/api/v2/state-version-outputs/wsout-abcdef"
    }
  }
}

Thanks!
-alex

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.