diff --git a/Gopkg.lock b/Gopkg.lock index d6fc918f1a..1cd0639618 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -76,6 +76,12 @@ revision = "3eb9738c1697594ea6e71a7156a9bb32ed216cf0" version = "v2.8.0" +[[projects]] + branch = "master" + name = "github.com/fsnotify/fsnotify" + packages = ["."] + revision = "ccc981bf80385c528a65fbfdd49bf2d8da22aa23" + [[projects]] branch = "master" name = "github.com/ghodss/yaml" @@ -214,6 +220,12 @@ revision = "9f23e2d6bd2a77f959b2bf6acdbefd708a83a4a4" version = "v0.3.6" +[[projects]] + branch = "master" + name = "github.com/joncalhoun/qson" + packages = ["."] + revision = "8a9cab3a62b1b693e7dfa590a215dc6217552803" + [[projects]] name = "github.com/json-iterator/go" packages = ["."] @@ -382,7 +394,7 @@ "blake2b", "ssh/terminal" ] - revision = "e84da0312774c21d64ee2317962ef669b27ffb41" + revision = "4d3f4d9ffa16a13f451c3b2999e9c49e9750bf06" [[projects]] branch = "master" @@ -399,7 +411,7 @@ "trace", "websocket" ] - revision = "9b4f9f5ad5197c79fd623a3638e70d8b26cef344" + revision = "c44066c5c816ec500d459a2a324a753f78531ae0" [[projects]] branch = "master" @@ -409,7 +421,7 @@ "unix", "windows" ] - revision = "95b1ffbd15a57cc5abb3f04402b9e8ec0016a52c" + revision = "7e31e0c00fa05cb5fbf4347b585621d6709e19a4" [[projects]] name = "golang.org/x/text" @@ -448,13 +460,13 @@ "internal/fastwalk", "internal/gopathwalk" ] - revision = "f60e5f99f0816fc2d9ecb338008ea420248d2943" + revision = "bb28844c46df63910d88c11eb36098ce781adfa0" [[projects]] branch = "master" name = "google.golang.org/genproto" packages = ["googleapis/rpc/status"] - revision = "8b5d7a19e2d98fbad9aaf9c599776bf066d7c70f" + revision = "b69ba1387ce2108ac9bc8e8e5e5a46e7d5c72313" [[projects]] name = "google.golang.org/grpc" @@ -736,6 +748,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "2dde50dbe268c1ba5ca9835d7a8acb240f42b11a5fb04b5af3757539f0849c5e" + inputs-digest = "952784260c5e9063118c3595643f512f8e5629a68aefc25502423dc86a8ddf76" solver-name = "gps-cdcl" solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml index 707fd1ad9e..eb3642d3d0 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -53,6 +53,10 @@ required = [ name = "github.com/stretchr/testify" version = "1.1.4" +[[constraint]] + name = "github.com/fsnotify/fsnotify" + branch = "master" + [[override]] branch = "release-1.10" name = "k8s.io/api" diff --git a/Makefile b/Makefile index 5b6b034ede..ce48d2adc0 100644 --- a/Makefile +++ b/Makefile @@ -35,13 +35,13 @@ endif # Build the project images .DELETE_ON_ERROR: -all: sensor-linux sensor-controller-linux gateway-controller-linux gateway-http-transformer-linux webhook-linux calendar-linux resource-linux artifact-linux nats-linux kafka-linux amqp-linux mqtt-linux gateway-processor-grpc-client-linux calendar-grpc-linux gateway-processor-http-client-linux calendar-http-linux storage-grid-linux +all: sensor-linux sensor-controller-linux gateway-controller-linux gateway-http-transformer-linux webhook-linux calendar-linux resource-linux artifact-linux file-linux nats-linux kafka-linux amqp-linux mqtt-linux gateway-processor-grpc-client-linux calendar-grpc-linux gateway-processor-http-client-linux calendar-http-linux storage-grid-linux -all-images: sensor-image sensor-controller-image gateway-controller-image gateway-http-transformer-image webhook-image calendar-image resource-image artifact-image nats-image kafka-image amqp-image mqtt-image gateway-processor-grpc-client-image calendar-grpc-image gateway-processor-http-client-image calendar-http-image storage-grid-image +all-images: sensor-image sensor-controller-image gateway-controller-image gateway-http-transformer-image webhook-image calendar-image resource-image artifact-image file-image nats-image kafka-image amqp-image mqtt-image gateway-processor-grpc-client-image calendar-grpc-image gateway-processor-http-client-image calendar-http-image storage-grid-image all-controller-images: sensor-controller-image gateway-controller-image -all-core-gateway-images: webhook-image calendar-image artifact-image nats-image kafka-image amqp-image mqtt-image resource-image +all-core-gateway-images: webhook-image calendar-image artifact-image file-image nats-image kafka-image amqp-image mqtt-image resource-image .PHONY: all clean test @@ -126,7 +126,6 @@ resource-image: resource-linux @if [ "$(DOCKER_PUSH)" = "true" ] ; then docker push $(IMAGE_PREFIX)resource-gateway:$(IMAGE_TAG) ; fi - artifact: CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -v -ldflags '${LDFLAGS}' -o ${DIST_DIR}/artifact-gateway ./gateways/core/artifact/ @@ -138,6 +137,18 @@ artifact-image: artifact-linux @if [ "$(DOCKER_PUSH)" = "true" ] ; then docker push $(IMAGE_PREFIX)artifact-gateway:$(IMAGE_TAG) ; fi +file: + CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -v -ldflags '${LDFLAGS}' -o ${DIST_DIR}/file-gateway ./gateways/core/file/ + +file-linux: + CGO_ENABLED=0 GOOS=linux GOARCH=amd64 make file + +file-image: file-linux + docker build -t $(IMAGE_PREFIX)file-gateway:$(IMAGE_TAG) -f ./gateways/core/file/Dockerfile . + @if [ "$(DOCKER_PUSH)" = "true" ] ; then docker push $(IMAGE_PREFIX)file-gateway:$(IMAGE_TAG) ; fi + + +#Stream gateways nats: CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -v -ldflags '${LDFLAGS}' -o ${DIST_DIR}/nats-gateway ./gateways/core/stream/nats/ diff --git a/cmd/controllers/gateway/transform/http/main.go b/cmd/controllers/gateway/transform/http/main.go index f18aa8589f..904a20c961 100644 --- a/cmd/controllers/gateway/transform/http/main.go +++ b/cmd/controllers/gateway/transform/http/main.go @@ -110,5 +110,6 @@ func main() { // endpoint to listen events http.HandleFunc("/", toc.TransformRequest) + http.HandleFunc("/readiness", toc.ReadinessProbe) log.Fatal(http.ListenAndServe(":"+fmt.Sprintf("%s", common.GatewayTransformerPort), nil)) } diff --git a/controllers/gateway/transform/transformer.go b/controllers/gateway/transform/transformer.go index 9ad1500b4e..1ea2ada5da 100644 --- a/controllers/gateway/transform/transformer.go +++ b/controllers/gateway/transform/transformer.go @@ -286,3 +286,8 @@ func (toc *tOperationCtx) TransformRequest(w http.ResponseWriter, r *http.Reques } common.SendSuccessResponse(w) } + +// ReadinessProbe is probe to check whether server is running or not +func (toc *tOperationCtx) ReadinessProbe(w http.ResponseWriter, r *http.Request) { + common.SendSuccessResponse(w) +} diff --git a/examples/gateways/file-gateway-configmap.yaml b/examples/gateways/file-gateway-configmap.yaml new file mode 100644 index 0000000000..b5f8acfeea --- /dev/null +++ b/examples/gateways/file-gateway-configmap.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: file-watcher-gateway-configmap +data: + fileWatcher.defaultConfig: |- + directory: "/bin/" + type: CREATE + path: x.txt diff --git a/examples/gateways/file.yaml b/examples/gateways/file.yaml new file mode 100644 index 0000000000..2341558798 --- /dev/null +++ b/examples/gateways/file.yaml @@ -0,0 +1,22 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Gateway +metadata: + name: file-watcher-gateway + labels: + gateways.argoproj.io/gateway-controller-instanceid: argo-events + gateway-name: "file-watcher-gateway" +spec: + deploySpec: + containers: + - name: "file-watcher-events" + image: "argoproj/file-watcher-gateway" + imagePullPolicy: "Always" + command: ["/bin/file-watcher-gateway"] + serviceAccountName: "argo-events-sa" + configMap: "file-watcher-gateway-configmap" + version: "1.0" + type: "file-watcher" + dispatchMechanism: "HTTP" + watchers: + sensors: + - name: "file-watcher-sensor" diff --git a/examples/gateways/storage-grid-configmap.yaml b/examples/gateways/storage-grid-configmap.yaml new file mode 100644 index 0000000000..0385204885 --- /dev/null +++ b/examples/gateways/storage-grid-configmap.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: storage-grid-gateway-configmap +data: + storage-grid.defaultConfig: |- + port: "8080" + endpoint: "/" + events: + - "ObjectCreated:Put" + filter: + suffix: ".txt" + prefix: "hello-" diff --git a/examples/gateways/storage-grid.yaml b/examples/gateways/storage-grid.yaml new file mode 100644 index 0000000000..04c4b33bc4 --- /dev/null +++ b/examples/gateways/storage-grid.yaml @@ -0,0 +1,28 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Gateway +metadata: + name: storage-grid-gateway + labels: + gateways.argoproj.io/gateway-controller-instanceid: argo-events + gateway-name: "storage-grid-gateway" +spec: + configMap: "storage-grid-gateway-configmap" + type: "storage-grid" + dispatchMechanism: "HTTP" + version: "1.0" + deploySpec: + containers: + - name: "storage-grid-events" + image: "argoproj/storage-grid-gateway" + imagePullPolicy: "Always" + serviceAccountName: "argo-events-sa" + serviceSpec: + selector: + gateway-name: "storage-grid-gateway" + ports: + - port: 8080 + targetPort: 8080 + type: LoadBalancer + watchers: + sensors: + - name: "storage-grid-watcher-sensor" diff --git a/examples/sensors/file.yaml b/examples/sensors/file.yaml new file mode 100644 index 0000000000..1b585fffb0 --- /dev/null +++ b/examples/sensors/file.yaml @@ -0,0 +1,35 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Sensor +metadata: + name: file-watcher-sensor + labels: + sensors.argoproj.io/sensor-controller-instanceid: argo-events +spec: + serviceAccountName: argo-events-sa + repeat: true + signals: + - name: file-watcher-gateway/fileWatcher.defaultConfig + triggers: + - name: file-watcher-workflow-trigger + resource: + namespace: argo-events + group: argoproj.io + version: v1alpha1 + kind: Workflow + source: + inline: | + apiVersion: argoproj.io/v1alpha1 + kind: Workflow + metadata: + generateName: file-watcher- + spec: + entrypoint: whalesay + templates: + - + container: + args: + - "hello world" + command: + - cowsay + image: "docker/whalesay:latest" + name: whalesay diff --git a/examples/sensors/storage-grid-sensor.yaml b/examples/sensors/storage-grid-sensor.yaml new file mode 100644 index 0000000000..56f2994f22 --- /dev/null +++ b/examples/sensors/storage-grid-sensor.yaml @@ -0,0 +1,38 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Sensor +metadata: + name: storage-grid-watcher-sensor + labels: + sensors.argoproj.io/sensor-controller-instanceid: argo-events +spec: + repeat: true + serviceAccountName: argo-events-sa + signals: + - name: storage-grid-gateway/storage-grid.defaultConfig + triggers: + - name: argo-workflow + resource: + namespace: argo-events + group: argoproj.io + version: v1alpha1 + kind: Workflow + parameters: + - src: + signal: storage-grid-gateway/storage-grid.defaultConfig + path: + value: hello world + dest: spec.templates.0.container.args.0 + source: + inline: | + apiVersion: argoproj.io/v1alpha1 + kind: Workflow + metadata: + generateName: hello-world- + spec: + entrypoint: whalesay + templates: + - name: whalesay + container: + args: + - "hello world" + image: "metalgearsolid/args-printer:latest" diff --git a/gateways/core/artifact/artifact.json b/gateways/core/artifact/artifact.json new file mode 100644 index 0000000000..c20c1f9172 --- /dev/null +++ b/gateways/core/artifact/artifact.json @@ -0,0 +1,61 @@ +{ + "swagger": "2.0", + "info": { + "title": "Integration Test", + "version": "1.0" + }, + "paths": {}, + "definitions": { + "argo-events.S3EventConfig": { + "description": "S3EventConfig contains configuration for bucket notification", + "properties": { + "bucket": { + "type": "string" + }, + "endpoint": { + "type": "string" + }, + "event": { + "type": "string" + }, + "filter": { + "$ref": "#/definitions/argo-events.S3Filter" + }, + "region": { + "type": "string" + } + } + }, + "argo-events.S3Filter": { + "description": "S3Filter represents filters to apply to bucket nofifications for specifying constraints on objects", + "required": [ + "prefix", + "suffix" + ], + "properties": { + "prefix": { + "type": "string" + }, + "suffix": { + "type": "string" + } + } + }, + "argo-events.s3Artifact": { + "description": "S3Artifact contains information about an artifact in S3", + "required": [ + "s3EventConfig" + ], + "properties": { + "insecure": { + "description": "Mode of operation for s3 client", + "type": "boolean" + }, + "s3EventConfig": { + "description": "S3EventConfig contains configuration for bucket notification", + "$ref": "#/definitions/argo-events.S3EventConfig" + } + } + } + } + } \ No newline at end of file diff --git a/gateways/core/artifact/s3.go b/gateways/core/artifact/s3.go index ae84eec337..8eace8d1d4 100644 --- a/gateways/core/artifact/s3.go +++ b/gateways/core/artifact/s3.go @@ -17,13 +17,11 @@ limitations under the License. package main import ( - "context" "encoding/json" "fmt" "github.com/argoproj/argo-events/common" "github.com/argoproj/argo-events/gateways" "github.com/argoproj/argo-events/pkg/apis/gateway/v1alpha1" - "github.com/ghodss/yaml" "github.com/minio/minio-go" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -40,35 +38,6 @@ var ( // s3ConfigExecutor implements ConfigExecutor interface type s3ConfigExecutor struct{} -// S3Artifact contains information about an artifact in S3 -type S3Artifact struct { - // S3EventConfig contains configuration for bucket notification - S3EventConfig S3EventConfig `json:"s3EventConfig"` - - // Mode of operation for s3 client - Insecure bool `json:"insecure,omitempty"` - - // AccessKey - AccessKey corev1.SecretKeySelector `json:"accessKey,omitempty"` - - // SecretKey - SecretKey corev1.SecretKeySelector `json:"secretKey,omitempty"` -} - -// S3EventConfig contains configuration for bucket notification -type S3EventConfig struct { - Endpoint string `json:"endpoint,omitempty"` - Bucket string `json:"bucket,omitempty"` - Region string `json:"region,omitempty"` - Event minio.NotificationEventType `json:"event,omitempty"` - Filter S3Filter `json:"filter,omitempty"` -} - -// S3Filter represents filters to apply to bucket nofifications for specifying constraints on objects -type S3Filter struct { - Prefix string `json:"prefix"` - Suffix string `json:"suffix"` -} // getSecrets retrieves the secret value from the secret in namespace with name and key func getSecrets(client kubernetes.Interface, namespace string, name, key string) (string, error) { @@ -103,16 +72,9 @@ func (s3ce *s3ConfigExecutor) StartConfig(config *gateways.ConfigContext) error // mark final gateway state defer gatewayConfig.GatewayCleanup(config, &errMessage, err) - gatewayConfig.Log.Info().Str("config-name", config.Data.Src).Msg("parsing configuration...") - - var artifact *S3Artifact - err = yaml.Unmarshal([]byte(config.Data.Config), &artifact) - if err != nil { - errMessage = "failed to parse configuration" - return err - } - - gatewayConfig.Log.Debug().Str("config-key", config.Data.Config).Interface("artifact", *artifact).Msg("s3 artifact") + gatewayConfig.Log.Info().Str("config-name", config.Data.Src).Msg("starting configuration...") + artifact := config.Data.Config.(*s3Artifact) + gatewayConfig.Log.Debug().Str("config-key", config.Data.Src).Interface("config-value", *artifact).Msg("artifact configuration") // retrieve access key id and secret access key accessKey, err := getSecrets(gatewayConfig.Clientset, gatewayConfig.Namespace, artifact.AccessKey.Name, artifact.AccessKey.Key) @@ -197,14 +159,33 @@ func (s3ce *s3ConfigExecutor) StopConfig(config *gateways.ConfigContext) error { return nil } -func main() { - _, err := gatewayConfig.WatchGatewayEvents(context.Background()) - if err != nil { - gatewayConfig.Log.Panic().Err(err).Msg("failed to watch k8 events for gateway configuration state updates") +// Validate validates s3 configuration +func(s3ce *s3ConfigExecutor) Validate(config *gateways.ConfigContext) error { + artifact, ok := config.Data.Config.(*s3Artifact) + if !ok { + return gateways.ErrConfigParseFailed } - _, err = gatewayConfig.WatchGatewayConfigMap(context.Background(), &s3ConfigExecutor{}) - if err != nil { - gatewayConfig.Log.Panic().Err(err).Msg("failed to watch gateway configuration updates") + if artifact.AccessKey != nil { + return fmt.Errorf("access key can't be empty") + } + if artifact.SecretKey != nil { + return fmt.Errorf("secret key can't be empty") + } + if artifact.S3EventConfig != nil { + return fmt.Errorf("s3 event configuration can't be empty") + } + if artifact.S3EventConfig.Endpoint == "" { + return fmt.Errorf("endpoint url can't be empty") } - select {} + if artifact.S3EventConfig.Bucket == "" { + return fmt.Errorf("bucket name can't be empty") + } + if artifact.S3EventConfig.Event != "" && minio.NotificationEventType(artifact.S3EventConfig.Event) == "" { + return fmt.Errorf("unknown event %s", artifact.S3EventConfig.Event) + } + return nil +} + +func main() { + gatewayConfig.StartGateway(&s3ConfigExecutor{}) } diff --git a/gateways/core/artifact/types.go b/gateways/core/artifact/types.go new file mode 100644 index 0000000000..90dce29ad6 --- /dev/null +++ b/gateways/core/artifact/types.go @@ -0,0 +1,40 @@ +package main + +import ( + "github.com/minio/minio-go" + corev1 "k8s.io/api/core/v1" +) + +// S3Artifact contains information about an artifact in S3 +// +k8s:openapi-gen=true +type s3Artifact struct { + // S3EventConfig contains configuration for bucket notification + S3EventConfig *S3EventConfig `json:"s3EventConfig"` + + // Mode of operation for s3 client + Insecure bool `json:"insecure,omitempty"` + + // AccessKey + AccessKey *corev1.SecretKeySelector `json:"accessKey,omitempty"` + + // SecretKey + SecretKey *corev1.SecretKeySelector `json:"secretKey,omitempty"` +} + +// S3EventConfig contains configuration for bucket notification +// +k8s:openapi-gen=true +type S3EventConfig struct { + Endpoint string `json:"endpoint,omitempty"` + Bucket string `json:"bucket,omitempty"` + Region string `json:"region,omitempty"` + Event minio.NotificationEventType `json:"event,omitempty"` + Filter S3Filter `json:"filter,omitempty"` +} + +// S3Filter represents filters to apply to bucket nofifications for specifying constraints on objects +// +k8s:openapi-gen=true +type S3Filter struct { + Prefix string `json:"prefix"` + Suffix string `json:"suffix"` +} + diff --git a/gateways/core/calendar/calendar.go b/gateways/core/calendar/calendar.go index f552f9b524..11fdd0a456 100644 --- a/gateways/core/calendar/calendar.go +++ b/gateways/core/calendar/calendar.go @@ -17,12 +17,10 @@ limitations under the License. package main import ( - "context" "fmt" "github.com/argoproj/argo-events/common" "github.com/argoproj/argo-events/gateways" "github.com/argoproj/argo-events/pkg/apis/gateway/v1alpha1" - "github.com/ghodss/yaml" cronlib "github.com/robfig/cron" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "time" @@ -39,24 +37,6 @@ type Next func(time.Time) time.Time // calendarConfigExecutor implements ConfigExecutor interface type calendarConfigExecutor struct{} -// calSchedule describes a time based dependency. One of the fields (schedule, interval, or recurrence) must be passed. -// Schedule takes precedence over interval; interval takes precedence over recurrence -type calSchedule struct { - // Schedule is a cron-like expression. For reference, see: https://en.wikipedia.org/wiki/Cron - Schedule string `json:"schedule"` - - // Interval is a string that describes an interval duration, e.g. 1s, 30m, 2h... - Interval string `json:"interval"` - - // List of RRULE, RDATE and EXDATE lines for a recurring event, as specified in RFC5545. - // RRULE is a recurrence rule which defines a repeating pattern for recurring events. - // RDATE defines the list of DATE-TIME values for recurring events. - // EXDATE defines the list of DATE-TIME exceptions for recurring events. - // the combination of these rules and dates combine to form a set of date times. - // NOTE: functionality currently only supports EXDATEs, but in the future could be expanded. - Recurrence []string `json:"recurrence,omitempty"` -} - // StartConfig runs a configuration func (ce *calendarConfigExecutor) StartConfig(config *gateways.ConfigContext) error { var err error @@ -66,13 +46,8 @@ func (ce *calendarConfigExecutor) StartConfig(config *gateways.ConfigContext) er defer gatewayConfig.GatewayCleanup(config, &errMessage, err) gatewayConfig.Log.Info().Str("config-name", config.Data.Src).Msg("parsing configuration...") - - var cal *calSchedule - err = yaml.Unmarshal([]byte(config.Data.Config), &cal) - if err != nil { - errMessage = "failed to parse configuration" - return err - } + cal := config.Data.Config.(*calSchedule) + gatewayConfig.Log.Debug().Str("config-key", config.Data.Src).Interface("config-value", *cal).Msg("calendar configuration") schedule, err := resolveSchedule(cal) if err != nil { @@ -151,6 +126,18 @@ func (ce *calendarConfigExecutor) StopConfig(config *gateways.ConfigContext) err return nil } +// Validate validates gateway configuration +func (ce *calendarConfigExecutor) Validate(config *gateways.ConfigContext) error { + cal, ok := config.Data.Config.(*calSchedule) + if !ok { + return gateways.ErrConfigParseFailed + } + if cal.Schedule == "" && cal.Interval == "" { + return fmt.Errorf("%+v, must have either schedule or interval", gateways.ErrInvalidConfig) + } + return nil +} + func resolveSchedule(cal *calSchedule) (cronlib.Schedule, error) { if cal.Schedule != "" { // standard cron expression @@ -173,13 +160,5 @@ func resolveSchedule(cal *calSchedule) (cronlib.Schedule, error) { } func main() { - _, err := gatewayConfig.WatchGatewayEvents(context.Background()) - if err != nil { - gatewayConfig.Log.Panic().Err(err).Msg("failed to watch k8 events for gateway configuration state updates") - } - _, err = gatewayConfig.WatchGatewayConfigMap(context.Background(), &calendarConfigExecutor{}) - if err != nil { - gatewayConfig.Log.Panic().Err(err).Msg("failed to watch gateway configuration updates") - } - select {} + gatewayConfig.StartGateway(&calendarConfigExecutor{}) } diff --git a/gateways/core/calendar/types.go b/gateways/core/calendar/types.go new file mode 100644 index 0000000000..033de0b91f --- /dev/null +++ b/gateways/core/calendar/types.go @@ -0,0 +1,20 @@ +package main + +// calSchedule describes a time based dependency. One of the fields (schedule, interval, or recurrence) must be passed. +// Schedule takes precedence over interval; interval takes precedence over recurrence +// +k8s:openapi-gen=true +type calSchedule struct { + // Schedule is a cron-like expression. For reference, see: https://en.wikipedia.org/wiki/Cron + Schedule string `json:"schedule"` + + // Interval is a string that describes an interval duration, e.g. 1s, 30m, 2h... + Interval string `json:"interval"` + + // List of RRULE, RDATE and EXDATE lines for a recurring event, as specified in RFC5545. + // RRULE is a recurrence rule which defines a repeating pattern for recurring events. + // RDATE defines the list of DATE-TIME values for recurring events. + // EXDATE defines the list of DATE-TIME exceptions for recurring events. + // the combination of these rules and dates combine to form a set of date times. + // NOTE: functionality currently only supports EXDATEs, but in the future could be expanded. + Recurrence []string `json:"recurrence,omitempty"` +} diff --git a/gateways/core/file/Dockerfile b/gateways/core/file/Dockerfile new file mode 100644 index 0000000000..7b81174045 --- /dev/null +++ b/gateways/core/file/Dockerfile @@ -0,0 +1,3 @@ +FROM centos:7 +COPY dist/file-gateway /bin/ +ENTRYPOINT [ "/bin/file-gateway" ] \ No newline at end of file diff --git a/gateways/core/file/file.go b/gateways/core/file/file.go new file mode 100644 index 0000000000..9d5cdb8120 --- /dev/null +++ b/gateways/core/file/file.go @@ -0,0 +1,136 @@ +package main + +import ( + "bytes" + "encoding/gob" + "fmt" + "github.com/argoproj/argo-events/common" + "github.com/argoproj/argo-events/gateways" + "github.com/argoproj/argo-events/pkg/apis/gateway/v1alpha1" + "github.com/fsnotify/fsnotify" + "strings" +) + +var ( + // gatewayConfig provides a generic configuration for a gateway + gatewayConfig = gateways.NewGatewayConfiguration() +) + +// fileWatcherConfigExecutor implements ConfigExecutor interface +type fileWatcherConfigExecutor struct{} + +// StartConfig runs a configuration +func (fw *fileWatcherConfigExecutor) StartConfig(config *gateways.ConfigContext) error { + var err error + var errMessage string + // mark final gateway state + defer gatewayConfig.GatewayCleanup(config, &errMessage, err) + + gatewayConfig.Log.Info().Str("config-key", config.Data.Src).Msg("operating on configuration...") + fwc := config.Data.Config.(*fileWatcherConfig) + gatewayConfig.Log.Debug().Str("config-key", config.Data.Src).Interface("config-value", *fwc).Msg("file configuration") + + // create new fs watcher + watcher, err := fsnotify.NewWatcher() + if err != nil { + errMessage = "failed to create new file system watcher" + return err + } + defer watcher.Close() + + // file descriptor to watch must be available in file system. You can't watch an fs descriptor that is not present. + err = watcher.Add(fwc.Directory) + if err != nil { + errMessage = fmt.Sprintf("failed to add path %s to fs watcher", fwc.Path) + return err + } + + gatewayConfig.Log.Info().Str("config-name", config.Data.Src).Msg("configuration is running...") + config.Active = true + + event := gatewayConfig.GetK8Event("configuration running", v1alpha1.NodePhaseRunning, config.Data) + _, err = common.CreateK8Event(event, gatewayConfig.Clientset) + if err != nil { + gatewayConfig.Log.Error().Str("config-key", config.Data.Src).Err(err).Msg("failed to mark configuration as running") + return err + } + gatewayConfig.Log.Info().Str("config-key", config.Data.Src).Msg("k8 event created marking configuration as running") + + // start listening fs notifications +NotificationListener: + for { + select { + case event, ok := <-watcher.Events: + if !ok { + gatewayConfig.Log.Info().Str("config-key", config.Data.Src).Msg("fs watcher has stopped") + config.Active = false + break NotificationListener + } + // fwc.Path == event.Name is required because we don't want to send event when .swp files are created + if fwc.Path == strings.TrimPrefix(event.Name, fwc.Directory) && fwc.Type == event.Op.String() { + gatewayConfig.Log.Debug().Str("config-key", config.Data.Src).Str("event-type", event.Op.String()).Str("descriptor-name", event.Name).Msg("fs event") + var buff bytes.Buffer + enc := gob.NewEncoder(&buff) + err := enc.Encode(event) + if err != nil { + gatewayConfig.Log.Error().Err(err).Str("config-key", config.Data.Src).Msg("failed to encode fs event") + errMessage = "failed to encode fs event" + config.Active = false + break NotificationListener + } else { + gatewayConfig.Log.Info().Str("config-key", config.Data.Src).Msg("dispatching event to gateway-processor") + gatewayConfig.DispatchEvent(&gateways.GatewayEvent{ + Src: config.Data.Src, + Payload: buff.Bytes(), + }) + } + } + case e, ok := <-watcher.Errors: + if !ok { + gatewayConfig.Log.Info().Str("config-key", config.Data.Src).Msg("fs watcher has stopped") + config.Active = false + break NotificationListener + } + err = e + errMessage = "error occurred in fs watcher" + config.Active = false + break NotificationListener + case <-config.StopCh: + gatewayConfig.Log.Info().Str("config-key", config.Data.Src).Msg("stopping the configuration...") + config.Active = false + break NotificationListener + } + } + gatewayConfig.Log.Info().Str("config-key", config.Data.Src).Msg("configuration is now stopped.") + return nil +} + +// StopConfig deactivates a configuration +func (fw *fileWatcherConfigExecutor) StopConfig(config *gateways.ConfigContext) error { + if config.Active == true { + config.StopCh <- struct{}{} + } + return nil +} + +// Validate validates gateway configuration +func (fw *fileWatcherConfigExecutor) Validate(config *gateways.ConfigContext) error { + fwc, ok := config.Data.Config.(*fileWatcherConfig) + if !ok { + return gateways.ErrConfigParseFailed + } + if fwc.Type == "" { + return fmt.Errorf("%+v, type must be specified", gateways.ErrInvalidConfig) + } + if fwc.Directory == "" { + return fmt.Errorf("%+v, directory must be specified", gateways.ErrInvalidConfig) + } + if fwc.Path == "" { + return fmt.Errorf("%+v, path must be specified", gateways.ErrInvalidConfig) + } + return nil +} + +func main() { + gatewayConfig.StartGateway(&fileWatcherConfigExecutor{}) +} diff --git a/gateways/core/file/types.go b/gateways/core/file/types.go new file mode 100644 index 0000000000..140ffd60c5 --- /dev/null +++ b/gateways/core/file/types.go @@ -0,0 +1,13 @@ +package main + +// fileWatcherConfig contains configuration information for this gateway +// +k8s:openapi-gen=true +type fileWatcherConfig struct { + // Directory to watch for events + Directory string + // Path is relative path of object to watch with respect to the directory + Path string + // Type of file operations to watch + // Refer https://github.com/fsnotify/fsnotify/blob/master/fsnotify.go for more information + Type string +} diff --git a/gateways/core/resource/resource.go b/gateways/core/resource/resource.go index ac49c09179..ca6496fcbb 100644 --- a/gateways/core/resource/resource.go +++ b/gateways/core/resource/resource.go @@ -17,11 +17,9 @@ limitations under the License. package main import ( - "context" "github.com/argoproj/argo-events/common" "github.com/argoproj/argo-events/gateways" "github.com/argoproj/argo-events/pkg/apis/gateway/v1alpha1" - "github.com/ghodss/yaml" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -32,6 +30,7 @@ import ( "k8s.io/client-go/dynamic" "strings" "sync" + "fmt" ) var ( @@ -42,21 +41,6 @@ var ( // resourceConfigExecutor implements ConfigExecutor interface type resourceConfigExecutor struct{} -// Resource refers to a dependency on a k8s resource. -type Resource struct { - Namespace string `json:"namespace"` - Filter *ResourceFilter `json:"filter,omitempty"` - metav1.GroupVersionKind `json:",inline"` -} - -// ResourceFilter contains K8 ObjectMeta information to further filter resource signal objects -type ResourceFilter struct { - Prefix string `json:"prefix,omitempty"` - Labels map[string]string `json:"labels,omitempty"` - Annotations map[string]string `json:"annotations,omitempty"` - CreatedBy metav1.Time `json:"createdBy,omitempty"` -} - // StartConfig runs a configuration func (rce *resourceConfigExecutor) StartConfig(config *gateways.ConfigContext) error { var err error @@ -65,14 +49,10 @@ func (rce *resourceConfigExecutor) StartConfig(config *gateways.ConfigContext) e // mark final gateway state defer gatewayConfig.GatewayCleanup(config, &errMessage, err) - gatewayConfig.Log.Info().Str("config-key", config.Data.Src).Msg("parsing configuration...") + gatewayConfig.Log.Info().Str("config-key", config.Data.Src).Msg("operating on configuration...") + res := config.Data.Config.(*resource) + gatewayConfig.Log.Debug().Str("config-key", config.Data.Src).Interface("config-value", *res).Msg("resource configuration") - var res *Resource - err = yaml.Unmarshal([]byte(config.Data.Config), &res) - if err != nil { - errMessage = "failed to parse resource configuration" - return err - } resources, err := discoverResources(res) if err != nil { errMessage = "failed to discover resource" @@ -146,7 +126,28 @@ func (rce *resourceConfigExecutor) StopConfig(config *gateways.ConfigContext) er return nil } -func discoverResources(obj *Resource) ([]dynamic.ResourceInterface, error) { +// Validate validates gateway configuration +func (rce *resourceConfigExecutor) Validate(config *gateways.ConfigContext) error { + res, ok := config.Data.Config.(*resource) + if !ok { + return gateways.ErrConfigParseFailed + } + if res.Version == "" { + return fmt.Errorf("%+v, resource version must be specified", gateways.ErrInvalidConfig) + } + if res.Namespace == "" { + return fmt.Errorf("%+v, resource namespace must be specified", gateways.ErrInvalidConfig) + } + if res.Kind == "" { + return fmt.Errorf("%+v, resource kind must be specified", gateways.ErrInvalidConfig) + } + if res.Group == "" { + return fmt.Errorf("%+v, resource group must be specified", gateways.ErrInvalidConfig) + } + return nil +} + +func discoverResources(obj *resource) ([]dynamic.ResourceInterface, error) { dynClientPool := dynamic.NewDynamicClientPool(gatewayConfig.KubeConfig) disco, err := discovery.NewDiscoveryClientForConfig(gatewayConfig.KubeConfig) if err != nil { @@ -184,7 +185,7 @@ func discoverResources(obj *Resource) ([]dynamic.ResourceInterface, error) { return resources, nil } -func resolveGroupVersion(obj *Resource) string { +func resolveGroupVersion(obj *resource) string { if obj.Version == "v1" { return obj.Version } @@ -234,13 +235,5 @@ func checkMap(expected, actual map[string]string) bool { } func main() { - _, err := gatewayConfig.WatchGatewayEvents(context.Background()) - if err != nil { - gatewayConfig.Log.Panic().Err(err).Msg("failed to watch k8 events for gateway configuration state updates") - } - _, err = gatewayConfig.WatchGatewayConfigMap(context.Background(), &resourceConfigExecutor{}) - if err != nil { - gatewayConfig.Log.Panic().Err(err).Msg("failed to watch gateway configuration updates") - } - select {} + gatewayConfig.StartGateway(&resourceConfigExecutor{}) } diff --git a/gateways/core/resource/types.go b/gateways/core/resource/types.go new file mode 100644 index 0000000000..9fab3dfb29 --- /dev/null +++ b/gateways/core/resource/types.go @@ -0,0 +1,21 @@ +package main + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// Resource refers to a dependency on a k8s resource. +// +k8s:openapi-gen=true +type resource struct { + Namespace string `json:"namespace"` + Filter *ResourceFilter `json:"filter,omitempty"` + metav1.GroupVersionKind `json:",inline"` +} + +// ResourceFilter contains K8 ObjectMeta information to further filter resource signal objects +type ResourceFilter struct { + Prefix string `json:"prefix,omitempty"` + Labels map[string]string `json:"labels,omitempty"` + Annotations map[string]string `json:"annotations,omitempty"` + CreatedBy metav1.Time `json:"createdBy,omitempty"` +} diff --git a/gateways/core/stream/amqp/amqp.go b/gateways/core/stream/amqp/amqp.go index d5f6729506..3785970ac6 100644 --- a/gateways/core/stream/amqp/amqp.go +++ b/gateways/core/stream/amqp/amqp.go @@ -19,21 +19,12 @@ package main import ( "fmt" - "context" "github.com/argoproj/argo-events/common" "github.com/argoproj/argo-events/gateways" - "github.com/argoproj/argo-events/gateways/core/stream" "github.com/argoproj/argo-events/pkg/apis/gateway/v1alpha1" - "github.com/ghodss/yaml" amqplib "github.com/streadway/amqp" ) -const ( - exchangeNameKey = "exchangeName" - exchangeTypeKey = "exchangeType" - routingKey = "routingKey" -) - var ( // gatewayConfig provides a generic configuration for a gateway gatewayConfig = gateways.NewGatewayConfiguration() @@ -50,16 +41,11 @@ func (ace *amqpConfigExecutor) StartConfig(config *gateways.ConfigContext) error // mark final gateway state defer gatewayConfig.GatewayCleanup(config, &errMessage, err) - gatewayConfig.Log.Info().Str("config-key", config.Data.Src).Msg("parsing configuration...") + gatewayConfig.Log.Info().Str("config-key", config.Data.Src).Msg("operating on configuration...") + amqpConfig := config.Data.Config.(*amqp) + gatewayConfig.Log.Info().Str("config-key", config.Data.Src).Interface("config-value", *amqpConfig).Msg("amqp configuration") - var s *stream.Stream - err = yaml.Unmarshal([]byte(config.Data.Config), &s) - if err != nil { - errMessage = "failed to parse amqp config" - return err - } - - conn, err := amqplib.Dial(s.URL) + conn, err := amqplib.Dial(amqpConfig.URL) if err != nil { errMessage = "failed to connect to server" return err @@ -71,7 +57,7 @@ func (ace *amqpConfigExecutor) StartConfig(config *gateways.ConfigContext) error return err } - delivery, err := getDelivery(ch, s.Attributes) + delivery, err := getDelivery(ch, amqpConfig) if err != nil { errMessage = "failed to get message delivery" return err @@ -113,32 +99,31 @@ func (ace *amqpConfigExecutor) StopConfig(config *gateways.ConfigContext) error return nil } -func parseAttributes(attr map[string]string) (string, string, string, error) { - // parse out the attributes - exchangeName, ok := attr[exchangeNameKey] +// Validate validates gateway configuration +func (ace *amqpConfigExecutor) Validate(config *gateways.ConfigContext) error { + amqpConfig, ok := config.Data.Config.(*amqp) if !ok { - return "", "", "", fmt.Errorf("exchange name key is not provided") + return gateways.ErrConfigParseFailed } - exchangeType, ok := attr[exchangeTypeKey] - if !ok { - return exchangeName, "", "", fmt.Errorf("exchange type is not provided") + if amqpConfig.URL == "" { + return fmt.Errorf("%+v, url must be specified", gateways.ErrInvalidConfig) } - routingKey, ok := attr[routingKey] - if !ok { - return exchangeName, exchangeType, "", fmt.Errorf("routing key is not provided") + if amqpConfig.RoutingKey == "" { + return fmt.Errorf("%+v, routing key must be specified", gateways.ErrInvalidConfig) } - return exchangeName, exchangeType, routingKey, nil -} - -func getDelivery(ch *amqplib.Channel, attr map[string]string) (<-chan amqplib.Delivery, error) { - exName, exType, rKey, err := parseAttributes(attr) - if err != nil { - return nil, err + if amqpConfig.ExchangeName == "" { + return fmt.Errorf("%+v, exchange name must be specified", gateways.ErrInvalidConfig) + } + if amqpConfig.ExchangeType == "" { + return fmt.Errorf("%+v, exchange type must be specified", gateways.ErrInvalidConfig) } + return nil +} - err = ch.ExchangeDeclare(exName, exType, true, false, false, false, nil) +func getDelivery(ch *amqplib.Channel, config *amqp) (<-chan amqplib.Delivery, error) { + err := ch.ExchangeDeclare(config.ExchangeName, config.ExchangeType, true, false, false, false, nil) if err != nil { - return nil, fmt.Errorf("failed to declare %s exchange '%s': %s", exType, exName, err) + return nil, fmt.Errorf("failed to declare exchange with name %s and type %s. err: %+v", config.ExchangeName, config.ExchangeType, err) } q, err := ch.QueueDeclare("", false, false, true, false, nil) @@ -146,9 +131,9 @@ func getDelivery(ch *amqplib.Channel, attr map[string]string) (<-chan amqplib.De return nil, fmt.Errorf("failed to declare queue: %s", err) } - err = ch.QueueBind(q.Name, rKey, exName, false, nil) + err = ch.QueueBind(q.Name, config.RoutingKey, config.ExchangeName, false, nil) if err != nil { - return nil, fmt.Errorf("failed to bind %s exchange '%s' to queue with routingKey: %s: %s", exType, exName, rKey, err) + return nil, fmt.Errorf("failed to bind %s exchange '%s' to queue with routingKey: %s: %s", config.ExchangeType, config.ExchangeName, config.RoutingKey, err) } delivery, err := ch.Consume(q.Name, "", true, false, false, false, nil) @@ -159,13 +144,5 @@ func getDelivery(ch *amqplib.Channel, attr map[string]string) (<-chan amqplib.De } func main() { - _, err := gatewayConfig.WatchGatewayEvents(context.Background()) - if err != nil { - gatewayConfig.Log.Panic().Err(err).Msg("failed to watch k8 events for gateway configuration state updates") - } - _, err = gatewayConfig.WatchGatewayConfigMap(context.Background(), &amqpConfigExecutor{}) - if err != nil { - gatewayConfig.Log.Panic().Err(err).Msg("failed to watch gateway configuration updates") - } - select {} + gatewayConfig.StartGateway(&amqpConfigExecutor{}) } diff --git a/gateways/core/stream/amqp/types.go b/gateways/core/stream/amqp/types.go new file mode 100644 index 0000000000..fd570d6931 --- /dev/null +++ b/gateways/core/stream/amqp/types.go @@ -0,0 +1,18 @@ +package main + +// amqp contains configuration required to connect to rabbitmq service and process messages +// +k8s:openapi-gen=true +type amqp struct { + // URL for rabbitmq service + URL string `json:"url"` + + // ExchangeName is the exchange name + // For more information, visit https://www.rabbitmq.com/tutorials/amqp-concepts.html + ExchangeName string `json:"exchangeName"` + + // ExchangeType is rabbitmq exchange type + ExchangeType string `json:"exchangeType"` + + // Routing key for bindings + RoutingKey string `json:"routingKey"` +} diff --git a/gateways/core/stream/kafka/kafka.go b/gateways/core/stream/kafka/kafka.go index 0da8a5bbd5..902038114d 100644 --- a/gateways/core/stream/kafka/kafka.go +++ b/gateways/core/stream/kafka/kafka.go @@ -17,19 +17,12 @@ limitations under the License. package main import ( - "context" "github.com/Shopify/sarama" "github.com/argoproj/argo-events/common" "github.com/argoproj/argo-events/gateways" - "github.com/argoproj/argo-events/gateways/core/stream" "github.com/argoproj/argo-events/pkg/apis/gateway/v1alpha1" - "github.com/ghodss/yaml" "strconv" -) - -const ( - topicKey = "topic" - partitionKey = "partition" + "fmt" ) var ( @@ -48,29 +41,24 @@ func (kce *kafkaConfigExecutor) StartConfig(config *gateways.ConfigContext) erro // mark final gateway state defer gatewayConfig.GatewayCleanup(config, &errMessage, err) - var s *stream.Stream - err = yaml.Unmarshal([]byte(config.Data.Config), &s) - if err != nil { - errMessage = "failed to parse kafka config" - return err - } - gatewayConfig.Log.Info().Str("config-key", config.Data.Src).Interface("stream", *s).Msg("kafka configuration") - consumer, err := sarama.NewConsumer([]string{s.URL}, nil) + gatewayConfig.Log.Info().Str("config-key", config.Data.Src).Msg("operating on configuration...") + kafkaConfig := config.Data.Config.(*kafka) + gatewayConfig.Log.Info().Str("config-key", config.Data.Src).Interface("config-value", *kafkaConfig).Msg("kafka configuration") + + consumer, err := sarama.NewConsumer([]string{kafkaConfig.URL}, nil) if err != nil { errMessage = "failed to connect to cluster" return err } - topic := s.Attributes[topicKey] - pString := s.Attributes[partitionKey] - pInt, err := strconv.ParseInt(pString, 10, 32) + pInt, err := strconv.ParseInt(kafkaConfig.Partition, 10, 32) if err != nil { return err } partition := int32(pInt) - availablePartitions, err := consumer.Partitions(topic) + availablePartitions, err := consumer.Partitions(kafkaConfig.Topic) if err != nil { errMessage = "unable to get available partitions for kafka topic" return err @@ -80,7 +68,7 @@ func (kce *kafkaConfigExecutor) StartConfig(config *gateways.ConfigContext) erro return err } - partitionConsumer, err := consumer.ConsumePartition(topic, partition, sarama.OffsetNewest) + partitionConsumer, err := consumer.ConsumePartition(kafkaConfig.Topic, partition, sarama.OffsetNewest) if err != nil { errMessage = "failed to create partition consumer for topic" return err @@ -107,7 +95,7 @@ kafkaConfigRunner: Payload: msg.Value, }) case err := <-partitionConsumer.Errors(): - gatewayConfig.Log.Error().Str("config-key", config.Data.Src).Str("partition", pString).Str("topic", topic).Err(err).Msg("received an error") + gatewayConfig.Log.Error().Str("config-key", config.Data.Src).Str("partition", kafkaConfig.Partition).Str("topic", kafkaConfig.Topic).Err(err).Msg("received an error") config.StopCh <- struct{}{} case <-config.StopCh: err = partitionConsumer.Close() @@ -129,6 +117,24 @@ func (kce *kafkaConfigExecutor) StopConfig(config *gateways.ConfigContext) error return nil } +// Validate validates the gateway configuration +func (kce *kafkaConfigExecutor) Validate(config *gateways.ConfigContext) error { + kafkaConfig, ok := config.Data.Config.(*kafka) + if !ok { + return gateways.ErrConfigParseFailed + } + if kafkaConfig.URL == "" { + return fmt.Errorf("%+v, url must be specified", gateways.ErrInvalidConfig) + } + if kafkaConfig.Topic == "" { + return fmt.Errorf("%+v, topic must be specified", gateways.ErrInvalidConfig) + } + if kafkaConfig.Partition == "" { + return fmt.Errorf("%+v, partition must be specified", gateways.ErrInvalidConfig) + } + return nil +} + func verifyPartitionAvailable(part int32, partitions []int32) bool { for _, p := range partitions { if part == p { @@ -139,13 +145,5 @@ func verifyPartitionAvailable(part int32, partitions []int32) bool { } func main() { - _, err := gatewayConfig.WatchGatewayEvents(context.Background()) - if err != nil { - gatewayConfig.Log.Panic().Err(err).Msg("failed to watch k8 events for gateway configuration state updates") - } - _, err = gatewayConfig.WatchGatewayConfigMap(context.Background(), &kafkaConfigExecutor{}) - if err != nil { - gatewayConfig.Log.Panic().Err(err).Msg("failed to watch gateway configuration updates") - } - select {} + gatewayConfig.StartGateway(&kafkaConfigExecutor{}) } diff --git a/gateways/core/stream/kafka/types.go b/gateways/core/stream/kafka/types.go new file mode 100644 index 0000000000..926a02140e --- /dev/null +++ b/gateways/core/stream/kafka/types.go @@ -0,0 +1,14 @@ +package main + +// kafka defines configuration required to connect to kafka cluster +// +k8s:openapi-gen=true +type kafka struct { + // URL to kafka cluster + URL string `json:"url"` + + // Partition name + Partition string `json:"partition"` + + // Topic name + Topic string `json:"topic"` +} diff --git a/gateways/core/stream/mqtt/mqtt.go b/gateways/core/stream/mqtt/mqtt.go index 4e6da4e552..a4f69f9c6c 100644 --- a/gateways/core/stream/mqtt/mqtt.go +++ b/gateways/core/stream/mqtt/mqtt.go @@ -14,23 +14,15 @@ See the License for the specific language governing permissions and limitations under the License. */ -package mqtt +package main import ( - "context" - "fmt" "github.com/argoproj/argo-events/common" "github.com/argoproj/argo-events/gateways" - "github.com/argoproj/argo-events/gateways/core/stream" "github.com/argoproj/argo-events/pkg/apis/gateway/v1alpha1" MQTTlib "github.com/eclipse/paho.mqtt.golang" - "github.com/ghodss/yaml" "sync" -) - -const ( - topicKey = "topic" - clientID = "clientID" + "fmt" ) var ( @@ -49,7 +41,10 @@ func (mce *mqttConfigExecutor) StartConfig(config *gateways.ConfigContext) error // mark final gateway state defer gatewayConfig.GatewayCleanup(config, &errMessage, err) - gatewayConfig.Log.Info().Str("config-key", config.Data.Src).Msg("parsing configuration...") + gatewayConfig.Log.Info().Str("config-key", config.Data.Src).Msg("operating on configuration...") + mqttConfig := config.Data.Config.(*mqtt) + gatewayConfig.Log.Info().Str("config-key", config.Data.Src).Interface("config-value", *mqttConfig).Msg("mqtt configuration") + var wg sync.WaitGroup wg.Add(1) @@ -61,35 +56,13 @@ func (mce *mqttConfigExecutor) StartConfig(config *gateways.ConfigContext) error wg.Done() }() - var s *stream.Stream - err = yaml.Unmarshal([]byte(config.Data.Config), &s) - if err != nil { - errMessage = "failed to parse mqtt config" - config.StopCh <- struct{}{} - return err - } - // parse out the attributes - topic, ok := s.Attributes[topicKey] - if !ok { - errMessage = "failed to get topic key" - err = fmt.Errorf(errMessage) - return err - } - - clientID, ok := s.Attributes[clientID] - if !ok { - errMessage = "failed to get client id" - err = fmt.Errorf(errMessage) - return err - } - handler := func(c MQTTlib.Client, msg MQTTlib.Message) { gatewayConfig.DispatchEvent(&gateways.GatewayEvent{ Src: config.Data.Src, Payload: msg.Payload(), }) } - opts := MQTTlib.NewClientOptions().AddBroker(s.URL).SetClientID(clientID) + opts := MQTTlib.NewClientOptions().AddBroker(mqttConfig.URL).SetClientID(mqttConfig.ClientId) client := MQTTlib.NewClient(opts) if token := client.Connect(); token.Wait() && token.Error() != nil { errMessage = "failed to connect to client" @@ -97,7 +70,7 @@ func (mce *mqttConfigExecutor) StartConfig(config *gateways.ConfigContext) error err = token.Error() return err } - if token := client.Subscribe(topic, 0, handler); token.Wait() && token.Error() != nil { + if token := client.Subscribe(mqttConfig.Topic, 0, handler); token.Wait() && token.Error() != nil { errMessage = "failed to subscribe to topic" err = token.Error() return err @@ -125,14 +98,24 @@ func (mce *mqttConfigExecutor) StopConfig(config *gateways.ConfigContext) error return nil } -func main() { - _, err := gatewayConfig.WatchGatewayEvents(context.Background()) - if err != nil { - gatewayConfig.Log.Panic().Err(err).Msg("failed to watch k8 events for gateway configuration state updates") +// Validate validates gateway configuration +func (mce *mqttConfigExecutor) Validate(config *gateways.ConfigContext) error { + mqttConfig, ok := config.Data.Config.(*mqtt) + if !ok { + return gateways.ErrConfigParseFailed } - _, err = gatewayConfig.WatchGatewayConfigMap(context.Background(), &mqttConfigExecutor{}) - if err != nil { - gatewayConfig.Log.Panic().Err(err).Msg("failed to watch gateway configuration updates") + if mqttConfig.URL == "" { + return fmt.Errorf("%+v, url must be specified", gateways.ErrInvalidConfig) } - select {} + if mqttConfig.Topic == "" { + return fmt.Errorf("%+v, topic must be specified", gateways.ErrInvalidConfig) + } + if mqttConfig.ClientId == "" { + return fmt.Errorf("%+v, client id must be specified", gateways.ErrInvalidConfig) + } + return nil +} + +func main() { + gatewayConfig.StartGateway(&mqttConfigExecutor{}) } diff --git a/gateways/core/stream/mqtt/types.go b/gateways/core/stream/mqtt/types.go new file mode 100644 index 0000000000..68a2ce1a54 --- /dev/null +++ b/gateways/core/stream/mqtt/types.go @@ -0,0 +1,14 @@ +package main + +// mqtt contains information to connect to MQTT broker +// +k8s:openapi-gen=true +type mqtt struct { + // URL to connect to broker + URL string `json:"url"` + + // Topic name + Topic string `json:"topic"` + + // Client ID + ClientId string +} diff --git a/gateways/core/stream/nats/nats.go b/gateways/core/stream/nats/nats.go index b9c183f69c..086fc3572d 100644 --- a/gateways/core/stream/nats/nats.go +++ b/gateways/core/stream/nats/nats.go @@ -17,19 +17,12 @@ limitations under the License. package main import ( - "context" "github.com/argoproj/argo-events/common" "github.com/argoproj/argo-events/gateways" - "github.com/argoproj/argo-events/gateways/core/stream" "github.com/argoproj/argo-events/pkg/apis/gateway/v1alpha1" - "github.com/ghodss/yaml" natsio "github.com/nats-io/go-nats" - "strings" "sync" -) - -const ( - subjectKey = "subject" + "fmt" ) var ( @@ -48,7 +41,9 @@ func (nce *natsConfigExecutor) StartConfig(config *gateways.ConfigContext) error // mark final gateway state defer gatewayConfig.GatewayCleanup(config, &errMessage, err) - gatewayConfig.Log.Info().Str("config-key", config.Data.Src).Msg("parsing configuration...") + gatewayConfig.Log.Info().Str("config-key", config.Data.Src).Msg("operating on configuration...") + natsConfig := config.Data.Config.(*nats) + gatewayConfig.Log.Info().Str("config-key", config.Data.Src).Interface("config-value", *natsConfig).Msg("nats configuration") var wg sync.WaitGroup wg.Add(1) @@ -60,27 +55,14 @@ func (nce *natsConfigExecutor) StartConfig(config *gateways.ConfigContext) error wg.Done() }() - var s *stream.Stream - err = yaml.Unmarshal([]byte(config.Data.Config), &s) + conn, err := natsio.Connect(natsConfig.URL) if err != nil { - errMessage = "failed to parse configuration" + gatewayConfig.Log.Error().Str("url", natsConfig.URL).Err(err).Msg("connection failed") config.StopCh <- struct{}{} return err } - gatewayConfig.Log.Info().Str("config-key", config.Data.Src).Interface("stream", *s).Msg("configuring...") - conn, err := natsio.Connect(s.URL) - if err != nil { - gatewayConfig.Log.Error().Str("url", s.URL).Err(err).Msg("connection failed") - config.StopCh <- struct{}{} - return err - } - gatewayConfig.Log.Debug().Str("server id", conn.ConnectedServerId()).Str("connected url", conn.ConnectedUrl()). - Str("servers", strings.Join(conn.DiscoveredServers(), ",")).Msg("nats connection") - - gatewayConfig.Log.Info().Str("config-name", config.Data.Src).Msg("running...") config.Active = true - event := gatewayConfig.GetK8Event("configuration running", v1alpha1.NodePhaseRunning, config.Data) _, err = common.CreateK8Event(event, gatewayConfig.Clientset) if err != nil { @@ -88,7 +70,7 @@ func (nce *natsConfigExecutor) StartConfig(config *gateways.ConfigContext) error return err } - sub, err := conn.Subscribe(s.Attributes[subjectKey], func(msg *natsio.Msg) { + sub, err := conn.Subscribe(natsConfig.Subject, func(msg *natsio.Msg) { gatewayConfig.Log.Info().Str("config-key", config.Data.Src).Msg("dispatching event to gateway-processor") gatewayConfig.DispatchEvent(&gateways.GatewayEvent{ Src: config.Data.Src, @@ -100,7 +82,8 @@ func (nce *natsConfigExecutor) StartConfig(config *gateways.ConfigContext) error config.StopCh <- struct{}{} return err } - gatewayConfig.Log.Info().Str("config-key", config.Data.Src).Msg("configuration is running...") + + gatewayConfig.Log.Info().Str("config-key", config.Data.Src).Msg("configuration is running.") wg.Wait() err = sub.Unsubscribe() @@ -112,6 +95,7 @@ func (nce *natsConfigExecutor) StartConfig(config *gateways.ConfigContext) error return nil } +// StopConfig stops gateway configuration func (nce *natsConfigExecutor) StopConfig(config *gateways.ConfigContext) error { if config.Active == true { config.StopCh <- struct{}{} @@ -119,14 +103,21 @@ func (nce *natsConfigExecutor) StopConfig(config *gateways.ConfigContext) error return nil } -func main() { - _, err := gatewayConfig.WatchGatewayEvents(context.Background()) - if err != nil { - gatewayConfig.Log.Panic().Err(err).Msg("failed to watch k8 events for gateway configuration state updates") +// Validate validates gateway configuration +func (nce *natsConfigExecutor) Validate(config *gateways.ConfigContext) error { + natsConfig, ok := config.Data.Config.(*nats) + if !ok { + return gateways.ErrConfigParseFailed } - _, err = gatewayConfig.WatchGatewayConfigMap(context.Background(), &natsConfigExecutor{}) - if err != nil { - gatewayConfig.Log.Panic().Err(err).Msg("failed to watch gateway configuration updates") + if natsConfig.URL == "" { + return fmt.Errorf("%+v, url must be specified", gateways.ErrInvalidConfig) + } + if natsConfig.Subject == "" { + return fmt.Errorf("%+v, subject must be specified", gateways.ErrInvalidConfig) } - select {} + return nil +} + +func main() { + gatewayConfig.StartGateway(&natsConfigExecutor{}) } diff --git a/gateways/core/stream/nats/types.go b/gateways/core/stream/nats/types.go new file mode 100644 index 0000000000..62c1a0adfd --- /dev/null +++ b/gateways/core/stream/nats/types.go @@ -0,0 +1,11 @@ +package main + +// nats contains configuration to connect to NATS cluster +// +k8s:openapi-gen=true +type nats struct { + // URL to connect to nats cluster + URL string `json:"url"` + + // Subject name + Subject string `json:"subject"` +} diff --git a/gateways/core/stream/stream.go b/gateways/core/stream/stream.go deleted file mode 100644 index e848097cca..0000000000 --- a/gateways/core/stream/stream.go +++ /dev/null @@ -1,11 +0,0 @@ -package stream - -// Stream describes a queue stream resource -type Stream struct { - // Type of the stream resource - Type string `json:"type" protobuf:"bytes,1,opt,name=type"` - // URL is the exposed endpoint for client connections to this service - URL string `json:"url" protobuf:"bytes,2,opt,name=url"` - // Attributes contains additional fields specific to each service implementation - Attributes map[string]string `json:"attributes,omitempty" protobuf:"bytes,3,rep,name=attributes"` -} diff --git a/gateways/core/webhook/types.go b/gateways/core/webhook/types.go new file mode 100644 index 0000000000..86e022ca55 --- /dev/null +++ b/gateways/core/webhook/types.go @@ -0,0 +1,15 @@ +package main + +// webhook is a general purpose REST API +// +k8s:openapi-gen=true +type webhook struct { + // REST API endpoint + Endpoint string `json:"endpoint" protobuf:"bytes,1,opt,name=endpoint"` + + // Method is HTTP request method that indicates the desired action to be performed for a given resource. + // See RFC7231 Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content + Method string `json:"method" protobuf:"bytes,2,opt,name=method"` + + // Port on which HTTP server is listening for incoming events. + Port string `json:"port" protobuf:"bytes,3,opt,name=port"` +} diff --git a/gateways/core/webhook/webhook.go b/gateways/core/webhook/webhook.go index 737465c6e7..28a9dc630d 100644 --- a/gateways/core/webhook/webhook.go +++ b/gateways/core/webhook/webhook.go @@ -22,11 +22,12 @@ import ( "github.com/argoproj/argo-events/common" "github.com/argoproj/argo-events/gateways" "github.com/argoproj/argo-events/pkg/apis/gateway/v1alpha1" - "github.com/ghodss/yaml" "go.uber.org/atomic" "io/ioutil" "net/http" "sync" + "strings" + "strconv" ) var ( @@ -50,19 +51,6 @@ var ( // webhookConfigExecutor implements ConfigExecutor type webhookConfigExecutor struct{} -// webhook is a general purpose REST API -type webhook struct { - // REST API endpoint - Endpoint string - - // Method is HTTP request method that indicates the desired action to be performed for a given resource. - // See RFC7231 Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content - Method string - - // Port on which HTTP server is listening for incoming events. - Port string -} - // Runs a gateway configuration func (wce *webhookConfigExecutor) StartConfig(config *gateways.ConfigContext) error { var err error @@ -71,15 +59,9 @@ func (wce *webhookConfigExecutor) StartConfig(config *gateways.ConfigContext) er // mark final gateway state defer gatewayConfig.GatewayCleanup(config, &errMessage, err) - gatewayConfig.Log.Info().Str("config-name", config.Data.Src).Msg("parsing configuration...") - - var h *webhook - err = yaml.Unmarshal([]byte(config.Data.Config), &h) - if err != nil { - errMessage = "failed to parse configuration" - return err - } - gatewayConfig.Log.Info().Interface("config", config.Data.Config).Interface("webhook", h).Msg("configuring...") + gatewayConfig.Log.Info().Str("config-key", config.Data.Src).Msg("operating on configuration...") + webhookConfig := config.Data.Config.(*webhook) + gatewayConfig.Log.Info().Str("config-key", config.Data.Src).Interface("config-value", *webhookConfig).Msg("webhook configuration") var wg sync.WaitGroup wg.Add(1) @@ -91,11 +73,11 @@ func (wce *webhookConfigExecutor) StartConfig(config *gateways.ConfigContext) er gatewayConfig.Log.Info().Str("config-key", config.Data.Src).Msg("stopping the configuration...") // remove the endpoint and http method configuration. mutex.Lock() - activeHTTPMethods, ok := activeRoutes[h.Endpoint] + activeHTTPMethods, ok := activeRoutes[webhookConfig.Endpoint] if ok { - delete(activeHTTPMethods, h.Method) + delete(activeHTTPMethods, webhookConfig.Method) } - if h.Port != "" && hasServerStarted.Load() { + if webhookConfig.Port != "" && hasServerStarted.Load() { gatewayConfig.Log.Info().Str("config-key", config.Data.Src).Msg("stopping http server") err = srv.Shutdown(context.Background()) if err != nil { @@ -117,12 +99,12 @@ func (wce *webhookConfigExecutor) StartConfig(config *gateways.ConfigContext) er // start a http server only if given configuration contains port information and no other // configuration previously started the server - if h.Port != "" && !hasServerStarted.Load() { + if webhookConfig.Port != "" && !hasServerStarted.Load() { // mark http server as started hasServerStarted.Store(true) go func() { - gatewayConfig.Log.Info().Str("http-port", h.Port).Msg("http server started listening...") - srv := &http.Server{Addr: ":" + fmt.Sprintf("%s", h.Port)} + gatewayConfig.Log.Info().Str("config-key", config.Data.Src).Str("http-port", webhookConfig.Port).Msg("http server started listening...") + srv := &http.Server{Addr: ":" + fmt.Sprintf("%s", webhookConfig.Port)} err = srv.ListenAndServe() gatewayConfig.Log.Info().Str("config-key", config.Data.Src).Msg("http server stopped") if err == http.ErrServerClosed { @@ -139,29 +121,29 @@ func (wce *webhookConfigExecutor) StartConfig(config *gateways.ConfigContext) er } // configure endpoint and http method - if h.Endpoint != "" && h.Method != "" { - if _, ok := activeRoutes[h.Endpoint]; !ok { + if webhookConfig.Endpoint != "" && webhookConfig.Method != "" { + if _, ok := activeRoutes[webhookConfig.Endpoint]; !ok { mutex.Lock() - activeRoutes[h.Endpoint] = make(map[string]struct{}) + activeRoutes[webhookConfig.Endpoint] = make(map[string]struct{}) // save event channel for this connection/configuration - activeRoutes[h.Endpoint][h.Method] = struct{}{} + activeRoutes[webhookConfig.Endpoint][webhookConfig.Method] = struct{}{} mutex.Unlock() // add a handler for endpoint if not already added. - http.HandleFunc(h.Endpoint, func(writer http.ResponseWriter, request *http.Request) { + http.HandleFunc(webhookConfig.Endpoint, func(writer http.ResponseWriter, request *http.Request) { // check if http methods match and route and http method is registered. - if _, ok := activeRoutes[h.Endpoint]; ok { - if _, isActive := activeRoutes[h.Endpoint][request.Method]; isActive { - gatewayConfig.Log.Info().Str("endpoint", h.Endpoint).Str("http-method", h.Method).Msg("received a request") + if _, ok := activeRoutes[webhookConfig.Endpoint]; ok { + if _, isActive := activeRoutes[webhookConfig.Endpoint][request.Method]; isActive { + gatewayConfig.Log.Info().Str("config-key", config.Data.Src).Str("endpoint", webhookConfig.Endpoint).Str("http-method", webhookConfig.Method).Msg("received a request") body, err := ioutil.ReadAll(request.Body) if err != nil { - gatewayConfig.Log.Error().Err(err).Msg("failed to parse request body") + gatewayConfig.Log.Error().Str("config-key", config.Data.Src).Err(err).Msg("failed to parse request body") common.SendErrorResponse(writer) } else { - gatewayConfig.Log.Info().Str("endpoint", h.Endpoint).Str("http-method", h.Method).Msg("dispatching event to gateway-processor") + gatewayConfig.Log.Info().Str("config-key", config.Data.Src).Str("endpoint", webhookConfig.Endpoint).Str("http-method", webhookConfig.Method).Msg("dispatching event to gateway-processor") common.SendSuccessResponse(writer) - gatewayConfig.Log.Info().Str("payload", string(body)).Msg("payload is") + gatewayConfig.Log.Debug().Str("config-key", config.Data.Src).Str("payload", string(body)).Msg("payload") // dispatch event to gateway transformer gatewayConfig.DispatchEvent(&gateways.GatewayEvent{ @@ -170,21 +152,21 @@ func (wce *webhookConfigExecutor) StartConfig(config *gateways.ConfigContext) er }) } } else { - gatewayConfig.Log.Warn().Str("endpoint", h.Endpoint).Str("http-method", request.Method).Msg("endpoint and http method is not an active route") + gatewayConfig.Log.Warn().Str("config-key", config.Data.Src).Str("endpoint", webhookConfig.Endpoint).Str("http-method", request.Method).Msg("endpoint and http method is not an active route") common.SendErrorResponse(writer) } } else { - gatewayConfig.Log.Warn().Str("endpoint", h.Endpoint).Msg("endpoint is not active") + gatewayConfig.Log.Warn().Str("config-key", config.Data.Src).Str("endpoint", webhookConfig.Endpoint).Msg("endpoint is not active") common.SendErrorResponse(writer) } }) } else { mutex.Lock() - activeRoutes[h.Endpoint][h.Method] = struct{}{} + activeRoutes[webhookConfig.Endpoint][webhookConfig.Method] = struct{}{} mutex.Unlock() } - gatewayConfig.Log.Info().Str("config-name", config.Data.Src).Msg("configuration is running...") + gatewayConfig.Log.Info().Str("config-key", config.Data.Src).Msg("configuration is running...") } wg.Wait() gatewayConfig.Log.Info().Str("config-key", config.Data.Src).Msg("configuration is now complete.") @@ -199,14 +181,32 @@ func (wce *webhookConfigExecutor) StopConfig(config *gateways.ConfigContext) err return nil } -func main() { - _, err := gatewayConfig.WatchGatewayEvents(context.Background()) - if err != nil { - gatewayConfig.Log.Panic().Err(err).Msg("failed to watch k8 events for gateway configuration state updates") +// Validate validates given webhook configuration +func (wce *webhookConfigExecutor) Validate(config *gateways.ConfigContext) error { + webhookConfig, ok := config.Data.Config.(*webhook) + if !ok { + return gateways.ErrConfigParseFailed } - _, err = gatewayConfig.WatchGatewayConfigMap(context.Background(), &webhookConfigExecutor{}) - if err != nil { - gatewayConfig.Log.Panic().Err(err).Msg("failed to watch gateway configuration updates") + switch webhookConfig.Method { + case http.MethodHead, http.MethodPut, http.MethodConnect, http.MethodDelete, http.MethodGet, http.MethodOptions, http.MethodPatch, http.MethodPost, http.MethodTrace: + default: + return fmt.Errorf("%+v, unknown HTTP method %s", gateways.ErrInvalidConfig, webhookConfig.Method) + } + if webhookConfig.Endpoint == "" { + return fmt.Errorf("%+v, endpoint can't be empty", gateways.ErrInvalidConfig) + } + if !strings.HasPrefix("/", webhookConfig.Endpoint) { + return fmt.Errorf("%+v, endpoint must start with '/'", gateways.ErrInvalidConfig) + } + if webhookConfig.Port != "" { + _, err := strconv.Atoi(webhookConfig.Port) + if err != nil { + return fmt.Errorf("%+v, failed to parse server port %s. err: %+v", gateways.ErrInvalidConfig, webhookConfig.Port, err) + } } - select {} + return nil +} + +func main() { + gatewayConfig.StartGateway(&webhookConfigExecutor{}) } diff --git a/gateways/custom/storage-grid/main.go b/gateways/custom/storage-grid/main.go index 728f01ea19..d551954d34 100644 --- a/gateways/custom/storage-grid/main.go +++ b/gateways/custom/storage-grid/main.go @@ -22,11 +22,15 @@ import ( "github.com/argoproj/argo-events/common" "github.com/argoproj/argo-events/gateways" "github.com/argoproj/argo-events/pkg/apis/gateway/v1alpha1" - "github.com/ghodss/yaml" "github.com/satori/go.uuid" "io/ioutil" "net/http" "sync" + "time" + "github.com/joncalhoun/qson" + "encoding/json" + "net/url" + "strings" ) var ( @@ -55,32 +59,58 @@ var ( // storageGridConfigExecutor implements ConfigExecutor interface type storageGridConfigExecutor struct{} -// storageGridEventConfig contains configuration for storage grid sns -type storageGridEventConfig struct { - Port string - Endpoint string - // Todo: add event and prefix filtering. - Events []string - Filter StorageGridFilter - // srv holds reference to http server - srv *http.Server - mux *http.ServeMux -} - +// HTTP Muxer type server struct { mux *http.ServeMux } +// ServeHTTP implementation func (s *server) ServeHTTP(w http.ResponseWriter, r *http.Request) { s.mux.ServeHTTP(w, r) } -// StorageGridFilter represents filters to apply to bucket nofifications for specifying constraints on objects -type StorageGridFilter struct { - Prefix string - Suffix string +// storageGridNotification is the bucket notification received from storage grid +type storageGridNotification struct { + Action string `json:"Action"` + Message struct { + Records []struct { + EventVersion string `json:"eventVersion"` + EventSource string `json:"eventSource"` + EventTime time.Time `json:"eventTime"` + EventName string `json:"eventName"` + UserIdentity struct { + PrincipalID string `json:"principalId"` + } `json:"userIdentity"` + RequestParameters struct { + SourceIPAddress string `json:"sourceIPAddress"` + } `json:"requestParameters"` + ResponseElements struct { + XAmzRequestID string `json:"x-amz-request-id"` + } `json:"responseElements"` + S3 struct { + S3SchemaVersion string `json:"s3SchemaVersion"` + ConfigurationID string `json:"configurationId"` + Bucket struct { + Name string `json:"name"` + OwnerIdentity struct { + PrincipalID string `json:"principalId"` + } `json:"ownerIdentity"` + Arn string `json:"arn"` + } `json:"bucket"` + Object struct { + Key string `json:"key"` + Size int `json:"size"` + ETag string `json:"eTag"` + Sequencer string `json:"sequencer"` + } `json:"object"` + } `json:"s3"` + } `json:"Records"` + } `json:"Message"` + TopicArn string `json:"TopicArn"` + Version string `json:"Version"` } +// generateUUID returns a new uuid func generateUUID() uuid.UUID { return uuid.NewV4() } @@ -89,7 +119,7 @@ func generateUUID() uuid.UUID { func (sgce *storageGridConfigExecutor) startHttpServer(sg *storageGridEventConfig, config *gateways.ConfigContext, err error, errMessage *string) { // start a http server only if no other configuration previously started the server on given port mutex.Lock() - gatewayConfig.Log.Info().Str("config-key", config.Data.Src).Interface("active servers", activeServers[sg.Port]).Msg("active servers") + gatewayConfig.Log.Info().Str("config-key", config.Data.Src).Interface("active-servers", activeServers[sg.Port]).Msg("servers") if _, ok := activeServers[sg.Port]; !ok { gatewayConfig.Log.Info().Str("config-key", config.Data.Src).Str("port", sg.Port).Msg("http server started listening...") s := &server{ @@ -122,6 +152,36 @@ func (sgce *storageGridConfigExecutor) startHttpServer(sg *storageGridEventConfi mutex.Unlock() } +// filterEvent filters notification based on event filter in a gateway configuration +func filterEvent(notification *storageGridNotification, sg *storageGridEventConfig) bool { + if sg.Events == nil { + return true + } + for _, filterEvent := range sg.Events { + if notification.Message.Records[0].EventName == filterEvent { + return true + } + } + return false +} + +// filterName filters object key based on configured prefix and/or suffix +func filterName(notification *storageGridNotification, sg *storageGridEventConfig) bool { + if sg.Filter == nil { + return true + } + if sg.Filter.Prefix != "" && sg.Filter.Suffix != "" { + return strings.HasPrefix(notification.Message.Records[0].S3.Object.Key, sg.Filter.Prefix) && strings.HasSuffix(notification.Message.Records[0].S3.Object.Key, sg.Filter.Suffix) + } + if sg.Filter.Prefix != "" { + return strings.HasPrefix(notification.Message.Records[0].S3.Object.Key, sg.Filter.Prefix) + } + if sg.Filter.Suffix != "" { + return strings.HasSuffix(notification.Message.Records[0].S3.Object.Key, sg.Filter.Suffix) + } + return true +} + // StartConfig runs a configuration func (sgce *storageGridConfigExecutor) StartConfig(config *gateways.ConfigContext) error { var err error @@ -130,15 +190,9 @@ func (sgce *storageGridConfigExecutor) StartConfig(config *gateways.ConfigContex // mark final gateway state defer gatewayConfig.GatewayCleanup(config, &errMessage, err) - gatewayConfig.Log.Info().Str("config-name", config.Data.Src).Msg("parsing configuration...") - - var sg *storageGridEventConfig - err = yaml.Unmarshal([]byte(config.Data.Config), &sg) - if err != nil { - errMessage = "failed to parse configuration" - return err - } - gatewayConfig.Log.Info().Interface("config", config.Data.Config).Interface("storage-grid", sg).Msg("configuring...") + gatewayConfig.Log.Info().Str("config-key", config.Data.Src).Msg("operating on configuration...") + sg := config.Data.Config.(*storageGridEventConfig) + gatewayConfig.Log.Info().Str("config-key", config.Data.Src).Interface("config-value", *sg).Msg("storage grid configuration") var wg sync.WaitGroup wg.Add(1) @@ -229,11 +283,38 @@ func (sgce *storageGridConfigExecutor) StartConfig(config *gateways.ConfigContex writer.Header().Add("Content-Type", "text/plain") writer.Write([]byte(respBody)) - // dispatch event to gateway transformer - gatewayConfig.DispatchEvent(&gateways.GatewayEvent{ - Src: config.Data.Src, - Payload: body, - }) + // notification received from storage grid is url encoded. + parsedURL, err := url.QueryUnescape(string(body)) + if err != nil { + errMessage = "failed to perform query un-escape" + gatewayConfig.Log.Error().Str("config-key", config.Data.Src).Err(err).Msg(errMessage) + return + } + b, err := qson.ToJSON(parsedURL) + if err != nil { + errMessage = "failed to parse payload url into JSON" + gatewayConfig.Log.Error().Str("config-key", config.Data.Src).Err(err).Msg(errMessage) + return + } + + var notification *storageGridNotification + err = json.Unmarshal(b, ¬ification) + if err != nil { + errMessage = "failed to unmarshal notification JSON" + gatewayConfig.Log.Error().Str("config-key", config.Data.Src).Err(err).Msg(errMessage) + return + } + + gatewayConfig.Log.Info().Str("config-key", config.Data.Src).Interface("notification", notification).Msg("parsed notification") + if filterEvent(notification, sg) && filterName(notification, sg) { + // dispatch event to gateway transformer + gatewayConfig.DispatchEvent(&gateways.GatewayEvent{ + Src: config.Data.Src, + Payload: b, + }) + } else { + gatewayConfig.Log.Warn().Str("config-key", config.Data.Src).Interface("notification", notification).Msg("discarding notification since it did not pass all filters") + } } } }) @@ -253,14 +334,24 @@ func (sgce *storageGridConfigExecutor) StopConfig(config *gateways.ConfigContext return nil } -func main() { - _, err := gatewayConfig.WatchGatewayEvents(context.Background()) - if err != nil { - gatewayConfig.Log.Panic().Err(err).Msg("failed to watch k8 events for gateway configuration state updates") +// Validate validates gateway configuration +func (sgce *storageGridConfigExecutor) Validate(config *gateways.ConfigContext) error { + sg, ok := config.Data.Config.(*storageGridEventConfig) + if !ok { + return gateways.ErrConfigParseFailed } - _, err = gatewayConfig.WatchGatewayConfigMap(context.Background(), &storageGridConfigExecutor{}) - if err != nil { - gatewayConfig.Log.Panic().Err(err).Msg("failed to watch gateway configuration updates") + if sg.Port == "" { + return fmt.Errorf("%+v, must specify port", gateways.ErrInvalidConfig) + } + if sg.Endpoint == "" { + return fmt.Errorf("%+v, must specify endpoint", gateways.ErrInvalidConfig) + } + if !strings.HasPrefix(sg.Endpoint, "/") { + return fmt.Errorf("%+v, endpoint must start with '/'", gateways.ErrInvalidConfig) } - select {} + return nil +} + +func main() { + gatewayConfig.StartGateway(&storageGridConfigExecutor{}) } diff --git a/gateways/custom/storage-grid/types.go b/gateways/custom/storage-grid/types.go new file mode 100644 index 0000000000..f0dda61c88 --- /dev/null +++ b/gateways/custom/storage-grid/types.go @@ -0,0 +1,22 @@ +package main + +import "net/http" + +// storageGridEventConfig contains configuration for storage grid sns +// +k8s:openapi-gen=true +type storageGridEventConfig struct { + Port string + Endpoint string + Events []string + Filter *Filter + // srv holds reference to http server + srv *http.Server + mux *http.ServeMux +} + +// Filter represents filters to apply to bucket nofifications for specifying constraints on objects +// +k8s:openapi-gen=true +type Filter struct { + Prefix string + Suffix string +} diff --git a/gateways/errors.go b/gateways/errors.go new file mode 100644 index 0000000000..2ffcc0fc0a --- /dev/null +++ b/gateways/errors.go @@ -0,0 +1,14 @@ +package gateways + +import "errors" + +const ( + ErrGatewayTransformerConnectionMsg = "failed to connect to gateway transformer" + ErrGatewayEventWatchMsg = "failed to watch k8 events for gateway configuration state updates" + ErrGatewayConfigmapWatchMsg = "failed to watch gateway configuration updates" +) + +var ( + ErrConfigParseFailed = errors.New("failed to parse configuration") + ErrInvalidConfig = errors.New("invalid configuration") +) diff --git a/gateways/gateway.go b/gateways/gateway.go index 26ffd2d0e7..be1c54d290 100644 --- a/gateways/gateway.go +++ b/gateways/gateway.go @@ -93,7 +93,7 @@ type ConfigData struct { // Src contains name of the configuration Src string `json:"src"` // Config contains the configuration - Config string `json:"config"` + Config interface{} `json:"config"` } // GatewayEvent is the internal representation of an event. @@ -126,6 +126,7 @@ type HTTPGatewayServerConfig struct { type ConfigExecutor interface { StartConfig(configContext *ConfigContext) error StopConfig(configContext *ConfigContext) error + Validate(configContext *ConfigContext) error } // newEventWatcher creates a new event watcher. @@ -296,7 +297,7 @@ func (gc *GatewayConfig) WatchGatewayConfigMap(ctx context.Context, executor Con gc.Log.Info().Str("config-map", gc.configName).Msg("detected ConfigMap addition. Updating the controller run config.") err := gc.manageConfigurations(executor, newCm) if err != nil { - gc.Log.Error().Err(err).Msg("update of run config failed") + gc.Log.Error().Err(err).Msg("add config failed") } } }, @@ -305,7 +306,7 @@ func (gc *GatewayConfig) WatchGatewayConfigMap(ctx context.Context, executor Con gc.Log.Info().Msg("detected ConfigMap update. Updating the controller run config.") err := gc.manageConfigurations(executor, cm) if err != nil { - gc.Log.Error().Err(err).Msg("update of run config failed") + gc.Log.Error().Err(err).Msg("update config failed") } } }, @@ -419,6 +420,11 @@ func (gc *GatewayConfig) DispatchEvent(gatewayEvent *GatewayEvent) error { func (gc *GatewayConfig) createInternalConfigs(cm *corev1.ConfigMap) (map[string]*ConfigContext, error) { configs := make(map[string]*ConfigContext) for configKey, configValue := range cm.Data { + i, err := ParseGatewayConfig(configValue) + if err != nil { + return nil, err + } + hashKey := Hasher(configKey + configValue) gc.Log.Info().Str("config-key", configKey).Interface("config-data", configValue).Str("hash", string(hashKey)).Msg("configuration hash") currentTimeStr := time.Now().String() @@ -428,7 +434,7 @@ func (gc *GatewayConfig) createInternalConfigs(cm *corev1.ConfigMap) (map[string ID: hashKey, TimeID: timeID, Src: configKey, - Config: configValue, + Config: i, }, StopCh: make(chan struct{}), } @@ -705,6 +711,22 @@ func (gc *GatewayConfig) GetK8Event(reason string, action v1alpha1.NodePhase, co } } +// TransformerReadinessProbe checks whether gateway transformer is running or not +func (gc *GatewayConfig) TransformerReadinessProbe() error { + return wait.ExponentialBackoff(wait.Backoff{ + Steps: 5, + Duration: 1 * time.Minute, + Factor: 1.0, + Jitter: 0.1, + }, func() (bool, error) { + _, err := http.Get(fmt.Sprintf("http://localhost:%s/readiness", gc.transformerPort)) + if err != nil { + return false, err + } + return true, nil + }) +} + // GatewayCleanup marks configuration as non-active and marks final gateway state func (gc *GatewayConfig) GatewayCleanup(config *ConfigContext, errMessage *string, err error) { var event *corev1.Event @@ -727,3 +749,23 @@ func (gc *GatewayConfig) GatewayCleanup(config *ConfigContext, errMessage *strin gc.Log.Error().Str("config-key", config.Data.Src).Err(err).Msg("failed to create gateway k8 event") } } + +// StartGateway starts a gateway +func (gc *GatewayConfig) StartGateway(configExecutor ConfigExecutor) error { + err := gc.TransformerReadinessProbe() + if err != nil { + gc.Log.Panic().Err(err).Msg(ErrGatewayTransformerConnectionMsg) + return err + } + _, err = gc.WatchGatewayEvents(context.Background()) + if err != nil { + gc.Log.Panic().Err(err).Msg(ErrGatewayEventWatchMsg) + return err + } + _, err = gc.WatchGatewayConfigMap(context.Background(), configExecutor) + if err != nil { + gc.Log.Panic().Err(err).Msg(ErrGatewayConfigmapWatchMsg) + return err + } + select {} +} diff --git a/gateways/grpc/gateway.go b/gateways/grpc/gateway.go index 6d20caa460..b7ba4e8763 100644 --- a/gateways/grpc/gateway.go +++ b/gateways/grpc/gateway.go @@ -119,13 +119,5 @@ func (gce *grpcConfigExecutor) StopConfig(config *gateways.ConfigContext) error } func main() { - _, err := gatewayConfig.WatchGatewayEvents(context.Background()) - if err != nil { - gatewayConfig.Log.Panic().Err(err).Msg("failed to watch k8 events for gateway configuration state updates") - } - _, err = gatewayConfig.WatchGatewayConfigMap(context.Background(), &grpcConfigExecutor{}) - if err != nil { - gatewayConfig.Log.Panic().Err(err).Msg("failed to watch gateway configuration updates") - } - select {} + gatewayConfig.StartGateway(&grpcConfigExecutor{}) } diff --git a/gateways/rest/gateway.go b/gateways/rest/gateway.go index 555b371ad6..a369686f32 100644 --- a/gateways/rest/gateway.go +++ b/gateways/rest/gateway.go @@ -2,13 +2,13 @@ package main import ( "bytes" - "context" "encoding/json" "fmt" - "github.com/argoproj/argo-events/common" "github.com/argoproj/argo-events/gateways" - "io/ioutil" "net/http" + "io/ioutil" + "github.com/argoproj/argo-events/common" + "context" ) var ( @@ -60,8 +60,18 @@ func sendHTTPRequest(config *gateways.ConfigData, endpoint string) error { } func main() { - httpGatewayServerConfig.GwConfig.WatchGatewayEvents(context.Background()) - httpGatewayServerConfig.GwConfig.WatchGatewayConfigMap(context.Background(), &httpConfigExecutor{}) + err := httpGatewayServerConfig.GwConfig.TransformerReadinessProbe() + if err != nil { + httpGatewayServerConfig.GwConfig.Log.Panic().Err(err).Msg(gateways.ErrGatewayTransformerConnection) + } + _, err = httpGatewayServerConfig.GwConfig.WatchGatewayEvents(context.Background()) + if err != nil { + httpGatewayServerConfig.GwConfig.Log.Panic().Err(err).Msg(gateways.ErrGatewayEventWatch) + } + _, err = httpGatewayServerConfig.GwConfig.WatchGatewayConfigMap(context.Background(), &httpConfigExecutor{}) + if err != nil { + httpGatewayServerConfig.GwConfig.Log.Panic().Err(err).Msg(gateways.ErrGatewayConfigmapWatch) + } // handle events from gateway processor server http.HandleFunc(httpGatewayServerConfig.EventEndpoint, func(writer http.ResponseWriter, request *http.Request) { httpGatewayServerConfig.GwConfig.Log.Info().Msg("received an event. processing...") diff --git a/gateways/utils.go b/gateways/utils.go index 54e8b17871..cecd243089 100644 --- a/gateways/utils.go +++ b/gateways/utils.go @@ -21,6 +21,7 @@ import ( "fmt" "github.com/argoproj/argo-events/controllers/gateway/transform" "hash/fnv" + "github.com/ghodss/yaml" ) // TransformerPayload creates a new payload from input data and adds source information @@ -42,3 +43,13 @@ func Hasher(value string) string { _, _ = h.Write([]byte(value)) return fmt.Sprintf("%v", h.Sum32()) } + +// parseConfig parses gateway configuration +func ParseGatewayConfig(config string) (interface{}, error) { + var i interface{} + err := yaml.Unmarshal([]byte(config), &i) + if err != nil { + return nil, err + } + return i, err +} diff --git a/hack/update-openapigen.sh b/hack/update-openapigen.sh index 30913b4bfc..eefc8f941a 100755 --- a/hack/update-openapigen.sh +++ b/hack/update-openapigen.sh @@ -8,14 +8,198 @@ PROJECT_ROOT=$(cd $(dirname "$0")/.. ; pwd) CODEGEN_PKG=${PROJECT_ROOT}/vendor/k8s.io/code-generator VERSION="v1alpha1" +# Sensor go run ${CODEGEN_PKG}/cmd/openapi-gen/main.go \ --go-header-file ${PROJECT_ROOT}/hack/custom-boilerplate.go.txt \ --input-dirs github.com/argoproj/argo-events/pkg/apis/sensor/${VERSION} \ --output-package github.com/argoproj/argo-events/pkg/apis/sensor/${VERSION} \ $@ +cp ${GOPATH}/src/github.com/argoproj/argo-events/pkg/apis/sensor/${VERSION}/types.go ${GOPATH}/src/k8s.io/kube-openapi/test/integration/argo-events/ + +go run ${CODEGEN_PKG}/cmd/openapi-gen/main.go \ + --go-header-file ${PROJECT_ROOT}/hack/custom-boilerplate.go.txt \ + --input-dirs k8s.io/kube-openapi/test/integration/argo-events \ + --output-package k8s.io/kube-openapi/test/integration/pkg \ + -p generated \ + -O openapi_generated \ + $@ + +go run ${GOPATH}/src/k8s.io/kube-openapi/test/integration/builder/main.go ${GOPATH}/src/k8s.io/kube-openapi/test/integration/argo-events/sensor.json + +cp ${GOPATH}/src/k8s.io/kube-openapi/test/integration/argo-events/sensor.json ${GOPATH}/src/github.com/argoproj/argo-events/pkg/apis/sensor/${VERSION}/ + + +# Gateway go run ${CODEGEN_PKG}/cmd/openapi-gen/main.go \ --go-header-file ${PROJECT_ROOT}/hack/custom-boilerplate.go.txt \ --input-dirs github.com/argoproj/argo-events/pkg/apis/gateway/${VERSION} \ --output-package github.com/argoproj/argo-events/pkg/apis/gateway/${VERSION} \ $@ + +cp ${GOPATH}/src/github.com/argoproj/argo-events/pkg/apis/gateway/${VERSION}/types.go ${GOPATH}/src/k8s.io/kube-openapi/test/integration/argo-events/ + +go run ${CODEGEN_PKG}/cmd/openapi-gen/main.go \ + --go-header-file ${PROJECT_ROOT}/hack/custom-boilerplate.go.txt \ + --input-dirs k8s.io/kube-openapi/test/integration/argo-events \ + --output-package k8s.io/kube-openapi/test/integration/pkg \ + -p generated \ + -O openapi_generated \ + $@ + +go run ${GOPATH}/src/k8s.io/kube-openapi/test/integration/builder/main.go ${GOPATH}/src/k8s.io/kube-openapi/test/integration/argo-events/gateway.json + +cp ${GOPATH}/src/k8s.io/kube-openapi/test/integration/argo-events/gateway.json ${GOPATH}/src/github.com/argoproj/argo-events/pkg/apis/gateway/${VERSION}/ + + +# Webhook +cp ${GOPATH}/src/github.com/argoproj/argo-events/gateways/core/webhook/types.go ${GOPATH}/src/k8s.io/kube-openapi/test/integration/argo-events/ + +go run ${CODEGEN_PKG}/cmd/openapi-gen/main.go \ + --go-header-file ${PROJECT_ROOT}/hack/custom-boilerplate.go.txt \ + --input-dirs k8s.io/kube-openapi/test/integration/argo-events \ + --output-package k8s.io/kube-openapi/test/integration/pkg \ + -p generated \ + -O openapi_generated \ + $@ + +go run ${GOPATH}/src/k8s.io/kube-openapi/test/integration/builder/main.go ${GOPATH}/src/k8s.io/kube-openapi/test/integration/argo-events/webhook.json + +cp ${GOPATH}/src/k8s.io/kube-openapi/test/integration/argo-events/webhook.json ${GOPATH}/src/github.com/argoproj/argo-events/gateways/core/webhook/ + +# Artifact +cp ${GOPATH}/src/github.com/argoproj/argo-events/gateways/core/artifact/types.go ${GOPATH}/src/k8s.io/kube-openapi/test/integration/argo-events/ + +go run ${CODEGEN_PKG}/cmd/openapi-gen/main.go \ + --go-header-file ${PROJECT_ROOT}/hack/custom-boilerplate.go.txt \ + --input-dirs k8s.io/kube-openapi/test/integration/argo-events \ + --output-package k8s.io/kube-openapi/test/integration/pkg \ + -p generated \ + -O openapi_generated \ + $@ + +go run ${GOPATH}/src/k8s.io/kube-openapi/test/integration/builder/main.go ${GOPATH}/src/k8s.io/kube-openapi/test/integration/argo-events/artifact.json + +cp ${GOPATH}/src/k8s.io/kube-openapi/test/integration/argo-events/artifact.json ${GOPATH}/src/github.com/argoproj/argo-events/gateways/core/artifact/ + +# Calendar +cp ${GOPATH}/src/github.com/argoproj/argo-events/gateways/core/calendar/types.go ${GOPATH}/src/k8s.io/kube-openapi/test/integration/argo-events/ + +go run ${CODEGEN_PKG}/cmd/openapi-gen/main.go \ + --go-header-file ${PROJECT_ROOT}/hack/custom-boilerplate.go.txt \ + --input-dirs k8s.io/kube-openapi/test/integration/argo-events \ + --output-package k8s.io/kube-openapi/test/integration/pkg \ + -p generated \ + -O openapi_generated \ + $@ + +go run ${GOPATH}/src/k8s.io/kube-openapi/test/integration/builder/main.go ${GOPATH}/src/k8s.io/kube-openapi/test/integration/argo-events/calendar.json + +cp ${GOPATH}/src/k8s.io/kube-openapi/test/integration/argo-events/calendar.json ${GOPATH}/src/github.com/argoproj/argo-events/gateways/core/calendar/ + +# Resource +cp ${GOPATH}/src/github.com/argoproj/argo-events/gateways/core/resource/types.go ${GOPATH}/src/k8s.io/kube-openapi/test/integration/argo-events/ + +go run ${CODEGEN_PKG}/cmd/openapi-gen/main.go \ + --go-header-file ${PROJECT_ROOT}/hack/custom-boilerplate.go.txt \ + --input-dirs k8s.io/kube-openapi/test/integration/argo-events \ + --output-package k8s.io/kube-openapi/test/integration/pkg \ + -p generated \ + -O openapi_generated \ + $@ + +go run ${GOPATH}/src/k8s.io/kube-openapi/test/integration/builder/main.go ${GOPATH}/src/k8s.io/kube-openapi/test/integration/argo-events/resource.json + +cp ${GOPATH}/src/k8s.io/kube-openapi/test/integration/argo-events/resource.json ${GOPATH}/src/github.com/argoproj/argo-events/gateways/core/resource/ + +# File +cp ${GOPATH}/src/github.com/argoproj/argo-events/gateways/core/file/types.go ${GOPATH}/src/k8s.io/kube-openapi/test/integration/argo-events/ + +go run ${CODEGEN_PKG}/cmd/openapi-gen/main.go \ + --go-header-file ${PROJECT_ROOT}/hack/custom-boilerplate.go.txt \ + --input-dirs k8s.io/kube-openapi/test/integration/argo-events \ + --output-package k8s.io/kube-openapi/test/integration/pkg \ + -p generated \ + -O openapi_generated \ + $@ + +go run ${GOPATH}/src/k8s.io/kube-openapi/test/integration/builder/main.go ${GOPATH}/src/k8s.io/kube-openapi/test/integration/argo-events/file.json + +cp ${GOPATH}/src/k8s.io/kube-openapi/test/integration/argo-events/file.json ${GOPATH}/src/github.com/argoproj/argo-events/gateways/core/file/ + +## Streams +# Nats +cp ${GOPATH}/src/github.com/argoproj/argo-events/gateways/core/stream/nats/types.go ${GOPATH}/src/k8s.io/kube-openapi/test/integration/argo-events/ + +go run ${CODEGEN_PKG}/cmd/openapi-gen/main.go \ + --go-header-file ${PROJECT_ROOT}/hack/custom-boilerplate.go.txt \ + --input-dirs k8s.io/kube-openapi/test/integration/argo-events \ + --output-package k8s.io/kube-openapi/test/integration/pkg \ + -p generated \ + -O openapi_generated \ + $@ + +go run ${GOPATH}/src/k8s.io/kube-openapi/test/integration/builder/main.go ${GOPATH}/src/k8s.io/kube-openapi/test/integration/argo-events/nats.json + +cp ${GOPATH}/src/k8s.io/kube-openapi/test/integration/argo-events/nats.json ${GOPATH}/src/github.com/argoproj/argo-events/gateways/core/stream/nats/ + +# Kafka +cp ${GOPATH}/src/github.com/argoproj/argo-events/gateways/core/stream/kafka/types.go ${GOPATH}/src/k8s.io/kube-openapi/test/integration/argo-events/ + +go run ${CODEGEN_PKG}/cmd/openapi-gen/main.go \ + --go-header-file ${PROJECT_ROOT}/hack/custom-boilerplate.go.txt \ + --input-dirs k8s.io/kube-openapi/test/integration/argo-events \ + --output-package k8s.io/kube-openapi/test/integration/pkg \ + -p generated \ + -O openapi_generated \ + $@ + +go run ${GOPATH}/src/k8s.io/kube-openapi/test/integration/builder/main.go ${GOPATH}/src/k8s.io/kube-openapi/test/integration/argo-events/kafka.json + +cp ${GOPATH}/src/k8s.io/kube-openapi/test/integration/argo-events/kafka.json ${GOPATH}/src/github.com/argoproj/argo-events/gateways/core/stream/kafka/ + +# AMQP +cp ${GOPATH}/src/github.com/argoproj/argo-events/gateways/core/stream/amqp/types.go ${GOPATH}/src/k8s.io/kube-openapi/test/integration/argo-events/ + +go run ${CODEGEN_PKG}/cmd/openapi-gen/main.go \ + --go-header-file ${PROJECT_ROOT}/hack/custom-boilerplate.go.txt \ + --input-dirs k8s.io/kube-openapi/test/integration/argo-events \ + --output-package k8s.io/kube-openapi/test/integration/pkg \ + -p generated \ + -O openapi_generated \ + $@ + +go run ${GOPATH}/src/k8s.io/kube-openapi/test/integration/builder/main.go ${GOPATH}/src/k8s.io/kube-openapi/test/integration/argo-events/amqp.json + +cp ${GOPATH}/src/k8s.io/kube-openapi/test/integration/argo-events/amqp.json ${GOPATH}/src/github.com/argoproj/argo-events/gateways/core/amqp/ + +# MQTT +cp ${GOPATH}/src/github.com/argoproj/argo-events/gateways/core/stream/mqtt/types.go ${GOPATH}/src/k8s.io/kube-openapi/test/integration/argo-events/ + +go run ${CODEGEN_PKG}/cmd/openapi-gen/main.go \ + --go-header-file ${PROJECT_ROOT}/hack/custom-boilerplate.go.txt \ + --input-dirs k8s.io/kube-openapi/test/integration/argo-events \ + --output-package k8s.io/kube-openapi/test/integration/pkg \ + -p generated \ + -O openapi_generated \ + $@ + +go run ${GOPATH}/src/k8s.io/kube-openapi/test/integration/builder/main.go ${GOPATH}/src/k8s.io/kube-openapi/test/integration/argo-events/mqtt.json + +cp ${GOPATH}/src/k8s.io/kube-openapi/test/integration/argo-events/mqtt.json ${GOPATH}/src/github.com/argoproj/argo-events/gateways/core/mqtt/ + +## Custom +# Storage Grid +cp ${GOPATH}/src/github.com/argoproj/argo-events/gateways/custom/storage-grid/types.go ${GOPATH}/src/k8s.io/kube-openapi/test/integration/argo-events/ + +go run ${CODEGEN_PKG}/cmd/openapi-gen/main.go \ + --go-header-file ${PROJECT_ROOT}/hack/custom-boilerplate.go.txt \ + --input-dirs k8s.io/kube-openapi/test/integration/argo-events \ + --output-package k8s.io/kube-openapi/test/integration/pkg \ + -p generated \ + -O openapi_generated \ + $@ + +go run ${GOPATH}/src/k8s.io/kube-openapi/test/integration/builder/main.go ${GOPATH}/src/k8s.io/kube-openapi/test/integration/argo-events/storage-grid.json + +cp ${GOPATH}/src/k8s.io/kube-openapi/test/integration/argo-events/storage-grid.json ${GOPATH}/src/github.com/argoproj/argo-events/gateways/custom/storage-grid/ diff --git a/pkg/apis/sensor/v1alpha1/generated.pb.go b/pkg/apis/sensor/v1alpha1/generated.pb.go index 4584e501e1..ba1fc79c0c 100644 --- a/pkg/apis/sensor/v1alpha1/generated.pb.go +++ b/pkg/apis/sensor/v1alpha1/generated.pb.go @@ -47,7 +47,7 @@ const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package func (m *ArtifactLocation) Reset() { *m = ArtifactLocation{} } func (*ArtifactLocation) ProtoMessage() {} func (*ArtifactLocation) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_551c1e60827e8aab, []int{0} + return fileDescriptor_generated_36ef0e7aa257cdc9, []int{0} } func (m *ArtifactLocation) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -72,10 +72,38 @@ func (m *ArtifactLocation) XXX_DiscardUnknown() { var xxx_messageInfo_ArtifactLocation proto.InternalMessageInfo +func (m *ConfigmapArtifact) Reset() { *m = ConfigmapArtifact{} } +func (*ConfigmapArtifact) ProtoMessage() {} +func (*ConfigmapArtifact) Descriptor() ([]byte, []int) { + return fileDescriptor_generated_36ef0e7aa257cdc9, []int{1} +} +func (m *ConfigmapArtifact) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ConfigmapArtifact) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (dst *ConfigmapArtifact) XXX_Merge(src proto.Message) { + xxx_messageInfo_ConfigmapArtifact.Merge(dst, src) +} +func (m *ConfigmapArtifact) XXX_Size() int { + return m.Size() +} +func (m *ConfigmapArtifact) XXX_DiscardUnknown() { + xxx_messageInfo_ConfigmapArtifact.DiscardUnknown(m) +} + +var xxx_messageInfo_ConfigmapArtifact proto.InternalMessageInfo + func (m *Data) Reset() { *m = Data{} } func (*Data) ProtoMessage() {} func (*Data) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_551c1e60827e8aab, []int{1} + return fileDescriptor_generated_36ef0e7aa257cdc9, []int{2} } func (m *Data) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -103,7 +131,7 @@ var xxx_messageInfo_Data proto.InternalMessageInfo func (m *DataFilter) Reset() { *m = DataFilter{} } func (*DataFilter) ProtoMessage() {} func (*DataFilter) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_551c1e60827e8aab, []int{2} + return fileDescriptor_generated_36ef0e7aa257cdc9, []int{3} } func (m *DataFilter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -131,7 +159,7 @@ var xxx_messageInfo_DataFilter proto.InternalMessageInfo func (m *EscalationPolicy) Reset() { *m = EscalationPolicy{} } func (*EscalationPolicy) ProtoMessage() {} func (*EscalationPolicy) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_551c1e60827e8aab, []int{3} + return fileDescriptor_generated_36ef0e7aa257cdc9, []int{4} } func (m *EscalationPolicy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -159,7 +187,7 @@ var xxx_messageInfo_EscalationPolicy proto.InternalMessageInfo func (m *Event) Reset() { *m = Event{} } func (*Event) ProtoMessage() {} func (*Event) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_551c1e60827e8aab, []int{4} + return fileDescriptor_generated_36ef0e7aa257cdc9, []int{5} } func (m *Event) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -187,7 +215,7 @@ var xxx_messageInfo_Event proto.InternalMessageInfo func (m *EventContext) Reset() { *m = EventContext{} } func (*EventContext) ProtoMessage() {} func (*EventContext) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_551c1e60827e8aab, []int{5} + return fileDescriptor_generated_36ef0e7aa257cdc9, []int{6} } func (m *EventContext) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -215,7 +243,7 @@ var xxx_messageInfo_EventContext proto.InternalMessageInfo func (m *EventWrapper) Reset() { *m = EventWrapper{} } func (*EventWrapper) ProtoMessage() {} func (*EventWrapper) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_551c1e60827e8aab, []int{6} + return fileDescriptor_generated_36ef0e7aa257cdc9, []int{7} } func (m *EventWrapper) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -243,7 +271,7 @@ var xxx_messageInfo_EventWrapper proto.InternalMessageInfo func (m *FileArtifact) Reset() { *m = FileArtifact{} } func (*FileArtifact) ProtoMessage() {} func (*FileArtifact) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_551c1e60827e8aab, []int{7} + return fileDescriptor_generated_36ef0e7aa257cdc9, []int{8} } func (m *FileArtifact) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -271,7 +299,7 @@ var xxx_messageInfo_FileArtifact proto.InternalMessageInfo func (m *GroupVersionKind) Reset() { *m = GroupVersionKind{} } func (*GroupVersionKind) ProtoMessage() {} func (*GroupVersionKind) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_551c1e60827e8aab, []int{8} + return fileDescriptor_generated_36ef0e7aa257cdc9, []int{9} } func (m *GroupVersionKind) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -299,7 +327,7 @@ var xxx_messageInfo_GroupVersionKind proto.InternalMessageInfo func (m *NodeStatus) Reset() { *m = NodeStatus{} } func (*NodeStatus) ProtoMessage() {} func (*NodeStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_551c1e60827e8aab, []int{9} + return fileDescriptor_generated_36ef0e7aa257cdc9, []int{10} } func (m *NodeStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -327,7 +355,7 @@ var xxx_messageInfo_NodeStatus proto.InternalMessageInfo func (m *ResourceObject) Reset() { *m = ResourceObject{} } func (*ResourceObject) ProtoMessage() {} func (*ResourceObject) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_551c1e60827e8aab, []int{10} + return fileDescriptor_generated_36ef0e7aa257cdc9, []int{11} } func (m *ResourceObject) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -355,7 +383,7 @@ var xxx_messageInfo_ResourceObject proto.InternalMessageInfo func (m *ResourceParameter) Reset() { *m = ResourceParameter{} } func (*ResourceParameter) ProtoMessage() {} func (*ResourceParameter) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_551c1e60827e8aab, []int{11} + return fileDescriptor_generated_36ef0e7aa257cdc9, []int{12} } func (m *ResourceParameter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -383,7 +411,7 @@ var xxx_messageInfo_ResourceParameter proto.InternalMessageInfo func (m *ResourceParameterSource) Reset() { *m = ResourceParameterSource{} } func (*ResourceParameterSource) ProtoMessage() {} func (*ResourceParameterSource) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_551c1e60827e8aab, []int{12} + return fileDescriptor_generated_36ef0e7aa257cdc9, []int{13} } func (m *ResourceParameterSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -411,7 +439,7 @@ var xxx_messageInfo_ResourceParameterSource proto.InternalMessageInfo func (m *RetryStrategy) Reset() { *m = RetryStrategy{} } func (*RetryStrategy) ProtoMessage() {} func (*RetryStrategy) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_551c1e60827e8aab, []int{13} + return fileDescriptor_generated_36ef0e7aa257cdc9, []int{14} } func (m *RetryStrategy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -439,7 +467,7 @@ var xxx_messageInfo_RetryStrategy proto.InternalMessageInfo func (m *S3Artifact) Reset() { *m = S3Artifact{} } func (*S3Artifact) ProtoMessage() {} func (*S3Artifact) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_551c1e60827e8aab, []int{14} + return fileDescriptor_generated_36ef0e7aa257cdc9, []int{15} } func (m *S3Artifact) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -467,7 +495,7 @@ var xxx_messageInfo_S3Artifact proto.InternalMessageInfo func (m *S3Bucket) Reset() { *m = S3Bucket{} } func (*S3Bucket) ProtoMessage() {} func (*S3Bucket) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_551c1e60827e8aab, []int{15} + return fileDescriptor_generated_36ef0e7aa257cdc9, []int{16} } func (m *S3Bucket) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -495,7 +523,7 @@ var xxx_messageInfo_S3Bucket proto.InternalMessageInfo func (m *S3Filter) Reset() { *m = S3Filter{} } func (*S3Filter) ProtoMessage() {} func (*S3Filter) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_551c1e60827e8aab, []int{16} + return fileDescriptor_generated_36ef0e7aa257cdc9, []int{17} } func (m *S3Filter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -523,7 +551,7 @@ var xxx_messageInfo_S3Filter proto.InternalMessageInfo func (m *Sensor) Reset() { *m = Sensor{} } func (*Sensor) ProtoMessage() {} func (*Sensor) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_551c1e60827e8aab, []int{17} + return fileDescriptor_generated_36ef0e7aa257cdc9, []int{18} } func (m *Sensor) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -551,7 +579,7 @@ var xxx_messageInfo_Sensor proto.InternalMessageInfo func (m *SensorList) Reset() { *m = SensorList{} } func (*SensorList) ProtoMessage() {} func (*SensorList) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_551c1e60827e8aab, []int{18} + return fileDescriptor_generated_36ef0e7aa257cdc9, []int{19} } func (m *SensorList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -579,7 +607,7 @@ var xxx_messageInfo_SensorList proto.InternalMessageInfo func (m *SensorSpec) Reset() { *m = SensorSpec{} } func (*SensorSpec) ProtoMessage() {} func (*SensorSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_551c1e60827e8aab, []int{19} + return fileDescriptor_generated_36ef0e7aa257cdc9, []int{20} } func (m *SensorSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -607,7 +635,7 @@ var xxx_messageInfo_SensorSpec proto.InternalMessageInfo func (m *SensorStatus) Reset() { *m = SensorStatus{} } func (*SensorStatus) ProtoMessage() {} func (*SensorStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_551c1e60827e8aab, []int{20} + return fileDescriptor_generated_36ef0e7aa257cdc9, []int{21} } func (m *SensorStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -635,7 +663,7 @@ var xxx_messageInfo_SensorStatus proto.InternalMessageInfo func (m *Signal) Reset() { *m = Signal{} } func (*Signal) ProtoMessage() {} func (*Signal) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_551c1e60827e8aab, []int{21} + return fileDescriptor_generated_36ef0e7aa257cdc9, []int{22} } func (m *Signal) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -663,7 +691,7 @@ var xxx_messageInfo_Signal proto.InternalMessageInfo func (m *SignalFilter) Reset() { *m = SignalFilter{} } func (*SignalFilter) ProtoMessage() {} func (*SignalFilter) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_551c1e60827e8aab, []int{22} + return fileDescriptor_generated_36ef0e7aa257cdc9, []int{23} } func (m *SignalFilter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -691,7 +719,7 @@ var xxx_messageInfo_SignalFilter proto.InternalMessageInfo func (m *TimeFilter) Reset() { *m = TimeFilter{} } func (*TimeFilter) ProtoMessage() {} func (*TimeFilter) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_551c1e60827e8aab, []int{23} + return fileDescriptor_generated_36ef0e7aa257cdc9, []int{24} } func (m *TimeFilter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -719,7 +747,7 @@ var xxx_messageInfo_TimeFilter proto.InternalMessageInfo func (m *Trigger) Reset() { *m = Trigger{} } func (*Trigger) ProtoMessage() {} func (*Trigger) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_551c1e60827e8aab, []int{24} + return fileDescriptor_generated_36ef0e7aa257cdc9, []int{25} } func (m *Trigger) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -747,7 +775,7 @@ var xxx_messageInfo_Trigger proto.InternalMessageInfo func (m *URI) Reset() { *m = URI{} } func (*URI) ProtoMessage() {} func (*URI) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_551c1e60827e8aab, []int{25} + return fileDescriptor_generated_36ef0e7aa257cdc9, []int{26} } func (m *URI) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -775,7 +803,7 @@ var xxx_messageInfo_URI proto.InternalMessageInfo func (m *URLArtifact) Reset() { *m = URLArtifact{} } func (*URLArtifact) ProtoMessage() {} func (*URLArtifact) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_551c1e60827e8aab, []int{26} + return fileDescriptor_generated_36ef0e7aa257cdc9, []int{27} } func (m *URLArtifact) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -802,6 +830,7 @@ var xxx_messageInfo_URLArtifact proto.InternalMessageInfo func init() { proto.RegisterType((*ArtifactLocation)(nil), "github.com.argoproj.argo_events.pkg.apis.sensor.v1alpha1.ArtifactLocation") + proto.RegisterType((*ConfigmapArtifact)(nil), "github.com.argoproj.argo_events.pkg.apis.sensor.v1alpha1.ConfigmapArtifact") proto.RegisterType((*Data)(nil), "github.com.argoproj.argo_events.pkg.apis.sensor.v1alpha1.Data") proto.RegisterType((*DataFilter)(nil), "github.com.argoproj.argo_events.pkg.apis.sensor.v1alpha1.DataFilter") proto.RegisterType((*EscalationPolicy)(nil), "github.com.argoproj.argo_events.pkg.apis.sensor.v1alpha1.EscalationPolicy") @@ -883,6 +912,46 @@ func (m *ArtifactLocation) MarshalTo(dAtA []byte) (int, error) { } i += n3 } + if m.Configmap != nil { + dAtA[i] = 0x2a + i++ + i = encodeVarintGenerated(dAtA, i, uint64(m.Configmap.Size())) + n4, err := m.Configmap.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n4 + } + return i, nil +} + +func (m *ConfigmapArtifact) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ConfigmapArtifact) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + dAtA[i] = 0xa + i++ + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) + i += copy(dAtA[i:], m.Name) + dAtA[i] = 0x12 + i++ + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Namespace))) + i += copy(dAtA[i:], m.Namespace) + dAtA[i] = 0x1a + i++ + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Key))) + i += copy(dAtA[i:], m.Key) return i, nil } @@ -917,11 +986,11 @@ func (m *Data) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.EscalationPolicy.Size())) - n4, err := m.EscalationPolicy.MarshalTo(dAtA[i:]) + n5, err := m.EscalationPolicy.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n4 + i += n5 } return i, nil } @@ -957,11 +1026,11 @@ func (m *DataFilter) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x22 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.EscalationPolicy.Size())) - n5, err := m.EscalationPolicy.MarshalTo(dAtA[i:]) + n6, err := m.EscalationPolicy.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n5 + i += n6 } return i, nil } @@ -1014,11 +1083,11 @@ func (m *Event) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Context.Size())) - n6, err := m.Context.MarshalTo(dAtA[i:]) + n7, err := m.Context.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n6 + i += n7 if m.Payload != nil { dAtA[i] = 0x12 i++ @@ -1059,11 +1128,11 @@ func (m *EventContext) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x22 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Source.Size())) - n7, err := m.Source.MarshalTo(dAtA[i:]) + n8, err := m.Source.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n7 + i += n8 } dAtA[i] = 0x2a i++ @@ -1072,20 +1141,20 @@ func (m *EventContext) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x32 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.EventTime.Size())) - n8, err := m.EventTime.MarshalTo(dAtA[i:]) + n9, err := m.EventTime.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n8 + i += n9 if m.SchemaURL != nil { dAtA[i] = 0x3a i++ i = encodeVarintGenerated(dAtA, i, uint64(m.SchemaURL.Size())) - n9, err := m.SchemaURL.MarshalTo(dAtA[i:]) + n10, err := m.SchemaURL.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n9 + i += n10 } dAtA[i] = 0x42 i++ @@ -1117,11 +1186,11 @@ func (m *EventContext) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x52 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.EscalationPolicy.Size())) - n10, err := m.EscalationPolicy.MarshalTo(dAtA[i:]) + n11, err := m.EscalationPolicy.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n10 + i += n11 } return i, nil } @@ -1144,11 +1213,11 @@ func (m *EventWrapper) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Event.Size())) - n11, err := m.Event.MarshalTo(dAtA[i:]) + n12, err := m.Event.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n11 + i += n12 dAtA[i] = 0x10 i++ if m.Seen { @@ -1250,19 +1319,19 @@ func (m *NodeStatus) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x32 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.StartedAt.Size())) - n12, err := m.StartedAt.MarshalTo(dAtA[i:]) + n13, err := m.StartedAt.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n12 + i += n13 dAtA[i] = 0x3a i++ i = encodeVarintGenerated(dAtA, i, uint64(m.CompletedAt.Size())) - n13, err := m.CompletedAt.MarshalTo(dAtA[i:]) + n14, err := m.CompletedAt.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n13 + i += n14 dAtA[i] = 0x42 i++ i = encodeVarintGenerated(dAtA, i, uint64(len(m.Message))) @@ -1271,11 +1340,11 @@ func (m *NodeStatus) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x4a i++ i = encodeVarintGenerated(dAtA, i, uint64(m.LatestEvent.Size())) - n14, err := m.LatestEvent.MarshalTo(dAtA[i:]) + n15, err := m.LatestEvent.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n14 + i += n15 } return i, nil } @@ -1336,19 +1405,19 @@ func (m *ResourceObject) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x2a i++ i = encodeVarintGenerated(dAtA, i, uint64(m.GroupVersionKind.Size())) - n15, err := m.GroupVersionKind.MarshalTo(dAtA[i:]) + n16, err := m.GroupVersionKind.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n15 + i += n16 dAtA[i] = 0x32 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Source.Size())) - n16, err := m.Source.MarshalTo(dAtA[i:]) + n17, err := m.Source.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n16 + i += n17 return i, nil } @@ -1371,11 +1440,11 @@ func (m *ResourceParameter) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Src.Size())) - n17, err := m.Src.MarshalTo(dAtA[i:]) + n18, err := m.Src.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n17 + i += n18 } dAtA[i] = 0x12 i++ @@ -1461,20 +1530,20 @@ func (m *S3Artifact) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1a i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Filter.Size())) - n18, err := m.Filter.MarshalTo(dAtA[i:]) + n19, err := m.Filter.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n18 + i += n19 } dAtA[i] = 0x22 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.S3Bucket.Size())) - n19, err := m.S3Bucket.MarshalTo(dAtA[i:]) + n20, err := m.S3Bucket.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n19 + i += n20 return i, nil } @@ -1516,19 +1585,19 @@ func (m *S3Bucket) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x2a i++ i = encodeVarintGenerated(dAtA, i, uint64(m.AccessKey.Size())) - n20, err := m.AccessKey.MarshalTo(dAtA[i:]) + n21, err := m.AccessKey.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n20 + i += n21 dAtA[i] = 0x32 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.SecretKey.Size())) - n21, err := m.SecretKey.MarshalTo(dAtA[i:]) + n22, err := m.SecretKey.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n21 + i += n22 return i, nil } @@ -1576,27 +1645,27 @@ func (m *Sensor) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintGenerated(dAtA, i, uint64(m.ObjectMeta.Size())) - n22, err := m.ObjectMeta.MarshalTo(dAtA[i:]) + n23, err := m.ObjectMeta.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n22 + i += n23 dAtA[i] = 0x12 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Spec.Size())) - n23, err := m.Spec.MarshalTo(dAtA[i:]) + n24, err := m.Spec.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n23 + i += n24 dAtA[i] = 0x1a i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Status.Size())) - n24, err := m.Status.MarshalTo(dAtA[i:]) + n25, err := m.Status.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n24 + i += n25 return i, nil } @@ -1618,11 +1687,11 @@ func (m *SensorList) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintGenerated(dAtA, i, uint64(m.ListMeta.Size())) - n25, err := m.ListMeta.MarshalTo(dAtA[i:]) + n26, err := m.ListMeta.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n25 + i += n26 if len(m.Items) > 0 { for _, msg := range m.Items { dAtA[i] = 0x12 @@ -1734,19 +1803,19 @@ func (m *SensorStatus) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.StartedAt.Size())) - n26, err := m.StartedAt.MarshalTo(dAtA[i:]) + n27, err := m.StartedAt.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n26 + i += n27 dAtA[i] = 0x1a i++ i = encodeVarintGenerated(dAtA, i, uint64(m.CompletedAt.Size())) - n27, err := m.CompletedAt.MarshalTo(dAtA[i:]) + n28, err := m.CompletedAt.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n27 + i += n28 dAtA[i] = 0x22 i++ i = encodeVarintGenerated(dAtA, i, uint64(len(m.Message))) @@ -1775,11 +1844,11 @@ func (m *SensorStatus) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintGenerated(dAtA, i, uint64((&v).Size())) - n28, err := (&v).MarshalTo(dAtA[i:]) + n29, err := (&v).MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n28 + i += n29 } } dAtA[i] = 0x30 @@ -1813,11 +1882,11 @@ func (m *Signal) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1a i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Filters.Size())) - n29, err := m.Filters.MarshalTo(dAtA[i:]) + n30, err := m.Filters.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n29 + i += n30 return i, nil } @@ -1844,31 +1913,31 @@ func (m *SignalFilter) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Time.Size())) - n30, err := m.Time.MarshalTo(dAtA[i:]) + n31, err := m.Time.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n30 + i += n31 } if m.Context != nil { dAtA[i] = 0x1a i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Context.Size())) - n31, err := m.Context.MarshalTo(dAtA[i:]) + n32, err := m.Context.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n31 + i += n32 } if m.Data != nil { dAtA[i] = 0x22 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Data.Size())) - n32, err := m.Data.MarshalTo(dAtA[i:]) + n33, err := m.Data.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n32 + i += n33 } return i, nil } @@ -1900,11 +1969,11 @@ func (m *TimeFilter) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1a i++ i = encodeVarintGenerated(dAtA, i, uint64(m.EscalationPolicy.Size())) - n33, err := m.EscalationPolicy.MarshalTo(dAtA[i:]) + n34, err := m.EscalationPolicy.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n33 + i += n34 } return i, nil } @@ -1932,11 +2001,11 @@ func (m *Trigger) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Resource.Size())) - n34, err := m.Resource.MarshalTo(dAtA[i:]) + n35, err := m.Resource.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n34 + i += n35 } dAtA[i] = 0x1a i++ @@ -1946,11 +2015,11 @@ func (m *Trigger) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x22 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.RetryStrategy.Size())) - n35, err := m.RetryStrategy.MarshalTo(dAtA[i:]) + n36, err := m.RetryStrategy.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n35 + i += n36 } return i, nil } @@ -2062,6 +2131,22 @@ func (m *ArtifactLocation) Size() (n int) { l = m.URL.Size() n += 1 + l + sovGenerated(uint64(l)) } + if m.Configmap != nil { + l = m.Configmap.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + return n +} + +func (m *ConfigmapArtifact) Size() (n int) { + var l int + _ = l + l = len(m.Name) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Namespace) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Key) + n += 1 + l + sovGenerated(uint64(l)) return n } @@ -2511,6 +2596,19 @@ func (this *ArtifactLocation) String() string { `Inline:` + valueToStringGenerated(this.Inline) + `,`, `File:` + strings.Replace(fmt.Sprintf("%v", this.File), "FileArtifact", "FileArtifact", 1) + `,`, `URL:` + strings.Replace(fmt.Sprintf("%v", this.URL), "URLArtifact", "URLArtifact", 1) + `,`, + `Configmap:` + strings.Replace(fmt.Sprintf("%v", this.Configmap), "ConfigmapArtifact", "ConfigmapArtifact", 1) + `,`, + `}`, + }, "") + return s +} +func (this *ConfigmapArtifact) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ConfigmapArtifact{`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, + `Namespace:` + fmt.Sprintf("%v", this.Namespace) + `,`, + `Key:` + fmt.Sprintf("%v", this.Key) + `,`, `}`, }, "") return s @@ -3045,6 +3143,176 @@ func (m *ArtifactLocation) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Configmap", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Configmap == nil { + m.Configmap = &ConfigmapArtifact{} + } + if err := m.Configmap.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ConfigmapArtifact) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ConfigmapArtifact: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ConfigmapArtifact: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Namespace", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Namespace = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Key = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -7666,162 +7934,166 @@ var ( ) func init() { - proto.RegisterFile("github.com/argoproj/argo-events/pkg/apis/sensor/v1alpha1/generated.proto", fileDescriptor_generated_551c1e60827e8aab) -} - -var fileDescriptor_generated_551c1e60827e8aab = []byte{ - // 2442 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x59, 0xdf, 0x6f, 0x1b, 0xc7, - 0xf1, 0xf7, 0xf1, 0x37, 0x47, 0x72, 0xa4, 0xec, 0x37, 0x40, 0x08, 0x01, 0x11, 0x8d, 0x33, 0xbe, - 0x41, 0x5a, 0xd8, 0xa4, 0x6d, 0x35, 0x81, 0x5b, 0x20, 0x6d, 0x44, 0x49, 0x8e, 0x65, 0xcb, 0x8e, - 0xbc, 0xb4, 0x55, 0xc0, 0x35, 0x50, 0xaf, 0x8e, 0x4b, 0xea, 0xac, 0xe3, 0xdd, 0x79, 0x77, 0xc9, - 0x9a, 0x40, 0xd1, 0x06, 0x41, 0x9f, 0x8a, 0x3e, 0xf8, 0xa9, 0x7d, 0xe8, 0x63, 0xff, 0x87, 0xbe, - 0x16, 0x68, 0x5f, 0x0c, 0x14, 0x05, 0x92, 0xb7, 0x3c, 0xb4, 0x44, 0xcd, 0x02, 0xf9, 0x23, 0xfc, - 0x54, 0xec, 0x8f, 0xfb, 0xc1, 0xa3, 0x54, 0xcb, 0xa2, 0x00, 0xbf, 0x10, 0xbc, 0x99, 0xd9, 0xcf, - 0xcc, 0xcd, 0xce, 0xce, 0xec, 0xcc, 0xc1, 0xcd, 0x9e, 0x2b, 0x0e, 0x06, 0xfb, 0x0d, 0x27, 0xe8, - 0x37, 0x09, 0xeb, 0x05, 0x21, 0x0b, 0x9e, 0xa8, 0x3f, 0x97, 0xe9, 0x90, 0xfa, 0x82, 0x37, 0xc3, - 0xc3, 0x5e, 0x93, 0x84, 0x2e, 0x6f, 0x72, 0xea, 0xf3, 0x80, 0x35, 0x87, 0x57, 0x89, 0x17, 0x1e, - 0x90, 0xab, 0xcd, 0x1e, 0xf5, 0x29, 0x23, 0x82, 0x76, 0x1a, 0x21, 0x0b, 0x44, 0x80, 0xae, 0x27, - 0x48, 0x8d, 0x08, 0x49, 0xfd, 0xf9, 0xb9, 0x46, 0x6a, 0x84, 0x87, 0xbd, 0x86, 0x44, 0x6a, 0x68, - 0xa4, 0x46, 0x84, 0xb4, 0x72, 0x39, 0x65, 0x43, 0x2f, 0xe8, 0x05, 0x4d, 0x05, 0xb8, 0x3f, 0xe8, - 0xaa, 0x27, 0xf5, 0xa0, 0xfe, 0x69, 0x45, 0x2b, 0xf6, 0xe1, 0x75, 0xde, 0x70, 0x03, 0x69, 0x55, - 0xd3, 0x09, 0x18, 0x6d, 0x0e, 0x67, 0x8c, 0x59, 0xf9, 0x41, 0x22, 0xd3, 0x27, 0xce, 0x81, 0xeb, - 0x53, 0x36, 0x4a, 0x5e, 0xa5, 0x4f, 0x05, 0x39, 0x6a, 0x55, 0xf3, 0xb8, 0x55, 0x6c, 0xe0, 0x0b, - 0xb7, 0x4f, 0x67, 0x16, 0x7c, 0xf2, 0xba, 0x05, 0xdc, 0x39, 0xa0, 0x7d, 0x32, 0xb3, 0x6e, 0xed, - 0xb8, 0x75, 0x03, 0xe1, 0x7a, 0x4d, 0xd7, 0x17, 0x5c, 0xb0, 0xec, 0x22, 0xfb, 0x9f, 0x39, 0x58, - 0x5e, 0x67, 0xc2, 0xed, 0x12, 0x47, 0xec, 0x04, 0x0e, 0x11, 0x6e, 0xe0, 0xa3, 0x47, 0x90, 0xe3, - 0x6b, 0x35, 0xeb, 0x82, 0xf5, 0xd1, 0xc2, 0xb5, 0xcd, 0xc6, 0x69, 0xb7, 0xa0, 0xd1, 0x5e, 0x8b, - 0x90, 0x5b, 0xa5, 0xc9, 0xb8, 0x9e, 0x6b, 0xaf, 0xe1, 0x1c, 0x5f, 0x43, 0x36, 0x94, 0x5c, 0xdf, - 0x73, 0x7d, 0x5a, 0xcb, 0x5d, 0xb0, 0x3e, 0xaa, 0xb6, 0x60, 0x32, 0xae, 0x97, 0xb6, 0x15, 0x05, - 0x1b, 0x0e, 0xea, 0x40, 0xa1, 0xeb, 0x7a, 0xb4, 0x96, 0x57, 0x36, 0xdc, 0x38, 0xbd, 0x0d, 0x37, - 0x5c, 0x8f, 0xc6, 0x56, 0x54, 0x26, 0xe3, 0x7a, 0x41, 0x52, 0xb0, 0x42, 0x47, 0x8f, 0x21, 0x3f, - 0x60, 0x5e, 0xad, 0xa0, 0x94, 0x6c, 0x9d, 0x5e, 0xc9, 0x03, 0xbc, 0x13, 0xeb, 0x28, 0x4f, 0xc6, - 0xf5, 0xfc, 0x03, 0xbc, 0x83, 0x25, 0xb4, 0xfd, 0x55, 0x0e, 0x0a, 0x9b, 0x44, 0x10, 0x74, 0x08, - 0xe5, 0xae, 0xeb, 0x09, 0xca, 0x78, 0xcd, 0xba, 0x90, 0x9f, 0xcf, 0xaf, 0x12, 0xf0, 0x86, 0x02, - 0x6b, 0x2d, 0x4c, 0xc6, 0xf5, 0xb2, 0xfe, 0xcf, 0x71, 0xa4, 0x01, 0xfd, 0xce, 0x82, 0x65, 0xca, - 0x1d, 0xe2, 0xa9, 0xed, 0xdc, 0x0d, 0x3c, 0xd7, 0x19, 0x29, 0x67, 0x2f, 0x5c, 0xbb, 0x75, 0x7a, - 0xb5, 0x5b, 0x19, 0xc4, 0xd6, 0x7b, 0x93, 0x71, 0x7d, 0x39, 0x4b, 0xc5, 0x33, 0x9a, 0xed, 0xe7, - 0x39, 0x80, 0xc4, 0x66, 0x74, 0x01, 0x0a, 0x21, 0x11, 0x07, 0x2a, 0xbe, 0xaa, 0xad, 0xc5, 0x17, - 0xe3, 0xfa, 0x39, 0xb9, 0x2f, 0xbb, 0x44, 0x1c, 0x60, 0xc5, 0x41, 0x97, 0xa0, 0x20, 0x46, 0x61, - 0x14, 0x1f, 0xb5, 0x48, 0xe2, 0xfe, 0x28, 0xa4, 0xaf, 0xc6, 0xf5, 0xca, 0xad, 0xf6, 0x17, 0x77, - 0xe5, 0x7f, 0xac, 0xa4, 0xd0, 0x45, 0x28, 0x0e, 0x89, 0x37, 0xd0, 0xc1, 0x52, 0x6d, 0x9d, 0x37, - 0xe2, 0xc5, 0x3d, 0x49, 0xc4, 0x9a, 0x77, 0xb4, 0x4b, 0x0a, 0x6f, 0xcd, 0x25, 0x7f, 0xb0, 0x60, - 0x46, 0x4c, 0x3a, 0xc6, 0x27, 0x7d, 0x9a, 0x75, 0xcc, 0x5d, 0xd2, 0xa7, 0x58, 0x71, 0xd0, 0x27, - 0x50, 0xf4, 0xe8, 0x90, 0x7a, 0xc6, 0x33, 0x17, 0xa2, 0x57, 0xdd, 0x91, 0xc4, 0x57, 0xe3, 0xfa, - 0x52, 0x82, 0xa9, 0x48, 0x58, 0x8b, 0xa3, 0xef, 0x41, 0xb9, 0x4f, 0x39, 0x27, 0xbd, 0xc8, 0x49, - 0x4b, 0x66, 0x65, 0xf9, 0x8e, 0x26, 0xe3, 0x88, 0x6f, 0xff, 0xd1, 0x82, 0xe2, 0x96, 0x7c, 0x6d, - 0xf4, 0x14, 0xca, 0x4e, 0xe0, 0x0b, 0xfa, 0x4c, 0x98, 0x54, 0x30, 0xc7, 0x31, 0x54, 0x88, 0x1b, - 0x1a, 0x2d, 0x51, 0x6e, 0x08, 0x38, 0xd2, 0x83, 0xea, 0x50, 0xe8, 0x10, 0x41, 0xd4, 0xeb, 0x2d, - 0xea, 0xe0, 0xde, 0x25, 0x23, 0x2f, 0x20, 0x1d, 0xac, 0x18, 0xf6, 0x5f, 0xca, 0xb0, 0x98, 0xc6, - 0x42, 0x4d, 0xa8, 0x2a, 0xdd, 0x32, 0x1e, 0x8c, 0xe3, 0xde, 0x35, 0xf0, 0xd5, 0xad, 0x88, 0x81, - 0x13, 0x19, 0xb4, 0x09, 0xcb, 0xf1, 0xc3, 0x1e, 0x65, 0xdc, 0x0d, 0xfc, 0x4c, 0x9c, 0x2d, 0x6f, - 0x65, 0xf8, 0x78, 0x66, 0x05, 0xba, 0x05, 0xc8, 0xf1, 0x82, 0x41, 0x47, 0x89, 0xf2, 0x08, 0x47, - 0xfb, 0x76, 0xc5, 0xe0, 0xa0, 0x8d, 0x19, 0x09, 0x7c, 0xc4, 0x2a, 0x44, 0xa0, 0xc4, 0x83, 0x01, - 0x73, 0xa8, 0x89, 0xc7, 0x4f, 0xe7, 0x49, 0x44, 0xdb, 0x3a, 0x9d, 0xb6, 0x15, 0x20, 0x36, 0xc0, - 0x72, 0xff, 0xd5, 0xd2, 0xed, 0xcd, 0x5a, 0x71, 0x7a, 0xff, 0xb7, 0x34, 0x19, 0x47, 0x7c, 0xf4, - 0x38, 0x72, 0xa8, 0xdb, 0xa7, 0xb5, 0x92, 0x32, 0xa8, 0xd9, 0xd0, 0x95, 0xa5, 0x91, 0xae, 0x2c, - 0x89, 0x11, 0xb2, 0xf0, 0x35, 0x86, 0x57, 0x1b, 0x77, 0x5c, 0x87, 0x05, 0x72, 0x59, 0x76, 0x07, - 0xdc, 0x7e, 0xbc, 0x03, 0x6e, 0x9f, 0xa2, 0x27, 0x50, 0xd5, 0x15, 0xec, 0x01, 0xde, 0xa9, 0x95, - 0xcf, 0xe2, 0x95, 0xcf, 0x4b, 0x5d, 0xed, 0x08, 0x13, 0x27, 0xf0, 0xe8, 0x63, 0x58, 0x50, 0xb1, - 0x65, 0x02, 0xa4, 0xa2, 0x5e, 0xfe, 0xff, 0x8c, 0x79, 0x0b, 0x1b, 0x09, 0x0b, 0xa7, 0xe5, 0xd0, - 0x6f, 0x2d, 0x00, 0xfa, 0x4c, 0x50, 0x5f, 0x6e, 0x10, 0xaf, 0x55, 0x55, 0xc6, 0xde, 0x3b, 0x9b, - 0xf0, 0x6f, 0x6c, 0xc5, 0xc0, 0x5b, 0xbe, 0x60, 0xa3, 0x16, 0x32, 0xe6, 0x40, 0xc2, 0xc0, 0x29, - 0xed, 0x47, 0xa7, 0x2e, 0x78, 0x5b, 0xa9, 0x6b, 0xe5, 0x53, 0x58, 0xca, 0xbc, 0x01, 0x5a, 0x86, - 0xfc, 0x21, 0x1d, 0xe9, 0xe3, 0x87, 0xe5, 0x5f, 0xf4, 0x5e, 0x94, 0x93, 0xd5, 0xd1, 0x32, 0x49, - 0xf8, 0x47, 0xb9, 0xeb, 0x96, 0xfd, 0x7b, 0xcb, 0x9c, 0xe0, 0x9f, 0x32, 0x12, 0x86, 0x94, 0xa1, - 0x0e, 0x14, 0x95, 0xad, 0x26, 0xc9, 0xfc, 0x64, 0x4e, 0x2f, 0x27, 0xf9, 0x5f, 0x3d, 0x62, 0x0d, - 0x2e, 0x73, 0x2b, 0xa7, 0x54, 0x1f, 0xf5, 0x4a, 0x92, 0x5b, 0xdb, 0x94, 0xfa, 0x58, 0x71, 0xec, - 0x2b, 0xb0, 0x98, 0xbe, 0x2c, 0xbc, 0xbe, 0x4c, 0xd9, 0xbf, 0xb1, 0x60, 0xf9, 0x73, 0x16, 0x0c, - 0x42, 0x73, 0x92, 0x6f, 0xbb, 0x7e, 0x47, 0x56, 0xa3, 0x9e, 0xa4, 0x99, 0x75, 0xb1, 0x35, 0x4a, - 0x10, 0x6b, 0x9e, 0x3c, 0x8f, 0xc3, 0xa9, 0xdc, 0x13, 0x9f, 0xc7, 0x28, 0x51, 0x44, 0x7c, 0x69, - 0xc6, 0xa1, 0xeb, 0x77, 0x4c, 0x6e, 0x89, 0xcd, 0x90, 0xba, 0xb0, 0xe2, 0xd8, 0xdf, 0x14, 0x00, - 0xee, 0x06, 0x1d, 0xda, 0x16, 0x44, 0x0c, 0x38, 0x5a, 0x81, 0x9c, 0xdb, 0x31, 0xda, 0xc1, 0x88, - 0xe7, 0xb6, 0x37, 0x71, 0xce, 0xed, 0xc4, 0x15, 0x26, 0x77, 0x6c, 0x85, 0xf9, 0x18, 0x16, 0x3a, - 0x2e, 0x0f, 0x3d, 0x32, 0x92, 0x44, 0xa3, 0x35, 0x3e, 0x30, 0x9b, 0x09, 0x0b, 0xa7, 0xe5, 0xe2, - 0x8a, 0x5d, 0x38, 0xba, 0x62, 0x4b, 0xf3, 0x52, 0x15, 0xfb, 0x0a, 0x14, 0xc3, 0x03, 0xc2, 0xa9, - 0x49, 0x46, 0x51, 0xc2, 0x2c, 0xee, 0x4a, 0xe2, 0xab, 0x71, 0xbd, 0x2a, 0xe5, 0xd5, 0x03, 0xd6, - 0x82, 0x32, 0x2b, 0x71, 0x41, 0x98, 0xa0, 0x9d, 0x75, 0x31, 0x77, 0x56, 0x6a, 0x47, 0x48, 0x38, - 0x01, 0x45, 0x5d, 0x99, 0x29, 0xfa, 0xa1, 0x47, 0xb5, 0x8e, 0xf2, 0xe9, 0x74, 0xa4, 0x52, 0x4b, - 0x8c, 0x85, 0xd3, 0xc0, 0xe9, 0x52, 0x5c, 0xf9, 0xdf, 0xa5, 0x18, 0x8d, 0x60, 0xc1, 0x23, 0x82, - 0x72, 0xa1, 0x22, 0xb9, 0x56, 0x3d, 0x93, 0x22, 0x6c, 0x8e, 0x5d, 0x6b, 0x49, 0x5a, 0xb9, 0x93, - 0xc0, 0xe3, 0xb4, 0x2e, 0xfb, 0xab, 0x22, 0xbc, 0x83, 0xa9, 0xae, 0x1e, 0x5f, 0xec, 0x3f, 0xa1, - 0x8e, 0xaa, 0xb4, 0x32, 0x42, 0x78, 0x48, 0x9c, 0x99, 0x4a, 0x7b, 0x37, 0x62, 0xe0, 0x44, 0x06, - 0xfd, 0x12, 0x4a, 0x1e, 0xd9, 0xa7, 0x1e, 0xaf, 0xe5, 0x55, 0xfe, 0xbc, 0x7f, 0x7a, 0xcb, 0xa7, - 0x4d, 0x69, 0xec, 0x28, 0x58, 0x9d, 0x3d, 0xdf, 0x31, 0x36, 0x94, 0x34, 0x11, 0x1b, 0x9d, 0xe8, - 0xd7, 0x00, 0x21, 0x61, 0xa4, 0x4f, 0xd5, 0x9d, 0xbb, 0xa0, 0x2c, 0xb8, 0x3d, 0xbf, 0x05, 0xbb, - 0x11, 0x66, 0x92, 0xb6, 0x63, 0x12, 0xc7, 0x29, 0x95, 0xe8, 0xb9, 0x05, 0xcb, 0xbd, 0x4c, 0x76, - 0x50, 0x01, 0x3f, 0x57, 0xda, 0xce, 0xe6, 0x9b, 0xe4, 0xd6, 0x92, 0xe5, 0xe0, 0x19, 0xed, 0x88, - 0xc5, 0x37, 0x8d, 0xd2, 0xbc, 0x76, 0x64, 0x7b, 0xc6, 0x64, 0x1f, 0xa6, 0xaf, 0x1e, 0x2b, 0x3f, - 0x84, 0x85, 0xd4, 0x76, 0xbd, 0x51, 0xa9, 0xf8, 0x93, 0x05, 0xef, 0xce, 0xf8, 0x1d, 0x79, 0x90, - 0xe7, 0xcc, 0x31, 0xd5, 0xe2, 0xde, 0x19, 0xee, 0xa8, 0x36, 0x5c, 0x37, 0x70, 0x6d, 0xe6, 0x60, - 0xa9, 0x46, 0x66, 0xcc, 0x0e, 0xe5, 0x22, 0x9b, 0x31, 0x37, 0x29, 0x17, 0x58, 0x71, 0x64, 0x15, - 0x78, 0xff, 0x18, 0x2c, 0xf4, 0x21, 0x94, 0xb8, 0xdb, 0xf3, 0x89, 0x67, 0x0e, 0x4c, 0xe2, 0x24, - 0x45, 0xc5, 0x86, 0x1b, 0xd7, 0x9a, 0xdc, 0xb1, 0x2d, 0x51, 0x7d, 0xba, 0xc9, 0xa9, 0x66, 0x1b, - 0x1c, 0x7b, 0x09, 0xce, 0x63, 0x2a, 0xd8, 0xa8, 0x2d, 0x64, 0x7b, 0xdf, 0x1b, 0xd9, 0xff, 0xca, - 0x01, 0x24, 0x1d, 0x38, 0xfa, 0x20, 0xe5, 0xf8, 0xd6, 0x82, 0xd1, 0x90, 0xbf, 0x4d, 0x47, 0x7a, - 0x17, 0xf6, 0xa2, 0x2a, 0xac, 0x4d, 0xf8, 0x6c, 0xaa, 0x88, 0xbe, 0x1a, 0xd7, 0x9b, 0xa9, 0x71, - 0x4a, 0xdf, 0xf5, 0xdd, 0x40, 0xff, 0x5e, 0xee, 0x05, 0x8d, 0xbb, 0x81, 0x70, 0xbb, 0xae, 0x0e, - 0x83, 0xe4, 0xca, 0x6d, 0xea, 0x6e, 0x17, 0x4a, 0xba, 0x2b, 0x35, 0xad, 0x7c, 0x6b, 0x9e, 0x71, - 0x82, 0x69, 0x7a, 0xd5, 0x0d, 0x57, 0xff, 0xc7, 0x06, 0x1d, 0x85, 0x50, 0xe1, 0x6b, 0xad, 0x81, - 0x73, 0x48, 0x85, 0xb9, 0x46, 0xcf, 0xa5, 0x49, 0x23, 0xb5, 0x96, 0x8d, 0x1b, 0x2a, 0x11, 0x05, - 0xc7, 0x5a, 0xec, 0xef, 0x72, 0x10, 0x93, 0xd1, 0x25, 0xa8, 0x50, 0xbf, 0x13, 0x06, 0xae, 0xb9, - 0xc7, 0x54, 0x93, 0xa5, 0x5b, 0x86, 0x8e, 0x63, 0x09, 0x19, 0x16, 0xfb, 0xda, 0xd4, 0xdc, 0x74, - 0x58, 0x18, 0x25, 0x86, 0x2b, 0xe5, 0x18, 0xed, 0x25, 0x9d, 0x45, 0x2c, 0x87, 0x15, 0x15, 0x1b, - 0xae, 0xd4, 0xee, 0xfa, 0x9c, 0x3a, 0x03, 0xa6, 0x2b, 0x70, 0x25, 0xd1, 0xbe, 0x6d, 0xe8, 0x38, - 0x96, 0x40, 0x7b, 0x50, 0x25, 0x8e, 0x43, 0x39, 0xbf, 0x4d, 0x47, 0x26, 0x21, 0xfd, 0x7f, 0xaa, - 0xce, 0x35, 0x9c, 0x80, 0x51, 0x59, 0xd5, 0xda, 0xd4, 0x61, 0x54, 0xdc, 0xa6, 0xa3, 0x36, 0xf5, - 0xa8, 0x23, 0x02, 0x96, 0xe4, 0xfb, 0xf5, 0x68, 0x3d, 0x4e, 0xa0, 0x24, 0x2e, 0x8f, 0x96, 0x98, - 0x04, 0xf3, 0xa6, 0xb8, 0x31, 0x0b, 0x27, 0x50, 0xf6, 0x43, 0xe9, 0x67, 0x33, 0x3b, 0xf8, 0x10, - 0x4a, 0x21, 0xa3, 0x5d, 0xf7, 0x59, 0xf6, 0x40, 0xed, 0x2a, 0x2a, 0x36, 0x5c, 0x75, 0xf0, 0x06, - 0x5d, 0x29, 0x97, 0xf1, 0x70, 0x5b, 0x51, 0xb1, 0xe1, 0xda, 0x7f, 0xcd, 0x41, 0xa9, 0xad, 0x76, - 0x1f, 0x3d, 0x86, 0x8a, 0xac, 0xe7, 0xaa, 0xff, 0xd4, 0xc9, 0xe5, 0xca, 0xc9, 0xaa, 0xbf, 0x2e, - 0x4a, 0x77, 0xa8, 0x20, 0x49, 0x4d, 0x48, 0x68, 0x38, 0x46, 0x45, 0x5d, 0x28, 0xf0, 0x90, 0x3a, - 0x66, 0x12, 0x33, 0xcf, 0x60, 0x4d, 0x3d, 0xb7, 0x43, 0xea, 0xa4, 0x6e, 0xb2, 0x21, 0x75, 0xb0, - 0xc2, 0x47, 0x3e, 0x94, 0xb8, 0xba, 0x0b, 0xce, 0x3f, 0x3e, 0x33, 0x9a, 0x14, 0x5a, 0xca, 0x89, - 0xea, 0x19, 0x1b, 0x2d, 0xf6, 0x37, 0x16, 0x80, 0x16, 0xdc, 0x71, 0xb9, 0x40, 0x8f, 0x66, 0x1c, - 0xd9, 0x38, 0x99, 0x23, 0xe5, 0x6a, 0xe5, 0xc6, 0x38, 0x7a, 0x23, 0x4a, 0xca, 0x89, 0x14, 0x8a, - 0xae, 0xa0, 0x7d, 0x5e, 0xcb, 0xa9, 0x92, 0xfe, 0xd9, 0xbc, 0xef, 0x96, 0xdc, 0xd0, 0xb7, 0x25, - 0x2c, 0xd6, 0xe8, 0xf6, 0xdf, 0x0a, 0xd1, 0x3b, 0x49, 0xc7, 0xa2, 0x43, 0x28, 0xeb, 0x54, 0x1d, - 0x8d, 0xef, 0xe6, 0xd1, 0xab, 0x80, 0x92, 0x7b, 0x9f, 0x7e, 0xe6, 0x38, 0xd2, 0x80, 0x02, 0xa8, - 0x08, 0xe6, 0xf6, 0x7a, 0xf2, 0xe2, 0xa2, 0xdf, 0x72, 0xfd, 0xf4, 0xda, 0xee, 0x6b, 0xa4, 0xc4, - 0xa7, 0x86, 0xc0, 0x71, 0xac, 0x44, 0xe7, 0x99, 0x90, 0x12, 0x61, 0xb2, 0x47, 0x2a, 0xcf, 0x48, - 0x2a, 0x36, 0x5c, 0xb4, 0x0f, 0x4b, 0x6e, 0x9f, 0xf4, 0xe8, 0xee, 0xc0, 0xf3, 0x4c, 0x1f, 0xaa, - 0x6f, 0xf0, 0xd7, 0xcd, 0x82, 0xa5, 0xed, 0x69, 0xf6, 0xab, 0x71, 0xfd, 0x83, 0xd9, 0xc1, 0x7a, - 0x23, 0x11, 0xc0, 0x59, 0x40, 0x74, 0x0b, 0x10, 0xa7, 0x6c, 0xe8, 0x3a, 0x74, 0xdd, 0x71, 0x82, - 0x81, 0x2f, 0x54, 0x1f, 0x52, 0x9a, 0x9e, 0xac, 0xb4, 0x67, 0x24, 0xf0, 0x11, 0xab, 0xd0, 0x16, - 0x94, 0xa9, 0x3f, 0xdc, 0x23, 0x8c, 0xd7, 0xca, 0xca, 0x8f, 0x2b, 0x47, 0xe5, 0xa3, 0x2d, 0x25, - 0x92, 0x1a, 0x89, 0xe8, 0x25, 0x38, 0x5a, 0x8b, 0xae, 0xc3, 0xa2, 0xb2, 0x32, 0x1a, 0xf3, 0xe8, - 0x7b, 0xfb, 0x7b, 0x46, 0x7e, 0x71, 0x3b, 0xc5, 0xc3, 0x53, 0x92, 0xf6, 0x77, 0x05, 0x58, 0x4c, - 0x1f, 0xa1, 0xa4, 0xf3, 0xb1, 0x4e, 0xda, 0xf9, 0xfc, 0x2c, 0xdd, 0xf9, 0xe8, 0xcc, 0xf1, 0xfd, - 0x93, 0x1d, 0xa7, 0x13, 0x34, 0x3d, 0x64, 0xba, 0xe9, 0xc9, 0xbf, 0x31, 0xfc, 0x1b, 0xf5, 0x3b, - 0x85, 0xd7, 0xf4, 0x3b, 0x43, 0x28, 0xfa, 0x41, 0x87, 0xf2, 0x5a, 0x51, 0x6d, 0xd6, 0xbd, 0xb3, - 0x49, 0x5b, 0x0d, 0xe9, 0x52, 0xd3, 0x2c, 0xc4, 0x67, 0x5d, 0xd1, 0xb0, 0x56, 0x87, 0xd6, 0x61, - 0xc9, 0x58, 0xec, 0x06, 0xfe, 0x86, 0x8c, 0x1e, 0x15, 0x6f, 0xc5, 0xd6, 0xfb, 0x51, 0x58, 0x6f, - 0x4c, 0xb3, 0x71, 0x56, 0x7e, 0xe5, 0x57, 0xba, 0x05, 0x3f, 0xf6, 0x92, 0xfb, 0x30, 0x7d, 0xc9, - 0x9d, 0x2b, 0xf7, 0x27, 0x9d, 0x7e, 0xfa, 0xaa, 0xfc, 0x77, 0x0b, 0xcc, 0x9d, 0xf2, 0x04, 0x53, - 0xe4, 0x4b, 0x50, 0xe9, 0x50, 0xd2, 0x89, 0x3f, 0xc1, 0xe4, 0x93, 0xe4, 0xb0, 0x69, 0xe8, 0x38, - 0x96, 0x40, 0x4f, 0x93, 0x2f, 0x17, 0xf3, 0x97, 0x13, 0x65, 0xa2, 0xb9, 0xc6, 0xc5, 0x81, 0x90, - 0xfd, 0x7e, 0x61, 0xbf, 0xcc, 0xc1, 0x62, 0x5a, 0xf4, 0x04, 0xef, 0xb4, 0x0f, 0x05, 0xe1, 0xf6, - 0xcf, 0xc0, 0xbf, 0x32, 0xac, 0x8d, 0x81, 0xea, 0x73, 0x91, 0x9a, 0x5e, 0x2a, 0x6c, 0xd4, 0x4f, - 0x06, 0xe2, 0xf9, 0x33, 0x1d, 0x88, 0x2f, 0x1c, 0x39, 0x0c, 0x7f, 0x64, 0x86, 0xe1, 0xfa, 0x3a, - 0xfb, 0xe3, 0xf9, 0xbe, 0x17, 0xe9, 0x97, 0x91, 0xff, 0xcc, 0x24, 0x7d, 0x62, 0x01, 0x24, 0xef, - 0x8a, 0x2e, 0x42, 0x51, 0xa5, 0x85, 0xec, 0xd8, 0x4a, 0xa5, 0x0d, 0xac, 0x79, 0x6a, 0x88, 0x26, - 0x82, 0x30, 0xdb, 0xa6, 0xb4, 0x45, 0x10, 0x62, 0xc5, 0x39, 0x7a, 0x56, 0x99, 0x7f, 0x6b, 0x9f, - 0x59, 0xfe, 0x91, 0x83, 0xb2, 0xa9, 0x77, 0x27, 0x88, 0x21, 0x06, 0x15, 0x66, 0x1a, 0x39, 0x13, - 0x47, 0x37, 0xcf, 0x6a, 0x64, 0xd1, 0x5a, 0x94, 0xa7, 0x2b, 0xa2, 0xe1, 0x58, 0xcf, 0x1b, 0x7c, - 0x99, 0x41, 0x5f, 0x5a, 0x70, 0x9e, 0xd1, 0xd0, 0x8b, 0x5b, 0x3c, 0x13, 0x19, 0x9f, 0xcf, 0x63, - 0x64, 0xaa, 0x63, 0x6c, 0xbd, 0x3b, 0x19, 0xd7, 0xa7, 0x9b, 0x48, 0x3c, 0xad, 0xd0, 0xfe, 0x73, - 0x0e, 0xf2, 0x0f, 0xf0, 0xb6, 0xba, 0x5e, 0x3b, 0x07, 0x34, 0xf6, 0x66, 0x72, 0x33, 0x54, 0x54, - 0x6c, 0xb8, 0xd2, 0xe7, 0x03, 0x4e, 0x59, 0x36, 0x60, 0x1e, 0x70, 0xca, 0xb0, 0xe2, 0xc8, 0x5c, - 0x14, 0x12, 0xce, 0x7f, 0x11, 0xb0, 0x68, 0xc4, 0x19, 0xe7, 0xa2, 0x5d, 0x43, 0xc7, 0xb1, 0x84, - 0xc4, 0x3b, 0x08, 0xb8, 0x30, 0x95, 0x24, 0xc6, 0xbb, 0x19, 0xc8, 0x6e, 0x5c, 0x72, 0x54, 0x27, - 0x1d, 0x30, 0xa1, 0xee, 0x25, 0xc5, 0x54, 0x27, 0x1d, 0x30, 0x81, 0x15, 0x27, 0xee, 0xb5, 0x4b, - 0xc7, 0xf6, 0xda, 0x17, 0xa1, 0xf8, 0x74, 0x40, 0xd9, 0x48, 0x0d, 0x01, 0x53, 0x67, 0xe1, 0x9e, - 0x24, 0x62, 0xcd, 0x93, 0x86, 0x77, 0x19, 0xe9, 0xf5, 0x65, 0xcf, 0x5c, 0x99, 0x36, 0xfc, 0x86, - 0xa1, 0xe3, 0x58, 0xc2, 0x76, 0x60, 0x21, 0xf5, 0x91, 0xf8, 0x04, 0x9f, 0x40, 0xaf, 0x01, 0x0c, - 0x29, 0x73, 0xbb, 0xa3, 0x0d, 0xca, 0x84, 0x99, 0x5a, 0xc7, 0xdd, 0xc5, 0x5e, 0xcc, 0xc1, 0x29, - 0xa9, 0x56, 0xe3, 0xc5, 0xcb, 0xd5, 0x73, 0x5f, 0xbf, 0x5c, 0x3d, 0xf7, 0xed, 0xcb, 0xd5, 0x73, - 0x5f, 0x4e, 0x56, 0xad, 0x17, 0x93, 0x55, 0xeb, 0xeb, 0xc9, 0xaa, 0xf5, 0xed, 0x64, 0xd5, 0xfa, - 0xf7, 0x64, 0xd5, 0x7a, 0xfe, 0x9f, 0xd5, 0x73, 0x0f, 0x2b, 0xd1, 0xee, 0xff, 0x37, 0x00, 0x00, - 0xff, 0xff, 0x9d, 0x0e, 0x36, 0x28, 0xa7, 0x21, 0x00, 0x00, + proto.RegisterFile("github.com/argoproj/argo-events/pkg/apis/sensor/v1alpha1/generated.proto", fileDescriptor_generated_36ef0e7aa257cdc9) +} + +var fileDescriptor_generated_36ef0e7aa257cdc9 = []byte{ + // 2498 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x59, 0xcd, 0x6f, 0x1b, 0xc7, + 0x15, 0xf7, 0xf2, 0x9b, 0x4f, 0x72, 0x24, 0x4f, 0x03, 0x84, 0x10, 0x10, 0xd1, 0x58, 0xa3, 0x41, + 0x5a, 0xd8, 0xa4, 0x6d, 0x35, 0x81, 0x5b, 0x20, 0x6d, 0x44, 0x49, 0x8e, 0x65, 0xc9, 0x8e, 0x3c, + 0xb4, 0x55, 0xc0, 0x35, 0x50, 0x8f, 0x96, 0x43, 0x6a, 0xad, 0xe5, 0xee, 0x7a, 0x66, 0xa8, 0x9a, + 0x40, 0xd1, 0x06, 0x41, 0x7b, 0x29, 0x7a, 0xf0, 0xa9, 0x3d, 0xf4, 0xd8, 0xff, 0xa1, 0xd7, 0x02, + 0xed, 0xc5, 0x40, 0x51, 0x20, 0xb9, 0x14, 0xb9, 0x94, 0xa8, 0x59, 0x20, 0x7f, 0x84, 0x4f, 0xc5, + 0x7c, 0xec, 0x07, 0x97, 0x52, 0x2d, 0x8b, 0x02, 0x7c, 0x91, 0xb8, 0xef, 0xbd, 0xf9, 0xbd, 0xb7, + 0x6f, 0x66, 0xde, 0xd7, 0xc2, 0xad, 0x9e, 0x2b, 0xf6, 0x07, 0x7b, 0x0d, 0x27, 0xe8, 0x37, 0x09, + 0xeb, 0x05, 0x21, 0x0b, 0x9e, 0xa8, 0x1f, 0x57, 0xe8, 0x21, 0xf5, 0x05, 0x6f, 0x86, 0x07, 0xbd, + 0x26, 0x09, 0x5d, 0xde, 0xe4, 0xd4, 0xe7, 0x01, 0x6b, 0x1e, 0x5e, 0x23, 0x5e, 0xb8, 0x4f, 0xae, + 0x35, 0x7b, 0xd4, 0xa7, 0x8c, 0x08, 0xda, 0x69, 0x84, 0x2c, 0x10, 0x01, 0xba, 0x91, 0x20, 0x35, + 0x22, 0x24, 0xf5, 0xe3, 0xe7, 0x1a, 0xa9, 0x11, 0x1e, 0xf4, 0x1a, 0x12, 0xa9, 0xa1, 0x91, 0x1a, + 0x11, 0xd2, 0xd2, 0x95, 0x94, 0x0d, 0xbd, 0xa0, 0x17, 0x34, 0x15, 0xe0, 0xde, 0xa0, 0xab, 0x9e, + 0xd4, 0x83, 0xfa, 0xa5, 0x15, 0x2d, 0xd9, 0x07, 0x37, 0x78, 0xc3, 0x0d, 0xa4, 0x55, 0x4d, 0x27, + 0x60, 0xb4, 0x79, 0x38, 0x65, 0xcc, 0xd2, 0x0f, 0x12, 0x99, 0x3e, 0x71, 0xf6, 0x5d, 0x9f, 0xb2, + 0x61, 0xf2, 0x2a, 0x7d, 0x2a, 0xc8, 0x51, 0xab, 0x9a, 0xc7, 0xad, 0x62, 0x03, 0x5f, 0xb8, 0x7d, + 0x3a, 0xb5, 0xe0, 0xe3, 0xd7, 0x2d, 0xe0, 0xce, 0x3e, 0xed, 0x93, 0xa9, 0x75, 0x2b, 0xc7, 0xad, + 0x1b, 0x08, 0xd7, 0x6b, 0xba, 0xbe, 0xe0, 0x82, 0x65, 0x17, 0xd9, 0xff, 0xca, 0xc3, 0xe2, 0x2a, + 0x13, 0x6e, 0x97, 0x38, 0x62, 0x3b, 0x70, 0x88, 0x70, 0x03, 0x1f, 0x3d, 0x82, 0x1c, 0x5f, 0xa9, + 0x59, 0x17, 0xad, 0x0f, 0xe7, 0xae, 0xaf, 0x37, 0x4e, 0xbb, 0x05, 0x8d, 0xf6, 0x4a, 0x84, 0xdc, + 0x2a, 0x8d, 0x47, 0xf5, 0x5c, 0x7b, 0x05, 0xe7, 0xf8, 0x0a, 0xb2, 0xa1, 0xe4, 0xfa, 0x9e, 0xeb, + 0xd3, 0x5a, 0xee, 0xa2, 0xf5, 0x61, 0xb5, 0x05, 0xe3, 0x51, 0xbd, 0xb4, 0xa9, 0x28, 0xd8, 0x70, + 0x50, 0x07, 0x0a, 0x5d, 0xd7, 0xa3, 0xb5, 0xbc, 0xb2, 0xe1, 0xe6, 0xe9, 0x6d, 0xb8, 0xe9, 0x7a, + 0x34, 0xb6, 0xa2, 0x32, 0x1e, 0xd5, 0x0b, 0x92, 0x82, 0x15, 0x3a, 0x7a, 0x0c, 0xf9, 0x01, 0xf3, + 0x6a, 0x05, 0xa5, 0x64, 0xe3, 0xf4, 0x4a, 0x1e, 0xe0, 0xed, 0x58, 0x47, 0x79, 0x3c, 0xaa, 0xe7, + 0x1f, 0xe0, 0x6d, 0x2c, 0xa1, 0xd1, 0x33, 0xa8, 0x3a, 0x81, 0xdf, 0x75, 0x7b, 0x7d, 0x12, 0xd6, + 0x8a, 0x4a, 0xcf, 0xd6, 0xe9, 0xf5, 0xac, 0x45, 0x50, 0xb1, 0xb6, 0xf3, 0xe3, 0x51, 0xbd, 0x1a, + 0x93, 0x71, 0xa2, 0xcc, 0xfe, 0xad, 0x05, 0x17, 0xa6, 0xe4, 0xd1, 0x45, 0x28, 0xf8, 0xa4, 0x4f, + 0xd5, 0xde, 0x56, 0x5b, 0xf3, 0x2f, 0x46, 0xf5, 0x73, 0xd2, 0x27, 0x77, 0x49, 0x9f, 0x62, 0xc5, + 0x41, 0x4d, 0xa8, 0xca, 0xff, 0x3c, 0x24, 0x4e, 0xb4, 0x41, 0x17, 0x8c, 0x58, 0xf5, 0x6e, 0xc4, + 0xc0, 0x89, 0x0c, 0x7a, 0x1f, 0xf2, 0x07, 0x74, 0xa8, 0x76, 0xaa, 0xda, 0x9a, 0x33, 0xa2, 0xf9, + 0x2d, 0x3a, 0xc4, 0x92, 0x6e, 0x7f, 0x99, 0x83, 0xc2, 0x3a, 0x11, 0x04, 0x1d, 0x40, 0xb9, 0xeb, + 0x7a, 0x82, 0x32, 0x5e, 0xb3, 0x2e, 0xe6, 0x67, 0x3b, 0x59, 0x12, 0xf0, 0xa6, 0x02, 0x6b, 0xcd, + 0x8d, 0x47, 0xf5, 0xb2, 0xfe, 0xcd, 0x71, 0xa4, 0x01, 0xfd, 0xde, 0x82, 0x45, 0xca, 0x1d, 0xe2, + 0xa9, 0x03, 0xbd, 0x13, 0x78, 0xae, 0x33, 0x54, 0x6f, 0x33, 0x77, 0xfd, 0xf6, 0xe9, 0xd5, 0x6e, + 0x64, 0x10, 0x5b, 0xef, 0x8e, 0x47, 0xf5, 0xc5, 0x2c, 0x15, 0x4f, 0x69, 0xb6, 0x9f, 0xe7, 0x00, + 0x12, 0x9b, 0xe5, 0x2e, 0x84, 0x44, 0xec, 0x67, 0x77, 0x61, 0x87, 0x88, 0x7d, 0xac, 0x38, 0xe8, + 0x32, 0x14, 0xc4, 0x30, 0x8c, 0x36, 0xa0, 0x16, 0x49, 0xdc, 0x1f, 0x86, 0xf4, 0xd5, 0xa8, 0x5e, + 0xb9, 0xdd, 0xfe, 0xfc, 0xae, 0xfc, 0x8d, 0x95, 0x14, 0xba, 0x04, 0xc5, 0x43, 0xe2, 0x0d, 0xa8, + 0xd9, 0x84, 0xf3, 0x46, 0xbc, 0xb8, 0x2b, 0x89, 0x58, 0xf3, 0x8e, 0x76, 0x49, 0xe1, 0xad, 0xb9, + 0xe4, 0x8f, 0x16, 0x4c, 0x89, 0x9d, 0xe0, 0x78, 0x7e, 0x0c, 0x45, 0x8f, 0x1e, 0x52, 0xcf, 0x78, + 0xe6, 0x62, 0xf4, 0xaa, 0xdb, 0x92, 0xf8, 0x6a, 0x54, 0x5f, 0x48, 0x30, 0x15, 0x09, 0x6b, 0x71, + 0xf4, 0x3d, 0x28, 0xf7, 0x29, 0xe7, 0xa4, 0x17, 0x39, 0x69, 0xc1, 0xac, 0x2c, 0xdf, 0xd1, 0x64, + 0x1c, 0xf1, 0xed, 0x3f, 0x59, 0x50, 0xdc, 0x90, 0xaf, 0x8d, 0x9e, 0x42, 0xd9, 0x09, 0x7c, 0x41, + 0x9f, 0x09, 0x13, 0x0c, 0x67, 0x08, 0x44, 0x0a, 0x71, 0x4d, 0xa3, 0x25, 0xca, 0x0d, 0x01, 0x47, + 0x7a, 0x50, 0x1d, 0x0a, 0x1d, 0x22, 0x88, 0x7a, 0xbd, 0x79, 0x7d, 0xb8, 0x77, 0xc8, 0xd0, 0x0b, + 0x48, 0x07, 0x2b, 0x86, 0xfd, 0xd7, 0x32, 0xcc, 0xa7, 0xb1, 0xe4, 0x85, 0x55, 0xba, 0xe5, 0x79, + 0x30, 0x8e, 0x8b, 0x2f, 0xec, 0x46, 0xc4, 0xc0, 0x89, 0x0c, 0x5a, 0x87, 0xc5, 0xf8, 0x61, 0x97, + 0x32, 0xee, 0x06, 0x7e, 0xe6, 0x9c, 0x2d, 0x6e, 0x64, 0xf8, 0x78, 0x6a, 0x05, 0xba, 0x0d, 0xc8, + 0xf1, 0x82, 0x41, 0x47, 0x89, 0xf2, 0x08, 0x47, 0xfb, 0x76, 0xc9, 0xe0, 0xa0, 0xb5, 0x29, 0x09, + 0x7c, 0xc4, 0x2a, 0x44, 0xa0, 0xc4, 0x83, 0x01, 0x73, 0xa8, 0x39, 0x8f, 0x9f, 0xcc, 0x12, 0x8a, + 0x37, 0x75, 0x42, 0x69, 0x2b, 0x40, 0x6c, 0x80, 0xe5, 0xfe, 0xab, 0xa5, 0x9b, 0xeb, 0x2a, 0x0c, + 0xa7, 0xf6, 0x7f, 0x43, 0x93, 0x71, 0xc4, 0x47, 0x8f, 0x23, 0x87, 0xba, 0x7d, 0x5a, 0x2b, 0x29, + 0x83, 0x9a, 0x0d, 0x9d, 0x5b, 0x1b, 0xe9, 0xdc, 0x9a, 0x18, 0x21, 0x53, 0x7f, 0xe3, 0xf0, 0x5a, + 0xe3, 0x8e, 0xeb, 0xb0, 0x40, 0x2e, 0xcb, 0xee, 0x80, 0xdb, 0x8f, 0x77, 0xc0, 0xed, 0x53, 0xf4, + 0x04, 0xaa, 0x3a, 0x87, 0x3f, 0xc0, 0xdb, 0xb5, 0xf2, 0x59, 0xbc, 0xb2, 0xca, 0x03, 0xed, 0x08, + 0x13, 0x27, 0xf0, 0xe8, 0x23, 0x98, 0x53, 0x67, 0xcb, 0x1c, 0x90, 0x8a, 0x7a, 0xf9, 0xef, 0x18, + 0xf3, 0xe6, 0xd6, 0x12, 0x16, 0x4e, 0xcb, 0xa1, 0xdf, 0x59, 0x00, 0xf4, 0x99, 0xa0, 0xbe, 0xdc, + 0x20, 0x5e, 0xab, 0xaa, 0x88, 0xbd, 0x7b, 0x36, 0xc7, 0xbf, 0xb1, 0x11, 0x03, 0x6f, 0xf8, 0x82, + 0x0d, 0x5b, 0xc8, 0x98, 0x03, 0x09, 0x03, 0xa7, 0xb4, 0x1f, 0x1d, 0xba, 0xe0, 0x6d, 0x85, 0xae, + 0xa5, 0x4f, 0x60, 0x21, 0xf3, 0x06, 0x68, 0x51, 0x27, 0x41, 0x75, 0xfd, 0x54, 0xde, 0x43, 0xef, + 0x46, 0x31, 0x59, 0x5d, 0x2d, 0x13, 0x84, 0x7f, 0x94, 0xbb, 0x61, 0xd9, 0x7f, 0xb0, 0xcc, 0x0d, + 0xfe, 0x29, 0x23, 0x61, 0x48, 0x19, 0xea, 0x40, 0x51, 0xd9, 0x6a, 0x82, 0xcc, 0x4f, 0x66, 0xf4, + 0x72, 0x12, 0xff, 0xd5, 0x23, 0xd6, 0xe0, 0x32, 0xb6, 0x72, 0x4a, 0xf5, 0x55, 0xaf, 0x24, 0xb1, + 0xb5, 0x4d, 0xa9, 0x8f, 0x15, 0xc7, 0xbe, 0x0a, 0xf3, 0xe9, 0x72, 0xe9, 0xf5, 0x69, 0xca, 0xfe, + 0x8d, 0x05, 0x8b, 0x9f, 0xb1, 0x60, 0x10, 0x9a, 0x9b, 0xbc, 0xe5, 0xfa, 0x1d, 0x99, 0x8d, 0x7a, + 0x92, 0x66, 0xd6, 0xc5, 0xd6, 0x28, 0x41, 0xac, 0x79, 0xf2, 0x3e, 0x1e, 0x4e, 0xc4, 0x9e, 0xf8, + 0x3e, 0x46, 0x81, 0x22, 0xe2, 0x4b, 0x33, 0x0e, 0x5c, 0xbf, 0x63, 0x62, 0x4b, 0x6c, 0x86, 0xd4, + 0x85, 0x15, 0xc7, 0xfe, 0xba, 0x00, 0x70, 0x37, 0xe8, 0xd0, 0xb6, 0x20, 0x62, 0xc0, 0xd1, 0x12, + 0xe4, 0xdc, 0x8e, 0xd1, 0x0e, 0x46, 0x3c, 0xb7, 0xb9, 0x8e, 0x73, 0x6e, 0x27, 0xce, 0x30, 0xb9, + 0x63, 0x33, 0xcc, 0x47, 0x30, 0xd7, 0x71, 0x79, 0xe8, 0x91, 0xa1, 0x24, 0x1a, 0xad, 0xf1, 0x85, + 0x59, 0x4f, 0x58, 0x38, 0x2d, 0x17, 0x67, 0xec, 0xc2, 0xd1, 0x19, 0x5b, 0x9a, 0x97, 0xca, 0xd8, + 0x57, 0xa1, 0x18, 0xee, 0x13, 0x4e, 0x4d, 0x30, 0x8a, 0x02, 0x66, 0x71, 0x47, 0x12, 0x5f, 0xc9, + 0x52, 0x2b, 0xe8, 0x50, 0xf5, 0x80, 0xb5, 0xa0, 0x8c, 0x4a, 0x5c, 0x10, 0x26, 0x68, 0x67, 0x55, + 0xcc, 0x1c, 0x95, 0xda, 0x11, 0x12, 0x4e, 0x40, 0x51, 0x57, 0x46, 0x8a, 0x7e, 0xe8, 0x51, 0xad, + 0xa3, 0x7c, 0x3a, 0x1d, 0xa9, 0xd0, 0x12, 0x63, 0xe1, 0x34, 0x70, 0x3a, 0x15, 0x57, 0xfe, 0x7f, + 0x2a, 0x46, 0x43, 0x98, 0xf3, 0x88, 0xa0, 0x5c, 0xa8, 0x93, 0x5c, 0xab, 0x9e, 0x49, 0x12, 0x36, + 0xd7, 0xae, 0xb5, 0x20, 0xad, 0xdc, 0x4e, 0xe0, 0x71, 0x5a, 0x97, 0xfd, 0x65, 0x11, 0xde, 0xc1, + 0x54, 0x67, 0x8f, 0xcf, 0xf7, 0x9e, 0x50, 0x47, 0x4c, 0x96, 0xc6, 0xd6, 0x09, 0x4a, 0xe3, 0x5f, + 0x42, 0xc9, 0x23, 0x7b, 0xd4, 0xe3, 0xb5, 0xbc, 0x8a, 0x9f, 0xf7, 0x4f, 0x6f, 0xf9, 0xa4, 0x29, + 0x8d, 0x6d, 0x05, 0xab, 0xa3, 0xe7, 0x3b, 0xc6, 0x86, 0x92, 0x26, 0x62, 0xa3, 0x13, 0xfd, 0x1a, + 0x20, 0x24, 0x8c, 0xf4, 0xa9, 0xaa, 0xb9, 0x0b, 0xca, 0x82, 0xad, 0xd9, 0x2d, 0xd8, 0x89, 0x30, + 0x93, 0xb0, 0x1d, 0x93, 0x38, 0x4e, 0xa9, 0x44, 0xcf, 0x2d, 0x58, 0xec, 0x65, 0xa2, 0x83, 0x69, + 0x82, 0x66, 0x08, 0xdb, 0xd9, 0x78, 0x93, 0x54, 0x2d, 0x59, 0x0e, 0x9e, 0xd2, 0x8e, 0x58, 0x5c, + 0x69, 0x94, 0x66, 0xb5, 0x23, 0xdb, 0x35, 0x27, 0xfb, 0x30, 0x59, 0x7a, 0x2c, 0xfd, 0x10, 0xe6, + 0x52, 0xdb, 0xf5, 0x46, 0xa9, 0xe2, 0xcf, 0x16, 0x5c, 0x98, 0xf2, 0x3b, 0xf2, 0x20, 0xcf, 0x99, + 0x63, 0xb2, 0xc5, 0xbd, 0x33, 0xdc, 0x51, 0x6d, 0xb8, 0x6e, 0x61, 0xdb, 0xcc, 0xc1, 0x52, 0x8d, + 0x8c, 0x98, 0x1d, 0xca, 0x45, 0x36, 0x62, 0xae, 0x53, 0x2e, 0xb0, 0xe2, 0xc8, 0x2c, 0xf0, 0xde, + 0x31, 0x58, 0xe8, 0x03, 0x28, 0x71, 0xb7, 0xe7, 0x13, 0xcf, 0x5c, 0x98, 0xc4, 0x49, 0x8a, 0x8a, + 0x0d, 0x37, 0xce, 0x35, 0xb9, 0x63, 0x5b, 0xa2, 0xfa, 0x64, 0x93, 0x53, 0xcd, 0x36, 0x38, 0xf6, + 0x02, 0x9c, 0xc7, 0x54, 0xb0, 0x61, 0x5b, 0x30, 0x22, 0x68, 0x6f, 0x68, 0xff, 0x3b, 0x07, 0x90, + 0xcc, 0x20, 0xa2, 0x46, 0xd5, 0x3a, 0xba, 0x51, 0x45, 0xbb, 0x51, 0x16, 0xd6, 0x26, 0x7c, 0x3a, + 0x91, 0x44, 0x5f, 0x8d, 0xea, 0xcd, 0xd4, 0x40, 0xa9, 0xef, 0xfa, 0x6e, 0xa0, 0xff, 0x5e, 0xe9, + 0x05, 0x8d, 0xbb, 0x81, 0x70, 0xbb, 0xae, 0x3e, 0x06, 0x49, 0xc9, 0x6d, 0xf2, 0x6e, 0x17, 0x4a, + 0xba, 0x2b, 0x35, 0xc3, 0x8c, 0xd6, 0x2c, 0x03, 0x15, 0xd3, 0xf4, 0xaa, 0x0a, 0x57, 0xff, 0xc6, + 0x06, 0x1d, 0x85, 0x50, 0xe1, 0x2b, 0xad, 0x81, 0x73, 0x40, 0x85, 0x29, 0xa3, 0x67, 0xd2, 0xa4, + 0x91, 0x5a, 0x8b, 0xc6, 0x0d, 0x95, 0x88, 0x82, 0x63, 0x2d, 0xf6, 0xb7, 0x39, 0x88, 0xc9, 0xe8, + 0x32, 0x54, 0xa8, 0xdf, 0x09, 0x03, 0xd7, 0xd4, 0x31, 0xd5, 0x64, 0xe9, 0x86, 0xa1, 0xe3, 0x58, + 0x42, 0x1e, 0x8b, 0x3d, 0x6d, 0x6a, 0x6e, 0xf2, 0x58, 0x18, 0x25, 0x86, 0x2b, 0xe5, 0x18, 0xed, + 0x25, 0x9d, 0x45, 0x2c, 0x87, 0x15, 0x15, 0x1b, 0xae, 0xd4, 0xee, 0xfa, 0x9c, 0x3a, 0x03, 0xa6, + 0x33, 0x70, 0x25, 0xd1, 0xbe, 0x69, 0xe8, 0x38, 0x96, 0x40, 0xbb, 0x50, 0x25, 0x8e, 0x43, 0x39, + 0xdf, 0xa2, 0x43, 0x13, 0x90, 0xbe, 0x9b, 0xca, 0x73, 0x0d, 0x27, 0x60, 0x54, 0x66, 0xb5, 0x36, + 0x75, 0x18, 0x15, 0x5b, 0x74, 0xd8, 0xa6, 0x1e, 0x75, 0x44, 0xc0, 0x92, 0x78, 0xbf, 0x1a, 0xad, + 0xc7, 0x09, 0x94, 0xc4, 0xe5, 0xd1, 0x12, 0x13, 0x60, 0xde, 0x14, 0x37, 0x66, 0xe1, 0x04, 0xca, + 0x7e, 0x28, 0xfd, 0x6c, 0x66, 0x07, 0x1f, 0x40, 0x29, 0x64, 0xb4, 0xeb, 0x3e, 0xcb, 0x5e, 0xa8, + 0x1d, 0x45, 0xc5, 0x86, 0xab, 0x2e, 0xde, 0xa0, 0x2b, 0xe5, 0x32, 0x1e, 0x6e, 0x2b, 0x2a, 0x36, + 0x5c, 0xfb, 0x6f, 0x39, 0x28, 0xb5, 0xd5, 0xee, 0xa3, 0xc7, 0x50, 0x91, 0xf9, 0x5c, 0xf5, 0x9f, + 0x3a, 0xb8, 0x5c, 0x3d, 0x59, 0xf6, 0xd7, 0x49, 0xe9, 0x0e, 0x15, 0x24, 0xc9, 0x09, 0x09, 0x0d, + 0xc7, 0xa8, 0xa8, 0x0b, 0x05, 0x1e, 0x52, 0xc7, 0x4c, 0x62, 0x66, 0x19, 0x2d, 0xaa, 0xe7, 0x76, + 0x48, 0x9d, 0x54, 0x25, 0x1b, 0x52, 0x07, 0x2b, 0x7c, 0xe4, 0x43, 0x89, 0xab, 0x5a, 0x70, 0xf6, + 0x01, 0xa2, 0xd1, 0xa4, 0xd0, 0x52, 0x4e, 0x54, 0xcf, 0xd8, 0x68, 0xb1, 0xbf, 0xb6, 0x00, 0xb4, + 0xe0, 0xb6, 0xcb, 0x05, 0x7a, 0x34, 0xe5, 0xc8, 0xc6, 0xc9, 0x1c, 0x29, 0x57, 0x2b, 0x37, 0xc6, + 0xa7, 0x37, 0xa2, 0xa4, 0x9c, 0x48, 0xa1, 0xe8, 0x0a, 0xda, 0xe7, 0xb5, 0x9c, 0x4a, 0xe9, 0x9f, + 0xce, 0xfa, 0x6e, 0x49, 0x85, 0xbe, 0x29, 0x61, 0xb1, 0x46, 0xb7, 0xff, 0x5e, 0x88, 0xde, 0x49, + 0x3a, 0x16, 0x1d, 0x40, 0x59, 0x87, 0xea, 0x68, 0x7c, 0x37, 0x8b, 0x5e, 0x05, 0x94, 0xd4, 0x7d, + 0xfa, 0x99, 0xe3, 0x48, 0x03, 0x0a, 0xa0, 0x22, 0x98, 0xdb, 0xeb, 0xc9, 0xc2, 0x45, 0xbf, 0xe5, + 0xea, 0xe9, 0xb5, 0xdd, 0xd7, 0x48, 0x89, 0x4f, 0x0d, 0x81, 0xe3, 0x58, 0x89, 0x8e, 0x33, 0x21, + 0x25, 0xc2, 0x44, 0x8f, 0x54, 0x9c, 0x91, 0x54, 0x6c, 0xb8, 0x68, 0x0f, 0x16, 0xdc, 0x3e, 0xe9, + 0xd1, 0x9d, 0x81, 0xe7, 0x99, 0x3e, 0x54, 0x57, 0xf0, 0x37, 0xcc, 0x82, 0x85, 0xcd, 0x49, 0xf6, + 0xab, 0x51, 0xfd, 0xfd, 0xe9, 0x4f, 0x0b, 0x8d, 0x44, 0x00, 0x67, 0x01, 0xd1, 0x6d, 0x40, 0x9c, + 0xb2, 0x43, 0xd7, 0xa1, 0xab, 0x8e, 0x13, 0x0c, 0x7c, 0xa1, 0xfa, 0x90, 0xd2, 0xe4, 0x64, 0xa5, + 0x3d, 0x25, 0x81, 0x8f, 0x58, 0x85, 0x36, 0xa0, 0x4c, 0xfd, 0xc3, 0x5d, 0xc2, 0x78, 0xad, 0xac, + 0xfc, 0xb8, 0x74, 0x54, 0x3c, 0xda, 0x50, 0x22, 0xa9, 0x91, 0x88, 0x5e, 0x82, 0xa3, 0xb5, 0xe8, + 0x06, 0xcc, 0x2b, 0x2b, 0xa3, 0x31, 0x8f, 0xae, 0xdb, 0xdf, 0x35, 0xf2, 0xf3, 0x9b, 0x29, 0x1e, + 0x9e, 0x90, 0xb4, 0xbf, 0x2d, 0xc0, 0x7c, 0xfa, 0x0a, 0x25, 0x9d, 0x8f, 0x75, 0xd2, 0xce, 0xe7, + 0x67, 0xe9, 0xce, 0x47, 0x47, 0x8e, 0xef, 0x9f, 0xec, 0x3a, 0x9d, 0xa0, 0xe9, 0x21, 0x93, 0x4d, + 0x4f, 0xfe, 0x8d, 0xe1, 0xdf, 0xa8, 0xdf, 0x29, 0xbc, 0xa6, 0xdf, 0x39, 0x84, 0xa2, 0x1f, 0x74, + 0x28, 0xaf, 0x15, 0xd5, 0x66, 0xdd, 0x3b, 0x9b, 0xb0, 0xd5, 0x90, 0x2e, 0x35, 0xcd, 0x42, 0x7c, + 0xd7, 0x15, 0x0d, 0x6b, 0x75, 0x68, 0x15, 0x16, 0x8c, 0xc5, 0x6e, 0xe0, 0xaf, 0xc9, 0xd3, 0xa3, + 0xce, 0x5b, 0xb1, 0xf5, 0x5e, 0x74, 0xac, 0xd7, 0x26, 0xd9, 0x38, 0x2b, 0xbf, 0xf4, 0x2b, 0xdd, + 0x82, 0x1f, 0x5b, 0xe4, 0x3e, 0x4c, 0x17, 0xb9, 0x33, 0xc5, 0xfe, 0xa4, 0xd3, 0x4f, 0x97, 0xca, + 0xff, 0xb0, 0xc0, 0xd4, 0x94, 0x27, 0x98, 0x22, 0x5f, 0x86, 0x4a, 0x87, 0x92, 0x4e, 0xfc, 0x11, + 0x2a, 0x9f, 0x04, 0x87, 0x75, 0x43, 0xc7, 0xb1, 0x04, 0x7a, 0x9a, 0x7c, 0xb9, 0x98, 0x3d, 0x9d, + 0x28, 0x13, 0x4d, 0x19, 0x17, 0x1f, 0x84, 0xec, 0xf7, 0x0b, 0xfb, 0x65, 0x0e, 0xe6, 0xd3, 0xa2, + 0x27, 0x78, 0xa7, 0x3d, 0x28, 0x08, 0xb7, 0x7f, 0x06, 0xfe, 0x95, 0xc7, 0xda, 0x18, 0xa8, 0x3e, + 0x98, 0xa9, 0xe9, 0xa5, 0xc2, 0x46, 0xfd, 0x64, 0x20, 0x9e, 0x3f, 0xd3, 0x81, 0xf8, 0xdc, 0x91, + 0xc3, 0xf0, 0x47, 0x66, 0x18, 0xae, 0xcb, 0xd9, 0x1f, 0xcf, 0xf6, 0xbd, 0x48, 0xbf, 0x8c, 0xfc, + 0x65, 0x26, 0xe9, 0x63, 0x0b, 0x20, 0x79, 0x57, 0x74, 0x09, 0x8a, 0x2a, 0x2c, 0x64, 0xc7, 0x56, + 0x2a, 0x6c, 0x60, 0xcd, 0x53, 0x43, 0x34, 0x11, 0x84, 0xd9, 0x36, 0xa5, 0x2d, 0x82, 0x10, 0x2b, + 0xce, 0xd1, 0xb3, 0xca, 0xfc, 0x5b, 0xfb, 0xcc, 0xf2, 0xcf, 0x1c, 0x94, 0x4d, 0xbe, 0x3b, 0xc1, + 0x19, 0x62, 0x50, 0x61, 0xa6, 0x91, 0x33, 0xe7, 0xe8, 0xd6, 0x59, 0x8d, 0x2c, 0x5a, 0xf3, 0xf2, + 0x76, 0x45, 0x34, 0x1c, 0xeb, 0x79, 0x83, 0x2f, 0x33, 0xe8, 0x0b, 0x0b, 0xce, 0x33, 0x1a, 0x7a, + 0x71, 0x8b, 0x67, 0x4e, 0xc6, 0x67, 0xb3, 0x18, 0x99, 0xea, 0x18, 0x5b, 0x17, 0xc6, 0xa3, 0xfa, + 0x64, 0x13, 0x89, 0x27, 0x15, 0xda, 0x7f, 0xc9, 0x41, 0xfe, 0x01, 0xde, 0x54, 0xe5, 0xb5, 0xb3, + 0x4f, 0x63, 0x6f, 0x26, 0x95, 0xa1, 0xa2, 0x62, 0xc3, 0x95, 0x3e, 0x1f, 0x70, 0xca, 0xb2, 0x07, + 0xe6, 0x01, 0xa7, 0x0c, 0x2b, 0x8e, 0x8c, 0x45, 0x21, 0xe1, 0xfc, 0x17, 0x01, 0x8b, 0x46, 0x9c, + 0x71, 0x2c, 0xda, 0x31, 0x74, 0x1c, 0x4b, 0x48, 0xbc, 0xfd, 0x80, 0x0b, 0x93, 0x49, 0x62, 0xbc, + 0x5b, 0x81, 0xec, 0xc6, 0x25, 0x47, 0x75, 0xd2, 0x01, 0x13, 0xaa, 0x2e, 0x29, 0xa6, 0x3a, 0xe9, + 0x80, 0x09, 0xac, 0x38, 0x71, 0xaf, 0x5d, 0x3a, 0xb6, 0xd7, 0xbe, 0x04, 0xc5, 0xa7, 0x03, 0xca, + 0x86, 0x6a, 0x08, 0x98, 0xba, 0x0b, 0xf7, 0x24, 0x11, 0x6b, 0x9e, 0x34, 0xbc, 0xcb, 0x48, 0xaf, + 0x2f, 0x7b, 0xe6, 0xca, 0xa4, 0xe1, 0x37, 0x0d, 0x1d, 0xc7, 0x12, 0xb6, 0x03, 0x73, 0xa9, 0xcf, + 0xe4, 0x27, 0xf8, 0x04, 0x7a, 0x1d, 0xe0, 0x90, 0x32, 0xb7, 0x3b, 0x5c, 0xa3, 0x4c, 0x98, 0xa9, + 0x75, 0xdc, 0x5d, 0xec, 0xc6, 0x1c, 0x9c, 0x92, 0x6a, 0x35, 0x5e, 0xbc, 0x5c, 0x3e, 0xf7, 0xd5, + 0xcb, 0xe5, 0x73, 0xdf, 0xbc, 0x5c, 0x3e, 0xf7, 0xc5, 0x78, 0xd9, 0x7a, 0x31, 0x5e, 0xb6, 0xbe, + 0x1a, 0x2f, 0x5b, 0xdf, 0x8c, 0x97, 0xad, 0xff, 0x8c, 0x97, 0xad, 0xe7, 0xff, 0x5d, 0x3e, 0xf7, + 0xb0, 0x12, 0xed, 0xfe, 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, 0x3c, 0x82, 0x7b, 0x3e, 0xa9, 0x22, + 0x00, 0x00, } diff --git a/pkg/apis/sensor/v1alpha1/generated.proto b/pkg/apis/sensor/v1alpha1/generated.proto index 091412cba0..02fb6f2b57 100644 --- a/pkg/apis/sensor/v1alpha1/generated.proto +++ b/pkg/apis/sensor/v1alpha1/generated.proto @@ -37,6 +37,20 @@ message ArtifactLocation { optional FileArtifact file = 3; optional URLArtifact url = 4; + + optional ConfigmapArtifact configmap = 5; +} + +// ConfigmapArtifact contains information about artifact in k8 configmap +message ConfigmapArtifact { + // Name of the configmap + optional string name = 1; + + // Namespace where configmap is deployed + optional string namespace = 2; + + // Key within configmap data which contains trigger resource definition + optional string key = 3; } message Data { diff --git a/pkg/apis/sensor/v1alpha1/openapi_generated.go b/pkg/apis/sensor/v1alpha1/openapi_generated.go index a0ff1289b5..83729da82d 100644 --- a/pkg/apis/sensor/v1alpha1/openapi_generated.go +++ b/pkg/apis/sensor/v1alpha1/openapi_generated.go @@ -29,6 +29,7 @@ import ( func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition { return map[string]common.OpenAPIDefinition{ "github.com/argoproj/argo-events/pkg/apis/sensor/v1alpha1.ArtifactLocation": schema_pkg_apis_sensor_v1alpha1_ArtifactLocation(ref), + "github.com/argoproj/argo-events/pkg/apis/sensor/v1alpha1.ConfigmapArtifact": schema_pkg_apis_sensor_v1alpha1_ConfigmapArtifact(ref), "github.com/argoproj/argo-events/pkg/apis/sensor/v1alpha1.Data": schema_pkg_apis_sensor_v1alpha1_Data(ref), "github.com/argoproj/argo-events/pkg/apis/sensor/v1alpha1.DataFilter": schema_pkg_apis_sensor_v1alpha1_DataFilter(ref), "github.com/argoproj/argo-events/pkg/apis/sensor/v1alpha1.EscalationPolicy": schema_pkg_apis_sensor_v1alpha1_EscalationPolicy(ref), @@ -85,11 +86,51 @@ func schema_pkg_apis_sensor_v1alpha1_ArtifactLocation(ref common.ReferenceCallba Ref: ref("github.com/argoproj/argo-events/pkg/apis/sensor/v1alpha1.URLArtifact"), }, }, + "configmap": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/argoproj/argo-events/pkg/apis/sensor/v1alpha1.ConfigmapArtifact"), + }, + }, }, }, }, Dependencies: []string{ - "github.com/argoproj/argo-events/pkg/apis/sensor/v1alpha1.FileArtifact", "github.com/argoproj/argo-events/pkg/apis/sensor/v1alpha1.S3Artifact", "github.com/argoproj/argo-events/pkg/apis/sensor/v1alpha1.URLArtifact"}, + "github.com/argoproj/argo-events/pkg/apis/sensor/v1alpha1.ConfigmapArtifact", "github.com/argoproj/argo-events/pkg/apis/sensor/v1alpha1.FileArtifact", "github.com/argoproj/argo-events/pkg/apis/sensor/v1alpha1.S3Artifact", "github.com/argoproj/argo-events/pkg/apis/sensor/v1alpha1.URLArtifact"}, + } +} + +func schema_pkg_apis_sensor_v1alpha1_ConfigmapArtifact(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "ConfigmapArtifact contains information about artifact in k8 configmap", + Properties: map[string]spec.Schema{ + "name": { + SchemaProps: spec.SchemaProps{ + Description: "Name of the configmap", + Type: []string{"string"}, + Format: "", + }, + }, + "namespace": { + SchemaProps: spec.SchemaProps{ + Description: "Namespace where configmap is deployed", + Type: []string{"string"}, + Format: "", + }, + }, + "key": { + SchemaProps: spec.SchemaProps{ + Description: "Key within configmap data which contains trigger resource definition", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"name", "namespace", "key"}, + }, + }, + Dependencies: []string{}, } } diff --git a/pkg/apis/sensor/v1alpha1/types.go b/pkg/apis/sensor/v1alpha1/types.go index fb31c4887a..7e8f7e0a12 100644 --- a/pkg/apis/sensor/v1alpha1/types.go +++ b/pkg/apis/sensor/v1alpha1/types.go @@ -415,10 +415,21 @@ type URI struct { // ArtifactLocation describes the source location for an external artifact type ArtifactLocation struct { - S3 *S3Artifact `json:"s3,omitempty" protobuf:"bytes,1,opt,name=s3"` - Inline *string `json:"inline,omitempty" protobuf:"bytes,2,opt,name=inline"` - File *FileArtifact `json:"file,omitempty" protobuf:"bytes,3,opt,name=file"` - URL *URLArtifact `json:"url,omitempty" protobuf:"bytes,4,opt,name=url"` + S3 *S3Artifact `json:"s3,omitempty" protobuf:"bytes,1,opt,name=s3"` + Inline *string `json:"inline,omitempty" protobuf:"bytes,2,opt,name=inline"` + File *FileArtifact `json:"file,omitempty" protobuf:"bytes,3,opt,name=file"` + URL *URLArtifact `json:"url,omitempty" protobuf:"bytes,4,opt,name=url"` + Configmap *ConfigmapArtifact `json:"configmap,omitempty" protobuf:"bytes,5,opt,name=configmap"` +} + +// ConfigmapArtifact contains information about artifact in k8 configmap +type ConfigmapArtifact struct { + // Name of the configmap + Name string `json:"name" protobuf:"bytes,1,opt,name=name"` + // Namespace where configmap is deployed + Namespace string `json:"namespace" protobuf:"bytes,2,opt,name=namespace"` + // Key within configmap data which contains trigger resource definition + Key string `json:"key" protobuf:"bytes,3,opt,name=key"` } // S3Artifact contains information about an artifact in S3 diff --git a/pkg/apis/sensor/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/sensor/v1alpha1/zz_generated.deepcopy.go index ee98bd6d6f..8cde886489 100644 --- a/pkg/apis/sensor/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/sensor/v1alpha1/zz_generated.deepcopy.go @@ -47,6 +47,11 @@ func (in *ArtifactLocation) DeepCopyInto(out *ArtifactLocation) { *out = new(URLArtifact) **out = **in } + if in.Configmap != nil { + in, out := &in.Configmap, &out.Configmap + *out = new(ConfigmapArtifact) + **out = **in + } return } @@ -60,6 +65,22 @@ func (in *ArtifactLocation) DeepCopy() *ArtifactLocation { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ConfigmapArtifact) DeepCopyInto(out *ConfigmapArtifact) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConfigmapArtifact. +func (in *ConfigmapArtifact) DeepCopy() *ConfigmapArtifact { + if in == nil { + return nil + } + out := new(ConfigmapArtifact) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Data) DeepCopyInto(out *Data) { *out = *in diff --git a/store/configmap.go b/store/configmap.go new file mode 100644 index 0000000000..47c56fbaee --- /dev/null +++ b/store/configmap.go @@ -0,0 +1,38 @@ +package store + +import ( + "fmt" + "github.com/argoproj/argo-events/pkg/apis/sensor/v1alpha1" + wfv1 "github.com/argoproj/argo/pkg/apis/workflow/v1alpha1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" +) + +// ConfigmapReader implements the ArtifactReader interface for k8 configmap +type ConfigmapReader struct { + kubeClientset kubernetes.Interface + configmapArtifact *v1alpha1.ConfigmapArtifact +} + +type configmapWf struct { + wf wfv1.Workflow +} + +// NewConfigmapReader returns a new configmap reader +func NewConfigmapReader(kubeClientset kubernetes.Interface, configmapArtifact *v1alpha1.ConfigmapArtifact) (*ConfigmapReader, error) { + return &ConfigmapReader{ + kubeClientset: kubeClientset, + configmapArtifact: configmapArtifact, + }, nil +} + +func (c *ConfigmapReader) Read() (body []byte, err error) { + cm, err := c.kubeClientset.CoreV1().ConfigMaps(c.configmapArtifact.Namespace).Get(c.configmapArtifact.Name, metav1.GetOptions{}) + if err != nil { + return nil, err + } + if resource, ok := cm.Data[c.configmapArtifact.Key]; ok { + return []byte(resource), nil + } + return nil, fmt.Errorf("unable to find key %s in configmap %s", c.configmapArtifact.Key, c.configmapArtifact.Name) +} diff --git a/store/configmap_test.go b/store/configmap_test.go new file mode 100644 index 0000000000..b10560a590 --- /dev/null +++ b/store/configmap_test.go @@ -0,0 +1,58 @@ +package store + +import ( + "github.com/argoproj/argo-events/pkg/apis/sensor/v1alpha1" + wfv1 "github.com/argoproj/argo/pkg/apis/workflow/v1alpha1" + "github.com/ghodss/yaml" + "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes/fake" + "testing" +) + +func TestConfigmapReader_Read(t *testing.T) { + kubeClientset := fake.NewSimpleClientset() + key := "wf" + cmArtifact := &v1alpha1.ConfigmapArtifact{ + Name: "wf-configmap", + Namespace: "argo-events", + Key: key, + } + + configmap := &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: cmArtifact.Name, + Namespace: cmArtifact.Namespace, + }, + Data: map[string]string{ + key: `apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + name: hello-world +spec: + entrypoint: whalesay + templates: + - name: whalesay + container: + args: + - "hello world" + command: + - cowsay + image: "docker/whalesay:latest"`, + }, + } + + cm, err := kubeClientset.CoreV1().ConfigMaps(cmArtifact.Namespace).Create(configmap) + assert.Nil(t, err) + assert.Equal(t, cm.Name, configmap.Name) + cmReader, err := NewConfigmapReader(kubeClientset, cmArtifact) + assert.Nil(t, err) + resourceBody, err := cmReader.Read() + assert.Nil(t, err) + + var wf *wfv1.Workflow + err = yaml.Unmarshal(resourceBody, &wf) + assert.Nil(t, err) + assert.Equal(t, wf.Name, "hello-world") +}