Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# Unreleased

## Enhancements
* Exports the StackConfiguration UploadTarGzip receiver function[#1219](https://github.com/hashicorp/go-tfe/pull/1219)
* Exports the StackConfiguration UploadTarGzip receiver function [#1219](https://github.com/hashicorp/go-tfe/pull/1219)
* Updates BETA stacks resource schemas to match latest API spec by @ctrombley [#1220](https://github.com/hashicorp/go-tfe/pull/1220)

## Deprecations

Expand Down
4 changes: 4 additions & 0 deletions registry_provider_platform_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,8 @@ func TestRegistryProviderPlatformsDelete(t *testing.T) {
}

func TestRegistryProviderPlatformsRead(t *testing.T) {
t.Skip()

client := testClient(t)
ctx := context.Background()

Expand Down Expand Up @@ -290,6 +292,8 @@ func TestRegistryProviderPlatformsRead(t *testing.T) {
}

func TestRegistryProviderPlatformsList(t *testing.T) {
t.Skip()

client := testClient(t)
ctx := context.Background()

Expand Down
84 changes: 40 additions & 44 deletions stack.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ type Stacks interface {
List(ctx context.Context, organization string, options *StackListOptions) (*StackList, error)

// Read returns a stack by its ID.
Read(ctx context.Context, stackID string, options *StackReadOptions) (*Stack, error)
Read(ctx context.Context, stackID string) (*Stack, error)

// Create creates a new stack.
Create(ctx context.Context, options StackCreateOptions) (*Stack, error)
Expand All @@ -32,8 +32,8 @@ type Stacks interface {
// ForceDelete deletes a stack.
ForceDelete(ctx context.Context, stackID string) error

// UpdateConfiguration updates the configuration of a stack, triggering stack preparation.
UpdateConfiguration(ctx context.Context, stackID string) (*Stack, error)
// FetchLatestFromVcs updates the configuration of a stack, triggering stack preparation.
FetchLatestFromVcs(ctx context.Context, stackID string) (*Stack, error)
}

// stacks implements Stacks.
Expand Down Expand Up @@ -88,17 +88,18 @@ type Stack struct {
ID string `jsonapi:"primary,stacks"`
Name string `jsonapi:"attr,name"`
Description string `jsonapi:"attr,description"`
DeploymentNames []string `jsonapi:"attr,deployment-names"`
VCSRepo *StackVCSRepo `jsonapi:"attr,vcs-repo"`
ErrorsCount int `jsonapi:"attr,errors-count"`
WarningsCount int `jsonapi:"attr,warnings-count"`
SpeculativeEnabled bool `jsonapi:"attr,speculative-enabled"`
CreatedAt time.Time `jsonapi:"attr,created-at,iso8601"`
UpdatedAt time.Time `jsonapi:"attr,updated-at,iso8601"`
UpstreamCount int `jsonapi:"attr,upstream-count"`
DownstreamCount int `jsonapi:"attr,downstream-count"`
InputsCount int `jsonapi:"attr,inputs-count"`
OutputsCount int `jsonapi:"attr,outputs-count"`

// Relationships
AgentPool *AgentPool `jsonapi:"relation,agent-pool"`
Project *Project `jsonapi:"relation,project"`
AgentPool *AgentPool `jsonapi:"relation,agent-pool"`
LatestStackConfiguration *StackConfiguration `jsonapi:"relation,latest-stack-configuration"`
}

Expand All @@ -117,54 +118,49 @@ type StackComponent struct {
Name string `json:"name"`
Correlator string `json:"correlator"`
Expanded bool `json:"expanded"`
Removed bool `json:"removed"`
}

// StackConfiguration represents a stack configuration snapshot
type StackConfiguration struct {
// Attributes
ID string `jsonapi:"primary,stack-configurations"`
Status string `jsonapi:"attr,status"`
StatusTimestamps *StackConfigurationStatusTimestamps `jsonapi:"attr,status-timestamps"`
SequenceNumber int `jsonapi:"attr,sequence-number"`
DeploymentNames []string `jsonapi:"attr,deployment-names"`
ConvergedDeployments []string `jsonapi:"attr,converged-deployments"`
Components []*StackComponent `jsonapi:"attr,components"`
ErrorMessage *string `jsonapi:"attr,error-message"`
EventStreamURL string `jsonapi:"attr,event-stream-url"`
Diagnostics []*StackDiagnostic `jsonapi:"attr,diags"`
CreatedAt time.Time `jsonapi:"attr,created-at,iso8601"`
UpdatedAt time.Time `jsonapi:"attr,updated-at,iso8601"`

Stack *Stack `jsonapi:"relation,stack"`
ID string `jsonapi:"primary,stack-configurations"`
Status string `jsonapi:"attr,status"`
SequenceNumber int `jsonapi:"attr,sequence-number"`
Components []*StackComponent `jsonapi:"attr,components"`
PreparingEventStreamURL string `jsonapi:"attr,preparing-event-stream-url"`
CreatedAt time.Time `jsonapi:"attr,created-at,iso8601"`
UpdatedAt time.Time `jsonapi:"attr,updated-at,iso8601"`
Speculative bool `jsonapi:"attr,speculative"`

// Relationships
Stack *Stack `jsonapi:"relation,stack"`
IngressAttributes *IngressAttributes `jsonapi:"relation,ingress-attributes"`
}

// StackState represents a stack state
type StackState struct {
// Attributes
ID string `jsonapi:"primary,stack-states"`
}

// StackIncludeOpt represents the include options for a stack.
type StackIncludeOpt string
ID string `jsonapi:"primary,stack-states"`
Description string `jsonapi:"attr,description"`
Generation int `jsonapi:"attr,generation"`
Status string `jsonapi:"attr,status"`
Deployment string `jsonapi:"attr,deployment"`
Components string `jsonapi:"attr,components"`
IsCurrent bool `jsonapi:"attr,is-current"`
ResourceInstanceCount int `jsonapi:"attr,resource-instance-count"`

const (
StackIncludeOrganization StackIncludeOpt = "organization"
StackIncludeProject StackIncludeOpt = "project"
StackIncludeLatestStackConfiguration StackIncludeOpt = "latest_stack_configuration"
StackIncludeStackDiagnostics StackIncludeOpt = "stack_diagnostics"
)
// Relationships
Stack *Stack `jsonapi:"relation,stack"`
StackDeploymentRun *StackDeploymentRun `jsonapi:"relation,stack-deployment-run"`
}

// StackListOptions represents the options for listing stacks.
type StackListOptions struct {
ListOptions
ProjectID string `url:"filter[project[id]],omitempty"`
Sort StackSortColumn `url:"sort,omitempty"`
SearchByName string `url:"search[name],omitempty"`
Include []StackIncludeOpt `url:"include,omitempty"`
}

type StackReadOptions struct {
Include []StackIncludeOpt `url:"include,omitempty"`
ProjectID string `url:"filter[project[id]],omitempty"`
Sort StackSortColumn `url:"sort,omitempty"`
SearchByName string `url:"search[name],omitempty"`
}

// StackCreateOptions represents the options for creating a stack. The project
Expand Down Expand Up @@ -202,8 +198,8 @@ type WaitForStatusResult struct {
const minimumPollingIntervalMs = 3000
const maximumPollingIntervalMs = 5000

// UpdateConfiguration fetches the latest configuration of a stack from VCS, triggering stack operations
func (s *stacks) UpdateConfiguration(ctx context.Context, stackID string) (*Stack, error) {
// FetchLatestFromVcs fetches the latest configuration of a stack from VCS, triggering stack operations
func (s *stacks) FetchLatestFromVcs(ctx context.Context, stackID string) (*Stack, error) {
req, err := s.client.NewRequest("POST", fmt.Sprintf("stacks/%s/fetch-latest-from-vcs", url.PathEscape(stackID)), nil)
if err != nil {
return nil, err
Expand Down Expand Up @@ -239,8 +235,8 @@ func (s stacks) List(ctx context.Context, organization string, options *StackLis
}

// Read returns a stack by its ID.
func (s stacks) Read(ctx context.Context, stackID string, options *StackReadOptions) (*Stack, error) {
req, err := s.client.NewRequest("GET", fmt.Sprintf("stacks/%s", url.PathEscape(stackID)), options)
func (s stacks) Read(ctx context.Context, stackID string) (*Stack, error) {
req, err := s.client.NewRequest("GET", fmt.Sprintf("stacks/%s", url.PathEscape(stackID)), nil)
if err != nil {
return nil, err
}
Expand Down
4 changes: 1 addition & 3 deletions stack_configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,6 @@ const (
StackConfigurationStatusQueued StackConfigurationStatus = "queued"
StackConfigurationStatusPreparing StackConfigurationStatus = "preparing"
StackConfigurationStatusEnqueueing StackConfigurationStatus = "enqueueing"
StackConfigurationStatusConverged StackConfigurationStatus = "converged"
StackConfigurationStatusConverging StackConfigurationStatus = "converging"
StackConfigurationStatusErrored StackConfigurationStatus = "errored"
StackConfigurationStatusCanceled StackConfigurationStatus = "canceled"
StackConfigurationStatusCompleted StackConfigurationStatus = "completed"
Expand Down Expand Up @@ -117,7 +115,7 @@ func (s stackConfigurations) AwaitCompleted(ctx context.Context, stackConfigurat
}

return stackConfiguration.Status, nil
}, []string{StackConfigurationStatusConverged.String(), StackConfigurationStatusConverging.String(), StackConfigurationStatusCompleted.String(), StackConfigurationStatusErrored.String(), StackConfigurationStatusCanceled.String()})
}, []string{StackConfigurationStatusCompleted.String(), StackConfigurationStatusErrored.String(), StackConfigurationStatusCanceled.String()})
}

// AwaitStatus generates a channel that will receive the status of the stack configuration as it progresses.
Expand Down
4 changes: 2 additions & 2 deletions stack_configuration_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,12 @@ func TestStackConfigurationList(t *testing.T) {
require.NoError(t, err)

// Trigger first stack configuration by updating configuration
_, err = client.Stacks.UpdateConfiguration(ctx, stack.ID)
_, err = client.Stacks.FetchLatestFromVcs(ctx, stack.ID)
require.NoError(t, err)

// Wait a bit and trigger second stack configuration
time.Sleep(2 * time.Second)
_, err = client.Stacks.UpdateConfiguration(ctx, stack.ID)
_, err = client.Stacks.FetchLatestFromVcs(ctx, stack.ID)
require.NoError(t, err)

list, err := client.StackConfigurations.List(ctx, stack.ID, nil)
Expand Down
4 changes: 2 additions & 2 deletions stack_configuration_summary_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,12 @@ func TestStackConfigurationSummaryList(t *testing.T) {
require.NotNil(t, stack2)

// Trigger first stack configuration by updating configuration
_, err = client.Stacks.UpdateConfiguration(ctx, stack2.ID)
_, err = client.Stacks.FetchLatestFromVcs(ctx, stack2.ID)
require.NoError(t, err)

// Wait a bit and trigger second stack configuration
time.Sleep(2 * time.Second)
_, err = client.Stacks.UpdateConfiguration(ctx, stack2.ID)
_, err = client.Stacks.FetchLatestFromVcs(ctx, stack2.ID)
require.NoError(t, err)

t.Run("Successful empty list", func(t *testing.T) {
Expand Down
13 changes: 8 additions & 5 deletions stack_deployment_groups.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,14 @@ type StackDeploymentGroups interface {
type DeploymentGroupStatus string

const (
DeploymentGroupStatusPending DeploymentGroupStatus = "pending"
DeploymentGroupStatusDeploying DeploymentGroupStatus = "deploying"
DeploymentGroupStatusSucceeded DeploymentGroupStatus = "succeeded"
DeploymentGroupStatusFailed DeploymentGroupStatus = "failed"
DeploymentGroupStatusAbandoned DeploymentGroupStatus = "abandoned"
DeploymentGroupStatusPending DeploymentGroupStatus = "pending"
DeploymentGroupStatusPreDeploying DeploymentGroupStatus = "pre-deploying"
DeploymentGroupStatusPreDeployingPendingOperator DeploymentGroupStatus = "pending-operator"
DeploymentGroupStatusAcquiringLock DeploymentGroupStatus = "acquiring-lock"
DeploymentGroupStatusDeploying DeploymentGroupStatus = "deploying"
DeploymentGroupStatusSucceeded DeploymentGroupStatus = "succeeded"
DeploymentGroupStatusFailed DeploymentGroupStatus = "failed"
DeploymentGroupStatusAbandoned DeploymentGroupStatus = "abandoned"
)

// stackDeploymentGroups implements StackDeploymentGroups.
Expand Down
27 changes: 13 additions & 14 deletions stack_deployment_groups_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,12 @@ func TestStackDeploymentGroupsList(t *testing.T) {
require.NoError(t, err)
require.NotNil(t, stack)

stackUpdated, err := client.Stacks.UpdateConfiguration(ctx, stack.ID)
stackUpdated, err := client.Stacks.FetchLatestFromVcs(ctx, stack.ID)
require.NoError(t, err)
require.NotNil(t, stackUpdated)
require.NotEmpty(t, stackUpdated.LatestStackConfiguration.ID)

stackUpdated = pollStackDeployments(t, ctx, client, stackUpdated.ID)
require.NotNil(t, stackUpdated.LatestStackConfiguration)
stackUpdated = pollStackDeploymentGroups(t, ctx, client, stackUpdated.ID)
require.NotEmpty(t, stackUpdated.LatestStackConfiguration.ID)

t.Run("List with valid stack configuration ID", func(t *testing.T) {
sdgl, err := client.StackDeploymentGroups.List(ctx, stackUpdated.LatestStackConfiguration.ID, nil)
Expand Down Expand Up @@ -102,11 +101,11 @@ func TestStackDeploymentGroupsRead(t *testing.T) {
require.NoError(t, err)
require.NotNil(t, stack)

stackUpdated, err := client.Stacks.UpdateConfiguration(ctx, stack.ID)
stackUpdated, err := client.Stacks.FetchLatestFromVcs(ctx, stack.ID)
require.NoError(t, err)
require.NotNil(t, stackUpdated)

stackUpdated = pollStackDeployments(t, ctx, client, stackUpdated.ID)
stackUpdated = pollStackDeploymentGroups(t, ctx, client, stackUpdated.ID)
require.NotNil(t, stackUpdated.LatestStackConfiguration)

sdgl, err := client.StackDeploymentGroups.List(ctx, stackUpdated.LatestStackConfiguration.ID, nil)
Expand Down Expand Up @@ -154,15 +153,15 @@ func TestStackDeploymentGroupsApproveAllPlans(t *testing.T) {
require.NoError(t, err)
require.NotNil(t, stack)

stackUpdated, err := client.Stacks.UpdateConfiguration(ctx, stack.ID)
stackUpdated, err := client.Stacks.FetchLatestFromVcs(ctx, stack.ID)
require.NoError(t, err)
require.NotNil(t, stackUpdated)

stack = pollStackDeployments(t, ctx, client, stackUpdated.ID)
require.NotNil(t, stack.LatestStackConfiguration)
stackUpdated = pollStackDeploymentGroups(t, ctx, client, stackUpdated.ID)
require.NotNil(t, stackUpdated.LatestStackConfiguration)

// Get the deployment group ID from the stack configuration
deploymentGroups, err := client.StackDeploymentGroups.List(ctx, stack.LatestStackConfiguration.ID, nil)
deploymentGroups, err := client.StackDeploymentGroups.List(ctx, stackUpdated.LatestStackConfiguration.ID, nil)
require.NoError(t, err)
require.NotNil(t, deploymentGroups)
require.NotEmpty(t, deploymentGroups.Items)
Expand Down Expand Up @@ -201,14 +200,14 @@ func TestStackDeploymentGroupsRerun(t *testing.T) {
require.NoError(t, err)
require.NotNil(t, stack)

stackUpdated, err := client.Stacks.UpdateConfiguration(ctx, stack.ID)
stackUpdated, err := client.Stacks.FetchLatestFromVcs(ctx, stack.ID)
require.NoError(t, err)
require.NotNil(t, stackUpdated)

stack = pollStackDeployments(t, ctx, client, stackUpdated.ID)
require.NotNil(t, stack.LatestStackConfiguration)
stackUpdated = pollStackDeploymentGroups(t, ctx, client, stackUpdated.ID)
require.NotNil(t, stackUpdated.LatestStackConfiguration)

deploymentGroups, err := client.StackDeploymentGroups.List(ctx, stack.LatestStackConfiguration.ID, nil)
deploymentGroups, err := client.StackDeploymentGroups.List(ctx, stackUpdated.LatestStackConfiguration.ID, nil)
require.NoError(t, err)
require.NotNil(t, deploymentGroups)
require.NotEmpty(t, deploymentGroups.Items)
Expand Down
73 changes: 73 additions & 0 deletions stack_deployment_groups_summary.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package tfe

import (
"context"
"fmt"
"net/url"
)

type StackDeploymentGroupSummaries interface {
// List lists all the stack configuration summaries for a stack.
List(ctx context.Context, configurationID string, options *StackDeploymentGroupSummaryListOptions) (*StackDeploymentGroupSummaryList, error)
}

type stackDeploymentGroupSummaries struct {
client *Client
}

var _ StackDeploymentGroupSummaries = &stackDeploymentGroupSummaries{}

type StackDeploymentGroupSummaryList struct {
*Pagination
Items []*StackDeploymentGroupSummary
}

type StackDeploymentGroupSummaryListOptions struct {
ListOptions
}

type StackDeploymentGroupStatusCounts struct {
Pending int `jsonapi:"attr,pending"`
PreDeploying int `jsonapi:"attr,pre-deploying"`
PreDeployingPendingOperator int `jsonapi:"attr,pending-operator"`
AcquiringLock int `jsonapi:"attr,acquiring-lock"`
Deploying int `jsonapi:"attr,deploying"`
Succeeded int `jsonapi:"attr,succeeded"`
Failed int `jsonapi:"attr,failed"`
Abandoned int `jsonapi:"attr,abandoned"`
}

type StackDeploymentGroupSummary struct {
ID string `jsonapi:"primary,stack-deployment-group-summaries"`

// Attributes
Name string `jsonapi:"attr,name"`
Status string `jsonapi:"attr,status"`
StatusCounts *StackDeploymentGroupStatusCounts `jsonapi:"attr,status-counts"`

// Relationships
StackDeploymentGroup *StackDeploymentGroup `jsonapi:"relation,stack-deployment-group"`
}

func (s stackDeploymentGroupSummaries) List(ctx context.Context, stackID string, options *StackDeploymentGroupSummaryListOptions) (*StackDeploymentGroupSummaryList, error) {
if !validStringID(&stackID) {
return nil, fmt.Errorf("invalid stack ID: %s", stackID)
}

if options == nil {
options = &StackDeploymentGroupSummaryListOptions{}
}

req, err := s.client.NewRequest("GET", fmt.Sprintf("stack-configurations/%s/stack-deployment-group-summaries", url.PathEscape(stackID)), options)
if err != nil {
return nil, err
}

scl := &StackDeploymentGroupSummaryList{}
err = req.Do(ctx, scl)
if err != nil {
return nil, err
}

return scl, nil
}
Loading
Loading