4 clients demo

main
han-joker 9 months ago
parent 82e9378a19
commit acc9386cd3

@ -14,6 +14,7 @@ require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/emicklei/go-restful/v3 v3.9.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
github.com/gin-contrib/cors v1.4.0 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-logr/logr v1.2.4 // indirect
github.com/go-openapi/jsonpointer v0.19.6 // indirect

@ -12,8 +12,11 @@ github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhF
github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
github.com/gin-contrib/cors v1.4.0 h1:oJ6gwtUl3lqV0WEIwM/LxPF1QZ5qe2lGWdY2+bz7y0g=
github.com/gin-contrib/cors v1.4.0/go.mod h1:bs9pNM0x/UsmHPBWT2xZz9ROh8xYjYkiURUfmBoMlcs=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk=
github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU=
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
@ -25,16 +28,21 @@ github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2Kv
github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g=
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos=
github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js=
github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
@ -66,17 +74,21 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk=
github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@ -90,10 +102,14 @@ github.com/onsi/ginkgo/v2 v2.9.4 h1:xR7vG4IXt5RWx6FfIjyAtsoMAtnc3C/rFXBBd2AjZwE=
github.com/onsi/ginkgo/v2 v2.9.4/go.mod h1:gCQYp2Q+kSoIj7ykSVb9nskRSsR6PUj4AiLywzIhbKM=
github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE=
github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg=
github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo=
github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ=
github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
@ -102,6 +118,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
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/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
@ -111,6 +128,8 @@ github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gt
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
@ -121,6 +140,7 @@ golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
@ -130,6 +150,7 @@ golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.13.0 h1:Nvo8UFsZ8X3BhAC9699Z1j7XQ3rsZnUUm7jfBEk1ueY=
golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
golang.org/x/oauth2 v0.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8=
@ -140,15 +161,21 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c=
golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4=
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
@ -167,17 +194,21 @@ google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
k8s.io/api v0.28.1 h1:i+0O8k2NPBCPYaMB+uCkseEbawEt/eFaiRqUx8aB108=

@ -22,9 +22,9 @@ func GetClientSet() (*kubernetes.Clientset, error) {
// 2. 配置 kubeconfig, 得到clientClientSet对象
// 配置文件位置
kubeConfigPath := ".kube/config"
//kubeConfigPath := kubeConfigPath
// 构建配置,读取配置文件内容,解析为配置对象
config, err := clientcmd.BuildConfigFromFlags("", kubeConfigPath)
config, err := clientcmd.BuildConfigFromFlags("", KubeConfigPath)
if err != nil {
return nil, err
}

@ -0,0 +1,5 @@
package common
const (
KubeConfigPath = ".kube/config"
)

@ -0,0 +1,122 @@
package config
import (
"io"
"k8s-manager/handler/common"
"log"
"net/http"
"os"
"path/filepath"
"k8s.io/client-go/tools/clientcmd"
"github.com/gin-gonic/gin"
)
// 配置文件上传接口的handler
func Upload(ctx *gin.Context) {
// 1. 获取上传的临时文件, post/put,
tmpFile, err := ctx.FormFile("config")
if err != nil {
log.Println(err)
ctx.JSON(http.StatusOK, gin.H{
"code": 1,
"message": err.Error(),
})
return
}
// 2. 校验配置文件是否合理
// clientcmd.Validate(config)
// 打开文件,读取文件内容,加载为配置,校验合法性
// 打开文件
file, err := tmpFile.Open()
if err != nil {
log.Println(err)
ctx.JSON(http.StatusOK, gin.H{
"code": 1,
"message": err.Error(),
})
return
}
// 读取文件内容
content, err := io.ReadAll(file)
if err != nil {
log.Println(err)
ctx.JSON(http.StatusOK, gin.H{
"code": 1,
"message": err.Error(),
})
return
}
// 加载为配置
config, err := clientcmd.Load(content)
if err != nil {
log.Println(err)
ctx.JSON(http.StatusOK, gin.H{
"code": 1,
"message": err.Error(),
})
return
}
// 校验合法性
if err := clientcmd.Validate(*config); err != nil {
log.Println(err)
ctx.JSON(http.StatusOK, gin.H{
"code": 1,
"message": err.Error(),
})
return
}
// 3. 将配置文件存储在正确的位置
// 设置目标位置
//kubeConfigPath := common.KubeConfigPath
// 创建必要的目录
dir := filepath.Dir(common.KubeConfigPath)
if err := os.MkdirAll(dir, 0644); err != nil {
log.Println(err)
ctx.JSON(http.StatusOK, gin.H{
"code": 1,
"message": err.Error(),
})
return
}
// 将临时文件存储到目标位置
if err := ctx.SaveUploadedFile(tmpFile, common.KubeConfigPath); err != nil {
log.Println(err)
ctx.JSON(http.StatusOK, gin.H{
"code": 1,
"message": err.Error(),
})
return
}
// 4. 成功的响应
ctx.JSON(http.StatusOK, gin.H{
"code": 0,
"message": "config file uploaded",
})
}
func Config(ctx *gin.Context) {
// 1. 读取文件内容
content, err := os.ReadFile(common.KubeConfigPath)
if err != nil {
log.Println(err)
ctx.JSON(http.StatusOK, gin.H{
"code": 1,
"message": err.Error(),
})
return
}
// 2. 响应
ctx.JSON(http.StatusOK, gin.H{
"code": 0,
"data": string(content),
})
}

@ -18,7 +18,8 @@ func List(ctx *gin.Context) {
if err != nil {
log.Println(err)
ctx.JSON(http.StatusOK, gin.H{
"code": 1,
// code == 2, 意味着配置文件有问题
"code": 2,
"message": err.Error(),
})
return

@ -1,9 +1,12 @@
package main
import (
"k8s-manager/handler/config"
"k8s-manager/handler/node"
"k8s-manager/handler/sys"
"github.com/gin-contrib/cors"
"github.com/gin-gonic/gin"
)
@ -11,9 +14,22 @@ func main() {
// 初始化默认的路由引擎
r := gin.Default()
// 中间件 middle ware
corsDC := cors.DefaultConfig()
// 配置响应头,通过属性配置
corsDC.AllowAllOrigins = true // 允许全部的源,访问
corsDC.AllowCredentials = true
corsDC.AddAllowHeaders("Authorization")
// 应用到全部路上
r.Use(cors.New(corsDC))
// 定义路由
r.GET("/ping", sys.Ping)
r.GET("/node/get", node.List)
r.POST("/config/upload", config.Upload)
r.GET("/config", config.Config)
r.Static("/ui", "./ui")
r.Run(":8080") // 监听并在 0.0.0.0:8080 上启动服务
}

@ -0,0 +1,39 @@
package test
import (
"context"
"k8s-manager/handler/common"
"log"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
)
func ClientSetDeployments() {
// 1. 初始化配置
// 加载配置
config, err := clientcmd.BuildConfigFromFlags("", "../"+common.KubeConfigPath)
if err != nil {
log.Fatalln(err)
}
// 2. 获取clientSet客户端
clientSet, err := kubernetes.NewForConfig(config)
if err != nil {
log.Fatalln(err)
}
// 3. 调用封装的方法获取资源。获取deployments
namespace := "kube-system"
deploymentList, err := clientSet.AppsV1().Deployments(namespace).List(context.Background(), metav1.ListOptions{})
if err != nil {
log.Fatalln(err)
}
// 4. 处理响应
for _, item := range deploymentList.Items {
log.Printf("NAME: %s READY: %d/%d AVAILABLE: %d", item.Name, item.Status.ReadyReplicas, item.Status.Replicas, item.Status.AvailableReplicas)
}
}

@ -0,0 +1,7 @@
package test
import "testing"
func TestClientSetDeployments(t *testing.T) {
ClientSetDeployments()
}

@ -0,0 +1,59 @@
package test
import (
"k8s-manager/handler/common"
"log"
"k8s.io/client-go/discovery"
"k8s.io/client-go/tools/clientcmd"
)
func DiscoveryClientGroupAndVersions() {
//discovery.DiscoveryClient{}
// 1. 配置
config, err := clientcmd.BuildConfigFromFlags("", "../"+common.KubeConfigPath)
if err != nil {
log.Fatalln(err)
}
// 2. 客户端
discoveryClient, err := discovery.NewDiscoveryClientForConfig(config)
if err != nil {
log.Fatalln(err)
}
// 3. 获取资源,获取全部的组和版本资源
apiGroups, apiResourceList, err := discoveryClient.ServerGroupsAndResources()
if err != nil {
log.Fatalln(err)
}
// 4. 处理结果
// groups
for _, g := range apiGroups {
log.Println("----------------Group----------------")
log.Printf("Name: %s \n", g.Name)
// version
log.Println("================Versions================")
for _, v := range g.Versions {
log.Printf("GroupVersion: %s \n", v.GroupVersion)
}
}
log.Println("******************************************************")
// apiResourceList
for _, ar := range apiResourceList {
log.Println("----------------apiResource----------------")
log.Printf("GroupVerion: %s, ", ar.GroupVersion)
log.Println("----------------Resources----------------")
for _, r := range ar.APIResources {
log.Printf("Name: %s Namespace: %v\n", r.Name, r.Namespaced)
}
}
//log.Println(_)
}

@ -0,0 +1,7 @@
package test
import "testing"
func TestDiscoveryClientGroupAndVersions(t *testing.T) {
DiscoveryClientGroupAndVersions()
}

@ -0,0 +1,141 @@
package test
import (
"context"
"k8s-manager/handler/common"
"log"
"k8s.io/apimachinery/pkg/runtime"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/tools/clientcmd"
)
// DynamicClientPods native resource
func DynamicClientPods() {
// 1. 加载配置
config, err := clientcmd.BuildConfigFromFlags("", "../"+common.KubeConfigPath)
if err != nil {
log.Fatalln(err)
}
// 2. 获取客户端
dynamicClient, err := dynamic.NewForConfig(config)
if err != nil {
log.Fatalln(err)
}
// 3. 获取资源,pod list
// 基于 gvr 来获取
gvr := schema.GroupVersionResource{
Group: "",
Version: "v1",
Resource: "pods",
}
// 发出请求,获取资源
namespace := "kube-system"
unstructruedList, err := dynamicClient.
Resource(gvr).
Namespace(namespace).
List(context.Background(), metav1.ListOptions{})
if err != nil {
log.Fatalln(err)
}
// 4. 从未结构化类型转换到具体的资源类型,重要
// 定义目标类型,由于是原生资源,可以直接使用包中定义的类型
podList := &corev1.PodList{}
// untructured to podlist 转换
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(unstructruedList.UnstructuredContent(), podList); err != nil {
log.Fatalln(err)
}
// 5. 处理结果
for _, pod := range podList.Items {
log.Printf("Name: %s Status: %s\n", pod.Name, pod.Status.Phase)
}
// 结构说明,动态客户端类型
//dynamic.DynamicClient{}
// 未结构化类型
//runtime.Unstructured{}
}
// DynamicClientCrontabs custome resource
func DynamicClientCrontabs() {
// 1. 加载配置
config, err := clientcmd.BuildConfigFromFlags("", "../"+common.KubeConfigPath)
if err != nil {
log.Fatalln(err)
}
// 2. 获取客户端
dynamicClient, err := dynamic.NewForConfig(config)
if err != nil {
log.Fatalln(err)
}
// 3. 获取资源,crontab list
// 基于 gvr 来获取
gvr := schema.GroupVersionResource{
Group: "stable.example.com",
Version: "v1",
Resource: "crontabs",
}
// 发出请求,获取资源
unstructruedList, err := dynamicClient.
Resource(gvr).
List(context.Background(), metav1.ListOptions{})
if err != nil {
log.Fatalln(err)
}
// 4. 从未结构化类型转换到具体的资源类型,重要
// 定义目标类型,由于是原生资源,可以直接使用包中定义的类型
list := &CrontabList{}
// untructured to podlist 转换
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(unstructruedList.UnstructuredContent(), list); err != nil {
log.Fatalln(err)
}
// 5. 处理结果
for _, item := range list.Items {
log.Printf("Name: %s Cron: %s\n", item.Name, item.Spec.CronSpec)
}
}
// CrontabList is a list of Crontab.
// 定义资源类型
type CrontabList struct {
// 类型元信息
metav1.TypeMeta `json:",inline"`
// 列表元信息
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
// 自定义资源列表
Items []Crontab `json:"items" protobuf:"bytes,2,rep,name=items"`
}
// Pod is a collection of containers that can run on a host. This resource is created
// by clients and scheduled onto hosts.
type Crontab struct {
// 类型元信息
metav1.TypeMeta `json:",inline"`
// 列表元信息
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
// 特定字段
Spec CrontabSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"`
}
// PodSpec is a description of a pod.
type CrontabSpec struct {
// 自定义的字段
CronSpec string `json:"cronSpec,omitempty" protobuf:"bytes,1,opt,name=cronSpec"`
Image string `json:"image,omitempty" protobuf:"bytes,2,opt,name=image"`
}

@ -0,0 +1,11 @@
package test
import "testing"
func TestDynamicClientPods(t *testing.T) {
DynamicClientPods()
}
func TestDynamicClientCrontabs(t *testing.T) {
DynamicClientCrontabs()
}

@ -0,0 +1,54 @@
package test
import (
"context"
"k8s-manager/handler/common"
"log"
"k8s.io/client-go/kubernetes/scheme"
corev1 "k8s.io/api/core/v1"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
)
func RestClientPods() {
// 1. 获取RestClient
// 加载配置
config, err := clientcmd.BuildConfigFromFlags("", "../"+common.KubeConfigPath)
if err != nil {
log.Fatalln(err)
}
// 完成基础配置
// api 路径
config.APIPath = "api"
// 组版本
config.GroupVersion = &corev1.SchemeGroupVersion
// 约定的编解码器(序列化器)
config.NegotiatedSerializer = scheme.Codecs
// 获取 RestClient
restClient, err := rest.RESTClientFor(config)
if err != nil {
log.Fatalln(err)
}
// 2. 发出获取Pods的请求
// 结果对象
podList := &corev1.PodList{}
// 请求配置参数method选项
namespace := "kube-system"
if err := restClient.Get().
Resource("pods").
Namespace(namespace).
Do(context.Background()).
Into(podList); err != nil {
log.Fatalln(err)
}
// 3. 处理获取的响应
for _, pod := range podList.Items {
log.Printf("Name: %s Status: %s\n", pod.Name, pod.Status.Phase)
}
}

@ -0,0 +1,8 @@
package test
import "testing"
func TestRestClientPods(t *testing.T) {
//RestClientPods()
ClientSetDeployments()
}

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>K8S集群管理平台</title>
</head>
<body>
</body>
</html>
Loading…
Cancel
Save