Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Admin Terraform Versions API (#186)
* Add Admin Terraform Versions
- Loading branch information
1 parent
3ecf508
commit 862478c
Showing
5 changed files
with
357 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,176 @@ | ||
package tfe | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"net/url" | ||
"time" | ||
) | ||
|
||
// Compile-time proof of interface implementation. | ||
var _ AdminTerraformVersions = (*adminTerraformVersions)(nil) | ||
|
||
// 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. | ||
// | ||
// TFE API docs: https://www.terraform.io/docs/cloud/api/admin/terraform-versions.html | ||
type AdminTerraformVersions interface { | ||
// List all the terraform versions. | ||
List(ctx context.Context, options AdminTerraformVersionsListOptions) (*AdminTerraformVersionsList, error) | ||
|
||
// Read a terraform version by its ID. | ||
Read(ctx context.Context, id string) (*AdminTerraformVersion, error) | ||
|
||
// Create a terraform version. | ||
Create(ctx context.Context, options AdminTerraformVersionCreateOptions) (*AdminTerraformVersion, error) | ||
|
||
// Update a terraform version. | ||
Update(ctx context.Context, id string, options AdminTerraformVersionUpdateOptions) (*AdminTerraformVersion, error) | ||
|
||
// Delete a terraform version | ||
Delete(ctx context.Context, id string) error | ||
} | ||
|
||
// adminTerraformVersions implements AdminTerraformVersions. | ||
type adminTerraformVersions struct { | ||
client *Client | ||
} | ||
|
||
// AdminTerraformVersion represents a Terraform Version | ||
type AdminTerraformVersion struct { | ||
ID string `jsonapi:"primary,terraform-versions"` | ||
Version string `jsonapi:"attr,version"` | ||
URL string `jsonapi:"attr,url"` | ||
Sha string `jsonapi:"attr,sha"` | ||
Official bool `jsonapi:"attr,official"` | ||
Enabled bool `jsonapi:"attr,enabled"` | ||
Beta bool `jsonapi:"attr,beta"` | ||
Usage int `jsonapi:"attr,usage"` | ||
CreatedAt time.Time `jsonapi:"attr,created-at,iso8601"` | ||
} | ||
|
||
// AdminTerraformVersionsListOptions represents the options for listing | ||
// terraform versions. | ||
type AdminTerraformVersionsListOptions struct { | ||
ListOptions | ||
} | ||
|
||
// AdminTerraformVersionsList represents a list of terraform versions. | ||
type AdminTerraformVersionsList struct { | ||
*Pagination | ||
Items []*AdminTerraformVersion | ||
} | ||
|
||
// List all the terraform versions. | ||
func (a *adminTerraformVersions) List(ctx context.Context, options AdminTerraformVersionsListOptions) (*AdminTerraformVersionsList, error) { | ||
req, err := a.client.newRequest("GET", "admin/terraform-versions", &options) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
tvl := &AdminTerraformVersionsList{} | ||
err = a.client.do(ctx, req, tvl) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return tvl, nil | ||
} | ||
|
||
// Read a terraform version by its ID. | ||
func (a *adminTerraformVersions) Read(ctx context.Context, id string) (*AdminTerraformVersion, error) { | ||
if !validStringID(&id) { | ||
return nil, ErrInvalidTerraformVersionID | ||
} | ||
|
||
u := fmt.Sprintf("admin/terraform-versions/%s", url.QueryEscape(id)) | ||
req, err := a.client.newRequest("GET", u, nil) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
tfv := &AdminTerraformVersion{} | ||
err = a.client.do(ctx, req, tfv) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return tfv, nil | ||
} | ||
|
||
// AdminTerraformVersionCreateOptions for creating a terraform version. | ||
// https://www.terraform.io/docs/cloud/api/admin/terraform-versions.html#request-body | ||
type AdminTerraformVersionCreateOptions struct { | ||
Type string `jsonapi:"primary,terraform-versions"` | ||
Version *string `jsonapi:"attr,version"` | ||
URL *string `jsonapi:"attr,url"` | ||
Sha *string `jsonapi:"attr,sha"` | ||
Official *bool `jsonapi:"attr,official"` | ||
Enabled *bool `jsonapi:"attr,enabled"` | ||
Beta *bool `jsonapi:"attr,beta"` | ||
} | ||
|
||
// Create a new terraform version. | ||
func (a *adminTerraformVersions) Create(ctx context.Context, options AdminTerraformVersionCreateOptions) (*AdminTerraformVersion, error) { | ||
req, err := a.client.newRequest("POST", "admin/terraform-versions", &options) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
tfv := &AdminTerraformVersion{} | ||
err = a.client.do(ctx, req, tfv) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return tfv, nil | ||
} | ||
|
||
// AdminTerraformVersionUpdateOptions for updating terraform version. | ||
// https://www.terraform.io/docs/cloud/api/admin/terraform-versions.html#request-body | ||
type AdminTerraformVersionUpdateOptions struct { | ||
Type string `jsonapi:"primary,terraform-versions"` | ||
Version *string `jsonapi:"attr,version,omitempty"` | ||
URL *string `jsonapi:"attr,url,omitempty"` | ||
Sha *string `jsonapi:"attr,sha,omitempty"` | ||
Official *bool `jsonapi:"attr,official,omitempty"` | ||
Enabled *bool `jsonapi:"attr,enabled,omitempty"` | ||
Beta *bool `jsonapi:"attr,beta,omitempty"` | ||
} | ||
|
||
// Update an existing terraform version. | ||
func (a *adminTerraformVersions) Update(ctx context.Context, id string, options AdminTerraformVersionUpdateOptions) (*AdminTerraformVersion, error) { | ||
if !validStringID(&id) { | ||
return nil, ErrInvalidTerraformVersionID | ||
} | ||
|
||
u := fmt.Sprintf("admin/terraform-versions/%s", url.QueryEscape(id)) | ||
req, err := a.client.newRequest("PATCH", u, &options) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
tfv := &AdminTerraformVersion{} | ||
err = a.client.do(ctx, req, tfv) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return tfv, nil | ||
} | ||
|
||
// Delete a terraform version. | ||
func (a *adminTerraformVersions) Delete(ctx context.Context, id string) error { | ||
if !validStringID(&id) { | ||
return ErrInvalidTerraformVersionID | ||
} | ||
|
||
u := fmt.Sprintf("admin/terraform-versions/%s", url.QueryEscape(id)) | ||
req, err := a.client.newRequest("DELETE", u, nil) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return a.client.do(ctx, req, nil) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
package tfe | ||
|
||
import ( | ||
"context" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestAdminTerraformVersions_List(t *testing.T) { | ||
skipIfCloud(t) | ||
|
||
client := testClient(t) | ||
ctx := context.Background() | ||
|
||
t.Run("without list options", func(t *testing.T) { | ||
tfList, err := client.Admin.TerraformVersions.List(ctx, AdminTerraformVersionsListOptions{}) | ||
require.NoError(t, err) | ||
|
||
assert.NotEmpty(t, tfList.Items) | ||
}) | ||
|
||
t.Run("with list options", func(t *testing.T) { | ||
tfList, err := client.Admin.TerraformVersions.List(ctx, AdminTerraformVersionsListOptions{ | ||
ListOptions: ListOptions{ | ||
PageNumber: 999, | ||
PageSize: 100, | ||
}, | ||
}) | ||
require.NoError(t, err) | ||
// Out of range page number, so the items should be empty | ||
assert.Empty(t, tfList.Items) | ||
assert.Equal(t, 999, tfList.CurrentPage) | ||
|
||
tfList, err = client.Admin.TerraformVersions.List(ctx, AdminTerraformVersionsListOptions{ | ||
ListOptions: ListOptions{ | ||
PageNumber: 1, | ||
PageSize: 100, | ||
}, | ||
}) | ||
require.NoError(t, err) | ||
assert.Equal(t, 1, tfList.CurrentPage) | ||
for _, item := range tfList.Items { | ||
assert.NotNil(t, item.ID) | ||
assert.NotNil(t, item.Version) | ||
assert.NotNil(t, item.URL) | ||
assert.NotNil(t, item.Sha) | ||
assert.NotNil(t, item.Official) | ||
assert.NotNil(t, item.Enabled) | ||
assert.NotNil(t, item.Beta) | ||
assert.NotNil(t, item.Usage) | ||
assert.NotNil(t, item.CreatedAt) | ||
} | ||
}) | ||
} | ||
|
||
func TestAdminTerraformVersions_CreateDelete(t *testing.T) { | ||
skipIfCloud(t) | ||
|
||
client := testClient(t) | ||
ctx := context.Background() | ||
|
||
t.Run("with valid options", func(t *testing.T) { | ||
opts := AdminTerraformVersionCreateOptions{ | ||
Version: String("1.1.1"), | ||
URL: String("https://www.hashicorp.com"), | ||
Sha: String(genSha("secret", "data")), | ||
Official: Bool(false), | ||
Enabled: Bool(false), | ||
Beta: Bool(false), | ||
} | ||
tfv, err := client.Admin.TerraformVersions.Create(ctx, opts) | ||
require.NoError(t, err) | ||
|
||
defer func() { | ||
deleteErr := client.Admin.TerraformVersions.Delete(ctx, tfv.ID) | ||
require.NoError(t, deleteErr) | ||
}() | ||
|
||
assert.Equal(t, *opts.Version, tfv.Version) | ||
assert.Equal(t, *opts.URL, tfv.URL) | ||
assert.Equal(t, *opts.Sha, tfv.Sha) | ||
assert.Equal(t, *opts.Official, tfv.Official) | ||
assert.Equal(t, *opts.Enabled, tfv.Enabled) | ||
assert.Equal(t, *opts.Beta, tfv.Beta) | ||
}) | ||
|
||
t.Run("with empty options", func(t *testing.T) { | ||
opts := AdminTerraformVersionCreateOptions{} | ||
|
||
_, err := client.Admin.TerraformVersions.Create(ctx, opts) | ||
require.Error(t, err) | ||
}) | ||
} | ||
|
||
func TestAdminTerraformVersions_ReadUpdate(t *testing.T) { | ||
skipIfCloud(t) | ||
|
||
client := testClient(t) | ||
ctx := context.Background() | ||
|
||
t.Run("reads and updates", func(t *testing.T) { | ||
opts := AdminTerraformVersionCreateOptions{ | ||
Version: String("1.1.1"), | ||
URL: String("https://www.hashicorp.com"), | ||
Sha: String(genSha("secret", "data")), | ||
Official: Bool(false), | ||
Enabled: Bool(false), | ||
Beta: Bool(false), | ||
} | ||
tfv, err := client.Admin.TerraformVersions.Create(ctx, opts) | ||
require.NoError(t, err) | ||
id := tfv.ID | ||
|
||
defer func() { | ||
deleteErr := client.Admin.TerraformVersions.Delete(ctx, id) | ||
require.NoError(t, deleteErr) | ||
}() | ||
|
||
tfv, err = client.Admin.TerraformVersions.Read(ctx, id) | ||
require.NoError(t, err) | ||
|
||
assert.Equal(t, *opts.Version, tfv.Version) | ||
assert.Equal(t, *opts.URL, tfv.URL) | ||
assert.Equal(t, *opts.Sha, tfv.Sha) | ||
assert.Equal(t, *opts.Official, tfv.Official) | ||
assert.Equal(t, *opts.Enabled, tfv.Enabled) | ||
assert.Equal(t, *opts.Beta, tfv.Beta) | ||
|
||
updateVersion := "1.1.2" | ||
updateURL := "https://app.terraform.io/" | ||
updateOpts := AdminTerraformVersionUpdateOptions{ | ||
Version: String(updateVersion), | ||
URL: String(updateURL), | ||
} | ||
|
||
tfv, err = client.Admin.TerraformVersions.Update(ctx, id, updateOpts) | ||
require.NoError(t, err) | ||
|
||
assert.Equal(t, updateVersion, tfv.Version) | ||
assert.Equal(t, updateURL, tfv.URL) | ||
assert.Equal(t, *opts.Sha, tfv.Sha) | ||
assert.Equal(t, *opts.Official, tfv.Official) | ||
assert.Equal(t, *opts.Enabled, tfv.Enabled) | ||
assert.Equal(t, *opts.Beta, tfv.Beta) | ||
}) | ||
|
||
t.Run("with non existant terraform version", func(t *testing.T) { | ||
randomID := "random-id" | ||
_, err := client.Admin.TerraformVersions.Read(ctx, randomID) | ||
require.Error(t, err) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters