Skip to content

Commit bbb6398

Browse files
SinghVikram97VikramBedirlymbur
authored
add annotation for overriding default service name generation (#849)
* Fix IAMAuthPolicy resource cleanup bug when targetRef changes * add annotation for overriding default service name generation * fix access log policy test * increase timeout for iamauthpolicy test * increase timeout for iamauthpolicy test --------- Co-authored-by: VikramBedi <[email protected]> Co-authored-by: Ryan Lymburner <[email protected]>
1 parent 9b189f0 commit bbb6398

22 files changed

+1302
-228
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Service Name Override
2+
3+
Override default generated VPC Lattice service names for Routes to avoid conflicts or implement naming conventions.
4+
5+
## Usage
6+
7+
Add the annotation to HTTPRoute or GRPCRoute:
8+
9+
```yaml
10+
apiVersion: gateway.networking.k8s.io/v1
11+
kind: HTTPRoute
12+
metadata:
13+
name: api-service
14+
namespace: production
15+
annotations:
16+
application-networking.k8s.aws/service-name-override: "custom-service-name"
17+
spec:
18+
parentRefs:
19+
- name: my-gateway
20+
rules:
21+
- backendRefs:
22+
- name: backend-service
23+
port: 80
24+
```
25+
26+
## Before You Start
27+
28+
Service name overrides must be set during route creation and cannot be modified. Adding or changing the annotation on existing routes does not work.
29+
30+
**To add or change a service name override for existing route:**
31+
1. Delete the route: `kubectl delete httproute my-route`
32+
2. Update annotation and recreate: `kubectl apply -f updated-route.yaml`
33+
34+
## Validation Rules
35+
36+
Service names must:
37+
- Be 3-40 characters long
38+
- Use only lowercase letters, numbers, and hyphens
39+
- Start and end with alphanumeric characters
40+
- Not start with `svc-`
41+
- Not contain `--` or start/end with `-`

pkg/apis/applicationnetworking/v1alpha1/accesslogpolicy_types.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ import (
1010
)
1111

1212
const (
13-
AccessLogSubscriptionAnnotationKey = k8s.AnnotationPrefix + "accessLogSubscription"
13+
AccessLogSubscriptionAnnotationKey = k8s.AnnotationPrefix + "accessLogSubscription"
14+
AccessLogSubscriptionResourceNameAnnotationKey = k8s.AnnotationPrefix + "accessLogSubscriptionResourceName"
1415
)
1516

1617
// +genclient

pkg/controllers/accesslogpolicy_controller.go

Lines changed: 68 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -134,15 +134,25 @@ func (r *accessLogPolicyReconciler) reconcile(ctx context.Context, req ctrl.Requ
134134

135135
r.eventRecorder.Event(alp, corev1.EventTypeNormal, k8s.ReconcilingEvent, "Started reconciling")
136136

137+
var err error
137138
if !alp.DeletionTimestamp.IsZero() {
138-
return r.reconcileDelete(ctx, alp)
139+
err = r.reconcileDelete(ctx, alp)
139140
} else {
140-
return r.reconcileUpsert(ctx, alp)
141+
err = r.reconcileUpsert(ctx, alp)
141142
}
143+
144+
if err != nil {
145+
r.eventRecorder.Event(alp, corev1.EventTypeWarning, k8s.FailedReconcileEvent, fmt.Sprintf("Reconcile failed: %s", err))
146+
return err
147+
}
148+
149+
r.eventRecorder.Event(alp, corev1.EventTypeNormal, k8s.ReconciledEvent, "Successfully reconciled")
150+
return nil
142151
}
143152

144153
func (r *accessLogPolicyReconciler) reconcileDelete(ctx context.Context, alp *anv1alpha1.AccessLogPolicy) error {
145-
_, err := r.buildAndDeployModel(ctx, alp)
154+
targetRefName := alp.Annotations[anv1alpha1.AccessLogSubscriptionResourceNameAnnotationKey]
155+
_, err := r.buildAndDeployModel(ctx, alp, targetRefName)
146156
if err != nil {
147157
r.eventRecorder.Event(alp, corev1.EventTypeWarning,
148158
k8s.FailedReconcileEvent, fmt.Sprintf("Failed to delete due to %s", err))
@@ -189,7 +199,7 @@ func (r *accessLogPolicyReconciler) reconcileUpsert(ctx context.Context, alp *an
189199
return r.updateAccessLogPolicyStatus(ctx, alp, gwv1alpha2.PolicyReasonInvalid, message)
190200
}
191201

192-
targetRefExists, err := r.targetRefExists(ctx, alp)
202+
targetRefExists, targetRef, err := r.targetRefExists(ctx, alp)
193203
if err != nil {
194204
return err
195205
}
@@ -199,7 +209,15 @@ func (r *accessLogPolicyReconciler) reconcileUpsert(ctx context.Context, alp *an
199209
return r.updateAccessLogPolicyStatus(ctx, alp, gwv1alpha2.PolicyReasonTargetNotFound, message)
200210
}
201211

202-
stack, err := r.buildAndDeployModel(ctx, alp)
212+
targetRefName, err := r.targetRefToResourceName(alp, targetRef)
213+
if err != nil {
214+
if k8s.IsInvalidServiceNameOverrideError(err) {
215+
return r.updateAccessLogPolicyStatus(ctx, alp, gwv1alpha2.PolicyReasonInvalid, err.Error())
216+
}
217+
return err
218+
}
219+
220+
stack, err := r.buildAndDeployModel(ctx, alp, targetRefName)
203221
if err != nil {
204222
if services.IsConflictError(err) {
205223
message := "An Access Log Policy with a Destination Arn for the same destination type already exists for this targetRef"
@@ -215,7 +233,7 @@ func (r *accessLogPolicyReconciler) reconcileUpsert(ctx context.Context, alp *an
215233
return err
216234
}
217235

218-
err = r.updateAccessLogPolicyAnnotations(ctx, alp, stack)
236+
err = r.updateAccessLogPolicyAnnotations(ctx, alp, stack, targetRefName)
219237
if err != nil {
220238
return err
221239
}
@@ -230,40 +248,46 @@ func (r *accessLogPolicyReconciler) reconcileUpsert(ctx context.Context, alp *an
230248
return nil
231249
}
232250

233-
func (r *accessLogPolicyReconciler) targetRefExists(ctx context.Context, alp *anv1alpha1.AccessLogPolicy) (bool, error) {
251+
func (r *accessLogPolicyReconciler) targetRefExists(ctx context.Context, alp *anv1alpha1.AccessLogPolicy) (bool, metav1.Object, error) {
234252
targetRefNamespacedName := types.NamespacedName{
235253
Name: string(alp.Spec.TargetRef.Name),
236254
Namespace: k8s.NamespaceOrDefault(alp.Spec.TargetRef.Namespace),
237255
}
238256

239257
var err error
258+
var targetObj metav1.Object
240259

241260
switch alp.Spec.TargetRef.Kind {
242261
case "Gateway":
243262
gw := &gwv1.Gateway{}
244263
err = r.client.Get(ctx, targetRefNamespacedName, gw)
264+
targetObj = gw
245265
case "HTTPRoute":
246-
httpRoute := &gwv1.HTTPRoute{}
247-
err = r.client.Get(ctx, targetRefNamespacedName, httpRoute)
266+
route := &gwv1.HTTPRoute{}
267+
err = r.client.Get(ctx, targetRefNamespacedName, route)
268+
targetObj = route
248269
case "GRPCRoute":
249-
grpcRoute := &gwv1.GRPCRoute{}
250-
err = r.client.Get(ctx, targetRefNamespacedName, grpcRoute)
270+
route := &gwv1.GRPCRoute{}
271+
err = r.client.Get(ctx, targetRefNamespacedName, route)
272+
targetObj = route
251273
default:
252-
return false, fmt.Errorf("access Log Policy targetRef is for unsupported Kind: %s", alp.Spec.TargetRef.Kind)
274+
return false, nil, fmt.Errorf("access Log Policy targetRef is for unsupported Kind: %s", alp.Spec.TargetRef.Kind)
253275
}
254276

255277
if err != nil && !apierrors.IsNotFound(err) {
256-
return false, err
278+
return false, nil, err
257279
}
258280

259-
return err == nil, nil
281+
exists := err == nil
282+
return exists, targetObj, nil
260283
}
261284

262285
func (r *accessLogPolicyReconciler) buildAndDeployModel(
263286
ctx context.Context,
264287
alp *anv1alpha1.AccessLogPolicy,
288+
targetRefName string,
265289
) (core.Stack, error) {
266-
stack, _, err := r.modelBuilder.Build(ctx, alp)
290+
stack, _, err := r.modelBuilder.Build(ctx, alp, targetRefName)
267291
if err != nil {
268292
return nil, err
269293
}
@@ -286,6 +310,7 @@ func (r *accessLogPolicyReconciler) updateAccessLogPolicyAnnotations(
286310
ctx context.Context,
287311
alp *anv1alpha1.AccessLogPolicy,
288312
stack core.Stack,
313+
targetRefName string,
289314
) error {
290315
var accessLogSubscriptions []*model.AccessLogSubscription
291316
err := stack.ListResources(&accessLogSubscriptions)
@@ -300,6 +325,7 @@ func (r *accessLogPolicyReconciler) updateAccessLogPolicyAnnotations(
300325
alp.Annotations = make(map[string]string)
301326
}
302327
alp.Annotations[anv1alpha1.AccessLogSubscriptionAnnotationKey] = als.Status.Arn
328+
alp.Annotations[anv1alpha1.AccessLogSubscriptionResourceNameAnnotationKey] = targetRefName
303329
if err := r.client.Patch(ctx, alp, client.MergeFrom(oldAlp)); err != nil {
304330
r.eventRecorder.Event(alp, corev1.EventTypeWarning, k8s.FailedReconcileEvent,
305331
"Failed to update annotation due to "+err.Error())
@@ -375,3 +401,30 @@ func (r *accessLogPolicyReconciler) findImpactedAccessLogPolicies(ctx context.Co
375401

376402
return requests
377403
}
404+
405+
func (r *accessLogPolicyReconciler) targetRefToResourceName(
406+
alp *anv1alpha1.AccessLogPolicy,
407+
targetObj metav1.Object,
408+
) (string, error) {
409+
targetRef := alp.Spec.TargetRef
410+
411+
if targetRef.Kind == "Gateway" {
412+
return string(targetRef.Name), nil
413+
}
414+
415+
if targetRef.Kind == "HTTPRoute" || targetRef.Kind == "GRPCRoute" {
416+
namespace := alp.Namespace
417+
if targetRef.Namespace != nil {
418+
namespace = string(*targetRef.Namespace)
419+
}
420+
421+
serviceNameOverride, err := k8s.GetServiceNameOverrideWithValidation(targetObj)
422+
if err != nil {
423+
return "", fmt.Errorf("route '%s' has %w", targetRef.Name, err)
424+
}
425+
426+
return utils.LatticeServiceName(string(targetRef.Name), namespace, serviceNameOverride), nil
427+
}
428+
429+
return "", fmt.Errorf("unsupported targetRef kind: %s", targetRef.Kind)
430+
}

0 commit comments

Comments
 (0)