mirror of
https://github.com/opentofu/opentofu.git
synced 2024-12-24 16:10:46 -06:00
Merge pull request #21102 from hashicorp/pault/remote-backend-go-tfe-update
update to latest go-tfe
This commit is contained in:
commit
6183ca44c8
@ -227,6 +227,57 @@ func (b *Remote) parseVariableValues(op *backend.Operation) (terraform.InputValu
|
||||
return result, diags
|
||||
}
|
||||
|
||||
func (b *Remote) costEstimation(stopCtx, cancelCtx context.Context, op *backend.Operation, r *tfe.Run) error {
|
||||
if r.CostEstimation == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if b.CLI != nil {
|
||||
b.CLI.Output("\n------------------------------------------------------------------------\n")
|
||||
}
|
||||
|
||||
logs, err := b.client.CostEstimations.Logs(stopCtx, r.CostEstimation.ID)
|
||||
if err != nil {
|
||||
return generalError("Failed to retrieve cost estimation logs", err)
|
||||
}
|
||||
scanner := bufio.NewScanner(logs)
|
||||
|
||||
// Retrieve the cost estimation to get its current status.
|
||||
ce, err := b.client.CostEstimations.Read(stopCtx, r.CostEstimation.ID)
|
||||
if err != nil {
|
||||
return generalError("Failed to retrieve cost estimation", err)
|
||||
}
|
||||
|
||||
msgPrefix := "Cost estimation"
|
||||
if b.CLI != nil {
|
||||
b.CLI.Output(b.Colorize().Color(msgPrefix + ":\n"))
|
||||
}
|
||||
|
||||
for scanner.Scan() {
|
||||
if b.CLI != nil {
|
||||
b.CLI.Output(b.Colorize().Color(scanner.Text()))
|
||||
}
|
||||
}
|
||||
|
||||
if err := scanner.Err(); err != nil {
|
||||
return generalError("Failed to read logs", err)
|
||||
}
|
||||
|
||||
switch ce.Status {
|
||||
case tfe.CostEstimationFinished:
|
||||
if len(r.PolicyChecks) == 0 && r.HasChanges && op.Type == backend.OperationTypeApply && b.CLI != nil {
|
||||
b.CLI.Output("\n------------------------------------------------------------------------")
|
||||
}
|
||||
return nil
|
||||
case tfe.CostEstimationErrored:
|
||||
return fmt.Errorf(msgPrefix + " errored.")
|
||||
case tfe.CostEstimationCanceled:
|
||||
return fmt.Errorf(msgPrefix + " canceled.")
|
||||
default:
|
||||
return fmt.Errorf("Unknown or unexpected cost estimation state: %s", ce.Status)
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Remote) checkPolicy(stopCtx, cancelCtx context.Context, op *backend.Operation, r *tfe.Run) error {
|
||||
if b.CLI != nil {
|
||||
b.CLI.Output("\n------------------------------------------------------------------------\n")
|
||||
|
@ -21,6 +21,7 @@ import (
|
||||
type mockClient struct {
|
||||
Applies *mockApplies
|
||||
ConfigurationVersions *mockConfigurationVersions
|
||||
CostEstimations *mockCostEstimations
|
||||
Organizations *mockOrganizations
|
||||
Plans *mockPlans
|
||||
PolicyChecks *mockPolicyChecks
|
||||
@ -33,6 +34,7 @@ func newMockClient() *mockClient {
|
||||
c := &mockClient{}
|
||||
c.Applies = newMockApplies(c)
|
||||
c.ConfigurationVersions = newMockConfigurationVersions(c)
|
||||
c.CostEstimations = newMockCostEstimations(c)
|
||||
c.Organizations = newMockOrganizations(c)
|
||||
c.Plans = newMockPlans(c)
|
||||
c.PolicyChecks = newMockPolicyChecks(c)
|
||||
@ -212,6 +214,84 @@ func (m *mockConfigurationVersions) Upload(ctx context.Context, url, path string
|
||||
return nil
|
||||
}
|
||||
|
||||
type mockCostEstimations struct {
|
||||
client *mockClient
|
||||
estimations map[string]*tfe.CostEstimation
|
||||
logs map[string]string
|
||||
}
|
||||
|
||||
func newMockCostEstimations(client *mockClient) *mockCostEstimations {
|
||||
return &mockCostEstimations{
|
||||
client: client,
|
||||
estimations: make(map[string]*tfe.CostEstimation),
|
||||
logs: make(map[string]string),
|
||||
}
|
||||
}
|
||||
|
||||
// create is a helper function to create a mock cost estimation that uses the
|
||||
// configured working directory to find the logfile.
|
||||
func (m *mockCostEstimations) create(cvID, workspaceID string) (*tfe.CostEstimation, error) {
|
||||
id := generateID("ce-")
|
||||
|
||||
ce := &tfe.CostEstimation{
|
||||
ID: id,
|
||||
Status: tfe.CostEstimationQueued,
|
||||
}
|
||||
|
||||
w, ok := m.client.Workspaces.workspaceIDs[workspaceID]
|
||||
if !ok {
|
||||
return nil, tfe.ErrResourceNotFound
|
||||
}
|
||||
|
||||
logfile := filepath.Join(
|
||||
m.client.ConfigurationVersions.uploadPaths[cvID],
|
||||
w.WorkingDirectory,
|
||||
"ce.log",
|
||||
)
|
||||
|
||||
if _, err := os.Stat(logfile); os.IsNotExist(err) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
m.logs[ce.ID] = logfile
|
||||
m.estimations[ce.ID] = ce
|
||||
|
||||
return ce, nil
|
||||
}
|
||||
|
||||
func (m *mockCostEstimations) Read(ctx context.Context, costEstimationID string) (*tfe.CostEstimation, error) {
|
||||
ce, ok := m.estimations[costEstimationID]
|
||||
if !ok {
|
||||
return nil, tfe.ErrResourceNotFound
|
||||
}
|
||||
return ce, nil
|
||||
}
|
||||
|
||||
func (m *mockCostEstimations) Logs(ctx context.Context, costEstimationID string) (io.Reader, error) {
|
||||
ce, ok := m.estimations[costEstimationID]
|
||||
if !ok {
|
||||
return nil, tfe.ErrResourceNotFound
|
||||
}
|
||||
|
||||
logfile, ok := m.logs[ce.ID]
|
||||
if !ok {
|
||||
return nil, tfe.ErrResourceNotFound
|
||||
}
|
||||
|
||||
if _, err := os.Stat(logfile); os.IsNotExist(err) {
|
||||
return bytes.NewBufferString("logfile does not exist"), nil
|
||||
}
|
||||
|
||||
logs, err := ioutil.ReadFile(logfile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ce.Status = tfe.CostEstimationFinished
|
||||
|
||||
return bytes.NewBuffer(logs), nil
|
||||
}
|
||||
|
||||
// mockInput is a mock implementation of terraform.UIInput.
|
||||
type mockInput struct {
|
||||
answers map[string]string
|
||||
@ -652,19 +732,25 @@ func (m *mockRuns) Create(ctx context.Context, options tfe.RunCreateOptions) (*t
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ce, err := m.client.CostEstimations.create(options.ConfigurationVersion.ID, options.Workspace.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pc, err := m.client.PolicyChecks.create(options.ConfigurationVersion.ID, options.Workspace.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
r := &tfe.Run{
|
||||
ID: generateID("run-"),
|
||||
Actions: &tfe.RunActions{IsCancelable: true},
|
||||
Apply: a,
|
||||
HasChanges: false,
|
||||
Permissions: &tfe.RunPermissions{},
|
||||
Plan: p,
|
||||
Status: tfe.RunPending,
|
||||
ID: generateID("run-"),
|
||||
Actions: &tfe.RunActions{IsCancelable: true},
|
||||
Apply: a,
|
||||
CostEstimation: ce,
|
||||
HasChanges: false,
|
||||
Permissions: &tfe.RunPermissions{},
|
||||
Plan: p,
|
||||
Status: tfe.RunPending,
|
||||
}
|
||||
|
||||
if pc != nil {
|
||||
|
@ -290,6 +290,14 @@ func (b *Remote) plan(stopCtx, cancelCtx context.Context, op *backend.Operation,
|
||||
return r, nil
|
||||
}
|
||||
|
||||
// Show any cost estimation output.
|
||||
if r.CostEstimation != nil {
|
||||
err = b.costEstimation(stopCtx, cancelCtx, op, r)
|
||||
if err != nil {
|
||||
return r, err
|
||||
}
|
||||
}
|
||||
|
||||
// Check any configured sentinel policies.
|
||||
if len(r.PolicyChecks) > 0 {
|
||||
err = b.checkPolicy(stopCtx, cancelCtx, op, r)
|
||||
|
@ -655,6 +655,40 @@ func TestRemote_planWithWorkingDirectory(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemote_costEstimation(t *testing.T) {
|
||||
b, bCleanup := testBackendDefault(t)
|
||||
defer bCleanup()
|
||||
|
||||
op, configCleanup := testOperationPlan(t, "./test-fixtures/plan-cost-estimation")
|
||||
defer configCleanup()
|
||||
|
||||
op.Workspace = backend.DefaultStateName
|
||||
|
||||
run, err := b.Operation(context.Background(), op)
|
||||
if err != nil {
|
||||
t.Fatalf("error starting operation: %v", err)
|
||||
}
|
||||
|
||||
<-run.Done()
|
||||
if run.Result != backend.OperationSuccess {
|
||||
t.Fatalf("operation failed: %s", b.CLI.(*cli.MockUi).ErrorWriter.String())
|
||||
}
|
||||
if run.PlanEmpty {
|
||||
t.Fatalf("expected a non-empty plan")
|
||||
}
|
||||
|
||||
output := b.CLI.(*cli.MockUi).OutputWriter.String()
|
||||
if !strings.Contains(output, "Running plan in the remote backend") {
|
||||
t.Fatalf("expected remote backend header in output: %s", output)
|
||||
}
|
||||
if !strings.Contains(output, "SKU") {
|
||||
t.Fatalf("expected cost estimation result in output: %s", output)
|
||||
}
|
||||
if !strings.Contains(output, "1 to add, 0 to change, 0 to destroy") {
|
||||
t.Fatalf("expected plan summary in output: %s", output)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemote_planPolicyPass(t *testing.T) {
|
||||
b, bCleanup := testBackendDefault(t)
|
||||
defer bCleanup()
|
||||
@ -681,12 +715,12 @@ func TestRemote_planPolicyPass(t *testing.T) {
|
||||
if !strings.Contains(output, "Running plan in the remote backend") {
|
||||
t.Fatalf("expected remote backend header in output: %s", output)
|
||||
}
|
||||
if !strings.Contains(output, "1 to add, 0 to change, 0 to destroy") {
|
||||
t.Fatalf("expected plan summery in output: %s", output)
|
||||
}
|
||||
if !strings.Contains(output, "Sentinel Result: true") {
|
||||
t.Fatalf("expected policy check result in output: %s", output)
|
||||
}
|
||||
if !strings.Contains(output, "1 to add, 0 to change, 0 to destroy") {
|
||||
t.Fatalf("expected plan summery in output: %s", output)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemote_planPolicyHardFail(t *testing.T) {
|
||||
@ -720,12 +754,12 @@ func TestRemote_planPolicyHardFail(t *testing.T) {
|
||||
if !strings.Contains(output, "Running plan in the remote backend") {
|
||||
t.Fatalf("expected remote backend header in output: %s", output)
|
||||
}
|
||||
if !strings.Contains(output, "1 to add, 0 to change, 0 to destroy") {
|
||||
t.Fatalf("expected plan summery in output: %s", output)
|
||||
}
|
||||
if !strings.Contains(output, "Sentinel Result: false") {
|
||||
t.Fatalf("expected policy check result in output: %s", output)
|
||||
}
|
||||
if !strings.Contains(output, "1 to add, 0 to change, 0 to destroy") {
|
||||
t.Fatalf("expected plan summery in output: %s", output)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemote_planPolicySoftFail(t *testing.T) {
|
||||
@ -759,12 +793,12 @@ func TestRemote_planPolicySoftFail(t *testing.T) {
|
||||
if !strings.Contains(output, "Running plan in the remote backend") {
|
||||
t.Fatalf("expected remote backend header in output: %s", output)
|
||||
}
|
||||
if !strings.Contains(output, "1 to add, 0 to change, 0 to destroy") {
|
||||
t.Fatalf("expected plan summery in output: %s", output)
|
||||
}
|
||||
if !strings.Contains(output, "Sentinel Result: false") {
|
||||
t.Fatalf("expected policy check result in output: %s", output)
|
||||
}
|
||||
if !strings.Contains(output, "1 to add, 0 to change, 0 to destroy") {
|
||||
t.Fatalf("expected plan summery in output: %s", output)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemote_planWithRemoteError(t *testing.T) {
|
||||
|
6
backend/remote/test-fixtures/plan-cost-estimation/ce.log
Normal file
6
backend/remote/test-fixtures/plan-cost-estimation/ce.log
Normal file
@ -0,0 +1,6 @@
|
||||
+---------+------+-----+-------------+----------------------+
|
||||
| PRODUCT | NAME | SKU | DESCRIPTION | DELTA |
|
||||
+---------+------+-----+-------------+----------------------+
|
||||
+---------+------+-----+-------------+----------------------+
|
||||
| TOTAL | $0.000 USD / 720 HRS |
|
||||
+---------+------+-----+-------------+----------------------+
|
@ -0,0 +1 @@
|
||||
resource "null_resource" "foo" {}
|
21
backend/remote/test-fixtures/plan-cost-estimation/plan.log
Normal file
21
backend/remote/test-fixtures/plan-cost-estimation/plan.log
Normal file
@ -0,0 +1,21 @@
|
||||
Terraform v0.11.7
|
||||
|
||||
Configuring remote state backend...
|
||||
Initializing Terraform configuration...
|
||||
Refreshing Terraform state in-memory prior to plan...
|
||||
The refreshed state will be used to calculate this plan, but will not be
|
||||
persisted to local or remote state storage.
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
An execution plan has been generated and is shown below.
|
||||
Resource actions are indicated with the following symbols:
|
||||
+ create
|
||||
|
||||
Terraform will perform the following actions:
|
||||
|
||||
+ null_resource.foo
|
||||
id: <computed>
|
||||
|
||||
|
||||
Plan: 1 to add, 0 to change, 0 to destroy.
|
@ -115,6 +115,7 @@ func testBackend(t *testing.T, obj cty.Value) (*Remote, func()) {
|
||||
b.CLI = cli.NewMockUi()
|
||||
b.client.Applies = mc.Applies
|
||||
b.client.ConfigurationVersions = mc.ConfigurationVersions
|
||||
b.client.CostEstimations = mc.CostEstimations
|
||||
b.client.Organizations = mc.Organizations
|
||||
b.client.Plans = mc.Plans
|
||||
b.client.PolicyChecks = mc.PolicyChecks
|
||||
|
2
go.mod
2
go.mod
@ -55,7 +55,7 @@ require (
|
||||
github.com/hashicorp/go-retryablehttp v0.5.2
|
||||
github.com/hashicorp/go-rootcerts v1.0.0
|
||||
github.com/hashicorp/go-sockaddr v0.0.0-20180320115054-6d291a969b86 // indirect
|
||||
github.com/hashicorp/go-tfe v0.3.14
|
||||
github.com/hashicorp/go-tfe v0.3.16
|
||||
github.com/hashicorp/go-uuid v1.0.1
|
||||
github.com/hashicorp/go-version v1.1.0
|
||||
github.com/hashicorp/golang-lru v0.5.0 // indirect
|
||||
|
4
go.sum
4
go.sum
@ -191,8 +191,8 @@ github.com/hashicorp/go-slug v0.3.0 h1:L0c+AvH/J64iMNF4VqRaRku2DMTEuHioPVS7kMjWI
|
||||
github.com/hashicorp/go-slug v0.3.0/go.mod h1:I5tq5Lv0E2xcNXNkmx7BSfzi1PsJ2cNjs3cC3LwyhK8=
|
||||
github.com/hashicorp/go-sockaddr v0.0.0-20180320115054-6d291a969b86 h1:7YOlAIO2YWnJZkQp7B5eFykaIY7C9JndqAFQyVV5BhM=
|
||||
github.com/hashicorp/go-sockaddr v0.0.0-20180320115054-6d291a969b86/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
|
||||
github.com/hashicorp/go-tfe v0.3.14 h1:1eWmq4RAICGufydNUWu7ahb0gtq24pN9jatD2FkdxdE=
|
||||
github.com/hashicorp/go-tfe v0.3.14/go.mod h1:SuPHR+OcxvzBZNye7nGPfwZTEyd3rWPfLVbCgyZPezM=
|
||||
github.com/hashicorp/go-tfe v0.3.16 h1:GS2yv580p0co4j3FBVaC6Zahd9mxdCGehhJ0qqzFMH0=
|
||||
github.com/hashicorp/go-tfe v0.3.16/go.mod h1:SuPHR+OcxvzBZNye7nGPfwZTEyd3rWPfLVbCgyZPezM=
|
||||
github.com/hashicorp/go-uuid v1.0.0 h1:RS8zrF7PhGwyNPOtxSClXXj9HA8feRnJzgnI1RJCSnM=
|
||||
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE=
|
||||
|
121
vendor/github.com/hashicorp/go-tfe/cost_estimation.go
generated
vendored
Normal file
121
vendor/github.com/hashicorp/go-tfe/cost_estimation.go
generated
vendored
Normal file
@ -0,0 +1,121 @@
|
||||
package tfe
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/url"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Compile-time proof of interface implementation.
|
||||
var _ CostEstimations = (*costEstimations)(nil)
|
||||
|
||||
// CostEstimations describes all the costEstimation related methods that
|
||||
// the Terraform Enterprise API supports.
|
||||
//
|
||||
// TFE API docs: https://www.terraform.io/docs/enterprise/api/ (TBD)
|
||||
type CostEstimations interface {
|
||||
// Read a costEstimation by its ID.
|
||||
Read(ctx context.Context, costEstimationID string) (*CostEstimation, error)
|
||||
|
||||
// Logs retrieves the logs of a costEstimation.
|
||||
Logs(ctx context.Context, costEstimationID string) (io.Reader, error)
|
||||
}
|
||||
|
||||
// costEstimations implements CostEstimations.
|
||||
type costEstimations struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// CostEstimationStatus represents a costEstimation state.
|
||||
type CostEstimationStatus string
|
||||
|
||||
//List all available costEstimation statuses.
|
||||
const (
|
||||
CostEstimationCanceled CostEstimationStatus = "canceled"
|
||||
CostEstimationErrored CostEstimationStatus = "errored"
|
||||
CostEstimationFinished CostEstimationStatus = "finished"
|
||||
CostEstimationQueued CostEstimationStatus = "queued"
|
||||
)
|
||||
|
||||
// CostEstimation represents a Terraform Enterprise costEstimation.
|
||||
type CostEstimation struct {
|
||||
ID string `jsonapi:"primary,cost-estimations"`
|
||||
ErrorMessage string `jsonapi:"attr,error-message"`
|
||||
Status CostEstimationStatus `jsonapi:"attr,status"`
|
||||
StatusTimestamps *CostEstimationStatusTimestamps `jsonapi:"attr,status-timestamps"`
|
||||
}
|
||||
|
||||
// CostEstimationStatusTimestamps holds the timestamps for individual costEstimation statuses.
|
||||
type CostEstimationStatusTimestamps struct {
|
||||
CanceledAt time.Time `json:"canceled-at"`
|
||||
ErroredAt time.Time `json:"errored-at"`
|
||||
FinishedAt time.Time `json:"finished-at"`
|
||||
QueuedAt time.Time `json:"queued-at"`
|
||||
}
|
||||
|
||||
// Read a costEstimation by its ID.
|
||||
func (s *costEstimations) Read(ctx context.Context, costEstimationID string) (*CostEstimation, error) {
|
||||
if !validStringID(&costEstimationID) {
|
||||
return nil, errors.New("invalid value for cost estimation ID")
|
||||
}
|
||||
|
||||
u := fmt.Sprintf("cost-estimations/%s", url.QueryEscape(costEstimationID))
|
||||
req, err := s.client.newRequest("GET", u, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ce := &CostEstimation{}
|
||||
err = s.client.do(ctx, req, ce)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ce, nil
|
||||
}
|
||||
|
||||
// Logs retrieves the logs of a costEstimation.
|
||||
func (s *costEstimations) Logs(ctx context.Context, costEstimationID string) (io.Reader, error) {
|
||||
if !validStringID(&costEstimationID) {
|
||||
return nil, errors.New("invalid value for cost estimation ID")
|
||||
}
|
||||
|
||||
// Loop until the context is canceled or the cost estimation is finished
|
||||
// running. The cost estimation logs are not streamed and so only available
|
||||
// once the estimation is finished.
|
||||
for {
|
||||
// Get the costEstimation to make sure it exists.
|
||||
ce, err := s.Read(ctx, costEstimationID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
switch ce.Status {
|
||||
case CostEstimationQueued:
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil, ctx.Err()
|
||||
case <-time.After(500 * time.Millisecond):
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
u := fmt.Sprintf("cost-estimations/%s/output", url.QueryEscape(costEstimationID))
|
||||
req, err := s.client.newRequest("GET", u, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
logs := bytes.NewBuffer(nil)
|
||||
err = s.client.do(ctx, req, logs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return logs, nil
|
||||
}
|
||||
}
|
7
vendor/github.com/hashicorp/go-tfe/organization.go
generated
vendored
7
vendor/github.com/hashicorp/go-tfe/organization.go
generated
vendored
@ -77,6 +77,7 @@ type OrganizationList struct {
|
||||
type Organization struct {
|
||||
Name string `jsonapi:"primary,organizations"`
|
||||
CollaboratorAuthPolicy AuthPolicyType `jsonapi:"attr,collaborator-auth-policy"`
|
||||
CostEstimationEnabled bool `jsonapi:"attr,cost-estimation-enabled"`
|
||||
CreatedAt time.Time `jsonapi:"attr,created-at,iso8601"`
|
||||
Email string `jsonapi:"attr,email"`
|
||||
EnterprisePlan EnterprisePlanType `jsonapi:"attr,enterprise-plan"`
|
||||
@ -167,6 +168,9 @@ type OrganizationCreateOptions struct {
|
||||
// Authentication policy.
|
||||
CollaboratorAuthPolicy *AuthPolicyType `jsonapi:"attr,collaborator-auth-policy,omitempty"`
|
||||
|
||||
// Enable Cost Estimation
|
||||
CostEstimationEnabled *bool `jsonapi:"attr,cost-estimation-enabled,omitempty"`
|
||||
|
||||
// The name of the "owners" team
|
||||
OwnersTeamSAMLRoleID *string `jsonapi:"attr,owners-team-saml-role-id,omitempty"`
|
||||
}
|
||||
@ -248,6 +252,9 @@ type OrganizationUpdateOptions struct {
|
||||
// Authentication policy.
|
||||
CollaboratorAuthPolicy *AuthPolicyType `jsonapi:"attr,collaborator-auth-policy,omitempty"`
|
||||
|
||||
// Enable Cost Estimation
|
||||
CostEstimationEnabled *bool `jsonapi:"attr,cost-estimation-enabled,omitempty"`
|
||||
|
||||
// The name of the "owners" team
|
||||
OwnersTeamSAMLRoleID *string `jsonapi:"attr,owners-team-saml-role-id,omitempty"`
|
||||
}
|
||||
|
7
vendor/github.com/hashicorp/go-tfe/run.go
generated
vendored
7
vendor/github.com/hashicorp/go-tfe/run.go
generated
vendored
@ -49,12 +49,16 @@ type RunStatus string
|
||||
//List all available run statuses.
|
||||
const (
|
||||
RunApplied RunStatus = "applied"
|
||||
RunApplyQueued RunStatus = "apply_queued"
|
||||
RunApplying RunStatus = "applying"
|
||||
RunCanceled RunStatus = "canceled"
|
||||
RunConfirmed RunStatus = "confirmed"
|
||||
RunCostEstimated RunStatus = "cost_estimated"
|
||||
RunCostEstimating RunStatus = "cost_estimating"
|
||||
RunDiscarded RunStatus = "discarded"
|
||||
RunErrored RunStatus = "errored"
|
||||
RunPending RunStatus = "pending"
|
||||
RunPlanQueued RunStatus = "plan_queued"
|
||||
RunPlanned RunStatus = "planned"
|
||||
RunPlannedAndFinished RunStatus = "planned_and_finished"
|
||||
RunPlanning RunStatus = "planning"
|
||||
@ -98,6 +102,7 @@ type Run struct {
|
||||
// Relations
|
||||
Apply *Apply `jsonapi:"relation,apply"`
|
||||
ConfigurationVersion *ConfigurationVersion `jsonapi:"relation,configuration-version"`
|
||||
CostEstimation *CostEstimation `jsonapi:"relation,cost-estimation"`
|
||||
Plan *Plan `jsonapi:"relation,plan"`
|
||||
PolicyChecks []*PolicyCheck `jsonapi:"relation,policy-checks"`
|
||||
Workspace *Workspace `jsonapi:"relation,workspace"`
|
||||
@ -274,7 +279,7 @@ func (s *runs) Cancel(ctx context.Context, runID string, options RunCancelOption
|
||||
return s.client.do(ctx, req, nil)
|
||||
}
|
||||
|
||||
// RunCancelOptions represents the options for force-canceling a run.
|
||||
// RunForceCancelOptions represents the options for force-canceling a run.
|
||||
type RunForceCancelOptions struct {
|
||||
// An optional comment explaining the reason for the force-cancel.
|
||||
Comment *string `json:"comment,omitempty"`
|
||||
|
4
vendor/github.com/hashicorp/go-tfe/tfe.go
generated
vendored
4
vendor/github.com/hashicorp/go-tfe/tfe.go
generated
vendored
@ -106,6 +106,7 @@ type Client struct {
|
||||
|
||||
Applies Applies
|
||||
ConfigurationVersions ConfigurationVersions
|
||||
CostEstimations CostEstimations
|
||||
NotificationConfigurations NotificationConfigurations
|
||||
OAuthClients OAuthClients
|
||||
OAuthTokens OAuthTokens
|
||||
@ -195,6 +196,7 @@ func NewClient(cfg *Config) (*Client, error) {
|
||||
// Create the services.
|
||||
client.Applies = &applies{client: client}
|
||||
client.ConfigurationVersions = &configurationVersions{client: client}
|
||||
client.CostEstimations = &costEstimations{client: client}
|
||||
client.NotificationConfigurations = ¬ificationConfigurations{client: client}
|
||||
client.OAuthClients = &oAuthClients{client: client}
|
||||
client.OAuthTokens = &oAuthTokens{client: client}
|
||||
@ -247,7 +249,7 @@ func (c *Client) retryHTTPBackoff(min, max time.Duration, attemptNum int, resp *
|
||||
}
|
||||
|
||||
// Use the rate limit backoff function when we are rate limited.
|
||||
if resp.StatusCode == 429 {
|
||||
if resp != nil && resp.StatusCode == 429 {
|
||||
return rateLimitBackoff(min, max, attemptNum, resp)
|
||||
}
|
||||
|
||||
|
2
vendor/modules.txt
vendored
2
vendor/modules.txt
vendored
@ -290,7 +290,7 @@ github.com/hashicorp/go-rootcerts
|
||||
github.com/hashicorp/go-safetemp
|
||||
# github.com/hashicorp/go-slug v0.3.0
|
||||
github.com/hashicorp/go-slug
|
||||
# github.com/hashicorp/go-tfe v0.3.14
|
||||
# github.com/hashicorp/go-tfe v0.3.16
|
||||
github.com/hashicorp/go-tfe
|
||||
# github.com/hashicorp/go-uuid v1.0.1
|
||||
github.com/hashicorp/go-uuid
|
||||
|
Loading…
Reference in New Issue
Block a user