From 606dc73ffcfa96bb8d9e6f9dba559d356cf19659 Mon Sep 17 00:00:00 2001 From: jiangpengcheng Date: Mon, 23 Oct 2023 11:47:52 +0800 Subject: [PATCH] Support rust generic runtime (#688) * Support rust generic runtime * Update webhook * Update runner image * Fix rust oauth2 * Fix vulnerability * Fix vulnerability * Remove unittest for go1.18 * Add default runner image for wasm --- .github/workflows/project.yml | 2 +- api/compute/v1alpha1/common.go | 19 +++- api/compute/v1alpha1/zz_generated.deepcopy.go | 20 ++++ ...ompute.functionmesh.io-functionmeshes.yaml | 36 +++++++ ...crd-compute.functionmesh.io-functions.yaml | 12 +++ .../crd-compute.functionmesh.io-sinks.yaml | 12 +++ .../crd-compute.functionmesh.io-sources.yaml | 12 +++ ...ompute.functionmesh.io_functionmeshes.yaml | 36 +++++++ .../compute.functionmesh.io_functions.yaml | 12 +++ .../bases/compute.functionmesh.io_sinks.yaml | 12 +++ .../compute.functionmesh.io_sources.yaml | 12 +++ controllers/spec/common.go | 94 ++++++++++++++++--- controllers/spec/controller_configs.go | 13 ++- controllers/spec/function.go | 8 ++ go.mod | 10 +- go.sum | 10 ++ manifests/crd.yaml | 72 ++++++++++++++ pkg/webhook/function_webhook.go | 4 +- 18 files changed, 369 insertions(+), 27 deletions(-) diff --git a/.github/workflows/project.yml b/.github/workflows/project.yml index a1140296f..c5288aa9f 100644 --- a/.github/workflows/project.yml +++ b/.github/workflows/project.yml @@ -18,7 +18,7 @@ jobs: strategy: fail-fast: false matrix: - go-version: [1.18, 1.19, 1.20.4] + go-version: [1.19, 1.20.4] steps: - name: clean disk run: | diff --git a/api/compute/v1alpha1/common.go b/api/compute/v1alpha1/common.go index 434a75396..3a8d90769 100644 --- a/api/compute/v1alpha1/common.go +++ b/api/compute/v1alpha1/common.go @@ -131,7 +131,7 @@ func (o *OAuth2Config) GetMountFile() string { } func (o *OAuth2Config) AuthenticationParameters() string { - return fmt.Sprintf(`'{"privateKey":"%s","private_key":"%s","issuerUrl":"%s","issuer_url":"%s","audience":"%s","scope":"%s"}'`, o.GetMountFile(), o.GetMountFile(), o.IssuerURL, o.IssuerURL, o.Audience, o.Scope) + return fmt.Sprintf(`'{"credentials_url":"file://%s","privateKey":"%s","private_key":"%s","issuerUrl":"%s","issuer_url":"%s","audience":"%s","scope":"%s"}'`, o.GetMountFile(), o.GetMountFile(), o.GetMountFile(), o.IssuerURL, o.IssuerURL, o.Audience, o.Scope) } type GenericAuth struct { @@ -234,9 +234,10 @@ type PodPolicy struct { } type Runtime struct { - Java *JavaRuntime `json:"java,omitempty"` - Python *PythonRuntime `json:"python,omitempty"` - Golang *GoRuntime `json:"golang,omitempty"` + Java *JavaRuntime `json:"java,omitempty"` + Python *PythonRuntime `json:"python,omitempty"` + Golang *GoRuntime `json:"golang,omitempty"` + GenericRuntime *GenericRuntime `json:"genericRuntime,omitempty"` } // JavaRuntime contains the java runtime configs @@ -268,6 +269,16 @@ type GoRuntime struct { Log *RuntimeLogConfig `json:"log,omitempty"` } +// GenericRuntime contains the generic runtime configs +// +kubebuilder:validation:Optional +type GenericRuntime struct { + // +kubebuilder:validation:Required + FunctionFile string `json:"functionFile"` + // +kubebuilder:validation:Required + Language string `json:"language"` + FunctionFileLocation string `json:"functionFileLocation,omitempty"` +} + type SecretRef struct { Path string `json:"path,omitempty"` Key string `json:"key,omitempty"` diff --git a/api/compute/v1alpha1/zz_generated.deepcopy.go b/api/compute/v1alpha1/zz_generated.deepcopy.go index 054ae4ab6..a52e7c9ec 100644 --- a/api/compute/v1alpha1/zz_generated.deepcopy.go +++ b/api/compute/v1alpha1/zz_generated.deepcopy.go @@ -493,6 +493,21 @@ func (in *GenericAuth) DeepCopy() *GenericAuth { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GenericRuntime) DeepCopyInto(out *GenericRuntime) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GenericRuntime. +func (in *GenericRuntime) DeepCopy() *GenericRuntime { + if in == nil { + return nil + } + out := new(GenericRuntime) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *GoRuntime) DeepCopyInto(out *GoRuntime) { *out = *in @@ -942,6 +957,11 @@ func (in *Runtime) DeepCopyInto(out *Runtime) { *out = new(GoRuntime) (*in).DeepCopyInto(*out) } + if in.GenericRuntime != nil { + in, out := &in.GenericRuntime, &out.GenericRuntime + *out = new(GenericRuntime) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Runtime. diff --git a/charts/function-mesh-operator/charts/admission-webhook/templates/crd-compute.functionmesh.io-functionmeshes.yaml b/charts/function-mesh-operator/charts/admission-webhook/templates/crd-compute.functionmesh.io-functionmeshes.yaml index 82a51281d..93862ea4d 100644 --- a/charts/function-mesh-operator/charts/admission-webhook/templates/crd-compute.functionmesh.io-functionmeshes.yaml +++ b/charts/function-mesh-operator/charts/admission-webhook/templates/crd-compute.functionmesh.io-functionmeshes.yaml @@ -50,6 +50,18 @@ spec: funcConfig: type: object x-kubernetes-preserve-unknown-fields: true + genericRuntime: + properties: + functionFile: + type: string + functionFileLocation: + type: string + language: + type: string + required: + - functionFile + - language + type: object golang: properties: go: @@ -3620,6 +3632,18 @@ spec: type: string filebeatImage: type: string + genericRuntime: + properties: + functionFile: + type: string + functionFileLocation: + type: string + language: + type: string + required: + - functionFile + - language + type: object golang: properties: go: @@ -6937,6 +6961,18 @@ spec: type: string forwardSourceMessageProperty: type: boolean + genericRuntime: + properties: + functionFile: + type: string + functionFileLocation: + type: string + language: + type: string + required: + - functionFile + - language + type: object golang: properties: go: diff --git a/charts/function-mesh-operator/charts/admission-webhook/templates/crd-compute.functionmesh.io-functions.yaml b/charts/function-mesh-operator/charts/admission-webhook/templates/crd-compute.functionmesh.io-functions.yaml index ad1874b0e..70352c95c 100644 --- a/charts/function-mesh-operator/charts/admission-webhook/templates/crd-compute.functionmesh.io-functions.yaml +++ b/charts/function-mesh-operator/charts/admission-webhook/templates/crd-compute.functionmesh.io-functions.yaml @@ -69,6 +69,18 @@ spec: funcConfig: type: object x-kubernetes-preserve-unknown-fields: true + genericRuntime: + properties: + functionFile: + type: string + functionFileLocation: + type: string + language: + type: string + required: + - functionFile + - language + type: object golang: properties: go: diff --git a/charts/function-mesh-operator/charts/admission-webhook/templates/crd-compute.functionmesh.io-sinks.yaml b/charts/function-mesh-operator/charts/admission-webhook/templates/crd-compute.functionmesh.io-sinks.yaml index a3fb9ab2f..63caa207a 100644 --- a/charts/function-mesh-operator/charts/admission-webhook/templates/crd-compute.functionmesh.io-sinks.yaml +++ b/charts/function-mesh-operator/charts/admission-webhook/templates/crd-compute.functionmesh.io-sinks.yaml @@ -64,6 +64,18 @@ spec: type: string filebeatImage: type: string + genericRuntime: + properties: + functionFile: + type: string + functionFileLocation: + type: string + language: + type: string + required: + - functionFile + - language + type: object golang: properties: go: diff --git a/charts/function-mesh-operator/charts/admission-webhook/templates/crd-compute.functionmesh.io-sources.yaml b/charts/function-mesh-operator/charts/admission-webhook/templates/crd-compute.functionmesh.io-sources.yaml index 076359d84..49f19b1c1 100644 --- a/charts/function-mesh-operator/charts/admission-webhook/templates/crd-compute.functionmesh.io-sources.yaml +++ b/charts/function-mesh-operator/charts/admission-webhook/templates/crd-compute.functionmesh.io-sources.yaml @@ -70,6 +70,18 @@ spec: type: string forwardSourceMessageProperty: type: boolean + genericRuntime: + properties: + functionFile: + type: string + functionFileLocation: + type: string + language: + type: string + required: + - functionFile + - language + type: object golang: properties: go: diff --git a/config/crd/bases/compute.functionmesh.io_functionmeshes.yaml b/config/crd/bases/compute.functionmesh.io_functionmeshes.yaml index 4c0b466ad..f8c01e895 100644 --- a/config/crd/bases/compute.functionmesh.io_functionmeshes.yaml +++ b/config/crd/bases/compute.functionmesh.io_functionmeshes.yaml @@ -51,6 +51,18 @@ spec: funcConfig: type: object x-kubernetes-preserve-unknown-fields: true + genericRuntime: + properties: + functionFile: + type: string + functionFileLocation: + type: string + language: + type: string + required: + - functionFile + - language + type: object golang: properties: go: @@ -3621,6 +3633,18 @@ spec: type: string filebeatImage: type: string + genericRuntime: + properties: + functionFile: + type: string + functionFileLocation: + type: string + language: + type: string + required: + - functionFile + - language + type: object golang: properties: go: @@ -6938,6 +6962,18 @@ spec: type: string forwardSourceMessageProperty: type: boolean + genericRuntime: + properties: + functionFile: + type: string + functionFileLocation: + type: string + language: + type: string + required: + - functionFile + - language + type: object golang: properties: go: diff --git a/config/crd/bases/compute.functionmesh.io_functions.yaml b/config/crd/bases/compute.functionmesh.io_functions.yaml index 1fd92fc00..8f066dbdb 100644 --- a/config/crd/bases/compute.functionmesh.io_functions.yaml +++ b/config/crd/bases/compute.functionmesh.io_functions.yaml @@ -48,6 +48,18 @@ spec: funcConfig: type: object x-kubernetes-preserve-unknown-fields: true + genericRuntime: + properties: + functionFile: + type: string + functionFileLocation: + type: string + language: + type: string + required: + - functionFile + - language + type: object golang: properties: go: diff --git a/config/crd/bases/compute.functionmesh.io_sinks.yaml b/config/crd/bases/compute.functionmesh.io_sinks.yaml index c54b582b6..d46d9b1c8 100644 --- a/config/crd/bases/compute.functionmesh.io_sinks.yaml +++ b/config/crd/bases/compute.functionmesh.io_sinks.yaml @@ -43,6 +43,18 @@ spec: type: string filebeatImage: type: string + genericRuntime: + properties: + functionFile: + type: string + functionFileLocation: + type: string + language: + type: string + required: + - functionFile + - language + type: object golang: properties: go: diff --git a/config/crd/bases/compute.functionmesh.io_sources.yaml b/config/crd/bases/compute.functionmesh.io_sources.yaml index 57d8fe42e..bba96bbc1 100644 --- a/config/crd/bases/compute.functionmesh.io_sources.yaml +++ b/config/crd/bases/compute.functionmesh.io_sources.yaml @@ -49,6 +49,18 @@ spec: type: string forwardSourceMessageProperty: type: boolean + genericRuntime: + properties: + functionFile: + type: string + functionFileLocation: + type: string + language: + type: string + required: + - functionFile + - language + type: object golang: properties: go: diff --git a/controllers/spec/common.go b/controllers/spec/common.go index 9b5e0999c..f1d8c48f5 100644 --- a/controllers/spec/common.go +++ b/controllers/spec/common.go @@ -55,18 +55,22 @@ import ( ) const ( - EnvShardID = "SHARD_ID" - FunctionsInstanceClasspath = "pulsar.functions.instance.classpath" - DefaultRunnerTag = "2.10.0.0-rc10" - DefaultRunnerPrefix = "streamnative/" - DefaultRunnerImage = DefaultRunnerPrefix + "pulsar-all:" + DefaultRunnerTag - DefaultJavaRunnerImage = DefaultRunnerPrefix + "pulsar-functions-java-runner:" + DefaultRunnerTag - DefaultPythonRunnerImage = DefaultRunnerPrefix + "pulsar-functions-python-runner:" + DefaultRunnerTag - DefaultGoRunnerImage = DefaultRunnerPrefix + "pulsar-functions-go-runner:" + DefaultRunnerTag - PulsarAdminExecutableFile = "/pulsar/bin/pulsar-admin" - WorkDir = "/pulsar/" - - RunnerImageHasPulsarctl = "pulsar-functions-(pulsarctl|sn)-(java|python|go)-runner" + EnvShardID = "SHARD_ID" + FunctionsInstanceClasspath = "pulsar.functions.instance.classpath" + DefaultRunnerTag = "2.10.0.0-rc10" + DefaultGenericRunnerTag = "0.1.0" + DefaultRunnerPrefix = "streamnative/" + DefaultRunnerImage = DefaultRunnerPrefix + "pulsar-all:" + DefaultRunnerTag + DefaultJavaRunnerImage = DefaultRunnerPrefix + "pulsar-functions-java-runner:" + DefaultRunnerTag + DefaultPythonRunnerImage = DefaultRunnerPrefix + "pulsar-functions-python-runner:" + DefaultRunnerTag + DefaultGoRunnerImage = DefaultRunnerPrefix + "pulsar-functions-go-runner:" + DefaultRunnerTag + DefaultGenericNodejsRunnerImage = DefaultRunnerPrefix + "pulsar-functions-generic-nodejs-runner:" + DefaultGenericRunnerTag + DefaultGenericPythonRunnerImage = DefaultRunnerPrefix + "pulsar-functions-generic-python-runner:" + DefaultGenericRunnerTag + DefaultGenericRunnerImage = DefaultRunnerPrefix + "pulsar-functions-generic-base-runner:" + DefaultGenericRunnerTag + PulsarAdminExecutableFile = "/pulsar/bin/pulsar-admin" + WorkDir = "/pulsar/" + + RunnerImageHasPulsarctl = "pulsar-functions-(pulsarctl|sn|generic)-(java|python|go|nodejs|base)-runner" PulsarctlExecutableFile = "pulsarctl" DownloaderName = "downloader" @@ -390,6 +394,22 @@ func MakeGoFunctionCommand(downloadPath, goExecFilePath string, function *v1alph return []string{"sh", "-c", processCommand} } +func MakeGenericFunctionCommand(downloadPath, functionFile, language, clusterName, details, uid string, authProvided, tlsProvided bool, secretMaps map[string]v1alpha1.SecretRef, + state *v1alpha1.Stateful, + tlsConfig TLSConfig, authConfig *v1alpha1.AuthConfig) []string { + processCommand := setShardIDEnvironmentVariableCommand() + " && " + + strings.Join(getProcessGenericRuntimeArgs(language, functionFile, clusterName, + details, uid, authProvided, tlsProvided, secretMaps, state, tlsConfig, authConfig), " ") + if downloadPath != "" && !utils.EnableInitContainers { + // prepend download command if the downPath is provided + downloadCommand := strings.Join(getDownloadCommand(downloadPath, functionFile, true, true, + authProvided, + tlsProvided, tlsConfig, authConfig), " ") + processCommand = downloadCommand + " && " + processCommand + } + return []string{"sh", "-c", processCommand} +} + func MakeLivenessProbe(liveness *v1alpha1.Liveness) *corev1.Probe { if liveness == nil || liveness.PeriodSeconds <= 0 { return nil @@ -1172,6 +1192,34 @@ func getProcessPythonRuntimeArgs(name, packageName, clusterName, details, uid st return args } +func getProcessGenericRuntimeArgs(language, functionFile, clusterName, details, uid string, authProvided, tlsProvided bool, + secretMaps map[string]v1alpha1.SecretRef, state *v1alpha1.Stateful, tlsConfig TLSConfig, + authConfig *v1alpha1.AuthConfig) []string { + + args := []string{ + "exec", + "pulsar_rust_instance", + "--function_file", + functionFile, + "--language", + language, + } + sharedArgs := getSharedArgs(details, clusterName, uid, authProvided, tlsProvided, tlsConfig, authConfig) + args = append(args, sharedArgs...) + if len(secretMaps) > 0 { + secretProviderArgs := getGenericSecretProviderArgs(secretMaps, language) + args = append(args, secretProviderArgs...) + } + if state != nil && state.Pulsar != nil && state.Pulsar.ServiceURL != "" { + statefulArgs := []string{ + "--state_storage_serviceurl", + state.Pulsar.ServiceURL, + } + args = append(args, statefulArgs...) + } + return args +} + // This method is suitable for Java and Python runtime, not include Go runtime. func getSharedArgs(details, clusterName, uid string, authProvided bool, tlsProvided bool, tlsConfig TLSConfig, authConfig *v1alpha1.AuthConfig) []string { @@ -1193,7 +1241,7 @@ func getSharedArgs(details, clusterName, uid string, authProvided bool, tlsProvi "--metrics_port", strconv.Itoa(int(MetricsPort.ContainerPort)), "--expected_healthcheck_interval", - "-1", // TurnOff BuiltIn HealthCheck to avoid instance exit + "0", // TurnOff BuiltIn HealthCheck to avoid instance exit "--cluster_name", clusterName, } @@ -1787,6 +1835,8 @@ func getFunctionRunnerImage(spec *v1alpha1.FunctionSpec) string { return Configs.RunnerImages.Python } else if runtime.Golang != nil && runtime.Golang.Go != "" { return Configs.RunnerImages.Go + } else if runtime.GenericRuntime != nil && runtime.GenericRuntime.Language != "" { + return Configs.RunnerImages.GenericRuntime[runtime.GenericRuntime.Language] } return DefaultRunnerImage } @@ -1854,6 +1904,24 @@ func getPythonSecretProviderArgs(secretMaps map[string]v1alpha1.SecretRef) []str return ret } +func getGenericSecretProviderArgs(secretMaps map[string]v1alpha1.SecretRef, language string) []string { + var ret []string + if len(secretMaps) > 0 { + if language == "python" { + ret = []string{ + "--secrets_provider", + "secrets_provider.EnvironmentBasedSecretsProvider", + } + } else if language == "nodejs" { + ret = []string{ + "--secrets_provider", + "EnvironmentBasedSecretsProvider", + } + } + } + return ret +} + // Java command requires memory values in resource.DecimalSI format func getDecimalSIMemory(quantity *resource.Quantity) string { if quantity.Format == resource.DecimalSI { diff --git a/controllers/spec/controller_configs.go b/controllers/spec/controller_configs.go index 5b7935ff1..2ee4edbd9 100644 --- a/controllers/spec/controller_configs.go +++ b/controllers/spec/controller_configs.go @@ -24,9 +24,10 @@ import ( ) type RunnerImages struct { - Java string `yaml:"java,omitempty"` - Python string `yaml:"python,omitempty"` - Go string `yaml:"go,omitempty"` + Java string `yaml:"java,omitempty"` + Python string `yaml:"python,omitempty"` + Go string `yaml:"go,omitempty"` + GenericRuntime map[string]string `yaml:"genericRuntime,omitempty"` } type ControllerConfigs struct { @@ -43,6 +44,12 @@ func DefaultConfigs() *ControllerConfigs { Java: DefaultJavaRunnerImage, Python: DefaultPythonRunnerImage, Go: DefaultGoRunnerImage, + GenericRuntime: map[string]string{ + "nodejs": DefaultGenericNodejsRunnerImage, + "python": DefaultGenericPythonRunnerImage, + "executable": DefaultGenericRunnerImage, + "wasm": DefaultGenericRunnerImage, + }, }, } } diff --git a/controllers/spec/function.go b/controllers/spec/function.go index ae511d3bb..e9f63bf83 100644 --- a/controllers/spec/function.go +++ b/controllers/spec/function.go @@ -241,6 +241,14 @@ func makeFunctionCommand(function *v1alpha1.Function) []string { if spec.Golang.Go != "" { return MakeGoFunctionCommand(spec.Golang.GoLocation, spec.Golang.Go, function) } + } else if spec.GenericRuntime != nil { + if spec.GenericRuntime.FunctionFile != "" { + return MakeGenericFunctionCommand(spec.GenericRuntime.FunctionFileLocation, spec.GenericRuntime.FunctionFile, + spec.GenericRuntime.Language, spec.ClusterName, + generateFunctionDetailsInJSON(function), string(function.UID), + spec.Pulsar.AuthSecret != "", spec.Pulsar.TLSSecret != "", function.Spec.SecretsMap, + function.Spec.StateConfig, function.Spec.Pulsar.TLSConfig, function.Spec.Pulsar.AuthConfig) + } } return nil diff --git a/go.mod b/go.mod index 7ae9d6816..614dbf3c0 100644 --- a/go.mod +++ b/go.mod @@ -80,12 +80,12 @@ require ( go.uber.org/atomic v1.7.0 // indirect go.uber.org/multierr v1.6.0 // indirect go.uber.org/zap v1.21.0 // indirect - golang.org/x/crypto v0.1.0 // indirect - golang.org/x/net v0.7.0 // indirect + golang.org/x/crypto v0.14.0 // indirect + golang.org/x/net v0.17.0 // indirect golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect - golang.org/x/sys v0.5.0 // indirect - golang.org/x/term v0.5.0 // indirect - golang.org/x/text v0.7.0 // indirect + golang.org/x/sys v0.13.0 // indirect + golang.org/x/term v0.13.0 // indirect + golang.org/x/text v0.13.0 // indirect golang.org/x/time v0.0.0-20220609170525-579cf78fd858 // indirect gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect google.golang.org/appengine v1.6.7 // indirect diff --git a/go.sum b/go.sum index 4dfed51ba..c58444ea3 100644 --- a/go.sum +++ b/go.sum @@ -452,6 +452,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -531,6 +533,8 @@ golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -626,9 +630,13 @@ golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= +golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -639,6 +647,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/manifests/crd.yaml b/manifests/crd.yaml index 7c79cd2d1..cbec5ea39 100644 --- a/manifests/crd.yaml +++ b/manifests/crd.yaml @@ -62,6 +62,18 @@ spec: funcConfig: type: object x-kubernetes-preserve-unknown-fields: true + genericRuntime: + properties: + functionFile: + type: string + functionFileLocation: + type: string + language: + type: string + required: + - functionFile + - language + type: object golang: properties: go: @@ -3632,6 +3644,18 @@ spec: type: string filebeatImage: type: string + genericRuntime: + properties: + functionFile: + type: string + functionFileLocation: + type: string + language: + type: string + required: + - functionFile + - language + type: object golang: properties: go: @@ -6949,6 +6973,18 @@ spec: type: string forwardSourceMessageProperty: type: boolean + genericRuntime: + properties: + functionFile: + type: string + functionFileLocation: + type: string + language: + type: string + required: + - functionFile + - language + type: object golang: properties: go: @@ -10332,6 +10368,18 @@ spec: funcConfig: type: object x-kubernetes-preserve-unknown-fields: true + genericRuntime: + properties: + functionFile: + type: string + functionFileLocation: + type: string + language: + type: string + required: + - functionFile + - language + type: object golang: properties: go: @@ -13975,6 +14023,18 @@ spec: type: string filebeatImage: type: string + genericRuntime: + properties: + functionFile: + type: string + functionFileLocation: + type: string + language: + type: string + required: + - functionFile + - language + type: object golang: properties: go: @@ -17365,6 +17425,18 @@ spec: type: string forwardSourceMessageProperty: type: boolean + genericRuntime: + properties: + functionFile: + type: string + functionFileLocation: + type: string + language: + type: string + required: + - functionFile + - language + type: object golang: properties: go: diff --git a/pkg/webhook/function_webhook.go b/pkg/webhook/function_webhook.go index 06a90dab4..3d9278106 100644 --- a/pkg/webhook/function_webhook.go +++ b/pkg/webhook/function_webhook.go @@ -189,13 +189,15 @@ func (webhook *FunctionWebhook) ValidateCreate(ctx context.Context, obj runtime. allErrs = append(allErrs, field.Invalid(field.NewPath("name"), r.Name, "function name is not provided")) } - if r.Spec.Runtime.Java == nil && r.Spec.Runtime.Python == nil && r.Spec.Runtime.Golang == nil { + if r.Spec.Runtime.Java == nil && r.Spec.Runtime.Python == nil && r.Spec.Runtime.Golang == nil && r.Spec.GenericRuntime == nil { allErrs = append(allErrs, field.Invalid(field.NewPath("spec").Child("runtime", "java"), r.Spec.Runtime.Java, "runtime cannot be empty")) allErrs = append(allErrs, field.Invalid(field.NewPath("spec").Child("runtime", "python"), r.Spec.Runtime.Python, "runtime cannot be empty")) allErrs = append(allErrs, field.Invalid(field.NewPath("spec").Child("runtime", "golang"), r.Spec.Runtime.Golang, "runtime cannot be empty")) + allErrs = append(allErrs, field.Invalid(field.NewPath("spec").Child("runtime", "genericRuntime"), r.Spec.Runtime.GenericRuntime, + "runtime cannot be empty")) } if (r.Spec.Runtime.Java != nil && r.Spec.Runtime.Python != nil) ||