Skip to content

Commit

Permalink
Provide default gateway setup (#502)
Browse files Browse the repository at this point in the history
  • Loading branch information
Doyoon Kim authored Nov 15, 2023
1 parent 7b50ad7 commit 37f548a
Show file tree
Hide file tree
Showing 12 changed files with 266 additions and 1,113 deletions.
18 changes: 17 additions & 1 deletion controllers/gateway_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ import (

"github.com/aws/aws-application-networking-k8s/controllers/eventhandlers"
"github.com/aws/aws-application-networking-k8s/pkg/aws/services"
deploy "github.com/aws/aws-application-networking-k8s/pkg/deploy/lattice"
model "github.com/aws/aws-application-networking-k8s/pkg/model/lattice"
pkg_builder "sigs.k8s.io/controller-runtime/pkg/builder"
"sigs.k8s.io/controller-runtime/pkg/predicate"
)
Expand Down Expand Up @@ -80,6 +82,20 @@ func RegisterGatewayController(
cloud: cloud,
}

if config.DefaultServiceNetwork != "" {
// Attempt creation of default service network, move gracefully even if it fails.
snManager := deploy.NewDefaultServiceNetworkManager(log, cloud)
_, err := snManager.CreateOrUpdate(context.Background(), &model.ServiceNetwork{
Spec: model.ServiceNetworkSpec{
Name: config.DefaultServiceNetwork,
},
})
if err != nil {
log.Infof("Could not setup default service network %s, proceeding without it - %s",
config.DefaultServiceNetwork, err.Error())
}
}

gwClassEventHandler := eventhandlers.NewEnqueueRequestsForGatewayClassEvent(log, mgrClient)
vpcAssociationPolicyEventHandler := eventhandlers.NewVpcAssociationPolicyEventHandler(log, mgrClient)
builder := ctrl.NewControllerManagedBy(mgr).
Expand Down Expand Up @@ -212,7 +228,7 @@ func (r *gatewayReconciler) reconcileUpsert(ctx context.Context, gw *gwv1beta1.G
if err != nil {
if services.IsNotFoundError(err) {
if err = r.updateGatewayProgrammedStatus(ctx, "", gw, false); err != nil {
return err
return lattice_runtime.NewRetryError()
}
return nil
}
Expand Down
1 change: 1 addition & 0 deletions controllers/vpcassociationpolicy_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ func RegisterVpcAssociationPolicyController(log gwlog.Logger, mgr ctrl.Manager,
cloud: cloud,
manager: deploy.NewDefaultServiceNetworkManager(log, cloud),
}

eh := eventhandlers.NewPolicyEventHandler(log, mgr.GetClient(), &anv1alpha1.VpcAssociationPolicy{})
err := ctrl.NewControllerManagedBy(mgr).
For(&anv1alpha1.VpcAssociationPolicy{}, builder.WithPredicates(predicate.GenerationChangedPredicate{})).
Expand Down
79 changes: 9 additions & 70 deletions docs/configure/environment.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,84 +55,23 @@ When set as "debug", the AWS Gateway API Controller will emit debug level logs.

---

#### `CLUSTER_LOCAL_GATEWAY`
#### `DEFAULT_SERVICE_NETWORK`

Type: string

Default: "NO_DEFAULT_SERVICE_NETWORK"
Default: ""

When it is set to something different from "NO_DEFAULT_SERVICE_NETWORK", the AWS Gateway API Controller will associate its correspoding Lattice Service Network to cluster's VPC.
Also, all HTTPRoutes will automatically have an additional parentref to this `CLUSTER_LOCAL_GATEWAY`.
When set as a non-empty value, creates a service network with that name.
The created service network will be also associated with cluster VPC.

---

#### `TARGET_GROUP_NAME_LEN_MODE`
#### `ENABLE_SERVICE_NETWORK_OVERRIDE`

Type: string

Default: "short"
Default: ""

When set to "long", the controller will create Lattice TargetGroup as follows.

For Kubernetes Service as BackendRef:

`k8s-(k8s service name)-(k8s service namespace)-(k8s httproute name)-(VPC ID)-(protocol)-(protocol version)`

For ServiceExport of a Kubernetes Service:

`k8s-(k8s service name)-(k8s service namespace)-(VPC-ID)-(protocol)-(protocol version)`

By default, the controller will create Lattice TargetGroup as follows

For Kubernetes Service as BackendRef:

`k8s-(k8s service name)-(k8s service namespace)-(protocol)-(protocol version)`

For ServiceExport of a Kubernetes Service:

`k8s-(k8s service name)-(k8s service namespace)-(protocol)-(protocol version)`


```
# for examples/inventory-route.yaml
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: inventory
spec:
parentRefs:
- name: my-hotel
sectionName: http
rules:
- backendRefs:
- name: inventory-ver1
kind: Service
port: 8090
weight: 10
# by default, lattice target group name
k8s-inventory-ver1-default
# when TARGET_GROUP_NAME_LEN_MODE = "long", lattice target group name, e.g.
k8s-inventory-ver1-default-inventory-vpc-05c7322a3df3f255a
```

```
# for examples/parking-ver2-export.yaml
apiVersion: application-networking.k8s.aws/v1alpha1
kind: ServiceExport
metadata:
name: parking-ver2
annotations:
application-networking.k8s.aws/federation: "amazon-vpc-lattice"
# by default, lattice target group name is
k8s-parking-ver2-default
# when TARGET_GROUP_NAME_LEN_MODE = "long", lattice target group name, e.g.
k8s-parking-ver2-default-vpc-05c7322a3df3f255a
```
When set as "true", the controller will run in "single service network" mode that will override all gateways
to point to default service network, instead of searching for service network with the same name.
Can be used for small setups and conformance tests.
5 changes: 1 addition & 4 deletions docs/conformance-test.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,9 @@
### Running controller from cloud desktop

```
# create a gateway first in the cluster
kubectl apply -f examples/my-hotel-gateway.yaml
# run controller in following mode
REGION=us-west-2 CLUSTER_LOCAL_GATEWAY=my-hotel TARGET_GROUP_NAME_LEN_MODE="long" \
REGION=us-west-2 DEFAULT_SERVICE_NETWORK=my-cluster-default ENABLE_SERVICE_NETWORK_OVERRIDE=true \
make run
```

Expand Down
5 changes: 2 additions & 3 deletions docs/developer.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ And use "EnvFile" GoLand plugin to read the env variables from the generated `.e
## End-to-End Testing

For larger changes it's recommended to run e2e suites on your local cluster.
E2E tests require a service network named `test-gateway` with cluster VPC associated to run.
You can either setup service network manually or use DEFAULT_SERVICE_NETWORK option when running controller locally. (e.g. `DEFAULT_SERVICE_NETWORK=test-gateway make run`)

```
REGION=us-west-2 make e2e-test
Expand Down Expand Up @@ -155,9 +157,6 @@ For larger, functional changes, run e2e tests:
make e2e-test
```
It is recommended to run `make e2e-test` in both environments where `DNSEndpoint` CRD exists and does not exist,
as the controller is designed to support both use cases.
## Make Docker Image
```
Expand Down
5 changes: 5 additions & 0 deletions pkg/aws/services/vpclattice.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/hashicorp/golang-lru/v2/expirable"

"github.com/aws/aws-application-networking-k8s/pkg/config"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/arn"
"github.com/aws/aws-sdk-go/aws/request"
Expand Down Expand Up @@ -310,6 +311,10 @@ func (d *defaultLattice) ListServiceNetworkServiceAssociationsAsList(ctx context
}

func (d *defaultLattice) FindServiceNetwork(ctx context.Context, name string, optionalAccountId string) (*ServiceNetworkInfo, error) {
// When default service network is provided, override for any kind of SN search
if config.ServiceNetworkOverrideMode {
name = config.DefaultServiceNetwork
}
input := vpclattice.ListServiceNetworksInput{}

var innerErr error
Expand Down
30 changes: 15 additions & 15 deletions pkg/config/controller_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,21 @@ import (
"github.com/aws/aws-sdk-go/aws/ec2metadata"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ec2"
"strings"
)

const (
LatticeGatewayControllerName = "application-networking.k8s.aws/gateway-api-controller"
defaultLogLevel = "Info"
UnknownInput = ""
)

const (
NO_DEFAULT_SERVICE_NETWORK = "NO_DEFAULT_SERVICE_NETWORK"
REGION = "REGION"
CLUSTER_VPC_ID = "CLUSTER_VPC_ID"
CLUSTER_NAME = "CLUSTER_NAME"
CLUSTER_LOCAL_GATEWAY = "CLUSTER_LOCAL_GATEWAY"
AWS_ACCOUNT_ID = "AWS_ACCOUNT_ID"
REGION = "REGION"
CLUSTER_VPC_ID = "CLUSTER_VPC_ID"
CLUSTER_NAME = "CLUSTER_NAME"
DEFAULT_SERVICE_NETWORK = "DEFAULT_SERVICE_NETWORK"
ENABLE_SERVICE_NETWORK_OVERRIDE = "ENABLE_SERVICE_NETWORK_OVERRIDE"
AWS_ACCOUNT_ID = "AWS_ACCOUNT_ID"
)

var VpcID = ""
Expand All @@ -33,12 +33,7 @@ var logLevel = defaultLogLevel
var DefaultServiceNetwork = ""
var ClusterName = ""

func GetClusterLocalGateway() (string, error) {
if DefaultServiceNetwork == UnknownInput {
return UnknownInput, errors.New(NO_DEFAULT_SERVICE_NETWORK)
}
return DefaultServiceNetwork, nil
}
var ServiceNetworkOverrideMode = false

func ConfigInit() error {
sess, _ := session.NewSession()
Expand Down Expand Up @@ -76,8 +71,13 @@ func configInit(sess *session.Session, metadata EC2Metadata) error {
}
}

// CLUSTER_LOCAL_GATEWAY
DefaultServiceNetwork = os.Getenv(CLUSTER_LOCAL_GATEWAY)
// DEFAULT_SERVICE_NETWORK
DefaultServiceNetwork = os.Getenv(DEFAULT_SERVICE_NETWORK)

overrideFlag := os.Getenv(ENABLE_SERVICE_NETWORK_OVERRIDE)
if strings.ToLower(overrideFlag) == "true" && DefaultServiceNetwork != "" {
ServiceNetworkOverrideMode = true
}

// CLUSTER_NAME
ClusterName, err = getClusterName(sess)
Expand Down
6 changes: 3 additions & 3 deletions pkg/config/controller_config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func Test_config_init_with_partial_env_var(t *testing.T) {

os.Setenv(REGION, testRegion)
os.Setenv(CLUSTER_VPC_ID, testClusterVpcId)
os.Setenv(CLUSTER_LOCAL_GATEWAY, testClusterLocalGateway)
os.Setenv(DEFAULT_SERVICE_NETWORK, testClusterLocalGateway)
os.Unsetenv(AWS_ACCOUNT_ID)
err := configInit(nil, ec2MetadataUnavailable())
assert.NotNil(t, err)
Expand All @@ -44,7 +44,7 @@ func Test_config_init_with_partial_env_var(t *testing.T) {
func Test_config_init_no_env_var(t *testing.T) {
os.Unsetenv(REGION)
os.Unsetenv(CLUSTER_VPC_ID)
os.Unsetenv(CLUSTER_LOCAL_GATEWAY)
os.Unsetenv(DEFAULT_SERVICE_NETWORK)
os.Unsetenv(AWS_ACCOUNT_ID)
err := configInit(nil, ec2MetadataUnavailable())
assert.NotNil(t, err)
Expand All @@ -61,7 +61,7 @@ func Test_config_init_with_all_env_var(t *testing.T) {

os.Setenv(REGION, testRegion)
os.Setenv(CLUSTER_VPC_ID, testClusterVpcId)
os.Setenv(CLUSTER_LOCAL_GATEWAY, testClusterLocalGateway)
os.Setenv(DEFAULT_SERVICE_NETWORK, testClusterLocalGateway)
os.Setenv(AWS_ACCOUNT_ID, testAwsAccountId)
os.Setenv(CLUSTER_NAME, testClusterName)
configInit(nil, ec2MetadataUnavailable())
Expand Down
Loading

0 comments on commit 37f548a

Please sign in to comment.