mirror of
https://github.com/labring/sealos.git
synced 2026-08-30 17:58:09 +08:00
refactor:Strip billing function to reosurce-controller (#2811)
* refactor:Strip billing function to reosurce-controller Signed-off-by: 晓杰 <2561589453@qq.com> * fix(metering): clearResourceUsed should delete after create accountbalance Signed-off-by: 晓杰 <2561589453@qq.com> * fix: calculate price Rounded up Signed-off-by: 晓杰 <2561589453@qq.com> * feat(account):add resoureinfoList in accountbalance CRD Signed-off-by: 晓杰 <2561589453@qq.com> * log:metering add log when runnning Signed-off-by: 晓杰 <2561589453@qq.com> * fix:double reconcile by status updates Signed-off-by: 晓杰 <2561589453@qq.com> * fix(metering): code format and fix calculate the terminating pod Signed-off-by: 晓杰 <2561589453@qq.com> * fix:git rebase error Signed-off-by: 晓杰 <2561589453@qq.com> * format(metering): name format Signed-off-by: 晓杰 <2561589453@qq.com> * code format:add interface Signed-off-by: 晓杰 <2561589453@qq.com> * golangci-link fix Signed-off-by: 晓杰 <2561589453@qq.com> * ci(metering): update metering e2e ci Signed-off-by: 晓杰 <2561589453@qq.com> * update readme Signed-off-by: 晓杰 <2561589453@qq.com> * fix: fix account.crd.base error Signed-off-by: 晓杰 <2561589453@qq.com> * update metering e2e ci go test Signed-off-by: 晓杰 <2561589453@qq.com> * update ci Signed-off-by: 晓杰 <2561589453@qq.com> * update c Signed-off-by: 晓杰 <2561589453@qq.com> * delete unused file Signed-off-by: 晓杰 <2561589453@qq.com> * delete useless webhook file Signed-off-by: 晓杰 <2561589453@qq.com> --------- Signed-off-by: 晓杰 <2561589453@qq.com>
This commit is contained in:
@@ -52,7 +52,8 @@ jobs:
|
||||
uses: magnetikonline/action-golang-cache@v3
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
|
||||
- name: Install Dependencies
|
||||
run: sudo apt update && sudo apt install -y libgpgme-dev libbtrfs-dev libdevmapper-dev
|
||||
- name: Run Linter
|
||||
uses: golangci/golangci-lint-action@v3
|
||||
with:
|
||||
|
||||
@@ -12,6 +12,7 @@ on:
|
||||
- ".github/workflows/e2e_metering.yml"
|
||||
- "!**/*.md"
|
||||
- "!**/*.yaml"
|
||||
|
||||
jobs:
|
||||
build-image:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -35,9 +36,11 @@ jobs:
|
||||
chmod +x bin/controller-${{ matrix.module }}-amd64
|
||||
- name: Prepare
|
||||
id: prepare
|
||||
working-directory: controllers/${{ matrix.module }}
|
||||
run: |
|
||||
TAG=deploy
|
||||
echo tag_name=${TAG} >> $GITHUB_OUTPUT
|
||||
IMG=ghcr.io/${{ github.repository_owner }}/sealos-${{ matrix.module }}-controller:dev make pre-deploy
|
||||
- name: build ${{ matrix.module }} main controller image
|
||||
env:
|
||||
# fork friendly ^^
|
||||
@@ -94,7 +97,11 @@ jobs:
|
||||
run: |
|
||||
TAG=deploy
|
||||
echo tag_name=${TAG} >> $GITHUB_OUTPUT
|
||||
|
||||
- name: install common metering CRD
|
||||
working-directory: ./controllers/common/metering
|
||||
run: |
|
||||
sudo -u root apt install make
|
||||
make install
|
||||
- name: install CRD metering
|
||||
working-directory: ./controllers/metering
|
||||
run: |
|
||||
@@ -103,17 +110,12 @@ jobs:
|
||||
- name: install CRD account
|
||||
working-directory: ./controllers/account
|
||||
run: |
|
||||
sudo -u root sealos run docker.io/labring/cert-manager:v1.8.0
|
||||
make pre-deploy
|
||||
sudo -u root kubectl create namespace account-system
|
||||
sudo -u root kubectl create namespace sealos-system
|
||||
sudo -u root kubectl create secret generic payment-secret -n account-system
|
||||
sudo -u root kubectl apply -f ./deploy/manifests/deploy.yaml
|
||||
- name: install CRD infra
|
||||
working-directory: ./controllers/infra
|
||||
run: |
|
||||
make pre-deploy
|
||||
sudo -u root kubectl apply -f ./deploy/manifests/deploy.yaml
|
||||
sleep 30
|
||||
- name: Setup Golang with cache
|
||||
uses: magnetikonline/action-golang-cache@v3
|
||||
with:
|
||||
@@ -122,4 +124,4 @@ jobs:
|
||||
working-directory: ./controllers/metering
|
||||
run: |
|
||||
sudo -u root kubectl get pod -A
|
||||
go test ./testdata/e2e/metering_test.go -v
|
||||
go test -v ./testdata/e2e/metering_test.go -run TestMetering
|
||||
|
||||
@@ -17,6 +17,7 @@ limitations under the License.
|
||||
package v1
|
||||
|
||||
import (
|
||||
meteringcommonv1 "github.com/labring/sealos/controllers/common/metering/api/v1"
|
||||
meteringv1 "github.com/labring/sealos/controllers/metering/api/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
@@ -25,10 +26,11 @@ const AccountBalancePrefix = "accountbalance"
|
||||
|
||||
// AccountBalanceSpec defines the desired state of AccountBalance
|
||||
type AccountBalanceSpec struct {
|
||||
Owner string `json:"owner"`
|
||||
Timestamp int64 `json:"timestamp,omitempty"`
|
||||
Amount int64 `json:"amount,omitempty"`
|
||||
Details string `json:"details,omitempty"`
|
||||
Owner string `json:"owner"`
|
||||
Timestamp int64 `json:"timestamp,omitempty"`
|
||||
Amount int64 `json:"amount,omitempty"`
|
||||
Details string `json:"details,omitempty"`
|
||||
ResourceInfoList meteringcommonv1.ResourceInfoList `json:"resourceInfoList,omitempty"`
|
||||
}
|
||||
|
||||
// AccountBalanceStatus defines the observed state of AccountBalance
|
||||
|
||||
@@ -46,6 +46,27 @@ spec:
|
||||
type: string
|
||||
owner:
|
||||
type: string
|
||||
resourceInfoList:
|
||||
items:
|
||||
properties:
|
||||
cost:
|
||||
format: int64
|
||||
type: integer
|
||||
namespace:
|
||||
type: string
|
||||
resourceName:
|
||||
type: string
|
||||
time:
|
||||
format: int64
|
||||
type: integer
|
||||
used:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
|
||||
x-kubernetes-int-or-string: true
|
||||
type: object
|
||||
type: array
|
||||
timestamp:
|
||||
format: int64
|
||||
type: integer
|
||||
|
||||
@@ -52,6 +52,27 @@ spec:
|
||||
type: string
|
||||
owner:
|
||||
type: string
|
||||
resourceInfoList:
|
||||
items:
|
||||
properties:
|
||||
cost:
|
||||
format: int64
|
||||
type: integer
|
||||
namespace:
|
||||
type: string
|
||||
resourceName:
|
||||
type: string
|
||||
time:
|
||||
format: int64
|
||||
type: integer
|
||||
used:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
|
||||
x-kubernetes-int-or-string: true
|
||||
type: object
|
||||
type: array
|
||||
timestamp:
|
||||
format: int64
|
||||
type: integer
|
||||
|
||||
@@ -14,11 +14,11 @@ func WaitSSHReady(ssh ssh.Interface, _ int, hosts ...string) error {
|
||||
for i := range hosts {
|
||||
host := hosts[i]
|
||||
eg.Go(func() (err error) {
|
||||
timeStamp, err := ssh.CmdToString(host, "date +%s", "")
|
||||
timestamp, err := ssh.CmdToString(host, "date +%s", "")
|
||||
if err != nil {
|
||||
return fmt.Errorf("ssh is not ready")
|
||||
}
|
||||
_, err = strconv.Atoi(timeStamp)
|
||||
_, err = strconv.Atoi(timestamp)
|
||||
if err != nil {
|
||||
return fmt.Errorf("ssh is not ready")
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
module github.com/labring/sealos/controllers/common
|
||||
|
||||
go 1.20
|
||||
|
||||
|
||||
require (
|
||||
k8s.io/api v0.26.3
|
||||
k8s.io/apimachinery v0.26.3
|
||||
sigs.k8s.io/controller-runtime v0.13.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/go-logr/logr v1.2.3 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/google/gofuzz v1.1.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
golang.org/x/net v0.7.0 // indirect
|
||||
golang.org/x/text v0.7.0 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
k8s.io/klog/v2 v2.80.1 // indirect
|
||||
k8s.io/utils v0.0.0-20221128185143-99ec85e7a448 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
|
||||
)
|
||||
@@ -0,0 +1,86 @@
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
|
||||
github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
|
||||
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
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/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||
github.com/onsi/ginkgo/v2 v2.6.0 h1:9t9b9vRUbFq3C4qKFCGkVuq/fIHji802N1nrtkh1mNc=
|
||||
github.com/onsi/gomega v1.24.1 h1:KORJXNNTzJXzu4ScJWssJfJMnJ+2QJqhoQSRwNlze9E=
|
||||
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/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
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/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
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.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
|
||||
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
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.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
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/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.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
k8s.io/api v0.26.3 h1:emf74GIQMTik01Aum9dPP0gAypL8JTLl/lHa4V9RFSU=
|
||||
k8s.io/api v0.26.3/go.mod h1:PXsqwPMXBSBcL1lJ9CYDKy7kIReUydukS5JiRlxC3qE=
|
||||
k8s.io/apimachinery v0.26.3 h1:dQx6PNETJ7nODU3XPtrwkfuubs6w7sX0M8n61zHIV/k=
|
||||
k8s.io/apimachinery v0.26.3/go.mod h1:ats7nN1LExKHvJ9TmwootT00Yz05MuYqPXEXaVeOy5I=
|
||||
k8s.io/klog/v2 v2.80.1 h1:atnLQ121W371wYYFawwYx1aEY2eUfs4l3J72wtgAwV4=
|
||||
k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
|
||||
k8s.io/utils v0.0.0-20221128185143-99ec85e7a448 h1:KTgPnR10d5zhztWptI952TNtt/4u5h3IzDXkdIMuo2Y=
|
||||
k8s.io/utils v0.0.0-20221128185143-99ec85e7a448/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||
sigs.k8s.io/controller-runtime v0.14.5 h1:6xaWFqzT5KuAQ9ufgUaj1G/+C4Y1GRkhrxl+BJ9i+5s=
|
||||
sigs.k8s.io/controller-runtime v0.14.5/go.mod h1:WqIdsAY6JBsjfc/CqO0CORmNtoCtE4S6qbPc9s68h+0=
|
||||
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k=
|
||||
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E=
|
||||
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
|
||||
@@ -0,0 +1,26 @@
|
||||
|
||||
# Binaries for programs and plugins
|
||||
*.exe
|
||||
*.exe~
|
||||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
bin
|
||||
testbin/*
|
||||
Dockerfile.cross
|
||||
|
||||
# Test binary, build with `go test -c`
|
||||
*.test
|
||||
|
||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||
*.out
|
||||
|
||||
# Kubernetes Generated files - skip generated files, except for vendored files
|
||||
|
||||
!vendor/**/zz_generated.*
|
||||
|
||||
# editor and IDE paraphernalia
|
||||
.idea
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
@@ -0,0 +1,107 @@
|
||||
|
||||
# Image URL to use all building/pushing image targets
|
||||
IMG ?= controller:latest
|
||||
# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary.
|
||||
ENVTEST_K8S_VERSION = 1.26.1
|
||||
|
||||
# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set)
|
||||
ifeq (,$(shell go env GOBIN))
|
||||
GOBIN=$(shell go env GOPATH)/bin
|
||||
else
|
||||
GOBIN=$(shell go env GOBIN)
|
||||
endif
|
||||
|
||||
# Setting SHELL to bash allows bash commands to be executed by recipes.
|
||||
# Options are set to exit when a recipe line exits non-zero or a piped command fails.
|
||||
SHELL = /usr/bin/env bash -o pipefail
|
||||
.SHELLFLAGS = -ec
|
||||
|
||||
.PHONY: all
|
||||
all: build
|
||||
|
||||
|
||||
.PHONY: help
|
||||
help: ## Display this help.
|
||||
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)
|
||||
|
||||
##@ Development
|
||||
|
||||
.PHONY: manifests
|
||||
manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects.
|
||||
$(CONTROLLER_GEN) rbac:roleName=manager-role crd paths="./..." output:crd:artifacts:config=config/crd/bases
|
||||
|
||||
.PHONY: generate
|
||||
generate: controller-gen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations.
|
||||
$(CONTROLLER_GEN) object paths="./..."
|
||||
|
||||
.PHONY: fmt
|
||||
fmt: ## Run go fmt against code.
|
||||
go fmt ./...
|
||||
|
||||
.PHONY: vet
|
||||
vet: ## Run go vet against code.
|
||||
go vet ./...
|
||||
|
||||
.PHONY: test
|
||||
test: manifests generate fmt vet envtest ## Run tests.
|
||||
KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" go test ./... -coverprofile cover.out
|
||||
|
||||
##@ Deployment
|
||||
|
||||
ifndef ignore-not-found
|
||||
ignore-not-found = false
|
||||
endif
|
||||
|
||||
.PHONY: install
|
||||
install: manifests kustomize ## Install CRDs into the K8s cluster specified in ~/.kube/config.
|
||||
$(KUSTOMIZE) build config/crd | kubectl apply -f -
|
||||
|
||||
.PHONY: uninstall
|
||||
uninstall: manifests kustomize ## Uninstall CRDs from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion.
|
||||
$(KUSTOMIZE) build config/crd | kubectl delete --ignore-not-found=$(ignore-not-found) -f -
|
||||
|
||||
.PHONY: deploy
|
||||
deploy: manifests kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config.
|
||||
cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG}
|
||||
$(KUSTOMIZE) build config/default | kubectl apply -f -
|
||||
|
||||
.PHONY: undeploy
|
||||
undeploy: ## Undeploy controller from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion.
|
||||
$(KUSTOMIZE) build config/default | kubectl delete --ignore-not-found=$(ignore-not-found) -f -
|
||||
|
||||
##@ Build Dependencies
|
||||
|
||||
## Location to install dependencies to
|
||||
LOCALBIN ?= $(shell pwd)/bin
|
||||
$(LOCALBIN):
|
||||
mkdir -p $(LOCALBIN)
|
||||
|
||||
## Tool Binaries
|
||||
KUSTOMIZE ?= $(LOCALBIN)/kustomize
|
||||
CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen
|
||||
ENVTEST ?= $(LOCALBIN)/setup-envtest
|
||||
|
||||
## Tool Versions
|
||||
KUSTOMIZE_VERSION ?= v4.2.0
|
||||
CONTROLLER_TOOLS_VERSION ?= v0.11.3
|
||||
|
||||
KUSTOMIZE_INSTALL_SCRIPT ?= "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh"
|
||||
.PHONY: kustomize
|
||||
kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary. If wrong version is installed, it will be removed before downloading.
|
||||
$(KUSTOMIZE): $(LOCALBIN)
|
||||
@if test -x $(LOCALBIN)/kustomize && ! $(LOCALBIN)/kustomize version | grep -q $(KUSTOMIZE_VERSION); then \
|
||||
echo "$(LOCALBIN)/kustomize version is not expected $(KUSTOMIZE_VERSION). Removing it before installing."; \
|
||||
rm -rf $(LOCALBIN)/kustomize; \
|
||||
fi
|
||||
test -s $(LOCALBIN)/kustomize || { curl -Ss $(KUSTOMIZE_INSTALL_SCRIPT) --output install_kustomize.sh && bash install_kustomize.sh $(subst v,,$(KUSTOMIZE_VERSION)) $(LOCALBIN); rm install_kustomize.sh; }
|
||||
|
||||
.PHONY: controller-gen
|
||||
controller-gen: $(CONTROLLER_GEN) ## Download controller-gen locally if necessary. If wrong version is installed, it will be overwritten.
|
||||
$(CONTROLLER_GEN): $(LOCALBIN)
|
||||
test -s $(LOCALBIN)/controller-gen && $(LOCALBIN)/controller-gen --version | grep -q $(CONTROLLER_TOOLS_VERSION) || \
|
||||
GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-tools/cmd/controller-gen@$(CONTROLLER_TOOLS_VERSION)
|
||||
|
||||
.PHONY: envtest
|
||||
envtest: $(ENVTEST) ## Download envtest-setup locally if necessary.
|
||||
$(ENVTEST): $(LOCALBIN)
|
||||
test -s $(LOCALBIN)/setup-envtest || GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest
|
||||
@@ -0,0 +1,94 @@
|
||||
# metering
|
||||
// TODO(user): Add simple overview of use/purpose
|
||||
|
||||
## Description
|
||||
// TODO(user): An in-depth paragraph about your project and overview of use
|
||||
|
||||
## Getting Started
|
||||
You’ll need a Kubernetes cluster to run against. You can use [KIND](https://sigs.k8s.io/kind) to get a local cluster for testing, or run against a remote cluster.
|
||||
**Note:** Your controller will automatically use the current context in your kubeconfig file (i.e. whatever cluster `kubectl cluster-info` shows).
|
||||
|
||||
### Running on the cluster
|
||||
1. Install Instances of Custom Resources:
|
||||
|
||||
```sh
|
||||
kubectl apply -f config/samples/
|
||||
```
|
||||
|
||||
2. Build and push your image to the location specified by `IMG`:
|
||||
|
||||
```sh
|
||||
make docker-build docker-push IMG=<some-registry>/metering:tag
|
||||
```
|
||||
|
||||
3. Deploy the controller to the cluster with the image specified by `IMG`:
|
||||
|
||||
```sh
|
||||
make deploy IMG=<some-registry>/metering:tag
|
||||
```
|
||||
|
||||
### Uninstall CRDs
|
||||
To delete the CRDs from the cluster:
|
||||
|
||||
```sh
|
||||
make uninstall
|
||||
```
|
||||
|
||||
### Undeploy controller
|
||||
UnDeploy the controller from the cluster:
|
||||
|
||||
```sh
|
||||
make undeploy
|
||||
```
|
||||
|
||||
## Contributing
|
||||
// TODO(user): Add detailed information on how you would like others to contribute to this project
|
||||
|
||||
### How it works
|
||||
This project aims to follow the Kubernetes [Operator pattern](https://kubernetes.io/docs/concepts/extend-kubernetes/operator/).
|
||||
|
||||
It uses [Controllers](https://kubernetes.io/docs/concepts/architecture/controller/),
|
||||
which provide a reconcile function responsible for synchronizing resources until the desired state is reached on the cluster.
|
||||
|
||||
### Test It Out
|
||||
1. Install the CRDs into the cluster:
|
||||
|
||||
```sh
|
||||
make install
|
||||
```
|
||||
|
||||
2. Run your controller (this will run in the foreground, so switch to a new terminal if you want to leave it running):
|
||||
|
||||
```sh
|
||||
make run
|
||||
```
|
||||
|
||||
**NOTE:** You can also run this in one step by running: `make install run`
|
||||
|
||||
### Modifying the API definitions
|
||||
If you are editing the API definitions, generate the manifests such as CRs or CRDs using:
|
||||
|
||||
```sh
|
||||
make manifests
|
||||
```
|
||||
|
||||
**NOTE:** Run `make --help` for more information on all potential `make` targets
|
||||
|
||||
More information can be found via the [Kubebuilder Documentation](https://book.kubebuilder.io/introduction.html)
|
||||
|
||||
## License
|
||||
|
||||
Copyright 2023.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
+9
@@ -18,15 +18,24 @@ package v1
|
||||
|
||||
import (
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
const ExtensionResourcePricePrefix = "extensionresourceprice-"
|
||||
|
||||
// ExtensionResourcePriceSpec defines the desired state of ExtensionResourcePrice
|
||||
type ExtensionResourcePriceSpec struct {
|
||||
ResourceName string `json:"resourceName,omitempty"`
|
||||
Resources map[v1.ResourceName]ResourcePrice `json:"resources,omitempty"`
|
||||
}
|
||||
|
||||
type ResourcePrice struct {
|
||||
Unit *resource.Quantity `json:"unit"`
|
||||
Price int64 `json:"price"` // 100 = 1¥
|
||||
Describe string `json:"describe,omitempty"`
|
||||
}
|
||||
|
||||
// ExtensionResourcePriceStatus defines the observed state of ExtensionResourcePrice
|
||||
type ExtensionResourcePriceStatus struct {
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
Copyright 2023.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package v1 contains API Schema definitions for the metering v1 API group
|
||||
// +kubebuilder:object:generate=true
|
||||
// +groupName=metering.common.sealos.io
|
||||
package v1
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"sigs.k8s.io/controller-runtime/pkg/scheme"
|
||||
)
|
||||
|
||||
var (
|
||||
// GroupVersion is group version used to register these objects
|
||||
GroupVersion = schema.GroupVersion{Group: "metering.common.sealos.io", Version: "v1"}
|
||||
|
||||
// SchemeBuilder is used to add go types to the GroupVersionKind scheme
|
||||
SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
|
||||
|
||||
// AddToScheme adds the types in this group-version to the given scheme.
|
||||
AddToScheme = SchemeBuilder.AddToScheme
|
||||
)
|
||||
+12
-3
@@ -35,9 +35,18 @@ type ResourceSpec struct {
|
||||
}
|
||||
|
||||
type ResourceInfo struct {
|
||||
Used *resource.Quantity `json:"used,omitempty"`
|
||||
TimeStamp int64 `json:"time,omitempty"`
|
||||
NameSpace string `json:"namespace,omitempty"`
|
||||
ResourceName string `json:"resourceName,omitempty"`
|
||||
Used *resource.Quantity `json:"used,omitempty"`
|
||||
Timestamp int64 `json:"time,omitempty"`
|
||||
Namespace string `json:"namespace,omitempty"`
|
||||
Cost int64 `json:"cost,omitempty"`
|
||||
}
|
||||
|
||||
type ResourceInfoList []ResourceInfo
|
||||
|
||||
type ResourcePriceAndUsed struct {
|
||||
ResourcePrice `json:",inline"`
|
||||
Used *resource.Quantity `json:"used,omitempty"`
|
||||
}
|
||||
|
||||
// ResourceStatus defines the observed state of Resource
|
||||
@@ -0,0 +1,285 @@
|
||||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
// Code generated by controller-gen. DO NOT EDIT.
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ExtensionResourcePrice) DeepCopyInto(out *ExtensionResourcePrice) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
out.Status = in.Status
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExtensionResourcePrice.
|
||||
func (in *ExtensionResourcePrice) DeepCopy() *ExtensionResourcePrice {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ExtensionResourcePrice)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *ExtensionResourcePrice) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ExtensionResourcePriceList) DeepCopyInto(out *ExtensionResourcePriceList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]ExtensionResourcePrice, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExtensionResourcePriceList.
|
||||
func (in *ExtensionResourcePriceList) DeepCopy() *ExtensionResourcePriceList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ExtensionResourcePriceList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *ExtensionResourcePriceList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ExtensionResourcePriceSpec) DeepCopyInto(out *ExtensionResourcePriceSpec) {
|
||||
*out = *in
|
||||
if in.Resources != nil {
|
||||
in, out := &in.Resources, &out.Resources
|
||||
*out = make(map[corev1.ResourceName]ResourcePrice, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = *val.DeepCopy()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExtensionResourcePriceSpec.
|
||||
func (in *ExtensionResourcePriceSpec) DeepCopy() *ExtensionResourcePriceSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ExtensionResourcePriceSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ExtensionResourcePriceStatus) DeepCopyInto(out *ExtensionResourcePriceStatus) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExtensionResourcePriceStatus.
|
||||
func (in *ExtensionResourcePriceStatus) DeepCopy() *ExtensionResourcePriceStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ExtensionResourcePriceStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Resource) DeepCopyInto(out *Resource) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
out.Status = in.Status
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Resource.
|
||||
func (in *Resource) DeepCopy() *Resource {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Resource)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *Resource) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ResourceInfo) DeepCopyInto(out *ResourceInfo) {
|
||||
*out = *in
|
||||
if in.Used != nil {
|
||||
in, out := &in.Used, &out.Used
|
||||
x := (*in).DeepCopy()
|
||||
*out = &x
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceInfo.
|
||||
func (in *ResourceInfo) DeepCopy() *ResourceInfo {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ResourceInfo)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in ResourceInfoList) DeepCopyInto(out *ResourceInfoList) {
|
||||
{
|
||||
in := &in
|
||||
*out = make(ResourceInfoList, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceInfoList.
|
||||
func (in ResourceInfoList) DeepCopy() ResourceInfoList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ResourceInfoList)
|
||||
in.DeepCopyInto(out)
|
||||
return *out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ResourceList) DeepCopyInto(out *ResourceList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]Resource, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceList.
|
||||
func (in *ResourceList) DeepCopy() *ResourceList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ResourceList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *ResourceList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ResourcePrice) DeepCopyInto(out *ResourcePrice) {
|
||||
*out = *in
|
||||
if in.Unit != nil {
|
||||
in, out := &in.Unit, &out.Unit
|
||||
x := (*in).DeepCopy()
|
||||
*out = &x
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourcePrice.
|
||||
func (in *ResourcePrice) DeepCopy() *ResourcePrice {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ResourcePrice)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ResourcePriceAndUsed) DeepCopyInto(out *ResourcePriceAndUsed) {
|
||||
*out = *in
|
||||
in.ResourcePrice.DeepCopyInto(&out.ResourcePrice)
|
||||
if in.Used != nil {
|
||||
in, out := &in.Used, &out.Used
|
||||
x := (*in).DeepCopy()
|
||||
*out = &x
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourcePriceAndUsed.
|
||||
func (in *ResourcePriceAndUsed) DeepCopy() *ResourcePriceAndUsed {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ResourcePriceAndUsed)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ResourceSpec) DeepCopyInto(out *ResourceSpec) {
|
||||
*out = *in
|
||||
if in.Resources != nil {
|
||||
in, out := &in.Resources, &out.Resources
|
||||
*out = make(map[corev1.ResourceName]ResourceInfo, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = *val.DeepCopy()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceSpec.
|
||||
func (in *ResourceSpec) DeepCopy() *ResourceSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ResourceSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ResourceStatus) DeepCopyInto(out *ResourceStatus) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceStatus.
|
||||
func (in *ResourceStatus) DeepCopy() *ResourceStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ResourceStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
+3
-9
@@ -3,11 +3,11 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.8.0
|
||||
controller-gen.kubebuilder.io/version: v0.11.3
|
||||
creationTimestamp: null
|
||||
name: extensionresourceprices.metering.sealos.io
|
||||
name: extensionresourceprices.metering.common.sealos.io
|
||||
spec:
|
||||
group: metering.sealos.io
|
||||
group: metering.common.sealos.io
|
||||
names:
|
||||
kind: ExtensionResourcePrice
|
||||
listKind: ExtensionResourcePriceList
|
||||
@@ -67,9 +67,3 @@ spec:
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
plural: ""
|
||||
conditions: []
|
||||
storedVersions: []
|
||||
+8
-9
@@ -3,11 +3,11 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.8.0
|
||||
controller-gen.kubebuilder.io/version: v0.11.3
|
||||
creationTimestamp: null
|
||||
name: resources.metering.sealos.io
|
||||
name: resources.metering.common.sealos.io
|
||||
spec:
|
||||
group: metering.sealos.io
|
||||
group: metering.common.sealos.io
|
||||
names:
|
||||
kind: Resource
|
||||
listKind: ResourceList
|
||||
@@ -38,8 +38,13 @@ spec:
|
||||
resources:
|
||||
additionalProperties:
|
||||
properties:
|
||||
cost:
|
||||
format: int64
|
||||
type: integer
|
||||
namespace:
|
||||
type: string
|
||||
resourceName:
|
||||
type: string
|
||||
time:
|
||||
format: int64
|
||||
type: integer
|
||||
@@ -63,9 +68,3 @@ spec:
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
plural: ""
|
||||
conditions: []
|
||||
storedVersions: []
|
||||
@@ -0,0 +1,24 @@
|
||||
# This kustomization.yaml is not intended to be run by itself,
|
||||
# since it depends on service name and namespace that are out of this kustomize package.
|
||||
# It should be run by config/default
|
||||
resources:
|
||||
- bases/metering.common.sealos.io_resources.yaml
|
||||
- bases/metering.common.sealos.io_extensionresourceprices.yaml
|
||||
#+kubebuilder:scaffold:crdkustomizeresource
|
||||
|
||||
patchesStrategicMerge:
|
||||
# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix.
|
||||
# patches here are for enabling the conversion webhook for each CRD
|
||||
#- patches/webhook_in_resources.yaml
|
||||
#- patches/webhook_in_extensionresourceprice.yaml
|
||||
#+kubebuilder:scaffold:crdkustomizewebhookpatch
|
||||
|
||||
# [CERTMANAGER] To enable cert-manager, uncomment all the sections with [CERTMANAGER] prefix.
|
||||
# patches here are for enabling the CA injection for each CRD
|
||||
#- patches/cainjection_in_resources.yaml
|
||||
#- patches/cainjection_in_extensionresourceprice.yaml
|
||||
#+kubebuilder:scaffold:crdkustomizecainjectionpatch
|
||||
|
||||
# the following config is for teaching kustomize how to do kustomization for CRDs.
|
||||
configurations:
|
||||
- kustomizeconfig.yaml
|
||||
@@ -0,0 +1,19 @@
|
||||
# This file is for teaching kustomize how to substitute name and namespace reference in CRD
|
||||
nameReference:
|
||||
- kind: Service
|
||||
version: v1
|
||||
fieldSpecs:
|
||||
- kind: CustomResourceDefinition
|
||||
version: v1
|
||||
group: apiextensions.k8s.io
|
||||
path: spec/conversion/webhook/clientConfig/service/name
|
||||
|
||||
namespace:
|
||||
- kind: CustomResourceDefinition
|
||||
version: v1
|
||||
group: apiextensions.k8s.io
|
||||
path: spec/conversion/webhook/clientConfig/service/namespace
|
||||
create: false
|
||||
|
||||
varReference:
|
||||
- path: metadata/annotations
|
||||
+1
-1
@@ -4,4 +4,4 @@ kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME)
|
||||
name: extensionresourceprices.metering.sealos.io
|
||||
name: extensionresourceprice.metering.common.sealos.io
|
||||
+1
-1
@@ -4,4 +4,4 @@ kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME)
|
||||
name: resources.metering.sealos.io
|
||||
name: resources.metering.common.sealos.io
|
||||
@@ -22,21 +22,4 @@ resources:
|
||||
kind: PodResource
|
||||
path: github.com/labring/sealos/controllers/metering/api/v1
|
||||
version: v1
|
||||
- api:
|
||||
crdVersion: v1
|
||||
namespaced: true
|
||||
controller: true
|
||||
domain: sealos.io
|
||||
group: metering
|
||||
kind: ExtensionResourcePrice
|
||||
path: github.com/labring/sealos/controllers/metering/api/v1
|
||||
version: v1
|
||||
- api:
|
||||
crdVersion: v1
|
||||
namespaced: true
|
||||
domain: sealos.io
|
||||
group: metering
|
||||
kind: Resource
|
||||
path: github.com/labring/sealos/controllers/metering/api/v1
|
||||
version: v1
|
||||
version: "3"
|
||||
|
||||
@@ -63,5 +63,5 @@ sealos cloud 是一个多租户的,以 k8s 为内核的云操作系统,每
|
||||
|
||||
4、deduction扣费模块可以按任意时间间隔扣费。
|
||||
|
||||
|
||||
|
||||
## Metering e2e 测试
|
||||
需要在自己仓库的secret写入GH_PAT 这个secret,github-> Developer settings -> Personal Access Tokens.
|
||||
@@ -1,10 +1,10 @@
|
||||
package v1
|
||||
|
||||
const (
|
||||
ExtensionResourcePricePrefix = "extensionresourceprice-"
|
||||
MeteringPrefix = "metering-"
|
||||
ResourceQuotaPrefix = "quota-"
|
||||
METERINGNAMESPACEENV = "METERING_SYSTEM_NAMESPACE"
|
||||
DEFAULTMETERINGNAMESPACE = "metering-system"
|
||||
PodResourcePricePrefix = "sealos-pod-controller"
|
||||
MeteringPrefix = "metering-"
|
||||
ResourceQuotaPrefix = "quota-"
|
||||
METERINGNAMESPACEENV = "METERING_SYSTEM_NAMESPACE"
|
||||
DEFAULTMETERINGNAMESPACE = "metering-system"
|
||||
PodResourcePricePrefix = "sealos-pod-controller"
|
||||
UserAnnotationOwnerKey = "user.sealos.io/creator"
|
||||
)
|
||||
|
||||
@@ -17,17 +17,21 @@ limitations under the License.
|
||||
package v1
|
||||
|
||||
import (
|
||||
meteringcommonv1 "github.com/labring/sealos/controllers/common/metering/api/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
type TimeIntervalType string
|
||||
type Status string
|
||||
|
||||
const (
|
||||
MINUTE TimeIntervalType = "Minute"
|
||||
HOUR TimeIntervalType = "Hour"
|
||||
DAY TimeIntervalType = "Day"
|
||||
MINUTE TimeIntervalType = "Minute"
|
||||
HOUR TimeIntervalType = "Hour"
|
||||
DAY TimeIntervalType = "Day"
|
||||
Complete Status = "complete"
|
||||
Create Status = "create"
|
||||
)
|
||||
|
||||
/*
|
||||
@@ -48,8 +52,8 @@ type MeteringSpec struct {
|
||||
Owner string `json:"owner"`
|
||||
|
||||
//timeInterval unit is minutes
|
||||
TimeInterval int `json:"timeInterval,omitempty"`
|
||||
Resources map[corev1.ResourceName]ResourcePriceAndUsed `json:"resources,omitempty"`
|
||||
TimeInterval int `json:"timeInterval,omitempty"`
|
||||
Resources map[corev1.ResourceName]meteringcommonv1.ResourceInfo `json:"resources,omitempty"`
|
||||
}
|
||||
|
||||
// MeteringStatus defines the observed state of Metering
|
||||
@@ -61,26 +65,15 @@ type MeteringStatus struct {
|
||||
SeqID int64 `json:"seqID,omitempty"`
|
||||
}
|
||||
|
||||
type ResourcePrice struct {
|
||||
Unit *resource.Quantity `json:"unit"`
|
||||
Price int64 `json:"price"` // 100 = 1¥
|
||||
Describe string `json:"describe,omitempty"`
|
||||
}
|
||||
|
||||
type ResourcePriceAndUsed struct {
|
||||
ResourcePrice `json:",inline"`
|
||||
Used *resource.Quantity `json:"used,omitempty"`
|
||||
}
|
||||
|
||||
type ResourceMsg struct {
|
||||
ResourceName corev1.ResourceName
|
||||
Amount float64
|
||||
Amount int64
|
||||
Used *resource.Quantity
|
||||
Unit *resource.Quantity
|
||||
}
|
||||
|
||||
type BillingList struct {
|
||||
TimeStamp int64 `json:"timeStamp,omitempty"`
|
||||
Timestamp int64 `json:"timestamp,omitempty"`
|
||||
TimeInterval TimeIntervalType `json:"timeInterval,omitempty"` //time interval,/Minute/Hour/Day
|
||||
Settled bool `json:"settled,omitempty"` //is settled
|
||||
Amount int64 `json:"amount,omitempty"` //need to pay amount,100 = 1¥
|
||||
|
||||
@@ -17,18 +17,17 @@ limitations under the License.
|
||||
package v1
|
||||
|
||||
import (
|
||||
meteringcommonv1 "github.com/labring/sealos/controllers/common/metering/api/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// PodResourceSpec defines the desired state of PodResource
|
||||
type PodResourceSpec struct {
|
||||
ResourceName string `json:"resourceName,omitempty"`
|
||||
Resources map[v1.ResourceName]ResourcePrice `json:"resources,omitempty"`
|
||||
ResourceName string `json:"resourceName,omitempty"`
|
||||
Resources map[v1.ResourceName]meteringcommonv1.ResourcePrice `json:"resources,omitempty"`
|
||||
|
||||
// update used resources every Interval minutes
|
||||
//+kubebuilder:default=50
|
||||
//+kubebuilder:validation:Minimum=1
|
||||
Interval int `json:"interval,omitempty"`
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ limitations under the License.
|
||||
package v1
|
||||
|
||||
import (
|
||||
apiv1 "github.com/labring/sealos/controllers/common/metering/api/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
@@ -41,102 +42,6 @@ func (in *BillingList) DeepCopy() *BillingList {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ExtensionResourcePrice) DeepCopyInto(out *ExtensionResourcePrice) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
out.Status = in.Status
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExtensionResourcePrice.
|
||||
func (in *ExtensionResourcePrice) DeepCopy() *ExtensionResourcePrice {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ExtensionResourcePrice)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *ExtensionResourcePrice) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ExtensionResourcePriceList) DeepCopyInto(out *ExtensionResourcePriceList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]ExtensionResourcePrice, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExtensionResourcePriceList.
|
||||
func (in *ExtensionResourcePriceList) DeepCopy() *ExtensionResourcePriceList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ExtensionResourcePriceList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *ExtensionResourcePriceList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ExtensionResourcePriceSpec) DeepCopyInto(out *ExtensionResourcePriceSpec) {
|
||||
*out = *in
|
||||
if in.Resources != nil {
|
||||
in, out := &in.Resources, &out.Resources
|
||||
*out = make(map[corev1.ResourceName]ResourcePrice, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = *val.DeepCopy()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExtensionResourcePriceSpec.
|
||||
func (in *ExtensionResourcePriceSpec) DeepCopy() *ExtensionResourcePriceSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ExtensionResourcePriceSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ExtensionResourcePriceStatus) DeepCopyInto(out *ExtensionResourcePriceStatus) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExtensionResourcePriceStatus.
|
||||
func (in *ExtensionResourcePriceStatus) DeepCopy() *ExtensionResourcePriceStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ExtensionResourcePriceStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Metering) DeepCopyInto(out *Metering) {
|
||||
*out = *in
|
||||
@@ -201,7 +106,7 @@ func (in *MeteringSpec) DeepCopyInto(out *MeteringSpec) {
|
||||
*out = *in
|
||||
if in.Resources != nil {
|
||||
in, out := &in.Resources, &out.Resources
|
||||
*out = make(map[corev1.ResourceName]ResourcePriceAndUsed, len(*in))
|
||||
*out = make(map[corev1.ResourceName]apiv1.ResourceInfo, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = *val.DeepCopy()
|
||||
}
|
||||
@@ -307,7 +212,7 @@ func (in *PodResourceSpec) DeepCopyInto(out *PodResourceSpec) {
|
||||
*out = *in
|
||||
if in.Resources != nil {
|
||||
in, out := &in.Resources, &out.Resources
|
||||
*out = make(map[corev1.ResourceName]ResourcePrice, len(*in))
|
||||
*out = make(map[corev1.ResourceName]apiv1.ResourcePrice, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = *val.DeepCopy()
|
||||
}
|
||||
@@ -339,85 +244,6 @@ func (in *PodResourceStatus) DeepCopy() *PodResourceStatus {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Resource) DeepCopyInto(out *Resource) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
out.Status = in.Status
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Resource.
|
||||
func (in *Resource) DeepCopy() *Resource {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Resource)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *Resource) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ResourceInfo) DeepCopyInto(out *ResourceInfo) {
|
||||
*out = *in
|
||||
if in.Used != nil {
|
||||
in, out := &in.Used, &out.Used
|
||||
x := (*in).DeepCopy()
|
||||
*out = &x
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceInfo.
|
||||
func (in *ResourceInfo) DeepCopy() *ResourceInfo {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ResourceInfo)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ResourceList) DeepCopyInto(out *ResourceList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]Resource, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceList.
|
||||
func (in *ResourceList) DeepCopy() *ResourceList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ResourceList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *ResourceList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ResourceMsg) DeepCopyInto(out *ResourceMsg) {
|
||||
*out = *in
|
||||
@@ -442,81 +268,3 @@ func (in *ResourceMsg) DeepCopy() *ResourceMsg {
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ResourcePrice) DeepCopyInto(out *ResourcePrice) {
|
||||
*out = *in
|
||||
if in.Unit != nil {
|
||||
in, out := &in.Unit, &out.Unit
|
||||
x := (*in).DeepCopy()
|
||||
*out = &x
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourcePrice.
|
||||
func (in *ResourcePrice) DeepCopy() *ResourcePrice {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ResourcePrice)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ResourcePriceAndUsed) DeepCopyInto(out *ResourcePriceAndUsed) {
|
||||
*out = *in
|
||||
in.ResourcePrice.DeepCopyInto(&out.ResourcePrice)
|
||||
if in.Used != nil {
|
||||
in, out := &in.Used, &out.Used
|
||||
x := (*in).DeepCopy()
|
||||
*out = &x
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourcePriceAndUsed.
|
||||
func (in *ResourcePriceAndUsed) DeepCopy() *ResourcePriceAndUsed {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ResourcePriceAndUsed)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ResourceSpec) DeepCopyInto(out *ResourceSpec) {
|
||||
*out = *in
|
||||
if in.Resources != nil {
|
||||
in, out := &in.Resources, &out.Resources
|
||||
*out = make(map[corev1.ResourceName]ResourceInfo, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = *val.DeepCopy()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceSpec.
|
||||
func (in *ResourceSpec) DeepCopy() *ResourceSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ResourceSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ResourceStatus) DeepCopyInto(out *ResourceStatus) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceStatus.
|
||||
func (in *ResourceStatus) DeepCopy() *ResourceStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ResourceStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
@@ -53,26 +53,22 @@ spec:
|
||||
resources:
|
||||
additionalProperties:
|
||||
properties:
|
||||
describe:
|
||||
type: string
|
||||
price:
|
||||
cost:
|
||||
format: int64
|
||||
type: integer
|
||||
namespace:
|
||||
type: string
|
||||
resourceName:
|
||||
type: string
|
||||
time:
|
||||
format: int64
|
||||
type: integer
|
||||
unit:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
|
||||
x-kubernetes-int-or-string: true
|
||||
used:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
|
||||
x-kubernetes-int-or-string: true
|
||||
required:
|
||||
- price
|
||||
- unit
|
||||
type: object
|
||||
type: object
|
||||
timeInterval:
|
||||
@@ -95,7 +91,7 @@ spec:
|
||||
type: boolean
|
||||
timeInterval:
|
||||
type: string
|
||||
timeStamp:
|
||||
timestamp:
|
||||
format: int64
|
||||
type: integer
|
||||
type: object
|
||||
@@ -110,7 +106,7 @@ spec:
|
||||
type: boolean
|
||||
timeInterval:
|
||||
type: string
|
||||
timeStamp:
|
||||
timestamp:
|
||||
format: int64
|
||||
type: integer
|
||||
type: object
|
||||
|
||||
@@ -36,9 +36,7 @@ spec:
|
||||
description: PodResourceSpec defines the desired state of PodResource
|
||||
properties:
|
||||
interval:
|
||||
default: 50
|
||||
description: update used resources every Interval minutes
|
||||
minimum: 1
|
||||
type: integer
|
||||
resourceName:
|
||||
type: string
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
resources:
|
||||
- bases/metering.sealos.io_meterings.yaml
|
||||
- bases/metering.sealos.io_podresources.yaml
|
||||
- bases/metering.sealos.io_extensionresourceprices.yaml
|
||||
- bases/metering.sealos.io_resources.yaml
|
||||
#+kubebuilder:scaffold:crdkustomizeresource
|
||||
|
||||
patchesStrategicMerge:
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
# The following patch adds a directive for certmanager to inject CA into the CRD
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME)
|
||||
name: podresources.metering.sealos.io
|
||||
@@ -1,16 +0,0 @@
|
||||
# The following patch enables a conversion webhook for the CRD
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: extensionresourceprices.metering.sealos.io
|
||||
spec:
|
||||
conversion:
|
||||
strategy: Webhook
|
||||
webhook:
|
||||
clientConfig:
|
||||
service:
|
||||
namespace: system
|
||||
name: webhook-service
|
||||
path: /convert
|
||||
conversionReviewVersions:
|
||||
- v1
|
||||
@@ -1,16 +0,0 @@
|
||||
# The following patch enables a conversion webhook for the CRD
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: podresources.metering.sealos.io
|
||||
spec:
|
||||
conversion:
|
||||
strategy: Webhook
|
||||
webhook:
|
||||
clientConfig:
|
||||
service:
|
||||
namespace: system
|
||||
name: webhook-service
|
||||
path: /convert
|
||||
conversionReviewVersions:
|
||||
- v1
|
||||
@@ -1,16 +0,0 @@
|
||||
# The following patch enables a conversion webhook for the CRD
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: resources.metering.sealos.io
|
||||
spec:
|
||||
conversion:
|
||||
strategy: Webhook
|
||||
webhook:
|
||||
clientConfig:
|
||||
service:
|
||||
namespace: system
|
||||
name: webhook-service
|
||||
path: /convert
|
||||
conversionReviewVersions:
|
||||
- v1
|
||||
@@ -1,24 +0,0 @@
|
||||
# permissions for end users to edit extensionresourceprices.
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: extensionresourceprice-editor-role
|
||||
rules:
|
||||
- apiGroups:
|
||||
- metering.sealos.io
|
||||
resources:
|
||||
- extensionresourceprices
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- metering.sealos.io
|
||||
resources:
|
||||
- extensionresourceprices/status
|
||||
verbs:
|
||||
- get
|
||||
@@ -1,20 +0,0 @@
|
||||
# permissions for end users to view extensionresourceprices.
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: extensionresourceprice-viewer-role
|
||||
rules:
|
||||
- apiGroups:
|
||||
- metering.sealos.io
|
||||
resources:
|
||||
- extensionresourceprices
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- metering.sealos.io
|
||||
resources:
|
||||
- extensionresourceprices/status
|
||||
verbs:
|
||||
- get
|
||||
@@ -1,24 +0,0 @@
|
||||
# permissions for end users to edit resources.
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: resource-editor-role
|
||||
rules:
|
||||
- apiGroups:
|
||||
- metering.sealos.io
|
||||
resources:
|
||||
- resources
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- metering.sealos.io
|
||||
resources:
|
||||
- resources/status
|
||||
verbs:
|
||||
- get
|
||||
@@ -1,20 +0,0 @@
|
||||
# permissions for end users to view resources.
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: resource-viewer-role
|
||||
rules:
|
||||
- apiGroups:
|
||||
- metering.sealos.io
|
||||
resources:
|
||||
- resources
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- metering.sealos.io
|
||||
resources:
|
||||
- resources/status
|
||||
verbs:
|
||||
- get
|
||||
@@ -54,19 +54,7 @@ rules:
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- infra.sealos.io
|
||||
resources:
|
||||
- infras
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- metering.sealos.io
|
||||
- metering.common.sealos.io
|
||||
resources:
|
||||
- extensionresourceprices
|
||||
verbs:
|
||||
@@ -77,6 +65,26 @@ rules:
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- metering.common.sealos.io
|
||||
resources:
|
||||
- resources
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- metering.common.sealos.io
|
||||
resources:
|
||||
- resources/status
|
||||
verbs:
|
||||
- get
|
||||
- patch
|
||||
- update
|
||||
- apiGroups:
|
||||
- metering.sealos.io
|
||||
resources:
|
||||
@@ -129,23 +137,3 @@ rules:
|
||||
- get
|
||||
- patch
|
||||
- update
|
||||
- apiGroups:
|
||||
- metering.sealos.io
|
||||
resources:
|
||||
- resources
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- metering.sealos.io
|
||||
resources:
|
||||
- resources/status
|
||||
verbs:
|
||||
- get
|
||||
- patch
|
||||
- update
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
apiVersion: metering.sealos.io/v1
|
||||
kind: ExtensionResourcePrice
|
||||
metadata:
|
||||
name: extensionresourceprice-sample
|
||||
spec:
|
||||
resourceName: pod
|
||||
resources:
|
||||
cpu:
|
||||
unit: "10"
|
||||
price: 67
|
||||
describe: "cost per cpu per hour(price:100 = 1¥)"
|
||||
@@ -8,21 +8,21 @@ spec:
|
||||
interval: 60
|
||||
resources:
|
||||
cpu:
|
||||
unit: "10"
|
||||
price: 67
|
||||
unit: "1"
|
||||
price: 670
|
||||
describe: "cost per cpu per hour(price:100 = 1¥)"
|
||||
|
||||
memory:
|
||||
unit: "10G"
|
||||
price: 33
|
||||
unit: "1G"
|
||||
price: 330
|
||||
describe: "the cost per gigabyte of memory per hour(price:100 = 1¥)"
|
||||
|
||||
storage:
|
||||
unit: "100G"
|
||||
unit: "1G"
|
||||
price: 21
|
||||
describe: "cost per gigabyte of storage per hour(price:100 = 1¥)"
|
||||
|
||||
ephemeral-storage:
|
||||
unit: "100G"
|
||||
unit: "1G"
|
||||
price: 21
|
||||
describe: "cost per gigabyte of storage per hour(price:100 = 1¥)"
|
||||
@@ -1,9 +0,0 @@
|
||||
apiVersion: metering.sealos.io/v1
|
||||
kind: Resource
|
||||
metadata:
|
||||
name: resource-sample
|
||||
spec:
|
||||
resources:
|
||||
resourceName: "cpu"
|
||||
Used: 1
|
||||
|
||||
@@ -18,7 +18,6 @@ package controllers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
@@ -28,18 +27,16 @@ import (
|
||||
|
||||
"k8s.io/client-go/util/retry"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
infrav1 "github.com/labring/sealos/controllers/infra/api/v1"
|
||||
userv1 "github.com/labring/sealos/controllers/user/api/v1"
|
||||
meteringcommonv1 "github.com/labring/sealos/controllers/common/metering/api/v1"
|
||||
meteringv1 "github.com/labring/sealos/controllers/metering/api/v1"
|
||||
|
||||
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
|
||||
"sigs.k8s.io/controller-runtime/pkg/handler"
|
||||
"sigs.k8s.io/controller-runtime/pkg/source"
|
||||
|
||||
meteringv1 "github.com/labring/sealos/controllers/metering/api/v1"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
@@ -53,19 +50,18 @@ type MeteringReconcile struct {
|
||||
client.Client
|
||||
Scheme *runtime.Scheme
|
||||
logr.Logger
|
||||
MeteringSystemNameSpace string
|
||||
MeteringSystemNamespace string
|
||||
MeteringInterval int
|
||||
}
|
||||
|
||||
//+kubebuilder:rbac:groups=metering.sealos.io,resources=meterings,verbs=get;list;watch;create;update;patch;delete
|
||||
//+kubebuilder:rbac:groups=metering.sealos.io,resources=meterings/status,verbs=get;update;patch
|
||||
//+kubebuilder:rbac:groups=metering.sealos.io,resources=meterings/finalizers,verbs=update
|
||||
//+kubebuilder:rbac:groups=metering.sealos.io,resources=extensionresourceprices,verbs=get;list;watch;create;update;patch;delete
|
||||
//+kubebuilder:rbac:groups=metering.sealos.io,resources=resources,verbs=get;list;watch;create;update;patch;delete
|
||||
//+kubebuilder:rbac:groups=metering.sealos.io,resources=resources/status,verbs=get;update;patch
|
||||
//+kubebuilder:rbac:groups=metering.common.sealos.io,resources=extensionresourceprices,verbs=get;list;watch;create;update;patch;delete
|
||||
//+kubebuilder:rbac:groups=metering.common.sealos.io,resources=resources,verbs=get;list;watch;create;update;patch;delete
|
||||
//+kubebuilder:rbac:groups=metering.common.sealos.io,resources=resources/status,verbs=get;update;patch
|
||||
//+kubebuilder:rbac:groups=core,resources=namespaces,verbs=get;list;watch;create;update;patch;delete
|
||||
//+kubebuilder:rbac:groups=core,resources=resourcequotas,verbs=get;list;watch;create;update;patch;delete
|
||||
//+kubebuilder:rbac:groups=infra.sealos.io,resources=infras,verbs=get;list;watch;create;update;patch;delete
|
||||
//+kubebuilder:rbac:groups=account.sealos.io,resources=accountbalances,verbs=get;list;watch;create;update;patch;delete
|
||||
|
||||
// Reconcile metering belong to account,resourceQuota belong to metering
|
||||
@@ -75,10 +71,10 @@ func (r *MeteringReconcile) Reconcile(ctx context.Context, req ctrl.Request) (ct
|
||||
var ns corev1.Namespace
|
||||
if err := r.Get(ctx, req.NamespacedName, &ns); err == nil {
|
||||
// if create a user namespace ,will enter this reconcile
|
||||
if _, ok := ns.Annotations[userv1.UserAnnotationOwnerKey]; ok {
|
||||
if _, ok := ns.Annotations[meteringv1.UserAnnotationOwnerKey]; ok {
|
||||
if ns.DeletionTimestamp != nil {
|
||||
r.Logger.Info("namespace is deleting,want to delete metering", "namespace", ns.Name)
|
||||
err := r.DelMetering(ctx, meteringv1.MeteringPrefix+ns.Name, r.MeteringSystemNameSpace)
|
||||
err := r.DelMetering(ctx, meteringv1.MeteringPrefix+ns.Name, r.MeteringSystemNamespace)
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
if err := r.initMetering(ctx, ns); err != nil {
|
||||
@@ -90,58 +86,43 @@ func (r *MeteringReconcile) Reconcile(ctx context.Context, req ctrl.Request) (ct
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
|
||||
// when extensionResourcePrice change will enter this logic
|
||||
var extensionResourcePrice meteringv1.ExtensionResourcePrice
|
||||
if err := r.Get(ctx, req.NamespacedName, &extensionResourcePrice); err == nil {
|
||||
meteringList := &meteringv1.MeteringList{}
|
||||
err = r.List(ctx, meteringList)
|
||||
if err != nil {
|
||||
return ctrl.Result{}, client.IgnoreNotFound(err)
|
||||
}
|
||||
for _, metering := range meteringList.Items {
|
||||
if _, err := controllerutil.CreateOrUpdate(ctx, r.Client, &metering, func() error {
|
||||
if metering.Spec.Resources == nil {
|
||||
metering.Spec.Resources = make(map[corev1.ResourceName]meteringv1.ResourcePriceAndUsed, 0)
|
||||
}
|
||||
for resourceName, v := range extensionResourcePrice.Spec.Resources {
|
||||
metering.Spec.Resources[resourceName] = meteringv1.ResourcePriceAndUsed{ResourcePrice: v, Used: &resource.Quantity{}}
|
||||
}
|
||||
//r.Logger.Info("metering", "metering", metering)
|
||||
return nil
|
||||
}); err != nil {
|
||||
return ctrl.Result{}, fmt.Errorf("sync metering failed: %v", err)
|
||||
}
|
||||
}
|
||||
//r.Logger.Info("", "meteringList", meteringList)
|
||||
} else if client.IgnoreNotFound(err) != nil {
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
|
||||
// when Resource create will enter this logic
|
||||
resources := &meteringv1.Resource{}
|
||||
resources := &meteringcommonv1.Resource{}
|
||||
if err := r.Get(ctx, req.NamespacedName, resources); err == nil {
|
||||
if resources.Status.Status == meteringv1.Complete || !resources.DeletionTimestamp.IsZero() {
|
||||
if resources.Status.Status == meteringcommonv1.Complete || !resources.DeletionTimestamp.IsZero() {
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
r.Logger.Info("enter update resource used", "resource name: ", req.Name, "resource namespace: ", req.Namespace, "resource Used", resources.Spec.Resources)
|
||||
var metering meteringv1.Metering
|
||||
for resourceName, resourceInfo := range resources.Spec.Resources {
|
||||
if err := r.Get(ctx, types.NamespacedName{Namespace: r.MeteringSystemNameSpace, Name: meteringv1.MeteringPrefix + resourceInfo.NameSpace}, &metering); err != nil {
|
||||
r.Logger.Error(err, "get metering failed", "name", meteringv1.MeteringPrefix+resourceInfo.NameSpace)
|
||||
continue
|
||||
}
|
||||
if _, ok := metering.Spec.Resources[resourceName]; !ok {
|
||||
r.Logger.Error(err, "resource not found in metering", "name", resourceName)
|
||||
continue
|
||||
if err := r.Get(ctx, types.NamespacedName{Namespace: r.MeteringSystemNamespace, Name: meteringv1.MeteringPrefix + resourceInfo.Namespace}, &metering); err != nil {
|
||||
if err := r.Get(ctx, types.NamespacedName{Namespace: r.MeteringSystemNamespace, Name: meteringv1.MeteringPrefix + req.Namespace}, &metering); err != nil {
|
||||
r.Logger.Error(err, "get metering failed", "name", meteringv1.MeteringPrefix+resourceInfo.Namespace)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if _, err := controllerutil.CreateOrUpdate(ctx, r.Client, &metering, func() error {
|
||||
metering.Spec.Resources[resourceName].Used.Add(*resourceInfo.Used)
|
||||
if metering.Spec.Resources == nil {
|
||||
metering.Spec.Resources = make(map[corev1.ResourceName]meteringcommonv1.ResourceInfo)
|
||||
}
|
||||
if _, ok := metering.Spec.Resources[resourceName]; !ok {
|
||||
metering.Spec.Resources[resourceName] = resourceInfo
|
||||
} else {
|
||||
metering.Spec.Resources[resourceName] = meteringcommonv1.ResourceInfo{
|
||||
Timestamp: time.Now().Unix(),
|
||||
Namespace: metering.Spec.Resources[resourceName].Namespace,
|
||||
Cost: metering.Spec.Resources[resourceName].Cost + resourceInfo.Cost,
|
||||
Used: metering.Spec.Resources[resourceName].Used,
|
||||
}
|
||||
metering.Spec.Resources[resourceName].Used.Add(*resourceInfo.Used)
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
r.Logger.Error(err, "update metering failed", "name", meteringv1.MeteringPrefix+resourceInfo.NameSpace)
|
||||
r.Logger.Error(err, "update metering failed", "name", meteringv1.MeteringPrefix+resourceInfo.Namespace)
|
||||
return ctrl.Result{Requeue: true}, err
|
||||
}
|
||||
resources.Status.Status = meteringv1.Complete
|
||||
resources.Status.Status = meteringcommonv1.Complete
|
||||
if err := r.Status().Update(ctx, resources); err != nil {
|
||||
r.Logger.Error(err, err.Error())
|
||||
return ctrl.Result{Requeue: true}, err
|
||||
@@ -156,23 +137,23 @@ func (r *MeteringReconcile) Reconcile(ctx context.Context, req ctrl.Request) (ct
|
||||
return ctrl.Result{}, client.IgnoreNotFound(err)
|
||||
}
|
||||
|
||||
if time.Now().Unix()-metering.Status.LatestUpdateTime >= int64(time.Minute.Seconds())*int64(metering.Spec.TimeInterval) {
|
||||
//r.Logger.Info("enter update metering", "metering name:", req.Name, "metering namespace:", req.Namespace, "lastUpdate Time", metering.Status.LatestUpdateTime, "now", time.Now().Unix(), "diff", time.Now().Unix()-metering.Status.LatestUpdateTime, "interval", int64(time.Minute.Seconds())*int64(metering.Spec.TimeInterval))
|
||||
totalAccount, resourceMsgs, err := r.CalculateCost(ctx, &metering)
|
||||
if overTimeInterval(metering) {
|
||||
r.Logger.Info("enter update metering", "metering name:", req.Name, "metering namespace:", req.Namespace, "lastUpdate Time", metering.Status.LatestUpdateTime, "now", time.Now().Unix(), "diff", time.Now().Unix()-metering.Status.LatestUpdateTime, "interval", int64(metering.Spec.TimeInterval))
|
||||
totalAmount, err := r.CalculateCost(metering)
|
||||
if err != nil {
|
||||
r.Logger.Error(err, err.Error())
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
if err := r.createAccountBalance(ctx, metering, totalAmount); err != nil {
|
||||
r.Logger.Error(err, err.Error())
|
||||
return ctrl.Result{}, fmt.Errorf("meteringName:%v,amount:%v,err:%v", metering.Name, totalAmount, err)
|
||||
}
|
||||
if err := r.clearResourceUsed(ctx, &metering); err != nil {
|
||||
r.Logger.Error(err, err.Error())
|
||||
return ctrl.Result{Requeue: true}, err
|
||||
}
|
||||
|
||||
if err := r.createAccountBalance(ctx, metering.Spec.Owner, totalAccount, metering.Status.SeqID, resourceMsgs); err != nil {
|
||||
r.Logger.Error(err, err.Error())
|
||||
return ctrl.Result{}, fmt.Errorf("meteringName:%v,amount:%v,err:%v", metering.Name, totalAccount, err)
|
||||
}
|
||||
if err := r.updateBillingList(ctx, totalAccount, &metering); err != nil {
|
||||
if err := r.updateBillingList(ctx, totalAmount, &metering); err != nil {
|
||||
r.Logger.Error(err, err.Error())
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
@@ -181,67 +162,22 @@ func (r *MeteringReconcile) Reconcile(ctx context.Context, req ctrl.Request) (ct
|
||||
return ctrl.Result{Requeue: true, RequeueAfter: time.Minute * time.Duration(r.MeteringInterval)}, nil
|
||||
}
|
||||
|
||||
func (r *MeteringReconcile) CalculateCost(ctx context.Context, metering *meteringv1.Metering) (int64, interface{}, error) {
|
||||
var resourceMsgs []meteringv1.ResourceMsg
|
||||
infraAmount, err := r.calculateInfraCost(ctx, metering)
|
||||
if err != nil {
|
||||
r.Logger.Error(err, "Failed to get InfraCost")
|
||||
} else {
|
||||
resourceMsgs = append(resourceMsgs, meteringv1.ResourceMsg{
|
||||
ResourceName: "infra",
|
||||
Amount: float64(infraAmount),
|
||||
})
|
||||
}
|
||||
|
||||
var totalAmount float64
|
||||
for resourceName, resourceValue := range metering.Spec.Resources {
|
||||
if _, ok := metering.Spec.Resources[resourceName]; ok {
|
||||
amount := float64(resourceValue.Used.MilliValue()) * float64(resourceValue.Price) / float64(resourceValue.Unit.MilliValue())
|
||||
resourceMsgs = append(resourceMsgs, meteringv1.ResourceMsg{
|
||||
ResourceName: resourceName,
|
||||
Amount: amount,
|
||||
Used: resourceValue.Used,
|
||||
Unit: resourceValue.Unit,
|
||||
})
|
||||
totalAmount += amount
|
||||
} else {
|
||||
r.Logger.Error(fmt.Errorf("resource: %v is not found", resourceName), "Failed to get Resource")
|
||||
}
|
||||
}
|
||||
totalAmount += float64(infraAmount)
|
||||
r.Logger.Info(fmt.Sprintf("meteringNmae %v,resourceMsg: %+v", metering.Name, resourceMsgs), "totalAmount", totalAmount, "seqID", metering.Status.SeqID)
|
||||
return int64(totalAmount), resourceMsgs, nil
|
||||
func overTimeInterval(metering meteringv1.Metering) bool {
|
||||
return time.Now().Unix()-metering.Status.LatestUpdateTime >= int64(time.Minute.Seconds())*int64(metering.Spec.TimeInterval)
|
||||
}
|
||||
|
||||
func (r *MeteringReconcile) calculateInfraCost(ctx context.Context, metering *meteringv1.Metering) (int64, error) {
|
||||
infraList := &infrav1.InfraList{}
|
||||
err := r.List(ctx, infraList)
|
||||
//r.Logger.Info("infraList", "infraList", infraList)
|
||||
if client.IgnoreNotFound(err) != nil {
|
||||
r.Logger.Error(err, "Failed to get InfraList")
|
||||
return 0, err
|
||||
func (r *MeteringReconcile) CalculateCost(metering meteringv1.Metering) (int64, error) {
|
||||
var totalAmount int64
|
||||
for _, resourceValue := range metering.Spec.Resources {
|
||||
totalAmount += resourceValue.Cost
|
||||
}
|
||||
var amount int64
|
||||
for _, infra := range infraList.Items {
|
||||
if infra.Namespace == metering.Spec.Namespace {
|
||||
count, err := infra.QueryPrice()
|
||||
r.Logger.Info("get infra :", "name: ", infra.Name, "namespace: ", infra.Namespace, "price: ", count, "meteringName", metering.Name, "userNamespace", metering.Spec.Namespace)
|
||||
if err != nil {
|
||||
r.Logger.Error(err, "Failed to get InfraPrice", "meteringName", metering.Name)
|
||||
}
|
||||
amount += count
|
||||
}
|
||||
}
|
||||
// amount is preHour,but billing is perMinute
|
||||
r.Logger.V(1).Info("infra", "price:", amount)
|
||||
return amount, nil
|
||||
return totalAmount, nil
|
||||
}
|
||||
|
||||
func (r *MeteringReconcile) clearResourceUsed(ctx context.Context, metering *meteringv1.Metering) error {
|
||||
if _, err := controllerutil.CreateOrUpdate(ctx, r.Client, metering, func() error {
|
||||
for _, v := range metering.Spec.Resources {
|
||||
used := resource.MustParse(v.Used.String())
|
||||
v.Used.Sub(used)
|
||||
for k := range metering.Spec.Resources {
|
||||
delete(metering.Spec.Resources, k)
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
@@ -274,7 +210,7 @@ func (r *MeteringReconcile) updateBillingList(ctx context.Context, amount int64,
|
||||
|
||||
func NewBillingList(TimeInterval meteringv1.TimeIntervalType, amount int64) meteringv1.BillingList {
|
||||
return meteringv1.BillingList{
|
||||
TimeStamp: time.Now().Unix(),
|
||||
Timestamp: time.Now().Unix(),
|
||||
TimeInterval: TimeInterval,
|
||||
Settled: false,
|
||||
Amount: amount,
|
||||
@@ -287,23 +223,18 @@ func (r *MeteringReconcile) initMetering(ctx context.Context, ns corev1.Namespac
|
||||
r.Error(err, "Failed to syncResourceQuota")
|
||||
return err
|
||||
}
|
||||
totalResourcePrice, err := r.GetAllExtensionResources(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
r.Logger.Info("totalResourcePrice", "totalResourcePrice", totalResourcePrice)
|
||||
if err = r.syncMetering(ctx, ns, totalResourcePrice); err != nil {
|
||||
if err := r.syncMetering(ctx, ns); err != nil {
|
||||
r.Logger.Error(err, "Failed to create Metering", "nsName", ns.Name)
|
||||
return client.IgnoreNotFound(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *MeteringReconcile) syncMetering(ctx context.Context, ns corev1.Namespace, resourcePrice map[corev1.ResourceName]meteringv1.ResourcePriceAndUsed) error {
|
||||
func (r *MeteringReconcile) syncMetering(ctx context.Context, ns corev1.Namespace) error {
|
||||
metering := meteringv1.Metering{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: meteringv1.MeteringPrefix + ns.Name,
|
||||
Namespace: r.MeteringSystemNameSpace,
|
||||
Namespace: r.MeteringSystemNamespace,
|
||||
},
|
||||
}
|
||||
if err := r.Get(ctx, types.NamespacedName{Name: metering.Name, Namespace: metering.Namespace}, &metering); err == nil {
|
||||
@@ -311,12 +242,14 @@ func (r *MeteringReconcile) syncMetering(ctx context.Context, ns corev1.Namespac
|
||||
return nil
|
||||
}
|
||||
|
||||
r.Logger.V(1).Info("metering env", "METERING_INTERVAL", r.MeteringSystemNameSpace, "timeInterval: ", r.MeteringInterval)
|
||||
r.Logger.V(1).Info("metering env", "METERING_INTERVAL", r.MeteringSystemNamespace, "timeInterval: ", r.MeteringInterval)
|
||||
if _, err := controllerutil.CreateOrUpdate(ctx, r.Client, &metering, func() error {
|
||||
metering.Spec.Namespace = ns.Name
|
||||
metering.Spec.Owner = ns.Annotations[userv1.UserAnnotationOwnerKey]
|
||||
metering.Spec.Resources = resourcePrice
|
||||
metering.Spec.Owner = ns.Annotations[meteringv1.UserAnnotationOwnerKey]
|
||||
metering.Spec.TimeInterval = r.MeteringInterval
|
||||
if metering.Spec.Resources == nil {
|
||||
metering.Spec.Resources = make(map[corev1.ResourceName]meteringcommonv1.ResourceInfo)
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
r.Error(err, "Failed to update Metering")
|
||||
@@ -357,32 +290,17 @@ func (r *MeteringReconcile) DelMetering(ctx context.Context, name, namespace str
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *MeteringReconcile) GetAllExtensionResources(ctx context.Context) (map[corev1.ResourceName]meteringv1.ResourcePriceAndUsed, error) {
|
||||
extensionResourcesPriceList := meteringv1.ExtensionResourcePriceList{}
|
||||
totalResourcePrice := make(map[corev1.ResourceName]meteringv1.ResourcePriceAndUsed, 0)
|
||||
err := r.List(ctx, &extensionResourcesPriceList)
|
||||
if err != nil {
|
||||
return totalResourcePrice, client.IgnoreNotFound(err)
|
||||
}
|
||||
for _, extensionResourcesPrice := range extensionResourcesPriceList.Items {
|
||||
for k, v := range extensionResourcesPrice.Spec.Resources {
|
||||
totalResourcePrice[k] = meteringv1.ResourcePriceAndUsed{ResourcePrice: v, Used: &resource.Quantity{}}
|
||||
}
|
||||
}
|
||||
return totalResourcePrice, nil
|
||||
}
|
||||
|
||||
func (r *MeteringReconcile) createAccountBalance(ctx context.Context, owner string, amount int64, seqID int64, resourceMsgs interface{}) error {
|
||||
if amount == 0 {
|
||||
func (r *MeteringReconcile) createAccountBalance(ctx context.Context, metering meteringv1.Metering, totalAmount int64) error {
|
||||
if totalAmount == 0 {
|
||||
return nil
|
||||
} else if amount < 0 {
|
||||
} else if totalAmount < 0 {
|
||||
return fmt.Errorf("deduction amount is <0")
|
||||
}
|
||||
|
||||
accountBalance := accountv1.AccountBalance{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: fmt.Sprintf("%s-%s-%v", accountv1.AccountBalancePrefix, owner, seqID),
|
||||
Namespace: r.MeteringSystemNameSpace,
|
||||
Name: fmt.Sprintf("%s-%s-%v", accountv1.AccountBalancePrefix, metering.Spec.Owner, metering.Status.SeqID),
|
||||
Namespace: r.MeteringSystemNamespace,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -390,18 +308,22 @@ func (r *MeteringReconcile) createAccountBalance(ctx context.Context, owner stri
|
||||
if err := r.Get(ctx, types.NamespacedName{Name: accountBalance.Name, Namespace: accountBalance.Namespace}, &accountBalance); err == nil {
|
||||
return fmt.Errorf("accountbalancnce have existed,name:%v", accountBalance.Name)
|
||||
} else if client.IgnoreNotFound(err) == nil {
|
||||
accountBalance.Spec.Owner = owner
|
||||
accountBalance.Spec.Owner = metering.Spec.Owner
|
||||
accountBalance.Spec.Timestamp = time.Now().Unix()
|
||||
accountBalance.Spec.Amount = amount
|
||||
resourceMsgsjson, err := json.Marshal(resourceMsgs)
|
||||
if err != nil {
|
||||
accountBalance.Spec.Amount = totalAmount
|
||||
if metering.Spec.Resources != nil {
|
||||
for resourceName, resourceInfo := range metering.Spec.Resources {
|
||||
resourceInfo.ResourceName = string(resourceName)
|
||||
accountBalance.Spec.ResourceInfoList = append(accountBalance.Spec.ResourceInfoList, resourceInfo)
|
||||
}
|
||||
}
|
||||
if err := r.Create(ctx, &accountBalance); err != nil {
|
||||
return err
|
||||
}
|
||||
accountBalance.Spec.Details = string(resourceMsgsjson)
|
||||
return r.Create(ctx, &accountBalance)
|
||||
} else if err != nil {
|
||||
return err
|
||||
}
|
||||
r.Logger.Info("create accountBalance", "name", accountBalance.Name, "accountBalance.spec", accountBalance.Spec, "metering.spec.Resource", metering.Spec.Resources)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -412,9 +334,9 @@ func (r *MeteringReconcile) SetupWithManager(mgr ctrl.Manager) error {
|
||||
r.Logger.V(1).Info("reconcile controller metering")
|
||||
|
||||
// get env METERING_SYSTEM_NAMESPACE and METERING_INTERVAL
|
||||
r.MeteringSystemNameSpace = os.Getenv(meteringv1.METERINGNAMESPACEENV)
|
||||
r.MeteringSystemNamespace = os.Getenv(meteringv1.METERINGNAMESPACEENV)
|
||||
if os.Getenv(meteringv1.METERINGNAMESPACEENV) == "" {
|
||||
r.MeteringSystemNameSpace = meteringv1.DEFAULTMETERINGNAMESPACE
|
||||
r.MeteringSystemNamespace = meteringv1.DEFAULTMETERINGNAMESPACE
|
||||
}
|
||||
|
||||
timeInterval := os.Getenv("METERING_INTERVAL")
|
||||
@@ -426,12 +348,11 @@ func (r *MeteringReconcile) SetupWithManager(mgr ctrl.Manager) error {
|
||||
if r.MeteringInterval == 0 {
|
||||
r.MeteringInterval = DefaultIntervalInt()
|
||||
}
|
||||
r.Logger.Info("metering env", meteringv1.METERINGNAMESPACEENV, r.MeteringSystemNameSpace, "timeinterval:", r.MeteringInterval, "envtimeinterval", os.Getenv("METERING_INTERVAL"))
|
||||
r.Logger.Info("metering env", meteringv1.METERINGNAMESPACEENV, r.MeteringSystemNamespace, "timeinterval:", r.MeteringInterval, "envtimeinterval", os.Getenv("METERING_INTERVAL"))
|
||||
return ctrl.NewControllerManagedBy(mgr).
|
||||
For(&meteringv1.Metering{}).
|
||||
Watches(&source.Kind{Type: &corev1.Namespace{}}, &handler.EnqueueRequestForObject{}).
|
||||
Watches(&source.Kind{Type: &meteringv1.ExtensionResourcePrice{}}, &handler.EnqueueRequestForObject{}).
|
||||
Watches(&source.Kind{Type: &meteringv1.Resource{}}, &handler.EnqueueRequestForObject{}).
|
||||
Watches(&source.Kind{Type: &meteringcommonv1.Resource{}}, &handler.EnqueueRequestForObject{}).
|
||||
Complete(r)
|
||||
}
|
||||
|
||||
|
||||
@@ -19,11 +19,19 @@ package controllers
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/labring/sealos/pkg/metering"
|
||||
|
||||
"sigs.k8s.io/controller-runtime/pkg/builder"
|
||||
"sigs.k8s.io/controller-runtime/pkg/predicate"
|
||||
|
||||
meteringcommonv1 "github.com/labring/sealos/controllers/common/metering/api/v1"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
userv1 "github.com/labring/sealos/controllers/user/api/v1"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@@ -37,18 +45,20 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
)
|
||||
|
||||
var _ metering.ResourceControllerInterface = &PodResourceReconciler{}
|
||||
|
||||
// PodResourceReconciler reconciles a PodResource object
|
||||
type PodResourceReconciler struct {
|
||||
client.Client
|
||||
Scheme *runtime.Scheme
|
||||
logr.Logger
|
||||
MeteringSystemNameSpace string
|
||||
MeteringSystemNamespace string
|
||||
}
|
||||
|
||||
//+kubebuilder:rbac:groups=metering.sealos.io,resources=podresources,verbs=get;list;watch;create;update;patch;delete
|
||||
//+kubebuilder:rbac:groups=metering.sealos.io,resources=podresources/status,verbs=get;update;patch
|
||||
//+kubebuilder:rbac:groups=metering.sealos.io,resources=podresources/finalizers,verbs=update
|
||||
//+kubebuilder:rbac:groups=metering.sealos.io,resources=resources,verbs=get;list;watch;create;update;patch;delete
|
||||
//+kubebuilder:rbac:groups=metering.common.sealos.io,resources=resources,verbs=get;list;watch;create;update;patch;delete
|
||||
//+kubebuilder:rbac:groups=core,resources=namespaces,verbs=get;list;watch;create;update;patch;delete
|
||||
//+kubebuilder:rbac:groups=core,resources=pods,verbs=get;list;watch;create;update;patch;delete
|
||||
|
||||
@@ -77,10 +87,10 @@ func (r *PodResourceReconciler) Reconcile(ctx context.Context, req ctrl.Request)
|
||||
// CreateOrUpdateExtensionResourcesPrice need to create a ExtensionResourcesPrice to make metering-quota know this resource
|
||||
func (r *PodResourceReconciler) CreateOrUpdateExtensionResourcesPrice(ctx context.Context, obj client.Object) error {
|
||||
podController := obj.(*meteringv1.PodResource)
|
||||
extensionResourcesPrice := &meteringv1.ExtensionResourcePrice{
|
||||
extensionResourcesPrice := &meteringcommonv1.ExtensionResourcePrice{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: r.MeteringSystemNameSpace,
|
||||
Name: meteringv1.ExtensionResourcePricePrefix + meteringv1.PodResourcePricePrefix,
|
||||
Namespace: r.MeteringSystemNamespace,
|
||||
Name: meteringcommonv1.ExtensionResourcePricePrefix + meteringv1.PodResourcePricePrefix,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -89,7 +99,7 @@ func (r *PodResourceReconciler) CreateOrUpdateExtensionResourcesPrice(ctx contex
|
||||
extensionResourcesPrice.Spec.Resources = podController.Spec.Resources
|
||||
extensionResourcesPrice.Spec.ResourceName = podController.Spec.ResourceName
|
||||
//extensionResourcesPrice.SetPrice(apiVersion, kind, podController.Name)
|
||||
return controllerutil.SetControllerReference(podController, extensionResourcesPrice, r.Scheme)
|
||||
return nil
|
||||
}); err != nil {
|
||||
return fmt.Errorf("sync ExtensionResourcesPrice failed: %v", err)
|
||||
}
|
||||
@@ -104,20 +114,30 @@ func (r *PodResourceReconciler) UpdateResourceUsed(ctx context.Context, obj clie
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, pod := range podList.Items {
|
||||
resourceInfos := make(map[v1.ResourceName]meteringcommonv1.ResourceInfo, 0)
|
||||
if !r.checkPodStatus(pod) || !r.checkPodNamespace(pod) {
|
||||
continue
|
||||
}
|
||||
for _, con := range pod.Spec.Containers {
|
||||
for resourceName := range podController.Spec.Resources {
|
||||
var resourceQuantity resource.Quantity
|
||||
var ok bool
|
||||
if resourceQuantity, ok = r.checkResourceExist(resourceName, con); !ok {
|
||||
continue
|
||||
}
|
||||
if err := r.syncResource(ctx, pod, con.Name, resourceName, &resourceQuantity, *podController); err != nil {
|
||||
r.Logger.Error(err, "syncResource failed")
|
||||
if resourceQuantity, ok := r.checkResourceExist(resourceName, con); ok {
|
||||
if _, ok := resourceInfos[resourceName]; !ok {
|
||||
resourceInfos[resourceName] = meteringcommonv1.ResourceInfo{
|
||||
Used: &resourceQuantity,
|
||||
Timestamp: time.Now().Unix(),
|
||||
Namespace: pod.Namespace,
|
||||
Cost: int64(float64(resourceQuantity.MilliValue()*podController.Spec.Resources[resourceName].Price) / float64(podController.Spec.Resources[resourceName].Unit.MilliValue())),
|
||||
}
|
||||
} else {
|
||||
resourceInfos[resourceName] = meteringcommonv1.ResourceInfo{
|
||||
Cost: resourceInfos[resourceName].Cost + int64(float64(resourceQuantity.MilliValue()*podController.Spec.Resources[resourceName].Price)/float64(podController.Spec.Resources[resourceName].Unit.MilliValue())),
|
||||
Timestamp: time.Now().Unix(),
|
||||
Namespace: pod.Namespace,
|
||||
Used: resourceInfos[resourceName].Used,
|
||||
}
|
||||
resourceInfos[resourceName].Used.Add(resourceQuantity)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -129,8 +149,25 @@ func (r *PodResourceReconciler) UpdateResourceUsed(ctx context.Context, obj clie
|
||||
}
|
||||
//r.Logger.V(1).Info("resourceQuota", "resourceQuota", resourceQuota)
|
||||
storage := resourceQuota.Status.Used.Name("requests.storage", resource.BinarySI)
|
||||
if err = r.syncResource(ctx, pod, "", "storage", storage, *podController); err != nil {
|
||||
r.Logger.Error(err, "syncMeteringQuota failed")
|
||||
resourceName := v1.ResourceName("storage")
|
||||
if _, ok := resourceInfos[resourceName]; !ok {
|
||||
resourceInfos[resourceName] = meteringcommonv1.ResourceInfo{
|
||||
Used: storage,
|
||||
Timestamp: time.Now().Unix(),
|
||||
Namespace: pod.Namespace,
|
||||
Cost: int64(math.Ceil(float64(storage.MilliValue()*podController.Spec.Resources[resourceName].Price) / float64(podController.Spec.Resources[resourceName].Unit.MilliValue()))),
|
||||
}
|
||||
} else {
|
||||
resourceInfos[resourceName] = meteringcommonv1.ResourceInfo{
|
||||
Cost: resourceInfos[resourceName].Cost + int64(math.Ceil(float64(storage.MilliValue()*podController.Spec.Resources[resourceName].Price)/float64(podController.Spec.Resources[resourceName].Unit.MilliValue()))),
|
||||
Timestamp: time.Now().Unix(),
|
||||
Namespace: pod.Namespace,
|
||||
Used: resourceInfos[resourceName].Used,
|
||||
}
|
||||
resourceInfos[resourceName].Used.Add(*storage)
|
||||
}
|
||||
if err := r.syncResource(ctx, pod, resourceInfos, *podController); err != nil {
|
||||
r.Logger.Error(err, "syncResource failed")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,36 +200,27 @@ func (r *PodResourceReconciler) checkPodNamespace(pod v1.Pod) bool {
|
||||
r.Logger.Error(err, "get namespace failed", "pod NS", pod.Namespace)
|
||||
return false
|
||||
}
|
||||
if _, ok := ns.Annotations[userv1.UserAnnotationOwnerKey]; !ok {
|
||||
if _, ok := ns.Annotations[meteringv1.UserAnnotationOwnerKey]; !ok {
|
||||
r.Logger.Info("pod namespace is not user namespace", "pod name", pod.Name, "pod namespace", pod.Namespace)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (r *PodResourceReconciler) syncResource(ctx context.Context, pod v1.Pod, containerName string, resourceName v1.ResourceName, Used *resource.Quantity, podController meteringv1.PodResource) error {
|
||||
podResource := meteringv1.Resource{
|
||||
func (r *PodResourceReconciler) syncResource(ctx context.Context, pod v1.Pod, ResourceCR map[v1.ResourceName]meteringcommonv1.ResourceInfo, podController meteringv1.PodResource) error {
|
||||
Resource := meteringcommonv1.Resource{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: GetResourceName(pod.Namespace, pod.Name, containerName, resourceName, podController.Status.SeqID),
|
||||
Namespace: r.MeteringSystemNameSpace,
|
||||
Name: GetResourceName(pod.Namespace, pod.Name, podController.Status.SeqID),
|
||||
Namespace: r.MeteringSystemNamespace,
|
||||
},
|
||||
}
|
||||
|
||||
if _, err := controllerutil.CreateOrUpdate(ctx, r.Client, &podResource, func() error {
|
||||
if podResource.Spec.Resources == nil {
|
||||
podResource.Spec.Resources = make(map[v1.ResourceName]meteringv1.ResourceInfo)
|
||||
}
|
||||
podResource.Spec.Resources[resourceName] = meteringv1.ResourceInfo{
|
||||
Used: Used,
|
||||
TimeStamp: time.Now().Unix(),
|
||||
NameSpace: pod.Namespace,
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
if err := r.Get(ctx, types.NamespacedName{Namespace: Resource.Namespace, Name: Resource.Name}, &Resource); err == nil {
|
||||
return fmt.Errorf("resource already exist resource name:%v", Resource.Name)
|
||||
}
|
||||
|
||||
return nil
|
||||
Resource.Spec.Resources = ResourceCR
|
||||
r.Logger.Info("want to create resource", "resource name", GetResourceName(pod.Namespace, pod.Name, podController.Status.SeqID), "resource info", Resource.Spec.Resources)
|
||||
return r.Create(ctx, &Resource)
|
||||
}
|
||||
|
||||
func (r *PodResourceReconciler) checkResourceExist(resourceName v1.ResourceName, container v1.Container) (resource.Quantity, bool) {
|
||||
@@ -207,12 +235,8 @@ func (r *PodResourceReconciler) checkResourceExist(resourceName v1.ResourceName,
|
||||
return resource.Quantity{}, false
|
||||
}
|
||||
|
||||
func GetResourceName(namespaceName, podName string, containerName string, resourceName v1.ResourceName, seqID int64) string {
|
||||
if containerName == "" {
|
||||
return fmt.Sprintf("%s-%s-%s-%s-%v", namespaceName, meteringv1.PodResourcePricePrefix, podName, resourceName, seqID)
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s-%s-%s-%s-%s-%v", namespaceName, meteringv1.PodResourcePricePrefix, podName, containerName, resourceName, seqID)
|
||||
func GetResourceName(namespaceName, podName string, seqID int64) string {
|
||||
return fmt.Sprintf("%s-%s-%s-%v", namespaceName, meteringv1.PodResourcePricePrefix, podName, seqID)
|
||||
}
|
||||
|
||||
// SetupWithManager sets up the controller with the Manager.
|
||||
@@ -220,11 +244,11 @@ func (r *PodResourceReconciler) SetupWithManager(mgr ctrl.Manager) error {
|
||||
const controllerName = "podResource-controller"
|
||||
r.Logger = ctrl.Log.WithName(controllerName)
|
||||
r.Logger.V(1).Info("reconcile podResource-controller")
|
||||
r.MeteringSystemNameSpace = os.Getenv(meteringv1.METERINGNAMESPACEENV)
|
||||
r.MeteringSystemNamespace = os.Getenv(meteringv1.METERINGNAMESPACEENV)
|
||||
if os.Getenv(meteringv1.METERINGNAMESPACEENV) == "" {
|
||||
r.MeteringSystemNameSpace = meteringv1.DEFAULTMETERINGNAMESPACE
|
||||
r.MeteringSystemNamespace = meteringv1.DEFAULTMETERINGNAMESPACE
|
||||
}
|
||||
return ctrl.NewControllerManagedBy(mgr).
|
||||
For(&meteringv1.PodResource{}).
|
||||
For(&meteringv1.PodResource{}, builder.WithPredicates(predicate.Or(predicate.GenerationChangedPredicate{}))).
|
||||
Complete(r)
|
||||
}
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
/*
|
||||
Copyright 2022.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"k8s.io/client-go/rest"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/envtest"
|
||||
"sigs.k8s.io/controller-runtime/pkg/envtest/printer"
|
||||
logf "sigs.k8s.io/controller-runtime/pkg/log"
|
||||
"sigs.k8s.io/controller-runtime/pkg/log/zap"
|
||||
|
||||
meteringv1 "github.com/labring/sealos/controllers/metering/api/v1"
|
||||
//+kubebuilder:scaffold:imports
|
||||
)
|
||||
|
||||
// These tests use Ginkgo (BDD-style Go testing framework). Refer to
|
||||
// http://onsi.github.io/ginkgo/ to learn more about Ginkgo.
|
||||
|
||||
var cfg *rest.Config
|
||||
var k8sClient client.Client
|
||||
var testEnv *envtest.Environment
|
||||
|
||||
func TestAPIs(t *testing.T) {
|
||||
RegisterFailHandler(Fail)
|
||||
|
||||
RunSpecsWithDefaultAndCustomReporters(t,
|
||||
"Controller Suite",
|
||||
[]Reporter{printer.NewlineReporter{}})
|
||||
}
|
||||
|
||||
var _ = BeforeSuite(func() {
|
||||
logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true)))
|
||||
|
||||
By("bootstrapping test environment")
|
||||
testEnv = &envtest.Environment{
|
||||
CRDDirectoryPaths: []string{filepath.Join("..", "config", "crd", "bases")},
|
||||
ErrorIfCRDPathMissing: true,
|
||||
}
|
||||
|
||||
var err error
|
||||
// cfg is defined in this file globally.
|
||||
cfg, err = testEnv.Start()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(cfg).NotTo(BeNil())
|
||||
|
||||
err = meteringv1.AddToScheme(scheme.Scheme)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
//+kubebuilder:scaffold:scheme
|
||||
|
||||
k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(k8sClient).NotTo(BeNil())
|
||||
|
||||
}, 60)
|
||||
|
||||
var _ = AfterSuite(func() {
|
||||
By("tearing down the test environment")
|
||||
err := testEnv.Stop()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
@@ -7,81 +7,6 @@ metadata:
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.8.0
|
||||
creationTimestamp: null
|
||||
name: extensionresourceprices.metering.sealos.io
|
||||
spec:
|
||||
group: metering.sealos.io
|
||||
names:
|
||||
kind: ExtensionResourcePrice
|
||||
listKind: ExtensionResourcePriceList
|
||||
plural: extensionresourceprices
|
||||
singular: extensionresourceprice
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- name: v1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: ExtensionResourcePrice is the Schema for the extensionresourceprices
|
||||
API
|
||||
properties:
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation
|
||||
of an object. Servers should convert recognized schemas to the latest
|
||||
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this
|
||||
object represents. Servers may infer this from the endpoint the client
|
||||
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: ExtensionResourcePriceSpec defines the desired state of ExtensionResourcePrice
|
||||
properties:
|
||||
resourceName:
|
||||
type: string
|
||||
resources:
|
||||
additionalProperties:
|
||||
properties:
|
||||
describe:
|
||||
type: string
|
||||
price:
|
||||
format: int64
|
||||
type: integer
|
||||
unit:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
|
||||
x-kubernetes-int-or-string: true
|
||||
required:
|
||||
- price
|
||||
- unit
|
||||
type: object
|
||||
type: object
|
||||
type: object
|
||||
status:
|
||||
description: ExtensionResourcePriceStatus defines the observed state of
|
||||
ExtensionResourcePrice
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
plural: ""
|
||||
conditions: []
|
||||
storedVersions: []
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.8.0
|
||||
@@ -134,26 +59,22 @@ spec:
|
||||
resources:
|
||||
additionalProperties:
|
||||
properties:
|
||||
describe:
|
||||
type: string
|
||||
price:
|
||||
cost:
|
||||
format: int64
|
||||
type: integer
|
||||
namespace:
|
||||
type: string
|
||||
resourceName:
|
||||
type: string
|
||||
time:
|
||||
format: int64
|
||||
type: integer
|
||||
unit:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
|
||||
x-kubernetes-int-or-string: true
|
||||
used:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
|
||||
x-kubernetes-int-or-string: true
|
||||
required:
|
||||
- price
|
||||
- unit
|
||||
type: object
|
||||
type: object
|
||||
timeInterval:
|
||||
@@ -255,9 +176,7 @@ spec:
|
||||
description: PodResourceSpec defines the desired state of PodResource
|
||||
properties:
|
||||
interval:
|
||||
default: 50
|
||||
description: update used resources every Interval minutes
|
||||
minimum: 1
|
||||
type: integer
|
||||
resourceName:
|
||||
type: string
|
||||
@@ -303,77 +222,6 @@ status:
|
||||
conditions: []
|
||||
storedVersions: []
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.8.0
|
||||
creationTimestamp: null
|
||||
name: resources.metering.sealos.io
|
||||
spec:
|
||||
group: metering.sealos.io
|
||||
names:
|
||||
kind: Resource
|
||||
listKind: ResourceList
|
||||
plural: resources
|
||||
singular: resource
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- name: v1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: Resource is the Schema for the resources API
|
||||
properties:
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation
|
||||
of an object. Servers should convert recognized schemas to the latest
|
||||
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this
|
||||
object represents. Servers may infer this from the endpoint the client
|
||||
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: ResourceSpec defines the desired state of Resource
|
||||
properties:
|
||||
resources:
|
||||
additionalProperties:
|
||||
properties:
|
||||
namespace:
|
||||
type: string
|
||||
time:
|
||||
format: int64
|
||||
type: integer
|
||||
used:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
|
||||
x-kubernetes-int-or-string: true
|
||||
type: object
|
||||
type: object
|
||||
type: object
|
||||
status:
|
||||
description: ResourceStatus defines the observed state of Resource
|
||||
properties:
|
||||
status:
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
plural: ""
|
||||
conditions: []
|
||||
storedVersions: []
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
@@ -473,19 +321,7 @@ rules:
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- infra.sealos.io
|
||||
resources:
|
||||
- infras
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- metering.sealos.io
|
||||
- metering.common.sealos.io
|
||||
resources:
|
||||
- extensionresourceprices
|
||||
verbs:
|
||||
@@ -496,6 +332,26 @@ rules:
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- metering.common.sealos.io
|
||||
resources:
|
||||
- resources
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- metering.common.sealos.io
|
||||
resources:
|
||||
- resources/status
|
||||
verbs:
|
||||
- get
|
||||
- patch
|
||||
- update
|
||||
- apiGroups:
|
||||
- metering.sealos.io
|
||||
resources:
|
||||
@@ -548,26 +404,6 @@ rules:
|
||||
- get
|
||||
- patch
|
||||
- update
|
||||
- apiGroups:
|
||||
- metering.sealos.io
|
||||
resources:
|
||||
- resources
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- metering.sealos.io
|
||||
resources:
|
||||
- resources/status
|
||||
verbs:
|
||||
- get
|
||||
- patch
|
||||
- update
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
|
||||
+16
-33
@@ -2,28 +2,22 @@ module github.com/labring/sealos/controllers/metering
|
||||
|
||||
go 1.20
|
||||
|
||||
replace (
|
||||
github.com/labring/sealos => ../../
|
||||
github.com/labring/sealos/controllers/account => ../../controllers/account
|
||||
github.com/labring/sealos/controllers/common => ../../controllers/common
|
||||
github.com/labring/sealos/controllers/user => ../../controllers/user
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/go-logr/logr v1.2.3
|
||||
github.com/labring/sealos/controllers/account v0.0.0
|
||||
github.com/labring/sealos/controllers/infra v0.0.0
|
||||
github.com/labring/sealos/controllers/user v0.0.0
|
||||
github.com/onsi/ginkgo v1.16.5
|
||||
github.com/onsi/gomega v1.23.0
|
||||
k8s.io/api v0.25.6
|
||||
k8s.io/apimachinery v0.25.6
|
||||
k8s.io/client-go v0.25.6
|
||||
k8s.io/api v0.26.1
|
||||
k8s.io/apimachinery v0.26.1
|
||||
k8s.io/client-go v0.26.1
|
||||
sigs.k8s.io/controller-runtime v0.13.0
|
||||
)
|
||||
|
||||
require (
|
||||
cloud.google.com/go/compute v1.14.0 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
|
||||
github.com/Azure/go-autorest/autorest v0.11.28 // indirect
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.21 // indirect
|
||||
github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect
|
||||
github.com/Azure/go-autorest/logger v0.2.1 // indirect
|
||||
github.com/Azure/go-autorest/tracing v0.6.0 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
@@ -35,7 +29,6 @@ require (
|
||||
github.com/go-openapi/jsonreference v0.20.0 // indirect
|
||||
github.com/go-openapi/swag v0.22.0 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.4.2 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/google/gnostic v0.6.9 // indirect
|
||||
@@ -46,50 +39,40 @@ require (
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/kr/pretty v0.3.0 // indirect
|
||||
github.com/labring/sealos v0.0.0 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/nxadm/tail v1.4.8 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/prometheus/client_golang v1.14.0 // indirect
|
||||
github.com/prometheus/client_model v0.3.0 // indirect
|
||||
github.com/prometheus/common v0.39.0 // indirect
|
||||
github.com/prometheus/procfs v0.9.0 // indirect
|
||||
github.com/rogpeppe/go-internal v1.9.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/stretchr/testify v1.8.1 // indirect
|
||||
go.uber.org/atomic v1.10.0 // indirect
|
||||
go.uber.org/multierr v1.9.0 // indirect
|
||||
go.uber.org/zap v1.24.0 // indirect
|
||||
golang.org/x/crypto v0.1.0 // indirect
|
||||
golang.org/x/net v0.5.0 // indirect
|
||||
golang.org/x/oauth2 v0.3.0 // indirect
|
||||
golang.org/x/sys v0.4.0 // indirect
|
||||
golang.org/x/term v0.4.0 // indirect
|
||||
golang.org/x/text v0.6.0 // indirect
|
||||
golang.org/x/time v0.1.0 // indirect
|
||||
golang.org/x/time v0.3.0 // indirect
|
||||
gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/protobuf v1.28.1 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
k8s.io/apiextensions-apiserver v0.25.6 // indirect
|
||||
k8s.io/component-base v0.25.6 // indirect
|
||||
k8s.io/apiextensions-apiserver v0.26.1 // indirect
|
||||
k8s.io/component-base v0.26.1 // indirect
|
||||
k8s.io/klog/v2 v2.80.1 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 // indirect
|
||||
k8s.io/utils v0.0.0-20221107191617-1a15be271d1d // indirect
|
||||
k8s.io/utils v0.0.0-20221128185143-99ec85e7a448 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
|
||||
sigs.k8s.io/yaml v1.3.0 // indirect
|
||||
)
|
||||
|
||||
replace (
|
||||
github.com/labring/sealos => ../../
|
||||
github.com/labring/sealos/controllers/account => ../../controllers/account
|
||||
github.com/labring/sealos/controllers/infra => ../../controllers/infra
|
||||
github.com/labring/sealos/controllers/user => ../../controllers/user
|
||||
)
|
||||
|
||||
+24
-78
@@ -1,27 +1,6 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go/compute v1.14.0 h1:hfm2+FfxVmnRlh6LpB7cg1ZNU+5edAHmW679JePztk0=
|
||||
cloud.google.com/go/compute v1.14.0/go.mod h1:YfLtxrj9sU4Yxv+sXzZkyPjEyPBZfXHUvjxega5vAdo=
|
||||
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
|
||||
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs=
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
|
||||
github.com/Azure/go-autorest/autorest v0.11.28 h1:ndAExarwr5Y+GaHE6VCaY1kyS/HwwGGyuimVhWsHOEM=
|
||||
github.com/Azure/go-autorest/autorest v0.11.28/go.mod h1:MrkzG3Y3AH668QyF9KRk5neJnGgmhQ6krbhR8Q5eMvA=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.18/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.21 h1:jjQnVFXPfekaqb8vIsv2G1lxshoW+oGv4MDlhRtnYZk=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.21/go.mod h1:zua7mBUaCc5YnSLKYgGJR/w5ePdMDA6H56upLsHzA9U=
|
||||
github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw=
|
||||
github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.4.2 h1:PGN4EDXnuQbojHbU0UWoNvmu9AGVwYHG9/fkDYhtAfw=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.4.2/go.mod h1:Vy7OitM9Kei0i1Oj+LvyAWMXJHeKH1MVlzFugfVrmyU=
|
||||
github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg=
|
||||
github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
|
||||
github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo=
|
||||
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
|
||||
@@ -55,8 +34,6 @@ github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH
|
||||
github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww=
|
||||
github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4=
|
||||
github.com/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM0rVwpMwimd3F3N0=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
||||
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
@@ -74,13 +51,8 @@ github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXym
|
||||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-openapi/swag v0.22.0 h1:1VXunYCNgapcSzFtcY+eBmrwESlYCnFJZahQRgTRoo8=
|
||||
github.com/go-openapi/swag v0.22.0/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
|
||||
github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
|
||||
github.com/golang-jwt/jwt/v4 v4.4.2 h1:rcc4lwaZgFMCZ5jxF9ABolDcIHdBytAFgqFPbSJQAYs=
|
||||
github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
@@ -118,7 +90,6 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk=
|
||||
github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg=
|
||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
@@ -149,18 +120,9 @@ 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/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
||||
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
|
||||
github.com/onsi/ginkgo/v2 v2.4.0 h1:+Ig9nvqgS5OBSACXNk15PLdp0U9XPYROt9CFzVdFGIs=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/onsi/gomega v1.23.0 h1:/oxKu9c2HVap+F3PfKort2Hw5DEU+HGlW8n+tguWsys=
|
||||
github.com/onsi/gomega v1.23.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg=
|
||||
github.com/onsi/ginkgo/v2 v2.6.0 h1:9t9b9vRUbFq3C4qKFCGkVuq/fIHji802N1nrtkh1mNc=
|
||||
github.com/onsi/gomega v1.24.1 h1:KORJXNNTzJXzu4ScJWssJfJMnJ+2QJqhoQSRwNlze9E=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
@@ -178,16 +140,22 @@ github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB
|
||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
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/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
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.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.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=
|
||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
||||
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
||||
@@ -208,10 +176,6 @@ go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
|
||||
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-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU=
|
||||
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
@@ -221,7 +185,6 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
@@ -229,13 +192,10 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
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-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
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.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw=
|
||||
golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
@@ -249,20 +209,14 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
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-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/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-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18=
|
||||
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
@@ -276,8 +230,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k=
|
||||
golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/time v0.1.0 h1:xYY+Bajn2a7VBmTM5GikTmnK8ZuX8YgnQCqZpbBNtmA=
|
||||
golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
|
||||
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
@@ -286,7 +240,6 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn
|
||||
golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
@@ -329,18 +282,11 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0/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=
|
||||
@@ -351,24 +297,24 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
k8s.io/api v0.25.6 h1:LwDY2H6kD/3R8TekJYYaJWOdekNdXDO44eVpX6sNtJA=
|
||||
k8s.io/api v0.25.6/go.mod h1:bVp01KUcl8VUHFBTJMOknWNo7XvR0cMbeTTuFg1zCUs=
|
||||
k8s.io/apiextensions-apiserver v0.25.6 h1:MwdaCpHtGVSM5SiA6Hm4g2w5voMNiPCwBjOqz9YTlrg=
|
||||
k8s.io/apiextensions-apiserver v0.25.6/go.mod h1:aXw8Xmhf6/gfGx3y0xkj8o8evTZbfOFqZeWIigg4XsE=
|
||||
k8s.io/apimachinery v0.25.6 h1:r6KIF2AHwLqFfZ0LcOA3I11SF62YZK83dxj1fn14NOQ=
|
||||
k8s.io/apimachinery v0.25.6/go.mod h1:1S2i1QHkmxc8+EZCIxe/fX5hpldVXk4gvnJInMEb8D4=
|
||||
k8s.io/client-go v0.25.6 h1:CHxACHi0DijmlYyUR7ooZoXnD5P8jYLgBHcxp775x/U=
|
||||
k8s.io/client-go v0.25.6/go.mod h1:s9mMAGFYiH3Z66j7BESzu0GEradT9GQ2LjFf/YRrnyc=
|
||||
k8s.io/component-base v0.25.6 h1:v3ci6FbXFcxpjyQJaaLq0MgzT3vyFzwUDWtO+KRv9Bk=
|
||||
k8s.io/component-base v0.25.6/go.mod h1:k7DfcfJ8cOI6A2xTCfU5LxsnXV+lWw1ME8cRCHzIh6o=
|
||||
k8s.io/api v0.26.1 h1:f+SWYiPd/GsiWwVRz+NbFyCgvv75Pk9NK6dlkZgpCRQ=
|
||||
k8s.io/api v0.26.1/go.mod h1:xd/GBNgR0f707+ATNyPmQ1oyKSgndzXij81FzWGsejg=
|
||||
k8s.io/apiextensions-apiserver v0.26.1 h1:cB8h1SRk6e/+i3NOrQgSFij1B2S0Y0wDoNl66bn8RMI=
|
||||
k8s.io/apiextensions-apiserver v0.26.1/go.mod h1:AptjOSXDGuE0JICx/Em15PaoO7buLwTs0dGleIHixSM=
|
||||
k8s.io/apimachinery v0.26.1 h1:8EZ/eGJL+hY/MYCNwhmDzVqq2lPl3N3Bo8rvweJwXUQ=
|
||||
k8s.io/apimachinery v0.26.1/go.mod h1:tnPmbONNJ7ByJNz9+n9kMjNP8ON+1qoAIIC70lztu74=
|
||||
k8s.io/client-go v0.26.1 h1:87CXzYJnAMGaa/IDDfRdhTzxk/wzGZ+/HUQpqgVSZXU=
|
||||
k8s.io/client-go v0.26.1/go.mod h1:IWNSglg+rQ3OcvDkhY6+QLeasV4OYHDjdqeWkDQZwGE=
|
||||
k8s.io/component-base v0.26.1 h1:4ahudpeQXHZL5kko+iDHqLj/FSGAEUnSVO0EBbgDd+4=
|
||||
k8s.io/component-base v0.26.1/go.mod h1:VHrLR0b58oC035w6YQiBSbtsf0ThuSwXP+p5dD/kAWU=
|
||||
k8s.io/klog/v2 v2.80.1 h1:atnLQ121W371wYYFawwYx1aEY2eUfs4l3J72wtgAwV4=
|
||||
k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
|
||||
k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 h1:+70TFaan3hfJzs+7VK2o+OGxg8HsuBr/5f6tVAjDu6E=
|
||||
k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280/go.mod h1:+Axhij7bCpeqhklhUTe3xmOn6bWxolyZEeyaFpjGtl4=
|
||||
k8s.io/utils v0.0.0-20221107191617-1a15be271d1d h1:0Smp/HP1OH4Rvhe+4B8nWGERtlqAGSftbSbbmm45oFs=
|
||||
k8s.io/utils v0.0.0-20221107191617-1a15be271d1d/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||
sigs.k8s.io/controller-runtime v0.13.0 h1:iqa5RNciy7ADWnIc8QxCbOX5FEKVR3uxVxKHRMc2WIQ=
|
||||
sigs.k8s.io/controller-runtime v0.13.0/go.mod h1:Zbz+el8Yg31jubvAEyglRZGdLAjplZl+PgtYNI6WNTI=
|
||||
k8s.io/utils v0.0.0-20221128185143-99ec85e7a448 h1:KTgPnR10d5zhztWptI952TNtt/4u5h3IzDXkdIMuo2Y=
|
||||
k8s.io/utils v0.0.0-20221128185143-99ec85e7a448/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||
sigs.k8s.io/controller-runtime v0.14.4 h1:Kd/Qgx5pd2XUL08eOV2vwIq3L9GhIbJ5Nxengbd4/0M=
|
||||
sigs.k8s.io/controller-runtime v0.14.4/go.mod h1:WqIdsAY6JBsjfc/CqO0CORmNtoCtE4S6qbPc9s68h+0=
|
||||
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k=
|
||||
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE=
|
||||
|
||||
@@ -19,12 +19,10 @@ package main
|
||||
import (
|
||||
"flag"
|
||||
|
||||
meteringcommonv1 "github.com/labring/sealos/controllers/common/metering/api/v1"
|
||||
|
||||
accountv1 "github.com/labring/sealos/controllers/account/api/v1"
|
||||
|
||||
infrav1 "github.com/labring/sealos/controllers/infra/api/v1"
|
||||
|
||||
userv1 "github.com/labring/sealos/controllers/user/api/v1"
|
||||
|
||||
"github.com/labring/sealos/controllers/metering/controllers"
|
||||
|
||||
"os"
|
||||
@@ -51,9 +49,8 @@ var (
|
||||
|
||||
func init() {
|
||||
utilruntime.Must(clientgoscheme.AddToScheme(scheme))
|
||||
utilruntime.Must(infrav1.AddToScheme(scheme))
|
||||
utilruntime.Must(meteringv1.AddToScheme(scheme))
|
||||
utilruntime.Must(userv1.AddToScheme(scheme))
|
||||
utilruntime.Must(meteringcommonv1.AddToScheme(scheme))
|
||||
utilruntime.Must(accountv1.AddToScheme(scheme))
|
||||
//+kubebuilder:scaffold:scheme
|
||||
}
|
||||
@@ -94,6 +91,7 @@ func main() {
|
||||
setupLog.Error(err, "unable to create controller", "controller", "Metering")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if err = (&controllers.PodResourceReconciler{
|
||||
Client: mgr.GetClient(),
|
||||
Scheme: mgr.GetScheme(),
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
meteringv1 "github.com/labring/sealos/controllers/metering/api/v1"
|
||||
meteringcommonv1 "github.com/labring/sealos/controllers/common/metering/api/v1"
|
||||
baseapi "github.com/labring/sealos/test/testdata/api"
|
||||
)
|
||||
|
||||
const ExtensionResourcePriceYaml = `
|
||||
apiVersion: metering.sealos.io/v1
|
||||
apiVersion: metering.common.sealos.io/v1
|
||||
kind: ExtensionResourcePrice
|
||||
metadata:
|
||||
name: ${name}
|
||||
@@ -21,9 +21,9 @@ spec:
|
||||
describe: "cost per cpu per hour(price:100 = 1¥)"
|
||||
`
|
||||
|
||||
func GetExtensionResourcePrice(namespace string, name string) (*meteringv1.ExtensionResourcePrice, error) {
|
||||
gvr := meteringv1.GroupVersion.WithResource("extensionresourceprices")
|
||||
var extensionResourcesPrice meteringv1.ExtensionResourcePrice
|
||||
func GetExtensionResourcePrice(namespace string, name string) (*meteringcommonv1.ExtensionResourcePrice, error) {
|
||||
gvr := meteringcommonv1.GroupVersion.WithResource("extensionresourceprices")
|
||||
var extensionResourcesPrice meteringcommonv1.ExtensionResourcePrice
|
||||
if err := baseapi.GetObject(namespace, name, gvr, &extensionResourcesPrice); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
-65
@@ -1,65 +0,0 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
infrav1 "github.com/labring/sealos/controllers/infra/api/v1"
|
||||
baseapi "github.com/labring/sealos/test/testdata/api"
|
||||
"time"
|
||||
)
|
||||
|
||||
const InfraYaml = `
|
||||
apiVersion: infra.sealos.io/v1
|
||||
kind: Infra
|
||||
metadata:
|
||||
name: ${name}
|
||||
namespace: ${namespace}
|
||||
spec:
|
||||
hosts:
|
||||
- roles: [master]
|
||||
count: 1
|
||||
flavor: t2.medium
|
||||
image: "ami-0d66b970b9f16f1f5"
|
||||
disks:
|
||||
- capacity: 16
|
||||
volumeType: gp3
|
||||
# allowed value is root|data
|
||||
type: "root"
|
||||
|
||||
- roles: [ node ]
|
||||
count: 1
|
||||
flavor: t2.medium
|
||||
image: "ami-0d66b970b9f16f1f5"
|
||||
disks:
|
||||
- capacity: 16
|
||||
volumeType: gp3
|
||||
# allowed value is root|data
|
||||
type: "root"
|
||||
`
|
||||
|
||||
func GetInfra(namespace string, name string) (*infrav1.Infra, error) {
|
||||
gvr := infrav1.GroupVersion.WithResource("infras")
|
||||
var infra infrav1.Infra
|
||||
if err := baseapi.GetObject(namespace, name, gvr, &infra); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &infra, nil
|
||||
}
|
||||
|
||||
func EnsureInfra(namespace string, name string, times int) error {
|
||||
_, err := GetInfra(namespace, name)
|
||||
if err != nil {
|
||||
baseapi.CreateCRD(namespace, name, InfraYaml)
|
||||
}
|
||||
|
||||
for i := 0; i < times; i++ {
|
||||
infra, err := GetInfra(namespace, name)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if infra.Status.Status == infrav1.Running.String() {
|
||||
return nil
|
||||
}
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
return fmt.Errorf("infra time out")
|
||||
}
|
||||
+2
-1
@@ -72,7 +72,8 @@ func EnsureMeteringUsed(namespace string, name string, times int) (*meteringv1.M
|
||||
continue
|
||||
}
|
||||
if _, ok := metering.Spec.Resources["cpu"]; !ok {
|
||||
return nil, fmt.Errorf("metering resource cpu is not found")
|
||||
time.Sleep(time.Second)
|
||||
continue
|
||||
}
|
||||
if metering.Spec.Resources["cpu"].Used.Value() > 0 {
|
||||
return metering, nil
|
||||
|
||||
+14
-8
@@ -20,14 +20,20 @@ spec:
|
||||
resources:
|
||||
cpu:
|
||||
unit: "1"
|
||||
price: 1
|
||||
price: 670
|
||||
describe: "cost per cpu per hour(price:100 = 1¥)"
|
||||
|
||||
memory:
|
||||
unit: "1G"
|
||||
price: 330
|
||||
describe: "cost per gigabyte of storage per hour(price:100 = 1¥)"
|
||||
ephemeral-storage:
|
||||
unit: "1G"
|
||||
price: 21
|
||||
describe: "cost per gigabyte of storage per hour(price:100 = 1¥)"
|
||||
storage:
|
||||
unit: "1G"
|
||||
price: 1
|
||||
price: 21
|
||||
describe: "cost per gigabyte of storage per hour(price:100 = 1¥)"
|
||||
|
||||
`
|
||||
|
||||
func CreatePodController(namespace string, name string) {
|
||||
@@ -76,13 +82,13 @@ spec:
|
||||
image: nginx:1.14.2
|
||||
resources:
|
||||
requests:
|
||||
cpu: 1000m
|
||||
memory: 1Gi
|
||||
cpu: 50m
|
||||
memory: 100Mi
|
||||
ephemeral-storage: 1Gi
|
||||
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 1Gi
|
||||
cpu: 100m
|
||||
memory: 100Mi
|
||||
ephemeral-storage: 1Gi
|
||||
ports:
|
||||
- containerPort: 80
|
||||
|
||||
+6
-6
@@ -2,13 +2,13 @@ package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
meteringv1 "github.com/labring/sealos/controllers/metering/api/v1"
|
||||
meteringcommonv1 "github.com/labring/sealos/controllers/common/metering/api/v1"
|
||||
baseapi "github.com/labring/sealos/test/testdata/api"
|
||||
"time"
|
||||
)
|
||||
|
||||
const ResourceYaml = `
|
||||
apiVersion: metering.sealos.io/v1
|
||||
apiVersion: metering.common.sealos.io/v1
|
||||
kind: Resource
|
||||
metadata:
|
||||
name: ${name}
|
||||
@@ -19,16 +19,16 @@ spec:
|
||||
Used: 1
|
||||
`
|
||||
|
||||
func GetResource(namespace string, name string) (*meteringv1.Resource, error) {
|
||||
gvr := meteringv1.GroupVersion.WithResource("resources")
|
||||
var resource meteringv1.Resource
|
||||
func GetResource(namespace string, name string) (*meteringcommonv1.Resource, error) {
|
||||
gvr := meteringcommonv1.GroupVersion.WithResource("resources")
|
||||
var resource meteringcommonv1.Resource
|
||||
if err := baseapi.GetObject(namespace, name, gvr, &resource); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &resource, nil
|
||||
}
|
||||
|
||||
func EnsureResourceCreate(namespace string, name string, times int) (*meteringv1.Resource, error) {
|
||||
func EnsureResourceCreate(namespace string, name string, times int) (*meteringcommonv1.Resource, error) {
|
||||
time.Sleep(time.Second)
|
||||
for i := 1; i <= times; i++ {
|
||||
resource, err := GetResource(namespace, name)
|
||||
|
||||
+72
-88
@@ -3,6 +3,7 @@ package e2e
|
||||
import (
|
||||
"fmt"
|
||||
accountv1 "github.com/labring/sealos/controllers/account/api/v1"
|
||||
meteringcommonv1 "github.com/labring/sealos/controllers/common/metering/api/v1"
|
||||
meteringv1 "github.com/labring/sealos/controllers/metering/api/v1"
|
||||
"github.com/labring/sealos/controllers/metering/controllers"
|
||||
"github.com/labring/sealos/controllers/metering/testdata/api"
|
||||
@@ -34,6 +35,36 @@ func init() {
|
||||
fmt.Println("METERING_INTERVAL:", os.Getenv("METERING_INTERVAL"))
|
||||
}
|
||||
|
||||
func TestPressure(t *testing.T) {
|
||||
t.Run("running many pod should be calculate right and ok", func(t *testing.T) {
|
||||
baseapi.EnsureNamespace(TestNamespace)
|
||||
time.Sleep(2 * time.Second)
|
||||
nums := 10
|
||||
t.Log(fmt.Sprintf("create %v pod", nums))
|
||||
for i := 0; i < nums; i++ {
|
||||
api.EnsurePod(TestNamespace, fmt.Sprintf("%s-%v", PodName, i))
|
||||
}
|
||||
time.Sleep(time.Second * 30)
|
||||
metering, err := api.GetMetering(MeteringSystemNamespace, meteringv1.MeteringPrefix+TestNamespace)
|
||||
if err != nil {
|
||||
t.Fatalf("fail get metering: %v", err)
|
||||
}
|
||||
baseapi.CreateCRD(AccountNamespace, metering.Spec.Owner, api.AccountYaml)
|
||||
time.Sleep(time.Second * 5)
|
||||
api.EnsurePodController(MeteringSystemNamespace, meteringv1.PodResourcePricePrefix)
|
||||
time.Sleep(time.Second * 10)
|
||||
for i := 0; i < 30; i++ {
|
||||
time.Sleep(time.Minute)
|
||||
account, err := api.GetAccount(AccountNamespace, metering.Spec.Owner)
|
||||
if err != nil {
|
||||
t.Fatalf("fail get account: %v", err)
|
||||
}
|
||||
t.Log(account.Status)
|
||||
}
|
||||
})
|
||||
t.Cleanup(clear)
|
||||
}
|
||||
|
||||
func TestMetering(t *testing.T) {
|
||||
t.Run("metering should be ok", func(t *testing.T) {
|
||||
t.Run("metering should be created when create a user ns", func(t *testing.T) {
|
||||
@@ -59,43 +90,16 @@ func TestMetering(t *testing.T) {
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("extension should be ok", func(t *testing.T) {
|
||||
// test extension will register cpu price to metering
|
||||
t.Log("create metering ")
|
||||
time.Sleep(time.Second * 10)
|
||||
baseapi.EnsureNamespace(TestNamespace)
|
||||
time.Sleep(time.Second * 10)
|
||||
metering, err := api.GetMetering(MeteringSystemNamespace, meteringv1.MeteringPrefix+TestNamespace)
|
||||
if err != nil {
|
||||
t.Fatalf("fail get metering: %v", err)
|
||||
}
|
||||
|
||||
if _, ok := metering.Spec.Resources["cpu"]; ok {
|
||||
t.Fatalf("metering spec.Resources should not have cpu")
|
||||
}
|
||||
t.Log("create extensionResourcePrice ")
|
||||
baseapi.CreateCRD(MeteringSystemNamespace, meteringv1.GetExtensionResourcePriceName(meteringv1.PodResourcePricePrefix), api.ExtensionResourcePriceYaml)
|
||||
time.Sleep(time.Second)
|
||||
metering, err = api.GetMetering(MeteringSystemNamespace, meteringv1.MeteringPrefix+TestNamespace)
|
||||
if err != nil {
|
||||
t.Fatalf("success get metering: %v", err)
|
||||
}
|
||||
|
||||
if _, ok := metering.Spec.Resources["cpu"]; !ok {
|
||||
t.Fatalf("metering spec.Resources should have cpu")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("pod controller should be ok", func(t *testing.T) {
|
||||
time.Sleep(5 * time.Second)
|
||||
baseapi.EnsureNamespace(TestNamespace)
|
||||
time.Sleep(5 * time.Second)
|
||||
time.Sleep(20 * time.Second)
|
||||
t.Log("creat pod controller")
|
||||
api.CreatePodController(MeteringSystemNamespace, meteringv1.PodResourcePricePrefix)
|
||||
|
||||
time.Sleep(5 * time.Second)
|
||||
t.Log("ensure extension resource is created")
|
||||
podExtensionResourcePrice, err := api.GetExtensionResourcePrice(MeteringSystemNamespace, meteringv1.GetExtensionResourcePriceName(meteringv1.PodResourcePricePrefix))
|
||||
podExtensionResourcePrice, err := api.GetExtensionResourcePrice(MeteringSystemNamespace, meteringcommonv1.GetExtensionResourcePriceName(meteringv1.PodResourcePricePrefix))
|
||||
if err != nil {
|
||||
t.Fatalf("failed to get extension resource: %v", err)
|
||||
}
|
||||
@@ -111,9 +115,9 @@ func TestMetering(t *testing.T) {
|
||||
api.MustCreatPod(TestNamespace, PodName)
|
||||
|
||||
t.Log("ensure resource CR is created")
|
||||
resource, err := api.EnsureResourceCreate(MeteringSystemNamespace, controllers.GetResourceName(TestNamespace, PodName, containerName, "cpu", 1), 90)
|
||||
resource, err := api.EnsureResourceCreate(MeteringSystemNamespace, controllers.GetResourceName(TestNamespace, PodName, 1), 90)
|
||||
if err != nil {
|
||||
resource, err = api.EnsureResourceCreate(MeteringSystemNamespace, controllers.GetResourceName(TestNamespace, PodName, containerName, "cpu", 2), 90)
|
||||
resource, err = api.EnsureResourceCreate(MeteringSystemNamespace, controllers.GetResourceName(TestNamespace, PodName, 2), 90)
|
||||
if err != nil {
|
||||
t.Fatalf(err.Error())
|
||||
}
|
||||
@@ -126,7 +130,6 @@ func TestMetering(t *testing.T) {
|
||||
t.Fatalf("not fount cpu resource used %v", resource.Spec.Resources["cpu"].Used.Value())
|
||||
}
|
||||
t.Log(resource)
|
||||
|
||||
})
|
||||
|
||||
t.Run("metering used update and calculate should be ok", func(t *testing.T) {
|
||||
@@ -141,36 +144,32 @@ func TestMetering(t *testing.T) {
|
||||
t.Fatalf("fail get metering: %v", err)
|
||||
}
|
||||
|
||||
if _, ok := metering.Spec.Resources["cpu"]; !ok {
|
||||
t.Fatalf("not fount cpu resource info in metering ")
|
||||
}
|
||||
|
||||
t.Log("metering calculate should be ok")
|
||||
metering, err = api.EnsureMeteringCalculate(MeteringSystemNamespace, meteringv1.MeteringPrefix+TestNamespace, 90)
|
||||
if err != nil {
|
||||
t.Fatalf("metering calculate failer: %v,calculate: %v", err, metering)
|
||||
}
|
||||
t.Logf("metering:%+v", metering.Spec.Resources)
|
||||
t.Logf("metering:%+v", metering.Status)
|
||||
})
|
||||
|
||||
t.Run("metering create accountBalance should be ok", func(t *testing.T) {
|
||||
api.EnsurePodController(MeteringSystemNamespace, meteringv1.PodResourcePricePrefix)
|
||||
time.Sleep(time.Second * 2)
|
||||
baseapi.EnsureNamespace(TestNamespace)
|
||||
api.EnsurePod(TestNamespace, PodName)
|
||||
time.Sleep(time.Second * 20)
|
||||
api.EnsurePodController(MeteringSystemNamespace, meteringv1.PodResourcePricePrefix)
|
||||
time.Sleep(time.Second * 2)
|
||||
|
||||
t.Log("ensure accountBalance is created")
|
||||
t.Log("ensure metering used is update")
|
||||
metering, err := api.GetMetering(MeteringSystemNamespace, meteringv1.MeteringPrefix+TestNamespace)
|
||||
if err != nil {
|
||||
t.Fatalf("fail get metering: %v", err)
|
||||
}
|
||||
|
||||
t.Log(metering.Spec)
|
||||
t.Log("ensure accountBalance is created")
|
||||
accountBalance, err := api.EnsureAccountBalanceCreate(MeteringSystemNamespace, fmt.Sprintf("%s-%s-%v", accountv1.AccountBalancePrefix, metering.Spec.Owner, 1), 90)
|
||||
if err != nil {
|
||||
t.Log("ensure accountBalance is created again")
|
||||
metering, err = api.GetMetering(MeteringSystemNamespace, meteringv1.MeteringPrefix+TestNamespace)
|
||||
accountBalance, err = api.EnsureAccountBalanceCreate(MeteringSystemNamespace, fmt.Sprintf("%s-%s-%v", accountv1.AccountBalancePrefix, metering.Spec.Owner, 1), 90)
|
||||
accountBalance, err = api.EnsureAccountBalanceCreate(MeteringSystemNamespace, fmt.Sprintf("%s-%s-%v", accountv1.AccountBalancePrefix, metering.Spec.Owner, 2), 90)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create accountBalance: %v", err)
|
||||
}
|
||||
@@ -181,6 +180,9 @@ func TestMetering(t *testing.T) {
|
||||
t.Fatalf("failed to create accountBalance: %v", accountBalance)
|
||||
}
|
||||
|
||||
if accountBalance.Spec.ResourceInfoList == nil {
|
||||
t.Fatalf("failed to add resoureinfo list: accoutnbalance spec:%v", accountBalance.Spec)
|
||||
}
|
||||
time.Sleep(2 * time.Second)
|
||||
account, err := api.GetAccount(AccountNamespace, metering.Spec.Owner)
|
||||
if err != nil {
|
||||
@@ -193,48 +195,41 @@ func TestMetering(t *testing.T) {
|
||||
|
||||
defer t.Log(fmt.Sprintf("account:%v", account))
|
||||
})
|
||||
|
||||
t.Run("metering calculate infra should be ok", func(t *testing.T) {
|
||||
t.Log("ensure infra is created")
|
||||
baseapi.EnsureNamespace(TestNamespace)
|
||||
baseapi.CreateCRD(TestNamespace, InfraName, api.InfraYaml)
|
||||
err := api.EnsureInfra(TestNamespace, InfraName, 12)
|
||||
//if err != nil {
|
||||
// t.Fatalf(err.Error())
|
||||
//}
|
||||
infra, err := api.GetInfra(TestNamespace, InfraName)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to get infra: %v", err)
|
||||
}
|
||||
|
||||
t.Log("check infra QueryPrice")
|
||||
price, err := infra.QueryPrice()
|
||||
t.Log("infra price is ", price)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to query infra price: %v", err)
|
||||
}
|
||||
})
|
||||
})
|
||||
t.Cleanup(clear)
|
||||
}
|
||||
|
||||
func clear() {
|
||||
//time.Sleep(200 * time.Second)
|
||||
execout, err := baseapi.Exec("sudo -u root kubectl get pod -n metering-system|grep metering |awk '{print $1}' |xargs kubectl logs -n metering-system")
|
||||
execout, err := baseapi.Exec("kubectl get accountbalance -A ")
|
||||
log.Println(execout)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
execout, err = baseapi.Exec("sudo -u root kubectl get pod -n account-system|grep account |awk '{print $1}' |xargs kubectl logs -n account-system")
|
||||
execout, err = baseapi.Exec("kubectl get pod -n metering-system|grep metering |awk '{print $1}' |xargs kubectl logs -n metering-system")
|
||||
log.Println(execout)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
execout, err = baseapi.Exec("sudo -u root kubectl get accountbalance -A")
|
||||
execout, err = baseapi.Exec("kubectl get pod -n account-system|grep account |awk '{print $1}' |xargs kubectl logs -n account-system")
|
||||
log.Println(execout)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
execout, err = baseapi.Exec("kubectl get resource -A -oyaml")
|
||||
log.Println(execout)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
execout, err = baseapi.Exec("kubectl get accountbalance -A -oyaml")
|
||||
log.Println(execout)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
err = api.DeletePod(TestNamespace, PodName)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
|
||||
err = baseapi.DeleteNamespace(TestNamespace)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
@@ -245,7 +240,7 @@ func clear() {
|
||||
log.Println(err)
|
||||
}
|
||||
|
||||
err = baseapi.DeleteCRD(MeteringSystemNamespace, meteringv1.GetExtensionResourcePriceName(meteringv1.PodResourcePricePrefix), api.ExtensionResourcePriceYaml)
|
||||
err = baseapi.DeleteCRD(MeteringSystemNamespace, meteringcommonv1.GetExtensionResourcePriceName(meteringv1.PodResourcePricePrefix), api.ExtensionResourcePriceYaml)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
@@ -255,11 +250,6 @@ func clear() {
|
||||
log.Println(err)
|
||||
}
|
||||
|
||||
err = api.DeletePod(TestNamespace, PodName)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
|
||||
if err = api.DeleteExtensionResourcePrice(MeteringSystemNamespace, meteringv1.PodResourcePricePrefix); err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
@@ -267,22 +257,16 @@ func clear() {
|
||||
if err = baseapi.DeleteCRD(AccountNamespace, DefaultOwner, api.AccountYaml); err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
|
||||
if err = baseapi.DeleteCRD(TestNamespace, InfraName, api.InfraYaml); err != nil {
|
||||
execout, err = baseapi.Exec("kubectl get resource -A| awk '{print $2}' | xargs kubectl delete resource -n metering-system")
|
||||
log.Println(execout)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
|
||||
for i := 0; i <= 5; i++ {
|
||||
if err = baseapi.DeleteCRD(MeteringSystemNamespace, controllers.GetResourceName(TestNamespace, PodName, containerName, "cpu", int64(i)), api.ResourceYaml); err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
|
||||
if err = baseapi.DeleteCRD(MeteringSystemNamespace, controllers.GetResourceName(TestNamespace, PodName, "", "storage", int64(i)), api.ResourceYaml); err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
|
||||
if err = baseapi.DeleteCRD(MeteringSystemNamespace, fmt.Sprintf("%s-%s-%v", accountv1.AccountBalancePrefix, DefaultOwner, i), api.AccountBalanceYaml); err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
execout, err = baseapi.Exec("kubectl get accountbalance -A | awk '{print $2}' | xargs kubectl delete accountbalance -n metering-system")
|
||||
log.Println(execout)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -807,8 +807,7 @@ github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042
|
||||
github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
|
||||
github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU=
|
||||
github.com/onsi/ginkgo/v2 v2.1.6/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk=
|
||||
github.com/onsi/ginkgo/v2 v2.3.1 h1:8SbseP7qM32WcvE6VaN6vfXxv698izmsJ1UQX9ve7T8=
|
||||
github.com/onsi/ginkgo/v2 v2.3.1/go.mod h1:Sv4yQXwG5VmF7tm3Q5Z+RWUpPo24LF1mpnz2crUb8Ys=
|
||||
github.com/onsi/ginkgo/v2 v2.6.0 h1:9t9b9vRUbFq3C4qKFCGkVuq/fIHji802N1nrtkh1mNc=
|
||||
github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
@@ -819,8 +818,8 @@ github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDs
|
||||
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
|
||||
github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro=
|
||||
github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo=
|
||||
github.com/onsi/gomega v1.22.1 h1:pY8O4lBfsHKZHM/6nrxkhVPUznOlIu3quZcKP/M20KI=
|
||||
github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ1tuM=
|
||||
github.com/onsi/gomega v1.24.1 h1:KORJXNNTzJXzu4ScJWssJfJMnJ+2QJqhoQSRwNlze9E=
|
||||
github.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmvt1jM=
|
||||
github.com/openconfig/gnmi v0.0.0-20220920173703-480bf53a74d2 h1:3YLlQFLDsFTvruKoYBbuYqhCgsXMtNewSrLjNXcF/Sg=
|
||||
github.com/openconfig/gnmi v0.0.0-20220920173703-480bf53a74d2/go.mod h1:Y9os75GmSkhHw2wX8sMsxfI7qRGAEcDh8NTa5a8vj6E=
|
||||
github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
@@ -1428,8 +1427,8 @@ golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxb
|
||||
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 h1:ftMN5LMiBFjbzleLqtoBZk7KdJwhuybIU+FckUHgoyQ=
|
||||
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
|
||||
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
@@ -1736,11 +1735,12 @@ k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
|
||||
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
|
||||
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
||||
k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
||||
k8s.io/klog/v2 v2.70.1 h1:7aaoSdahviPmR+XkS7FyxlkkXs6tHISSG03RxleQAVQ=
|
||||
k8s.io/klog/v2 v2.70.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
|
||||
k8s.io/klog/v2 v2.80.1 h1:atnLQ121W371wYYFawwYx1aEY2eUfs4l3J72wtgAwV4=
|
||||
k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
|
||||
k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1/go.mod h1:C/N6wCaBHeBHkHUesQOQy2/MZqGgMAFPqGsGQLdbZBU=
|
||||
k8s.io/kube-openapi v0.0.0-20220803164354-a70c9af30aea h1:3QOH5+2fGsY8e1qf+GIFpg+zw/JGNrgyZRQR7/m6uWg=
|
||||
k8s.io/kube-openapi v0.0.0-20220803164354-a70c9af30aea/go.mod h1:C/N6wCaBHeBHkHUesQOQy2/MZqGgMAFPqGsGQLdbZBU=
|
||||
k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 h1:+70TFaan3hfJzs+7VK2o+OGxg8HsuBr/5f6tVAjDu6E=
|
||||
k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280/go.mod h1:+Axhij7bCpeqhklhUTe3xmOn6bWxolyZEeyaFpjGtl4=
|
||||
k8s.io/kube-proxy v0.25.6 h1:vG8Zg8xMFOGg2gnEkmYuSU/RJ4waIOW6Ti6/Y8at26M=
|
||||
k8s.io/kube-proxy v0.25.6/go.mod h1:uMzY4OdkcMQ+sNAnze9iyKdff035UfCDc1k6dLOjj8Q=
|
||||
k8s.io/kubelet v0.25.6 h1:rZntZUVRlZ1nys1C9QBPJ2drzy6Mq67yfgmDlFzrQHw=
|
||||
@@ -1750,16 +1750,17 @@ k8s.io/kubernetes v1.25.6 h1:3zBcz3I4CXKnzR/K37Kzjtmu4O+/5XV/tUCa7gSiJG4=
|
||||
k8s.io/kubernetes v1.25.6/go.mod h1:iB7lKyWeYg8+Oi5EPDEfdMtmae8BvjzziSpek2CcBe4=
|
||||
k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed h1:jAne/RjBTyawwAy0utX5eqigAwz/lQhTmy+Hr/Cpue4=
|
||||
k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
k8s.io/utils v0.0.0-20221128185143-99ec85e7a448 h1:KTgPnR10d5zhztWptI952TNtt/4u5h3IzDXkdIMuo2Y=
|
||||
k8s.io/utils v0.0.0-20221128185143-99ec85e7a448/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||
oras.land/oras-go v1.2.0 h1:yoKosVIbsPoFMqAIFHTnrmOuafHal+J/r+I5bdbVWu4=
|
||||
oras.land/oras-go v1.2.0/go.mod h1:pFNs7oHp2dYsYMSS82HaX5l4mpnGO7hbpPN6EWH2ltc=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.35/go.mod h1:WxjusMwXlKzfAs4p9km6XJRndVt2FROgMVCE4cdohFo=
|
||||
sigs.k8s.io/controller-runtime v0.13.0 h1:iqa5RNciy7ADWnIc8QxCbOX5FEKVR3uxVxKHRMc2WIQ=
|
||||
sigs.k8s.io/controller-runtime v0.13.0/go.mod h1:Zbz+el8Yg31jubvAEyglRZGdLAjplZl+PgtYNI6WNTI=
|
||||
sigs.k8s.io/controller-runtime v0.14.4 h1:Kd/Qgx5pd2XUL08eOV2vwIq3L9GhIbJ5Nxengbd4/0M=
|
||||
sigs.k8s.io/controller-runtime v0.14.4/go.mod h1:WqIdsAY6JBsjfc/CqO0CORmNtoCtE4S6qbPc9s68h+0=
|
||||
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k=
|
||||
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
|
||||
sigs.k8s.io/kustomize/api v0.12.1 h1:7YM7gW3kYBwtKvoY216ZzY+8hM+lV53LUayghNRJ0vM=
|
||||
|
||||
@@ -16,4 +16,5 @@ use (
|
||||
./staging/src/github.com/labring/image-cri-shim
|
||||
./staging/src/github.com/labring/lvscare
|
||||
./webhooks/whitelist
|
||||
./controllers/common
|
||||
)
|
||||
|
||||
+381
@@ -455,57 +455,438 @@ github.com/DataDog/zstd v1.5.0 h1:+K/VEwIAaPcHiMtQvpLD4lqW7f0Gk3xdYZmI1hD+CXo=
|
||||
github.com/DataDog/zstd v1.5.0/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw=
|
||||
github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs=
|
||||
github.com/GoogleCloudPlatform/k8s-cloud-provider v1.16.1-0.20210702024009-ea6160c1d0e3 h1:FCalqNmQYSMCCHoCtAxZN/ZgLc8ufgeo5Z3wrIoJZvs=
|
||||
github.com/GoogleCloudPlatform/k8s-cloud-provider v1.18.1-0.20220218231025-f11817397a1b h1:Heo1J/ttaQFgGJSVnCZquy3e5eH5j1nqxBuomztB3P0=
|
||||
github.com/JeffAshton/win_pdh v0.0.0-20161109143554-76bb4ee9f0ab h1:UKkYhof1njT1/xq4SEg5z+VpTgjmNeHwPGRQl7takDI=
|
||||
github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ=
|
||||
github.com/Masterminds/squirrel v1.5.3 h1:YPpoceAcxuzIljlr5iWpNKaql7hLeG1KLSrhvdHpkZc=
|
||||
github.com/Masterminds/vcs v1.13.3 h1:IIA2aBdXvfbIM+yl/eTnL4hb1XwdpvuQLglAix1gweE=
|
||||
github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3 h1:4FA+QBaydEHlwxg0lMN3rhwoDaQy6LKhVWR4qvq4BuA=
|
||||
github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I=
|
||||
github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE=
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20220824120805-4b6e5c587895 h1:NsReiLpErIPzRrnogAXYwSoU7txA977LjDGrbkewJbg=
|
||||
github.com/ahmetb/gen-crd-api-reference-docs v0.3.0 h1:+XfOU14S4bGuwyvCijJwhhBIjYN+YXS18jrCY2EzJaY=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
|
||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2cI+DC1Mbh0TJxzA3RcLoMsFw+aXw7E=
|
||||
github.com/alexflint/go-filemutex v1.1.0 h1:IAWuUuRYL2hETx5b8vCgwnD+xSdlsTQY6s2JjBsqLdg=
|
||||
github.com/antihax/optional v1.0.0 h1:xK2lYat7ZLaVVcIuj82J8kIro4V6kDe0AUDFboUCwcg=
|
||||
github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20220418222510-f25a4f6275ed h1:ue9pVfIcP+QMEjfgo/Ez4ZjNZfonGgR6NgjMaJMu1Cg=
|
||||
github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20220418222510-f25a4f6275ed/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY=
|
||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e h1:QEF07wC0T1rKkctt1RINW/+RMTVmiwxETico2l3gxJA=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6 h1:G1bPvciwNyF7IUmKXNt9Ak3m6u9DE1rF+RmtIkBpVdA=
|
||||
github.com/armon/go-metrics v0.4.0 h1:yCQqn7dwca4ITXb+CbubHmedzaQYHhNhrEXLYUeEe8Q=
|
||||
github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
|
||||
github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 h1:4daAzAu0S6Vi7/lbWECcX0j45yZReDZ56BQsrVBOEEY=
|
||||
github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg=
|
||||
github.com/auth0/go-jwt-middleware v1.0.1 h1:/fsQ4vRr4zod1wKReUH+0A3ySRjGiT9G34kypO/EKwI=
|
||||
github.com/aws/aws-sdk-go v1.44.102 h1:6tUCTGL2UDbFZae1TLGk8vTgeXuzkb8KbAe2FiAeKHc=
|
||||
github.com/aws/aws-sdk-go-v2 v1.16.16 h1:M1fj4FE2lB4NzRb9Y0xdWsn2P0+2UHVxwKyOa4YJNjk=
|
||||
github.com/aws/aws-sdk-go-v2 v1.16.16/go.mod h1:SwiyXi/1zTUZ6KIAmLK5V5ll8SiURNUYOqTerZPaF9k=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.17.7 h1:odVM52tFHhpqZBKNjVW5h+Zt1tKHbhdTQRb+0WHrNtw=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.17.7/go.mod h1:dN2gja/QXxFF15hQreyrqYhLBaQo1d9ZKe/v/uplQoI=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.12.20 h1:9+ZhlDY7N9dPnUmf7CDfW9In4sW5Ff3bh7oy4DzS1IE=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.12.20/go.mod h1:UKY5HyIux08bbNA7Blv4PcXQ8cTkGh7ghHMFklaviR4=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.17 h1:r08j4sbZu/RVi+BNxkBJwPMUYY3P8mgSDuKkZ/ZN1lE=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.17/go.mod h1:yIkQcCDYNsZfXpd5UX2Cy+sWA1jPgIhGTw9cOBzfVnQ=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.23 h1:s4g/wnzMf+qepSNgTvaQQHNxyMLKSawNhKCPNy++2xY=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.23/go.mod h1:2DFxAQ9pfIRy0imBCJv+vZ2X6RKxves6fbnEuSry6b4=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.17 h1:/K482T5A3623WJgWT8w1yRAFK4RzGzEl7y39yhtn9eA=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.17/go.mod h1:pRwaTYCJemADaqCbUAxltMoHKata7hmB5PjEXeu0kfg=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.24 h1:wj5Rwc05hvUSvKuOF29IYb9QrCLjU+rHAy/x/o0DK2c=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.24/go.mod h1:jULHjqqjDlbyTa7pfM7WICATnOv+iOhjletM3N0Xbu8=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.17 h1:Jrd/oMh0PKQc6+BowB+pLEwLIgaQF29eYbe7E1Av9Ug=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.17/go.mod h1:4nYOrY41Lrbk2170/BGkcJKBhws9Pfn8MG3aGqjjeFI=
|
||||
github.com/aws/aws-sdk-go-v2/service/kms v1.18.10 h1:rl0vxqQ/DFZZMLk9+FLgIuiE/GwMPoI5BeoCkkM2DA4=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.11.23 h1:pwvCchFUEnlceKIgPUouBJwK81aCkQ8UDMORfeFtW10=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.11.23/go.mod h1:/w0eg9IhFGjGyyncHIQrXtU8wvNsTJOP0R6PPj0wf80=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.13.5 h1:GUnZ62TevLqIoDyHeiWj2P7EqaosgakBKVvWriIdLQY=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.13.5/go.mod h1:csZuQY65DAdFBt1oIjO5hhBR49kQqop4+lcuCjf2arA=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.16.19 h1:9pPi0PsFNAGILFfPCk8Y0iyEBGc6lu6OQ97U7hmdesg=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.16.19/go.mod h1:h4J3oPZQbxLhzGnk+j9dfYHi5qIOVJ5kczZd658/ydM=
|
||||
github.com/aws/smithy-go v1.13.3 h1:l7LYxGuzK6/K+NzJ2mC+VvLUbae0sL3bXU//04MkmnA=
|
||||
github.com/aws/smithy-go v1.13.3/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA=
|
||||
github.com/beeker1121/goque v1.0.3-0.20191103205551-d618510128af h1:XbgLdZvVbWsK9HAhAYOp6rksTAdOVYDBQtGSVOLlJrw=
|
||||
github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY=
|
||||
github.com/bitly/go-simplejson v0.5.0 h1:6IH+V8/tVMab511d5bn4M7EwGXZf9Hj6i2xSwkNEM+Y=
|
||||
github.com/bits-and-blooms/bitset v1.2.0 h1:Kn4yilvwNtMACtf1eYDlG8H77R07mZSPbMjLyS07ChA=
|
||||
github.com/bketelsen/crypt v0.0.4 h1:w/jqZtC9YD4DS/Vp9GhWfWcCpuAL58oTnLoI8vE9YHU=
|
||||
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY=
|
||||
github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4=
|
||||
github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs=
|
||||
github.com/cenkalti/backoff/v3 v3.2.2 h1:cfUAAO3yvKMYKPrvhDuHSwQnhZNk/RMHKdZqKTxfm6M=
|
||||
github.com/cenkalti/backoff/v4 v4.1.2 h1:6Yo7N8UP2K6LWZnW94DLVSSrbobcWdVzAYOisuDPIFo=
|
||||
github.com/census-instrumentation/opencensus-proto v0.3.0 h1:t/LhUZLVitR1Ow2YOnduCsavhwFUklBMoGVYUCqmCqk=
|
||||
github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054 h1:uH66TXeswKn5PW5zdZ39xEwfS9an067BirqA+P4QaLI=
|
||||
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
|
||||
github.com/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNSjIRk=
|
||||
github.com/checkpoint-restore/go-criu/v4 v4.1.0 h1:WW2B2uxx9KWF6bGlHqhm8Okiafwwx7Y2kcpn8lCpjgo=
|
||||
github.com/checkpoint-restore/go-criu/v5 v5.3.0 h1:wpFFOoomK3389ue2lAb0Boag6XPht5QYpipxmSNL4d8=
|
||||
github.com/cilium/ebpf v0.7.0 h1:1k/q3ATgxSXRdrmPfH8d7YK0GfqVsEKZAX9dQZvs56k=
|
||||
github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI=
|
||||
github.com/cloudflare/circl v1.1.0 h1:bZgT/A+cikZnKIwn7xL2OBj012Bmvho/o6RpRvv3GKY=
|
||||
github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4 h1:hzAQntlaYRkVSFEfj9OTWlVV1H155FMD8BTKktLv0QI=
|
||||
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1 h1:zH8ljVhhq7yC0MIeUL/IviMtY8hx2mK8cN9wEYb8ggw=
|
||||
github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5 h1:xD/lrqdvwsc+O2bjSSi3YqY73Ke3LAiSCx49aCesA0E=
|
||||
github.com/cockroachdb/errors v1.2.4 h1:Lap807SXTH5tri2TivECb/4abUkMZC9zRoLarvcKDqs=
|
||||
github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f h1:o/kfcElHqOiXqcou5a3rIlMc7oJbMQkeLk0VQJ7zgqY=
|
||||
github.com/container-storage-interface/spec v1.6.0 h1:vwN9uCciKygX/a0toYryoYD5+qI9ZFeAMuhEEKO+JBA=
|
||||
github.com/containerd/aufs v1.0.0 h1:2oeJiwX5HstO7shSrPZjrohJZLzK36wvpdmzDRkL/LY=
|
||||
github.com/containerd/btrfs v1.0.0 h1:osn1exbzdub9L5SouXO5swW4ea/xVdJZ3wokxN5GrnA=
|
||||
github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw=
|
||||
github.com/containerd/fifo v1.0.0 h1:6PirWBr9/L7GDamKr+XM0IeUFXu5mf3M/BPpH9gaLBU=
|
||||
github.com/containerd/go-cni v1.1.6 h1:el5WPymG5nRRLQF1EfB97FWob4Tdc8INg8RZMaXWZlo=
|
||||
github.com/containerd/go-runc v1.0.0 h1:oU+lLv1ULm5taqgV/CJivypVODI4SUz1znWjv3nNYS0=
|
||||
github.com/containerd/imgcrypt v1.1.4 h1:iKTstFebwy3Ak5UF0RHSeuCTahC5OIrPJa6vjMAM81s=
|
||||
github.com/containerd/nri v0.1.0 h1:6QioHRlThlKh2RkRTR4kIT3PKAcrLo3gIWnjkM4dQmQ=
|
||||
github.com/containerd/ttrpc v1.1.0 h1:GbtyLRxb0gOLR0TYQWt3O6B0NvT8tMdorEHqIQo/lWI=
|
||||
github.com/containerd/typeurl v1.0.2 h1:Chlt8zIieDbzQFzXzAeBEF92KhExuE4p9p92/QmY7aY=
|
||||
github.com/containerd/zfs v1.0.0 h1:cXLJbx+4Jj7rNsTiqVfm6i+RNLx6FFA2fMmDlEf+Wm8=
|
||||
github.com/coredns/caddy v1.1.0 h1:ezvsPrT/tA/7pYDBZxu0cT0VmWk75AfIaf6GSYCNMf0=
|
||||
github.com/coredns/corefile-migration v1.0.17 h1:tNwh8+4WOANV6NjSljwgW7qViJfhvPUt1kosj4rR8yg=
|
||||
github.com/coreos/bbolt v1.3.2 h1:wZwiHHUieZCquLkDL0B8UhzreNWsPHooDAG3q34zk0s=
|
||||
github.com/coreos/etcd v3.3.13+incompatible h1:8F3hqu9fGYLBifCmRCJsicFqDx/D68Rt3q1JMazcgBQ=
|
||||
github.com/coreos/go-iptables v0.6.0 h1:is9qnZMPYjLd8LYqmm/qlE+wwEgJIkTYdhV3rfZo4jk=
|
||||
github.com/coreos/go-oidc v2.1.0+incompatible h1:sdJrfw8akMnCuUlaZU3tE/uYXFgfqom8DBE9so9EBsM=
|
||||
github.com/coreos/go-oidc/v3 v3.4.0 h1:xz7elHb/LDwm/ERpwHd+5nb7wFHL32rsr6bBOgaeu6g=
|
||||
github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM=
|
||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8=
|
||||
github.com/coreos/go-systemd/v22 v22.4.0 h1:y9YHcjnjynCd/DVbg5j9L/33jQM3MxJlbj/zWskzfGU=
|
||||
github.com/coreos/go-systemd/v22 v22.4.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg=
|
||||
github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c h1:Xo2rK1pzOm0jO6abTPIQwbAmqBIOj132otexc1mmzFc=
|
||||
github.com/d2g/dhcp4client v1.0.0 h1:suYBsYZIkSlUMEz4TAYCczKf62IA2UWC+O8+KtdOhCo=
|
||||
github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5 h1:+CpLbZIeUn94m02LdEKPcgErLJ347NUwxPKs5u8ieiY=
|
||||
github.com/d2g/hardwareaddr v0.0.0-20190221164911-e7d9fbe030e4 h1:itqmmf1PFpC4n5JW+j4BU7X4MTfVurhYRTjODoPb2Y8=
|
||||
github.com/danieljoos/wincred v1.1.2 h1:QLdCxFs1/Yl4zduvBdcHB8goaYk9RARS2SgLLRuAyr0=
|
||||
github.com/daviddengcn/go-colortext v1.0.0 h1:ANqDyC0ys6qCSvuEK7l3g5RaehL/Xck9EX8ATG8oKsE=
|
||||
github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba h1:p6poVbjHDkKa+wtC8frBMwQtT3BmqGYBjzMwJ63tuR4=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954 h1:RMLoZVzv4GliuWafOuPuQDKSm1SJph7uCRnnS61JAn4=
|
||||
github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi/U=
|
||||
github.com/dnaeon/go-vcr v1.0.1 h1:r8L/HqC0Hje5AXMu1ooW8oyQyOFv4GxqpL0nRP7SLLY=
|
||||
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815 h1:bWDMxwH3px2JBh6AyO7hdCn/PkvCZXii8TGj7sbtEbQ=
|
||||
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
|
||||
github.com/eggsampler/acme/v3 v3.3.0 h1:5M7vwYRy65iPpCFHZ01RyWXmYT8e8MlcWn/9BUUB7Ro=
|
||||
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153 h1:yUdfgN0XgIJw7foRItutHYUIhlcKzcSf5vDpdhQAKTc=
|
||||
github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1 h1:xvqufLtNVwAhN8NMyWklVgxnWohi+wtMGQMhtxexlm0=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A=
|
||||
github.com/euank/go-kmsg-parser v2.0.0+incompatible h1:cHD53+PLQuuQyLZeriD1V/esuG4MuU0Pjs5y6iknohY=
|
||||
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwCFad8crR9dcMQWvV9Hvulu6hwUh4tWPJnM=
|
||||
github.com/fatih/camelcase v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8=
|
||||
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
|
||||
github.com/felixge/httpsnoop v1.0.2 h1:+nS9g82KMXccJ/wp0zyRW9ZBHFETmMGtkk+2CTTrW4o=
|
||||
github.com/flowstack/go-jsonschema v0.1.1 h1:dCrjGJRXIlbDsLAgTJZTjhwUJnnxVWl1OgNyYh5nyDc=
|
||||
github.com/flynn/go-docopt v0.0.0-20140912013429-f6dd2ebbb31e h1:Ss/B3/5wWRh8+emnK0++g5zQzwDTi30W10pKxKc4JXI=
|
||||
github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa h1:RDBNVkRviHZtvDvId8XSGPu3rmpmSe+wKRcEWNgsfWU=
|
||||
github.com/fvbommel/sortorder v1.0.1 h1:dSnXLt4mJYH25uDDGa3biZNQsozaUWDSWeKJ0qqFfzE=
|
||||
github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7 h1:LofdAjjjqCSXMwLGgOgnE+rdPuvX9DxCqaHwKy7i/ko=
|
||||
github.com/getkin/kin-openapi v0.76.0 h1:j77zg3Ec+k+r+GA3d8hBoXpAc6KX9TbBPrwQGBIy2sY=
|
||||
github.com/getsentry/raven-go v0.2.0 h1:no+xWJRb5ZI7eE8TWgIq1jLulQiIoLG0IfYxv5JYMGs=
|
||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||
github.com/gin-gonic/gin v1.7.7 h1:3DoBmSbJbZAWqXJC3SLjAPfutPJJRN1U5pALB7EeTTs=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1 h1:QbL/5oDUmRBzO9/Z7Seo6zf912W/a6Sr4Eu0G/3Jho0=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4 h1:WtGNWLvXpe6ZudgnXrq0barxBImvnnJoMEhXAzcbM0I=
|
||||
github.com/go-gorp/gorp/v3 v3.0.2 h1:ULqJXIekoqMx29FI5ekXXFoH1dT2Vc8UhnRzBg+Emz4=
|
||||
github.com/go-ini/ini v1.25.4 h1:Mujh4R/dH6YL8bxuISne3xX2+qcQ9p0IxKAP6ExWoUo=
|
||||
github.com/go-kit/kit v0.9.0 h1:wDJmvq38kDhkVxi50ni9ykkdUr1PKgqKOoi01fa0Mdk=
|
||||
github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU=
|
||||
github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
|
||||
github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA=
|
||||
github.com/go-logr/logr v1.2.1/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/stdr v1.2.0/go.mod h1:YkVgnZu1ZjjL7xTxrfm/LLZBfkhTqSR1ydtm6jTKKwI=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-ozzo/ozzo-validation v3.5.0+incompatible h1:sUy/in/P6askYr16XJgTKq/0SZhiWsdg4WZGaLsGQkM=
|
||||
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
|
||||
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
|
||||
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
|
||||
github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE=
|
||||
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
|
||||
github.com/go-rod/rod v0.109.3 h1:MxuSJGK9lEUq07K+QPfnxnuvQpsQT+YI4SoQjSE0LVg=
|
||||
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
|
||||
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I=
|
||||
github.com/gobuffalo/flect v0.2.3 h1:f/ZukRnSNA/DUpSNDadko7Qc0PhGvsew35p/2tu+CRY=
|
||||
github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e h1:BWhy2j3IXJhjCbC68FptL43tDKIq8FladmaTs3Xs7Z8=
|
||||
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
|
||||
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw=
|
||||
github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw=
|
||||
github.com/gogo/googleapis v1.4.0 h1:zgVt4UpGxcqVOw97aRGxT4svlcmdK35fynLNctY32zI=
|
||||
github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d h1:lBXNCxVENCipq4D1Is42JVOP4eQjlB8TQ6H69Yx5J9Q=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
||||
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
|
||||
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
||||
github.com/google/cadvisor v0.45.0 h1:bXQze1sd8srZiQwiQ19Qaq/AoMIZS8YceBXrIaEvkX0=
|
||||
github.com/google/cel-go v0.12.6 h1:kjeKudqV0OygrAqA9fX6J55S8gj+Jre2tckIm5RoG4M=
|
||||
github.com/google/cel-go v0.12.6/go.mod h1:Jk7ljRzLBhkmiAwBoUxB1sZSCVBAzkqPF25olK/iRDw=
|
||||
github.com/google/certificate-transparency-go v1.0.22-0.20181127102053-c25855a82c75 h1:+QTUt+tQMFBQPGB/gfpLj6JKfKISHo0c4U6jLkLYLoY=
|
||||
github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no=
|
||||
github.com/google/martian/v3 v3.2.1 h1:d8MncMlErDFTwQGBK1xhv026j9kqhvw1Qv9IbWT1VLQ=
|
||||
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec=
|
||||
github.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.2.0 h1:y8Yozv7SZtlU//QXbezB6QkpuE6jMD2/gfzk4AftXjs=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg=
|
||||
github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY=
|
||||
github.com/googleapis/gax-go/v2 v2.7.0 h1:IcsPKeInNvYi7eqSaDjiZqDDKu5rsmunY0Y1YupQSSQ=
|
||||
github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8=
|
||||
github.com/googleapis/gnostic v0.5.5 h1:9fHAtK0uDfpveeqqo1hkEZJcFvYXAiCN3UutL8F9xHw=
|
||||
github.com/googleapis/go-type-adapters v1.0.0 h1:9XdMn+d/G57qq1s8dNc5IesGCXHf6V2HZ2JwRxfA2tA=
|
||||
github.com/gophercloud/gophercloud v0.1.0 h1:P/nh25+rzXouhytV2pUHBb65fnds26Ghl8/391+sT5o=
|
||||
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
||||
github.com/gosuri/uitable v0.0.4 h1:IG2xLKRvErL3uhY6e1BylFzG+aJiwQviDDTfOKeKTpY=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
|
||||
github.com/hashicorp/consul/api v1.1.0 h1:BNQPM9ytxj6jbjjdRPioQ94T6YXriSopn0i8COv6SRA=
|
||||
github.com/hashicorp/consul/sdk v0.1.1 h1:LnuDWGNsoajlhGyHJvuWW6FVqRl8JOTPqS6CPTsYjhY=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
|
||||
github.com/hashicorp/go-hclog v1.2.1 h1:YQsLlGDJgwhXFpucSPyVbCBviQtjlHv3jLTlp8YmtEw=
|
||||
github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc=
|
||||
github.com/hashicorp/go-memdb v1.3.2 h1:RBKHOsnSszpU6vxq80LzC2BaQjuuvoyaQbkLTf7V7g8=
|
||||
github.com/hashicorp/go-msgpack v0.5.3 h1:zKjpN5BK/P5lMYrLmBHdBULWbJ0XpYR+7NGzqkZzoD4=
|
||||
github.com/hashicorp/go-plugin v1.4.4 h1:NVdrSdFRt3SkZtNckJ6tog7gbpRrcbOjQi/rgF7JYWQ=
|
||||
github.com/hashicorp/go-retryablehttp v0.7.1 h1:sUiuQAnLlbvmExtFQs72iFW/HXeUn8Z1aJLQ4LJJbTQ=
|
||||
github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc=
|
||||
github.com/hashicorp/go-secure-stdlib/mlock v0.1.2 h1:p4AKXPPS24tO8Wc8i1gLvSKdmkiSY5xuju57czJ/IJQ=
|
||||
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6 h1:om4Al8Oy7kCm/B86rLCLah4Dt5Aa0Fr5rYBG60OzwHQ=
|
||||
github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9CdjCtrXrXGuOpxEA7Ts=
|
||||
github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc=
|
||||
github.com/hashicorp/go-syslog v1.0.0 h1:KaodqZuhUoZereWVIYmpUgZysurB1kBLX2j0MwMrUAE=
|
||||
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
|
||||
github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek=
|
||||
github.com/hashicorp/go.net v0.0.1 h1:sNCoNyDEvN1xa+X0baata4RdcpKwcMS6DH+xwfqPgjw=
|
||||
github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
|
||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y=
|
||||
github.com/hashicorp/mdns v1.0.0 h1:WhIgCr5a7AaVH6jPUwjtRuuE7/RDufnUvzIr48smyxs=
|
||||
github.com/hashicorp/memberlist v0.1.3 h1:EmmoJme1matNzb+hMpDuR/0sbJSUisxyqBGG676r31M=
|
||||
github.com/hashicorp/serf v0.8.2 h1:YZ7UKsJv+hKjqGVUUbtE3HNj79Eln2oQ75tniF6iPt0=
|
||||
github.com/hashicorp/vault/api v1.8.0 h1:7765sW1XBt+qf4XKIYE4ebY9qc/yi9V2/egzGSUNMZU=
|
||||
github.com/hashicorp/vault/sdk v0.6.0 h1:6Z+In5DXHiUfZvIZdMx7e2loL1PPyDjA4bVh9ZTIAhs=
|
||||
github.com/hashicorp/yamux v0.1.0 h1:DzDIF6Sd7GD2sX0kDFpHAsJMY4L+OfTvtuaQsOYXxzk=
|
||||
github.com/heketi/heketi v10.3.0+incompatible h1:X4DBFPzcyWZWhia32d94UhDECQJHH0M5kpRb1gxxUHk=
|
||||
github.com/heketi/tests v0.0.0-20151005000721-f3775cbcefd6 h1:oJ/NLadJn5HoxvonA6VxG31lg0d6XOURNA09BTtM4fY=
|
||||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639 h1:mV02weKRL81bEnm8A0HT1/CAelMQDBuQIfLw8n+d6xI=
|
||||
github.com/intel/goresctrl v0.2.0 h1:JyZjdMQu9Kl/wLXe9xA6s1X+tF6BWsQPFGJMEeCfWzE=
|
||||
github.com/ishidawataru/sctp v0.0.0-20190723014705-7c296d48a2b5 h1:qPmlgoeRS18y2dT+iAH5vEKZgIqgiPi2Y8UCu/b7Aq8=
|
||||
github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56 h1:742eGXur0715JMq73aD95/FU0XpVKXqNuTnEfXsLOYQ=
|
||||
github.com/jellydator/ttlcache/v2 v2.11.1 h1:AZGME43Eh2Vv3giG6GeqeLeFXxwxn1/qHItqWZl6U64=
|
||||
github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA=
|
||||
github.com/jhump/protoreflect v1.12.0 h1:1NQ4FpWMgn3by/n1X0fbeKEUxP1wBt7+Oitpv01HR10=
|
||||
github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g=
|
||||
github.com/joefitzgerald/rainbow-reporter v0.1.0 h1:AuMG652zjdzI0YCCnXAqATtRBpGXMcAnrajcaTrSeuo=
|
||||
github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9qUBdQ=
|
||||
github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA=
|
||||
github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o=
|
||||
github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U=
|
||||
github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213 h1:qGQQKEcAR99REcMpsXCp3lJ03zYT1PkRd3kQGPn9GVg=
|
||||
github.com/karrick/godirwalk v1.16.1 h1:DynhcF+bztK8gooS0+NDJFrdNZjJ3gzVzC545UNA9iw=
|
||||
github.com/kisielk/errcheck v1.5.0 h1:e8esj/e4R+SAOwFwN+n3zr0nYeCyeweozKfO23MvHzY=
|
||||
github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY=
|
||||
github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw=
|
||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 h1:SOEGU9fKiNWd/HOJuq6+3iTQz8KNCLtVX6idSoTLdUw=
|
||||
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 h1:P6pPBnrTSX3DEVR4fDembhRWSsG5rVo6hYhAB/ADZrk=
|
||||
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
|
||||
github.com/letsencrypt/challtestsrv v1.2.1 h1:Lzv4jM+wSgVMCeO5a/F/IzSanhClstFMnX6SfrAJXjI=
|
||||
github.com/letsencrypt/pkcs11key/v4 v4.0.0 h1:qLc/OznH7xMr5ARJgkZCCWk+EomQkiNTOoOF5LAgagc=
|
||||
github.com/lib/pq v1.10.6 h1:jbk+ZieJ0D7EVGJYpL9QTz7/YW6UHbmdnZWYyK5cdBs=
|
||||
github.com/libopenstorage/openstorage v1.0.0 h1:GLPam7/0mpdP8ZZtKjbfcXJBTIA/T1O6CBErVEFEyIM=
|
||||
github.com/linuxkit/virtsock v0.0.0-20201010232012-f8cee7dfc7a3 h1:jUp75lepDg0phMUJBCmvaeFDldD2N3S1lBuPwUTszio=
|
||||
github.com/lpabon/godbc v0.1.1 h1:ilqjArN1UOENJJdM34I2YHKmF/B0gGq4VLoSGy9iAao=
|
||||
github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls=
|
||||
github.com/marstr/guid v1.1.0 h1:/M4H/1G4avsieL6BbUwCOBzulmoeKVP5ux/3mQNnbyI=
|
||||
github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
|
||||
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.2/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||
github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2 h1:g+4J5sZg6osfvEfkRZxJ1em0VT95/UOZgi/l7zi1/oE=
|
||||
github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA=
|
||||
github.com/mindprince/gonvml v0.0.0-20190828220739-9ebdce4bb989 h1:PS1dLCGtD8bb9RPKJrc8bS7qHL6JnW1CZvwzH9dPoUs=
|
||||
github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible h1:aKW/4cBs+yK6gpqU3K/oIwk9Q/XICqd3zOX/UFuvqmk=
|
||||
github.com/mitchellh/cli v1.0.0 h1:iGBIsUe3+HZ/AD/Vd7DErOt5sU9fa8Uj7A2s1aggv1Y=
|
||||
github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU=
|
||||
github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0=
|
||||
github.com/mitchellh/gox v0.4.0 h1:lfGJxY7ToLJQjHHwi0EX6uYBdK78egf954SQl13PQJc=
|
||||
github.com/mitchellh/iochan v1.0.0 h1:C+X3KsSTLFVBr/tK1eYN/vs4rJcvsiLU338UhYPJWeY=
|
||||
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/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f h1:2+myh5ml7lgEU/51gbeLHfKGNfgEQQIWrlbdaOsidbQ=
|
||||
github.com/mndrix/tap-go v0.0.0-20171203230836-629fa407e90b h1:Ga1nclDSe8gOw37MVLMhfu2QKWtD6gvtQ298zsKVh8g=
|
||||
github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8=
|
||||
github.com/moby/sys/signal v0.6.0 h1:aDpY94H8VlhTGa9sNYUFCFsMZIUh5wm0B6XkIoJj/iY=
|
||||
github.com/moby/sys/symlink v0.2.0 h1:tk1rOM+Ljp0nFmfOIBtlV3rTDlWOwFRhjEeAhZB0nZc=
|
||||
github.com/mohae/deepcopy v0.0.0-20170603005431-491d3605edfb h1:e+l77LJOEqXTIQihQJVkA6ZxPOUmfPM5e4H7rcpgtSk=
|
||||
github.com/mrunalp/fileutils v0.5.0 h1:NKzVxiH7eSk+OQ4M+ZYW1K6h27RUV3MI6NUTsHhU6Z4=
|
||||
github.com/mvdan/xurls v1.1.0 h1:OpuDelGQ1R1ueQ6sSryzi6P+1RtBpfQHM8fJwlE45ww=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU=
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus=
|
||||
github.com/ncw/swift v1.0.47 h1:4DQRPj35Y41WogBxyhOXlrI37nzGlyEcsforeudyYPQ=
|
||||
github.com/networkplumbing/go-nft v0.2.0 h1:eKapmyVUt/3VGfhYaDos5yeprm+LPt881UeksmKKZHY=
|
||||
github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA=
|
||||
github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4=
|
||||
github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkAt4OrFo=
|
||||
github.com/onsi/ginkgo/v2 v2.5.0/go.mod h1:Luc4sArBICYCS8THh8v3i3i5CuSZO+RaQRaJoeNwomw=
|
||||
github.com/onsi/ginkgo/v2 v2.6.0/go.mod h1:63DOGlLAH8+REH8jUGdL3YpCpu7JODesutUjdENfUAc=
|
||||
github.com/onsi/gomega v1.24.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg=
|
||||
github.com/openconfig/goyang v0.0.0-20200115183954-d0a48929f0ea h1:5MyIz4bN4vpH6aHDN339bkWXAjTkhg1ZKMhR4aIi5Rk=
|
||||
github.com/openconfig/grpctunnel v0.0.0-20220819142823-6f5422b8ca70 h1:t6SvvdfWCMlw0XPlsdxO8EgO+q/fXnTevDjdYREKFwU=
|
||||
github.com/openconfig/ygot v0.6.0 h1:kJJFPBrczC6TDnz/HMlFTJEdW2CuyUftV13XveIukg0=
|
||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c h1:Lgl0gzECD8GnQ5QCWA8o6BtfL6mDH5rQgM4/fX3avOs=
|
||||
github.com/pierrec/lz4 v2.6.1+incompatible h1:9UY3+iC23yxF0UfGaYrGplQ+79Rg+h/q9FV9ix19jjM=
|
||||
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e h1:aoZm08cpOy4WuID//EZDgcC4zIxODThtZNPirFr42+A=
|
||||
github.com/posener/complete v1.1.1 h1:ccV59UEOTzVDnDUEFdT95ZzHVZ+5+158q8+SJb2QV5w=
|
||||
github.com/pquerna/cachecontrol v0.1.0 h1:yJMy84ti9h/+OEWa752kBTKv4XC30OtVVHYv/8cTqKc=
|
||||
github.com/prometheus/tsdb v0.7.1 h1:YZcsG11NqnK4czYLrWd9mpEuAJIHVQLwdrleYfszMAA=
|
||||
github.com/protocolbuffers/txtpbfmt v0.0.0-20220608084003-fc78c767cd6a h1:AKJY61V2SQtJ2a2PdeswKk0NM1qF77X+julRNYRxPOk=
|
||||
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
|
||||
github.com/rogpeppe/fastuuid v1.2.0 h1:Ppwyp6VYCF1nvBTXL3trRso7mXMlRrw9ooo375wvi2s=
|
||||
github.com/rubenv/sql-migrate v1.1.1 h1:haR5Hn8hbW9/SpAICrXoZqXnywS7Q5WijwkQENPeNWY=
|
||||
github.com/rubiojr/go-vhd v0.0.0-20200706105327-02e210299021 h1:if3/24+h9Sq6eDx8UUz1SO9cT9tizyIsATfB7b4D3tc=
|
||||
github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww=
|
||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f h1:UFr9zpz4xgTnIE5yIMtWAMngCdZ9p/+q6lTbgelo80M=
|
||||
github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk=
|
||||
github.com/safchain/ethtool v0.0.0-20210803160452-9aa261dae9b1 h1:ZFfeKAhIQiiOrQaI3/znw0gOmYpO28Tcu1YaqMa/jtQ=
|
||||
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
|
||||
github.com/sclevine/spec v1.2.0 h1:1Jwdf9jSfDl9NVmt8ndHqbTZ7XCCPbh1jI3hkDBHVYA=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I=
|
||||
github.com/secure-systems-lab/go-securesystemslib v0.4.0 h1:b23VGrQhTA8cN2CbBw7/FulN9fTtqYUdS5+Oxzt+DUE=
|
||||
github.com/segmentio/ksuid v1.0.4 h1:sBo2BdShXjmcugAMwjugoGUdUV0pcxY5mW4xKRn3v4c=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
|
||||
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EEf9cgbU6AtGPK4CTG3Zf6CKMNqf0MHTggAUA=
|
||||
github.com/slok/kubewebhook/v2 v2.2.0 h1:pOrFBTp6hnO0zakRfR9rd5WDRGiUimerNfR/JoNg1uI=
|
||||
github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ=
|
||||
github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY=
|
||||
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
|
||||
github.com/spf13/viper v1.8.1 h1:Kq1fyeebqsBfbjZj4EL7gj2IO0mMaiyjYUWcUsl2O44=
|
||||
github.com/stoewer/go-strcase v1.2.0 h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ainaU=
|
||||
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
|
||||
github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d h1:vfofYNRScrDdvS342BElfbETmL1Aiz3i2t0zfRj16Hs=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 h1:uruHq4dN7GR16kFc5fp3d1RIYzJW5onx8Ybykw2YQFA=
|
||||
github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
|
||||
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
|
||||
github.com/urfave/cli v1.22.4 h1:u7tSpNPPswAFymm8IehJhy4uJMlUuU/GmqSkvJ1InXA=
|
||||
github.com/urfave/negroni v1.0.0 h1:kIimOitoypq34K7TG7DUaJ9kq/N4Ofuwi1sjz0KipXc=
|
||||
github.com/vmihailenco/msgpack/v4 v4.3.12 h1:07s4sz9IReOgdikxLTKNbBdqDMLsjPKXwvCazn8G65U=
|
||||
github.com/vmware/govmomi v0.20.3 h1:gpw/0Ku+6RgF3jsi7fnCLmlcikBHfKBCUcu1qgc16OU=
|
||||
github.com/weppos/publicsuffix-go v0.15.1-0.20220413065649-906f534b73a4 h1:yjlKwqH2cVMLWnKXtpTIIJ1Rq9fEGqcUh6ukfJAGTo4=
|
||||
github.com/willf/bitset v1.1.11 h1:N7Z7E9UvjW+sGsEl7k/SJrvY2reP1A07MrGuCjIOjRE=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8=
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77 h1:ESFSdwYZvkeru3RtdrYueztKhOBCSAAzS4Gf+k0tEow=
|
||||
github.com/ysmood/goob v0.4.0 h1:HsxXhyLBeGzWXnqVKtmT9qM7EuVs/XOgkX7T6r1o1AQ=
|
||||
github.com/ysmood/gson v0.7.2 h1:1iWUvpi5DPvd2j59W7ifRPR9DiAZ3Ga+fmMl1mJrRbM=
|
||||
github.com/ysmood/leakless v0.8.0 h1:BzLrVoiwxikpgEQR0Lk8NyBN5Cit2b1z+u0mgL4ZJak=
|
||||
github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE=
|
||||
github.com/zmap/zcrypto v0.0.0-20210811211718-6f9bc4aff20f h1:MzfKzJlHUwLuo5aFqBY5PHBoJRdTCiUpyieQ2NC82kM=
|
||||
github.com/zmap/zlint/v3 v3.3.1-0.20211019173530-cb17369b4628 h1:KdHxmTxFmsKE8BGa5/JP7RuNgyNya4VoB15cnHDYWpw=
|
||||
go.etcd.io/etcd/api/v3 v3.5.4 h1:OHVyt3TopwtUQ2GKdd5wu3PmmipR4FTwCqoEjSyRdIc=
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.4 h1:lrneYvz923dvC14R54XcA7FXoZ3mlGZAgmwhfm7HqOg=
|
||||
go.etcd.io/etcd/client/v2 v2.305.4 h1:Dcx3/MYyfKcPNLpR4VVQUP5KgYrBeJtktBwEKkw08Ao=
|
||||
go.etcd.io/etcd/client/v3 v3.5.4 h1:p83BUL3tAYS0OT/r0qglgc3M1JjhM0diV8DSWAhVXv4=
|
||||
go.etcd.io/etcd/pkg/v3 v3.5.4 h1:V5Dvl7S39ZDwjkKqJG2BfXgxZ3QREqqKifWQgIw5IM0=
|
||||
go.etcd.io/etcd/raft/v3 v3.5.4 h1:YGrnAgRfgXloBNuqa+oBI/aRZMcK/1GS6trJePJ/Gqc=
|
||||
go.etcd.io/etcd/server/v3 v3.5.4 h1:CMAZd0g8Bn5NRhynW6pKhc4FRg41/0QYy3d7aNm9874=
|
||||
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
||||
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
||||
go.opentelemetry.io/contrib v0.20.0 h1:ubFQUn0VCZ0gPwIoJfBJVpeBlyRMxu8Mm/huKWYd9p0=
|
||||
go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful v0.20.0 h1:8YW+SL62UmcwRQJFZVfnyOlIUUtmlR13NaMKi+Fa6Fo=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.28.0 h1:Ky1MObd188aGbgb5OgNnwGuEEwI9MVIcc7rBW6zk5Ak=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.28.0/go.mod h1:vEhqr0m4eTc+DWxfsXoXue2GBgV2uUwVznkGIHW/e5w=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.27.0 h1:0BgiNWjN7rUWO9HdjF4L12r8OW86QkVQcYmCjnayJLo=
|
||||
go.opentelemetry.io/contrib/propagators v0.19.0 h1:HrixVNZYFjUl/Db+Tr3DhqzLsVW9GeVf/Gye+C5dNUY=
|
||||
go.opentelemetry.io/otel v1.3.0 h1:APxLf0eiBwLl+SOXiJJCVYzA1OOJNyAoV8C5RNRyy7Y=
|
||||
go.opentelemetry.io/otel v1.3.0/go.mod h1:PWIKzi6JCp7sM0k9yZ43VX+T345uNbAkDKwHVjb2PTs=
|
||||
go.opentelemetry.io/otel/exporters/otlp v0.20.0 h1:PTNgq9MRmQqqJY0REVbZFvwkYOA85vbdQU/nVfxDyqg=
|
||||
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.3.0 h1:R/OBkMoGgfy2fLhs2QhkCI1w4HLEQX92GCcJB6SSdNk=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.3.0 h1:giGm8w67Ja7amYNfYMdme7xSp2pIxThWopw8+QP51Yk=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.3.0 h1:VQbUHoJqytHHSJ1OZodPH9tvZZSVzUHjPHpkO85sT6k=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.3.0 h1:Ydage/P0fRrSPpZeCVxzjqGcI6iVmG2xb43+IR8cjqM=
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.2.0 h1:OiYdrCq1Ctwnovp6EofSPwlp5aGy4LgKNbkg7PtEUw8=
|
||||
go.opentelemetry.io/otel/internal/metric v0.25.0 h1:w/7RXe16WdPylaIXDgcYM6t/q0K5lXgSdZOEbIEyliE=
|
||||
go.opentelemetry.io/otel/metric v0.25.0 h1:7cXOnCADUsR3+EOqxPaSKwhEuNu0gz/56dRN1hpIdKw=
|
||||
go.opentelemetry.io/otel/oteltest v0.20.0 h1:HiITxCawalo5vQzdHfKeZurV8x7ljcqAgiWzF6Vaeaw=
|
||||
go.opentelemetry.io/otel/sdk v1.3.0 h1:3278edCoH89MEJ0Ky8WQXVmDQv3FX4ZJ3Pp+9fJreAI=
|
||||
go.opentelemetry.io/otel/sdk v1.3.0/go.mod h1:rIo4suHNhQwBIPg9axF8V9CA72Wz2mKF1teNrup8yzs=
|
||||
go.opentelemetry.io/otel/sdk/export/metric v0.20.0 h1:c5VRjxCXdQlx1HjzwGdQHzZaVI82b5EbBgOu2ljD92g=
|
||||
go.opentelemetry.io/otel/sdk/metric v0.20.0 h1:7ao1wpzHRVKf0OQ7GIxiQJA6X7DLX9o14gmVon7mMK8=
|
||||
go.opentelemetry.io/otel/trace v1.3.0 h1:doy8Hzb1RJ+I3yFhtDmwNc7tIyw1tNMOIsyPzp1NOGY=
|
||||
go.opentelemetry.io/otel/trace v1.3.0/go.mod h1:c/VDhno8888bvQYmbYLqe41/Ldmr/KKunbvWM4/fEjk=
|
||||
go.opentelemetry.io/proto/otlp v0.11.0 h1:cLDgIBTf4lLOlztkhzAEdQsJ4Lj+i5Wc9k6Nn0K1VyU=
|
||||
go.opentelemetry.io/proto/otlp v0.11.0/go.mod h1:QpEjXPrNQzrFDZgoTo49dgHR9RYRSrg3NAKnUGl9YpQ=
|
||||
golang.org/x/exp v0.0.0-20210220032938-85be41e4509f h1:GrkO5AtFUU9U/1f5ctbIBXtBGeSJbWwIYfIsTcFMaX4=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDArnOixOzGD9HUJfcg0mb4=
|
||||
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug=
|
||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028 h1:4+4C/Iv2U4fMZBiMCc98MG1In4gJY5YRhtpDNeDeHWs=
|
||||
golang.org/x/mod v0.6.0 h1:b9gGHsz9/HhJ3HF5DHQytPpuwocVTChQJK3AvoLRD5I=
|
||||
golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI=
|
||||
golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
|
||||
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
||||
golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
|
||||
golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
|
||||
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/tools v0.2.0 h1:G6AHpWxTMGY1KyEYoAQ5WTtIekUUvDNjan3ugu60JvE=
|
||||
golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA=
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk=
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
|
||||
gomodules.xyz/jsonpatch/v3 v3.0.1 h1:Te7hKxV52TKCbNYq3t84tzKav3xhThdvSsSp/W89IyI=
|
||||
gomodules.xyz/orderedmap v0.1.0 h1:fM/+TGh/O1KkqGR5xjTKg6bU8OKBkg7p0Y+x/J9m8Os=
|
||||
gonum.org/v1/gonum v0.6.2 h1:4r+yNT0+8SWcOkXP+63H2zQbN+USnC73cjGUxnDF94Q=
|
||||
gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e h1:jRyg0XfpwWlhEV8mDfdNGBeSJM2fuyh9Yjrnd8kF2Ts=
|
||||
google.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB7a70=
|
||||
google.golang.org/api v0.102.0/go.mod h1:3VFl6/fzoA+qNuS1N1/VfXY4LjoXN/wzeIp7TweWwGo=
|
||||
google.golang.org/api v0.103.0 h1:9yuVqlu2JCvcLg9p8S3fcFLZij8EPSyvODIY1rkMizQ=
|
||||
google.golang.org/api v0.103.0/go.mod h1:hGtW6nK1AC+d9si/UBhw8Xli+QMOf6xyNAyJw4qU9w0=
|
||||
google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8 h1:Cpp2P6TPjujNoC5M2KHY6g7wfyLYfIWRZaSdIKfDasA=
|
||||
google.golang.org/genproto v0.0.0-20221027153422-115e99e71e1c/go.mod h1:CGI5F/G+E5bKwmfYo09AXuVN4dD894kIKUFmVbP2/Fo=
|
||||
google.golang.org/genproto v0.0.0-20221202195650-67e5cbc046fd h1:OjndDrsik+Gt+e6fs45z9AxiewiKyLKYpA45W5Kpkks=
|
||||
google.golang.org/genproto v0.0.0-20221202195650-67e5cbc046fd/go.mod h1:cTsE614GARnxrLsqKREzmNYJACSWWpAWdNMwnD7c2BE=
|
||||
google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 h1:M1YKkFIboKNieVO5DLUEVzQfGwJD30Nv2jfUgzb5UcE=
|
||||
gopkg.in/airbrake/gobrake.v2 v2.0.9 h1:7z2uVWwn7oVeeugY1DtlPAy5H+KYgB1KeKTnqjNatLo=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/errgo.v2 v2.1.0 h1:0vLT13EuvQ0hNvakwLuFZ/jYrLp5F3kcWHXdRggjCE8=
|
||||
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||
gopkg.in/gcfg.v1 v1.2.0 h1:0HIbH907iBTAntm+88IJV2qmJALDAh8sPekI9Vc1fm0=
|
||||
gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2 h1:OAj3g0cR6Dx/R07QgQe8wkA9RNjB2u4i700xBkIT4e0=
|
||||
gopkg.in/resty.v1 v1.12.0 h1:CuXP0Pjfw9rOuY6EP+UvtNvt5DSqHpIxILZKT/quCZI=
|
||||
gopkg.in/warnings.v0 v0.1.1 h1:XM28wIgFzaBmeZ5dNHIpWLQpt/9DGKxk+rCg/22nnYE=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4 h1:UoveltGrhghAA7ePc+e+QYDHXrBps2PqFZiHkGR/xK8=
|
||||
k8s.io/cloud-provider v0.25.6 h1:xxJg78XIeotzLRaXlk8HgZ+OsOWy5uBmDCkErGtgkl0=
|
||||
k8s.io/code-generator v0.25.6 h1:md8jqhQiMqos8WaTY0ZxhDk8ttlmJl/ijCneJ8ahBNQ=
|
||||
k8s.io/controller-manager v0.25.6 h1:m6TOcxj20Na0mBg3d8596XdEsgdGwa0Fp36YsgS1G5o=
|
||||
k8s.io/csi-translation-lib v0.25.6 h1:MnMgkTkhYfkyq4r9Bcem3TCjxZdlbSoyphZygJqoToE=
|
||||
k8s.io/gengo v0.0.0-20211129171323-c02415ce4185 h1:TT1WdmqqXareKxZ/oNXEUSwKlLiHzPMyB0t8BaFeBYI=
|
||||
k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8=
|
||||
k8s.io/kube-aggregator v0.25.6 h1:+8OPm8EAD98Vguqdz5mWQ0dMqa5A9QUtspGYDjWAwvY=
|
||||
k8s.io/kube-controller-manager v0.25.6 h1:FKYRr7lmvOZNDQlXJk3WhhBVG+hchWaFuubtNGMC1sA=
|
||||
k8s.io/kube-scheduler v0.25.6 h1:Wbxc1u8I6CWhi48vINZl1AJ9R7LEKX5PAqJomlknd7I=
|
||||
k8s.io/kubectl v0.25.6 h1:uGoNw4vF+O62NTwRqM40gMCEI5ujw2g0ocT6dDPt55c=
|
||||
k8s.io/legacy-cloud-providers v0.25.6 h1:r0b+6jCmB7YiF79xrUTTFUJ40Q85wxhe4yhQ9/cIVMg=
|
||||
k8s.io/metrics v0.25.6 h1:EezfQTfTsSW/Cs9oHJXAftRlbL0fnHfDh02ObTOs/34=
|
||||
k8s.io/mount-utils v0.25.6 h1:7fK5wzp7F93PZiz7RdnvEavRVuoe89yJ+zspy4hrzGc=
|
||||
k8s.io/pod-security-admission v0.25.6 h1:xBoOFwzhi2Yz1m2wURl0v8lu7HBem+vig2ByOlc7UfY=
|
||||
k8s.io/sample-apiserver v0.25.6 h1:3YyQmSBsYK/zXofIEuk0SFTcg0XhXLWo56CSgWDwTk8=
|
||||
k8s.io/system-validators v1.8.0 h1:tq05tdO9zdJZnNF3SXrq6LE7Knc/KfJm5wk68467JDg=
|
||||
rsc.io/binaryregexp v0.2.0 h1:HfqmD5MEmC0zvwBuF187nq9mdnXjXsSivRiXN7SmRkE=
|
||||
rsc.io/quote/v3 v3.1.0 h1:9JKUTTIUgS6kzR9mK1YuGKv6Nl+DijDNIc0ghT58FaY=
|
||||
rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4=
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.35 h1:+xBL5uTc+BkPBwmMi3vYfUJjq+N3K+H6PXeETwf5cPI=
|
||||
sigs.k8s.io/controller-tools v0.6.2 h1:+Y8L0UsAugDipGRw8lrkPoAi6XqlQVZuf1DQHME3PgU=
|
||||
sigs.k8s.io/gateway-api v0.4.0 h1:07IJkTt21NetZTHtPKJk2I4XIgDN4BAlTIq1wK7V11o=
|
||||
sigs.k8s.io/kustomize/kustomize/v4 v4.5.7 h1:cDW6AVMl6t/SLuQaezMET8hgnadZGIAr8tUrxFVOrpg=
|
||||
|
||||
@@ -76,13 +76,13 @@ func checkHostnameUnique(s ssh.Interface, ipList []string) error {
|
||||
func checkTimeSync(s ssh.Interface, ipList []string) error {
|
||||
logger.Info("checker:timeSync %v", ipList)
|
||||
for _, ip := range ipList {
|
||||
timeStamp, err := s.CmdToString(ip, "date +%s", "")
|
||||
timestamp, err := s.CmdToString(ip, "date +%s", "")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get %s timestamp, %v", ip, err)
|
||||
}
|
||||
ts, err := strconv.Atoi(timeStamp)
|
||||
ts, err := strconv.Atoi(timestamp)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to reverse timestamp %s, %v", timeStamp, err)
|
||||
return fmt.Errorf("failed to reverse timestamp %s, %v", timestamp, err)
|
||||
}
|
||||
timeDiff := time.Since(time.Unix(int64(ts), 0)).Minutes()
|
||||
if timeDiff < -1 || timeDiff > 1 {
|
||||
|
||||
@@ -105,7 +105,7 @@ metadata:
|
||||
spec:
|
||||
amount: 6 //需要支付的金额
|
||||
owner: b257ee11-5e85-4e3f-b1e4-4fa291dcdfd6
|
||||
timeStamp: 1672031381
|
||||
timestamp: 1672031381
|
||||
status:
|
||||
status: complete //已支付
|
||||
```
|
||||
@@ -238,7 +238,7 @@ metadata:
|
||||
spec:
|
||||
amount: 1 //需要支付的金额大小
|
||||
owner: b257ee11-5e85-4e3f-b1e4-4fa291dcdfd6 //用户名字
|
||||
timeStamp: 1672031381
|
||||
timestamp: 1672031381
|
||||
```
|
||||
|
||||
#### 4.4、扣费过程:
|
||||
|
||||
Vendored
+2
@@ -16,12 +16,14 @@ package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
func EnsureNamespace(name string) *v1.Namespace {
|
||||
defer time.Sleep(time.Second * 2)
|
||||
client := GetDefaultKubernetesClient()
|
||||
ns, err := client.CoreV1().Namespaces().Get(context.TODO(), name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user