mirror of
https://github.com/kubevela/kubevela.git
synced 2026-08-27 16:17:34 +00:00
Feat: support secret in webhook notification (#2509)
This commit is contained in:
@@ -13,11 +13,18 @@ spec:
|
||||
template: |
|
||||
import (
|
||||
"vela/op"
|
||||
"encoding/base64"
|
||||
)
|
||||
|
||||
parameter: {
|
||||
dingding?: {
|
||||
url: string
|
||||
url: {
|
||||
address?: string
|
||||
fromSecret?: {
|
||||
name: string
|
||||
key: string
|
||||
}
|
||||
}
|
||||
message: {
|
||||
text?: *null | {
|
||||
content: string
|
||||
@@ -62,7 +69,13 @@ spec:
|
||||
}
|
||||
|
||||
slack?: {
|
||||
url: string
|
||||
url: {
|
||||
address?: string
|
||||
fromSecret?: {
|
||||
name: string
|
||||
key: string
|
||||
}
|
||||
}
|
||||
message: {
|
||||
text: string
|
||||
blocks?: *null | [...block]
|
||||
@@ -121,19 +134,61 @@ spec:
|
||||
url?: string
|
||||
}
|
||||
// send webhook notification
|
||||
ding: {
|
||||
ding: op.#Steps & {
|
||||
if parameter.dingding != _|_ {
|
||||
op.#DingTalk & {
|
||||
message: parameter.dingding.message
|
||||
dingUrl: parameter.dingding.url
|
||||
if parameter.dingding.url.address != _|_ {
|
||||
ding1: op.#DingTalk & {
|
||||
message: parameter.dingding.message
|
||||
dingUrl: parameter.dingding.url.address
|
||||
}
|
||||
}
|
||||
if parameter.dingding.url.fromSecret != _|_ && parameter.dingding.url.address == _|_ {
|
||||
read: op.#Read & {
|
||||
value: {
|
||||
apiVersion: "v1"
|
||||
kind: "Secret"
|
||||
metadata: {
|
||||
name: parameter.dingding.url.fromSecret.name
|
||||
namespace: context.namespace
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
decoded: base64.Decode(null, read.value.data[parameter.dingding.url.fromSecret.key])
|
||||
stringValue: op.#ConvertString & {bt: decoded}
|
||||
ding2: op.#DingTalk & {
|
||||
message: parameter.dingding.message
|
||||
dingUrl: stringValue.str
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
slack: {
|
||||
slack: op.#Steps & {
|
||||
if parameter.slack != _|_ {
|
||||
op.#Slack & {
|
||||
message: parameter.slack.message
|
||||
slackUrl: parameter.slack.url
|
||||
if parameter.slack.url.address != _|_ {
|
||||
slack1: op.#Slack & {
|
||||
message: parameter.slack.message
|
||||
slackUrl: parameter.slack.url.address
|
||||
}
|
||||
}
|
||||
if parameter.slack.url.fromSecret != _|_ && parameter.slack.url.address == _|_ {
|
||||
read: op.#Read & {
|
||||
value: {
|
||||
kind: "Secret"
|
||||
apiVersion: "v1"
|
||||
metadata: {
|
||||
name: parameter.slack.url.fromSecret.name
|
||||
namespace: context.namespace
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
decoded: base64.Decode(null, read.value.data[parameter.slack.url.fromSecret.key])
|
||||
stringValue: op.#ConvertString & {bt: decoded}
|
||||
slack2: op.#Slack & {
|
||||
message: parameter.slack.message
|
||||
slackUrl: stringValue.str
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,11 +13,18 @@ spec:
|
||||
template: |
|
||||
import (
|
||||
"vela/op"
|
||||
"encoding/base64"
|
||||
)
|
||||
|
||||
parameter: {
|
||||
dingding?: {
|
||||
url: string
|
||||
url: {
|
||||
address?: string
|
||||
fromSecret?: {
|
||||
name: string
|
||||
key: string
|
||||
}
|
||||
}
|
||||
message: {
|
||||
text?: *null | {
|
||||
content: string
|
||||
@@ -62,7 +69,13 @@ spec:
|
||||
}
|
||||
|
||||
slack?: {
|
||||
url: string
|
||||
url: {
|
||||
address?: string
|
||||
fromSecret?: {
|
||||
name: string
|
||||
key: string
|
||||
}
|
||||
}
|
||||
message: {
|
||||
text: string
|
||||
blocks?: *null | [...block]
|
||||
@@ -121,19 +134,61 @@ spec:
|
||||
url?: string
|
||||
}
|
||||
// send webhook notification
|
||||
ding: {
|
||||
ding: op.#Steps & {
|
||||
if parameter.dingding != _|_ {
|
||||
op.#DingTalk & {
|
||||
message: parameter.dingding.message
|
||||
dingUrl: parameter.dingding.url
|
||||
if parameter.dingding.url.address != _|_ {
|
||||
ding1: op.#DingTalk & {
|
||||
message: parameter.dingding.message
|
||||
dingUrl: parameter.dingding.url.address
|
||||
}
|
||||
}
|
||||
if parameter.dingding.url.fromSecret != _|_ && parameter.dingding.url.address == _|_ {
|
||||
read: op.#Read & {
|
||||
value: {
|
||||
apiVersion: "v1"
|
||||
kind: "Secret"
|
||||
metadata: {
|
||||
name: parameter.dingding.url.fromSecret.name
|
||||
namespace: context.namespace
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
decoded: base64.Decode(null, read.value.data[parameter.dingding.url.fromSecret.key])
|
||||
stringValue: op.#ConvertString & {bt: decoded}
|
||||
ding2: op.#DingTalk & {
|
||||
message: parameter.dingding.message
|
||||
dingUrl: stringValue.str
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
slack: {
|
||||
slack: op.#Steps & {
|
||||
if parameter.slack != _|_ {
|
||||
op.#Slack & {
|
||||
message: parameter.slack.message
|
||||
slackUrl: parameter.slack.url
|
||||
if parameter.slack.url.address != _|_ {
|
||||
slack1: op.#Slack & {
|
||||
message: parameter.slack.message
|
||||
slackUrl: parameter.slack.url.address
|
||||
}
|
||||
}
|
||||
if parameter.slack.url.fromSecret != _|_ && parameter.slack.url.address == _|_ {
|
||||
read: op.#Read & {
|
||||
value: {
|
||||
kind: "Secret"
|
||||
apiVersion: "v1"
|
||||
metadata: {
|
||||
name: parameter.slack.url.fromSecret.name
|
||||
namespace: context.namespace
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
decoded: base64.Decode(null, read.value.data[parameter.slack.url.fromSecret.key])
|
||||
stringValue: op.#ConvertString & {bt: decoded}
|
||||
slack2: op.#Slack & {
|
||||
message: parameter.slack.message
|
||||
slackUrl: stringValue.str
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,6 +134,8 @@ import (
|
||||
|
||||
#HTTPDelete: http.#Do & {method: "DELETE"}
|
||||
|
||||
#ConvertString: convert.#String
|
||||
|
||||
#Load: oam.#LoadComponets
|
||||
|
||||
#Read: kube.#Read
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
#String: {
|
||||
#do: "string"
|
||||
#provider: "convert"
|
||||
|
||||
bt: bytes
|
||||
str?: string
|
||||
...
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
Copyright 2021 The KubeVela Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package convert
|
||||
|
||||
import (
|
||||
"github.com/oam-dev/kubevela/pkg/cue/model/value"
|
||||
wfContext "github.com/oam-dev/kubevela/pkg/workflow/context"
|
||||
"github.com/oam-dev/kubevela/pkg/workflow/providers"
|
||||
"github.com/oam-dev/kubevela/pkg/workflow/types"
|
||||
)
|
||||
|
||||
const (
|
||||
// ProviderName is provider name for install.
|
||||
ProviderName = "convert"
|
||||
)
|
||||
|
||||
type provider struct {
|
||||
}
|
||||
|
||||
// String convert byte to string
|
||||
func (h *provider) String(ctx wfContext.Context, v *value.Value, act types.Action) error {
|
||||
b, err := v.LookupValue("bt")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s, err := b.CueValue().Bytes()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return v.FillObject(string(s), "str")
|
||||
}
|
||||
|
||||
// Install register handlers to provider discover.
|
||||
func Install(p providers.Providers) {
|
||||
prd := &provider{}
|
||||
p.Register(ProviderName, map[string]providers.Handler{
|
||||
"string": prd.String,
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
Copyright 2021 The KubeVela Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package convert
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"gotest.tools/assert"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/oam-dev/kubevela/pkg/cue/model/value"
|
||||
"github.com/oam-dev/kubevela/pkg/workflow/providers"
|
||||
)
|
||||
|
||||
func TestConvertString(t *testing.T) {
|
||||
testCases := map[string]struct {
|
||||
from string
|
||||
expected string
|
||||
expectedErr error
|
||||
}{
|
||||
"success": {
|
||||
from: `bt: 'test'`,
|
||||
expected: "test",
|
||||
},
|
||||
"fail": {
|
||||
from: `bt: 123`,
|
||||
expectedErr: errors.New("bt: cannot use value 123 (type int) as string|bytes"),
|
||||
},
|
||||
}
|
||||
|
||||
for name, tc := range testCases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
r := require.New(t)
|
||||
v, err := value.NewValue(tc.from, nil, "")
|
||||
r.NoError(err)
|
||||
prd := &provider{}
|
||||
err = prd.String(nil, v, nil)
|
||||
if tc.expectedErr != nil {
|
||||
r.Equal(tc.expectedErr.Error(), err.Error())
|
||||
return
|
||||
}
|
||||
r.NoError(err)
|
||||
expected, err := v.LookupValue("str")
|
||||
r.NoError(err)
|
||||
ret, err := expected.CueValue().String()
|
||||
r.NoError(err)
|
||||
r.Equal(ret, tc.expected)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestInstall(t *testing.T) {
|
||||
p := providers.NewProviders()
|
||||
Install(p)
|
||||
h, ok := p.GetHandler("convert", "string")
|
||||
assert.Equal(t, ok, true)
|
||||
assert.Equal(t, h != nil, true)
|
||||
}
|
||||
@@ -28,6 +28,7 @@ import (
|
||||
"github.com/oam-dev/kubevela/pkg/oam/discoverymapper"
|
||||
wfContext "github.com/oam-dev/kubevela/pkg/workflow/context"
|
||||
"github.com/oam-dev/kubevela/pkg/workflow/providers"
|
||||
"github.com/oam-dev/kubevela/pkg/workflow/providers/convert"
|
||||
"github.com/oam-dev/kubevela/pkg/workflow/providers/http"
|
||||
"github.com/oam-dev/kubevela/pkg/workflow/providers/workspace"
|
||||
"github.com/oam-dev/kubevela/pkg/workflow/tasks/custom"
|
||||
@@ -72,6 +73,7 @@ func NewTaskDiscover(providerHandlers providers.Providers, pd *packages.PackageD
|
||||
// install builtin provider
|
||||
workspace.Install(providerHandlers)
|
||||
http.Install(providerHandlers)
|
||||
convert.Install(providerHandlers)
|
||||
templateLoader := template.NewTemplateLoader(cli, dm)
|
||||
return &taskDiscover{
|
||||
builtins: map[string]types.TaskGenerator{
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import (
|
||||
"vela/op"
|
||||
"encoding/base64"
|
||||
)
|
||||
|
||||
"webhook-notification": {
|
||||
@@ -12,7 +13,13 @@ template: {
|
||||
|
||||
parameter: {
|
||||
dingding?: {
|
||||
url: string
|
||||
url: {
|
||||
address?: string
|
||||
fromSecret?: {
|
||||
name: string
|
||||
key: string
|
||||
}
|
||||
}
|
||||
message: {
|
||||
text?: *null | {
|
||||
content: string
|
||||
@@ -57,7 +64,13 @@ template: {
|
||||
}
|
||||
|
||||
slack?: {
|
||||
url: string
|
||||
url: {
|
||||
address?: string
|
||||
fromSecret?: {
|
||||
name: string
|
||||
key: string
|
||||
}
|
||||
}
|
||||
message: {
|
||||
text: string
|
||||
blocks?: *null | [...block]
|
||||
@@ -122,20 +135,62 @@ template: {
|
||||
}
|
||||
|
||||
// send webhook notification
|
||||
ding: {
|
||||
ding: op.#Steps & {
|
||||
if parameter.dingding != _|_ {
|
||||
op.#DingTalk & {
|
||||
message: parameter.dingding.message
|
||||
dingUrl: parameter.dingding.url
|
||||
if parameter.dingding.url.address != _|_ {
|
||||
ding1: op.#DingTalk & {
|
||||
message: parameter.dingding.message
|
||||
dingUrl: parameter.dingding.url.address
|
||||
}
|
||||
}
|
||||
if parameter.dingding.url.fromSecret != _|_ && parameter.dingding.url.address == _|_ {
|
||||
read: op.#Read & {
|
||||
value: {
|
||||
apiVersion: "v1"
|
||||
kind: "Secret"
|
||||
metadata: {
|
||||
name: parameter.dingding.url.fromSecret.name
|
||||
namespace: context.namespace
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
decoded: base64.Decode(null, read.value.data[parameter.dingding.url.fromSecret.key])
|
||||
stringValue: op.#ConvertString & {bt: decoded}
|
||||
ding2: op.#DingTalk & {
|
||||
message: parameter.dingding.message
|
||||
dingUrl: stringValue.str
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
slack: {
|
||||
slack: op.#Steps & {
|
||||
if parameter.slack != _|_ {
|
||||
op.#Slack & {
|
||||
message: parameter.slack.message
|
||||
slackUrl: parameter.slack.url
|
||||
if parameter.slack.url.address != _|_ {
|
||||
slack1: op.#Slack & {
|
||||
message: parameter.slack.message
|
||||
slackUrl: parameter.slack.url.address
|
||||
}
|
||||
}
|
||||
if parameter.slack.url.fromSecret != _|_ && parameter.slack.url.address == _|_ {
|
||||
read: op.#Read & {
|
||||
value: {
|
||||
kind: "Secret"
|
||||
apiVersion: "v1"
|
||||
metadata: {
|
||||
name: parameter.slack.url.fromSecret.name
|
||||
namespace: context.namespace
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
decoded: base64.Decode(null, read.value.data[parameter.slack.url.fromSecret.key])
|
||||
stringValue: op.#ConvertString & {bt: decoded}
|
||||
slack2: op.#Slack & {
|
||||
message: parameter.slack.message
|
||||
slackUrl: stringValue.str
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user