├── img
└── readme
│ ├── slack-128.png
│ ├── slack-dark-128.png
│ ├── community.svg
│ ├── layer5-light-no-trim.svg
│ ├── layer5-no-trim.svg
│ └── meshery-logo-light-text.svg
├── smi-conformance
├── test-gen
│ ├── test-yamls
│ │ ├── traffic-spec
│ │ │ ├── 04-trafficPath.yaml
│ │ │ ├── 06-trafficMethod.yaml
│ │ │ ├── 01-assert.yaml
│ │ │ ├── 03-assert.yaml
│ │ │ ├── 03-install.yaml
│ │ │ ├── 05-assert.yaml
│ │ │ ├── 05-install.yaml
│ │ │ ├── Tests.md
│ │ │ ├── 02-assert.yaml
│ │ │ └── 02-install.yaml
│ │ ├── traffic-split
│ │ │ ├── 05-trafficOnlyB.yaml
│ │ │ ├── 07-trafficOnlyC.yaml
│ │ │ ├── 09-trafficBGrtC.yaml
│ │ │ ├── 11-trafficCGrtB.yaml
│ │ │ ├── 03-trafficDefault.yaml
│ │ │ ├── 04-assert.yaml
│ │ │ ├── 04-install.yaml
│ │ │ ├── 06-assert.yaml
│ │ │ ├── 06-install.yaml
│ │ │ ├── 08-assert.yaml
│ │ │ ├── 10-assert.yaml
│ │ │ ├── 08-install.yaml
│ │ │ ├── 10-install.yaml
│ │ │ ├── 01-assert.yaml
│ │ │ ├── Tests.md
│ │ │ ├── 02-assert.yaml
│ │ │ └── 02-install.yaml
│ │ └── traffic-access
│ │ │ ├── 03-trafficDefault.yaml
│ │ │ ├── 05-trafficAllowed.yaml
│ │ │ ├── 07-trafficBlocked.yaml
│ │ │ ├── 06-install.yaml
│ │ │ ├── 01-assert.yaml
│ │ │ ├── 04-assert.yaml
│ │ │ ├── 04-install.yaml
│ │ │ ├── 06-errors.yaml
│ │ │ ├── Tests.md
│ │ │ ├── 02-assert.yaml
│ │ │ └── 02-install.yaml
│ ├── utils.go
│ ├── test_gen.go
│ ├── service-mesh.go
│ ├── traffic-access.go
│ ├── traffic-spec.go
│ └── traffic-split.go
├── Makefile
├── main.go
├── .golangci.yml
├── Dockerfile
├── conformance
│ ├── client.go
│ ├── conformance.proto
│ └── conformance.pb.go
├── go.mod
├── manifest.yml
└── grpc
│ ├── grpc.go
│ └── handlers.go
├── charts
├── smi-conformance-0.1.0.tgz
└── smi-conformance
│ ├── Chart.yaml
│ ├── templates
│ ├── serviceaccount.yaml
│ ├── rolebinding.yaml
│ ├── service.yaml
│ ├── deployment.yaml
│ ├── NOTES.txt
│ └── _helpers.tpl
│ ├── values.yaml
│ └── .helmignore
├── service
├── go.mod
├── Dockerfile
├── go.sum
└── main.go
├── .github
├── welcome
│ └── Layer5-celebration.png
├── workflows
│ ├── release-drafter.yml
│ ├── slack.yml
│ ├── ci.yml
│ └── label-commenter-config.yml
├── ISSUE_TEMPLATE
│ ├── question.md
│ ├── documentation.md
│ ├── feature_request.md
│ └── bug_report.md
├── PULL_REQUEST_TEMPLATE.md
├── releasedrafter.yml
├── stale.yml
├── config.yml
└── label-commenter-config.yml
├── deploy
├── linkerd
│ ├── traffic.yaml
│ └── app.yaml
├── traffic-crd.yaml
├── k8s-maesh.yaml
├── k8s-consul.yaml
└── maesh.yaml
├── .gitignore
├── Makefile
├── CONTRIBUTING.md
├── README.md
└── LICENSE
/img/readme/slack-128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/layer5io/learn-layer5/HEAD/img/readme/slack-128.png
--------------------------------------------------------------------------------
/img/readme/slack-dark-128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/layer5io/learn-layer5/HEAD/img/readme/slack-dark-128.png
--------------------------------------------------------------------------------
/smi-conformance/test-gen/test-yamls/traffic-spec/04-trafficPath.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kudo.dev/v1alpha1
2 | kind: TestStep
--------------------------------------------------------------------------------
/smi-conformance/test-gen/test-yamls/traffic-spec/06-trafficMethod.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kudo.dev/v1alpha1
2 | kind: TestStep
--------------------------------------------------------------------------------
/smi-conformance/test-gen/test-yamls/traffic-split/05-trafficOnlyB.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kudo.dev/v1alpha1
2 | kind: TestStep
--------------------------------------------------------------------------------
/smi-conformance/test-gen/test-yamls/traffic-split/07-trafficOnlyC.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kudo.dev/v1alpha1
2 | kind: TestStep
--------------------------------------------------------------------------------
/smi-conformance/test-gen/test-yamls/traffic-split/09-trafficBGrtC.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kudo.dev/v1alpha1
2 | kind: TestStep
--------------------------------------------------------------------------------
/smi-conformance/test-gen/test-yamls/traffic-split/11-trafficCGrtB.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kudo.dev/v1alpha1
2 | kind: TestStep
--------------------------------------------------------------------------------
/charts/smi-conformance-0.1.0.tgz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/layer5io/learn-layer5/HEAD/charts/smi-conformance-0.1.0.tgz
--------------------------------------------------------------------------------
/smi-conformance/test-gen/test-yamls/traffic-access/03-trafficDefault.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kudo.dev/v1alpha1
2 | kind: TestStep
--------------------------------------------------------------------------------
/smi-conformance/test-gen/test-yamls/traffic-access/05-trafficAllowed.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kudo.dev/v1alpha1
2 | kind: TestStep
--------------------------------------------------------------------------------
/smi-conformance/test-gen/test-yamls/traffic-access/07-trafficBlocked.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kudo.dev/v1alpha1
2 | kind: TestStep
--------------------------------------------------------------------------------
/smi-conformance/test-gen/test-yamls/traffic-split/03-trafficDefault.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kudo.dev/v1alpha1
2 | kind: TestStep
--------------------------------------------------------------------------------
/service/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/layer5io/sample-app
2 |
3 | go 1.14
4 |
5 | require github.com/sirupsen/logrus v1.6.0
6 |
--------------------------------------------------------------------------------
/.github/welcome/Layer5-celebration.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/layer5io/learn-layer5/HEAD/.github/welcome/Layer5-celebration.png
--------------------------------------------------------------------------------
/smi-conformance/Makefile:
--------------------------------------------------------------------------------
1 | .PHONY: go-lint
2 | go-lint:
3 | go run github.com/golangci/golangci-lint/cmd/golangci-lint run --config .golangci.yml
--------------------------------------------------------------------------------
/charts/smi-conformance/Chart.yaml:
--------------------------------------------------------------------------------
1 | Name: smi-conformance
2 | description: A Helm chart to install the SMI conformance tool on Kubernetes
3 | version: 0.1.0
--------------------------------------------------------------------------------
/charts/smi-conformance/templates/serviceaccount.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: ServiceAccount
3 | metadata:
4 | name: {{ include "smi-conformance.serviceAccount" . }}
5 | namespace: {{ include "smi-conformance.namespace" . }}
--------------------------------------------------------------------------------
/deploy/linkerd/traffic.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: split.smi-spec.io/v1alpha1
2 | kind: TrafficSplit
3 | metadata:
4 | name: server-split
5 | namespace:
6 | spec:
7 | service: app-svc
8 | backends:
9 | - service: app-v1
10 | weight: 1
11 | - service: app-v2
12 | weight: 0
--------------------------------------------------------------------------------
/service/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM golang:1.13.7 as bd
2 | WORKDIR /github.com/layer5io/sample-app-service
3 | ADD . .
4 | RUN go build -a -o ./main .
5 |
6 | FROM golang:1.13.7
7 | COPY --from=bd /github.com/layer5io/sample-app-service/main /home/main
8 | WORKDIR /home/
9 | EXPOSE 9091
10 | CMD ["./main"]
--------------------------------------------------------------------------------
/smi-conformance/test-gen/test-yamls/traffic-split/04-assert.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: split.smi-spec.io/v1alpha4
2 | kind: TrafficSplit
3 | metadata:
4 | name: server-split
5 | namespace:
6 | spec:
7 | service: app-svc
8 | backends:
9 | - service: app-b
10 | weight: 1
11 | - service: app-c
12 | weight: 0
--------------------------------------------------------------------------------
/smi-conformance/test-gen/test-yamls/traffic-split/04-install.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: split.smi-spec.io/v1alpha4
2 | kind: TrafficSplit
3 | metadata:
4 | name: server-split
5 | namespace:
6 | spec:
7 | service: app-svc
8 | backends:
9 | - service: app-b
10 | weight: 1
11 | - service: app-c
12 | weight: 0
--------------------------------------------------------------------------------
/smi-conformance/test-gen/test-yamls/traffic-split/06-assert.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: split.smi-spec.io/v1alpha4
2 | kind: TrafficSplit
3 | metadata:
4 | name: server-split
5 | namespace:
6 | spec:
7 | service: app-svc
8 | backends:
9 | - service: app-b
10 | weight: 0
11 | - service: app-c
12 | weight: 1
--------------------------------------------------------------------------------
/smi-conformance/test-gen/test-yamls/traffic-split/06-install.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: split.smi-spec.io/v1alpha4
2 | kind: TrafficSplit
3 | metadata:
4 | name: server-split
5 | namespace:
6 | spec:
7 | service: app-svc
8 | backends:
9 | - service: app-b
10 | weight: 0
11 | - service: app-c
12 | weight: 1
--------------------------------------------------------------------------------
/smi-conformance/test-gen/test-yamls/traffic-split/08-assert.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: split.smi-spec.io/v1alpha4
2 | kind: TrafficSplit
3 | metadata:
4 | name: server-split
5 | namespace:
6 | spec:
7 | service: app-svc
8 | backends:
9 | - service: app-b
10 | weight: 75
11 | - service: app-c
12 | weight: 25
--------------------------------------------------------------------------------
/smi-conformance/test-gen/test-yamls/traffic-split/10-assert.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: split.smi-spec.io/v1alpha4
2 | kind: TrafficSplit
3 | metadata:
4 | name: server-split
5 | namespace:
6 | spec:
7 | service: app-svc
8 | backends:
9 | - service: app-b
10 | weight: 25
11 | - service: app-c
12 | weight: 75
--------------------------------------------------------------------------------
/smi-conformance/test-gen/test-yamls/traffic-split/08-install.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: split.smi-spec.io/v1alpha4
2 | kind: TrafficSplit
3 | metadata:
4 | name: server-split
5 | namespace:
6 | spec:
7 | service: app-svc
8 | backends:
9 | - service: app-b
10 | weight: 75
11 | - service: app-c
12 | weight: 25
--------------------------------------------------------------------------------
/smi-conformance/test-gen/test-yamls/traffic-split/10-install.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: split.smi-spec.io/v1alpha4
2 | kind: TrafficSplit
3 | metadata:
4 | name: server-split
5 | namespace:
6 | spec:
7 | service: app-svc
8 | backends:
9 | - service: app-b
10 | weight: 25
11 | - service: app-c
12 | weight: 75
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | service/main
2 | # Binaries for programs and plugins
3 | *.exe
4 | *.exe~
5 | *.dll
6 | *.so
7 | *.dylib
8 |
9 | # Test binary, built with `go test -c`
10 | *.test
11 |
12 | # Output of the go coverage tool, specifically when used with LiteIDE
13 | *.out
14 |
15 | # Dependency directories (remove the comment below to include it)
16 | # vendor/
17 |
--------------------------------------------------------------------------------
/smi-conformance/test-gen/test-yamls/traffic-access/06-install.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kudo.dev/v1alpha1
2 | kind: TestStep
3 | delete:
4 | - apiVersion: specs.smi-spec.io/v1alpha4
5 | kind: TCPRoute
6 | namespace:
7 | name: service-tcp-route
8 | - apiVersion: access.smi-spec.io/v1alpha3
9 | kind: TrafficTarget
10 | namespace:
11 | name: service-targets
--------------------------------------------------------------------------------
/smi-conformance/test-gen/test-yamls/traffic-access/01-assert.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: apiextensions.k8s.io/v1beta1
2 | kind: CustomResourceDefinition
3 | metadata:
4 | name: traffictargets.access.smi-spec.io
5 | spec:
6 | group: access.smi-spec.io
7 | status:
8 | acceptedNames:
9 | kind: TrafficTarget
10 | shortNames:
11 | - tt
12 | plural: traffictargets
13 | singular: traffictarget
--------------------------------------------------------------------------------
/smi-conformance/test-gen/test-yamls/traffic-spec/01-assert.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: apiextensions.k8s.io/v1beta1
2 | kind: CustomResourceDefinition
3 | metadata:
4 | name: httproutegroups.specs.smi-spec.io
5 | spec:
6 | group: specs.smi-spec.io
7 | status:
8 | acceptedNames:
9 | kind: HTTPRouteGroup
10 | shortNames:
11 | - htr
12 | plural: httproutegroups
13 | singular: httproutegroup
--------------------------------------------------------------------------------
/smi-conformance/test-gen/test-yamls/traffic-split/01-assert.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: apiextensions.k8s.io/v1beta1
2 | kind: CustomResourceDefinition
3 | metadata:
4 | name: trafficsplits.split.smi-spec.io
5 | spec:
6 | group: split.smi-spec.io
7 | status:
8 | acceptedNames:
9 | kind: TrafficSplit
10 | shortNames:
11 | - ts
12 | plural: trafficsplits
13 | singular: trafficsplit
14 |
--------------------------------------------------------------------------------
/charts/smi-conformance/values.yaml:
--------------------------------------------------------------------------------
1 | namespace: meshery
2 | serviceAccount: meshery
3 | labels:
4 | app: smi-conformance
5 | release: smi-conformance
6 | image:
7 | repository: layer5/learn-layer5
8 | tag: smi
9 | pullPolicy: Always
10 | port: 10011
11 | resources:
12 | limits:
13 | cpu: "500m"
14 | memory: 1000Mi
15 | requests:
16 | cpu: "200m"
17 | memory: 500Mi
18 | service:
19 | type: NodePort
20 | port: 10011
--------------------------------------------------------------------------------
/charts/smi-conformance/templates/rolebinding.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | apiVersion: rbac.authorization.k8s.io/v1
3 | kind: ClusterRoleBinding
4 | metadata:
5 | name: {{ include "smi-conformance.name" . }}
6 | namespace: meshery
7 | subjects:
8 | - kind: ServiceAccount
9 | name: {{ include "smi-conformance.serviceAccount" . }}
10 | namespace: {{ include "smi-conformance.namespace" . }}
11 | roleRef:
12 | kind: ClusterRole
13 | name: cluster-admin
14 | apiGroup: rbac.authorization.k8s.io
--------------------------------------------------------------------------------
/charts/smi-conformance/.helmignore:
--------------------------------------------------------------------------------
1 | # Patterns to ignore when building packages.
2 | # This supports shell glob matching, relative path matching, and
3 | # negation (prefixed with !). Only one pattern per line.
4 | .DS_Store
5 | # Common VCS dirs
6 | .git/
7 | .gitignore
8 | .bzr/
9 | .bzrignore
10 | .hg/
11 | .hgignore
12 | .svn/
13 | # Common backup files
14 | *.swp
15 | *.bak
16 | *.tmp
17 | *.orig
18 | *~
19 | # Various IDEs
20 | .project
21 | .idea/
22 | *.tmproj
23 | .vscode/
24 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | VER=$(shell git rev-parse --short HEAD)
2 |
3 | build-service:
4 | cd service && go build -a -o ./main .
5 |
6 | run-service-a:
7 | SERVICE_NAME="service-a" \
8 | PORT=9091 \
9 | ./service/main
10 |
11 | run-service-b:
12 | SERVICE_NAME="service-b" \
13 | PORT=9092 \
14 | ./service/main
15 |
16 | build-img-service:
17 | cd service && docker build -t layer5/learn-layer5:latest -t layer5/learn-layer5:$(VER) .
18 |
19 | image-push:
20 | docker push layer5/learn-layer5
21 |
--------------------------------------------------------------------------------
/.github/workflows/release-drafter.yml:
--------------------------------------------------------------------------------
1 | name: Release Drafter
2 |
3 | on:
4 | push:
5 | # our release branch
6 | branches:
7 | - master
8 |
9 | jobs:
10 | update_release_draft:
11 | runs-on: ubuntu-latest
12 | steps:
13 | # Drafts your next Release notes as Pull Requests are merged into "master"
14 | - uses: release-drafter/release-drafter@v5
15 | with:
16 | config-name: releasedrafter.yml
17 | env:
18 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
19 |
--------------------------------------------------------------------------------
/charts/smi-conformance/templates/service.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: {{ include "smi-conformance.name" . }}
5 | namespace: {{ include "smi-conformance.namespace" . }}
6 | labels:
7 | {{- include "smi-conformance.labels" . | nindent 4 }}
8 | spec:
9 | type: {{ .Values.service.type }}
10 | ports:
11 | - port: {{ .Values.service.port }}
12 | targetPort: grpc
13 | protocol: TCP
14 | name: {{ include "smi-conformance.name" . }}
15 | selector:
16 | {{- include "smi-conformance.labels" . | nindent 4 }}
17 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/question.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: General question
3 | about: Request information about the project; clarify behavior of the software
4 | title: '[Question]'
5 | labels: 'question'
6 | assignees: ''
7 | ---
8 |
9 | **How can we help?**
10 |
11 |
12 | **Contributor Resources**
13 | - 🎨 Wireframes and [designs for Layer5 site](https://www.figma.com/file/5ZwEkSJwUPitURD59YHMEN/Layer5-Designs) in Figma [(open invite)](https://www.figma.com/team_invite/redeem/qJy1c95qirjgWQODApilR9)
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | **Description**
2 |
3 | This PR fixes #
4 |
5 | **Notes for Reviewers**
6 |
7 |
8 | **[Signed commits](../CONTRIBUTING.md#signing-off-on-commits-developer-certificate-of-origin)**
9 | - [ ] Yes, I signed my commits.
10 |
11 |
12 |
--------------------------------------------------------------------------------
/smi-conformance/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "os"
5 | "time"
6 |
7 | "github.com/layer5io/learn-layer5/smi-conformance/grpc"
8 | "sigs.k8s.io/controller-runtime/pkg/log"
9 | )
10 |
11 | func main() {
12 | service := &grpc.Service{
13 | Name: "smi-conformance",
14 | Port: "10011",
15 | Version: "v1.0.0",
16 | StartedAt: time.Now(),
17 | }
18 | // Initialize Logger instance
19 | logger := log.Log.WithName(service.Name)
20 | logger.Info("Conformance tool Started")
21 | // Server Initialization
22 | err := grpc.Start(service)
23 | if err != nil {
24 | logger.Error(err, "Conformance tool crashed!!")
25 | os.Exit(1)
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/smi-conformance/test-gen/test-yamls/traffic-access/04-assert.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | apiVersion: specs.smi-spec.io/v1alpha4
3 | kind: TCPRoute
4 | metadata:
5 | name: service-tcp-route
6 | namespace:
7 | spec:
8 | matches:
9 | ports: []
10 | ---
11 | apiVersion: access.smi-spec.io/v1alpha3
12 | kind: TrafficTarget
13 | metadata:
14 | name: service-targets
15 | namespace:
16 | spec:
17 | destination:
18 | kind: ServiceAccount
19 | name: service-b
20 | namespace:
21 | sources:
22 | - kind: ServiceAccount
23 | name: service-a
24 | namespace:
25 | rules:
26 | - kind: TCPRoute
27 | name: service-tcp-route
28 |
--------------------------------------------------------------------------------
/smi-conformance/test-gen/test-yamls/traffic-access/04-install.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | apiVersion: specs.smi-spec.io/v1alpha4
3 | kind: TCPRoute
4 | metadata:
5 | name: service-tcp-route
6 | namespace:
7 | spec:
8 | matches:
9 | ports: []
10 | ---
11 | apiVersion: access.smi-spec.io/v1alpha3
12 | kind: TrafficTarget
13 | metadata:
14 | name: service-targets
15 | namespace:
16 | spec:
17 | destination:
18 | kind: ServiceAccount
19 | name: service-b
20 | namespace:
21 | sources:
22 | - kind: ServiceAccount
23 | name: service-a
24 | namespace:
25 | rules:
26 | - kind: TCPRoute
27 | name: service-tcp-route
28 |
--------------------------------------------------------------------------------
/smi-conformance/test-gen/test-yamls/traffic-access/06-errors.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | apiVersion: specs.smi-spec.io/v1alpha4
3 | kind: TCPRoute
4 | metadata:
5 | name: service-tcp-route
6 | namespace:
7 | spec:
8 | matches:
9 | ports: []
10 | ---
11 | apiVersion: access.smi-spec.io/v1alpha3
12 | kind: TrafficTarget
13 | metadata:
14 | name: service-targets
15 | namespace:
16 | spec:
17 | destination:
18 | kind: ServiceAccount
19 | name: service-b
20 | namespace:
21 | sources:
22 | - kind: ServiceAccount
23 | name: service-a
24 | namespace:
25 | rules:
26 | - kind: TCPRoute
27 | name: service-tcp-route
28 |
--------------------------------------------------------------------------------
/.github/releasedrafter.yml:
--------------------------------------------------------------------------------
1 | name-template: 'v$NEXT_PATCH_VERSION'
2 | tag-template: 'v$NEXT_PATCH_VERSION'
3 | categories:
4 | - title: '🚀 Features'
5 | labels:
6 | - 'kind/feature'
7 | - 'kind/enhancement'
8 | - title: '🐛 Bug Fixes'
9 | labels:
10 | - 'kind/fix'
11 | - 'kind/bugfix'
12 | - 'kind/bug'
13 | - title: '🧰 Maintenance'
14 | labels:
15 | - 'kind/chore'
16 | - 'area/ci'
17 | - 'area/tests'
18 | - title: 📖 Documentation
19 | label: area/docs
20 | change-template: '- $TITLE @$AUTHOR (#$NUMBER)'
21 | template: |
22 | ## What's New
23 | $CHANGES
24 |
25 | ## Contributors
26 |
27 | Thank you to our contributors for making this release possible:
28 | $CONTRIBUTORS
29 |
--------------------------------------------------------------------------------
/smi-conformance/test-gen/test-yamls/traffic-spec/03-assert.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: specs.smi-spec.io/v1alpha4
2 | kind: HTTPRouteGroup
3 | metadata:
4 | name: http-rg
5 | namespace:
6 | matches:
7 | - name: testMatch
8 | pathRegex: /metrics
9 | methods: ["*"]
10 | ---
11 | apiVersion: access.smi-spec.io/v1alpha3
12 | kind: TrafficTarget
13 | metadata:
14 | name: service-targets
15 | namespace:
16 | spec:
17 | destination:
18 | kind: ServiceAccount
19 | name: service-b
20 | namespace:
21 | port: "9091"
22 | sources:
23 | - kind: ServiceAccount
24 | name: service-a
25 | namespace:
26 | rules:
27 | - kind: HTTPRouteGroup
28 | name: http-rg
29 | matches:
30 | - testMatch
--------------------------------------------------------------------------------
/smi-conformance/test-gen/test-yamls/traffic-spec/03-install.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: specs.smi-spec.io/v1alpha4
2 | kind: HTTPRouteGroup
3 | metadata:
4 | name: http-rg
5 | namespace:
6 | matches:
7 | - name: testMatch
8 | pathRegex: /metrics
9 | methods: ["*"]
10 | ---
11 | apiVersion: access.smi-spec.io/v1alpha3
12 | kind: TrafficTarget
13 | metadata:
14 | name: service-targets
15 | namespace:
16 | spec:
17 | destination:
18 | kind: ServiceAccount
19 | name: service-b
20 | namespace:
21 | port: "9091"
22 | sources:
23 | - kind: ServiceAccount
24 | name: service-a
25 | namespace:
26 | rules:
27 | - kind: HTTPRouteGroup
28 | name: http-rg
29 | matches:
30 | - testMatch
--------------------------------------------------------------------------------
/smi-conformance/test-gen/test-yamls/traffic-access/Tests.md:
--------------------------------------------------------------------------------
1 | # Traffic Access
2 |
3 | Note that the following tests are executed sequentially in an temporarily spawned namespace.
4 |
5 | * *01* : Asserts if the TrafficTarget CRD exists.
6 | * *02* : Deploys the app and asserts if the app has been deployed
7 | * *03* : Custom test is run where we verify if by default all traffic is blocked.
8 | * *04* : Create and assert a TrafficTarget which allows traffic from `service-a` to `service-b`.
9 | * *05* : Custom test is run where we verify if traffic from `service-a` to `service-b` succeeds.
10 | * *06* : Deletes the CRDs created in step *04* and asserts its deletion.
11 | * *07* : Custom test to verify if the traffic from `service-a` to `service-b` fails as the CRD has been deleted.
--------------------------------------------------------------------------------
/service/go.sum:
--------------------------------------------------------------------------------
1 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
2 | github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
3 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
4 | github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I=
5 | github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
6 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
7 | golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc=
8 | golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
9 |
--------------------------------------------------------------------------------
/smi-conformance/test-gen/test-yamls/traffic-spec/05-assert.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: specs.smi-spec.io/v1alpha4
2 | kind: HTTPRouteGroup
3 | metadata:
4 | name: http-rg
5 | namespace:
6 | spec:
7 | matches:
8 | - name: testMatch
9 | pathRegex: ".*"
10 | methods:
11 | - GET
12 | ---
13 | apiVersion: access.smi-spec.io/v1alpha3
14 | kind: TrafficTarget
15 | metadata:
16 | name: service-targets
17 | namespace:
18 | spec:
19 | destination:
20 | kind: ServiceAccount
21 | name: service-b
22 | namespace:
23 | port: "9091"
24 | sources:
25 | - kind: ServiceAccount
26 | name: service-a
27 | namespace:
28 | rules:
29 | - kind: HTTPRouteGroup
30 | name: http-rg
31 | matches:
32 | - testMatch
--------------------------------------------------------------------------------
/smi-conformance/test-gen/test-yamls/traffic-spec/05-install.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: specs.smi-spec.io/v1alpha4
2 | kind: HTTPRouteGroup
3 | metadata:
4 | name: http-rg
5 | namespace:
6 | spec:
7 | matches:
8 | - name: testMatch
9 | pathRegex: ".*"
10 | methods:
11 | - GET
12 | ---
13 | apiVersion: access.smi-spec.io/v1alpha3
14 | kind: TrafficTarget
15 | metadata:
16 | name: service-targets
17 | namespace:
18 | spec:
19 | destination:
20 | kind: ServiceAccount
21 | name: service-b
22 | namespace:
23 | port: "9091"
24 | sources:
25 | - kind: ServiceAccount
26 | name: service-a
27 | namespace:
28 | rules:
29 | - kind: HTTPRouteGroup
30 | name: http-rg
31 | matches:
32 | - testMatch
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/documentation.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Documentation issue
3 | about: Issues related to documentation.
4 | title: '[Docs]'
5 | labels: 'docs'
6 | assignees: ''
7 | ---
8 | **Current State:**
9 |
10 |
11 | **Desired State:**
12 |
13 |
14 | ---
15 | **Contributor Resources**
16 | - [Meshery documentation site](https://meshery.layer5.io/docs/)
17 | - [Meshery documentation source](https://github.com/layer5io/meshery/tree/master/docs)
18 | - [Instructions for contributing to documentation](https://github.com/layer5io/meshery/blob/master/CONTRIBUTING.md#documentation-contribution-flow)
19 | - 🎨 Wireframes and [designs for Layer5 site](https://www.figma.com/file/5ZwEkSJwUPitURD59YHMEN/Layer5-Designs) in Figma [(open invite)](https://www.figma.com/team_invite/redeem/qJy1c95qirjgWQODApilR9)
20 |
--------------------------------------------------------------------------------
/deploy/traffic-crd.yaml:
--------------------------------------------------------------------------------
1 | # TCPRoute for Counting Service
2 | ---
3 | apiVersion: specs.smi-spec.io/v1alpha1
4 | kind: TCPRoute
5 | metadata:
6 | name: service-tcp-route
7 | namespace:
8 |
9 | # TrafficTarget defines allowed routes for service-a
10 | # In this example service-a is allowed to connect using
11 | # TCP
12 | ---
13 | kind: TrafficTarget
14 | apiVersion: access.smi-spec.io/v1alpha1
15 | metadata:
16 | name: service-targets
17 | namespace:
18 | # namespace: default
19 | destination:
20 | kind: ServiceAccount
21 | name: service-b
22 | namespace:
23 | # namespace: default
24 | sources:
25 | - kind: ServiceAccount
26 | name: service-a
27 | namespace:
28 | # namespace: default
29 | specs:
30 | - kind: TCPRoute
31 | name: service-tcp-route
--------------------------------------------------------------------------------
/.github/stale.yml:
--------------------------------------------------------------------------------
1 | # Number of days of inactivity before an issue becomes stale
2 | daysUntilStale: 45
3 | # Number of days of inactivity before a stale issue is closed
4 | daysUntilClose: 10
5 | # Issues with these labels will never be considered stale
6 | exemptLabels:
7 | - issue/willfix
8 | # Label to use when marking an issue as stale
9 | staleLabel: issue/stale
10 | # Comment to post when marking an issue as stale. Set to `false` to disable
11 | markComment: >
12 | This issue has been automatically marked as stale because it has not had
13 | recent activity. It will be closed if no further activity occurs. Thank you
14 | for your contributions.
15 | # Comment to post when closing a stale issue. Set to `false` to disable
16 | closeComment: >
17 | This issue is being automatically closed due to inactivity.
18 | However, you may choose to reopen this issue.
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature Request
3 | about: Suggest an enhancement to this project.
4 | title: ''
5 | labels: 'enhancement'
6 | assignees: ''
7 | ---
8 |
9 | **Current Behavior**
10 |
11 |
12 |
13 | **Desired Behavior**
14 |
15 |
16 |
17 | ---
18 | **Resources**
19 |
20 |
21 | **Alternatives / Additional Context**
22 |
23 |
24 | **Contributor Resources**
25 | - 🎨 Wireframes and [designs for Layer5 site](https://www.figma.com/file/5ZwEkSJwUPitURD59YHMEN/Layer5-Designs) in Figma [(open invite)](https://www.figma.com/team_invite/redeem/qJy1c95qirjgWQODApilR9)
--------------------------------------------------------------------------------
/smi-conformance/test-gen/test-yamls/traffic-spec/Tests.md:
--------------------------------------------------------------------------------
1 | # Traffic Spec
2 |
3 | Note that the following tests are executed sequentially in an temporarily spawned namespace.
4 |
5 | * *01* : Asserts if the HttpRoute group CRD exists.
6 | * *02* : Deploys the app and asserts if the app has been deployed
7 | * *03* : Configures HTTPRouteGroup such that traffic from `service-a` to only `service-b:PORT/metrics` (all HTTP methods) is allowed and the rest is blocked.
8 | * *04* : Custom test which verifies if the above configuration works as intended.
9 | * *05* : Configures the above created HTTPRouteGroup such that traffic from `service-a` to `service-b:PORT/*` (only GET HTTP Method) is allowed and the rest is blocked.
10 | * *06* : Custom test which verifies if the above configuration works as intended.
11 |
12 | > We aren't validating TCPRouteGroup CRD here as it has been used in the traffic access tests, so if it is not conformant even TrafficAccess will not be.
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug/issue report
3 | about: Report an issue to help improve the project.
4 | title: ''
5 | labels: 'bug'
6 | assignees: ''
7 | ---
8 | **Description**
9 |
10 |
11 | **Expected Behavior**
12 |
13 |
14 | **Screenshots**
15 |
16 |
17 | **Environment:**
18 | - OS: [e.g. Ubuntu]
19 | - Browser: [e.g. Chrome, Safari]
20 | - Version: [e.g. 22]
21 | - Device: [e.g. laptop, iPhone 8]
22 |
23 | ---
24 | [Optional] **To Reproduce**
25 | Steps to reproduce the behavior:
26 | 1. Go to '...'
27 | 2. Click on '....'
28 | 3. Scroll down to '....'
29 | 4. See error
30 |
31 | [Optional] **Additional Context**
32 |
33 |
34 | **Contributor Resources**
35 | - 🎨 Wireframes and [designs for Layer5 site](https://www.figma.com/file/5ZwEkSJwUPitURD59YHMEN/Layer5-Designs) in Figma [(open invite)](https://www.figma.com/team_invite/redeem/qJy1c95qirjgWQODApilR9)
--------------------------------------------------------------------------------
/smi-conformance/test-gen/test-yamls/traffic-split/Tests.md:
--------------------------------------------------------------------------------
1 | # Traffic Access
2 |
3 | Note that the following tests are executed sequentially in an temporarily spawned namespace.
4 |
5 | * *01* : Asserts if the TrafficSplit CRD exists.
6 | * *02* : Deploys the app and asserts that it is deployed.
7 | * *03* : Custom test which verifies that if in default scenario the traffic to `app-svc` is split randomly between `app-b` and `app-c`.
8 | * *04* : Configure a TrafficSplit CRD such that all traffic to `app-svc` is sent to only `app-b` and none to `app-c`.
9 | * *05* : Custom test which verifies the above scenario.
10 | * *06* : Configure a TrafficSplit CRD such that all traffic to `app-svc` is sent to only `app-c` and none to `app-b`.
11 | * *07* : Custom test which verifies the above scenario.
12 | * *08* : Configure a TrafficSplit CRD such that all traffic to `app-svc` is split between the two such that `app-b` gets more traffic (75%) than `app-c` (25%).
13 | * *09* : Custom test which verifies the above scenario.
14 | * *10* : Configure a TrafficSplit CRD such that all traffic to `app-svc` is split between the two such that `app-b` gets more traffic (25%) than `app-c` (75%).
15 | * *11* : Custom test which verifies the above scenario.
--------------------------------------------------------------------------------
/charts/smi-conformance/templates/deployment.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: Deployment
3 | metadata:
4 | name: {{ include "smi-conformance.name" . }}
5 | namespace: {{ include "smi-conformance.namespace" . }}
6 | labels:
7 | {{- include "smi-conformance.labels" . | nindent 4 }}
8 | spec:
9 | replicas: 1
10 | selector:
11 | matchLabels:
12 | {{- include "smi-conformance.labels" . | nindent 6 }}
13 | strategy:
14 | rollingUpdate:
15 | maxSurge: 10%
16 | maxUnavailable: 0
17 | type: RollingUpdate
18 | template:
19 | metadata:
20 | labels:
21 | {{- include "smi-conformance.labels" . | nindent 8 }}
22 | spec:
23 | serviceAccountName: {{ include "smi-conformance.serviceAccount" . }}
24 | containers:
25 | - name: {{ .Chart.Name }}
26 | image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.Version }}"
27 | imagePullPolicy: {{ .Values.image.pullPolicy }}
28 | ports:
29 | - name: grpc
30 | containerPort: {{ .Values.image.port }}
31 | protocol: TCP
32 | resources:
33 | {{- toYaml .Values.resources | nindent 12 }}
34 | restartPolicy: Always
--------------------------------------------------------------------------------
/smi-conformance/.golangci.yml:
--------------------------------------------------------------------------------
1 | run:
2 | tests: true
3 |
4 | linters:
5 | enable:
6 | - goconst
7 | - gocyclo
8 | - gofmt
9 | - goimports
10 | - golint
11 | - gosec
12 | - govet
13 | - misspell
14 | - unused
15 | - whitespace
16 |
17 | linters-settings:
18 | goimports:
19 | local-prefixes: github.com/openservicemesh/osm
20 |
21 | issues:
22 | exclude-rules:
23 | # Ignore error for ginkgo and gomega dot imports
24 | - linters:
25 | - golint
26 | source: ". \"github.com/onsi/(ginkgo|gomega)\""
27 | text: "dot imports"
28 | # Ignore error for test framework imports
29 | - linters:
30 | - golint
31 | source: ". \"github.com/openservicemesh/osm/tests/framework\""
32 | text: "dot imports"
33 | # ignore unused linters on keyvault as this code isn't being used
34 | # TODO: disable this rule once keyvault is integrated
35 | - path: pkg/certificate/providers/keyvault/
36 | linters:
37 | - unused
38 | - deadcode
39 | # Exclude staticcheck messages for deprecated function, variable or constant
40 | # This causes issues with package github.com/golang/protobuf/proto
41 | - linters:
42 | - staticcheck
43 | text: "SA1019:"
44 | exclude-use-default: false
45 |
46 |
--------------------------------------------------------------------------------
/smi-conformance/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM golang:1.14-alpine3.11 as build-img
2 |
3 | RUN apk update && apk add --no-cache git libc-dev gcc pkgconf && mkdir /home/meshery
4 | COPY ${PWD} /go/src/github.com/layer5io/learn-layer5/smi-conformance/
5 | WORKDIR /go/src/github.com/layer5io/learn-layer5/smi-conformance/
6 | # RUN git rev-parse HEAD > /home/meshery/version
7 | # RUN git describe --tags `git rev-list --tags --max-count=1` >> /home/com/version
8 | RUN go mod vendor && go build -a -ldflags "-s -w" -o /home/meshery/smi_conformance main.go
9 |
10 | FROM alpine:latest
11 |
12 | RUN apk --no-cache add ca-certificates && mkdir /home/test-yamls && mkdir /home/test-yamls/traffic-access && mkdir /home/test-yamls/traffic-spec && mkdir /home/test-yamls/traffic-split
13 | COPY --from=build-img /home/meshery/** /home/
14 | COPY --from=build-img /go/src/github.com/layer5io/learn-layer5/smi-conformance/test-gen/test-yamls/traffic-access/** /home/test-yamls/traffic-access/
15 | COPY --from=build-img /go/src/github.com/layer5io/learn-layer5/smi-conformance/test-gen/test-yamls/traffic-split/** /home/test-yamls/traffic-split/
16 | COPY --from=build-img /go/src/github.com/layer5io/learn-layer5/smi-conformance/test-gen/test-yamls/traffic-spec/** /home/test-yamls/traffic-spec/
17 | WORKDIR /home/
18 | EXPOSE 10008
19 | CMD ["sh","-c","./smi_conformance"]
--------------------------------------------------------------------------------
/smi-conformance/conformance/client.go:
--------------------------------------------------------------------------------
1 | package conformance
2 |
3 | import (
4 | context "context"
5 |
6 | "github.com/sirupsen/logrus"
7 | "google.golang.org/grpc"
8 | )
9 |
10 | // ConformanceClient represents a gRPC adapter client
11 | type ConformanceClient struct {
12 | CClient ConformanceTestingClient
13 | conn *grpc.ClientConn
14 | }
15 |
16 | // CreateClient creates a ConformanceClient for the given params
17 | func CreateClient(ctx context.Context, conformanceLocationURL string) (*ConformanceClient, error) {
18 | var opts []grpc.DialOption
19 | // creds, err := credentials.NewClientTLSFromFile(*caFile, *serverHostOverride)
20 | // if err != nil {
21 | // logrus.Errorf("Failed to create TLS credentials %v", err)
22 | // }
23 | // opts = append(opts, grpc.WithTransportCredentials(creds))
24 | // } else {
25 | opts = append(opts, grpc.WithInsecure())
26 | // }
27 | conn, err := grpc.Dial(conformanceLocationURL, opts...)
28 | if err != nil {
29 | logrus.Errorf("fail to dial: %v", err)
30 | }
31 |
32 | cClient := NewConformanceTestingClient(conn)
33 |
34 | return &ConformanceClient{
35 | conn: conn,
36 | CClient: cClient,
37 | }, nil
38 | }
39 |
40 | // Close closes the ConformanceClient
41 | func (c *ConformanceClient) Close() error {
42 | if c.conn != nil {
43 | return c.conn.Close()
44 | }
45 | return nil
46 | }
47 |
--------------------------------------------------------------------------------
/img/readme/community.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/charts/smi-conformance/templates/NOTES.txt:
--------------------------------------------------------------------------------
1 | 1. Get the application URL by running these commands:
2 | {{- if contains "NodePort" .Values.service.type }}
3 | export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "smi-conformance.fullname" . }})
4 | export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
5 | echo http://$NODE_IP:$NODE_PORT
6 | {{- else if contains "LoadBalancer" .Values.service.type }}
7 | NOTE: It may take a few minutes for the LoadBalancer IP to be available.
8 | You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "smi-conformance.fullname" . }}'
9 | export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "smi-conformance.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
10 | echo http://$SERVICE_IP:{{ .Values.service.port }}
11 | {{- else if contains "ClusterIP" .Values.service.type }}
12 | export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "smi-conformance.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
13 | echo "Visit http://127.0.0.1:8080 to use your application"
14 | kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:80
15 | {{- end }}
16 |
--------------------------------------------------------------------------------
/smi-conformance/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/layer5io/learn-layer5/smi-conformance
2 |
3 | go 1.13
4 |
5 | require (
6 | cloud.google.com/go v0.46.3 // indirect
7 | github.com/golang/protobuf v1.4.2
8 | github.com/google/go-cmp v0.5.2 // indirect
9 | github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4
10 | github.com/kr/text v0.2.0 // indirect
11 | github.com/kudobuilder/kuttl v0.0.0-00010101000000-000000000000
12 | // github.com/layer5io/meshkit v0.2.0
13 | github.com/layer5io/service-mesh-performance v0.3.2-0.20210122142912-a94e0658b021
14 | github.com/mattn/go-isatty v0.0.12 // indirect
15 | github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
16 | github.com/onsi/ginkgo v1.14.1 // indirect
17 | github.com/onsi/gomega v1.10.2 // indirect
18 | github.com/pkg/errors v0.9.1 // indirect
19 | github.com/sirupsen/logrus v1.7.0
20 | github.com/stretchr/testify v1.6.1 // indirect
21 | golang.org/x/net v0.0.0-20200822124328-c89045814202 // indirect
22 | golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634 // indirect
23 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
24 | google.golang.org/grpc v1.30.0
25 | google.golang.org/protobuf v1.24.0
26 | gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
27 | k8s.io/api v0.17.3
28 | k8s.io/client-go v0.17.3
29 | sigs.k8s.io/controller-runtime v0.5.1
30 | )
31 |
32 | replace github.com/kudobuilder/kuttl => github.com/layer5io/kuttl v0.4.1-0.20200806180306-b7e46afd657f
33 |
--------------------------------------------------------------------------------
/smi-conformance/manifest.yml:
--------------------------------------------------------------------------------
1 | ---
2 | apiVersion: v1
3 | kind: Service
4 | metadata:
5 | name: smi-conformance
6 | namespace: meshery
7 | labels:
8 | app.kubernetes.io/name: smi-conformance
9 | spec:
10 | type: LoadBalancer
11 | ports:
12 | - port: 10011
13 | targetPort: grpc
14 | protocol: TCP
15 | name: smi-conformance
16 | selector:
17 | app.kubernetes.io/name: smi-conformance
18 | ---
19 | apiVersion: apps/v1
20 | kind: Deployment
21 | metadata:
22 | name: smi-conformance
23 | namespace: meshery
24 | labels:
25 | app.kubernetes.io/name: smi-conformance
26 | spec:
27 | replicas: 1
28 | selector:
29 | matchLabels:
30 | app.kubernetes.io/name: smi-conformance
31 | strategy:
32 | rollingUpdate:
33 | maxSurge: 10%
34 | maxUnavailable: 0
35 | type: RollingUpdate
36 | template:
37 | metadata:
38 | labels:
39 | app.kubernetes.io/name: smi-conformance
40 | spec:
41 | serviceAccountName: meshery-operator
42 | containers:
43 | - name: smi-conformance
44 | image: "layer5/learn-layer5:smi"
45 | imagePullPolicy: Always
46 | ports:
47 | - name: grpc
48 | containerPort: 10011
49 | protocol: TCP
50 | resources:
51 | limits:
52 | cpu: 500m
53 | memory: 1000Mi
54 | requests:
55 | cpu: 200m
56 | memory: 500Mi
57 | restartPolicy: Always
58 |
--------------------------------------------------------------------------------
/smi-conformance/grpc/grpc.go:
--------------------------------------------------------------------------------
1 | package grpc
2 |
3 | import (
4 | "fmt"
5 | "net"
6 | "time"
7 |
8 | middleware "github.com/grpc-ecosystem/go-grpc-middleware"
9 | grpc_recovery "github.com/grpc-ecosystem/go-grpc-middleware/recovery"
10 | "google.golang.org/grpc"
11 |
12 | "github.com/layer5io/learn-layer5/smi-conformance/conformance"
13 | )
14 |
15 | // Service object holds all the information about the server parameters.
16 | type Service struct {
17 | Name string `json:"name"`
18 | Port string `json:"port"`
19 | Version string `json:"version"`
20 | StartedAt time.Time `json:"startedat"`
21 | }
22 |
23 | // panicHandler is the handler function to handle panic errors
24 | func panicHandler(r interface{}) error {
25 | fmt.Println("500 panic Error")
26 | return fmt.Errorf("Panic error for: %+v", r)
27 | }
28 |
29 | // Start grpc server
30 | func Start(s *Service) error {
31 | address := fmt.Sprintf(":%s", s.Port)
32 | listener, err := net.Listen("tcp", address)
33 | if err != nil {
34 | return err
35 | }
36 |
37 | middlewares := middleware.ChainUnaryServer(
38 | grpc_recovery.UnaryServerInterceptor(
39 | grpc_recovery.WithRecoveryHandler(panicHandler),
40 | ),
41 | )
42 |
43 | server := grpc.NewServer(
44 | grpc.UnaryInterceptor(middlewares),
45 | )
46 |
47 | //Register Proto
48 | conformance.RegisterConformanceTestingServer(server, s)
49 |
50 | // Start serving requests
51 | if err = server.Serve(listener); err != nil {
52 | return err
53 | }
54 | return nil
55 | }
56 |
--------------------------------------------------------------------------------
/smi-conformance/conformance/conformance.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 | import "google/protobuf/empty.proto";
3 | import "service-mesh-performance/service/error.proto";
4 | import "service-mesh-performance/service/health.proto";
5 | import "service-mesh-performance/service/info.proto";
6 | import "service-mesh-performance/protos/service_mesh.proto";
7 |
8 | package smi_conformance;
9 | option go_package = "conformance;conformance";
10 |
11 | enum Capability {
12 | FULL = 0;
13 | HALF = 1;
14 | NONE = 2;
15 | }
16 |
17 | enum TestStatus {
18 | COMPLETED = 0;
19 | INPROGRESS = 1;
20 | CRASHED = 2;
21 | }
22 |
23 | enum ResultStatus {
24 | PASSED = 0;
25 | FAILED = 1;
26 | }
27 |
28 | message Request {
29 | smp.ServiceMesh mesh = 1;
30 | }
31 |
32 | message Result {
33 | oneof result {
34 | string message = 1;
35 | service.CommonError error = 2;
36 | }
37 | }
38 |
39 | message Detail {
40 | string smispec = 1;
41 | string specversion = 2;
42 | string assertion = 3;
43 | string duration = 4;
44 | Result result = 5;
45 | Capability capability = 6;
46 | ResultStatus status = 7;
47 | }
48 |
49 | message Response {
50 | string passpercent = 1;
51 | string casespassed = 2;
52 | smp.ServiceMesh mesh = 3;
53 | repeated Detail details = 5;
54 | }
55 |
56 | service conformanceTesting{
57 | rpc Info (google.protobuf.Empty) returns (service.ServiceInfo);
58 | rpc Health (google.protobuf.Empty) returns (service.ServiceHealth);
59 | rpc RunTest (Request) returns (Response);
60 | }
--------------------------------------------------------------------------------
/img/readme/layer5-light-no-trim.svg:
--------------------------------------------------------------------------------
1 | layer5-light-no-trim
--------------------------------------------------------------------------------
/img/readme/layer5-no-trim.svg:
--------------------------------------------------------------------------------
1 | layer5-no-trim
--------------------------------------------------------------------------------
/smi-conformance/test-gen/test-yamls/traffic-split/02-assert.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: app-b
5 | namespace:
6 | spec:
7 | type: NodePort
8 | selector:
9 | app: app
10 | version: b
11 | ports:
12 | - name: http
13 | protocol: TCP
14 | port: 9091
15 | targetPort: 9091
16 | ---
17 | apiVersion: v1
18 | kind: Service
19 | metadata:
20 | name: app-c
21 | namespace:
22 | spec:
23 | type: NodePort
24 | selector:
25 | app: app
26 | version: c
27 | ports:
28 | - name: http
29 | protocol: TCP
30 | port: 9091
31 | targetPort: 9091
32 | ---
33 | apiVersion: v1
34 | kind: Service
35 | metadata:
36 | name: app-a
37 | namespace:
38 | spec:
39 | type: NodePort
40 | selector:
41 | app: app-a
42 | ports:
43 | - name: http
44 | protocol: TCP
45 | port: 9091
46 | targetPort: 9091
47 | ---
48 | apiVersion: v1
49 | kind: Service
50 | metadata:
51 | name: app-svc
52 | namespace:
53 | spec:
54 | type: NodePort
55 | selector:
56 | app: app
57 | ports:
58 | - name: http
59 | protocol: TCP
60 | port: 9091
61 | targetPort: 9091
62 | ---
63 | apiVersion: apps/v1
64 | kind: Deployment
65 | metadata:
66 | name: app-a-deployment
67 | namespace:
68 | status:
69 | readyReplicas: 1
70 | ---
71 | apiVersion: apps/v1
72 | kind: Deployment
73 | metadata:
74 | name: app-b-deployment
75 | namespace:
76 | status:
77 | readyReplicas: 1
78 | ---
79 | apiVersion: apps/v1
80 | kind: Deployment
81 | metadata:
82 | name: app-c-deployment
83 | namespace:
84 | status:
85 | readyReplicas: 1
--------------------------------------------------------------------------------
/.github/workflows/slack.yml:
--------------------------------------------------------------------------------
1 | name: Slack Notify
2 |
3 | on:
4 | watch:
5 | types: [started]
6 | issues:
7 | types: [labeled]
8 |
9 | jobs:
10 | star-notify:
11 | if: github.event_name == 'watch'
12 | name: Notify Slack on star
13 | runs-on: ubuntu-latest
14 | steps:
15 | - name: Get current star count
16 | run: |
17 | echo "STARS=$(curl --silent 'https://api.github.com/repos/${{ github.repository }}' -H 'Accept: application/vnd.github.preview' | jq '.stargazers_count')" >> $GITHUB_ENV
18 |
19 | - name: Notify Slack
20 | uses: slackapi/slack-github-action@v2.1.1
21 | with:
22 | method: chat.postMessage
23 | token: ${{ secrets.SLACK_BOT_TOKEN }}
24 | payload: |
25 | channel: CSK7N9TGX
26 | type: "mrkdwn"
27 | text: " just starred bringing the total ⭐️ count up to: ${{ env.STARS }}"
28 |
29 | good-first-issue-notify:
30 | if: github.event_name == 'issues' && (github.event.label.name == 'good first issue' || github.event.label.name == 'first-timers-only')
31 | name: Notify Slack for new good-first-issue
32 | runs-on: ubuntu-latest
33 | steps:
34 | - name: Notify Slack
35 | uses: slackapi/slack-github-action@v2.1.1
36 | with:
37 | method: chat.postMessage
38 | token: ${{ secrets.SLACK_BOT_TOKEN }}
39 | payload: |
40 | channel: C019426UBNY
41 | text: ":new: Good first issue up for grabs: <${{ github.event.issue.html_url }}|${{ github.event.issue.title }}>"
42 |
--------------------------------------------------------------------------------
/smi-conformance/test-gen/test-yamls/traffic-spec/02-assert.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: ServiceAccount
3 | metadata:
4 | name: service-a
5 | namespace:
6 | ---
7 | apiVersion: v1
8 | kind: ServiceAccount
9 | metadata:
10 | name: service-b
11 | namespace:
12 | ---
13 | apiVersion: v1
14 | kind: ServiceAccount
15 | metadata:
16 | name: service-c
17 | namespace:
18 | ---
19 | apiVersion: apps/v1
20 | kind: Deployment
21 | metadata:
22 | name: app-a-deployment
23 | namespace:
24 | status:
25 | readyReplicas: 1
26 | ---
27 | apiVersion: apps/v1
28 | kind: Deployment
29 | metadata:
30 | name: app-b-deployment
31 | namespace:
32 | status:
33 | readyReplicas: 1
34 | ---
35 | apiVersion: apps/v1
36 | kind: Deployment
37 | metadata:
38 | name: app-c-deployment
39 | namespace:
40 | status:
41 | readyReplicas: 1
42 | ---
43 | apiVersion: v1
44 | kind: Service
45 | metadata:
46 | name: app-a
47 | namespace:
48 | spec:
49 | type: NodePort
50 | selector:
51 | app: app-a
52 | ports:
53 | - name: http
54 | protocol: TCP
55 | port: 9091
56 | # targetPort: 9091
57 | ---
58 | apiVersion: v1
59 | kind: Service
60 | metadata:
61 | name: app-b
62 | namespace:
63 | spec:
64 | type: NodePort
65 | selector:
66 | app: app-b
67 | ports:
68 | - name: http
69 | protocol: TCP
70 | port: 9091
71 | # targetPort: 9091
72 | ---
73 | apiVersion: v1
74 | kind: Service
75 | metadata:
76 | name: app-c
77 | namespace:
78 | spec:
79 | type: NodePort
80 | selector:
81 | app: app-c
82 | ports:
83 | - name: http
84 | protocol: TCP
85 | port: 9091
86 | # targetPort: 9091
--------------------------------------------------------------------------------
/smi-conformance/test-gen/test-yamls/traffic-access/02-assert.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: ServiceAccount
3 | metadata:
4 | name: service-a
5 | namespace:
6 | ---
7 | apiVersion: v1
8 | kind: ServiceAccount
9 | metadata:
10 | name: service-b
11 | namespace:
12 | ---
13 | apiVersion: v1
14 | kind: ServiceAccount
15 | metadata:
16 | name: service-c
17 | namespace:
18 | ---
19 | apiVersion: apps/v1
20 | kind: Deployment
21 | metadata:
22 | name: app-a-deployment
23 | namespace:
24 | status:
25 | readyReplicas: 1
26 | ---
27 | apiVersion: apps/v1
28 | kind: Deployment
29 | metadata:
30 | name: app-b-deployment
31 | namespace:
32 | status:
33 | readyReplicas: 1
34 | ---
35 | apiVersion: apps/v1
36 | kind: Deployment
37 | metadata:
38 | name: app-c-deployment
39 | namespace:
40 | status:
41 | readyReplicas: 1
42 | ---
43 | apiVersion: v1
44 | kind: Service
45 | metadata:
46 | name: app-a
47 | namespace:
48 | spec:
49 | type: NodePort
50 | selector:
51 | app: app-a
52 | ports:
53 | - name: http
54 | protocol: TCP
55 | port: 9091
56 | # targetPort: 9091
57 | ---
58 | apiVersion: v1
59 | kind: Service
60 | metadata:
61 | name: app-b
62 | namespace:
63 | spec:
64 | type: NodePort
65 | selector:
66 | app: app-b
67 | ports:
68 | - name: http
69 | protocol: TCP
70 | port: 9091
71 | # targetPort: 9091
72 | ---
73 | apiVersion: v1
74 | kind: Service
75 | metadata:
76 | name: app-c
77 | namespace:
78 | spec:
79 | type: NodePort
80 | selector:
81 | app: app-c
82 | ports:
83 | - name: http
84 | protocol: TCP
85 | port: 9091
86 | # targetPort: 9091
--------------------------------------------------------------------------------
/charts/smi-conformance/templates/_helpers.tpl:
--------------------------------------------------------------------------------
1 | {{/* vim: set filetype=mustache: */}}
2 | {{/*
3 | Expand the name of the chart.
4 | */}}
5 | {{- define "smi-conformance.name" -}}
6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
7 | {{- end }}
8 |
9 | {{/*
10 | Create a default fully qualified app name.
11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
12 | If release name contains chart name it will be used as a full name.
13 | */}}
14 | {{- define "smi-conformance.fullname" -}}
15 | {{- if .Values.fullnameOverride }}
16 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
17 | {{- else }}
18 | {{- $name := default .Chart.Name .Values.nameOverride }}
19 | {{- if contains $name .Release.Name }}
20 | {{- .Release.Name | trunc 63 | trimSuffix "-" }}
21 | {{- else }}
22 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
23 | {{- end }}
24 | {{- end }}
25 | {{- end }}
26 |
27 | {{/*
28 | Create chart name and version as used by the chart label.
29 | */}}
30 | {{- define "smi-conformance.chart" -}}
31 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
32 | {{- end }}
33 |
34 | {{/*
35 | Common labels
36 | */}}
37 | {{- define "smi-conformance.labels" -}}
38 | helm.sh/chart: {{ include "smi-conformance.chart" . }}
39 | {{ include "smi-conformance.selectorLabels" . }}
40 | {{- if .Chart.AppVersion }}
41 | app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
42 | {{- end }}
43 | app.kubernetes.io/managed-by: {{ .Release.Service }}
44 | {{- end }}
45 |
46 | {{/*
47 | Selector labels
48 | */}}
49 | {{- define "smi-conformance.selectorLabels" -}}
50 | app.kubernetes.io/name: {{ include "smi-conformance.name" . }}
51 | app.kubernetes.io/instance: {{ .Release.Name }}
52 | {{- end }}
53 |
54 | {{/*
55 | Create the name of the service account to use
56 | */}}
57 | {{- define "smi-conformance.serviceAccount" -}}
58 | {{- if .Values.serviceAccount }}
59 | {{- default (include "smi-conformance.fullname" .) .Values.serviceAccount }}
60 | {{- else }}
61 | {{- default "default" .Values.serviceAccount }}
62 | {{- end }}
63 | {{- end }}
64 |
65 | {{/*
66 | Create the name of the namespace to use
67 | */}}
68 | {{- define "smi-conformance.namespace" -}}
69 | {{- if .Values.namespace }}
70 | {{- default (include "smi-conformance.fullname" .) .Values.namespace }}
71 | {{- else }}
72 | {{- default "default" .Values.namespace }}
73 | {{- end }}
74 | {{- end }}
75 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: Learn-Layer5
2 | on:
3 | push:
4 | branches:
5 | - 'master'
6 | tags:
7 | - 'v*'
8 | pull_request:
9 | branches:
10 | - 'master'
11 |
12 | jobs:
13 | docker:
14 | name: Docker build and push
15 | runs-on: ubuntu-latest
16 | steps:
17 | - name: Check out code
18 | if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/') || github.ref == 'refs/heads/master') && success()
19 | uses: actions/checkout@master
20 | with:
21 | fetch-depth: 1
22 | - name: Docker login
23 | if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/') || github.ref == 'refs/heads/master') && success()
24 | uses: azure/docker-login@v1
25 | with:
26 | username: ${{ secrets.DOCKER_USERNAME }}
27 | password: ${{ secrets.DOCKER_PASSWORD }}
28 | - name: Docker build & push services
29 | if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/') || github.ref == 'refs/heads/master') && success()
30 | run: |
31 | cd service && docker build --no-cache -t ${{ secrets.IMAGE_NAME }} .
32 | docker tag ${{ secrets.IMAGE_NAME }}:latest ${{ secrets.IMAGE_NAME }}:${GITHUB_SHA::6}
33 | docker push ${{ secrets.IMAGE_NAME }}:latest
34 | docker push ${{ secrets.IMAGE_NAME }}:${GITHUB_SHA::6}
35 | cd ../smi-conformance && docker build --no-cache -t ${{ secrets.IMAGE_NAME }}:smi .
36 | docker tag ${{ secrets.IMAGE_NAME }}:smi ${{ secrets.IMAGE_NAME }}:smi-${GITHUB_SHA::6}
37 | docker push ${{ secrets.IMAGE_NAME }}:smi
38 | docker push ${{ secrets.IMAGE_NAME }}:smi-${GITHUB_SHA::6}
39 | - name: Docker tag release & push
40 | if: github.event_name != 'pull_request' && startsWith(github.ref, 'refs/tags/') && success()
41 | run: |
42 | docker tag ${{ secrets.IMAGE_NAME }}:latest ${{ secrets.IMAGE_NAME }}:${GITHUB_REF/refs\/tags\//}
43 | docker push ${{ secrets.IMAGE_NAME }}:${GITHUB_REF/refs\/tags\//}
44 | docker tag ${{ secrets.IMAGE_NAME }}:smi ${{ secrets.IMAGE_NAME }}:smi-${GITHUB_REF/refs\/tags\//}
45 | docker push ${{ secrets.IMAGE_NAME }}:smi-${GITHUB_REF/refs\/tags\//}
46 | helm:
47 | name: Helm charts publish
48 | runs-on: ubuntu-latest
49 | steps:
50 | - name: Checkout code
51 | uses: actions/checkout@master
52 | with:
53 | fetch-depth: 1
54 | - name: Configure Git
55 | run: |
56 | git config user.name "$GITHUB_ACTOR"
57 | git config user.email "$GITHUB_ACTOR@users.noreply.github.com"
58 | - name: Run chart-releaser
59 | uses: helm/chart-releaser-action@v1.0.0
60 | with:
61 | version: ${GITHUB_REF/refs\/tags\//}
62 | charts_repo_url: https://layer5io.github.io/master/charts
63 | env:
64 | CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
65 |
--------------------------------------------------------------------------------
/.github/config.yml:
--------------------------------------------------------------------------------
1 | #-------------------------------------------------------------------------------
2 | # Configuration for new-issue-welcome - https://github.com/behaviorbot/new-issue-welcome
3 | # Comment to be posted to on first time issues
4 | newIssueWelcomeComment: >
5 | Thanks for opening this issue. A contributor will be by to give feedback soon. In the meantime, please review the [Layer5 Community Welcome Guide](https://docs.google.com/document/d/17OPtDE_rdnPQxmk2Kauhm3GwXF1R5dZ3Cj8qZLKdo5E/edit?usp=sharing) and sure to join the [community Slack](http://slack.layer5.io/).
6 | # Configuration for new-pr-welcome - https://github.com/behaviorbot/new-pr-welcome
7 | # Comment to be posted to on PRs from first time contributors in your repository
8 | newPRWelcomeComment: >
9 | Yay, your first pull request! :thumbsup: A contributor will be by to give feedback soon. In the meantime, please review the [Layer5 Community Welcome Guide](https://docs.google.com/document/d/17OPtDE_rdnPQxmk2Kauhm3GwXF1R5dZ3Cj8qZLKdo5E/edit?usp=sharing) and sure to join the [community Slack](http://slack.layer5.io/).
10 |
11 | Be sure to double-check that you have signed your commits. Here are instructions for [making signing an implicit activity while peforming a commit](../CONTRIBUTING.md#signing-off-on-commits-developer-certificate-of-origin).
12 |
13 |
14 | #-------------------------------------------------------------------------------
15 | # Configuration for first-pr-merge - https://github.com/behaviorbot/first-pr-merge
16 | # Comment to be posted to on pull requests merged by a first time user
17 | firstPRMergeComment: >
18 | Thanks for your contribution to the Layer5 community! :tada:
19 |
20 | 
21 |
22 | :star: Please [star the project](../stargazers) if you have yet to do so and sure to join the [community Slack](http://slack.layer5.io/).
23 |
24 |
25 | #-------------------------------------------------------------------------------
26 | # Configuration for request-info - https://github.com/behaviorbot/request-info
27 | # Comment to reply with
28 | requestInfoReplyComment: >
29 | Thanks for opening this issue. We welcome all input! If you could provide a little more information, this will greatly aid in its resolution. :thumbsup:
30 | # *OPTIONAL* Add a list of people whose Issues/PRs will not be commented on
31 | # keys must be GitHub usernames
32 | #requestInfoUserstoExclude:
33 | # - layer5io/maintainers
34 |
35 |
36 | #-------------------------------------------------------------------------------
37 | # Configuration for sentiment-bot - https://github.com/behaviorbot/sentiment-bot
38 | # *Required* toxicity threshold between 0 and .99 with the higher numbers being the most toxic
39 | # Anything higher than this threshold will be marked as toxic and commented on
40 | sentimentBotToxicityThreshold: .9
41 |
42 | # *Required* Comment to reply with
43 | sentimentBotReplyComment: >
44 | Please be sure to review the code of conduct and be respectful of other users. // @layer5io/maintainers
45 |
46 |
--------------------------------------------------------------------------------
/smi-conformance/test-gen/test-yamls/traffic-access/02-install.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: ServiceAccount
3 | metadata:
4 | name: service-a
5 | namespace:
6 | ---
7 | apiVersion: v1
8 | kind: ServiceAccount
9 | metadata:
10 | name: service-b
11 | namespace:
12 | ---
13 | apiVersion: v1
14 | kind: ServiceAccount
15 | metadata:
16 | name: service-c
17 | namespace:
18 | ---
19 | apiVersion: apps/v1
20 | kind: Deployment
21 | metadata:
22 | name: app-a-deployment
23 | namespace:
24 | labels:
25 | app: app-a
26 | spec:
27 | replicas: 1
28 | selector:
29 | matchLabels:
30 | app: app-a
31 | template:
32 | metadata:
33 | labels:
34 | app: app-a
35 | spec:
36 | serviceAccountName: service-a
37 | containers:
38 | - name: app-a
39 | image: layer5/learn-layer5:latest
40 | ports:
41 | - containerPort: 9091
42 | name: http
43 | env:
44 | - name: SERVICE_NAME
45 | value: "app-a"
46 | ---
47 | apiVersion: apps/v1
48 | kind: Deployment
49 | metadata:
50 | name: app-b-deployment
51 | namespace:
52 | labels:
53 | app: app-b
54 | spec:
55 | replicas: 1
56 | selector:
57 | matchLabels:
58 | app: app-b
59 | template:
60 | metadata:
61 | labels:
62 | app: app-b
63 | spec:
64 | serviceAccountName: service-b
65 | containers:
66 | - name: app-b
67 | image: layer5/learn-layer5:latest
68 | ports:
69 | - containerPort: 9091
70 | name: http
71 | env:
72 | - name: SERVICE_NAME
73 | value: "app-b"
74 | ---
75 | apiVersion: apps/v1
76 | kind: Deployment
77 | metadata:
78 | name: app-c-deployment
79 | namespace:
80 | labels:
81 | app: app-c
82 | spec:
83 | replicas: 1
84 | selector:
85 | matchLabels:
86 | app: app-c
87 | template:
88 | metadata:
89 | labels:
90 | app: app-c
91 | spec:
92 | serviceAccountName: service-c
93 | containers:
94 | - name: app-c
95 | image: layer5/learn-layer5:latest
96 | ports:
97 | - containerPort: 9091
98 | name: http
99 | env:
100 | - name: SERVICE_NAME
101 | value: "app-c"
102 | ---
103 | apiVersion: v1
104 | kind: Service
105 | metadata:
106 | name: app-a
107 | namespace:
108 | spec:
109 | type: NodePort
110 | selector:
111 | app: app-a
112 | ports:
113 | - name: http
114 | protocol: TCP
115 | port: 9091
116 | targetPort: 9091
117 | ---
118 | apiVersion: v1
119 | kind: Service
120 | metadata:
121 | name: app-b
122 | namespace:
123 | spec:
124 | type: NodePort
125 | selector:
126 | app: app-b
127 | ports:
128 | - name: http
129 | protocol: TCP
130 | port: 9091
131 | targetPort: 9091
132 | ---
133 | apiVersion: v1
134 | kind: Service
135 | metadata:
136 | name: app-c
137 | namespace:
138 | spec:
139 | type: NodePort
140 | selector:
141 | app: app-c
142 | ports:
143 | - name: http
144 | protocol: TCP
145 | port: 9091
146 | targetPort: 9091
--------------------------------------------------------------------------------
/smi-conformance/test-gen/test-yamls/traffic-spec/02-install.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: ServiceAccount
3 | metadata:
4 | name: service-a
5 | namespace:
6 | ---
7 | apiVersion: v1
8 | kind: ServiceAccount
9 | metadata:
10 | name: service-b
11 | namespace:
12 | ---
13 | apiVersion: v1
14 | kind: ServiceAccount
15 | metadata:
16 | name: service-c
17 | namespace:
18 | ---
19 | apiVersion: apps/v1
20 | kind: Deployment
21 | metadata:
22 | name: app-a-deployment
23 | namespace:
24 | labels:
25 | app: app-a
26 | spec:
27 | replicas: 1
28 | selector:
29 | matchLabels:
30 | app: app-a
31 | template:
32 | metadata:
33 | labels:
34 | app: app-a
35 | spec:
36 | serviceAccountName: service-a
37 | containers:
38 | - name: app-a
39 | image: layer5/learn-layer5:latest
40 | ports:
41 | - containerPort: 9091
42 | name: http
43 | env:
44 | - name: SERVICE_NAME
45 | value: "app-a"
46 | ---
47 | apiVersion: apps/v1
48 | kind: Deployment
49 | metadata:
50 | name: app-b-deployment
51 | namespace:
52 | labels:
53 | app: app-b
54 | spec:
55 | replicas: 1
56 | selector:
57 | matchLabels:
58 | app: app-b
59 | template:
60 | metadata:
61 | labels:
62 | app: app-b
63 | spec:
64 | serviceAccountName: service-b
65 | containers:
66 | - name: app-b
67 | image: layer5/learn-layer5:latest
68 | ports:
69 | - containerPort: 9091
70 | name: http
71 | env:
72 | - name: SERVICE_NAME
73 | value: "app-b"
74 | ---
75 | apiVersion: apps/v1
76 | kind: Deployment
77 | metadata:
78 | name: app-c-deployment
79 | namespace:
80 | labels:
81 | app: app-c
82 | spec:
83 | replicas: 1
84 | selector:
85 | matchLabels:
86 | app: app-c
87 | template:
88 | metadata:
89 | labels:
90 | app: app-c
91 | spec:
92 | serviceAccountName: service-c
93 | containers:
94 | - name: app-c
95 | image: layer5/learn-layer5:latest
96 | ports:
97 | - containerPort: 9091
98 | name: http
99 | env:
100 | - name: SERVICE_NAME
101 | value: "app-c"
102 | ---
103 | apiVersion: v1
104 | kind: Service
105 | metadata:
106 | name: app-a
107 | namespace:
108 | spec:
109 | type: NodePort
110 | selector:
111 | app: app-a
112 | ports:
113 | - name: http
114 | protocol: TCP
115 | port: 9091
116 | targetPort: 9091
117 | ---
118 | apiVersion: v1
119 | kind: Service
120 | metadata:
121 | name: app-b
122 | namespace:
123 | spec:
124 | type: NodePort
125 | selector:
126 | app: app-b
127 | ports:
128 | - name: http
129 | protocol: TCP
130 | port: 9091
131 | targetPort: 9091
132 | ---
133 | apiVersion: v1
134 | kind: Service
135 | metadata:
136 | name: app-c
137 | namespace:
138 | spec:
139 | type: NodePort
140 | selector:
141 | app: app-c
142 | ports:
143 | - name: http
144 | protocol: TCP
145 | port: 9091
146 | targetPort: 9091
--------------------------------------------------------------------------------
/smi-conformance/test-gen/test-yamls/traffic-split/02-install.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: Deployment
3 | metadata:
4 | name: app-a-deployment
5 | namespace:
6 | labels:
7 | app: app-a
8 | spec:
9 | replicas: 1
10 | selector:
11 | matchLabels:
12 | app: app-a
13 | template:
14 | metadata:
15 | labels:
16 | app: app-a
17 | spec:
18 | containers:
19 | - name: app-a
20 | image: layer5/learn-layer5:latest
21 | ports:
22 | - containerPort: 9091
23 | name: http
24 | env:
25 | - name: SERVICE_NAME
26 | value: "app-a"
27 | ---
28 | apiVersion: apps/v1
29 | kind: Deployment
30 | metadata:
31 | name: app-b-deployment
32 | namespace:
33 | labels:
34 | app: app
35 | version: b
36 | spec:
37 | replicas: 1
38 | selector:
39 | matchLabels:
40 | app: app
41 | version: b
42 | template:
43 | metadata:
44 | labels:
45 | app: app
46 | version: b
47 | spec:
48 | containers:
49 | - name: app-b
50 | image: layer5/learn-layer5:latest
51 | ports:
52 | - containerPort: 9091
53 | name: http
54 | protocol: TCP
55 | env:
56 | - name: SERVICE_NAME
57 | value: "app-b"
58 | ---
59 | apiVersion: apps/v1
60 | kind: Deployment
61 | metadata:
62 | name: app-c-deployment
63 | namespace:
64 | labels:
65 | app: app
66 | version: c
67 | spec:
68 | replicas: 1
69 | selector:
70 | matchLabels:
71 | app: app
72 | version: c
73 | template:
74 | metadata:
75 | labels:
76 | app: app
77 | version: c
78 | spec:
79 | containers:
80 | - name: app-c
81 | image: layer5/learn-layer5:latest
82 | ports:
83 | - containerPort: 9091
84 | name: http
85 | protocol: TCP
86 | env:
87 | - name: SERVICE_NAME
88 | value: "app-c"
89 | ---
90 | apiVersion: v1
91 | kind: Service
92 | metadata:
93 | name: app-a
94 | namespace:
95 | spec:
96 | type: NodePort
97 | selector:
98 | app: app-a
99 | ports:
100 | - name: http
101 | protocol: TCP
102 | port: 9091
103 | targetPort: 9091
104 | ---
105 | apiVersion: v1
106 | kind: Service
107 | metadata:
108 | name: app-b
109 | namespace:
110 | spec:
111 | type: NodePort
112 | selector:
113 | app: app
114 | version: b
115 | ports:
116 | - name: http
117 | protocol: TCP
118 | port: 9091
119 | targetPort: 9091
120 | ---
121 | apiVersion: v1
122 | kind: Service
123 | metadata:
124 | name: app-c
125 | namespace:
126 | spec:
127 | type: NodePort
128 | selector:
129 | app: app
130 | version: c
131 | ports:
132 | - name: http
133 | protocol: TCP
134 | port: 9091
135 | targetPort: 9091
136 | ---
137 | apiVersion: v1
138 | kind: Service
139 | metadata:
140 | name: app-svc
141 | namespace:
142 | spec:
143 | type: NodePort
144 | selector:
145 | app: app
146 | ports:
147 | - name: http
148 | protocol: TCP
149 | port: 9091
150 | targetPort: 9091
--------------------------------------------------------------------------------
/deploy/k8s-maesh.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Namespace
3 | metadata:
4 | name:
5 | ---
6 | apiVersion: v1
7 | kind: ServiceAccount
8 | metadata:
9 | name: service-a
10 | namespace:
11 | ---
12 | apiVersion: v1
13 | kind: ServiceAccount
14 | metadata:
15 | name: service-b
16 | namespace:
17 | ---
18 | apiVersion: v1
19 | kind: ServiceAccount
20 | metadata:
21 | name: service-c
22 | namespace:
23 | ---
24 | apiVersion: apps/v1
25 | kind: Deployment
26 | metadata:
27 | name: app-a-deployment
28 | namespace:
29 | labels:
30 | app: app-a
31 | spec:
32 | replicas: 1
33 | selector:
34 | matchLabels:
35 | app: app-a
36 | template:
37 | metadata:
38 | labels:
39 | app: app-a
40 | spec:
41 | serviceAccountName: service-a
42 | containers:
43 | - name: app-a
44 | image: layer5/learn-layer5:latest
45 | ports:
46 | - containerPort: 9091
47 | name: http
48 | env:
49 | - name: SERVICE_NAME
50 | value: "Service-a"
51 | ---
52 | apiVersion: apps/v1
53 | kind: Deployment
54 | metadata:
55 | name: app-b-deployment
56 | namespace:
57 | labels:
58 | app: app-b
59 | spec:
60 | replicas: 1
61 | selector:
62 | matchLabels:
63 | app: app-b
64 | template:
65 | metadata:
66 | labels:
67 | app: app-b
68 | spec:
69 | serviceAccountName: service-b
70 | containers:
71 | - name: app-b
72 | image: layer5/learn-layer5:latest
73 | ports:
74 | - containerPort: 9091
75 | name: http
76 | env:
77 | - name: SERVICE_NAME
78 | value: "Service-b"
79 | ---
80 | apiVersion: apps/v1
81 | kind: Deployment
82 | metadata:
83 | name: app-c-deployment
84 | namespace:
85 | labels:
86 | app: app-c
87 | spec:
88 | replicas: 1
89 | selector:
90 | matchLabels:
91 | app: app-c
92 | template:
93 | metadata:
94 | labels:
95 | app: app-c
96 | spec:
97 | serviceAccountName: service-c
98 | containers:
99 | - name: app-c
100 | image: layer5/learn-layer5:latest
101 | ports:
102 | - containerPort: 9091
103 | name: http
104 | env:
105 | - name: SERVICE_NAME
106 | value: "Service-c"
107 | ---
108 | apiVersion: v1
109 | kind: Service
110 | metadata:
111 | name: app-a
112 | namespace:
113 | spec:
114 | type: NodePort
115 | selector:
116 | app: app-a
117 | ports:
118 | - name: http
119 | protocol: TCP
120 | port: 9091
121 | targetPort: 9091
122 | ---
123 | apiVersion: v1
124 | kind: Service
125 | metadata:
126 | name: app-b
127 | namespace:
128 | spec:
129 | type: NodePort
130 | selector:
131 | app: app-b
132 | ports:
133 | - name: http
134 | protocol: TCP
135 | port: 9091
136 | targetPort: 9091
137 | ---
138 | apiVersion: v1
139 | kind: Service
140 | metadata:
141 | name: app-c
142 | namespace:
143 | spec:
144 | type: NodePort
145 | selector:
146 | app: app-c
147 | ports:
148 | - name: http
149 | protocol: TCP
150 | port: 9091
151 | targetPort: 9091
--------------------------------------------------------------------------------
/deploy/linkerd/app.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Namespace
3 | metadata:
4 | name:
5 | annotations:
6 | 'linkerd.io/inject': 'enabled'
7 | ---
8 | apiVersion: apps/v1
9 | kind: Deployment
10 | metadata:
11 | name: app-a-deployment
12 | namespace:
13 | labels:
14 | app: app-a
15 | spec:
16 | replicas: 1
17 | selector:
18 | matchLabels:
19 | app: app-a
20 | template:
21 | metadata:
22 | labels:
23 | app: app-a
24 | spec:
25 | containers:
26 | - name: app-a
27 | image: layer5/learn-layer5:latest
28 | ports:
29 | - containerPort: 9091
30 | name: http
31 | env:
32 | - name: SERVICE_NAME
33 | value: "app-a"
34 | ---
35 | apiVersion: apps/v1
36 | kind: Deployment
37 | metadata:
38 | name: app-b-deployment
39 | namespace:
40 | labels:
41 | app: app
42 | version: v1
43 | spec:
44 | replicas: 1
45 | selector:
46 | matchLabels:
47 | app: app
48 | version: v1
49 | template:
50 | metadata:
51 | labels:
52 | app: app
53 | version: v1
54 | spec:
55 | containers:
56 | - name: app-b
57 | image: layer5/learn-layer5:latest
58 | ports:
59 | - containerPort: 9091
60 | name: http
61 | protocol: TCP
62 | env:
63 | - name: SERVICE_NAME
64 | value: "app-b"
65 | ---
66 | apiVersion: apps/v1
67 | kind: Deployment
68 | metadata:
69 | name: app-c-deployment
70 | namespace:
71 | labels:
72 | app: app
73 | version: v2
74 | spec:
75 | replicas: 1
76 | selector:
77 | matchLabels:
78 | app: app
79 | version: v2
80 | template:
81 | metadata:
82 | labels:
83 | app: app
84 | version: v2
85 | spec:
86 | containers:
87 | - name: app-c
88 | image: layer5/learn-layer5:latest
89 | ports:
90 | - containerPort: 9091
91 | name: http
92 | protocol: TCP
93 | env:
94 | - name: SERVICE_NAME
95 | value: "app-c"
96 | ---
97 | apiVersion: v1
98 | kind: Service
99 | metadata:
100 | name: app-v1
101 | namespace:
102 | spec:
103 | type: NodePort
104 | selector:
105 | app: app
106 | version: v1
107 | ports:
108 | - name: http
109 | protocol: TCP
110 | port: 9091
111 | targetPort: 9091
112 | ---
113 | apiVersion: v1
114 | kind: Service
115 | metadata:
116 | name: app-v2
117 | namespace:
118 | spec:
119 | type: NodePort
120 | selector:
121 | app: app
122 | version: v2
123 | ports:
124 | - name: http
125 | protocol: TCP
126 | port: 9091
127 | targetPort: 9091
128 | ---
129 | apiVersion: v1
130 | kind: Service
131 | metadata:
132 | name: app-svc
133 | namespace:
134 | spec:
135 | type: NodePort
136 | selector:
137 | app: app
138 | ports:
139 | - name: http
140 | protocol: TCP
141 | port: 9091
142 | targetPort: 9091
143 |
144 | # for i in {1..20};do curl app-svc..svc.cluster.local.:9091/echo; echo; done
145 | # curl app-v1..svc.cluster.local.:9091/metrics
146 | # curl -X "DELETE" app-v1..svc.cluster.local.:9091/metrics
--------------------------------------------------------------------------------
/smi-conformance/test-gen/utils.go:
--------------------------------------------------------------------------------
1 | package test_gen
2 |
3 | import (
4 | "bytes"
5 | "context"
6 | "encoding/json"
7 | "errors"
8 | "fmt"
9 | "io/ioutil"
10 | "net/http"
11 | "time"
12 |
13 | v1 "k8s.io/api/core/v1"
14 | "sigs.k8s.io/controller-runtime/pkg/client"
15 | )
16 |
17 | // App service names
18 | const (
19 | SvcNameA = "app-a"
20 | SvcNameB = "app-b"
21 | SvcNameC = "app-c"
22 | )
23 |
24 | // App API endpoints
25 | const (
26 | METRICS = "metrics"
27 | CALL = "call"
28 | ECHO = "echo"
29 | )
30 |
31 | // URLstruct is a part of the metrics exposed by the app
32 | type URLstruct struct {
33 | URL string
34 | Method string
35 | Headers map[string]string
36 | }
37 |
38 | // MetricResponse is a part of the metrics exposed by the app
39 | type MetricResponse struct {
40 | ReqReceived []string
41 | RespSucceeded []URLstruct
42 | RespFailed []URLstruct
43 | }
44 |
45 | // GetClusterIPs returns the ClusterIPs of various services exposed in the namespace
46 | func GetClusterIPs(kubeClient client.Client, namespace string) (map[string]string, error) {
47 | deps := &v1.ServiceList{}
48 | err := kubeClient.List(context.TODO(), deps, client.InNamespace(namespace))
49 | if err != nil {
50 | return nil, err
51 | }
52 | ipMap := make(map[string]string)
53 | for _, svc := range deps.Items {
54 | ipMap[svc.Name] = svc.Spec.ClusterIP
55 | }
56 | return ipMap, nil
57 | }
58 |
59 | // GetHTTPClient returns a configured HTTP client
60 | func GetHTTPClient() http.Client {
61 | return http.Client{
62 | Timeout: 30 * time.Second,
63 | }
64 | }
65 |
66 | // ClearMetrics remove all the resources
67 | func ClearMetrics(hostname string, port string) error {
68 | url := fmt.Sprintf("http://%s:%s/%s", hostname, port, METRICS)
69 | httpClient := GetHTTPClient()
70 | req, err := http.NewRequest(http.MethodDelete, url, nil)
71 | if err != nil {
72 | return err
73 | }
74 | resp, err := httpClient.Do(req)
75 | if err != nil {
76 | return err
77 | }
78 | if resp.StatusCode != http.StatusOK {
79 | return errors.New("Request failed")
80 | }
81 | return nil
82 | }
83 |
84 | // GetMetrics return a type MetricResponse
85 | func GetMetrics(hostname string, port string) (*MetricResponse, error) {
86 | url := fmt.Sprintf("http://%s:%s/%s", hostname, port, METRICS)
87 | httpClient := GetHTTPClient()
88 | resp, err := httpClient.Get(url)
89 | if err != nil {
90 | return nil, err
91 | }
92 | if resp.StatusCode != http.StatusOK {
93 | return nil, errors.New("Request failed")
94 | }
95 | data, err := ioutil.ReadAll(resp.Body)
96 | if err != nil {
97 | return nil, err
98 | }
99 | defer resp.Body.Close()
100 | metrics := MetricResponse{}
101 | if err := json.Unmarshal(data, &metrics); err != nil {
102 | return nil, err
103 | }
104 | return &metrics, nil
105 | }
106 |
107 | func generatePOSTLoad(no int, url string, body []byte) error {
108 | hclient := GetHTTPClient()
109 | for i := 0; i < no; i++ {
110 | if _, err := hclient.Post(url, "application/json", bytes.NewReader(body)); err != nil {
111 | return err
112 | }
113 | }
114 | return nil
115 | }
116 |
117 | // ClearAllMetrics aggregate all the svc metrics
118 | func ClearAllMetrics(clusterIPs map[string]string, smObj ServiceMesh) {
119 | ClearMetrics(clusterIPs[SvcNameA], smObj.SvcAGetPort())
120 | ClearMetrics(clusterIPs[SvcNameB], smObj.SvcBGetPort())
121 | ClearMetrics(clusterIPs[SvcNameC], smObj.SvcCGetPort())
122 | }
123 |
--------------------------------------------------------------------------------
/smi-conformance/test-gen/test_gen.go:
--------------------------------------------------------------------------------
1 | package test_gen
2 |
3 | import (
4 | "encoding/json"
5 | "fmt"
6 | "testing"
7 | "time"
8 |
9 | harness "github.com/kudobuilder/kuttl/pkg/apis/testharness/v1beta1"
10 | "github.com/kudobuilder/kuttl/pkg/report"
11 | "github.com/kudobuilder/kuttl/pkg/test"
12 | testutils "github.com/kudobuilder/kuttl/pkg/test/utils"
13 | )
14 |
15 | type Failure struct {
16 | Text string `json:"text,omitempty"`
17 | Message string `json:"message,omitempty"`
18 | }
19 |
20 | type Results struct {
21 | Name string `json:"name,omitempty"`
22 | Tests int `json:"tests,omitempty"`
23 | Failures int `json:"failures,omitempty"`
24 | Time string `json:"time,omitempty"`
25 | Testsuite []struct {
26 | Tests int `json:"tests,omitempty"`
27 | Failures int `json:"failures,omitempty"`
28 | Time string `json:"time,omitempty"`
29 | Name string `json:"name,omitempty"`
30 | Testcase []struct {
31 | Classname string `json:"classname,omitempty"`
32 | Name string `json:"name,omitempty"`
33 | Time string `json:"time,omitempty"`
34 | Assertions int `json:"assertions,omitempty"`
35 | Failure Failure `json:"failure,omitempty"`
36 | } `json:"testcase,omitempty"`
37 | } `json:"testsuite,omitempty"`
38 | }
39 |
40 | func RunTest(meshConfig ServiceMesh, annotations, labels map[string]string) Results {
41 |
42 | c := make(chan Results)
43 | go func() {
44 | manifestDirs := []string{}
45 | results := &report.Testsuites{}
46 | output := Results{}
47 |
48 | // Run all testCases
49 | testToRun := ""
50 | // Run only traffic-split
51 | // testToRun := "traffic-split"
52 |
53 | options := harness.TestSuite{}
54 |
55 | args := []string{"./test-yamls/"}
56 |
57 | options.TestDirs = args
58 | options.Timeout = 180
59 | options.Parallel = 1
60 | options.TestDirs = manifestDirs
61 | options.StartKIND = false
62 | options.SkipDelete = false
63 |
64 | if options.KINDContext == "" {
65 | options.KINDContext = harness.DefaultKINDContext
66 | }
67 |
68 | serviceMeshConfObj := SMIConformance{
69 | SMObj: meshConfig,
70 | }
71 |
72 | if len(args) != 0 {
73 | options.TestDirs = args
74 | }
75 |
76 | testHandlers := make(map[string]map[string]test.CustomTest)
77 | testHandlers["traffic-access"] = serviceMeshConfObj.TrafficAccessGetTests()
78 | testHandlers["traffic-spec"] = serviceMeshConfObj.TrafficSpecGetTests()
79 | testHandlers["traffic-split"] = serviceMeshConfObj.TrafficSplitGetTests()
80 |
81 | testutils.RunTests("kudo", testToRun, options.Parallel, func(t *testing.T) {
82 | harness := test.Harness{
83 | TestSuite: options,
84 | T: t,
85 | SuiteCustomTests: testHandlers,
86 | NamespaceAnnotations: annotations,
87 | NamespaceLabels: labels,
88 | }
89 |
90 | // Runs the test using the inCluster kubeConfig (runs only when the code is running inside the pod)
91 | harness.InCluster = true
92 |
93 | s, _ := json.MarshalIndent(options, "", " ")
94 | fmt.Printf("Running integration tests with following options:\n%s\n", string(s))
95 | results = harness.Run()
96 | data, _ := json.Marshal(results)
97 | // Results of the test
98 | fmt.Printf("Results :\n%v\n", string(data))
99 | err := json.Unmarshal([]byte(data), &output)
100 | if err != nil {
101 | fmt.Printf("Unable to unmarshal results")
102 | }
103 | c <- output
104 | time.Sleep(30 * time.Second)
105 | })
106 | }()
107 | return <-c
108 | }
109 |
--------------------------------------------------------------------------------
/deploy/k8s-consul.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: ServiceAccount
3 | metadata:
4 | name: service-a
5 | automountServiceAccountToken: false
6 | ---
7 | apiVersion: v1
8 | kind: ServiceAccount
9 | metadata:
10 | name: service-b
11 | automountServiceAccountToken: false
12 | ---
13 | apiVersion: v1
14 | kind: ServiceAccount
15 | metadata:
16 | name: service-c
17 | automountServiceAccountToken: false
18 | ---
19 | apiVersion: apps/v1
20 | kind: Deployment
21 | metadata:
22 | name: service-a-deployment
23 | labels:
24 | app: service-a
25 | spec:
26 | replicas: 1
27 | selector:
28 | matchLabels:
29 | app: service-a
30 | template:
31 | metadata:
32 | name: service-a
33 | labels:
34 | app: service-a
35 | annotations:
36 | 'consul.hashicorp.com/connect-inject': 'true'
37 | 'consul.hashicorp.com/connect-service-upstreams': 'service-b:9092'
38 | spec:
39 | serviceAccountName: service-a
40 | automountServiceAccountToken: true
41 | containers:
42 | - name: service-a
43 | image: layer5/learn-layer5:latest
44 | ports:
45 | - containerPort: 9091
46 | name: http
47 | env:
48 | - name: SERVICE_NAME
49 | value: "Service-a"
50 | ---
51 | apiVersion: apps/v1
52 | kind: Deployment
53 | metadata:
54 | name: service-b-deployment
55 | labels:
56 | app: service-b
57 | spec:
58 | replicas: 1
59 | selector:
60 | matchLabels:
61 | app: service-b
62 | template:
63 | metadata:
64 | name: service-b
65 | annotations:
66 | 'consul.hashicorp.com/connect-inject': 'true'
67 | "consul.hashicorp.com/connect-service": "service-b"
68 | labels:
69 | app: service-b
70 | spec:
71 | serviceAccountName: service-b
72 | automountServiceAccountToken: true
73 | containers:
74 | - name: service-b
75 | image: layer5/learn-layer5:latest
76 | ports:
77 | - containerPort: 9091
78 | env:
79 | - name: SERVICE_NAME
80 | value: "Service-b"
81 | ---
82 | apiVersion: apps/v1
83 | kind: Deployment
84 | metadata:
85 | name: service-c-deployment
86 | labels:
87 | app: service-c
88 | spec:
89 | replicas: 1
90 | selector:
91 | matchLabels:
92 | app: service-c
93 | template:
94 | metadata:
95 | name: service-c
96 | annotations:
97 | 'consul.hashicorp.com/connect-inject': 'true'
98 | "consul.hashicorp.com/connect-service": "service-c"
99 | labels:
100 | app: service-c
101 | spec:
102 | serviceAccountName: service-c
103 | automountServiceAccountToken: true
104 | containers:
105 | - name: service-c
106 | image: layer5/learn-layer5:latest
107 | ports:
108 | - containerPort: 9091
109 | env:
110 | - name: SERVICE_NAME
111 | value: "Service-c"
112 | ---
113 | apiVersion: v1
114 | kind: Service
115 | metadata:
116 | name: app-a
117 | spec:
118 | type: LoadBalancer
119 | selector:
120 | app: app-a
121 | ports:
122 | - name: http
123 | protocol: TCP
124 | port: 9091
125 | # targetPort: 9091
126 | ---
127 | apiVersion: v1
128 | kind: Service
129 | metadata:
130 | name: app-b
131 | spec:
132 | type: LoadBalancer
133 | selector:
134 | app: app-b
135 | ports:
136 | - name: http
137 | protocol: TCP
138 | port: 9091
139 | # targetPort: 9091
140 | ---
141 | apiVersion: v1
142 | kind: Service
143 | metadata:
144 | name: app-c
145 | spec:
146 | type: LoadBalancer
147 | selector:
148 | app: app-c
149 | ports:
150 | - name: http
151 | protocol: TCP
152 | port: 9091
153 | # targetPort: 9091
154 |
--------------------------------------------------------------------------------
/img/readme/meshery-logo-light-text.svg:
--------------------------------------------------------------------------------
1 | meshery-logo-light-text
--------------------------------------------------------------------------------
/smi-conformance/test-gen/service-mesh.go:
--------------------------------------------------------------------------------
1 | package test_gen
2 |
3 | import "fmt"
4 |
5 | // SMIConformance holds the SMI conformance tests
6 | type SMIConformance struct {
7 | SMObj ServiceMesh
8 | }
9 |
10 | // ServiceMesh provides an abstract interface for different service meshes.
11 | // This is required as each service mesh has different ways to expose their internals.
12 | type ServiceMesh interface {
13 | SvcAGetInternalName(string) string
14 | SvcBGetInternalName(string) string
15 | SvcCGetInternalName(string) string
16 |
17 | SvcAGetPort() string
18 | SvcBGetPort() string
19 | SvcCGetPort() string
20 | }
21 |
22 | type Maesh struct {
23 | PortSvcA string
24 | PortSvcB string
25 | PortSvcC string
26 | }
27 |
28 | func (sm Maesh) SvcAGetInternalName(namespace string) string {
29 | return fmt.Sprintf("http://%s.%s.maesh:%s", SvcNameA, namespace, sm.PortSvcA)
30 | }
31 |
32 | func (sm Maesh) SvcBGetInternalName(namespace string) string {
33 | return fmt.Sprintf("http://%s.%s.maesh:%s", SvcNameB, namespace, sm.PortSvcB)
34 | }
35 |
36 | func (sm Maesh) SvcCGetInternalName(namespace string) string {
37 | return fmt.Sprintf("http://%s.%s.maesh:%s", SvcNameC, namespace, sm.PortSvcC)
38 | }
39 |
40 | func (sm Maesh) SvcAGetPort() string {
41 | return sm.PortSvcA
42 | }
43 |
44 | func (sm Maesh) SvcBGetPort() string {
45 | return sm.PortSvcB
46 | }
47 |
48 | func (sm Maesh) SvcCGetPort() string {
49 | return sm.PortSvcC
50 | }
51 |
52 | type Linkerd struct {
53 | PortSvcA string
54 | PortSvcB string
55 | PortSvcC string
56 | }
57 |
58 | func (sm Linkerd) SvcAGetInternalName(namespace string) string {
59 | return fmt.Sprintf("http://%s.%s..svc.cluster.local.:%s", SvcNameA, namespace, sm.PortSvcA)
60 | }
61 |
62 | func (sm Linkerd) SvcBGetInternalName(namespace string) string {
63 | return fmt.Sprintf("http://%s.%s..svc.cluster.local.:%s", SvcNameB, namespace, sm.PortSvcB)
64 | }
65 |
66 | func (sm Linkerd) SvcCGetInternalName(namespace string) string {
67 | return fmt.Sprintf("http://%s.%s..svc.cluster.local.:%s", SvcNameC, namespace, sm.PortSvcC)
68 | }
69 |
70 | func (sm Linkerd) SvcAGetPort() string {
71 | return sm.PortSvcA
72 | }
73 |
74 | func (sm Linkerd) SvcBGetPort() string {
75 | return sm.PortSvcB
76 | }
77 |
78 | func (sm Linkerd) SvcCGetPort() string {
79 | return sm.PortSvcC
80 | }
81 |
82 | type Istio struct {
83 | PortSvcA string
84 | PortSvcB string
85 | PortSvcC string
86 | }
87 |
88 | func (sm Istio) SvcAGetInternalName(namespace string) string {
89 | return fmt.Sprintf("http://%s.%s..svc.cluster.local.:%s", SvcNameA, namespace, sm.PortSvcA)
90 | }
91 |
92 | func (sm Istio) SvcBGetInternalName(namespace string) string {
93 | return fmt.Sprintf("http://%s.%s..svc.cluster.local.:%s", SvcNameB, namespace, sm.PortSvcB)
94 | }
95 |
96 | func (sm Istio) SvcCGetInternalName(namespace string) string {
97 | return fmt.Sprintf("http://%s.%s..svc.cluster.local.:%s", SvcNameC, namespace, sm.PortSvcC)
98 | }
99 |
100 | func (sm Istio) SvcAGetPort() string {
101 | return sm.PortSvcA
102 | }
103 |
104 | func (sm Istio) SvcBGetPort() string {
105 | return sm.PortSvcB
106 | }
107 |
108 | func (sm Istio) SvcCGetPort() string {
109 | return sm.PortSvcC
110 | }
111 |
112 | type OSM struct {
113 | PortSvcA string
114 | PortSvcB string
115 | PortSvcC string
116 | }
117 |
118 | func (sm OSM) SvcAGetInternalName(namespace string) string {
119 | return fmt.Sprintf("http://%s.%s..svc.cluster.local.:%s", SvcNameA, namespace, sm.PortSvcA)
120 | }
121 |
122 | func (sm OSM) SvcBGetInternalName(namespace string) string {
123 | return fmt.Sprintf("http://%s.%s..svc.cluster.local.:%s", SvcNameB, namespace, sm.PortSvcB)
124 | }
125 |
126 | func (sm OSM) SvcCGetInternalName(namespace string) string {
127 | return fmt.Sprintf("http://%s.%s..svc.cluster.local.:%s", SvcNameC, namespace, sm.PortSvcC)
128 | }
129 |
130 | func (sm OSM) SvcAGetPort() string {
131 | return sm.PortSvcA
132 | }
133 |
134 | func (sm OSM) SvcBGetPort() string {
135 | return sm.PortSvcB
136 | }
137 |
138 | func (sm OSM) SvcCGetPort() string {
139 | return sm.PortSvcC
140 | }
141 |
--------------------------------------------------------------------------------
/deploy/maesh.yaml:
--------------------------------------------------------------------------------
1 | # Default values for Maesh.
2 | image:
3 | name: containous/maesh
4 | # (Optional)
5 | # pullPolicy: IfNotPresent
6 | # (Optional)
7 | # tag: v1.1.0
8 | # (Optional)
9 | # pullSecret: xxx
10 |
11 | acl: true
12 |
13 | kubedns: true
14 |
15 | # clusterDomain: cluster.local
16 |
17 | # logLevel: error
18 | # logFormat: common
19 |
20 | # defaultMode: http
21 |
22 | limits:
23 | http: 10
24 | tcp: 25
25 | udp: 25
26 |
27 | controller:
28 | # logLevel: error
29 | # logFormat: common
30 |
31 | # ignoreNamespaces:
32 | # - example
33 |
34 | # watchNamespaces:
35 | # - example
36 |
37 | resources:
38 | limit:
39 | mem: 100Mi
40 | cpu: 200m
41 | request:
42 | mem: 50Mi
43 | cpu: 100m
44 |
45 | # Added so we can launch on nodes with restrictions.
46 | nodeSelector: {}
47 | tolerations: []
48 | affinity: {}
49 |
50 | mesh:
51 | # (Deprecated)
52 | # defaultMode: http
53 |
54 | # logLevel: error
55 | # logFormat: common
56 |
57 | # pollInterval: 1s
58 | # pollTimeout: 1s
59 |
60 | # forwardingTimeouts:
61 | # dialTimeout: 30s
62 | # (Optional)
63 | # responseHeaderTimeout: 0s
64 | # (Optional)
65 | # idleConnTimeout: 1s
66 |
67 | # env:
68 | # - name: NAME
69 | # value: "value"
70 |
71 | # envFrom:
72 | # - configMapRef:
73 | # name: config
74 |
75 | # additionalArguments:
76 | # - "--name=value"
77 |
78 | resources:
79 | limit:
80 | mem: 100Mi
81 | cpu: 200m
82 | request:
83 | mem: 50Mi
84 | cpu: 100m
85 |
86 | # Added so we can launch on nodes with restrictions.
87 | nodeSelector: {}
88 | tolerations: []
89 |
90 | # Additional deployment annotations.
91 | # annotations: {}
92 |
93 | # Additional pod annotations.
94 | # podAnnotations: {}
95 |
96 | #
97 | # Tracing configuration.
98 | #
99 | tracing:
100 | deploy: false
101 | jaeger:
102 | image:
103 | name: groundnuty/k8s-wait-for:v1.3
104 | enabled: false
105 | localagenthostport: ""
106 | samplingserverurl: ""
107 | # datadog:
108 | # localagenthostport: "127.0.0.1:8126"
109 | # (Optional)
110 | # debug: true
111 | # (Optional)
112 | # globalTag: "sample"
113 | # (Optional)
114 | # prioritySampling: true
115 | # zipkin:
116 | # httpEndpoint: "127.0.0.1:8125"
117 | # (Optional)
118 | # sameSpan: true
119 | # (Optional)
120 | # id128Bit: true
121 | # (Optional)
122 | # sampleRate: 0.2
123 | # instana:
124 | # localAgentHost: "127.0.0.1"
125 | # localAgentPort: 42699
126 | # logLevel: info
127 | # haystack:
128 | # localAgentHost: "127.0.0.1"
129 | # localAgentPort: 42699
130 | # (Optional)
131 | # globalTag: "sample:test"
132 | # (Optional)
133 | # traceIDHeaderName: "sample"
134 | # (Optional)
135 | # parentIDHeaderName: "sample"
136 | # (Optional)
137 | # spanIDHeaderName: "sample"
138 | # (Optional)
139 | # baggagePrefixHeaderName: "sample"
140 |
141 | #
142 | # Metrics configuration.
143 | #
144 | metrics:
145 | deploy: false
146 | prometheus:
147 | # whether to expose Prometheus metrics
148 | enabled: false
149 | ## you can override values of the metrics subchart here.
150 | ## check charts/metrics/values.yaml for the defaults.
151 | ## example:
152 | # grafana:
153 | # storageClassName: "metrics-storage"
154 | # resources:
155 | # limit:
156 | # mem: "500Mi"
157 | # cpu: "500m"
158 | # request:
159 | # mem: "200Mi"
160 | # cpu: "200m"
161 | # datadog:
162 | # address: "127.0.0.1:8125"
163 | # (Optional)
164 | # addEntrypointsLabels: true
165 | # (Optional)
166 | # addServiceLabels: true
167 | # (Optional)
168 | # pushInterval: 10s
169 | # influxdb:
170 | # address: "localhost:8089"
171 | # protocol: "udp"
172 | # (Optional)
173 | # database: "db"
174 | # (Optional)
175 | # retentionPolicy: "two_hours"
176 | # (Optional)
177 | # username: "john"
178 | # (Optional)
179 | # password: "secret"
180 | # (Optional)
181 | # addEntrypointsLabels: true
182 | # (Optional)
183 | # addServiceLabels: true
184 | # (Optional)
185 | # pushInterval: 10s
186 | # statsd:
187 | # address: "127.0.0.1:8125"
188 | # (Optional)
189 | # addEntrypointsLabels: true
190 | # (Optional)
191 | # addServiceLabels: true
192 | # (Optional)
193 | # pushInterval: 10s
194 |
--------------------------------------------------------------------------------
/.github/label-commenter-config.yml:
--------------------------------------------------------------------------------
1 | comment:
2 | # header: "Please note the following requirement:"
3 | footer: "\
4 | ---\n\n
5 | > Be sure to [join the community](https://slack.meshery.io), if you haven't yet and please leave a :star: [star on the project](../stargazers) :smile:
6 | "
7 |
8 | labels:
9 | - name: issue/design required
10 | labeled:
11 | issue:
12 | body: This issue has been labeled with 'design-required'. Note that prior to commencing on implementation, a design specification needs to be created and reviewed for approval. See [Creating a Functional Specification](https://docs.google.com/document/d/1RP3IWLc-MiQS-QYasqCoVuCH7--G87p5ezE5f_nOzB8/edit?usp=sharing) to create a design spec.
13 | action: open
14 | - name: issue/remind
15 | labeled:
16 | issue:
17 | body: Checking in... it has been awhile since we've heard from you on this issue. Are you still working on it? Please let us know and please don't hesitate to contact a [MeshMate](https://layer5.io/community/meshmates/) or any other [community member](https://layer5.io/community/members) for assistance.
18 | action: open
19 | pr:
20 | body: Checking in... it has been awhile since we've heard from you on this issue. Are you still working on it? Please let us know and please don't hesitate to contact a [MeshMate](https://layer5.io/community/meshmates/) or any other [community member](https://layer5.io/community/members) for assistance.
21 | action: open
22 | - name: issue/dco
23 | labeled:
24 | issue:
25 | body: "🚨 Alert! Git Police! We couldn’t help but notice that one or more of your commits is missing a sign-off. _A what?_ A commit sign-off (your email address).\n\n
26 | To amend the commits in this PR with your signoff using the instructions provided in the DCO check. \n\n
27 | To configure your dev environment to automatically signoff on your commits in the future, see [these instructions](https://github.com/meshery/meshery/blob/master/CONTRIBUTING.md#signing-off-on-commits-developer-certificate-of-origin)."
28 | action: open
29 | pr:
30 | body: "🚨 Alert! Git Police! We couldn’t help but notice that one or more of your commits is missing a sign-off. _A what?_ A commit sign-off (your email address).\n\n
31 | To amend the commits in this PR with your signoff using the instructions provided in the DCO check. \n\n
32 | To configure your dev environment to automatically signoff on your commits in the future, see [these instructions](https://github.com/meshery/meshery/blob/master/CONTRIBUTING.md#signing-off-on-commits-developer-certificate-of-origin)."
33 | action: open
34 | - name: component/ui
35 | labeled:
36 | issue:
37 | body: This issue has been labeled with 'component/ui'. 🧰 Here are docs on [Contributing to Meshery UI](https://docs.meshery.io/project/contributing/contributing-ui). 🎨 Here is the [Meshery UI Figma File](https://www.figma.com/file/SMP3zxOjZztdOLtgN4dS2W/Meshery-UI?node-id=4%3A0) File. Lastly, here are docs on [Contributing to Meshery's End-to-End Tests Using Cypress](https://docs.meshery.io/project/contributing/contributing-cypress).
38 | action: open
39 | pr:
40 | body: This PR has been labeled with 'component/ui'. 🧰 Here are docs on [Contributing to Meshery UI](https://docs.meshery.io/project/contributing/contributing-ui). 🎨 Here is the [Meshery UI Figma File](https://www.figma.com/file/SMP3zxOjZztdOLtgN4dS2W/Meshery-UI?node-id=4%3A0) File. Lastly, here are docs on [Contributing to Meshery's End-to-End Tests Using Cypress](https://docs.meshery.io/project/contributing/contributing-cypress)
41 | action: open
42 | - name: component/mesheryctl
43 | labeled:
44 | issue:
45 | body: This issue has been labeled with 'component/mesheryctl'. Note that after making changes you need to update it in the [mesheryctl command tracker](https://docs.google.com/spreadsheets/d/1q63sIGAuCnIeDs8PeM-0BAkNj8BBgPUXhLbe1Y-318o/edit#gid=0) spreadsheet.
46 | action: open
47 | pr:
48 | body: This PR has been labeled with 'component/mesheryctl'. Note that after making changes you need to update it in the [mesheryctl command tracker](https://docs.google.com/spreadsheets/d/1q63sIGAuCnIeDs8PeM-0BAkNj8BBgPUXhLbe1Y-318o/edit#gid=0) spreadsheet.
49 | action: open
50 | # pr:
51 | # body: Hi, please note that this issue will need an approved design specification before implementation proceeds. See [Creating a Functional Specification](https://docs.google.com/document/d/1RP3IWLc-MiQS-QYasqCoVuCH7--G87p5ezE5f_nOzB8/edit?usp=sharing) to create a design spec.
52 | # action: open
53 |
--------------------------------------------------------------------------------
/.github/workflows/label-commenter-config.yml:
--------------------------------------------------------------------------------
1 | comment:
2 | # header: "Please note the following requirement:"
3 | footer: "\
4 | ---\n\n
5 | > Be sure to [join the community](https://slack.meshery.io), if you haven't yet and please leave a :star: [star on the project](../stargazers) :smile:
6 | "
7 |
8 | labels:
9 | - name: issue/design required
10 | labeled:
11 | issue:
12 | body: This issue has been labeled with 'design-required'. Note that prior to commencing on implementation, a design specification needs to be created and reviewed for approval. See [Creating a Functional Specification](https://docs.google.com/document/d/1RP3IWLc-MiQS-QYasqCoVuCH7--G87p5ezE5f_nOzB8/edit?usp=sharing) to create a design spec.
13 | action: open
14 | - name: issue/remind
15 | labeled:
16 | issue:
17 | body: Checking in... it has been awhile since we've heard from you on this issue. Are you still working on it? Please let us know and please don't hesitate to contact a [MeshMate](https://layer5.io/community/meshmates/) or any other [community member](https://layer5.io/community/members) for assistance.
18 | action: open
19 | pr:
20 | body: Checking in... it has been awhile since we've heard from you on this issue. Are you still working on it? Please let us know and please don't hesitate to contact a [MeshMate](https://layer5.io/community/meshmates/) or any other [community member](https://layer5.io/community/members) for assistance.
21 | action: open
22 | - name: issue/dco
23 | labeled:
24 | issue:
25 | body: "🚨 Alert! Git Police! We couldn’t help but notice that one or more of your commits is missing a sign-off. _A what?_ A commit sign-off (your email address).\n\n
26 | To amend the commits in this PR with your signoff using the instructions provided in the DCO check. \n\n
27 | To configure your dev environment to automatically signoff on your commits in the future, see [these instructions](https://github.com/meshery/meshery/blob/master/CONTRIBUTING.md#signing-off-on-commits-developer-certificate-of-origin)."
28 | action: open
29 | pr:
30 | body: "🚨 Alert! Git Police! We couldn’t help but notice that one or more of your commits is missing a sign-off. _A what?_ A commit sign-off (your email address).\n\n
31 | To amend the commits in this PR with your signoff using the instructions provided in the DCO check. \n\n
32 | To configure your dev environment to automatically signoff on your commits in the future, see [these instructions](https://github.com/meshery/meshery/blob/master/CONTRIBUTING.md#signing-off-on-commits-developer-certificate-of-origin)."
33 | action: open
34 | - name: component/ui
35 | labeled:
36 | issue:
37 | body: This issue has been labeled with 'component/ui'. 🧰 Here are docs on [Contributing to Meshery UI](https://docs.meshery.io/project/contributing/contributing-ui). 🎨 Here is the [Meshery UI Figma File](https://www.figma.com/file/SMP3zxOjZztdOLtgN4dS2W/Meshery-UI?node-id=4%3A0) File. Lastly, here are docs on [Contributing to Meshery's End-to-End Tests Using Cypress](https://docs.meshery.io/project/contributing/contributing-cypress).
38 | action: open
39 | pr:
40 | body: This PR has been labeled with 'component/ui'. 🧰 Here are docs on [Contributing to Meshery UI](https://docs.meshery.io/project/contributing/contributing-ui). 🎨 Here is the [Meshery UI Figma File](https://www.figma.com/file/SMP3zxOjZztdOLtgN4dS2W/Meshery-UI?node-id=4%3A0) File. Lastly, here are docs on [Contributing to Meshery's End-to-End Tests Using Cypress](https://docs.meshery.io/project/contributing/contributing-cypress)
41 | action: open
42 | - name: component/mesheryctl
43 | labeled:
44 | issue:
45 | body: This issue has been labeled with 'component/mesheryctl'. Note that after making changes you need to update it in the [mesheryctl command tracker](https://docs.google.com/spreadsheets/d/1q63sIGAuCnIeDs8PeM-0BAkNj8BBgPUXhLbe1Y-318o/edit#gid=0) spreadsheet.
46 | action: open
47 | pr:
48 | body: This PR has been labeled with 'component/mesheryctl'. Note that after making changes you need to update it in the [mesheryctl command tracker](https://docs.google.com/spreadsheets/d/1q63sIGAuCnIeDs8PeM-0BAkNj8BBgPUXhLbe1Y-318o/edit#gid=0) spreadsheet.
49 | action: open
50 | # pr:
51 | # body: Hi, please note that this issue will need an approved design specification before implementation proceeds. See [Creating a Functional Specification](https://docs.google.com/document/d/1RP3IWLc-MiQS-QYasqCoVuCH7--G87p5ezE5f_nOzB8/edit?usp=sharing) to create a design spec.
52 | # action: open
53 |
54 |
55 |
--------------------------------------------------------------------------------
/smi-conformance/grpc/handlers.go:
--------------------------------------------------------------------------------
1 | package grpc
2 |
3 | import (
4 | "context"
5 | "regexp"
6 | "strconv"
7 |
8 | empty "github.com/golang/protobuf/ptypes/empty"
9 | "github.com/layer5io/learn-layer5/smi-conformance/conformance"
10 | test_gen "github.com/layer5io/learn-layer5/smi-conformance/test-gen"
11 | service "github.com/layer5io/service-mesh-performance/service"
12 | smp "github.com/layer5io/service-mesh-performance/spec"
13 | )
14 |
15 | var (
16 | maeshConfig = &test_gen.Maesh{
17 | PortSvcA: "9091",
18 | PortSvcB: "9091",
19 | PortSvcC: "9091",
20 | }
21 |
22 | linkerdConfig = &test_gen.Linkerd{
23 | PortSvcA: "9091",
24 | PortSvcB: "9091",
25 | PortSvcC: "9091",
26 | }
27 | istioConfig = &test_gen.Istio{
28 | PortSvcA: "9091",
29 | PortSvcB: "9091",
30 | PortSvcC: "9091",
31 | }
32 | osmConfig = &test_gen.OSM{
33 | PortSvcA: "9091",
34 | PortSvcB: "9091",
35 | PortSvcC: "9091",
36 | }
37 | )
38 |
39 | // RunTest return conformance response
40 | func (s *Service) RunTest(ctx context.Context, req *conformance.Request) (*conformance.Response, error) {
41 | var config test_gen.ServiceMesh
42 |
43 | config = linkerdConfig
44 | switch req.Mesh.Type {
45 | case smp.ServiceMesh_LINKERD:
46 | config = linkerdConfig
47 | req.Mesh.Annotations["linkerd.io/inject"] = "enabled"
48 | case smp.ServiceMesh_APP_MESH:
49 | config = linkerdConfig
50 | req.Mesh.Labels["appmesh.k8s.aws/sidecarInjectorWebhook"] = "enabled"
51 | case smp.ServiceMesh_MAESH:
52 | config = maeshConfig
53 | case smp.ServiceMesh_ISTIO:
54 | config = istioConfig
55 | req.Mesh.Labels["istio-injection"] = "enabled"
56 | case smp.ServiceMesh_OPEN_SERVICE_MESH:
57 | config = osmConfig
58 | req.Mesh.Labels["openservicemesh.io/monitored-by"] = "osm"
59 | case smp.ServiceMesh_KUMA:
60 | req.Mesh.Annotations["kuma.io/sidecar-injection"] = "enabled"
61 | case smp.ServiceMesh_NGINX_SERVICE_MESH:
62 | req.Mesh.Annotations["njector.nsm.nginx.com/auto-inject"] = "true"
63 |
64 | }
65 |
66 | result := test_gen.RunTest(config, req.Mesh.Annotations, req.Mesh.Labels)
67 | totalSteps := 24
68 | totalFailures := 0
69 | stepsCount := map[string]int{
70 | "traffic-access": 7,
71 | "traffic-split": 11,
72 | "traffic-spec": 6,
73 | }
74 | specVersion := map[string]string{
75 | "traffic-access": "v0.6.0/v1alpha3",
76 | "traffic-split": "v0.6.0/v1alpha4",
77 | "traffic-spec": "v0.6.0/v1alpha4",
78 | }
79 |
80 | details := make([]*conformance.Detail, 0)
81 | for _, res := range result.Testsuite[0].Testcase {
82 | d := &conformance.Detail{
83 | Smispec: res.Name,
84 | Specversion: specVersion[res.Name],
85 | Assertion: strconv.Itoa(stepsCount[res.Name]),
86 | Duration: res.Time,
87 | Capability: conformance.Capability_FULL,
88 | Status: conformance.ResultStatus_PASSED,
89 | Result: &conformance.Result{
90 | Result: &conformance.Result_Message{
91 | Message: "All test passed",
92 | },
93 | },
94 | }
95 | if len(res.Failure.Text) > 2 {
96 | d.Result = &conformance.Result{
97 | Result: &conformance.Result_Error{
98 | Error: &service.CommonError{
99 | Code: "",
100 | Severity: "",
101 | ShortDescription: res.Failure.Text,
102 | LongDescription: res.Failure.Message,
103 | ProbableCause: "",
104 | SuggestedRemediation: "",
105 | },
106 | },
107 | }
108 | d.Status = conformance.ResultStatus_FAILED
109 | d.Capability = conformance.Capability_NONE
110 |
111 | // A hacky way to see the testStep Failed, since KUDO only provides it in Failure.Message
112 | re := regexp.MustCompile(`[0-9]+`)
113 | if res.Failure.Message != "" {
114 | stepFailed := re.FindAllString(res.Failure.Message, 1)
115 | if len(stepFailed) != 0 {
116 | passed, _ := strconv.Atoi(stepFailed[0])
117 | passed = passed - 1
118 | failures := stepsCount[res.Name] - passed
119 | totalFailures += failures
120 | if (passed) >= (stepsCount[res.Name] / 2) {
121 | d.Capability = conformance.Capability_HALF
122 | }
123 | }
124 | }
125 | }
126 | details = append(details, d)
127 | }
128 |
129 | return &conformance.Response{
130 | Casespassed: strconv.Itoa(totalSteps - totalFailures),
131 | Passpercent: strconv.FormatFloat(float64(totalSteps-totalFailures)/float64(totalSteps)*100, 'f', 2, 64),
132 | Mesh: req.Mesh,
133 | Details: details,
134 | }, nil
135 | }
136 |
137 | func (s *Service) Info(context.Context, *empty.Empty) (*service.ServiceInfo, error) {
138 | return &service.ServiceInfo{}, nil
139 | }
140 |
141 | func (s *Service) Health(context.Context, *empty.Empty) (*service.ServiceHealth, error) {
142 | return &service.ServiceHealth{}, nil
143 | }
144 |
--------------------------------------------------------------------------------
/smi-conformance/test-gen/traffic-access.go:
--------------------------------------------------------------------------------
1 | package test_gen
2 |
3 | import (
4 | "bytes"
5 | "fmt"
6 | "testing"
7 | "time"
8 |
9 | "github.com/kudobuilder/kuttl/pkg/test"
10 | testutils "github.com/kudobuilder/kuttl/pkg/test/utils"
11 | "k8s.io/client-go/discovery"
12 | "sigs.k8s.io/controller-runtime/pkg/client"
13 | )
14 |
15 | func (smi *SMIConformance) TrafficAccessGetTests() map[string]test.CustomTest {
16 | testHandlers := make(map[string]test.CustomTest)
17 |
18 | testHandlers["trafficDefault"] = smi.trafficBlocked
19 | testHandlers["trafficAllowed"] = smi.trafficAllow
20 | testHandlers["trafficBlocked"] = smi.trafficBlocked
21 |
22 | return testHandlers
23 | }
24 |
25 | func (smi *SMIConformance) trafficBlocked(
26 | t *testing.T,
27 | namespace string,
28 | clientFn func(forceNew bool) (client.Client, error),
29 | DiscoveryClient func() (discovery.DiscoveryInterface, error),
30 | Logger testutils.Logger,
31 | ) []error {
32 | time.Sleep(5 * time.Second)
33 |
34 | httpClient := GetHTTPClient()
35 | kubeClient, err := clientFn(false)
36 | if err != nil {
37 | t.Fail()
38 | return []error{err}
39 | }
40 | clusterIPs, err := GetClusterIPs(kubeClient, namespace)
41 | if err != nil {
42 | t.Fail()
43 | return []error{err}
44 | }
45 | ClearAllMetrics(clusterIPs, smi.SMObj)
46 |
47 | // This test will make SERVICE A make a request to SERVICE B
48 | svcBTestURL := fmt.Sprintf("%s/%s", smi.SMObj.SvcBGetInternalName(namespace), ECHO)
49 | var jsonStr = []byte(`{"url":"` + svcBTestURL + `", "body":"", "method": "GET", "headers": {}}`)
50 |
51 | url := fmt.Sprintf("http://%s:%s/%s", clusterIPs[SvcNameA], smi.SMObj.SvcAGetPort(), CALL)
52 | _, err = httpClient.Post(url, "application/json", bytes.NewBuffer(jsonStr))
53 |
54 | Logger.Logf("URL : \n", url)
55 | Logger.Logf("Body : \n", string(jsonStr))
56 | if err != nil {
57 | t.Fail()
58 | Logger.Logf("Error : %s", err.Error())
59 | return []error{err}
60 | }
61 |
62 | metricsSvcA, err := GetMetrics(clusterIPs[SvcNameA], "9091")
63 | if err != nil {
64 | t.Fail()
65 | Logger.Logf("Error : %s", err.Error())
66 | return []error{err}
67 | }
68 |
69 | Logger.Log("Service A : Response Failed", metricsSvcA.RespFailed)
70 | Logger.Log("Service A : Response Succeeded", metricsSvcA.RespSucceeded)
71 | Logger.Log("Service A : Requests Received", metricsSvcA.ReqReceived)
72 |
73 | // Validates if the request failed
74 | if !(len(metricsSvcA.RespFailed) == 1 && len(metricsSvcA.RespSucceeded) == 0) {
75 | t.Fail()
76 | return nil
77 | }
78 | Logger.Log("Validated: Response count")
79 | if metricsSvcA.RespFailed[0].URL != svcBTestURL {
80 | t.Fail()
81 | return nil
82 | }
83 | Logger.Log("Validated: Response destination")
84 |
85 | Logger.Log("Done")
86 | return nil
87 | }
88 |
89 | func (smi *SMIConformance) trafficAllow(
90 | t *testing.T,
91 | namespace string,
92 | clientFn func(forceNew bool) (client.Client, error),
93 | DiscoveryClient func() (discovery.DiscoveryInterface, error),
94 | Logger testutils.Logger,
95 | ) []error {
96 | time.Sleep(5 * time.Second)
97 |
98 | httpClient := GetHTTPClient()
99 | kubeClient, err := clientFn(false)
100 | if err != nil {
101 | t.Fail()
102 | Logger.Logf("Error : %s", err.Error())
103 | return []error{err}
104 | }
105 | clusterIPs, err := GetClusterIPs(kubeClient, namespace)
106 | if err!=nil{
107 | t.Fail()
108 | Logger.Logf("Error : %s", err.Error())
109 | return []error{err}
110 | }
111 | ClearAllMetrics(clusterIPs, smi.SMObj)
112 |
113 | // This test will make SERVICE A make a request to SERVICE B
114 | svcBTestURL := fmt.Sprintf("%s/%s", smi.SMObj.SvcBGetInternalName(namespace), ECHO)
115 | var jsonStr = []byte(`{"url":"` + svcBTestURL + `", "body":"", "method": "GET", "headers": {}}`)
116 |
117 | url := fmt.Sprintf("http://%s:%s/%s", clusterIPs[SvcNameA], smi.SMObj.SvcAGetPort(), CALL)
118 | _, err = httpClient.Post(url, "application/json", bytes.NewBuffer(jsonStr))
119 |
120 | Logger.Logf("URL : \n", url)
121 | Logger.Logf("Body : \n", string(jsonStr))
122 | if err != nil {
123 | t.Fail()
124 | Logger.Logf("Error : %s", err.Error())
125 | return []error{err}
126 | }
127 |
128 | metricsSvcA, err := GetMetrics(clusterIPs[SvcNameA], "9091")
129 |
130 | if err != nil {
131 | t.Fail()
132 | Logger.Logf("Error : %s", err.Error())
133 | return []error{err}
134 | }
135 |
136 | Logger.Log("Service A : Response Failed", metricsSvcA.RespFailed)
137 | Logger.Log("Service A : Response Succeeded", metricsSvcA.RespSucceeded)
138 | Logger.Log("Service A : Requests Received", metricsSvcA.ReqReceived)
139 |
140 | // Validates if the request succeeded
141 | if !(len(metricsSvcA.RespFailed) == 0 && len(metricsSvcA.RespSucceeded) == 1) {
142 | t.Fail()
143 | return nil
144 | }
145 | Logger.Log("Validated: Response count")
146 |
147 | if metricsSvcA.RespSucceeded[0].URL != svcBTestURL {
148 | t.Fail()
149 | return nil
150 | }
151 | Logger.Log("Validated: Response destination")
152 |
153 | metricsSvcB, err := GetMetrics(clusterIPs[SvcNameB], "9091")
154 | if err != nil {
155 | t.Fail()
156 | Logger.Log("Error: ", err)
157 | return []error{err}
158 | }
159 |
160 | Logger.Log("Service B : Response Failed", metricsSvcB.RespFailed)
161 | Logger.Log("Service B : Response Succeeded", metricsSvcB.RespSucceeded)
162 | Logger.Log("Service B : Requests Received", metricsSvcB.ReqReceived)
163 |
164 | if !(len(metricsSvcB.ReqReceived) == 1) {
165 | t.Fail()
166 | return nil
167 | }
168 | Logger.Log("Validated: Request count")
169 | if metricsSvcB.ReqReceived[0] != "app-a" {
170 | t.Fail()
171 | return nil
172 | }
173 | Logger.Log("Validated: Request Source")
174 |
175 | Logger.Log("Done")
176 | return nil
177 | }
178 |
--------------------------------------------------------------------------------
/smi-conformance/test-gen/traffic-spec.go:
--------------------------------------------------------------------------------
1 | package test_gen
2 |
3 | import (
4 | "bytes"
5 | "fmt"
6 | "net/http"
7 | "testing"
8 | "time"
9 |
10 | "github.com/kudobuilder/kuttl/pkg/test"
11 | testutils "github.com/kudobuilder/kuttl/pkg/test/utils"
12 | "k8s.io/client-go/discovery"
13 | "sigs.k8s.io/controller-runtime/pkg/client"
14 | )
15 |
16 | func (smi *SMIConformance) TrafficSpecGetTests() map[string]test.CustomTest {
17 | testHandlers := make(map[string]test.CustomTest)
18 |
19 | testHandlers["trafficPath"] = smi.trafficPath
20 | testHandlers["trafficMethod"] = smi.trafficMethod
21 |
22 | return testHandlers
23 | }
24 |
25 | func (smi *SMIConformance) trafficPath(
26 | t *testing.T,
27 | namespace string,
28 | clientFn func(forceNew bool) (client.Client, error),
29 | DiscoveryClient func() (discovery.DiscoveryInterface, error),
30 | Logger testutils.Logger,
31 | ) []error {
32 | time.Sleep(5 * time.Second)
33 |
34 | httpClient := GetHTTPClient()
35 | kubeClient, err := clientFn(false)
36 | if err != nil {
37 | t.Fail()
38 | return []error{err}
39 | }
40 | clusterIPs, err := GetClusterIPs(kubeClient, namespace)
41 | if err!=nil{
42 | t.Fail()
43 | return []error{err}
44 | }
45 | ClearAllMetrics(clusterIPs, smi.SMObj)
46 |
47 | // call to SERVICE B metrics (allowed)
48 | svcBTestURLMetrics := fmt.Sprintf("%s/%s", smi.SMObj.SvcBGetInternalName(namespace), METRICS)
49 | jsonStr := []byte(`{"url":"` + svcBTestURLMetrics + `", "body":"", "method": "GET", "headers": {}}`)
50 |
51 | url := fmt.Sprintf("http://%s:%s/%s", clusterIPs[SvcNameA], smi.SMObj.SvcAGetPort(), CALL)
52 | _, err = httpClient.Post(url, "application/json", bytes.NewBuffer(jsonStr))
53 |
54 | Logger.Logf("URL : \n", url)
55 | Logger.Logf("Body : \n", string(jsonStr))
56 | if err != nil {
57 | t.Fail()
58 | Logger.Logf("Error : %s", err.Error())
59 | return []error{err}
60 | }
61 |
62 | // call to SERVICE B echo (blocked)
63 | svcBTestURLEcho := fmt.Sprintf("%s/%s", smi.SMObj.SvcBGetInternalName(namespace), ECHO)
64 | jsonStr = []byte(`{"url":"` + svcBTestURLEcho + `", "body":"", "method": "GET", "headers": {}}`)
65 |
66 | url = fmt.Sprintf("http://%s:%s/%s", clusterIPs[SvcNameA], smi.SMObj.SvcAGetPort(), CALL)
67 | _, err = httpClient.Post(url, "application/json", bytes.NewBuffer(jsonStr))
68 |
69 | if err != nil {
70 | t.Fail()
71 | return []error{err}
72 | }
73 |
74 | metricsSvcA, err := GetMetrics(clusterIPs[SvcNameA], "9091")
75 | if err != nil {
76 | t.Fail()
77 | Logger.Logf("Error : %s", err.Error())
78 | return []error{err}
79 | }
80 |
81 | Logger.Log("Service A : Response Failed", metricsSvcA.RespFailed)
82 | Logger.Log("Service A : Response Succeeded", metricsSvcA.RespSucceeded)
83 | Logger.Log("Service A : Requests Received", metricsSvcA.ReqReceived)
84 |
85 | // validates the requests that failed and the ones that succeeded
86 | if !(len(metricsSvcA.RespFailed) == 1 && len(metricsSvcA.RespSucceeded) == 1) {
87 | t.Fail()
88 | return nil
89 | }
90 | Logger.Log("Validated: Response count")
91 | if metricsSvcA.RespSucceeded[0].URL != svcBTestURLMetrics {
92 | t.Fail()
93 | return nil
94 | }
95 | Logger.Log("Validated: Allowed Path")
96 | if metricsSvcA.RespFailed[0].URL != svcBTestURLEcho {
97 | t.Fail()
98 | return nil
99 | }
100 | Logger.Log("Validated: Disallowed Path")
101 |
102 | Logger.Log("Done")
103 | return nil
104 | }
105 |
106 | func (smi *SMIConformance) trafficMethod(
107 | t *testing.T,
108 | namespace string,
109 | clientFn func(forceNew bool) (client.Client, error),
110 | DiscoveryClient func() (discovery.DiscoveryInterface, error),
111 | Logger testutils.Logger,
112 | ) []error {
113 | time.Sleep(5 * time.Second)
114 |
115 | httpClient := GetHTTPClient()
116 | kubeClient, err := clientFn(false)
117 | if err != nil {
118 | t.Fail()
119 | return []error{err}
120 | }
121 | clusterIPs, err := GetClusterIPs(kubeClient, namespace)
122 | if err != nil {
123 | t.Fail()
124 | return []error{err}
125 | }
126 | ClearAllMetrics(clusterIPs, smi.SMObj)
127 |
128 | // GET to echo (allowed)
129 | svcBTestURL := fmt.Sprintf("%s/%s", smi.SMObj.SvcBGetInternalName(namespace), ECHO)
130 | jsonStr := []byte(`{"url":"` + svcBTestURL + `", "body":"", "method": "GET", "headers": {}}`)
131 |
132 | url := fmt.Sprintf("http://%s:%s/%s", clusterIPs[SvcNameA], smi.SMObj.SvcAGetPort(), CALL)
133 | _, err = httpClient.Post(url, "application/json", bytes.NewBuffer(jsonStr))
134 |
135 | Logger.Logf("URL : \n", url)
136 | Logger.Logf("Body : \n", string(jsonStr))
137 | if err != nil {
138 | t.Fail()
139 | Logger.Logf("Error : %s", err.Error())
140 | return []error{err}
141 | }
142 |
143 | // POST to echo (blocked)
144 | jsonStr = []byte(`{"url":"` + svcBTestURL + `", "body":"", "method": "POST", "headers": {}}`)
145 |
146 | url = fmt.Sprintf("http://%s:%s/%s", clusterIPs[SvcNameA], smi.SMObj.SvcAGetPort(), CALL)
147 | _, err = httpClient.Post(url, "application/json", bytes.NewBuffer(jsonStr))
148 |
149 | Logger.Logf("URL : \n", url)
150 | Logger.Logf("Body : \n", string(jsonStr))
151 | if err != nil {
152 | t.Fail()
153 | Logger.Logf("Error : %s", err.Error())
154 | return []error{err}
155 | }
156 |
157 | metricsSvcA, err := GetMetrics(clusterIPs[SvcNameA], "9091")
158 | if err != nil {
159 | t.Fail()
160 | Logger.Logf("Error : %s", err.Error())
161 | return []error{err}
162 | }
163 |
164 | Logger.Log("Service A : Response Failed", metricsSvcA.RespFailed)
165 | Logger.Log("Service A : Response Succeeded", metricsSvcA.RespSucceeded)
166 | Logger.Log("Service A : Requests Received", metricsSvcA.ReqReceived)
167 |
168 | // validates the requests that failed and the ones that succeeded
169 | if !(len(metricsSvcA.RespFailed) == 1 && len(metricsSvcA.RespSucceeded) == 1) {
170 | t.Fail()
171 | return nil
172 | }
173 | Logger.Log("Validated: Response count")
174 | if metricsSvcA.RespSucceeded[0].Method != http.MethodGet {
175 | t.Fail()
176 | return nil
177 | }
178 | Logger.Log("Validated: Allowed Method")
179 | if metricsSvcA.RespFailed[0].Method != http.MethodPost {
180 | t.Fail()
181 | return nil
182 | }
183 | Logger.Log("Validated: Disallowed Method")
184 |
185 | Logger.Log("Done")
186 | return nil
187 | }
188 |
--------------------------------------------------------------------------------
/service/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "encoding/json"
5 | "io/ioutil"
6 | "net/http"
7 | "os"
8 | "strings"
9 | "sync"
10 |
11 | logrus "github.com/sirupsen/logrus"
12 | )
13 |
14 | type MetricsResponse struct {
15 | URL string
16 | Method string
17 | Headers map[string]interface{}
18 | }
19 |
20 | type Metrics struct {
21 | ReqReceived []string
22 | RespSucceeded []MetricsResponse
23 | RespFailed []MetricsResponse
24 | }
25 |
26 | var metricsObj Metrics
27 |
28 | var mutex sync.Mutex
29 |
30 | func execExclusive(fn func()) {
31 | defer mutex.Unlock()
32 | mutex.Lock()
33 | fn()
34 | }
35 |
36 | const serviceID = "ServiceName"
37 | const defaultRequestID = "Default"
38 |
39 | var serviceName string
40 |
41 | func MetricsMiddleware(next http.Handler) http.Handler {
42 | return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
43 | execExclusive(func() {
44 | svcName := r.Header.Get(serviceID)
45 | if svcName == "" {
46 | svcName = "Unidentified"
47 | }
48 | metricsObj.ReqReceived = append(metricsObj.ReqReceived, svcName)
49 | })
50 | next.ServeHTTP(w, r)
51 | })
52 | }
53 |
54 | func call(w http.ResponseWriter, r *http.Request) {
55 | if r.Method != http.MethodPost {
56 | return
57 | }
58 |
59 | defer r.Body.Close()
60 |
61 | var data map[string]interface{}
62 | bytes, err := ioutil.ReadAll(r.Body)
63 | if err != nil {
64 | http.Error(w, "Error reading body", http.StatusBadRequest)
65 | logrus.Errorf("Error reading body: %s", err.Error())
66 | return
67 | }
68 | logrus.Debugf("request body: %v", string(bytes))
69 |
70 | if string(bytes) == "" {
71 | return
72 | }
73 |
74 | err = json.Unmarshal(bytes, &data)
75 | if err != nil {
76 | http.Error(w, "Error parsing body", http.StatusBadRequest)
77 | logrus.Errorf("Error parsing body: %s", err.Error())
78 | return
79 | }
80 |
81 | url := data["url"].(string)
82 | method := data["method"].(string)
83 | headers := data["headers"]
84 | body := data["body"].(string)
85 |
86 | var req *http.Request
87 | if method == http.MethodPost || method == http.MethodPatch || method == http.MethodPut {
88 | req, err = http.NewRequest(method, url, strings.NewReader(body))
89 | if err != nil {
90 | logrus.Errorf("Error creating request %s", err.Error())
91 | http.Error(w, "Error creating request", http.StatusBadRequest)
92 | return
93 | }
94 | } else {
95 | req, err = http.NewRequest(method, url, nil)
96 | if err != nil {
97 | logrus.Errorf("Error creating request %s", err.Error())
98 | http.Error(w, "Error creating request", http.StatusBadRequest)
99 | return
100 | }
101 | }
102 |
103 | client := http.Client{}
104 |
105 | if headers != nil {
106 | headers := headers.(map[string]interface{})
107 | for key, val := range headers {
108 | req.Header.Add(key, val.(string))
109 | }
110 | }
111 | req.Header.Add(serviceID, serviceName)
112 |
113 | resp, err := client.Do(req)
114 | if err != nil {
115 | logrus.Errorf("Error completing the request %s", err.Error())
116 | http.Error(w, "Error completing the request", http.StatusInternalServerError)
117 | return
118 | }
119 |
120 | logrus.Debugf("Call response: %v", resp)
121 | if err != nil {
122 | http.Error(w, "Error making the calling", http.StatusBadRequest)
123 | logrus.Errorf("Error making the calling: %s", err.Error())
124 | return
125 | }
126 |
127 | if resp.StatusCode >= 200 && resp.StatusCode < 400 {
128 | w.WriteHeader(http.StatusOK)
129 | execExclusive(func() {
130 | if headers != nil {
131 | headers := headers.(map[string]interface{})
132 | metricsObj.RespSucceeded = append(metricsObj.RespSucceeded, MetricsResponse{
133 | URL: url,
134 | Method: method,
135 | Headers: headers,
136 | })
137 | } else {
138 | metricsObj.RespSucceeded = append(metricsObj.RespSucceeded, MetricsResponse{
139 | URL: url,
140 | Method: method,
141 | })
142 | }
143 | })
144 | } else {
145 | execExclusive(func() {
146 | if headers != nil {
147 | headers := headers.(map[string]interface{})
148 | metricsObj.RespFailed = append(metricsObj.RespFailed, MetricsResponse{
149 | URL: url,
150 | Method: method,
151 | Headers: headers,
152 | })
153 | } else {
154 | metricsObj.RespFailed = append(metricsObj.RespFailed, MetricsResponse{
155 | URL: url,
156 | Method: method,
157 | })
158 | }
159 | })
160 | }
161 |
162 | bytes, err = ioutil.ReadAll(resp.Body)
163 | if err != nil {
164 | logrus.Errorf("Error parsing body: %s", err.Error())
165 | return
166 | }
167 | logrus.Debugf("Response body: %s", string(bytes))
168 | w.Write(bytes)
169 | }
170 |
171 | func echo(w http.ResponseWriter, req *http.Request) {
172 | req.Write(w)
173 | }
174 |
175 | func metrics(w http.ResponseWriter, req *http.Request) {
176 | if req.Method == http.MethodGet {
177 | w.Header().Set("Content-Type", "application/json")
178 | execExclusive(func() {
179 | if err := json.NewEncoder(w).Encode(&metricsObj); err != nil {
180 | w.WriteHeader(http.StatusInternalServerError)
181 | }
182 | })
183 | } else if req.Method == http.MethodDelete {
184 | execExclusive(func() {
185 | metricsObj = Metrics{
186 | RespSucceeded: []MetricsResponse{},
187 | RespFailed: []MetricsResponse{},
188 | ReqReceived: []string{},
189 | }
190 | })
191 | } else {
192 | http.Error(w, "Method not defined", http.StatusBadRequest)
193 | }
194 | }
195 |
196 | func main() {
197 | logrus.SetOutput(os.Stdout)
198 | logrus.SetLevel(logrus.DebugLevel)
199 |
200 | serviceName = os.Getenv("SERVICE_NAME")
201 | if serviceName == "" {
202 | serviceName = "Default"
203 | }
204 |
205 | port := os.Getenv("PORT")
206 | if port == "" {
207 | port = "9091"
208 | }
209 |
210 | metricsObj = Metrics{
211 | RespSucceeded: []MetricsResponse{},
212 | RespFailed: []MetricsResponse{},
213 | ReqReceived: []string{},
214 | }
215 |
216 | mux := http.NewServeMux()
217 |
218 | mux.Handle("/call", MetricsMiddleware(http.HandlerFunc(call)))
219 | mux.Handle("/metrics", http.HandlerFunc(metrics))
220 | mux.Handle("/echo", MetricsMiddleware(http.HandlerFunc(echo)))
221 | logrus.Infof("Started serving at: %s", port)
222 | http.ListenAndServe(":"+port, mux)
223 | }
224 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing Overview
2 | Please do! Thanks for your help improving the project! :balloon:
3 |
4 | All contributors are welcome. Please see the [newcomers welcome guide](https://docs.google.com/document/d/17OPtDE_rdnPQxmk2Kauhm3GwXF1R5dZ3Cj8qZLKdo5E/edit) for how, where and why to contribute. This project is community-built and welcomes collaboration. Contributors are expected to adhere to our [Code of Conduct](.CODE_OF_CONDUCT.md).
5 |
6 | Not sure where to start? First, see the [newcomers welcome guide](https://docs.google.com/document/d/17OPtDE_rdnPQxmk2Kauhm3GwXF1R5dZ3Cj8qZLKdo5E/edit). Grab an open issue with the [help-wanted label](../../labels/help%20wanted) and jump in. Join the [Slack account](http://slack.layer5.io) and engage in conversation. Create a [new issue](/../../issues/new/choose) if needed. All [pull requests](/../../pulls) should reference an open [issue](/../../issues). Include keywords in your pull request descriptions, as well as commit messages, to [automatically close issues in GitHub](https://help.github.com/en/github/managing-your-work-on-github/closing-issues-using-keywords).
7 |
8 | **Sections**
9 | - General Contribution Flow
10 | - Developer Certificate of Origin
11 |
12 | ## Issues & Pull Requests
13 |
14 | ### Creating an Issue
15 |
16 | Before **creating** an Issue i.e for `features`/`bugs`/`improvements` please follow these steps:
17 |
18 |
19 | 1. Search existing Issues before creating a new Issue (look to see if the Issue has already been created).
20 | 1. If it doesn't exist create a new Issue giving as much context as possible (please take note and select the correct Issue type, for example `bug`, `documentation` or `feature`.
21 | 1. If you wish to work on the Issue once it has been triaged, please include this in your Issue description.
22 |
23 | ### Working on an Issue
24 |
25 | Before working on an existing Issue please follow these steps:
26 |
27 | 1. Comment asking for the Issue to be assigned to you.
28 | 1. To best position yourself for Issues assignment, we recommend that you:
29 | 1. Confirm that you have read the CONTRIBUTING.md.
30 | 1. Have a functional development environment (have built and are able to run the project).
31 | 1. Convey your intended approach to solving the issue.
32 | 1. Put each of these items in writing in one or more comments.
33 | 1. After the Issue is assigned to you, you can start working on it.
34 | 1. In general, **only** start working on this Issue (and open a Pull Request) when it has been assigned to you. Doing so will prevent confusion, duplicate work (some of which may go unaccepted given its duplicity), incidental stepping on toes, and the headache involved for maintainers and contributors alike as Issue assignments collide and heads bump together.
35 | 1. Reference the Issue in your Pull Request (for example `This PR fixes #123`). so that the corresponding Issue is automatically closed upon merge of your Pull Request.
36 |
37 | > Notes:
38 | >
39 | > - Check the `Assignees` box at the top of the page to see if the Issue has been assigned to someone else before requesting this be assigned to you. If the issue has a current Assignee, but appears to be inactive, politely inquire with the current Assignee as to whether they are still working on a solution and/or if you might collaborate with them.
40 | > - Only request to be assigned an Issue if you know how to work on it.
41 | > - If an Issue is unclear, ask questions to get more clarity before asking to have the Issue assigned to you; avoid asking "what do I do next? how do I fix this?" (see the item above this line)
42 | > - An Issue can be assigned to multiple people, if you all agree to collaborate on the Issue (the Pull Request can contain commits from different collaborators)
43 | > - Any Issues that has no activity after 2 weeks will be unassigned and re-assigned to someone else.
44 |
45 | ## Reviewing Pull Requests
46 |
47 | We welcome everyone to review Pull Requests. It is a great way to learn, network, and support each other.
48 |
49 | ### DOs
50 |
51 | - Use inline comments to explain your suggestions
52 | - Use inline suggestions to propose changes
53 | - Exercise patience and empathy while offering critiques of the works of others.
54 |
55 | ### DON'Ts
56 |
57 | - Do not repeat feedback, this creates more noise than value (check the existing conversation), use GitHub reactions if you agree/disagree with a comment
58 | - Do not blindly approve Pull Requests to improve your GitHub contributors graph
59 |
60 |
61 | ## Signing-off on Commits (Developer Certificate of Origin)
62 |
63 | To contribute to this project, you must agree to the Developer Certificate of
64 | Origin (DCO) for each commit you make. The DCO is a simple statement that you,
65 | as a contributor, have the legal right to make the contribution.
66 |
67 | See the [DCO](https://developercertificate.org) file for the full text of what you must agree to
68 | and how it works [here](https://github.com/probot/dco#how-it-works).
69 | To signify that you agree to the DCO for contributions, you simply add a line to each of your
70 | git commit messages:
71 |
72 | ```
73 | Signed-off-by: Jane Smith
74 | ```
75 |
76 | In most cases, you can add this signoff to your commit automatically with the
77 | `-s` or `--signoff` flag to `git commit`. You must use your real name and a reachable email
78 | address (sorry, no pseudonyms or anonymous contributions). An example of signing off on a commit:
79 | ```
80 | $ commit -s -m “my commit message w/signoff”
81 | ```
82 |
83 | To ensure all your commits are signed, you may choose to add this alias to your global ```.gitconfig```:
84 |
85 | *~/.gitconfig*
86 | ```
87 | [alias]
88 | amend = commit -s --amend
89 | cm = commit -s -m
90 | commit = commit -s
91 | ```
92 | Or you may configure your IDE, for example, Visual Studio Code to automatically sign-off commits for you:
93 |
94 |
95 |
96 | # Reviews
97 | All contributors are invited to review pull requests. See this short video on [how to review a pull request](https://www.youtube.com/watch?v=isLfo7jfE6g&feature=youtu.be).
98 |
99 | # New to Git?
100 | Resources: https://lab.github.com and https://try.github.com/
101 |
102 | ### License
103 |
104 | This repository and site are available as open source under the terms of the [Apache 2.0 License](https://opensource.org/licenses/Apache-2.0).
105 |
--------------------------------------------------------------------------------
/smi-conformance/test-gen/traffic-split.go:
--------------------------------------------------------------------------------
1 | package test_gen
2 |
3 | import (
4 | "fmt"
5 | "testing"
6 | "time"
7 |
8 | "github.com/kudobuilder/kuttl/pkg/test"
9 | testutils "github.com/kudobuilder/kuttl/pkg/test/utils"
10 | "k8s.io/client-go/discovery"
11 | "sigs.k8s.io/controller-runtime/pkg/client"
12 | )
13 |
14 | const reqNo = 50
15 |
16 | // TrafficSplitGetTests return type of map[string]test.CustomTest
17 | func (smi *SMIConformance) TrafficSplitGetTests() map[string]test.CustomTest {
18 | testHandlers := make(map[string]test.CustomTest)
19 |
20 | testHandlers["trafficDefault"] = smi.trafficSplitDefault
21 | testHandlers["trafficOnlyB"] = smi.trafficSplitOnlyB
22 | testHandlers["trafficOnlyC"] = smi.trafficSplitOnlyC
23 | testHandlers["trafficBGrtC"] = smi.trafficSplitBGrtC
24 | testHandlers["trafficCGrtB"] = smi.trafficSplitCGrtB
25 |
26 | return testHandlers
27 | }
28 |
29 | // Executes a Test Scenario where SERVICE A makes a request to the service named `app-svc`
30 | func trafficSplitTestScenario(clusterIPs map[string]string, namespace string, smObj ServiceMesh) error {
31 | svcTrafficSplit := fmt.Sprintf("http://app-svc.%s.svc.cluster.local.:9091/%s", namespace, ECHO)
32 | jsonStr := []byte(`{"url":"` + svcTrafficSplit + `", "body":"", "method": "GET", "headers": {}}`)
33 |
34 | url := fmt.Sprintf("http://%s:%s/%s", clusterIPs[SvcNameA], smObj.SvcAGetPort(), CALL)
35 |
36 | return generatePOSTLoad(reqNo, url, jsonStr)
37 | }
38 |
39 | func (smi *SMIConformance) trafficSplitDefault(
40 | t *testing.T,
41 | namespace string,
42 | clientFn func(forceNew bool) (client.Client, error),
43 | DiscoveryClient func() (discovery.DiscoveryInterface, error),
44 | Logger testutils.Logger,
45 | ) []error {
46 | time.Sleep(5 * time.Second)
47 |
48 | kubeClient, err := clientFn(false)
49 | if err != nil {
50 | t.Fail()
51 | return []error{err}
52 | }
53 | clusterIPs, err := GetClusterIPs(kubeClient, namespace)
54 | if err != nil {
55 | t.Fail()
56 | return []error{err}
57 | }
58 | ClearAllMetrics(clusterIPs, smi.SMObj)
59 |
60 | if err = trafficSplitTestScenario(clusterIPs, namespace, smi.SMObj); err != nil {
61 | t.Fail()
62 | return []error{err}
63 | }
64 |
65 | metricsSvcB, err := GetMetrics(clusterIPs[SvcNameB], "9091")
66 | if err != nil {
67 | t.Fail()
68 | return []error{err}
69 | }
70 | Logger.Log("Service B : Requests Received", metricsSvcB.ReqReceived)
71 |
72 | metricsSvcC, err := GetMetrics(clusterIPs[SvcNameC], "9091")
73 | if err != nil {
74 | t.Fail()
75 | return []error{err}
76 | }
77 | Logger.Log("Service C : Requests Received", metricsSvcC.ReqReceived)
78 |
79 | if len(metricsSvcB.ReqReceived) == 0 || len(metricsSvcC.ReqReceived) == 0 {
80 | t.Fail()
81 | return nil
82 | }
83 | Logger.Log("Validated: Random Request count")
84 |
85 | Logger.Log("Done")
86 | return nil
87 | }
88 |
89 | func (smi *SMIConformance) trafficSplitOnlyB(
90 | t *testing.T,
91 | namespace string,
92 | clientFn func(forceNew bool) (client.Client, error),
93 | DiscoveryClient func() (discovery.DiscoveryInterface, error),
94 | Logger testutils.Logger,
95 | ) []error {
96 | time.Sleep(5 * time.Second)
97 |
98 | kubeClient, err := clientFn(false)
99 | if err != nil {
100 | t.Fail()
101 | return []error{err}
102 | }
103 | clusterIPs, err := GetClusterIPs(kubeClient, namespace)
104 | if err != nil {
105 | t.Fail()
106 | return []error{err}
107 | }
108 | ClearAllMetrics(clusterIPs, smi.SMObj)
109 |
110 | if err = trafficSplitTestScenario(clusterIPs, namespace, smi.SMObj); err != nil {
111 | t.Fail()
112 | return []error{err}
113 | }
114 |
115 | metricsSvcB, err := GetMetrics(clusterIPs[SvcNameB], "9091")
116 | if err != nil {
117 | t.Fail()
118 | return []error{err}
119 | }
120 | Logger.Log("Service B : Requests Received", metricsSvcB.ReqReceived)
121 |
122 | metricsSvcC, err := GetMetrics(clusterIPs[SvcNameC], "9091")
123 | if err != nil {
124 | t.Fail()
125 | return []error{err}
126 | }
127 | Logger.Log("Service C : Requests Received", metricsSvcC.ReqReceived)
128 |
129 | if !(len(metricsSvcB.ReqReceived) == reqNo && len(metricsSvcC.ReqReceived) == 0) {
130 | t.Fail()
131 | return nil
132 | }
133 | Logger.Log("Validated: C Request count zero")
134 |
135 | Logger.Log("Done")
136 | return nil
137 | }
138 |
139 | func (smi *SMIConformance) trafficSplitOnlyC(
140 | t *testing.T,
141 | namespace string,
142 | clientFn func(forceNew bool) (client.Client, error),
143 | DiscoveryClient func() (discovery.DiscoveryInterface, error),
144 | Logger testutils.Logger,
145 | ) []error {
146 | time.Sleep(5 * time.Second)
147 |
148 | kubeClient, err := clientFn(false)
149 | if err != nil {
150 | t.Fail()
151 | return []error{err}
152 | }
153 | clusterIPs, err := GetClusterIPs(kubeClient, namespace)
154 | if err != nil {
155 | t.Fail()
156 | return []error{err}
157 | }
158 | ClearAllMetrics(clusterIPs, smi.SMObj)
159 |
160 | if err = trafficSplitTestScenario(clusterIPs, namespace, smi.SMObj); err != nil {
161 | t.Fail()
162 | return []error{err}
163 | }
164 |
165 | metricsSvcB, err := GetMetrics(clusterIPs[SvcNameB], "9091")
166 | if err != nil {
167 | t.Fail()
168 | return []error{err}
169 | }
170 | Logger.Log("Service B : Requests Received", metricsSvcB.ReqReceived)
171 |
172 | metricsSvcC, err := GetMetrics(clusterIPs[SvcNameC], "9091")
173 | if err != nil {
174 | t.Fail()
175 | return []error{err}
176 | }
177 | Logger.Log("Service C : Requests Received", metricsSvcC.ReqReceived)
178 |
179 | if !(len(metricsSvcB.ReqReceived) == 0 && len(metricsSvcC.ReqReceived) == reqNo) {
180 | t.Fail()
181 | return nil
182 | }
183 | Logger.Log("Validated: B Request count zero")
184 |
185 | Logger.Log("Done")
186 | return nil
187 | }
188 |
189 | func (smi *SMIConformance) trafficSplitBGrtC(
190 | t *testing.T,
191 | namespace string,
192 | clientFn func(forceNew bool) (client.Client, error),
193 | DiscoveryClient func() (discovery.DiscoveryInterface, error),
194 | Logger testutils.Logger,
195 | ) []error {
196 | time.Sleep(5 * time.Second)
197 |
198 | kubeClient, err := clientFn(false)
199 | if err != nil {
200 | t.Fail()
201 | return []error{err}
202 | }
203 | clusterIPs, err := GetClusterIPs(kubeClient, namespace)
204 | if err != nil {
205 | t.Fail()
206 | return []error{err}
207 | }
208 | ClearAllMetrics(clusterIPs, smi.SMObj)
209 |
210 | if err = trafficSplitTestScenario(clusterIPs, namespace, smi.SMObj); err != nil {
211 | t.Fail()
212 | return []error{err}
213 | }
214 |
215 | metricsSvcB, err := GetMetrics(clusterIPs[SvcNameB], "9091")
216 | if err != nil {
217 | t.Fail()
218 | return []error{err}
219 | }
220 | Logger.Log("Service B : Requests Received", metricsSvcB.ReqReceived)
221 |
222 | metricsSvcC, err := GetMetrics(clusterIPs[SvcNameC], "9091")
223 | if err != nil {
224 | t.Fail()
225 | return []error{err}
226 | }
227 | Logger.Log("Service C : Requests Received", metricsSvcC.ReqReceived)
228 |
229 | if !(len(metricsSvcB.ReqReceived) > len(metricsSvcC.ReqReceived)) {
230 | t.Fail()
231 | return nil
232 | }
233 | Logger.Log("Validated: B Request count greater than C")
234 |
235 | Logger.Log("Done")
236 | return nil
237 | }
238 |
239 | func (smi *SMIConformance) trafficSplitCGrtB(
240 | t *testing.T,
241 | namespace string,
242 | clientFn func(forceNew bool) (client.Client, error),
243 | DiscoveryClient func() (discovery.DiscoveryInterface, error),
244 | Logger testutils.Logger,
245 | ) []error {
246 | time.Sleep(5 * time.Second)
247 |
248 | kubeClient, err := clientFn(false)
249 | if err != nil {
250 | t.Fail()
251 | return []error{err}
252 | }
253 | clusterIPs, err := GetClusterIPs(kubeClient, namespace)
254 | if err != nil {
255 | t.Fail()
256 | return []error{err}
257 | }
258 | ClearAllMetrics(clusterIPs, smi.SMObj)
259 |
260 | if err = trafficSplitTestScenario(clusterIPs, namespace, smi.SMObj); err != nil {
261 | t.Fail()
262 | return []error{err}
263 | }
264 |
265 | metricsSvcB, err := GetMetrics(clusterIPs[SvcNameB], "9091")
266 | if err != nil {
267 | t.Fail()
268 | return []error{err}
269 | }
270 | Logger.Log("Service B : Requests Received", metricsSvcB.ReqReceived)
271 |
272 | metricsSvcC, err := GetMetrics(clusterIPs[SvcNameC], "9091")
273 | if err != nil {
274 | t.Fail()
275 | return []error{err}
276 | }
277 | Logger.Log("Service C : Requests Received", metricsSvcC.ReqReceived)
278 |
279 | if !(len(metricsSvcB.ReqReceived) < len(metricsSvcC.ReqReceived)) {
280 | t.Fail()
281 | return nil
282 | }
283 | Logger.Log("Validated: C Request count greater than B")
284 |
285 | Logger.Log("Done")
286 | return nil
287 | }
288 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | 
10 | 
11 | [](https://hub.docker.com/r/layer5/learn-layer5)
12 | [](https://goreportcard.com/report/github.com/layer5io/learn-layer5)
13 | [](https://github.com/issues?utf8=✓&q=is%3Aopen+is%3Aissue+archived%3Afalse+org%3Alayer5io+label%3A%22help+wanted%22+")
14 | [](https://layer5.io)
15 | [](https://twitter.com/intent/follow?screen_name=mesheryio)
16 | [](http://slack.layer5.io)
17 | [](https://bestpractices.coreinfrastructure.org/projects/3564)
18 |
19 |
20 |
21 | # Learn to service mesh
22 |
23 | The "Learn Layer5" sample application is to be available for use across all service meshes that Meshery supports and is to used as:
24 |
25 | - a learning device (for [service mesh workshops](https://layer5.io/workshops))
26 | - for [Service Mesh Interface conformance](https://docs.google.com/document/d/1HL8Sk7NSLLj-9PRqoHYVIGyU6fZxUQFotrxbmfFtjwc/edit#)
27 |
28 | ## Application Architecture
29 | The Learn Layer5 application includes three services: `app-a`, `app-b`, and `app-c`. Though they are different services, they are defined using the same app (source code in ./service). Each service is listening on port `9091/tcp`.
30 |
31 | ### Service
32 |
33 | The following are the routes defined by the `service` app and their functionality.
34 |
35 | #### POST /call
36 |
37 | This route makes the service make requests to another service. Metrics are collected for this route. sample usage given below:
38 |
39 |
40 | ```shell
41 | # Command
42 | curl --location --request POST 'http://service-a:9091/call' \
43 | --header 'Content-Type: application/json' \
44 | --data-raw '{
45 | "url": "http://service-b:9091/call",
46 | "body": "{\r\n\"url\": \"http:\/\/service-c:9091\/echo\",\r\n\"body\": \"\",\r\n\"method\": \"GET\"\r\n}",
47 | "method": "POST",
48 | "headers": {
49 | "h1":"v1"
50 | }
51 | }'
52 |
53 | # No Output
54 | GET /echo HTTP/1.1
55 | Host: service-c:9091
56 | User-Agent: Go-http-client/1.1
57 | Accept-Encoding: gzip
58 | Servicename: Service-B
59 | ```
60 |
61 | In the above example, we are making a post request to `service-a` with the body:
62 | ```json
63 | {
64 | "url": "http://service-b:9091/call",
65 | "body": "{\r\n\"url\": \"http:\/\/service-c:9091\/echo\",\r\n\"body\": \"\",\r\n\"method\": \"GET\"\r\n}",
66 | "method": "POST",
67 | "headers": {
68 | "h1":"v1"
69 | }
70 | }
71 | ```
72 | This will make `service-a` to make a `POST` request to `http://service-b:9091/call` with the headers specified above, and the body:
73 | ```json
74 | {
75 | "url": "http://service-c:9091/echo",
76 | "body":"",
77 | "method": "GET"
78 | }
79 | ```
80 | This inturn will make `service-b` to make a `GET` request to `http://service-c:9091/echo`.
81 |
82 | #### GET /metrics
83 |
84 | Gets the metrics from `service-a`
85 | ```shell
86 | # Command
87 | curl --location --request GET 'http://service-b:9091/metrics'
88 | # Output
89 | {
90 | "ReqReceived": [
91 | "Service-A"
92 | ],
93 | "RespSucceeded": [
94 | {
95 | "URL": "http://service-c:9091/echo",
96 | "Method": "GET",
97 | "Headers": null
98 | }
99 | ],
100 | "RespFailed": []
101 | }
102 | ```
103 | * In ReqReceived we see list of requests `service-b` received and from whom it received. Here we see `service-A`. Actually each of the service sets a header `ServiceName` which is read by the service to determine the sender.
104 | * As `service-b` made a request to `service-c` and the request succeeded, we can see the details in the list of successful responses (RespSucceeded).
105 |
106 | #### DELETE /metrics
107 |
108 | Clears the counters in `service`
109 | ```shell
110 | # Command
111 | curl --location --request DELETE 'http://34.68.35.174:9091/metrics'
112 | # No Output
113 | ```
114 |
115 | > Note: metrics are collected only for `/call` and `/echo`.
116 |
117 | # Service Mesh Interface (SMI) Conformance
118 | The `learn-layer5` application serves as a sample application to validate the conformance of any service mesh with the SMI specifications. To verify SMI conformance, run Meshery and the Meshery adapter for the specific service mesh you wish to test. Invoke the suite of SMI conformance tests on the specific service mesh you would like to validate.
119 |
120 | ## Invoking conformance tests
121 |
122 | **As a Service Mesh user**
123 | Meshery allows you to schedule tests and invoke them programmatically. Meshery will store these test results and allow you to retrieve them later.
124 |
125 | **As a Service Mesh maker**
126 | Meshery guarantees provenance of these tests and facilitates the public publicing of this suite of tests results into a versioned, public matrix of conformance status (consisting of both supported capabilities and test compliance).
127 |
146 |
147 |
If you’re using Learn Layer5 or if you like the project, please ★ star this repository to show your support! 🤩
148 |
149 |
150 |
151 |
152 | Our projects are community-built and welcome collaboration. 👍 Be sure to see the Layer5 Community Welcome Guide for a tour of resources available to you and jump into our Slack ! Contributors are expected to adhere to the CNCF Code of Conduct .
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 | ✔️ Join any or all of the weekly meetings on the community calendar .
167 | ✔️ Watch community meeting recordings .
168 | ✔️ Access the community drive .
169 | ✔️ Discuss in the Community Forum .
170 |
171 |
172 | Not sure where to start? Grab an open issue with the help-wanted label .
173 |
174 |
175 | ## About Layer5
176 |
177 | [Layer5](https://layer5.io)'s cloud native application and infrastructure management software enables organizations to expect more from their infrastructure. We embrace developer-defined infrastructure. We empower engineer to change how they write applications, support operators in rethinking how they run modern infrastructure and enable product owners to regain full control over their product portfolio.
178 |
179 | **License**
180 |
181 | This repository and site are available as open source under the terms of the [Apache 2.0 License](https://opensource.org/licenses/Apache-2.0).
182 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright 2020 Layer5, Inc.
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/smi-conformance/conformance/conformance.pb.go:
--------------------------------------------------------------------------------
1 | // Code generated by protoc-gen-go. DO NOT EDIT.
2 | // versions:
3 | // protoc-gen-go v1.24.0
4 | // protoc v3.6.1
5 | // source: learn-layer5/smi-conformance/conformance/conformance.proto
6 |
7 | package conformance
8 |
9 | import (
10 | context "context"
11 | proto "github.com/golang/protobuf/proto"
12 | empty "github.com/golang/protobuf/ptypes/empty"
13 | service "github.com/layer5io/service-mesh-performance/service"
14 | spec "github.com/layer5io/service-mesh-performance/spec"
15 | grpc "google.golang.org/grpc"
16 | codes "google.golang.org/grpc/codes"
17 | status "google.golang.org/grpc/status"
18 | protoreflect "google.golang.org/protobuf/reflect/protoreflect"
19 | protoimpl "google.golang.org/protobuf/runtime/protoimpl"
20 | reflect "reflect"
21 | sync "sync"
22 | )
23 |
24 | const (
25 | // Verify that this generated code is sufficiently up-to-date.
26 | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
27 | // Verify that runtime/protoimpl is sufficiently up-to-date.
28 | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
29 | )
30 |
31 | // This is a compile-time assertion that a sufficiently up-to-date version
32 | // of the legacy proto package is being used.
33 | const _ = proto.ProtoPackageIsVersion4
34 |
35 | type Capability int32
36 |
37 | const (
38 | Capability_FULL Capability = 0
39 | Capability_HALF Capability = 1
40 | Capability_NONE Capability = 2
41 | )
42 |
43 | // Enum value maps for Capability.
44 | var (
45 | Capability_name = map[int32]string{
46 | 0: "FULL",
47 | 1: "HALF",
48 | 2: "NONE",
49 | }
50 | Capability_value = map[string]int32{
51 | "FULL": 0,
52 | "HALF": 1,
53 | "NONE": 2,
54 | }
55 | )
56 |
57 | func (x Capability) Enum() *Capability {
58 | p := new(Capability)
59 | *p = x
60 | return p
61 | }
62 |
63 | func (x Capability) String() string {
64 | return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
65 | }
66 |
67 | func (Capability) Descriptor() protoreflect.EnumDescriptor {
68 | return file_learn_layer5_smi_conformance_conformance_conformance_proto_enumTypes[0].Descriptor()
69 | }
70 |
71 | func (Capability) Type() protoreflect.EnumType {
72 | return &file_learn_layer5_smi_conformance_conformance_conformance_proto_enumTypes[0]
73 | }
74 |
75 | func (x Capability) Number() protoreflect.EnumNumber {
76 | return protoreflect.EnumNumber(x)
77 | }
78 |
79 | // Deprecated: Use Capability.Descriptor instead.
80 | func (Capability) EnumDescriptor() ([]byte, []int) {
81 | return file_learn_layer5_smi_conformance_conformance_conformance_proto_rawDescGZIP(), []int{0}
82 | }
83 |
84 | type TestStatus int32
85 |
86 | const (
87 | TestStatus_COMPLETED TestStatus = 0
88 | TestStatus_INPROGRESS TestStatus = 1
89 | TestStatus_CRASHED TestStatus = 2
90 | )
91 |
92 | // Enum value maps for TestStatus.
93 | var (
94 | TestStatus_name = map[int32]string{
95 | 0: "COMPLETED",
96 | 1: "INPROGRESS",
97 | 2: "CRASHED",
98 | }
99 | TestStatus_value = map[string]int32{
100 | "COMPLETED": 0,
101 | "INPROGRESS": 1,
102 | "CRASHED": 2,
103 | }
104 | )
105 |
106 | func (x TestStatus) Enum() *TestStatus {
107 | p := new(TestStatus)
108 | *p = x
109 | return p
110 | }
111 |
112 | func (x TestStatus) String() string {
113 | return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
114 | }
115 |
116 | func (TestStatus) Descriptor() protoreflect.EnumDescriptor {
117 | return file_learn_layer5_smi_conformance_conformance_conformance_proto_enumTypes[1].Descriptor()
118 | }
119 |
120 | func (TestStatus) Type() protoreflect.EnumType {
121 | return &file_learn_layer5_smi_conformance_conformance_conformance_proto_enumTypes[1]
122 | }
123 |
124 | func (x TestStatus) Number() protoreflect.EnumNumber {
125 | return protoreflect.EnumNumber(x)
126 | }
127 |
128 | // Deprecated: Use TestStatus.Descriptor instead.
129 | func (TestStatus) EnumDescriptor() ([]byte, []int) {
130 | return file_learn_layer5_smi_conformance_conformance_conformance_proto_rawDescGZIP(), []int{1}
131 | }
132 |
133 | type ResultStatus int32
134 |
135 | const (
136 | ResultStatus_PASSED ResultStatus = 0
137 | ResultStatus_FAILED ResultStatus = 1
138 | )
139 |
140 | // Enum value maps for ResultStatus.
141 | var (
142 | ResultStatus_name = map[int32]string{
143 | 0: "PASSED",
144 | 1: "FAILED",
145 | }
146 | ResultStatus_value = map[string]int32{
147 | "PASSED": 0,
148 | "FAILED": 1,
149 | }
150 | )
151 |
152 | func (x ResultStatus) Enum() *ResultStatus {
153 | p := new(ResultStatus)
154 | *p = x
155 | return p
156 | }
157 |
158 | func (x ResultStatus) String() string {
159 | return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
160 | }
161 |
162 | func (ResultStatus) Descriptor() protoreflect.EnumDescriptor {
163 | return file_learn_layer5_smi_conformance_conformance_conformance_proto_enumTypes[2].Descriptor()
164 | }
165 |
166 | func (ResultStatus) Type() protoreflect.EnumType {
167 | return &file_learn_layer5_smi_conformance_conformance_conformance_proto_enumTypes[2]
168 | }
169 |
170 | func (x ResultStatus) Number() protoreflect.EnumNumber {
171 | return protoreflect.EnumNumber(x)
172 | }
173 |
174 | // Deprecated: Use ResultStatus.Descriptor instead.
175 | func (ResultStatus) EnumDescriptor() ([]byte, []int) {
176 | return file_learn_layer5_smi_conformance_conformance_conformance_proto_rawDescGZIP(), []int{2}
177 | }
178 |
179 | type Request struct {
180 | state protoimpl.MessageState
181 | sizeCache protoimpl.SizeCache
182 | unknownFields protoimpl.UnknownFields
183 |
184 | Mesh *spec.ServiceMesh `protobuf:"bytes,1,opt,name=mesh,proto3" json:"mesh,omitempty"`
185 | }
186 |
187 | func (x *Request) Reset() {
188 | *x = Request{}
189 | if protoimpl.UnsafeEnabled {
190 | mi := &file_learn_layer5_smi_conformance_conformance_conformance_proto_msgTypes[0]
191 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
192 | ms.StoreMessageInfo(mi)
193 | }
194 | }
195 |
196 | func (x *Request) String() string {
197 | return protoimpl.X.MessageStringOf(x)
198 | }
199 |
200 | func (*Request) ProtoMessage() {}
201 |
202 | func (x *Request) ProtoReflect() protoreflect.Message {
203 | mi := &file_learn_layer5_smi_conformance_conformance_conformance_proto_msgTypes[0]
204 | if protoimpl.UnsafeEnabled && x != nil {
205 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
206 | if ms.LoadMessageInfo() == nil {
207 | ms.StoreMessageInfo(mi)
208 | }
209 | return ms
210 | }
211 | return mi.MessageOf(x)
212 | }
213 |
214 | // Deprecated: Use Request.ProtoReflect.Descriptor instead.
215 | func (*Request) Descriptor() ([]byte, []int) {
216 | return file_learn_layer5_smi_conformance_conformance_conformance_proto_rawDescGZIP(), []int{0}
217 | }
218 |
219 | func (x *Request) GetMesh() *spec.ServiceMesh {
220 | if x != nil {
221 | return x.Mesh
222 | }
223 | return nil
224 | }
225 |
226 | type Result struct {
227 | state protoimpl.MessageState
228 | sizeCache protoimpl.SizeCache
229 | unknownFields protoimpl.UnknownFields
230 |
231 | // Types that are assignable to Result:
232 | // *Result_Message
233 | // *Result_Error
234 | Result isResult_Result `protobuf_oneof:"result"`
235 | }
236 |
237 | func (x *Result) Reset() {
238 | *x = Result{}
239 | if protoimpl.UnsafeEnabled {
240 | mi := &file_learn_layer5_smi_conformance_conformance_conformance_proto_msgTypes[1]
241 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
242 | ms.StoreMessageInfo(mi)
243 | }
244 | }
245 |
246 | func (x *Result) String() string {
247 | return protoimpl.X.MessageStringOf(x)
248 | }
249 |
250 | func (*Result) ProtoMessage() {}
251 |
252 | func (x *Result) ProtoReflect() protoreflect.Message {
253 | mi := &file_learn_layer5_smi_conformance_conformance_conformance_proto_msgTypes[1]
254 | if protoimpl.UnsafeEnabled && x != nil {
255 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
256 | if ms.LoadMessageInfo() == nil {
257 | ms.StoreMessageInfo(mi)
258 | }
259 | return ms
260 | }
261 | return mi.MessageOf(x)
262 | }
263 |
264 | // Deprecated: Use Result.ProtoReflect.Descriptor instead.
265 | func (*Result) Descriptor() ([]byte, []int) {
266 | return file_learn_layer5_smi_conformance_conformance_conformance_proto_rawDescGZIP(), []int{1}
267 | }
268 |
269 | func (m *Result) GetResult() isResult_Result {
270 | if m != nil {
271 | return m.Result
272 | }
273 | return nil
274 | }
275 |
276 | func (x *Result) GetMessage() string {
277 | if x, ok := x.GetResult().(*Result_Message); ok {
278 | return x.Message
279 | }
280 | return ""
281 | }
282 |
283 | func (x *Result) GetError() *service.CommonError {
284 | if x, ok := x.GetResult().(*Result_Error); ok {
285 | return x.Error
286 | }
287 | return nil
288 | }
289 |
290 | type isResult_Result interface {
291 | isResult_Result()
292 | }
293 |
294 | type Result_Message struct {
295 | Message string `protobuf:"bytes,1,opt,name=message,proto3,oneof"`
296 | }
297 |
298 | type Result_Error struct {
299 | Error *service.CommonError `protobuf:"bytes,2,opt,name=error,proto3,oneof"`
300 | }
301 |
302 | func (*Result_Message) isResult_Result() {}
303 |
304 | func (*Result_Error) isResult_Result() {}
305 |
306 | type Detail struct {
307 | state protoimpl.MessageState
308 | sizeCache protoimpl.SizeCache
309 | unknownFields protoimpl.UnknownFields
310 |
311 | Smispec string `protobuf:"bytes,1,opt,name=smispec,proto3" json:"smispec,omitempty"`
312 | Specversion string `protobuf:"bytes,2,opt,name=specversion,proto3" json:"specversion,omitempty"`
313 | Assertion string `protobuf:"bytes,3,opt,name=assertion,proto3" json:"assertion,omitempty"`
314 | Duration string `protobuf:"bytes,4,opt,name=duration,proto3" json:"duration,omitempty"`
315 | Result *Result `protobuf:"bytes,5,opt,name=result,proto3" json:"result,omitempty"`
316 | Capability Capability `protobuf:"varint,6,opt,name=capability,proto3,enum=smi_conformance.Capability" json:"capability,omitempty"`
317 | Status ResultStatus `protobuf:"varint,7,opt,name=status,proto3,enum=smi_conformance.ResultStatus" json:"status,omitempty"`
318 | }
319 |
320 | func (x *Detail) Reset() {
321 | *x = Detail{}
322 | if protoimpl.UnsafeEnabled {
323 | mi := &file_learn_layer5_smi_conformance_conformance_conformance_proto_msgTypes[2]
324 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
325 | ms.StoreMessageInfo(mi)
326 | }
327 | }
328 |
329 | func (x *Detail) String() string {
330 | return protoimpl.X.MessageStringOf(x)
331 | }
332 |
333 | func (*Detail) ProtoMessage() {}
334 |
335 | func (x *Detail) ProtoReflect() protoreflect.Message {
336 | mi := &file_learn_layer5_smi_conformance_conformance_conformance_proto_msgTypes[2]
337 | if protoimpl.UnsafeEnabled && x != nil {
338 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
339 | if ms.LoadMessageInfo() == nil {
340 | ms.StoreMessageInfo(mi)
341 | }
342 | return ms
343 | }
344 | return mi.MessageOf(x)
345 | }
346 |
347 | // Deprecated: Use Detail.ProtoReflect.Descriptor instead.
348 | func (*Detail) Descriptor() ([]byte, []int) {
349 | return file_learn_layer5_smi_conformance_conformance_conformance_proto_rawDescGZIP(), []int{2}
350 | }
351 |
352 | func (x *Detail) GetSmispec() string {
353 | if x != nil {
354 | return x.Smispec
355 | }
356 | return ""
357 | }
358 |
359 | func (x *Detail) GetSpecversion() string {
360 | if x != nil {
361 | return x.Specversion
362 | }
363 | return ""
364 | }
365 |
366 | func (x *Detail) GetAssertion() string {
367 | if x != nil {
368 | return x.Assertion
369 | }
370 | return ""
371 | }
372 |
373 | func (x *Detail) GetDuration() string {
374 | if x != nil {
375 | return x.Duration
376 | }
377 | return ""
378 | }
379 |
380 | func (x *Detail) GetResult() *Result {
381 | if x != nil {
382 | return x.Result
383 | }
384 | return nil
385 | }
386 |
387 | func (x *Detail) GetCapability() Capability {
388 | if x != nil {
389 | return x.Capability
390 | }
391 | return Capability_FULL
392 | }
393 |
394 | func (x *Detail) GetStatus() ResultStatus {
395 | if x != nil {
396 | return x.Status
397 | }
398 | return ResultStatus_PASSED
399 | }
400 |
401 | type Response struct {
402 | state protoimpl.MessageState
403 | sizeCache protoimpl.SizeCache
404 | unknownFields protoimpl.UnknownFields
405 |
406 | Passpercent string `protobuf:"bytes,1,opt,name=passpercent,proto3" json:"passpercent,omitempty"`
407 | Casespassed string `protobuf:"bytes,2,opt,name=casespassed,proto3" json:"casespassed,omitempty"`
408 | Mesh *spec.ServiceMesh `protobuf:"bytes,3,opt,name=mesh,proto3" json:"mesh,omitempty"`
409 | Details []*Detail `protobuf:"bytes,5,rep,name=details,proto3" json:"details,omitempty"`
410 | }
411 |
412 | func (x *Response) Reset() {
413 | *x = Response{}
414 | if protoimpl.UnsafeEnabled {
415 | mi := &file_learn_layer5_smi_conformance_conformance_conformance_proto_msgTypes[3]
416 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
417 | ms.StoreMessageInfo(mi)
418 | }
419 | }
420 |
421 | func (x *Response) String() string {
422 | return protoimpl.X.MessageStringOf(x)
423 | }
424 |
425 | func (*Response) ProtoMessage() {}
426 |
427 | func (x *Response) ProtoReflect() protoreflect.Message {
428 | mi := &file_learn_layer5_smi_conformance_conformance_conformance_proto_msgTypes[3]
429 | if protoimpl.UnsafeEnabled && x != nil {
430 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
431 | if ms.LoadMessageInfo() == nil {
432 | ms.StoreMessageInfo(mi)
433 | }
434 | return ms
435 | }
436 | return mi.MessageOf(x)
437 | }
438 |
439 | // Deprecated: Use Response.ProtoReflect.Descriptor instead.
440 | func (*Response) Descriptor() ([]byte, []int) {
441 | return file_learn_layer5_smi_conformance_conformance_conformance_proto_rawDescGZIP(), []int{3}
442 | }
443 |
444 | func (x *Response) GetPasspercent() string {
445 | if x != nil {
446 | return x.Passpercent
447 | }
448 | return ""
449 | }
450 |
451 | func (x *Response) GetCasespassed() string {
452 | if x != nil {
453 | return x.Casespassed
454 | }
455 | return ""
456 | }
457 |
458 | func (x *Response) GetMesh() *spec.ServiceMesh {
459 | if x != nil {
460 | return x.Mesh
461 | }
462 | return nil
463 | }
464 |
465 | func (x *Response) GetDetails() []*Detail {
466 | if x != nil {
467 | return x.Details
468 | }
469 | return nil
470 | }
471 |
472 | var File_learn_layer5_smi_conformance_conformance_conformance_proto protoreflect.FileDescriptor
473 |
474 | var file_learn_layer5_smi_conformance_conformance_conformance_proto_rawDesc = []byte{
475 | 0x0a, 0x3a, 0x6c, 0x65, 0x61, 0x72, 0x6e, 0x2d, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x35, 0x2f, 0x73,
476 | 0x6d, 0x69, 0x2d, 0x63, 0x6f, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x63, 0x65, 0x2f, 0x63,
477 | 0x6f, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x63, 0x65, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x6f,
478 | 0x72, 0x6d, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x73, 0x6d,
479 | 0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x63, 0x65, 0x1a, 0x1b, 0x67,
480 | 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65,
481 | 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2c, 0x73, 0x65, 0x72, 0x76,
482 | 0x69, 0x63, 0x65, 0x2d, 0x6d, 0x65, 0x73, 0x68, 0x2d, 0x70, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x6d,
483 | 0x61, 0x6e, 0x63, 0x65, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x65, 0x72, 0x72,
484 | 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
485 | 0x65, 0x2d, 0x6d, 0x65, 0x73, 0x68, 0x2d, 0x70, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6e,
486 | 0x63, 0x65, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x68, 0x65, 0x61, 0x6c, 0x74,
487 | 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
488 | 0x2d, 0x6d, 0x65, 0x73, 0x68, 0x2d, 0x70, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x63,
489 | 0x65, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x70,
490 | 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x32, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2d, 0x6d, 0x65,
491 | 0x73, 0x68, 0x2d, 0x70, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x63, 0x65, 0x2f, 0x70,
492 | 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6d, 0x65,
493 | 0x73, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x2f, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75,
494 | 0x65, 0x73, 0x74, 0x12, 0x24, 0x0a, 0x04, 0x6d, 0x65, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28,
495 | 0x0b, 0x32, 0x10, 0x2e, 0x73, 0x6d, 0x70, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4d,
496 | 0x65, 0x73, 0x68, 0x52, 0x04, 0x6d, 0x65, 0x73, 0x68, 0x22, 0x5c, 0x0a, 0x06, 0x52, 0x65, 0x73,
497 | 0x75, 0x6c, 0x74, 0x12, 0x1a, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01,
498 | 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12,
499 | 0x2c, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14,
500 | 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x45,
501 | 0x72, 0x72, 0x6f, 0x72, 0x48, 0x00, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x42, 0x08, 0x0a,
502 | 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0xa3, 0x02, 0x0a, 0x06, 0x44, 0x65, 0x74, 0x61,
503 | 0x69, 0x6c, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x6d, 0x69, 0x73, 0x70, 0x65, 0x63, 0x18, 0x01, 0x20,
504 | 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x6d, 0x69, 0x73, 0x70, 0x65, 0x63, 0x12, 0x20, 0x0a, 0x0b,
505 | 0x73, 0x70, 0x65, 0x63, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28,
506 | 0x09, 0x52, 0x0b, 0x73, 0x70, 0x65, 0x63, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1c,
507 | 0x0a, 0x09, 0x61, 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28,
508 | 0x09, 0x52, 0x09, 0x61, 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08,
509 | 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08,
510 | 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2f, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75,
511 | 0x6c, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x6d, 0x69, 0x5f, 0x63,
512 | 0x6f, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c,
513 | 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x3b, 0x0a, 0x0a, 0x63, 0x61, 0x70,
514 | 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e,
515 | 0x73, 0x6d, 0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x63, 0x65, 0x2e,
516 | 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x0a, 0x63, 0x61, 0x70, 0x61,
517 | 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x35, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73,
518 | 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x73, 0x6d, 0x69, 0x5f, 0x63, 0x6f, 0x6e,
519 | 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x53,
520 | 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0xa7, 0x01,
521 | 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x70, 0x61,
522 | 0x73, 0x73, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
523 | 0x0b, 0x70, 0x61, 0x73, 0x73, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x12, 0x20, 0x0a, 0x0b,
524 | 0x63, 0x61, 0x73, 0x65, 0x73, 0x70, 0x61, 0x73, 0x73, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28,
525 | 0x09, 0x52, 0x0b, 0x63, 0x61, 0x73, 0x65, 0x73, 0x70, 0x61, 0x73, 0x73, 0x65, 0x64, 0x12, 0x24,
526 | 0x0a, 0x04, 0x6d, 0x65, 0x73, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x73,
527 | 0x6d, 0x70, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x65, 0x73, 0x68, 0x52, 0x04,
528 | 0x6d, 0x65, 0x73, 0x68, 0x12, 0x31, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18,
529 | 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x6d, 0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x66,
530 | 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x07,
531 | 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x2a, 0x2a, 0x0a, 0x0a, 0x43, 0x61, 0x70, 0x61, 0x62,
532 | 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x08, 0x0a, 0x04, 0x46, 0x55, 0x4c, 0x4c, 0x10, 0x00, 0x12,
533 | 0x08, 0x0a, 0x04, 0x48, 0x41, 0x4c, 0x46, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e,
534 | 0x45, 0x10, 0x02, 0x2a, 0x38, 0x0a, 0x0a, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75,
535 | 0x73, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x00,
536 | 0x12, 0x0e, 0x0a, 0x0a, 0x49, 0x4e, 0x50, 0x52, 0x4f, 0x47, 0x52, 0x45, 0x53, 0x53, 0x10, 0x01,
537 | 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x52, 0x41, 0x53, 0x48, 0x45, 0x44, 0x10, 0x02, 0x2a, 0x26, 0x0a,
538 | 0x0c, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0a, 0x0a,
539 | 0x06, 0x50, 0x41, 0x53, 0x53, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x46, 0x41, 0x49,
540 | 0x4c, 0x45, 0x44, 0x10, 0x01, 0x32, 0xc4, 0x01, 0x0a, 0x12, 0x63, 0x6f, 0x6e, 0x66, 0x6f, 0x72,
541 | 0x6d, 0x61, 0x6e, 0x63, 0x65, 0x54, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x34, 0x0a, 0x04,
542 | 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
543 | 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x14, 0x2e, 0x73,
544 | 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e,
545 | 0x66, 0x6f, 0x12, 0x38, 0x0a, 0x06, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x16, 0x2e, 0x67,
546 | 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45,
547 | 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x16, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53,
548 | 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x3e, 0x0a, 0x07,
549 | 0x52, 0x75, 0x6e, 0x54, 0x65, 0x73, 0x74, 0x12, 0x18, 0x2e, 0x73, 0x6d, 0x69, 0x5f, 0x63, 0x6f,
550 | 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
551 | 0x74, 0x1a, 0x19, 0x2e, 0x73, 0x6d, 0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61,
552 | 0x6e, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x19, 0x5a, 0x17,
553 | 0x63, 0x6f, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x63, 0x65, 0x3b, 0x63, 0x6f, 0x6e, 0x66,
554 | 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x63, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
555 | }
556 |
557 | var (
558 | file_learn_layer5_smi_conformance_conformance_conformance_proto_rawDescOnce sync.Once
559 | file_learn_layer5_smi_conformance_conformance_conformance_proto_rawDescData = file_learn_layer5_smi_conformance_conformance_conformance_proto_rawDesc
560 | )
561 |
562 | func file_learn_layer5_smi_conformance_conformance_conformance_proto_rawDescGZIP() []byte {
563 | file_learn_layer5_smi_conformance_conformance_conformance_proto_rawDescOnce.Do(func() {
564 | file_learn_layer5_smi_conformance_conformance_conformance_proto_rawDescData = protoimpl.X.CompressGZIP(file_learn_layer5_smi_conformance_conformance_conformance_proto_rawDescData)
565 | })
566 | return file_learn_layer5_smi_conformance_conformance_conformance_proto_rawDescData
567 | }
568 |
569 | var file_learn_layer5_smi_conformance_conformance_conformance_proto_enumTypes = make([]protoimpl.EnumInfo, 3)
570 | var file_learn_layer5_smi_conformance_conformance_conformance_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
571 | var file_learn_layer5_smi_conformance_conformance_conformance_proto_goTypes = []interface{}{
572 | (Capability)(0), // 0: smi_conformance.Capability
573 | (TestStatus)(0), // 1: smi_conformance.TestStatus
574 | (ResultStatus)(0), // 2: smi_conformance.ResultStatus
575 | (*Request)(nil), // 3: smi_conformance.Request
576 | (*Result)(nil), // 4: smi_conformance.Result
577 | (*Detail)(nil), // 5: smi_conformance.Detail
578 | (*Response)(nil), // 6: smi_conformance.Response
579 | (*spec.ServiceMesh)(nil), // 7: smp.ServiceMesh
580 | (*service.CommonError)(nil), // 8: service.CommonError
581 | (*empty.Empty)(nil), // 9: google.protobuf.Empty
582 | (*service.ServiceInfo)(nil), // 10: service.ServiceInfo
583 | (*service.ServiceHealth)(nil), // 11: service.ServiceHealth
584 | }
585 | var file_learn_layer5_smi_conformance_conformance_conformance_proto_depIdxs = []int32{
586 | 7, // 0: smi_conformance.Request.mesh:type_name -> smp.ServiceMesh
587 | 8, // 1: smi_conformance.Result.error:type_name -> service.CommonError
588 | 4, // 2: smi_conformance.Detail.result:type_name -> smi_conformance.Result
589 | 0, // 3: smi_conformance.Detail.capability:type_name -> smi_conformance.Capability
590 | 2, // 4: smi_conformance.Detail.status:type_name -> smi_conformance.ResultStatus
591 | 7, // 5: smi_conformance.Response.mesh:type_name -> smp.ServiceMesh
592 | 5, // 6: smi_conformance.Response.details:type_name -> smi_conformance.Detail
593 | 9, // 7: smi_conformance.conformanceTesting.Info:input_type -> google.protobuf.Empty
594 | 9, // 8: smi_conformance.conformanceTesting.Health:input_type -> google.protobuf.Empty
595 | 3, // 9: smi_conformance.conformanceTesting.RunTest:input_type -> smi_conformance.Request
596 | 10, // 10: smi_conformance.conformanceTesting.Info:output_type -> service.ServiceInfo
597 | 11, // 11: smi_conformance.conformanceTesting.Health:output_type -> service.ServiceHealth
598 | 6, // 12: smi_conformance.conformanceTesting.RunTest:output_type -> smi_conformance.Response
599 | 10, // [10:13] is the sub-list for method output_type
600 | 7, // [7:10] is the sub-list for method input_type
601 | 7, // [7:7] is the sub-list for extension type_name
602 | 7, // [7:7] is the sub-list for extension extendee
603 | 0, // [0:7] is the sub-list for field type_name
604 | }
605 |
606 | func init() { file_learn_layer5_smi_conformance_conformance_conformance_proto_init() }
607 | func file_learn_layer5_smi_conformance_conformance_conformance_proto_init() {
608 | if File_learn_layer5_smi_conformance_conformance_conformance_proto != nil {
609 | return
610 | }
611 | if !protoimpl.UnsafeEnabled {
612 | file_learn_layer5_smi_conformance_conformance_conformance_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
613 | switch v := v.(*Request); i {
614 | case 0:
615 | return &v.state
616 | case 1:
617 | return &v.sizeCache
618 | case 2:
619 | return &v.unknownFields
620 | default:
621 | return nil
622 | }
623 | }
624 | file_learn_layer5_smi_conformance_conformance_conformance_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
625 | switch v := v.(*Result); i {
626 | case 0:
627 | return &v.state
628 | case 1:
629 | return &v.sizeCache
630 | case 2:
631 | return &v.unknownFields
632 | default:
633 | return nil
634 | }
635 | }
636 | file_learn_layer5_smi_conformance_conformance_conformance_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
637 | switch v := v.(*Detail); i {
638 | case 0:
639 | return &v.state
640 | case 1:
641 | return &v.sizeCache
642 | case 2:
643 | return &v.unknownFields
644 | default:
645 | return nil
646 | }
647 | }
648 | file_learn_layer5_smi_conformance_conformance_conformance_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
649 | switch v := v.(*Response); i {
650 | case 0:
651 | return &v.state
652 | case 1:
653 | return &v.sizeCache
654 | case 2:
655 | return &v.unknownFields
656 | default:
657 | return nil
658 | }
659 | }
660 | }
661 | file_learn_layer5_smi_conformance_conformance_conformance_proto_msgTypes[1].OneofWrappers = []interface{}{
662 | (*Result_Message)(nil),
663 | (*Result_Error)(nil),
664 | }
665 | type x struct{}
666 | out := protoimpl.TypeBuilder{
667 | File: protoimpl.DescBuilder{
668 | GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
669 | RawDescriptor: file_learn_layer5_smi_conformance_conformance_conformance_proto_rawDesc,
670 | NumEnums: 3,
671 | NumMessages: 4,
672 | NumExtensions: 0,
673 | NumServices: 1,
674 | },
675 | GoTypes: file_learn_layer5_smi_conformance_conformance_conformance_proto_goTypes,
676 | DependencyIndexes: file_learn_layer5_smi_conformance_conformance_conformance_proto_depIdxs,
677 | EnumInfos: file_learn_layer5_smi_conformance_conformance_conformance_proto_enumTypes,
678 | MessageInfos: file_learn_layer5_smi_conformance_conformance_conformance_proto_msgTypes,
679 | }.Build()
680 | File_learn_layer5_smi_conformance_conformance_conformance_proto = out.File
681 | file_learn_layer5_smi_conformance_conformance_conformance_proto_rawDesc = nil
682 | file_learn_layer5_smi_conformance_conformance_conformance_proto_goTypes = nil
683 | file_learn_layer5_smi_conformance_conformance_conformance_proto_depIdxs = nil
684 | }
685 |
686 | // Reference imports to suppress errors if they are not otherwise used.
687 | var _ context.Context
688 | var _ grpc.ClientConnInterface
689 |
690 | // This is a compile-time assertion to ensure that this generated file
691 | // is compatible with the grpc package it is being compiled against.
692 | const _ = grpc.SupportPackageIsVersion6
693 |
694 | // ConformanceTestingClient is the client API for ConformanceTesting service.
695 | //
696 | // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
697 | type ConformanceTestingClient interface {
698 | Info(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*service.ServiceInfo, error)
699 | Health(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*service.ServiceHealth, error)
700 | RunTest(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error)
701 | }
702 |
703 | type conformanceTestingClient struct {
704 | cc grpc.ClientConnInterface
705 | }
706 |
707 | func NewConformanceTestingClient(cc grpc.ClientConnInterface) ConformanceTestingClient {
708 | return &conformanceTestingClient{cc}
709 | }
710 |
711 | func (c *conformanceTestingClient) Info(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*service.ServiceInfo, error) {
712 | out := new(service.ServiceInfo)
713 | err := c.cc.Invoke(ctx, "/smi_conformance.conformanceTesting/Info", in, out, opts...)
714 | if err != nil {
715 | return nil, err
716 | }
717 | return out, nil
718 | }
719 |
720 | func (c *conformanceTestingClient) Health(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*service.ServiceHealth, error) {
721 | out := new(service.ServiceHealth)
722 | err := c.cc.Invoke(ctx, "/smi_conformance.conformanceTesting/Health", in, out, opts...)
723 | if err != nil {
724 | return nil, err
725 | }
726 | return out, nil
727 | }
728 |
729 | func (c *conformanceTestingClient) RunTest(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error) {
730 | out := new(Response)
731 | err := c.cc.Invoke(ctx, "/smi_conformance.conformanceTesting/RunTest", in, out, opts...)
732 | if err != nil {
733 | return nil, err
734 | }
735 | return out, nil
736 | }
737 |
738 | // ConformanceTestingServer is the server API for ConformanceTesting service.
739 | type ConformanceTestingServer interface {
740 | Info(context.Context, *empty.Empty) (*service.ServiceInfo, error)
741 | Health(context.Context, *empty.Empty) (*service.ServiceHealth, error)
742 | RunTest(context.Context, *Request) (*Response, error)
743 | }
744 |
745 | // UnimplementedConformanceTestingServer can be embedded to have forward compatible implementations.
746 | type UnimplementedConformanceTestingServer struct {
747 | }
748 |
749 | func (*UnimplementedConformanceTestingServer) Info(context.Context, *empty.Empty) (*service.ServiceInfo, error) {
750 | return nil, status.Errorf(codes.Unimplemented, "method Info not implemented")
751 | }
752 | func (*UnimplementedConformanceTestingServer) Health(context.Context, *empty.Empty) (*service.ServiceHealth, error) {
753 | return nil, status.Errorf(codes.Unimplemented, "method Health not implemented")
754 | }
755 | func (*UnimplementedConformanceTestingServer) RunTest(context.Context, *Request) (*Response, error) {
756 | return nil, status.Errorf(codes.Unimplemented, "method RunTest not implemented")
757 | }
758 |
759 | func RegisterConformanceTestingServer(s *grpc.Server, srv ConformanceTestingServer) {
760 | s.RegisterService(&_ConformanceTesting_serviceDesc, srv)
761 | }
762 |
763 | func _ConformanceTesting_Info_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
764 | in := new(empty.Empty)
765 | if err := dec(in); err != nil {
766 | return nil, err
767 | }
768 | if interceptor == nil {
769 | return srv.(ConformanceTestingServer).Info(ctx, in)
770 | }
771 | info := &grpc.UnaryServerInfo{
772 | Server: srv,
773 | FullMethod: "/smi_conformance.conformanceTesting/Info",
774 | }
775 | handler := func(ctx context.Context, req interface{}) (interface{}, error) {
776 | return srv.(ConformanceTestingServer).Info(ctx, req.(*empty.Empty))
777 | }
778 | return interceptor(ctx, in, info, handler)
779 | }
780 |
781 | func _ConformanceTesting_Health_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
782 | in := new(empty.Empty)
783 | if err := dec(in); err != nil {
784 | return nil, err
785 | }
786 | if interceptor == nil {
787 | return srv.(ConformanceTestingServer).Health(ctx, in)
788 | }
789 | info := &grpc.UnaryServerInfo{
790 | Server: srv,
791 | FullMethod: "/smi_conformance.conformanceTesting/Health",
792 | }
793 | handler := func(ctx context.Context, req interface{}) (interface{}, error) {
794 | return srv.(ConformanceTestingServer).Health(ctx, req.(*empty.Empty))
795 | }
796 | return interceptor(ctx, in, info, handler)
797 | }
798 |
799 | func _ConformanceTesting_RunTest_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
800 | in := new(Request)
801 | if err := dec(in); err != nil {
802 | return nil, err
803 | }
804 | if interceptor == nil {
805 | return srv.(ConformanceTestingServer).RunTest(ctx, in)
806 | }
807 | info := &grpc.UnaryServerInfo{
808 | Server: srv,
809 | FullMethod: "/smi_conformance.conformanceTesting/RunTest",
810 | }
811 | handler := func(ctx context.Context, req interface{}) (interface{}, error) {
812 | return srv.(ConformanceTestingServer).RunTest(ctx, req.(*Request))
813 | }
814 | return interceptor(ctx, in, info, handler)
815 | }
816 |
817 | var _ConformanceTesting_serviceDesc = grpc.ServiceDesc{
818 | ServiceName: "smi_conformance.conformanceTesting",
819 | HandlerType: (*ConformanceTestingServer)(nil),
820 | Methods: []grpc.MethodDesc{
821 | {
822 | MethodName: "Info",
823 | Handler: _ConformanceTesting_Info_Handler,
824 | },
825 | {
826 | MethodName: "Health",
827 | Handler: _ConformanceTesting_Health_Handler,
828 | },
829 | {
830 | MethodName: "RunTest",
831 | Handler: _ConformanceTesting_RunTest_Handler,
832 | },
833 | },
834 | Streams: []grpc.StreamDesc{},
835 | Metadata: "learn-layer5/smi-conformance/conformance/conformance.proto",
836 | }
837 |
--------------------------------------------------------------------------------