Skip to content

Commit

Permalink
Merge branch 'main' into netramali/TF-22972-add-project-varset-permis…
Browse files Browse the repository at this point in the history
…sion-to-team-project
  • Loading branch information
netramali authored Jan 9, 2025
2 parents 79d0852 + 2b26a23 commit 5c2d6f0
Show file tree
Hide file tree
Showing 19 changed files with 957 additions and 69 deletions.
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
# Unreleased

# v1.73.0

## Enhancements

* Add support for team notification configurations @notchairmk [#1016](https://github.com/hashicorp/go-tfe/pull/1016)

# v1.72.0

## Enhancements

* Add support for project level auto destroy settings @simonxmh [#1011](https://github.com/hashicorp/go-tfe/pull/1011)
* Add BETA support for Linux arm64 agents, which is EXPERIMENTAL, SUBJECT TO CHANGE, and may not be available to all users @natalie-todd [#1022](https://github.com/hashicorp/go-tfe/pull/1022)
* Adds support to delete all tag bindings on either a project or workspace by @sebasslash [#1023](https://github.com/hashicorp/go-tfe/pull/1023)

# v1.71.0

## Enhancements
Expand Down
54 changes: 38 additions & 16 deletions admin_terraform_version.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,19 @@ import (
"context"
"fmt"
"net/url"
"reflect"
"time"
)

// Compile-time proof of interface implementation.
var _ AdminTerraformVersions = (*adminTerraformVersions)(nil)

const (
linux = "linux"
amd64 = "amd64"
arm64 = "arm64"
)

// AdminTerraformVersions describes all the admin terraform versions related methods that
// the Terraform Enterprise API supports.
// Note that admin terraform versions are only available in Terraform Enterprise.
Expand Down Expand Up @@ -55,6 +62,13 @@ type AdminTerraformVersion struct {
CreatedAt time.Time `jsonapi:"attr,created-at,iso8601"`
}

type ToolVersionArchitecture struct {
URL string `jsonapi:"attr,url"`
Sha string `jsonapi:"attr,sha"`
OS string `jsonapi:"attr,os"`
Arch string `jsonapi:"attr,arch"`
}

// AdminTerraformVersionsListOptions represents the options for listing
// terraform versions.
type AdminTerraformVersionsListOptions struct {
Expand All @@ -70,15 +84,16 @@ type AdminTerraformVersionsListOptions struct {
// AdminTerraformVersionCreateOptions for creating a terraform version.
// https://developer.hashicorp.com/terraform/enterprise/api-docs/admin/terraform-versions#request-body
type AdminTerraformVersionCreateOptions struct {
Type string `jsonapi:"primary,terraform-versions"`
Version *string `jsonapi:"attr,version"` // Required
URL *string `jsonapi:"attr,url"` // Required
Sha *string `jsonapi:"attr,sha"` // Required
Official *bool `jsonapi:"attr,official,omitempty"`
Deprecated *bool `jsonapi:"attr,deprecated,omitempty"`
DeprecatedReason *string `jsonapi:"attr,deprecated-reason,omitempty"`
Enabled *bool `jsonapi:"attr,enabled,omitempty"`
Beta *bool `jsonapi:"attr,beta,omitempty"`
Type string `jsonapi:"primary,terraform-versions"`
Version *string `jsonapi:"attr,version"` // Required
URL *string `jsonapi:"attr,url"` // Required
Sha *string `jsonapi:"attr,sha"` // Required
Official *bool `jsonapi:"attr,official,omitempty"`
Deprecated *bool `jsonapi:"attr,deprecated,omitempty"`
DeprecatedReason *string `jsonapi:"attr,deprecated-reason,omitempty"`
Enabled *bool `jsonapi:"attr,enabled,omitempty"`
Beta *bool `jsonapi:"attr,beta,omitempty"`
Archs []*ToolVersionArchitecture `jsonapi:"attr,archs,omitempty"`
}

// AdminTerraformVersionUpdateOptions for updating terraform version.
Expand Down Expand Up @@ -194,18 +209,25 @@ func (a *adminTerraformVersions) Delete(ctx context.Context, id string) error {
}

func (o AdminTerraformVersionCreateOptions) valid() error {
if (o == AdminTerraformVersionCreateOptions{}) {
if (reflect.DeepEqual(o, AdminTerraformVersionCreateOptions{})) {
return ErrRequiredTFVerCreateOps
}
if !validString(o.Version) {
return ErrRequiredVersion
}
if !validString(o.URL) {
return ErrRequiredURL
if !o.validArch() && (!validString(o.URL) || !validString(o.Sha)) {
return ErrRequiredArchOrURLAndSha
}
if !validString(o.Sha) {
return ErrRequiredSha
}

return nil
}

func (o AdminTerraformVersionCreateOptions) validArch() bool {
var valid bool
for _, a := range o.Archs {
valid = validString(&a.URL) && validString(&a.Sha) && a.OS == linux && (a.Arch == amd64 || a.Arch == arm64)
if valid {
break
}
}
return valid
}
16 changes: 15 additions & 1 deletion admin_terraform_version_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,15 +103,22 @@ func TestAdminTerraformVersions_CreateDelete(t *testing.T) {
version := genSafeRandomTerraformVersion()

t.Run("with valid options", func(t *testing.T) {
sha := String(genSha(t))
opts := AdminTerraformVersionCreateOptions{
Version: String(version),
URL: String("https://www.hashicorp.com"),
Sha: String(genSha(t)),
Sha: sha,
Deprecated: Bool(true),
DeprecatedReason: String("Test Reason"),
Official: Bool(false),
Enabled: Bool(false),
Beta: Bool(false),
Archs: []*ToolVersionArchitecture{{
URL: "https://www.hashicorp.com",
Sha: *sha,
OS: linux,
Arch: amd64,
}},
}
tfv, err := client.Admin.TerraformVersions.Create(ctx, opts)
require.NoError(t, err)
Expand Down Expand Up @@ -170,6 +177,7 @@ func TestAdminTerraformVersions_ReadUpdate(t *testing.T) {

t.Run("reads and updates", func(t *testing.T) {
version := genSafeRandomTerraformVersion()
sha := String(genSha(t))
opts := AdminTerraformVersionCreateOptions{
Version: String(version),
URL: String("https://www.hashicorp.com"),
Expand All @@ -179,6 +187,12 @@ func TestAdminTerraformVersions_ReadUpdate(t *testing.T) {
DeprecatedReason: String("Test Reason"),
Enabled: Bool(false),
Beta: Bool(false),
Archs: []*ToolVersionArchitecture{{
URL: "https://www.hashicorp.com",
Sha: *sha,
OS: linux,
Arch: amd64,
}},
}
tfv, err := client.Admin.TerraformVersions.Create(ctx, opts)
require.NoError(t, err)
Expand Down
2 changes: 2 additions & 0 deletions errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,8 @@ var (

ErrRequiredURL = errors.New("url is required")

ErrRequiredArchOrURLAndSha = errors.New("valid arch or url and sha is required")

ErrRequiredAPIURL = errors.New("API URL is required")

ErrRequiredHTTPURL = errors.New("HTTP URL is required")
Expand Down
57 changes: 57 additions & 0 deletions examples/projects/main.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 main

import (
"context"
"log"

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

"github.com/hashicorp/jsonapi"
)

func main() {
config := &tfe.Config{
Token: "insert-your-token-here",
RetryServerErrors: true,
}

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

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

// Create a new project
p, err := client.Projects.Create(ctx, "org-test", tfe.ProjectCreateOptions{
Name: "my-app-tst",
})
if err != nil {
log.Fatal(err)
}

// Update the project auto destroy activity duration
p, err = client.Projects.Update(ctx, p.ID, tfe.ProjectUpdateOptions{
AutoDestroyActivityDuration: jsonapi.NewNullableAttrWithValue("3d"),
})
if err != nil {
log.Fatal(err)
}

// Disable auto destroy
p, err = client.Projects.Update(ctx, p.ID, tfe.ProjectUpdateOptions{
AutoDestroyActivityDuration: jsonapi.NewNullNullableAttr[string](),
})
if err != nil {
log.Fatal(err)
}

err = client.Projects.Delete(ctx, p.ID)
if err != nil {
log.Fatal(err)
}
}
14 changes: 8 additions & 6 deletions examples/workspaces/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,21 @@ func main() {

// Create a new workspace
w, err := client.Workspaces.Create(ctx, "org-name", tfe.WorkspaceCreateOptions{
Name: tfe.String("my-app-tst"),
AutoDestroyAt: tfe.NullableTime(time.Date(2025, 1, 1, 0, 0, 0, 0, time.UTC)),
Name: tfe.String("my-app-tst"),
AutoDestroyAt: tfe.NullableTime(time.Date(2025, 1, 1, 0, 0, 0, 0, time.UTC)),
InheritsProjectAutoDestroy: tfe.Bool(false),
})
if err != nil {
log.Fatal(err)
}

// Update the workspace
w, err = client.Workspaces.Update(ctx, "org-name", w.Name, tfe.WorkspaceUpdateOptions{
AutoApply: tfe.Bool(false),
TerraformVersion: tfe.String("0.11.1"),
WorkingDirectory: tfe.String("my-app/infra"),
AutoDestroyAt: tfe.NullableTime(time.Date(2025, 1, 1, 0, 0, 0, 0, time.UTC)),
AutoApply: tfe.Bool(false),
TerraformVersion: tfe.String("0.11.1"),
WorkingDirectory: tfe.String("my-app/infra"),
AutoDestroyAt: tfe.NullableTime(time.Date(2025, 1, 1, 0, 0, 0, 0, time.UTC)),
InheritsProjectAutoDestroy: tfe.Bool(false),
})
if err != nil {
log.Fatal(err)
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ require (
github.com/hashicorp/go-slug v0.16.0
github.com/hashicorp/go-uuid v1.0.3
github.com/hashicorp/go-version v1.7.0
github.com/hashicorp/jsonapi v1.3.1
github.com/hashicorp/jsonapi v1.3.2
github.com/stretchr/testify v1.9.0
go.uber.org/mock v0.4.0
golang.org/x/sync v0.8.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/C
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY=
github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/jsonapi v1.3.1 h1:GtPvnmcWgYwCuDGvYT5VZBHcUyFdq9lSyCzDjn1DdPo=
github.com/hashicorp/jsonapi v1.3.1/go.mod h1:kWfdn49yCjQvbpnvY1dxxAuAFzISwrrMDQOcu6NsFoM=
github.com/hashicorp/jsonapi v1.3.2 h1:gP3fX2ZT7qXi+PbwieptzkspIohO2kCSiBUvUTBAbMs=
github.com/hashicorp/jsonapi v1.3.2/go.mod h1:kWfdn49yCjQvbpnvY1dxxAuAFzISwrrMDQOcu6NsFoM=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
Expand Down
49 changes: 49 additions & 0 deletions helper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -615,6 +615,55 @@ func createNotificationConfiguration(t *testing.T, client *Client, w *Workspace,
}
}

func createTeamNotificationConfiguration(t *testing.T, client *Client, team *Team, options *NotificationConfigurationCreateOptions) (*NotificationConfiguration, func()) {
var tCleanup func()

if team == nil {
team, tCleanup = createTeam(t, client, nil)
}

// Team notification configurations do not actually require a run task, but we'll
// reuse this as a URL that returns a 200.
runTaskURL := os.Getenv("TFC_RUN_TASK_URL")
if runTaskURL == "" {
t.Error("You must set TFC_RUN_TASK_URL for run task related tests.")
}

if options == nil {
options = &NotificationConfigurationCreateOptions{
DestinationType: NotificationDestination(NotificationDestinationTypeGeneric),
Enabled: Bool(false),
Name: String(randomString(t)),
Token: String(randomString(t)),
URL: String(runTaskURL),
Triggers: []NotificationTriggerType{NotificationTriggerChangeRequestCreated},
SubscribableChoice: &NotificationConfigurationSubscribableChoice{Team: team},
}
}

ctx := context.Background()
nc, err := client.NotificationConfigurations.Create(
ctx,
team.ID,
*options,
)
if err != nil {
t.Fatal(err)
}

return nc, func() {
if err := client.NotificationConfigurations.Delete(ctx, nc.ID); err != nil {
t.Errorf("Error destroying team notification configuration! WARNING: Dangling\n"+
"resources may exist! The full error is shown below.\n\n"+
"NotificationConfiguration: %s\nError: %s", nc.ID, err)
}

if tCleanup != nil {
tCleanup()
}
}
}

func createPolicySetParameter(t *testing.T, client *Client, ps *PolicySet) (*PolicySetParameter, func()) {
var psCleanup func()

Expand Down
16 changes: 8 additions & 8 deletions mocks/notification_configuration_mocks.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions mocks/project_mocks.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 5c2d6f0

Please sign in to comment.