Skip to content

Commit

Permalink
Added support for updating Access Log Policy
Browse files Browse the repository at this point in the history
  • Loading branch information
Shawn Kaplan committed Oct 19, 2023
1 parent 19d3ea7 commit de37839
Show file tree
Hide file tree
Showing 7 changed files with 670 additions and 66 deletions.
2 changes: 1 addition & 1 deletion controllers/accesslogpolicy_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ func (r *accessLogPolicyReconciler) updateAccessLogPolicyAnnotations(
}

for _, als := range accessLogSubscriptions {
if als.Spec.EventType == core.CreateEvent {
if als.Spec.EventType != core.DeleteEvent {
oldAlp := alp.DeepCopy()
if alp.ObjectMeta.Annotations == nil {
alp.ObjectMeta.Annotations = make(map[string]string)
Expand Down
138 changes: 91 additions & 47 deletions pkg/deploy/lattice/access_log_subscription_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (

type AccessLogSubscriptionManager interface {
Create(ctx context.Context, accessLogSubscription *lattice.AccessLogSubscription) (*lattice.AccessLogSubscriptionStatus, error)
Update(ctx context.Context, accessLogSubscription *lattice.AccessLogSubscription) (*lattice.AccessLogSubscriptionStatus, error)
Delete(ctx context.Context, accessLogSubscription *lattice.AccessLogSubscription) error
}

Expand Down Expand Up @@ -72,58 +73,101 @@ func (m *defaultAccessLogSubscriptionManager) Create(
}

createALSOutput, err := vpcLatticeSess.CreateAccessLogSubscriptionWithContext(ctx, createALSInput)
if err != nil {
switch e := err.(type) {
case *vpclattice.AccessDeniedException:
return nil, services.NewInvalidError(e.Message())
case *vpclattice.ResourceNotFoundException:
if *e.ResourceType == "SERVICE_NETWORK" || *e.ResourceType == "SERVICE" {
return nil, services.NewNotFoundError(string(accessLogSubscription.Spec.SourceType), accessLogSubscription.Spec.SourceName)
}
return nil, services.NewInvalidError(e.Message())
case *vpclattice.ConflictException:
/*
* Conflict may arise if we retry creation due to a failure elsewhere in the controller,
* so we check if the conflicting ALS was created for the same ALP via its tags.
* If it is the same ALP, return success. Else, return ConflictError.
*/
listALSInput := &vpclattice.ListAccessLogSubscriptionsInput{
ResourceIdentifier: &resourceIdentifier,
}
listALSOutput, err := vpcLatticeSess.ListAccessLogSubscriptionsWithContext(ctx, listALSInput)
if err != nil {
return nil, err
}
for _, als := range listALSOutput.Items {
if *als.DestinationArn == accessLogSubscription.Spec.DestinationArn {
listTagsInput := &vpclattice.ListTagsForResourceInput{
ResourceArn: als.Arn,
}
listTagsOutput, err := vpcLatticeSess.ListTagsForResourceWithContext(ctx, listTagsInput)
if err != nil {
return nil, err
}
value, exists := listTagsOutput.Tags[lattice.AccessLogPolicyTagKey]
if exists && *value == accessLogSubscription.Spec.ALPNamespacedName.String() {
return &lattice.AccessLogSubscriptionStatus{
Arn: *als.Arn,
}, nil
}
if err == nil {
return &lattice.AccessLogSubscriptionStatus{
Arn: *createALSOutput.Arn,
}, nil
}

switch e := err.(type) {
case *vpclattice.AccessDeniedException:
return nil, services.NewInvalidError(e.Message())
case *vpclattice.ResourceNotFoundException:
if *e.ResourceType == "SERVICE_NETWORK" || *e.ResourceType == "SERVICE" {
return nil, services.NewNotFoundError(string(accessLogSubscription.Spec.SourceType), accessLogSubscription.Spec.SourceName)
}
return nil, services.NewInvalidError(e.Message())
case *vpclattice.ConflictException:
/*
* Conflict may arise if we retry creation due to a failure elsewhere in the controller,
* so we check if the conflicting ALS was created for the same ALP via its tags.
* If it is the same ALP, return success. Else, return ConflictError.
*/
listALSInput := &vpclattice.ListAccessLogSubscriptionsInput{
ResourceIdentifier: &resourceIdentifier,
}
listALSOutput, err := vpcLatticeSess.ListAccessLogSubscriptionsWithContext(ctx, listALSInput)
if err != nil {
return nil, err
}
for _, als := range listALSOutput.Items {
if *als.DestinationArn == accessLogSubscription.Spec.DestinationArn {
listTagsInput := &vpclattice.ListTagsForResourceInput{
ResourceArn: als.Arn,
}
listTagsOutput, err := vpcLatticeSess.ListTagsForResourceWithContext(ctx, listTagsInput)
if err != nil {
return nil, err
}
value, exists := listTagsOutput.Tags[lattice.AccessLogPolicyTagKey]
if exists && *value == accessLogSubscription.Spec.ALPNamespacedName.String() {
return &lattice.AccessLogSubscriptionStatus{
Arn: *als.Arn,
}, nil
}
}
return nil, services.NewConflictError(
string(accessLogSubscription.Spec.SourceType),
accessLogSubscription.Spec.SourceName,
e.Message(),
)
default:
return nil, err
}
return nil, services.NewConflictError(
string(accessLogSubscription.Spec.SourceType),
accessLogSubscription.Spec.SourceName,
e.Message(),
)
default:
return nil, err
}
}

return &lattice.AccessLogSubscriptionStatus{
Arn: *createALSOutput.Arn,
}, nil
func (m *defaultAccessLogSubscriptionManager) Update(
ctx context.Context,
accessLogSubscription *lattice.AccessLogSubscription,
) (*lattice.AccessLogSubscriptionStatus, error) {
vpcLatticeSess := m.cloud.Lattice()
updateALSInput := &vpclattice.UpdateAccessLogSubscriptionInput{
AccessLogSubscriptionIdentifier: aws.String(accessLogSubscription.Status.Arn),
DestinationArn: aws.String(accessLogSubscription.Spec.DestinationArn),
}
updateALSOutput, err := vpcLatticeSess.UpdateAccessLogSubscriptionWithContext(ctx, updateALSInput)
if err == nil {
return &lattice.AccessLogSubscriptionStatus{
Arn: *updateALSOutput.Arn,
}, nil
}

switch e := err.(type) {
case *vpclattice.AccessDeniedException:
return nil, services.NewInvalidError(e.Message())
case *vpclattice.ResourceNotFoundException:
if *e.ResourceType == "SERVICE_NETWORK" || *e.ResourceType == "SERVICE" {
return nil, services.NewNotFoundError(string(accessLogSubscription.Spec.SourceType), accessLogSubscription.Spec.SourceName)
}
return nil, services.NewInvalidError(e.Message())
case *vpclattice.ConflictException:
/*
* A conflict can happen when the destination type of the new ALS is different from the original.
* To gracefully handle this, we create a new ALS with the new destination, then delete the old one.
*/
alsStatus, err := m.Create(ctx, accessLogSubscription)
if err != nil {
return nil, err
}
err = m.Delete(ctx, accessLogSubscription)
if err != nil {
return nil, err
}
return alsStatus, nil
default:
return nil, err
}
}

func (m *defaultAccessLogSubscriptionManager) Delete(
Expand Down
15 changes: 15 additions & 0 deletions pkg/deploy/lattice/access_log_subscription_manager_mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit de37839

Please sign in to comment.