Skip to content

Commit

Permalink
Merge branch 'main' into barrett/update-codeowners
Browse files Browse the repository at this point in the history
  • Loading branch information
barrettclark committed Apr 22, 2024
2 parents 1b6b6b2 + 85eac5e commit f0ba673
Show file tree
Hide file tree
Showing 21 changed files with 536 additions and 120 deletions.
2 changes: 1 addition & 1 deletion .github/actions/test-go-tfe/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ runs:
GO111MODULE: "on"
ENABLE_TFE: ${{ inputs.enterprise }}
run: |
gotestsum --junitfile summary.xml --format short-verbose -- -timeout=29m -run "${{ steps.test_split.outputs.run }}"
gotestsum --junitfile summary.xml --format short-verbose -- -parallel=1 -timeout=29m -run "${{ steps.test_split.outputs.run }}"
- name: Upload test artifacts
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ jobs:
fail-fast: false
matrix:
# If you adjust these parameters, also adjust the jrm input files on the "Merge reports" step below
total: [ 4 ]
index: [ 0, 1, 2, 3 ]
total: [ 1 ]
index: [ 0 ]

timeout-minutes: 30
steps:
Expand Down Expand Up @@ -73,7 +73,7 @@ jobs:
run: npm install -g junit-report-merger

- name: Merge reports
run: jrm ./ci-summary.xml "junit-test-summary-0/*.xml" "junit-test-summary-1/*.xml" "junit-test-summary-2/*.xml" "junit-test-summary-3/*.xml"
run: jrm ./ci-summary.xml "junit-test-summary-0/*.xml"

- name: Upload test artifacts
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/nightly-tfe-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ jobs:
strategy:
fail-fast: false
matrix:
total: [ 4 ]
index: [ 0, 1, 2, 3 ]
total: [ 1 ]
index: [ 0 ]

steps:
- name: terraform-cloud/outputs
Expand Down
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
# Unreleased

## Enhancements
* Adds `Teams` field to `OrganizationMembershipCreateOptions` to allow users to be added to teams at the same time they are invited to an organization. @JarrettSpiker [#886](https://github.com/hashicorp/go-tfe/pull/886)

# v1.50.0

## Enhancements
* Adds Bitbucket Data Center as a new `ServiceProviderType` and ensures similar validation as Bitbucket Server by @zainq11 [#879](https://github.com/hashicorp/go-tfe/pull/879)
* Add `GlobalRunTasks` field to `Entitlements`. by @glennsarti [#865](https://github.com/hashicorp/go-tfe/pull/865)
* Add `Global` field to `RunTask`. by @glennsarti [#865](https://github.com/hashicorp/go-tfe/pull/865)
* Add `Stages` field to `WorkspaceRunTask`. by @glennsarti [#865](https://github.com/hashicorp/go-tfe/pull/865)
* Changing BETA `OrganizationScoped` attribute of `OAuthClient` to be a pointer for bug fix by @netramali [884](https://github.com/hashicorp/go-tfe/pull/884)
* Adds `Query` parameter to `VariableSetListOptions` to allow searching variable sets by name, by @JarrettSpiker[#877](https://github.com/hashicorp/go-tfe/pull/877)

## Deprecations
* The `Stage` field has been deprecated on `WorkspaceRunTask`. Instead, use `Stages`. by @glennsarti [#865](https://github.com/hashicorp/go-tfe/pull/865)

# v1.49.0

Expand Down
10 changes: 10 additions & 0 deletions META.d/_summary.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---

schema: 1.1
partition: tfc
category: library

summary:
owner: team-tf-cli
description: Terraform Cloud/Enterprise API Client/SDK in Golang
visibility: external
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ require (
github.com/google/go-querystring v1.1.0
github.com/hashicorp/go-cleanhttp v0.5.2
github.com/hashicorp/go-retryablehttp v0.7.5
github.com/hashicorp/go-slug v0.14.0
github.com/hashicorp/go-slug v0.15.0
github.com/hashicorp/go-uuid v1.0.3
github.com/hashicorp/go-version v1.6.0
github.com/hashicorp/jsonapi v1.3.1
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ github.com/hashicorp/go-hclog v0.9.2 h1:CG6TE5H9/JXsFWJCfoIVpKFIkFe6ysEuHirp4DxC
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
github.com/hashicorp/go-retryablehttp v0.7.5 h1:bJj+Pj19UZMIweq/iie+1u5YCdGrnxCT9yvm0e+Nd5M=
github.com/hashicorp/go-retryablehttp v0.7.5/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8=
github.com/hashicorp/go-slug v0.14.0 h1:/aZdUDjR74TSlsQp3hA9nqhCQkQHAUr2jjtuUfWqI9E=
github.com/hashicorp/go-slug v0.14.0/go.mod h1:THWVTAXwJEinbsp4/bBRcmbaO5EYNLTqxbG4tZ3gCYQ=
github.com/hashicorp/go-slug v0.15.0 h1:AhMnE6JIyW0KoDJlmRDwv4xd52a5ZK3VdioQ7SMmZhI=
github.com/hashicorp/go-slug v0.15.0/go.mod h1:THWVTAXwJEinbsp4/bBRcmbaO5EYNLTqxbG4tZ3gCYQ=
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek=
Expand Down
74 changes: 4 additions & 70 deletions helper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import (
"io"
"math/rand"
"net/http"
"net/url"
"os"
"os/exec"
"path/filepath"
Expand All @@ -38,31 +37,6 @@ const agentVersion = "1.3.0"

var _testAccountDetails *TestAccountDetails

type featureSet struct {
ID string `jsonapi:"primary,feature-sets"`
}

type featureSetList struct {
Items []*featureSet
*Pagination
}

type featureSetListOptions struct {
Q string `url:"q,omitempty"`
}

type retryableFn func() (interface{}, error)

type updateFeatureSetOptions struct {
Type string `jsonapi:"primary,subscription"`
RunsCeiling int `jsonapi:"attr,runs-ceiling"`
ContractStartAt time.Time `jsonapi:"attr,contract-start-at,iso8601"`
ContractUserLimit int `jsonapi:"attr,contract-user-limit"`
ContractApplyLimit int `jsonapi:"attr,contract-apply-limit"`

FeatureSet *featureSet `jsonapi:"relation,feature-set"`
}

func testClient(t *testing.T) *Client {
client, err := NewClient(&Config{
RetryServerErrors: true,
Expand Down Expand Up @@ -959,7 +933,7 @@ func createOrganizationWithOptions(t *testing.T, client *Client, options Organiz
ctx := context.Background()
org, err := client.Organizations.Create(ctx, options)
if err != nil {
t.Fatal(err)
t.Fatalf("Failed to create organization: %s", err)
}

return org, func() {
Expand Down Expand Up @@ -2526,49 +2500,9 @@ func createVariableSetVariable(t *testing.T, client *Client, vs *VariableSet, op
}

// Attempts to upgrade an organization to the business plan. Requires a user token with admin access.
func upgradeOrganizationSubscription(t *testing.T, client *Client, organization *Organization) {
if enterpriseEnabled() {
t.Skip("Cannot upgrade an organization's subscription when enterprise is enabled. Set ENABLE_TFE=0 to run.")
}

adminClient := testAdminClient(t, provisionLicensesAdmin)
req, err := adminClient.NewRequest("GET", "admin/feature-sets", featureSetListOptions{
Q: "Business",
})
if err != nil {
t.Fatal(err)
return
}

fsl := &featureSetList{}
err = req.Do(context.Background(), fsl)
if err != nil {
t.Fatalf("failed to enumerate feature sets: %v", err)
return
} else if len(fsl.Items) == 0 {
t.Fatalf("feature set response was empty")
return
}

opts := updateFeatureSetOptions{
RunsCeiling: 10,
ContractStartAt: time.Now(),
ContractUserLimit: 1000,
ContractApplyLimit: 5000,
FeatureSet: fsl.Items[0],
}

u := fmt.Sprintf("admin/organizations/%s/subscription", url.QueryEscape(organization.Name))
req, err = adminClient.NewRequest("POST", u, &opts)
if err != nil {
t.Fatalf("Failed to create request: %v", err)
return
}

err = req.Do(context.Background(), nil)
if err != nil {
t.Fatalf("Failed to upgrade subscription: %v", err)
}
// DEPRECATED : Please use the newSubscriptionUpdater instead.
func upgradeOrganizationSubscription(t *testing.T, _ *Client, organization *Organization) {
newSubscriptionUpdater(organization).WithBusinessPlan().Update(t)
}

func createProject(t *testing.T, client *Client, org *Organization) (*Project, func()) {
Expand Down
103 changes: 103 additions & 0 deletions internal_run_task.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package tfe

// A private struct we need for unmarshalling
type internalRunTask struct {
ID string `jsonapi:"primary,tasks"`
Name string `jsonapi:"attr,name"`
URL string `jsonapi:"attr,url"`
Description string `jsonapi:"attr,description"`
Category string `jsonapi:"attr,category"`
HMACKey *string `jsonapi:"attr,hmac-key,omitempty"`
Enabled bool `jsonapi:"attr,enabled"`
RawGlobal map[string]interface{} `jsonapi:"attr,global-configuration,omitempty"`

Organization *Organization `jsonapi:"relation,organization"`
WorkspaceRunTasks []*internalWorkspaceRunTask `jsonapi:"relation,workspace-tasks"`
}

// Due to https://github.com/google/jsonapi/issues/74 we must first unmarshall using map[string]interface{}
// and then perform our own conversion from the map into a GlobalRunTask struct
func (irt internalRunTask) ToRunTask() *RunTask {
obj := RunTask{
ID: irt.ID,
Name: irt.Name,
URL: irt.URL,
Description: irt.Description,
Category: irt.Category,
HMACKey: irt.HMACKey,
Enabled: irt.Enabled,

Organization: irt.Organization,
}

// Convert the WorkspaceRunTasks
workspaceTasks := make([]*WorkspaceRunTask, len(irt.WorkspaceRunTasks))
for idx, rawTask := range irt.WorkspaceRunTasks {
if rawTask != nil {
workspaceTasks[idx] = rawTask.ToWorkspaceRunTask()
}
}
obj.WorkspaceRunTasks = workspaceTasks

// Check if the global configuration exists
if val, ok := irt.RawGlobal["enabled"]; !ok {
// The enabled property is required so we can assume now that the
// global configuration was not supplied
return &obj
} else if boolVal, ok := val.(bool); !ok {
// The enabled property exists but it is invalid (Couldn't cast to boolean)
// so assume the global configuration was not supplied
return &obj
} else {
obj.Global = &GlobalRunTask{
Enabled: boolVal,
}
}

// Global Enforcement Level
if val, ok := irt.RawGlobal["enforcement-level"]; ok {
if stringVal, ok := val.(string); ok {
obj.Global.EnforcementLevel = TaskEnforcementLevel(stringVal)
}
}

// Global Stages
if val, ok := irt.RawGlobal["stages"]; ok {
if stringsVal, ok := val.([]interface{}); ok {
obj.Global.Stages = make([]Stage, len(stringsVal))
for idx, stageName := range stringsVal {
if stringVal, ok := stageName.(string); ok {
obj.Global.Stages[idx] = Stage(stringVal)
}
}
}
}

return &obj
}

// A private struct we need for unmarshalling
type internalRunTaskList struct {
*Pagination
Items []*internalRunTask
}

// Due to https://github.com/google/jsonapi/issues/74 we must first unmarshall using
// the internal RunTask struct and convert that a RunTask
func (irt internalRunTaskList) ToRunTaskList() *RunTaskList {
obj := RunTaskList{
Pagination: irt.Pagination,
Items: make([]*RunTask, len(irt.Items)),
}

for idx, src := range irt.Items {
if src != nil {
obj.Items[idx] = src.ToRunTask()
}
}

return &obj
}
57 changes: 57 additions & 0 deletions internal_workspace_run_task.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package tfe

// A private struct we need for unmarshalling
type internalWorkspaceRunTask struct {
ID string `jsonapi:"primary,workspace-tasks"`
EnforcementLevel TaskEnforcementLevel `jsonapi:"attr,enforcement-level"`
Stage Stage `jsonapi:"attr,stage"`
Stages []string `jsonapi:"attr,stages"`

RunTask *RunTask `jsonapi:"relation,task"`
Workspace *Workspace `jsonapi:"relation,workspace"`
}

// Due to https://github.com/google/jsonapi/issues/74 we must first unmarshall using map[string]interface{}
// and then perform our own conversion for the Stages
func (irt internalWorkspaceRunTask) ToWorkspaceRunTask() *WorkspaceRunTask {
obj := WorkspaceRunTask{
ID: irt.ID,
EnforcementLevel: irt.EnforcementLevel,
Stage: irt.Stage,
Stages: make([]Stage, len(irt.Stages)),
RunTask: irt.RunTask,
Workspace: irt.Workspace,
}

for idx, val := range irt.Stages {
obj.Stages[idx] = Stage(val)
}

return &obj
}

// A private struct we need for unmarshalling
type internalWorkspaceRunTaskList struct {
*Pagination
Items []*internalWorkspaceRunTask
}

// Due to https://github.com/google/jsonapi/issues/74 we must first unmarshall using
// the internal WorkspaceRunTask struct and convert that a WorkspaceRunTask
func (irt internalWorkspaceRunTaskList) ToWorkspaceRunTaskList() *WorkspaceRunTaskList {
obj := WorkspaceRunTaskList{
Pagination: irt.Pagination,
Items: make([]*WorkspaceRunTask, len(irt.Items)),
}

for idx, src := range irt.Items {
if src != nil {
obj.Items[idx] = src.ToWorkspaceRunTask()
}
}

return &obj
}
2 changes: 1 addition & 1 deletion oauth_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ type OAuthClient struct {
ServiceProvider ServiceProviderType `jsonapi:"attr,service-provider"`
ServiceProviderName string `jsonapi:"attr,service-provider-display-name"`
// **Note: This field is still in BETA and subject to change.**
OrganizationScoped bool `jsonapi:"attr,organization-scoped"`
OrganizationScoped *bool `jsonapi:"attr,organization-scoped"`

// Relations
Organization *Organization `jsonapi:"relation,organization"`
Expand Down
1 change: 1 addition & 0 deletions organization.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ type Entitlements struct {
Agents bool `jsonapi:"attr,agents"`
AuditLogging bool `jsonapi:"attr,audit-logging"`
CostEstimation bool `jsonapi:"attr,cost-estimation"`
GlobalRunTasks bool `jsonapi:"attr,global-run-tasks"`
Operations bool `jsonapi:"attr,operations"`
PrivateModuleRegistry bool `jsonapi:"attr,private-module-registry"`
RunTasks bool `jsonapi:"attr,run-tasks"`
Expand Down
3 changes: 3 additions & 0 deletions organization_membership.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ type OrganizationMembershipCreateOptions struct {

// Required: User's email address.
Email *string `jsonapi:"attr,email"`

// Optional: A list of teams in the organization to add the user to
Teams []*Team `jsonapi:"relation,teams,omitempty"`
}

// OrganizationMembershipReadOptions represents the options for reading organization memberships.
Expand Down

0 comments on commit f0ba673

Please sign in to comment.