From a8de3989b37168639bae57262e05367c6e084bb0 Mon Sep 17 00:00:00 2001 From: Kiran Meduri Date: Tue, 18 Jun 2019 14:58:31 -0700 Subject: [PATCH] Added listeners to virtual-router under VirtualService CRD --- deploy/all.yaml | 17 ++++ examples/{color.yaml => color.yaml.template} | 94 ++++++++++--------- go.mod | 2 +- go.sum | 6 +- pkg/apis/appmesh/v1beta1/types.go | 8 +- .../appmesh/v1beta1/zz_generated.deepcopy.go | 7 +- pkg/aws/appmesh.go | 20 +++- pkg/client/clientset/versioned/clientset.go | 8 -- .../versioned/fake/clientset_generated.go | 5 - pkg/controller/virtualservice.go | 20 ++-- scripts/example.sh | 30 +++++- scripts/update-codegen.sh | 7 +- 12 files changed, 146 insertions(+), 78 deletions(-) rename examples/{color.yaml => color.yaml.template} (75%) diff --git a/deploy/all.yaml b/deploy/all.yaml index fcd2669c..cc1456d9 100644 --- a/deploy/all.yaml +++ b/deploy/all.yaml @@ -209,6 +209,23 @@ spec: properties: name: type: string + listeners: + type: array + items: + type: object + properties: + portMapping: + properties: + port: + type: integer + protocol: + type: string + enum: + - tcp + - http + - grpc + - http2 + - https routes: type: array items: diff --git a/examples/color.yaml b/examples/color.yaml.template similarity index 75% rename from examples/color.yaml rename to examples/color.yaml.template index 787bc538..03d8c65f 100644 --- a/examples/color.yaml +++ b/examples/color.yaml.template @@ -4,98 +4,103 @@ kind: Namespace metadata: labels: appmesh.k8s.aws/sidecarInjectorWebhook: enabled - name: appmesh-demo + name: ${APP_NAMESPACE} --- apiVersion: appmesh.k8s.aws/v1beta1 kind: Mesh metadata: - name: color-mesh + name: ${MESH_NAME} --- apiVersion: appmesh.k8s.aws/v1beta1 kind: VirtualNode metadata: name: colorgateway - namespace: appmesh-demo + namespace: ${APP_NAMESPACE} spec: - meshName: color-mesh + meshName: ${MESH_NAME} listeners: - portMapping: port: 9080 protocol: http serviceDiscovery: dns: - hostName: colorgateway.appmesh-demo.svc.cluster.local + hostName: colorgateway.${APP_NAMESPACE}.svc.cluster.local backends: - virtualService: - virtualServiceName: colorteller.appmesh-demo + virtualServiceName: colorteller.${APP_NAMESPACE} --- apiVersion: appmesh.k8s.aws/v1beta1 kind: VirtualNode metadata: name: colorteller - namespace: appmesh-demo + namespace: ${APP_NAMESPACE} spec: - meshName: color-mesh + meshName: ${MESH_NAME} listeners: - portMapping: port: 9080 protocol: http serviceDiscovery: dns: - hostName: colorteller.appmesh-demo.svc.cluster.local + hostName: colorteller.${APP_NAMESPACE}.svc.cluster.local --- apiVersion: appmesh.k8s.aws/v1beta1 kind: VirtualNode metadata: name: colorteller-black - namespace: appmesh-demo + namespace: ${APP_NAMESPACE} spec: - meshName: color-mesh + meshName: ${MESH_NAME} listeners: - portMapping: port: 9080 protocol: http serviceDiscovery: dns: - hostName: colorteller-black.appmesh-demo.svc.cluster.local + hostName: colorteller-black.${APP_NAMESPACE}.svc.cluster.local --- apiVersion: appmesh.k8s.aws/v1beta1 kind: VirtualNode metadata: name: colorteller-blue - namespace: appmesh-demo + namespace: ${APP_NAMESPACE} spec: - meshName: color-mesh + meshName: ${MESH_NAME} listeners: - portMapping: port: 9080 protocol: http serviceDiscovery: dns: - hostName: colorteller-blue.appmesh-demo.svc.cluster.local + hostName: colorteller-blue.${APP_NAMESPACE}.svc.cluster.local --- apiVersion: appmesh.k8s.aws/v1beta1 kind: VirtualNode metadata: name: colorteller-red - namespace: appmesh-demo + namespace: ${APP_NAMESPACE} spec: - meshName: color-mesh + meshName: ${MESH_NAME} listeners: - portMapping: port: 9080 protocol: http serviceDiscovery: dns: - hostName: colorteller-red.appmesh-demo.svc.cluster.local + hostName: colorteller-red.${APP_NAMESPACE}.svc.cluster.local --- apiVersion: appmesh.k8s.aws/v1beta1 kind: VirtualService metadata: - name: colorteller.appmesh-demo - namespace: appmesh-demo + name: colorteller.${APP_NAMESPACE} + namespace: ${APP_NAMESPACE} spec: - meshName: color-mesh + meshName: ${MESH_NAME} + virtualRouter: + listeners: + - portMapping: + port: 9080 + protocol: http routes: - name: color-route http: @@ -103,20 +108,25 @@ spec: prefix: / action: weightedTargets: - - virtualNodeName: colorteller.appmesh-demo + - virtualNodeName: colorteller weight: 1 - virtualNodeName: colorteller-blue weight: 1 - - virtualNodeName: colorteller-black.appmesh-demo + - virtualNodeName: colorteller-black weight: 1 --- apiVersion: appmesh.k8s.aws/v1beta1 kind: VirtualService metadata: - name: colorgateway.appmesh-demo - namespace: appmesh-demo + name: colorgateway.${APP_NAMESPACE} + namespace: ${APP_NAMESPACE} spec: - meshName: color-mesh + meshName: ${MESH_NAME} + virtualRouter: + listeners: + - portMapping: + port: 9080 + protocol: http routes: - name: color-route http: @@ -131,7 +141,7 @@ apiVersion: v1 kind: Service metadata: name: colorgateway - namespace: appmesh-demo + namespace: ${APP_NAMESPACE} labels: app: colorgateway spec: @@ -145,7 +155,7 @@ apiVersion: apps/v1 kind: Deployment metadata: name: colorgateway - namespace: appmesh-demo + namespace: ${APP_NAMESPACE} spec: replicas: 1 selector: @@ -160,20 +170,20 @@ spec: spec: containers: - name: colorgateway - image: "970805265562.dkr.ecr.us-west-2.amazonaws.com/gateway:latest" + image: ${COLOR_GATEWAY_IMAGE} ports: - containerPort: 9080 env: - name: "SERVER_PORT" value: "9080" - name: "COLOR_TELLER_ENDPOINT" - value: "colorteller.appmesh-demo:9080" + value: "colorteller.${APP_NAMESPACE}:9080" --- apiVersion: v1 kind: Service metadata: name: colorteller - namespace: appmesh-demo + namespace: ${APP_NAMESPACE} labels: app: colorteller spec: @@ -190,7 +200,7 @@ apiVersion: apps/v1 kind: Deployment metadata: name: colorteller - namespace: appmesh-demo + namespace: ${APP_NAMESPACE} spec: replicas: 1 selector: @@ -205,7 +215,7 @@ spec: spec: containers: - name: colorteller - image: 970805265562.dkr.ecr.us-west-2.amazonaws.com/colorteller:latest + image: ${COLOR_TELLER_IMAGE} ports: - containerPort: 9080 env: @@ -219,7 +229,7 @@ apiVersion: v1 kind: Service metadata: name: colorteller-black - namespace: appmesh-demo + namespace: ${APP_NAMESPACE} labels: app: colorteller version: black @@ -235,7 +245,7 @@ apiVersion: apps/v1 kind: Deployment metadata: name: colorteller-black - namespace: appmesh-demo + namespace: ${APP_NAMESPACE} spec: replicas: 1 selector: @@ -250,7 +260,7 @@ spec: spec: containers: - name: colorteller - image: 970805265562.dkr.ecr.us-west-2.amazonaws.com/colorteller:latest + image: ${COLOR_TELLER_IMAGE} ports: - containerPort: 9080 env: @@ -264,7 +274,7 @@ apiVersion: v1 kind: Service metadata: name: colorteller-blue - namespace: appmesh-demo + namespace: ${APP_NAMESPACE} labels: app: colorteller version: blue @@ -280,7 +290,7 @@ apiVersion: apps/v1 kind: Deployment metadata: name: colorteller-blue - namespace: appmesh-demo + namespace: ${APP_NAMESPACE} spec: replicas: 1 selector: @@ -295,7 +305,7 @@ spec: spec: containers: - name: colorteller - image: 970805265562.dkr.ecr.us-west-2.amazonaws.com/colorteller:latest + image: ${COLOR_TELLER_IMAGE} ports: - containerPort: 9080 env: @@ -309,7 +319,7 @@ apiVersion: v1 kind: Service metadata: name: colorteller-red - namespace: appmesh-demo + namespace: ${APP_NAMESPACE} labels: app: colorteller version: red @@ -325,7 +335,7 @@ apiVersion: apps/v1 kind: Deployment metadata: name: colorteller-red - namespace: appmesh-demo + namespace: ${APP_NAMESPACE} spec: replicas: 1 selector: @@ -340,7 +350,7 @@ spec: spec: containers: - name: colorteller - image: 970805265562.dkr.ecr.us-west-2.amazonaws.com/colorteller:latest + image: ${COLOR_TELLER_IMAGE} ports: - containerPort: 9080 env: diff --git a/go.mod b/go.mod index 73d83628..42e7a9f2 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,7 @@ module github.com/aws/aws-app-mesh-controller-for-k8s require ( github.com/BurntSushi/toml v0.3.1 // indirect - github.com/aws/aws-sdk-go v1.19.0 + github.com/aws/aws-sdk-go v1.20.3 github.com/deckarep/golang-set v1.7.1 github.com/ghodss/yaml v1.0.0 // indirect github.com/gogo/protobuf v1.2.1 // indirect diff --git a/go.sum b/go.sum index 9bed7359..30e9b2df 100644 --- a/go.sum +++ b/go.sum @@ -2,10 +2,8 @@ cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/aws/aws-sdk-go v1.17.13 h1:MJZwZoDI/UGp/6l0+cfZOQlWCqKmrHTuewhxfd5uQeE= -github.com/aws/aws-sdk-go v1.17.13/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.19.0 h1:3d9Htr/dl/+8xJYx/fpjEifvfpabZB1YUu61i/WX87Q= -github.com/aws/aws-sdk-go v1.19.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.20.3 h1:iQLxGfR0yh7g5M8Xg7wOGyhQ4hoZb/zA0XQNOGPdlpY= +github.com/aws/aws-sdk-go v1.20.3/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= diff --git a/pkg/apis/appmesh/v1beta1/types.go b/pkg/apis/appmesh/v1beta1/types.go index 22eb33e9..b6a6e5d0 100644 --- a/pkg/apis/appmesh/v1beta1/types.go +++ b/pkg/apis/appmesh/v1beta1/types.go @@ -41,8 +41,8 @@ type MeshSpec struct { type MeshStatus struct { // MeshArn is the AppMesh Mesh object's Amazon Resource Name // +optional - MeshArn *string `json:"meshArn,omitempty"` - Conditions []MeshCondition `json:"meshCondition"` + MeshArn *string `json:"meshArn,omitempty"` + Conditions []MeshCondition `json:"meshCondition"` } type MeshConditionType string @@ -102,8 +102,10 @@ type VirtualServiceSpec struct { Routes []Route `json:"routes,omitempty"` } +// VirtualRouter is the spec for a VirtualRouter resource type VirtualRouter struct { - Name string `json:"name"` + Name string `json:"name"` + Listeners []Listener `json:"listeners,omitempty"` } type Route struct { diff --git a/pkg/apis/appmesh/v1beta1/zz_generated.deepcopy.go b/pkg/apis/appmesh/v1beta1/zz_generated.deepcopy.go index a19fd31d..9d53822f 100644 --- a/pkg/apis/appmesh/v1beta1/zz_generated.deepcopy.go +++ b/pkg/apis/appmesh/v1beta1/zz_generated.deepcopy.go @@ -510,6 +510,11 @@ func (in *VirtualNodeStatus) DeepCopy() *VirtualNodeStatus { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *VirtualRouter) DeepCopyInto(out *VirtualRouter) { *out = *in + if in.Listeners != nil { + in, out := &in.Listeners, &out.Listeners + *out = make([]Listener, len(*in)) + copy(*out, *in) + } return } @@ -636,7 +641,7 @@ func (in *VirtualServiceSpec) DeepCopyInto(out *VirtualServiceSpec) { if in.VirtualRouter != nil { in, out := &in.VirtualRouter, &out.VirtualRouter *out = new(VirtualRouter) - **out = **in + (*in).DeepCopyInto(*out) } if in.Routes != nil { in, out := &in.Routes, &out.Routes diff --git a/pkg/aws/appmesh.go b/pkg/aws/appmesh.go index 80629f11..386411c0 100644 --- a/pkg/aws/appmesh.go +++ b/pkg/aws/appmesh.go @@ -107,6 +107,7 @@ func (c *Cloud) CreateMesh(ctx context.Context, mesh *appmeshv1beta1.Mesh) (*Mes } } +// DeleteMesh deletes the given mesh func (c *Cloud) DeleteMesh(ctx context.Context, name string) (*Mesh, error) { ctx, cancel := context.WithTimeout(ctx, time.Second*DeleteMeshTimeout) defer cancel() @@ -198,7 +199,7 @@ func (v *VirtualNode) Backends() []appmeshv1beta1.Backend { return backends } -// Backends converts into a Set of Backends +// BackendsSet returns a set of Backends defined for virtual-node func (v *VirtualNode) BackendsSet() set.Set { backends := v.Backends() s := set.NewSet() @@ -208,7 +209,7 @@ func (v *VirtualNode) BackendsSet() set.Set { return s } -// CreateVirtualNode calls describe virtual node. +// GetVirtualNode calls describe virtual node. func (c *Cloud) GetVirtualNode(ctx context.Context, name string, meshName string) (*VirtualNode, error) { ctx, cancel := context.WithTimeout(ctx, time.Second*DescribeVirtualNodeTimeout) defer cancel() @@ -557,11 +558,24 @@ func (c *Cloud) CreateVirtualRouter(ctx context.Context, vrouter *appmeshv1beta1 ctx, cancel := context.WithTimeout(ctx, time.Second*CreateVirtualRouterTimeout) defer cancel() + listeners := []*appmesh.VirtualRouterListener{} + if vrouter.Listeners != nil { + for _, listener := range vrouter.Listeners { + listeners = append(listeners, &appmesh.VirtualRouterListener{ + PortMapping: &appmesh.PortMapping{ + Port: &listener.PortMapping.Port, + Protocol: aws.String(listener.PortMapping.Protocol), + }, + }) + } + } + + klog.Infof("Using %d vrouter listeners to build %d input listeners", len(vrouter.Listeners), len(listeners)) input := &appmesh.CreateVirtualRouterInput{ MeshName: aws.String(meshName), VirtualRouterName: aws.String(vrouter.Name), Spec: &appmesh.VirtualRouterSpec{ - Listeners: []*appmesh.VirtualRouterListener{}, + Listeners: listeners, }, } diff --git a/pkg/client/clientset/versioned/clientset.go b/pkg/client/clientset/versioned/clientset.go index 1249c099..c61fc5eb 100644 --- a/pkg/client/clientset/versioned/clientset.go +++ b/pkg/client/clientset/versioned/clientset.go @@ -24,8 +24,6 @@ import ( type Interface interface { Discovery() discovery.DiscoveryInterface AppmeshV1beta1() appmeshv1beta1.AppmeshV1beta1Interface - // Deprecated: please explicitly pick a version if possible. - Appmesh() appmeshv1beta1.AppmeshV1beta1Interface } // Clientset contains the clients for groups. Each group has exactly one @@ -40,12 +38,6 @@ func (c *Clientset) AppmeshV1beta1() appmeshv1beta1.AppmeshV1beta1Interface { return c.appmeshV1beta1 } -// Deprecated: Appmesh retrieves the default version of AppmeshClient. -// Please explicitly pick a version. -func (c *Clientset) Appmesh() appmeshv1beta1.AppmeshV1beta1Interface { - return c.appmeshV1beta1 -} - // Discovery retrieves the DiscoveryClient func (c *Clientset) Discovery() discovery.DiscoveryInterface { if c == nil { diff --git a/pkg/client/clientset/versioned/fake/clientset_generated.go b/pkg/client/clientset/versioned/fake/clientset_generated.go index a24f2275..5cca2e25 100644 --- a/pkg/client/clientset/versioned/fake/clientset_generated.go +++ b/pkg/client/clientset/versioned/fake/clientset_generated.go @@ -71,8 +71,3 @@ var _ clientset.Interface = &Clientset{} func (c *Clientset) AppmeshV1beta1() appmeshv1beta1.AppmeshV1beta1Interface { return &fakeappmeshv1beta1.FakeAppmeshV1beta1{Fake: &c.Fake} } - -// Appmesh retrieves the AppmeshV1beta1Client -func (c *Clientset) Appmesh() appmeshv1beta1.AppmeshV1beta1Interface { - return &fakeappmeshv1beta1.FakeAppmeshV1beta1{Fake: &c.Fake} -} diff --git a/pkg/controller/virtualservice.go b/pkg/controller/virtualservice.go index c05c92a1..656947b4 100644 --- a/pkg/controller/virtualservice.go +++ b/pkg/controller/virtualservice.go @@ -36,12 +36,15 @@ func (c *Controller) handleVService(key string) error { vservice := shared.DeepCopy() // Make copy for updates so we don't save namespaced resource names copy := shared.DeepCopy() - copy.Spec.VirtualRouter = getVirtualRouter(copy) // Namespace resource names for use against App Mesh API - vservice.Spec.VirtualRouter = &appmeshv1beta1.VirtualRouter{ - Name: getNamespacedVirtualRouterName(vservice), + if vservice.Spec.VirtualRouter == nil { + vservice.Spec.VirtualRouter = &appmeshv1beta1.VirtualRouter{ + Name: getNamespacedVirtualRouterName(vservice), + } + } else { + vservice.Spec.VirtualRouter.Name = getNamespacedVirtualRouterName(vservice) } for i := range vservice.Spec.Routes { @@ -251,11 +254,14 @@ func getVirtualRouter(vservice *appmeshv1beta1.VirtualService) *appmeshv1beta1.V } func getNamespacedVirtualRouterName(vservice *appmeshv1beta1.VirtualService) string { - + var name string if vservice.Spec.VirtualRouter != nil { - return namespacedResourceName(vservice.Spec.VirtualRouter.Name, vservice.Namespace) + name = strings.TrimSpace(vservice.Spec.VirtualRouter.Name) + } + if len(name) == 0 { + name = vservice.Name } - return namespacedResourceName(vservice.Name, vservice.Namespace) + return namespacedResourceName(name, vservice.Namespace) } func getRoutes(vservice *appmeshv1beta1.VirtualService) []appmeshv1beta1.Route { @@ -339,7 +345,7 @@ func routeNeedsUpdate(desired appmeshv1beta1.Route, target aws.Route) bool { if desired.Http.Action.WeightedTargets != nil { desiredSet := set.NewSet() for _, target := range desired.Http.Action.WeightedTargets { - desiredSet.Add(appmeshv1beta1.WeightedTarget{VirtualNodeName: target.VirtualNodeName, Weight:target.Weight}) + desiredSet.Add(appmeshv1beta1.WeightedTarget{VirtualNodeName: target.VirtualNodeName, Weight: target.Weight}) } currSet := target.WeightedTargetSet() if !desiredSet.Equal(currSet) { diff --git a/scripts/example.sh b/scripts/example.sh index 049084af..29a26b12 100755 --- a/scripts/example.sh +++ b/scripts/example.sh @@ -1,6 +1,34 @@ #!/bin/bash +set -e + +if [ -z "${AWS_ACCOUNT}" ]; then + echo "AWS_ACCOUNT must be set." + exit 1 +fi + +if [ -z "${AWS_REGION}" ]; then + echo "AWS_REGION must be set." + exit 1 +fi + +if [ -z "${MESH_NAME}" ]; then + echo "MESH_NAME must be set." + exit 1 +fi + +APP_NAMESPACE=${APP_NAMESPACE:-"appmesh-demo"} + DIR=$(cd "$(dirname "$0")"; pwd)/.. +EXAMPLES_OUT_DIR="${DIR}/_output/examples/" +mkdir -p ${EXAMPLES_OUT_DIR} + +COLOR_GATEWAY_IMAGE=${COLOR_GATEWAY_IMAGE:-"970805265562.dkr.ecr.us-west-2.amazonaws.com/gateway:latest"} +COLOR_TELLER_IMAGE=${COLOR_TELLER_IMAGE:-"970805265562.dkr.ecr.us-west-2.amazonaws.com/colorteller:latest"} -kubectl apply -f $DIR/examples/color.yaml +eval "cat < ${EXAMPLES_OUT_DIR}/color.yaml +kubectl apply -f ${EXAMPLES_OUT_DIR}/color.yaml \ No newline at end of file diff --git a/scripts/update-codegen.sh b/scripts/update-codegen.sh index 15be31a6..7d182362 100755 --- a/scripts/update-codegen.sh +++ b/scripts/update-codegen.sh @@ -4,8 +4,8 @@ set -o errexit set -o nounset set -o pipefail -SCRIPT_ROOT=$(dirname ${BASH_SOURCE})/.. -CODEGEN_PKG=${CODEGEN_PKG:-$(cd ${SCRIPT_ROOT}; ls -d -1 ./vendor/k8s.io/code-generator 2>/dev/null || echo ../code-generator)} +SCRIPT_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. +CODEGEN_PKG=${CODEGEN_PKG:-$(cd "${SCRIPT_ROOT}"; ls -d -1 ./vendor/k8s.io/code-generator 2>/dev/null || echo ../code-generator)} CLIENT_PKG=github.com/aws/aws-app-mesh-controller-for-k8s/pkg/client APIS_PKG=github.com/aws/aws-app-mesh-controller-for-k8s/pkg/apis @@ -13,4 +13,5 @@ ${CODEGEN_PKG}/generate-groups.sh all \ ${CLIENT_PKG} \ ${APIS_PKG} \ appmesh:v1beta1 \ - --go-header-file ${SCRIPT_ROOT}/hack/custom-boilerplate.go.txt + --output-base "${SCRIPT_ROOT}/../../.." \ + --go-header-file ${SCRIPT_ROOT}/scripts/custom-boilerplate.go.txt