Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ make run

# or run it in debug mode
GATEWAY_API_CONTROLLER_LOGLEVEL=debug make run

# to run it against specific lattice service endpoint
LATTICE_ENDPOINT=https://mercury-gamma.us-west-2.amazonaws.com/ make run
```

## End-to-End Testing
Expand Down
11 changes: 9 additions & 2 deletions controllers/httproute_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,13 @@ func (r *HTTPRouteReconciler) updateHTTPRouteStatus(ctx context.Context, dns str
httproute.Status.RouteStatus.Parents[0].Conditions = make([]metav1.Condition, 1)
httproute.Status.RouteStatus.Parents[0].Conditions[0].LastTransitionTime = eventhandlers.ZeroTransitionTime
}

if len(httproute.ObjectMeta.Annotations) == 0 {
httproute.ObjectMeta.Annotations = make(map[string]string)
}

httproute.ObjectMeta.Annotations["application-networking.k8s.aws/lattice-assigned-domain-name"] = dns

httproute.Status.RouteStatus.Parents[0].ControllerName = config.LatticeGatewayControllerName

httproute.Status.RouteStatus.Parents[0].Conditions[0].Type = "httproute"
Expand All @@ -290,8 +297,8 @@ func (r *HTTPRouteReconciler) updateHTTPRouteStatus(ctx context.Context, dns str
httproute.Status.RouteStatus.Parents[0].ParentRef.Kind = httproute.Spec.ParentRefs[0].Kind
httproute.Status.RouteStatus.Parents[0].ParentRef.Name = httproute.Spec.ParentRefs[0].Name

if err := r.Client.Status().Patch(ctx, httproute, client.MergeFrom(httprouteOld)); err != nil {
glog.V(6).Infof("updateHTTPRouteStatus: Patch() received err %v \n", err)
if err := r.Client.Patch(ctx, httproute, client.MergeFrom(httprouteOld)); err != nil {
glog.V(2).Infof("updateHTTPRouteStatus: Patch() received err %v \n", err)
return errors.Wrapf(err, "failed to update httproute status")
}

Expand Down
33 changes: 33 additions & 0 deletions docs/customer_domain_name.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Configure a Custom Domain Name for HTTPRoute
Today when you create a HTTPRoute using `amazon-vpc-lattice` gatewayclass, Lattice gateway-api-controller creates a AWS VPC Lattice Service during reconciliation. And VPC Lattice generates a unique Fully Qualified Domain Name (FQDN). However, this VPC Lattice generated domain name is not easy for customers to remember and use.

If you'd prefer to use a custom domain name for a HTTPRoute, you can specify them in hostname field of HTTPRoute. Here is one example

```
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: HTTPRoute
metadata:
name: review
spec:
hostnames:
- review.my-test.com <----------- this is the custom domain name
parentRefs:
- name: my-hotel
sectionName: http
rules:
- backendRefs:
- name: review2
kind: Service
port: 8090
matches:
- path:
type: PathPrefix
value: /review2

```

## Notes

* You MUST have a registered domain name (e.g. `my-test.com`) in route53 and complete the `Prerequisites` mentioned in [TODO - public BYOC doc](http://dev-dsk-tnmat-1d-8836d755.us-east-1.amazon.com/mercury/build/AWSMercuryDocs/AWSMercuryDocs-3.0/AL2_x86_64/DEV.STD.PTHREAD/build/server-root/vpc-lattice/latest/ug/service-custom-domain-name.html#dns-associate-custom)

* In addition, you NEED to manually associate your custom domain name with your service following [TODO - public BYOC doc](http://dev-dsk-tnmat-1d-8836d755.us-east-1.amazon.com/mercury/build/AWSMercuryDocs/AWSMercuryDocs-3.0/AL2_x86_64/DEV.STD.PTHREAD/build/server-root/vpc-lattice/latest/ug/service-custom-domain-name.html#dns-associate-custom). We do have [github issue](https://github.com/aws/aws-application-networking-k8s/issues/88), an enhancement request, to automate this process
113 changes: 113 additions & 0 deletions docs/https_byoc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# HTTPS and Bring Your Own Certificte (BYOC)
## Securing Traffic using HTTPS

Today, the HTTPRoute owner can specify all incoming traffic `MUST` use HTTPs. e.g.

```
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: Gateway
metadata:
name: my-hotel
spec:
gatewayClassName: amazon-vpc-lattice
listeners:
- name: http
protocol: HTTP
port: 80
- name: https <-------------- specify HTTPs listener
protocol: HTTPS
port: 443
```

```
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: HTTPRoute
metadata:
name: rates
spec:
parentRefs:
- name: my-hotel
sectionName: http
- name: my-hotel
sectionName: https <--- specify all traffic MUST use HTTPs
rules:
- backendRefs:
- name: parking
kind: Service
port: 8090
matches:
- path:
type: PathPrefix
value: /parking
- backendRefs:
- name: review
kind: Service
port: 8090
matches:
- path:
type: PathPrefix
value: /review
```

In this case, VPC Lattice service will automatically generate a managed ACM certificate and use it for encryting client to service traffic.

## Bring Your Own Certificate (BYOC)

If customer desires to use custom domain name along with their own certificate, they can do following:
* follow [TODO Bring Your Own Certicate DOC](http://dev-dsk-tnmat-1d-8836d755.us-east-1.amazon.com/mercury/build/AWSMercuryDocs/AWSMercuryDocs-3.0/AL2_x86_64/DEV.STD.PTHREAD/build/server-root/vpc-lattice/latest/ug/service-byoc.html), and get ACM certificate ARN
* specify certificate ARN

```
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: Gateway
metadata:
name: my-hotel
spec:
gatewayClassName: amazon-vpc-lattice
listeners:
- name: http
protocol: HTTP
port: 80
- name: https
protocol: HTTPS
port: 443
- name: rates-with-custom-cert
protocol: HTTPS
port: 443
tls:
mode: Terminate
options:
application-networking.k8s.aws/certificate-arn: arn:aws:acm:us-west-2:<account>:certificate/4555204d-07e1-43f0-a533-d02750f41545
```

* associate HTTPRoute to this

```
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: HTTPRoute
metadata:
name: rates
spec:
parentRefs:
- name: my-hotel
sectionName: http
- name: my-hotel
sectionName: rates-with-custom-cert <-----using custom defined certification
rules:
- backendRefs:
- name: parking
kind: Service
port: 8090
matches:
- path:
type: PathPrefix
value: /parking
- backendRefs:
- name: review
kind: Service
port: 8090
matches:
- path:
type: PathPrefix
value: /review
```
19 changes: 19 additions & 0 deletions examples/http-route-use-vanity-name.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: HTTPRoute
metadata:
name: review
spec:
hostnames:
- review.my-test.com
parentRefs:
- name: my-hotel
sectionName: http
rules:
- backendRefs:
- name: review2
kind: Service
port: 8090
matches:
- path:
type: PathPrefix
value: /review2
20 changes: 20 additions & 0 deletions examples/my-hotel-gateway-tls.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: Gateway
metadata:
name: my-hotel
spec:
gatewayClassName: amazon-vpc-lattice
listeners:
- name: http
protocol: HTTP
port: 80
- name: https
protocol: HTTPS
port: 443
- name: tls-with-customer-cert
protocol: HTTPS
port: 443
tls:
mode: Terminate
options:
application-networking.k8s.aws/certificate-arn: arn:aws:acm:us-west-2:<account>:certificate/4555204d-07e1-43f0-a533-d02750f41545
19 changes: 19 additions & 0 deletions examples/tls-route-with-own-cert.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: HTTPRoute
metadata:
name: review
spec:
hostnames:
- review.my-test.com
parentRefs:
- name: my-hotel
sectionName: tls-with-customer-cert
rules:
- backendRefs:
- name: review1
kind: Service
port: 8090
matches:
- path:
type: PathPrefix
value: /review1
15 changes: 11 additions & 4 deletions pkg/aws/services/vpclattice.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package services

import (
"context"
"github.com/golang/glog"
"os"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
Expand Down Expand Up @@ -30,11 +32,16 @@ const (

func NewDefaultLattice(sess *session.Session, region string) *defaultLattice {
var latticeSess vpclatticeiface.VpcLatticeAPI
if region == "us-east-1" {
latticeSess = vpclattice.New(sess, aws.NewConfig().WithRegion("us-east-1").WithEndpoint("https://mercury-beta.us-east-1.amazonaws.com/"))
} else {
latticeSess = vpclattice.New(sess, aws.NewConfig().WithRegion("us-west-2").WithEndpoint(BetaProdEndpoint))
endpoint := os.Getenv("LATTICE_ENDPOINT")

if endpoint == "" {
endpoint = BetaProdEndpoint
}

latticeSess = vpclattice.New(sess, aws.NewConfig().WithRegion("us-west-2").WithEndpoint(endpoint))

glog.V(2).Infoln("Lattice Service EndPoint:", endpoint)

return &defaultLattice{VpcLatticeAPI: latticeSess}
}

Expand Down
24 changes: 24 additions & 0 deletions pkg/deploy/lattice/service_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,14 @@ func (s *defaultServiceManager) Create(ctx context.Context, service *latticemode
Name: &svcName,
Tags: nil,
}

if len(service.Spec.CustomerDomainName) > 0 {
serviceInput.CustomDomainName = &service.Spec.CustomerDomainName
}

if len(service.Spec.CustomerCertARN) > 0 {
serviceInput.SetCertificateArn(service.Spec.CustomerCertARN)
}
latticeSess := s.cloud.Lattice()
resp, err := latticeSess.CreateServiceWithContext(ctx, &serviceInput)
glog.V(2).Infof("CreateServiceWithContext >>>> req %v resp %v err %v\n", serviceInput, resp, err)
Expand All @@ -92,6 +100,22 @@ func (s *defaultServiceManager) Create(ctx context.Context, service *latticemode
if serviceSummary.DnsEntry != nil {
serviceDNS = aws.StringValue(serviceSummary.DnsEntry.DomainName)
}

if len(service.Spec.CustomerCertARN) > 0 {
serviceUpdateInput := vpclattice.UpdateServiceInput{
ServiceIdentifier: serviceSummary.Id,
CertificateArn: aws.String(service.Spec.CustomerCertARN),
}

latticeSess := s.cloud.Lattice()
resp, err := latticeSess.UpdateServiceWithContext(ctx, &serviceUpdateInput)
glog.V(2).Infof("UpdateServiceWithContext >>>> req %v resp %v err %v\n", serviceUpdateInput, resp, err)
if err != nil {
glog.V(6).Infoln("fail to update service")
return latticemodel.ServiceStatus{ServiceARN: "", ServiceID: ""}, err
}

}
isServiceAssociatedWithServiceNetwork, serviceDNS, err = s.isServiceAssociatedWithServiceNetwork(ctx, serviceID, serviceNetwork.ID)
if err != nil {
return latticemodel.ServiceStatus{ServiceARN: "", ServiceID: ""}, err
Expand Down
19 changes: 19 additions & 0 deletions pkg/gateway/model_build_lattice_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@ func (t *latticeServiceModelBuildTask) buildModel(ctx context.Context) error {
return err
}

if !t.httpRoute.DeletionTimestamp.IsZero() {
// in case of deleting HTTPRoute, we will let reconcile logic to delete
// stated target group(s) at next reconcile interval
glog.V(6).Infof("latticeServiceModuleBuildTask: for HTTPRouteDelete, reconcile tagetgroups/targets at reconcile interval")
return nil
}

_, err = t.buildTargetGroup(ctx, t.Client)

if err != nil {
Expand Down Expand Up @@ -118,6 +125,18 @@ func (t *latticeServiceModelBuildTask) buildLatticeService(ctx context.Context)
ServiceNetworkName: string(t.httpRoute.Spec.ParentRefs[0].Name),
}

if len(t.httpRoute.Spec.Hostnames) > 0 {
// The 1st hostname will be used as lattice customer-domain-name
spec.CustomerDomainName = string(t.httpRoute.Spec.Hostnames[0])

glog.V(2).Infof("Setting customer-domain-name: %v for httpRoute %v-%v",
spec.CustomerDomainName, t.httpRoute.Name, t.httpRoute.Namespace)
} else {
glog.V(2).Infof("No customter-domain-name for httproute :%v-%v",
t.httpRoute.Name, t.httpRoute.Namespace)
spec.CustomerDomainName = ""
}

if t.httpRoute.DeletionTimestamp.IsZero() {
spec.IsDeleted = false
} else {
Expand Down
32 changes: 32 additions & 0 deletions pkg/gateway/model_build_lattice_service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,32 @@ func Test_LatticeServiceModelBuild(t *testing.T) {
wantName string
wantIsDeleted bool
}{
{
name: "Add LatticeService with hostname",
httpRoute: &v1alpha2.HTTPRoute{
ObjectMeta: metav1.ObjectMeta{
Name: "service1",
},
Spec: v1alpha2.HTTPRouteSpec{
CommonRouteSpec: v1alpha2.CommonRouteSpec{
ParentRefs: []v1alpha2.ParentRef{
{
Name: "gateway1",
},
},
},
Hostnames: []v1alpha2.Hostname{
"test1.test.com",
"test2.test.com",
},
},
},

wantError: nil,
wantName: "service1",
wantIsDeleted: false,
wantErrIsNil: true,
},
{
name: "Add LatticeService",
httpRoute: &v1alpha2.HTTPRoute{
Expand Down Expand Up @@ -159,6 +185,12 @@ func Test_LatticeServiceModelBuild(t *testing.T) {
assert.Equal(t, false, task.latticeService.Spec.IsDeleted)
assert.Equal(t, tt.httpRoute.Name, task.latticeService.Spec.Name)
assert.Equal(t, tt.httpRoute.Namespace, task.latticeService.Spec.Namespace)

if len(tt.httpRoute.Spec.Hostnames) > 0 {
assert.Equal(t, string(tt.httpRoute.Spec.Hostnames[0]), task.latticeService.Spec.CustomerDomainName)
} else {
assert.Equal(t, "", task.latticeService.Spec.CustomerDomainName)
}
}

if tt.wantErrIsNil {
Expand Down
Loading