Skip to content

Commit 81b1d48

Browse files
Fawad Khaliqkaranvasnani
Fawad Khaliq
andauthored
Add resource manager and utils for gatewayroute (#254)
Co-authored-by: Karan Vasnani <vasnk@amazon.com>
1 parent 9b2d3a5 commit 81b1d48

8 files changed

+1351
-0
lines changed

pkg/gatewayroute/conditions.go

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package gatewayroute
2+
3+
import (
4+
appmesh "github.com/aws/aws-app-mesh-controller-for-k8s/apis/appmesh/v1beta2"
5+
"github.com/aws/aws-sdk-go/aws"
6+
corev1 "k8s.io/api/core/v1"
7+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
8+
)
9+
10+
// getCondition will get pointer to gatewayRoute's existing condition.
11+
func getCondition(gr *appmesh.GatewayRoute, conditionType appmesh.GatewayRouteConditionType) *appmesh.GatewayRouteCondition {
12+
for i := range gr.Status.Conditions {
13+
if gr.Status.Conditions[i].Type == conditionType {
14+
return &gr.Status.Conditions[i]
15+
}
16+
}
17+
return nil
18+
}
19+
20+
// updateCondition will update gatewayRoute's condition. returns whether it's updated.
21+
func updateCondition(gr *appmesh.GatewayRoute, conditionType appmesh.GatewayRouteConditionType, status corev1.ConditionStatus, reason *string, message *string) bool {
22+
now := metav1.Now()
23+
existingCondition := getCondition(gr, conditionType)
24+
if existingCondition == nil {
25+
newCondition := appmesh.GatewayRouteCondition{
26+
Type: conditionType,
27+
Status: status,
28+
LastTransitionTime: &now,
29+
Reason: reason,
30+
Message: message,
31+
}
32+
gr.Status.Conditions = append(gr.Status.Conditions, newCondition)
33+
return true
34+
}
35+
36+
hasChanged := false
37+
if existingCondition.Status != status {
38+
existingCondition.Status = status
39+
existingCondition.LastTransitionTime = &now
40+
hasChanged = true
41+
}
42+
if aws.StringValue(existingCondition.Reason) != aws.StringValue(reason) {
43+
existingCondition.Reason = reason
44+
hasChanged = true
45+
}
46+
if aws.StringValue(existingCondition.Message) != aws.StringValue(message) {
47+
existingCondition.Message = message
48+
hasChanged = true
49+
}
50+
return hasChanged
51+
}

pkg/gatewayroute/conditions_test.go

+269
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,269 @@
1+
package gatewayroute
2+
3+
import (
4+
appmesh "github.com/aws/aws-app-mesh-controller-for-k8s/apis/appmesh/v1beta2"
5+
"github.com/aws/aws-sdk-go/aws"
6+
"github.com/google/go-cmp/cmp"
7+
"github.com/google/go-cmp/cmp/cmpopts"
8+
"github.com/stretchr/testify/assert"
9+
corev1 "k8s.io/api/core/v1"
10+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
11+
"testing"
12+
)
13+
14+
func Test_getCondition(t *testing.T) {
15+
type args struct {
16+
gr *appmesh.GatewayRoute
17+
conditionType appmesh.GatewayRouteConditionType
18+
}
19+
tests := []struct {
20+
name string
21+
args args
22+
want *appmesh.GatewayRouteCondition
23+
}{
24+
{
25+
name: "condition found",
26+
args: args{
27+
gr: &appmesh.GatewayRoute{
28+
Status: appmesh.GatewayRouteStatus{
29+
Conditions: []appmesh.GatewayRouteCondition{
30+
{
31+
Type: appmesh.GatewayRouteActive,
32+
Status: corev1.ConditionFalse,
33+
},
34+
},
35+
},
36+
},
37+
conditionType: appmesh.GatewayRouteActive,
38+
},
39+
want: &appmesh.GatewayRouteCondition{
40+
Type: appmesh.GatewayRouteActive,
41+
Status: corev1.ConditionFalse,
42+
},
43+
},
44+
{
45+
name: "condition not found",
46+
args: args{
47+
gr: &appmesh.GatewayRoute{
48+
Status: appmesh.GatewayRouteStatus{
49+
Conditions: []appmesh.GatewayRouteCondition{},
50+
},
51+
},
52+
conditionType: appmesh.GatewayRouteActive,
53+
},
54+
want: nil,
55+
},
56+
}
57+
for _, tt := range tests {
58+
t.Run(tt.name, func(t *testing.T) {
59+
got := getCondition(tt.args.gr, tt.args.conditionType)
60+
assert.Equal(t, tt.want, got)
61+
})
62+
}
63+
}
64+
65+
func Test_updateCondition(t *testing.T) {
66+
type args struct {
67+
gr *appmesh.GatewayRoute
68+
conditionType appmesh.GatewayRouteConditionType
69+
status corev1.ConditionStatus
70+
reason *string
71+
message *string
72+
}
73+
tests := []struct {
74+
name string
75+
args args
76+
wantGR *appmesh.GatewayRoute
77+
wantChanged bool
78+
}{
79+
{
80+
name: "condition updated by modify condition status",
81+
args: args{
82+
gr: &appmesh.GatewayRoute{
83+
Status: appmesh.GatewayRouteStatus{
84+
Conditions: []appmesh.GatewayRouteCondition{
85+
{
86+
Type: appmesh.GatewayRouteActive,
87+
Status: corev1.ConditionFalse,
88+
},
89+
},
90+
},
91+
},
92+
conditionType: appmesh.GatewayRouteActive,
93+
status: corev1.ConditionTrue,
94+
},
95+
wantGR: &appmesh.GatewayRoute{
96+
Status: appmesh.GatewayRouteStatus{
97+
Conditions: []appmesh.GatewayRouteCondition{
98+
{
99+
Type: appmesh.GatewayRouteActive,
100+
Status: corev1.ConditionTrue,
101+
},
102+
},
103+
},
104+
},
105+
wantChanged: true,
106+
},
107+
{
108+
name: "condition updated by modify condition reason",
109+
args: args{
110+
gr: &appmesh.GatewayRoute{
111+
Status: appmesh.GatewayRouteStatus{
112+
Conditions: []appmesh.GatewayRouteCondition{
113+
{
114+
Type: appmesh.GatewayRouteActive,
115+
Status: corev1.ConditionTrue,
116+
},
117+
},
118+
},
119+
},
120+
conditionType: appmesh.GatewayRouteActive,
121+
status: corev1.ConditionTrue,
122+
reason: aws.String("reason"),
123+
},
124+
wantGR: &appmesh.GatewayRoute{
125+
Status: appmesh.GatewayRouteStatus{
126+
Conditions: []appmesh.GatewayRouteCondition{
127+
{
128+
Type: appmesh.GatewayRouteActive,
129+
Status: corev1.ConditionTrue,
130+
Reason: aws.String("reason"),
131+
},
132+
},
133+
},
134+
},
135+
wantChanged: true,
136+
},
137+
{
138+
name: "condition updated by modify condition message",
139+
args: args{
140+
gr: &appmesh.GatewayRoute{
141+
Status: appmesh.GatewayRouteStatus{
142+
Conditions: []appmesh.GatewayRouteCondition{
143+
{
144+
Type: appmesh.GatewayRouteActive,
145+
Status: corev1.ConditionTrue,
146+
},
147+
},
148+
},
149+
},
150+
conditionType: appmesh.GatewayRouteActive,
151+
status: corev1.ConditionTrue,
152+
message: aws.String("message"),
153+
},
154+
wantGR: &appmesh.GatewayRoute{
155+
Status: appmesh.GatewayRouteStatus{
156+
Conditions: []appmesh.GatewayRouteCondition{
157+
{
158+
Type: appmesh.GatewayRouteActive,
159+
Status: corev1.ConditionTrue,
160+
Message: aws.String("message"),
161+
},
162+
},
163+
},
164+
},
165+
wantChanged: true,
166+
},
167+
{
168+
name: "condition updated by modify condition status/reason/message",
169+
args: args{
170+
gr: &appmesh.GatewayRoute{
171+
Status: appmesh.GatewayRouteStatus{
172+
Conditions: []appmesh.GatewayRouteCondition{
173+
{
174+
Type: appmesh.GatewayRouteActive,
175+
Status: corev1.ConditionFalse,
176+
},
177+
},
178+
},
179+
},
180+
conditionType: appmesh.GatewayRouteActive,
181+
status: corev1.ConditionTrue,
182+
reason: aws.String("reason"),
183+
message: aws.String("message"),
184+
},
185+
wantGR: &appmesh.GatewayRoute{
186+
Status: appmesh.GatewayRouteStatus{
187+
Conditions: []appmesh.GatewayRouteCondition{
188+
{
189+
Type: appmesh.GatewayRouteActive,
190+
Status: corev1.ConditionTrue,
191+
Reason: aws.String("reason"),
192+
Message: aws.String("message"),
193+
},
194+
},
195+
},
196+
},
197+
wantChanged: true,
198+
},
199+
{
200+
name: "condition updated by new condition",
201+
args: args{
202+
gr: &appmesh.GatewayRoute{
203+
Status: appmesh.GatewayRouteStatus{
204+
Conditions: nil,
205+
},
206+
},
207+
conditionType: appmesh.GatewayRouteActive,
208+
status: corev1.ConditionTrue,
209+
reason: aws.String("reason"),
210+
message: aws.String("message"),
211+
},
212+
wantGR: &appmesh.GatewayRoute{
213+
Status: appmesh.GatewayRouteStatus{
214+
Conditions: []appmesh.GatewayRouteCondition{
215+
{
216+
Type: appmesh.GatewayRouteActive,
217+
Status: corev1.ConditionTrue,
218+
Reason: aws.String("reason"),
219+
Message: aws.String("message"),
220+
},
221+
},
222+
},
223+
},
224+
wantChanged: true,
225+
},
226+
{
227+
name: "condition unmodified",
228+
args: args{
229+
gr: &appmesh.GatewayRoute{
230+
Status: appmesh.GatewayRouteStatus{
231+
Conditions: []appmesh.GatewayRouteCondition{
232+
{
233+
Type: appmesh.GatewayRouteActive,
234+
Status: corev1.ConditionTrue,
235+
Reason: aws.String("reason"),
236+
Message: aws.String("message"),
237+
},
238+
},
239+
},
240+
},
241+
conditionType: appmesh.GatewayRouteActive,
242+
status: corev1.ConditionTrue,
243+
reason: aws.String("reason"),
244+
message: aws.String("message"),
245+
},
246+
wantGR: &appmesh.GatewayRoute{
247+
Status: appmesh.GatewayRouteStatus{
248+
Conditions: []appmesh.GatewayRouteCondition{
249+
{
250+
Type: appmesh.GatewayRouteActive,
251+
Status: corev1.ConditionTrue,
252+
Reason: aws.String("reason"),
253+
Message: aws.String("message"),
254+
},
255+
},
256+
},
257+
},
258+
wantChanged: false,
259+
},
260+
}
261+
for _, tt := range tests {
262+
t.Run(tt.name, func(t *testing.T) {
263+
gotChanged := updateCondition(tt.args.gr, tt.args.conditionType, tt.args.status, tt.args.reason, tt.args.message)
264+
opts := cmpopts.IgnoreTypes((*metav1.Time)(nil))
265+
assert.True(t, cmp.Equal(tt.wantGR, tt.args.gr, opts), "diff", cmp.Diff(tt.wantGR, tt.args.gr, opts))
266+
assert.Equal(t, tt.wantChanged, gotChanged)
267+
})
268+
}
269+
}

pkg/gatewayroute/references.go

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package gatewayroute
2+
3+
import (
4+
appmesh "github.com/aws/aws-app-mesh-controller-for-k8s/apis/appmesh/v1beta2"
5+
"github.com/aws/aws-app-mesh-controller-for-k8s/pkg/references"
6+
"k8s.io/apimachinery/pkg/runtime"
7+
"k8s.io/apimachinery/pkg/types"
8+
)
9+
10+
const (
11+
ReferenceKindVirtualService = "VirtualService"
12+
)
13+
14+
// extractVirtualServiceReferences extracts all virtualServiceReferences for this gatewayRoute
15+
func extractVirtualServiceReferences(gr *appmesh.GatewayRoute) []appmesh.VirtualServiceReference {
16+
var vsRefs []appmesh.VirtualServiceReference
17+
18+
if gr.Spec.GRPCRoute != nil {
19+
vsRefs = append(vsRefs, gr.Spec.GRPCRoute.Action.Target.VirtualService.VirtualServiceRef)
20+
}
21+
if gr.Spec.HTTPRoute != nil {
22+
vsRefs = append(vsRefs, gr.Spec.HTTPRoute.Action.Target.VirtualService.VirtualServiceRef)
23+
}
24+
if gr.Spec.HTTP2Route != nil {
25+
vsRefs = append(vsRefs, gr.Spec.HTTP2Route.Action.Target.VirtualService.VirtualServiceRef)
26+
}
27+
28+
return vsRefs
29+
}
30+
31+
func VirtualServiceReferenceIndexFunc(obj runtime.Object) []types.NamespacedName {
32+
gr := obj.(*appmesh.GatewayRoute)
33+
vsRefs := extractVirtualServiceReferences(gr)
34+
var vsKeys []types.NamespacedName
35+
for _, vsRef := range vsRefs {
36+
vsKeys = append(vsKeys, references.ObjectKeyForVirtualServiceReference(gr, vsRef))
37+
}
38+
return vsKeys
39+
}

0 commit comments

Comments
 (0)