From a1ded32f58eb097b4c84f1adab98a82d7d2b1aef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bryan=E2=84=A2=EF=B8=8F?= Date: Mon, 8 Nov 2021 16:10:14 -0600 Subject: [PATCH 01/16] RouteTable move Routes from Status to Spec --- apis/v1alpha1/ack-generate-metadata.yaml | 6 +- apis/v1alpha1/generator.yaml | 11 +++ apis/v1alpha1/route_table.go | 4 +- apis/v1alpha1/zz_generated.deepcopy.go | 22 +++--- .../ec2.services.k8s.aws_routetables.yaml | 73 +++++++++---------- generator.yaml | 14 +++- .../ec2.services.k8s.aws_routetables.yaml | 73 +++++++++---------- pkg/resource/route_table/delta.go | 3 + pkg/resource/route_table/sdk.go | 8 +- 9 files changed, 117 insertions(+), 97 deletions(-) diff --git a/apis/v1alpha1/ack-generate-metadata.yaml b/apis/v1alpha1/ack-generate-metadata.yaml index 51a63d76..80ab19fb 100755 --- a/apis/v1alpha1/ack-generate-metadata.yaml +++ b/apis/v1alpha1/ack-generate-metadata.yaml @@ -1,13 +1,13 @@ ack_generate_info: - build_date: "2021-11-08T20:16:44Z" + build_date: "2021-11-08T22:08:27Z" build_hash: 6ce1a672eabd3908bdaa4ace356e1b58ee3e80ba go_version: go1.17 version: v0.15.2 -api_directory_checksum: 231335e65c729f31ac368b1483a38c2964b3219a +api_directory_checksum: 675e7b70bd7797b824a147e03a8c3ff293e7e894 api_version: v1alpha1 aws_sdk_go_version: v1.37.10 generator_config_info: - file_checksum: 438c2600566029a9ab883076d641246f0a8fbb88 + file_checksum: 6539228d5d6822f3d644803760f8bfeb047107a2 original_file_name: generator.yaml last_modification: reason: API generation diff --git a/apis/v1alpha1/generator.yaml b/apis/v1alpha1/generator.yaml index 46e2c362..eba8c74d 100644 --- a/apis/v1alpha1/generator.yaml +++ b/apis/v1alpha1/generator.yaml @@ -86,6 +86,16 @@ resources: terminal_codes: - InvalidVpcID.Malformed - InvalidVpcID.NotFound + - InvalidParameterValue + fields: + Routes: + custom_field: + list_of: Route + hooks: + sdk_create_post_set_output: + template_path: hooks/route_table/sdk_create_post_set_output.go.tpl + update_operation: + custom_method_name: customUpdateRouteTable SecurityGroup: fields: # support EC2-VPC only @@ -118,6 +128,7 @@ resources: terminal_codes: - InvalidVpcID.Malformed - InvalidVpcID.NotFound + - InvalidParameterValue VpcEndpoint: exceptions: terminal_codes: diff --git a/apis/v1alpha1/route_table.go b/apis/v1alpha1/route_table.go index 6ecf6e35..85b1ff8b 100644 --- a/apis/v1alpha1/route_table.go +++ b/apis/v1alpha1/route_table.go @@ -24,6 +24,7 @@ import ( // // Describes a route table. type RouteTableSpec struct { + Routes []*Route `json:"routes,omitempty"` // The tags to assign to the route table. TagSpecifications []*TagSpecification `json:"tagSpecifications,omitempty"` // The ID of the VPC. @@ -56,9 +57,6 @@ type RouteTableStatus struct { // The ID of the route table. // +kubebuilder:validation:Optional RouteTableID *string `json:"routeTableID,omitempty"` - // The routes in the route table. - // +kubebuilder:validation:Optional - Routes []*Route `json:"routes,omitempty"` // Any tags assigned to the route table. // +kubebuilder:validation:Optional Tags []*Tag `json:"tags,omitempty"` diff --git a/apis/v1alpha1/zz_generated.deepcopy.go b/apis/v1alpha1/zz_generated.deepcopy.go index 265a2f8c..b3a1e1fa 100644 --- a/apis/v1alpha1/zz_generated.deepcopy.go +++ b/apis/v1alpha1/zz_generated.deepcopy.go @@ -10573,6 +10573,17 @@ func (in *RouteTableList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *RouteTableSpec) DeepCopyInto(out *RouteTableSpec) { *out = *in + if in.Routes != nil { + in, out := &in.Routes, &out.Routes + *out = make([]*Route, len(*in)) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = new(Route) + (*in).DeepCopyInto(*out) + } + } + } if in.TagSpecifications != nil { in, out := &in.TagSpecifications, &out.TagSpecifications *out = make([]*TagSpecification, len(*in)) @@ -10652,17 +10663,6 @@ func (in *RouteTableStatus) DeepCopyInto(out *RouteTableStatus) { *out = new(string) **out = **in } - if in.Routes != nil { - in, out := &in.Routes, &out.Routes - *out = make([]*Route, len(*in)) - for i := range *in { - if (*in)[i] != nil { - in, out := &(*in)[i], &(*out)[i] - *out = new(Route) - (*in).DeepCopyInto(*out) - } - } - } if in.Tags != nil { in, out := &in.Tags, &out.Tags *out = make([]*Tag, len(*in)) diff --git a/config/crd/bases/ec2.services.k8s.aws_routetables.yaml b/config/crd/bases/ec2.services.k8s.aws_routetables.yaml index c1f71c11..3f27fae5 100644 --- a/config/crd/bases/ec2.services.k8s.aws_routetables.yaml +++ b/config/crd/bases/ec2.services.k8s.aws_routetables.yaml @@ -37,6 +37,42 @@ spec: description: "RouteTableSpec defines the desired state of RouteTable. \n Describes a route table." properties: + routes: + items: + description: Describes a route in a route table. + properties: + carrierGatewayID: + type: string + destinationCIDRBlock: + type: string + destinationIPv6CIDRBlock: + type: string + destinationPrefixListID: + type: string + egressOnlyInternetGatewayID: + type: string + gatewayID: + type: string + instanceID: + type: string + instanceOwnerID: + type: string + localGatewayID: + type: string + natGatewayID: + type: string + networkInterfaceID: + type: string + origin: + type: string + state: + type: string + transitGatewayID: + type: string + vpcPeeringConnectionID: + type: string + type: object + type: array tagSpecifications: description: The tags to assign to the route table. items: @@ -165,43 +201,6 @@ spec: routeTableID: description: The ID of the route table. type: string - routes: - description: The routes in the route table. - items: - description: Describes a route in a route table. - properties: - carrierGatewayID: - type: string - destinationCIDRBlock: - type: string - destinationIPv6CIDRBlock: - type: string - destinationPrefixListID: - type: string - egressOnlyInternetGatewayID: - type: string - gatewayID: - type: string - instanceID: - type: string - instanceOwnerID: - type: string - localGatewayID: - type: string - natGatewayID: - type: string - networkInterfaceID: - type: string - origin: - type: string - state: - type: string - transitGatewayID: - type: string - vpcPeeringConnectionID: - type: string - type: object - type: array tags: description: Any tags assigned to the route table. items: diff --git a/generator.yaml b/generator.yaml index 46e2c362..3e20b0a5 100644 --- a/generator.yaml +++ b/generator.yaml @@ -86,6 +86,16 @@ resources: terminal_codes: - InvalidVpcID.Malformed - InvalidVpcID.NotFound + - InvalidParameterValue + fields: + Routes: + custom_field: + list_of: Route + hooks: + sdk_create_post_set_output: + template_path: hooks/route_table/sdk_create_post_set_output.go.tpl + update_operation: + custom_method_name: customUpdateRouteTable SecurityGroup: fields: # support EC2-VPC only @@ -118,6 +128,7 @@ resources: terminal_codes: - InvalidVpcID.Malformed - InvalidVpcID.NotFound + - InvalidParameterValue VpcEndpoint: exceptions: terminal_codes: @@ -126,5 +137,4 @@ resources: - InvalidServiceName hooks: sdk_delete_post_build_request: - template_path: hooks/vpc_endpoint/sdk_delete_post_build_request.go.tpl - + template_path: hooks/vpc_endpoint/sdk_delete_post_build_request.go.tpl \ No newline at end of file diff --git a/helm/crds/ec2.services.k8s.aws_routetables.yaml b/helm/crds/ec2.services.k8s.aws_routetables.yaml index c1f71c11..3f27fae5 100644 --- a/helm/crds/ec2.services.k8s.aws_routetables.yaml +++ b/helm/crds/ec2.services.k8s.aws_routetables.yaml @@ -37,6 +37,42 @@ spec: description: "RouteTableSpec defines the desired state of RouteTable. \n Describes a route table." properties: + routes: + items: + description: Describes a route in a route table. + properties: + carrierGatewayID: + type: string + destinationCIDRBlock: + type: string + destinationIPv6CIDRBlock: + type: string + destinationPrefixListID: + type: string + egressOnlyInternetGatewayID: + type: string + gatewayID: + type: string + instanceID: + type: string + instanceOwnerID: + type: string + localGatewayID: + type: string + natGatewayID: + type: string + networkInterfaceID: + type: string + origin: + type: string + state: + type: string + transitGatewayID: + type: string + vpcPeeringConnectionID: + type: string + type: object + type: array tagSpecifications: description: The tags to assign to the route table. items: @@ -165,43 +201,6 @@ spec: routeTableID: description: The ID of the route table. type: string - routes: - description: The routes in the route table. - items: - description: Describes a route in a route table. - properties: - carrierGatewayID: - type: string - destinationCIDRBlock: - type: string - destinationIPv6CIDRBlock: - type: string - destinationPrefixListID: - type: string - egressOnlyInternetGatewayID: - type: string - gatewayID: - type: string - instanceID: - type: string - instanceOwnerID: - type: string - localGatewayID: - type: string - natGatewayID: - type: string - networkInterfaceID: - type: string - origin: - type: string - state: - type: string - transitGatewayID: - type: string - vpcPeeringConnectionID: - type: string - type: object - type: array tags: description: Any tags assigned to the route table. items: diff --git a/pkg/resource/route_table/delta.go b/pkg/resource/route_table/delta.go index 0cfce948..b12feb6d 100644 --- a/pkg/resource/route_table/delta.go +++ b/pkg/resource/route_table/delta.go @@ -41,6 +41,9 @@ func newResourceDelta( return delta } + if !reflect.DeepEqual(a.ko.Spec.Routes, b.ko.Spec.Routes) { + delta.Add("Spec.Routes", a.ko.Spec.Routes, b.ko.Spec.Routes) + } if !reflect.DeepEqual(a.ko.Spec.TagSpecifications, b.ko.Spec.TagSpecifications) { delta.Add("Spec.TagSpecifications", a.ko.Spec.TagSpecifications, b.ko.Spec.TagSpecifications) } diff --git a/pkg/resource/route_table/sdk.go b/pkg/resource/route_table/sdk.go index 71fa5072..55457955 100644 --- a/pkg/resource/route_table/sdk.go +++ b/pkg/resource/route_table/sdk.go @@ -190,9 +190,9 @@ func (rm *resourceManager) sdkFind( } f4 = append(f4, f4elem) } - ko.Status.Routes = f4 + ko.Spec.Routes = f4 } else { - ko.Status.Routes = nil + ko.Spec.Routes = nil } if elem.Tags != nil { f5 := []*svcapitypes.Tag{} @@ -387,9 +387,9 @@ func (rm *resourceManager) sdkCreate( } f4 = append(f4, f4elem) } - ko.Status.Routes = f4 + ko.Spec.Routes = f4 } else { - ko.Status.Routes = nil + ko.Spec.Routes = nil } if resp.RouteTable.Tags != nil { f5 := []*svcapitypes.Tag{} From 63f6c239f83f8cc13f37105b84d49525b868b401 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bryan=E2=84=A2=EF=B8=8F?= Date: Mon, 15 Nov 2021 13:10:45 -0600 Subject: [PATCH 02/16] add hooks for Route --- apis/v1alpha1/ack-generate-metadata.yaml | 6 +- apis/v1alpha1/generator.yaml | 3 +- generator.yaml | 3 +- pkg/resource/route_table/hooks.go | 433 ++++++++++++++++++ pkg/resource/route_table/sdk.go | 9 +- .../sdk_create_post_set_output.go.tpl | 6 + 6 files changed, 452 insertions(+), 8 deletions(-) create mode 100644 pkg/resource/route_table/hooks.go create mode 100644 templates/hooks/route_table/sdk_create_post_set_output.go.tpl diff --git a/apis/v1alpha1/ack-generate-metadata.yaml b/apis/v1alpha1/ack-generate-metadata.yaml index 80ab19fb..35ce4403 100755 --- a/apis/v1alpha1/ack-generate-metadata.yaml +++ b/apis/v1alpha1/ack-generate-metadata.yaml @@ -1,13 +1,13 @@ ack_generate_info: - build_date: "2021-11-08T22:08:27Z" + build_date: "2021-11-15T18:29:12Z" build_hash: 6ce1a672eabd3908bdaa4ace356e1b58ee3e80ba go_version: go1.17 version: v0.15.2 -api_directory_checksum: 675e7b70bd7797b824a147e03a8c3ff293e7e894 +api_directory_checksum: 2a4836424559dfcd59758d41a6a98078ba6f0baf api_version: v1alpha1 aws_sdk_go_version: v1.37.10 generator_config_info: - file_checksum: 6539228d5d6822f3d644803760f8bfeb047107a2 + file_checksum: 4e2135ec04a34c66529a3d264ea16faec118c7bd original_file_name: generator.yaml last_modification: reason: API generation diff --git a/apis/v1alpha1/generator.yaml b/apis/v1alpha1/generator.yaml index eba8c74d..3e20b0a5 100644 --- a/apis/v1alpha1/generator.yaml +++ b/apis/v1alpha1/generator.yaml @@ -137,5 +137,4 @@ resources: - InvalidServiceName hooks: sdk_delete_post_build_request: - template_path: hooks/vpc_endpoint/sdk_delete_post_build_request.go.tpl - + template_path: hooks/vpc_endpoint/sdk_delete_post_build_request.go.tpl \ No newline at end of file diff --git a/generator.yaml b/generator.yaml index 3e20b0a5..eba8c74d 100644 --- a/generator.yaml +++ b/generator.yaml @@ -137,4 +137,5 @@ resources: - InvalidServiceName hooks: sdk_delete_post_build_request: - template_path: hooks/vpc_endpoint/sdk_delete_post_build_request.go.tpl \ No newline at end of file + template_path: hooks/vpc_endpoint/sdk_delete_post_build_request.go.tpl + diff --git a/pkg/resource/route_table/hooks.go b/pkg/resource/route_table/hooks.go new file mode 100644 index 00000000..585afa6a --- /dev/null +++ b/pkg/resource/route_table/hooks.go @@ -0,0 +1,433 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). You may +// not use this file except in compliance with the License. A copy of the +// License is located at +// +// http://aws.amazon.com/apache2.0/ +// +// or in the "license" file accompanying this file. This file is distributed +// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language governing +// permissions and limitations under the License. + +package route_table + +import ( + "context" + "fmt" + + svcapitypes "github.com/aws-controllers-k8s/ec2-controller/apis/v1alpha1" + ackcompare "github.com/aws-controllers-k8s/runtime/pkg/compare" + ackrtlog "github.com/aws-controllers-k8s/runtime/pkg/runtime/log" + svcsdk "github.com/aws/aws-sdk-go/service/ec2" +) + +// RouteAction stores the possible actions that can be performed on +// any of a Route Table's Routes +type RouteAction int + +const ( + RouteActionNone RouteAction = iota + RouteActionDefault + RouteActionCreate + RouteActionDelete + RouteActionServer + RouteActionUpdate +) + +func (rm *resourceManager) createRoutes( + ctx context.Context, + r *resource, +) error { + if len(r.ko.Spec.Routes) > 0 { + if err := rm.syncRoutes(ctx, r, nil); err != nil { + return err + } + } + return nil +} + +func (rm *resourceManager) syncRoutes( + ctx context.Context, + desired *resource, + latest *resource, +) (err error) { + rlog := ackrtlog.FromContext(ctx) + exit := rlog.Trace("rm.syncRoutes") + defer exit(err) + + // if there are desired routes then we need to see if we got to create any + // no-op if same + // if desired doesn't match anything in latest we need to create it + for _, rc := range desired.ko.Spec.Routes { + action := getRouteAction(rc, latest) + switch action { + case RouteActionCreate: + if err = rm.createRoute(ctx, desired, *rc); err != nil { + return err + } + // case RouteActionServer: + //directly set current resource's field directly from server + // case RouteActionDefault: + // // if err = rm.addDefaultRoute(ctx, desired, *rc); err != nil { + // // return err + // // } + // defaultCIDRBlock := "172.31.0.0/16" + // defaultGatewayID := "local" //not valid in api req + // defaultRoute := svcapitypes.Route{ + // DestinationCIDRBlock: &defaultCIDRBlock, + // GatewayID: &defaultGatewayID, + // } + + default: + } + } + + if latest != nil { + // it's possible we either have fewer desired routes than latest/current routes OR + // latest/current routes do not match desired route spec + // we need to find which latest routes are not desired routes and delete them! + for _, l := range latest.ko.Spec.Routes { + desiredRoute := false + for _, d := range desired.ko.Spec.Routes { + delta := compareRoute(l, d) + //if a Route matches identically, then it is desired + if len(delta.Differences) == 0 { + desiredRoute = true + break + } + //if only diffs are Origin/State (set server-side take the desired) + onlyDifference := false + for _, dd := range delta.Differences { + if !(dd.Path.Contains("Route.Origin") || dd.Path.Contains("Route.State")) { + onlyDifference = false + break + } + onlyDifference = true + } + if onlyDifference { + desiredRoute = true + //Latest was actually CreateRoute Active not desired + // fmt.Println("Route Origin and/or State are the only diffs! hard-coding from desired") + // if d.Origin != nil { + // fmt.Printf("Desired Origin: %s\n", *d.Origin) + // } + // if d.State != nil { + // fmt.Printf("Desired STate: %s\n", *d.State) + // } + // fmt.Printf("Current Origin + State: %s %s\n", *l.Origin, *l.State) + // l.Origin = d.Origin + // l.State = d.State + } + + } + if !desiredRoute { + //TODO: 2nd param is set to 'desired' in s3 controller...? + if err = rm.deleteRoute(ctx, latest, *l); err != nil { + return err + } + } + + } + } + + return nil +} + +// getRouteAction returns the determined action for a given +// route object, depending on the latest and desired values +func getRouteAction( + desired *svcapitypes.Route, + latest *resource, +) RouteAction { + fmt.Println("getRouteAction") + //Origin and State are decided by server.. + + //Needed even with LateInitializtion?? The api call to CreateRoute w/'local' still happens + //if desired Route is default Route, then do NOT make API call + if *desired.GatewayID == "local" { + fmt.Println("getRouteAction: desired GatewayID is local..this is a defaulted field req") + return RouteActionDefault + } + + action := RouteActionCreate + if latest != nil { + for _, l := range latest.ko.Spec.Routes { + delta := compareRoute(l, desired) + if len(delta.Differences) == 0 { + return RouteActionNone + } + } + } + return action +} + +func compareRoute( + a *svcapitypes.Route, + b *svcapitypes.Route, +) *ackcompare.Delta { + delta := ackcompare.NewDelta() + if ackcompare.HasNilDifference(a.CarrierGatewayID, b.CarrierGatewayID) { + delta.Add("Route.CarrierGatewayID", a.CarrierGatewayID, b.CarrierGatewayID) + } else if a.CarrierGatewayID != nil && b.CarrierGatewayID != nil { + if *a.CarrierGatewayID != *b.CarrierGatewayID { + delta.Add("Route.CarrierGatewayID", a.CarrierGatewayID, b.CarrierGatewayID) + } + } + if ackcompare.HasNilDifference(a.DestinationCIDRBlock, b.DestinationCIDRBlock) { + delta.Add("Route.DestinationCIDRBlock", a.DestinationCIDRBlock, b.DestinationCIDRBlock) + } else if a.DestinationCIDRBlock != nil && b.DestinationCIDRBlock != nil { + if *a.DestinationCIDRBlock != *b.DestinationCIDRBlock { + delta.Add("Route.DestinationCIDRBlock", a.DestinationCIDRBlock, b.DestinationCIDRBlock) + } + } + if ackcompare.HasNilDifference(a.DestinationIPv6CIDRBlock, b.DestinationIPv6CIDRBlock) { + delta.Add("Route.DestinationIPv6CIDRBlock", a.DestinationIPv6CIDRBlock, b.DestinationIPv6CIDRBlock) + } else if a.DestinationIPv6CIDRBlock != nil && b.DestinationIPv6CIDRBlock != nil { + if *a.DestinationIPv6CIDRBlock != *b.DestinationIPv6CIDRBlock { + delta.Add("Route.DestinationIPv6CIDRBlock", a.DestinationIPv6CIDRBlock, b.DestinationIPv6CIDRBlock) + } + } + if ackcompare.HasNilDifference(a.DestinationPrefixListID, b.DestinationPrefixListID) { + delta.Add("Route.DestinationPrefixListID", a.DestinationPrefixListID, b.DestinationPrefixListID) + } else if a.DestinationPrefixListID != nil && b.DestinationPrefixListID != nil { + if *a.DestinationPrefixListID != *b.DestinationPrefixListID { + delta.Add("Route.DestinationPrefixListID", a.DestinationPrefixListID, b.DestinationPrefixListID) + } + } + if ackcompare.HasNilDifference(a.EgressOnlyInternetGatewayID, b.EgressOnlyInternetGatewayID) { + delta.Add("Route.EgressOnlyInternetGatewayID", a.EgressOnlyInternetGatewayID, b.EgressOnlyInternetGatewayID) + } else if a.EgressOnlyInternetGatewayID != nil && b.EgressOnlyInternetGatewayID != nil { + if *a.EgressOnlyInternetGatewayID != *b.EgressOnlyInternetGatewayID { + delta.Add("Route.EgressOnlyInternetGatewayID", a.EgressOnlyInternetGatewayID, b.EgressOnlyInternetGatewayID) + } + } + if ackcompare.HasNilDifference(a.GatewayID, b.GatewayID) { + delta.Add("Route.GatewayID", a.GatewayID, b.GatewayID) + } else if a.GatewayID != nil && b.GatewayID != nil { + if *a.GatewayID != *b.GatewayID { + delta.Add("Route.GatewayID", a.GatewayID, b.GatewayID) + } + } + if ackcompare.HasNilDifference(a.InstanceID, b.InstanceID) { + delta.Add("Route.InstanceID", a.InstanceID, b.InstanceID) + } else if a.InstanceID != nil && b.InstanceID != nil { + if *a.InstanceID != *b.InstanceID { + delta.Add("Route.InstanceID", a.InstanceID, b.InstanceID) + } + } + if ackcompare.HasNilDifference(a.InstanceOwnerID, b.InstanceOwnerID) { + delta.Add("Route.InstanceOwnerID", a.InstanceOwnerID, b.InstanceOwnerID) + } else if a.InstanceOwnerID != nil && b.InstanceOwnerID != nil { + if *a.InstanceOwnerID != *b.InstanceOwnerID { + delta.Add("Route.InstanceOwnerID", a.InstanceOwnerID, b.InstanceOwnerID) + } + } + if ackcompare.HasNilDifference(a.LocalGatewayID, b.LocalGatewayID) { + delta.Add("Route.LocalGatewayID", a.LocalGatewayID, b.LocalGatewayID) + } else if a.LocalGatewayID != nil && b.LocalGatewayID != nil { + if *a.LocalGatewayID != *b.LocalGatewayID { + delta.Add("Route.LocalGatewayID", a.LocalGatewayID, b.LocalGatewayID) + } + } + if ackcompare.HasNilDifference(a.NatGatewayID, b.NatGatewayID) { + delta.Add("Route.NatGatewayID", a.NatGatewayID, b.NatGatewayID) + } else if a.NatGatewayID != nil && b.NatGatewayID != nil { + if *a.NatGatewayID != *b.NatGatewayID { + delta.Add("Route.NatGatewayID", a.NatGatewayID, b.NatGatewayID) + } + } + if ackcompare.HasNilDifference(a.NetworkInterfaceID, b.NetworkInterfaceID) { + delta.Add("Route.NetworkInterfaceID", a.NetworkInterfaceID, b.NetworkInterfaceID) + } else if a.NetworkInterfaceID != nil && b.NetworkInterfaceID != nil { + if *a.NetworkInterfaceID != *b.NetworkInterfaceID { + delta.Add("Route.NetworkInterfaceID", a.NetworkInterfaceID, b.NetworkInterfaceID) + } + } + if ackcompare.HasNilDifference(a.TransitGatewayID, b.TransitGatewayID) { + delta.Add("Route.TransitGatewayID", a.TransitGatewayID, b.TransitGatewayID) + } else if a.TransitGatewayID != nil && b.TransitGatewayID != nil { + if *a.TransitGatewayID != *b.TransitGatewayID { + delta.Add("Route.TransitGatewayID", a.TransitGatewayID, b.TransitGatewayID) + } + } + if ackcompare.HasNilDifference(a.VPCPeeringConnectionID, b.VPCPeeringConnectionID) { + delta.Add("Route.VPCPeeringConnectionID", a.VPCPeeringConnectionID, b.VPCPeeringConnectionID) + } else if a.VPCPeeringConnectionID != nil && b.VPCPeeringConnectionID != nil { + if *a.VPCPeeringConnectionID != *b.VPCPeeringConnectionID { + delta.Add("Route.VPCPeeringConnectionID", a.VPCPeeringConnectionID, b.VPCPeeringConnectionID) + } + } + if ackcompare.HasNilDifference(a.Origin, b.Origin) { + delta.Add("Route.Origin", a.Origin, b.Origin) + } else if a.Origin != nil && b.Origin != nil { + if *a.Origin != *b.Origin { + delta.Add("Route.Origin", a.Origin, b.Origin) + } + } + if ackcompare.HasNilDifference(a.State, b.State) { + delta.Add("Route.State", a.State, b.State) + } else if a.State != nil && b.State != nil { + if *a.State != *b.State { + delta.Add("Route.State", a.State, b.State) + } + } + + return delta +} + +func (rm *resourceManager) createRoute( + ctx context.Context, + r *resource, + c svcapitypes.Route, +) (err error) { + rlog := ackrtlog.FromContext(ctx) + exit := rlog.Trace("rm.createRoute") + defer exit(err) + + input := rm.newCreateRoutePayload(r, c) + _, err = rm.sdkapi.CreateRouteWithContext(ctx, input) + rm.metrics.RecordAPICall("CREATE", "CreateRoute", err) + return err +} + +func (rm *resourceManager) deleteRoute( + ctx context.Context, + r *resource, + c svcapitypes.Route, +) (err error) { + rlog := ackrtlog.FromContext(ctx) + exit := rlog.Trace("rm.deleteRoute") + defer exit(err) + + input := rm.newDeleteRoutePayload(r, c) + _, err = rm.sdkapi.DeleteRouteWithContext(ctx, input) + rm.metrics.RecordAPICall("DELETE", "DeleteRoute", err) + return err +} + +// newCreateRouteRequestPayload +func (rm *resourceManager) newCreateRoutePayload( + r *resource, + c svcapitypes.Route, +) *svcsdk.CreateRouteInput { + input := &svcsdk.CreateRouteInput{} + + //TODO: right place to check here? this is required! + if r.ko.Status.RouteTableID != nil { + input.SetRouteTableId(*r.ko.Status.RouteTableID) + } + + if c.CarrierGatewayID != nil { + input.SetCarrierGatewayId(*c.CarrierGatewayID) + } + if c.DestinationCIDRBlock != nil { + input.SetDestinationCidrBlock(*c.DestinationCIDRBlock) + } + if c.DestinationIPv6CIDRBlock != nil { + input.SetDestinationIpv6CidrBlock(*c.DestinationIPv6CIDRBlock) + } + if c.DestinationPrefixListID != nil { + input.SetDestinationPrefixListId(*c.DestinationPrefixListID) + } + if c.EgressOnlyInternetGatewayID != nil { + input.SetEgressOnlyInternetGatewayId(*c.EgressOnlyInternetGatewayID) + } + if c.GatewayID != nil { + input.SetGatewayId(*c.GatewayID) + } + if c.InstanceID != nil { + input.SetInstanceId(*c.InstanceID) + } + if c.LocalGatewayID != nil { + input.SetLocalGatewayId(*c.LocalGatewayID) + } + if c.NatGatewayID != nil { + input.SetNatGatewayId(*c.NatGatewayID) + } + if c.NetworkInterfaceID != nil { + input.SetNetworkInterfaceId(*c.NetworkInterfaceID) + } + if c.TransitGatewayID != nil { + input.SetTransitGatewayId(*c.TransitGatewayID) + } + if c.VPCPeeringConnectionID != nil { + input.SetVpcPeeringConnectionId(*c.VPCPeeringConnectionID) + } + //TODO: VpcEndpointId got ignored for some reason? + + return input +} + +// newDeleteRoutePayload +func (rm *resourceManager) newDeleteRoutePayload( + r *resource, + c svcapitypes.Route, +) *svcsdk.DeleteRouteInput { + input := &svcsdk.DeleteRouteInput{} + + //TODO: right place to check here? this is required! + if r.ko.Status.RouteTableID != nil { + input.SetRouteTableId(*r.ko.Status.RouteTableID) + } + + if c.DestinationCIDRBlock != nil { + input.SetDestinationCidrBlock(*c.DestinationCIDRBlock) + } + if c.DestinationIPv6CIDRBlock != nil { + input.SetDestinationIpv6CidrBlock(*c.DestinationIPv6CIDRBlock) + } + if c.DestinationPrefixListID != nil { + input.SetDestinationPrefixListId(*c.DestinationPrefixListID) + } + + return input +} + +// customUpdateRouteTable patches each of the resource properties in the backend AWS +// service API and returns a new resource with updated fields. +func (rm *resourceManager) customUpdateRouteTable( + ctx context.Context, + desired *resource, + latest *resource, + delta *ackcompare.Delta, +) (updated *resource, err error) { + rlog := ackrtlog.FromContext(ctx) + exit := rlog.Trace("rm.customUpdateRouteTable") + defer exit(err) + + // Merge in the information we read from the API call above to the copy of + // the original Kubernetes object we passed to the function + ko := desired.ko.DeepCopy() + + rm.setStatusDefaults(ko) + + if delta.DifferentAt("Spec.Routes") { + if err := rm.syncRoutes(ctx, desired, latest); err != nil { + return nil, err + } + latest, err = rm.sdkFind(ctx, latest) + if err != nil { + return nil, err + } + } + + return latest, nil +} + +func (rm *resourceManager) requiredFieldsMissingForCreateRoute( + r *resource, +) bool { + return r.ko.Status.RouteTableID == nil +} + +// customPreCompare ensures that default values of nil-able types are +// appropriately replaced with empty maps or structs depending on the default +// output of the SDK. +// func customPreCompare( +// a *resource, +// b *resource, +// ) { + +// } diff --git a/pkg/resource/route_table/sdk.go b/pkg/resource/route_table/sdk.go index 55457955..7323b219 100644 --- a/pkg/resource/route_table/sdk.go +++ b/pkg/resource/route_table/sdk.go @@ -414,6 +414,12 @@ func (rm *resourceManager) sdkCreate( } rm.setStatusDefaults(ko) + if rm.requiredFieldsMissingForCreateRoute(&resource{ko}) { + return nil, ackerr.NotFound + } + if err := rm.createRoutes(ctx, &resource{ko}); err != nil { + return nil, err + } return &resource{ko}, nil } @@ -465,8 +471,7 @@ func (rm *resourceManager) sdkUpdate( latest *resource, delta *ackcompare.Delta, ) (*resource, error) { - // TODO(jaypipes): Figure this out... - return nil, ackerr.NotImplemented + return rm.customUpdateRouteTable(ctx, desired, latest, delta) } // sdkDelete deletes the supplied resource in the backend AWS service API diff --git a/templates/hooks/route_table/sdk_create_post_set_output.go.tpl b/templates/hooks/route_table/sdk_create_post_set_output.go.tpl new file mode 100644 index 00000000..b150a656 --- /dev/null +++ b/templates/hooks/route_table/sdk_create_post_set_output.go.tpl @@ -0,0 +1,6 @@ + if rm.requiredFieldsMissingForCreateRoute(&resource{ko}) { + return nil, ackerr.NotFound + } + if err := rm.createRoutes(ctx, &resource{ko}); err != nil { + return nil, err + } \ No newline at end of file From f877b687bcd5eec448d6b068df44c05d804335b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bryan=E2=84=A2=EF=B8=8F?= Date: Mon, 15 Nov 2021 13:36:03 -0600 Subject: [PATCH 03/16] fix creating RouteTable with Routes --- .../sdk_create_post_set_output.go.tpl | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/templates/hooks/route_table/sdk_create_post_set_output.go.tpl b/templates/hooks/route_table/sdk_create_post_set_output.go.tpl index b150a656..3984bf4f 100644 --- a/templates/hooks/route_table/sdk_create_post_set_output.go.tpl +++ b/templates/hooks/route_table/sdk_create_post_set_output.go.tpl @@ -1,6 +1,11 @@ - if rm.requiredFieldsMissingForCreateRoute(&resource{ko}) { - return nil, ackerr.NotFound - } - if err := rm.createRoutes(ctx, &resource{ko}); err != nil { - return nil, err - } \ No newline at end of file + if rm.requiredFieldsMissingForCreateRoute(&resource{ko}) { + return nil, ackerr.NotFound + } + + if len(desired.ko.Spec.Routes) > 0 { + //desired routes are overwritten by RouteTable's default route + ko.Spec.Routes = append(ko.Spec.Routes, desired.ko.Spec.Routes...) + if err := rm.createRoutes(ctx, &resource{ko}); err != nil { + return nil, err + } + } \ No newline at end of file From 7de88b14b7c11b949f8101dfc2b10913437a4472 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bryan=E2=84=A2=EF=B8=8F?= Date: Mon, 15 Nov 2021 17:29:09 -0600 Subject: [PATCH 04/16] add crud test for route --- test/e2e/resources/route_table.yaml | 3 + test/e2e/service_bootstrap.py | 2 +- test/e2e/tests/test_route_table.py | 149 +++++++++++++++++++++++++++- 3 files changed, 150 insertions(+), 4 deletions(-) diff --git a/test/e2e/resources/route_table.yaml b/test/e2e/resources/route_table.yaml index 2e34dfea..c8e2ff42 100644 --- a/test/e2e/resources/route_table.yaml +++ b/test/e2e/resources/route_table.yaml @@ -3,4 +3,7 @@ kind: RouteTable metadata: name: $ROUTE_TABLE_NAME spec: + routes: + - destinationCIDRBlock: $DEST_CIDR_BLOCK + gatewayID: $IGW_ID vpcID: $VPC_ID \ No newline at end of file diff --git a/test/e2e/service_bootstrap.py b/test/e2e/service_bootstrap.py index 12009de1..f1e96539 100644 --- a/test/e2e/service_bootstrap.py +++ b/test/e2e/service_bootstrap.py @@ -24,7 +24,7 @@ def service_bootstrap() -> Resources: logging.getLogger().setLevel(logging.INFO) resources = BootstrapResources( - SharedTestVPC=VPC(name_prefix="e2e-test-vpc", num_public_subnet=0, num_private_subnet=0) + SharedTestVPC=VPC(name_prefix="e2e-test-vpc", num_public_subnet=1, num_private_subnet=0) ) try: diff --git a/test/e2e/tests/test_route_table.py b/test/e2e/tests/test_route_table.py index bedc6469..07332fba 100644 --- a/test/e2e/tests/test_route_table.py +++ b/test/e2e/tests/test_route_table.py @@ -26,9 +26,11 @@ RESOURCE_PLURAL = "routetables" +DEFAULT_WAIT_AFTER_SECONDS = 5 CREATE_WAIT_AFTER_SECONDS = 10 DELETE_WAIT_AFTER_SECONDS = 10 + def get_route_table(ec2_client, route_table_id: str) -> dict: try: resp = ec2_client.describe_route_tables( @@ -46,6 +48,26 @@ def get_route_table(ec2_client, route_table_id: str) -> dict: def route_table_exists(ec2_client, route_table_id: str) -> bool: return get_route_table(ec2_client, route_table_id) is not None +def get_routes(ec2_client, route_table_id: str) -> list: + try: + resp = ec2_client.describe_route_tables( + Filters=[{"Name": "route-table-id", "Values": [route_table_id]}] + ) + except Exception as e: + logging.debug(e) + return None + + if len(resp["RouteTables"]) == 0: + return None + return resp["RouteTables"][0]["Routes"] + +def route_exists(ec2_client, route_table_id: str, gateway_id: str, origin: str) -> bool: + routes = get_routes(ec2_client, route_table_id) + for route in routes: + if route["Origin"] == origin and route["GatewayId"] == gateway_id: + return True + return False + @service_marker @pytest.mark.canary class TestRouteTable: @@ -54,9 +76,13 @@ def test_create_delete(self, ec2_client): resource_name = random_suffix_name("route-table-test", 24) test_vpc = get_bootstrap_resources().SharedTestVPC vpc_id = test_vpc.vpc_id + igw_id = test_vpc.public_subnets.route_table.internet_gateway.internet_gateway_id + test_cidr_block = "100.68.0.0/18" test_resource_values["ROUTE_TABLE_NAME"] = resource_name test_resource_values["VPC_ID"] = vpc_id + test_resource_values["IGW_ID"] = igw_id + test_resource_values["DEST_CIDR_BLOCK"] = test_cidr_block # Load Route Table CR resource_data = load_ec2_resource( @@ -82,8 +108,7 @@ def test_create_delete(self, ec2_client): time.sleep(CREATE_WAIT_AFTER_SECONDS) # Check Route Table exists - exists = route_table_exists(ec2_client, resource_id) - assert exists + assert route_table_exists(ec2_client, resource_id) # Delete k8s resource _, deleted = k8s.delete_custom_resource(ref) @@ -95,6 +120,7 @@ def test_create_delete(self, ec2_client): exists = route_table_exists(ec2_client, resource_id) assert not exists + def test_terminal_condition(self): test_resource_values = REPLACEMENT_VALUES.copy() resource_name = random_suffix_name("route-table-fail", 24) @@ -125,4 +151,121 @@ def test_terminal_condition(self): # InvalidVpcID.NotFound: The vpc ID 'InvalidVpcId' does not exist # status code: 400, request id: 5801fc80-67cf-465f-8b83-5e02d517d554 # This check only verifies the error message; the request hash is irrelevant and therefore can be ignored. - assert expected_msg in terminal_condition['message'] \ No newline at end of file + assert expected_msg in terminal_condition['message'] + + def test_crud_route(self, ec2_client): + test_resource_values = REPLACEMENT_VALUES.copy() + resource_name = random_suffix_name("route-table-test", 24) + test_vpc = get_bootstrap_resources().SharedTestVPC + vpc_id = test_vpc.vpc_id + igw_id = test_vpc.public_subnets.route_table.internet_gateway.internet_gateway_id + test_cidr_block = "100.68.0.0/18" + + test_resource_values["ROUTE_TABLE_NAME"] = resource_name + test_resource_values["VPC_ID"] = vpc_id + test_resource_values["IGW_ID"] = igw_id + test_resource_values["DEST_CIDR_BLOCK"] = test_cidr_block + + # Load Route Table CR + resource_data = load_ec2_resource( + "route_table", + additional_replacements=test_resource_values, + ) + logging.debug(resource_data) + + # Create k8s resource + ref = k8s.CustomResourceReference( + CRD_GROUP, CRD_VERSION, RESOURCE_PLURAL, + resource_name, namespace="default", + ) + k8s.create_custom_resource(ref, resource_data) + cr = k8s.wait_resource_consumed_by_controller(ref) + + assert cr is not None + assert k8s.get_resource_exists(ref) + + resource = k8s.get_resource(ref) + resource_id = resource["status"]["routeTableID"] + + time.sleep(CREATE_WAIT_AFTER_SECONDS) + + # Check Route Table exists + assert route_table_exists(ec2_client, resource_id) + + # Check Routes exist (default and desired) + routes = get_routes(ec2_client, resource_id) + for route in routes: + if route["GatewayId"] == "local": + default_cidr = route["DestinationCidrBlock"] + assert route["Origin"] == "CreateRouteTable" + elif route["GatewayId"] == igw_id: + assert route["Origin"] == "CreateRoute" + else: + assert False + + # Update Route + updated_cidr = "100.68.0.0/18" + patch = {"spec": {"routes": [ + { + #Default route cannot be changed + "destinationCIDRBlock": default_cidr, + "gatewayID": "local", + "origin": "CreateRouteTable", + "state": "active" + }, + { + "destinationCIDRBlock": updated_cidr, + "gatewayID": igw_id, + "origin": "no", + "state": "texas" + } + ] + } + } + _ = k8s.patch_custom_resource(ref, patch) + time.sleep(DEFAULT_WAIT_AFTER_SECONDS) + + # assert patched state + resource = k8s.get_resource(ref) + assert len(resource['spec']['routes']) == 2 + for route in resource['spec']['routes']: + if route["gatewayID"] == "local": + assert route_exists(ec2_client, resource_id, "local", "CreateRouteTable") + elif route["gatewayID"] == igw_id: + # origin and state are set server-side + assert route_exists(ec2_client, resource_id, igw_id, "CreateRoute") + assert route["state"] == "active" + else: + assert False + + # Delete Route + patch = {"spec": {"routes": [ + { + "destinationCIDRBlock": default_cidr, + "gatewayID": "local", + "origin": "CreateRouteTable", + "state": "active" + } + ] + } + } + _ = k8s.patch_custom_resource(ref, patch) + time.sleep(DEFAULT_WAIT_AFTER_SECONDS) + + resource = k8s.get_resource(ref) + assert len(resource['spec']['routes']) == 1 + for route in resource['spec']['routes']: + if route["gatewayID"] == "local": + assert route_exists(ec2_client, resource_id, "local", "CreateRouteTable") + else: + assert False + + # Delete k8s resource + _, deleted = k8s.delete_custom_resource(ref) + assert deleted is True + + time.sleep(DELETE_WAIT_AFTER_SECONDS) + + # Check Route Table doesn't exist + exists = route_table_exists(ec2_client, resource_id) + assert not exists \ No newline at end of file From 45bcf45f98f28f98be1734180ea8fa3a6c4eff90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bryan=E2=84=A2=EF=B8=8F?= Date: Mon, 15 Nov 2021 18:03:03 -0600 Subject: [PATCH 05/16] add terminal condition for attempting to delete default route and test --- apis/v1alpha1/ack-generate-metadata.yaml | 4 ++-- apis/v1alpha1/generator.yaml | 3 ++- pkg/resource/route_table/sdk.go | 12 +++++++++--- test/e2e/tests/test_route_table.py | 19 ++++++++++++++++--- 4 files changed, 29 insertions(+), 9 deletions(-) diff --git a/apis/v1alpha1/ack-generate-metadata.yaml b/apis/v1alpha1/ack-generate-metadata.yaml index 35ce4403..326265b2 100755 --- a/apis/v1alpha1/ack-generate-metadata.yaml +++ b/apis/v1alpha1/ack-generate-metadata.yaml @@ -1,5 +1,5 @@ ack_generate_info: - build_date: "2021-11-15T18:29:12Z" + build_date: "2021-11-15T23:40:12Z" build_hash: 6ce1a672eabd3908bdaa4ace356e1b58ee3e80ba go_version: go1.17 version: v0.15.2 @@ -7,7 +7,7 @@ api_directory_checksum: 2a4836424559dfcd59758d41a6a98078ba6f0baf api_version: v1alpha1 aws_sdk_go_version: v1.37.10 generator_config_info: - file_checksum: 4e2135ec04a34c66529a3d264ea16faec118c7bd + file_checksum: 417a3c1c010e19ea6b3638045ded5cd00c20d049 original_file_name: generator.yaml last_modification: reason: API generation diff --git a/apis/v1alpha1/generator.yaml b/apis/v1alpha1/generator.yaml index 3e20b0a5..eba8c74d 100644 --- a/apis/v1alpha1/generator.yaml +++ b/apis/v1alpha1/generator.yaml @@ -137,4 +137,5 @@ resources: - InvalidServiceName hooks: sdk_delete_post_build_request: - template_path: hooks/vpc_endpoint/sdk_delete_post_build_request.go.tpl \ No newline at end of file + template_path: hooks/vpc_endpoint/sdk_delete_post_build_request.go.tpl + diff --git a/pkg/resource/route_table/sdk.go b/pkg/resource/route_table/sdk.go index 7323b219..54ed93c1 100644 --- a/pkg/resource/route_table/sdk.go +++ b/pkg/resource/route_table/sdk.go @@ -417,8 +417,13 @@ func (rm *resourceManager) sdkCreate( if rm.requiredFieldsMissingForCreateRoute(&resource{ko}) { return nil, ackerr.NotFound } - if err := rm.createRoutes(ctx, &resource{ko}); err != nil { - return nil, err + + if len(desired.ko.Spec.Routes) > 0 { + //desired routes are overwritten by RouteTable's default route + ko.Spec.Routes = append(ko.Spec.Routes, desired.ko.Spec.Routes...) + if err := rm.createRoutes(ctx, &resource{ko}); err != nil { + return nil, err + } } return &resource{ko}, nil } @@ -612,7 +617,8 @@ func (rm *resourceManager) terminalAWSError(err error) bool { } switch awsErr.Code() { case "InvalidVpcID.Malformed", - "InvalidVpcID.NotFound": + "InvalidVpcID.NotFound", + "InvalidParameterValue": return true default: return false diff --git a/test/e2e/tests/test_route_table.py b/test/e2e/tests/test_route_table.py index 07332fba..c25bcab1 100644 --- a/test/e2e/tests/test_route_table.py +++ b/test/e2e/tests/test_route_table.py @@ -173,7 +173,7 @@ def test_crud_route(self, ec2_client): ) logging.debug(resource_data) - # Create k8s resource + # Create Route Table ref = k8s.CustomResourceReference( CRD_GROUP, CRD_VERSION, RESOURCE_PLURAL, resource_name, namespace="default", @@ -202,7 +202,7 @@ def test_crud_route(self, ec2_client): assert route["Origin"] == "CreateRoute" else: assert False - + # Update Route updated_cidr = "100.68.0.0/18" patch = {"spec": {"routes": [ @@ -260,7 +260,20 @@ def test_crud_route(self, ec2_client): else: assert False - # Delete k8s resource + + # Should not be able to delete default route + patch = {"spec": {"routes": [ + ] + } + } + _ = k8s.patch_custom_resource(ref, patch) + time.sleep(DEFAULT_WAIT_AFTER_SECONDS) + + expected_msg = "InvalidParameterValue: cannot remove local route" + terminal_condition = k8s.get_resource_condition(ref, "ACK.Terminal") + assert expected_msg in terminal_condition['message'] + + # Delete Route Table _, deleted = k8s.delete_custom_resource(ref) assert deleted is True From c43e34910e84cda4c875f2ee69456a8cde7a4d19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bryan=E2=84=A2=EF=B8=8F?= Date: Mon, 15 Nov 2021 18:04:15 -0600 Subject: [PATCH 06/16] cleanup route table hook code --- apis/v1alpha1/generator.yaml | 1 - generator.yaml | 1 - pkg/resource/route_table/hooks.go | 87 ++----------------------------- 3 files changed, 4 insertions(+), 85 deletions(-) diff --git a/apis/v1alpha1/generator.yaml b/apis/v1alpha1/generator.yaml index eba8c74d..19d635e6 100644 --- a/apis/v1alpha1/generator.yaml +++ b/apis/v1alpha1/generator.yaml @@ -128,7 +128,6 @@ resources: terminal_codes: - InvalidVpcID.Malformed - InvalidVpcID.NotFound - - InvalidParameterValue VpcEndpoint: exceptions: terminal_codes: diff --git a/generator.yaml b/generator.yaml index eba8c74d..19d635e6 100644 --- a/generator.yaml +++ b/generator.yaml @@ -128,7 +128,6 @@ resources: terminal_codes: - InvalidVpcID.Malformed - InvalidVpcID.NotFound - - InvalidParameterValue VpcEndpoint: exceptions: terminal_codes: diff --git a/pkg/resource/route_table/hooks.go b/pkg/resource/route_table/hooks.go index 585afa6a..59797bc2 100644 --- a/pkg/resource/route_table/hooks.go +++ b/pkg/resource/route_table/hooks.go @@ -15,7 +15,6 @@ package route_table import ( "context" - "fmt" svcapitypes "github.com/aws-controllers-k8s/ec2-controller/apis/v1alpha1" ackcompare "github.com/aws-controllers-k8s/runtime/pkg/compare" @@ -29,21 +28,15 @@ type RouteAction int const ( RouteActionNone RouteAction = iota - RouteActionDefault RouteActionCreate - RouteActionDelete - RouteActionServer - RouteActionUpdate ) func (rm *resourceManager) createRoutes( ctx context.Context, r *resource, ) error { - if len(r.ko.Spec.Routes) > 0 { - if err := rm.syncRoutes(ctx, r, nil); err != nil { - return err - } + if err := rm.syncRoutes(ctx, r, nil); err != nil { + return err } return nil } @@ -57,9 +50,6 @@ func (rm *resourceManager) syncRoutes( exit := rlog.Trace("rm.syncRoutes") defer exit(err) - // if there are desired routes then we need to see if we got to create any - // no-op if same - // if desired doesn't match anything in latest we need to create it for _, rc := range desired.ko.Spec.Routes { action := getRouteAction(rc, latest) switch action { @@ -67,27 +57,12 @@ func (rm *resourceManager) syncRoutes( if err = rm.createRoute(ctx, desired, *rc); err != nil { return err } - // case RouteActionServer: - //directly set current resource's field directly from server - // case RouteActionDefault: - // // if err = rm.addDefaultRoute(ctx, desired, *rc); err != nil { - // // return err - // // } - // defaultCIDRBlock := "172.31.0.0/16" - // defaultGatewayID := "local" //not valid in api req - // defaultRoute := svcapitypes.Route{ - // DestinationCIDRBlock: &defaultCIDRBlock, - // GatewayID: &defaultGatewayID, - // } default: } } if latest != nil { - // it's possible we either have fewer desired routes than latest/current routes OR - // latest/current routes do not match desired route spec - // we need to find which latest routes are not desired routes and delete them! for _, l := range latest.ko.Spec.Routes { desiredRoute := false for _, d := range desired.ko.Spec.Routes { @@ -97,33 +72,8 @@ func (rm *resourceManager) syncRoutes( desiredRoute = true break } - //if only diffs are Origin/State (set server-side take the desired) - onlyDifference := false - for _, dd := range delta.Differences { - if !(dd.Path.Contains("Route.Origin") || dd.Path.Contains("Route.State")) { - onlyDifference = false - break - } - onlyDifference = true - } - if onlyDifference { - desiredRoute = true - //Latest was actually CreateRoute Active not desired - // fmt.Println("Route Origin and/or State are the only diffs! hard-coding from desired") - // if d.Origin != nil { - // fmt.Printf("Desired Origin: %s\n", *d.Origin) - // } - // if d.State != nil { - // fmt.Printf("Desired STate: %s\n", *d.State) - // } - // fmt.Printf("Current Origin + State: %s %s\n", *l.Origin, *l.State) - // l.Origin = d.Origin - // l.State = d.State - } - } if !desiredRoute { - //TODO: 2nd param is set to 'desired' in s3 controller...? if err = rm.deleteRoute(ctx, latest, *l); err != nil { return err } @@ -141,14 +91,9 @@ func getRouteAction( desired *svcapitypes.Route, latest *resource, ) RouteAction { - fmt.Println("getRouteAction") - //Origin and State are decided by server.. - - //Needed even with LateInitializtion?? The api call to CreateRoute w/'local' still happens - //if desired Route is default Route, then do NOT make API call + //the default route created by RouteTable; no action needed if *desired.GatewayID == "local" { - fmt.Println("getRouteAction: desired GatewayID is local..this is a defaulted field req") - return RouteActionDefault + return RouteActionNone } action := RouteActionCreate @@ -307,18 +252,14 @@ func (rm *resourceManager) deleteRoute( return err } -// newCreateRouteRequestPayload func (rm *resourceManager) newCreateRoutePayload( r *resource, c svcapitypes.Route, ) *svcsdk.CreateRouteInput { input := &svcsdk.CreateRouteInput{} - - //TODO: right place to check here? this is required! if r.ko.Status.RouteTableID != nil { input.SetRouteTableId(*r.ko.Status.RouteTableID) } - if c.CarrierGatewayID != nil { input.SetCarrierGatewayId(*c.CarrierGatewayID) } @@ -355,23 +296,18 @@ func (rm *resourceManager) newCreateRoutePayload( if c.VPCPeeringConnectionID != nil { input.SetVpcPeeringConnectionId(*c.VPCPeeringConnectionID) } - //TODO: VpcEndpointId got ignored for some reason? return input } -// newDeleteRoutePayload func (rm *resourceManager) newDeleteRoutePayload( r *resource, c svcapitypes.Route, ) *svcsdk.DeleteRouteInput { input := &svcsdk.DeleteRouteInput{} - - //TODO: right place to check here? this is required! if r.ko.Status.RouteTableID != nil { input.SetRouteTableId(*r.ko.Status.RouteTableID) } - if c.DestinationCIDRBlock != nil { input.SetDestinationCidrBlock(*c.DestinationCIDRBlock) } @@ -385,8 +321,6 @@ func (rm *resourceManager) newDeleteRoutePayload( return input } -// customUpdateRouteTable patches each of the resource properties in the backend AWS -// service API and returns a new resource with updated fields. func (rm *resourceManager) customUpdateRouteTable( ctx context.Context, desired *resource, @@ -397,10 +331,7 @@ func (rm *resourceManager) customUpdateRouteTable( exit := rlog.Trace("rm.customUpdateRouteTable") defer exit(err) - // Merge in the information we read from the API call above to the copy of - // the original Kubernetes object we passed to the function ko := desired.ko.DeepCopy() - rm.setStatusDefaults(ko) if delta.DifferentAt("Spec.Routes") { @@ -421,13 +352,3 @@ func (rm *resourceManager) requiredFieldsMissingForCreateRoute( ) bool { return r.ko.Status.RouteTableID == nil } - -// customPreCompare ensures that default values of nil-able types are -// appropriately replaced with empty maps or structs depending on the default -// output of the SDK. -// func customPreCompare( -// a *resource, -// b *resource, -// ) { - -// } From bd6c24b686673b7d9ad9891cddfc2425eb6c6aff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bryan=E2=84=A2=EF=B8=8F?= Date: Tue, 16 Nov 2021 11:00:27 -0600 Subject: [PATCH 07/16] fix cidr block in subnet test --- test/e2e/tests/test_subnet.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/e2e/tests/test_subnet.py b/test/e2e/tests/test_subnet.py index c55b5492..85ead176 100644 --- a/test/e2e/tests/test_subnet.py +++ b/test/e2e/tests/test_subnet.py @@ -56,11 +56,11 @@ def test_create_delete(self, ec2_client): resource_name = random_suffix_name("subnet-test", 24) test_vpc = get_bootstrap_resources().SharedTestVPC vpc_id = test_vpc.vpc_id - vpc_cidr = test_vpc.vpc_cidr_block test_resource_values["SUBNET_NAME"] = resource_name test_resource_values["VPC_ID"] = vpc_id - test_resource_values["CIDR_BLOCK"] = vpc_cidr + # CIDR needs to be within SharedTestVPC range and not overlap other subnets + test_resource_values["CIDR_BLOCK"] = "10.0.255.0/24" # Load Subnet CR resource_data = load_ec2_resource( @@ -80,7 +80,9 @@ def test_create_delete(self, ec2_client): assert cr is not None assert k8s.get_resource_exists(ref) + print(f"ref is {ref}") resource = k8s.get_resource(ref) + print(f"res is {resource}") resource_id = resource["status"]["subnetID"] time.sleep(CREATE_WAIT_AFTER_SECONDS) From 1da63766c3afb49c92c2e8b10ebdf9e39bd40d56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bryan=E2=84=A2=EF=B8=8F?= Date: Tue, 16 Nov 2021 13:17:50 -0600 Subject: [PATCH 08/16] dynamically generate compareRoute --- apis/v1alpha1/ack-generate-metadata.yaml | 6 +- apis/v1alpha1/generator.yaml | 2 + generator.yaml | 2 + pkg/resource/route_table/hooks.go | 115 +----------------- pkg/resource/route_table/sdk.go | 114 +++++++++++++++++ .../hooks/route_table/sdk_file_end.go.tpl | 26 ++++ 6 files changed, 148 insertions(+), 117 deletions(-) create mode 100644 templates/hooks/route_table/sdk_file_end.go.tpl diff --git a/apis/v1alpha1/ack-generate-metadata.yaml b/apis/v1alpha1/ack-generate-metadata.yaml index 326265b2..a1e11112 100755 --- a/apis/v1alpha1/ack-generate-metadata.yaml +++ b/apis/v1alpha1/ack-generate-metadata.yaml @@ -1,13 +1,13 @@ ack_generate_info: - build_date: "2021-11-15T23:40:12Z" + build_date: "2021-11-16T19:16:05Z" build_hash: 6ce1a672eabd3908bdaa4ace356e1b58ee3e80ba go_version: go1.17 version: v0.15.2 -api_directory_checksum: 2a4836424559dfcd59758d41a6a98078ba6f0baf +api_directory_checksum: 1eb52a5e544da8ce7e0a002e605254e4501296b2 api_version: v1alpha1 aws_sdk_go_version: v1.37.10 generator_config_info: - file_checksum: 417a3c1c010e19ea6b3638045ded5cd00c20d049 + file_checksum: acb593a25988c80f7edc78127b9d8e859236809d original_file_name: generator.yaml last_modification: reason: API generation diff --git a/apis/v1alpha1/generator.yaml b/apis/v1alpha1/generator.yaml index 19d635e6..5833fe3c 100644 --- a/apis/v1alpha1/generator.yaml +++ b/apis/v1alpha1/generator.yaml @@ -94,6 +94,8 @@ resources: hooks: sdk_create_post_set_output: template_path: hooks/route_table/sdk_create_post_set_output.go.tpl + sdk_file_end: + template_path: hooks/route_table/sdk_file_end.go.tpl update_operation: custom_method_name: customUpdateRouteTable SecurityGroup: diff --git a/generator.yaml b/generator.yaml index 19d635e6..5833fe3c 100644 --- a/generator.yaml +++ b/generator.yaml @@ -94,6 +94,8 @@ resources: hooks: sdk_create_post_set_output: template_path: hooks/route_table/sdk_create_post_set_output.go.tpl + sdk_file_end: + template_path: hooks/route_table/sdk_file_end.go.tpl update_operation: custom_method_name: customUpdateRouteTable SecurityGroup: diff --git a/pkg/resource/route_table/hooks.go b/pkg/resource/route_table/hooks.go index 59797bc2..3b809595 100644 --- a/pkg/resource/route_table/hooks.go +++ b/pkg/resource/route_table/hooks.go @@ -108,120 +108,6 @@ func getRouteAction( return action } -func compareRoute( - a *svcapitypes.Route, - b *svcapitypes.Route, -) *ackcompare.Delta { - delta := ackcompare.NewDelta() - if ackcompare.HasNilDifference(a.CarrierGatewayID, b.CarrierGatewayID) { - delta.Add("Route.CarrierGatewayID", a.CarrierGatewayID, b.CarrierGatewayID) - } else if a.CarrierGatewayID != nil && b.CarrierGatewayID != nil { - if *a.CarrierGatewayID != *b.CarrierGatewayID { - delta.Add("Route.CarrierGatewayID", a.CarrierGatewayID, b.CarrierGatewayID) - } - } - if ackcompare.HasNilDifference(a.DestinationCIDRBlock, b.DestinationCIDRBlock) { - delta.Add("Route.DestinationCIDRBlock", a.DestinationCIDRBlock, b.DestinationCIDRBlock) - } else if a.DestinationCIDRBlock != nil && b.DestinationCIDRBlock != nil { - if *a.DestinationCIDRBlock != *b.DestinationCIDRBlock { - delta.Add("Route.DestinationCIDRBlock", a.DestinationCIDRBlock, b.DestinationCIDRBlock) - } - } - if ackcompare.HasNilDifference(a.DestinationIPv6CIDRBlock, b.DestinationIPv6CIDRBlock) { - delta.Add("Route.DestinationIPv6CIDRBlock", a.DestinationIPv6CIDRBlock, b.DestinationIPv6CIDRBlock) - } else if a.DestinationIPv6CIDRBlock != nil && b.DestinationIPv6CIDRBlock != nil { - if *a.DestinationIPv6CIDRBlock != *b.DestinationIPv6CIDRBlock { - delta.Add("Route.DestinationIPv6CIDRBlock", a.DestinationIPv6CIDRBlock, b.DestinationIPv6CIDRBlock) - } - } - if ackcompare.HasNilDifference(a.DestinationPrefixListID, b.DestinationPrefixListID) { - delta.Add("Route.DestinationPrefixListID", a.DestinationPrefixListID, b.DestinationPrefixListID) - } else if a.DestinationPrefixListID != nil && b.DestinationPrefixListID != nil { - if *a.DestinationPrefixListID != *b.DestinationPrefixListID { - delta.Add("Route.DestinationPrefixListID", a.DestinationPrefixListID, b.DestinationPrefixListID) - } - } - if ackcompare.HasNilDifference(a.EgressOnlyInternetGatewayID, b.EgressOnlyInternetGatewayID) { - delta.Add("Route.EgressOnlyInternetGatewayID", a.EgressOnlyInternetGatewayID, b.EgressOnlyInternetGatewayID) - } else if a.EgressOnlyInternetGatewayID != nil && b.EgressOnlyInternetGatewayID != nil { - if *a.EgressOnlyInternetGatewayID != *b.EgressOnlyInternetGatewayID { - delta.Add("Route.EgressOnlyInternetGatewayID", a.EgressOnlyInternetGatewayID, b.EgressOnlyInternetGatewayID) - } - } - if ackcompare.HasNilDifference(a.GatewayID, b.GatewayID) { - delta.Add("Route.GatewayID", a.GatewayID, b.GatewayID) - } else if a.GatewayID != nil && b.GatewayID != nil { - if *a.GatewayID != *b.GatewayID { - delta.Add("Route.GatewayID", a.GatewayID, b.GatewayID) - } - } - if ackcompare.HasNilDifference(a.InstanceID, b.InstanceID) { - delta.Add("Route.InstanceID", a.InstanceID, b.InstanceID) - } else if a.InstanceID != nil && b.InstanceID != nil { - if *a.InstanceID != *b.InstanceID { - delta.Add("Route.InstanceID", a.InstanceID, b.InstanceID) - } - } - if ackcompare.HasNilDifference(a.InstanceOwnerID, b.InstanceOwnerID) { - delta.Add("Route.InstanceOwnerID", a.InstanceOwnerID, b.InstanceOwnerID) - } else if a.InstanceOwnerID != nil && b.InstanceOwnerID != nil { - if *a.InstanceOwnerID != *b.InstanceOwnerID { - delta.Add("Route.InstanceOwnerID", a.InstanceOwnerID, b.InstanceOwnerID) - } - } - if ackcompare.HasNilDifference(a.LocalGatewayID, b.LocalGatewayID) { - delta.Add("Route.LocalGatewayID", a.LocalGatewayID, b.LocalGatewayID) - } else if a.LocalGatewayID != nil && b.LocalGatewayID != nil { - if *a.LocalGatewayID != *b.LocalGatewayID { - delta.Add("Route.LocalGatewayID", a.LocalGatewayID, b.LocalGatewayID) - } - } - if ackcompare.HasNilDifference(a.NatGatewayID, b.NatGatewayID) { - delta.Add("Route.NatGatewayID", a.NatGatewayID, b.NatGatewayID) - } else if a.NatGatewayID != nil && b.NatGatewayID != nil { - if *a.NatGatewayID != *b.NatGatewayID { - delta.Add("Route.NatGatewayID", a.NatGatewayID, b.NatGatewayID) - } - } - if ackcompare.HasNilDifference(a.NetworkInterfaceID, b.NetworkInterfaceID) { - delta.Add("Route.NetworkInterfaceID", a.NetworkInterfaceID, b.NetworkInterfaceID) - } else if a.NetworkInterfaceID != nil && b.NetworkInterfaceID != nil { - if *a.NetworkInterfaceID != *b.NetworkInterfaceID { - delta.Add("Route.NetworkInterfaceID", a.NetworkInterfaceID, b.NetworkInterfaceID) - } - } - if ackcompare.HasNilDifference(a.TransitGatewayID, b.TransitGatewayID) { - delta.Add("Route.TransitGatewayID", a.TransitGatewayID, b.TransitGatewayID) - } else if a.TransitGatewayID != nil && b.TransitGatewayID != nil { - if *a.TransitGatewayID != *b.TransitGatewayID { - delta.Add("Route.TransitGatewayID", a.TransitGatewayID, b.TransitGatewayID) - } - } - if ackcompare.HasNilDifference(a.VPCPeeringConnectionID, b.VPCPeeringConnectionID) { - delta.Add("Route.VPCPeeringConnectionID", a.VPCPeeringConnectionID, b.VPCPeeringConnectionID) - } else if a.VPCPeeringConnectionID != nil && b.VPCPeeringConnectionID != nil { - if *a.VPCPeeringConnectionID != *b.VPCPeeringConnectionID { - delta.Add("Route.VPCPeeringConnectionID", a.VPCPeeringConnectionID, b.VPCPeeringConnectionID) - } - } - if ackcompare.HasNilDifference(a.Origin, b.Origin) { - delta.Add("Route.Origin", a.Origin, b.Origin) - } else if a.Origin != nil && b.Origin != nil { - if *a.Origin != *b.Origin { - delta.Add("Route.Origin", a.Origin, b.Origin) - } - } - if ackcompare.HasNilDifference(a.State, b.State) { - delta.Add("Route.State", a.State, b.State) - } else if a.State != nil && b.State != nil { - if *a.State != *b.State { - delta.Add("Route.State", a.State, b.State) - } - } - - return delta -} - func (rm *resourceManager) createRoute( ctx context.Context, r *resource, @@ -296,6 +182,7 @@ func (rm *resourceManager) newCreateRoutePayload( if c.VPCPeeringConnectionID != nil { input.SetVpcPeeringConnectionId(*c.VPCPeeringConnectionID) } + input.SetDryRun(false) return input } diff --git a/pkg/resource/route_table/sdk.go b/pkg/resource/route_table/sdk.go index 54ed93c1..d06c95a4 100644 --- a/pkg/resource/route_table/sdk.go +++ b/pkg/resource/route_table/sdk.go @@ -624,3 +624,117 @@ func (rm *resourceManager) terminalAWSError(err error) bool { return false } } + +func compareRoute( + a *svcapitypes.Route, + b *svcapitypes.Route, +) *ackcompare.Delta { + delta := ackcompare.NewDelta() + if ackcompare.HasNilDifference(a.CarrierGatewayID, b.CarrierGatewayID) { + delta.Add("Route.CarrierGatewayID", a.CarrierGatewayID, b.CarrierGatewayID) + } else if a.CarrierGatewayID != nil && b.CarrierGatewayID != nil { + if *a.CarrierGatewayID != *b.CarrierGatewayID { + delta.Add("Route.CarrierGatewayID", a.CarrierGatewayID, b.CarrierGatewayID) + } + } + if ackcompare.HasNilDifference(a.DestinationCIDRBlock, b.DestinationCIDRBlock) { + delta.Add("Route.DestinationCIDRBlock", a.DestinationCIDRBlock, b.DestinationCIDRBlock) + } else if a.DestinationCIDRBlock != nil && b.DestinationCIDRBlock != nil { + if *a.DestinationCIDRBlock != *b.DestinationCIDRBlock { + delta.Add("Route.DestinationCIDRBlock", a.DestinationCIDRBlock, b.DestinationCIDRBlock) + } + } + if ackcompare.HasNilDifference(a.DestinationIPv6CIDRBlock, b.DestinationIPv6CIDRBlock) { + delta.Add("Route.DestinationIPv6CIDRBlock", a.DestinationIPv6CIDRBlock, b.DestinationIPv6CIDRBlock) + } else if a.DestinationIPv6CIDRBlock != nil && b.DestinationIPv6CIDRBlock != nil { + if *a.DestinationIPv6CIDRBlock != *b.DestinationIPv6CIDRBlock { + delta.Add("Route.DestinationIPv6CIDRBlock", a.DestinationIPv6CIDRBlock, b.DestinationIPv6CIDRBlock) + } + } + if ackcompare.HasNilDifference(a.DestinationPrefixListID, b.DestinationPrefixListID) { + delta.Add("Route.DestinationPrefixListID", a.DestinationPrefixListID, b.DestinationPrefixListID) + } else if a.DestinationPrefixListID != nil && b.DestinationPrefixListID != nil { + if *a.DestinationPrefixListID != *b.DestinationPrefixListID { + delta.Add("Route.DestinationPrefixListID", a.DestinationPrefixListID, b.DestinationPrefixListID) + } + } + if ackcompare.HasNilDifference(a.EgressOnlyInternetGatewayID, b.EgressOnlyInternetGatewayID) { + delta.Add("Route.EgressOnlyInternetGatewayID", a.EgressOnlyInternetGatewayID, b.EgressOnlyInternetGatewayID) + } else if a.EgressOnlyInternetGatewayID != nil && b.EgressOnlyInternetGatewayID != nil { + if *a.EgressOnlyInternetGatewayID != *b.EgressOnlyInternetGatewayID { + delta.Add("Route.EgressOnlyInternetGatewayID", a.EgressOnlyInternetGatewayID, b.EgressOnlyInternetGatewayID) + } + } + if ackcompare.HasNilDifference(a.GatewayID, b.GatewayID) { + delta.Add("Route.GatewayID", a.GatewayID, b.GatewayID) + } else if a.GatewayID != nil && b.GatewayID != nil { + if *a.GatewayID != *b.GatewayID { + delta.Add("Route.GatewayID", a.GatewayID, b.GatewayID) + } + } + if ackcompare.HasNilDifference(a.InstanceID, b.InstanceID) { + delta.Add("Route.InstanceID", a.InstanceID, b.InstanceID) + } else if a.InstanceID != nil && b.InstanceID != nil { + if *a.InstanceID != *b.InstanceID { + delta.Add("Route.InstanceID", a.InstanceID, b.InstanceID) + } + } + if ackcompare.HasNilDifference(a.InstanceOwnerID, b.InstanceOwnerID) { + delta.Add("Route.InstanceOwnerID", a.InstanceOwnerID, b.InstanceOwnerID) + } else if a.InstanceOwnerID != nil && b.InstanceOwnerID != nil { + if *a.InstanceOwnerID != *b.InstanceOwnerID { + delta.Add("Route.InstanceOwnerID", a.InstanceOwnerID, b.InstanceOwnerID) + } + } + if ackcompare.HasNilDifference(a.LocalGatewayID, b.LocalGatewayID) { + delta.Add("Route.LocalGatewayID", a.LocalGatewayID, b.LocalGatewayID) + } else if a.LocalGatewayID != nil && b.LocalGatewayID != nil { + if *a.LocalGatewayID != *b.LocalGatewayID { + delta.Add("Route.LocalGatewayID", a.LocalGatewayID, b.LocalGatewayID) + } + } + if ackcompare.HasNilDifference(a.NatGatewayID, b.NatGatewayID) { + delta.Add("Route.NatGatewayID", a.NatGatewayID, b.NatGatewayID) + } else if a.NatGatewayID != nil && b.NatGatewayID != nil { + if *a.NatGatewayID != *b.NatGatewayID { + delta.Add("Route.NatGatewayID", a.NatGatewayID, b.NatGatewayID) + } + } + if ackcompare.HasNilDifference(a.NetworkInterfaceID, b.NetworkInterfaceID) { + delta.Add("Route.NetworkInterfaceID", a.NetworkInterfaceID, b.NetworkInterfaceID) + } else if a.NetworkInterfaceID != nil && b.NetworkInterfaceID != nil { + if *a.NetworkInterfaceID != *b.NetworkInterfaceID { + delta.Add("Route.NetworkInterfaceID", a.NetworkInterfaceID, b.NetworkInterfaceID) + } + } + if ackcompare.HasNilDifference(a.Origin, b.Origin) { + delta.Add("Route.Origin", a.Origin, b.Origin) + } else if a.Origin != nil && b.Origin != nil { + if *a.Origin != *b.Origin { + delta.Add("Route.Origin", a.Origin, b.Origin) + } + } + if ackcompare.HasNilDifference(a.State, b.State) { + delta.Add("Route.State", a.State, b.State) + } else if a.State != nil && b.State != nil { + if *a.State != *b.State { + delta.Add("Route.State", a.State, b.State) + } + } + if ackcompare.HasNilDifference(a.TransitGatewayID, b.TransitGatewayID) { + delta.Add("Route.TransitGatewayID", a.TransitGatewayID, b.TransitGatewayID) + } else if a.TransitGatewayID != nil && b.TransitGatewayID != nil { + if *a.TransitGatewayID != *b.TransitGatewayID { + delta.Add("Route.TransitGatewayID", a.TransitGatewayID, b.TransitGatewayID) + } + } + if ackcompare.HasNilDifference(a.VPCPeeringConnectionID, b.VPCPeeringConnectionID) { + delta.Add("Route.VPCPeeringConnectionID", a.VPCPeeringConnectionID, b.VPCPeeringConnectionID) + } else if a.VPCPeeringConnectionID != nil && b.VPCPeeringConnectionID != nil { + if *a.VPCPeeringConnectionID != *b.VPCPeeringConnectionID { + delta.Add("Route.VPCPeeringConnectionID", a.VPCPeeringConnectionID, b.VPCPeeringConnectionID) + } + } + + return delta +} diff --git a/templates/hooks/route_table/sdk_file_end.go.tpl b/templates/hooks/route_table/sdk_file_end.go.tpl new file mode 100644 index 00000000..2418c5a0 --- /dev/null +++ b/templates/hooks/route_table/sdk_file_end.go.tpl @@ -0,0 +1,26 @@ +{{ $CRD := .CRD }} +{{ $SDKAPI := .SDKAPI }} + +{{ range $specFieldName, $specField := $CRD.Config.Resources.RouteTable.Fields -}} + +{{/* Route is a CustomField */}} +{{- if $specField.CustomField }} +{{- $memberRefName := $specField.CustomField.ListOf }} +{{- range $index, $customShape := $SDKAPI.CustomShapes }} +{{- if (eq (Dereference $customShape.MemberShapeName) $memberRefName) }} + +{{- $memberRef := $customShape.Shape.MemberRef }} + +func compare{{$memberRefName}} ( + a *svcapitypes.{{ $memberRefName }}, + b *svcapitypes.{{ $memberRefName }}, +) *ackcompare.Delta { + delta := ackcompare.NewDelta() +{{ GoCodeCompareStruct $CRD $memberRef.Shape "delta" "a" "b" $memberRefName 1 }} + return delta +} + +{{- end }} +{{- end }} +{{- end }} +{{- end }} \ No newline at end of file From b870365f5b428ca755e35847e41f00786b0f3ee6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bryan=E2=84=A2=EF=B8=8F?= Date: Tue, 16 Nov 2021 14:22:34 -0600 Subject: [PATCH 09/16] refactor syncRoutes --- pkg/resource/route_table/hooks.go | 109 ++++++++++++++++++------------ 1 file changed, 64 insertions(+), 45 deletions(-) diff --git a/pkg/resource/route_table/hooks.go b/pkg/resource/route_table/hooks.go index 3b809595..86b25ef7 100644 --- a/pkg/resource/route_table/hooks.go +++ b/pkg/resource/route_table/hooks.go @@ -27,8 +27,7 @@ import ( type RouteAction int const ( - RouteActionNone RouteAction = iota - RouteActionCreate + LocalRouteGateway = "local" ) func (rm *resourceManager) createRoutes( @@ -49,63 +48,83 @@ func (rm *resourceManager) syncRoutes( rlog := ackrtlog.FromContext(ctx) exit := rlog.Trace("rm.syncRoutes") defer exit(err) + toAdd := []*svcapitypes.Route{} + toDelete := []*svcapitypes.Route{} - for _, rc := range desired.ko.Spec.Routes { - action := getRouteAction(rc, latest) - switch action { - case RouteActionCreate: - if err = rm.createRoute(ctx, desired, *rc); err != nil { - return err + for _, desiredRoute := range desired.ko.Spec.Routes { + if *desiredRoute.GatewayID == LocalRouteGateway { + // no-op for default route + continue + } + if latestRoute := getMatchingRoute(desiredRoute, latest); latestRoute != nil { + delta := compareRoute(desiredRoute, latestRoute) + if len(delta.Differences) > 0 { + // "update" route by deleting old route and adding the new route + toDelete = append(toDelete, latestRoute) + toAdd = append(toAdd, desiredRoute) } - - default: + } else { + // a desired route is not in latest; therefore, create + toAdd = append(toAdd, desiredRoute) + } + } + for _, latestRoute := range latest.ko.Spec.Routes { + if desiredRoute := getMatchingRoute(latestRoute, desired); desiredRoute == nil { + // latest has a route that is not desired; therefore, delete + toDelete = append(toDelete, latestRoute) } } - if latest != nil { - for _, l := range latest.ko.Spec.Routes { - desiredRoute := false - for _, d := range desired.ko.Spec.Routes { - delta := compareRoute(l, d) - //if a Route matches identically, then it is desired - if len(delta.Differences) == 0 { - desiredRoute = true - break - } - } - if !desiredRoute { - if err = rm.deleteRoute(ctx, latest, *l); err != nil { - return err - } - } - + for _, route := range toAdd { + rlog.Debug("adding route to route table") + if err = rm.createRoute(ctx, desired, *route); err != nil { + return err + } + } + for _, route := range toDelete { + rlog.Debug("deleting route from route table") + if err = rm.deleteRoute(ctx, latest, *route); err != nil { + return err } } return nil } -// getRouteAction returns the determined action for a given -// route object, depending on the latest and desired values -func getRouteAction( - desired *svcapitypes.Route, - latest *resource, -) RouteAction { - //the default route created by RouteTable; no action needed - if *desired.GatewayID == "local" { - return RouteActionNone - } - - action := RouteActionCreate - if latest != nil { - for _, l := range latest.ko.Spec.Routes { - delta := compareRoute(l, desired) - if len(delta.Differences) == 0 { - return RouteActionNone +func getMatchingRoute( + routeToMatch *svcapitypes.Route, + resource *resource, +) *svcapitypes.Route { + for _, route := range resource.ko.Spec.Routes { + delta := compareRoute(routeToMatch, route) + if len(delta.Differences) == 0 { + return route + } else { + if !delta.DifferentAt("Route.CarrierGatewayID") { + return route + } + if !delta.DifferentAt("Route.EgressOnlyInternetGatewayID") { + return route + } + if !delta.DifferentAt("Route.GatewayID") { + return route + } + if !delta.DifferentAt("Route.LocalGatewayID") { + return route + } + if !delta.DifferentAt("Route.NatGatewayID") { + return route + } + if !delta.DifferentAt("Route.TransitGatewayID") { + return route + } + if !delta.DifferentAt("Route.VPCPeeringConnectionID") { + return route } } } - return action + + return nil } func (rm *resourceManager) createRoute( From 8e6dff531496449a344585f1b75542aee3c31ee2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bryan=E2=84=A2=EF=B8=8F?= Date: Tue, 16 Nov 2021 17:20:07 -0600 Subject: [PATCH 10/16] update cidr block in RouteTable tests --- test/e2e/tests/test_route_table.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/e2e/tests/test_route_table.py b/test/e2e/tests/test_route_table.py index c25bcab1..d1a2e03f 100644 --- a/test/e2e/tests/test_route_table.py +++ b/test/e2e/tests/test_route_table.py @@ -77,7 +77,7 @@ def test_create_delete(self, ec2_client): test_vpc = get_bootstrap_resources().SharedTestVPC vpc_id = test_vpc.vpc_id igw_id = test_vpc.public_subnets.route_table.internet_gateway.internet_gateway_id - test_cidr_block = "100.68.0.0/18" + test_cidr_block = "192.168.0.0/24" test_resource_values["ROUTE_TABLE_NAME"] = resource_name test_resource_values["VPC_ID"] = vpc_id @@ -159,7 +159,7 @@ def test_crud_route(self, ec2_client): test_vpc = get_bootstrap_resources().SharedTestVPC vpc_id = test_vpc.vpc_id igw_id = test_vpc.public_subnets.route_table.internet_gateway.internet_gateway_id - test_cidr_block = "100.68.0.0/18" + test_cidr_block = "192.168.0.0/24" test_resource_values["ROUTE_TABLE_NAME"] = resource_name test_resource_values["VPC_ID"] = vpc_id @@ -204,7 +204,7 @@ def test_crud_route(self, ec2_client): assert False # Update Route - updated_cidr = "100.68.0.0/18" + updated_cidr = "192.168.1.0/24" patch = {"spec": {"routes": [ { #Default route cannot be changed From c62f8fffe43c02a3c7e6ae29ee6e6306b0a02f6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bryan=E2=84=A2=EF=B8=8F?= Date: Tue, 16 Nov 2021 17:21:20 -0600 Subject: [PATCH 11/16] fix matchRoute logic --- pkg/resource/route_table/hooks.go | 59 +++++++++++++++++++------------ 1 file changed, 37 insertions(+), 22 deletions(-) diff --git a/pkg/resource/route_table/hooks.go b/pkg/resource/route_table/hooks.go index 86b25ef7..bc426041 100644 --- a/pkg/resource/route_table/hooks.go +++ b/pkg/resource/route_table/hooks.go @@ -22,10 +22,6 @@ import ( svcsdk "github.com/aws/aws-sdk-go/service/ec2" ) -// RouteAction stores the possible actions that can be performed on -// any of a Route Table's Routes -type RouteAction int - const ( LocalRouteGateway = "local" ) @@ -68,10 +64,12 @@ func (rm *resourceManager) syncRoutes( toAdd = append(toAdd, desiredRoute) } } - for _, latestRoute := range latest.ko.Spec.Routes { - if desiredRoute := getMatchingRoute(latestRoute, desired); desiredRoute == nil { - // latest has a route that is not desired; therefore, delete - toDelete = append(toDelete, latestRoute) + if latest != nil { + for _, latestRoute := range latest.ko.Spec.Routes { + if desiredRoute := getMatchingRoute(latestRoute, desired); desiredRoute == nil { + // latest has a route that is not desired; therefore, delete + toDelete = append(toDelete, latestRoute) + } } } @@ -95,31 +93,48 @@ func getMatchingRoute( routeToMatch *svcapitypes.Route, resource *resource, ) *svcapitypes.Route { + if resource == nil { + return nil + } for _, route := range resource.ko.Spec.Routes { delta := compareRoute(routeToMatch, route) if len(delta.Differences) == 0 { return route } else { - if !delta.DifferentAt("Route.CarrierGatewayID") { - return route + if routeToMatch.CarrierGatewayID != nil { + if !delta.DifferentAt("Route.CarrierGatewayID") { + return route + } } - if !delta.DifferentAt("Route.EgressOnlyInternetGatewayID") { - return route + if routeToMatch.EgressOnlyInternetGatewayID != nil { + if !delta.DifferentAt("Route.EgressOnlyInternetGatewayID") { + return route + } } - if !delta.DifferentAt("Route.GatewayID") { - return route + if routeToMatch.GatewayID != nil { + if !delta.DifferentAt("Route.GatewayID") { + return route + } } - if !delta.DifferentAt("Route.LocalGatewayID") { - return route + if routeToMatch.LocalGatewayID != nil { + if !delta.DifferentAt("Route.LocalGatewayID") { + return route + } } - if !delta.DifferentAt("Route.NatGatewayID") { - return route + if routeToMatch.NatGatewayID != nil { + if !delta.DifferentAt("Route.NatGatewayID") { + return route + } } - if !delta.DifferentAt("Route.TransitGatewayID") { - return route + if routeToMatch.TransitGatewayID != nil { + if !delta.DifferentAt("Route.TransitGatewayID") { + return route + } } - if !delta.DifferentAt("Route.VPCPeeringConnectionID") { - return route + if routeToMatch.VPCPeeringConnectionID != nil { + if !delta.DifferentAt("Route.VPCPeeringConnectionID") { + return route + } } } } From c90642e67ca922385f2106dc1ac36fd43ea03b47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bryan=E2=84=A2=EF=B8=8F?= Date: Wed, 17 Nov 2021 16:48:55 -0600 Subject: [PATCH 12/16] add Routes to Status --- apis/v1alpha1/ack-generate-metadata.yaml | 8 +- apis/v1alpha1/enums.go | 12 +- apis/v1alpha1/generator.yaml | 10 +- apis/v1alpha1/route_table.go | 5 +- apis/v1alpha1/types.go | 62 ++++-- apis/v1alpha1/zz_generated.deepcopy.go | 193 ++++++++++++++++-- .../ec2.services.k8s.aws_routetables.yaml | 46 ++++- generator.yaml | 10 +- .../ec2.services.k8s.aws_routetables.yaml | 46 ++++- pkg/resource/route_table/sdk.go | 128 +++++------- .../sdk_read_many_post_set_output.go.tpl | 5 + 11 files changed, 395 insertions(+), 130 deletions(-) create mode 100644 templates/hooks/route_table/sdk_read_many_post_set_output.go.tpl diff --git a/apis/v1alpha1/ack-generate-metadata.yaml b/apis/v1alpha1/ack-generate-metadata.yaml index a1e11112..52d3ebb5 100755 --- a/apis/v1alpha1/ack-generate-metadata.yaml +++ b/apis/v1alpha1/ack-generate-metadata.yaml @@ -1,13 +1,13 @@ ack_generate_info: - build_date: "2021-11-16T19:16:05Z" - build_hash: 6ce1a672eabd3908bdaa4ace356e1b58ee3e80ba + build_date: "2021-11-17T22:45:36Z" + build_hash: 966e9a9ac6dfb4bbc2d3ded1972ce2b706391d44 go_version: go1.17 version: v0.15.2 -api_directory_checksum: 1eb52a5e544da8ce7e0a002e605254e4501296b2 +api_directory_checksum: e13129556d60164826bdeea39735660c7cfa1212 api_version: v1alpha1 aws_sdk_go_version: v1.37.10 generator_config_info: - file_checksum: acb593a25988c80f7edc78127b9d8e859236809d + file_checksum: 9909796f8b2f4f236120776f311f46f1e3859462 original_file_name: generator.yaml last_modification: reason: API generation diff --git a/apis/v1alpha1/enums.go b/apis/v1alpha1/enums.go index 7fa73436..239e9c2c 100644 --- a/apis/v1alpha1/enums.go +++ b/apis/v1alpha1/enums.go @@ -1367,14 +1367,14 @@ const ( MulticastSupportValue_disable MulticastSupportValue = "disable" ) -type NatGatewayState string +type NATGatewayState string const ( - NatGatewayState_pending NatGatewayState = "pending" - NatGatewayState_failed NatGatewayState = "failed" - NatGatewayState_available NatGatewayState = "available" - NatGatewayState_deleting NatGatewayState = "deleting" - NatGatewayState_deleted NatGatewayState = "deleted" + NATGatewayState_pending NATGatewayState = "pending" + NATGatewayState_failed NATGatewayState = "failed" + NATGatewayState_available NATGatewayState = "available" + NATGatewayState_deleting NATGatewayState = "deleting" + NATGatewayState_deleted NATGatewayState = "deleted" ) type NetworkInterfaceAttribute string diff --git a/apis/v1alpha1/generator.yaml b/apis/v1alpha1/generator.yaml index 5833fe3c..ff32a632 100644 --- a/apis/v1alpha1/generator.yaml +++ b/apis/v1alpha1/generator.yaml @@ -4,6 +4,7 @@ ignore: - ModifyVpcEndpoint field_paths: - CreateInternetGatewayInput.DryRun + - CreateRouteInput.DryRun - CreateRouteTableInput.DryRun - CreateSecurityGroupInput.DryRun - CreateSubnetInput.DryRun @@ -88,12 +89,19 @@ resources: - InvalidVpcID.NotFound - InvalidParameterValue fields: + RouteStatuses: + from: + operation: DescribeRouteTables + path: RouteTables.Routes + is_read_only: true Routes: custom_field: - list_of: Route + list_of: CreateRouteInput hooks: sdk_create_post_set_output: template_path: hooks/route_table/sdk_create_post_set_output.go.tpl + sdk_read_many_post_set_output: + template_path: hooks/route_table/sdk_read_many_post_set_output.go.tpl sdk_file_end: template_path: hooks/route_table/sdk_file_end.go.tpl update_operation: diff --git a/apis/v1alpha1/route_table.go b/apis/v1alpha1/route_table.go index 85b1ff8b..5a6e6b13 100644 --- a/apis/v1alpha1/route_table.go +++ b/apis/v1alpha1/route_table.go @@ -24,7 +24,7 @@ import ( // // Describes a route table. type RouteTableSpec struct { - Routes []*Route `json:"routes,omitempty"` + Routes []*CreateRouteInput `json:"routes,omitempty"` // The tags to assign to the route table. TagSpecifications []*TagSpecification `json:"tagSpecifications,omitempty"` // The ID of the VPC. @@ -54,6 +54,9 @@ type RouteTableStatus struct { // Any virtual private gateway (VGW) propagating routes. // +kubebuilder:validation:Optional PropagatingVGWs []*PropagatingVGW `json:"propagatingVGWs,omitempty"` + // The routes in the route table. + // +kubebuilder:validation:Optional + RouteStatuses []*Route `json:"routeStatuses,omitempty"` // The ID of the route table. // +kubebuilder:validation:Optional RouteTableID *string `json:"routeTableID,omitempty"` diff --git a/apis/v1alpha1/types.go b/apis/v1alpha1/types.go index e45f97a7..f5328a8b 100644 --- a/apis/v1alpha1/types.go +++ b/apis/v1alpha1/types.go @@ -118,7 +118,7 @@ type AnalysisRouteTableRoute struct { EgressOnlyInternetGatewayID *string `json:"egressOnlyInternetGatewayID,omitempty"` GatewayID *string `json:"gatewayID,omitempty"` InstanceID *string `json:"instanceID,omitempty"` - NatGatewayID *string `json:"natGatewayID,omitempty"` + NATGatewayID *string `json:"natGatewayID,omitempty"` NetworkInterfaceID *string `json:"networkInterfaceID,omitempty"` Origin *string `json:"origin,omitempty"` TransitGatewayID *string `json:"transitGatewayID,omitempty"` @@ -495,6 +495,23 @@ type CreateFleetError struct { ErrorMessage *string `json:"errorMessage,omitempty"` } +type CreateRouteInput struct { + CarrierGatewayID *string `json:"carrierGatewayID,omitempty"` + DestinationCIDRBlock *string `json:"destinationCIDRBlock,omitempty"` + DestinationIPv6CIDRBlock *string `json:"destinationIPv6CIDRBlock,omitempty"` + DestinationPrefixListID *string `json:"destinationPrefixListID,omitempty"` + EgressOnlyInternetGatewayID *string `json:"egressOnlyInternetGatewayID,omitempty"` + GatewayID *string `json:"gatewayID,omitempty"` + InstanceID *string `json:"instanceID,omitempty"` + LocalGatewayID *string `json:"localGatewayID,omitempty"` + NATGatewayID *string `json:"natGatewayID,omitempty"` + NetworkInterfaceID *string `json:"networkInterfaceID,omitempty"` + RouteTableID *string `json:"routeTableID,omitempty"` + TransitGatewayID *string `json:"transitGatewayID,omitempty"` + VPCEndpointID *string `json:"vpcEndpointID,omitempty"` + VPCPeeringConnectionID *string `json:"vpcPeeringConnectionID,omitempty"` +} + // Describes the options for a VPC attachment. type CreateTransitGatewayVPCAttachmentRequestOptions struct { DNSSupport *string `json:"dnsSupport,omitempty"` @@ -699,8 +716,9 @@ type EBSInstanceBlockDeviceSpecification struct { // Describes an egress-only internet gateway. type EgressOnlyInternetGateway struct { - Attachments []*InternetGatewayAttachment `json:"attachments,omitempty"` - Tags []*Tag `json:"tags,omitempty"` + Attachments []*InternetGatewayAttachment `json:"attachments,omitempty"` + EgressOnlyInternetGatewayID *string `json:"egressOnlyInternetGatewayID,omitempty"` + Tags []*Tag `json:"tags,omitempty"` } // Describes the association between an instance and an Elastic Graphics accelerator. @@ -1307,6 +1325,7 @@ type InstanceCreditSpecification struct { // Describes the credit option for CPU usage of a burstable performance instance. type InstanceCreditSpecificationRequest struct { CPUCredits *string `json:"cpuCredits,omitempty"` + InstanceID *string `json:"instanceID,omitempty"` } // Describes an instance to export. @@ -1402,7 +1421,8 @@ type InstancePrivateIPAddress struct { // The instance details to specify which volumes should be snapshotted. type InstanceSpecification struct { - ExcludeBootVolume *bool `json:"excludeBootVolume,omitempty"` + ExcludeBootVolume *bool `json:"excludeBootVolume,omitempty"` + InstanceID *string `json:"instanceID,omitempty"` } // Describes the current state of an instance. @@ -1618,6 +1638,7 @@ type LaunchTemplateInstanceNetworkInterfaceSpecification struct { InterfaceType *string `json:"interfaceType,omitempty"` IPv6AddressCount *int64 `json:"ipv6AddressCount,omitempty"` NetworkCardIndex *int64 `json:"networkCardIndex,omitempty"` + NetworkInterfaceID *string `json:"networkInterfaceID,omitempty"` PrivateIPAddress *string `json:"privateIPAddress,omitempty"` SecondaryPrivateIPAddressCount *int64 `json:"secondaryPrivateIPAddressCount,omitempty"` SubnetID *string `json:"subnetID,omitempty"` @@ -1633,6 +1654,7 @@ type LaunchTemplateInstanceNetworkInterfaceSpecificationRequest struct { InterfaceType *string `json:"interfaceType,omitempty"` IPv6AddressCount *int64 `json:"ipv6AddressCount,omitempty"` NetworkCardIndex *int64 `json:"networkCardIndex,omitempty"` + NetworkInterfaceID *string `json:"networkInterfaceID,omitempty"` PrivateIPAddress *string `json:"privateIPAddress,omitempty"` SecondaryPrivateIPAddressCount *int64 `json:"secondaryPrivateIPAddressCount,omitempty"` SubnetID *string `json:"subnetID,omitempty"` @@ -1751,10 +1773,11 @@ type LoadPermissionRequest struct { // Describes a local gateway. type LocalGateway struct { - OutpostARN *string `json:"outpostARN,omitempty"` - OwnerID *string `json:"ownerID,omitempty"` - State *string `json:"state,omitempty"` - Tags []*Tag `json:"tags,omitempty"` + LocalGatewayID *string `json:"localGatewayID,omitempty"` + OutpostARN *string `json:"outpostARN,omitempty"` + OwnerID *string `json:"ownerID,omitempty"` + State *string `json:"state,omitempty"` + Tags []*Tag `json:"tags,omitempty"` } // Describes a route for a local gateway route table. @@ -1765,6 +1788,7 @@ type LocalGatewayRoute struct { // Describes a local gateway route table. type LocalGatewayRouteTable struct { + LocalGatewayID *string `json:"localGatewayID,omitempty"` LocalGatewayRouteTableID *string `json:"localGatewayRouteTableID,omitempty"` OutpostARN *string `json:"outpostARN,omitempty"` OwnerID *string `json:"ownerID,omitempty"` @@ -1785,10 +1809,11 @@ type LocalGatewayRouteTableVPCAssociation struct { // Describes an association between a local gateway route table and a virtual // interface group. type LocalGatewayRouteTableVirtualInterfaceGroupAssociation struct { - LocalGatewayID *string `json:"localGatewayID,omitempty"` - OwnerID *string `json:"ownerID,omitempty"` - State *string `json:"state,omitempty"` - Tags []*Tag `json:"tags,omitempty"` + LocalGatewayID *string `json:"localGatewayID,omitempty"` + LocalGatewayRouteTableID *string `json:"localGatewayRouteTableID,omitempty"` + OwnerID *string `json:"ownerID,omitempty"` + State *string `json:"state,omitempty"` + Tags []*Tag `json:"tags,omitempty"` } // Describes a local gateway virtual interface. @@ -1815,6 +1840,7 @@ type ManagedPrefixList struct { AddressFamily *string `json:"addressFamily,omitempty"` MaxEntries *int64 `json:"maxEntries,omitempty"` OwnerID *string `json:"ownerID,omitempty"` + PrefixListID *string `json:"prefixListID,omitempty"` PrefixListName *string `json:"prefixListName,omitempty"` StateMessage *string `json:"stateMessage,omitempty"` Tags []*Tag `json:"tags,omitempty"` @@ -1858,19 +1884,19 @@ type MovingAddressStatus struct { } // Describes a NAT gateway. -type NatGateway struct { +type NATGateway struct { CreateTime *metav1.Time `json:"createTime,omitempty"` DeleteTime *metav1.Time `json:"deleteTime,omitempty"` FailureCode *string `json:"failureCode,omitempty"` FailureMessage *string `json:"failureMessage,omitempty"` - NatGatewayID *string `json:"natGatewayID,omitempty"` + NATGatewayID *string `json:"natGatewayID,omitempty"` SubnetID *string `json:"subnetID,omitempty"` Tags []*Tag `json:"tags,omitempty"` VPCID *string `json:"vpcID,omitempty"` } // Describes the IP addresses and network interface associated with a NAT gateway. -type NatGatewayAddress struct { +type NATGatewayAddress struct { AllocationID *string `json:"allocationID,omitempty"` NetworkInterfaceID *string `json:"networkInterfaceID,omitempty"` PrivateIP *string `json:"privateIP,omitempty"` @@ -2417,7 +2443,7 @@ type Route struct { InstanceID *string `json:"instanceID,omitempty"` InstanceOwnerID *string `json:"instanceOwnerID,omitempty"` LocalGatewayID *string `json:"localGatewayID,omitempty"` - NatGatewayID *string `json:"natGatewayID,omitempty"` + NATGatewayID *string `json:"natGatewayID,omitempty"` NetworkInterfaceID *string `json:"networkInterfaceID,omitempty"` Origin *string `json:"origin,omitempty"` State *string `json:"state,omitempty"` @@ -2565,6 +2591,7 @@ type ScheduledInstancesNetworkInterface struct { Description *string `json:"description,omitempty"` DeviceIndex *int64 `json:"deviceIndex,omitempty"` IPv6AddressCount *int64 `json:"ipv6AddressCount,omitempty"` + NetworkInterfaceID *string `json:"networkInterfaceID,omitempty"` PrivateIPAddress *string `json:"privateIPAddress,omitempty"` SecondaryPrivateIPAddressCount *int64 `json:"secondaryPrivateIPAddressCount,omitempty"` SubnetID *string `json:"subnetID,omitempty"` @@ -2757,6 +2784,7 @@ type SpotInstanceRequest struct { AvailabilityZoneGroup *string `json:"availabilityZoneGroup,omitempty"` BlockDurationMinutes *int64 `json:"blockDurationMinutes,omitempty"` CreateTime *metav1.Time `json:"createTime,omitempty"` + InstanceID *string `json:"instanceID,omitempty"` LaunchGroup *string `json:"launchGroup,omitempty"` LaunchedAvailabilityZone *string `json:"launchedAvailabilityZone,omitempty"` SpotInstanceRequestID *string `json:"spotInstanceRequestID,omitempty"` @@ -3196,6 +3224,7 @@ type TransitGatewayPrefixListAttachment struct { // Describes a prefix list reference. type TransitGatewayPrefixListReference struct { Blackhole *bool `json:"blackhole,omitempty"` + PrefixListID *string `json:"prefixListID,omitempty"` PrefixListOwnerID *string `json:"prefixListOwnerID,omitempty"` } @@ -3220,6 +3249,7 @@ type TransitGatewayRequestOptions struct { // Describes a route for a transit gateway route table. type TransitGatewayRoute struct { DestinationCIDRBlock *string `json:"destinationCIDRBlock,omitempty"` + PrefixListID *string `json:"prefixListID,omitempty"` } // Describes a route attachment. diff --git a/apis/v1alpha1/zz_generated.deepcopy.go b/apis/v1alpha1/zz_generated.deepcopy.go index b3a1e1fa..00142b27 100644 --- a/apis/v1alpha1/zz_generated.deepcopy.go +++ b/apis/v1alpha1/zz_generated.deepcopy.go @@ -404,8 +404,8 @@ func (in *AnalysisRouteTableRoute) DeepCopyInto(out *AnalysisRouteTableRoute) { *out = new(string) **out = **in } - if in.NatGatewayID != nil { - in, out := &in.NatGatewayID, &out.NatGatewayID + if in.NATGatewayID != nil { + in, out := &in.NATGatewayID, &out.NATGatewayID *out = new(string) **out = **in } @@ -2034,6 +2034,91 @@ func (in *CreateFleetError) DeepCopy() *CreateFleetError { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CreateRouteInput) DeepCopyInto(out *CreateRouteInput) { + *out = *in + if in.CarrierGatewayID != nil { + in, out := &in.CarrierGatewayID, &out.CarrierGatewayID + *out = new(string) + **out = **in + } + if in.DestinationCIDRBlock != nil { + in, out := &in.DestinationCIDRBlock, &out.DestinationCIDRBlock + *out = new(string) + **out = **in + } + if in.DestinationIPv6CIDRBlock != nil { + in, out := &in.DestinationIPv6CIDRBlock, &out.DestinationIPv6CIDRBlock + *out = new(string) + **out = **in + } + if in.DestinationPrefixListID != nil { + in, out := &in.DestinationPrefixListID, &out.DestinationPrefixListID + *out = new(string) + **out = **in + } + if in.EgressOnlyInternetGatewayID != nil { + in, out := &in.EgressOnlyInternetGatewayID, &out.EgressOnlyInternetGatewayID + *out = new(string) + **out = **in + } + if in.GatewayID != nil { + in, out := &in.GatewayID, &out.GatewayID + *out = new(string) + **out = **in + } + if in.InstanceID != nil { + in, out := &in.InstanceID, &out.InstanceID + *out = new(string) + **out = **in + } + if in.LocalGatewayID != nil { + in, out := &in.LocalGatewayID, &out.LocalGatewayID + *out = new(string) + **out = **in + } + if in.NATGatewayID != nil { + in, out := &in.NATGatewayID, &out.NATGatewayID + *out = new(string) + **out = **in + } + if in.NetworkInterfaceID != nil { + in, out := &in.NetworkInterfaceID, &out.NetworkInterfaceID + *out = new(string) + **out = **in + } + if in.RouteTableID != nil { + in, out := &in.RouteTableID, &out.RouteTableID + *out = new(string) + **out = **in + } + if in.TransitGatewayID != nil { + in, out := &in.TransitGatewayID, &out.TransitGatewayID + *out = new(string) + **out = **in + } + if in.VPCEndpointID != nil { + in, out := &in.VPCEndpointID, &out.VPCEndpointID + *out = new(string) + **out = **in + } + if in.VPCPeeringConnectionID != nil { + in, out := &in.VPCPeeringConnectionID, &out.VPCPeeringConnectionID + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CreateRouteInput. +func (in *CreateRouteInput) DeepCopy() *CreateRouteInput { + if in == nil { + return nil + } + out := new(CreateRouteInput) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CreateTransitGatewayVPCAttachmentRequestOptions) DeepCopyInto(out *CreateTransitGatewayVPCAttachmentRequestOptions) { *out = *in @@ -2880,6 +2965,11 @@ func (in *EgressOnlyInternetGateway) DeepCopyInto(out *EgressOnlyInternetGateway } } } + if in.EgressOnlyInternetGatewayID != nil { + in, out := &in.EgressOnlyInternetGatewayID, &out.EgressOnlyInternetGatewayID + *out = new(string) + **out = **in + } if in.Tags != nil { in, out := &in.Tags, &out.Tags *out = make([]*Tag, len(*in)) @@ -5430,6 +5520,11 @@ func (in *InstanceCreditSpecificationRequest) DeepCopyInto(out *InstanceCreditSp *out = new(string) **out = **in } + if in.InstanceID != nil { + in, out := &in.InstanceID, &out.InstanceID + *out = new(string) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceCreditSpecificationRequest. @@ -5839,6 +5934,11 @@ func (in *InstanceSpecification) DeepCopyInto(out *InstanceSpecification) { *out = new(bool) **out = **in } + if in.InstanceID != nil { + in, out := &in.InstanceID, &out.InstanceID + *out = new(string) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceSpecification. @@ -6887,6 +6987,11 @@ func (in *LaunchTemplateInstanceNetworkInterfaceSpecification) DeepCopyInto(out *out = new(int64) **out = **in } + if in.NetworkInterfaceID != nil { + in, out := &in.NetworkInterfaceID, &out.NetworkInterfaceID + *out = new(string) + **out = **in + } if in.PrivateIPAddress != nil { in, out := &in.PrivateIPAddress, &out.PrivateIPAddress *out = new(string) @@ -6957,6 +7062,11 @@ func (in *LaunchTemplateInstanceNetworkInterfaceSpecificationRequest) DeepCopyIn *out = new(int64) **out = **in } + if in.NetworkInterfaceID != nil { + in, out := &in.NetworkInterfaceID, &out.NetworkInterfaceID + *out = new(string) + **out = **in + } if in.PrivateIPAddress != nil { in, out := &in.PrivateIPAddress, &out.PrivateIPAddress *out = new(string) @@ -7461,6 +7571,11 @@ func (in *LoadPermissionRequest) DeepCopy() *LoadPermissionRequest { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *LocalGateway) DeepCopyInto(out *LocalGateway) { *out = *in + if in.LocalGatewayID != nil { + in, out := &in.LocalGatewayID, &out.LocalGatewayID + *out = new(string) + **out = **in + } if in.OutpostARN != nil { in, out := &in.OutpostARN, &out.OutpostARN *out = new(string) @@ -7527,6 +7642,11 @@ func (in *LocalGatewayRoute) DeepCopy() *LocalGatewayRoute { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *LocalGatewayRouteTable) DeepCopyInto(out *LocalGatewayRouteTable) { *out = *in + if in.LocalGatewayID != nil { + in, out := &in.LocalGatewayID, &out.LocalGatewayID + *out = new(string) + **out = **in + } if in.LocalGatewayRouteTableID != nil { in, out := &in.LocalGatewayRouteTableID, &out.LocalGatewayRouteTableID *out = new(string) @@ -7629,6 +7749,11 @@ func (in *LocalGatewayRouteTableVirtualInterfaceGroupAssociation) DeepCopyInto(o *out = new(string) **out = **in } + if in.LocalGatewayRouteTableID != nil { + in, out := &in.LocalGatewayRouteTableID, &out.LocalGatewayRouteTableID + *out = new(string) + **out = **in + } if in.OwnerID != nil { in, out := &in.OwnerID, &out.OwnerID *out = new(string) @@ -7777,6 +7902,11 @@ func (in *ManagedPrefixList) DeepCopyInto(out *ManagedPrefixList) { *out = new(string) **out = **in } + if in.PrefixListID != nil { + in, out := &in.PrefixListID, &out.PrefixListID + *out = new(string) + **out = **in + } if in.PrefixListName != nil { in, out := &in.PrefixListName, &out.PrefixListName *out = new(string) @@ -7988,7 +8118,7 @@ func (in *MovingAddressStatus) DeepCopy() *MovingAddressStatus { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *NatGateway) DeepCopyInto(out *NatGateway) { +func (in *NATGateway) DeepCopyInto(out *NATGateway) { *out = *in if in.CreateTime != nil { in, out := &in.CreateTime, &out.CreateTime @@ -8008,8 +8138,8 @@ func (in *NatGateway) DeepCopyInto(out *NatGateway) { *out = new(string) **out = **in } - if in.NatGatewayID != nil { - in, out := &in.NatGatewayID, &out.NatGatewayID + if in.NATGatewayID != nil { + in, out := &in.NATGatewayID, &out.NATGatewayID *out = new(string) **out = **in } @@ -8036,18 +8166,18 @@ func (in *NatGateway) DeepCopyInto(out *NatGateway) { } } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NatGateway. -func (in *NatGateway) DeepCopy() *NatGateway { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NATGateway. +func (in *NATGateway) DeepCopy() *NATGateway { if in == nil { return nil } - out := new(NatGateway) + out := new(NATGateway) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *NatGatewayAddress) DeepCopyInto(out *NatGatewayAddress) { +func (in *NATGatewayAddress) DeepCopyInto(out *NATGatewayAddress) { *out = *in if in.AllocationID != nil { in, out := &in.AllocationID, &out.AllocationID @@ -8071,12 +8201,12 @@ func (in *NatGatewayAddress) DeepCopyInto(out *NatGatewayAddress) { } } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NatGatewayAddress. -func (in *NatGatewayAddress) DeepCopy() *NatGatewayAddress { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NATGatewayAddress. +func (in *NATGatewayAddress) DeepCopy() *NATGatewayAddress { if in == nil { return nil } - out := new(NatGatewayAddress) + out := new(NATGatewayAddress) in.DeepCopyInto(out) return out } @@ -10399,8 +10529,8 @@ func (in *Route) DeepCopyInto(out *Route) { *out = new(string) **out = **in } - if in.NatGatewayID != nil { - in, out := &in.NatGatewayID, &out.NatGatewayID + if in.NATGatewayID != nil { + in, out := &in.NATGatewayID, &out.NATGatewayID *out = new(string) **out = **in } @@ -10575,11 +10705,11 @@ func (in *RouteTableSpec) DeepCopyInto(out *RouteTableSpec) { *out = *in if in.Routes != nil { in, out := &in.Routes, &out.Routes - *out = make([]*Route, len(*in)) + *out = make([]*CreateRouteInput, len(*in)) for i := range *in { if (*in)[i] != nil { in, out := &(*in)[i], &(*out)[i] - *out = new(Route) + *out = new(CreateRouteInput) (*in).DeepCopyInto(*out) } } @@ -10658,6 +10788,17 @@ func (in *RouteTableStatus) DeepCopyInto(out *RouteTableStatus) { } } } + if in.RouteStatuses != nil { + in, out := &in.RouteStatuses, &out.RouteStatuses + *out = make([]*Route, len(*in)) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = new(Route) + (*in).DeepCopyInto(*out) + } + } + } if in.RouteTableID != nil { in, out := &in.RouteTableID, &out.RouteTableID *out = new(string) @@ -11217,6 +11358,11 @@ func (in *ScheduledInstancesNetworkInterface) DeepCopyInto(out *ScheduledInstanc *out = new(int64) **out = **in } + if in.NetworkInterfaceID != nil { + in, out := &in.NetworkInterfaceID, &out.NetworkInterfaceID + *out = new(string) + **out = **in + } if in.PrivateIPAddress != nil { in, out := &in.PrivateIPAddress, &out.PrivateIPAddress *out = new(string) @@ -12285,6 +12431,11 @@ func (in *SpotInstanceRequest) DeepCopyInto(out *SpotInstanceRequest) { in, out := &in.CreateTime, &out.CreateTime *out = (*in).DeepCopy() } + if in.InstanceID != nil { + in, out := &in.InstanceID, &out.InstanceID + *out = new(string) + **out = **in + } if in.LaunchGroup != nil { in, out := &in.LaunchGroup, &out.LaunchGroup *out = new(string) @@ -14420,6 +14571,11 @@ func (in *TransitGatewayPrefixListReference) DeepCopyInto(out *TransitGatewayPre *out = new(bool) **out = **in } + if in.PrefixListID != nil { + in, out := &in.PrefixListID, &out.PrefixListID + *out = new(string) + **out = **in + } if in.PrefixListOwnerID != nil { in, out := &in.PrefixListOwnerID, &out.PrefixListOwnerID *out = new(string) @@ -14531,6 +14687,11 @@ func (in *TransitGatewayRoute) DeepCopyInto(out *TransitGatewayRoute) { *out = new(string) **out = **in } + if in.PrefixListID != nil { + in, out := &in.PrefixListID, &out.PrefixListID + *out = new(string) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TransitGatewayRoute. diff --git a/config/crd/bases/ec2.services.k8s.aws_routetables.yaml b/config/crd/bases/ec2.services.k8s.aws_routetables.yaml index 3f27fae5..aacd7c32 100644 --- a/config/crd/bases/ec2.services.k8s.aws_routetables.yaml +++ b/config/crd/bases/ec2.services.k8s.aws_routetables.yaml @@ -39,7 +39,6 @@ spec: properties: routes: items: - description: Describes a route in a route table. properties: carrierGatewayID: type: string @@ -55,20 +54,18 @@ spec: type: string instanceID: type: string - instanceOwnerID: - type: string localGatewayID: type: string natGatewayID: type: string networkInterfaceID: type: string - origin: - type: string - state: + routeTableID: type: string transitGatewayID: type: string + vpcEndpointID: + type: string vpcPeeringConnectionID: type: string type: object @@ -198,6 +195,43 @@ spec: type: string type: object type: array + routeStatuses: + description: The routes in the route table. + items: + description: Describes a route in a route table. + properties: + carrierGatewayID: + type: string + destinationCIDRBlock: + type: string + destinationIPv6CIDRBlock: + type: string + destinationPrefixListID: + type: string + egressOnlyInternetGatewayID: + type: string + gatewayID: + type: string + instanceID: + type: string + instanceOwnerID: + type: string + localGatewayID: + type: string + natGatewayID: + type: string + networkInterfaceID: + type: string + origin: + type: string + state: + type: string + transitGatewayID: + type: string + vpcPeeringConnectionID: + type: string + type: object + type: array routeTableID: description: The ID of the route table. type: string diff --git a/generator.yaml b/generator.yaml index 5833fe3c..ff32a632 100644 --- a/generator.yaml +++ b/generator.yaml @@ -4,6 +4,7 @@ ignore: - ModifyVpcEndpoint field_paths: - CreateInternetGatewayInput.DryRun + - CreateRouteInput.DryRun - CreateRouteTableInput.DryRun - CreateSecurityGroupInput.DryRun - CreateSubnetInput.DryRun @@ -88,12 +89,19 @@ resources: - InvalidVpcID.NotFound - InvalidParameterValue fields: + RouteStatuses: + from: + operation: DescribeRouteTables + path: RouteTables.Routes + is_read_only: true Routes: custom_field: - list_of: Route + list_of: CreateRouteInput hooks: sdk_create_post_set_output: template_path: hooks/route_table/sdk_create_post_set_output.go.tpl + sdk_read_many_post_set_output: + template_path: hooks/route_table/sdk_read_many_post_set_output.go.tpl sdk_file_end: template_path: hooks/route_table/sdk_file_end.go.tpl update_operation: diff --git a/helm/crds/ec2.services.k8s.aws_routetables.yaml b/helm/crds/ec2.services.k8s.aws_routetables.yaml index 3f27fae5..aacd7c32 100644 --- a/helm/crds/ec2.services.k8s.aws_routetables.yaml +++ b/helm/crds/ec2.services.k8s.aws_routetables.yaml @@ -39,7 +39,6 @@ spec: properties: routes: items: - description: Describes a route in a route table. properties: carrierGatewayID: type: string @@ -55,20 +54,18 @@ spec: type: string instanceID: type: string - instanceOwnerID: - type: string localGatewayID: type: string natGatewayID: type: string networkInterfaceID: type: string - origin: - type: string - state: + routeTableID: type: string transitGatewayID: type: string + vpcEndpointID: + type: string vpcPeeringConnectionID: type: string type: object @@ -198,6 +195,43 @@ spec: type: string type: object type: array + routeStatuses: + description: The routes in the route table. + items: + description: Describes a route in a route table. + properties: + carrierGatewayID: + type: string + destinationCIDRBlock: + type: string + destinationIPv6CIDRBlock: + type: string + destinationPrefixListID: + type: string + egressOnlyInternetGatewayID: + type: string + gatewayID: + type: string + instanceID: + type: string + instanceOwnerID: + type: string + localGatewayID: + type: string + natGatewayID: + type: string + networkInterfaceID: + type: string + origin: + type: string + state: + type: string + transitGatewayID: + type: string + vpcPeeringConnectionID: + type: string + type: object + type: array routeTableID: description: The ID of the route table. type: string diff --git a/pkg/resource/route_table/sdk.go b/pkg/resource/route_table/sdk.go index d06c95a4..2dda11c7 100644 --- a/pkg/resource/route_table/sdk.go +++ b/pkg/resource/route_table/sdk.go @@ -140,9 +140,9 @@ func (rm *resourceManager) sdkFind( ko.Status.RouteTableID = nil } if elem.Routes != nil { - f4 := []*svcapitypes.Route{} + f4 := []*svcapitypes.CreateRouteInput{} for _, f4iter := range elem.Routes { - f4elem := &svcapitypes.Route{} + f4elem := &svcapitypes.CreateRouteInput{} if f4iter.CarrierGatewayId != nil { f4elem.CarrierGatewayID = f4iter.CarrierGatewayId } @@ -164,24 +164,15 @@ func (rm *resourceManager) sdkFind( if f4iter.InstanceId != nil { f4elem.InstanceID = f4iter.InstanceId } - if f4iter.InstanceOwnerId != nil { - f4elem.InstanceOwnerID = f4iter.InstanceOwnerId - } if f4iter.LocalGatewayId != nil { f4elem.LocalGatewayID = f4iter.LocalGatewayId } if f4iter.NatGatewayId != nil { - f4elem.NatGatewayID = f4iter.NatGatewayId + f4elem.NATGatewayID = f4iter.NatGatewayId } if f4iter.NetworkInterfaceId != nil { f4elem.NetworkInterfaceID = f4iter.NetworkInterfaceId } - if f4iter.Origin != nil { - f4elem.Origin = f4iter.Origin - } - if f4iter.State != nil { - f4elem.State = f4iter.State - } if f4iter.TransitGatewayId != nil { f4elem.TransitGatewayID = f4iter.TransitGatewayId } @@ -223,6 +214,11 @@ func (rm *resourceManager) sdkFind( } rm.setStatusDefaults(ko) + + if found { + rm.addRoutesToStatus(ko, resp.RouteTables[0]) + } + return &resource{ko}, nil } @@ -337,9 +333,9 @@ func (rm *resourceManager) sdkCreate( ko.Status.RouteTableID = nil } if resp.RouteTable.Routes != nil { - f4 := []*svcapitypes.Route{} + f4 := []*svcapitypes.CreateRouteInput{} for _, f4iter := range resp.RouteTable.Routes { - f4elem := &svcapitypes.Route{} + f4elem := &svcapitypes.CreateRouteInput{} if f4iter.CarrierGatewayId != nil { f4elem.CarrierGatewayID = f4iter.CarrierGatewayId } @@ -361,24 +357,15 @@ func (rm *resourceManager) sdkCreate( if f4iter.InstanceId != nil { f4elem.InstanceID = f4iter.InstanceId } - if f4iter.InstanceOwnerId != nil { - f4elem.InstanceOwnerID = f4iter.InstanceOwnerId - } if f4iter.LocalGatewayId != nil { f4elem.LocalGatewayID = f4iter.LocalGatewayId } if f4iter.NatGatewayId != nil { - f4elem.NatGatewayID = f4iter.NatGatewayId + f4elem.NATGatewayID = f4iter.NatGatewayId } if f4iter.NetworkInterfaceId != nil { f4elem.NetworkInterfaceID = f4iter.NetworkInterfaceId } - if f4iter.Origin != nil { - f4elem.Origin = f4iter.Origin - } - if f4iter.State != nil { - f4elem.State = f4iter.State - } if f4iter.TransitGatewayId != nil { f4elem.TransitGatewayID = f4iter.TransitGatewayId } @@ -414,6 +401,8 @@ func (rm *resourceManager) sdkCreate( } rm.setStatusDefaults(ko) + rm.addRoutesToStatus(ko, resp.RouteTable) + if rm.requiredFieldsMissingForCreateRoute(&resource{ko}) { return nil, ackerr.NotFound } @@ -625,114 +614,107 @@ func (rm *resourceManager) terminalAWSError(err error) bool { } } -func compareRoute( - a *svcapitypes.Route, - b *svcapitypes.Route, +func compareCreateRouteInput( + a *svcapitypes.CreateRouteInput, + b *svcapitypes.CreateRouteInput, ) *ackcompare.Delta { delta := ackcompare.NewDelta() if ackcompare.HasNilDifference(a.CarrierGatewayID, b.CarrierGatewayID) { - delta.Add("Route.CarrierGatewayID", a.CarrierGatewayID, b.CarrierGatewayID) + delta.Add("CreateRouteInput.CarrierGatewayID", a.CarrierGatewayID, b.CarrierGatewayID) } else if a.CarrierGatewayID != nil && b.CarrierGatewayID != nil { if *a.CarrierGatewayID != *b.CarrierGatewayID { - delta.Add("Route.CarrierGatewayID", a.CarrierGatewayID, b.CarrierGatewayID) + delta.Add("CreateRouteInput.CarrierGatewayID", a.CarrierGatewayID, b.CarrierGatewayID) } } if ackcompare.HasNilDifference(a.DestinationCIDRBlock, b.DestinationCIDRBlock) { - delta.Add("Route.DestinationCIDRBlock", a.DestinationCIDRBlock, b.DestinationCIDRBlock) + delta.Add("CreateRouteInput.DestinationCIDRBlock", a.DestinationCIDRBlock, b.DestinationCIDRBlock) } else if a.DestinationCIDRBlock != nil && b.DestinationCIDRBlock != nil { if *a.DestinationCIDRBlock != *b.DestinationCIDRBlock { - delta.Add("Route.DestinationCIDRBlock", a.DestinationCIDRBlock, b.DestinationCIDRBlock) + delta.Add("CreateRouteInput.DestinationCIDRBlock", a.DestinationCIDRBlock, b.DestinationCIDRBlock) } } if ackcompare.HasNilDifference(a.DestinationIPv6CIDRBlock, b.DestinationIPv6CIDRBlock) { - delta.Add("Route.DestinationIPv6CIDRBlock", a.DestinationIPv6CIDRBlock, b.DestinationIPv6CIDRBlock) + delta.Add("CreateRouteInput.DestinationIPv6CIDRBlock", a.DestinationIPv6CIDRBlock, b.DestinationIPv6CIDRBlock) } else if a.DestinationIPv6CIDRBlock != nil && b.DestinationIPv6CIDRBlock != nil { if *a.DestinationIPv6CIDRBlock != *b.DestinationIPv6CIDRBlock { - delta.Add("Route.DestinationIPv6CIDRBlock", a.DestinationIPv6CIDRBlock, b.DestinationIPv6CIDRBlock) + delta.Add("CreateRouteInput.DestinationIPv6CIDRBlock", a.DestinationIPv6CIDRBlock, b.DestinationIPv6CIDRBlock) } } if ackcompare.HasNilDifference(a.DestinationPrefixListID, b.DestinationPrefixListID) { - delta.Add("Route.DestinationPrefixListID", a.DestinationPrefixListID, b.DestinationPrefixListID) + delta.Add("CreateRouteInput.DestinationPrefixListID", a.DestinationPrefixListID, b.DestinationPrefixListID) } else if a.DestinationPrefixListID != nil && b.DestinationPrefixListID != nil { if *a.DestinationPrefixListID != *b.DestinationPrefixListID { - delta.Add("Route.DestinationPrefixListID", a.DestinationPrefixListID, b.DestinationPrefixListID) + delta.Add("CreateRouteInput.DestinationPrefixListID", a.DestinationPrefixListID, b.DestinationPrefixListID) } } if ackcompare.HasNilDifference(a.EgressOnlyInternetGatewayID, b.EgressOnlyInternetGatewayID) { - delta.Add("Route.EgressOnlyInternetGatewayID", a.EgressOnlyInternetGatewayID, b.EgressOnlyInternetGatewayID) + delta.Add("CreateRouteInput.EgressOnlyInternetGatewayID", a.EgressOnlyInternetGatewayID, b.EgressOnlyInternetGatewayID) } else if a.EgressOnlyInternetGatewayID != nil && b.EgressOnlyInternetGatewayID != nil { if *a.EgressOnlyInternetGatewayID != *b.EgressOnlyInternetGatewayID { - delta.Add("Route.EgressOnlyInternetGatewayID", a.EgressOnlyInternetGatewayID, b.EgressOnlyInternetGatewayID) + delta.Add("CreateRouteInput.EgressOnlyInternetGatewayID", a.EgressOnlyInternetGatewayID, b.EgressOnlyInternetGatewayID) } } if ackcompare.HasNilDifference(a.GatewayID, b.GatewayID) { - delta.Add("Route.GatewayID", a.GatewayID, b.GatewayID) + delta.Add("CreateRouteInput.GatewayID", a.GatewayID, b.GatewayID) } else if a.GatewayID != nil && b.GatewayID != nil { if *a.GatewayID != *b.GatewayID { - delta.Add("Route.GatewayID", a.GatewayID, b.GatewayID) + delta.Add("CreateRouteInput.GatewayID", a.GatewayID, b.GatewayID) } } if ackcompare.HasNilDifference(a.InstanceID, b.InstanceID) { - delta.Add("Route.InstanceID", a.InstanceID, b.InstanceID) + delta.Add("CreateRouteInput.InstanceID", a.InstanceID, b.InstanceID) } else if a.InstanceID != nil && b.InstanceID != nil { if *a.InstanceID != *b.InstanceID { - delta.Add("Route.InstanceID", a.InstanceID, b.InstanceID) - } - } - if ackcompare.HasNilDifference(a.InstanceOwnerID, b.InstanceOwnerID) { - delta.Add("Route.InstanceOwnerID", a.InstanceOwnerID, b.InstanceOwnerID) - } else if a.InstanceOwnerID != nil && b.InstanceOwnerID != nil { - if *a.InstanceOwnerID != *b.InstanceOwnerID { - delta.Add("Route.InstanceOwnerID", a.InstanceOwnerID, b.InstanceOwnerID) + delta.Add("CreateRouteInput.InstanceID", a.InstanceID, b.InstanceID) } } if ackcompare.HasNilDifference(a.LocalGatewayID, b.LocalGatewayID) { - delta.Add("Route.LocalGatewayID", a.LocalGatewayID, b.LocalGatewayID) + delta.Add("CreateRouteInput.LocalGatewayID", a.LocalGatewayID, b.LocalGatewayID) } else if a.LocalGatewayID != nil && b.LocalGatewayID != nil { if *a.LocalGatewayID != *b.LocalGatewayID { - delta.Add("Route.LocalGatewayID", a.LocalGatewayID, b.LocalGatewayID) + delta.Add("CreateRouteInput.LocalGatewayID", a.LocalGatewayID, b.LocalGatewayID) } } - if ackcompare.HasNilDifference(a.NatGatewayID, b.NatGatewayID) { - delta.Add("Route.NatGatewayID", a.NatGatewayID, b.NatGatewayID) - } else if a.NatGatewayID != nil && b.NatGatewayID != nil { - if *a.NatGatewayID != *b.NatGatewayID { - delta.Add("Route.NatGatewayID", a.NatGatewayID, b.NatGatewayID) + if ackcompare.HasNilDifference(a.NATGatewayID, b.NATGatewayID) { + delta.Add("CreateRouteInput.NATGatewayID", a.NATGatewayID, b.NATGatewayID) + } else if a.NATGatewayID != nil && b.NATGatewayID != nil { + if *a.NATGatewayID != *b.NATGatewayID { + delta.Add("CreateRouteInput.NATGatewayID", a.NATGatewayID, b.NATGatewayID) } } if ackcompare.HasNilDifference(a.NetworkInterfaceID, b.NetworkInterfaceID) { - delta.Add("Route.NetworkInterfaceID", a.NetworkInterfaceID, b.NetworkInterfaceID) + delta.Add("CreateRouteInput.NetworkInterfaceID", a.NetworkInterfaceID, b.NetworkInterfaceID) } else if a.NetworkInterfaceID != nil && b.NetworkInterfaceID != nil { if *a.NetworkInterfaceID != *b.NetworkInterfaceID { - delta.Add("Route.NetworkInterfaceID", a.NetworkInterfaceID, b.NetworkInterfaceID) + delta.Add("CreateRouteInput.NetworkInterfaceID", a.NetworkInterfaceID, b.NetworkInterfaceID) } } - if ackcompare.HasNilDifference(a.Origin, b.Origin) { - delta.Add("Route.Origin", a.Origin, b.Origin) - } else if a.Origin != nil && b.Origin != nil { - if *a.Origin != *b.Origin { - delta.Add("Route.Origin", a.Origin, b.Origin) - } - } - if ackcompare.HasNilDifference(a.State, b.State) { - delta.Add("Route.State", a.State, b.State) - } else if a.State != nil && b.State != nil { - if *a.State != *b.State { - delta.Add("Route.State", a.State, b.State) + if ackcompare.HasNilDifference(a.RouteTableID, b.RouteTableID) { + delta.Add("CreateRouteInput.RouteTableID", a.RouteTableID, b.RouteTableID) + } else if a.RouteTableID != nil && b.RouteTableID != nil { + if *a.RouteTableID != *b.RouteTableID { + delta.Add("CreateRouteInput.RouteTableID", a.RouteTableID, b.RouteTableID) } } if ackcompare.HasNilDifference(a.TransitGatewayID, b.TransitGatewayID) { - delta.Add("Route.TransitGatewayID", a.TransitGatewayID, b.TransitGatewayID) + delta.Add("CreateRouteInput.TransitGatewayID", a.TransitGatewayID, b.TransitGatewayID) } else if a.TransitGatewayID != nil && b.TransitGatewayID != nil { if *a.TransitGatewayID != *b.TransitGatewayID { - delta.Add("Route.TransitGatewayID", a.TransitGatewayID, b.TransitGatewayID) + delta.Add("CreateRouteInput.TransitGatewayID", a.TransitGatewayID, b.TransitGatewayID) + } + } + if ackcompare.HasNilDifference(a.VPCEndpointID, b.VPCEndpointID) { + delta.Add("CreateRouteInput.VPCEndpointID", a.VPCEndpointID, b.VPCEndpointID) + } else if a.VPCEndpointID != nil && b.VPCEndpointID != nil { + if *a.VPCEndpointID != *b.VPCEndpointID { + delta.Add("CreateRouteInput.VPCEndpointID", a.VPCEndpointID, b.VPCEndpointID) } } if ackcompare.HasNilDifference(a.VPCPeeringConnectionID, b.VPCPeeringConnectionID) { - delta.Add("Route.VPCPeeringConnectionID", a.VPCPeeringConnectionID, b.VPCPeeringConnectionID) + delta.Add("CreateRouteInput.VPCPeeringConnectionID", a.VPCPeeringConnectionID, b.VPCPeeringConnectionID) } else if a.VPCPeeringConnectionID != nil && b.VPCPeeringConnectionID != nil { if *a.VPCPeeringConnectionID != *b.VPCPeeringConnectionID { - delta.Add("Route.VPCPeeringConnectionID", a.VPCPeeringConnectionID, b.VPCPeeringConnectionID) + delta.Add("CreateRouteInput.VPCPeeringConnectionID", a.VPCPeeringConnectionID, b.VPCPeeringConnectionID) } } diff --git a/templates/hooks/route_table/sdk_read_many_post_set_output.go.tpl b/templates/hooks/route_table/sdk_read_many_post_set_output.go.tpl new file mode 100644 index 00000000..4a80fab8 --- /dev/null +++ b/templates/hooks/route_table/sdk_read_many_post_set_output.go.tpl @@ -0,0 +1,5 @@ + + if found { + rm.addRoutesToStatus(ko, resp.RouteTables[0]) + } + From 2c73566758a3dc265aa55f8832f87646b21918ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bryan=E2=84=A2=EF=B8=8F?= Date: Wed, 17 Nov 2021 16:50:09 -0600 Subject: [PATCH 13/16] update hook logic to populate RouteStatuses and fix test --- pkg/resource/route_table/hooks.go | 107 ++++++++++++++---- .../sdk_create_post_set_output.go.tpl | 2 + test/e2e/tests/test_route_table.py | 16 +-- test/e2e/tests/test_subnet.py | 2 - 4 files changed, 90 insertions(+), 37 deletions(-) diff --git a/pkg/resource/route_table/hooks.go b/pkg/resource/route_table/hooks.go index bc426041..ab90ccb7 100644 --- a/pkg/resource/route_table/hooks.go +++ b/pkg/resource/route_table/hooks.go @@ -22,9 +22,7 @@ import ( svcsdk "github.com/aws/aws-sdk-go/service/ec2" ) -const ( - LocalRouteGateway = "local" -) +const LocalRouteGateway = "local" func (rm *resourceManager) createRoutes( ctx context.Context, @@ -44,8 +42,8 @@ func (rm *resourceManager) syncRoutes( rlog := ackrtlog.FromContext(ctx) exit := rlog.Trace("rm.syncRoutes") defer exit(err) - toAdd := []*svcapitypes.Route{} - toDelete := []*svcapitypes.Route{} + toAdd := []*svcapitypes.CreateRouteInput{} + toDelete := []*svcapitypes.CreateRouteInput{} for _, desiredRoute := range desired.ko.Spec.Routes { if *desiredRoute.GatewayID == LocalRouteGateway { @@ -53,7 +51,7 @@ func (rm *resourceManager) syncRoutes( continue } if latestRoute := getMatchingRoute(desiredRoute, latest); latestRoute != nil { - delta := compareRoute(desiredRoute, latestRoute) + delta := compareCreateRouteInput(desiredRoute, latestRoute) if len(delta.Differences) > 0 { // "update" route by deleting old route and adding the new route toDelete = append(toDelete, latestRoute) @@ -90,49 +88,50 @@ func (rm *resourceManager) syncRoutes( } func getMatchingRoute( - routeToMatch *svcapitypes.Route, + routeToMatch *svcapitypes.CreateRouteInput, resource *resource, -) *svcapitypes.Route { +) *svcapitypes.CreateRouteInput { if resource == nil { return nil } + for _, route := range resource.ko.Spec.Routes { - delta := compareRoute(routeToMatch, route) + delta := compareCreateRouteInput(routeToMatch, route) if len(delta.Differences) == 0 { return route } else { if routeToMatch.CarrierGatewayID != nil { - if !delta.DifferentAt("Route.CarrierGatewayID") { + if !delta.DifferentAt("CreateRouteInput.CarrierGatewayID") { return route } } if routeToMatch.EgressOnlyInternetGatewayID != nil { - if !delta.DifferentAt("Route.EgressOnlyInternetGatewayID") { + if !delta.DifferentAt("CreateRouteInput.EgressOnlyInternetGatewayID") { return route } } if routeToMatch.GatewayID != nil { - if !delta.DifferentAt("Route.GatewayID") { + if !delta.DifferentAt("CreateRouteInput.GatewayID") { return route } } if routeToMatch.LocalGatewayID != nil { - if !delta.DifferentAt("Route.LocalGatewayID") { + if !delta.DifferentAt("CreateRouteInput.LocalGatewayID") { return route } } - if routeToMatch.NatGatewayID != nil { - if !delta.DifferentAt("Route.NatGatewayID") { + if routeToMatch.NATGatewayID != nil { + if !delta.DifferentAt("CreateRouteInput.NATGatewayID") { return route } } if routeToMatch.TransitGatewayID != nil { - if !delta.DifferentAt("Route.TransitGatewayID") { + if !delta.DifferentAt("CreateRouteInput.TransitGatewayID") { return route } } if routeToMatch.VPCPeeringConnectionID != nil { - if !delta.DifferentAt("Route.VPCPeeringConnectionID") { + if !delta.DifferentAt("CreateRouteInput.VPCPeeringConnectionID") { return route } } @@ -145,7 +144,7 @@ func getMatchingRoute( func (rm *resourceManager) createRoute( ctx context.Context, r *resource, - c svcapitypes.Route, + c svcapitypes.CreateRouteInput, ) (err error) { rlog := ackrtlog.FromContext(ctx) exit := rlog.Trace("rm.createRoute") @@ -160,7 +159,7 @@ func (rm *resourceManager) createRoute( func (rm *resourceManager) deleteRoute( ctx context.Context, r *resource, - c svcapitypes.Route, + c svcapitypes.CreateRouteInput, ) (err error) { rlog := ackrtlog.FromContext(ctx) exit := rlog.Trace("rm.deleteRoute") @@ -174,7 +173,7 @@ func (rm *resourceManager) deleteRoute( func (rm *resourceManager) newCreateRoutePayload( r *resource, - c svcapitypes.Route, + c svcapitypes.CreateRouteInput, ) *svcsdk.CreateRouteInput { input := &svcsdk.CreateRouteInput{} if r.ko.Status.RouteTableID != nil { @@ -204,8 +203,8 @@ func (rm *resourceManager) newCreateRoutePayload( if c.LocalGatewayID != nil { input.SetLocalGatewayId(*c.LocalGatewayID) } - if c.NatGatewayID != nil { - input.SetNatGatewayId(*c.NatGatewayID) + if c.NATGatewayID != nil { + input.SetNatGatewayId(*c.NATGatewayID) } if c.NetworkInterfaceID != nil { input.SetNetworkInterfaceId(*c.NetworkInterfaceID) @@ -216,14 +215,13 @@ func (rm *resourceManager) newCreateRoutePayload( if c.VPCPeeringConnectionID != nil { input.SetVpcPeeringConnectionId(*c.VPCPeeringConnectionID) } - input.SetDryRun(false) return input } func (rm *resourceManager) newDeleteRoutePayload( r *resource, - c svcapitypes.Route, + c svcapitypes.CreateRouteInput, ) *svcsdk.DeleteRouteInput { input := &svcsdk.DeleteRouteInput{} if r.ko.Status.RouteTableID != nil { @@ -273,3 +271,64 @@ func (rm *resourceManager) requiredFieldsMissingForCreateRoute( ) bool { return r.ko.Status.RouteTableID == nil } + +// addRoutesToStatus takes a RouteTable from an aws-sdk output +// and adds its Routes to RouteTable.Status.RouteStatuses. +// This cannot be auto-generated because the code-generator already associates +// RouteTable's Routes from aws-sdk output with RouteTable.Spec.Routes. +func (rm *resourceManager) addRoutesToStatus( + ko *svcapitypes.RouteTable, + routeTable *svcsdk.RouteTable, +) { + ko.Status.RouteStatuses = nil + if routeTable.Routes != nil { + routesInStatus := []*svcapitypes.Route{} + for _, r := range routeTable.Routes { + routeInStatus := &svcapitypes.Route{} + if r.CarrierGatewayId != nil { + routeInStatus.CarrierGatewayID = r.CarrierGatewayId + } + if r.DestinationCidrBlock != nil { + routeInStatus.DestinationCIDRBlock = r.DestinationCidrBlock + } + if r.DestinationIpv6CidrBlock != nil { + routeInStatus.DestinationIPv6CIDRBlock = r.DestinationIpv6CidrBlock + } + if r.DestinationPrefixListId != nil { + routeInStatus.DestinationPrefixListID = r.DestinationPrefixListId + } + if r.EgressOnlyInternetGatewayId != nil { + routeInStatus.EgressOnlyInternetGatewayID = r.EgressOnlyInternetGatewayId + } + if r.GatewayId != nil { + routeInStatus.GatewayID = r.GatewayId + } + if r.InstanceId != nil { + routeInStatus.InstanceID = r.InstanceId + } + if r.LocalGatewayId != nil { + routeInStatus.LocalGatewayID = r.LocalGatewayId + } + if r.NatGatewayId != nil { + routeInStatus.NATGatewayID = r.NatGatewayId + } + if r.NetworkInterfaceId != nil { + routeInStatus.NetworkInterfaceID = r.NetworkInterfaceId + } + if r.TransitGatewayId != nil { + routeInStatus.TransitGatewayID = r.TransitGatewayId + } + if r.VpcPeeringConnectionId != nil { + routeInStatus.VPCPeeringConnectionID = r.VpcPeeringConnectionId + } + if r.Origin != nil { + routeInStatus.Origin = r.Origin + } + if r.State != nil { + routeInStatus.State = r.State + } + routesInStatus = append(routesInStatus, routeInStatus) + } + ko.Status.RouteStatuses = routesInStatus + } +} diff --git a/templates/hooks/route_table/sdk_create_post_set_output.go.tpl b/templates/hooks/route_table/sdk_create_post_set_output.go.tpl index 3984bf4f..94d6d632 100644 --- a/templates/hooks/route_table/sdk_create_post_set_output.go.tpl +++ b/templates/hooks/route_table/sdk_create_post_set_output.go.tpl @@ -1,3 +1,5 @@ + rm.addRoutesToStatus(ko, resp.RouteTable) + if rm.requiredFieldsMissingForCreateRoute(&resource{ko}) { return nil, ackerr.NotFound } diff --git a/test/e2e/tests/test_route_table.py b/test/e2e/tests/test_route_table.py index d1a2e03f..d322a549 100644 --- a/test/e2e/tests/test_route_table.py +++ b/test/e2e/tests/test_route_table.py @@ -209,15 +209,11 @@ def test_crud_route(self, ec2_client): { #Default route cannot be changed "destinationCIDRBlock": default_cidr, - "gatewayID": "local", - "origin": "CreateRouteTable", - "state": "active" + "gatewayID": "local" }, { "destinationCIDRBlock": updated_cidr, - "gatewayID": igw_id, - "origin": "no", - "state": "texas" + "gatewayID": igw_id } ] } @@ -227,8 +223,8 @@ def test_crud_route(self, ec2_client): # assert patched state resource = k8s.get_resource(ref) - assert len(resource['spec']['routes']) == 2 - for route in resource['spec']['routes']: + assert len(resource['status']['routeStatuses']) == 2 + for route in resource['status']['routeStatuses']: if route["gatewayID"] == "local": assert route_exists(ec2_client, resource_id, "local", "CreateRouteTable") elif route["gatewayID"] == igw_id: @@ -242,9 +238,7 @@ def test_crud_route(self, ec2_client): patch = {"spec": {"routes": [ { "destinationCIDRBlock": default_cidr, - "gatewayID": "local", - "origin": "CreateRouteTable", - "state": "active" + "gatewayID": "local" } ] } diff --git a/test/e2e/tests/test_subnet.py b/test/e2e/tests/test_subnet.py index 85ead176..433d2358 100644 --- a/test/e2e/tests/test_subnet.py +++ b/test/e2e/tests/test_subnet.py @@ -80,9 +80,7 @@ def test_create_delete(self, ec2_client): assert cr is not None assert k8s.get_resource_exists(ref) - print(f"ref is {ref}") resource = k8s.get_resource(ref) - print(f"res is {resource}") resource_id = resource["status"]["subnetID"] time.sleep(CREATE_WAIT_AFTER_SECONDS) From 0863ab7cb7de711c3070b4bbd862c4bcd4bec147 Mon Sep 17 00:00:00 2001 From: Nicholas Thomson Date: Wed, 17 Nov 2021 16:18:19 -0800 Subject: [PATCH 14/16] Generate create, delete and setter for Route --- apis/v1alpha1/ack-generate-metadata.yaml | 6 +- apis/v1alpha1/generator.yaml | 1 + generator.yaml | 1 + pkg/resource/route_table/hooks.go | 118 +--------------- pkg/resource/route_table/sdk.go | 128 ++++++++++++++++++ .../hooks/route_table/sdk_file_end.go.tpl | 43 +++++- 6 files changed, 178 insertions(+), 119 deletions(-) diff --git a/apis/v1alpha1/ack-generate-metadata.yaml b/apis/v1alpha1/ack-generate-metadata.yaml index 52d3ebb5..dbc2bab6 100755 --- a/apis/v1alpha1/ack-generate-metadata.yaml +++ b/apis/v1alpha1/ack-generate-metadata.yaml @@ -1,13 +1,13 @@ ack_generate_info: - build_date: "2021-11-17T22:45:36Z" + build_date: "2021-11-18T00:17:24Z" build_hash: 966e9a9ac6dfb4bbc2d3ded1972ce2b706391d44 - go_version: go1.17 + go_version: go1.17.1 version: v0.15.2 api_directory_checksum: e13129556d60164826bdeea39735660c7cfa1212 api_version: v1alpha1 aws_sdk_go_version: v1.37.10 generator_config_info: - file_checksum: 9909796f8b2f4f236120776f311f46f1e3859462 + file_checksum: c181a37589ac5c979a81e499c2561dbd69264368 original_file_name: generator.yaml last_modification: reason: API generation diff --git a/apis/v1alpha1/generator.yaml b/apis/v1alpha1/generator.yaml index ff32a632..e9e80b9a 100644 --- a/apis/v1alpha1/generator.yaml +++ b/apis/v1alpha1/generator.yaml @@ -11,6 +11,7 @@ ignore: - CreateTransitGatewayInput.DryRun - CreateVpcInput.DryRun - CreateVpcEndpointInput.DryRun + - DeleteRouteInput.DryRun # support EC2-VPC only - DeleteSecurityGroupInput.GroupName resource_names: diff --git a/generator.yaml b/generator.yaml index ff32a632..e9e80b9a 100644 --- a/generator.yaml +++ b/generator.yaml @@ -11,6 +11,7 @@ ignore: - CreateTransitGatewayInput.DryRun - CreateVpcInput.DryRun - CreateVpcEndpointInput.DryRun + - DeleteRouteInput.DryRun # support EC2-VPC only - DeleteSecurityGroupInput.GroupName resource_names: diff --git a/pkg/resource/route_table/hooks.go b/pkg/resource/route_table/hooks.go index ab90ccb7..cf3fbdf5 100644 --- a/pkg/resource/route_table/hooks.go +++ b/pkg/resource/route_table/hooks.go @@ -150,7 +150,7 @@ func (rm *resourceManager) createRoute( exit := rlog.Trace("rm.createRoute") defer exit(err) - input := rm.newCreateRoutePayload(r, c) + input := rm.newCreateRouteInput(c) _, err = rm.sdkapi.CreateRouteWithContext(ctx, input) rm.metrics.RecordAPICall("CREATE", "CreateRoute", err) return err @@ -165,81 +165,12 @@ func (rm *resourceManager) deleteRoute( exit := rlog.Trace("rm.deleteRoute") defer exit(err) - input := rm.newDeleteRoutePayload(r, c) + input := rm.newDeleteRouteInput(c) _, err = rm.sdkapi.DeleteRouteWithContext(ctx, input) rm.metrics.RecordAPICall("DELETE", "DeleteRoute", err) return err } -func (rm *resourceManager) newCreateRoutePayload( - r *resource, - c svcapitypes.CreateRouteInput, -) *svcsdk.CreateRouteInput { - input := &svcsdk.CreateRouteInput{} - if r.ko.Status.RouteTableID != nil { - input.SetRouteTableId(*r.ko.Status.RouteTableID) - } - if c.CarrierGatewayID != nil { - input.SetCarrierGatewayId(*c.CarrierGatewayID) - } - if c.DestinationCIDRBlock != nil { - input.SetDestinationCidrBlock(*c.DestinationCIDRBlock) - } - if c.DestinationIPv6CIDRBlock != nil { - input.SetDestinationIpv6CidrBlock(*c.DestinationIPv6CIDRBlock) - } - if c.DestinationPrefixListID != nil { - input.SetDestinationPrefixListId(*c.DestinationPrefixListID) - } - if c.EgressOnlyInternetGatewayID != nil { - input.SetEgressOnlyInternetGatewayId(*c.EgressOnlyInternetGatewayID) - } - if c.GatewayID != nil { - input.SetGatewayId(*c.GatewayID) - } - if c.InstanceID != nil { - input.SetInstanceId(*c.InstanceID) - } - if c.LocalGatewayID != nil { - input.SetLocalGatewayId(*c.LocalGatewayID) - } - if c.NATGatewayID != nil { - input.SetNatGatewayId(*c.NATGatewayID) - } - if c.NetworkInterfaceID != nil { - input.SetNetworkInterfaceId(*c.NetworkInterfaceID) - } - if c.TransitGatewayID != nil { - input.SetTransitGatewayId(*c.TransitGatewayID) - } - if c.VPCPeeringConnectionID != nil { - input.SetVpcPeeringConnectionId(*c.VPCPeeringConnectionID) - } - - return input -} - -func (rm *resourceManager) newDeleteRoutePayload( - r *resource, - c svcapitypes.CreateRouteInput, -) *svcsdk.DeleteRouteInput { - input := &svcsdk.DeleteRouteInput{} - if r.ko.Status.RouteTableID != nil { - input.SetRouteTableId(*r.ko.Status.RouteTableID) - } - if c.DestinationCIDRBlock != nil { - input.SetDestinationCidrBlock(*c.DestinationCIDRBlock) - } - if c.DestinationIPv6CIDRBlock != nil { - input.SetDestinationIpv6CidrBlock(*c.DestinationIPv6CIDRBlock) - } - if c.DestinationPrefixListID != nil { - input.SetDestinationPrefixListId(*c.DestinationPrefixListID) - } - - return input -} - func (rm *resourceManager) customUpdateRouteTable( ctx context.Context, desired *resource, @@ -284,50 +215,7 @@ func (rm *resourceManager) addRoutesToStatus( if routeTable.Routes != nil { routesInStatus := []*svcapitypes.Route{} for _, r := range routeTable.Routes { - routeInStatus := &svcapitypes.Route{} - if r.CarrierGatewayId != nil { - routeInStatus.CarrierGatewayID = r.CarrierGatewayId - } - if r.DestinationCidrBlock != nil { - routeInStatus.DestinationCIDRBlock = r.DestinationCidrBlock - } - if r.DestinationIpv6CidrBlock != nil { - routeInStatus.DestinationIPv6CIDRBlock = r.DestinationIpv6CidrBlock - } - if r.DestinationPrefixListId != nil { - routeInStatus.DestinationPrefixListID = r.DestinationPrefixListId - } - if r.EgressOnlyInternetGatewayId != nil { - routeInStatus.EgressOnlyInternetGatewayID = r.EgressOnlyInternetGatewayId - } - if r.GatewayId != nil { - routeInStatus.GatewayID = r.GatewayId - } - if r.InstanceId != nil { - routeInStatus.InstanceID = r.InstanceId - } - if r.LocalGatewayId != nil { - routeInStatus.LocalGatewayID = r.LocalGatewayId - } - if r.NatGatewayId != nil { - routeInStatus.NATGatewayID = r.NatGatewayId - } - if r.NetworkInterfaceId != nil { - routeInStatus.NetworkInterfaceID = r.NetworkInterfaceId - } - if r.TransitGatewayId != nil { - routeInStatus.TransitGatewayID = r.TransitGatewayId - } - if r.VpcPeeringConnectionId != nil { - routeInStatus.VPCPeeringConnectionID = r.VpcPeeringConnectionId - } - if r.Origin != nil { - routeInStatus.Origin = r.Origin - } - if r.State != nil { - routeInStatus.State = r.State - } - routesInStatus = append(routesInStatus, routeInStatus) + routesInStatus = append(routesInStatus, rm.setResourceRoute(r)) } ko.Status.RouteStatuses = routesInStatus } diff --git a/pkg/resource/route_table/sdk.go b/pkg/resource/route_table/sdk.go index 2dda11c7..34924162 100644 --- a/pkg/resource/route_table/sdk.go +++ b/pkg/resource/route_table/sdk.go @@ -720,3 +720,131 @@ func compareCreateRouteInput( return delta } + +func (rm *resourceManager) newCreateRouteInput( + c svcapitypes.CreateRouteInput, +) *svcsdk.CreateRouteInput { + res := &svcsdk.CreateRouteInput{} + + if c.CarrierGatewayID != nil { + res.SetCarrierGatewayId(*c.CarrierGatewayID) + } + if c.DestinationCIDRBlock != nil { + res.SetDestinationCidrBlock(*c.DestinationCIDRBlock) + } + if c.DestinationIPv6CIDRBlock != nil { + res.SetDestinationIpv6CidrBlock(*c.DestinationIPv6CIDRBlock) + } + if c.DestinationPrefixListID != nil { + res.SetDestinationPrefixListId(*c.DestinationPrefixListID) + } + if c.EgressOnlyInternetGatewayID != nil { + res.SetEgressOnlyInternetGatewayId(*c.EgressOnlyInternetGatewayID) + } + if c.GatewayID != nil { + res.SetGatewayId(*c.GatewayID) + } + if c.InstanceID != nil { + res.SetInstanceId(*c.InstanceID) + } + if c.LocalGatewayID != nil { + res.SetLocalGatewayId(*c.LocalGatewayID) + } + if c.NATGatewayID != nil { + res.SetNatGatewayId(*c.NATGatewayID) + } + if c.NetworkInterfaceID != nil { + res.SetNetworkInterfaceId(*c.NetworkInterfaceID) + } + if c.RouteTableID != nil { + res.SetRouteTableId(*c.RouteTableID) + } + if c.TransitGatewayID != nil { + res.SetTransitGatewayId(*c.TransitGatewayID) + } + if c.VPCEndpointID != nil { + res.SetVpcEndpointId(*c.VPCEndpointID) + } + if c.VPCPeeringConnectionID != nil { + res.SetVpcPeeringConnectionId(*c.VPCPeeringConnectionID) + } + + return res +} + +func (rm *resourceManager) newDeleteRouteInput( + c svcapitypes.CreateRouteInput, +) *svcsdk.DeleteRouteInput { + res := &svcsdk.DeleteRouteInput{} + + if c.DestinationCIDRBlock != nil { + res.SetDestinationCidrBlock(*c.DestinationCIDRBlock) + } + if c.DestinationIPv6CIDRBlock != nil { + res.SetDestinationIpv6CidrBlock(*c.DestinationIPv6CIDRBlock) + } + if c.DestinationPrefixListID != nil { + res.SetDestinationPrefixListId(*c.DestinationPrefixListID) + } + if c.RouteTableID != nil { + res.SetRouteTableId(*c.RouteTableID) + } + + return res +} + +// setRoute sets a resource Route type +// given the SDK type. +func (rm *resourceManager) setResourceRoute( + resp *svcsdk.Route, +) *svcapitypes.Route { + res := &svcapitypes.Route{} + + if resp.CarrierGatewayId != nil { + res.CarrierGatewayID = resp.CarrierGatewayId + } + if resp.DestinationCidrBlock != nil { + res.DestinationCIDRBlock = resp.DestinationCidrBlock + } + if resp.DestinationIpv6CidrBlock != nil { + res.DestinationIPv6CIDRBlock = resp.DestinationIpv6CidrBlock + } + if resp.DestinationPrefixListId != nil { + res.DestinationPrefixListID = resp.DestinationPrefixListId + } + if resp.EgressOnlyInternetGatewayId != nil { + res.EgressOnlyInternetGatewayID = resp.EgressOnlyInternetGatewayId + } + if resp.GatewayId != nil { + res.GatewayID = resp.GatewayId + } + if resp.InstanceId != nil { + res.InstanceID = resp.InstanceId + } + if resp.InstanceOwnerId != nil { + res.InstanceOwnerID = resp.InstanceOwnerId + } + if resp.LocalGatewayId != nil { + res.LocalGatewayID = resp.LocalGatewayId + } + if resp.NatGatewayId != nil { + res.NATGatewayID = resp.NatGatewayId + } + if resp.NetworkInterfaceId != nil { + res.NetworkInterfaceID = resp.NetworkInterfaceId + } + if resp.Origin != nil { + res.Origin = resp.Origin + } + if resp.State != nil { + res.State = resp.State + } + if resp.TransitGatewayId != nil { + res.TransitGatewayID = resp.TransitGatewayId + } + if resp.VpcPeeringConnectionId != nil { + res.VPCPeeringConnectionID = resp.VpcPeeringConnectionId + } + + return res +} diff --git a/templates/hooks/route_table/sdk_file_end.go.tpl b/templates/hooks/route_table/sdk_file_end.go.tpl index 2418c5a0..6c522317 100644 --- a/templates/hooks/route_table/sdk_file_end.go.tpl +++ b/templates/hooks/route_table/sdk_file_end.go.tpl @@ -20,7 +20,48 @@ func compare{{$memberRefName}} ( return delta } +func (rm *resourceManager) new{{ $memberRefName }}( + c svcapitypes.{{ $memberRefName }}, +) *svcsdk.{{ $memberRefName }} { + res := &svcsdk.{{ $memberRefName }}{} + +{{ GoCodeSetSDKForStruct $CRD "" "res" $memberRef "" "c" 1 }} + + return res +} + {{- end }} {{- end }} {{- end }} -{{- end }} \ No newline at end of file +{{- end }} + +{{/* Delete operation for Routes */}} + +{{- $deleteInputRef := (index $SDKAPI.API.Operations "DeleteRoute").InputRef }} +{{- $deleteInputName := $deleteInputRef.ShapeName }} + +func (rm *resourceManager) new{{ $deleteInputName }}( + c svcapitypes.CreateRouteInput, +) *svcsdk.{{ $deleteInputName }} { + res := &svcsdk.{{ $deleteInputName }}{} + +{{ GoCodeSetSDKForStruct $CRD "" "res" $deleteInputRef "" "c" 1 }} + + return res +} + +{{/* Setter for Route */}} + +{{- $routeRef := (index (index $SDKAPI.API.Shapes "RouteTable").MemberRefs "Routes").Shape.MemberRef }} +{{- $routeRefName := $routeRef.ShapeName }} + +// set{{ $routeRefName }} sets a resource {{ $routeRefName }} type +// given the SDK type. +func (rm *resourceManager) setResource{{ $routeRefName }}( + resp *svcsdk.{{ $routeRefName }}, +) *svcapitypes.{{ $routeRefName }} { + res := &svcapitypes.{{ $routeRefName }}{} + +{{ GoCodeSetResourceForStruct $CRD "RouteStatuses" "res" $routeRef "resp" $routeRef 1 }} + return res +} \ No newline at end of file From 0117e4c38eb89fe5593af6f3003c4ae66a7537e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bryan=E2=84=A2=EF=B8=8F?= Date: Thu, 18 Nov 2021 11:23:21 -0600 Subject: [PATCH 15/16] add Route comments to generator.yaml --- apis/v1alpha1/ack-generate-metadata.yaml | 6 +++--- apis/v1alpha1/generator.yaml | 5 +++++ generator.yaml | 5 +++++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/apis/v1alpha1/ack-generate-metadata.yaml b/apis/v1alpha1/ack-generate-metadata.yaml index dbc2bab6..54edf472 100755 --- a/apis/v1alpha1/ack-generate-metadata.yaml +++ b/apis/v1alpha1/ack-generate-metadata.yaml @@ -1,13 +1,13 @@ ack_generate_info: - build_date: "2021-11-18T00:17:24Z" + build_date: "2021-11-18T17:23:33Z" build_hash: 966e9a9ac6dfb4bbc2d3ded1972ce2b706391d44 - go_version: go1.17.1 + go_version: go1.17 version: v0.15.2 api_directory_checksum: e13129556d60164826bdeea39735660c7cfa1212 api_version: v1alpha1 aws_sdk_go_version: v1.37.10 generator_config_info: - file_checksum: c181a37589ac5c979a81e499c2561dbd69264368 + file_checksum: c69b7d971ffb1c4bb6bdee584289390e9362f4d9 original_file_name: generator.yaml last_modification: reason: API generation diff --git a/apis/v1alpha1/generator.yaml b/apis/v1alpha1/generator.yaml index e9e80b9a..b1c666ac 100644 --- a/apis/v1alpha1/generator.yaml +++ b/apis/v1alpha1/generator.yaml @@ -90,11 +90,16 @@ resources: - InvalidVpcID.NotFound - InvalidParameterValue fields: + # RouteStatuses as Route to ensure + # fields set server-side (active, origin) + # are exposed in Status RouteStatuses: from: operation: DescribeRouteTables path: RouteTables.Routes is_read_only: true + # Routes as CreateRouteInput to ensure only + # user-editable fields are exposed in Spec Routes: custom_field: list_of: CreateRouteInput diff --git a/generator.yaml b/generator.yaml index e9e80b9a..b1c666ac 100644 --- a/generator.yaml +++ b/generator.yaml @@ -90,11 +90,16 @@ resources: - InvalidVpcID.NotFound - InvalidParameterValue fields: + # RouteStatuses as Route to ensure + # fields set server-side (active, origin) + # are exposed in Status RouteStatuses: from: operation: DescribeRouteTables path: RouteTables.Routes is_read_only: true + # Routes as CreateRouteInput to ensure only + # user-editable fields are exposed in Spec Routes: custom_field: list_of: CreateRouteInput From 3fbe7a37e99660b05ef67cee704cf0e7cdd12700 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bryan=E2=84=A2=EF=B8=8F?= Date: Thu, 18 Nov 2021 14:11:58 -0600 Subject: [PATCH 16/16] Remove RouteTableId from Route Spec --- apis/v1alpha1/ack-generate-metadata.yaml | 6 +++--- apis/v1alpha1/generator.yaml | 2 ++ apis/v1alpha1/types.go | 1 - apis/v1alpha1/zz_generated.deepcopy.go | 5 ----- .../crd/bases/ec2.services.k8s.aws_routetables.yaml | 2 -- generator.yaml | 2 ++ helm/crds/ec2.services.k8s.aws_routetables.yaml | 2 -- pkg/resource/route_table/hooks.go | 6 ++++++ pkg/resource/route_table/sdk.go | 13 ------------- 9 files changed, 13 insertions(+), 26 deletions(-) diff --git a/apis/v1alpha1/ack-generate-metadata.yaml b/apis/v1alpha1/ack-generate-metadata.yaml index 54edf472..bad512ec 100755 --- a/apis/v1alpha1/ack-generate-metadata.yaml +++ b/apis/v1alpha1/ack-generate-metadata.yaml @@ -1,13 +1,13 @@ ack_generate_info: - build_date: "2021-11-18T17:23:33Z" + build_date: "2021-11-18T20:10:16Z" build_hash: 966e9a9ac6dfb4bbc2d3ded1972ce2b706391d44 go_version: go1.17 version: v0.15.2 -api_directory_checksum: e13129556d60164826bdeea39735660c7cfa1212 +api_directory_checksum: 43cfac78c9b056059cb202c220f24ac4fb02477f api_version: v1alpha1 aws_sdk_go_version: v1.37.10 generator_config_info: - file_checksum: c69b7d971ffb1c4bb6bdee584289390e9362f4d9 + file_checksum: c2aa55a1129fa79f889cea05f77bc97ab4b70d89 original_file_name: generator.yaml last_modification: reason: API generation diff --git a/apis/v1alpha1/generator.yaml b/apis/v1alpha1/generator.yaml index b1c666ac..4018d737 100644 --- a/apis/v1alpha1/generator.yaml +++ b/apis/v1alpha1/generator.yaml @@ -5,6 +5,7 @@ ignore: field_paths: - CreateInternetGatewayInput.DryRun - CreateRouteInput.DryRun + - CreateRouteInput.RouteTableId - CreateRouteTableInput.DryRun - CreateSecurityGroupInput.DryRun - CreateSubnetInput.DryRun @@ -12,6 +13,7 @@ ignore: - CreateVpcInput.DryRun - CreateVpcEndpointInput.DryRun - DeleteRouteInput.DryRun + - DeleteRouteInput.RouteTableId # support EC2-VPC only - DeleteSecurityGroupInput.GroupName resource_names: diff --git a/apis/v1alpha1/types.go b/apis/v1alpha1/types.go index f5328a8b..9264aafd 100644 --- a/apis/v1alpha1/types.go +++ b/apis/v1alpha1/types.go @@ -506,7 +506,6 @@ type CreateRouteInput struct { LocalGatewayID *string `json:"localGatewayID,omitempty"` NATGatewayID *string `json:"natGatewayID,omitempty"` NetworkInterfaceID *string `json:"networkInterfaceID,omitempty"` - RouteTableID *string `json:"routeTableID,omitempty"` TransitGatewayID *string `json:"transitGatewayID,omitempty"` VPCEndpointID *string `json:"vpcEndpointID,omitempty"` VPCPeeringConnectionID *string `json:"vpcPeeringConnectionID,omitempty"` diff --git a/apis/v1alpha1/zz_generated.deepcopy.go b/apis/v1alpha1/zz_generated.deepcopy.go index 00142b27..517b0e4b 100644 --- a/apis/v1alpha1/zz_generated.deepcopy.go +++ b/apis/v1alpha1/zz_generated.deepcopy.go @@ -2087,11 +2087,6 @@ func (in *CreateRouteInput) DeepCopyInto(out *CreateRouteInput) { *out = new(string) **out = **in } - if in.RouteTableID != nil { - in, out := &in.RouteTableID, &out.RouteTableID - *out = new(string) - **out = **in - } if in.TransitGatewayID != nil { in, out := &in.TransitGatewayID, &out.TransitGatewayID *out = new(string) diff --git a/config/crd/bases/ec2.services.k8s.aws_routetables.yaml b/config/crd/bases/ec2.services.k8s.aws_routetables.yaml index aacd7c32..d32afb1d 100644 --- a/config/crd/bases/ec2.services.k8s.aws_routetables.yaml +++ b/config/crd/bases/ec2.services.k8s.aws_routetables.yaml @@ -60,8 +60,6 @@ spec: type: string networkInterfaceID: type: string - routeTableID: - type: string transitGatewayID: type: string vpcEndpointID: diff --git a/generator.yaml b/generator.yaml index b1c666ac..4018d737 100644 --- a/generator.yaml +++ b/generator.yaml @@ -5,6 +5,7 @@ ignore: field_paths: - CreateInternetGatewayInput.DryRun - CreateRouteInput.DryRun + - CreateRouteInput.RouteTableId - CreateRouteTableInput.DryRun - CreateSecurityGroupInput.DryRun - CreateSubnetInput.DryRun @@ -12,6 +13,7 @@ ignore: - CreateVpcInput.DryRun - CreateVpcEndpointInput.DryRun - DeleteRouteInput.DryRun + - DeleteRouteInput.RouteTableId # support EC2-VPC only - DeleteSecurityGroupInput.GroupName resource_names: diff --git a/helm/crds/ec2.services.k8s.aws_routetables.yaml b/helm/crds/ec2.services.k8s.aws_routetables.yaml index aacd7c32..d32afb1d 100644 --- a/helm/crds/ec2.services.k8s.aws_routetables.yaml +++ b/helm/crds/ec2.services.k8s.aws_routetables.yaml @@ -60,8 +60,6 @@ spec: type: string networkInterfaceID: type: string - routeTableID: - type: string transitGatewayID: type: string vpcEndpointID: diff --git a/pkg/resource/route_table/hooks.go b/pkg/resource/route_table/hooks.go index cf3fbdf5..fad8de96 100644 --- a/pkg/resource/route_table/hooks.go +++ b/pkg/resource/route_table/hooks.go @@ -151,6 +151,9 @@ func (rm *resourceManager) createRoute( defer exit(err) input := rm.newCreateRouteInput(c) + // Routes should only be configurable for the + // RouteTable in which they are defined + input.RouteTableId = r.ko.Status.RouteTableID _, err = rm.sdkapi.CreateRouteWithContext(ctx, input) rm.metrics.RecordAPICall("CREATE", "CreateRoute", err) return err @@ -166,6 +169,9 @@ func (rm *resourceManager) deleteRoute( defer exit(err) input := rm.newDeleteRouteInput(c) + // Routes should only be configurable for the + // RouteTable in which they are defined + input.RouteTableId = r.ko.Status.RouteTableID _, err = rm.sdkapi.DeleteRouteWithContext(ctx, input) rm.metrics.RecordAPICall("DELETE", "DeleteRoute", err) return err diff --git a/pkg/resource/route_table/sdk.go b/pkg/resource/route_table/sdk.go index 34924162..faed41a1 100644 --- a/pkg/resource/route_table/sdk.go +++ b/pkg/resource/route_table/sdk.go @@ -689,13 +689,6 @@ func compareCreateRouteInput( delta.Add("CreateRouteInput.NetworkInterfaceID", a.NetworkInterfaceID, b.NetworkInterfaceID) } } - if ackcompare.HasNilDifference(a.RouteTableID, b.RouteTableID) { - delta.Add("CreateRouteInput.RouteTableID", a.RouteTableID, b.RouteTableID) - } else if a.RouteTableID != nil && b.RouteTableID != nil { - if *a.RouteTableID != *b.RouteTableID { - delta.Add("CreateRouteInput.RouteTableID", a.RouteTableID, b.RouteTableID) - } - } if ackcompare.HasNilDifference(a.TransitGatewayID, b.TransitGatewayID) { delta.Add("CreateRouteInput.TransitGatewayID", a.TransitGatewayID, b.TransitGatewayID) } else if a.TransitGatewayID != nil && b.TransitGatewayID != nil { @@ -756,9 +749,6 @@ func (rm *resourceManager) newCreateRouteInput( if c.NetworkInterfaceID != nil { res.SetNetworkInterfaceId(*c.NetworkInterfaceID) } - if c.RouteTableID != nil { - res.SetRouteTableId(*c.RouteTableID) - } if c.TransitGatewayID != nil { res.SetTransitGatewayId(*c.TransitGatewayID) } @@ -786,9 +776,6 @@ func (rm *resourceManager) newDeleteRouteInput( if c.DestinationPrefixListID != nil { res.SetDestinationPrefixListId(*c.DestinationPrefixListID) } - if c.RouteTableID != nil { - res.SetRouteTableId(*c.RouteTableID) - } return res }