Merge pull request #18816 from hashicorp/f-update-deps

govendor: update `go-tfe`
This commit is contained in:
Sander van Harmelen 2018-09-09 21:25:27 +02:00 committed by GitHub
commit cd8fcf74e0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 432 additions and 142 deletions

View File

@ -336,13 +336,13 @@ func (b *Remote) states() ([]string, error) {
}
options := tfe.WorkspaceListOptions{}
ws, err := b.client.Workspaces.List(context.Background(), b.organization, options)
wl, err := b.client.Workspaces.List(context.Background(), b.organization, options)
if err != nil {
return nil, err
}
var names []string
for _, w := range ws {
for _, w := range wl.Items {
if b.workspace != "" && w.Name == b.workspace {
names = append(names, backend.DefaultStateName)
continue

View File

@ -51,12 +51,21 @@ func newMockConfigurationVersions(client *mockClient) *mockConfigurationVersions
}
}
func (m *mockConfigurationVersions) List(ctx context.Context, workspaceID string, options tfe.ConfigurationVersionListOptions) ([]*tfe.ConfigurationVersion, error) {
var cvs []*tfe.ConfigurationVersion
func (m *mockConfigurationVersions) List(ctx context.Context, workspaceID string, options tfe.ConfigurationVersionListOptions) (*tfe.ConfigurationVersionList, error) {
cvl := &tfe.ConfigurationVersionList{}
for _, cv := range m.configVersions {
cvs = append(cvs, cv)
cvl.Items = append(cvl.Items, cv)
}
return cvs, nil
cvl.Pagination = &tfe.Pagination{
CurrentPage: 1,
NextPage: 1,
PreviousPage: 1,
TotalPages: 1,
TotalCount: len(cvl.Items),
}
return cvl, nil
}
func (m *mockConfigurationVersions) Create(ctx context.Context, workspaceID string, options tfe.ConfigurationVersionCreateOptions) (*tfe.ConfigurationVersion, error) {
@ -105,12 +114,21 @@ func newMockOrganizations(client *mockClient) *mockOrganizations {
}
}
func (m *mockOrganizations) List(ctx context.Context, options tfe.OrganizationListOptions) ([]*tfe.Organization, error) {
var orgs []*tfe.Organization
func (m *mockOrganizations) List(ctx context.Context, options tfe.OrganizationListOptions) (*tfe.OrganizationList, error) {
orgl := &tfe.OrganizationList{}
for _, org := range m.organizations {
orgs = append(orgs, org)
orgl.Items = append(orgl.Items, org)
}
return orgs, nil
orgl.Pagination = &tfe.Pagination{
CurrentPage: 1,
NextPage: 1,
PreviousPage: 1,
TotalPages: 1,
TotalCount: len(orgl.Items),
}
return orgl, nil
}
func (m *mockOrganizations) Create(ctx context.Context, options tfe.OrganizationCreateOptions) (*tfe.Organization, error) {
@ -230,16 +248,26 @@ func newMockRuns(client *mockClient) *mockRuns {
}
}
func (m *mockRuns) List(ctx context.Context, workspaceID string, options tfe.RunListOptions) ([]*tfe.Run, error) {
func (m *mockRuns) List(ctx context.Context, workspaceID string, options tfe.RunListOptions) (*tfe.RunList, error) {
w, ok := m.client.Workspaces.workspaceIDs[workspaceID]
if !ok {
return nil, tfe.ErrResourceNotFound
}
var rs []*tfe.Run
rl := &tfe.RunList{}
for _, r := range m.workspaces[w.ID] {
rs = append(rs, r)
rl.Items = append(rl.Items, r)
}
return rs, nil
rl.Pagination = &tfe.Pagination{
CurrentPage: 1,
NextPage: 1,
PreviousPage: 1,
TotalPages: 1,
TotalCount: len(rl.Items),
}
return rl, nil
}
func (m *mockRuns) Create(ctx context.Context, options tfe.RunCreateOptions) (*tfe.Run, error) {
@ -296,12 +324,21 @@ func newMockStateVersions(client *mockClient) *mockStateVersions {
}
}
func (m *mockStateVersions) List(ctx context.Context, options tfe.StateVersionListOptions) ([]*tfe.StateVersion, error) {
var svs []*tfe.StateVersion
func (m *mockStateVersions) List(ctx context.Context, options tfe.StateVersionListOptions) (*tfe.StateVersionList, error) {
svl := &tfe.StateVersionList{}
for _, sv := range m.stateVersions {
svs = append(svs, sv)
svl.Items = append(svl.Items, sv)
}
return svs, nil
svl.Pagination = &tfe.Pagination{
CurrentPage: 1,
NextPage: 1,
PreviousPage: 1,
TotalPages: 1,
TotalCount: len(svl.Items),
}
return svl, nil
}
func (m *mockStateVersions) Create(ctx context.Context, workspaceID string, options tfe.StateVersionCreateOptions) (*tfe.StateVersion, error) {
@ -375,12 +412,21 @@ func newMockWorkspaces(client *mockClient) *mockWorkspaces {
}
}
func (m *mockWorkspaces) List(ctx context.Context, organization string, options tfe.WorkspaceListOptions) ([]*tfe.Workspace, error) {
var ws []*tfe.Workspace
func (m *mockWorkspaces) List(ctx context.Context, organization string, options tfe.WorkspaceListOptions) (*tfe.WorkspaceList, error) {
wl := &tfe.WorkspaceList{}
for _, w := range m.workspaceIDs {
ws = append(ws, w)
wl.Items = append(wl.Items, w)
}
return ws, nil
wl.Pagination = &tfe.Pagination{
CurrentPage: 1,
NextPage: 1,
PreviousPage: 1,
TotalPages: 1,
TotalCount: len(wl.Items),
}
return wl, nil
}
func (m *mockWorkspaces) Create(ctx context.Context, organization string, options tfe.WorkspaceCreateOptions) (*tfe.Workspace, error) {

View File

@ -21,7 +21,7 @@ var _ ConfigurationVersions = (*configurationVersions)(nil)
// https://www.terraform.io/docs/enterprise/api/configuration-versions.html
type ConfigurationVersions interface {
// List returns all configuration versions of a workspace.
List(ctx context.Context, workspaceID string, options ConfigurationVersionListOptions) ([]*ConfigurationVersion, error)
List(ctx context.Context, workspaceID string, options ConfigurationVersionListOptions) (*ConfigurationVersionList, error)
// Create is used to create a new configuration version. The created
// configuration version will be usable once data is uploaded to it.
@ -63,6 +63,12 @@ const (
ConfigurationSourceTerraform ConfigurationSource = "terraform"
)
// ConfigurationVersionList represents a list of configuration versions.
type ConfigurationVersionList struct {
*Pagination
Items []*ConfigurationVersion
}
// ConfigurationVersion is a representation of an uploaded or ingressed
// Terraform configuration in TFE. A workspace must have at least one
// configuration version before any runs may be queued on it.
@ -93,7 +99,7 @@ type ConfigurationVersionListOptions struct {
}
// List returns all configuration versions of a workspace.
func (s *configurationVersions) List(ctx context.Context, workspaceID string, options ConfigurationVersionListOptions) ([]*ConfigurationVersion, error) {
func (s *configurationVersions) List(ctx context.Context, workspaceID string, options ConfigurationVersionListOptions) (*ConfigurationVersionList, error) {
if !validStringID(&workspaceID) {
return nil, errors.New("Invalid value for workspace ID")
}
@ -104,13 +110,13 @@ func (s *configurationVersions) List(ctx context.Context, workspaceID string, op
return nil, err
}
var cvs []*ConfigurationVersion
err = s.client.do(ctx, req, &cvs)
cvl := &ConfigurationVersionList{}
err = s.client.do(ctx, req, cvl)
if err != nil {
return nil, err
}
return cvs, nil
return cvl, nil
}
// ConfigurationVersionCreateOptions represents the options for creating a

View File

@ -18,7 +18,7 @@ var _ OAuthTokens = (*oAuthTokens)(nil)
// https://www.terraform.io/docs/enterprise/api/oauth-tokens.html
type OAuthTokens interface {
// List all the OAuth Tokens for a given organization.
List(ctx context.Context, organization string) ([]*OAuthToken, error)
List(ctx context.Context, organization string, options OAuthTokenListOptions) (*OAuthTokenList, error)
}
// oAuthTokens implements OAuthTokens.
@ -26,6 +26,12 @@ type oAuthTokens struct {
client *Client
}
// OAuthTokenList represents a list of OAuth tokens.
type OAuthTokenList struct {
*Pagination
Items []*OAuthToken
}
// OAuthToken represents a VCS configuration including the associated
// OAuth token
type OAuthToken struct {
@ -39,23 +45,29 @@ type OAuthToken struct {
OAuthClient *OAuthClient `jsonapi:"relation,oauth-client"`
}
// List all the OAuth Tokens for a given organization.
func (s *oAuthTokens) List(ctx context.Context, organization string) ([]*OAuthToken, error) {
// OAuthTokenListOptions represents the options for listing
// OAuth tokens.
type OAuthTokenListOptions struct {
ListOptions
}
// List all the OAuth tokens for a given organization.
func (s *oAuthTokens) List(ctx context.Context, organization string, options OAuthTokenListOptions) (*OAuthTokenList, error) {
if !validStringID(&organization) {
return nil, errors.New("Invalid value for organization")
}
u := fmt.Sprintf("organizations/%s/oauth-tokens", url.QueryEscape(organization))
req, err := s.client.newRequest("GET", u, nil)
req, err := s.client.newRequest("GET", u, &options)
if err != nil {
return nil, err
}
var ots []*OAuthToken
err = s.client.do(ctx, req, &ots)
otl := &OAuthTokenList{}
err = s.client.do(ctx, req, otl)
if err != nil {
return nil, err
}
return ots, nil
return otl, nil
}

View File

@ -18,7 +18,7 @@ var _ Organizations = (*organizations)(nil)
// https://www.terraform.io/docs/enterprise/api/organizations.html
type Organizations interface {
// List all the organizations visible to the current user.
List(ctx context.Context, options OrganizationListOptions) ([]*Organization, error)
List(ctx context.Context, options OrganizationListOptions) (*OrganizationList, error)
// Create a new organization with the given options.
Create(ctx context.Context, options OrganizationCreateOptions) (*Organization, error)
@ -58,6 +58,12 @@ const (
EnterprisePlanTrial EnterprisePlanType = "trial"
)
// OrganizationList represents a list of organizations.
type OrganizationList struct {
*Pagination
Items []*Organization
}
// Organization represents a Terraform Enterprise organization.
type Organization struct {
Name string `jsonapi:"primary,organizations"`
@ -93,19 +99,19 @@ type OrganizationListOptions struct {
}
// List all the organizations visible to the current user.
func (s *organizations) List(ctx context.Context, options OrganizationListOptions) ([]*Organization, error) {
func (s *organizations) List(ctx context.Context, options OrganizationListOptions) (*OrganizationList, error) {
req, err := s.client.newRequest("GET", "organizations", &options)
if err != nil {
return nil, err
}
var orgs []*Organization
err = s.client.do(ctx, req, &orgs)
orgl := &OrganizationList{}
err = s.client.do(ctx, req, orgl)
if err != nil {
return nil, err
}
return orgs, nil
return orgl, nil
}
// OrganizationCreateOptions represents the options for creating an organization.

View File

@ -20,6 +20,9 @@ type OrganizationTokens interface {
// Generate a new organization token, replacing any existing token.
Generate(ctx context.Context, organization string) (*OrganizationToken, error)
// Read an organization token.
Read(ctx context.Context, organization string) (*OrganizationToken, error)
// Delete an organization token.
Delete(ctx context.Context, organization string) error
}
@ -59,6 +62,27 @@ func (s *organizationTokens) Generate(ctx context.Context, organization string)
return ot, err
}
// Read an organization token.
func (s *organizationTokens) Read(ctx context.Context, organization string) (*OrganizationToken, error) {
if !validStringID(&organization) {
return nil, errors.New("Invalid value for organization")
}
u := fmt.Sprintf("organizations/%s/authentication-token", url.QueryEscape(organization))
req, err := s.client.newRequest("GET", u, nil)
if err != nil {
return nil, err
}
ot := &OrganizationToken{}
err = s.client.do(ctx, req, ot)
if err != nil {
return nil, err
}
return ot, err
}
// Delete an organization token.
func (s *organizationTokens) Delete(ctx context.Context, organization string) error {
if !validStringID(&organization) {

View File

@ -170,10 +170,19 @@ func (r *LogReader) read(l []byte) (int, error) {
return 0, err
}
// Read the retrieved chunk.
written, err := resp.Body.Read(l)
if err != nil && err != io.EOF {
// Ignore io.EOF errors returned when reading from the response
// body as this indicates the end of the chunk and not the end
// of the logfile.
return written, err
}
// Check if we need to continue the loop and wait 500 miliseconds
// before checking if there is a new chunk available or that the
// plan is finished and we are done reading all chunks.
if resp.ContentLength == 0 {
if written == 0 {
if r.reads%2 == 0 {
r.plan, err = r.client.Plans.Read(r.ctx, r.plan.ID)
if err != nil {
@ -190,17 +199,8 @@ func (r *LogReader) read(l []byte) (int, error) {
}
}
// Read the retrieved chunk.
written, err := resp.Body.Read(l)
if err == io.EOF {
// Ignore io.EOF errors returned when reading from the response
// body as this indicates the end of the chunk and not the end
// of the logfile.
err = nil
}
// Update the offset for the next read.
r.offset += int64(written)
return written, err
return written, nil
}

View File

@ -1,6 +1,7 @@
package tfe
import (
"bytes"
"context"
"errors"
"fmt"
@ -17,7 +18,7 @@ var _ Policies = (*policies)(nil)
// TFE API docs: https://www.terraform.io/docs/enterprise/api/policies.html
type Policies interface {
// List all the policies for a given organization
List(ctx context.Context, organization string, options PolicyListOptions) ([]*Policy, error)
List(ctx context.Context, organization string, options PolicyListOptions) (*PolicyList, error)
// Create a policy and associate it with an organization.
Create(ctx context.Context, organization string, options PolicyCreateOptions) (*Policy, error)
@ -25,14 +26,17 @@ type Policies interface {
// Read a policy by its ID.
Read(ctx context.Context, policyID string) (*Policy, error)
// Upload the policy content of the policy.
Upload(ctx context.Context, policyID string, content []byte) error
// Update an existing policy.
Update(ctx context.Context, policyID string, options PolicyUpdateOptions) (*Policy, error)
// Delete a policy by its ID.
Delete(ctx context.Context, policyID string) error
// Upload the policy content of the policy.
Upload(ctx context.Context, policyID string, content []byte) error
// Upload the policy content of the policy.
Download(ctx context.Context, policyID string) ([]byte, error)
}
// policies implements Policies.
@ -50,6 +54,12 @@ const (
EnforcementSoft EnforcementLevel = "soft-mandatory"
)
// PolicyList represents a list of policies..
type PolicyList struct {
*Pagination
Items []*Policy
}
// Policy represents a Terraform Enterprise policy.
type Policy struct {
ID string `jsonapi:"primary,policies"`
@ -70,7 +80,7 @@ type PolicyListOptions struct {
}
// List all the policies for a given organization
func (s *policies) List(ctx context.Context, organization string, options PolicyListOptions) ([]*Policy, error) {
func (s *policies) List(ctx context.Context, organization string, options PolicyListOptions) (*PolicyList, error) {
if !validStringID(&organization) {
return nil, errors.New("Invalid value for organization")
}
@ -81,13 +91,13 @@ func (s *policies) List(ctx context.Context, organization string, options Policy
return nil, err
}
var ps []*Policy
err = s.client.do(ctx, req, &ps)
pl := &PolicyList{}
err = s.client.do(ctx, req, pl)
if err != nil {
return nil, err
}
return ps, nil
return pl, nil
}
// PolicyCreateOptions represents the options for creating a new policy.
@ -177,21 +187,6 @@ func (s *policies) Read(ctx context.Context, policyID string) (*Policy, error) {
return p, err
}
// Upload the policy content of the policy.
func (s *policies) Upload(ctx context.Context, policyID string, content []byte) error {
if !validStringID(&policyID) {
return errors.New("Invalid value for policy ID")
}
u := fmt.Sprintf("policies/%s/upload", url.QueryEscape(policyID))
req, err := s.client.newRequest("PUT", u, content)
if err != nil {
return err
}
return s.client.do(ctx, req, nil)
}
// PolicyUpdateOptions represents the options for updating a policy.
type PolicyUpdateOptions struct {
// For internal use only!
@ -249,3 +244,39 @@ func (s *policies) Delete(ctx context.Context, policyID string) error {
return s.client.do(ctx, req, nil)
}
// Upload the policy content of the policy.
func (s *policies) Upload(ctx context.Context, policyID string, content []byte) error {
if !validStringID(&policyID) {
return errors.New("Invalid value for policy ID")
}
u := fmt.Sprintf("policies/%s/upload", url.QueryEscape(policyID))
req, err := s.client.newRequest("PUT", u, content)
if err != nil {
return err
}
return s.client.do(ctx, req, nil)
}
// Download the policy content of the policy.
func (s *policies) Download(ctx context.Context, policyID string) ([]byte, error) {
if !validStringID(&policyID) {
return nil, errors.New("Invalid value for policy ID")
}
u := fmt.Sprintf("policies/%s/download", url.QueryEscape(policyID))
req, err := s.client.newRequest("GET", u, nil)
if err != nil {
return nil, err
}
var buf bytes.Buffer
err = s.client.do(ctx, req, &buf)
if err != nil {
return nil, err
}
return buf.Bytes(), nil
}

View File

@ -18,7 +18,7 @@ var _ PolicyChecks = (*policyChecks)(nil)
// https://www.terraform.io/docs/enterprise/api/policy-checks.html
type PolicyChecks interface {
// List all policy checks of the given run.
List(ctx context.Context, runID string, options PolicyCheckListOptions) ([]*PolicyCheck, error)
List(ctx context.Context, runID string, options PolicyCheckListOptions) (*PolicyCheckList, error)
// Override a soft-mandatory or warning policy.
Override(ctx context.Context, policyCheckID string) (*PolicyCheck, error)
@ -52,6 +52,12 @@ const (
PolicySoftFailed PolicyStatus = "soft_failed"
)
// PolicyCheckList represents a list of policy checks.
type PolicyCheckList struct {
*Pagination
Items []*PolicyCheck
}
// PolicyCheck represents a Terraform Enterprise policy check..
type PolicyCheck struct {
ID string `jsonapi:"primary,policy-checks"`
@ -101,7 +107,7 @@ type PolicyCheckListOptions struct {
}
// List all policy checks of the given run.
func (s *policyChecks) List(ctx context.Context, runID string, options PolicyCheckListOptions) ([]*PolicyCheck, error) {
func (s *policyChecks) List(ctx context.Context, runID string, options PolicyCheckListOptions) (*PolicyCheckList, error) {
if !validStringID(&runID) {
return nil, errors.New("Invalid value for run ID")
}
@ -112,13 +118,13 @@ func (s *policyChecks) List(ctx context.Context, runID string, options PolicyChe
return nil, err
}
var pcs []*PolicyCheck
err = s.client.do(ctx, req, &pcs)
pcl := &PolicyCheckList{}
err = s.client.do(ctx, req, pcl)
if err != nil {
return nil, err
}
return pcs, nil
return pcl, nil
}
// Override a soft-mandatory or warning policy.

View File

@ -17,7 +17,7 @@ var _ Runs = (*runs)(nil)
// TFE API docs: https://www.terraform.io/docs/enterprise/api/run.html
type Runs interface {
// List all the runs of the given workspace.
List(ctx context.Context, workspaceID string, options RunListOptions) ([]*Run, error)
List(ctx context.Context, workspaceID string, options RunListOptions) (*RunList, error)
// Create a new run with the given options.
Create(ctx context.Context, options RunCreateOptions) (*Run, error)
@ -69,6 +69,12 @@ const (
RunSourceUI RunSource = "tfe-ui"
)
// RunList represents a list of runs.
type RunList struct {
*Pagination
Items []*Run
}
// Run represents a Terraform Enterprise run.
type Run struct {
ID string `jsonapi:"primary,runs"`
@ -117,7 +123,7 @@ type RunListOptions struct {
}
// List all the runs of the given workspace.
func (s *runs) List(ctx context.Context, workspaceID string, options RunListOptions) ([]*Run, error) {
func (s *runs) List(ctx context.Context, workspaceID string, options RunListOptions) (*RunList, error) {
if !validStringID(&workspaceID) {
return nil, errors.New("Invalid value for workspace ID")
}
@ -128,13 +134,13 @@ func (s *runs) List(ctx context.Context, workspaceID string, options RunListOpti
return nil, err
}
var rs []*Run
err = s.client.do(ctx, req, &rs)
rl := &RunList{}
err = s.client.do(ctx, req, rl)
if err != nil {
return nil, err
}
return rs, nil
return rl, nil
}
// RunCreateOptions represents the options for creating a new run.

View File

@ -17,7 +17,7 @@ var _ SSHKeys = (*sshKeys)(nil)
// https://www.terraform.io/docs/enterprise/api/ssh-keys.html
type SSHKeys interface {
// List all the SSH keys for a given organization
List(ctx context.Context, organization string, options SSHKeyListOptions) ([]*SSHKey, error)
List(ctx context.Context, organization string, options SSHKeyListOptions) (*SSHKeyList, error)
// Create an SSH key and associate it with an organization.
Create(ctx context.Context, organization string, options SSHKeyCreateOptions) (*SSHKey, error)
@ -37,6 +37,12 @@ type sshKeys struct {
client *Client
}
// SSHKeyList represents a list of SSH keys.
type SSHKeyList struct {
*Pagination
Items []*SSHKey
}
// SSHKey represents a SSH key.
type SSHKey struct {
ID string `jsonapi:"primary,ssh-keys"`
@ -49,7 +55,7 @@ type SSHKeyListOptions struct {
}
// List all the SSH keys for a given organization
func (s *sshKeys) List(ctx context.Context, organization string, options SSHKeyListOptions) ([]*SSHKey, error) {
func (s *sshKeys) List(ctx context.Context, organization string, options SSHKeyListOptions) (*SSHKeyList, error) {
if !validStringID(&organization) {
return nil, errors.New("Invalid value for organization")
}
@ -60,13 +66,13 @@ func (s *sshKeys) List(ctx context.Context, organization string, options SSHKeyL
return nil, err
}
var ks []*SSHKey
err = s.client.do(ctx, req, &ks)
kl := &SSHKeyList{}
err = s.client.do(ctx, req, kl)
if err != nil {
return nil, err
}
return ks, nil
return kl, nil
}
// SSHKeyCreateOptions represents the options for creating an SSH key.

View File

@ -19,7 +19,7 @@ var _ StateVersions = (*stateVersions)(nil)
// https://www.terraform.io/docs/enterprise/api/state-versions.html
type StateVersions interface {
// List all the state versions for a given workspace.
List(ctx context.Context, options StateVersionListOptions) ([]*StateVersion, error)
List(ctx context.Context, options StateVersionListOptions) (*StateVersionList, error)
// Create a new state version for the given workspace.
Create(ctx context.Context, workspaceID string, options StateVersionCreateOptions) (*StateVersion, error)
@ -39,6 +39,12 @@ type stateVersions struct {
client *Client
}
// StateVersionList represents a list of state versions.
type StateVersionList struct {
*Pagination
Items []*StateVersion
}
// StateVersion represents a Terraform Enterprise state version.
type StateVersion struct {
ID string `jsonapi:"primary,state-versions"`
@ -70,7 +76,7 @@ func (o StateVersionListOptions) valid() error {
}
// List all the state versions for a given workspace.
func (s *stateVersions) List(ctx context.Context, options StateVersionListOptions) ([]*StateVersion, error) {
func (s *stateVersions) List(ctx context.Context, options StateVersionListOptions) (*StateVersionList, error) {
if err := options.valid(); err != nil {
return nil, err
}
@ -80,13 +86,13 @@ func (s *stateVersions) List(ctx context.Context, options StateVersionListOption
return nil, err
}
var svs []*StateVersion
err = s.client.do(ctx, req, &svs)
svl := &StateVersionList{}
err = s.client.do(ctx, req, svl)
if err != nil {
return nil, err
}
return svs, nil
return svl, nil
}
// StateVersionCreateOptions represents the options for creating a state version.
@ -105,6 +111,9 @@ type StateVersionCreateOptions struct {
// The base64 encoded state.
State *string `jsonapi:"attr,state"`
// Specifies the run to associate the state with.
Run *Run `jsonapi:"relation,run,omitempty"`
}
func (o StateVersionCreateOptions) valid() error {

View File

@ -16,7 +16,7 @@ var _ Teams = (*teams)(nil)
// TFE API docs: https://www.terraform.io/docs/enterprise/api/teams.html
type Teams interface {
// List all the teams of the given organization.
List(ctx context.Context, organization string, options TeamListOptions) ([]*Team, error)
List(ctx context.Context, organization string, options TeamListOptions) (*TeamList, error)
// Create a new team with the given options.
Create(ctx context.Context, organization string, options TeamCreateOptions) (*Team, error)
@ -33,6 +33,12 @@ type teams struct {
client *Client
}
// TeamList represents a list of teams.
type TeamList struct {
*Pagination
Items []*Team
}
// Team represents a Terraform Enterprise team.
type Team struct {
ID string `jsonapi:"primary,teams"`
@ -41,7 +47,7 @@ type Team struct {
UserCount int `jsonapi:"attr,users-count"`
// Relations
//User []*User `jsonapi:"relation,users"`
Users []*User `jsonapi:"relation,users"`
}
// TeamPermissions represents the team permissions.
@ -56,7 +62,7 @@ type TeamListOptions struct {
}
// List all the teams of the given organization.
func (s *teams) List(ctx context.Context, organization string, options TeamListOptions) ([]*Team, error) {
func (s *teams) List(ctx context.Context, organization string, options TeamListOptions) (*TeamList, error) {
if !validStringID(&organization) {
return nil, errors.New("Invalid value for organization")
}
@ -67,13 +73,13 @@ func (s *teams) List(ctx context.Context, organization string, options TeamListO
return nil, err
}
var ts []*Team
err = s.client.do(ctx, req, &ts)
tl := &TeamList{}
err = s.client.do(ctx, req, tl)
if err != nil {
return nil, err
}
return ts, nil
return tl, nil
}
// TeamCreateOptions represents the options for creating a team.

View File

@ -17,7 +17,7 @@ var _ TeamAccesses = (*teamAccesses)(nil)
// https://www.terraform.io/docs/enterprise/api/team-access.html
type TeamAccesses interface {
// List all the team accesses for a given workspace.
List(ctx context.Context, options TeamAccessListOptions) ([]*TeamAccess, error)
List(ctx context.Context, options TeamAccessListOptions) (*TeamAccessList, error)
// Add team access for a workspace.
Add(ctx context.Context, options TeamAccessAddOptions) (*TeamAccess, error)
@ -34,20 +34,26 @@ type teamAccesses struct {
client *Client
}
// TeamAccessType represents a team access type.
type TeamAccessType string
// AccessType represents a team access type.
type AccessType string
// List all available team access types.
const (
TeamAccessAdmin TeamAccessType = "admin"
TeamAccessRead TeamAccessType = "read"
TeamAccessWrite TeamAccessType = "write"
AccessAdmin AccessType = "admin"
AccessRead AccessType = "read"
AccessWrite AccessType = "write"
)
// TeamAccessList represents a list of team accesses.
type TeamAccessList struct {
*Pagination
Items []*TeamAccess
}
// TeamAccess represents the workspace access for a team.
type TeamAccess struct {
ID string `jsonapi:"primary,team-workspaces"`
Access TeamAccessType `jsonapi:"attr,access"`
Access AccessType `jsonapi:"attr,access"`
// Relations
Team *Team `jsonapi:"relation,team"`
@ -71,7 +77,7 @@ func (o TeamAccessListOptions) valid() error {
}
// List all the team accesses for a given workspace.
func (s *teamAccesses) List(ctx context.Context, options TeamAccessListOptions) ([]*TeamAccess, error) {
func (s *teamAccesses) List(ctx context.Context, options TeamAccessListOptions) (*TeamAccessList, error) {
if err := options.valid(); err != nil {
return nil, err
}
@ -81,13 +87,13 @@ func (s *teamAccesses) List(ctx context.Context, options TeamAccessListOptions)
return nil, err
}
var tas []*TeamAccess
err = s.client.do(ctx, req, &tas)
tal := &TeamAccessList{}
err = s.client.do(ctx, req, tal)
if err != nil {
return nil, err
}
return tas, nil
return tal, nil
}
// TeamAccessAddOptions represents the options for adding team access.
@ -96,7 +102,7 @@ type TeamAccessAddOptions struct {
ID string `jsonapi:"primary,team-workspaces"`
// The type of access to grant.
Access *TeamAccessType `jsonapi:"attr,access"`
Access *AccessType `jsonapi:"attr,access"`
// The team to add to the workspace
Team *Team `jsonapi:"relation,team"`

View File

@ -16,6 +16,9 @@ var _ TeamMembers = (*teamMembers)(nil)
// TFE API docs:
// https://www.terraform.io/docs/enterprise/api/team-members.html
type TeamMembers interface {
// List all members of a team.
List(ctx context.Context, teamID string) ([]*User, error)
// Add multiple users to a team.
Add(ctx context.Context, teamID string, options TeamMemberAddOptions) error
@ -32,6 +35,33 @@ type teamMember struct {
Username string `jsonapi:"primary,users"`
}
// List all members of a team.
func (s *teamMembers) List(ctx context.Context, teamID string) ([]*User, error) {
if !validStringID(&teamID) {
return nil, errors.New("Invalid value for team ID")
}
options := struct {
Include string `url:"include"`
}{
Include: "users",
}
u := fmt.Sprintf("teams/%s", url.QueryEscape(teamID))
req, err := s.client.newRequest("GET", u, options)
if err != nil {
return nil, err
}
t := &Team{}
err = s.client.do(ctx, req, t)
if err != nil {
return nil, err
}
return t.Users, nil
}
// TeamMemberAddOptions represents the options for adding team members.
type TeamMemberAddOptions struct {
Usernames []string

View File

@ -20,6 +20,9 @@ type TeamTokens interface {
// Generate a new team token, replacing any existing token.
Generate(ctx context.Context, teamID string) (*TeamToken, error)
// Read a team token by its ID.
Read(ctx context.Context, teamID string) (*TeamToken, error)
// Delete a team token by its ID.
Delete(ctx context.Context, teamID string) error
}
@ -59,6 +62,27 @@ func (s *teamTokens) Generate(ctx context.Context, teamID string) (*TeamToken, e
return tt, err
}
// Read a team token by its ID.
func (s *teamTokens) Read(ctx context.Context, teamID string) (*TeamToken, error) {
if !validStringID(&teamID) {
return nil, errors.New("Invalid value for team ID")
}
u := fmt.Sprintf("teams/%s/authentication-token", url.QueryEscape(teamID))
req, err := s.client.newRequest("GET", u, nil)
if err != nil {
return nil, err
}
tt := &TeamToken{}
err = s.client.do(ctx, req, tt)
if err != nil {
return nil, err
}
return tt, err
}
// Delete a team token by its ID.
func (s *teamTokens) Delete(ctx context.Context, teamID string) error {
if !validStringID(&teamID) {

View File

@ -174,6 +174,15 @@ type ListOptions struct {
PageSize int `url:"page[size],omitempty"`
}
// Pagination is used to return the pagination details of an API request.
type Pagination struct {
CurrentPage int `json:"current-page"`
PreviousPage int `json:"prev-page"`
NextPage int `json:"next-page"`
TotalPages int `json:"total-pages"`
TotalCount int `json:"total-count"`
}
// newRequest creates an API request. A relative URL path can be provided in
// path, in which case it is resolved relative to the apiVersionPath of the
// Client. Relative URL paths should always be specified without a preceding
@ -208,7 +217,7 @@ func (c *Client) newRequest(method, path string, v interface{}) (*http.Request,
}
u.RawQuery = q.Encode()
}
case "PATCH", "POST":
case "DELETE", "PATCH", "POST":
req.Header.Set("Accept", "application/vnd.api+json")
req.Header.Set("Content-Type", "application/vnd.api+json")
@ -245,11 +254,13 @@ func (c *Client) newRequest(method, path string, v interface{}) (*http.Request,
return req, nil
}
// do sends an API request and returns the API response. The API response is
// JSONAPI decoded and stored in the value pointed to by v, or returned as an
// error if an API error has occurred.
// do sends an API request and returns the API response. The API response
// is JSONAPI decoded and the document's primary data is stored in the value
// pointed to by v, or returned as an error if an API error has occurred.
// If v implements the io.Writer interface, the raw response body will be
// written to v, without attempting to first decode it.
//
// The provided ctx must be non-nil. If it is canceled or times out, ctx.Err()
// will be returned.
func (c *Client) do(ctx context.Context, req *http.Request, v interface{}) error {
@ -286,22 +297,41 @@ func (c *Client) do(ctx context.Context, req *http.Request, v interface{}) error
return err
}
// Get the value of v so we can test if it's a slice.
// Get the value of v so we can test if it's a struct.
dst := reflect.Indirect(reflect.ValueOf(v))
// Unmarshal a single value if v isn't a slice.
if dst.Type().Kind() != reflect.Slice {
// Return an error if v is not a struct or an io.Writer.
if dst.Kind() != reflect.Struct {
return fmt.Errorf("v must be a struct or an io.Writer")
}
// Try to get the Items and Pagination struct fields.
items := dst.FieldByName("Items")
pagination := dst.FieldByName("Pagination")
// Unmarshal a single value if v does not contain the
// Items and Pagination struct fields.
if !items.IsValid() || !pagination.IsValid() {
return jsonapi.UnmarshalPayload(resp.Body, v)
}
// Unmarshal as a list of values if v is a slice.
raw, err := jsonapi.UnmarshalManyPayload(resp.Body, dst.Type().Elem())
// Return an error if v.Items is not a slice.
if items.Type().Kind() != reflect.Slice {
return fmt.Errorf("v.Items must be a slice")
}
// Create a temporary buffer and copy all the read data into it.
body := bytes.NewBuffer(nil)
reader := io.TeeReader(resp.Body, body)
// Unmarshal as a list of values as v.Items is a slice.
raw, err := jsonapi.UnmarshalManyPayload(reader, items.Type().Elem())
if err != nil {
return err
}
// Make a new slice to hold the results.
sliceType := reflect.SliceOf(dst.Type().Elem())
sliceType := reflect.SliceOf(items.Type().Elem())
result := reflect.MakeSlice(sliceType, 0, len(raw))
// Add all of the results to the new slice.
@ -310,11 +340,36 @@ func (c *Client) do(ctx context.Context, req *http.Request, v interface{}) error
}
// Pointer-swap the result.
dst.Set(result)
items.Set(result)
// As we are getting a list of values, we need to decode
// the pagination details out of the response body.
p, err := parsePagination(body)
if err != nil {
return err
}
// Pointer-swap the decoded pagination details.
pagination.Set(reflect.ValueOf(p))
return nil
}
func parsePagination(body io.Reader) (*Pagination, error) {
var raw struct {
Meta struct {
Pagination Pagination `json:"pagination"`
} `json:"meta"`
}
// JSON decode the raw response.
if err := json.NewDecoder(body).Decode(&raw); err != nil {
return &Pagination{}, err
}
return &raw.Meta.Pagination, nil
}
// checkResponseCode can be used to check the status code of an HTTP request.
func checkResponseCode(r *http.Response) error {
if r.StatusCode >= 200 && r.StatusCode <= 299 {

View File

@ -1,7 +1,7 @@
package tfe
// Access returns a pointer to the given team access type.
func Access(v TeamAccessType) *TeamAccessType {
func Access(v AccessType) *AccessType {
return &v
}
@ -25,6 +25,11 @@ func EnforcementMode(v EnforcementLevel) *EnforcementLevel {
return &v
}
// Int returns a pointer to the given int.
func Int(v int) *int {
return &v
}
// Int64 returns a pointer to the given int64.
func Int64(v int64) *int64 {
return &v

View File

@ -16,7 +16,7 @@ var _ Variables = (*variables)(nil)
// TFE API docs: https://www.terraform.io/docs/enterprise/api/variables.html
type Variables interface {
// List all the variables associated with the given workspace.
List(ctx context.Context, options VariableListOptions) ([]*Variable, error)
List(ctx context.Context, options VariableListOptions) (*VariableList, error)
// Create is used to create a new variable.
Create(ctx context.Context, options VariableCreateOptions) (*Variable, error)
@ -42,6 +42,12 @@ const (
CategoryTerraform CategoryType = "terraform"
)
// VariableList represents a list of variables.
type VariableList struct {
*Pagination
Items []*Variable
}
// Variable represents a Terraform Enterprise variable.
type Variable struct {
ID string `jsonapi:"primary,vars"`
@ -73,7 +79,7 @@ func (o VariableListOptions) valid() error {
}
// List all the variables associated with the given workspace.
func (s *variables) List(ctx context.Context, options VariableListOptions) ([]*Variable, error) {
func (s *variables) List(ctx context.Context, options VariableListOptions) (*VariableList, error) {
if err := options.valid(); err != nil {
return nil, err
}
@ -83,13 +89,13 @@ func (s *variables) List(ctx context.Context, options VariableListOptions) ([]*V
return nil, err
}
var vs []*Variable
err = s.client.do(ctx, req, &vs)
vl := &VariableList{}
err = s.client.do(ctx, req, vl)
if err != nil {
return nil, err
}
return vs, nil
return vl, nil
}
// VariableCreateOptions represents the options for creating a new variable.
@ -166,9 +172,6 @@ type VariableUpdateOptions struct {
// The value of the variable.
Value *string `jsonapi:"attr,value,omitempty"`
// Whether this is a Terraform or environment variable.
Category *CategoryType `jsonapi:"attr,category,omitempty"`
// Whether to evaluate the value of the variable as a string of HCL code.
HCL *bool `jsonapi:"attr,hcl,omitempty"`

View File

@ -17,7 +17,7 @@ var _ Workspaces = (*workspaces)(nil)
// TFE API docs: https://www.terraform.io/docs/enterprise/api/workspaces.html
type Workspaces interface {
// List all the workspaces within an organization.
List(ctx context.Context, organization string, options WorkspaceListOptions) ([]*Workspace, error)
List(ctx context.Context, organization string, options WorkspaceListOptions) (*WorkspaceList, error)
// Create is used to create a new workspace.
Create(ctx context.Context, organization string, options WorkspaceCreateOptions) (*Workspace, error)
@ -49,6 +49,12 @@ type workspaces struct {
client *Client
}
// WorkspaceList represents a list of workspaces.
type WorkspaceList struct {
*Pagination
Items []*Workspace
}
// Workspace represents a Terraform Enterprise workspace.
type Workspace struct {
ID string `jsonapi:"primary,workspaces"`
@ -74,7 +80,7 @@ type Workspace struct {
type VCSRepo struct {
Branch string `json:"branch"`
Identifier string `json:"identifier"`
IncludeSubmodules bool `json:"ingress-submodules"`
IngressSubmodules bool `json:"ingress-submodules"`
OAuthTokenID string `json:"oauth-token-id"`
}
@ -97,10 +103,13 @@ type WorkspacePermissions struct {
// WorkspaceListOptions represents the options for listing workspaces.
type WorkspaceListOptions struct {
ListOptions
// A search string (partial workspace name) used to filter the results.
Search *string `url:"search[name],omitempty"`
}
// List all the workspaces within an organization.
func (s *workspaces) List(ctx context.Context, organization string, options WorkspaceListOptions) ([]*Workspace, error) {
func (s *workspaces) List(ctx context.Context, organization string, options WorkspaceListOptions) (*WorkspaceList, error) {
if !validStringID(&organization) {
return nil, errors.New("Invalid value for organization")
}
@ -111,13 +120,13 @@ func (s *workspaces) List(ctx context.Context, organization string, options Work
return nil, err
}
var ws []*Workspace
err = s.client.do(ctx, req, &ws)
wl := &WorkspaceList{}
err = s.client.do(ctx, req, wl)
if err != nil {
return nil, err
}
return ws, nil
return wl, nil
}
// WorkspaceCreateOptions represents the options for creating a new workspace.
@ -157,7 +166,7 @@ type WorkspaceCreateOptions struct {
type VCSRepoOptions struct {
Branch *string `json:"branch,omitempty"`
Identifier *string `json:"identifier,omitempty"`
IncludeSubmodules *bool `json:"ingress-submodules,omitempty"`
IngressSubmodules *bool `json:"ingress-submodules,omitempty"`
OAuthTokenID *string `json:"oauth-token-id,omitempty"`
}

6
vendor/vendor.json vendored
View File

@ -1804,10 +1804,10 @@
"revisionTime": "2018-07-12T07:51:27Z"
},
{
"checksumSHA1": "926/ijhO8KTdgb02B/++x3w+Ykc=",
"checksumSHA1": "Xo/jovk4kg+1xHsdyfTtBhcLkXo=",
"path": "github.com/hashicorp/go-tfe",
"revision": "0e7cd8ef626181232db2d6886263a3db937708cd",
"revisionTime": "2018-08-01T08:24:33Z"
"revision": "6781009f2a64d61df9aff58f17427f0ef43abad0",
"revisionTime": "2018-09-08T08:19:18Z"
},
{
"checksumSHA1": "85XUnluYJL7F55ptcwdmN8eSOsk=",