Skip to content

Commit 28cee8f

Browse files
authored
V2 ga deploy (#1385)
* add algorithms for string & map * add stackID and ListResources into stack * add elbv2 tagging operations and pagination wrapper
1 parent 813e5d7 commit 28cee8f

22 files changed

+882
-131
lines changed

controllers/service/service_controller.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ func (r *ServiceReconciler) SetupWithManager(mgr ctrl.Manager) error {
9292

9393
func (r *ServiceReconciler) setupWatches(mgr ctrl.Manager, c controller.Controller) error {
9494
svcEventHandler := eventhandlers.NewEnqueueRequestForServiceEvent(mgr.GetEventRecorderFor(controllerName), r.annotationParser)
95-
if err:= c.Watch(&source.Kind{Type: &corev1.Service{}}, svcEventHandler); err != nil {
95+
if err := c.Watch(&source.Kind{Type: &corev1.Service{}}, svcEventHandler); err != nil {
9696
return err
9797
}
9898
return nil

mocks/aws/services/mock_elbv2.go

Lines changed: 30 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/algorithm/maps.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,18 @@ func MapFindFirst(key string, maps ...map[string]string) (string, bool) {
1010
}
1111
return "", false
1212
}
13+
14+
// MergeStringMap will merge multiple map[string]string into single one.
15+
// The merge is executed for maps argument in sequential order, if a key already exists, the value from previous map is kept.
16+
// e.g. MergeStringMap(map[string]string{"a": "1", "b": "2"}, map[string]string{"a": "3", "d": "4"}) == map[string]string{"a": "1", "b": "2", "d": "4"}
17+
func MergeStringMap(maps ...map[string]string) map[string]string {
18+
ret := make(map[string]string)
19+
for _, _map := range maps {
20+
for k, v := range _map {
21+
if _, ok := ret[k]; !ok {
22+
ret[k] = v
23+
}
24+
}
25+
}
26+
return ret
27+
}

pkg/algorithm/maps_test.go

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,104 @@ func TestMapFindFirst(t *testing.T) {
7878
})
7979
}
8080
}
81+
82+
func TestMergeStringMap(t *testing.T) {
83+
type args struct {
84+
maps []map[string]string
85+
}
86+
tests := []struct {
87+
name string
88+
args args
89+
want map[string]string
90+
}{
91+
{
92+
name: "merge two maps without duplicates",
93+
args: args{
94+
maps: []map[string]string{
95+
{
96+
"a": "1",
97+
"b": "2",
98+
},
99+
{
100+
"c": "3",
101+
"d": "4",
102+
},
103+
},
104+
},
105+
want: map[string]string{
106+
"a": "1",
107+
"b": "2",
108+
"c": "3",
109+
"d": "4",
110+
},
111+
},
112+
{
113+
name: "merge two maps with duplicates",
114+
args: args{
115+
maps: []map[string]string{
116+
{
117+
"a": "1",
118+
"b": "2",
119+
},
120+
{
121+
"a": "3",
122+
"d": "4",
123+
},
124+
},
125+
},
126+
want: map[string]string{
127+
"a": "1",
128+
"b": "2",
129+
"d": "4",
130+
},
131+
},
132+
{
133+
name: "merge two maps when first map is nil",
134+
args: args{
135+
maps: []map[string]string{
136+
nil,
137+
{
138+
"c": "3",
139+
"d": "4",
140+
},
141+
},
142+
},
143+
want: map[string]string{
144+
"c": "3",
145+
"d": "4",
146+
},
147+
},
148+
{
149+
name: "merge two maps when second map is nil",
150+
args: args{
151+
maps: []map[string]string{
152+
{
153+
"a": "1",
154+
"b": "2",
155+
},
156+
nil,
157+
},
158+
},
159+
want: map[string]string{
160+
"a": "1",
161+
"b": "2",
162+
},
163+
},
164+
{
165+
name: "merge two maps when both map is nil",
166+
args: args{
167+
maps: []map[string]string{
168+
nil,
169+
nil,
170+
},
171+
},
172+
want: map[string]string{},
173+
},
174+
}
175+
for _, tt := range tests {
176+
t.Run(tt.name, func(t *testing.T) {
177+
got := MergeStringMap(tt.args.maps...)
178+
assert.Equal(t, tt.want, got)
179+
})
180+
}
181+
}

pkg/algorithm/strings.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package algorithm
2+
3+
// ChunkStrings will split slice of String into chunks
4+
func ChunkStrings(targets []string, chunkSize int) [][]string {
5+
var chunks [][]string
6+
for i := 0; i < len(targets); i += chunkSize {
7+
end := i + chunkSize
8+
if end > len(targets) {
9+
end = len(targets)
10+
}
11+
chunks = append(chunks, targets[i:end])
12+
}
13+
return chunks
14+
}

pkg/algorithm/strings_test.go

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package algorithm
2+
3+
import (
4+
"github.com/stretchr/testify/assert"
5+
"testing"
6+
)
7+
8+
func TestChunkStrings(t *testing.T) {
9+
type args struct {
10+
targets []string
11+
chunkSize int
12+
}
13+
tests := []struct {
14+
name string
15+
args args
16+
want [][]string
17+
}{
18+
{
19+
name: "can be evenly chunked",
20+
args: args{
21+
targets: []string{"a", "b", "c", "d"},
22+
chunkSize: 2,
23+
},
24+
want: [][]string{
25+
{"a", "b"},
26+
{"c", "d"},
27+
},
28+
},
29+
{
30+
name: "cannot be evenly chunked",
31+
args: args{
32+
targets: []string{"a", "b", "c", "d"},
33+
chunkSize: 3,
34+
},
35+
want: [][]string{
36+
{"a", "b", "c"},
37+
{"d"},
38+
},
39+
},
40+
{
41+
name: "chunkSize equal to total count",
42+
args: args{
43+
targets: []string{"a", "b", "c", "d"},
44+
chunkSize: 4,
45+
},
46+
want: [][]string{
47+
{"a", "b", "c", "d"},
48+
},
49+
},
50+
{
51+
name: "chunkSize greater than total count",
52+
args: args{
53+
targets: []string{"a", "b", "c", "d"},
54+
chunkSize: 5,
55+
},
56+
want: [][]string{
57+
{"a", "b", "c", "d"},
58+
},
59+
},
60+
{
61+
name: "chunk nil slice",
62+
args: args{
63+
targets: nil,
64+
chunkSize: 2,
65+
},
66+
want: nil,
67+
},
68+
{
69+
name: "chunk empty slice",
70+
args: args{
71+
targets: []string{},
72+
chunkSize: 2,
73+
},
74+
want: nil,
75+
},
76+
}
77+
for _, tt := range tests {
78+
t.Run(tt.name, func(t *testing.T) {
79+
got := ChunkStrings(tt.args.targets, tt.args.chunkSize)
80+
assert.Equal(t, tt.want, got)
81+
})
82+
}
83+
}

pkg/aws/services/elbv2.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,20 @@
11
package services
22

33
import (
4+
"context"
45
"github.com/aws/aws-sdk-go/aws/session"
56
"github.com/aws/aws-sdk-go/service/elbv2"
67
"github.com/aws/aws-sdk-go/service/elbv2/elbv2iface"
78
)
89

910
type ELBV2 interface {
1011
elbv2iface.ELBV2API
12+
13+
// wrapper to DescribeLoadBalancersPagesWithContext API, which aggregates paged results into list.
14+
DescribeLoadBalancersAsList(ctx context.Context, input *elbv2.DescribeLoadBalancersInput) ([]*elbv2.LoadBalancer, error)
15+
16+
// wrapper to DescribeTargetGroupsPagesWithContext API, which aggregates paged results into list.
17+
DescribeTargetGroupsAsList(ctx context.Context, input *elbv2.DescribeTargetGroupsInput) ([]*elbv2.TargetGroup, error)
1118
}
1219

1320
// NewELBV2 constructs new ELBV2 implementation.
@@ -17,6 +24,29 @@ func NewELBV2(session *session.Session) ELBV2 {
1724
}
1825
}
1926

27+
// default implementation for ELBV2.
2028
type defaultELBV2 struct {
2129
elbv2iface.ELBV2API
2230
}
31+
32+
func (c *defaultELBV2) DescribeLoadBalancersAsList(ctx context.Context, input *elbv2.DescribeLoadBalancersInput) ([]*elbv2.LoadBalancer, error) {
33+
var result []*elbv2.LoadBalancer
34+
if err := c.DescribeLoadBalancersPagesWithContext(ctx, input, func(output *elbv2.DescribeLoadBalancersOutput, _ bool) bool {
35+
result = append(result, output.LoadBalancers...)
36+
return true
37+
}); err != nil {
38+
return nil, err
39+
}
40+
return result, nil
41+
}
42+
43+
func (c *defaultELBV2) DescribeTargetGroupsAsList(ctx context.Context, input *elbv2.DescribeTargetGroupsInput) ([]*elbv2.TargetGroup, error) {
44+
var result []*elbv2.TargetGroup
45+
if err := c.DescribeTargetGroupsPagesWithContext(ctx, input, func(output *elbv2.DescribeTargetGroupsOutput, _ bool) bool {
46+
result = append(result, output.TargetGroups...)
47+
return true
48+
}); err != nil {
49+
return nil, err
50+
}
51+
return result, nil
52+
}

pkg/aws/throttle/defaults.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package throttle
33
// NewDefaultServiceOperationsThrottleConfig returns a ServiceOperationsThrottleConfig with default settings.
44
func NewDefaultServiceOperationsThrottleConfig() *ServiceOperationsThrottleConfig {
55
return &ServiceOperationsThrottleConfig{
6-
value: map[string][]throttleConfig{
7-
},
6+
value: map[string][]throttleConfig{},
87
}
98
}

pkg/deploy/stack_marshaller.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ var _ StackMarshaller = &defaultStackMarshaller{}
1919
type defaultStackMarshaller struct{}
2020

2121
func (m *defaultStackMarshaller) Marshal(stack core.Stack) (string, error) {
22-
builder := NewStackSchemaBuilder()
22+
builder := NewStackSchemaBuilder(stack.StackID())
2323
if err := stack.TopologicalTraversal(builder); err != nil {
2424
return "", err
2525
}

pkg/deploy/stack_marshaller_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,18 @@ func Test_defaultDeployer_Deploy(t *testing.T) {
1616
{
1717
name: "single resource",
1818
modelBuildFunc: func() core.Stack {
19-
stack := core.NewDefaultStack()
19+
stack := core.NewDefaultStack("namespace/name")
2020
_ = core.NewFakeResource(stack, "typeX", "resA", core.FakeResourceSpec{
2121
FieldA: []core.StringToken{core.LiteralStringToken("valueA")},
2222
}, nil)
2323
return stack
2424
},
25-
want: `{"resources":{"typeX":{"resA":{"spec":{"fieldA":["valueA"]}}}}}`,
25+
want: `{"id":"namespace/name","resources":{"typeX":{"resA":{"spec":{"fieldA":["valueA"]}}}}}`,
2626
},
2727
{
2828
name: "multiple resources",
2929
modelBuildFunc: func() core.Stack {
30-
stack := core.NewDefaultStack()
30+
stack := core.NewDefaultStack("namespace/name")
3131
resA := core.NewFakeResource(stack, "typeX", "resA", core.FakeResourceSpec{
3232
FieldA: []core.StringToken{core.LiteralStringToken("valueA")},
3333
}, nil)
@@ -39,7 +39,7 @@ func Test_defaultDeployer_Deploy(t *testing.T) {
3939
}, nil)
4040
return stack
4141
},
42-
want: `{"resources":{"typeX":{"resA":{"spec":{"fieldA":["valueA"]}},"resB":{"spec":{"fieldA":[{"$ref":"#/resources/typeX/resA/status/fieldB"}]}}},"typeY":{"resC":{"spec":{"fieldA":["valueA",{"$ref":"#/resources/typeX/resB/status/fieldB"}]}}}}}`,
42+
want: `{"id":"namespace/name","resources":{"typeX":{"resA":{"spec":{"fieldA":["valueA"]}},"resB":{"spec":{"fieldA":[{"$ref":"#/resources/typeX/resA/status/fieldB"}]}}},"typeY":{"resC":{"spec":{"fieldA":["valueA",{"$ref":"#/resources/typeX/resB/status/fieldB"}]}}}}}`,
4343
},
4444
}
4545
for _, tt := range tests {

0 commit comments

Comments
 (0)