├── cmd ├── README.md ├── iptables │ ├── go.mod │ └── Makefile ├── lua │ └── test.lua └── dynamic │ └── main.go ├── api ├── go │ ├── .gitattributes │ └── proto │ │ └── go.mod ├── proto │ └── v1 │ │ ├── healthcheck.proto │ │ ├── instance.proto │ │ ├── types.proto │ │ └── service.proto ├── README.md └── Makefile ├── controller ├── apis │ ├── .gitattributes │ ├── amesh │ │ └── v1alpha1 │ │ │ ├── doc.go │ │ │ └── zz_generated.register.go │ └── client │ │ ├── clientset │ │ └── versioned │ │ │ ├── doc.go │ │ │ ├── fake │ │ │ ├── doc.go │ │ │ └── register.go │ │ │ ├── typed │ │ │ └── amesh │ │ │ │ └── v1alpha1 │ │ │ │ ├── fake │ │ │ │ ├── doc.go │ │ │ │ └── fake_amesh_client.go │ │ │ │ ├── doc.go │ │ │ │ └── generated_expansion.go │ │ │ └── scheme │ │ │ ├── doc.go │ │ │ └── register.go │ │ ├── listers │ │ └── amesh │ │ │ └── v1alpha1 │ │ │ └── expansion_generated.go │ │ └── informers │ │ └── externalversions │ │ ├── internalinterfaces │ │ └── factory_interfaces.go │ │ ├── amesh │ │ ├── interface.go │ │ └── v1alpha1 │ │ │ └── interface.go │ │ └── generic.go ├── config │ ├── prometheus │ │ ├── kustomization.yaml │ │ └── monitor.yaml │ ├── rbac │ │ ├── service_account.yaml │ │ ├── auth_proxy_client_clusterrole.yaml │ │ ├── role_binding.yaml │ │ ├── auth_proxy_role_binding.yaml │ │ ├── leader_election_role_binding.yaml │ │ ├── auth_proxy_service.yaml │ │ ├── auth_proxy_role.yaml │ │ ├── ameshpluginconfig_viewer_role.yaml │ │ ├── ameshpluginconfig_editor_role.yaml │ │ ├── role.yaml │ │ ├── leader_election_role.yaml │ │ └── kustomization.yaml │ ├── manager │ │ ├── kustomization.yaml │ │ ├── controller_manager_config.yaml │ │ └── manager.yaml │ ├── samples │ │ └── _v1alpha1_ameshpluginconfig.yaml │ ├── crd │ │ ├── patches │ │ │ ├── cainjection_in_ameshpluginconfigs.yaml │ │ │ └── webhook_in_ameshpluginconfigs.yaml │ │ ├── kustomizeconfig.yaml │ │ └── kustomization.yaml │ └── default │ │ ├── manager_config_patch.yaml │ │ ├── manager_auth_proxy_patch.yaml │ │ └── kustomization.yaml ├── .dockerignore ├── charts │ └── amesh-controller │ │ ├── values.yaml │ │ ├── templates │ │ ├── serviceaccount.yaml │ │ └── controller.yaml │ │ └── Chart.yaml ├── hack │ ├── update-imports.sh │ ├── boilerplate.go.txt │ └── update-codegen.sh ├── PROJECT ├── .gitignore ├── utils │ └── status.go ├── pkg │ ├── types │ │ └── types.go │ └── instance_manager.go ├── Dockerfile ├── controllers │ └── amesh │ │ └── suite_test.go └── README.md ├── docs ├── images │ └── arch.png └── zh │ └── amesh-prom.md ├── .dockerignore ├── charts └── amesh │ ├── charts │ ├── istio-base.tgz │ └── istio-discovery.tgz │ ├── .helmignore │ └── Chart.yaml ├── .gitignore ├── e2e ├── bookinfo │ ├── README.md │ ├── bookinfo-certificate.yaml │ ├── bookinfo-ratings-discovery.yaml │ ├── productpage-nodeport.yaml │ ├── bookinfo-details-v2.yaml │ ├── bookinfo-db.yaml │ ├── bookinfo-ingress.yaml │ ├── bookinfo-details.yaml │ ├── bookinfo-ratings.yaml │ ├── bookinfo-ratings-v2-mysql-vm.yaml │ ├── bookinfo-reviews-v2.yaml │ ├── bookinfo-ratings-v2-mysql.yaml │ ├── bookinfo-ratings-v2.yaml │ ├── cleanup.sh │ └── bookinfo-mysql.yaml ├── charts │ ├── base │ │ ├── templates │ │ │ ├── crds.yaml │ │ │ ├── NOTES.txt │ │ │ ├── reader-serviceaccount.yaml │ │ │ ├── serviceaccount.yaml │ │ │ ├── rolebinding.yaml │ │ │ ├── endpoints.yaml │ │ │ ├── role.yaml │ │ │ ├── services.yaml │ │ │ ├── clusterrolebinding.yaml │ │ │ └── default.yaml │ │ ├── Chart.yaml │ │ ├── README.md │ │ ├── values.yaml │ │ └── crds │ │ │ └── crd-operator.yaml │ ├── README.md │ └── istio-discovery │ │ ├── templates │ │ ├── serviceaccount.yaml │ │ ├── configmap-jwks.yaml │ │ ├── rolebinding.yaml │ │ ├── reader-clusterrolebinding.yaml │ │ ├── role.yaml │ │ ├── poddisruptionbudget.yaml │ │ ├── autoscale.yaml │ │ ├── NOTES.txt │ │ ├── service.yaml │ │ ├── clusterrolebinding.yaml │ │ ├── validatingwebhookconfiguration.yaml │ │ └── reader-clusterrole.yaml │ │ ├── Chart.yaml │ │ ├── README.md │ │ └── files │ │ └── grpc-simple.yaml ├── test │ ├── istio │ │ └── traffic_management │ │ │ ├── 5_circuit_breaking.go │ │ │ ├── 6_mirroring.go │ │ │ ├── 3_traffic_shifting.go │ │ │ ├── 1_request_routing.go │ │ │ ├── 2_fault_injection.go │ │ │ └── 4_request_timeouts.go │ └── amesh │ │ ├── reconnect.go │ │ ├── reconnect_tester.go │ │ └── pluginconfig.go ├── manifests │ └── httpbin.yaml ├── e2e.go ├── framework │ ├── controlplane │ │ └── controlplane.go │ ├── httpbin_test.go │ └── utils │ │ └── executor.go └── e2e_test.go ├── Dockerfiles ├── entry.sh ├── standalone.Dockerfile ├── luajit.Dockerfile ├── iptables.Dockerfile └── amesh-sidecar.Dockerfile ├── .github ├── semantic.yml └── workflows │ ├── license-checker.yaml │ └── lint.yaml ├── scripts ├── update-imports.sh └── clean-dirty-e2e-envrionment.sh ├── .gitattributes ├── pkg ├── apisix │ ├── storage.go │ ├── storage │ │ ├── noop.go │ │ ├── xds.h │ │ └── shdict.go │ ├── base.go │ ├── base_test.go │ └── plugins.go ├── amesh │ ├── util │ │ ├── id_test.go │ │ ├── id.go │ │ ├── string_set_test.go │ │ ├── string_set.go │ │ └── manifest.go │ ├── provisioner │ │ └── cluster_translator_test.go │ └── agent_demo.go ├── utils │ ├── die.go │ └── signal.go ├── xds │ └── utils.go └── version │ └── version.go ├── manifest └── manifest.yaml ├── README.md ├── .licenserc.yaml └── go.mod /cmd/README.md: -------------------------------------------------------------------------------- 1 | # Sidecar bin 2 | 3 | For test purpose. -------------------------------------------------------------------------------- /api/go/.gitattributes: -------------------------------------------------------------------------------- 1 | proto linguist-generated=true 2 | -------------------------------------------------------------------------------- /controller/apis/.gitattributes: -------------------------------------------------------------------------------- 1 | client linguist-generated=true 2 | -------------------------------------------------------------------------------- /controller/config/prometheus/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - monitor.yaml 3 | -------------------------------------------------------------------------------- /docs/images/arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/api7/Amesh/HEAD/docs/images/arch.png -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | *.test 2 | **/*.test 3 | .idea 4 | .vscode 5 | .local 6 | controller/bin 7 | -------------------------------------------------------------------------------- /charts/amesh/charts/istio-base.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/api7/Amesh/HEAD/charts/amesh/charts/istio-base.tgz -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # binaries 2 | test/bin 3 | *.test 4 | bin 5 | 6 | # ide settings 7 | .idea 8 | .vscode 9 | .api.tmp 10 | -------------------------------------------------------------------------------- /charts/amesh/charts/istio-discovery.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/api7/Amesh/HEAD/charts/amesh/charts/istio-discovery.tgz -------------------------------------------------------------------------------- /controller/config/rbac/service_account.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | name: controller-manager 5 | namespace: system 6 | -------------------------------------------------------------------------------- /e2e/bookinfo/README.md: -------------------------------------------------------------------------------- 1 | See the [Bookinfo guide](https://istio.io/docs/guides/bookinfo.html) in Istio 2 | docs for instructions on how to run this demo application. 3 | -------------------------------------------------------------------------------- /controller/.dockerignore: -------------------------------------------------------------------------------- 1 | # More info: https://docs.docker.com/engine/reference/builder/#dockerignore-file 2 | # Ignore build and test binaries. 3 | bin/ 4 | testbin/ 5 | -------------------------------------------------------------------------------- /e2e/charts/base/templates/crds.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.base.enableCRDTemplates }} 2 | {{ .Files.Get "crds/crd-all.gen.yaml" }} 3 | {{ .Files.Get "crds/crd-operator.yaml" }} 4 | {{- end }} 5 | -------------------------------------------------------------------------------- /cmd/iptables/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/amesh-io/amesh-iptables 2 | 3 | go 1.16 4 | 5 | require ( 6 | github.com/spf13/cobra v1.4.0 7 | istio.io/istio v0.0.0-20220705194127-d85042dbcde9 8 | ) 9 | -------------------------------------------------------------------------------- /controller/charts/amesh-controller/values.yaml: -------------------------------------------------------------------------------- 1 | images: 2 | 3 | controller: 4 | image: "10.0.0.20:5000/amesh-controller:latest" 5 | pullPolicy: Always #IfNotPresent 6 | # log_level: debug 7 | -------------------------------------------------------------------------------- /e2e/charts/base/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | Istio base successfully installed! 2 | 3 | To learn more about the release, try: 4 | $ helm status {{ .Release.Name }} 5 | $ helm get all {{ .Release.Name }} 6 | -------------------------------------------------------------------------------- /e2e/charts/README.md: -------------------------------------------------------------------------------- 1 | # Istio Helm Chart 2 | 3 | This chart is copied from [Istio](https://github.com/istio/istio) v1.13.1. 4 | 5 | The template `istio-discovery/files/injection-template.yaml` is copied from Amesh. -------------------------------------------------------------------------------- /controller/config/rbac/auth_proxy_client_clusterrole.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | name: metrics-reader 5 | rules: 6 | - nonResourceURLs: 7 | - "/metrics" 8 | verbs: 9 | - get 10 | -------------------------------------------------------------------------------- /Dockerfiles/entry.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "===ARGS===" 4 | echo "$@" 5 | echo "==========" 6 | 7 | 8 | /usr/bin/apisix init 9 | /usr/local/openresty/bin/openresty -p /usr/local/apisix -g 'daemon off;' # remove /usr/bin/apisix init_etcd 10 | -------------------------------------------------------------------------------- /controller/config/manager/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - manager.yaml 3 | 4 | generatorOptions: 5 | disableNameSuffixHash: true 6 | 7 | configMapGenerator: 8 | - name: manager-config 9 | files: 10 | - controller_manager_config.yaml 11 | -------------------------------------------------------------------------------- /.github/semantic.yml: -------------------------------------------------------------------------------- 1 | titleOnly: true 2 | allowRevertCommits: true 3 | types: 4 | - feat 5 | - fix 6 | - docs 7 | - style 8 | - refactor 9 | - perf 10 | - test 11 | - build 12 | - ci 13 | - chore 14 | - revert 15 | - change 16 | -------------------------------------------------------------------------------- /api/go/proto/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/api7/amesh/api/proto 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/envoyproxy/protoc-gen-validate v0.6.1 7 | google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83 8 | google.golang.org/grpc v1.40.0 9 | google.golang.org/protobuf v1.27.1 10 | ) 11 | -------------------------------------------------------------------------------- /controller/hack/update-imports.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | PROJECT_NAME=github.com/api7/amesh 6 | while IFS= read -r -d '' file; do 7 | goimports-reviser -file-path "$file" -project-name $PROJECT_NAME 8 | done < <(find . -name '*.go' -not -path "./apis/client/**" -not -path './main.go' -print0) 9 | -------------------------------------------------------------------------------- /controller/config/samples/_v1alpha1_ameshpluginconfig.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apisix.apache.org/v1alpha1 2 | kind: AmeshPluginConfig 3 | metadata: 4 | name: ameshpluginconfig-sample 5 | spec: 6 | plugins: 7 | - name: response-rewrite 8 | type: "" 9 | config: '{"body": "BODY_REWRITE", "headers": {"X-Header":"Rewrite"}}' 10 | -------------------------------------------------------------------------------- /controller/config/rbac/role_binding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | name: manager-rolebinding 5 | roleRef: 6 | apiGroup: rbac.authorization.k8s.io 7 | kind: ClusterRole 8 | name: manager-role 9 | subjects: 10 | - kind: ServiceAccount 11 | name: controller-manager 12 | namespace: system 13 | -------------------------------------------------------------------------------- /api/proto/v1/healthcheck.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package ai.api7.amesh.proto.v1; 4 | 5 | option go_package = "github.com/api7/amesh/api/proto/v1"; 6 | 7 | message Empty { 8 | } 9 | 10 | message HealthCheckResponse { 11 | string text = 1; 12 | } 13 | 14 | service HealthCheckService { 15 | rpc Ping(Empty) returns (HealthCheckResponse) {} 16 | } 17 | -------------------------------------------------------------------------------- /scripts/update-imports.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | PROJECT_NAME=github.com/api7/amesh 6 | while IFS= read -r -d '' file; do 7 | goimports-reviser -file-path "$file" -project-name $PROJECT_NAME 8 | done < <(find . -name '*.go' -not -path "./test/*" -not -path "./controller/apis/client/**" -not -path './controller/main.go' -not -path './api/go' -print0) 9 | -------------------------------------------------------------------------------- /controller/config/rbac/auth_proxy_role_binding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | name: proxy-rolebinding 5 | roleRef: 6 | apiGroup: rbac.authorization.k8s.io 7 | kind: ClusterRole 8 | name: proxy-role 9 | subjects: 10 | - kind: ServiceAccount 11 | name: controller-manager 12 | namespace: system 13 | -------------------------------------------------------------------------------- /controller/config/rbac/leader_election_role_binding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: RoleBinding 3 | metadata: 4 | name: leader-election-rolebinding 5 | roleRef: 6 | apiGroup: rbac.authorization.k8s.io 7 | kind: Role 8 | name: leader-election-role 9 | subjects: 10 | - kind: ServiceAccount 11 | name: controller-manager 12 | namespace: system 13 | -------------------------------------------------------------------------------- /controller/config/crd/patches/cainjection_in_ameshpluginconfigs.yaml: -------------------------------------------------------------------------------- 1 | # The following patch adds a directive for certmanager to inject CA into the CRD 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | annotations: 6 | cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) 7 | name: ameshpluginconfigs.apisix.apache.org 8 | -------------------------------------------------------------------------------- /controller/config/rbac/auth_proxy_service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | labels: 5 | control-plane: controller-manager 6 | name: controller-manager-metrics-service 7 | namespace: system 8 | spec: 9 | ports: 10 | - name: https 11 | port: 8443 12 | protocol: TCP 13 | targetPort: https 14 | selector: 15 | control-plane: controller-manager 16 | -------------------------------------------------------------------------------- /controller/config/rbac/auth_proxy_role.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | name: proxy-role 5 | rules: 6 | - apiGroups: 7 | - authentication.k8s.io 8 | resources: 9 | - tokenreviews 10 | verbs: 11 | - create 12 | - apiGroups: 13 | - authorization.k8s.io 14 | resources: 15 | - subjectaccessreviews 16 | verbs: 17 | - create 18 | -------------------------------------------------------------------------------- /controller/PROJECT: -------------------------------------------------------------------------------- 1 | domain: apisix.apache.org 2 | layout: 3 | - go.kubebuilder.io/v3 4 | multigroup: true 5 | projectName: test 6 | repo: github.com/api7/amesh 7 | resources: 8 | - api: 9 | crdVersion: v1 10 | namespaced: true 11 | controller: true 12 | domain: apisix.apache.org 13 | kind: AmeshPluginConfig 14 | path: github.com/api7/amesh/api/v1alpha1 15 | version: v1alpha1 16 | version: "3" 17 | -------------------------------------------------------------------------------- /api/proto/v1/instance.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package ai.api7.amesh.proto.v1; 4 | 5 | option go_package = "github.com/api7/amesh/api/proto/v1"; 6 | 7 | import "validate/validate.proto"; 8 | import "google/protobuf/struct.proto"; 9 | 10 | // Instance contains metadata to describe the proxy instance. 11 | message Instance { 12 | // Key of the proxy Pod. 13 | string key = 1 [(validate.rules).string = {min_len: 2, max_len: 253}]; 14 | } 15 | -------------------------------------------------------------------------------- /charts/amesh/.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 | -------------------------------------------------------------------------------- /scripts/clean-dirty-e2e-envrionment.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/bash 2 | 3 | kubectl delete validatingwebhookconfigurations.admissionregistration.k8s.io istiod-default-validator 4 | kubectl delete mutatingwebhookconfigurations $(kubectl get mutatingwebhookconfigurations| grep amesh | awk "{print \$1}") 5 | kubectl delete clusterrole $(kubectl get clusterrole| grep amesh | awk "{print \$1}") 6 | kubectl delete clusterrolebinding $(kubectl get clusterrolebinding | grep amesh | awk "{print \$1}") 7 | -------------------------------------------------------------------------------- /e2e/charts/base/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | name: base 3 | # This version is never actually shipped. istio/release-builder will replace it at build-time 4 | # with the appropriate version 5 | version: 1.0.0 6 | appVersion: 1.0.0 7 | tillerVersion: ">=2.7.2" 8 | description: Helm chart for deploying Istio cluster resources and CRDs 9 | keywords: 10 | - istio 11 | sources: 12 | - http://github.com/istio/istio 13 | engine: gotpl 14 | icon: https://istio.io/latest/favicons/android-192x192.png 15 | -------------------------------------------------------------------------------- /controller/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Binaries for programs and plugins 3 | *.exe 4 | *.exe~ 5 | *.dll 6 | *.so 7 | *.dylib 8 | bin 9 | testbin/* 10 | 11 | # Test binary, build with `go test -c` 12 | *.test 13 | 14 | # Output of the go coverage tool, specifically when used with LiteIDE 15 | *.out 16 | 17 | # Kubernetes Generated files - skip generated files, except for vendored files 18 | 19 | !vendor/**/zz_generated.* 20 | 21 | # editor and IDE paraphernalia 22 | .idea 23 | *.swp 24 | *.swo 25 | *~ 26 | -------------------------------------------------------------------------------- /controller/config/rbac/ameshpluginconfig_viewer_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to view ameshpluginconfigs. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: ameshpluginconfig-viewer-role 6 | rules: 7 | - apiGroups: 8 | - apisix.apache.org 9 | resources: 10 | - ameshpluginconfigs 11 | verbs: 12 | - get 13 | - list 14 | - watch 15 | - apiGroups: 16 | - apisix.apache.org 17 | resources: 18 | - ameshpluginconfigs/status 19 | verbs: 20 | - get 21 | -------------------------------------------------------------------------------- /e2e/charts/istio-discovery/templates/serviceaccount.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | {{- if .Values.global.imagePullSecrets }} 4 | imagePullSecrets: 5 | {{- range .Values.global.imagePullSecrets }} 6 | - name: {{ . }} 7 | {{- end }} 8 | {{- end }} 9 | metadata: 10 | name: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }} 11 | namespace: {{ .Values.global.istioNamespace }} 12 | labels: 13 | app: istiod 14 | release: {{ .Release.Name }} 15 | --- 16 | -------------------------------------------------------------------------------- /e2e/charts/istio-discovery/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | name: istiod 3 | # This version is never actually shipped. istio/release-builder will replace it at build-time 4 | # with the appropriate version 5 | version: 1.0.0 6 | appVersion: 1.0.0 7 | tillerVersion: ">=2.7.2" 8 | description: Helm chart for istio control plane 9 | keywords: 10 | - istio 11 | - istiod 12 | - istio-discovery 13 | sources: 14 | - http://github.com/istio/istio 15 | engine: gotpl 16 | icon: https://istio.io/latest/favicons/android-192x192.png 17 | -------------------------------------------------------------------------------- /controller/config/crd/patches/webhook_in_ameshpluginconfigs.yaml: -------------------------------------------------------------------------------- 1 | # The following patch enables a conversion webhook for the CRD 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | name: ameshpluginconfigs.apisix.apache.org 6 | spec: 7 | conversion: 8 | strategy: Webhook 9 | webhook: 10 | clientConfig: 11 | service: 12 | namespace: system 13 | name: webhook-service 14 | path: /convert 15 | conversionReviewVersions: 16 | - v1 17 | -------------------------------------------------------------------------------- /controller/config/rbac/ameshpluginconfig_editor_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to edit ameshpluginconfigs. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: ameshpluginconfig-editor-role 6 | rules: 7 | - apiGroups: 8 | - apisix.apache.org 9 | resources: 10 | - ameshpluginconfigs 11 | verbs: 12 | - create 13 | - delete 14 | - get 15 | - list 16 | - patch 17 | - update 18 | - watch 19 | - apiGroups: 20 | - apisix.apache.org 21 | resources: 22 | - ameshpluginconfigs/status 23 | verbs: 24 | - get 25 | -------------------------------------------------------------------------------- /e2e/charts/base/templates/reader-serviceaccount.yaml: -------------------------------------------------------------------------------- 1 | # This service account aggregates reader permissions for the revisions in a given cluster 2 | # Should be used for remote secret creation. 3 | apiVersion: v1 4 | kind: ServiceAccount 5 | {{- if .Values.global.imagePullSecrets }} 6 | imagePullSecrets: 7 | {{- range .Values.global.imagePullSecrets }} 8 | - name: {{ . }} 9 | {{- end }} 10 | {{- end }} 11 | metadata: 12 | name: istio-reader-service-account 13 | namespace: {{ .Values.global.istioNamespace }} 14 | labels: 15 | app: istio-reader 16 | release: {{ .Release.Name }} 17 | -------------------------------------------------------------------------------- /controller/config/default/manager_config_patch.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: controller-manager 5 | namespace: system 6 | spec: 7 | template: 8 | spec: 9 | containers: 10 | - name: manager 11 | args: 12 | - "--config=controller_manager_config.yaml" 13 | volumeMounts: 14 | - name: manager-config 15 | mountPath: /controller_manager_config.yaml 16 | subPath: controller_manager_config.yaml 17 | volumes: 18 | - name: manager-config 19 | configMap: 20 | name: manager-config 21 | -------------------------------------------------------------------------------- /controller/config/prometheus/monitor.yaml: -------------------------------------------------------------------------------- 1 | 2 | # Prometheus Monitor Service (Metrics) 3 | apiVersion: monitoring.coreos.com/v1 4 | kind: ServiceMonitor 5 | metadata: 6 | labels: 7 | control-plane: controller-manager 8 | name: controller-manager-metrics-monitor 9 | namespace: system 10 | spec: 11 | endpoints: 12 | - path: /metrics 13 | port: https 14 | scheme: https 15 | bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token 16 | tlsConfig: 17 | insecureSkipVerify: true 18 | selector: 19 | matchLabels: 20 | control-plane: controller-manager 21 | -------------------------------------------------------------------------------- /e2e/charts/base/README.md: -------------------------------------------------------------------------------- 1 | # Istio base Helm Chart 2 | 3 | This chart installs resources shared by all Istio revisions. This includes Istio CRDs. 4 | 5 | ## Setup Repo Info 6 | 7 | ```console 8 | helm repo add istio https://istio-release.storage.googleapis.com/charts 9 | helm repo update 10 | ``` 11 | 12 | _See [helm repo](https://helm.sh/docs/helm/helm_repo/) for command documentation._ 13 | 14 | ## Installing the Chart 15 | 16 | To install the chart with the release name `istio-base`: 17 | 18 | ```console 19 | kubectl create namespace istio-system 20 | helm install istio-base istio/base -n istio-system 21 | ``` 22 | -------------------------------------------------------------------------------- /controller/config/crd/kustomizeconfig.yaml: -------------------------------------------------------------------------------- 1 | # This file is for teaching kustomize how to substitute name and namespace reference in CRD 2 | nameReference: 3 | - kind: Service 4 | version: v1 5 | fieldSpecs: 6 | - kind: CustomResourceDefinition 7 | version: v1 8 | group: apiextensions.k8s.io 9 | path: spec/conversion/webhook/clientConfig/service/name 10 | 11 | namespace: 12 | - kind: CustomResourceDefinition 13 | version: v1 14 | group: apiextensions.k8s.io 15 | path: spec/conversion/webhook/clientConfig/service/namespace 16 | create: false 17 | 18 | varReference: 19 | - path: metadata/annotations 20 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Istio Chart 2 | # https://github.com/istio/istio/tree/1.13.1/manifests/charts 3 | e2e/charts/** linguist-generated=true 4 | e2e/charts/istio-discovery/files/injection-template.yaml linguist-generated=false 5 | 6 | # Bookinfo 7 | # https://github.com/istio/istio/tree/1.13.1/samples/bookinfo/platform/kube 8 | e2e/bookinfo/* linguist-generated=true 9 | 10 | # K8s & gRPC 11 | **/zz_generated.*.go linguist-generated=true 12 | **/types.generated.go linguist-generated=true 13 | **/*.pb.go linguist-generated=true 14 | **/*.pb.validate.go linguist-generated=true 15 | go.sum linguist-generated=true 16 | **/go.sum linguist-generated=true 17 | -------------------------------------------------------------------------------- /controller/hack/boilerplate.go.txt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2022 The Amesh Authors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ -------------------------------------------------------------------------------- /e2e/charts/istio-discovery/templates/configmap-jwks.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.pilot.jwksResolverExtraRootCA }} 2 | apiVersion: v1 3 | kind: ConfigMap 4 | metadata: 5 | name: pilot-jwks-extra-cacerts{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }} 6 | namespace: {{ .Release.Namespace }} 7 | labels: 8 | release: {{ .Release.Name }} 9 | istio.io/rev: {{ .Values.revision | default "default" }} 10 | install.operator.istio.io/owning-resource: {{ .Values.ownerName | default "unknown" }} 11 | operator.istio.io/component: "Pilot" 12 | data: 13 | extra.pem: {{ .Values.pilot.jwksResolverExtraRootCA | quote }} 14 | {{- end }} 15 | -------------------------------------------------------------------------------- /controller/config/rbac/role.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | creationTimestamp: null 6 | name: manager-role 7 | rules: 8 | - apiGroups: 9 | - apisix.apache.org 10 | resources: 11 | - ameshpluginconfigs 12 | verbs: 13 | - create 14 | - delete 15 | - get 16 | - list 17 | - patch 18 | - update 19 | - watch 20 | - apiGroups: 21 | - apisix.apache.org 22 | resources: 23 | - ameshpluginconfigs/finalizers 24 | verbs: 25 | - update 26 | - apiGroups: 27 | - apisix.apache.org 28 | resources: 29 | - ameshpluginconfigs/status 30 | verbs: 31 | - get 32 | - patch 33 | - update 34 | -------------------------------------------------------------------------------- /e2e/charts/base/templates/serviceaccount.yaml: -------------------------------------------------------------------------------- 1 | # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 2 | # DO NOT EDIT! 3 | # THIS IS A LEGACY CHART HERE FOR BACKCOMPAT 4 | # UPDATED CHART AT manifests/charts/istio-control/istio-discovery 5 | # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 6 | apiVersion: v1 7 | kind: ServiceAccount 8 | {{- if .Values.global.imagePullSecrets }} 9 | imagePullSecrets: 10 | {{- range .Values.global.imagePullSecrets }} 11 | - name: {{ . }} 12 | {{- end }} 13 | {{- end }} 14 | metadata: 15 | name: istiod-service-account 16 | namespace: {{ .Values.global.istioNamespace }} 17 | labels: 18 | app: istiod 19 | release: {{ .Release.Name }} 20 | -------------------------------------------------------------------------------- /controller/config/rbac/leader_election_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions to do leader election. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: Role 4 | metadata: 5 | name: leader-election-role 6 | rules: 7 | - apiGroups: 8 | - "" 9 | resources: 10 | - configmaps 11 | verbs: 12 | - get 13 | - list 14 | - watch 15 | - create 16 | - update 17 | - patch 18 | - delete 19 | - apiGroups: 20 | - coordination.k8s.io 21 | resources: 22 | - leases 23 | verbs: 24 | - get 25 | - list 26 | - watch 27 | - create 28 | - update 29 | - patch 30 | - delete 31 | - apiGroups: 32 | - "" 33 | resources: 34 | - events 35 | verbs: 36 | - create 37 | - patch 38 | -------------------------------------------------------------------------------- /e2e/charts/istio-discovery/templates/rolebinding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: RoleBinding 3 | metadata: 4 | name: istiod{{- if not (eq .Values.revision "")}}-{{ .Values.revision }}{{- end }} 5 | namespace: {{ .Values.global.istioNamespace }} 6 | labels: 7 | app: istiod 8 | release: {{ .Release.Name }} 9 | roleRef: 10 | apiGroup: rbac.authorization.k8s.io 11 | kind: Role 12 | name: istiod{{- if not (eq .Values.revision "")}}-{{ .Values.revision }}{{- end }} 13 | subjects: 14 | - kind: ServiceAccount 15 | name: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }} 16 | namespace: {{ .Values.global.istioNamespace }} 17 | -------------------------------------------------------------------------------- /e2e/charts/istio-discovery/templates/reader-clusterrolebinding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | name: istio-reader-clusterrole{{- if not (eq .Values.revision "")}}-{{ .Values.revision }}{{- end }}-{{ .Release.Namespace }} 5 | labels: 6 | app: istio-reader 7 | release: {{ .Release.Name }} 8 | roleRef: 9 | apiGroup: rbac.authorization.k8s.io 10 | kind: ClusterRole 11 | name: istio-reader-clusterrole{{- if not (eq .Values.revision "")}}-{{ .Values.revision }}{{- end }}-{{ .Release.Namespace }} 12 | subjects: 13 | - kind: ServiceAccount 14 | name: istio-reader-service-account 15 | namespace: {{ .Values.global.istioNamespace }} 16 | -------------------------------------------------------------------------------- /e2e/test/istio/traffic_management/5_circuit_breaking.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 The Amesh Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package traffic_management 16 | -------------------------------------------------------------------------------- /cmd/iptables/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright 2022 The Amesh Authors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | .PHONY: build-amesh-iptables 16 | build-amesh-iptables: 17 | CGO_ENABLED=0 go build -o ./amesh-iptables . 18 | -------------------------------------------------------------------------------- /pkg/apisix/storage.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 The Amesh Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package apisix 15 | 16 | type Storage interface { 17 | Store(string, string) 18 | Delete(string) 19 | } 20 | -------------------------------------------------------------------------------- /controller/apis/amesh/v1alpha1/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 The Amesh Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // +k8s:deepcopy-gen=package 16 | // +groupName=apisix.apache.org 17 | package v1alpha1 18 | -------------------------------------------------------------------------------- /e2e/charts/base/templates/rolebinding.yaml: -------------------------------------------------------------------------------- 1 | # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 2 | # DO NOT EDIT! 3 | # THIS IS A LEGACY CHART HERE FOR BACKCOMPAT 4 | # UPDATED CHART AT manifests/charts/istio-control/istio-discovery 5 | # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 6 | apiVersion: rbac.authorization.k8s.io/v1 7 | kind: RoleBinding 8 | metadata: 9 | name: istiod-{{ .Values.global.istioNamespace }} 10 | namespace: {{ .Values.global.istioNamespace }} 11 | labels: 12 | app: istiod 13 | release: {{ .Release.Name }} 14 | roleRef: 15 | apiGroup: rbac.authorization.k8s.io 16 | kind: Role 17 | name: istiod-{{ .Values.global.istioNamespace }} 18 | subjects: 19 | - kind: ServiceAccount 20 | name: istiod-service-account 21 | namespace: {{ .Values.global.istioNamespace }} 22 | -------------------------------------------------------------------------------- /controller/config/rbac/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | # All RBAC will be applied under this service account in 3 | # the deployment namespace. You may comment out this resource 4 | # if your manager will use a service account that exists at 5 | # runtime. Be sure to update RoleBinding and ClusterRoleBinding 6 | # subjects if changing service account names. 7 | - service_account.yaml 8 | - role.yaml 9 | - role_binding.yaml 10 | - leader_election_role.yaml 11 | - leader_election_role_binding.yaml 12 | # Comment the following 4 lines if you want to disable 13 | # the auth proxy (https://github.com/brancz/kube-rbac-proxy) 14 | # which protects your /metrics endpoint. 15 | - auth_proxy_service.yaml 16 | - auth_proxy_role.yaml 17 | - auth_proxy_role_binding.yaml 18 | - auth_proxy_client_clusterrole.yaml 19 | -------------------------------------------------------------------------------- /controller/apis/client/clientset/versioned/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2022 The Amesh Authors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | // Code generated by client-gen. DO NOT EDIT. 17 | 18 | // This package has the automatically generated clientset. 19 | package versioned 20 | -------------------------------------------------------------------------------- /e2e/charts/istio-discovery/templates/role.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: Role 3 | metadata: 4 | name: istiod{{- if not (eq .Values.revision "")}}-{{ .Values.revision }}{{- end }} 5 | namespace: {{ .Values.global.istioNamespace }} 6 | labels: 7 | app: istiod 8 | release: {{ .Release.Name }} 9 | rules: 10 | # permissions to verify the webhook is ready and rejecting 11 | # invalid config. We use --server-dry-run so no config is persisted. 12 | - apiGroups: ["networking.istio.io"] 13 | verbs: ["create"] 14 | resources: ["gateways"] 15 | 16 | # For storing CA secret 17 | - apiGroups: [""] 18 | resources: ["secrets"] 19 | # TODO lock this down to istio-ca-cert if not using the DNS cert mesh config 20 | verbs: ["create", "get", "watch", "list", "update", "delete"] 21 | -------------------------------------------------------------------------------- /controller/apis/client/clientset/versioned/fake/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2022 The Amesh Authors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | // Code generated by client-gen. DO NOT EDIT. 17 | 18 | // This package has the automatically generated fake clientset. 19 | package fake 20 | -------------------------------------------------------------------------------- /e2e/charts/base/templates/endpoints.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.global.remotePilotAddress }} 2 | {{- if .Values.pilot.enabled }} 3 | apiVersion: v1 4 | kind: Endpoints 5 | metadata: 6 | name: istiod-remote 7 | namespace: {{ .Release.Namespace }} 8 | subsets: 9 | - addresses: 10 | - ip: {{ .Values.global.remotePilotAddress }} 11 | ports: 12 | - port: 15012 13 | name: tcp-istiod 14 | protocol: TCP 15 | {{- else if regexMatch "^([0-9]*\\.){3}[0-9]*$" .Values.global.remotePilotAddress }} 16 | apiVersion: v1 17 | kind: Endpoints 18 | metadata: 19 | name: istiod 20 | namespace: {{ .Release.Namespace }} 21 | subsets: 22 | - addresses: 23 | - ip: {{ .Values.global.remotePilotAddress }} 24 | ports: 25 | - port: 15012 26 | name: tcp-istiod 27 | protocol: TCP 28 | {{- end }} 29 | --- 30 | {{- end }} 31 | -------------------------------------------------------------------------------- /controller/apis/client/clientset/versioned/typed/amesh/v1alpha1/fake/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2022 The Amesh Authors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | // Code generated by client-gen. DO NOT EDIT. 17 | 18 | // Package fake has the automatically generated clients. 19 | package fake 20 | -------------------------------------------------------------------------------- /controller/apis/client/clientset/versioned/scheme/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2022 The Amesh Authors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | // Code generated by client-gen. DO NOT EDIT. 17 | 18 | // This package contains the scheme of the automatically generated clientset. 19 | package scheme 20 | -------------------------------------------------------------------------------- /controller/apis/client/clientset/versioned/typed/amesh/v1alpha1/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2022 The Amesh Authors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | // Code generated by client-gen. DO NOT EDIT. 17 | 18 | // This package has the automatically generated typed clients. 19 | package v1alpha1 20 | -------------------------------------------------------------------------------- /controller/apis/client/clientset/versioned/typed/amesh/v1alpha1/generated_expansion.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2022 The Amesh Authors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | // Code generated by client-gen. DO NOT EDIT. 17 | 18 | package v1alpha1 19 | 20 | type AmeshPluginConfigExpansion interface{} 21 | -------------------------------------------------------------------------------- /e2e/charts/istio-discovery/templates/poddisruptionbudget.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.global.defaultPodDisruptionBudget.enabled }} 2 | apiVersion: policy/v1beta1 3 | kind: PodDisruptionBudget 4 | metadata: 5 | name: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }} 6 | namespace: {{ .Release.Namespace }} 7 | labels: 8 | app: istiod 9 | istio.io/rev: {{ .Values.revision | default "default" }} 10 | install.operator.istio.io/owning-resource: {{ .Values.ownerName | default "unknown" }} 11 | operator.istio.io/component: "Pilot" 12 | release: {{ .Release.Name }} 13 | istio: pilot 14 | spec: 15 | minAvailable: 1 16 | selector: 17 | matchLabels: 18 | app: istiod 19 | {{- if ne .Values.revision "" }} 20 | istio.io/rev: {{ .Values.revision }} 21 | {{- else }} 22 | istio: pilot 23 | {{- end }} 24 | --- 25 | {{- end }} 26 | -------------------------------------------------------------------------------- /api/proto/v1/types.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package ai.api7.amesh.proto.v1; 4 | 5 | option go_package = "github.com/api7/amesh/api/proto/v1"; 6 | 7 | import "validate/validate.proto"; 8 | //import "google/protobuf/any.proto"; 9 | 10 | 11 | // Event represent a configuration change. 12 | message AmeshPlugin { 13 | // The plugin type 14 | string type = 1 [(validate.rules).string = {in: ["", "pre-req", "post-req"]}]; 15 | // The plugin name 16 | string name = 2 [(validate.rules).string = {min_len: 1}]; 17 | // The plugin config 18 | string config = 3 [(validate.rules).string = {min_len: 2}]; 19 | } 20 | 21 | message AmeshPluginConfig { 22 | string name = 1 [(validate.rules).string = {min_len: 1}]; 23 | repeated AmeshPlugin plugins = 2; 24 | // The resource version. Proxy should apply the newest version only. 25 | string version = 3 [(validate.rules).string = {min_len: 1}]; 26 | } 27 | -------------------------------------------------------------------------------- /e2e/charts/base/values.yaml: -------------------------------------------------------------------------------- 1 | global: 2 | 3 | # ImagePullSecrets for control plane ServiceAccount, list of secrets in the same namespace 4 | # to use for pulling any images in pods that reference this ServiceAccount. 5 | # Must be set for any cluster configured with private docker registry. 6 | imagePullSecrets: [] 7 | 8 | # Used to locate istiod. 9 | istioNamespace: istio-system 10 | 11 | istiod: 12 | enableAnalysis: false 13 | 14 | configValidation: true 15 | externalIstiod: false 16 | remotePilotAddress: "" 17 | 18 | base: 19 | # Used for helm2 to add the CRDs to templates. 20 | enableCRDTemplates: false 21 | 22 | # Validation webhook configuration url 23 | # For example: https://$remotePilotAddress:15017/validate 24 | validationURL: "" 25 | 26 | # For istioctl usage to disable istio config crds in base 27 | enableIstioConfigCRDs: true 28 | 29 | defaultRevision: "default" 30 | -------------------------------------------------------------------------------- /pkg/amesh/util/id_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 The Amesh Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package util 15 | 16 | import ( 17 | "testing" 18 | 19 | "github.com/stretchr/testify/assert" 20 | ) 21 | 22 | func TestGenNodeId(t *testing.T) { 23 | id := GenNodeId("12345", "10.0.5.3", "default.svc.cluster.local") 24 | assert.Equal(t, "sidecar~10.0.5.3~12345~default.svc.cluster.local", id) 25 | } 26 | -------------------------------------------------------------------------------- /e2e/charts/base/templates/role.yaml: -------------------------------------------------------------------------------- 1 | # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 2 | # DO NOT EDIT! 3 | # THIS IS A LEGACY CHART HERE FOR BACKCOMPAT 4 | # UPDATED CHART AT manifests/charts/istio-control/istio-discovery 5 | # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 6 | apiVersion: rbac.authorization.k8s.io/v1 7 | kind: Role 8 | metadata: 9 | name: istiod-{{ .Values.global.istioNamespace }} 10 | namespace: {{ .Values.global.istioNamespace }} 11 | labels: 12 | app: istiod 13 | release: {{ .Release.Name }} 14 | rules: 15 | # permissions to verify the webhook is ready and rejecting 16 | # invalid config. We use --server-dry-run so no config is persisted. 17 | - apiGroups: ["networking.istio.io"] 18 | verbs: ["create"] 19 | resources: ["gateways"] 20 | 21 | # For storing CA secret 22 | - apiGroups: [""] 23 | resources: ["secrets"] 24 | # TODO lock this down to istio-ca-cert if not using the DNS cert mesh config 25 | verbs: ["create", "get", "watch", "list", "update", "delete"] 26 | -------------------------------------------------------------------------------- /pkg/utils/die.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 The Amesh Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package utils 16 | 17 | import ( 18 | "fmt" 19 | "os" 20 | ) 21 | 22 | // Dief formats according to a format specifier and writes to stderr. It then 23 | // exits with code -1. 24 | // Note a linebreak will be appended. 25 | func Dief(format string, args ...interface{}) { 26 | message := fmt.Sprintf(format, args...) 27 | _, _ = fmt.Fprintln(os.Stderr, message) 28 | os.Exit(-1) 29 | } 30 | -------------------------------------------------------------------------------- /controller/config/manager/controller_manager_config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: controller-runtime.sigs.k8s.io/v1alpha1 2 | kind: ControllerManagerConfig 3 | health: 4 | healthProbeBindAddress: :8081 5 | metrics: 6 | bindAddress: 127.0.0.1:8080 7 | webhook: 8 | port: 9443 9 | leaderElection: 10 | leaderElect: true 11 | resourceName: c979a3f2.apisix.apache.org 12 | # leaderElectionReleaseOnCancel defines if the leader should step down volume 13 | # when the Manager ends. This requires the binary to immediately end when the 14 | # Manager is stopped, otherwise, this setting is unsafe. Setting this significantly 15 | # speeds up voluntary leader transitions as the new leader don't have to wait 16 | # LeaseDuration time first. 17 | # In the default scaffold provided, the program ends immediately after 18 | # the manager stops, so would be fine to enable this option. However, 19 | # if you are doing or is intended to do any operation such as perform cleanups 20 | # after the manager stops then its usage might be unsafe. 21 | # leaderElectionReleaseOnCancel: true 22 | -------------------------------------------------------------------------------- /controller/config/crd/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # This kustomization.yaml is not intended to be run by itself, 2 | # since it depends on service name and namespace that are out of this kustomize package. 3 | # It should be run by config/default 4 | resources: 5 | - bases/apisix.apache.org_ameshpluginconfigs.yaml 6 | #+kubebuilder:scaffold:crdkustomizeresource 7 | 8 | patchesStrategicMerge: 9 | # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix. 10 | # patches here are for enabling the conversion webhook for each CRD 11 | #- patches/webhook_in_ameshpluginconfigs.yaml 12 | #+kubebuilder:scaffold:crdkustomizewebhookpatch 13 | 14 | # [CERTMANAGER] To enable cert-manager, uncomment all the sections with [CERTMANAGER] prefix. 15 | # patches here are for enabling the CA injection for each CRD 16 | #- patches/cainjection_in_ameshpluginconfigs.yaml 17 | #+kubebuilder:scaffold:crdkustomizecainjectionpatch 18 | 19 | # the following config is for teaching kustomize how to do kustomization for CRDs. 20 | configurations: 21 | - kustomizeconfig.yaml 22 | -------------------------------------------------------------------------------- /controller/charts/amesh-controller/templates/serviceaccount.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | name: amesh-controller-service-account 5 | namespace: {{ .Release.Namespace }} 6 | --- 7 | apiVersion: rbac.authorization.k8s.io/v1 8 | kind: ClusterRoleBinding 9 | metadata: 10 | name: amesh-controller-crb 11 | roleRef: 12 | apiGroup: rbac.authorization.k8s.io 13 | kind: ClusterRole 14 | name: amesh-controller-role 15 | subjects: 16 | - kind: ServiceAccount 17 | name: amesh-controller-service-account 18 | namespace: {{ .Release.Namespace }} 19 | --- 20 | apiVersion: rbac.authorization.k8s.io/v1 21 | kind: ClusterRole 22 | metadata: 23 | name: amesh-controller-role 24 | namespace: {{ .Release.Namespace }} 25 | rules: 26 | - apiGroups: 27 | - apisix.apache.org 28 | resources: 29 | - ameshpluginconfigs 30 | - ameshpluginconfigs/status 31 | verbs: 32 | - '*' 33 | - apiGroups: [ "" ] 34 | resources: [ "configmaps", "pods", "endpoints", "services", "namespaces" ] 35 | verbs: [ "get", "list", "watch" ] 36 | -------------------------------------------------------------------------------- /e2e/bookinfo/bookinfo-certificate.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: certmanager.k8s.io/v1alpha1 3 | kind: ClusterIssuer 4 | metadata: 5 | name: letsencrypt-staging 6 | namespace: istio-system 7 | spec: 8 | acme: 9 | # The ACME server URL 10 | server: https://acme-staging-v02.api.letsencrypt.org/directory 11 | # Email address used for ACME registration 12 | email: stage@istio.io 13 | # Name of a secret used to store the ACME account private key 14 | privateKeySecretRef: 15 | name: letsencrypt-staging 16 | # Enable the HTTP-01 challenge provider 17 | http01: {} 18 | --- 19 | apiVersion: certmanager.k8s.io/v1alpha1 20 | kind: Certificate 21 | metadata: 22 | name: istio-ingressgateway-certs 23 | namespace: istio-system 24 | spec: 25 | secretName: istio-ingressgateway-certs 26 | issuerRef: 27 | name: letsencrypt-staging 28 | kind: ClusterIssuer 29 | commonName: bookinfo.example.com 30 | dnsNames: 31 | - bookinfo.example.com 32 | acme: 33 | config: 34 | - http01: 35 | ingressClass: none 36 | domains: 37 | - bookinfo.example.com 38 | -------------------------------------------------------------------------------- /e2e/charts/istio-discovery/templates/autoscale.yaml: -------------------------------------------------------------------------------- 1 | {{- if and .Values.pilot.autoscaleEnabled .Values.pilot.autoscaleMin .Values.pilot.autoscaleMax }} 2 | apiVersion: autoscaling/v2beta1 3 | kind: HorizontalPodAutoscaler 4 | metadata: 5 | name: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }} 6 | namespace: {{ .Release.Namespace }} 7 | labels: 8 | app: istiod 9 | release: {{ .Release.Name }} 10 | istio.io/rev: {{ .Values.revision | default "default" }} 11 | install.operator.istio.io/owning-resource: {{ .Values.ownerName | default "unknown" }} 12 | operator.istio.io/component: "Pilot" 13 | spec: 14 | maxReplicas: {{ .Values.pilot.autoscaleMax }} 15 | minReplicas: {{ .Values.pilot.autoscaleMin }} 16 | scaleTargetRef: 17 | apiVersion: apps/v1 18 | kind: Deployment 19 | name: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }} 20 | metrics: 21 | - type: Resource 22 | resource: 23 | name: cpu 24 | targetAverageUtilization: {{ .Values.pilot.cpu.targetAverageUtilization }} 25 | --- 26 | {{- end }} 27 | -------------------------------------------------------------------------------- /.github/workflows/license-checker.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2021 The Amesh Authors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | name: License checker 16 | 17 | on: 18 | push: 19 | branches: 20 | - master 21 | pull_request: 22 | branches: 23 | - master 24 | type: [review_requested, ready_for_review] 25 | 26 | jobs: 27 | check-license: 28 | timeout-minutes: 1.5 29 | runs-on: ubuntu-latest 30 | 31 | steps: 32 | - uses: actions/checkout@v2 33 | - name: Check License Header 34 | uses: apache/skywalking-eyes@main 35 | -------------------------------------------------------------------------------- /e2e/manifests/httpbin.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | name: httpbin 5 | labels: 6 | account: httpbin 7 | --- 8 | apiVersion: apps/v1 9 | kind: Deployment 10 | metadata: 11 | name: httpbin 12 | labels: 13 | app: httpbin 14 | spec: 15 | replicas: 1 16 | selector: 17 | matchLabels: 18 | app: httpbin 19 | template: 20 | metadata: 21 | labels: 22 | app: httpbin 23 | spec: 24 | serviceAccountName: httpbin 25 | containers: 26 | - name: httpbin 27 | image: kennethreitz/httpbin 28 | imagePullPolicy: IfNotPresent 29 | command: ["gunicorn", "--access-logfile", "-", "-b", "0.0.0.0:80", "httpbin:app"] 30 | ports: 31 | - containerPort: 80 32 | protocol: TCP 33 | name: http 34 | --- 35 | apiVersion: v1 36 | kind: Service 37 | metadata: 38 | labels: 39 | app: httpbin 40 | name: httpbin 41 | spec: 42 | selector: 43 | app: httpbin 44 | ports: 45 | - name: http 46 | targetPort: 80 47 | port: 80 48 | protocol: TCP 49 | -------------------------------------------------------------------------------- /controller/apis/client/listers/amesh/v1alpha1/expansion_generated.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2022 The Amesh Authors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | // Code generated by lister-gen. DO NOT EDIT. 17 | 18 | package v1alpha1 19 | 20 | // AmeshPluginConfigListerExpansion allows custom methods to be added to 21 | // AmeshPluginConfigLister. 22 | type AmeshPluginConfigListerExpansion interface{} 23 | 24 | // AmeshPluginConfigNamespaceListerExpansion allows custom methods to be added to 25 | // AmeshPluginConfigNamespaceLister. 26 | type AmeshPluginConfigNamespaceListerExpansion interface{} 27 | -------------------------------------------------------------------------------- /e2e/charts/istio-discovery/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | "istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}" successfully installed! 2 | 3 | To learn more about the release, try: 4 | $ helm status {{ .Release.Name }} 5 | $ helm get all {{ .Release.Name }} 6 | 7 | Next steps: 8 | * Deploy a Gateway: https://istio.io/latest/docs/setup/additional-setup/gateway/ 9 | * Try out our tasks to get started on common configurations: 10 | * https://istio.io/latest/docs/tasks/traffic-management 11 | * https://istio.io/latest/docs/tasks/security/ 12 | * https://istio.io/latest/docs/tasks/policy-enforcement/ 13 | * https://istio.io/latest/docs/tasks/policy-enforcement/ 14 | * Review the list of actively supported releases, CVE publications and our hardening guide: 15 | * https://istio.io/latest/docs/releases/supported-releases/ 16 | * https://istio.io/latest/news/security/ 17 | * https://istio.io/latest/docs/ops/best-practices/security/ 18 | 19 | For further documentation see https://istio.io website 20 | 21 | Tell us how your install/upgrade experience went at https://forms.gle/pzWZpAvMVBecaQ9h9 22 | -------------------------------------------------------------------------------- /pkg/xds/utils.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 The Amesh Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package xds 15 | 16 | import "strings" 17 | 18 | // GenNodeId generates an id used for xDS protocol. The format is like: 19 | // sidecar~172.10.0.2~12345asad034~default.svc.cluster.local 20 | func GenNodeId(runId, ipAddr, dnsDomain string) string { 21 | var buf strings.Builder 22 | buf.WriteString("sidecar~") 23 | buf.WriteString(ipAddr) 24 | buf.WriteString("~") 25 | buf.WriteString(runId) 26 | buf.WriteString("~") 27 | buf.WriteString(dnsDomain) 28 | return buf.String() 29 | } 30 | -------------------------------------------------------------------------------- /e2e/bookinfo/bookinfo-ratings-discovery.yaml: -------------------------------------------------------------------------------- 1 | # Copyright Istio Authors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | ################################################################################################## 16 | # Ratings service 17 | ################################################################################################## 18 | apiVersion: v1 19 | kind: Service 20 | metadata: 21 | name: ratings 22 | labels: 23 | app: ratings 24 | service: ratings 25 | spec: 26 | ports: 27 | - port: 9080 28 | name: http 29 | selector: 30 | app: ratings 31 | --- 32 | -------------------------------------------------------------------------------- /e2e/charts/base/templates/services.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.global.remotePilotAddress }} 2 | {{- if .Values.pilot.enabled }} 3 | # when local istiod is enabled, we can't use istiod service name to reach the remote control plane 4 | apiVersion: v1 5 | kind: Service 6 | metadata: 7 | name: istiod-remote 8 | namespace: {{ .Release.Namespace }} 9 | spec: 10 | ports: 11 | - port: 15012 12 | name: tcp-istiod 13 | protocol: TCP 14 | clusterIP: None 15 | {{- else }} 16 | # when local istiod isn't enabled, we can use istiod service name to reach the remote control plane 17 | apiVersion: v1 18 | kind: Service 19 | metadata: 20 | name: istiod 21 | namespace: {{ .Release.Namespace }} 22 | spec: 23 | ports: 24 | - port: 15012 25 | name: tcp-istiod 26 | protocol: TCP 27 | # if the remotePilotAddress is IP addr, we use clusterIP: None. 28 | # else, we use externalName 29 | {{- if regexMatch "^([0-9]*\\.){3}[0-9]*$" .Values.global.remotePilotAddress }} 30 | clusterIP: None 31 | {{- else }} 32 | type: ExternalName 33 | externalName: {{ .Values.global.remotePilotAddress }} 34 | {{- end }} 35 | {{- end }} 36 | --- 37 | {{- end }} 38 | -------------------------------------------------------------------------------- /pkg/amesh/util/id.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 The Amesh Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package util 15 | 16 | import ( 17 | "strings" 18 | ) 19 | 20 | // GenNodeId generates an id used for xDS protocol. The format is like: 21 | // sidecar~172.10.0.2~12345asad034~default.svc.cluster.local 22 | func GenNodeId(runId, ipAddr, dnsDomain string) string { 23 | var buf strings.Builder 24 | buf.WriteString("sidecar~") 25 | buf.WriteString(ipAddr) 26 | buf.WriteString("~") 27 | buf.WriteString(runId) 28 | buf.WriteString("~") 29 | buf.WriteString(dnsDomain) 30 | return buf.String() 31 | } 32 | -------------------------------------------------------------------------------- /e2e/bookinfo/productpage-nodeport.yaml: -------------------------------------------------------------------------------- 1 | # Copyright Istio Authors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | ################################################################################################## 16 | # Productpage services 17 | ################################################################################################## 18 | apiVersion: v1 19 | kind: Service 20 | metadata: 21 | name: productpage 22 | labels: 23 | app: productpage 24 | service: productpage 25 | spec: 26 | type: NodePort 27 | ports: 28 | - port: 9080 29 | name: http 30 | selector: 31 | app: productpage 32 | --- 33 | -------------------------------------------------------------------------------- /pkg/utils/signal.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021 The Amesh Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package utils 16 | 17 | import ( 18 | "os" 19 | "os/signal" 20 | "syscall" 21 | 22 | "github.com/api7/gopkg/pkg/log" 23 | ) 24 | 25 | // WaitForSignal creates a channel and wait until desired signal 26 | // arriving. It's a block call so be sure you're using it correctly. 27 | func WaitForSignal(callback func()) { 28 | sigCh := make(chan os.Signal, 1) 29 | signal.Notify(sigCh, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGINT) 30 | 31 | sig := <-sigCh 32 | log.Infof("signal arrived: %s", sig.String()) 33 | 34 | callback() 35 | } 36 | -------------------------------------------------------------------------------- /e2e/test/amesh/reconnect.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 The Amesh Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package amesh 16 | 17 | import ( 18 | "github.com/onsi/ginkgo/v2" 19 | 20 | "github.com/api7/amesh/e2e/framework" 21 | "github.com/api7/amesh/e2e/framework/utils" 22 | ) 23 | 24 | var _ = ginkgo.Describe("[amesh-controller functions] Controller Reconnect:", func() { 25 | f := framework.NewDefaultFramework() 26 | utils.Case("should be able to reconnect", func() { 27 | t := NewReconnectTester(f) 28 | 29 | t.Create() 30 | t.ValidateStatusAmeshIsOK() 31 | 32 | t.DeleteAmeshController() 33 | t.ValidateStatusAmeshIsOK() 34 | }) 35 | }) 36 | -------------------------------------------------------------------------------- /charts/amesh/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: amesh 3 | description: A Helm chart for Amesh 4 | 5 | # A chart can be either an 'application' or a 'library' chart. 6 | # 7 | # Application charts are a collection of templates that can be packaged into versioned archives 8 | # to be deployed. 9 | # 10 | # Library charts provide useful utilities or functions for the chart developer. They're included as 11 | # a dependency of application charts to inject those utilities and functions into the rendering 12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 13 | type: application 14 | 15 | # This is the chart version. This version number should be incremented each time you make changes 16 | # to the chart and its templates, including the app version. 17 | # Versions are expected to follow Semantic Versioning (https://semver.org/) 18 | version: 0.1.0 19 | 20 | # This is the version number of the application being deployed. This version number should be 21 | # incremented each time you make changes to the application. Versions are not expected to 22 | # follow Semantic Versioning. They should reflect the version the application is using. 23 | # It is recommended to use it with quotes. 24 | appVersion: "0.2.0" 25 | -------------------------------------------------------------------------------- /pkg/apisix/storage/noop.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 The Amesh Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | //go:build sidecar 16 | // +build sidecar 17 | 18 | package storage 19 | 20 | import "C" 21 | import ( 22 | "unsafe" 23 | 24 | "github.com/api7/amesh/pkg/apisix" 25 | ) 26 | 27 | var ( 28 | _ apisix.Storage = (*SharedDictStorage)(nil) 29 | ) 30 | 31 | type SharedDictStorage struct { 32 | zone unsafe.Pointer 33 | } 34 | 35 | func NewSharedDictStorage(zone unsafe.Pointer) apisix.Storage { 36 | return &SharedDictStorage{ 37 | zone: zone, 38 | } 39 | } 40 | 41 | func (s *SharedDictStorage) Store(key, value string) { 42 | } 43 | 44 | func (s *SharedDictStorage) Delete(key string) { 45 | } 46 | -------------------------------------------------------------------------------- /controller/charts/amesh-controller/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: amesh-controller 3 | description: Amesh Controller Helm Chart 4 | 5 | # A chart can be either an 'application' or a 'library' chart. 6 | # 7 | # Application charts are a collection of templates that can be packaged into versioned archives 8 | # to be deployed. 9 | # 10 | # Library charts provide useful utilities or functions for the chart developer. They're included as 11 | # a dependency of application charts to inject those utilities and functions into the rendering 12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 13 | type: application 14 | 15 | # This is the chart version. This version number should be incremented each time you make changes 16 | # to the chart and its templates, including the app version. 17 | # Versions are expected to follow Semantic Versioning (https://semver.org/) 18 | version: 0.1.0 19 | 20 | # This is the version number of the application being deployed. This version number should be 21 | # incremented each time you make changes to the application. Versions are not expected to 22 | # follow Semantic Versioning. They should reflect the version the application is using. 23 | # It is recommended to use it with quotes. 24 | appVersion: "0.1.0" 25 | -------------------------------------------------------------------------------- /api/proto/v1/service.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package ai.api7.amesh.proto.v1; 4 | 5 | option go_package = "github.com/api7/amesh/api/proto/v1"; 6 | 7 | import "proto/v1/types.proto"; 8 | import "proto/v1/instance.proto"; 9 | import "validate/validate.proto"; 10 | import "google/rpc/status.proto"; 11 | 12 | // PluginsRequest is a message which will be used in the AmeshService. 13 | // It's sent by the proxy instance and carries the proxy instance identifier 14 | message PluginsRequest { 15 | // The proxy instance identifier. 16 | Instance instance = 1 [(validate.rules).message.required = true]; 17 | } 18 | 19 | // PluginsResponse is a message which will be used in the AmeshService. 20 | // It's sent by the control plane, and contains extra plugin configurations of the proxy. 21 | message PluginsResponse { 22 | // error_message contains the error details about the PluginsRequest. 23 | // Proxy instance should detect the error message and decide to retry or 24 | // exit itself. 25 | google.rpc.Status error_message = 1; 26 | // the proxy needed plugins 27 | repeated AmeshPluginConfig plugins = 2; 28 | } 29 | 30 | // Controller service 31 | service AmeshService { 32 | rpc StreamPlugins(PluginsRequest) 33 | returns (stream PluginsResponse) { 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /e2e/charts/base/templates/clusterrolebinding.yaml: -------------------------------------------------------------------------------- 1 | # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 2 | # DO NOT EDIT! 3 | # THIS IS A LEGACY CHART HERE FOR BACKCOMPAT 4 | # UPDATED CHART AT manifests/charts/istio-control/istio-discovery 5 | # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 6 | apiVersion: rbac.authorization.k8s.io/v1 7 | kind: ClusterRoleBinding 8 | metadata: 9 | name: istio-reader-{{ .Values.global.istioNamespace }} 10 | labels: 11 | app: istio-reader 12 | release: {{ .Release.Name }} 13 | roleRef: 14 | apiGroup: rbac.authorization.k8s.io 15 | kind: ClusterRole 16 | name: istio-reader-{{ .Values.global.istioNamespace }} 17 | subjects: 18 | - kind: ServiceAccount 19 | name: istio-reader-service-account 20 | namespace: {{ .Values.global.istioNamespace }} 21 | --- 22 | apiVersion: rbac.authorization.k8s.io/v1 23 | kind: ClusterRoleBinding 24 | metadata: 25 | name: istiod-{{ .Values.global.istioNamespace }} 26 | labels: 27 | app: istiod 28 | release: {{ .Release.Name }} 29 | roleRef: 30 | apiGroup: rbac.authorization.k8s.io 31 | kind: ClusterRole 32 | name: istiod-{{ .Values.global.istioNamespace }} 33 | subjects: 34 | - kind: ServiceAccount 35 | name: istiod-service-account 36 | namespace: {{ .Values.global.istioNamespace }} 37 | --- 38 | -------------------------------------------------------------------------------- /.github/workflows/lint.yaml: -------------------------------------------------------------------------------- 1 | name: Lint 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | branches: 9 | - master 10 | jobs: 11 | gofmt: 12 | timeout-minutes: 1 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@v2 16 | - name: Setup Go Environment 17 | uses: actions/setup-go@v1 18 | with: 19 | go-version: '1.16.5' 20 | - name: Run gofmt 21 | run: | 22 | diffs=`gofmt -l .` 23 | if [[ -n $diffs ]]; then 24 | echo "Files are not formatted by gofmt:" 25 | echo $diffs 26 | exit 1 27 | fi 28 | golint: 29 | timeout-minutes: 3 30 | runs-on: ubuntu-latest 31 | steps: 32 | - uses: actions/checkout@v2 33 | - name: Setup Go Environment 34 | uses: actions/setup-go@v1 35 | with: 36 | go-version: '1.16.5' 37 | - name: Run staticcheck 38 | run: | 39 | TEMP_PATH="$(mktemp -d)" 40 | PATH="${TEMP_PATH}:$PATH" 41 | curl -sfL "https://github.com/dominikh/go-tools/releases/latest/download/staticcheck_linux_amd64.tar.gz" | tar -xvz -C "${TEMP_PATH}" --strip-components=1 42 | staticcheck -checks 'inherit,-SA1019' ./... 43 | -------------------------------------------------------------------------------- /api/README.md: -------------------------------------------------------------------------------- 1 | # Amesh CP and DP gRPC API 2 | 3 | ## Dependency 4 | 5 | Make sure the following prerequisites are satisfied if you want to modify the definitions in directory `proto`. 6 | 7 | 1. Install the [protoc-gen-validate](https://github.com/envoyproxy/protoc-gen-validate), and make sure the `protoc-gen-validate` binary is in your `$PATH`; 8 | 2. Install [googleapis](https://github.com/googleapis/googleapis); 9 | 3. Install [protobuf](https://github.com/protocolbuffers/protobuf), and make sure the `protoc` binary is in your `$PATH`; 10 | 4. Install [protoc-gen-go-grpc](https://grpc.io/docs/languages/go/quickstart/), and make sure the binary is in your `$PATH`; 11 | 12 | ## Code Generation (Go) 13 | 14 | Run `make go` to generate codes in Go. Following environment variables should be set: 15 | 16 | 1. Set `PROTOC_GEN_VALIDATE_DIR` to the home directory of `protoc-gen-validate`; 17 | 2. Set `GOOGLE_PROTOBUF_DIR` to the home directory of `protobuf`; 18 | 3. Set `GOOGLEAPIS_DIR` to the home directory of `googleapis`; 19 | 20 | ```bash 21 | make go PROTOC_GEN_VALIDATE_DIR=/path/to/protoc-gen-validate GOOGLE_PROTOBUF_DIR=/path/to/protobuf/src GOOGLEAPIS_DIR=/path/to/googleapis 22 | ``` 23 | 24 | After that, please enter the `go` directory and run `go mod tidy` to update the `go.mod` and `go.sum` files. 25 | -------------------------------------------------------------------------------- /controller/config/default/manager_auth_proxy_patch.yaml: -------------------------------------------------------------------------------- 1 | # This patch inject a sidecar container which is a HTTP proxy for the 2 | # controller manager, it performs RBAC authorization against the Kubernetes API using SubjectAccessReviews. 3 | apiVersion: apps/v1 4 | kind: Deployment 5 | metadata: 6 | name: controller-manager 7 | namespace: system 8 | spec: 9 | template: 10 | spec: 11 | containers: 12 | - name: kube-rbac-proxy 13 | securityContext: 14 | allowPrivilegeEscalation: false 15 | capabilities: 16 | drop: 17 | - "ALL" 18 | image: gcr.io/kubebuilder/kube-rbac-proxy:v0.13.0 19 | args: 20 | - "--secure-listen-address=0.0.0.0:8443" 21 | - "--upstream=http://127.0.0.1:8080/" 22 | - "--logtostderr=true" 23 | - "--v=0" 24 | ports: 25 | - containerPort: 8443 26 | protocol: TCP 27 | name: https 28 | resources: 29 | limits: 30 | cpu: 500m 31 | memory: 128Mi 32 | requests: 33 | cpu: 5m 34 | memory: 64Mi 35 | - name: manager 36 | args: 37 | - "--health-probe-bind-address=:8081" 38 | - "--metrics-bind-address=127.0.0.1:8080" 39 | - "--leader-elect" 40 | -------------------------------------------------------------------------------- /Dockerfiles/standalone.Dockerfile: -------------------------------------------------------------------------------- 1 | # Copyright 2022 The Amesh Authors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # 15 | FROM golang:1.18 as amesh-sidecar-build-stage 16 | 17 | ARG ENABLE_PROXY=false 18 | WORKDIR /amesh 19 | 20 | COPY go.* ./ 21 | RUN if [ "$ENABLE_PROXY" = "true" ]; then go env -w GOPROXY=https://goproxy.cn,direct ; fi \ 22 | && go mod download 23 | 24 | COPY Makefile Makefile 25 | COPY cmd/sidecar cmd/sidecar 26 | COPY pkg/ pkg/ 27 | RUN if [ "$ENABLE_PROXY" = "true" ]; then go env -w GOPROXY=https://goproxy.cn,direct ; fi \ 28 | && make build-amesh-sidecar 29 | 30 | FROM centos:7 31 | 32 | WORKDIR /usr/local/amesh 33 | 34 | COPY --from=amesh-sidecar-build-stage /amesh/bin/amesh-sidecar ./ 35 | 36 | #COPY ./bin/amesh-sidecar . 37 | 38 | ENTRYPOINT ["/usr/local/amesh/amesh-sidecar"] 39 | -------------------------------------------------------------------------------- /docs/zh/amesh-prom.md: -------------------------------------------------------------------------------- 1 | # Amesh 结合 Prometheus 的使用 2 | 3 | 4 | ## Amesh 的指标暴露 5 | 6 | Istio 可以通过 `prometheus.io` 注解来控制 sidecar 指标是否被 Prometheus 获取。 7 | 8 | 该选项默开启,Amesh 也将使用该方案。 9 | 10 | Sidecar 会将指标以纯文本的形式暴露在 `/stats/prometheus:15020`,通过该接口被 Prometheus 收集。 11 | 12 | 它同时也会采集来自 APISIX 9091 端口的 APISIX 指标。支持 gzip 和纯文本格式。 13 | 14 | ## 安装 Prometheus 与配置 15 | 16 | 在示例中,我们将直接使用 Istio 提供的快速示例配置来安装、运行 Prometheus。 17 | 18 | ```bash 19 | kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.16/samples/addons/prometheus.yaml 20 | ``` 21 | 22 | 以默认配置安装完成后,访问 Prometheus 的 `9090` 端口即可访问 Prometheus UI 界面。 23 | 24 | 此外,可以为该配置文件添加以下 job 来抓取、监测各 sidecar 的状态。 25 | 26 | ```yaml 27 | - job_name: 'envoy-stats' 28 | metrics_path: /stats/prometheus 29 | kubernetes_sd_configs: 30 | - role: pod 31 | 32 | relabel_configs: 33 | - source_labels: [__meta_kubernetes_pod_container_port_name] 34 | action: keep 35 | regex: 'prom' 36 | ``` 37 | 38 | 该 job 匹配了 Amesh 所注入的 sidecar 配置中名为 `prom` 的端口(该端口即为 `15020`)。 39 | 40 | 这样,就能够在 Prometheus UI 看到各 sidecar 的状态了。 41 | 42 | ## 验证 Amesh 的指标 43 | 44 | 运行示例程序,访问 `/stats/prometheus:15020` 即可查看指标数据。 45 | 46 | ```bash 47 | kubectl exec -it consumer -- curl http://127.0.0.1:15020/stats/prometheus 48 | ``` 49 | 50 | 注意,部分指标,例如延迟数据等,在没有实际数据的情况下是不会显示的。需要至少一次请求,这些指标才会出现。 51 | 52 | 随后,便可以从 Prometheus UI 查询指标了。 53 | -------------------------------------------------------------------------------- /controller/utils/status.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 The Amesh Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package utils 16 | 17 | import ( 18 | "k8s.io/apimachinery/pkg/api/meta" 19 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 20 | ) 21 | 22 | const ( 23 | ConditionSync = "Sync" 24 | ConditionSyncSuccess = "Sync Success" 25 | 26 | ResourceReconciled = "Reconciled" 27 | ) 28 | 29 | // VerifyGeneration verify generation to decide whether to update status 30 | func VerifyGeneration(conditions *[]metav1.Condition, newCondition metav1.Condition) bool { 31 | existingCondition := meta.FindStatusCondition(*conditions, newCondition.Type) 32 | if existingCondition != nil && existingCondition.ObservedGeneration > newCondition.ObservedGeneration { 33 | return false 34 | } 35 | return true 36 | } 37 | -------------------------------------------------------------------------------- /pkg/amesh/util/string_set_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 The Amesh Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package util 15 | 16 | import ( 17 | "testing" 18 | 19 | "github.com/stretchr/testify/assert" 20 | ) 21 | 22 | func TestStringSet(t *testing.T) { 23 | s := StringSet{} 24 | s.Add("123") 25 | s.Add("456") 26 | s2 := StringSet{} 27 | s2.Add("123") 28 | s2.Add("456") 29 | 30 | assert.Equal(t, s.Equals(s2), true) 31 | s2.Add("111") 32 | assert.Equal(t, s.Equals(s2), false) 33 | } 34 | 35 | func TestStringSetToArray(t *testing.T) { 36 | s := StringSet{} 37 | s.Add("123") 38 | s.Add("456") 39 | s2 := StringSet{} 40 | s2.Add("456") 41 | s2.Add("123") 42 | 43 | assert.NotNil(t, s.OrderedStrings()) 44 | assert.NotNil(t, s2.OrderedStrings()) 45 | assert.Equal(t, s.OrderedStrings(), s2.OrderedStrings()) 46 | } 47 | -------------------------------------------------------------------------------- /e2e/e2e.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 The Amesh Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package e2e 16 | 17 | import ( 18 | "github.com/api7/gopkg/pkg/log" 19 | "github.com/fatih/color" 20 | terratestlogger "github.com/gruntwork-io/terratest/modules/logger" 21 | 22 | _ "github.com/api7/amesh/e2e/test/amesh" 23 | _ "github.com/api7/amesh/e2e/test/base" 24 | _ "github.com/api7/amesh/e2e/test/istio/traffic_management" 25 | ) 26 | 27 | func runE2E() { 28 | var err error 29 | log.DefaultLogger, err = log.NewLogger( 30 | log.WithLogLevel("info"), 31 | log.WithSkipFrames(3), 32 | ) 33 | if err != nil { 34 | panic(err) 35 | } 36 | 37 | terratestlogger.Default = terratestlogger.Discard 38 | terratestlogger.Terratest = terratestlogger.Discard 39 | terratestlogger.Global = terratestlogger.Discard 40 | 41 | color.NoColor = false 42 | } 43 | -------------------------------------------------------------------------------- /e2e/test/istio/traffic_management/6_mirroring.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 The Amesh Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package traffic_management 16 | 17 | //var _ = ginkgo.Describe("[istio functions] Route Configuration:", func() { 18 | // f := framework.NewDefaultFramework() 19 | // utils.Case("should be able to config timeout", func() { 20 | // v1tester := NewVirtualServiceTester(f, []string{"v1"}) 21 | // v2tester := NewVirtualServiceTester(f, []string{"v2"}) 22 | // 23 | // v1tester.Create() 24 | // v2tester.Create() 25 | // 26 | // // apply routes 27 | // v2tester.AddRouteTo("httpbin-v2", "v2") 28 | // v2tester.ApplyRoute() 29 | // 30 | // v1tester.AddRouteToWithMirror("httpbin-v1", "v1", "httpbin-v2", "v2") 31 | // v1tester.ApplyRoute() 32 | // 33 | // time.Sleep(time.Hour * 4) 34 | // // validate access with timeout 35 | // }) 36 | //}) 37 | -------------------------------------------------------------------------------- /Dockerfiles/luajit.Dockerfile: -------------------------------------------------------------------------------- 1 | # Copyright 2022 The Amesh Authors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # 15 | FROM golang:1.18 as amesh-sidecar-build-stage 16 | 17 | ARG ENABLE_PROXY=false 18 | WORKDIR /amesh 19 | 20 | COPY api/ api/ 21 | COPY controller/go.* controller/ 22 | COPY controller/apis controller/apis 23 | COPY go.* ./ 24 | RUN if [ "$ENABLE_PROXY" = "true" ]; then go env -w GOPROXY=https://goproxy.cn,direct ; fi \ 25 | && go mod download 26 | 27 | COPY Makefile Makefile 28 | COPY cmd/dynamic cmd/dynamic 29 | COPY pkg/ pkg/ 30 | RUN if [ "$ENABLE_PROXY" = "true" ]; then go env -w GOPROXY=https://goproxy.cn,direct ; fi \ 31 | && make build-amesh-so 32 | 33 | FROM nickblah/luajit:2.0.5 34 | 35 | WORKDIR /amesh 36 | 37 | COPY --from=amesh-sidecar-build-stage /amesh/bin/libxds.so ./ 38 | COPY cmd/lua/test.lua . 39 | 40 | 41 | ENTRYPOINT ["luajit", "/amesh/test.lua"] 42 | -------------------------------------------------------------------------------- /controller/apis/client/clientset/versioned/typed/amesh/v1alpha1/fake/fake_amesh_client.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2022 The Amesh Authors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | // Code generated by client-gen. DO NOT EDIT. 17 | 18 | package fake 19 | 20 | import ( 21 | v1alpha1 "github.com/api7/amesh/controller/apis/client/clientset/versioned/typed/amesh/v1alpha1" 22 | rest "k8s.io/client-go/rest" 23 | testing "k8s.io/client-go/testing" 24 | ) 25 | 26 | type FakeApisixV1alpha1 struct { 27 | *testing.Fake 28 | } 29 | 30 | func (c *FakeApisixV1alpha1) AmeshPluginConfigs(namespace string) v1alpha1.AmeshPluginConfigInterface { 31 | return &FakeAmeshPluginConfigs{c, namespace} 32 | } 33 | 34 | // RESTClient returns a RESTClient that is used to communicate 35 | // with API server by this client implementation. 36 | func (c *FakeApisixV1alpha1) RESTClient() rest.Interface { 37 | var ret *rest.RESTClient 38 | return ret 39 | } 40 | -------------------------------------------------------------------------------- /e2e/charts/base/templates/default.yaml: -------------------------------------------------------------------------------- 1 | {{- if not (eq .Values.defaultRevision "") }} 2 | apiVersion: admissionregistration.k8s.io/v1 3 | kind: ValidatingWebhookConfiguration 4 | metadata: 5 | name: istiod-default-validator 6 | labels: 7 | app: istiod 8 | release: {{ .Release.Name }} 9 | istio: istiod 10 | istio.io/rev: {{ .Values.defaultRevision }} 11 | webhooks: 12 | - name: validation.istio.io 13 | clientConfig: 14 | {{- if .Values.base.validationURL }} 15 | url: {{ .Values.base.validationURL }} 16 | {{- else }} 17 | service: 18 | {{- if (eq .Values.defaultRevision "default") }} 19 | name: istiod 20 | {{- else }} 21 | name: istiod-{{ .Values.defaultRevision }} 22 | {{- end }} 23 | namespace: {{ .Values.global.istioNamespace }} 24 | path: "/validate" 25 | {{- end }} 26 | rules: 27 | - operations: 28 | - CREATE 29 | - UPDATE 30 | apiGroups: 31 | - security.istio.io 32 | - networking.istio.io 33 | apiVersions: 34 | - "*" 35 | resources: 36 | - "*" 37 | # Fail open until the validation webhook is ready. The webhook controller 38 | # will update this to `Fail` and patch in the `caBundle` when the webhook 39 | # endpoint is ready. 40 | failurePolicy: Ignore 41 | sideEffects: None 42 | admissionReviewVersions: ["v1beta1", "v1"] 43 | {{- end }} 44 | -------------------------------------------------------------------------------- /e2e/charts/istio-discovery/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }} 5 | namespace: {{ .Release.Namespace }} 6 | {{- if .Values.pilot.serviceAnnotations }} 7 | annotations: 8 | {{ toYaml .Values.pilot.serviceAnnotations | indent 4 }} 9 | {{- end }} 10 | labels: 11 | istio.io/rev: {{ .Values.revision | default "default" }} 12 | install.operator.istio.io/owning-resource: {{ .Values.ownerName | default "unknown" }} 13 | operator.istio.io/component: "Pilot" 14 | app: istiod 15 | istio: pilot 16 | release: {{ .Release.Name }} 17 | spec: 18 | ports: 19 | - port: 15010 20 | name: grpc-xds # plaintext 21 | protocol: TCP 22 | - port: 15012 23 | name: https-dns # mTLS with k8s-signed cert 24 | protocol: TCP 25 | - port: 443 26 | name: https-webhook # validation and injection 27 | targetPort: 15017 28 | protocol: TCP 29 | - port: 15014 30 | name: http-monitoring # prometheus stats 31 | protocol: TCP 32 | selector: 33 | app: istiod 34 | {{- if ne .Values.revision "" }} 35 | istio.io/rev: {{ .Values.revision }} 36 | {{- else }} 37 | # Label used by the 'default' service. For versioned deployments we match with app and version. 38 | # This avoids default deployment picking the canary 39 | istio: pilot 40 | {{- end }} 41 | --- 42 | -------------------------------------------------------------------------------- /controller/pkg/types/types.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 The Amesh Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package types 16 | 17 | import ( 18 | "k8s.io/apimachinery/pkg/util/sets" 19 | 20 | ameshv1alpha1 "github.com/api7/amesh/controller/apis/amesh/v1alpha1" 21 | ) 22 | 23 | type PodPluginConfig struct { 24 | Name string 25 | Plugins []ameshv1alpha1.AmeshPluginConfigPlugin 26 | Version string 27 | } 28 | 29 | type PodPluginConfigCache interface { 30 | GetPodPluginConfigs(key string) ([]*PodPluginConfig, error) 31 | } 32 | 33 | type UpdatePodPluginConfigEvent struct { 34 | Namespace string 35 | Pods sets.String 36 | //Plugins []ameshv1alpha1.AmeshPluginConfigPlugin 37 | } 38 | 39 | type PodChangeNotifier interface { 40 | AddPodChangeListener(receiver PodChangeReceiver) 41 | } 42 | 43 | type PodChangeReceiver interface { 44 | NotifyPodChange(*UpdatePodPluginConfigEvent) 45 | } 46 | -------------------------------------------------------------------------------- /e2e/framework/controlplane/controlplane.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 The Amesh Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package controlplane 16 | 17 | // ControlPlane represents the control plane in e2e test cases. 18 | type ControlPlane interface { 19 | // Type returns the control plane type. 20 | Type() string 21 | // Namespace fetches the deployed namespace of control plane components. 22 | Namespace() string 23 | // InjectNamespace marks the target namespace as injectable. Pod in this 24 | // namespace will be injected by control plane. 25 | InjectNamespace(string) error 26 | // Deploy deploys the control plane. 27 | Deploy() error 28 | // WaitForReady waits for control plane ready 29 | WaitForReady() error 30 | // Uninstall uninstalls the control plane. 31 | Uninstall() error 32 | // Addr returns the address to communicate with the control plane for fetching 33 | // configuration changes. 34 | Addr() string 35 | } 36 | -------------------------------------------------------------------------------- /e2e/charts/istio-discovery/templates/clusterrolebinding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | name: istiod-clusterrole{{- if not (eq .Values.revision "")}}-{{ .Values.revision }}{{- end }}-{{ .Release.Namespace }} 5 | labels: 6 | app: istiod 7 | release: {{ .Release.Name }} 8 | roleRef: 9 | apiGroup: rbac.authorization.k8s.io 10 | kind: ClusterRole 11 | name: istiod-clusterrole{{- if not (eq .Values.revision "")}}-{{ .Values.revision }}{{- end }}-{{ .Release.Namespace }} 12 | subjects: 13 | - kind: ServiceAccount 14 | name: istiod{{- if not (eq .Values.revision "")}}-{{ .Values.revision }}{{- end }} 15 | namespace: {{ .Values.global.istioNamespace }} 16 | --- 17 | {{- if not (eq (toString .Values.pilot.env.PILOT_ENABLE_GATEWAY_API_DEPLOYMENT_CONTROLLER) "false") }} 18 | apiVersion: rbac.authorization.k8s.io/v1 19 | kind: ClusterRoleBinding 20 | metadata: 21 | name: istiod-gateway-controller{{- if not (eq .Values.revision "")}}-{{ .Values.revision }}{{- end }}-{{ .Release.Namespace }} 22 | labels: 23 | app: istiod 24 | release: {{ .Release.Name }} 25 | roleRef: 26 | apiGroup: rbac.authorization.k8s.io 27 | kind: ClusterRole 28 | name: istiod-gateway-controller{{- if not (eq .Values.revision "")}}-{{ .Values.revision }}{{- end }}-{{ .Release.Namespace }} 29 | subjects: 30 | - kind: ServiceAccount 31 | name: istiod{{- if not (eq .Values.revision "")}}-{{ .Values.revision }}{{- end }} 32 | namespace: {{ .Values.global.istioNamespace }} 33 | {{- end }} -------------------------------------------------------------------------------- /Dockerfiles/iptables.Dockerfile: -------------------------------------------------------------------------------- 1 | # Copyright 2022 The Amesh Authors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # 15 | FROM golang:1.18 as amesh-iptables-build-stage 16 | 17 | ARG ENABLE_PROXY=false 18 | WORKDIR /amesh-iptables 19 | 20 | COPY cmd/iptables/go.* ./ 21 | RUN if [ "$ENABLE_PROXY" = "true" ]; then go env -w GOPROXY=https://goproxy.cn,direct ; fi \ 22 | && go mod download 23 | 24 | COPY cmd/iptables/Makefile Makefile 25 | COPY cmd/iptables . 26 | 27 | RUN if [ "$ENABLE_PROXY" = "true" ]; then go env -w GOPROXY=https://goproxy.cn,direct ; fi \ 28 | && make build-amesh-iptables 29 | 30 | FROM centos:7 31 | 32 | RUN yum install -y --disableplugin=fastestmirror \ 33 | iptables \ 34 | bash \ 35 | libstdc++ \ 36 | curl \ 37 | lsof \ 38 | patch \ 39 | which 40 | 41 | WORKDIR /usr/local/amesh 42 | 43 | COPY --from=amesh-iptables-build-stage /amesh-iptables/amesh-iptables ./ 44 | 45 | #COPY ./bin/amesh-iptables . 46 | 47 | ENTRYPOINT ["/usr/local/amesh/amesh-iptables"] 48 | -------------------------------------------------------------------------------- /api/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright 2021 The Amesh Authors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | PROTOC_GEN_VALIDATE_DIR ?= "" 16 | GOOGLE_PROTOBUF_DIR ?= "" 17 | GOOGLEAPIS_DIR ?= "" 18 | GO_OUT_DIR ?= go 19 | GO_TMP_DIR ?= . 20 | DOCS_OUT_DIR ?= docs 21 | 22 | PKG="github.com/api7/amesh/api" 23 | 24 | .PHONY: go 25 | go: go_proto 26 | rm -rf $(GO_TMP_DIR)/github.com 27 | 28 | .PHONY: go_proto 29 | go_proto: 30 | mkdir -p $(GO_OUT_DIR)/proto/v1 31 | protoc -I . \ 32 | -I $(PROTOC_GEN_VALIDATE_DIR) \ 33 | -I $(GOOGLE_PROTOBUF_DIR) \ 34 | -I $(GOOGLEAPIS_DIR) \ 35 | --go-grpc_out=$(GO_TMP_DIR) \ 36 | --go_out=$(GO_TMP_DIR) \ 37 | --validate_out="lang=go:$(GO_TMP_DIR)" \ 38 | proto/v1/*.proto 39 | cp -r $(GO_TMP_DIR)/$(PKG)/proto/v1 $(GO_OUT_DIR)/proto 40 | 41 | .PHONY: docs 42 | docs: 43 | protoc -I . \ 44 | -I $(PROTOC_GEN_VALIDATE_DIR) \ 45 | -I $(GOOGLE_PROTOBUF_DIR) \ 46 | -I $(GOOGLEAPIS_DIR) \ 47 | --doc_out=$(DOCS_OUT_DIR) \ 48 | --doc_opt=markdown,proto.md \ 49 | proto/v1/*.proto 50 | -------------------------------------------------------------------------------- /e2e/charts/istio-discovery/README.md: -------------------------------------------------------------------------------- 1 | # Istiod Helm Chart 2 | 3 | This chart installs an Istiod deployment. 4 | 5 | ## Setup Repo Info 6 | 7 | ```console 8 | helm repo add istio https://istio-release.storage.googleapis.com/charts 9 | helm repo update 10 | ``` 11 | 12 | _See [helm repo](https://helm.sh/docs/helm/helm_repo/) for command documentation._ 13 | 14 | ## Installing the Chart 15 | 16 | Before installing, ensure CRDs are installed in the cluster (from the `istio/base` chart). 17 | 18 | To install the chart with the release name `istiod`: 19 | 20 | ```console 21 | kubectl create namespace istio-system 22 | helm install istiod istio/istiod --namespace istio-system 23 | ``` 24 | 25 | ## Uninstalling the Chart 26 | 27 | To uninstall/delete the `istiod` deployment: 28 | 29 | ```console 30 | helm delete istiod --namespace istio-system 31 | ``` 32 | 33 | ## Configuration 34 | 35 | To view support configuration options and documentation, run: 36 | 37 | ```console 38 | helm show values istio/istiod 39 | ``` 40 | 41 | ### Examples 42 | 43 | #### Configuring mesh configuration settings 44 | 45 | Any [Mesh Config](https://istio.io/latest/docs/reference/config/istio.mesh.v1alpha1/) options can be configured like below: 46 | 47 | ```yaml 48 | meshConfig: 49 | accessLogFile: /dev/stdout 50 | ``` 51 | 52 | #### Revisions 53 | 54 | Control plane revisions allow deploying multiple versions of the control plane in the same cluster. 55 | This allows safe [canary upgrades](https://istio.io/latest/docs/setup/upgrade/canary/) 56 | 57 | ```yaml 58 | revision: my-revision-name 59 | ``` 60 | -------------------------------------------------------------------------------- /controller/charts/amesh-controller/templates/controller.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: amesh-controller 5 | labels: 6 | app: amesh-controller 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: amesh-controller 12 | template: 13 | metadata: 14 | name: amesh-controller 15 | labels: 16 | app: amesh-controller 17 | spec: 18 | serviceAccountName: amesh-controller-service-account 19 | containers: 20 | - name: amesh-controller 21 | image: "{{ .Values.controller.image }}" 22 | imagePullPolicy: {{ .Values.controller.pullPolicy }} 23 | resources: 24 | limits: 25 | cpu: 500m 26 | memory: 128Mi 27 | requests: 28 | cpu: 250m 29 | memory: 64Mi 30 | env: 31 | - name: POD_NAME 32 | valueFrom: 33 | fieldRef: 34 | fieldPath: metadata.name 35 | - name: POD_NAMESPACE 36 | valueFrom: 37 | fieldRef: 38 | fieldPath: metadata.namespace 39 | --- 40 | apiVersion: v1 41 | kind: Service 42 | metadata: 43 | name: amesh-controller 44 | labels: 45 | app: amesh-controller 46 | spec: 47 | publishNotReadyAddresses: true 48 | ports: 49 | - port: 18080 50 | targetPort: 18080 51 | name: metrics 52 | - port: 18081 53 | targetPort: 18081 54 | name: health 55 | - port: 15810 56 | targetPort: 15810 57 | name: grpc 58 | selector: 59 | app: amesh-controller 60 | -------------------------------------------------------------------------------- /e2e/bookinfo/bookinfo-details-v2.yaml: -------------------------------------------------------------------------------- 1 | # Copyright Istio Authors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | ################################################################################################## 16 | # Details service v2 17 | ################################################################################################## 18 | apiVersion: apps/v1 19 | kind: Deployment 20 | metadata: 21 | name: details-v2 22 | labels: 23 | app: details 24 | version: v2 25 | spec: 26 | replicas: 1 27 | selector: 28 | matchLabels: 29 | app: details 30 | version: v2 31 | template: 32 | metadata: 33 | labels: 34 | app: details 35 | version: v2 36 | spec: 37 | containers: 38 | - name: details 39 | image: docker.io/istio/examples-bookinfo-details-v2:1.16.2 40 | imagePullPolicy: IfNotPresent 41 | ports: 42 | - containerPort: 9080 43 | env: 44 | - name: DO_NOT_ENCRYPT 45 | value: "true" 46 | securityContext: 47 | runAsUser: 1000 48 | --- 49 | -------------------------------------------------------------------------------- /controller/Dockerfile: -------------------------------------------------------------------------------- 1 | # Copyright 2022 The Amesh Authors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Build the manager binary 16 | FROM golang:1.18 as builder 17 | 18 | WORKDIR /workspace/amesh/controller 19 | # Copy the Go Modules manifests 20 | COPY go.mod go.mod 21 | COPY go.sum go.sum 22 | # cache deps before building and copying source so that we don't need to re-download as much 23 | # and so that source changes don't invalidate our downloaded layer 24 | COPY .api.tmp ../api 25 | RUN go mod download 26 | 27 | # Copy the go source 28 | COPY apis/ apis/ 29 | COPY main.go main.go 30 | COPY utils/ utils/ 31 | COPY pkg/ pkg/ 32 | COPY controllers/ controllers/ 33 | 34 | # Build 35 | RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o manager main.go 36 | 37 | # Use distroless as minimal base image to package the manager binary 38 | # Refer to https://github.com/GoogleContainerTools/distroless for more details 39 | FROM gcr.io/distroless/static:nonroot 40 | WORKDIR / 41 | COPY --from=builder /workspace/amesh/controller/manager . 42 | USER 65532:65532 43 | 44 | ENTRYPOINT ["/manager"] 45 | -------------------------------------------------------------------------------- /e2e/charts/base/crds/crd-operator.yaml: -------------------------------------------------------------------------------- 1 | # SYNC WITH manifests/charts/istio-operator/templates 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | name: istiooperators.install.istio.io 6 | labels: 7 | release: istio 8 | spec: 9 | conversion: 10 | strategy: None 11 | group: install.istio.io 12 | names: 13 | kind: IstioOperator 14 | listKind: IstioOperatorList 15 | plural: istiooperators 16 | singular: istiooperator 17 | shortNames: 18 | - iop 19 | - io 20 | scope: Namespaced 21 | versions: 22 | - additionalPrinterColumns: 23 | - description: Istio control plane revision 24 | jsonPath: .spec.revision 25 | name: Revision 26 | type: string 27 | - description: IOP current state 28 | jsonPath: .status.status 29 | name: Status 30 | type: string 31 | - description: 'CreationTimestamp is a timestamp representing the server time 32 | when this object was created. It is not guaranteed to be set in happens-before 33 | order across separate operations. Clients may not set this value. It is represented 34 | in RFC3339 form and is in UTC. Populated by the system. Read-only. Null for 35 | lists. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata' 36 | jsonPath: .metadata.creationTimestamp 37 | name: Age 38 | type: date 39 | subresources: 40 | status: {} 41 | name: v1alpha1 42 | schema: 43 | openAPIV3Schema: 44 | type: object 45 | x-kubernetes-preserve-unknown-fields: true 46 | served: true 47 | storage: true 48 | --- 49 | -------------------------------------------------------------------------------- /controller/apis/client/informers/externalversions/internalinterfaces/factory_interfaces.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2022 The Amesh Authors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | // Code generated by informer-gen. DO NOT EDIT. 17 | 18 | package internalinterfaces 19 | 20 | import ( 21 | time "time" 22 | 23 | versioned "github.com/api7/amesh/controller/apis/client/clientset/versioned" 24 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 25 | runtime "k8s.io/apimachinery/pkg/runtime" 26 | cache "k8s.io/client-go/tools/cache" 27 | ) 28 | 29 | // NewInformerFunc takes versioned.Interface and time.Duration to return a SharedIndexInformer. 30 | type NewInformerFunc func(versioned.Interface, time.Duration) cache.SharedIndexInformer 31 | 32 | // SharedInformerFactory a small interface to allow for adding an informer without an import cycle 33 | type SharedInformerFactory interface { 34 | Start(stopCh <-chan struct{}) 35 | InformerFor(obj runtime.Object, newFunc NewInformerFunc) cache.SharedIndexInformer 36 | } 37 | 38 | // TweakListOptionsFunc is a function that transforms a v1.ListOptions. 39 | type TweakListOptionsFunc func(*v1.ListOptions) 40 | -------------------------------------------------------------------------------- /e2e/bookinfo/bookinfo-db.yaml: -------------------------------------------------------------------------------- 1 | # Copyright Istio Authors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | apiVersion: v1 16 | kind: Service 17 | metadata: 18 | name: mongodb 19 | labels: 20 | app: mongodb 21 | service: mongodb 22 | spec: 23 | ports: 24 | - port: 27017 25 | name: mongo 26 | selector: 27 | app: mongodb 28 | --- 29 | apiVersion: apps/v1 30 | kind: Deployment 31 | metadata: 32 | name: mongodb-v1 33 | labels: 34 | app: mongodb 35 | version: v1 36 | spec: 37 | replicas: 1 38 | selector: 39 | matchLabels: 40 | app: mongodb 41 | version: v1 42 | template: 43 | metadata: 44 | labels: 45 | app: mongodb 46 | version: v1 47 | spec: 48 | containers: 49 | - name: mongodb 50 | image: docker.io/istio/examples-bookinfo-mongodb:1.16.2 51 | imagePullPolicy: IfNotPresent 52 | ports: 53 | - containerPort: 27017 54 | volumeMounts: 55 | - name: data-db 56 | mountPath: /data/db 57 | volumes: 58 | - name: data-db 59 | emptyDir: {} 60 | --- 61 | -------------------------------------------------------------------------------- /manifest/manifest.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2022 The Amesh Authors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # 15 | apiVersion: v1 16 | kind: Pod 17 | metadata: 18 | name: test-sidecar 19 | spec: 20 | containers: 21 | - name: istio-proxy 22 | image: 10.0.0.20:5000/amesh-sidecar:dev 23 | # ports: 24 | # - containerPort: 9080 25 | # protocol: TCP 26 | # name: http-outbound 27 | # - containerPort: 9081 28 | # protocol: TCP 29 | # name: http-inbound 30 | # - containerPort: 17739 31 | # protocol: TCP 32 | # name: agent 33 | args: 34 | - run 35 | - --xds-config-source 36 | - "grpc://istiod.istio-system.svc.cluster.local:15010" 37 | env: 38 | - name: POD_NAME 39 | value: details-v1-79f774bdb9-s4d7w 40 | # valueFrom: 41 | # fieldRef: 42 | # fieldPath: metadata.name 43 | - name: POD_NAMESPACE 44 | value: test 45 | # valueFrom: 46 | # fieldRef: 47 | # fieldPath: metadata.namespace 48 | imagePullPolicy: Always 49 | -------------------------------------------------------------------------------- /pkg/version/version.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 The Amesh Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package version 15 | 16 | import ( 17 | "bytes" 18 | "fmt" 19 | "runtime" 20 | "strconv" 21 | "time" 22 | ) 23 | 24 | var ( 25 | // The following fields are populated at build time using -ldflags -X. 26 | _version = "unknown" 27 | _gitRevision = "unknown" 28 | _timestamp = "0" 29 | ) 30 | 31 | // Short returns a short version representation. 32 | func Short() string { 33 | return _version 34 | } 35 | 36 | // String returns a readable version info. 37 | func String() string { 38 | buf := bytes.NewBuffer(nil) 39 | fmt.Fprintf(buf, "Version: %s\n", _version) 40 | fmt.Fprintf(buf, "Git SHA: %s\n", _gitRevision) 41 | fmt.Fprintf(buf, "Go Version: %s\n", runtime.Version()) 42 | fmt.Fprintf(buf, "OS/Arch: %s/%s\n", runtime.GOOS, runtime.GOARCH) 43 | 44 | ts, err := strconv.ParseInt(_timestamp, 10, 32) 45 | if err != nil { 46 | fmt.Fprintln(buf, "Build Date: unknown") 47 | } else { 48 | date := time.Unix(ts, 0) 49 | fmt.Fprintf(buf, "Build Date: %s\n", date.String()) 50 | } 51 | 52 | return buf.String() 53 | } 54 | -------------------------------------------------------------------------------- /e2e/bookinfo/bookinfo-ingress.yaml: -------------------------------------------------------------------------------- 1 | # Copyright Istio Authors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | ########################################################################### 16 | # Ingress resource (gateway) 17 | ########################################################################## 18 | apiVersion: networking.k8s.io/v1beta1 19 | kind: Ingress 20 | metadata: 21 | name: gateway 22 | annotations: 23 | kubernetes.io/ingress.class: "istio" 24 | spec: 25 | rules: 26 | - http: 27 | paths: 28 | - path: /productpage 29 | backend: 30 | serviceName: productpage 31 | servicePort: 9080 32 | - path: /static/* 33 | backend: 34 | serviceName: productpage 35 | servicePort: 9080 36 | - path: /login 37 | backend: 38 | serviceName: productpage 39 | servicePort: 9080 40 | - path: /logout 41 | backend: 42 | serviceName: productpage 43 | servicePort: 9080 44 | - path: /api/v1/products.* 45 | backend: 46 | serviceName: productpage 47 | servicePort: 9080 48 | --- 49 | -------------------------------------------------------------------------------- /pkg/amesh/util/string_set.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 The Amesh Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package util 15 | 16 | import "sort" 17 | 18 | // StringSet represents a set which elements are string. 19 | type StringSet map[string]struct{} 20 | 21 | // Add adds an element to set. 22 | func (set StringSet) Add(e string) { 23 | set[e] = struct{}{} 24 | } 25 | 26 | // Equals compares two string set and checks whether they are identical. 27 | func (set StringSet) Equals(set2 StringSet) bool { 28 | if len(set) != len(set2) { 29 | return false 30 | } 31 | for e := range set2 { 32 | if _, ok := set[e]; !ok { 33 | return false 34 | } 35 | } 36 | for e := range set { 37 | if _, ok := set2[e]; !ok { 38 | return false 39 | } 40 | } 41 | return true 42 | } 43 | 44 | // Strings converts the string set to a string slice. 45 | func (set StringSet) Strings() []string { 46 | s := make([]string, 0, len(set)) 47 | for e := range set { 48 | s = append(s, e) 49 | } 50 | return s 51 | } 52 | 53 | // OrderedStrings converts the string set to a sorted string slice. 54 | func (set StringSet) OrderedStrings() []string { 55 | s := set.Strings() 56 | sort.Strings(s) 57 | return s 58 | } 59 | -------------------------------------------------------------------------------- /e2e/bookinfo/bookinfo-details.yaml: -------------------------------------------------------------------------------- 1 | # Copyright Istio Authors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | ################################################################################################## 16 | # Details service 17 | ################################################################################################## 18 | apiVersion: v1 19 | kind: Service 20 | metadata: 21 | name: details 22 | labels: 23 | app: details 24 | service: details 25 | spec: 26 | ports: 27 | - port: 9080 28 | name: http 29 | selector: 30 | app: details 31 | --- 32 | apiVersion: apps/v1 33 | kind: Deployment 34 | metadata: 35 | name: details-v1 36 | labels: 37 | app: details 38 | version: v1 39 | spec: 40 | replicas: 1 41 | selector: 42 | matchLabels: 43 | app: details 44 | version: v1 45 | template: 46 | metadata: 47 | labels: 48 | app: details 49 | version: v1 50 | spec: 51 | containers: 52 | - name: details 53 | image: docker.io/istio/examples-bookinfo-details-v1:1.16.2 54 | imagePullPolicy: IfNotPresent 55 | ports: 56 | - containerPort: 9080 57 | securityContext: 58 | runAsUser: 1000 59 | --- 60 | -------------------------------------------------------------------------------- /e2e/bookinfo/bookinfo-ratings.yaml: -------------------------------------------------------------------------------- 1 | # Copyright Istio Authors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | ################################################################################################## 16 | # Ratings service 17 | ################################################################################################## 18 | apiVersion: v1 19 | kind: Service 20 | metadata: 21 | name: ratings 22 | labels: 23 | app: ratings 24 | service: ratings 25 | spec: 26 | ports: 27 | - port: 9080 28 | name: http 29 | selector: 30 | app: ratings 31 | --- 32 | apiVersion: apps/v1 33 | kind: Deployment 34 | metadata: 35 | name: ratings-v1 36 | labels: 37 | app: ratings 38 | version: v1 39 | spec: 40 | replicas: 1 41 | selector: 42 | matchLabels: 43 | app: ratings 44 | version: v1 45 | template: 46 | metadata: 47 | labels: 48 | app: ratings 49 | version: v1 50 | spec: 51 | containers: 52 | - name: ratings 53 | image: docker.io/istio/examples-bookinfo-ratings-v1:1.16.2 54 | imagePullPolicy: IfNotPresent 55 | ports: 56 | - containerPort: 9080 57 | securityContext: 58 | runAsUser: 1000 59 | --- 60 | -------------------------------------------------------------------------------- /controller/hack/update-codegen.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Licensed to the Apache Software Foundation (ASF) under one or more 4 | # contributor license agreements. See the NOTICE file distributed with 5 | # this work for additional information regarding copyright ownership. 6 | # The ASF licenses this file to You under the Apache License, Version 2.0 7 | # (the "License"); you may not use this file except in compliance with 8 | # the License. You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | set -o errexit 20 | set -o nounset 21 | set -o pipefail 22 | 23 | SCRIPT_ROOT=$(dirname "${BASH_SOURCE[0]}") 24 | PROJECT_ROOT="$SCRIPT_ROOT/.." 25 | GENERATED_ROOT="$PROJECT_ROOT/.generated" 26 | 27 | PKG_NAME="github.com/api7/amesh" 28 | 29 | # Make sure no pollution 30 | rm -rf "$GENERATED_ROOT" 31 | 32 | bash "${SCRIPT_ROOT}"/generate-groups.sh "deepcopy,client,informer,lister" \ 33 | ${PKG_NAME}/apis/client ${PKG_NAME}/apis \ 34 | amesh:v1alpha1 ${PKG_NAME} \ 35 | --output-base "$GENERATED_ROOT" \ 36 | --go-header-file "${SCRIPT_ROOT}"/boilerplate.go.txt \ 37 | "$@" 38 | 39 | bash "${SCRIPT_ROOT}"/generate-groups.sh "register" \ 40 | ${PKG_NAME}/apis ${PKG_NAME}/apis \ 41 | amesh:v1alpha1 ${PKG_NAME} \ 42 | --output-base "$GENERATED_ROOT" \ 43 | --go-header-file "${SCRIPT_ROOT}"/boilerplate.go.txt \ 44 | "$@" 45 | 46 | cp -r "$GENERATED_ROOT/${PKG_NAME}/"** "$PROJECT_ROOT" 47 | rm -rf "$GENERATED_ROOT" 48 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Amesh 2 | 3 | Amesh is a service mesh library for [Apache APISIX](http://apisix.apache.org/). It adapts the xDS protocol, receives data from Istio's control plane, and generates the APISIX data structure. In addition, APISIX does not use the traditional data center etcd, but uses shdict to exchange data with the Amesh library. 4 | 5 | ## Project Status 6 | 7 | The Amesh project is currently under active development and is considered to be experimental. 8 | 9 | ## Architecture 10 | 11 | ![arch](./docs/images/arch.png) 12 | 13 | ## Quick Start 14 | 15 | Refer to the document [Amesh Demo](./docs/en/demo.md) to quickly run the demo with Istio. 16 | 17 | ## How It Works 18 | 19 | The Amesh injection template will create an init container, which will setup some iptables rules. These rules will capture all inbound and outbound traffic to APISIX, which allows APISIX to handle all traffic, providing the abilities and benefits of APISIX to full traffic management. 20 | 21 | Configure Apache APISIX to use xDS as the `config_center`, which will make APISIX to load the Amesh library and load data from the shdict shared by APISIX and Amesh, instead of etcd. 22 | 23 | The Amesh library will use the xDS protocol to communicate with the Istio control plane. It will translate xDS resources into APISIX routes and upstreams and store the data in shdict. When APISIX detects new data is written, the new configuration will be applied. In this way, APISIX can gain the ability of servise mesh by acting as sidecar of Istio. 24 | 25 | ## Support 26 | 27 | If you encounter any problems with Amesh, please refer to our [Issues]((https://github.com/api7/amesh/issues)) list. If your issue doesn't appear in the issues list, please [create a new one](https://github.com/api7/amesh/issues/new). 28 | 29 | ## Contribute 30 | 31 | ## License 32 | 33 | [Apache 2.0 LICENSE](./LICENSE) 34 | -------------------------------------------------------------------------------- /e2e/bookinfo/bookinfo-ratings-v2-mysql-vm.yaml: -------------------------------------------------------------------------------- 1 | # Copyright Istio Authors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | apiVersion: apps/v1 16 | kind: Deployment 17 | metadata: 18 | name: ratings-v2-mysql-vm 19 | labels: 20 | app: ratings 21 | version: v2-mysql-vm 22 | spec: 23 | replicas: 1 24 | selector: 25 | matchLabels: 26 | app: ratings 27 | version: v2-mysql-vm 28 | template: 29 | metadata: 30 | labels: 31 | app: ratings 32 | version: v2-mysql-vm 33 | spec: 34 | containers: 35 | - name: ratings 36 | image: docker.io/istio/examples-bookinfo-ratings-v2:1.16.2 37 | imagePullPolicy: IfNotPresent 38 | env: 39 | # This assumes you registered your mysql vm as 40 | # istioctl register -n vm mysqldb 1.2.3.4 3306 41 | - name: DB_TYPE 42 | value: "mysql" 43 | - name: MYSQL_DB_HOST 44 | value: mysqldb.vm.svc.cluster.local 45 | - name: MYSQL_DB_PORT 46 | value: "3306" 47 | - name: MYSQL_DB_USER 48 | value: root 49 | - name: MYSQL_DB_PASSWORD 50 | value: password 51 | ports: 52 | - containerPort: 9080 53 | securityContext: 54 | runAsUser: 1000 55 | --- 56 | -------------------------------------------------------------------------------- /Dockerfiles/amesh-sidecar.Dockerfile: -------------------------------------------------------------------------------- 1 | # Copyright 2022 The Amesh Authors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | FROM golang:1.18 as amesh-sidecar-build-stage 16 | 17 | ARG ENABLE_PROXY=false 18 | WORKDIR /amesh 19 | 20 | COPY api/ api/ 21 | COPY controller/go.* controller/ 22 | COPY controller/apis controller/apis 23 | COPY go.* ./ 24 | RUN if [ "$ENABLE_PROXY" = "true" ]; then go env -w GOPROXY=https://goproxy.cn,direct ; fi \ 25 | && go mod download 26 | 27 | COPY Makefile Makefile 28 | COPY cmd/dynamic cmd/dynamic 29 | COPY pkg/ pkg/ 30 | RUN if [ "$ENABLE_PROXY" = "true" ]; then go env -w GOPROXY=https://goproxy.cn,direct ; fi \ 31 | && make build-amesh-so 32 | 33 | FROM istio/proxyv2:1.13.1 as istio-proxyv2 34 | 35 | FROM amesh-apisix:dev 36 | 37 | WORKDIR / 38 | COPY --from=istio-proxyv2 /usr/local/bin/pilot-agent /usr/local/bin/pilot-agent 39 | COPY --from=istio-proxyv2 /var/lib/istio/envoy/envoy_bootstrap_tmpl.json /var/lib/istio/envoy/envoy_bootstrap_tmpl.json 40 | COPY --from=istio-proxyv2 /var/lib/istio/envoy/gcp_envoy_bootstrap_tmpl.json /var/lib/istio/envoy/gcp_envoy_bootstrap_tmpl.json 41 | COPY Dockerfiles/entry.sh /usr/local/bin/envoy 42 | 43 | COPY Dockerfiles/config.yaml /usr/local/apisix/conf/config.yaml 44 | COPY --from=amesh-sidecar-build-stage /amesh/bin/libxds.so /usr/local/apisix/libxds.so 45 | -------------------------------------------------------------------------------- /controller/apis/client/informers/externalversions/amesh/interface.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2022 The Amesh Authors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | // Code generated by informer-gen. DO NOT EDIT. 17 | 18 | package amesh 19 | 20 | import ( 21 | v1alpha1 "github.com/api7/amesh/controller/apis/client/informers/externalversions/amesh/v1alpha1" 22 | internalinterfaces "github.com/api7/amesh/controller/apis/client/informers/externalversions/internalinterfaces" 23 | ) 24 | 25 | // Interface provides access to each of this group's versions. 26 | type Interface interface { 27 | // V1alpha1 provides access to shared informers for resources in V1alpha1. 28 | V1alpha1() v1alpha1.Interface 29 | } 30 | 31 | type group struct { 32 | factory internalinterfaces.SharedInformerFactory 33 | namespace string 34 | tweakListOptions internalinterfaces.TweakListOptionsFunc 35 | } 36 | 37 | // New returns a new Interface. 38 | func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { 39 | return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} 40 | } 41 | 42 | // V1alpha1 returns a new v1alpha1.Interface. 43 | func (g *group) V1alpha1() v1alpha1.Interface { 44 | return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions) 45 | } 46 | -------------------------------------------------------------------------------- /controller/apis/client/informers/externalversions/amesh/v1alpha1/interface.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2022 The Amesh Authors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | // Code generated by informer-gen. DO NOT EDIT. 17 | 18 | package v1alpha1 19 | 20 | import ( 21 | internalinterfaces "github.com/api7/amesh/controller/apis/client/informers/externalversions/internalinterfaces" 22 | ) 23 | 24 | // Interface provides access to all the informers in this group version. 25 | type Interface interface { 26 | // AmeshPluginConfigs returns a AmeshPluginConfigInformer. 27 | AmeshPluginConfigs() AmeshPluginConfigInformer 28 | } 29 | 30 | type version struct { 31 | factory internalinterfaces.SharedInformerFactory 32 | namespace string 33 | tweakListOptions internalinterfaces.TweakListOptionsFunc 34 | } 35 | 36 | // New returns a new Interface. 37 | func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { 38 | return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} 39 | } 40 | 41 | // AmeshPluginConfigs returns a AmeshPluginConfigInformer. 42 | func (v *version) AmeshPluginConfigs() AmeshPluginConfigInformer { 43 | return &ameshPluginConfigInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} 44 | } 45 | -------------------------------------------------------------------------------- /e2e/e2e_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 The Amesh Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Licensed to the Apache Software Foundation (ASF) under one or more 16 | // contributor license agreements. See the NOTICE file distributed with 17 | // this work for additional information regarding copyright ownership. 18 | // The ASF licenses this file to You under the Apache License, Version 2.0 19 | // (the "License"); you may not use this file except in compliance with 20 | // the License. You may obtain a copy of the License at 21 | // 22 | // http://www.apache.org/licenses/LICENSE-2.0 23 | // 24 | // Unless required by applicable law or agreed to in writing, software 25 | // distributed under the License is distributed on an "AS IS" BASIS, 26 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 27 | // See the License for the specific language governing permissions and 28 | // limitations under the License. 29 | 30 | package e2e 31 | 32 | import ( 33 | "os" 34 | "testing" 35 | 36 | ginkgo "github.com/onsi/ginkgo/v2" 37 | ) 38 | 39 | func TestRunE2E(t *testing.T) { 40 | pwd, err := os.Getwd() 41 | if err != nil { 42 | panic(err) 43 | } 44 | if err := os.Setenv("AMESH_E2E_HOME", pwd); err != nil { 45 | panic(err) 46 | } 47 | 48 | runE2E() 49 | ginkgo.RunSpecs(t, "amesh e2e test suites") 50 | } 51 | -------------------------------------------------------------------------------- /e2e/bookinfo/bookinfo-reviews-v2.yaml: -------------------------------------------------------------------------------- 1 | # Copyright Istio Authors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | ################################################################################################## 16 | # Reviews service v2 17 | ################################################################################################## 18 | apiVersion: apps/v1 19 | kind: Deployment 20 | metadata: 21 | name: reviews-v2 22 | labels: 23 | app: reviews 24 | version: v2 25 | spec: 26 | replicas: 1 27 | selector: 28 | matchLabels: 29 | app: reviews 30 | version: v2 31 | template: 32 | metadata: 33 | labels: 34 | app: reviews 35 | version: v2 36 | spec: 37 | containers: 38 | - name: reviews 39 | image: docker.io/istio/examples-bookinfo-reviews-v2:1.16.2 40 | imagePullPolicy: IfNotPresent 41 | env: 42 | - name: LOG_DIR 43 | value: "/tmp/logs" 44 | ports: 45 | - containerPort: 9080 46 | volumeMounts: 47 | - name: tmp 48 | mountPath: /tmp 49 | - name: wlp-output 50 | mountPath: /opt/ibm/wlp/output 51 | securityContext: 52 | runAsUser: 1000 53 | volumes: 54 | - name: wlp-output 55 | emptyDir: {} 56 | - name: tmp 57 | emptyDir: {} 58 | --- 59 | -------------------------------------------------------------------------------- /pkg/apisix/base.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 The Amesh Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package apisix 15 | 16 | import "strings" 17 | 18 | // Valid Var array: 19 | // ["XXX", "==", "YYY"] 20 | // ["XXX", "in", ["A", "B", "C"]] 21 | // A Var should be string or string array 22 | type Var []interface{} 23 | 24 | // ToComparableString converts Var to string 25 | // The function doesn't guarantee that there are no conflicts in any case. 26 | func (v *Var) ToComparableString() string { 27 | s := "" 28 | 29 | for _, val := range *v { 30 | switch value := val.(type) { 31 | case string: 32 | // escape dot to avoid conflict 33 | s += strings.Replace(value, ".", `..`, -1) + "." 34 | case *Var: 35 | s += value.ToComparableString() + "." 36 | } 37 | } 38 | 39 | return s 40 | } 41 | 42 | // Timeout represents the timeout settings. 43 | // It's worth to note that the timeout is used to control the time duration 44 | // between two successive I/O operations. It doesn't constraint the whole I/O 45 | // operation durations. 46 | type Timeout struct { 47 | // connect controls the connect timeout in seconds. 48 | Connect float64 `json:"connect,omitempty"` 49 | // send controls the send timeout in seconds. 50 | Send float64 `json:"send,omitempty"` 51 | // read controls the read timeout in seconds. 52 | Read float64 `json:"read,omitempty"` 53 | } 54 | -------------------------------------------------------------------------------- /pkg/apisix/base_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 The Amesh Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package apisix 16 | 17 | import ( 18 | "testing" 19 | 20 | "github.com/api7/gopkg/pkg/log" 21 | "github.com/stretchr/testify/assert" 22 | "go.uber.org/zap" 23 | ) 24 | 25 | func TestVarToComparableString(t *testing.T) { 26 | cases := []struct { 27 | a *Var 28 | b *Var 29 | result bool 30 | }{ 31 | { 32 | a: &Var{}, 33 | b: &Var{}, 34 | result: true, 35 | }, 36 | { 37 | a: &Var{"A", "==", "B"}, 38 | b: &Var{"A", "==", "B"}, 39 | result: true, 40 | }, 41 | { 42 | a: &Var{"A", "in", &Var{"B", "C"}}, 43 | b: &Var{"A", "in", &Var{"B", "C"}}, 44 | result: true, 45 | }, 46 | { 47 | a: &Var{"A", "in", &Var{"B", "C"}}, 48 | b: &Var{"A", "in", &Var{"BC"}}, 49 | result: false, 50 | }, 51 | { 52 | a: &Var{"A", "in", &Var{"B", "C"}}, 53 | b: &Var{"A", "in", &Var{"B.C"}}, 54 | result: false, 55 | }, 56 | { 57 | a: &Var{"A", "in", &Var{"B.", "C"}}, 58 | b: &Var{"A", "in", &Var{"B..C"}}, 59 | result: false, 60 | }, 61 | } 62 | 63 | for _, tc := range cases { 64 | aStr := tc.a.ToComparableString() 65 | bStr := tc.b.ToComparableString() 66 | log.Errorw("compare", 67 | zap.String("a", aStr), 68 | zap.String("b", bStr), 69 | ) 70 | assert.Equal(t, tc.result, aStr == bStr) 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /cmd/lua/test.lua: -------------------------------------------------------------------------------- 1 | -- Copyright 2022 The Amesh Authors 2 | -- 3 | -- Licensed under the Apache License, Version 2.0 (the "License"); 4 | -- you may not use this file except in compliance with the License. 5 | -- You may obtain a copy of the License at 6 | -- 7 | -- http://www.apache.org/licenses/LICENSE-2.0 8 | -- 9 | -- Unless required by applicable law or agreed to in writing, software 10 | -- distributed under the License is distributed on an "AS IS" BASIS, 11 | -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | -- See the License for the specific language governing permissions and 13 | -- limitations under the License. 14 | -- 15 | local ffi = require "ffi" 16 | 17 | local amesh = ffi.load("/amesh/libxds.so") 18 | -- local amesh = ffi.load("./libxds.so") 19 | 20 | ffi.cdef[[ 21 | typedef signed char GoInt8; 22 | typedef unsigned char GoUint8; 23 | typedef short GoInt16; 24 | typedef unsigned short GoUint16; 25 | typedef int GoInt32; 26 | typedef unsigned int GoUint32; 27 | typedef long long GoInt64; 28 | typedef unsigned long long GoUint64; 29 | typedef GoInt64 GoInt; 30 | typedef GoUint64 GoUint; 31 | typedef float GoFloat32; 32 | typedef double GoFloat64; 33 | typedef float _Complex GoComplex64; 34 | typedef double _Complex GoComplex128; 35 | 36 | typedef struct { const char *p; ptrdiff_t n; } _GoString_; 37 | typedef _GoString_ GoString; 38 | 39 | typedef void *GoMap; 40 | typedef void *GoChan; 41 | typedef struct { void *t; void *v; } GoInterface; 42 | typedef struct { void *data; GoInt len; GoInt cap; } GoSlice; 43 | 44 | extern void Log(GoString msg); 45 | extern void StartAmesh(GoString src); 46 | 47 | ]] 48 | 49 | 50 | xdsSrc = ffi.new("GoString") 51 | local s = "grpc://istiod.istio-system.svc.cluster.local:15010" 52 | xdsSrc.p = s; 53 | xdsSrc.n = #s; 54 | 55 | amesh.StartAmesh(xdsSrc) 56 | 57 | startedStr = ffi.new("GoString") 58 | local msg = "amesh started" 59 | startedStr.p = msg; 60 | startedStr.n = #msg; 61 | amesh.Log(startedStr) 62 | while true do 63 | 64 | end -------------------------------------------------------------------------------- /e2e/test/istio/traffic_management/3_traffic_shifting.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 The Amesh Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package traffic_management 16 | 17 | import ( 18 | "strings" 19 | 20 | "github.com/onsi/ginkgo/v2" 21 | "github.com/stretchr/testify/assert" 22 | 23 | "github.com/api7/amesh/e2e/framework" 24 | "github.com/api7/amesh/e2e/framework/utils" 25 | ) 26 | 27 | var _ = ginkgo.Describe("[istio functions] Route Configuration:", func() { 28 | f := framework.NewDefaultFramework() 29 | utils.Case("should be able to split traffic", func() { 30 | tester := NewVirtualServiceTester(f, []string{"v1", "v2"}) 31 | 32 | tester.Create() 33 | 34 | // apply routes 35 | tester.AddWeightedRoutes("nginx-kind", []string{"v1", "v2"}) 36 | tester.ApplyRoute() 37 | 38 | // validate access count 39 | v1Counter := 0 40 | v2Counter := 0 41 | doRequest := func() { 42 | output := tester.DoAccess(200, nil, nil, "nginx-kind/status") 43 | if strings.Contains(output, "ngx-v1") { 44 | v1Counter++ 45 | } else if strings.Contains(output, "ngx-v2") { 46 | v2Counter++ 47 | } 48 | } 49 | doRequest() 50 | doRequest() 51 | doRequest() 52 | doRequest() 53 | 54 | assert.NotEqual(ginkgo.GinkgoT(), 0, v1Counter, "check v1 accessed") 55 | assert.NotEqual(ginkgo.GinkgoT(), 0, v2Counter, "check v2 accessed") 56 | assert.Equal(ginkgo.GinkgoT(), 4, v1Counter+v2Counter, "check total accessed") 57 | }) 58 | }) 59 | -------------------------------------------------------------------------------- /controller/pkg/instance_manager.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 The Amesh Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package pkg 16 | 17 | import ( 18 | "sync" 19 | 20 | "github.com/api7/amesh/controller/pkg/metrics" 21 | ) 22 | 23 | type ProxyInstance struct { 24 | UpdateNotifyChan chan struct{} 25 | //UpdateFunc func() error 26 | } 27 | 28 | type InstanceManager struct { 29 | lock sync.RWMutex 30 | instances map[string]*ProxyInstance 31 | collector metrics.Collector 32 | } 33 | 34 | func NewInstanceManager(collector metrics.Collector) *InstanceManager { 35 | return &InstanceManager{ 36 | instances: map[string]*ProxyInstance{}, 37 | collector: collector, 38 | } 39 | } 40 | 41 | func (m *InstanceManager) get(key string) *ProxyInstance { 42 | m.lock.RLock() 43 | i, ok := m.instances[key] 44 | m.lock.RUnlock() 45 | 46 | if ok { 47 | return i 48 | } 49 | return nil 50 | } 51 | 52 | func (m *InstanceManager) add(key string, instance *ProxyInstance) { 53 | m.lock.Lock() 54 | m.instances[key] = instance 55 | m.lock.Unlock() 56 | m.collector.IncManagedInstances() 57 | } 58 | 59 | func (m *InstanceManager) delete(key string) { 60 | m.lock.Lock() 61 | delete(m.instances, key) 62 | m.lock.Unlock() 63 | m.collector.DecManagedInstances() 64 | } 65 | 66 | func (m *InstanceManager) foreach(fn func(*ProxyInstance)) { 67 | m.lock.RLock() 68 | defer m.lock.RUnlock() 69 | for _, instance := range m.instances { 70 | fn(instance) 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /.licenserc.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2022 The Amesh Authors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | header: 16 | license: 17 | spdx-id: Apache-2.0 18 | copyright-owner: Apache Software Foundation 19 | content: | 20 | Copyright 2022 The Amesh Authors 21 | 22 | Licensed under the Apache License, Version 2.0 (the "License"); 23 | you may not use this file except in compliance with the License. 24 | You may obtain a copy of the License at 25 | 26 | http://www.apache.org/licenses/LICENSE-2.0 27 | 28 | Unless required by applicable law or agreed to in writing, software 29 | distributed under the License is distributed on an "AS IS" BASIS, 30 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 31 | See the License for the specific language governing permissions and 32 | limitations under the License. 33 | 34 | paths-ignore: 35 | - '.idea' 36 | - '.vscode' 37 | - '.gitignore' 38 | - '.gitattributes' 39 | - '.gitmodules' 40 | - '.dockerignore' 41 | - 'Makefile' 42 | - '**/*.md' 43 | - '**/testdata/**' 44 | - '**/go.mod' 45 | - '**/go.sum' 46 | - 'LICENSE' 47 | - 'NOTICE' 48 | - '**/*.json' 49 | - '.github/**' 50 | - 'scripts' 51 | - 'charts' 52 | - '**/*.patch' 53 | - '**/*.yaml' 54 | - '**/*.proto' 55 | - 'PROJECT' 56 | - 'controller/hack/**' 57 | - '**/*.out' 58 | - 'api/go/proto/**' 59 | - 'Dockerfiles/**' 60 | - '**/*.h' 61 | comment: never 62 | -------------------------------------------------------------------------------- /e2e/bookinfo/bookinfo-ratings-v2-mysql.yaml: -------------------------------------------------------------------------------- 1 | # Copyright Istio Authors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | apiVersion: apps/v1 16 | kind: Deployment 17 | metadata: 18 | name: ratings-v2-mysql 19 | labels: 20 | app: ratings 21 | version: v2-mysql 22 | spec: 23 | replicas: 1 24 | selector: 25 | matchLabels: 26 | app: ratings 27 | version: v2-mysql 28 | template: 29 | metadata: 30 | labels: 31 | app: ratings 32 | version: v2-mysql 33 | spec: 34 | containers: 35 | - name: ratings 36 | image: docker.io/istio/examples-bookinfo-ratings-v2:1.16.2 37 | imagePullPolicy: IfNotPresent 38 | env: 39 | # ratings-v2 will use mongodb as the default db backend. 40 | # if you would like to use mysqldb then you can use this file 41 | # which sets DB_TYPE = 'mysql' and the rest of the parameters shown 42 | # here and also create the # mysqldb service using bookinfo-mysql.yaml 43 | # NOTE: This file is mutually exclusive to bookinfo-ratings-v2.yaml 44 | - name: DB_TYPE 45 | value: "mysql" 46 | - name: MYSQL_DB_HOST 47 | value: mysqldb 48 | - name: MYSQL_DB_PORT 49 | value: "3306" 50 | - name: MYSQL_DB_USER 51 | value: root 52 | - name: MYSQL_DB_PASSWORD 53 | value: password 54 | ports: 55 | - containerPort: 9080 56 | securityContext: 57 | runAsUser: 1000 58 | --- 59 | -------------------------------------------------------------------------------- /controller/apis/client/clientset/versioned/fake/register.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2022 The Amesh Authors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | // Code generated by client-gen. DO NOT EDIT. 17 | 18 | package fake 19 | 20 | import ( 21 | apisixv1alpha1 "github.com/api7/amesh/controller/apis/amesh/v1alpha1" 22 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 23 | runtime "k8s.io/apimachinery/pkg/runtime" 24 | schema "k8s.io/apimachinery/pkg/runtime/schema" 25 | serializer "k8s.io/apimachinery/pkg/runtime/serializer" 26 | utilruntime "k8s.io/apimachinery/pkg/util/runtime" 27 | ) 28 | 29 | var scheme = runtime.NewScheme() 30 | var codecs = serializer.NewCodecFactory(scheme) 31 | 32 | var localSchemeBuilder = runtime.SchemeBuilder{ 33 | apisixv1alpha1.AddToScheme, 34 | } 35 | 36 | // AddToScheme adds all types of this clientset into the given scheme. This allows composition 37 | // of clientsets, like in: 38 | // 39 | // import ( 40 | // "k8s.io/client-go/kubernetes" 41 | // clientsetscheme "k8s.io/client-go/kubernetes/scheme" 42 | // aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" 43 | // ) 44 | // 45 | // kclientset, _ := kubernetes.NewForConfig(c) 46 | // _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) 47 | // 48 | // After this, RawExtensions in Kubernetes types will serialize kube-aggregator types 49 | // correctly. 50 | var AddToScheme = localSchemeBuilder.AddToScheme 51 | 52 | func init() { 53 | v1.AddToGroupVersion(scheme, schema.GroupVersion{Version: "v1"}) 54 | utilruntime.Must(AddToScheme(scheme)) 55 | } 56 | -------------------------------------------------------------------------------- /pkg/amesh/provisioner/cluster_translator_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 The Amesh Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package provisioner 16 | 17 | import ( 18 | "testing" 19 | 20 | "github.com/api7/gopkg/pkg/log" 21 | clusterv3 "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3" 22 | "github.com/golang/protobuf/ptypes/duration" 23 | "github.com/stretchr/testify/assert" 24 | 25 | "github.com/api7/amesh/pkg/apisix" 26 | ) 27 | 28 | func TestTranslateClusterLbPolicy(t *testing.T) { 29 | a := &xdsProvisioner{ 30 | logger: log.DefaultLogger, 31 | } 32 | c := &clusterv3.Cluster{ 33 | Name: "test", 34 | LbPolicy: clusterv3.Cluster_ROUND_ROBIN, 35 | } 36 | var ups apisix.Upstream 37 | assert.Nil(t, a.translateClusterLbPolicy(c, &ups)) 38 | assert.Equal(t, ups.Type, apisix.LoadBalanceType("roundrobin")) 39 | c.LbPolicy = clusterv3.Cluster_LEAST_REQUEST 40 | assert.Nil(t, a.translateClusterLbPolicy(c, &ups)) 41 | assert.Equal(t, ups.Type, apisix.LoadBalanceType("least_conn")) 42 | 43 | // Unsupported 44 | c.LbPolicy = clusterv3.Cluster_RING_HASH 45 | assert.Equal(t, a.translateClusterLbPolicy(c, &ups), nil) 46 | } 47 | 48 | func TestTranslateClusterTimeoutSettings(t *testing.T) { 49 | a := &xdsProvisioner{ 50 | logger: log.DefaultLogger, 51 | } 52 | c := &clusterv3.Cluster{ 53 | Name: "test", 54 | ConnectTimeout: &duration.Duration{ 55 | Seconds: 10, 56 | }, 57 | } 58 | var ups apisix.Upstream 59 | assert.Nil(t, a.translateClusterTimeoutSettings(c, &ups)) 60 | assert.Equal(t, ups.Timeout.Connect, float64(10)) 61 | } 62 | -------------------------------------------------------------------------------- /pkg/apisix/storage/xds.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | #ifndef XDS_H 18 | #define XDS_H 19 | #include 20 | #include 21 | 22 | 23 | void ngx_lua_ffi_shdict_store(void *zone, int op, 24 | const unsigned char *key, size_t key_len, 25 | int value_type, 26 | const unsigned char *str_value_buf, size_t str_value_len, 27 | double num_value, long exptime, int user_flags, char **errmsg, 28 | int *forcible) 29 | { 30 | static void* dlhandle; 31 | static void (*fp)(void *zone, int op, 32 | const unsigned char *key, size_t key_len, 33 | int value_type, 34 | const unsigned char *str_value_buf, size_t str_value_len, 35 | double num_value, long exptime, int user_flags, char **errmsg, 36 | int *forcible); 37 | 38 | if (!dlhandle) { 39 | dlhandle = dlopen(NULL, RTLD_NOW); 40 | } 41 | if (!dlhandle) { 42 | return; 43 | } 44 | 45 | fp = dlsym(dlhandle, "ngx_http_lua_ffi_shdict_store"); 46 | if (!fp) { 47 | fp = dlsym(dlhandle, "ngx_meta_lua_ffi_shdict_store"); 48 | } 49 | 50 | fp(zone, op, key, key_len, value_type, str_value_buf, str_value_len, 51 | num_value, exptime, user_flags, errmsg, forcible); 52 | } 53 | 54 | 55 | #endif // XDS_H 56 | -------------------------------------------------------------------------------- /e2e/charts/istio-discovery/files/grpc-simple.yaml: -------------------------------------------------------------------------------- 1 | metadata: 2 | sidecar.istio.io/rewriteAppHTTPProbers: "false" 3 | spec: 4 | initContainers: 5 | - name: grpc-bootstrap-init 6 | image: busybox:1.28 7 | volumeMounts: 8 | - mountPath: /var/lib/grpc/data/ 9 | name: grpc-io-proxyless-bootstrap 10 | env: 11 | - name: INSTANCE_IP 12 | valueFrom: 13 | fieldRef: 14 | fieldPath: status.podIP 15 | - name: POD_NAME 16 | valueFrom: 17 | fieldRef: 18 | fieldPath: metadata.name 19 | - name: POD_NAMESPACE 20 | valueFrom: 21 | fieldRef: 22 | fieldPath: metadata.namespace 23 | - name: ISTIO_NAMESPACE 24 | value: | 25 | {{ .Values.global.istioNamespace }} 26 | command: 27 | - sh 28 | - "-c" 29 | - |- 30 | NODE_ID="sidecar~${INSTANCE_IP}~${POD_NAME}.${POD_NAMESPACE}~cluster.local" 31 | SERVER_URI="dns:///istiod.${ISTIO_NAMESPACE}.svc:15010" 32 | echo ' 33 | { 34 | "xds_servers": [ 35 | { 36 | "server_uri": "'${SERVER_URI}'", 37 | "channel_creds": [{"type": "insecure"}], 38 | "server_features" : ["xds_v3"] 39 | } 40 | ], 41 | "node": { 42 | "id": "'${NODE_ID}'", 43 | "metadata": { 44 | "GENERATOR": "grpc" 45 | } 46 | } 47 | }' > /var/lib/grpc/data/bootstrap.json 48 | containers: 49 | {{- range $index, $container := .Spec.Containers }} 50 | - name: {{ $container.Name }} 51 | env: 52 | - name: GRPC_XDS_BOOTSTRAP 53 | value: /var/lib/grpc/data/bootstrap.json 54 | - name: GRPC_GO_LOG_VERBOSITY_LEVEL 55 | value: "99" 56 | - name: GRPC_GO_LOG_SEVERITY_LEVEL 57 | value: info 58 | volumeMounts: 59 | - mountPath: /var/lib/grpc/data/ 60 | name: grpc-io-proxyless-bootstrap 61 | {{- end }} 62 | volumes: 63 | - name: grpc-io-proxyless-bootstrap 64 | emptyDir: {} 65 | -------------------------------------------------------------------------------- /e2e/charts/istio-discovery/templates/validatingwebhookconfiguration.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.global.configValidation }} 2 | apiVersion: admissionregistration.k8s.io/v1 3 | kind: ValidatingWebhookConfiguration 4 | metadata: 5 | name: istio-validator{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}-{{ .Values.global.istioNamespace }} 6 | labels: 7 | app: istiod 8 | release: {{ .Release.Name }} 9 | istio: istiod 10 | istio.io/rev: {{ .Values.revision | default "default" }} 11 | webhooks: 12 | # Webhook handling per-revision validation. Mostly here so we can determine whether webhooks 13 | # are rejecting invalid configs on a per-revision basis. 14 | - name: rev.validation.istio.io 15 | clientConfig: 16 | # Should change from base but cannot for API compat 17 | {{- if .Values.base.validationURL }} 18 | url: {{ .Values.base.validationURL }} 19 | {{- else }} 20 | service: 21 | name: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }} 22 | namespace: {{ .Values.global.istioNamespace }} 23 | path: "/validate" 24 | {{- end }} 25 | caBundle: "" # patched at runtime when the webhook is ready. 26 | rules: 27 | - operations: 28 | - CREATE 29 | - UPDATE 30 | apiGroups: 31 | - security.istio.io 32 | - networking.istio.io 33 | - telemetry.istio.io 34 | - extensions.istio.io 35 | apiVersions: 36 | - "*" 37 | resources: 38 | - "*" 39 | # Fail open until the validation webhook is ready. The webhook controller 40 | # will update this to `Fail` and patch in the `caBundle` when the webhook 41 | # endpoint is ready. 42 | failurePolicy: Ignore 43 | sideEffects: None 44 | admissionReviewVersions: ["v1beta1", "v1"] 45 | objectSelector: 46 | matchExpressions: 47 | - key: istio.io/rev 48 | operator: In 49 | values: 50 | {{- if (eq .Values.revision "") }} 51 | - "default" 52 | {{- else }} 53 | - "{{ .Values.revision }}" 54 | {{- end }} 55 | --- 56 | {{- end }} 57 | -------------------------------------------------------------------------------- /controller/apis/client/clientset/versioned/scheme/register.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2022 The Amesh Authors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | // Code generated by client-gen. DO NOT EDIT. 17 | 18 | package scheme 19 | 20 | import ( 21 | apisixv1alpha1 "github.com/api7/amesh/controller/apis/amesh/v1alpha1" 22 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 23 | runtime "k8s.io/apimachinery/pkg/runtime" 24 | schema "k8s.io/apimachinery/pkg/runtime/schema" 25 | serializer "k8s.io/apimachinery/pkg/runtime/serializer" 26 | utilruntime "k8s.io/apimachinery/pkg/util/runtime" 27 | ) 28 | 29 | var Scheme = runtime.NewScheme() 30 | var Codecs = serializer.NewCodecFactory(Scheme) 31 | var ParameterCodec = runtime.NewParameterCodec(Scheme) 32 | var localSchemeBuilder = runtime.SchemeBuilder{ 33 | apisixv1alpha1.AddToScheme, 34 | } 35 | 36 | // AddToScheme adds all types of this clientset into the given scheme. This allows composition 37 | // of clientsets, like in: 38 | // 39 | // import ( 40 | // "k8s.io/client-go/kubernetes" 41 | // clientsetscheme "k8s.io/client-go/kubernetes/scheme" 42 | // aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" 43 | // ) 44 | // 45 | // kclientset, _ := kubernetes.NewForConfig(c) 46 | // _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) 47 | // 48 | // After this, RawExtensions in Kubernetes types will serialize kube-aggregator types 49 | // correctly. 50 | var AddToScheme = localSchemeBuilder.AddToScheme 51 | 52 | func init() { 53 | v1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: "v1"}) 54 | utilruntime.Must(AddToScheme(Scheme)) 55 | } 56 | -------------------------------------------------------------------------------- /e2e/bookinfo/bookinfo-ratings-v2.yaml: -------------------------------------------------------------------------------- 1 | # Copyright Istio Authors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | apiVersion: v1 16 | kind: ServiceAccount 17 | metadata: 18 | name: bookinfo-ratings-v2 19 | --- 20 | apiVersion: apps/v1 21 | kind: Deployment 22 | metadata: 23 | name: ratings-v2 24 | labels: 25 | app: ratings 26 | version: v2 27 | spec: 28 | replicas: 1 29 | selector: 30 | matchLabels: 31 | app: ratings 32 | version: v2 33 | template: 34 | metadata: 35 | labels: 36 | app: ratings 37 | version: v2 38 | spec: 39 | serviceAccountName: bookinfo-ratings-v2 40 | containers: 41 | - name: ratings 42 | image: docker.io/istio/examples-bookinfo-ratings-v2:1.16.2 43 | imagePullPolicy: IfNotPresent 44 | env: 45 | # ratings-v2 will use mongodb as the default db backend. 46 | # if you would like to use mysqldb then set DB_TYPE = 'mysql', set 47 | # the rest of the parameters shown here and also create the 48 | # mysqldb service using bookinfo-mysql.yaml 49 | # - name: DB_TYPE #default to 50 | # value: "mysql" 51 | # - name: MYSQL_DB_HOST 52 | # value: mysqldb 53 | # - name: MYSQL_DB_PORT 54 | # value: "3306" 55 | # - name: MYSQL_DB_USER 56 | # value: root 57 | # - name: MYSQL_DB_PASSWORD 58 | # value: password 59 | - name: MONGO_DB_URL 60 | value: mongodb://mongodb:27017/test 61 | ports: 62 | - containerPort: 9080 63 | securityContext: 64 | runAsUser: 1000 65 | --- 66 | -------------------------------------------------------------------------------- /e2e/test/istio/traffic_management/1_request_routing.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 The Amesh Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package traffic_management 16 | 17 | import ( 18 | "github.com/onsi/ginkgo/v2" 19 | 20 | "github.com/api7/amesh/e2e/framework" 21 | "github.com/api7/amesh/e2e/framework/utils" 22 | ) 23 | 24 | var _ = ginkgo.Describe("[istio functions] Route Configuration:", func() { 25 | f := framework.NewDefaultFramework() 26 | utils.Case("should be able to route requests", func() { 27 | tester := NewVirtualServiceTester(f, []string{"v1", "v2"}) 28 | 29 | // deploy apps 30 | tester.Create() 31 | 32 | // Case 1 33 | // Basic config to v1 34 | tester.AddRouteTo("nginx-kind", "v1") 35 | tester.ApplyRoute() 36 | 37 | // Validate normal access 38 | tester.ValidateSingleVersionAccess([]string{"ngx-v1"}, []string{"ngx-v2"}, "nginx-kind/status") 39 | 40 | // Case 2 41 | // Basic config to v2 42 | tester.ClearRoute("nginx-kind") 43 | tester.AddRouteTo("nginx-kind", "v2") 44 | tester.ApplyRoute() 45 | 46 | // Validate normal access 47 | tester.ValidateSingleVersionAccess([]string{"ngx-v2"}, []string{"ngx-v1"}, "nginx-kind/status") 48 | 49 | // Case 3 50 | // Match Conditions 51 | tester.ClearRoute("nginx-kind") 52 | tester.AddRouteToIfHeaderIs("nginx-kind", "v2", "X-USER", "v2User") 53 | tester.AddRouteTo("nginx-kind", "v1") 54 | tester.ApplyRoute() 55 | 56 | // Validate normal access 57 | tester.ValidateSingleVersionAccess([]string{"ngx-v1"}, []string{"ngx-v2"}, "nginx-kind/status") 58 | // Validate matched access 59 | tester.ValidateSingleVersionAccess([]string{"ngx-v2"}, []string{"ngx-v1"}, "nginx-kind/status", "-H", "X-USER: v2User") 60 | }) 61 | }) 62 | -------------------------------------------------------------------------------- /e2e/bookinfo/cleanup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright Istio Authors 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | SCRIPTDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) 18 | 19 | # only ask if in interactive mode 20 | if [[ -t 0 && -z ${NAMESPACE} ]];then 21 | echo -n "namespace ? [default] " 22 | read -r NAMESPACE 23 | fi 24 | 25 | # verify if the namespace exists, otherwise use default namespace 26 | if [[ -n ${NAMESPACE} ]];then 27 | ns=$(kubectl get namespace "${NAMESPACE}" --no-headers --output=go-template="{{.metadata.name}}" 2>/dev/null) 28 | if [[ -z ${ns} ]];then 29 | echo "NAMESPACE ${NAMESPACE} not found." 30 | NAMESPACE=default 31 | fi 32 | fi 33 | 34 | # if no namespace is provided, use default namespace 35 | if [[ -z ${NAMESPACE} ]];then 36 | NAMESPACE=default 37 | fi 38 | 39 | echo "using NAMESPACE=${NAMESPACE}" 40 | 41 | protos=( destinationrules virtualservices gateways ) 42 | for proto in "${protos[@]}"; do 43 | for resource in $(kubectl get -n ${NAMESPACE} "$proto" -o name); do 44 | kubectl delete -n ${NAMESPACE} "$resource"; 45 | done 46 | done 47 | 48 | OUTPUT=$(mktemp) 49 | export OUTPUT 50 | echo "Application cleanup may take up to one minute" 51 | kubectl delete -n ${NAMESPACE} -f "$SCRIPTDIR/bookinfo.yaml" > "${OUTPUT}" 2>&1 52 | ret=$? 53 | function cleanup() { 54 | rm -f "${OUTPUT}" 55 | } 56 | 57 | trap cleanup EXIT 58 | 59 | if [[ ${ret} -eq 0 ]];then 60 | cat "${OUTPUT}" 61 | else 62 | # ignore NotFound errors 63 | OUT2=$(grep -v NotFound "${OUTPUT}") 64 | if [[ -n ${OUT2} ]];then 65 | cat "${OUTPUT}" 66 | exit ${ret} 67 | fi 68 | fi 69 | 70 | # wait for 30 sec for bookinfo to clean up 71 | sleep 30 72 | 73 | echo "Application cleanup successful" 74 | -------------------------------------------------------------------------------- /e2e/test/istio/traffic_management/2_fault_injection.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 The Amesh Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package traffic_management 16 | 17 | import ( 18 | "time" 19 | 20 | "github.com/onsi/ginkgo/v2" 21 | 22 | "github.com/api7/amesh/e2e/framework" 23 | "github.com/api7/amesh/e2e/framework/utils" 24 | ) 25 | 26 | var _ = ginkgo.Describe("[istio functions] Route Configuration:", func() { 27 | f := framework.NewDefaultFramework() 28 | utils.Case("should be able to inject fault: abort", func() { 29 | tester := NewVirtualServiceTester(f, []string{"v1"}) 30 | 31 | tester.Create() 32 | 33 | // create fault routes 34 | tester.AddRouteToWithAbortFault("nginx-kind", "v1", "User", "fault-abort") 35 | tester.AddRouteTo("nginx-kind", "v1") 36 | tester.ApplyRoute() 37 | 38 | // validate 39 | tester.ValidateAccessible("origin", "nginx-kind/ip") 40 | // validate fault abort 41 | tester.ValidateInaccessible(555, "origin", "nginx-kind/ip", "-H", "User: fault-abort") 42 | }) 43 | 44 | utils.Case("should be able to inject fault: delay", func() { 45 | tester := NewVirtualServiceTester(f, []string{"v1"}) 46 | 47 | tester.Create() 48 | 49 | // create fault routes 50 | tester.AddRouteToWithDelayFault("nginx-kind", "v1", "User", "fault-delay", 10) 51 | tester.AddRouteTo("nginx-kind", "v1") 52 | tester.ApplyRoute() 53 | 54 | // validate duration < 10s 55 | tester.ValidateTimeout(0, time.Second*5, func() { 56 | tester.ValidateAccessible("origin", "nginx-kind/ip") 57 | }) 58 | 59 | // validate duration > 10s 60 | tester.ValidateTimeout(time.Second*10, time.Second*14, func() { 61 | tester.ValidateAccessible("origin", "nginx-kind/ip", "-H", "User: fault-delay") 62 | }) 63 | }) 64 | }) 65 | -------------------------------------------------------------------------------- /e2e/charts/istio-discovery/templates/reader-clusterrole.yaml: -------------------------------------------------------------------------------- 1 | {{ $mcsAPIGroup := or .Values.pilot.env.MCS_API_GROUP "multicluster.x-k8s.io" }} 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: istio-reader-clusterrole{{- if not (eq .Values.revision "")}}-{{ .Values.revision }}{{- end }}-{{ .Release.Namespace }} 6 | labels: 7 | app: istio-reader 8 | release: {{ .Release.Name }} 9 | rules: 10 | - apiGroups: 11 | - "config.istio.io" 12 | - "security.istio.io" 13 | - "networking.istio.io" 14 | - "authentication.istio.io" 15 | - "rbac.istio.io" 16 | resources: ["*"] 17 | verbs: ["get", "list", "watch"] 18 | - apiGroups: [""] 19 | resources: ["endpoints", "pods", "services", "nodes", "replicationcontrollers", "namespaces", "secrets"] 20 | verbs: ["get", "list", "watch"] 21 | - apiGroups: ["networking.istio.io"] 22 | verbs: [ "get", "watch", "list" ] 23 | resources: [ "workloadentries" ] 24 | - apiGroups: ["apiextensions.k8s.io"] 25 | resources: ["customresourcedefinitions"] 26 | verbs: ["get", "list", "watch"] 27 | - apiGroups: ["discovery.k8s.io"] 28 | resources: ["endpointslices"] 29 | verbs: ["get", "list", "watch"] 30 | - apiGroups: ["{{ $mcsAPIGroup }}"] 31 | resources: ["serviceexports"] 32 | verbs: ["get", "list", "watch", "create", "delete"] 33 | - apiGroups: ["{{ $mcsAPIGroup }}"] 34 | resources: ["serviceimports"] 35 | verbs: ["get", "list", "watch"] 36 | - apiGroups: ["apps"] 37 | resources: ["replicasets"] 38 | verbs: ["get", "list", "watch"] 39 | - apiGroups: ["authentication.k8s.io"] 40 | resources: ["tokenreviews"] 41 | verbs: ["create"] 42 | - apiGroups: ["authorization.k8s.io"] 43 | resources: ["subjectaccessreviews"] 44 | verbs: ["create"] 45 | {{- if .Values.global.externalIstiod }} 46 | - apiGroups: [""] 47 | resources: ["configmaps"] 48 | verbs: ["create", "get", "list", "watch", "update"] 49 | - apiGroups: ["admissionregistration.k8s.io"] 50 | resources: ["mutatingwebhookconfigurations"] 51 | verbs: ["get", "list", "watch", "update", "patch"] 52 | - apiGroups: ["admissionregistration.k8s.io"] 53 | resources: ["validatingwebhookconfigurations"] 54 | verbs: ["get", "list", "watch", "update"] 55 | {{- end}} 56 | -------------------------------------------------------------------------------- /e2e/framework/httpbin_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 The Amesh Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package framework 16 | 17 | import ( 18 | "testing" 19 | 20 | "github.com/stretchr/testify/assert" 21 | 22 | "github.com/api7/amesh/e2e/framework/utils" 23 | ) 24 | 25 | func TestName(t *testing.T) { 26 | 27 | artifact, _ := utils.RenderManifest(_httpbinManifest, &httpbinRenderArgs{ 28 | ManifestArgs: &ManifestArgs{ 29 | LocalRegistry: "10.0.0.2:5000", 30 | }, 31 | HttpBinReplicas: 1, 32 | Name: "httpbin", 33 | Version: "v3", 34 | InMesh: true, 35 | }) 36 | 37 | assert.Equal(t, ` 38 | apiVersion: apps/v1 39 | kind: Deployment 40 | metadata: 41 | name: httpbin 42 | labels: 43 | appKind: httpbin 44 | app: httpbin 45 | version: v3 46 | spec: 47 | replicas: 1 48 | selector: 49 | matchLabels: 50 | appKind: httpbin 51 | app: httpbin 52 | version: v3 53 | template: 54 | metadata: 55 | labels: 56 | appKind: httpbin 57 | app: httpbin 58 | version: v3 59 | annotations: 60 | sidecar.istio.io/inject: "true" 61 | spec: 62 | containers: 63 | - name: httpbin 64 | image: 10.0.0.2:5000/kennethreitz/httpbin 65 | imagePullPolicy: IfNotPresent 66 | command: ["gunicorn", "--access-logfile", "-", "-b", "0.0.0.0:80", "httpbin:app"] 67 | ports: 68 | - containerPort: 80 69 | protocol: TCP 70 | name: http 71 | --- 72 | apiVersion: v1 73 | kind: Service 74 | metadata: 75 | name: httpbin 76 | spec: 77 | selector: 78 | app: httpbin 79 | ports: 80 | - name: http 81 | targetPort: 80 82 | port: 80 83 | protocol: TCP 84 | `, artifact) 85 | } 86 | -------------------------------------------------------------------------------- /controller/apis/client/informers/externalversions/generic.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2022 The Amesh Authors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | // Code generated by informer-gen. DO NOT EDIT. 17 | 18 | package externalversions 19 | 20 | import ( 21 | "fmt" 22 | 23 | v1alpha1 "github.com/api7/amesh/controller/apis/amesh/v1alpha1" 24 | schema "k8s.io/apimachinery/pkg/runtime/schema" 25 | cache "k8s.io/client-go/tools/cache" 26 | ) 27 | 28 | // GenericInformer is type of SharedIndexInformer which will locate and delegate to other 29 | // sharedInformers based on type 30 | type GenericInformer interface { 31 | Informer() cache.SharedIndexInformer 32 | Lister() cache.GenericLister 33 | } 34 | 35 | type genericInformer struct { 36 | informer cache.SharedIndexInformer 37 | resource schema.GroupResource 38 | } 39 | 40 | // Informer returns the SharedIndexInformer. 41 | func (f *genericInformer) Informer() cache.SharedIndexInformer { 42 | return f.informer 43 | } 44 | 45 | // Lister returns the GenericLister. 46 | func (f *genericInformer) Lister() cache.GenericLister { 47 | return cache.NewGenericLister(f.Informer().GetIndexer(), f.resource) 48 | } 49 | 50 | // ForResource gives generic access to a shared informer of the matching type 51 | // TODO extend this to unknown resources with a client pool 52 | func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource) (GenericInformer, error) { 53 | switch resource { 54 | // Group=apisix.apache.org, Version=v1alpha1 55 | case v1alpha1.SchemeGroupVersion.WithResource("ameshpluginconfigs"): 56 | return &genericInformer{resource: resource.GroupResource(), informer: f.Apisix().V1alpha1().AmeshPluginConfigs().Informer()}, nil 57 | 58 | } 59 | 60 | return nil, fmt.Errorf("no informer found for %v", resource) 61 | } 62 | -------------------------------------------------------------------------------- /e2e/bookinfo/bookinfo-mysql.yaml: -------------------------------------------------------------------------------- 1 | # Copyright Istio Authors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | ################################################################################################## 16 | # Mysql db services 17 | # credentials: root/password 18 | ################################################################################################## 19 | apiVersion: v1 20 | kind: Secret 21 | metadata: 22 | name: mysql-credentials 23 | type: Opaque 24 | data: 25 | rootpasswd: cGFzc3dvcmQ= 26 | --- 27 | apiVersion: v1 28 | kind: Service 29 | metadata: 30 | name: mysqldb 31 | labels: 32 | app: mysqldb 33 | service: mysqldb 34 | spec: 35 | ports: 36 | - port: 3306 37 | name: tcp 38 | selector: 39 | app: mysqldb 40 | --- 41 | apiVersion: apps/v1 42 | kind: Deployment 43 | metadata: 44 | name: mysqldb-v1 45 | labels: 46 | app: mysqldb 47 | version: v1 48 | spec: 49 | replicas: 1 50 | selector: 51 | matchLabels: 52 | app: mysqldb 53 | version: v1 54 | template: 55 | metadata: 56 | labels: 57 | app: mysqldb 58 | version: v1 59 | spec: 60 | containers: 61 | - name: mysqldb 62 | image: docker.io/istio/examples-bookinfo-mysqldb:1.16.2 63 | imagePullPolicy: IfNotPresent 64 | ports: 65 | - containerPort: 3306 66 | env: 67 | - name: MYSQL_ROOT_PASSWORD 68 | valueFrom: 69 | secretKeyRef: 70 | name: mysql-credentials 71 | key: rootpasswd 72 | args: ["--default-authentication-plugin","mysql_native_password"] 73 | volumeMounts: 74 | - name: var-lib-mysql 75 | mountPath: /var/lib/mysql 76 | volumes: 77 | - name: var-lib-mysql 78 | emptyDir: {} 79 | --- 80 | -------------------------------------------------------------------------------- /pkg/apisix/plugins.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 The Amesh Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package apisix 16 | 17 | const ( 18 | PluginFaultInjection = "fault-injection" 19 | PluginProxyMirror = "proxy-mirror" 20 | PluginTrafficSplit = "traffic-split" 21 | PluginPrometheus = "prometheus" 22 | ) 23 | 24 | type FaultInjectionAbort struct { 25 | HttpStatus uint32 `json:"http_status,omitempty"` 26 | Body string `json:"body,omitempty"` 27 | Percentage uint32 `json:"percentage,omitempty"` 28 | Vars []*Var `json:"vars,omitempty"` 29 | } 30 | 31 | type FaultInjectionDelay struct { 32 | // Duration in seconds 33 | Duration int64 `json:"duration,omitempty"` 34 | Percentage uint32 `json:"percentage,omitempty"` 35 | Vars []*Var `json:"vars,omitempty" json:"vars,omitempty"` 36 | } 37 | 38 | type FaultInjection struct { 39 | Abort *FaultInjectionAbort `json:"abort,omitempty"` 40 | Delay *FaultInjectionDelay `json:"delay,omitempty"` 41 | } 42 | 43 | type TrafficSplitWeightedUpstreams struct { 44 | UpstreamId string `json:"upstream_id,omitempty"` 45 | Weight uint32 `json:"weight,omitempty"` 46 | } 47 | 48 | type TrafficSplitRule struct { 49 | Match []*Var `json:"match,omitempty"` 50 | WeightedUpstreams []*TrafficSplitWeightedUpstreams `json:"weighted_upstreams,omitempty"` 51 | } 52 | 53 | type TrafficSplit struct { 54 | Rules []*TrafficSplitRule `json:"rules,omitempty"` 55 | } 56 | 57 | type ProxyMirror struct { 58 | Host string `json:"host,omitempty"` 59 | Path string `json:"path,omitempty"` 60 | SampleRatio float32 `json:"sample_ratio,omitempty"` 61 | } 62 | 63 | type Prometheus struct { 64 | // When set to true, would print route/service name instead of id in Prometheus metric. 65 | PreferName bool `json:"prefer_name,omitempty"` 66 | } 67 | -------------------------------------------------------------------------------- /controller/config/manager/manager.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | labels: 5 | control-plane: controller-manager 6 | name: system 7 | --- 8 | apiVersion: apps/v1 9 | kind: Deployment 10 | metadata: 11 | name: controller-manager 12 | namespace: system 13 | labels: 14 | control-plane: controller-manager 15 | spec: 16 | selector: 17 | matchLabels: 18 | control-plane: controller-manager 19 | replicas: 1 20 | template: 21 | metadata: 22 | annotations: 23 | kubectl.kubernetes.io/default-container: manager 24 | labels: 25 | control-plane: controller-manager 26 | spec: 27 | securityContext: 28 | runAsNonRoot: true 29 | # TODO(user): For common cases that do not require escalating privileges 30 | # it is recommended to ensure that all your Pods/Containers are restrictive. 31 | # More info: https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted 32 | # Please uncomment the following code if your project does NOT have to work on old Kubernetes 33 | # versions < 1.19 or on vendors versions which do NOT support this field by default (i.e. Openshift < 4.11 ). 34 | # seccompProfile: 35 | # type: RuntimeDefault 36 | containers: 37 | - command: 38 | - /manager 39 | args: 40 | - --leader-elect 41 | image: controller:latest 42 | name: manager 43 | securityContext: 44 | allowPrivilegeEscalation: false 45 | capabilities: 46 | drop: 47 | - "ALL" 48 | livenessProbe: 49 | httpGet: 50 | path: /healthz 51 | port: 8081 52 | initialDelaySeconds: 15 53 | periodSeconds: 20 54 | readinessProbe: 55 | httpGet: 56 | path: /readyz 57 | port: 8081 58 | initialDelaySeconds: 5 59 | periodSeconds: 10 60 | # TODO(user): Configure the resources accordingly based on the project requirements. 61 | # More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ 62 | resources: 63 | limits: 64 | cpu: 500m 65 | memory: 128Mi 66 | requests: 67 | cpu: 10m 68 | memory: 64Mi 69 | serviceAccountName: controller-manager 70 | terminationGracePeriodSeconds: 10 71 | -------------------------------------------------------------------------------- /e2e/test/amesh/reconnect_tester.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 The Amesh Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package amesh 16 | 17 | import ( 18 | "time" 19 | 20 | "github.com/api7/gopkg/pkg/log" 21 | "github.com/onsi/ginkgo/v2" 22 | "github.com/stretchr/testify/assert" 23 | 24 | "github.com/api7/amesh/e2e/framework" 25 | "github.com/api7/amesh/e2e/framework/utils" 26 | ) 27 | 28 | type ReconnectTester struct { 29 | f *framework.Framework 30 | logger *log.Logger 31 | 32 | curlPod string 33 | } 34 | 35 | func NewReconnectTester(f *framework.Framework) *ReconnectTester { 36 | logger, err := log.NewLogger( 37 | log.WithLogLevel("info"), 38 | log.WithSkipFrames(3), 39 | ) 40 | utils.AssertNil(err, "create logger") 41 | return &ReconnectTester{ 42 | f: f, 43 | logger: logger, 44 | } 45 | } 46 | 47 | func (t *ReconnectTester) Create() { 48 | t.curlPod = t.f.CreateCurl() 49 | t.f.WaitForCurlReady() 50 | } 51 | 52 | func (t *ReconnectTester) ValidateStatusAmeshIsOK() { 53 | time.Sleep(time.Second * 3) 54 | 55 | condFunc := func() (bool, error) { 56 | return t.f.GetSidecarStatus(t.curlPod).AmeshConnected, nil 57 | } 58 | err := utils.WaitExponentialBackoff(condFunc) // ignore timeout error 59 | utils.AssertNil(err, "get amesh status") 60 | 61 | assert.Equal(ginkgo.GinkgoT(), true, t.f.GetSidecarStatus(t.curlPod).AmeshConnected, "amesh should connected") 62 | assert.Equal(ginkgo.GinkgoT(), true, t.f.GetSidecarStatus(t.curlPod).AmeshProvisionerReady, "amesh provisioner should ready") 63 | } 64 | 65 | func (t *ReconnectTester) DeleteAmeshController() { 66 | t.logger.Infof("delete amesh-controller pods...") 67 | utils.AssertNil(t.f.DeletePodByLabel(t.f.ControlPlaneNamespace(), "app=amesh-controller"), "delete amesh controller pods") 68 | 69 | utils.AssertNil(t.f.WaitForDeploymentPodsReady("amesh-controller", t.f.ControlPlaneNamespace()), "wait for amesh-controller pods") 70 | } 71 | -------------------------------------------------------------------------------- /e2e/test/istio/traffic_management/4_request_timeouts.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 The Amesh Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package traffic_management 16 | 17 | import ( 18 | "net/http" 19 | "time" 20 | 21 | "github.com/onsi/ginkgo/v2" 22 | 23 | "github.com/api7/amesh/e2e/framework" 24 | "github.com/api7/amesh/e2e/framework/utils" 25 | ) 26 | 27 | var _ = ginkgo.Describe("[istio functions] Route Configuration:", func() { 28 | f := framework.NewDefaultFramework() 29 | utils.Case("should be able to config timeout", func() { 30 | tester := NewVirtualServiceTester(f, []string{"v1"}) 31 | 32 | tester.Create() 33 | 34 | // Case 1, timeout 35 | // apply routes 36 | tester.AddRouteToWithDelayFault("httpbin-kind", "v1", "User", "fault-delay", 10) 37 | tester.AddRouteTo("httpbin-kind", "v1") 38 | tester.AddRouteToWithTimeout("nginx-kind", "v1", 5) 39 | tester.ApplyRoute() 40 | 41 | // validate access with timeout 42 | tester.ValidateTimeout(0, time.Second*5, func() { 43 | tester.ValidateAccessible("origin", "nginx-kind/ip") 44 | }) 45 | // validate longer than 5s (toleration timeout) but shorter than 10s (actual service timeout) 46 | tester.ValidateTimeout(time.Second*5, time.Second*8, func() { 47 | tester.ValidateInaccessible(http.StatusGatewayTimeout, "origin", "nginx-kind/ip", "-H", "User: fault-delay") 48 | }) 49 | 50 | // Case 2, tolerate timeout 51 | // apply routes 52 | tester.ClearRoute("nginx-kind") 53 | tester.AddRouteToWithTimeout("nginx-kind", "v1", 12) 54 | tester.ApplyRoute() 55 | 56 | // validate accessible 57 | tester.ValidateTimeout(0, time.Second*5, func() { 58 | tester.ValidateAccessible("origin", "nginx-kind/ip") 59 | }) 60 | // validate longer than 10s (actual service timeout) but shorter than 12s (toleration timeout) 61 | tester.ValidateTimeout(time.Second*10, time.Second*12, func() { 62 | tester.ValidateAccessible("origin", "nginx-kind/ip", "-H", "User: fault-delay") 63 | }) 64 | }) 65 | }) 66 | -------------------------------------------------------------------------------- /e2e/test/amesh/pluginconfig.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 The Amesh Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package amesh 16 | 17 | import ( 18 | "github.com/onsi/ginkgo/v2" 19 | 20 | "github.com/api7/amesh/e2e/framework" 21 | "github.com/api7/amesh/e2e/framework/utils" 22 | ) 23 | 24 | var _ = ginkgo.Describe("[amesh-controller functions] AmeshPluginConfig:", func() { 25 | f := framework.NewDefaultFramework() 26 | 27 | utils.Case("should be able to inject plugins", func() { 28 | t := NewPluginConfigTester(f, &ResponseRewriteConfig{ 29 | Body: "BODY_REWRITE", 30 | Headers: map[string]string{ 31 | "X-Header": "Rewrite", 32 | }, 33 | }) 34 | 35 | t.Create() 36 | t.ValidateInMeshNginxProxyAccess() 37 | t.ValidateInMeshCurlAccess() 38 | }) 39 | 40 | utils.Case("should be able to update plugins", func() { 41 | t := NewPluginConfigTester(f, &ResponseRewriteConfig{ 42 | Headers: map[string]string{ 43 | "X-Header": "Rewrite", 44 | }, 45 | }) 46 | 47 | t.Create() 48 | t.ValidateInMeshNginxProxyAccess() 49 | t.ValidateInMeshCurlAccess() 50 | 51 | t.UpdateConfig(&ResponseRewriteConfig{ 52 | Body: "BODY_REWRITE", 53 | Headers: map[string]string{ 54 | "X-Header": "RewriteChanged", 55 | }, 56 | }) 57 | t.ValidateInMeshNginxProxyAccess() 58 | t.ValidateInMeshCurlAccess() 59 | 60 | t.UpdateConfig(&ResponseRewriteConfig{ 61 | Body: "BODY_REWRITE", 62 | Headers: map[string]string{ 63 | "X-Header-Changed": "HeaderChanged", 64 | }, 65 | }) 66 | t.ValidateInMeshNginxProxyAccess() 67 | t.ValidateInMeshCurlAccess() 68 | }) 69 | 70 | utils.Case("should be able to delete plugins", func() { 71 | t := NewPluginConfigTester(f, &ResponseRewriteConfig{ 72 | Headers: map[string]string{ 73 | "X-Header": "Rewrite", 74 | }, 75 | Body: "REWRITE", 76 | }) 77 | 78 | t.Create() 79 | t.ValidateInMeshNginxProxyAccess() 80 | 81 | t.DeleteAmeshPluginConfig() 82 | t.ValidateInMeshNginxProxyAccess() 83 | }) 84 | }) 85 | -------------------------------------------------------------------------------- /controller/controllers/amesh/suite_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2022. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package amesh 18 | 19 | import ( 20 | "path/filepath" 21 | "testing" 22 | 23 | . "github.com/onsi/ginkgo" 24 | . "github.com/onsi/gomega" 25 | "k8s.io/client-go/kubernetes/scheme" 26 | "k8s.io/client-go/rest" 27 | "sigs.k8s.io/controller-runtime/pkg/client" 28 | "sigs.k8s.io/controller-runtime/pkg/envtest" 29 | "sigs.k8s.io/controller-runtime/pkg/envtest/printer" 30 | logf "sigs.k8s.io/controller-runtime/pkg/log" 31 | "sigs.k8s.io/controller-runtime/pkg/log/zap" 32 | 33 | ameshv1alpha1 "github.com/api7/amesh/controller/apis/amesh/v1alpha1" 34 | ) 35 | 36 | // These tests use Ginkgo (BDD-style Go testing framework). Refer to 37 | // http://onsi.github.io/ginkgo/ to learn more about Ginkgo. 38 | 39 | var cfg *rest.Config 40 | var k8sClient client.Client 41 | var testEnv *envtest.Environment 42 | 43 | func TestAPIs(t *testing.T) { 44 | RegisterFailHandler(Fail) 45 | 46 | RunSpecsWithDefaultAndCustomReporters(t, 47 | "Controller Suite", 48 | []Reporter{printer.NewlineReporter{}}) 49 | } 50 | 51 | var _ = BeforeSuite(func() { 52 | logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) 53 | 54 | By("bootstrapping test environment") 55 | testEnv = &envtest.Environment{ 56 | CRDDirectoryPaths: []string{filepath.Join("../..", "config", "crd", "bases")}, 57 | ErrorIfCRDPathMissing: true, 58 | } 59 | 60 | var err error 61 | // cfg is defined in this file globally. 62 | cfg, err = testEnv.Start() 63 | Expect(err).NotTo(HaveOccurred()) 64 | Expect(cfg).NotTo(BeNil()) 65 | 66 | err = ameshv1alpha1.AddToScheme(scheme.Scheme) 67 | Expect(err).NotTo(HaveOccurred()) 68 | 69 | //+kubebuilder:scaffold:scheme 70 | 71 | k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}) 72 | Expect(err).NotTo(HaveOccurred()) 73 | Expect(k8sClient).NotTo(BeNil()) 74 | 75 | }, 60) 76 | 77 | var _ = AfterSuite(func() { 78 | By("tearing down the test environment") 79 | err := testEnv.Stop() 80 | Expect(err).NotTo(HaveOccurred()) 81 | }) 82 | -------------------------------------------------------------------------------- /controller/apis/amesh/v1alpha1/zz_generated.register.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2022 The Amesh Authors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | // Code generated by register-gen. DO NOT EDIT. 17 | 18 | package v1alpha1 19 | 20 | import ( 21 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 22 | "k8s.io/apimachinery/pkg/runtime" 23 | "k8s.io/apimachinery/pkg/runtime/schema" 24 | ) 25 | 26 | // GroupName specifies the group name used to register the objects. 27 | const GroupName = "apisix.apache.org" 28 | 29 | // GroupVersion specifies the group and the version used to register the objects. 30 | var GroupVersion = v1.GroupVersion{Group: GroupName, Version: "v1alpha1"} 31 | 32 | // SchemeGroupVersion is group version used to register these objects 33 | // Deprecated: use GroupVersion instead. 34 | var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha1"} 35 | 36 | // Resource takes an unqualified resource and returns a Group qualified GroupResource 37 | func Resource(resource string) schema.GroupResource { 38 | return SchemeGroupVersion.WithResource(resource).GroupResource() 39 | } 40 | 41 | var ( 42 | // localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes. 43 | SchemeBuilder runtime.SchemeBuilder 44 | localSchemeBuilder = &SchemeBuilder 45 | // Depreciated: use Install instead 46 | AddToScheme = localSchemeBuilder.AddToScheme 47 | Install = localSchemeBuilder.AddToScheme 48 | ) 49 | 50 | func init() { 51 | // We only register manually written functions here. The registration of the 52 | // generated functions takes place in the generated files. The separation 53 | // makes the code compile even when the generated files are missing. 54 | localSchemeBuilder.Register(addKnownTypes) 55 | } 56 | 57 | // Adds the list of known types to Scheme. 58 | func addKnownTypes(scheme *runtime.Scheme) error { 59 | scheme.AddKnownTypes(SchemeGroupVersion, 60 | &AmeshPluginConfig{}, 61 | &AmeshPluginConfigList{}, 62 | ) 63 | // AddToGroupVersion allows the serialization of client types like ListOptions. 64 | v1.AddToGroupVersion(scheme, SchemeGroupVersion) 65 | return nil 66 | } 67 | -------------------------------------------------------------------------------- /pkg/amesh/agent_demo.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 The Amesh Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package amesh 15 | 16 | import ( 17 | "encoding/json" 18 | "fmt" 19 | "math/rand" 20 | "time" 21 | 22 | "github.com/api7/amesh/pkg/apisix" 23 | ) 24 | 25 | func (g *Agent) RunDemo() error { 26 | for { 27 | select { 28 | case <-g.ctx.Done(): 29 | return nil 30 | case <-time.After(time.Second * time.Duration(rand.Intn(10))): 31 | g.version = time.Now().Unix() 32 | 33 | routes := g.generateRandomRoutes() 34 | upstreams := g.generateRandomUpstreams() 35 | 36 | routesJson, err := json.Marshal(routes) 37 | if err != nil { 38 | return err 39 | } 40 | upstreamsJson, err := json.Marshal(upstreams) 41 | if err != nil { 42 | return err 43 | } 44 | 45 | g.DataStorage.Store("routes", string(routesJson)) 46 | g.DataStorage.Store("upstreams", string(upstreamsJson)) 47 | } 48 | } 49 | return nil 50 | } 51 | 52 | func (g *Agent) generateRandomRoutes() []*apisix.Route { 53 | return []*apisix.Route{ 54 | { 55 | Uris: nil, 56 | Name: fmt.Sprintf("route-%v", g.version), 57 | Id: "1", 58 | Desc: fmt.Sprintf("Route at %v", g.version), 59 | Priority: 0, 60 | Methods: []string{"GET", "POST"}, 61 | Hosts: []string{"example.com"}, 62 | RemoteAddrs: []string{"127.0.0.1"}, 63 | Vars: nil, 64 | Plugins: nil, 65 | UpstreamId: "1", 66 | Status: apisix.RouteEnable, 67 | Labels: nil, 68 | CreateTime: time.Now().Unix(), 69 | UpdateTime: time.Now().Unix(), 70 | }, 71 | } 72 | } 73 | 74 | func (g *Agent) generateRandomUpstreams() []*apisix.Upstream { 75 | return []*apisix.Upstream{ 76 | { 77 | CreateTime: time.Now().Unix(), 78 | UpdateTime: time.Now().Unix(), 79 | Nodes: []*apisix.Node{ 80 | { 81 | Host: "127.0.0.1", 82 | Port: 1980, 83 | }, 84 | }, 85 | Type: apisix.LoadBalanceTypeRoundrobin, 86 | Scheme: "", 87 | Labels: nil, 88 | Name: fmt.Sprintf("upstream-%v", g.version), 89 | Desc: fmt.Sprintf("Upstream at %v", g.version), 90 | Id: "1", 91 | }, 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /cmd/dynamic/main.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 The Amesh Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package main 15 | 16 | import "C" 17 | 18 | import ( 19 | "context" 20 | "os" 21 | "strconv" 22 | "unsafe" 23 | 24 | "github.com/api7/gopkg/pkg/log" 25 | 26 | "github.com/api7/amesh/pkg/amesh" 27 | "github.com/api7/amesh/pkg/utils" 28 | ) 29 | 30 | func main() { 31 | } 32 | 33 | //export Log 34 | func Log(msg string) { 35 | log.Infof(msg) 36 | } 37 | 38 | //export StartTestAmesh 39 | func StartTestAmesh(src string) { 40 | ctx, cancel := context.WithCancel(context.Background()) 41 | agent, err := amesh.NewAgent(ctx, src, "", 0, nil, nil, "debug", "stderr") 42 | if err != nil { 43 | utils.Dief("failed to create generator: %v", err.Error()) 44 | } 45 | 46 | _ = cancel 47 | go func() { 48 | utils.WaitForSignal(func() { 49 | cancel() 50 | }) 51 | }() 52 | 53 | go func() { 54 | if err = agent.Run(ctx.Done()); err != nil { 55 | utils.Dief("agent error: %v", err.Error()) 56 | } 57 | }() 58 | } 59 | 60 | //export initial 61 | func initial(dataZone, versionZone unsafe.Pointer) { 62 | src := os.Getenv("ISTIO_XDS_SOURCE") 63 | if src == "" { 64 | src = "grpc://istiod.istio-system.svc.cluster.local:15010" 65 | } 66 | ameshGrpc := os.Getenv("AMESH_GRPC_SOURCE") 67 | if ameshGrpc == "" { 68 | ameshGrpc = "grpc://amesh-controller.istio-system.svc.cluster.local:15810" 69 | } 70 | syncInterval := os.Getenv("AMESH_SYNC_INTERVAL") 71 | if syncInterval == "" { 72 | syncInterval = "10" 73 | } 74 | interval, err := strconv.Atoi(syncInterval) 75 | if err != nil { 76 | utils.Dief("parse interval failed: %v", err.Error()) 77 | } 78 | 79 | ctx, cancel := context.WithCancel(context.Background()) 80 | agent, err := amesh.NewAgent(ctx, src, ameshGrpc, interval, dataZone, versionZone, "debug", "stderr") 81 | if err != nil { 82 | utils.Dief("failed to create generator: %v", err.Error()) 83 | } 84 | 85 | _ = cancel 86 | go func() { 87 | utils.WaitForSignal(func() { 88 | cancel() 89 | }) 90 | }() 91 | 92 | go func() { 93 | if err = agent.Run(ctx.Done()); err != nil { 94 | utils.Dief("agent error: %v", err.Error()) 95 | } 96 | }() 97 | } 98 | -------------------------------------------------------------------------------- /controller/config/default/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # Adds namespace to all resources. 2 | namespace: test-system 3 | 4 | # Value of this field is prepended to the 5 | # names of all resources, e.g. a deployment named 6 | # "wordpress" becomes "alices-wordpress". 7 | # Note that it should also match with the prefix (text before '-') of the namespace 8 | # field above. 9 | namePrefix: test- 10 | 11 | # Labels to add to all resources and selectors. 12 | #commonLabels: 13 | # someName: someValue 14 | 15 | bases: 16 | - ../crd 17 | - ../rbac 18 | - ../manager 19 | # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in 20 | # crd/kustomization.yaml 21 | #- ../webhook 22 | # [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. 'WEBHOOK' components are required. 23 | #- ../certmanager 24 | # [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'. 25 | #- ../prometheus 26 | 27 | patchesStrategicMerge: 28 | # Protect the /metrics endpoint by putting it behind auth. 29 | # If you want your controller-manager to expose the /metrics 30 | # endpoint w/o any authn/z, please comment the following line. 31 | - manager_auth_proxy_patch.yaml 32 | 33 | # Mount the controller config file for loading manager configurations 34 | # through a ComponentConfig type 35 | #- manager_config_patch.yaml 36 | 37 | # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in 38 | # crd/kustomization.yaml 39 | #- manager_webhook_patch.yaml 40 | 41 | # [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. 42 | # Uncomment 'CERTMANAGER' sections in crd/kustomization.yaml to enable the CA injection in the admission webhooks. 43 | # 'CERTMANAGER' needs to be enabled to use ca injection 44 | #- webhookcainjection_patch.yaml 45 | 46 | # the following config is for teaching kustomize how to do var substitution 47 | vars: 48 | # [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER' prefix. 49 | #- name: CERTIFICATE_NAMESPACE # namespace of the certificate CR 50 | # objref: 51 | # kind: Certificate 52 | # group: cert-manager.io 53 | # version: v1 54 | # name: serving-cert # this name should match the one in certificate.yaml 55 | # fieldref: 56 | # fieldpath: metadata.namespace 57 | #- name: CERTIFICATE_NAME 58 | # objref: 59 | # kind: Certificate 60 | # group: cert-manager.io 61 | # version: v1 62 | # name: serving-cert # this name should match the one in certificate.yaml 63 | #- name: SERVICE_NAMESPACE # namespace of the service 64 | # objref: 65 | # kind: Service 66 | # version: v1 67 | # name: webhook-service 68 | # fieldref: 69 | # fieldpath: metadata.namespace 70 | #- name: SERVICE_NAME 71 | # objref: 72 | # kind: Service 73 | # version: v1 74 | # name: webhook-service 75 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/api7/amesh 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/api7/amesh/api/proto v0.0.0-00010101000000-000000000000 7 | github.com/api7/amesh/controller v0.0.0-00010101000000-000000000000 8 | github.com/api7/gopkg v0.1.4 9 | github.com/envoyproxy/go-control-plane v0.10.1 10 | github.com/fatih/color v1.13.0 11 | github.com/golang/protobuf v1.5.2 12 | github.com/google/uuid v1.2.0 13 | github.com/hashicorp/go-multierror v1.1.1 14 | github.com/prometheus/client_golang v1.14.0 15 | github.com/spf13/cobra v1.4.0 16 | github.com/stretchr/testify v1.7.1 17 | go.uber.org/zap v1.19.1 18 | google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368 19 | google.golang.org/grpc v1.45.0 20 | google.golang.org/protobuf v1.28.1 21 | ) 22 | 23 | require ( 24 | github.com/davecgh/go-spew v1.1.1 // indirect 25 | github.com/go-logr/logr v1.2.0 // indirect 26 | github.com/gogo/protobuf v1.3.2 // indirect 27 | github.com/google/gofuzz v1.1.0 // indirect 28 | github.com/inconshreveable/mousetrap v1.0.0 // indirect 29 | github.com/json-iterator/go v1.1.12 // indirect 30 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 31 | github.com/modern-go/reflect2 v1.0.2 // indirect 32 | github.com/pmezard/go-difflib v1.0.0 // indirect 33 | github.com/spf13/pflag v1.0.5 // indirect 34 | go.uber.org/atomic v1.7.0 // indirect 35 | go.uber.org/multierr v1.6.0 // indirect 36 | golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect 37 | golang.org/x/sys v0.3.0 // indirect 38 | golang.org/x/text v0.3.8 // indirect 39 | gopkg.in/inf.v0 v0.9.1 // indirect 40 | gopkg.in/yaml.v2 v2.4.0 // indirect 41 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect 42 | k8s.io/apimachinery v0.24.2 // indirect 43 | k8s.io/klog/v2 v2.60.1 // indirect 44 | k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 // indirect 45 | sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect 46 | sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect 47 | ) 48 | 49 | require ( 50 | github.com/beorn7/perks v1.0.1 // indirect 51 | github.com/census-instrumentation/opencensus-proto v0.3.0 // indirect 52 | github.com/cespare/xxhash/v2 v2.1.2 // indirect 53 | github.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490 // indirect 54 | github.com/envoyproxy/protoc-gen-validate v0.6.2 // indirect 55 | github.com/hashicorp/errwrap v1.0.0 // indirect 56 | github.com/mattn/go-colorable v0.1.9 // indirect 57 | github.com/mattn/go-isatty v0.0.14 // indirect 58 | github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect 59 | github.com/prometheus/client_model v0.3.0 // indirect 60 | github.com/prometheus/common v0.37.0 // indirect 61 | github.com/prometheus/procfs v0.9.0 // indirect 62 | ) 63 | 64 | replace github.com/api7/amesh/api/proto => ./api/go/proto 65 | 66 | replace github.com/api7/amesh/controller => ./controller 67 | -------------------------------------------------------------------------------- /e2e/framework/utils/executor.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 The Amesh Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package utils 16 | 17 | import ( 18 | "sync" 19 | "time" 20 | 21 | "github.com/api7/gopkg/pkg/log" 22 | "github.com/onsi/ginkgo/v2" 23 | ) 24 | 25 | type MultiError []error 26 | 27 | func (multi MultiError) Error() string { 28 | msg := "" 29 | for i, err := range multi { 30 | msg += err.Error() 31 | if i != len(multi) { 32 | msg += "\n" 33 | } 34 | } 35 | return msg 36 | } 37 | 38 | type parallelExecutor struct { 39 | name string 40 | started time.Time 41 | 42 | wg sync.WaitGroup 43 | 44 | errorsLock sync.Mutex 45 | errors MultiError 46 | } 47 | 48 | func NewParallelExecutor(name string) *parallelExecutor { 49 | return ¶llelExecutor{ 50 | name: name, 51 | started: time.Now(), 52 | } 53 | } 54 | 55 | func ParallelRunAndWait(handlers ...func()) { 56 | exec := NewParallelExecutor("") 57 | for _, handler := range handlers { 58 | exec.Add(handler) 59 | } 60 | exec.Wait() 61 | } 62 | 63 | func ParallelRunFunctionsAndWait(handlersArray ...[]func()) { 64 | exec := NewParallelExecutor("") 65 | for _, handlers := range handlersArray { 66 | exec.Add(handlers...) 67 | } 68 | exec.Wait() 69 | } 70 | 71 | func (exec *parallelExecutor) Add(handlers ...func()) { 72 | exec.wg.Add(1) 73 | go func() { 74 | defer ginkgo.GinkgoRecover() 75 | defer exec.wg.Done() 76 | 77 | for _, handler := range handlers { 78 | handler() 79 | } 80 | }() 81 | } 82 | 83 | func (exec *parallelExecutor) AddE(handlers ...func() error) { 84 | exec.wg.Add(1) 85 | go func() { 86 | defer ginkgo.GinkgoRecover() 87 | defer exec.wg.Done() 88 | 89 | for _, handler := range handlers { 90 | err := handler() 91 | if err != nil { 92 | exec.errorsLock.Lock() 93 | exec.errors = append(exec.errors, err) 94 | exec.errorsLock.Unlock() 95 | } 96 | } 97 | }() 98 | } 99 | 100 | func (exec *parallelExecutor) Wait() { 101 | exec.wg.Wait() 102 | if exec.name != "" { 103 | log.SkipFramesOnce(1) 104 | LogTimeTrack(exec.started, exec.name+" end (%v)") 105 | } 106 | } 107 | 108 | func (exec *parallelExecutor) Errors() error { 109 | if len(exec.errors) == 0 { 110 | return nil 111 | } 112 | return exec.errors 113 | } 114 | -------------------------------------------------------------------------------- /pkg/apisix/storage/shdict.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 The Amesh Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | //go:build shared_lib 16 | // +build shared_lib 17 | 18 | package storage 19 | 20 | /* 21 | #cgo LDFLAGS: -shared -ldl 22 | #include "xds.h" 23 | #include 24 | 25 | extern void ngx_lua_ffi_shdict_store(void *zone, int op, 26 | const unsigned char *key, size_t key_len, 27 | int value_type, 28 | const unsigned char *str_value_buf, size_t str_value_len, 29 | double num_value, long exptime, int user_flags, char **errmsg, 30 | int *forcible); 31 | */ 32 | import "C" 33 | import ( 34 | "unsafe" 35 | 36 | "github.com/api7/gopkg/pkg/log" 37 | 38 | "github.com/api7/amesh/pkg/apisix" 39 | ) 40 | 41 | var ( 42 | _ apisix.Storage = (*SharedDictStorage)(nil) 43 | ) 44 | 45 | type SharedDictStorage struct { 46 | zone unsafe.Pointer 47 | } 48 | 49 | func NewSharedDictStorage(zone unsafe.Pointer) apisix.Storage { 50 | return &SharedDictStorage{ 51 | zone: zone, 52 | } 53 | } 54 | 55 | func (s *SharedDictStorage) Store(key, value string) { 56 | if s.zone == nil { 57 | log.Warnw("zone is nil") 58 | return 59 | } 60 | 61 | var keyCStr = C.CString(key) 62 | defer C.free(unsafe.Pointer(keyCStr)) 63 | var keyLen = C.size_t(len(key)) 64 | 65 | var valueCStr = C.CString(value) 66 | defer C.free(unsafe.Pointer(valueCStr)) 67 | var valueLen = C.size_t(len(value)) 68 | 69 | errMsgBuf := make([]*C.char, 1) 70 | var forcible = 0 71 | 72 | C.ngx_lua_ffi_shdict_store(s.zone, 0x0004, 73 | (*C.uchar)(unsafe.Pointer(keyCStr)), keyLen, 74 | 4, 75 | (*C.uchar)(unsafe.Pointer(valueCStr)), valueLen, 76 | 0, 0, 0, 77 | (**C.char)(unsafe.Pointer(&errMsgBuf[0])), 78 | (*C.int)(unsafe.Pointer(&forcible)), 79 | ) 80 | } 81 | 82 | func (s *SharedDictStorage) Delete(key string) { 83 | if s.zone == nil { 84 | log.Warnw("zone is nil") 85 | return 86 | } 87 | 88 | var keyCStr = C.CString(key) 89 | defer C.free(unsafe.Pointer(keyCStr)) 90 | var keyLen = C.size_t(len(key)) 91 | 92 | errMsgBuf := make([]*C.char, 1) 93 | var forcible = 0 94 | 95 | C.ngx_lua_ffi_shdict_store(s.zone, 0x0004, 96 | (*C.uchar)(unsafe.Pointer(keyCStr)), keyLen, 97 | 4, 98 | nil, 0, 99 | 0, 0, 0, 100 | (**C.char)(unsafe.Pointer(&errMsgBuf[0])), 101 | (*C.int)(unsafe.Pointer(&forcible)), 102 | ) 103 | } 104 | -------------------------------------------------------------------------------- /controller/README.md: -------------------------------------------------------------------------------- 1 | # test 2 | // TODO(user): Add simple overview of use/purpose 3 | 4 | ## Description 5 | // TODO(user): An in-depth paragraph about your project and overview of use 6 | 7 | ## Getting Started 8 | You’ll need a Kubernetes cluster to run against. You can use [KIND](https://sigs.k8s.io/kind) to get a local cluster for testing, or run against a remote cluster. 9 | **Note:** Your controller will automatically use the current context in your kubeconfig file (i.e. whatever cluster `kubectl cluster-info` shows). 10 | 11 | ### Running on the cluster 12 | 1. Install Instances of Custom Resources: 13 | 14 | ```sh 15 | kubectl apply -f config/samples/ 16 | ``` 17 | 18 | 2. Build and push your image to the location specified by `IMG`: 19 | 20 | ```sh 21 | make docker-build docker-push IMG=/test:tag 22 | ``` 23 | 24 | 3. Deploy the controller to the cluster with the image specified by `IMG`: 25 | 26 | ```sh 27 | make deploy IMG=/test:tag 28 | ``` 29 | 30 | ### Uninstall CRDs 31 | To delete the CRDs from the cluster: 32 | 33 | ```sh 34 | make uninstall 35 | ``` 36 | 37 | ### Undeploy controller 38 | UnDeploy the controller to the cluster: 39 | 40 | ```sh 41 | make undeploy 42 | ``` 43 | 44 | ## Contributing 45 | // TODO(user): Add detailed information on how you would like others to contribute to this project 46 | 47 | ### How it works 48 | This project aims to follow the Kubernetes [Operator pattern](https://kubernetes.io/docs/concepts/extend-kubernetes/operator/) 49 | 50 | It uses [Controllers](https://kubernetes.io/docs/concepts/architecture/controller/) 51 | which provides a reconcile function responsible for synchronizing resources untile the desired state is reached on the cluster 52 | 53 | ### Test It Out 54 | 1. Install the CRDs into the cluster: 55 | 56 | ```sh 57 | make install 58 | ``` 59 | 60 | 2. Run your controller (this will run in the foreground, so switch to a new terminal if you want to leave it running): 61 | 62 | ```sh 63 | make run 64 | ``` 65 | 66 | **NOTE:** You can also run this in one step by running: `make install run` 67 | 68 | ### Modifying the API definitions 69 | If you are editing the API definitions, generate the manifests such as CRs or CRDs using: 70 | 71 | ```sh 72 | make manifests 73 | ``` 74 | 75 | **NOTE:** Run `make --help` for more information on all potential `make` targets 76 | 77 | More information can be found via the [Kubebuilder Documentation](https://book.kubebuilder.io/introduction.html) 78 | 79 | ## License 80 | 81 | Copyright 2022. 82 | 83 | Licensed under the Apache License, Version 2.0 (the "License"); 84 | you may not use this file except in compliance with the License. 85 | You may obtain a copy of the License at 86 | 87 | http://www.apache.org/licenses/LICENSE-2.0 88 | 89 | Unless required by applicable law or agreed to in writing, software 90 | distributed under the License is distributed on an "AS IS" BASIS, 91 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 92 | See the License for the specific language governing permissions and 93 | limitations under the License. 94 | 95 | -------------------------------------------------------------------------------- /pkg/amesh/util/manifest.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 The Amesh Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package util 15 | 16 | import ( 17 | "fmt" 18 | 19 | "github.com/api7/amesh/pkg/amesh/types" 20 | "github.com/api7/amesh/pkg/apisix" 21 | "github.com/api7/amesh/pkg/apisix/utils" 22 | ) 23 | 24 | // Manifest collects a couples Routes, Upstreams. 25 | type Manifest struct { 26 | Routes []*apisix.Route 27 | Upstreams []*apisix.Upstream 28 | } 29 | 30 | // DiffFrom checks the difference between m and m2 from m's point of view. 31 | func (m *Manifest) DiffFrom(m2 *Manifest) (*Manifest, *Manifest, *Manifest) { 32 | var ( 33 | added Manifest 34 | updated Manifest 35 | deleted Manifest 36 | ) 37 | 38 | a, d, u := utils.CompareRoutes(m.Routes, m2.Routes) 39 | added.Routes = append(added.Routes, a...) 40 | updated.Routes = append(updated.Routes, u...) 41 | deleted.Routes = append(deleted.Routes, d...) 42 | 43 | au, du, uu := utils.CompareUpstreams(m.Upstreams, m2.Upstreams) 44 | added.Upstreams = append(added.Upstreams, au...) 45 | updated.Upstreams = append(updated.Upstreams, uu...) 46 | deleted.Upstreams = append(deleted.Upstreams, du...) 47 | 48 | return &added, &deleted, &updated 49 | } 50 | 51 | // Size calculates the number of resources in the manifest. 52 | func (m *Manifest) Size() int { 53 | return len(m.Upstreams) + len(m.Routes) 54 | } 55 | 56 | // Events generates events according to its collection. 57 | func (m *Manifest) Events(evType types.EventType) []types.Event { 58 | var events []types.Event 59 | for _, r := range m.Routes { 60 | key := fmt.Sprintf("/routes/%s", r.Id) 61 | if evType == types.EventDelete { 62 | events = append(events, types.Event{ 63 | Type: types.EventDelete, 64 | Key: key, 65 | Tombstone: r, 66 | }) 67 | } else { 68 | events = append(events, types.Event{ 69 | Type: evType, 70 | Key: key, 71 | Object: r, 72 | }) 73 | } 74 | } 75 | for _, u := range m.Upstreams { 76 | key := fmt.Sprintf("/upstreams/%s", u.Id) 77 | if evType == types.EventDelete { 78 | events = append(events, types.Event{ 79 | Type: types.EventDelete, 80 | Key: key, 81 | Tombstone: u, 82 | }) 83 | } else { 84 | // TODO: We may turn update events into delete events once we handle ErrRequireFurtherEDS more properly 85 | if u.Nodes == nil || len(u.Nodes) == 0 { 86 | continue 87 | } 88 | events = append(events, types.Event{ 89 | Type: evType, 90 | Key: key, 91 | Object: u, 92 | }) 93 | } 94 | } 95 | return events 96 | } 97 | --------------------------------------------------------------------------------