Skip to content

Commit 046c5e7

Browse files
committed
add CloudFormationStackLister method
1 parent 5d80d93 commit 046c5e7

File tree

3 files changed

+197
-0
lines changed

3 files changed

+197
-0
lines changed

app/domain/model/cloudformation.go

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package model
2+
3+
import "time"
4+
5+
const (
6+
// CloudFormationRetryMaxAttempts is the maximum number of retries for CloudFormation.
7+
CloudFormationRetryMaxAttempts int = 2
8+
)
9+
10+
// StackStatus is the status of a CloudFormation stack.
11+
type StackStatus string
12+
13+
// StackDriftInformationSummary contains information about whether the stack's
14+
// actual configuration differs, or has drifted, from its expected configuration,
15+
// as defined in the stack template and any values specified as template parameters.
16+
// A stack is considered to have drifted if one or more of its resources have drifted.
17+
type StackDriftInformationSummary struct {
18+
// StackDriftStatus is status of the stack's actual configuration compared to its expected template
19+
// configuration.
20+
StackDriftStatus StackDriftStatus
21+
// LastCheckTimestamp is most recent time when a drift detection operation was
22+
// initiated on the stack, or any of its individual resources that support drift detection.
23+
LastCheckTimestamp *time.Time
24+
}
25+
26+
// StackDriftStatus is the status of a stack's actual configuration compared to
27+
// its expected template configuration.
28+
type StackDriftStatus string
29+
30+
const (
31+
// StackDriftStatusDrifted is the stack differs from its expected template configuration.
32+
// A stack is considered to have drifted if one or more of its resources have drifted.
33+
StackDriftStatusDrifted StackDriftStatus = "DRIFTED"
34+
// StackDriftStatusInSync is the stack's actual configuration matches its expected template
35+
// configuration.
36+
StackDriftStatusInSync StackDriftStatus = "IN_SYNC"
37+
// StackDriftStatusNotChecked is CloudFormation hasn't checked if the stack differs from its
38+
// expected template configuration.
39+
StackDriftStatusNotChecked StackDriftStatus = "NOT_CHECKED"
40+
// StackDriftStatusUnknown is this value is reserved for future use.
41+
StackDriftStatusUnknown StackDriftStatus = "UNKNOWN"
42+
)
43+
44+
// Values returns all known values for StackDriftStatus. Note that this can be
45+
// expanded in the future, and so it is only as up to date as the client. The
46+
// ordering of this slice is not guaranteed to be stable across updates.
47+
func (StackDriftStatus) Values() []StackDriftStatus {
48+
return []StackDriftStatus{
49+
"DRIFTED",
50+
"IN_SYNC",
51+
"UNKNOWN",
52+
"NOT_CHECKED",
53+
}
54+
}
55+
56+
// Stack is a CloudFormation stack. It is same as types.StackSummary.
57+
type Stack struct {
58+
// CreationTime is the time the stack was created.
59+
CreationTime *time.Time
60+
// StackName is the name associated with the stack.
61+
StackName *string
62+
// StackStatus is the current status of the stack.
63+
StackStatus StackStatus
64+
// DeletionTime is the time the stack was deleted.
65+
DeletionTime *time.Time
66+
// DriftInformation is summarizes information about whether a stack's actual
67+
// configuration differs, or has drifted, from its expected configuration,
68+
// as defined in the stack template and any values specified as template parameters.
69+
DriftInformation *StackDriftInformationSummary
70+
// LastUpdatedTime is the time the stack was last updated.
71+
LastUpdatedTime *time.Time
72+
// ParentID is used for nested stacks --stacks created as resources for
73+
// another stack-- the stack ID of the direct parent of this stack.
74+
// For the first level of nested stacks, the root stack is also the parent stack.
75+
ParentID *string
76+
// RootID id used for nested stacks --stacks created as resources for
77+
// another stack--the stack ID of the top-level stack to which the nested stack
78+
// ultimately belongs.
79+
RootID *string
80+
// StackID is unique stack identifier.
81+
StackID *string
82+
// StackStatusReason is Success/Failure message associated with the stack status.
83+
StackStatusReason *string
84+
// TemplateDescription is the template description of the template used to create the stack.
85+
TemplateDescription *string
86+
}

app/domain/service/cloudformation.go

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package service
2+
3+
import (
4+
"context"
5+
6+
"github.com/nao1215/rainbow/app/domain/model"
7+
)
8+
9+
// CloudFormationStackListerInput is the input of the CloudFormationStackLister method.
10+
type CloudFormationStackListerInput struct{}
11+
12+
// CloudFormationStackListerOutput is the output of the CloudFormationStackLister method.
13+
type CloudFormationStackListerOutput struct {
14+
// Stacks is a list of CloudFormation stacks.
15+
Stacks []*model.Stack
16+
}
17+
18+
// CloudFormationStackLister is the interface that wraps the basic CloudFormationStackLister method.
19+
type CloudFormationStackLister interface {
20+
CloudFormationStackLister(ctx context.Context, input *CloudFormationStackListerInput) (*CloudFormationStackListerOutput, error)
21+
}

app/external/cloudformation.go

+90
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
package external
2+
3+
import (
4+
"context"
5+
6+
"github.com/aws/aws-sdk-go-v2/aws"
7+
"github.com/aws/aws-sdk-go-v2/service/cloudformation"
8+
"github.com/google/wire"
9+
"github.com/nao1215/rainbow/app/domain/model"
10+
"github.com/nao1215/rainbow/app/domain/service"
11+
)
12+
13+
// NewCloudFormationClient returns a new CloudFormation client.
14+
func NewCloudFormationClient(cfg *model.AWSConfig) *cloudformation.Client {
15+
return cloudformation.NewFromConfig(
16+
*cfg.Config,
17+
func(o *cloudformation.Options) {
18+
o.RetryMaxAttempts = model.CloudFormationRetryMaxAttempts
19+
o.RetryMode = aws.RetryModeStandard
20+
})
21+
}
22+
23+
// CloudFormationStackLister implements the CloudFormationStackLister interface.
24+
type CloudFormationStackLister struct {
25+
client *cloudformation.Client
26+
}
27+
28+
// CloudFormationStackListerSet is a set of CloudFormationStackLister.
29+
//
30+
//nolint:gochecknoglobals
31+
var CloudFormationStackListerSet = wire.NewSet(
32+
NewCloudFormationStackLister,
33+
wire.Bind(new(service.CloudFormationStackLister), new(*CloudFormationStackLister)),
34+
)
35+
36+
var _ service.CloudFormationStackLister = (*CloudFormationStackLister)(nil)
37+
38+
// NewCloudFormationStackLister returns a new CloudFormationStackLister.
39+
func NewCloudFormationStackLister(client *cloudformation.Client) *CloudFormationStackLister {
40+
return &CloudFormationStackLister{client: client}
41+
}
42+
43+
// CloudFormationStackLister returns a list of CloudFormation stacks.
44+
func (l *CloudFormationStackLister) CloudFormationStackLister(ctx context.Context, input *service.CloudFormationStackListerInput) (*service.CloudFormationStackListerOutput, error) {
45+
in := &cloudformation.ListStacksInput{}
46+
stacks := make([]*model.Stack, 0, 100)
47+
48+
for {
49+
select {
50+
case <-ctx.Done():
51+
return &service.CloudFormationStackListerOutput{
52+
Stacks: stacks,
53+
}, ctx.Err()
54+
default:
55+
}
56+
57+
out, err := l.client.ListStacks(ctx, in)
58+
if err != nil {
59+
return nil, err
60+
}
61+
62+
for _, stack := range out.StackSummaries {
63+
stacks = append(stacks, &model.Stack{
64+
CreationTime: stack.CreationTime,
65+
StackName: stack.StackName,
66+
StackStatus: model.StackStatus(stack.StackStatus),
67+
DeletionTime: stack.DeletionTime,
68+
DriftInformation: &model.StackDriftInformationSummary{
69+
StackDriftStatus: model.StackDriftStatus(stack.DriftInformation.StackDriftStatus),
70+
LastCheckTimestamp: stack.DriftInformation.LastCheckTimestamp,
71+
},
72+
LastUpdatedTime: stack.LastUpdatedTime,
73+
ParentID: stack.ParentId,
74+
RootID: stack.RootId,
75+
StackID: stack.StackId,
76+
StackStatusReason: stack.StackStatusReason,
77+
TemplateDescription: stack.TemplateDescription,
78+
})
79+
}
80+
81+
if out.NextToken == nil {
82+
break
83+
}
84+
in.NextToken = out.NextToken
85+
}
86+
87+
return &service.CloudFormationStackListerOutput{
88+
Stacks: stacks,
89+
}, nil
90+
}

0 commit comments

Comments
 (0)