From 26d67c594c687208db8c7e87612df101592bd859 Mon Sep 17 00:00:00 2001 From: Michael Gasch Date: Wed, 23 Mar 2022 20:45:47 +0100 Subject: [PATCH] chore: Restructure VSphereSource (#395) Adding support for multiple sources by restructuring this source. Also removing pkg logstream because it was not working with the standard logging configuragion anymore. The zap configuration uses 'level' as the log level key, whereas logstream assumes 'severity'. Closes: #394 Signed-off-by: Michael Gasch --- .github/workflows/kind-e2e.yaml | 2 +- README.md | 37 ++- cmd/README.md | 9 +- cmd/vsphere-controller/main.go | 16 +- config/100-namespace.yaml | 1 + config/config-logging.yaml | 66 ++--- config/config-observability.yaml | 92 ++++++ config/{ => vsphere}/200-clusterrole-cm.yaml | 2 +- config/{ => vsphere}/200-clusterrole.yaml | 0 .../200-podspecable-binding-clusterrole.yaml | 0 config/{ => vsphere}/200-serviceaccount.yaml | 2 +- .../{ => vsphere}/201-clusterrolebinding.yaml | 6 +- config/{ => vsphere}/300-vspherebinding.yaml | 0 config/{ => vsphere}/300-vspheresource.yaml | 0 config/{ => vsphere}/400-webhook-service.yaml | 6 +- .../500-webhook-configuration.yaml | 26 +- config/{ => vsphere}/webhook.yaml | 22 +- .../vspheresource/resources/role_binding.go | 2 +- test/e2e/binding_test.go | 9 +- test/e2e/source_test.go | 5 +- .../knative.dev/pkg/test/logstream/README.md | 52 ---- vendor/knative.dev/pkg/test/logstream/doc.go | 21 -- .../pkg/test/logstream/interface.go | 97 ------- vendor/knative.dev/pkg/test/logstream/null.go | 27 -- .../pkg/test/logstream/v2/interface.go | 34 --- .../pkg/test/logstream/v2/stream.go | 269 ------------------ vendor/modules.txt | 2 - 27 files changed, 194 insertions(+), 611 deletions(-) rename config/{ => vsphere}/200-clusterrole-cm.yaml (88%) rename config/{ => vsphere}/200-clusterrole.yaml (100%) rename config/{ => vsphere}/200-podspecable-binding-clusterrole.yaml (100%) rename config/{ => vsphere}/200-serviceaccount.yaml (87%) rename config/{ => vsphere}/201-clusterrolebinding.yaml (92%) rename config/{ => vsphere}/300-vspherebinding.yaml (100%) rename config/{ => vsphere}/300-vspheresource.yaml (100%) rename config/{ => vsphere}/400-webhook-service.yaml (72%) rename config/{ => vsphere}/500-webhook-configuration.yaml (71%) rename config/{ => vsphere}/webhook.yaml (82%) delete mode 100644 vendor/knative.dev/pkg/test/logstream/README.md delete mode 100644 vendor/knative.dev/pkg/test/logstream/doc.go delete mode 100644 vendor/knative.dev/pkg/test/logstream/interface.go delete mode 100644 vendor/knative.dev/pkg/test/logstream/null.go delete mode 100644 vendor/knative.dev/pkg/test/logstream/v2/interface.go delete mode 100644 vendor/knative.dev/pkg/test/logstream/v2/stream.go diff --git a/.github/workflows/kind-e2e.yaml b/.github/workflows/kind-e2e.yaml index ab8a98fce..0d45ffca2 100644 --- a/.github/workflows/kind-e2e.yaml +++ b/.github/workflows/kind-e2e.yaml @@ -66,7 +66,7 @@ jobs: # Build Knative plugin go build -o kn-vsphere ./plugins/vsphere/cmd/vsphere - kubectl -n vmware-sources wait --timeout=10s --for=condition=Available deploy/webhook + kubectl -n vmware-sources wait --timeout=10s --for=condition=Available deploy/vsphere-source-webhook # For debugging. kubectl get pods --all-namespaces diff --git a/README.md b/README.md index 9df4b7b47..e3d0dcaa0 100644 --- a/README.md +++ b/README.md @@ -1,39 +1,50 @@ # VMware Tanzu Sources for Knative -This repo will be the home for VMware-related event sources compatible with the -[Knative](https://knative.dev) project. - [![GoDoc](https://godoc.org/github.com/vmware-tanzu/sources-for-knative?status.svg)](https://godoc.org/github.com/vmware-tanzu/sources-for-knative) [![Go Report Card](https://goreportcard.com/badge/vmware-tanzu/sources-for-knative)](https://goreportcard.com/report/vmware-tanzu/sources-for-knative) [![Slack Status](https://img.shields.io/badge/slack-join_chat-white.svg?logo=slack&style=social)](https://knative.slack.com) [![codecov](https://codecov.io/gh/vmware-tanzu/sources-for-knative/branch/master/graph/badge.svg?token=QwWjUwiLIN)](undefined) -This repo is under active development to get a Knative compatible Event Source -for vSphere events, and a Binding to easily access the VSphere API. +This repo is the home for VMware-related event sources compatible with the +[Knative](https://knative.dev) project. + + +This repo is under active development to get a Knative compatible Event `Source` +for VMware events, e.g. VMware vSphere incl. a `Binding` to easily access the +vSphere API from Kubernetes objects, e.g. a `Job`. ⚠️ **NOTE:** To run these examples, you will need [ko](https://github.com/google/ko) installed or use a -[release](https://github.com/vmware-tanzu/sources-for-knative/releases) and -deploy it via `kubectl`. +[release](https://github.com/vmware-tanzu/sources-for-knative/releases) +(preferred) and deploy it via `kubectl`. + +## Available `Sources` and `Bindings` + +- `VSphereSource` to create VMware vSphere (vCenter) event sources +- `VSphereBinding` to inject VMware vSphere (vCenter) credentials ## Install Tanzu Sources for Knative -### Install via Release +### Install via Release (`latest`) ``` -kubectl apply -f https://github.com/vmware-tanzu/sources-for-knative/releases/download/v0.21.0/release.yaml +kubectl apply -f https://github.com/vmware-tanzu/sources-for-knative/releases/latest/download/release.yaml ``` ### Install from Source -Install the CRD providing the control / dataplane for the -`VSphere{Source,Binding}`: +Install the CRD providing the control / dataplane for the various `Sources` and +`Bindings`: ```shell -ko apply -f config +# define environment variables accordingly, e.g. when using kind +# export KIND_CLUSTER_NAME=horizon +# export KO_DOCKER_REPO=kind.local + +ko apply -BRf config ``` -## Samples +## Examples To see examples of the Source and Binding in action, check out our [samples](./samples/README.md) directory. diff --git a/cmd/README.md b/cmd/README.md index 71e33701d..1ddd6ffcb 100644 --- a/cmd/README.md +++ b/cmd/README.md @@ -1,5 +1,8 @@ ## Binary names -The binaries in this directory are prefixed with `sources-for-knative-{foo}` so -that when published via `KO_DOCKER_REPO=docker.io/vmware ko apply -Bf config` -the resulting images are named `vmware/sources-for-knative-{foo}`. +The binaries in this directory are grouped by and prefixed with the +corresponding VMware product name, e.g. `vsphere` or `horizon`. + +When published via `KO_DOCKER_REPO=/vmware ko apply -BRf config` the +resulting images are named `/vmware/-{adapter|controller}`, +e.g. `docker.io/vmware/vsphere-adapter` diff --git a/cmd/vsphere-controller/main.go b/cmd/vsphere-controller/main.go index 390c2c36b..5939928f0 100644 --- a/cmd/vsphere-controller/main.go +++ b/cmd/vsphere-controller/main.go @@ -36,11 +36,13 @@ var types = map[schema.GroupVersionKind]resourcesemantics.GenericCRD{ v1alpha1.SchemeGroupVersion.WithKind("VSphereBinding"): &v1alpha1.VSphereBinding{}, } +const admissionWebhookName = "vsphere-source-webhook" + func NewDefaultingAdmissionController(ctx context.Context, cmw configmap.Watcher) *controller.Impl { return defaulting.NewAdmissionController(ctx, // Name of the resource webhook. - "defaulting.webhook.sources.tanzu.vmware.com", + "defaulting.webhook.vsphere.sources.tanzu.vmware.com", // The path on which to serve the webhook. "/defaulting", @@ -64,7 +66,7 @@ func NewValidationAdmissionController(ctx context.Context, cmw configmap.Watcher return validation.NewAdmissionController(ctx, // Name of the resource webhook. - "validation.webhook.sources.tanzu.vmware.com", + "validation.webhook.vsphere.sources.tanzu.vmware.com", // The path on which to serve the webhook. "/resource-validation", @@ -88,7 +90,7 @@ func NewConfigValidationController(ctx context.Context, cmw configmap.Watcher) * return configmaps.NewAdmissionController(ctx, // Name of the configmap webhook. - "config.webhook.sources.tanzu.vmware.com", + "config.webhook.vsphere.sources.tanzu.vmware.com", // The path on which to serve the webhook. "/config-validation", @@ -105,7 +107,7 @@ func NewVSphereBindingWebhook(opts ...psbinding.ReconcilerOption) injection.Cont return func(ctx context.Context, cmw configmap.Watcher) *controller.Impl { return psbinding.NewAdmissionController(ctx, // Name of the resource webhook. - "vspherebindings.webhook.sources.tanzu.vmware.com", + "vspherebindings.webhook.vsphere.sources.tanzu.vmware.com", // The path on which to serve the webhook. "/vspherebindings", @@ -126,9 +128,9 @@ func NewVSphereBindingWebhook(opts ...psbinding.ReconcilerOption) injection.Cont func main() { ctx := webhook.WithOptions(signals.NewContext(), webhook.Options{ - ServiceName: "webhook", + ServiceName: admissionWebhookName, Port: 8443, - SecretName: "webhook-certs", + SecretName: "vsphere-webhook-certs", }) vsbSelector := psbinding.WithSelector(psbinding.ExclusionSelector) @@ -136,7 +138,7 @@ func main() { vsbSelector = psbinding.WithSelector(psbinding.InclusionSelector) } - sharedmain.MainWithContext(ctx, "webhook", + sharedmain.MainWithContext(ctx, admissionWebhookName, certificates.NewController, NewDefaultingAdmissionController, NewValidationAdmissionController, diff --git a/config/100-namespace.yaml b/config/100-namespace.yaml index 412d0f018..49bb0971f 100644 --- a/config/100-namespace.yaml +++ b/config/100-namespace.yaml @@ -6,4 +6,5 @@ kind: Namespace metadata: name: vmware-sources labels: + istio-injection: enabled sources.tanzu.vmware.com/release: devel diff --git a/config/config-logging.yaml b/config/config-logging.yaml index e147f7e4b..81130f628 100644 --- a/config/config-logging.yaml +++ b/config/config-logging.yaml @@ -10,46 +10,30 @@ metadata: sources.tanzu.vmware.com/release: devel data: - _example: | - ################################ - # # - # EXAMPLE CONFIGURATION # - # # - ################################ - - # This block is not actually functional configuration, - # but serves to illustrate the available configuration - # options and document them in a way that is accessible - # to users that `kubectl edit` this config map. - # - # These sample configuration options may be copied out of - # this example block and unindented to be in the data block - # to actually change the configuration. - - # Common configuration for all Knative codebase - zap-logger-config: | - { - "level": "info", - "development": false, - "outputPaths": ["stdout"], - "errorOutputPaths": ["stderr"], - "encoding": "json", - "encoderConfig": { - "timeKey": "ts", - "levelKey": "level", - "nameKey": "logger", - "callerKey": "caller", - "messageKey": "msg", - "stacktraceKey": "stacktrace", - "lineEnding": "", - "levelEncoder": "", - "timeEncoder": "iso8601", - "durationEncoder": "", - "callerEncoder": "" - } + # Common configuration for all Knative codebase + zap-logger-config: | + { + "level": "info", + "development": false, + "outputPaths": ["stdout"], + "errorOutputPaths": ["stderr"], + "encoding": "json", + "encoderConfig": { + "timeKey": "ts", + "levelKey": "level", + "nameKey": "logger", + "callerKey": "caller", + "messageKey": "msg", + "stacktraceKey": "stacktrace", + "lineEnding": "", + "levelEncoder": "", + "timeEncoder": "iso8601", + "durationEncoder": "", + "callerEncoder": "" } + } - # Log level overrides - # Changes are be picked up immediately. - loglevel.controller: "info" - loglevel.webhook: "info" + # Log level overrides + # For all components changes are be picked up immediately. + loglevel.controller: "info" + loglevel.webhook: "info" diff --git a/config/config-observability.yaml b/config/config-observability.yaml index c5b79a24c..d025301a3 100644 --- a/config/config-observability.yaml +++ b/config/config-observability.yaml @@ -26,6 +26,98 @@ data: # this example block and unindented to be in the data block # to actually change the configuration. + # logging.enable-var-log-collection defaults to false. + # A fluentd sidecar will be set up to collect var log if + # this flag is true. + logging.enable-var-log-collection: false + + # logging.fluentd-sidecar-image provides the fluentd sidecar image + # to inject as a sidecar to collect logs from /var/log. + # Must be presented if logging.enable-var-log-collection is true. + logging.fluentd-sidecar-image: k8s.gcr.io/fluentd-elasticsearch:v2.0.4 + + # logging.fluentd-sidecar-output-config provides the configuration + # for the fluentd sidecar, which will be placed into a configmap and + # mounted into the fluentd sidecar image. + logging.fluentd-sidecar-output-config: | + # Parse json log before sending to Elastic Search + + @type parser + key_name log + + @type multi_format + + format json + time_key fluentd-time # fluentd-time is reserved for structured logs + time_format %Y-%m-%dT%H:%M:%S.%NZ + + + format none + message_key log + + + + # Send to Elastic Search + + @id elasticsearch + @type elasticsearch + @log_level info + include_tag_key true + # Elasticsearch service is in monitoring namespace. + host elasticsearch-logging.knative-monitoring + port 9200 + logstash_format true + + @type file + path /var/log/fluentd-buffers/kubernetes.system.buffer + flush_mode interval + retry_type exponential_backoff + flush_thread_count 2 + flush_interval 5s + retry_forever + retry_max_interval 30 + chunk_limit_size 2M + queue_limit_length 8 + overflow_action block + + + + # logging.revision-url-template provides a template to use for producing the + # logging URL that is injected into the status of each Revision. + # This value is what you might use the the Knative monitoring bundle, and provides + # access to Kibana after setting up kubectl proxy. + logging.revision-url-template: | + http://localhost:8001/api/v1/namespaces/knative-monitoring/services/kibana-logging/proxy/app/kibana#/discover?_a=(query:(match:(kubernetes.labels.knative-dev%2FrevisionUID:(query:'${REVISION_UID}',type:phrase)))) + + # If non-empty, this enables queue proxy writing request logs to stdout. + # The value determines the shape of the request logs and it must be a valid go text/template. + # It is important to keep this as a single line. Multiple lines are parsed as separate entities + # by most collection agents and will split the request logs into multiple records. + # + # The following fields and functions are available to the template: + # + # Request: An http.Request (see https://golang.org/pkg/net/http/#Request) + # representing an HTTP request received by the server. + # + # Response: + # struct { + # Code int // HTTP status code (see https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml) + # Size int // An int representing the size of the response. + # Latency float64 // A float64 representing the latency of the response in seconds. + # } + # + # Revision: + # struct { + # Name string // Knative revision name + # Namespace string // Knative revision namespace + # Service string // Knative service name + # Configuration string // Knative configuration name + # PodName string // Name of the pod hosting the revision + # PodIP string // IP of the pod hosting the revision + # } + # + logging.request-log-template: '{"httpRequest": {"requestMethod": "{{.Request.Method}}", "requestUrl": "{{js .Request.RequestURI}}", "requestSize": "{{.Request.ContentLength}}", "status": {{.Response.Code}}, "responseSize": "{{.Response.Size}}", "userAgent": "{{js .Request.UserAgent}}", "remoteIp": "{{js .Request.RemoteAddr}}", "serverIp": "{{.Revision.PodIP}}", "referer": "{{js .Request.Referer}}", "latency": "{{.Response.Latency}}s", "protocol": "{{.Request.Proto}}"}, "traceId": "{{index .Request.Header "X-B3-Traceid"}}"}' + # metrics.backend-destination field specifies the system metrics destination. # It supports either prometheus (the default) or stackdriver. # Note: Using stackdriver will incur additional charges diff --git a/config/200-clusterrole-cm.yaml b/config/vsphere/200-clusterrole-cm.yaml similarity index 88% rename from config/200-clusterrole-cm.yaml rename to config/vsphere/200-clusterrole-cm.yaml index 221863522..fdddf6846 100644 --- a/config/200-clusterrole-cm.yaml +++ b/config/vsphere/200-clusterrole-cm.yaml @@ -1,7 +1,7 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: - name: receive-adapter-cm + name: vsphere-receive-adapter-cm rules: - apiGroups: [""] # We need to create/update/get ConfigMaps so that the diff --git a/config/200-clusterrole.yaml b/config/vsphere/200-clusterrole.yaml similarity index 100% rename from config/200-clusterrole.yaml rename to config/vsphere/200-clusterrole.yaml diff --git a/config/200-podspecable-binding-clusterrole.yaml b/config/vsphere/200-podspecable-binding-clusterrole.yaml similarity index 100% rename from config/200-podspecable-binding-clusterrole.yaml rename to config/vsphere/200-podspecable-binding-clusterrole.yaml diff --git a/config/200-serviceaccount.yaml b/config/vsphere/200-serviceaccount.yaml similarity index 87% rename from config/200-serviceaccount.yaml rename to config/vsphere/200-serviceaccount.yaml index 3ae2158eb..e567a0005 100644 --- a/config/200-serviceaccount.yaml +++ b/config/vsphere/200-serviceaccount.yaml @@ -4,7 +4,7 @@ apiVersion: v1 kind: ServiceAccount metadata: - name: controller + name: vsphere-controller namespace: vmware-sources labels: sources.tanzu.vmware.com/release: devel diff --git a/config/201-clusterrolebinding.yaml b/config/vsphere/201-clusterrolebinding.yaml similarity index 92% rename from config/201-clusterrolebinding.yaml rename to config/vsphere/201-clusterrolebinding.yaml index 9eff0bb1b..0a8a7215c 100644 --- a/config/201-clusterrolebinding.yaml +++ b/config/vsphere/201-clusterrolebinding.yaml @@ -9,7 +9,7 @@ metadata: sources.tanzu.vmware.com/release: devel subjects: - kind: ServiceAccount - name: controller + name: vsphere-controller namespace: vmware-sources roleRef: kind: ClusterRole @@ -25,7 +25,7 @@ metadata: sources.tanzu.vmware.com/release: devel subjects: - kind: ServiceAccount - name: controller + name: vsphere-controller namespace: vmware-sources roleRef: kind: ClusterRole @@ -38,7 +38,7 @@ metadata: name: vmware-sources-webhook-addressable-resolver-binding subjects: - kind: ServiceAccount - name: controller + name: vsphere-controller namespace: vmware-sources roleRef: kind: ClusterRole diff --git a/config/300-vspherebinding.yaml b/config/vsphere/300-vspherebinding.yaml similarity index 100% rename from config/300-vspherebinding.yaml rename to config/vsphere/300-vspherebinding.yaml diff --git a/config/300-vspheresource.yaml b/config/vsphere/300-vspheresource.yaml similarity index 100% rename from config/300-vspheresource.yaml rename to config/vsphere/300-vspheresource.yaml diff --git a/config/400-webhook-service.yaml b/config/vsphere/400-webhook-service.yaml similarity index 72% rename from config/400-webhook-service.yaml rename to config/vsphere/400-webhook-service.yaml index 8ada854d8..df8f068c4 100644 --- a/config/400-webhook-service.yaml +++ b/config/vsphere/400-webhook-service.yaml @@ -5,13 +5,13 @@ apiVersion: v1 kind: Service metadata: labels: - role: webhook + role: vsphere-source-webhook sources.tanzu.vmware.com/release: devel - name: webhook + name: vsphere-source-webhook namespace: vmware-sources spec: ports: - port: 443 targetPort: 8443 selector: - role: webhook + role: vsphere-source-webhook diff --git a/config/500-webhook-configuration.yaml b/config/vsphere/500-webhook-configuration.yaml similarity index 71% rename from config/500-webhook-configuration.yaml rename to config/vsphere/500-webhook-configuration.yaml index ee9cf9f63..9b47f1dc0 100644 --- a/config/500-webhook-configuration.yaml +++ b/config/vsphere/500-webhook-configuration.yaml @@ -4,51 +4,51 @@ apiVersion: admissionregistration.k8s.io/v1 kind: MutatingWebhookConfiguration metadata: - name: defaulting.webhook.sources.tanzu.vmware.com + name: defaulting.webhook.vsphere.sources.tanzu.vmware.com labels: sources.tanzu.vmware.com/release: devel webhooks: - admissionReviewVersions: ["v1", "v1beta1"] clientConfig: service: - name: webhook + name: vsphere-source-webhook namespace: vmware-sources failurePolicy: Fail - name: defaulting.webhook.sources.tanzu.vmware.com + name: defaulting.webhook.vsphere.sources.tanzu.vmware.com sideEffects: None timeoutSeconds: 2 --- apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingWebhookConfiguration metadata: - name: validation.webhook.sources.tanzu.vmware.com + name: validation.webhook.vsphere.sources.tanzu.vmware.com labels: sources.tanzu.vmware.com/release: devel webhooks: - admissionReviewVersions: ["v1", "v1beta1"] clientConfig: service: - name: webhook + name: vsphere-source-webhook namespace: vmware-sources failurePolicy: Fail - name: validation.webhook.sources.tanzu.vmware.com + name: validation.webhook.vsphere.sources.tanzu.vmware.com sideEffects: None timeoutSeconds: 2 --- apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingWebhookConfiguration metadata: - name: config.webhook.sources.tanzu.vmware.com + name: config.webhook.vsphere.sources.tanzu.vmware.com labels: sources.tanzu.vmware.com/release: devel webhooks: - admissionReviewVersions: ["v1", "v1beta1"] clientConfig: service: - name: webhook + name: vsphere-source-webhook namespace: vmware-sources failurePolicy: Fail - name: config.webhook.sources.tanzu.vmware.com + name: config.webhook.vsphere.sources.tanzu.vmware.com namespaceSelector: matchExpressions: - key: sources.tanzu.vmware.com/release @@ -59,7 +59,7 @@ webhooks: apiVersion: v1 kind: Secret metadata: - name: webhook-certs + name: vsphere-webhook-certs namespace: vmware-sources labels: sources.tanzu.vmware.com/release: devel @@ -68,16 +68,16 @@ metadata: apiVersion: admissionregistration.k8s.io/v1 kind: MutatingWebhookConfiguration metadata: - name: vspherebindings.webhook.sources.tanzu.vmware.com + name: vspherebindings.webhook.vsphere.sources.tanzu.vmware.com labels: sources.tanzu.vmware.com/release: devel webhooks: - admissionReviewVersions: ["v1", "v1beta1"] clientConfig: service: - name: webhook + name: vsphere-source-webhook namespace: vmware-sources failurePolicy: Fail sideEffects: None - name: vspherebindings.webhook.sources.tanzu.vmware.com + name: vspherebindings.webhook.vsphere.sources.tanzu.vmware.com timeoutSeconds: 2 diff --git a/config/webhook.yaml b/config/vsphere/webhook.yaml similarity index 82% rename from config/webhook.yaml rename to config/vsphere/webhook.yaml index 67458561e..1e6759fa6 100644 --- a/config/webhook.yaml +++ b/config/vsphere/webhook.yaml @@ -4,7 +4,7 @@ apiVersion: apps/v1 kind: Deployment metadata: - name: webhook + name: vsphere-source-webhook namespace: vmware-sources labels: sources.tanzu.vmware.com/release: devel @@ -12,13 +12,13 @@ spec: replicas: 1 selector: matchLabels: - app: webhook - role: webhook + app: vsphere-source-webhook + role: vsphere-source-webhook template: metadata: labels: - app: webhook - role: webhook + app: vsphere-source-webhook + role: vsphere-source-webhook sources.tanzu.vmware.com/release: devel spec: # To avoid node becoming SPOF, spread our replicas to different nodes. @@ -28,13 +28,13 @@ spec: - podAffinityTerm: labelSelector: matchLabels: - app: webhook + app: vsphere-source-webhook topologyKey: kubernetes.io/hostname weight: 100 - serviceAccountName: controller + serviceAccountName: vsphere-controller containers: - - name: webhook + - name: vsphere-source-webhook # This is the Go import path for the binary that is containerized # and substituted here. image: ko://github.com/vmware-tanzu/sources-for-knative/cmd/vsphere-controller @@ -59,11 +59,11 @@ spec: - name: METRICS_DOMAIN value: tanzu.vmware.com/sources - name: WEBHOOK_NAME - value: webhook + value: vsphere-source-webhook readinessProbe: &probe # Increasing the failure threshold and adding an initial delay - # avoids the situation where failing probes cause the webhook to restart before it can + # avoids the situation where failing probes cause the vsphere-source-webhook to restart before it can # finish setup. See https://github.com/vmware-tanzu/sources-for-knative/issues/356 failureThreshold: 6 initialDelaySeconds: 20 @@ -72,5 +72,5 @@ spec: port: 8443 httpHeaders: - name: k-kubelet-probe - value: "webhook" + value: "vsphere-source-webhook" livenessProbe: *probe diff --git a/pkg/reconciler/vspheresource/resources/role_binding.go b/pkg/reconciler/vspheresource/resources/role_binding.go index cf792ca4a..831b7a7d7 100644 --- a/pkg/reconciler/vspheresource/resources/role_binding.go +++ b/pkg/reconciler/vspheresource/resources/role_binding.go @@ -28,7 +28,7 @@ func MakeRoleBinding(ctx context.Context, vms *v1alpha1.VSphereSource) *rbacv1.R RoleRef: rbacv1.RoleRef{ APIGroup: "rbac.authorization.k8s.io", Kind: "ClusterRole", - Name: "receive-adapter-cm", + Name: "vsphere-receive-adapter-cm", }, Subjects: []rbacv1.Subject{{ Kind: "ServiceAccount", diff --git a/test/e2e/binding_test.go b/test/e2e/binding_test.go index 58bf70baa..7b56ba6bd 100644 --- a/test/e2e/binding_test.go +++ b/test/e2e/binding_test.go @@ -13,7 +13,6 @@ import ( "testing" pkgtest "knative.dev/pkg/test" - "knative.dev/pkg/test/logstream" "github.com/vmware-tanzu/sources-for-knative/test" ) @@ -22,11 +21,9 @@ import ( // run to completion successfully. func TestBindingGOVC(t *testing.T) { // t.Parallel() - defer logstream.Start(t)() - clients := test.Setup(t) - //create vcsim + // create vcsim cleanupVcsim := CreateSimulator(t, clients) defer cleanupVcsim() @@ -50,11 +47,9 @@ func TestBindingGOVC(t *testing.T) { // and run to completion successfully. func TestBindingPowerCLICore(t *testing.T) { // t.Parallel() - defer logstream.Start(t)() - clients := test.Setup(t) - //create vcsim + // create vcsim cleanupVcsim := CreateSimulator(t, clients) defer cleanupVcsim() diff --git a/test/e2e/source_test.go b/test/e2e/source_test.go index c41b97604..1c43197df 100644 --- a/test/e2e/source_test.go +++ b/test/e2e/source_test.go @@ -13,7 +13,6 @@ import ( "testing" pkgtest "knative.dev/pkg/test" - "knative.dev/pkg/test/logstream" "github.com/vmware-tanzu/sources-for-knative/test" ) @@ -21,11 +20,9 @@ import ( // TestSource creates a Job that completes after receiving events, and a Source targeting that job. func TestSource(t *testing.T) { // t.Parallel() - defer logstream.Start(t)() - clients := test.Setup(t) - //create vcsim + // create vcsim cleanupVcsim := CreateSimulator(t, clients) defer cleanupVcsim() diff --git a/vendor/knative.dev/pkg/test/logstream/README.md b/vendor/knative.dev/pkg/test/logstream/README.md deleted file mode 100644 index 7c7886bd5..000000000 --- a/vendor/knative.dev/pkg/test/logstream/README.md +++ /dev/null @@ -1,52 +0,0 @@ -# How to use logstream - -This is a guide to start using `logstream` in your e2e testing. - -## Requirements - -1. The `SYSTEM_NAMESPACE` environment variable must be configured. Many of the - knative test scripts already define this, and in some places (e.g. serving) - randomize it. However, to facilitate usage outside of CI, you should consider - including a package like - [this](https://github.com/knative/serving/blob/main/test/defaultsystem/system.go) - and linking it like - [this](https://github.com/knative/serving/blob/e797247322b5aa35001152d2a2715dbc20a86cc4/test/conformance.go#L20-L23) - -2. Test resources must be named with - [`test.ObjectNameForTest(t)`](https://github.com/knative/networking/blob/40ef99aa5db0d38730a89a1de7e5b28b8ef6eed5/vendor/knative.dev/pkg/test/helpers/name.go#L50) - -3. At the start of your test add: `t.Cleanup(logstream.Start(t))` - -4. To enable logcapture from containers across multiple namespaces configure - SYSTEM_NAMESPACE to contains a csv list of namespaces - (`knative-serving,knative-test ??????{}`). Specific, well known containers - that do not produce key decorated logs (see detailed description below) need - to be enumerated in WellKnownContainers in stream.go. - -With that, you will start getting logs from the processes in the system -namespace interleaved into your test output via `t.Log`. - -## How it works - -In Knative we use `zap.Logger` for all of our logging, and most of those loggers -(e.g. in the context of a reconcile) have been decorated with the "key" of the -resource being processed. `logstream` simply decodes these structured log -messages and when the `key` matches the naming prefix that `ObjectNameForTest` -uses, it includes it into the test's output. - -## Integrating in Libraries. - -When a shared component is set up and called from reconciliation, it may have -it's own logger. If that component is dealing with individual resources, it can -scope individual log statements to that resource by decorating the logger with -its key like so: - -``` -logger := logger.With(zap.String(logkey.Key, resourceKey)) -``` - -Now, any log statements that the library prints through this logger will appear -in the logstream! - -For an example of this pattern, see -[the knative/networking prober library](https://github.com/knative/networking/blob/main/pkg/status/status.go). diff --git a/vendor/knative.dev/pkg/test/logstream/doc.go b/vendor/knative.dev/pkg/test/logstream/doc.go deleted file mode 100644 index ddad2c446..000000000 --- a/vendor/knative.dev/pkg/test/logstream/doc.go +++ /dev/null @@ -1,21 +0,0 @@ -/* -Copyright 2019 The Knative Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Package logstream lets end-to-end tests incorporate controller logs -// into the error output of tests. It is enabled by setting the -// SYSTEM_NAMESPACE environment variable, which tells this package -// what namespace to stream logs from. -package logstream diff --git a/vendor/knative.dev/pkg/test/logstream/interface.go b/vendor/knative.dev/pkg/test/logstream/interface.go deleted file mode 100644 index 33bc02332..000000000 --- a/vendor/knative.dev/pkg/test/logstream/interface.go +++ /dev/null @@ -1,97 +0,0 @@ -/* -Copyright 2019 The Knative Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package logstream - -import ( - "context" - "os" - "strings" - "sync" - - "k8s.io/client-go/kubernetes" - "knative.dev/pkg/system" - "knative.dev/pkg/test" - "knative.dev/pkg/test/helpers" - logstreamv2 "knative.dev/pkg/test/logstream/v2" -) - -// Canceler is the type of a function returned when a logstream is started to be -// deferred so that the logstream can be stopped when the test is complete. -type Canceler = logstreamv2.Canceler - -type ti interface { - Name() string - Error(args ...interface{}) - Log(args ...interface{}) - Logf(fmt string, args ...interface{}) -} - -// Start begins streaming the logs from system components with a `key:` matching -// `test.ObjectNameForTest(t)` to `t.Log`. It returns a Canceler, which must -// be called before the test completes. -func Start(t ti) Canceler { - // Do this lazily to make import ordering less important. - once.Do(func() { - if ns := os.Getenv(system.NamespaceEnvKey); ns != "" { - config, err := test.Flags.GetRESTConfig() - if err != nil { - t.Error("Error loading client config", "error", err) - return - } - - kc, err := kubernetes.NewForConfig(config) - if err != nil { - t.Error("Error creating kubernetes client", "error", err) - return - } - - // handle case when ns contains a csv list - namespaces := strings.Split(ns, ",") - stream = &shim{logstreamv2.FromNamespaces(context.Background(), kc, namespaces)} - - } else { - // Otherwise set up a null stream. - stream = &null{} - } - }) - - return stream.Start(t) -} - -type streamer interface { - Start(t ti) Canceler -} - -var ( - stream streamer - once sync.Once -) - -type shim struct { - logstreamv2.Source -} - -func (s *shim) Start(t ti) Canceler { - name := helpers.ObjectPrefixForTest(t) - canceler, err := s.StartStream(name, t.Logf) - - if err != nil { - t.Error("Failed to start logstream", "error", err) - } - - return canceler -} diff --git a/vendor/knative.dev/pkg/test/logstream/null.go b/vendor/knative.dev/pkg/test/logstream/null.go deleted file mode 100644 index 13697aae4..000000000 --- a/vendor/knative.dev/pkg/test/logstream/null.go +++ /dev/null @@ -1,27 +0,0 @@ -/* -Copyright 2019 The Knative Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package logstream - -type null struct{} - -var _ streamer = (*null)(nil) - -// Start implements streamer -func (*null) Start(t ti) Canceler { - t.Log("logstream was requested, but SYSTEM_NAMESPACE was unset.") - return func() {} -} diff --git a/vendor/knative.dev/pkg/test/logstream/v2/interface.go b/vendor/knative.dev/pkg/test/logstream/v2/interface.go deleted file mode 100644 index cf2359a5a..000000000 --- a/vendor/knative.dev/pkg/test/logstream/v2/interface.go +++ /dev/null @@ -1,34 +0,0 @@ -/* -Copyright 2020 The Knative Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package logstream - -type ( - // Canceler is the type of a function returned when a logstream is - // started to be deferred so that the logstream can be stopped when - // the test is complete. - Canceler func() - - // Callback is invoked after pod logs are transformed - Callback func(string, ...interface{}) - - // Source allows you to create streams for a given resource name - Source interface { - // Start a log stream for the given resource name and invoke - // the callback with the processed log - StartStream(name string, l Callback) (Canceler, error) - } -) diff --git a/vendor/knative.dev/pkg/test/logstream/v2/stream.go b/vendor/knative.dev/pkg/test/logstream/v2/stream.go deleted file mode 100644 index b244fe8b7..000000000 --- a/vendor/knative.dev/pkg/test/logstream/v2/stream.go +++ /dev/null @@ -1,269 +0,0 @@ -/* -Copyright 2020 The Knative Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package logstream - -import ( - "bufio" - "context" - "encoding/json" - "fmt" - "reflect" - "strings" - "sync" - "time" - - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/sets" - "k8s.io/apimachinery/pkg/watch" - "k8s.io/client-go/kubernetes" - "knative.dev/pkg/ptr" -) - -func FromNamespaces(ctx context.Context, c kubernetes.Interface, namespaces []string) Source { - return &namespaceSource{ - ctx: ctx, - kc: c, - namespaces: namespaces, - keys: make(map[string]Callback, 1), - } -} - -func FromNamespace(ctx context.Context, c kubernetes.Interface, namespace string) Source { - return &namespaceSource{ - ctx: ctx, - kc: c, - namespaces: []string{namespace}, - keys: make(map[string]Callback, 1), - } -} - -type namespaceSource struct { - namespaces []string - kc kubernetes.Interface - ctx context.Context - - m sync.RWMutex - once sync.Once - keys map[string]Callback - watchErr error -} - -func (s *namespaceSource) StartStream(name string, l Callback) (Canceler, error) { - s.once.Do(func() { s.watchErr = s.watchPods() }) - if s.watchErr != nil { - return nil, fmt.Errorf("failed to watch pods in one of the namespace(s) %q: %w", s.namespaces, s.watchErr) - } - - // Register a key - s.m.Lock() - defer s.m.Unlock() - s.keys[name] = l - - // Return a function that unregisters that key. - return func() { - s.m.Lock() - defer s.m.Unlock() - delete(s.keys, name) - }, nil -} - -func (s *namespaceSource) watchPods() error { - for _, ns := range s.namespaces { - wi, err := s.kc.CoreV1().Pods(ns).Watch(s.ctx, metav1.ListOptions{}) - if err != nil { - return err - } - - go func() { - defer wi.Stop() - watchedPods := sets.NewString() - - for { - select { - case <-s.ctx.Done(): - return - case ev := <-wi.ResultChan(): - // We have reports of this being randomly nil. - if ev.Object == nil || reflect.ValueOf(ev.Object).IsNil() { - continue - } - p, ok := ev.Object.(*corev1.Pod) - if !ok { - // The Watch interface can return errors via the channel as *metav1.Status. - // Log those to get notified that loglines might be missing but don't crash. - s.handleGenericLine([]byte(fmt.Sprintf("unexpected event: %v", p)), "no-pod", "no-container") - continue - } - switch ev.Type { - case watch.Deleted: - watchedPods.Delete(p.Name) - case watch.Added, watch.Modified: - if !watchedPods.Has(p.Name) && isPodReady(p) { - watchedPods.Insert(p.Name) - s.startForPod(p) - } - } - - } - } - }() - } - - return nil -} - -func (s *namespaceSource) startForPod(pod *corev1.Pod) { - // Grab data from all containers in the pods. We need this in case - // an envoy sidecar is injected for mesh installs. This should be - // equivalent to --all-containers. - for _, container := range pod.Spec.Containers { - // Required for capture below. - psn, pn, cn := pod.Namespace, pod.Name, container.Name - - handleLine := s.handleLine - if wellKnownContainers.Has(cn) { - // Specialcase logs from chaosduck, queueproxy etc. - // - ChaosDuck logs enable easy - // monitoring of killed pods throughout all tests. - // - QueueProxy logs enable - // debugging troubleshooting data plane request handling issues. - handleLine = s.handleGenericLine - } - - go func() { - options := &corev1.PodLogOptions{ - Container: cn, - // Follow directs the API server to continuously stream logs back. - Follow: true, - // Only return new logs (this value is being used for "epsilon"). - SinceSeconds: ptr.Int64(1), - } - - req := s.kc.CoreV1().Pods(psn).GetLogs(pn, options) - stream, err := req.Stream(context.Background()) - if err != nil { - s.handleGenericLine([]byte(err.Error()), pn, cn) - return - } - defer stream.Close() - // Read this container's stream. - for scanner := bufio.NewScanner(stream); scanner.Scan(); { - handleLine(scanner.Bytes(), pn, cn) - } - // Pods get killed with chaos duck, so logs might end - // before the test does. So don't report an error here. - }() - } -} - -func isPodReady(p *corev1.Pod) bool { - if p.Status.Phase == corev1.PodRunning && p.DeletionTimestamp == nil { - for _, cond := range p.Status.Conditions { - if cond.Type == corev1.PodReady && cond.Status == corev1.ConditionTrue { - return true - } - } - } - return false -} - -const ( - // timeFormat defines a simple timestamp with millisecond granularity - timeFormat = "15:04:05.000" - // ChaosDuck is the well known name for the chaosduck. - ChaosDuck = "chaosduck" - // QueueProxy is the well known name for the queueproxy. - QueueProxy = "queueproxy" -) - -// Names of well known containers that do not produce nicely formatted logs that -// could be easily filtered and parsed by handleLine. Logs from these containers -// are captured without filtering. -var wellKnownContainers = sets.NewString(ChaosDuck, QueueProxy) - -func (s *namespaceSource) handleLine(l []byte, pod string, _ string) { - // This holds the standard structure of our logs. - var line struct { - Level string `json:"severity"` - Timestamp time.Time `json:"timestamp"` - Controller string `json:"knative.dev/controller"` - Caller string `json:"caller"` - Key string `json:"knative.dev/key"` - Message string `json:"message"` - Error string `json:"error"` - - // TODO(mattmoor): Parse out more context. - } - if err := json.Unmarshal(l, &line); err != nil { - // Ignore malformed lines. - return - } - if line.Key == "" { - return - } - - s.m.RLock() - defer s.m.RUnlock() - - for name, logf := range s.keys { - // TODO(mattmoor): Do a slightly smarter match. - if !strings.Contains(line.Key, "/"+name) { - continue - } - - // We also get logs not from controllers (activator, autoscaler). - // So replace controller string in them with their callsite. - site := line.Controller - if site == "" { - site = line.Caller - } - func() { - defer func() { - if err := recover(); err != nil { - logf("Invalid log format for pod %s: %s", pod, string(l)) - } - }() - // E 15:04:05.000 webhook-699b7b668d-9smk2 [route-controller] [default/testroute-xyz] this is my message - msg := fmt.Sprintf("%s %s %s [%s] [%s] %s", - strings.ToUpper(string(line.Level[0])), - line.Timestamp.Format(timeFormat), - pod, - site, - line.Key, - line.Message) - - if line.Error != "" { - msg += " err=" + line.Error - } - - logf(msg) - }() - } -} - -// handleGenericLine prints the given logline to all active tests as it cannot be parsed -// and/or doesn't contain any correlation data (like the chaosduck for example). -func (s *namespaceSource) handleGenericLine(l []byte, pod string, cn string) { - s.m.RLock() - defer s.m.RUnlock() - - for _, logf := range s.keys { - // I 15:04:05.000 webhook-699b7b668d-9smk2 this is my message - logf("I %s %s %s %s", time.Now().Format(timeFormat), pod, cn, string(l)) - } -} diff --git a/vendor/modules.txt b/vendor/modules.txt index d6ae0cb67..e5060ebf2 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1333,8 +1333,6 @@ knative.dev/pkg/test/environment knative.dev/pkg/test/helpers knative.dev/pkg/test/ingress knative.dev/pkg/test/logging -knative.dev/pkg/test/logstream -knative.dev/pkg/test/logstream/v2 knative.dev/pkg/test/monitoring knative.dev/pkg/test/spoof knative.dev/pkg/test/zipkin