add webhook deployer

This commit is contained in:
yoan 2024-08-28 18:53:33 +08:00
parent 4b8fa3502c
commit 1861e73531
13 changed files with 366 additions and 31 deletions

8
go.mod
View File

@ -11,6 +11,7 @@ require (
github.com/alibabacloud-go/tea v1.2.1 github.com/alibabacloud-go/tea v1.2.1
github.com/alibabacloud-go/tea-utils/v2 v2.0.5 github.com/alibabacloud-go/tea-utils/v2 v2.0.5
github.com/go-acme/lego/v4 v4.17.4 github.com/go-acme/lego/v4 v4.17.4
github.com/gojek/heimdall/v7 v7.0.3
github.com/labstack/echo/v5 v5.0.0-20230722203903-ec5b858dab61 github.com/labstack/echo/v5 v5.0.0-20230722203903-ec5b858dab61
github.com/pkg/sftp v1.13.6 github.com/pkg/sftp v1.13.6
github.com/pocketbase/dbx v1.10.1 github.com/pocketbase/dbx v1.10.1
@ -52,6 +53,7 @@ require (
github.com/aws/smithy-go v1.20.3 // indirect github.com/aws/smithy-go v1.20.3 // indirect
github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect
github.com/clbanning/mxj/v2 v2.5.5 // indirect github.com/clbanning/mxj/v2 v2.5.5 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/disintegration/imaging v1.6.2 // indirect github.com/disintegration/imaging v1.6.2 // indirect
github.com/domodwyer/mailyak/v3 v3.6.2 // indirect github.com/domodwyer/mailyak/v3 v3.6.2 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect github.com/dustin/go-humanize v1.0.1 // indirect
@ -61,6 +63,7 @@ require (
github.com/go-jose/go-jose/v4 v4.0.2 // indirect github.com/go-jose/go-jose/v4 v4.0.2 // indirect
github.com/go-ozzo/ozzo-validation/v4 v4.3.0 // indirect github.com/go-ozzo/ozzo-validation/v4 v4.3.0 // indirect
github.com/goccy/go-json v0.10.3 // indirect github.com/goccy/go-json v0.10.3 // indirect
github.com/gojek/valkyrie v0.0.0-20180215180059-6aee720afcdf // indirect
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/google/uuid v1.6.0 // indirect github.com/google/uuid v1.6.0 // indirect
@ -80,9 +83,13 @@ require (
github.com/modern-go/reflect2 v1.0.2 // indirect github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/ncruces/go-strftime v0.1.9 // indirect github.com/ncruces/go-strftime v0.1.9 // indirect
github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b // indirect github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/spf13/cast v1.6.0 // indirect github.com/spf13/cast v1.6.0 // indirect
github.com/spf13/cobra v1.8.1 // indirect github.com/spf13/cobra v1.8.1 // indirect
github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/pflag v1.0.5 // indirect
github.com/stretchr/objx v0.5.2 // indirect
github.com/stretchr/testify v1.9.0 // indirect
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.898 // indirect github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.898 // indirect
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.898 // indirect github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.898 // indirect
github.com/tjfoc/gmsm v1.3.2 // indirect github.com/tjfoc/gmsm v1.3.2 // indirect
@ -106,6 +113,7 @@ require (
google.golang.org/grpc v1.65.0 // indirect google.golang.org/grpc v1.65.0 // indirect
google.golang.org/protobuf v1.34.2 // indirect google.golang.org/protobuf v1.34.2 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
modernc.org/gc/v3 v3.0.0-20240722195230-4a140ff9c08e // indirect modernc.org/gc/v3 v3.0.0-20240722195230-4a140ff9c08e // indirect
modernc.org/libc v1.55.3 // indirect modernc.org/libc v1.55.3 // indirect
modernc.org/mathutil v1.6.0 // indirect modernc.org/mathutil v1.6.0 // indirect

13
go.sum
View File

@ -19,9 +19,11 @@ github.com/AlecAivazis/survey/v2 v2.3.7 h1:6I/u8FvytdGsgonrYsVn2t8t4QiRnh6QSTqkk
github.com/AlecAivazis/survey/v2 v2.3.7/go.mod h1:xUTIdE4KCOIjsBAE1JYsUPoCqYdZ1reCfTwbto0Fduo= github.com/AlecAivazis/survey/v2 v2.3.7/go.mod h1:xUTIdE4KCOIjsBAE1JYsUPoCqYdZ1reCfTwbto0Fduo=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/DataDog/datadog-go v3.7.1+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo=
github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s= github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s=
github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w= github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w=
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.4 h1:iC9YFYKDGEy3n/FtqJnOkZsene9olVspKmkX5A2YBEo= github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.4 h1:iC9YFYKDGEy3n/FtqJnOkZsene9olVspKmkX5A2YBEo=
github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.4/go.mod h1:sCavSAvdzOjul4cEqeVtvlSaSScfNsTQ+46HwlTL1hc= github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.4/go.mod h1:sCavSAvdzOjul4cEqeVtvlSaSScfNsTQ+46HwlTL1hc=
@ -99,6 +101,7 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.30.3 h1:ZsDKRLXGWHk8WdtyYMoGNO7bTudr
github.com/aws/aws-sdk-go-v2/service/sts v1.30.3/go.mod h1:zwySh8fpFyXp9yOr/KVzxOl8SRqgf/IDw5aUt9UKFcQ= github.com/aws/aws-sdk-go-v2/service/sts v1.30.3/go.mod h1:zwySh8fpFyXp9yOr/KVzxOl8SRqgf/IDw5aUt9UKFcQ=
github.com/aws/smithy-go v1.20.3 h1:ryHwveWzPV5BIof6fyDvor6V3iUL7nTfiTKXHiW05nE= github.com/aws/smithy-go v1.20.3 h1:ryHwveWzPV5BIof6fyDvor6V3iUL7nTfiTKXHiW05nE=
github.com/aws/smithy-go v1.20.3/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E= github.com/aws/smithy-go v1.20.3/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E=
github.com/cactus/go-statsd-client/statsd v0.0.0-20200423205355-cb0885a1018c/go.mod h1:l/bIBLeOl9eX+wxJAzxS4TveKRtAqlyDpHjhkfO0MEI=
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
@ -150,6 +153,10 @@ github.com/go-sql-driver/mysql v1.8.0 h1:UtktXaU2Nb64z/pLiGIxY4431SJ4/dR5cjMmlVH
github.com/go-sql-driver/mysql v1.8.0/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= github.com/go-sql-driver/mysql v1.8.0/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA=
github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
github.com/gojek/heimdall/v7 v7.0.3 h1:+5sAhl8S0m+qRRL8IVeHCJudFh/XkG3wyO++nvOg+gc=
github.com/gojek/heimdall/v7 v7.0.3/go.mod h1:Z43HtMid7ysSjmsedPTXAki6jcdcNVnjn5pmsTyiMic=
github.com/gojek/valkyrie v0.0.0-20180215180059-6aee720afcdf h1:5xRGbUdOmZKoDXkGx5evVLehuCMpuO1hl701bEQqXOM=
github.com/gojek/valkyrie v0.0.0-20180215180059-6aee720afcdf/go.mod h1:QzhUKaYKJmcbTnCYCAVQrroCOY7vOOI8cSQ4NbuhYf0=
github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A= github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A=
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
@ -246,6 +253,7 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4=
github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b h1:FfH+VrHHk6Lxt9HdVS0PXzSXFyS2NbZKXv33FYPol0A= github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b h1:FfH+VrHHk6Lxt9HdVS0PXzSXFyS2NbZKXv33FYPol0A=
github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b/go.mod h1:AC62GU6hc0BrNm+9RK9VSiwa/EUe1bkIeFORAMcHvJU= github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b/go.mod h1:AC62GU6hc0BrNm+9RK9VSiwa/EUe1bkIeFORAMcHvJU=
@ -260,6 +268,7 @@ github.com/pocketbase/dbx v1.10.1/go.mod h1:xXRCIAKTHMgUCyCKZm55pUOdvFziJjQfXaWK
github.com/pocketbase/pocketbase v0.22.18 h1:yVckUhi5GDORqCb0BbtlvRB1CVxHY9HO9btEaeZHVJU= github.com/pocketbase/pocketbase v0.22.18 h1:yVckUhi5GDORqCb0BbtlvRB1CVxHY9HO9btEaeZHVJU=
github.com/pocketbase/pocketbase v0.22.18/go.mod h1:0QFvDOOW7ANId78ChZSagyHbmP6CgMxDQrQFXzeaDpA= github.com/pocketbase/pocketbase v0.22.18/go.mod h1:0QFvDOOW7ANId78ChZSagyHbmP6CgMxDQrQFXzeaDpA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
@ -276,8 +285,11 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/objx v0.3.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
@ -488,6 +500,7 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/ini.v1 v1.56.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.56.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=

View File

@ -17,6 +17,7 @@ const (
targetAliyunOss = "aliyun-oss" targetAliyunOss = "aliyun-oss"
targetAliyunCdn = "aliyun-cdn" targetAliyunCdn = "aliyun-cdn"
targetSSH = "ssh" targetSSH = "ssh"
targetWebhook = "webhook"
) )
type DeployerOption struct { type DeployerOption struct {
@ -55,6 +56,8 @@ func Get(record *models.Record, cert *applicant.Certificate) (Deployer, error) {
return NewAliyunCdn(option) return NewAliyunCdn(option)
case targetSSH: case targetSSH:
return NewSSH(option) return NewSSH(option)
case targetWebhook:
return NewWebhook(option)
} }
return nil, errors.New("not implemented") return nil, errors.New("not implemented")
} }

View File

@ -0,0 +1,55 @@
package deployer
import (
"bytes"
xhttp "certimate/internal/utils/http"
"context"
"encoding/json"
"fmt"
"net/http"
)
type webhookAccess struct {
Url string `json:"url"`
}
type hookData struct {
Domain string `json:"domain"`
Certificate string `json:"certificate"`
PrivateKey string `json:"privateKey"`
}
type webhook struct {
option *DeployerOption
}
func NewWebhook(option *DeployerOption) (Deployer, error) {
return &webhook{
option: option,
}, nil
}
func (w *webhook) Deploy(ctx context.Context) error {
access := &webhookAccess{}
if err := json.Unmarshal([]byte(w.option.Access), access); err != nil {
return fmt.Errorf("failed to parse hook access config: %w", err)
}
data := &hookData{
Domain: w.option.Domain,
Certificate: w.option.Certificate.Certificate,
PrivateKey: w.option.Certificate.PrivateKey,
}
body, _ := json.Marshal(data)
_, err := xhttp.Req(access.Url, http.MethodPost, bytes.NewReader(body), map[string]string{
"Content-Type": "application/json",
})
if err != nil {
return fmt.Errorf("failed to send hook request: %w", err)
}
return nil
}

View File

@ -0,0 +1,60 @@
package http
import (
"fmt"
"io"
"net/http"
"time"
"github.com/gojek/heimdall/v7/httpclient"
)
type Options struct {
Timeout time.Duration
}
type Option func(o *Options)
func WithTimeout(timeout time.Duration) Option {
return func(o *Options) {
o.Timeout = timeout
}
}
func Req(url string, method string, body io.Reader, head map[string]string, opts ...Option) ([]byte, error) {
reader, err := Req2GetReader(url, method, body, head, opts...)
if err != nil {
return nil, err
}
defer reader.Close()
return io.ReadAll(reader)
}
func Req2GetReader(url string, method string, body io.Reader, head map[string]string, opts ...Option) (io.ReadCloser, error) {
options := &Options{
Timeout: 30000 * time.Millisecond,
}
for _, opt := range opts {
opt(options)
}
client := httpclient.NewClient(httpclient.WithHTTPTimeout(options.Timeout))
// Create an http.Request instance
req, _ := http.NewRequest(method, url, body)
for k, v := range head {
req.Header.Set(k, v)
}
// Call the `Do` method, which has a similar interface to the `http.Do` method
res, err := client.Do(req)
if err != nil {
return nil, err
}
if res.StatusCode != http.StatusOK {
return nil, fmt.Errorf("status code is not 200: %d", res.StatusCode)
}
return res.Body, nil
}

File diff suppressed because one or more lines are too long

1
ui/dist/imgs/providers/webhook.svg vendored Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 24 24"><path fill="#059669" d="M7 20.5q-1.864 0-3.182-1.318T2.5 16q0-1.246.608-2.268t1.617-1.615q.275-.165.525-.026q.25.14.25.459q0 .121-.064.24q-.065.12-.169.181q-.776.452-1.272 1.258T3.5 16q0 1.442 1.029 2.471T7 19.5q1.404 0 2.414-.961q1.009-.962 1.086-2.347q.02-.31.199-.5q.18-.192.47-.192h4.725q.142-.321.44-.526q.297-.205.666-.205q.51 0 .87.36q.36.361.36.871t-.36.87t-.87.36q-.388 0-.676-.194q-.288-.196-.43-.536h-4.417q-.235 1.84-1.54 2.92T7 20.5m0-3.27q-.51 0-.87-.36T5.77 16q0-.512.378-.892q.379-.381.994-.314l2.562-4.265q-.84-.656-1.272-1.574T8 7q0-1.864 1.318-3.182T12.5 2.5q1.73 0 2.991 1.14t1.455 2.802q.048.225-.108.392q-.155.166-.386.166q-.171 0-.315-.132t-.185-.309q-.16-1.296-1.136-2.177Q13.838 3.5 12.5 3.5q-1.442 0-2.471 1.029T9 7q0 .883.393 1.618t1.101 1.251q.235.162.303.423q.069.262-.068.485l-2.727 4.542q.108.144.168.321t.06.36q0 .51-.36.87t-.87.36m10 3.27q-.708 0-1.34-.201t-1.195-.591q-.329-.221-.268-.58q.06-.359.474-.359q.106 0 .208.05t.188.106q.402.271.903.423T17 19.5q1.442 0 2.471-1.029T20.5 16t-1.029-2.471T17 12.5q-.25 0-.475.038t-.45.093q-.285.086-.558-.017t-.41-.32l-2.459-4.088q-.525.073-.952-.279T11.27 7q0-.51.36-.87q.362-.36.871-.36t.87.36t.36.87q0 .183-.057.357t-.165.299l2.367 3.977q.258-.05.53-.092q.274-.041.595-.041q1.864 0 3.182 1.318T21.5 16t-1.318 3.182T17 20.5"/></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

2
ui/dist/index.html vendored
View File

@ -5,7 +5,7 @@
<link rel="icon" type="image/svg+xml" href="/vite.svg" /> <link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Certimate - Your Trusted SSL Automation Partner</title> <title>Certimate - Your Trusted SSL Automation Partner</title>
<script type="module" crossorigin src="/assets/index-vWJSQP8e.js"></script> <script type="module" crossorigin src="/assets/index-D-MCicNE.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-VYJgHfoP.css"> <link rel="stylesheet" crossorigin href="/assets/index-VYJgHfoP.css">
</head> </head>
<body class="bg-background"> <body class="bg-background">

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 24 24"><path fill="#059669" d="M7 20.5q-1.864 0-3.182-1.318T2.5 16q0-1.246.608-2.268t1.617-1.615q.275-.165.525-.026q.25.14.25.459q0 .121-.064.24q-.065.12-.169.181q-.776.452-1.272 1.258T3.5 16q0 1.442 1.029 2.471T7 19.5q1.404 0 2.414-.961q1.009-.962 1.086-2.347q.02-.31.199-.5q.18-.192.47-.192h4.725q.142-.321.44-.526q.297-.205.666-.205q.51 0 .87.36q.36.361.36.871t-.36.87t-.87.36q-.388 0-.676-.194q-.288-.196-.43-.536h-4.417q-.235 1.84-1.54 2.92T7 20.5m0-3.27q-.51 0-.87-.36T5.77 16q0-.512.378-.892q.379-.381.994-.314l2.562-4.265q-.84-.656-1.272-1.574T8 7q0-1.864 1.318-3.182T12.5 2.5q1.73 0 2.991 1.14t1.455 2.802q.048.225-.108.392q-.155.166-.386.166q-.171 0-.315-.132t-.185-.309q-.16-1.296-1.136-2.177Q13.838 3.5 12.5 3.5q-1.442 0-2.471 1.029T9 7q0 .883.393 1.618t1.101 1.251q.235.162.303.423q.069.262-.068.485l-2.727 4.542q.108.144.168.321t.06.36q0 .51-.36.87t-.87.36m10 3.27q-.708 0-1.34-.201t-1.195-.591q-.329-.221-.268-.58q.06-.359.474-.359q.106 0 .208.05t.188.106q.402.271.903.423T17 19.5q1.442 0 2.471-1.029T20.5 16t-1.029-2.471T17 12.5q-.25 0-.475.038t-.45.093q-.285.086-.558-.017t-.41-.32l-2.459-4.088q-.525.073-.952-.279T11.27 7q0-.51.36-.87q.362-.36.871-.36t.87.36t.36.87q0 .183-.057.357t-.165.299l2.367 3.977q.258-.05.53-.092q.274-.041.595-.041q1.864 0 3.182 1.318T21.5 16t-1.318 3.182T17 20.5"/></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -18,6 +18,7 @@ import { cn } from "@/lib/utils";
import { RadioGroup, RadioGroupItem } from "../ui/radio-group"; import { RadioGroup, RadioGroupItem } from "../ui/radio-group";
import AccessSSHForm from "./AccessSSHForm"; import AccessSSHForm from "./AccessSSHForm";
import WebhookForm from "./AccessWebhookFrom";
type TargetConfigEditProps = { type TargetConfigEditProps = {
op: "add" | "edit"; op: "add" | "edit";
@ -69,6 +70,15 @@ export function AccessEdit({
/> />
); );
break; break;
case "webhook":
form = (
<WebhookForm
data={data}
onAfterReq={() => {
setOpen(false);
}}
/>
);
} }
const getOptionCls = (val: string) => { const getOptionCls = (val: string) => {

View File

@ -0,0 +1,173 @@
import { Input } from "@/components/ui/input";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import z from "zod";
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "@/components/ui/form";
import { Button } from "@/components/ui/button";
import { Access, accessFormType, WebhookConfig } from "@/domain/access";
import { save } from "@/repository/access";
import { useConfig } from "@/providers/config";
import { ClientResponseError } from "pocketbase";
import { PbErrorData } from "@/domain/base";
const WebhookForm = ({
data,
onAfterReq,
}: {
data?: Access;
onAfterReq: () => void;
}) => {
const { addAccess, updateAccess } = useConfig();
const formSchema = z.object({
id: z.string().optional(),
name: z.string().min(1).max(64),
configType: accessFormType,
url: z.string().url(),
});
let config: WebhookConfig = {
url: "",
};
if (data) config = data.config as WebhookConfig;
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
id: data?.id,
name: data?.name,
configType: "webhook",
url: config.url,
},
});
const onSubmit = async (data: z.infer<typeof formSchema>) => {
console.log(data);
const req: Access = {
id: data.id as string,
name: data.name,
configType: data.configType,
config: {
url: data.url,
},
};
try {
const rs = await save(req);
onAfterReq();
req.id = rs.id;
req.created = rs.created;
req.updated = rs.updated;
if (data.id) {
updateAccess(req);
return;
}
addAccess(req);
} catch (e) {
const err = e as ClientResponseError;
Object.entries(err.response.data as PbErrorData).forEach(
([key, value]) => {
form.setError(key as keyof z.infer<typeof formSchema>, {
type: "manual",
message: value.message,
});
}
);
}
};
return (
<>
<div className="max-w-[35em] mx-auto mt-10">
<Form {...form}>
<form
onSubmit={(e) => {
console.log(e);
e.stopPropagation();
form.handleSubmit(onSubmit)(e);
}}
className="space-y-8"
>
<FormField
control={form.control}
name="name"
render={({ field }) => (
<FormItem>
<FormLabel></FormLabel>
<FormControl>
<Input placeholder="请输入授权名称" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="id"
render={({ field }) => (
<FormItem className="hidden">
<FormLabel></FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="configType"
render={({ field }) => (
<FormItem className="hidden">
<FormLabel></FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="url"
render={({ field }) => (
<FormItem>
<FormLabel>Webhook Url</FormLabel>
<FormControl>
<Input placeholder="请输入Webhook Url" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<div className="flex justify-end">
<Button type="submit"></Button>
</div>
</form>
</Form>
</div>
</>
);
};
export default WebhookForm;

View File

@ -4,10 +4,16 @@ export const accessTypeMap: Map<string, [string, string]> = new Map([
["tencent", ["腾讯云", "/imgs/providers/tencent.svg"]], ["tencent", ["腾讯云", "/imgs/providers/tencent.svg"]],
["aliyun", ["阿里云", "/imgs/providers/aliyun.svg"]], ["aliyun", ["阿里云", "/imgs/providers/aliyun.svg"]],
["ssh", ["SSH部署", "/imgs/providers/ssh.png"]], ["ssh", ["SSH部署", "/imgs/providers/ssh.png"]],
["webhook", ["Webhook", "/imgs/providers/webhook.svg"]],
]); ]);
export const accessFormType = z.union( export const accessFormType = z.union(
[z.literal("aliyun"), z.literal("tencent"), z.literal("ssh")], [
z.literal("aliyun"),
z.literal("tencent"),
z.literal("ssh"),
z.literal("webhook"),
],
{ message: "请选择云服务商" } { message: "请选择云服务商" }
); );
@ -15,12 +21,16 @@ export type Access = {
id: string; id: string;
name: string; name: string;
configType: string; configType: string;
config: TencentConfig | AliyunConfig | SSHConfig; config: TencentConfig | AliyunConfig | SSHConfig | WebhookConfig;
deleted?: string; deleted?: string;
created?: string; created?: string;
updated?: string; updated?: string;
}; };
export type WebhookConfig = {
url: string;
};
export type TencentConfig = { export type TencentConfig = {
secretId: string; secretId: string;
secretKey: string; secretKey: string;

View File

@ -31,6 +31,7 @@ export const targetTypeMap: Map<string, [string, string]> = new Map([
["aliyun-cdn", ["阿里云-CDN", "/imgs/providers/aliyun.svg"]], ["aliyun-cdn", ["阿里云-CDN", "/imgs/providers/aliyun.svg"]],
["aliyun-oss", ["阿里云-OSS", "/imgs/providers/aliyun.svg"]], ["aliyun-oss", ["阿里云-OSS", "/imgs/providers/aliyun.svg"]],
["ssh", ["SSH部署", "/imgs/providers/ssh.png"]], ["ssh", ["SSH部署", "/imgs/providers/ssh.png"]],
["webhook", ["Webhook", "/imgs/providers/webhook.svg"]],
]); ]);
export const targetTypeKeys = Array.from(targetTypeMap.keys()); export const targetTypeKeys = Array.from(targetTypeMap.keys());