feat: new deployment provider: kong

This commit is contained in:
Fu Diwei 2025-06-25 20:50:18 +08:00 committed by RHQYZ
parent 64063554c2
commit 2db6d5c163
21 changed files with 491 additions and 10 deletions

7
go.mod
View File

@ -40,6 +40,7 @@ require (
github.com/go-viper/mapstructure/v2 v2.3.0 github.com/go-viper/mapstructure/v2 v2.3.0
github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.155 github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.155
github.com/jdcloud-api/jdcloud-sdk-go v1.64.0 github.com/jdcloud-api/jdcloud-sdk-go v1.64.0
github.com/kong/go-kong v0.66.1
github.com/libdns/dynv6 v1.0.0 github.com/libdns/dynv6 v1.0.0
github.com/libdns/libdns v0.2.3 github.com/libdns/libdns v0.2.3
github.com/luthermonson/go-proxmox v0.2.2 github.com/luthermonson/go-proxmox v0.2.2
@ -109,12 +110,15 @@ require (
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-retryablehttp v0.7.7 // indirect github.com/hashicorp/go-retryablehttp v0.7.7 // indirect
github.com/imdario/mergo v0.3.12 // indirect
github.com/jinzhu/copier v0.3.4 // indirect github.com/jinzhu/copier v0.3.4 // indirect
github.com/josharian/intern v1.0.0 // indirect github.com/josharian/intern v1.0.0 // indirect
github.com/kong/semver/v4 v4.0.1 // indirect
github.com/kylelemons/godebug v1.1.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect
github.com/leodido/go-urn v1.4.0 // indirect github.com/leodido/go-urn v1.4.0 // indirect
github.com/magefile/mage v1.14.0 // indirect github.com/magefile/mage v1.14.0 // indirect
github.com/mailru/easyjson v0.9.0 // indirect github.com/mailru/easyjson v0.9.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04 // indirect github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04 // indirect
github.com/nrdcg/bunny-go v0.0.0-20240207213615-dde5bf4577a3 // indirect github.com/nrdcg/bunny-go v0.0.0-20240207213615-dde5bf4577a3 // indirect
@ -127,6 +131,9 @@ require (
github.com/qiniu/x v1.10.5 // indirect github.com/qiniu/x v1.10.5 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/sirupsen/logrus v1.9.4-0.20230606125235-dd1b4c2e81af // indirect github.com/sirupsen/logrus v1.9.4-0.20230606125235-dd1b4c2e81af // indirect
github.com/tidwall/gjson v1.18.0 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.0 // indirect
github.com/x448/float16 v0.8.4 // indirect github.com/x448/float16 v0.8.4 // indirect
go.mongodb.org/mongo-driver v1.17.2 // indirect go.mongodb.org/mongo-driver v1.17.2 // indirect
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect

26
go.sum
View File

@ -552,6 +552,8 @@ github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.155/go.mod h1:Y/+YLCFCJtS29i2M
github.com/hudl/fargo v1.4.0/go.mod h1:9Ai6uvFy5fQNq6VPKtg+Ceq1+eTY4nKUlR2JElEOcDo= github.com/hudl/fargo v1.4.0/go.mod h1:9Ai6uvFy5fQNq6VPKtg+Ceq1+eTY4nKUlR2JElEOcDo=
github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/influxdata/influxdb1-client v0.0.0-20200827194710-b269163b24ab/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/influxdata/influxdb1-client v0.0.0-20200827194710-b269163b24ab/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
@ -596,6 +598,10 @@ github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47e
github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4= github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4=
github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM=
github.com/kong/go-kong v0.66.1 h1:UVdemzcCpfXEl6O/VHdf0rT2bXdIO5ykuJbf2z1JTko=
github.com/kong/go-kong v0.66.1/go.mod h1:wRMPAXGOB3kn53TF6zN4l2JhIWPUfXDFKNHkMHBB3iQ=
github.com/kong/semver/v4 v4.0.1 h1:DIcNR8W3gfx0KabFBADPalxxsp+q/5COwIFkkhrFQ2Y=
github.com/kong/semver/v4 v4.0.1/go.mod h1:LImQ0oT15pJvSns/hs2laLca2zcYoHu5EsSNY0J6/QA=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8=
@ -656,6 +662,8 @@ github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eI
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@ -786,6 +794,8 @@ github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWN
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/samber/lo v1.50.0 h1:XrG0xOeHs+4FQ8gJR97zDz5uOFMW7OwFWiFVzqopKgY=
github.com/samber/lo v1.50.0/go.mod h1:RjZyNk6WSnUFRKK6EyOhsRJMqft3G+pg7dCWHQCWvsc=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
@ -829,8 +839,6 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdn v1.0.1187 h1:x2q6BAFm2f+9YaE7/lGPWXL7HzRkovjoqOMbdtRdpBw=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdn v1.0.1187/go.mod h1:GoIHP0ayv0QOWN4c9aUEaKi74lY/tbeJz7h5i8y2gdU=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdn v1.0.1193 h1:zOWZKDVA3kvA5/b+AwKzDtz5ewdiibeKxVqtCFJSTNI= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdn v1.0.1193 h1:zOWZKDVA3kvA5/b+AwKzDtz5ewdiibeKxVqtCFJSTNI=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdn v1.0.1193/go.mod h1:ufxDBGyS3X/9QKkZzuOFKLNra9FmSfgAHBO/FlFZaTU= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdn v1.0.1193/go.mod h1:ufxDBGyS3X/9QKkZzuOFKLNra9FmSfgAHBO/FlFZaTU=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.0.1188 h1:zzaIE12soTfyAgRvBYhb5bYxFXRCelvYXDEfvtkT5Y4= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.0.1188 h1:zzaIE12soTfyAgRvBYhb5bYxFXRCelvYXDEfvtkT5Y4=
@ -840,26 +848,18 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1163/go.mod
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1172/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1172/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1182/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1182/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1183/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1183/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1187/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1188/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1188/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1189/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1191/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1191/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1192 h1:3K6aJXXkjBLxqFYnBqAqFW5YqxmwMT0HR2F4gxQiNMU=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1192/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1193 h1:anxhOjL4WrQDqUcX7eT8VEaQITiKWllKwsH1fEt6lBw= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1193 h1:anxhOjL4WrQDqUcX7eT8VEaQITiKWllKwsH1fEt6lBw=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1193/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1193/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1128 h1:mrJ5Fbkd7sZIJ5F6oRfh5zebPQaudPH9Y0+GUmFytYU= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1128 h1:mrJ5Fbkd7sZIJ5F6oRfh5zebPQaudPH9Y0+GUmFytYU=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1128/go.mod h1:zbsYIBT+VTX4z4ocjTAdLBIWyNYj3z0BRqd0iPdnjsk= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1128/go.mod h1:zbsYIBT+VTX4z4ocjTAdLBIWyNYj3z0BRqd0iPdnjsk=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/gaap v1.0.1163 h1:putqrH5n1SVRqFWHOylVqYI5yLQUjRTkHqZPLT2yeVY= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/gaap v1.0.1163 h1:putqrH5n1SVRqFWHOylVqYI5yLQUjRTkHqZPLT2yeVY=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/gaap v1.0.1163/go.mod h1:aEWRXlAvovPUUoS3kVB/LVWEQ19WqzTj2lXGvR1YArY= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/gaap v1.0.1163/go.mod h1:aEWRXlAvovPUUoS3kVB/LVWEQ19WqzTj2lXGvR1YArY=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/live v1.0.1192 h1:2430drceaOXASJZyVZ+e7QSzgBfgwSjDEDM5rh4046M=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/live v1.0.1192/go.mod h1:JHZLo95Fde/0et2Ag2E5P6VmCZQIq74MClUtanJ4JcY=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/live v1.0.1193 h1:VtXqRnzGz3KheXu2msNPvA/fUYQGsVVRC30WgyAUEqg= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/live v1.0.1193 h1:VtXqRnzGz3KheXu2msNPvA/fUYQGsVVRC30WgyAUEqg=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/live v1.0.1193/go.mod h1:42I1OwaedHR6Yvg7J6UYoOjNYUYfFqwaeEkvx3x+NZc= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/live v1.0.1193/go.mod h1:42I1OwaedHR6Yvg7J6UYoOjNYUYfFqwaeEkvx3x+NZc=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/scf v1.0.1172 h1:6SUO0hTie3zxnUEMxmhnS1iRIXpAukSZV27Nrx4NwIk= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/scf v1.0.1172 h1:6SUO0hTie3zxnUEMxmhnS1iRIXpAukSZV27Nrx4NwIk=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/scf v1.0.1172/go.mod h1:tmN4zfu70SD0iee3qfpc09NRLel30zGoAuzIs4X0Kfs= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/scf v1.0.1172/go.mod h1:tmN4zfu70SD0iee3qfpc09NRLel30zGoAuzIs4X0Kfs=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl v1.0.1189 h1:Db7gmkey7On70PAohvrna6RMLZzLHRjbALxPlH5JC3c=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl v1.0.1189/go.mod h1:x+WlMCjbePO7M3R0qzKmrpmieUWrtsRpcKBDpxJNQ5A=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl v1.0.1193 h1:tmACSthp5JLjrdxzng6XFs4gfQcZHBTTVlXR0tO6hSk= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl v1.0.1193 h1:tmACSthp5JLjrdxzng6XFs4gfQcZHBTTVlXR0tO6hSk=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl v1.0.1193/go.mod h1:LWf5UPUl41EQICrq0jswgQEO/BtRQY+CxAI6X+i709o= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl v1.0.1193/go.mod h1:LWf5UPUl41EQICrq0jswgQEO/BtRQY+CxAI6X+i709o=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo v1.0.1191 h1:4l1Db+yFh9HgqNynYbG93khxLtXSBwnXZgNmc88jOE0= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo v1.0.1191 h1:4l1Db+yFh9HgqNynYbG93khxLtXSBwnXZgNmc88jOE0=
@ -868,6 +868,12 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vod v1.0.1183 h1:3fvxkF
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vod v1.0.1183/go.mod h1:d47RTYqj/2xjIk/lmq8bQ9deUwfEQcWhPQxUgqZnz24= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vod v1.0.1183/go.mod h1:d47RTYqj/2xjIk/lmq8bQ9deUwfEQcWhPQxUgqZnz24=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/waf v1.0.1182 h1:2DaykFM5mXvQBvuhQEU/aOG5amissS31XI1wZh+FeMA= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/waf v1.0.1182 h1:2DaykFM5mXvQBvuhQEU/aOG5amissS31XI1wZh+FeMA=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/waf v1.0.1182/go.mod h1:pTAgdVcS28xFIARJXhg10hx2+g/Q9FqVkAkal3ARNfc= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/waf v1.0.1182/go.mod h1:pTAgdVcS28xFIARJXhg10hx2+g/Q9FqVkAkal3ARNfc=
github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/tjfoc/gmsm v1.3.2/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w= github.com/tjfoc/gmsm v1.3.2/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w=
github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho= github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho=
github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE= github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE=

View File

@ -63,6 +63,7 @@ import (
pJDCloudLive "github.com/certimate-go/certimate/pkg/core/ssl-deployer/providers/jdcloud-live" pJDCloudLive "github.com/certimate-go/certimate/pkg/core/ssl-deployer/providers/jdcloud-live"
pJDCloudVOD "github.com/certimate-go/certimate/pkg/core/ssl-deployer/providers/jdcloud-vod" pJDCloudVOD "github.com/certimate-go/certimate/pkg/core/ssl-deployer/providers/jdcloud-vod"
pK8sSecret "github.com/certimate-go/certimate/pkg/core/ssl-deployer/providers/k8s-secret" pK8sSecret "github.com/certimate-go/certimate/pkg/core/ssl-deployer/providers/k8s-secret"
pKong "github.com/certimate-go/certimate/pkg/core/ssl-deployer/providers/kong"
pLeCDN "github.com/certimate-go/certimate/pkg/core/ssl-deployer/providers/lecdn" pLeCDN "github.com/certimate-go/certimate/pkg/core/ssl-deployer/providers/lecdn"
pLocal "github.com/certimate-go/certimate/pkg/core/ssl-deployer/providers/local" pLocal "github.com/certimate-go/certimate/pkg/core/ssl-deployer/providers/local"
pNetlifySite "github.com/certimate-go/certimate/pkg/core/ssl-deployer/providers/netlify-site" pNetlifySite "github.com/certimate-go/certimate/pkg/core/ssl-deployer/providers/netlify-site"
@ -924,6 +925,24 @@ func createSSLDeployerProvider(options *deployerProviderOptions) (core.SSLDeploy
return deployer, err return deployer, err
} }
case domain.DeploymentProviderTypeKong:
{
access := domain.AccessConfigForKong{}
if err := xmaps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, fmt.Errorf("failed to populate provider access config: %w", err)
}
deployer, err := pKong.NewSSLDeployerProvider(&pKong.SSLDeployerProviderConfig{
ServerUrl: access.ServerUrl,
ApiToken: access.ApiToken,
AllowInsecureConnections: access.AllowInsecureConnections,
ResourceType: pKong.ResourceType(xmaps.GetString(options.ProviderServiceConfig, "resourceType")),
Workspace: xmaps.GetString(options.ProviderServiceConfig, "workspace"),
CertificateId: xmaps.GetString(options.ProviderServiceConfig, "certificateId"),
})
return deployer, err
}
case domain.DeploymentProviderTypeKubernetesSecret: case domain.DeploymentProviderTypeKubernetesSecret:
{ {
access := domain.AccessConfigForKubernetes{} access := domain.AccessConfigForKubernetes{}

View File

@ -227,6 +227,12 @@ type AccessConfigForJDCloud struct {
AccessKeySecret string `json:"accessKeySecret"` AccessKeySecret string `json:"accessKeySecret"`
} }
type AccessConfigForKong struct {
ServerUrl string `json:"serverUrl"`
ApiToken string `json:"apiToken"`
AllowInsecureConnections bool `json:"allowInsecureConnections,omitempty"`
}
type AccessConfigForKubernetes struct { type AccessConfigForKubernetes struct {
KubeConfig string `json:"kubeConfig,omitempty"` KubeConfig string `json:"kubeConfig,omitempty"`
} }

View File

@ -52,6 +52,7 @@ const (
AccessProviderTypeHetzner = AccessProviderType("hetzner") AccessProviderTypeHetzner = AccessProviderType("hetzner")
AccessProviderTypeHuaweiCloud = AccessProviderType("huaweicloud") AccessProviderTypeHuaweiCloud = AccessProviderType("huaweicloud")
AccessProviderTypeJDCloud = AccessProviderType("jdcloud") AccessProviderTypeJDCloud = AccessProviderType("jdcloud")
AccessProviderTypeKong = AccessProviderType("kong")
AccessProviderTypeKubernetes = AccessProviderType("k8s") AccessProviderTypeKubernetes = AccessProviderType("k8s")
AccessProviderTypeLarkBot = AccessProviderType("larkbot") AccessProviderTypeLarkBot = AccessProviderType("larkbot")
AccessProviderTypeLetsEncrypt = AccessProviderType("letsencrypt") AccessProviderTypeLetsEncrypt = AccessProviderType("letsencrypt")
@ -236,6 +237,7 @@ const (
DeploymentProviderTypeJDCloudCDN = DeploymentProviderType(AccessProviderTypeJDCloud + "-cdn") DeploymentProviderTypeJDCloudCDN = DeploymentProviderType(AccessProviderTypeJDCloud + "-cdn")
DeploymentProviderTypeJDCloudLive = DeploymentProviderType(AccessProviderTypeJDCloud + "-live") DeploymentProviderTypeJDCloudLive = DeploymentProviderType(AccessProviderTypeJDCloud + "-live")
DeploymentProviderTypeJDCloudVOD = DeploymentProviderType(AccessProviderTypeJDCloud + "-vod") DeploymentProviderTypeJDCloudVOD = DeploymentProviderType(AccessProviderTypeJDCloud + "-vod")
DeploymentProviderTypeKong = DeploymentProviderType(AccessProviderTypeKong)
DeploymentProviderTypeKubernetesSecret = DeploymentProviderType(AccessProviderTypeKubernetes + "-secret") DeploymentProviderTypeKubernetesSecret = DeploymentProviderType(AccessProviderTypeKubernetes + "-secret")
DeploymentProviderTypeLeCDN = DeploymentProviderType(AccessProviderTypeLeCDN) DeploymentProviderTypeLeCDN = DeploymentProviderType(AccessProviderTypeLeCDN)
DeploymentProviderTypeLocal = DeploymentProviderType(AccessProviderTypeLocal) DeploymentProviderTypeLocal = DeploymentProviderType(AccessProviderTypeLocal)

View File

@ -0,0 +1,8 @@
package kong
type ResourceType string
const (
// 资源类型:替换指定证书。
RESOURCE_TYPE_CERTIFICATE = ResourceType("certificate")
)

View File

@ -0,0 +1,149 @@
package kong
import (
"context"
"crypto/tls"
"errors"
"fmt"
"log/slog"
"net/http"
"net/url"
"strings"
"github.com/kong/go-kong/kong"
"github.com/certimate-go/certimate/pkg/core"
xcert "github.com/certimate-go/certimate/pkg/utils/cert"
xhttp "github.com/certimate-go/certimate/pkg/utils/http"
)
type SSLDeployerProviderConfig struct {
// Kong 服务地址。
ServerUrl string `json:"serverUrl"`
// Kong Admin API Token。
ApiToken string `json:"apiToken"`
// 是否允许不安全的连接。
AllowInsecureConnections bool `json:"allowInsecureConnections,omitempty"`
// 部署资源类型。
ResourceType ResourceType `json:"resourceType"`
// 工作空间。
// 选填。
Workspace string `json:"workspace,omitempty"`
// 证书 ID。
// 部署资源类型为 [RESOURCE_TYPE_CERTIFICATE] 时必填。
CertificateId string `json:"certificateId,omitempty"`
}
type SSLDeployerProvider struct {
config *SSLDeployerProviderConfig
logger *slog.Logger
sdkClient *kong.Client
}
var _ core.SSLDeployer = (*SSLDeployerProvider)(nil)
func NewSSLDeployerProvider(config *SSLDeployerProviderConfig) (*SSLDeployerProvider, error) {
if config == nil {
return nil, errors.New("the configuration of the ssl deployer provider is nil")
}
client, err := createSDKClient(config.ServerUrl, config.Workspace, config.ApiToken, config.AllowInsecureConnections)
if err != nil {
return nil, fmt.Errorf("could not create sdk client: %w", err)
}
return &SSLDeployerProvider{
config: config,
logger: slog.Default(),
sdkClient: client,
}, nil
}
func (d *SSLDeployerProvider) SetLogger(logger *slog.Logger) {
if logger == nil {
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}
}
func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPEM string) (*core.SSLDeployResult, error) {
// 根据部署资源类型决定部署方式
switch d.config.ResourceType {
case RESOURCE_TYPE_CERTIFICATE:
if err := d.deployToCertificate(ctx, certPEM, privkeyPEM); err != nil {
return nil, err
}
default:
return nil, fmt.Errorf("unsupported resource type '%s'", d.config.ResourceType)
}
return &core.SSLDeployResult{}, nil
}
func (d *SSLDeployerProvider) deployToCertificate(ctx context.Context, certPEM string, privkeyPEM string) error {
if d.config.CertificateId == "" {
return errors.New("config `certificateId` is required")
}
// 解析证书内容
certX509, err := xcert.ParseCertificateFromPEM(certPEM)
if err != nil {
return err
}
if d.config.Workspace == "" {
// 更新证书
// REF: https://developer.konghq.com/api/gateway/admin-ee/3.10/#/operations/upsert-certificate
updateCertificateReq := &kong.Certificate{
ID: kong.String(d.config.CertificateId),
Cert: kong.String(certPEM),
Key: kong.String(privkeyPEM),
SNIs: kong.StringSlice(certX509.DNSNames...),
}
updateCertificateResp, err := d.sdkClient.Certificates.Update(context.TODO(), updateCertificateReq)
d.logger.Debug("sdk request 'kong.UpdateCertificate'", slog.String("sslId", d.config.CertificateId), slog.Any("request", updateCertificateReq), slog.Any("response", updateCertificateResp))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'kong.UpdateCertificate': %w", err)
}
} else {
// 更新证书
// REF: https://developer.konghq.com/api/gateway/admin-ee/3.10/#/operations/upsert-certificate-in-workspace
updateCertificateReq := &kong.Certificate{
ID: kong.String(d.config.CertificateId),
Cert: kong.String(certPEM),
Key: kong.String(privkeyPEM),
SNIs: kong.StringSlice(certX509.DNSNames...),
}
updateCertificateResp, err := d.sdkClient.Certificates.Update(context.TODO(), updateCertificateReq)
d.logger.Debug("sdk request 'kong.UpdateCertificate'", slog.String("sslId", d.config.CertificateId), slog.Any("request", updateCertificateReq), slog.Any("response", updateCertificateResp))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'kong.UpdateCertificate': %w", err)
}
}
return nil
}
func createSDKClient(serverUrl, workspace, apiKey string, skipTlsVerify bool) (*kong.Client, error) {
httpClient := &http.Client{
Transport: xhttp.NewDefaultTransport(),
Timeout: http.DefaultClient.Timeout,
}
if skipTlsVerify {
transport := xhttp.NewDefaultTransport()
if transport.TLSClientConfig == nil {
transport.TLSClientConfig = &tls.Config{}
}
transport.TLSClientConfig.InsecureSkipVerify = true
httpClient.Transport = transport
}
baseUrl := strings.TrimRight(serverUrl, "/")
if workspace != "" {
baseUrl = fmt.Sprintf("%s/%s", baseUrl, url.PathEscape(workspace))
}
return kong.NewClient(kong.String(baseUrl), httpClient)
}

View File

@ -0,0 +1,77 @@
package kong_test
import (
"context"
"flag"
"fmt"
"os"
"strings"
"testing"
provider "github.com/certimate-go/certimate/pkg/core/ssl-deployer/providers/kong"
)
var (
fInputCertPath string
fInputKeyPath string
fServerUrl string
fApiToken string
fCertificateId string
)
func init() {
argsPrefix := "CERTIMATE_SSLDEPLOYER_KONG_"
flag.StringVar(&fInputCertPath, argsPrefix+"INPUTCERTPATH", "", "")
flag.StringVar(&fInputKeyPath, argsPrefix+"INPUTKEYPATH", "", "")
flag.StringVar(&fServerUrl, argsPrefix+"SERVERURL", "", "")
flag.StringVar(&fApiToken, argsPrefix+"APITOKEN", "", "")
flag.StringVar(&fCertificateId, argsPrefix+"CERTIFICATEID", "", "")
}
/*
Shell command to run this test:
go test -v ./kong_test.go -args \
--CERTIMATE_SSLDEPLOYER_KONG_INPUTCERTPATH="/path/to/your-input-cert.pem" \
--CERTIMATE_SSLDEPLOYER_KONG_INPUTKEYPATH="/path/to/your-input-key.pem" \
--CERTIMATE_SSLDEPLOYER_KONG_SERVERURL="http://127.0.0.1:9080" \
--CERTIMATE_SSLDEPLOYER_KONG_APITOKEN="your-admin-token" \
--CERTIMATE_SSLDEPLOYER_KONG_CERTIFICATEID="your-cerficiate-id"
*/
func TestDeploy(t *testing.T) {
flag.Parse()
t.Run("Deploy", func(t *testing.T) {
t.Log(strings.Join([]string{
"args:",
fmt.Sprintf("INPUTCERTPATH: %v", fInputCertPath),
fmt.Sprintf("INPUTKEYPATH: %v", fInputKeyPath),
fmt.Sprintf("SERVERURL: %v", fServerUrl),
fmt.Sprintf("APITOKEN: %v", fApiToken),
fmt.Sprintf("CERTIFICATEID: %v", fCertificateId),
}, "\n"))
deployer, err := provider.NewSSLDeployerProvider(&provider.SSLDeployerProviderConfig{
ServerUrl: fServerUrl,
ApiToken: fApiToken,
AllowInsecureConnections: true,
ResourceType: provider.RESOURCE_TYPE_CERTIFICATE,
CertificateId: fCertificateId,
})
if err != nil {
t.Errorf("err: %+v", err)
return
}
fInputCertData, _ := os.ReadFile(fInputCertPath)
fInputKeyData, _ := os.ReadFile(fInputKeyPath)
res, err := deployer.Deploy(context.Background(), string(fInputCertData), string(fInputKeyData))
if err != nil {
t.Errorf("err: %+v", err)
return
}
t.Logf("ok: %v", res)
})
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

View File

@ -50,6 +50,7 @@ import AccessFormGoogleTrustServicesConfig from "./AccessFormGoogleTrustServices
import AccessFormHetznerConfig from "./AccessFormHetznerConfig"; import AccessFormHetznerConfig from "./AccessFormHetznerConfig";
import AccessFormHuaweiCloudConfig from "./AccessFormHuaweiCloudConfig"; import AccessFormHuaweiCloudConfig from "./AccessFormHuaweiCloudConfig";
import AccessFormJDCloudConfig from "./AccessFormJDCloudConfig"; import AccessFormJDCloudConfig from "./AccessFormJDCloudConfig";
import AccessFormKongConfig from "./AccessFormKongConfig";
import AccessFormKubernetesConfig from "./AccessFormKubernetesConfig"; import AccessFormKubernetesConfig from "./AccessFormKubernetesConfig";
import AccessFormLarkBotConfig from "./AccessFormLarkBotConfig"; import AccessFormLarkBotConfig from "./AccessFormLarkBotConfig";
import AccessFormLeCDNConfig from "./AccessFormLeCDNConfig"; import AccessFormLeCDNConfig from "./AccessFormLeCDNConfig";
@ -266,6 +267,8 @@ const AccessForm = forwardRef<AccessFormInstance, AccessFormProps>(({ className,
return <AccessFormHuaweiCloudConfig {...nestedFormProps} />; return <AccessFormHuaweiCloudConfig {...nestedFormProps} />;
case ACCESS_PROVIDERS.JDCLOUD: case ACCESS_PROVIDERS.JDCLOUD:
return <AccessFormJDCloudConfig {...nestedFormProps} />; return <AccessFormJDCloudConfig {...nestedFormProps} />;
case ACCESS_PROVIDERS.KONG:
return <AccessFormKongConfig {...nestedFormProps} />;
case ACCESS_PROVIDERS.KUBERNETES: case ACCESS_PROVIDERS.KUBERNETES:
return <AccessFormKubernetesConfig {...nestedFormProps} />; return <AccessFormKubernetesConfig {...nestedFormProps} />;
case ACCESS_PROVIDERS.LARKBOT: case ACCESS_PROVIDERS.LARKBOT:

View File

@ -0,0 +1,71 @@
import { useTranslation } from "react-i18next";
import { Form, type FormInstance, Input, Switch } from "antd";
import { createSchemaFieldRule } from "antd-zod";
import { z } from "zod/v4";
import { type AccessConfigForKong } from "@/domain/access";
type AccessFormKongConfigFieldValues = Nullish<AccessConfigForKong>;
export type AccessFormKongConfigProps = {
form: FormInstance;
formName: string;
disabled?: boolean;
initialValues?: AccessFormKongConfigFieldValues;
onValuesChange?: (values: AccessFormKongConfigFieldValues) => void;
};
const initFormModel = (): AccessFormKongConfigFieldValues => {
return {
serverUrl: "http://<your-host-addr>:8001/",
apiToken: "",
};
};
const AccessFormKongConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormKongConfigProps) => {
const { t } = useTranslation();
const formSchema = z.object({
serverUrl: z.url(t("common.errmsg.url_invalid")),
apiToken: z.string().nonempty(t("access.form.kong_api_token.placeholder")),
allowInsecureConnections: z.boolean().nullish(),
});
const formRule = createSchemaFieldRule(formSchema);
const handleFormChange = (_: unknown, values: z.infer<typeof formSchema>) => {
onValuesChange?.(values);
};
return (
<Form
form={formInst}
disabled={disabled}
initialValues={initialValues ?? initFormModel()}
layout="vertical"
name={formName}
onValuesChange={handleFormChange}
>
<Form.Item name="serverUrl" label={t("access.form.kong_server_url.label")} rules={[formRule]}>
<Input placeholder={t("access.form.kong_server_url.placeholder")} />
</Form.Item>
<Form.Item
name="apiToken"
label={t("access.form.kong_api_token.label")}
rules={[formRule]}
tooltip={<span dangerouslySetInnerHTML={{ __html: t("access.form.kong_api_token.tooltip") }}></span>}
>
<Input.Password autoComplete="new-password" placeholder={t("access.form.kong_api_token.placeholder")} />
</Form.Item>
<Form.Item name="allowInsecureConnections" label={t("access.form.common_allow_insecure_conns.label")} rules={[formRule]}>
<Switch
checkedChildren={t("access.form.common_allow_insecure_conns.switch.on")}
unCheckedChildren={t("access.form.common_allow_insecure_conns.switch.off")}
/>
</Form.Item>
</Form>
);
};
export default AccessFormKongConfig;

View File

@ -65,6 +65,7 @@ import DeployNodeConfigFormJDCloudALBConfig from "./DeployNodeConfigFormJDCloudA
import DeployNodeConfigFormJDCloudCDNConfig from "./DeployNodeConfigFormJDCloudCDNConfig"; import DeployNodeConfigFormJDCloudCDNConfig from "./DeployNodeConfigFormJDCloudCDNConfig";
import DeployNodeConfigFormJDCloudLiveConfig from "./DeployNodeConfigFormJDCloudLiveConfig"; import DeployNodeConfigFormJDCloudLiveConfig from "./DeployNodeConfigFormJDCloudLiveConfig";
import DeployNodeConfigFormJDCloudVODConfig from "./DeployNodeConfigFormJDCloudVODConfig"; import DeployNodeConfigFormJDCloudVODConfig from "./DeployNodeConfigFormJDCloudVODConfig";
import DeployNodeConfigFormKongConfig from "./DeployNodeConfigFormKongConfig";
import DeployNodeConfigFormKubernetesSecretConfig from "./DeployNodeConfigFormKubernetesSecretConfig"; import DeployNodeConfigFormKubernetesSecretConfig from "./DeployNodeConfigFormKubernetesSecretConfig";
import DeployNodeConfigFormLeCDNConfig from "./DeployNodeConfigFormLeCDNConfig"; import DeployNodeConfigFormLeCDNConfig from "./DeployNodeConfigFormLeCDNConfig";
import DeployNodeConfigFormLocalConfig from "./DeployNodeConfigFormLocalConfig"; import DeployNodeConfigFormLocalConfig from "./DeployNodeConfigFormLocalConfig";
@ -304,6 +305,8 @@ const DeployNodeConfigForm = forwardRef<DeployNodeConfigFormInstance, DeployNode
return <DeployNodeConfigFormJDCloudLiveConfig {...nestedFormProps} />; return <DeployNodeConfigFormJDCloudLiveConfig {...nestedFormProps} />;
case DEPLOYMENT_PROVIDERS.JDCLOUD_VOD: case DEPLOYMENT_PROVIDERS.JDCLOUD_VOD:
return <DeployNodeConfigFormJDCloudVODConfig {...nestedFormProps} />; return <DeployNodeConfigFormJDCloudVODConfig {...nestedFormProps} />;
case DEPLOYMENT_PROVIDERS.KONG:
return <DeployNodeConfigFormKongConfig {...nestedFormProps} />;
case DEPLOYMENT_PROVIDERS.KUBERNETES_SECRET: case DEPLOYMENT_PROVIDERS.KUBERNETES_SECRET:
return <DeployNodeConfigFormKubernetesSecretConfig {...nestedFormProps} />; return <DeployNodeConfigFormKubernetesSecretConfig {...nestedFormProps} />;
case DEPLOYMENT_PROVIDERS.LECDN: case DEPLOYMENT_PROVIDERS.LECDN:

View File

@ -0,0 +1,89 @@
import { useTranslation } from "react-i18next";
import { Form, type FormInstance, Input, Select } from "antd";
import { createSchemaFieldRule } from "antd-zod";
import { z } from "zod/v4";
import Show from "@/components/Show";
type DeployNodeConfigFormKongConfigFieldValues = Nullish<{
resourceType: string;
certificateId?: string;
}>;
export type DeployNodeConfigFormKongConfigProps = {
form: FormInstance;
formName: string;
disabled?: boolean;
initialValues?: DeployNodeConfigFormKongConfigFieldValues;
onValuesChange?: (values: DeployNodeConfigFormKongConfigFieldValues) => void;
};
const RESOURCE_TYPE_CERTIFICATE = "certificate" as const;
const initFormModel = (): DeployNodeConfigFormKongConfigFieldValues => {
return {
resourceType: RESOURCE_TYPE_CERTIFICATE,
certificateId: "",
};
};
const DeployNodeConfigFormKongConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: DeployNodeConfigFormKongConfigProps) => {
const { t } = useTranslation();
const formSchema = z.object({
resourceType: z.literal(RESOURCE_TYPE_CERTIFICATE, t("workflow_node.deploy.form.kong_resource_type.placeholder")),
workspace: z.string().nullish(),
certificateId: z
.string()
.nullish()
.refine((v) => fieldResourceType !== RESOURCE_TYPE_CERTIFICATE || !!v?.trim(), t("workflow_node.deploy.form.kong_certificate_id.placeholder")),
});
const formRule = createSchemaFieldRule(formSchema);
const fieldResourceType = Form.useWatch("resourceType", formInst);
const handleFormChange = (_: unknown, values: z.infer<typeof formSchema>) => {
onValuesChange?.(values);
};
return (
<Form
form={formInst}
disabled={disabled}
initialValues={initialValues ?? initFormModel()}
layout="vertical"
name={formName}
onValuesChange={handleFormChange}
>
<Form.Item name="resourceType" label={t("workflow_node.deploy.form.kong_resource_type.label")} rules={[formRule]}>
<Select placeholder={t("workflow_node.deploy.form.kong_resource_type.placeholder")}>
<Select.Option key={RESOURCE_TYPE_CERTIFICATE} value={RESOURCE_TYPE_CERTIFICATE}>
{t("workflow_node.deploy.form.kong_resource_type.option.certificate.label")}
</Select.Option>
</Select>
</Form.Item>
<Form.Item
name="workspace"
label={t("workflow_node.deploy.form.kong_workspace.label")}
rules={[formRule]}
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.kong_workspace.tooltip") }}></span>}
>
<Input allowClear placeholder={t("workflow_node.deploy.form.kong_workspace.placeholder")} />
</Form.Item>
<Show when={fieldResourceType === RESOURCE_TYPE_CERTIFICATE}>
<Form.Item
name="certificateId"
label={t("workflow_node.deploy.form.kong_certificate_id.label")}
rules={[formRule]}
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.kong_certificate_id.tooltip") }}></span>}
>
<Input placeholder={t("workflow_node.deploy.form.kong_certificate_id.placeholder")} />
</Form.Item>
</Show>
</Form>
);
};
export default DeployNodeConfigFormKongConfig;

View File

@ -45,6 +45,7 @@ export interface AccessModel extends BaseModel {
| AccessConfigForHetzner | AccessConfigForHetzner
| AccessConfigForHuaweiCloud | AccessConfigForHuaweiCloud
| AccessConfigForJDCloud | AccessConfigForJDCloud
| AccessConfigForKong
| AccessConfigForKubernetes | AccessConfigForKubernetes
| AccessConfigForLarkBot | AccessConfigForLarkBot
| AccessConfigForLeCDN | AccessConfigForLeCDN
@ -293,6 +294,12 @@ export type AccessConfigForJDCloud = {
accessKeySecret: string; accessKeySecret: string;
}; };
export type AccessConfigForKong = {
serverUrl: string;
apiToken: string;
allowInsecureConnections?: boolean;
};
export type AccessConfigForKubernetes = { export type AccessConfigForKubernetes = {
kubeConfig?: string; kubeConfig?: string;
}; };

View File

@ -44,6 +44,7 @@ export const ACCESS_PROVIDERS = Object.freeze({
HETZNER: "hetzner", HETZNER: "hetzner",
HUAWEICLOUD: "huaweicloud", HUAWEICLOUD: "huaweicloud",
JDCLOUD: "jdcloud", JDCLOUD: "jdcloud",
KONG: "kong",
KUBERNETES: "k8s", KUBERNETES: "k8s",
LARKBOT: "larkbot", LARKBOT: "larkbot",
LECDN: "lecdn", LECDN: "lecdn",
@ -146,6 +147,7 @@ export const accessProvidersMap: Map<AccessProvider["type"] | string, AccessProv
[ACCESS_PROVIDERS.CACHEFLY, "provider.cachefly", "/imgs/providers/cachefly.png", [ACCESS_USAGES.HOSTING]], [ACCESS_PROVIDERS.CACHEFLY, "provider.cachefly", "/imgs/providers/cachefly.png", [ACCESS_USAGES.HOSTING]],
[ACCESS_PROVIDERS.EDGIO, "provider.edgio", "/imgs/providers/edgio.svg", [ACCESS_USAGES.HOSTING]], [ACCESS_PROVIDERS.EDGIO, "provider.edgio", "/imgs/providers/edgio.svg", [ACCESS_USAGES.HOSTING]],
[ACCESS_PROVIDERS.APISIX, "provider.apisix", "/imgs/providers/apisix.svg", [ACCESS_USAGES.HOSTING]], [ACCESS_PROVIDERS.APISIX, "provider.apisix", "/imgs/providers/apisix.svg", [ACCESS_USAGES.HOSTING]],
[ACCESS_PROVIDERS.KONG, "provider.kong", "/imgs/providers/kong.png", [ACCESS_USAGES.HOSTING]],
[ACCESS_PROVIDERS.PROXMOXVE, "provider.proxmoxve", "/imgs/providers/proxmoxve.svg", [ACCESS_USAGES.HOSTING]], [ACCESS_PROVIDERS.PROXMOXVE, "provider.proxmoxve", "/imgs/providers/proxmoxve.svg", [ACCESS_USAGES.HOSTING]],
[ACCESS_PROVIDERS.CLOUDFLARE, "provider.cloudflare", "/imgs/providers/cloudflare.svg", [ACCESS_USAGES.DNS]], [ACCESS_PROVIDERS.CLOUDFLARE, "provider.cloudflare", "/imgs/providers/cloudflare.svg", [ACCESS_USAGES.DNS]],
@ -436,6 +438,7 @@ export const DEPLOYMENT_PROVIDERS = Object.freeze({
JDCLOUD_CDN: `${ACCESS_PROVIDERS.JDCLOUD}-cdn`, JDCLOUD_CDN: `${ACCESS_PROVIDERS.JDCLOUD}-cdn`,
JDCLOUD_LIVE: `${ACCESS_PROVIDERS.JDCLOUD}-live`, JDCLOUD_LIVE: `${ACCESS_PROVIDERS.JDCLOUD}-live`,
JDCLOUD_VOD: `${ACCESS_PROVIDERS.JDCLOUD}-vod`, JDCLOUD_VOD: `${ACCESS_PROVIDERS.JDCLOUD}-vod`,
KONG: `${ACCESS_PROVIDERS.KONG}`,
KUBERNETES_SECRET: `${ACCESS_PROVIDERS.KUBERNETES}-secret`, KUBERNETES_SECRET: `${ACCESS_PROVIDERS.KUBERNETES}-secret`,
LECDN: `${ACCESS_PROVIDERS.LECDN}`, LECDN: `${ACCESS_PROVIDERS.LECDN}`,
LOCAL: `${ACCESS_PROVIDERS.LOCAL}`, LOCAL: `${ACCESS_PROVIDERS.LOCAL}`,
@ -613,6 +616,7 @@ export const deploymentProvidersMap: Map<DeploymentProvider["type"] | string, De
[DEPLOYMENT_PROVIDERS.BAOTAWAF_CONSOLE, "provider.baotawaf.console", DEPLOYMENT_CATEGORIES.OTHER], [DEPLOYMENT_PROVIDERS.BAOTAWAF_CONSOLE, "provider.baotawaf.console", DEPLOYMENT_CATEGORIES.OTHER],
[DEPLOYMENT_PROVIDERS.SAFELINE, "provider.safeline", DEPLOYMENT_CATEGORIES.FIREWALL], [DEPLOYMENT_PROVIDERS.SAFELINE, "provider.safeline", DEPLOYMENT_CATEGORIES.FIREWALL],
[DEPLOYMENT_PROVIDERS.APISIX, "provider.apisix", DEPLOYMENT_CATEGORIES.APIGATEWAY], [DEPLOYMENT_PROVIDERS.APISIX, "provider.apisix", DEPLOYMENT_CATEGORIES.APIGATEWAY],
[DEPLOYMENT_PROVIDERS.KONG, "provider.kong", DEPLOYMENT_CATEGORIES.APIGATEWAY],
[DEPLOYMENT_PROVIDERS.PROXMOXVE, "provider.proxmoxve", DEPLOYMENT_CATEGORIES.NAS], [DEPLOYMENT_PROVIDERS.PROXMOXVE, "provider.proxmoxve", DEPLOYMENT_CATEGORIES.NAS],
].map(([type, name, category, builtin]) => [ ].map(([type, name, category, builtin]) => [
type, type,

View File

@ -286,6 +286,11 @@
"access.form.k8s_kubeconfig.label": "KubeConfig", "access.form.k8s_kubeconfig.label": "KubeConfig",
"access.form.k8s_kubeconfig.placeholder": "Please enter KubeConfig file", "access.form.k8s_kubeconfig.placeholder": "Please enter KubeConfig file",
"access.form.k8s_kubeconfig.tooltip": "For more information, see <a href=\"https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/\" target=\"_blank\">https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/</a><br><br>Leave it blank to use the Pod's ServiceAccount.", "access.form.k8s_kubeconfig.tooltip": "For more information, see <a href=\"https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/\" target=\"_blank\">https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/</a><br><br>Leave it blank to use the Pod's ServiceAccount.",
"access.form.kong_server_url.label": "Kong admin API server URL",
"access.form.kong_server_url.placeholder": "Please enter Kong admin API server URL",
"access.form.kong_api_key.label": "Kong admin API token",
"access.form.kong_api_key.placeholder": "Please enter Kong admin API token",
"access.form.kong_api_key.tooltip": "For more information, see <a href=\"https://developer.konghq.com/\" target=\"_blank\">https://developer.konghq.com/</a>",
"access.form.larkbot_webhook_url.label": "Lark bot Webhook URL", "access.form.larkbot_webhook_url.label": "Lark bot Webhook URL",
"access.form.larkbot_webhook_url.placeholder": "Please enter Lark bot Webhook URL", "access.form.larkbot_webhook_url.placeholder": "Please enter Lark bot Webhook URL",
"access.form.larkbot_webhook_url.tooltip": "For more information, see <a href=\"https://www.feishu.cn/hc/en-US/articles/807992406756\" target=\"_blank\">https://www.feishu.cn/hc/en-US/articles/807992406756</a>", "access.form.larkbot_webhook_url.tooltip": "For more information, see <a href=\"https://www.feishu.cn/hc/en-US/articles/807992406756\" target=\"_blank\">https://www.feishu.cn/hc/en-US/articles/807992406756</a>",

View File

@ -101,6 +101,7 @@
"provider.jdcloud.dns": "JD Cloud - DNS", "provider.jdcloud.dns": "JD Cloud - DNS",
"provider.jdcloud.live": "JD Cloud - Live Video", "provider.jdcloud.live": "JD Cloud - Live Video",
"provider.jdcloud.vod": "JD Cloud - VOD (Video on Demand)", "provider.jdcloud.vod": "JD Cloud - VOD (Video on Demand)",
"provider.kong": "Kong",
"provider.kubernetes": "Kubernetes", "provider.kubernetes": "Kubernetes",
"provider.kubernetes.secret": "Kubernetes - Secret", "provider.kubernetes.secret": "Kubernetes - Secret",
"provider.larkbot": "Lark Bot", "provider.larkbot": "Lark Bot",

View File

@ -528,6 +528,15 @@
"workflow_node.deploy.form.k8s_secret_data_key_for_key.label": "Kubernetes Secret data key for private key", "workflow_node.deploy.form.k8s_secret_data_key_for_key.label": "Kubernetes Secret data key for private key",
"workflow_node.deploy.form.k8s_secret_data_key_for_key.placeholder": "Please enter Kubernetes Secret data key for private key", "workflow_node.deploy.form.k8s_secret_data_key_for_key.placeholder": "Please enter Kubernetes Secret data key for private key",
"workflow_node.deploy.form.k8s_secret_data_key_for_key.tooltip": "For more information, see <a href=\"https://kubernetes.io/docs/concepts/configuration/secret/\" target=\"_blank\">https://kubernetes.io/docs/concepts/configuration/secret/</a>", "workflow_node.deploy.form.k8s_secret_data_key_for_key.tooltip": "For more information, see <a href=\"https://kubernetes.io/docs/concepts/configuration/secret/\" target=\"_blank\">https://kubernetes.io/docs/concepts/configuration/secret/</a>",
"workflow_node.deploy.form.kong_resource_type.label": "Resource type",
"workflow_node.deploy.form.kong_resource_type.placeholder": "Please select resource type",
"workflow_node.deploy.form.kong_resource_type.option.certificate.label": "SSL certificate",
"workflow_node.deploy.form.kong_workspace.label": "Kong workspace (Optional)",
"workflow_node.deploy.form.kong_workspace.placeholder": "Please enter Kong workspace",
"workflow_node.deploy.form.kong_workspace.tooltip": "You can find it on Kong dashboard.",
"workflow_node.deploy.form.kong_certificate_id.label": "Kong certificate ID",
"workflow_node.deploy.form.kong_certificate_id.placeholder": "Please enter Kong certificate ID",
"workflow_node.deploy.form.kong_certificate_id.tooltip": "You can find it on Kong dashboard.",
"workflow_node.deploy.form.lecdn_resource_type.label": "Resource type", "workflow_node.deploy.form.lecdn_resource_type.label": "Resource type",
"workflow_node.deploy.form.lecdn_resource_type.placeholder": "Please select resource type", "workflow_node.deploy.form.lecdn_resource_type.placeholder": "Please select resource type",
"workflow_node.deploy.form.lecdn_resource_type.option.certificate.label": "Certificate", "workflow_node.deploy.form.lecdn_resource_type.option.certificate.label": "Certificate",

View File

@ -286,6 +286,11 @@
"access.form.k8s_kubeconfig.label": "KubeConfig", "access.form.k8s_kubeconfig.label": "KubeConfig",
"access.form.k8s_kubeconfig.placeholder": "请输入 KubeConfig 文件内容", "access.form.k8s_kubeconfig.placeholder": "请输入 KubeConfig 文件内容",
"access.form.k8s_kubeconfig.tooltip": "这是什么?请参阅 <a href=\"https://kubernetes.io/zh-cn/docs/concepts/configuration/organize-cluster-access-kubeconfig/\" target=\"_blank\">https://kubernetes.io/zh-cn/docs/concepts/configuration/organize-cluster-access-kubeconfig/</a><br><br>为空时,将使用 Pod 的 ServiceAccount 作为凭证。", "access.form.k8s_kubeconfig.tooltip": "这是什么?请参阅 <a href=\"https://kubernetes.io/zh-cn/docs/concepts/configuration/organize-cluster-access-kubeconfig/\" target=\"_blank\">https://kubernetes.io/zh-cn/docs/concepts/configuration/organize-cluster-access-kubeconfig/</a><br><br>为空时,将使用 Pod 的 ServiceAccount 作为凭证。",
"access.form.kong_server_url.label": "Kong Admin API 服务地址",
"access.form.kong_server_url.placeholder": "请输入 Kong Admin API 服务地址",
"access.form.kong_api_key.label": "Kong Admin API Token",
"access.form.kong_api_key.placeholder": "请输入 Kong Admin API Token",
"access.form.kong_api_key.tooltip": "这是什么?请参阅 <a href=\"https://developer.konghq.com/\" target=\"_blank\">https://developer.konghq.com/</a>",
"access.form.larkbot_webhook_url.label": "飞书群机器人 Webhook 地址", "access.form.larkbot_webhook_url.label": "飞书群机器人 Webhook 地址",
"access.form.larkbot_webhook_url.placeholder": "请输入飞书群机器人 Webhook 地址", "access.form.larkbot_webhook_url.placeholder": "请输入飞书群机器人 Webhook 地址",
"access.form.larkbot_webhook_url.tooltip": "这是什么?请参阅 <a href=\"https://www.feishu.cn/hc/zh-CN/articles/807992406756\" target=\"_blank\">https://www.feishu.cn/hc/zh-CN/articles/807992406756</a>", "access.form.larkbot_webhook_url.tooltip": "这是什么?请参阅 <a href=\"https://www.feishu.cn/hc/zh-CN/articles/807992406756\" target=\"_blank\">https://www.feishu.cn/hc/zh-CN/articles/807992406756</a>",

View File

@ -101,6 +101,7 @@
"provider.jdcloud.dns": "京东云 - 云解析 DNS", "provider.jdcloud.dns": "京东云 - 云解析 DNS",
"provider.jdcloud.live": "京东云 - 视频直播", "provider.jdcloud.live": "京东云 - 视频直播",
"provider.jdcloud.vod": "京东云 - 视频点播", "provider.jdcloud.vod": "京东云 - 视频点播",
"provider.kong": "Kong",
"provider.kubernetes": "Kubernetes", "provider.kubernetes": "Kubernetes",
"provider.kubernetes.secret": "Kubernetes - Secret", "provider.kubernetes.secret": "Kubernetes - Secret",
"provider.larkbot": "飞书群机器人", "provider.larkbot": "飞书群机器人",

View File

@ -526,6 +526,15 @@
"workflow_node.deploy.form.k8s_secret_data_key_for_key.label": "Kubernetes Secret 数据键(用于存放私钥的字段)", "workflow_node.deploy.form.k8s_secret_data_key_for_key.label": "Kubernetes Secret 数据键(用于存放私钥的字段)",
"workflow_node.deploy.form.k8s_secret_data_key_for_key.placeholder": "请输入 Kubernetes Secret 中用于存放私钥的数据键", "workflow_node.deploy.form.k8s_secret_data_key_for_key.placeholder": "请输入 Kubernetes Secret 中用于存放私钥的数据键",
"workflow_node.deploy.form.k8s_secret_data_key_for_key.tooltip": "这是什么?请参阅 <a href=\"https://kubernetes.io/zh-cn/docs/concepts/configuration/secret/\" target=\"_blank\">https://kubernetes.io/zh-cn/docs/concepts/configuration/secret/</a>", "workflow_node.deploy.form.k8s_secret_data_key_for_key.tooltip": "这是什么?请参阅 <a href=\"https://kubernetes.io/zh-cn/docs/concepts/configuration/secret/\" target=\"_blank\">https://kubernetes.io/zh-cn/docs/concepts/configuration/secret/</a>",
"workflow_node.deploy.form.kong_resource_type.label": "证书部署方式",
"workflow_node.deploy.form.kong_resource_type.placeholder": "请选择证书部署方式",
"workflow_node.deploy.form.kong_resource_type.option.certificate.label": "替换指定证书",
"workflow_node.deploy.form.kong_workspace.label": "Kong 工作空间(可选)",
"workflow_node.deploy.form.kong_workspace.placeholder": "请输入 Kong 工作空间",
"workflow_node.deploy.form.kong_workspace.tooltip": "请登录 Kong 控制台查看。",
"workflow_node.deploy.form.kong_certificate_id.label": "Kong 证书 ID",
"workflow_node.deploy.form.kong_certificate_id.placeholder": "请输入 Kong 证书 ID",
"workflow_node.deploy.form.kong_certificate_id.tooltip": "请登录 Kong 控制台查看。",
"workflow_node.deploy.form.lecdn_resource_type.label": "证书部署方式", "workflow_node.deploy.form.lecdn_resource_type.label": "证书部署方式",
"workflow_node.deploy.form.lecdn_resource_type.placeholder": "请选择证书部署方式", "workflow_node.deploy.form.lecdn_resource_type.placeholder": "请选择证书部署方式",
"workflow_node.deploy.form.lecdn_resource_type.option.certificate.label": "替换指定证书", "workflow_node.deploy.form.lecdn_resource_type.option.certificate.label": "替换指定证书",