@@ -158,7 +158,8 @@ func run(s *options.KubeSphereControllerManagerOptions, stopCh <-chan struct{})
|
||||
kubernetesClient.KubeSphere(),
|
||||
kubernetesClient.Istio(),
|
||||
kubernetesClient.Snapshot(),
|
||||
kubernetesClient.ApiExtensions())
|
||||
kubernetesClient.ApiExtensions(),
|
||||
kubernetesClient.Prometheus())
|
||||
|
||||
mgrOptions := manager.Options{
|
||||
CertDir: s.WebhookCertDir,
|
||||
|
||||
@@ -32,6 +32,7 @@ import (
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/cache"
|
||||
runtimecache "sigs.k8s.io/controller-runtime/pkg/cache"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/customalerting"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/devops/jenkins"
|
||||
eventsclient "kubesphere.io/kubesphere/pkg/simple/client/events/elasticsearch"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
|
||||
@@ -82,6 +83,7 @@ func (s *ServerRunOptions) Flags() (fss cliflag.NamedFlagSets) {
|
||||
s.MultiClusterOptions.AddFlags(fss.FlagSet("multicluster"), s.MultiClusterOptions)
|
||||
s.EventsOptions.AddFlags(fss.FlagSet("events"), s.EventsOptions)
|
||||
s.AuditingOptions.AddFlags(fss.FlagSet("auditing"), s.AuditingOptions)
|
||||
s.CustomAlertingOptions.AddFlags(fss.FlagSet("customalerting"), s.CustomAlertingOptions)
|
||||
|
||||
fs = fss.FlagSet("klog")
|
||||
local := flag.NewFlagSet("klog", flag.ExitOnError)
|
||||
@@ -109,7 +111,7 @@ func (s *ServerRunOptions) NewAPIServer(stopCh <-chan struct{}) (*apiserver.APIS
|
||||
apiServer.KubernetesClient = kubernetesClient
|
||||
|
||||
informerFactory := informers.NewInformerFactories(kubernetesClient.Kubernetes(), kubernetesClient.KubeSphere(),
|
||||
kubernetesClient.Istio(), kubernetesClient.Snapshot(), kubernetesClient.ApiExtensions())
|
||||
kubernetesClient.Istio(), kubernetesClient.Snapshot(), kubernetesClient.ApiExtensions(), kubernetesClient.Prometheus())
|
||||
apiServer.InformerFactory = informerFactory
|
||||
|
||||
if s.MonitoringOptions == nil || len(s.MonitoringOptions.Endpoint) == 0 {
|
||||
@@ -199,6 +201,14 @@ func (s *ServerRunOptions) NewAPIServer(stopCh <-chan struct{}) (*apiserver.APIS
|
||||
apiServer.OpenpitrixClient = opClient
|
||||
}
|
||||
|
||||
if s.CustomAlertingOptions != nil {
|
||||
customAlertingClient, err := customalerting.NewRuleClient(s.CustomAlertingOptions)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to init custom alerting client")
|
||||
}
|
||||
apiServer.CustomAlertingClient = customAlertingClient
|
||||
}
|
||||
|
||||
server := &http.Server{
|
||||
Addr: fmt.Sprintf(":%d", s.GenericServerRunOptions.InsecurePort),
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ func (s *ServerRunOptions) Validate() []error {
|
||||
errors = append(errors, s.AuthorizationOptions.Validate()...)
|
||||
errors = append(errors, s.EventsOptions.Validate()...)
|
||||
errors = append(errors, s.AuditingOptions.Validate()...)
|
||||
errors = append(errors, s.CustomAlertingOptions.Validate()...)
|
||||
|
||||
return errors
|
||||
}
|
||||
|
||||
42
go.mod
42
go.mod
@@ -8,10 +8,9 @@ go 1.13
|
||||
|
||||
require (
|
||||
code.cloudfoundry.org/bytefmt v0.0.0-20190710193110-1eb035ffe2b6
|
||||
github.com/NYTimes/gziphandler v1.1.1 // indirect
|
||||
github.com/PuerkitoBio/goquery v1.5.0
|
||||
github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496
|
||||
github.com/aws/aws-sdk-go v1.30.12
|
||||
github.com/aws/aws-sdk-go v1.33.12
|
||||
github.com/beevik/etree v1.1.0
|
||||
github.com/container-storage-interface/spec v1.2.0
|
||||
github.com/containernetworking/cni v0.8.0
|
||||
@@ -26,6 +25,7 @@ require (
|
||||
github.com/emicklei/go-restful-openapi v1.4.1
|
||||
github.com/emirpasic/gods v1.12.0 // indirect
|
||||
github.com/fatih/structs v1.1.0
|
||||
github.com/ghodss/yaml v1.0.0
|
||||
github.com/go-ldap/ldap v3.0.3+incompatible
|
||||
github.com/go-logr/logr v0.1.0
|
||||
github.com/go-logr/zapr v0.1.1 // indirect
|
||||
@@ -39,15 +39,13 @@ require (
|
||||
github.com/golang/example v0.0.0-20170904185048-46695d81d1fa
|
||||
github.com/golang/mock v1.4.3
|
||||
github.com/golang/protobuf v1.4.2
|
||||
github.com/google/go-cmp v0.4.0
|
||||
github.com/google/go-querystring v1.0.0 // indirect
|
||||
github.com/google/go-cmp v0.5.0
|
||||
github.com/google/uuid v1.1.1
|
||||
github.com/gorilla/websocket v1.4.1
|
||||
github.com/json-iterator/go v1.1.10
|
||||
github.com/kelseyhightower/envconfig v1.4.0 // indirect
|
||||
github.com/kubernetes-csi/external-snapshotter/client/v3 v3.0.0
|
||||
github.com/kubesphere/sonargo v0.0.2
|
||||
github.com/lib/pq v1.2.0 // indirect
|
||||
github.com/mitchellh/mapstructure v1.2.2
|
||||
github.com/onsi/ginkgo v1.14.0
|
||||
github.com/onsi/gomega v1.10.1
|
||||
@@ -58,9 +56,11 @@ require (
|
||||
github.com/projectcalico/kube-controllers v3.8.8+incompatible
|
||||
github.com/projectcalico/libcalico-go v1.7.2-0.20191104213956-8f81e1e344ce
|
||||
github.com/prometheus-community/prom-label-proxy v0.2.0
|
||||
github.com/prometheus-operator/prometheus-operator v0.42.2-0.20200928114327-fbd01683839a
|
||||
github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.42.1
|
||||
github.com/prometheus/client_golang v1.7.1
|
||||
github.com/prometheus/common v0.10.0
|
||||
github.com/prometheus/prometheus v1.8.2-0.20200507164740-ecee9c8abfd1
|
||||
github.com/prometheus/common v0.11.1
|
||||
github.com/prometheus/prometheus v1.8.2-0.20200907175821-8219b442c864
|
||||
github.com/sony/sonyflake v1.0.0
|
||||
github.com/speps/go-hashids v2.0.0+incompatible
|
||||
github.com/spf13/cobra v1.0.0
|
||||
@@ -68,15 +68,15 @@ require (
|
||||
github.com/spf13/viper v1.4.0
|
||||
github.com/stretchr/testify v1.6.1
|
||||
github.com/xanzy/ssh-agent v0.2.1 // indirect
|
||||
golang.org/x/crypto v0.0.0-20200422194213-44a606286825
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7
|
||||
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
|
||||
google.golang.org/grpc v1.29.0
|
||||
google.golang.org/grpc v1.30.0
|
||||
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d // indirect
|
||||
gopkg.in/src-d/go-billy.v4 v4.3.0 // indirect
|
||||
gopkg.in/src-d/go-git.v4 v4.11.0
|
||||
gopkg.in/yaml.v2 v2.3.0
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776
|
||||
gotest.tools v2.2.0+incompatible
|
||||
istio.io/api v0.0.0-20201113182140-d4b7e3fc2b44
|
||||
istio.io/client-go v0.0.0-20201113183938-0734e976e785
|
||||
@@ -86,7 +86,7 @@ require (
|
||||
k8s.io/apimachinery v0.19.0
|
||||
k8s.io/apiserver v0.18.6
|
||||
k8s.io/cli-runtime v0.18.6
|
||||
k8s.io/client-go v0.19.0
|
||||
k8s.io/client-go v12.0.0+incompatible
|
||||
k8s.io/code-generator v0.19.0
|
||||
k8s.io/component-base v0.18.6
|
||||
k8s.io/klog v1.0.0
|
||||
@@ -494,42 +494,37 @@ replace (
|
||||
github.com/rcrowley/go-metrics => github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a
|
||||
github.com/retailnext/hllpp => github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52
|
||||
github.com/robfig/cron => github.com/robfig/cron v1.2.0
|
||||
github.com/rogpeppe/fastuuid => github.com/rogpeppe/fastuuid v1.2.0
|
||||
github.com/rogpeppe/fastuuid => github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af
|
||||
github.com/rogpeppe/go-charset => github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4
|
||||
github.com/rogpeppe/go-internal => github.com/rogpeppe/go-internal v1.3.0
|
||||
github.com/rs/cors => github.com/rs/cors v1.6.0
|
||||
github.com/russross/blackfriday => github.com/russross/blackfriday v1.5.2
|
||||
github.com/russross/blackfriday/v2 => github.com/russross/blackfriday/v2 v2.0.1
|
||||
github.com/ryanuber/columnize => github.com/ryanuber/columnize v2.1.0+incompatible
|
||||
github.com/samuel/go-zookeeper => github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da
|
||||
github.com/satori/go.uuid => github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b
|
||||
github.com/satori/go.uuid => github.com/satori/go.uuid v1.2.0
|
||||
github.com/sean-/seed => github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529
|
||||
github.com/segmentio/kafka-go => github.com/segmentio/kafka-go v0.2.0
|
||||
github.com/sergi/go-diff => github.com/sergi/go-diff v1.0.0
|
||||
github.com/shirou/gopsutil => github.com/shirou/gopsutil v0.0.0-20180427012116-c95755e4bcd7
|
||||
github.com/shirou/w32 => github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4
|
||||
github.com/shurcooL/httpfs => github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749
|
||||
github.com/shurcooL/sanitized_anchor_name => github.com/shurcooL/sanitized_anchor_name v1.0.0
|
||||
github.com/shurcooL/vfsgen => github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd
|
||||
github.com/sirupsen/logrus => github.com/sirupsen/logrus v1.4.2
|
||||
github.com/smartystreets/assertions => github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d
|
||||
github.com/smartystreets/goconvey => github.com/smartystreets/goconvey v1.6.4
|
||||
github.com/soheilhy/cmux => github.com/soheilhy/cmux v0.1.4
|
||||
github.com/sony/gobreaker => github.com/sony/gobreaker v0.4.1
|
||||
github.com/sony/sonyflake => github.com/sony/sonyflake v1.0.0
|
||||
github.com/sony/sonyflake => github.com/sony/sonyflake v0.0.0-20181109022403-6d5bd6181009
|
||||
github.com/spaolacci/murmur3 => github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72
|
||||
github.com/speps/go-hashids => github.com/speps/go-hashids v2.0.0+incompatible
|
||||
github.com/spf13/afero => github.com/spf13/afero v1.2.2
|
||||
github.com/spf13/cast => github.com/spf13/cast v1.3.0
|
||||
github.com/spf13/cobra => github.com/spf13/cobra v1.0.0
|
||||
github.com/spf13/cobra => github.com/spf13/cobra v0.0.5
|
||||
github.com/spf13/jwalterweatherman => github.com/spf13/jwalterweatherman v1.0.0
|
||||
github.com/spf13/pflag => github.com/spf13/pflag v1.0.5
|
||||
github.com/spf13/viper => github.com/spf13/viper v1.4.0
|
||||
github.com/src-d/gcfg => github.com/src-d/gcfg v1.4.0
|
||||
github.com/streadway/amqp => github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271
|
||||
github.com/streadway/handy => github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a
|
||||
github.com/stretchr/objx => github.com/stretchr/objx v0.2.0
|
||||
github.com/stretchr/testify => github.com/stretchr/testify v1.6.1
|
||||
github.com/stretchr/testify => github.com/stretchr/testify v1.4.0
|
||||
github.com/tidwall/pretty => github.com/tidwall/pretty v1.0.0
|
||||
github.com/tinylib/msgp => github.com/tinylib/msgp v1.1.0
|
||||
github.com/tmc/grpc-websocket-proxy => github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5
|
||||
@@ -538,8 +533,7 @@ replace (
|
||||
github.com/uber/jaeger-lib => github.com/uber/jaeger-lib v2.2.0+incompatible
|
||||
github.com/ugorji/go => github.com/ugorji/go v1.1.4
|
||||
github.com/ugorji/go/codec => github.com/ugorji/go/codec v0.0.0-20190128213124-ee1426cffec0
|
||||
github.com/urfave/cli => github.com/urfave/cli v1.22.1
|
||||
github.com/vektah/gqlparser => github.com/vektah/gqlparser v1.1.2
|
||||
github.com/urfave/cli => github.com/urfave/cli v1.20.0
|
||||
github.com/willf/bitset => github.com/willf/bitset v1.1.3
|
||||
github.com/xanzy/ssh-agent => github.com/xanzy/ssh-agent v0.2.1
|
||||
github.com/xdg/scram => github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c
|
||||
|
||||
172
go.sum
172
go.sum
@@ -7,22 +7,19 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl
|
||||
code.cloudfoundry.org/bytefmt v0.0.0-20190710193110-1eb035ffe2b6 h1:tW+ztA4A9UT9xnco5wUjW1oNi35k22eUEn9tNpPYVwE=
|
||||
code.cloudfoundry.org/bytefmt v0.0.0-20190710193110-1eb035ffe2b6/go.mod h1:wN/zk7mhREp/oviagqUXY3EwuHhWyOvAdsn5Y4CzOrc=
|
||||
collectd.org v0.3.0/go.mod h1:A/8DzQBkF6abtvrT2j/AU/4tiBgJWYyh0y/oB/4MlWE=
|
||||
github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4=
|
||||
github.com/Azure/azure-pipeline-go v0.2.2/go.mod h1:4rQ/NZncSvGqNkkOsNpOU1tgoNuIlp9AfUH5G1tvCHc=
|
||||
github.com/Azure/azure-sdk-for-go v41.3.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/azure-storage-blob-go v0.8.0/go.mod h1:lPI3aLPpuLTeUwh1sViKXFxwl2B6teiRqI0deQUvsw0=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
||||
github.com/Azure/go-autorest/autorest v0.10.0 h1:mvdtztBqcL8se7MdrUweNieTNi4kfNG6GOJuurQJpuY=
|
||||
github.com/Azure/go-autorest/autorest v0.10.0/go.mod h1:/FALq9T/kS7b5J5qsQ+RSTUdAmGFqi0vUdVNNx8q630=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.8.3 h1:O1AGG9Xig71FxdX9HO5pGNyZ7TbSyHaVg+5eJO/jSGw=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.8.3/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q=
|
||||
github.com/Azure/go-autorest/autorest/date v0.2.0 h1:yW+Zlqf26583pE43KhfnhFcdmSWlm5Ew6bxipnr/tbM=
|
||||
github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.3.0 h1:qJumjCaCudz+OcqE9/XtEPfvtOjOmKaui4EOpFI6zZc=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM=
|
||||
github.com/Azure/go-autorest/autorest/to v0.3.0/go.mod h1:MgwOyqaIuKdG4TL/2ywSsIWKAfJfgHDo8ObuUk3t5sA=
|
||||
github.com/Azure/go-autorest/autorest/validation v0.2.0/go.mod h1:3EEqHnBxQGHXRYq3HT1WyXAvT7LLY3tl70hw6tQIbjI=
|
||||
github.com/Azure/go-autorest/logger v0.1.0 h1:ruG4BSDXONFRrZZJ2GUXDiUyVpayPmb1GnWeHDdaNKY=
|
||||
github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc=
|
||||
github.com/Azure/go-autorest/tracing v0.5.0 h1:TRn4WjSnkcSy5AEG3pnbtFSwNtwzjr4VYyQflFE619k=
|
||||
github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
|
||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
@@ -35,6 +32,7 @@ github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3Q
|
||||
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
|
||||
github.com/Masterminds/semver/v3 v3.0.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
|
||||
github.com/Masterminds/sprig/v3 v3.0.0/go.mod h1:NEUY/Qq8Gdm2xgYA+NwJM6wmfdRV9xkh8h/Rld20R0U=
|
||||
github.com/Masterminds/squirrel v0.0.0-20161115235646-20f192218cf5/go.mod h1:xnKTFzjGUiZtiOagBsfnvomW+nJg2usB1ZpordQWqNM=
|
||||
github.com/Masterminds/vcs v1.13.0/go.mod h1:N09YCmOQr6RLxC6UNHzuVwAdodYbbnycGHSmwVJjcKA=
|
||||
github.com/Microsoft/go-winio v0.4.12 h1:xAfWHN1IrQ0NJ9TBC0KBZoqLjzDTr1ML+4MywiUOryc=
|
||||
github.com/Microsoft/go-winio v0.4.12/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
|
||||
@@ -65,6 +63,7 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy
|
||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2cI+DC1Mbh0TJxzA3RcLoMsFw+aXw7E=
|
||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
|
||||
github.com/alessio/shellescape v1.2.2/go.mod h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30=
|
||||
github.com/aliyun/aliyun-oss-go-sdk v2.0.4+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
|
||||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
|
||||
github.com/andybalholm/cascadia v1.0.0 h1:hOCXnnZ5A+3eVDX8pvgl4kofXv2ELss0bKcqRySc45o=
|
||||
github.com/andybalholm/cascadia v1.0.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
|
||||
@@ -77,6 +76,7 @@ github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hC
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
github.com/armon/go-metrics v0.3.3/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc=
|
||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
||||
github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A=
|
||||
github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496 h1:zV3ejI06GQ59hwDQAvmK1qxOQGB3WuVTRoY0okPTAv0=
|
||||
github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg=
|
||||
@@ -84,11 +84,14 @@ github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQ
|
||||
github.com/aws/aws-sdk-go v1.30.12 h1:KrjyosZvkpJjcwMk0RNxMZewQ47v7+ZkbQDXjWsJMs8=
|
||||
github.com/aws/aws-sdk-go v1.30.12/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
|
||||
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
|
||||
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc=
|
||||
github.com/beevik/etree v1.1.0 h1:T0xke/WvNtMoCqgzPhkX2r4rjY3GDZFi+FjpRZY2Jbs=
|
||||
github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A=
|
||||
github.com/beevik/ntp v0.2.0/go.mod h1:hIHWr+l3+/clUnF44zdK+CWW7fO8dR5cIylAQ76NRpg=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||
github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k=
|
||||
github.com/bitly/go-simplejson v0.5.0 h1:6IH+V8/tVMab511d5bn4M7EwGXZf9Hj6i2xSwkNEM+Y=
|
||||
github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA=
|
||||
github.com/blang/semver v3.5.0+incompatible h1:CGxCgetQ64DKk7rdZ++Vfnb1+ogGNnB17OJKJXD2Cfs=
|
||||
@@ -97,10 +100,13 @@ github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4Yn
|
||||
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
|
||||
github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c=
|
||||
github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
|
||||
github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA=
|
||||
github.com/brancz/kube-rbac-proxy v0.5.0/go.mod h1:cL2VjiIFGS90Cjh5ZZ8+It6tMcBt8rwvuw2J6Mamnl0=
|
||||
github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk=
|
||||
github.com/bugsnag/bugsnag-go v1.5.0/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8=
|
||||
github.com/bugsnag/panicwrap v1.2.0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE=
|
||||
github.com/c-bata/go-prompt v0.2.2/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34=
|
||||
github.com/campoy/embedmd v1.0.0/go.mod h1:oxyr9RCiSXg0M3VJ3ks0UGfp98BpSSGr0kpiX3MzVl8=
|
||||
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
@@ -110,15 +116,20 @@ github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw=
|
||||
github.com/chai2010/jsonmap v1.0.0/go.mod h1:+30HSZixzW7NVqyqXTDyQi0hsexrb6hnpvhuW0bot6s=
|
||||
github.com/chromedp/cdproto v0.0.0-20200116234248-4da64dd111ac/go.mod h1:PfAWWKJqjlGFYJEidUM6aVIWPr0EpobeyVWEEmplX7g=
|
||||
github.com/chromedp/cdproto v0.0.0-20200424080200-0de008e41fa0/go.mod h1:PfAWWKJqjlGFYJEidUM6aVIWPr0EpobeyVWEEmplX7g=
|
||||
github.com/chromedp/chromedp v0.5.3/go.mod h1:YLdPtndaHQ4rCpSpBG+IPpy9JvX0VD+7aaLxYgYj28w=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
|
||||
github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
|
||||
github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
|
||||
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
|
||||
github.com/cockroachdb/cockroach-go v0.0.0-20181001143604-e0a95dfd547c/go.mod h1:XGLbWH/ujMcbPbhZq52Nv6UrCghb1yGn//133kEsvDk=
|
||||
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa h1:OaNxuTZr7kxeODyLWsRMC+OD03aFUH+mW6r2d+MWa5Y=
|
||||
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
|
||||
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd h1:qMd81Ts1T2OTKmB4acZcyKaMtRnY5Y44NuXGX2GFJ1w=
|
||||
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
|
||||
github.com/container-storage-interface/spec v1.2.0 h1:bD9KIVgaVKKkQ/UbVUY9kCaH/CJbhNxe0eeB4JeJV2s=
|
||||
github.com/container-storage-interface/spec v1.2.0/go.mod h1:6URME8mwIBbpVyZV93Ce5St17xBiQJQY67NDsuohiy4=
|
||||
@@ -126,9 +137,7 @@ github.com/containerd/containerd v1.3.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMX
|
||||
github.com/containerd/continuity v0.0.0-20181203112020-004b46473808/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
||||
github.com/containernetworking/cni v0.8.0 h1:BT9lpgGoH4jw3lFC7Odz2prU5ruiYKcgAjMCbgybcKI=
|
||||
github.com/containernetworking/cni v0.8.0/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
|
||||
github.com/coreos/bbolt v1.3.3 h1:n6AiVyVRKQFNb6mJlwESEvvLoDyiTzXX7ORAUlkeBdY=
|
||||
github.com/coreos/bbolt v1.3.3/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
github.com/coreos/etcd v3.3.17+incompatible h1:f/Z3EoDSx1yjaIjLQGo1diYUlQYSBrrAQ5vP8NjwXwo=
|
||||
github.com/coreos/etcd v3.3.17+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
|
||||
github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM=
|
||||
@@ -137,9 +146,22 @@ github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f h1:JOrtw2xFKzlg+
|
||||
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg=
|
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cortexproject/cortex v0.6.1-0.20200228110116-92ab6cbe0995/go.mod h1:3Xa3DjJxtpXqxcMGdk850lcIRb81M0fyY1MQ6udY134=
|
||||
github.com/cortexproject/cortex v1.2.1-0.20200805064754-d8edc95e2c91/go.mod h1:PVPxNLrxKH+yc8asaJOxuz7TiRmMizFfnSMOnRzM6oM=
|
||||
github.com/cortexproject/cortex v1.3.1-0.20200901115931-255ff3306960/go.mod h1:ub8BpRZrRa02BOM8NJTnI2YklxW/mGhEkJDrhsDfcfg=
|
||||
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
|
||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4=
|
||||
github.com/cznic/b v0.0.0-20180115125044-35e9bbe41f07/go.mod h1:URriBxXwVq5ijiJ12C7iIZqlA69nTlI+LgI6/pwftG8=
|
||||
github.com/cznic/fileutil v0.0.0-20180108211300-6a051e75936f/go.mod h1:8S58EK26zhXSxzv7NQFpnliaOQsmDUxvoQO3rt154Vg=
|
||||
github.com/cznic/golex v0.0.0-20170803123110-4ab7c5e190e4/go.mod h1:+bmmJDNmKlhWNG+gwWCkaBoTy39Fs+bzRxVBzoTQbIc=
|
||||
github.com/cznic/internal v0.0.0-20180608152220-f44710a21d00/go.mod h1:olo7eAdKwJdXxb55TKGLiJ6xt1H0/tiiRCWKVLmtjY4=
|
||||
github.com/cznic/lldb v1.1.0/go.mod h1:FIZVUmYUVhPwRiPzL8nD/mpFcJ/G7SSXjjXYG4uRI3A=
|
||||
github.com/cznic/mathutil v0.0.0-20180504122225-ca4c9f2c1369/go.mod h1:e6NPNENfs9mPDVNRekM7lKScauxd5kXTr1Mfyig6TDM=
|
||||
github.com/cznic/ql v1.2.0/go.mod h1:FbpzhyZrqr0PVlK6ury+PoW3T0ODUV22OeWIxcaOrSE=
|
||||
github.com/cznic/sortutil v0.0.0-20150617083342-4c7342852e65/go.mod h1:q2w6Bg5jeox1B+QkJ6Wp/+Vn0G/bo3f1uY7Fn3vivIQ=
|
||||
github.com/cznic/strutil v0.0.0-20171016134553-529a34b1c186/go.mod h1:AHHPPPXTw0h6pVabbcbyGRK1DckRn7r/STdZEeIDzZc=
|
||||
github.com/cznic/zappy v0.0.0-20160723133515-2533cb5b45cc/go.mod h1:Y1SNZ4dRUOKXshKUbwUapqNncRrho4mkjQebgEHZLj8=
|
||||
github.com/dave/jennifer v1.2.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg=
|
||||
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=
|
||||
@@ -152,6 +174,7 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumC
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dgryski/go-bitstream v0.0.0-20180413035011-3522498ce2c8/go.mod h1:VMaSuZ+SZcx/wljOQKvp5srsbCiKDEb6K2wC4+PiBmQ=
|
||||
github.com/dgryski/go-sip13 v0.0.0-20190329191031-25c5027a8c7b/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||
github.com/dhui/dktest v0.3.0/go.mod h1:cyzIUfGsBEbZ6BT7tnXqAShHSXCZhSNmFl70sZ7c1yc=
|
||||
github.com/disintegration/imaging v1.6.1/go.mod h1:xuIt+sRxDFrHS0drzXUlCJthkJ8k7lkkUojDSR247MQ=
|
||||
github.com/docker/cli v0.0.0-20190506213505-d88565df0c2d/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
|
||||
@@ -174,6 +197,7 @@ github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5m
|
||||
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
||||
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
||||
github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts=
|
||||
github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw=
|
||||
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||
github.com/elastic/go-elasticsearch/v5 v5.6.1 h1:RnL2wcXepOT5SdoKMMO1j1OBX0vxHYbBtkQNL2E3xs4=
|
||||
github.com/elastic/go-elasticsearch/v5 v5.6.1/go.mod h1:r7uV7HidpfkYh7D8SB4lkS13TNlNy3oa5GNmTZvuVqY=
|
||||
@@ -181,10 +205,15 @@ github.com/elastic/go-elasticsearch/v6 v6.8.2 h1:rp5DGrd63V5c6nHLjF6QEXUpZSvs0+Q
|
||||
github.com/elastic/go-elasticsearch/v6 v6.8.2/go.mod h1:UwaDJsD3rWLM5rKNFzv9hgox93HoX8utj1kxD9aFUcI=
|
||||
github.com/elastic/go-elasticsearch/v7 v7.3.0 h1:H29Nqf9cB9dVxX6LwS+zTDC2D4t9s+8dK8ln4HPS9rw=
|
||||
github.com/elastic/go-elasticsearch/v7 v7.3.0/go.mod h1:OJ4wdbtDNk5g503kvlHLyErCgQwwzmDtaFC4XyOxXA4=
|
||||
github.com/elastic/go-sysinfo v1.0.1/go.mod h1:O/D5m1VpYLwGjCYzEt63g3Z1uO3jXfwyzzjiW90t8cY=
|
||||
github.com/elastic/go-sysinfo v1.1.1/go.mod h1:i1ZYdU10oLNfRzq4vq62BEwD2fH8KaWh6eh0ikPT9F0=
|
||||
github.com/elastic/go-windows v1.0.0/go.mod h1:TsU0Nrp7/y3+VwE82FoZF8gC/XFg/Elz6CcloAxnPgU=
|
||||
github.com/elastic/go-windows v1.0.1/go.mod h1:FoVvqWSun28vaDQPbj2Elfc0JahhPB7WQEGa3c814Ss=
|
||||
github.com/elazarl/goproxy v0.0.0-20200315184450-1f3cb6622dad h1:zPs0fNF2Io1Qytf92EI2CDJ9oCXZr+NmjEVexrUEdq4=
|
||||
github.com/elazarl/goproxy v0.0.0-20200315184450-1f3cb6622dad/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM=
|
||||
github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2 h1:dWB6v3RcOy03t/bUadywsbyrQwCqZeNIEX6M1OtSZOM=
|
||||
github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8=
|
||||
github.com/ema/qdisc v0.0.0-20190904071900-b82c76788043/go.mod h1:ix4kG2zvdUd8kEKSW0ZTr1XLks0epFpI4j745DXxlNE=
|
||||
github.com/emicklei/go-restful v2.14.3+incompatible h1:i59XyRHAxKCVBw3vHzQlpP/+pi89wH1v1HL+RKyVgxk=
|
||||
github.com/emicklei/go-restful v2.14.3+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
|
||||
github.com/emicklei/go-restful-openapi v1.4.1 h1:SocVTIQWnXyit4dotTrwmncBAjtRaBmfcHjo3XGcCm4=
|
||||
@@ -198,19 +227,25 @@ github.com/evanphx/json-patch v4.9.0+incompatible h1:kLcOMZeuLAJvL2BPWLMIj5oaZQo
|
||||
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/evanphx/json-patch/v5 v5.0.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4=
|
||||
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4=
|
||||
github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb/go.mod h1:bH6Xx7IW64qjjJq8M2u4dxNaBiDfKK+z/3eGDpXEQhc=
|
||||
github.com/fatih/camelcase v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8=
|
||||
github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc=
|
||||
github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s=
|
||||
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
|
||||
github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
|
||||
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
|
||||
github.com/fatih/structtag v1.1.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94=
|
||||
github.com/felixge/fgprof v0.9.1/go.mod h1:7/HK6JFtFaARhIljgP2IV8rJLIoHDoOYoUphsnGvqxE=
|
||||
github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ=
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
||||
github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
|
||||
github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
|
||||
github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
|
||||
github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
|
||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/fsouza/fake-gcs-server v1.7.0/go.mod h1:5XIRs4YvwNbNoz+1JF8j6KLAyDh7RHGAyAK3EP2EsNk=
|
||||
github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
|
||||
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
@@ -251,9 +286,7 @@ github.com/go-openapi/swag v0.19.9 h1:1IxuqvBUU3S2Bi4YC7tlP9SJF1gVpCvqN0T2Qof4az
|
||||
github.com/go-openapi/swag v0.19.9/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY=
|
||||
github.com/go-openapi/validate v0.19.8 h1:YFzsdWIDfVuLvIOF+ZmKjVg1MbPJ1QgY9PihMwei1ys=
|
||||
github.com/go-openapi/validate v0.19.8/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4=
|
||||
github.com/go-playground/locales v0.12.1 h1:2FITxuFt/xuCNP1Acdhv62OzaCiviiE4kotfhkmOqEc=
|
||||
github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM=
|
||||
github.com/go-playground/universal-translator v0.0.0-20170327191703-71201497bace h1:vfBaUX49VsqTxXGADDIWvTPvaU4AbQyX/yENHE0f7AY=
|
||||
github.com/go-playground/universal-translator v0.0.0-20170327191703-71201497bace/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY=
|
||||
github.com/go-redis/redis v6.15.2+incompatible h1:9SpNVG76gr6InJGxoZ6IuuxaCOQwDAhzyXg+Bs+0Sb4=
|
||||
github.com/go-redis/redis v6.15.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
||||
@@ -276,12 +309,22 @@ github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/V
|
||||
github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw=
|
||||
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
|
||||
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
|
||||
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo=
|
||||
github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
|
||||
github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM=
|
||||
github.com/gocql/gocql v0.0.0-20190301043612-f6df8288f9b4/go.mod h1:4Fw1eo5iaEhDUs8XyuhSVCVy52Jq3L+/3GJgYkwc+/0=
|
||||
github.com/gocql/gocql v0.0.0-20200121121104-95d072f1b5bb/go.mod h1:DL0ekTmBSTdlNF25Orwt/JMzqIq3EJ4MVa/J/uK64OY=
|
||||
github.com/gocql/gocql v0.0.0-20200526081602-cd04bd7f22a7/go.mod h1:DL0ekTmBSTdlNF25Orwt/JMzqIq3EJ4MVa/J/uK64OY=
|
||||
github.com/gocraft/dbr v0.0.0-20180507214907-a0fd650918f6 h1:kumyNm8Vr8cbVm/aLQYTbDE3SKCbbn5HEVoDp/Dyyfc=
|
||||
github.com/gocraft/dbr v0.0.0-20180507214907-a0fd650918f6/go.mod h1:K/9g3pPouf13kP5K7pdriQEJAy272R9yXuWuDIEWJTM=
|
||||
github.com/godbus/dbus v0.0.0-20190402143921-271e53dc4968/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw=
|
||||
github.com/gofrs/flock v0.7.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
|
||||
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||
github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
|
||||
github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
|
||||
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||
github.com/gogo/status v1.0.3/go.mod h1:SavQ51ycCLnc7dGyJxp8YAmudx8xqiVrRf+6IXRsugc=
|
||||
github.com/golang-migrate/migrate/v4 v4.7.0/go.mod h1:Qvut3N4xKWjoH3sokBccML6WyHSnggXm/DvMMnTsQIc=
|
||||
github.com/golang/example v0.0.0-20170904185048-46695d81d1fa h1:iqCQC2Z53KkwGgTN9szyL4q0OQHmuNjeoNnMT6lk66k=
|
||||
github.com/golang/example v0.0.0-20170904185048-46695d81d1fa/go.mod h1:tO/5UvQ/uKigUjQBPqzstj6uxd3fUIjddi19DxGJeWg=
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
|
||||
@@ -290,20 +333,24 @@ github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekf
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E=
|
||||
github.com/golang/mock v1.4.3 h1:GV+pQPG/EUUbkh47niozDcADz6go/dUwhVzdUQHIVRw=
|
||||
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
|
||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golangplus/bytes v0.0.0-20160111154220-45c989fe5450/go.mod h1:Bk6SMAONeMXrxql8uvOKuAZSu8aM5RUGv+1C6IJaEho=
|
||||
github.com/golangplus/fmt v0.0.0-20150411045040-2a5d6d7d2995/go.mod h1:lJgMEyOkYFkPcDKwRXegd+iM6E7matEszMG5HhwytU8=
|
||||
github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e/go.mod h1:0AA//k/eakGydO4jKRoRL2j92ZKSzTgj9tclaCrvXHk=
|
||||
github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
|
||||
github.com/google/addlicense v0.0.0-20200906110928-a0294312aa76/go.mod h1:EMjYTRimagHs1FwlIqKyX3wAM0u3rA+McvlIIWmSamA=
|
||||
github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/flatbuffers v1.11.0/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
|
||||
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
|
||||
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
|
||||
@@ -314,6 +361,7 @@ github.com/google/pprof v0.0.0-20200417002340-c6e0a841f49a/go.mod h1:ZgVRPoUq/hf
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/gax-go v2.0.2+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/googleapis/gnostic v0.4.0 h1:BXDUo8p/DaxC+4FJY/SSx3gvnx9C1VdHNgaUkiEL5mk=
|
||||
github.com/googleapis/gnostic v0.4.0/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU=
|
||||
@@ -333,6 +381,7 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92Bcuy
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.14.4 h1:IOPK2xMPP3aV6/NPt4jt//ELFo3Vv8sDVD8j3+tleDU=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.14.4/go.mod h1:6CwZWGDSPRJidgKAtJVvND6soZe6fT7iteq8wDPdhb0=
|
||||
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=
|
||||
github.com/hashicorp/consul/api v1.4.0/go.mod h1:xc8u05kyMa3Wjr9eEAsIAo3dg8+LywT5E/Cl7cNS5nU=
|
||||
github.com/hashicorp/consul/sdk v0.4.0/go.mod h1:fY08Y9z5SvJqevyZNy6WWPXiG3KwBPAvlcdx16zZ0fM=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
@@ -355,6 +404,7 @@ github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO
|
||||
github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY=
|
||||
github.com/hashicorp/memberlist v0.2.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
|
||||
github.com/hashicorp/serf v0.9.0/go.mod h1:YL0HO+FifKOW2u1ke99DGVu1zhcpZzNwrLIqBC7vbYU=
|
||||
github.com/hodgesds/perf-utils v0.0.8/go.mod h1:F6TfvsbtrF88i++hou29dTXlI2sfsJv+gRZDtmTJkAs=
|
||||
github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4=
|
||||
github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
@@ -371,6 +421,8 @@ github.com/influxdata/promql/v2 v2.12.0/go.mod h1:fxOPu+DY0bqCTCECchSRtWfc+0X19y
|
||||
github.com/influxdata/roaring v0.4.13-0.20180809181101-fc520f41fab6/go.mod h1:bSgUQ7q5ZLSO+bKBGqJiCBGAl+9DxyW63zLTujjUlOE=
|
||||
github.com/influxdata/tdigest v0.0.0-20181121200506-bf2b5ad3c0a9/go.mod h1:Js0mqiSBE6Ffsg94weZZ2c+v/ciT8QRHFOap7EKDrR0=
|
||||
github.com/influxdata/usage-client v0.0.0-20160829180054-6d3895376368/go.mod h1:Wbbw6tYNvwa5dlB6304Sd+82Z3f7PmVZHVKU637d4po=
|
||||
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ=
|
||||
github.com/jackc/pgx v3.2.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
|
||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
@@ -379,10 +431,14 @@ github.com/jinzhu/inflection v0.0.0-20180308033659-04140366298a/go.mod h1:h+uFLl
|
||||
github.com/jinzhu/now v1.0.0/go.mod h1:oHTiXerJ20+SfYcrdlBO7rzZRJWGwSTQ0iUY2jI6Gfc=
|
||||
github.com/jmespath/go-jmespath v0.3.0 h1:OS12ieG61fsCg5+qLJ+SsW9NicxNkg3b25OyT2yCeUc=
|
||||
github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik=
|
||||
github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901/go.mod h1:Z86h9688Y0wesXCyonoVr47MasHilkuLMqGhRZ4Hpak=
|
||||
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
|
||||
github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20190606172950-9527aa82566a/go.mod h1:Oz+70psSo5OFh8DBl0Zv2ACw7Esh6pPUphlvZG9x7uw=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20190830100107-3784a6c7c552/go.mod h1:Oz+70psSo5OFh8DBl0Zv2ACw7Esh6pPUphlvZG9x7uw=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20200117123717-f846d4f6c1f4/go.mod h1:WGuG/smIU4J/54PblvSbh+xvCZmpJnFgr3ds6Z55XMQ=
|
||||
github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
@@ -404,21 +460,26 @@ github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0
|
||||
github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6/go.mod h1:+ZoRqAPRLkC4NPOvfYeR5KNOrY6TD+/sAC3HXPZgDYg=
|
||||
github.com/klauspost/pgzip v1.0.2-0.20170402124221-0bf5dcad4ada/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
||||
github.com/knq/sysutil v0.0.0-20191005231841-15668db23d08/go.mod h1:dFWs1zEqDjFtnBXsd1vPOZaLsESovai349994nHx3e0=
|
||||
github.com/koding/multiconfig v0.0.0-20171124222453-69c27309b2d7 h1:SWlt7BoQNASbhTUD0Oy5yysI2seJ7vWuGUp///OM4TM=
|
||||
github.com/koding/multiconfig v0.0.0-20171124222453-69c27309b2d7/go.mod h1:Y2SaZf2Rzd0pXkLVhLlCiAXFCLSXAIbTKDivVgff/AM=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs=
|
||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kshvakov/clickhouse v1.3.5/go.mod h1:DMzX7FxRymoNkVgizH0DWAL8Cur7wHLgx3MUnGwJqpE=
|
||||
github.com/kubernetes-csi/external-snapshotter/client/v3 v3.0.0 h1:OYDCOjVcx/5wNzlZ/At8otRibUlw0T6R0xOD31f32bw=
|
||||
github.com/kubernetes-csi/external-snapshotter/client/v3 v3.0.0/go.mod h1:Q7VUue/CIrKbtpBdF04a1yjGGgsMaDws1HUxtjzgnEY=
|
||||
github.com/kubesphere/sonargo v0.0.2 h1:hsSRE3sv3mkPcUAeSABdp7rtfcNW2zzeHXzFa01CTkU=
|
||||
github.com/kubesphere/sonargo v0.0.2/go.mod h1:ww8n9ANlDXhX5PBZ18iaRnCgEkXN0GMml3/KZXOZ11w=
|
||||
github.com/kylelemons/godebug v0.0.0-20160406211939-eadb3ce320cb/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k=
|
||||
github.com/leodido/go-urn v0.0.0-20181204092800-a67a23e1c1af h1:EhEGUQX36JFkvSWzrwGjjTJxrx7atfJdxv8cxFzmaB0=
|
||||
github.com/lann/builder v0.0.0-20150808151131-f22ce00fd939/go.mod h1:dXGbAdH5GtBTC4WfIxhKZfyBF/HBFgRZSWwZ9g/He9o=
|
||||
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6FmdpVm2joNMFikkuWg0EoCKLGUMNw=
|
||||
github.com/leanovate/gopter v0.2.4/go.mod h1:gNcbPWNEWRe4lm+bycKqxUYoH5uoVje5SkOJ3uoLer8=
|
||||
github.com/leodido/go-urn v0.0.0-20181204092800-a67a23e1c1af/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw=
|
||||
github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0=
|
||||
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
@@ -427,6 +488,8 @@ github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9
|
||||
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
|
||||
github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
|
||||
github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc=
|
||||
github.com/lovoo/gcloud-opentracing v0.3.0/go.mod h1:ZFqk2y38kMDDikZPAK7ynTTGuyt17nSPdS3K5e+ZTBY=
|
||||
github.com/lufia/iostat v1.1.0/go.mod h1:rEPNA0xXgjHQjuI5Cy05sLlS2oRcSlWHRLrvh/AQ+Pg=
|
||||
github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/mailru/easyjson v0.7.1 h1:mdxE1MF9o53iCb2Ghj1VfWvh7ZOwHpnVG/xwXrV90U8=
|
||||
@@ -435,6 +498,9 @@ github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsI
|
||||
github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
|
||||
github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE=
|
||||
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc=
|
||||
github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc=
|
||||
github.com/mattn/go-ieproxy v0.0.0-20191113090002-7c0f6868bffe/go.mod h1:pYabZ6IHcRpFh7vIaLfK7rdcWgFEb3SFJ6/gNWuh88E=
|
||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
@@ -442,15 +508,29 @@ github.com/mattn/go-shellwords v1.0.5/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vq
|
||||
github.com/mattn/go-sqlite3 v1.11.0 h1:LDdKkqtYlom37fkvqs8rMPFKAMe8+SgjbwZ6ex1/A/Q=
|
||||
github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/mattn/go-tty v0.0.0-20180907095812-13ff1204f104/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE=
|
||||
github.com/mattn/go-xmlrpc v0.0.3/go.mod h1:mqc2dz7tP5x5BKlCahN/n+hs7OSZKJkS9JsHNBRlrxA=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/mdlayher/genetlink v1.0.0/go.mod h1:0rJ0h4itni50A86M2kHcgS85ttZazNt7a8H2a2cw0Gc=
|
||||
github.com/mdlayher/netlink v0.0.0-20190409211403-11939a169225/go.mod h1:eQB3mZE4aiYnlUsyGGCOpPETfdQq4Jhsgf1fk3cwQaA=
|
||||
github.com/mdlayher/netlink v0.0.0-20190828143259-340058475d09/go.mod h1:KxeJAFOFLG6AjpyDkQ/iIhxygIUKD+vcwqcnu43w/+M=
|
||||
github.com/mdlayher/netlink v1.0.0/go.mod h1:KxeJAFOFLG6AjpyDkQ/iIhxygIUKD+vcwqcnu43w/+M=
|
||||
github.com/mdlayher/netlink v1.1.0/go.mod h1:H4WCitaheIsdF9yOYu8CFmCgQthAPIWZmcKp9uZHgmY=
|
||||
github.com/mdlayher/wifi v0.0.0-20190303161829-b1436901ddee/go.mod h1:Evt/EIne46u9PtQbeTx2NTcqURpr5K4SvKtGmBuDPN8=
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
|
||||
github.com/miekg/dns v1.1.29/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
|
||||
github.com/minio/md5-simd v1.1.0/go.mod h1:XpBqgZULrMYD3R+M28PcmP0CkI7PEMzB3U77ZrKZ0Gw=
|
||||
github.com/minio/minio-go/v6 v6.0.44/go.mod h1:qD0lajrGW49lKZLtXKtCB4X/qkMf0a5tBvN2PaZg7Gg=
|
||||
github.com/minio/minio-go/v6 v6.0.56/go.mod h1:KQMM+/44DSlSGSQWSfRrAZ12FVMmpWNuX37i2AX0jfI=
|
||||
github.com/minio/minio-go/v7 v7.0.2/go.mod h1:dJ80Mv2HeGkYLH1sqS/ksz07ON6csH3S6JUMSQ2zAns=
|
||||
github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM=
|
||||
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
||||
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
|
||||
github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
|
||||
github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ=
|
||||
github.com/mitchellh/mapstructure v1.2.2 h1:dxe5oCinTXiTIcfgmZecdCzPmAJKd46KsCWc35r0TV4=
|
||||
github.com/mitchellh/mapstructure v1.2.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||
@@ -462,17 +542,21 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb
|
||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
|
||||
github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c h1:nXxl5PrvVm2L/wCy8dQu6DMTwH4oIuGN8GJDAlqDdVE=
|
||||
github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
|
||||
github.com/mozillazg/go-cos v0.13.0/go.mod h1:Zp6DvvXn0RUOXGJ2chmWt2bLEqRAnJnS3DnAZsJsoaE=
|
||||
github.com/mozillazg/go-httpheader v0.2.1/go.mod h1:jJ8xECTlalr6ValeXYdOF8fFUISeBAdw6E61aqQma60=
|
||||
github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg=
|
||||
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/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus=
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
||||
github.com/nakagami/firebirdsql v0.0.0-20190310045651-3c02a58cfed8/go.mod h1:86wM1zFnC6/uDBfZGNwB65O+pR2OFi5q/YQaEUid1qA=
|
||||
github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU=
|
||||
github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k=
|
||||
github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w=
|
||||
github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
|
||||
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
|
||||
github.com/ncw/swift v1.0.50/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM=
|
||||
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
|
||||
@@ -492,6 +576,7 @@ github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQ
|
||||
github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI=
|
||||
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||
github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
|
||||
github.com/opentracing-contrib/go-grpc v0.0.0-20180928155321-4b5a12d3ff02/go.mod h1:JNdpVEzCpXBgIiv4ds+TzhN1hrtxq6ClLrTlT9OQRSc=
|
||||
github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
|
||||
github.com/opentracing-contrib/go-stdlib v0.0.0-20190519235532-cf7a6c988dc9/go.mod h1:PLldrQSroqzH70Xl+1DQcGnefIbqsKR7UDaiux3zV+w=
|
||||
github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
|
||||
@@ -535,6 +620,10 @@ github.com/projectcalico/libcalico-go v1.7.2-0.20191104213956-8f81e1e344ce h1:O/
|
||||
github.com/projectcalico/libcalico-go v1.7.2-0.20191104213956-8f81e1e344ce/go.mod h1:z4tuFqrAg/423AMSaDamY5LgqeOZ5ETui6iOxDwJ/ag=
|
||||
github.com/prometheus-community/prom-label-proxy v0.2.0 h1:2cNKhNjbTmmEDvBTW/6WUsE2x7bh76rBMZVBn4ey6To=
|
||||
github.com/prometheus-community/prom-label-proxy v0.2.0/go.mod h1:XdjyZg7LCbCC5FADHtpgNp6kQ0W9beXVGfmcvndMj5Y=
|
||||
github.com/prometheus-operator/prometheus-operator v0.42.2-0.20200928114327-fbd01683839a h1:21yBrtc90hdEhJaL815CHNV0GW0DEdgxDOiL5OYoSHo=
|
||||
github.com/prometheus-operator/prometheus-operator v0.42.2-0.20200928114327-fbd01683839a/go.mod h1:Ah5xJsVlBRNuzNCIf5cfASYMXNJemPoDpXZsncFvqCs=
|
||||
github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.42.1 h1:/CZyIylkTNOiVdzTtHwkTHTMOCGJXuLtu3ZLAQrH4u0=
|
||||
github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.42.1/go.mod h1:iIz0gzBgsmUvH3POupwMevtm74XmRcEBx8w/tE3sl4k=
|
||||
github.com/prometheus/alertmanager v0.20.0 h1:PBMNY7oyIvYMBBIag35/C0hO7xn8+35p4V5rNAph5N8=
|
||||
github.com/prometheus/alertmanager v0.20.0/go.mod h1:9g2i48FAyZW6BtbsnvHtMHQXl2aVtrORKwKVCQ+nbrg=
|
||||
github.com/prometheus/client_golang v1.7.1 h1:NTGy1Ja9pByO+xAeH/qiWnLrKtr3hJPNjaVUwnjpdpA=
|
||||
@@ -543,32 +632,38 @@ github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2
|
||||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/common v0.10.0 h1:RyRA7RzGXQZiW+tGMr7sxa85G1z0yOpM1qq5c8lNawc=
|
||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||
github.com/prometheus/node_exporter v1.0.0-rc.0.0.20200428091818-01054558c289/go.mod h1:FGbBv5OPKjch+jNUJmEQpMZytIdyW0NdBtWFcfSKusc=
|
||||
github.com/prometheus/procfs v0.1.3 h1:F0+tqvhOksq22sc6iCHF5WGlWjdwj92p0udFh1VFBS8=
|
||||
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/prometheus/prometheus v1.8.2-0.20200507164740-ecee9c8abfd1 h1:Oh/bmW9DXCbMeAZbxMmt2wuY6Q4cD0IIbR6vJP3kdHg=
|
||||
github.com/prometheus/prometheus v1.8.2-0.20200507164740-ecee9c8abfd1/go.mod h1:S5n0C6tSgdnwWshBUceRx5G1OsjLv/EeZ9t3wIfEtsY=
|
||||
github.com/rafaeljusto/redigomock v0.0.0-20190202135759-257e089e14a1/go.mod h1:JaY6n2sDr+z2WTsXkOmNRUfDy6FN0L6Nk7x06ndm4tY=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a h1:9ZKAASQSHhDYGoxY8uLVpewe1GDZ2vu2Tr/vTdVAkFQ=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc=
|
||||
github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k=
|
||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
|
||||
github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/santhosh-tekuri/jsonschema v1.2.4/go.mod h1:TEAUOeZSmIxTTuHatJzrvARHiuO9LYd+cIxzgEHCQI4=
|
||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||
github.com/segmentio/fasthash v0.0.0-20180216231524-a72b379d632e/go.mod h1:tm/wZFQ8e24NYaBGIlnO2WGCAi67re4HHuOm0sftE/M=
|
||||
github.com/segmentio/kafka-go v0.2.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo=
|
||||
github.com/sercand/kuberesolver v2.1.0+incompatible/go.mod h1:lWF3GL0xptCB/vCiJPl/ZshwPsX/n4Y7u0CW9E7aQIQ=
|
||||
github.com/sercand/kuberesolver v2.4.0+incompatible/go.mod h1:lWF3GL0xptCB/vCiJPl/ZshwPsX/n4Y7u0CW9E7aQIQ=
|
||||
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/shirou/gopsutil v0.0.0-20180427012116-c95755e4bcd7/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
||||
github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc=
|
||||
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
|
||||
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
|
||||
github.com/siebenmann/go-kstat v0.0.0-20160321171754-d34789b79745/go.mod h1:G81aIFAMS9ECrwBYR9YxhlPjWgrItd+Kje78O6+uqm8=
|
||||
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
@@ -576,8 +671,9 @@ github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9
|
||||
github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E=
|
||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
|
||||
github.com/sony/sonyflake v1.0.0 h1:MpU6Ro7tfXwgn2l5eluf9xQvQJDROTBImNCfRXn/YeM=
|
||||
github.com/sony/sonyflake v1.0.0/go.mod h1:Jv3cfhf/UFtolOTTRd3q4Nl6ENqM+KfyZ5PseKfZGF4=
|
||||
github.com/sony/sonyflake v0.0.0-20181109022403-6d5bd6181009 h1:3wBL/e/qjpSYaXacpbIV+Bsj/nwQ4UO1llG/av54zzw=
|
||||
github.com/sony/sonyflake v0.0.0-20181109022403-6d5bd6181009/go.mod h1:dVvZuWJd174umvm5g8CmZD6S2GWwHKtpK/0ZPHswuNo=
|
||||
github.com/soundcloud/go-runit v0.0.0-20150630195641-06ad41a06c4a/go.mod h1:LeFCbQYJ3KJlPs/FvPz2dy1tkpxyeNESVyCNNzRXFR0=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/speps/go-hashids v2.0.0+incompatible h1:kSfxGfESueJKTx0mpER9Y/1XHl+FVQjtCqRyYcviFbw=
|
||||
@@ -586,8 +682,8 @@ github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc=
|
||||
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
||||
github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
|
||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cobra v1.0.0 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8=
|
||||
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
|
||||
github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s=
|
||||
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
||||
github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk=
|
||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
@@ -596,27 +692,36 @@ github.com/spf13/viper v1.4.0 h1:yXHLWeravcrgGyFSyCgdYpXQ9dR9c/WED3pg1RhxqEU=
|
||||
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
|
||||
github.com/src-d/gcfg v1.4.0 h1:xXbNR5AlLSA315x2UO+fTSSAXCDf+Ar38/6oyGbDKQ4=
|
||||
github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI=
|
||||
github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
|
||||
github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
|
||||
github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
|
||||
github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=
|
||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/thanos-io/thanos v0.8.1-0.20200109203923-552ffa4c1a0d/go.mod h1:usT/TxtJQ7DzinTt+G9kinDQmRS5sxwu0unVKZ9vdcw=
|
||||
github.com/thanos-io/thanos v0.13.1-0.20200731083140-69b87607decf/go.mod h1:G8caR6G7pSDreRDvFm9wFuyjEBztmr8Ag3kBYpa/fEc=
|
||||
github.com/thanos-io/thanos v0.13.1-0.20200807203500-9b578afb4763/go.mod h1:KyW0a93tsh7v4hXAwo2CVAIRYuZT1Kkf4e04gisQjAg=
|
||||
github.com/thanos-io/thanos v0.13.1-0.20200910143741-e0b7f7b32e9c/go.mod h1:1IzeMKiS+pvxbG2M6ZJyi8ZHaAQKXNjDbP2gjhPbSXE=
|
||||
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
|
||||
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
github.com/tinylib/msgp v1.1.0/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
|
||||
github.com/uber/jaeger-client-go v2.23.0+incompatible h1:o2g11IUBdEsSZVzF3k7+bahLmxRP/dbOoW4zQ30UlKE=
|
||||
github.com/uber/jaeger-client-go v2.23.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
|
||||
github.com/uber/jaeger-lib v2.2.0+incompatible h1:MxZXOiR2JuoANZ3J6DE/U0kSFv/eJ/GfSYVCjK7dyaw=
|
||||
github.com/uber/jaeger-lib v2.2.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
|
||||
github.com/ugorji/go v1.1.4 h1:j4s+tAvLfL3bZyefP2SEWmhBzmuIlH/eqNuPdFPgngw=
|
||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||
github.com/ugorji/go/codec v0.0.0-20190128213124-ee1426cffec0 h1:Q3Bh5Dwzek5LreV9l86IftyLaexgU1mag9WNntbAW9c=
|
||||
github.com/ugorji/go/codec v0.0.0-20190128213124-ee1426cffec0/go.mod h1:iT03XoTwV7xq/+UGwKO3UbC1nNNlopQiY61beSdrtOA=
|
||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||
github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw=
|
||||
github.com/weaveworks/common v0.0.0-20200206153930-760e36ae819a/go.mod h1:6enWAqfQBFrE8X/XdJwZr8IKgh1chStuFR0mjU/UOUw=
|
||||
github.com/weaveworks/common v0.0.0-20200625145055-4b1847531bc9/go.mod h1:c98fKi5B9u8OsKGiWHLRKus6ToQ1Tubeow44ECO1uxY=
|
||||
github.com/weaveworks/common v0.0.0-20200820123129-280614068c5e/go.mod h1:hz10LOsAdzC3K/iXaKoFxOKTDRgxJl+BTGX1GY+TzO4=
|
||||
github.com/weaveworks/promrus v1.2.0/go.mod h1:SaE82+OJ91yqjrE1rsvBWVzNZKcHYFtMUyS1+Ogs/KA=
|
||||
github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
|
||||
github.com/xanzy/go-gitlab v0.15.0/go.mod h1:8zdQa/ri1dfn8eS3Ir1SyfvOKlw7WBJ8DVThkpGiXrs=
|
||||
github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70=
|
||||
github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4=
|
||||
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
|
||||
@@ -635,6 +740,11 @@ github.com/yashtewari/glob-intersection v0.0.0-20180916065949-5c77d914dd0b/go.mo
|
||||
github.com/yvasiyarov/go-metrics v0.0.0-20150112132944-c25f46c4b940/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs=
|
||||
github.com/yvasiyarov/gorelic v0.0.6/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA=
|
||||
github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg=
|
||||
gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b/go.mod h1:T3BPAOm2cqquPa0MKWeNkmOM5RQsRhkrwMWonFMN7fE=
|
||||
go.elastic.co/apm v1.5.0/go.mod h1:OdB9sPtM6Vt7oz3VXt7+KR96i9li74qrxBGHTQygFvk=
|
||||
go.elastic.co/apm/module/apmhttp v1.5.0/go.mod h1:1FbmNuyD3ddauwzgVwFB0fqY6KbZt3JkV187tGCYYhY=
|
||||
go.elastic.co/apm/module/apmot v1.5.0/go.mod h1:d2KYwhJParTpyw2WnTNy8geNlHKKFX+4oK3YLlsesWE=
|
||||
go.elastic.co/fastjson v1.0.0/go.mod h1:PmeUOMMtLHQr9ZS9J9owrAVg0FkaZDRZJEFTTGHtchs=
|
||||
go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk=
|
||||
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738 h1:VcrIfasaLFkyjk6KNlXQSzO+B0fZcnECiDrKJsfxka0=
|
||||
@@ -644,6 +754,8 @@ go.mongodb.org/mongo-driver v1.3.2/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
|
||||
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.uber.org/automaxprocs v1.2.0/go.mod h1:YfO3fm683kQpzETxlTGZhGIVmXAhaw3gxeBADbpZtnU=
|
||||
go.uber.org/goleak v1.1.0/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
|
||||
go.uber.org/multierr v1.3.0 h1:sFPn2GLc3poCkfrpIXGhBD2X0CMIo4Q/zSULXrj/+uc=
|
||||
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
|
||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4=
|
||||
@@ -652,7 +764,6 @@ go.uber.org/zap v1.13.0 h1:nR6NoDBgAf67s68NhaXbsojM+2gxp3S1hWkHDl27pVU=
|
||||
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4 h1:c2HOrn5iMezYjSlGPncknSEr/8x5LELb/ilJbXi9DEA=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f h1:hX65Cu3JDlGH3uEdK7I99Ii+9kjD6mvnnpfLdEAH0x4=
|
||||
@@ -698,7 +809,6 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogR
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/fsnotify/fsnotify.v1 v1.4.7/go.mod h1:Fyux9zXlo4rWoMSIzpn9fDAYjalPqJ/K1qJ27s+7ltE=
|
||||
gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
|
||||
@@ -709,6 +819,9 @@ gopkg.in/go-playground/validator.v9 v9.27.0/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWd
|
||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw=
|
||||
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.57.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/mail.v2 v2.3.1/go.mod h1:htwXN1Qh09vZJ1NVKxQqHPBaCBbzKhp5GzuJEA4VJWw=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
||||
@@ -735,6 +848,7 @@ gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81
|
||||
helm.sh/helm/v3 v3.0.1/go.mod h1:sI7B9yfvMgxtTPMWdk1jSKJ2aa59UyP9qhPydqW6mgo=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3 h1:sXmLre5bzIR6ypkjXCDI3jHPssRhc8KD/Ome589sc3U=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0=
|
||||
istio.io/api v0.0.0-20201113182140-d4b7e3fc2b44 h1:mfs4UJtpH8ElVEohFZw39qDGv9gg7TOkYVTwJZGQ5Yc=
|
||||
istio.io/api v0.0.0-20201113182140-d4b7e3fc2b44/go.mod h1:kyq3g5w42zl/AKlbzDGppYpGMQYMYMyZKeq0/eexML8=
|
||||
istio.io/client-go v0.0.0-20201113183938-0734e976e785 h1:dY+HxVBYoR26sl3L54G3NMziPEiUCcW3f7b2U+LvzOM=
|
||||
|
||||
389
pkg/api/customalerting/v1alpha1/types.go
Normal file
389
pkg/api/customalerting/v1alpha1/types.go
Normal file
@@ -0,0 +1,389 @@
|
||||
/*
|
||||
Copyright 2020 KubeSphere Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/emicklei/go-restful"
|
||||
"github.com/pkg/errors"
|
||||
prommodel "github.com/prometheus/common/model"
|
||||
"github.com/prometheus/prometheus/promql/parser"
|
||||
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
RuleLevelCluster RuleLevel = "cluster"
|
||||
RuleLevelNamespace RuleLevel = "namespace"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrThanosRulerNotEnabled = errors.New("The request operation to custom alerting rule could not be done because thanos ruler is not enabled")
|
||||
ErrAlertingRuleNotFound = errors.New("The alerting rule was not found")
|
||||
ErrAlertingRuleAlreadyExists = errors.New("The alerting rule already exists")
|
||||
|
||||
ruleLabelNameMatcher = regexp.MustCompile(`[a-zA-Z_][a-zA-Z0-9_]*`)
|
||||
)
|
||||
|
||||
type RuleLevel string
|
||||
|
||||
type AlertingRuleQualifier struct {
|
||||
Id string `json:"id,omitempty" description:"rule id is mainly for the builtin rules"`
|
||||
Name string `json:"name,omitempty" description:"rule name which should be uniq for custom rules in the specified namespace"`
|
||||
Level RuleLevel `json:"level,omitempty" description:"rule level is only for the custom rules and its value is one of cluster, namespace"`
|
||||
Custom bool `json:"custom" description:"whether to be a custom rule. The builtin rules are not custom and can only be viewed"`
|
||||
}
|
||||
|
||||
type AlertingRuleProps struct {
|
||||
Query string `json:"query,omitempty" description:"prometheus query expression, grammars of which may be referred to https://prometheus.io/docs/prometheus/latest/querying/basics/"`
|
||||
Duration string `json:"duration,omitempty" description:"duration an alert transitions from Pending to Firing state, which must match ^([0-9]+)(y|w|d|h|m|s|ms)$"`
|
||||
Labels map[string]string `json:"labels,omitempty" description:"extra labels to attach to the resulting alert sample vectors (the key string has to match [a-zA-Z_][a-zA-Z0-9_]*). eg: a typical label called severity, whose value may be info, warning, error, critical, is usually used to indicate the severity of an alert"`
|
||||
Annotations map[string]string `json:"annotations,omitempty" description:"non-identifying key/value pairs. summary, message, description are the commonly used annotation names"`
|
||||
}
|
||||
|
||||
type PostableAlertingRule struct {
|
||||
Name string `json:"name,omitempty" description:"rule name which should be uniq for custom rules in the specified namespace"`
|
||||
Alias string `json:"alias,omitempty" description:"alias for the rule"`
|
||||
Description string `json:"description,omitempty" description:"description for the rule"`
|
||||
|
||||
AlertingRuleProps `json:",omitempty"`
|
||||
}
|
||||
|
||||
func (r *PostableAlertingRule) Validate() error {
|
||||
errs := []error{}
|
||||
|
||||
if r.Name == "" {
|
||||
errs = append(errs, errors.New("name can not be empty"))
|
||||
}
|
||||
if _, err := parser.ParseExpr(r.Query); err != nil {
|
||||
errs = append(errs, errors.Wrapf(err, "query is invalid: %s", r.Query))
|
||||
}
|
||||
if r.Duration != "" {
|
||||
if _, err := prommodel.ParseDuration(r.Duration); err != nil {
|
||||
errs = append(errs, errors.Wrapf(err, "duration is invalid: %s", r.Duration))
|
||||
}
|
||||
}
|
||||
|
||||
if len(r.Labels) > 0 {
|
||||
for name, _ := range r.Labels {
|
||||
if !ruleLabelNameMatcher.MatchString(name) || strings.HasPrefix(name, "__") {
|
||||
errs = append(errs, errors.Errorf(
|
||||
"label name (%s) is not valid. The name must match [a-zA-Z_][a-zA-Z0-9_]* and has not the __ prefix (label names with this prefix are for internal use)", name))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return utilerrors.NewAggregate(errs)
|
||||
}
|
||||
|
||||
type GettableAlertingRule struct {
|
||||
AlertingRuleQualifier `json:",omitempty"`
|
||||
AlertingRuleProps `json:",omitempty"`
|
||||
|
||||
Alias string `json:"alias,omitempty" description:"alias for the rule"`
|
||||
Description string `json:"description,omitempty" description:"description for the rule"`
|
||||
|
||||
State string `json:"state,omitempty" description:"state of a rule based on its alerts, one of firing, pending, inactive"`
|
||||
Health string `json:"health,omitempty" description:"health state of a rule based on the last execution, one of ok, err, unknown"`
|
||||
LastError string `json:"lastError,omitempty" description:"error for the last execution"`
|
||||
EvaluationDurationSeconds float64 `json:"evaluationTime,omitempty" description:"taken seconds for evaluation of query expression"`
|
||||
LastEvaluation *time.Time `json:"lastEvaluation,omitempty" description:"time for last evaluation of query expression"`
|
||||
Alerts []*Alert `json:"alerts,omitempty" description:"alerts"`
|
||||
}
|
||||
|
||||
type GettableAlertingRuleList struct {
|
||||
Items []*GettableAlertingRule `json:"items"`
|
||||
Total int `json:"total"`
|
||||
}
|
||||
|
||||
type Alert struct {
|
||||
ActiveAt *time.Time `json:"activeAt,omitempty" description:"time when alert is active"`
|
||||
Annotations map[string]string `json:"annotations,omitempty" description:"annotations"`
|
||||
Labels map[string]string `json:"labels,omitempty" description:"labels"`
|
||||
State string `json:"state,omitempty" description:"state"`
|
||||
Value string `json:"value,omitempty" description:"the value at the last evaluation of the query expression"`
|
||||
|
||||
Rule *AlertingRuleQualifier `json:"rule,omitempty" description:"rule triggering the alert"`
|
||||
}
|
||||
|
||||
type AlertList struct {
|
||||
Items []*Alert `json:"items"`
|
||||
Total int `json:"total"`
|
||||
}
|
||||
|
||||
type AlertingRuleQueryParams struct {
|
||||
NameContainFilter string
|
||||
State string
|
||||
Health string
|
||||
LabelEqualFilters map[string]string
|
||||
LabelContainFilters map[string]string
|
||||
|
||||
Offset int
|
||||
Limit int
|
||||
SortField string
|
||||
SortType string
|
||||
}
|
||||
|
||||
func (q *AlertingRuleQueryParams) Filter(rules []*GettableAlertingRule) []*GettableAlertingRule {
|
||||
var ret []*GettableAlertingRule
|
||||
for _, rule := range rules {
|
||||
if rule == nil {
|
||||
continue
|
||||
}
|
||||
if q == nil || q.matches(rule) {
|
||||
ret = append(ret, rule)
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (q *AlertingRuleQueryParams) matches(rule *GettableAlertingRule) bool {
|
||||
if q.NameContainFilter != "" && !strings.Contains(rule.Name, q.NameContainFilter) {
|
||||
return false
|
||||
}
|
||||
if q.State != "" && q.State != rule.State {
|
||||
return false
|
||||
}
|
||||
if q.Health != "" && q.Health != rule.Health {
|
||||
return false
|
||||
}
|
||||
if len(rule.Labels) == 0 {
|
||||
return len(q.LabelEqualFilters) == 0 && len(q.LabelContainFilters) == 0
|
||||
}
|
||||
for k, v := range q.LabelEqualFilters {
|
||||
if fv, ok := rule.Labels[k]; !ok || fv != v {
|
||||
return false
|
||||
}
|
||||
}
|
||||
for k, v := range q.LabelContainFilters {
|
||||
if fv, ok := rule.Labels[k]; !ok || !strings.Contains(fv, v) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// AlertingRuleIdCompare defines the default order for the alerting rules.
|
||||
// For the alerting rule list, it guarantees a stable sort. For the custom alerting rules with possible same names
|
||||
// and the builtin alerting rules with possible same ids, it guarantees the stability of get operations.
|
||||
func AlertingRuleIdCompare(leftId, rightId string) bool {
|
||||
// default to ascending order of id
|
||||
return leftId <= rightId
|
||||
}
|
||||
|
||||
func (q *AlertingRuleQueryParams) Sort(rules []*GettableAlertingRule) {
|
||||
idCompare := func(left, right *GettableAlertingRule) bool {
|
||||
return AlertingRuleIdCompare(left.Id, right.Id)
|
||||
}
|
||||
var compare = idCompare
|
||||
if q != nil {
|
||||
reverse := q.SortType == "desc"
|
||||
switch q.SortField {
|
||||
case "name":
|
||||
compare = func(left, right *GettableAlertingRule) bool {
|
||||
if c := strings.Compare(left.Name, right.Name); c != 0 {
|
||||
if reverse {
|
||||
return c > 0
|
||||
}
|
||||
return c < 0
|
||||
}
|
||||
return idCompare(left, right)
|
||||
}
|
||||
case "lastEvaluation":
|
||||
compare = func(left, right *GettableAlertingRule) bool {
|
||||
if left.LastEvaluation == nil {
|
||||
if right.LastEvaluation != nil {
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
if right.LastEvaluation == nil {
|
||||
return true
|
||||
} else if left.LastEvaluation.Equal(*right.LastEvaluation) {
|
||||
if reverse {
|
||||
return left.LastEvaluation.After(*right.LastEvaluation)
|
||||
}
|
||||
return left.LastEvaluation.Before(*right.LastEvaluation)
|
||||
}
|
||||
}
|
||||
return idCompare(left, right)
|
||||
}
|
||||
case "evaluationTime":
|
||||
compare = func(left, right *GettableAlertingRule) bool {
|
||||
if left.EvaluationDurationSeconds != right.EvaluationDurationSeconds {
|
||||
if reverse {
|
||||
return left.EvaluationDurationSeconds > right.EvaluationDurationSeconds
|
||||
}
|
||||
return left.EvaluationDurationSeconds < right.EvaluationDurationSeconds
|
||||
}
|
||||
return idCompare(left, right)
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Slice(rules, func(i, j int) bool {
|
||||
return compare(rules[i], rules[j])
|
||||
})
|
||||
}
|
||||
|
||||
func (q *AlertingRuleQueryParams) Sub(rules []*GettableAlertingRule) []*GettableAlertingRule {
|
||||
start, stop := 0, 10
|
||||
if q != nil {
|
||||
start, stop = q.Offset, q.Offset+q.Limit
|
||||
}
|
||||
total := len(rules)
|
||||
if start < total {
|
||||
if stop > total {
|
||||
stop = total
|
||||
}
|
||||
return rules[start:stop]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type AlertQueryParams struct {
|
||||
State string
|
||||
LabelEqualFilters map[string]string
|
||||
LabelContainFilters map[string]string
|
||||
|
||||
Offset int
|
||||
Limit int
|
||||
}
|
||||
|
||||
func (q *AlertQueryParams) Filter(alerts []*Alert) []*Alert {
|
||||
var ret []*Alert
|
||||
for _, alert := range alerts {
|
||||
if alert == nil {
|
||||
continue
|
||||
}
|
||||
if q == nil || q.matches(alert) {
|
||||
ret = append(ret, alert)
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (q *AlertQueryParams) matches(alert *Alert) bool {
|
||||
if q.State != "" && q.State != alert.State {
|
||||
return false
|
||||
}
|
||||
if len(alert.Labels) == 0 {
|
||||
return len(q.LabelEqualFilters) == 0 && len(q.LabelContainFilters) == 0
|
||||
}
|
||||
for k, v := range q.LabelEqualFilters {
|
||||
if fv, ok := alert.Labels[k]; !ok || fv != v {
|
||||
return false
|
||||
}
|
||||
}
|
||||
for k, v := range q.LabelContainFilters {
|
||||
if fv, ok := alert.Labels[k]; !ok || !strings.Contains(fv, v) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (q *AlertQueryParams) Sort(alerts []*Alert) {
|
||||
compare := func(left, right *Alert) bool {
|
||||
if left.ActiveAt == nil {
|
||||
if right.ActiveAt != nil {
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
if right.ActiveAt == nil {
|
||||
return true
|
||||
} else if !left.ActiveAt.Equal(*right.ActiveAt) {
|
||||
return left.ActiveAt.After(*right.ActiveAt)
|
||||
}
|
||||
}
|
||||
return prommodel.LabelsToSignature(left.Labels) <= prommodel.LabelsToSignature(right.Labels)
|
||||
}
|
||||
sort.Slice(alerts, func(i, j int) bool {
|
||||
return compare(alerts[i], alerts[j])
|
||||
})
|
||||
}
|
||||
|
||||
func (q *AlertQueryParams) Sub(alerts []*Alert) []*Alert {
|
||||
start, stop := 0, 10
|
||||
if q != nil {
|
||||
start, stop = q.Offset, q.Offset+q.Limit
|
||||
}
|
||||
total := len(alerts)
|
||||
if start < total {
|
||||
if stop > total {
|
||||
stop = total
|
||||
}
|
||||
return alerts[start:stop]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func ParseAlertingRuleQueryParams(req *restful.Request) (*AlertingRuleQueryParams, error) {
|
||||
var (
|
||||
q = &AlertingRuleQueryParams{}
|
||||
err error
|
||||
)
|
||||
|
||||
q.NameContainFilter = req.QueryParameter("name")
|
||||
q.State = req.QueryParameter("state")
|
||||
q.Health = req.QueryParameter("health")
|
||||
q.Offset, _ = strconv.Atoi(req.QueryParameter("offset"))
|
||||
q.Limit, err = strconv.Atoi(req.QueryParameter("limit"))
|
||||
if err != nil {
|
||||
q.Limit = 10
|
||||
err = nil
|
||||
}
|
||||
q.LabelEqualFilters, q.LabelContainFilters = parseLabelFilters(req)
|
||||
q.SortField = req.QueryParameter("sort_field")
|
||||
q.SortType = req.QueryParameter("sort_type")
|
||||
return q, err
|
||||
}
|
||||
|
||||
func ParseAlertQueryParams(req *restful.Request) (*AlertQueryParams, error) {
|
||||
var (
|
||||
q = &AlertQueryParams{}
|
||||
err error
|
||||
)
|
||||
|
||||
q.State = req.QueryParameter("state")
|
||||
q.Offset, _ = strconv.Atoi(req.QueryParameter("offset"))
|
||||
q.Limit, err = strconv.Atoi(req.QueryParameter("limit"))
|
||||
if err != nil {
|
||||
q.Limit = 10
|
||||
err = nil
|
||||
}
|
||||
q.LabelEqualFilters, q.LabelContainFilters = parseLabelFilters(req)
|
||||
return q, err
|
||||
}
|
||||
|
||||
func parseLabelFilters(req *restful.Request) (map[string]string, map[string]string) {
|
||||
var (
|
||||
labelEqualFilters = make(map[string]string)
|
||||
labelContainFilters = make(map[string]string)
|
||||
labelFiltersString = req.QueryParameter("label_filters")
|
||||
)
|
||||
for _, filter := range strings.Split(labelFiltersString, ",") {
|
||||
if i := strings.Index(filter, "="); i > 0 && len(filter) > i+1 {
|
||||
labelEqualFilters[filter[:i]] = filter[i+1:]
|
||||
} else if i := strings.Index(filter, "~"); i > 0 && len(filter) > i+1 {
|
||||
labelContainFilters[filter[:i]] = filter[i+1:]
|
||||
}
|
||||
}
|
||||
return labelEqualFilters, labelContainFilters
|
||||
}
|
||||
@@ -51,6 +51,7 @@ import (
|
||||
alertingv1 "kubesphere.io/kubesphere/pkg/kapis/alerting/v1"
|
||||
clusterkapisv1alpha1 "kubesphere.io/kubesphere/pkg/kapis/cluster/v1alpha1"
|
||||
configv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/config/v1alpha2"
|
||||
customalertingv1alpha1 "kubesphere.io/kubesphere/pkg/kapis/customalerting/v1alpha1"
|
||||
devopsv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/devops/v1alpha2"
|
||||
devopsv1alpha3 "kubesphere.io/kubesphere/pkg/kapis/devops/v1alpha3"
|
||||
iamapi "kubesphere.io/kubesphere/pkg/kapis/iam/v1alpha2"
|
||||
@@ -74,6 +75,7 @@ import (
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/user"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/auditing"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/cache"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/customalerting"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/devops"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/events"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
|
||||
@@ -144,6 +146,8 @@ type APIServer struct {
|
||||
|
||||
AuditingClient auditing.Client
|
||||
|
||||
CustomAlertingClient customalerting.RuleClient
|
||||
|
||||
// controller-runtime cache
|
||||
RuntimeCache runtimecache.Cache
|
||||
}
|
||||
@@ -236,6 +240,8 @@ func (s *APIServer) installKubeSphereAPIs() {
|
||||
urlruntime.Must(notificationv1.AddToContainer(s.container, s.Config.NotificationOptions.Endpoint))
|
||||
urlruntime.Must(alertingv1.AddToContainer(s.container, s.Config.AlertingOptions.Endpoint))
|
||||
urlruntime.Must(version.AddToContainer(s.container, s.KubernetesClient.Discovery()))
|
||||
urlruntime.Must(customalertingv1alpha1.AddToContainer(s.container, s.InformerFactory,
|
||||
s.KubernetesClient.Prometheus(), s.CustomAlertingClient, s.Config.CustomAlertingOptions))
|
||||
}
|
||||
|
||||
func (s *APIServer) Run(stopCh <-chan struct{}) (err error) {
|
||||
@@ -503,6 +509,26 @@ func (s *APIServer) waitForResourceSync(stopCh <-chan struct{}) error {
|
||||
apiextensionsInformerFactory.Start(stopCh)
|
||||
apiextensionsInformerFactory.WaitForCacheSync(stopCh)
|
||||
|
||||
if promFactory := s.InformerFactory.PrometheusSharedInformerFactory(); promFactory != nil {
|
||||
prometheusGVRs := []schema.GroupVersionResource{
|
||||
{Group: "monitoring.coreos.com", Version: "v1", Resource: "prometheuses"},
|
||||
{Group: "monitoring.coreos.com", Version: "v1", Resource: "prometheusrules"},
|
||||
{Group: "monitoring.coreos.com", Version: "v1", Resource: "thanosrulers"},
|
||||
}
|
||||
for _, gvr := range prometheusGVRs {
|
||||
if isResourceExists(gvr) {
|
||||
_, err = promFactory.ForResource(gvr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
klog.Warningf("resource %s not exists in the cluster", gvr)
|
||||
}
|
||||
}
|
||||
promFactory.Start(stopCh)
|
||||
promFactory.WaitForCacheSync(stopCh)
|
||||
}
|
||||
|
||||
// controller runtime cache for resources
|
||||
go s.RuntimeCache.Start(stopCh)
|
||||
s.RuntimeCache.WaitForCacheSync(stopCh)
|
||||
|
||||
@@ -56,7 +56,7 @@ func TestGetAuditLevel(t *testing.T) {
|
||||
|
||||
ksClient := fake.NewSimpleClientset()
|
||||
k8sClient := fakek8s.NewSimpleClientset()
|
||||
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, nil, nil, nil)
|
||||
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, nil, nil, nil, nil)
|
||||
|
||||
a := auditing{
|
||||
webhookLister: fakeInformerFactory.KubeSphereSharedInformerFactory().Auditing().V1alpha1().Webhooks().Lister(),
|
||||
@@ -85,7 +85,7 @@ func TestAuditing_Enabled(t *testing.T) {
|
||||
|
||||
ksClient := fake.NewSimpleClientset()
|
||||
k8sClient := fakek8s.NewSimpleClientset()
|
||||
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, nil, nil, nil)
|
||||
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, nil, nil, nil, nil)
|
||||
|
||||
a := auditing{
|
||||
webhookLister: fakeInformerFactory.KubeSphereSharedInformerFactory().Auditing().V1alpha1().Webhooks().Lister(),
|
||||
@@ -115,7 +115,7 @@ func TestAuditing_K8sAuditingEnabled(t *testing.T) {
|
||||
|
||||
ksClient := fake.NewSimpleClientset()
|
||||
k8sClient := fakek8s.NewSimpleClientset()
|
||||
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, nil, nil, nil)
|
||||
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, nil, nil, nil, nil)
|
||||
|
||||
a := auditing{
|
||||
webhookLister: fakeInformerFactory.KubeSphereSharedInformerFactory().Auditing().V1alpha1().Webhooks().Lister(),
|
||||
@@ -145,7 +145,7 @@ func TestAuditing_LogRequestObject(t *testing.T) {
|
||||
|
||||
ksClient := fake.NewSimpleClientset()
|
||||
k8sClient := fakek8s.NewSimpleClientset()
|
||||
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, nil, nil, nil)
|
||||
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, nil, nil, nil, nil)
|
||||
|
||||
a := auditing{
|
||||
webhookLister: fakeInformerFactory.KubeSphereSharedInformerFactory().Auditing().V1alpha1().Webhooks().Lister(),
|
||||
@@ -236,7 +236,7 @@ func TestAuditing_LogResponseObject(t *testing.T) {
|
||||
|
||||
ksClient := fake.NewSimpleClientset()
|
||||
k8sClient := fakek8s.NewSimpleClientset()
|
||||
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, nil, nil, nil)
|
||||
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, nil, nil, nil, nil)
|
||||
|
||||
a := auditing{
|
||||
webhookLister: fakeInformerFactory.KubeSphereSharedInformerFactory().Auditing().V1alpha1().Webhooks().Lister(),
|
||||
|
||||
@@ -857,7 +857,7 @@ func newMockRBACAuthorizer(staticRoles *StaticRoles) (*RBACAuthorizer, error) {
|
||||
|
||||
ksClient := fakeks.NewSimpleClientset()
|
||||
k8sClient := fakek8s.NewSimpleClientset()
|
||||
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, nil, nil, nil)
|
||||
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, nil, nil, nil, nil)
|
||||
|
||||
k8sInformerFactory := fakeInformerFactory.KubernetesSharedInformerFactory()
|
||||
ksInformerFactory := fakeInformerFactory.KubeSphereSharedInformerFactory()
|
||||
|
||||
@@ -25,6 +25,7 @@ import (
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/alerting"
|
||||
auditingclient "kubesphere.io/kubesphere/pkg/simple/client/auditing/elasticsearch"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/cache"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/customalerting"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/devops/jenkins"
|
||||
eventsclient "kubesphere.io/kubesphere/pkg/simple/client/events/elasticsearch"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
|
||||
@@ -97,6 +98,7 @@ type Config struct {
|
||||
AuditingOptions *auditingclient.Options `json:"auditing,omitempty" yaml:"auditing,omitempty" mapstructure:"auditing"`
|
||||
AlertingOptions *alerting.Options `json:"alerting,omitempty" yaml:"alerting,omitempty" mapstructure:"alerting"`
|
||||
NotificationOptions *notification.Options `json:"notification,omitempty" yaml:"notification,omitempty" mapstructure:"notification"`
|
||||
CustomAlertingOptions *customalerting.Options `json:"customalerting,omitempty" yaml:"customalerting,omitempty" mapstructure:"customalerting"`
|
||||
}
|
||||
|
||||
// newConfig creates a default non-empty Config
|
||||
@@ -120,6 +122,7 @@ func New() *Config {
|
||||
MultiClusterOptions: multicluster.NewOptions(),
|
||||
EventsOptions: eventsclient.NewElasticSearchOptions(),
|
||||
AuditingOptions: auditingclient.NewElasticSearchOptions(),
|
||||
CustomAlertingOptions: customalerting.NewOptions(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ import (
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/alerting"
|
||||
auditingclient "kubesphere.io/kubesphere/pkg/simple/client/auditing/elasticsearch"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/cache"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/customalerting"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/devops/jenkins"
|
||||
eventsclient "kubesphere.io/kubesphere/pkg/simple/client/events/elasticsearch"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
|
||||
@@ -156,6 +157,11 @@ func newTestConfig() (*Config, error) {
|
||||
IndexPrefix: "ks-logstash-auditing",
|
||||
Version: "6",
|
||||
},
|
||||
CustomAlertingOptions: &customalerting.Options{
|
||||
PrometheusEndpoint: "http://prometheus-operated.kubesphere-monitoring-system.svc",
|
||||
ThanosRulerEndpoint: "http://thanos-ruler-operated.kubesphere-monitoring-system.svc",
|
||||
ThanosRuleResourceLabels: "thanosruler=thanos-ruler,role=thanos-alerting-rules",
|
||||
},
|
||||
}
|
||||
return conf, nil
|
||||
}
|
||||
|
||||
@@ -104,6 +104,8 @@ const (
|
||||
LogQueryTag = "Log Query"
|
||||
EventsQueryTag = "Events Query"
|
||||
AuditingQueryTag = "Auditing Query"
|
||||
|
||||
CustomAlertingTag = "Custom Alerting"
|
||||
)
|
||||
|
||||
var (
|
||||
|
||||
@@ -19,6 +19,8 @@ package informers
|
||||
import (
|
||||
snapshotclient "github.com/kubernetes-csi/external-snapshotter/client/v3/clientset/versioned"
|
||||
snapshotinformer "github.com/kubernetes-csi/external-snapshotter/client/v3/informers/externalversions"
|
||||
prominformers "github.com/prometheus-operator/prometheus-operator/pkg/client/informers/externalversions"
|
||||
promresourcesclient "github.com/prometheus-operator/prometheus-operator/pkg/client/versioned"
|
||||
istioclient "istio.io/client-go/pkg/clientset/versioned"
|
||||
istioinformers "istio.io/client-go/pkg/informers/externalversions"
|
||||
apiextensionsclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
|
||||
@@ -41,6 +43,7 @@ type InformerFactory interface {
|
||||
IstioSharedInformerFactory() istioinformers.SharedInformerFactory
|
||||
SnapshotSharedInformerFactory() snapshotinformer.SharedInformerFactory
|
||||
ApiExtensionSharedInformerFactory() apiextensionsinformers.SharedInformerFactory
|
||||
PrometheusSharedInformerFactory() prominformers.SharedInformerFactory
|
||||
|
||||
// Start shared informer factory one by one if they are not nil
|
||||
Start(stopCh <-chan struct{})
|
||||
@@ -52,10 +55,12 @@ type informerFactories struct {
|
||||
istioInformerFactory istioinformers.SharedInformerFactory
|
||||
snapshotInformerFactory snapshotinformer.SharedInformerFactory
|
||||
apiextensionsInformerFactory apiextensionsinformers.SharedInformerFactory
|
||||
prometheusInformerFactory prominformers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func NewInformerFactories(client kubernetes.Interface, ksClient versioned.Interface, istioClient istioclient.Interface,
|
||||
snapshotClient snapshotclient.Interface, apiextensionsClient apiextensionsclient.Interface) InformerFactory {
|
||||
snapshotClient snapshotclient.Interface, apiextensionsClient apiextensionsclient.Interface,
|
||||
prometheusClient promresourcesclient.Interface) InformerFactory {
|
||||
factory := &informerFactories{}
|
||||
|
||||
if client != nil {
|
||||
@@ -78,6 +83,10 @@ func NewInformerFactories(client kubernetes.Interface, ksClient versioned.Interf
|
||||
factory.apiextensionsInformerFactory = apiextensionsinformers.NewSharedInformerFactory(apiextensionsClient, defaultResync)
|
||||
}
|
||||
|
||||
if prometheusClient != nil {
|
||||
factory.prometheusInformerFactory = prominformers.NewSharedInformerFactory(prometheusClient, defaultResync)
|
||||
}
|
||||
|
||||
return factory
|
||||
}
|
||||
|
||||
@@ -101,6 +110,10 @@ func (f *informerFactories) ApiExtensionSharedInformerFactory() apiextensionsinf
|
||||
return f.apiextensionsInformerFactory
|
||||
}
|
||||
|
||||
func (f *informerFactories) PrometheusSharedInformerFactory() prominformers.SharedInformerFactory {
|
||||
return f.prometheusInformerFactory
|
||||
}
|
||||
|
||||
func (f *informerFactories) Start(stopCh <-chan struct{}) {
|
||||
if f.informerFactory != nil {
|
||||
f.informerFactory.Start(stopCh)
|
||||
@@ -121,4 +134,8 @@ func (f *informerFactories) Start(stopCh <-chan struct{}) {
|
||||
if f.apiextensionsInformerFactory != nil {
|
||||
f.apiextensionsInformerFactory.Start(stopCh)
|
||||
}
|
||||
|
||||
if f.prometheusInformerFactory != nil {
|
||||
f.prometheusInformerFactory.Start(stopCh)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@ limitations under the License.
|
||||
package informers
|
||||
|
||||
import (
|
||||
prominformers "github.com/prometheus-operator/prometheus-operator/pkg/client/informers/externalversions"
|
||||
promfake "github.com/prometheus-operator/prometheus-operator/pkg/client/versioned/fake"
|
||||
snapshotinformer "github.com/kubernetes-csi/external-snapshotter/client/v3/informers/externalversions"
|
||||
istioinformers "istio.io/client-go/pkg/informers/externalversions"
|
||||
apiextensionsinformers "k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions"
|
||||
@@ -30,6 +32,7 @@ import (
|
||||
type nullInformerFactory struct {
|
||||
fakeK8sInformerFactory informers.SharedInformerFactory
|
||||
fakeKsInformerFactory ksinformers.SharedInformerFactory
|
||||
fakePrometheusFactory prominformers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func NewNullInformerFactory() InformerFactory {
|
||||
@@ -39,9 +42,13 @@ func NewNullInformerFactory() InformerFactory {
|
||||
fakeKsClient := ksfake.NewSimpleClientset()
|
||||
fakeKsInformerFactory := ksinformers.NewSharedInformerFactory(fakeKsClient, time.Minute*10)
|
||||
|
||||
fakePrometheusClient := promfake.NewSimpleClientset()
|
||||
fakePrometheusFactory := prominformers.NewSharedInformerFactory(fakePrometheusClient, time.Minute*10)
|
||||
|
||||
return &nullInformerFactory{
|
||||
fakeK8sInformerFactory: fakeInformerFactory,
|
||||
fakeKsInformerFactory: fakeKsInformerFactory,
|
||||
fakePrometheusFactory: fakePrometheusFactory,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,5 +72,9 @@ func (n nullInformerFactory) ApiExtensionSharedInformerFactory() apiextensionsin
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *nullInformerFactory) PrometheusSharedInformerFactory() prominformers.SharedInformerFactory {
|
||||
return n.fakePrometheusFactory
|
||||
}
|
||||
|
||||
func (n nullInformerFactory) Start(stopCh <-chan struct{}) {
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ func TestGeranteAgentDeployment(t *testing.T) {
|
||||
k8sclient := k8sfake.NewSimpleClientset(service)
|
||||
ksclient := fake.NewSimpleClientset(cluster)
|
||||
|
||||
informersFactory := informers.NewInformerFactories(k8sclient, ksclient, nil, nil, nil)
|
||||
informersFactory := informers.NewInformerFactories(k8sclient, ksclient, nil, nil, nil, nil)
|
||||
|
||||
informersFactory.KubernetesSharedInformerFactory().Core().V1().Services().Informer().GetIndexer().Add(service)
|
||||
informersFactory.KubeSphereSharedInformerFactory().Cluster().V1alpha1().Clusters().Informer().GetIndexer().Add(cluster)
|
||||
@@ -233,7 +233,7 @@ func TestValidateKubeConfig(t *testing.T) {
|
||||
k8sclient := k8sfake.NewSimpleClientset(service)
|
||||
ksclient := fake.NewSimpleClientset(cluster)
|
||||
|
||||
informersFactory := informers.NewInformerFactories(k8sclient, ksclient, nil, nil, nil)
|
||||
informersFactory := informers.NewInformerFactories(k8sclient, ksclient, nil, nil, nil, nil)
|
||||
|
||||
informersFactory.KubernetesSharedInformerFactory().Core().V1().Services().Informer().GetIndexer().Add(service)
|
||||
informersFactory.KubeSphereSharedInformerFactory().Cluster().V1alpha1().Clusters().Informer().GetIndexer().Add(cluster)
|
||||
|
||||
285
pkg/kapis/customalerting/v1alpha1/handler.go
Normal file
285
pkg/kapis/customalerting/v1alpha1/handler.go
Normal file
@@ -0,0 +1,285 @@
|
||||
/*
|
||||
Copyright 2020 KubeSphere Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
promresourcesclient "github.com/prometheus-operator/prometheus-operator/pkg/client/versioned"
|
||||
"github.com/emicklei/go-restful"
|
||||
"k8s.io/klog"
|
||||
ksapi "kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/api/customalerting/v1alpha1"
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
customalertingmodels "kubesphere.io/kubesphere/pkg/models/customalerting"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/customalerting"
|
||||
)
|
||||
|
||||
type handler struct {
|
||||
operator customalertingmodels.Operator
|
||||
}
|
||||
|
||||
func newHandler(informers informers.InformerFactory,
|
||||
promResourceClient promresourcesclient.Interface, ruleClient customalerting.RuleClient,
|
||||
option *customalerting.Options) *handler {
|
||||
return &handler{
|
||||
operator: customalertingmodels.NewOperator(
|
||||
informers, promResourceClient, ruleClient, option),
|
||||
}
|
||||
}
|
||||
|
||||
func (h *handler) handleListCustomAlertingRules(req *restful.Request, resp *restful.Response) {
|
||||
namespace := req.PathParameter("namespace")
|
||||
query, err := v1alpha1.ParseAlertingRuleQueryParams(req)
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
ksapi.HandleBadRequest(resp, nil, err)
|
||||
return
|
||||
}
|
||||
|
||||
rules, err := h.operator.ListCustomAlertingRules(req.Request.Context(), namespace, query)
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
switch {
|
||||
case err == v1alpha1.ErrThanosRulerNotEnabled:
|
||||
ksapi.HandleBadRequest(resp, nil, err)
|
||||
default:
|
||||
ksapi.HandleInternalError(resp, nil, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
resp.WriteEntity(rules)
|
||||
}
|
||||
|
||||
func (h *handler) handleListCustomRulesAlerts(req *restful.Request, resp *restful.Response) {
|
||||
namespace := req.PathParameter("namespace")
|
||||
query, err := v1alpha1.ParseAlertQueryParams(req)
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
ksapi.HandleBadRequest(resp, nil, err)
|
||||
return
|
||||
}
|
||||
|
||||
alerts, err := h.operator.ListCustomRulesAlerts(req.Request.Context(), namespace, query)
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
switch {
|
||||
case err == v1alpha1.ErrThanosRulerNotEnabled:
|
||||
ksapi.HandleBadRequest(resp, nil, err)
|
||||
default:
|
||||
ksapi.HandleInternalError(resp, nil, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
resp.WriteEntity(alerts)
|
||||
}
|
||||
|
||||
func (h *handler) handleGetCustomAlertingRule(req *restful.Request, resp *restful.Response) {
|
||||
namespace := req.PathParameter("namespace")
|
||||
ruleName := req.PathParameter("rule_name")
|
||||
|
||||
rule, err := h.operator.GetCustomAlertingRule(req.Request.Context(), namespace, ruleName)
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
switch {
|
||||
case err == v1alpha1.ErrThanosRulerNotEnabled:
|
||||
ksapi.HandleBadRequest(resp, nil, err)
|
||||
case err == v1alpha1.ErrAlertingRuleNotFound:
|
||||
ksapi.HandleNotFound(resp, nil, err)
|
||||
default:
|
||||
ksapi.HandleInternalError(resp, nil, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
if rule == nil {
|
||||
ksapi.HandleNotFound(resp, nil, err)
|
||||
return
|
||||
}
|
||||
resp.WriteEntity(rule)
|
||||
}
|
||||
|
||||
func (h *handler) handleListCustomSpecifiedRuleAlerts(req *restful.Request, resp *restful.Response) {
|
||||
namespace := req.PathParameter("namespace")
|
||||
ruleName := req.PathParameter("rule_name")
|
||||
|
||||
alerts, err := h.operator.ListCustomSpecifiedRuleAlerts(req.Request.Context(), namespace, ruleName)
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
switch {
|
||||
case err == v1alpha1.ErrThanosRulerNotEnabled:
|
||||
ksapi.HandleBadRequest(resp, nil, err)
|
||||
case err == v1alpha1.ErrAlertingRuleNotFound:
|
||||
ksapi.HandleNotFound(resp, nil, err)
|
||||
default:
|
||||
ksapi.HandleInternalError(resp, nil, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
resp.WriteEntity(alerts)
|
||||
}
|
||||
|
||||
func (h *handler) handleCreateCustomAlertingRule(req *restful.Request, resp *restful.Response) {
|
||||
namespace := req.PathParameter("namespace")
|
||||
|
||||
var rule v1alpha1.PostableAlertingRule
|
||||
if err := req.ReadEntity(&rule); err != nil {
|
||||
klog.Error(err)
|
||||
ksapi.HandleBadRequest(resp, nil, err)
|
||||
return
|
||||
}
|
||||
if err := rule.Validate(); err != nil {
|
||||
klog.Error(err)
|
||||
ksapi.HandleBadRequest(resp, nil, err)
|
||||
return
|
||||
}
|
||||
|
||||
err := h.operator.CreateCustomAlertingRule(req.Request.Context(), namespace, &rule)
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
switch {
|
||||
case err == v1alpha1.ErrThanosRulerNotEnabled:
|
||||
ksapi.HandleBadRequest(resp, nil, err)
|
||||
case err == v1alpha1.ErrAlertingRuleAlreadyExists:
|
||||
ksapi.HandleConflict(resp, nil, err)
|
||||
default:
|
||||
ksapi.HandleInternalError(resp, nil, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (h *handler) handleUpdateCustomAlertingRule(req *restful.Request, resp *restful.Response) {
|
||||
namespace := req.PathParameter("namespace")
|
||||
ruleName := req.PathParameter("rule_name")
|
||||
|
||||
var rule v1alpha1.PostableAlertingRule
|
||||
if err := req.ReadEntity(&rule); err != nil {
|
||||
klog.Error(err)
|
||||
ksapi.HandleBadRequest(resp, nil, err)
|
||||
return
|
||||
}
|
||||
if err := rule.Validate(); err != nil {
|
||||
klog.Error(err)
|
||||
ksapi.HandleBadRequest(resp, nil, err)
|
||||
return
|
||||
}
|
||||
|
||||
err := h.operator.UpdateCustomAlertingRule(req.Request.Context(), namespace, ruleName, &rule)
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
switch {
|
||||
case err == v1alpha1.ErrThanosRulerNotEnabled:
|
||||
ksapi.HandleBadRequest(resp, nil, err)
|
||||
case err == v1alpha1.ErrAlertingRuleNotFound:
|
||||
ksapi.HandleNotFound(resp, nil, err)
|
||||
default:
|
||||
ksapi.HandleInternalError(resp, nil, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (h *handler) handleDeleteCustomAlertingRule(req *restful.Request, resp *restful.Response) {
|
||||
namespace := req.PathParameter("namespace")
|
||||
name := req.PathParameter("rule_name")
|
||||
|
||||
err := h.operator.DeleteCustomAlertingRule(req.Request.Context(), namespace, name)
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
switch {
|
||||
case err == v1alpha1.ErrThanosRulerNotEnabled:
|
||||
ksapi.HandleBadRequest(resp, nil, err)
|
||||
case err == v1alpha1.ErrAlertingRuleNotFound:
|
||||
ksapi.HandleNotFound(resp, nil, err)
|
||||
default:
|
||||
ksapi.HandleInternalError(resp, nil, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (h *handler) handleListBuiltinAlertingRules(req *restful.Request, resp *restful.Response) {
|
||||
query, err := v1alpha1.ParseAlertingRuleQueryParams(req)
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
ksapi.HandleBadRequest(resp, nil, err)
|
||||
return
|
||||
}
|
||||
|
||||
rules, err := h.operator.ListBuiltinAlertingRules(req.Request.Context(), query)
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
ksapi.HandleInternalError(resp, nil, err)
|
||||
return
|
||||
}
|
||||
resp.WriteEntity(rules)
|
||||
}
|
||||
|
||||
func (h *handler) handleListBuiltinRulesAlerts(req *restful.Request, resp *restful.Response) {
|
||||
query, err := v1alpha1.ParseAlertQueryParams(req)
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
ksapi.HandleBadRequest(resp, nil, err)
|
||||
return
|
||||
}
|
||||
|
||||
alerts, err := h.operator.ListBuiltinRulesAlerts(req.Request.Context(), query)
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
ksapi.HandleInternalError(resp, nil, err)
|
||||
return
|
||||
}
|
||||
resp.WriteEntity(alerts)
|
||||
}
|
||||
|
||||
func (h *handler) handleGetBuiltinAlertingRule(req *restful.Request, resp *restful.Response) {
|
||||
ruleId := req.PathParameter("rule_id")
|
||||
|
||||
rule, err := h.operator.GetBuiltinAlertingRule(req.Request.Context(), ruleId)
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
switch {
|
||||
case err == v1alpha1.ErrAlertingRuleNotFound:
|
||||
ksapi.HandleNotFound(resp, nil, err)
|
||||
default:
|
||||
ksapi.HandleInternalError(resp, nil, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
if rule == nil {
|
||||
ksapi.HandleNotFound(resp, nil, err)
|
||||
return
|
||||
}
|
||||
|
||||
resp.WriteEntity(rule)
|
||||
}
|
||||
|
||||
func (h *handler) handleListBuiltinSpecifiedRuleAlerts(req *restful.Request, resp *restful.Response) {
|
||||
ruleId := req.PathParameter("rule_id")
|
||||
|
||||
alerts, err := h.operator.ListBuiltinSpecifiedRuleAlerts(req.Request.Context(), ruleId)
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
switch {
|
||||
case err == v1alpha1.ErrAlertingRuleNotFound:
|
||||
ksapi.HandleNotFound(resp, nil, err)
|
||||
default:
|
||||
ksapi.HandleInternalError(resp, nil, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
resp.WriteEntity(alerts)
|
||||
}
|
||||
199
pkg/kapis/customalerting/v1alpha1/register.go
Normal file
199
pkg/kapis/customalerting/v1alpha1/register.go
Normal file
@@ -0,0 +1,199 @@
|
||||
/*
|
||||
Copyright 2020 KubeSphere Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
promresourcesclient "github.com/prometheus-operator/prometheus-operator/pkg/client/versioned"
|
||||
"github.com/emicklei/go-restful"
|
||||
restfulspec "github.com/emicklei/go-restful-openapi"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
ksapi "kubesphere.io/kubesphere/pkg/api"
|
||||
customalertingv1alpha1 "kubesphere.io/kubesphere/pkg/api/customalerting/v1alpha1"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/runtime"
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/customalerting"
|
||||
)
|
||||
|
||||
const (
|
||||
groupName = "custom.alerting.kubesphere.io"
|
||||
)
|
||||
|
||||
var GroupVersion = schema.GroupVersion{Group: groupName, Version: "v1alpha1"}
|
||||
|
||||
func AddToContainer(container *restful.Container, informers informers.InformerFactory,
|
||||
promResourceClient promresourcesclient.Interface, ruleClient customalerting.RuleClient,
|
||||
option *customalerting.Options) error {
|
||||
|
||||
handler := newHandler(informers, promResourceClient, ruleClient, option)
|
||||
|
||||
ws := runtime.NewWebService(GroupVersion)
|
||||
|
||||
ws.Route(ws.GET("/rules").
|
||||
To(handler.handleListCustomAlertingRules).
|
||||
Doc("list the cluster-level custom alerting rules").
|
||||
Param(ws.QueryParameter("name", "rule name")).
|
||||
Param(ws.QueryParameter("state", "state of a rule based on its alerts, one of `firing`, `pending`, `inactive`")).
|
||||
Param(ws.QueryParameter("health", "health state of a rule based on the last execution, one of `ok`, `err`, `unknown`")).
|
||||
Param(ws.QueryParameter("label_filters", "label filters, concatenating multiple filters with commas, equal symbol for exact query, wave symbol for fuzzy query e.g. name~a").DataFormat("key=%s,key~%s")).
|
||||
Param(ws.QueryParameter("sort_field", "sort field, one of `name`, `lastEvaluation`, `evaluationTime`")).
|
||||
Param(ws.QueryParameter("sort_type", "sort type, one of `asc`, `desc`")).
|
||||
Param(ws.QueryParameter("offset", "offset of the result set").DataType("integer").DefaultValue("0")).
|
||||
Param(ws.QueryParameter("limit", "limit size of the result set").DataType("integer").DefaultValue("10")).
|
||||
Returns(http.StatusOK, ksapi.StatusOK, customalertingv1alpha1.GettableAlertingRuleList{}).
|
||||
Metadata(restfulspec.KeyOpenAPITags, []string{constants.CustomAlertingTag}))
|
||||
|
||||
ws.Route(ws.GET("/alerts").
|
||||
To(handler.handleListCustomRulesAlerts).
|
||||
Doc("list the alerts of the cluster-level custom alerting rules").
|
||||
Param(ws.QueryParameter("state", "state, one of `firing`, `pending`, `inactive`")).
|
||||
Param(ws.QueryParameter("label_filters", "label filters, concatenating multiple filters with commas, equal symbol for exact query, wave symbol for fuzzy query e.g. name~a").DataFormat("key=%s,key~%s")).
|
||||
Param(ws.QueryParameter("offset", "offset of the result set").DataType("integer").DefaultValue("0")).
|
||||
Param(ws.QueryParameter("limit", "limit size of the result set").DataType("integer").DefaultValue("10")).
|
||||
Returns(http.StatusOK, ksapi.StatusOK, customalertingv1alpha1.AlertList{}).
|
||||
Metadata(restfulspec.KeyOpenAPITags, []string{constants.CustomAlertingTag}))
|
||||
|
||||
ws.Route(ws.GET("/rules/{rule_name}").
|
||||
To(handler.handleGetCustomAlertingRule).
|
||||
Doc("get the cluster-level custom alerting rule with the specified name").
|
||||
Returns(http.StatusOK, ksapi.StatusOK, customalertingv1alpha1.GettableAlertingRule{}).
|
||||
Metadata(restfulspec.KeyOpenAPITags, []string{constants.CustomAlertingTag}))
|
||||
|
||||
ws.Route(ws.GET("/rules/{rule_name}/alerts").
|
||||
To(handler.handleListCustomSpecifiedRuleAlerts).
|
||||
Doc("list the alerts of the cluster-level custom alerting rule with the specified name").
|
||||
Returns(http.StatusOK, ksapi.StatusOK, []customalertingv1alpha1.Alert{}).
|
||||
Metadata(restfulspec.KeyOpenAPITags, []string{constants.CustomAlertingTag}))
|
||||
|
||||
ws.Route(ws.POST("/rules").
|
||||
To(handler.handleCreateCustomAlertingRule).
|
||||
Doc("create a cluster-level custom alerting rule").
|
||||
Reads(customalertingv1alpha1.PostableAlertingRule{}).
|
||||
Returns(http.StatusOK, ksapi.StatusOK, nil).
|
||||
Metadata(restfulspec.KeyOpenAPITags, []string{constants.CustomAlertingTag}))
|
||||
|
||||
ws.Route(ws.PUT("/rules/{rule_name}").
|
||||
To(handler.handleUpdateCustomAlertingRule).
|
||||
Doc("update the cluster-level custom alerting rule with the specified name").
|
||||
Reads(customalertingv1alpha1.PostableAlertingRule{}).
|
||||
Returns(http.StatusOK, ksapi.StatusOK, nil).
|
||||
Metadata(restfulspec.KeyOpenAPITags, []string{constants.CustomAlertingTag}))
|
||||
|
||||
ws.Route(ws.DELETE("/rules/{rule_name}").
|
||||
To(handler.handleDeleteCustomAlertingRule).
|
||||
Doc("delete the cluster-level custom alerting rule with the specified name").
|
||||
Returns(http.StatusOK, ksapi.StatusOK, nil).
|
||||
Metadata(restfulspec.KeyOpenAPITags, []string{constants.CustomAlertingTag}))
|
||||
|
||||
ws.Route(ws.GET("/namespaces/{namespace}/rules").
|
||||
To(handler.handleListCustomAlertingRules).
|
||||
Doc("list the custom alerting rules in the specified namespace").
|
||||
Param(ws.QueryParameter("name", "rule name")).
|
||||
Param(ws.QueryParameter("state", "state of a rule based on its alerts, one of `firing`, `pending`, `inactive`")).
|
||||
Param(ws.QueryParameter("health", "health state of a rule based on the last execution, one of `ok`, `err`, `unknown`")).
|
||||
Param(ws.QueryParameter("label_filters", "label filters, concatenating multiple filters with commas, equal symbol for exact query, wave symbol for fuzzy query e.g. name~a").DataFormat("key=%s,key~%s")).
|
||||
Param(ws.QueryParameter("sort_field", "sort field, one of `name`, `lastEvaluation`, `evaluationTime`")).
|
||||
Param(ws.QueryParameter("sort_type", "sort type, one of `asc`, `desc`")).
|
||||
Param(ws.QueryParameter("offset", "offset of the result set").DataType("integer").DefaultValue("0")).
|
||||
Param(ws.QueryParameter("limit", "limit size of the result set").DataType("integer").DefaultValue("10")).
|
||||
Returns(http.StatusOK, ksapi.StatusOK, customalertingv1alpha1.GettableAlertingRuleList{}).
|
||||
Metadata(restfulspec.KeyOpenAPITags, []string{constants.CustomAlertingTag}))
|
||||
|
||||
ws.Route(ws.GET("/namespaces/{namespace}/alerts").
|
||||
To(handler.handleListCustomRulesAlerts).
|
||||
Doc("list the alerts of the custom alerting rules in the specified namespace.").
|
||||
Param(ws.QueryParameter("state", "state, one of `firing`, `pending`, `inactive`")).
|
||||
Param(ws.QueryParameter("label_filters", "label filters, concatenating multiple filters with commas, equal symbol for exact query, wave symbol for fuzzy query e.g. name~a").DataFormat("key=%s,key~%s")).
|
||||
Param(ws.QueryParameter("offset", "offset of the result set").DataType("integer").DefaultValue("0")).
|
||||
Param(ws.QueryParameter("limit", "limit size of the result set").DataType("integer").DefaultValue("10")).
|
||||
Returns(http.StatusOK, ksapi.StatusOK, customalertingv1alpha1.AlertList{}).
|
||||
Metadata(restfulspec.KeyOpenAPITags, []string{constants.CustomAlertingTag}))
|
||||
|
||||
ws.Route(ws.GET("/namespaces/{namespace}/rules/{rule_name}").
|
||||
To(handler.handleGetCustomAlertingRule).
|
||||
Doc("get the custom alerting rule with the specified name in the specified namespace").
|
||||
Returns(http.StatusOK, ksapi.StatusOK, customalertingv1alpha1.GettableAlertingRule{}).
|
||||
Metadata(restfulspec.KeyOpenAPITags, []string{constants.CustomAlertingTag}))
|
||||
|
||||
ws.Route(ws.GET("/namespaces/{namespace}/rules/{rule_name}/alerts").
|
||||
To(handler.handleListCustomSpecifiedRuleAlerts).
|
||||
Doc("get the alerts of the custom alerting rule with the specified name in the specified namespace").
|
||||
Returns(http.StatusOK, ksapi.StatusOK, []customalertingv1alpha1.Alert{}).
|
||||
Metadata(restfulspec.KeyOpenAPITags, []string{constants.CustomAlertingTag}))
|
||||
|
||||
ws.Route(ws.POST("/namespaces/{namespace}/rules").
|
||||
To(handler.handleCreateCustomAlertingRule).
|
||||
Doc("create a custom alerting rule in the specified namespace").
|
||||
Reads(customalertingv1alpha1.PostableAlertingRule{}).
|
||||
Returns(http.StatusOK, ksapi.StatusOK, "").
|
||||
Metadata(restfulspec.KeyOpenAPITags, []string{constants.CustomAlertingTag}))
|
||||
|
||||
ws.Route(ws.PUT("/namespaces/{namespace}/rules/{rule_name}").
|
||||
To(handler.handleUpdateCustomAlertingRule).
|
||||
Doc("update the custom alerting rule with the specified name in the specified namespace").
|
||||
Reads(customalertingv1alpha1.PostableAlertingRule{}).
|
||||
Returns(http.StatusOK, ksapi.StatusOK, "").
|
||||
Metadata(restfulspec.KeyOpenAPITags, []string{constants.CustomAlertingTag}))
|
||||
|
||||
ws.Route(ws.DELETE("/namespaces/{namespace}/rules/{rule_name}").
|
||||
To(handler.handleDeleteCustomAlertingRule).
|
||||
Doc("delete the custom alerting rule with the specified rule name in the specified namespace").
|
||||
Returns(http.StatusOK, ksapi.StatusOK, nil).
|
||||
Metadata(restfulspec.KeyOpenAPITags, []string{constants.CustomAlertingTag}))
|
||||
|
||||
ws.Route(ws.GET("/builtin/rules").
|
||||
To(handler.handleListBuiltinAlertingRules).
|
||||
Doc("list the builtin(non-custom) alerting rules").
|
||||
Param(ws.QueryParameter("name", "rule name")).
|
||||
Param(ws.QueryParameter("state", "state of a rule based on its alerts, one of `firing`, `pending`, `inactive`")).
|
||||
Param(ws.QueryParameter("health", "health state of a rule based on the last execution, one of `ok`, `err`, `unknown`")).
|
||||
Param(ws.QueryParameter("label_filters", "label filters, concatenating multiple filters with commas, equal symbol for exact query, wave symbol for fuzzy query e.g. name~a").DataFormat("key=%s,key~%s")).
|
||||
Param(ws.QueryParameter("sort_field", "sort field, one of `name`, `lastEvaluation`, `evaluationTime`")).
|
||||
Param(ws.QueryParameter("sort_type", "sort type, one of `asc`, `desc`")).
|
||||
Param(ws.QueryParameter("offset", "offset of the result set").DataType("integer").DefaultValue("0")).
|
||||
Param(ws.QueryParameter("limit", "limit size of the result set").DataType("integer").DefaultValue("10")).
|
||||
Returns(http.StatusOK, ksapi.StatusOK, customalertingv1alpha1.GettableAlertingRuleList{}).
|
||||
Metadata(restfulspec.KeyOpenAPITags, []string{constants.CustomAlertingTag}))
|
||||
|
||||
ws.Route(ws.GET("/builtin/alerts").
|
||||
To(handler.handleListBuiltinRulesAlerts).
|
||||
Doc("list the alerts of the builtin(non-custom) rules").
|
||||
Param(ws.QueryParameter("state", "state, one of `firing`, `pending`, `inactive`")).
|
||||
Param(ws.QueryParameter("label_filters", "label filters, concatenating multiple filters with commas, equal symbol for exact query, wave symbol for fuzzy query e.g. name~a").DataFormat("key=%s,key~%s")).
|
||||
Param(ws.QueryParameter("offset", "offset of the result set").DataType("integer").DefaultValue("0")).
|
||||
Param(ws.QueryParameter("limit", "limit size of the result set").DataType("integer").DefaultValue("10")).
|
||||
Returns(http.StatusOK, ksapi.StatusOK, customalertingv1alpha1.AlertList{}).
|
||||
Metadata(restfulspec.KeyOpenAPITags, []string{constants.CustomAlertingTag}))
|
||||
|
||||
ws.Route(ws.GET("/builtin/rules/{rule_id}").
|
||||
To(handler.handleGetBuiltinAlertingRule).
|
||||
Doc("get the builtin(non-custom) alerting rule with specified id").
|
||||
Returns(http.StatusOK, ksapi.StatusOK, customalertingv1alpha1.GettableAlertingRule{}).
|
||||
Metadata(restfulspec.KeyOpenAPITags, []string{constants.CustomAlertingTag}))
|
||||
|
||||
ws.Route(ws.GET("/builtin/rules/{rule_id}/alerts").
|
||||
To(handler.handleListBuiltinSpecifiedRuleAlerts).
|
||||
Doc("list the alerts of the builtin(non-custom) alerting rule with the specified id").
|
||||
Returns(http.StatusOK, ksapi.StatusOK, []customalertingv1alpha1.Alert{}).
|
||||
Metadata(restfulspec.KeyOpenAPITags, []string{constants.CustomAlertingTag}))
|
||||
|
||||
container.Add(ws)
|
||||
|
||||
return nil
|
||||
}
|
||||
147
pkg/kapis/customalerting/v1alpha1/test_test.go
Normal file
147
pkg/kapis/customalerting/v1alpha1/test_test.go
Normal file
@@ -0,0 +1,147 @@
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/emicklei/go-restful"
|
||||
restfulspec "github.com/emicklei/go-restful-openapi"
|
||||
"github.com/go-openapi/spec"
|
||||
promresourcesclient "github.com/prometheus-operator/prometheus-operator/pkg/client/versioned"
|
||||
"github.com/prometheus/prometheus/promql/parser"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/runtime"
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/customalerting"
|
||||
)
|
||||
|
||||
func TestTest(t *testing.T) {
|
||||
expr := `increase((max by(job) (etcd_server_leader_changes_seen_total{job=~".*etcd.*"}) or 0 * absent(etcd_server_leader_changes_seen_total{job=~".*etcd.*"}))[15m:1m]) >= 3`
|
||||
//expr = `absent_over_time(sum(nonexistent{job="myjob"})[1h:])`
|
||||
|
||||
pexpr, err := parser.ParseExpr(expr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Println(pexpr.String())
|
||||
}
|
||||
|
||||
func TestApis(t *testing.T) {
|
||||
kubeconfig := "D:/ks/conf/ks3-config"
|
||||
|
||||
config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
k8sClient := kubernetes.NewForConfigOrDie(config)
|
||||
promResourcesClient := promresourcesclient.NewForConfigOrDie(config)
|
||||
|
||||
option := &customalerting.Options{
|
||||
PrometheusEndpoint: "http://139.198.112.79:39090/",
|
||||
ThanosRulerEndpoint: "http://139.198.112.79:39091/",
|
||||
ThanosRuleResourceLabels: "role=thanos-alerting-rules,thanosruler:thanos-ruler",
|
||||
}
|
||||
ruleClient, err := customalerting.NewRuleClient(option)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
stopCh := make(chan struct{})
|
||||
|
||||
informerFactory := informers.NewInformerFactories(k8sClient, nil, nil, nil, nil, promResourcesClient)
|
||||
k8sGVRs := []schema.GroupVersionResource{
|
||||
{Group: "", Version: "v1", Resource: "namespaces"},
|
||||
}
|
||||
for _, gvr := range k8sGVRs {
|
||||
_, err = informerFactory.KubernetesSharedInformerFactory().ForResource(gvr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
prometheusGVRs := []schema.GroupVersionResource{
|
||||
{Group: "monitoring.coreos.com", Version: "v1", Resource: "prometheuses"},
|
||||
{Group: "monitoring.coreos.com", Version: "v1", Resource: "prometheusrules"},
|
||||
{Group: "monitoring.coreos.com", Version: "v1", Resource: "thanosrulers"},
|
||||
}
|
||||
for _, gvr := range prometheusGVRs {
|
||||
_, err = informerFactory.PrometheusSharedInformerFactory().ForResource(gvr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
informerFactory.Start(stopCh)
|
||||
informerFactory.KubernetesSharedInformerFactory().WaitForCacheSync(stopCh)
|
||||
informerFactory.PrometheusSharedInformerFactory().WaitForCacheSync(stopCh)
|
||||
informerFactory.Start(stopCh)
|
||||
|
||||
container := restful.NewContainer()
|
||||
AddToContainer(container, informerFactory, promResourcesClient, ruleClient, option)
|
||||
server := &http.Server{}
|
||||
server.Handler = container
|
||||
if err := server.ListenAndServe(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenSwaggerJson(t *testing.T) {
|
||||
container := runtime.Container
|
||||
|
||||
informerFactory := informers.NewNullInformerFactory()
|
||||
|
||||
AddToContainer(container, informerFactory, nil, nil, nil)
|
||||
|
||||
swagger := restfulspec.BuildSwagger(restfulspec.Config{
|
||||
WebServices: container.RegisteredWebServices(),
|
||||
PostBuildSwaggerObjectHandler: enrichSwaggerObject,
|
||||
})
|
||||
|
||||
swagger.Info.Extensions = make(spec.Extensions)
|
||||
swagger.Info.Extensions.Add("x-tagGroups", []struct {
|
||||
Name string `json:"name"`
|
||||
Tags []string `json:"tags"`
|
||||
}{
|
||||
{
|
||||
Name: "Custom Alerting",
|
||||
Tags: []string{constants.CustomAlertingTag},
|
||||
},
|
||||
})
|
||||
|
||||
enc := json.NewEncoder(os.Stdout)
|
||||
enc.SetIndent("", "\t")
|
||||
enc.Encode(swagger)
|
||||
}
|
||||
|
||||
func enrichSwaggerObject(swo *spec.Swagger) {
|
||||
swo.Info = &spec.Info{
|
||||
InfoProps: spec.InfoProps{
|
||||
Title: "KubeSphere",
|
||||
Description: "KubeSphere OpenAPI",
|
||||
Contact: &spec.ContactInfo{
|
||||
ContactInfoProps: spec.ContactInfoProps{
|
||||
Name: "KubeSphere",
|
||||
URL: "https://kubesphere.io/",
|
||||
Email: "kubesphere@yunify.com",
|
||||
},
|
||||
},
|
||||
License: &spec.License{
|
||||
LicenseProps: spec.LicenseProps{
|
||||
Name: "Apache 2.0",
|
||||
URL: "https://www.apache.org/licenses/LICENSE-2.0.html",
|
||||
},
|
||||
},
|
||||
Version: "0.1.0",
|
||||
}}
|
||||
|
||||
// setup security definitions
|
||||
swo.SecurityDefinitions = map[string]*spec.SecurityScheme{
|
||||
"jwt": spec.APIKeyAuth("Authorization", "header"),
|
||||
}
|
||||
swo.Security = []map[string][]string{{"jwt": []string{}}}
|
||||
}
|
||||
@@ -216,7 +216,7 @@ func TestParseRequestParams(t *testing.T) {
|
||||
for i, tt := range tests {
|
||||
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
|
||||
client := fake.NewSimpleClientset(&tt.namespace)
|
||||
fakeInformerFactory := informers.NewInformerFactories(client, nil, nil, nil, nil)
|
||||
fakeInformerFactory := informers.NewInformerFactories(client, nil, nil, nil, nil, nil)
|
||||
handler := newHandler(client, nil, fakeInformerFactory, nil)
|
||||
|
||||
result, err := handler.makeQueryOptions(tt.params, tt.lvl)
|
||||
|
||||
@@ -186,7 +186,7 @@ func prepare() (informers.InformerFactory, error) {
|
||||
snapshotClient := fakesnapshot.NewSimpleClientset()
|
||||
apiextensionsClient := fakeapiextensions.NewSimpleClientset()
|
||||
|
||||
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, istioClient, snapshotClient, apiextensionsClient)
|
||||
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, istioClient, snapshotClient, apiextensionsClient, nil)
|
||||
|
||||
k8sInformerFactory := fakeInformerFactory.KubernetesSharedInformerFactory()
|
||||
|
||||
|
||||
632
pkg/models/customalerting/customalerting.go
Normal file
632
pkg/models/customalerting/customalerting.go
Normal file
@@ -0,0 +1,632 @@
|
||||
package customalerting
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
promresourcesv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
|
||||
prominformersv1 "github.com/prometheus-operator/prometheus-operator/pkg/client/informers/externalversions/monitoring/v1"
|
||||
promresourcesclient "github.com/prometheus-operator/prometheus-operator/pkg/client/versioned"
|
||||
"github.com/pkg/errors"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
coreinformersv1 "k8s.io/client-go/informers/core/v1"
|
||||
"kubesphere.io/kubesphere/pkg/api/customalerting/v1alpha1"
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
"kubesphere.io/kubesphere/pkg/models/customalerting/rules"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/customalerting"
|
||||
)
|
||||
|
||||
const (
|
||||
rulerNamespace = constants.KubeSphereMonitoringNamespace
|
||||
customRuleGroupDefault = "alerting.custom.defaults"
|
||||
customRuleResourceLabelKeyLevel = "custom-alerting-rule-level"
|
||||
)
|
||||
|
||||
var (
|
||||
maxSecretSize = corev1.MaxSecretSize
|
||||
maxConfigMapDataSize = int(float64(maxSecretSize) * 0.45)
|
||||
)
|
||||
|
||||
// Operator contains all operations to alerting rules. The operations may involve manipulations of prometheusrule
|
||||
// custom resources where the rules are persisted, and querying the rules state from prometheus endpoint and
|
||||
// thanos ruler endpoint.
|
||||
// For the following apis, if namespace is empty, do operations to alerting rules with cluster level,
|
||||
// or do operations only to rules of the specified namespaces.
|
||||
// All custom rules will be configured for thanos ruler, so the operations to custom alerting rule can not be done
|
||||
// if thanos ruler is not enabled.
|
||||
type Operator interface {
|
||||
// ListCustomAlertingRules lists the custom alerting rules.
|
||||
ListCustomAlertingRules(ctx context.Context, namespace string,
|
||||
queryParams *v1alpha1.AlertingRuleQueryParams) (*v1alpha1.GettableAlertingRuleList, error)
|
||||
// ListCustomRulesAlerts lists the alerts of the custom alerting rules.
|
||||
ListCustomRulesAlerts(ctx context.Context, namespace string,
|
||||
queryParams *v1alpha1.AlertQueryParams) (*v1alpha1.AlertList, error)
|
||||
// GetCustomAlertingRule gets the custom alerting rule with the given name.
|
||||
GetCustomAlertingRule(ctx context.Context, namespace, ruleName string) (*v1alpha1.GettableAlertingRule, error)
|
||||
// ListCustomSpecifiedRuleAlerts lists the alerts of the custom alerting rule with the given name.
|
||||
ListCustomSpecifiedRuleAlerts(ctx context.Context, namespace, ruleName string) ([]*v1alpha1.Alert, error)
|
||||
// CreateCustomAlertingRule creates a custom alerting rule.
|
||||
CreateCustomAlertingRule(ctx context.Context, namespace string, rule *v1alpha1.PostableAlertingRule) error
|
||||
// UpdateCustomAlertingRule updates the custom alerting rule with the given name.
|
||||
UpdateCustomAlertingRule(ctx context.Context, namespace, ruleName string, rule *v1alpha1.PostableAlertingRule) error
|
||||
// DeleteCustomAlertingRule deletes the custom alerting rule with the given name.
|
||||
DeleteCustomAlertingRule(ctx context.Context, namespace, ruleName string) error
|
||||
|
||||
// ListBuiltinAlertingRules lists the builtin(non-custom) alerting rules
|
||||
ListBuiltinAlertingRules(ctx context.Context,
|
||||
queryParams *v1alpha1.AlertingRuleQueryParams) (*v1alpha1.GettableAlertingRuleList, error)
|
||||
// ListBuiltinRulesAlerts lists the alerts of the builtin(non-custom) alerting rules
|
||||
ListBuiltinRulesAlerts(ctx context.Context,
|
||||
queryParams *v1alpha1.AlertQueryParams) (*v1alpha1.AlertList, error)
|
||||
// GetBuiltinAlertingRule gets the builtin(non-custom) alerting rule with the given id
|
||||
GetBuiltinAlertingRule(ctx context.Context, ruleId string) (*v1alpha1.GettableAlertingRule, error)
|
||||
// ListBuiltinSpecifiedRuleAlerts lists the alerts of the builtin(non-custom) alerting rule with the given id
|
||||
ListBuiltinSpecifiedRuleAlerts(ctx context.Context, ruleId string) ([]*v1alpha1.Alert, error)
|
||||
}
|
||||
|
||||
func NewOperator(informers informers.InformerFactory,
|
||||
promResourceClient promresourcesclient.Interface, ruleClient customalerting.RuleClient,
|
||||
option *customalerting.Options) Operator {
|
||||
o := operator{
|
||||
namespaceInformer: informers.KubernetesSharedInformerFactory().Core().V1().Namespaces(),
|
||||
|
||||
promResourceClient: promResourceClient,
|
||||
|
||||
prometheusInformer: informers.PrometheusSharedInformerFactory().Monitoring().V1().Prometheuses(),
|
||||
thanosRulerInformer: informers.PrometheusSharedInformerFactory().Monitoring().V1().ThanosRulers(),
|
||||
ruleResourceInformer: informers.PrometheusSharedInformerFactory().Monitoring().V1().PrometheusRules(),
|
||||
|
||||
ruleClient: ruleClient,
|
||||
|
||||
thanosRuleResourceLabels: make(map[string]string),
|
||||
}
|
||||
|
||||
o.resourceRuleCache = rules.NewRuleCache(o.ruleResourceInformer)
|
||||
|
||||
if option != nil && len(option.ThanosRuleResourceLabels) != 0 {
|
||||
lblStrings := strings.Split(option.ThanosRuleResourceLabels, ",")
|
||||
for _, lblString := range lblStrings {
|
||||
lbl := strings.Split(lblString, "=")
|
||||
if len(lbl) == 2 {
|
||||
o.thanosRuleResourceLabels[lbl[0]] = lbl[1]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return &o
|
||||
}
|
||||
|
||||
type operator struct {
|
||||
ruleClient customalerting.RuleClient
|
||||
|
||||
promResourceClient promresourcesclient.Interface
|
||||
|
||||
prometheusInformer prominformersv1.PrometheusInformer
|
||||
thanosRulerInformer prominformersv1.ThanosRulerInformer
|
||||
ruleResourceInformer prominformersv1.PrometheusRuleInformer
|
||||
|
||||
namespaceInformer coreinformersv1.NamespaceInformer
|
||||
|
||||
resourceRuleCache *rules.RuleCache
|
||||
|
||||
thanosRuleResourceLabels map[string]string
|
||||
}
|
||||
|
||||
func (o *operator) ListCustomAlertingRules(ctx context.Context, namespace string,
|
||||
queryParams *v1alpha1.AlertingRuleQueryParams) (*v1alpha1.GettableAlertingRuleList, error) {
|
||||
|
||||
var level v1alpha1.RuleLevel
|
||||
if namespace == "" {
|
||||
namespace = rulerNamespace
|
||||
level = v1alpha1.RuleLevelCluster
|
||||
} else {
|
||||
level = v1alpha1.RuleLevelNamespace
|
||||
}
|
||||
|
||||
ruleNamespace, err := o.namespaceInformer.Lister().Get(namespace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
alertingRules, err := o.listCustomAlertingRules(ctx, ruleNamespace, level)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return pageAlertingRules(alertingRules, queryParams), nil
|
||||
}
|
||||
|
||||
func (o *operator) ListCustomRulesAlerts(ctx context.Context, namespace string,
|
||||
queryParams *v1alpha1.AlertQueryParams) (*v1alpha1.AlertList, error) {
|
||||
|
||||
var level v1alpha1.RuleLevel
|
||||
if namespace == "" {
|
||||
namespace = rulerNamespace
|
||||
level = v1alpha1.RuleLevelCluster
|
||||
} else {
|
||||
level = v1alpha1.RuleLevelNamespace
|
||||
}
|
||||
|
||||
ruleNamespace, err := o.namespaceInformer.Lister().Get(namespace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
alertingRules, err := o.listCustomAlertingRules(ctx, ruleNamespace, level)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return pageAlerts(alertingRules, queryParams), nil
|
||||
}
|
||||
|
||||
func (o *operator) GetCustomAlertingRule(ctx context.Context, namespace, ruleName string) (
|
||||
*v1alpha1.GettableAlertingRule, error) {
|
||||
|
||||
var level v1alpha1.RuleLevel
|
||||
if namespace == "" {
|
||||
namespace = rulerNamespace
|
||||
level = v1alpha1.RuleLevelCluster
|
||||
} else {
|
||||
level = v1alpha1.RuleLevelNamespace
|
||||
}
|
||||
|
||||
ruleNamespace, err := o.namespaceInformer.Lister().Get(namespace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return o.getCustomAlertingRule(ctx, ruleNamespace, ruleName, level)
|
||||
}
|
||||
|
||||
func (o *operator) ListCustomSpecifiedRuleAlerts(ctx context.Context, namespace, ruleName string) (
|
||||
[]*v1alpha1.Alert, error) {
|
||||
|
||||
rule, err := o.GetCustomAlertingRule(ctx, namespace, ruleName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if rule == nil {
|
||||
return nil, v1alpha1.ErrAlertingRuleNotFound
|
||||
}
|
||||
return rule.Alerts, nil
|
||||
}
|
||||
|
||||
func (o *operator) ListBuiltinAlertingRules(ctx context.Context,
|
||||
queryParams *v1alpha1.AlertingRuleQueryParams) (*v1alpha1.GettableAlertingRuleList, error) {
|
||||
|
||||
alertingRules, err := o.listBuiltinAlertingRules(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return pageAlertingRules(alertingRules, queryParams), nil
|
||||
}
|
||||
|
||||
func (o *operator) ListBuiltinRulesAlerts(ctx context.Context,
|
||||
queryParams *v1alpha1.AlertQueryParams) (*v1alpha1.AlertList, error) {
|
||||
alertingRules, err := o.listBuiltinAlertingRules(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return pageAlerts(alertingRules, queryParams), nil
|
||||
}
|
||||
|
||||
func (o *operator) GetBuiltinAlertingRule(ctx context.Context, ruleId string) (
|
||||
*v1alpha1.GettableAlertingRule, error) {
|
||||
|
||||
return o.getBuiltinAlertingRule(ctx, ruleId)
|
||||
}
|
||||
|
||||
func (o *operator) ListBuiltinSpecifiedRuleAlerts(ctx context.Context, ruleId string) ([]*v1alpha1.Alert, error) {
|
||||
rule, err := o.getBuiltinAlertingRule(ctx, ruleId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if rule == nil {
|
||||
return nil, v1alpha1.ErrAlertingRuleNotFound
|
||||
}
|
||||
return rule.Alerts, nil
|
||||
}
|
||||
|
||||
func (o *operator) ListClusterAlertingRules(ctx context.Context, customFlag string,
|
||||
queryParams *v1alpha1.AlertingRuleQueryParams) (*v1alpha1.GettableAlertingRuleList, error) {
|
||||
|
||||
namespace := rulerNamespace
|
||||
ruleNamespace, err := o.namespaceInformer.Lister().Get(namespace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
alertingRules, err := o.listCustomAlertingRules(ctx, ruleNamespace, v1alpha1.RuleLevelCluster)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return pageAlertingRules(alertingRules, queryParams), nil
|
||||
}
|
||||
|
||||
func (o *operator) ListClusterRulesAlerts(ctx context.Context,
|
||||
queryParams *v1alpha1.AlertQueryParams) (*v1alpha1.AlertList, error) {
|
||||
|
||||
namespace := rulerNamespace
|
||||
ruleNamespace, err := o.namespaceInformer.Lister().Get(namespace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
alertingRules, err := o.listCustomAlertingRules(ctx, ruleNamespace, v1alpha1.RuleLevelCluster)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return pageAlerts(alertingRules, queryParams), nil
|
||||
}
|
||||
|
||||
func (o *operator) listCustomAlertingRules(ctx context.Context, ruleNamespace *corev1.Namespace,
|
||||
level v1alpha1.RuleLevel) ([]*v1alpha1.GettableAlertingRule, error) {
|
||||
|
||||
ruler, err := o.getThanosRuler()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if ruler == nil {
|
||||
return nil, v1alpha1.ErrThanosRulerNotEnabled
|
||||
}
|
||||
|
||||
resourceRulesMap, err := o.resourceRuleCache.ListRules(ruler, ruleNamespace,
|
||||
labels.SelectorFromSet(labels.Set{customRuleResourceLabelKeyLevel: string(level)}))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ruleGroups, err := o.ruleClient.ThanosRules(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return rules.MixAlertingRules(ruleNamespace.Name, &rules.ResourceRuleChunk{
|
||||
ResourceRulesMap: resourceRulesMap,
|
||||
Custom: true,
|
||||
Level: level,
|
||||
}, ruleGroups, ruler.ExternalLabels())
|
||||
}
|
||||
|
||||
func (o *operator) getCustomAlertingRule(ctx context.Context, ruleNamespace *corev1.Namespace,
|
||||
ruleName string, level v1alpha1.RuleLevel) (*v1alpha1.GettableAlertingRule, error) {
|
||||
|
||||
ruler, err := o.getThanosRuler()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if ruler == nil {
|
||||
return nil, v1alpha1.ErrThanosRulerNotEnabled
|
||||
}
|
||||
|
||||
resourceRule, err := o.resourceRuleCache.GetRule(ruler, ruleNamespace,
|
||||
labels.SelectorFromSet(labels.Set{customRuleResourceLabelKeyLevel: string(level)}), ruleName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if resourceRule == nil {
|
||||
return nil, v1alpha1.ErrAlertingRuleNotFound
|
||||
}
|
||||
|
||||
ruleGroups, err := o.ruleClient.ThanosRules(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return rules.MixAlertingRule(ruleNamespace.Name, &rules.ResourceRuleSole{
|
||||
ResourceRule: *resourceRule,
|
||||
Custom: true,
|
||||
Level: level,
|
||||
}, ruleGroups, ruler.ExternalLabels())
|
||||
}
|
||||
|
||||
func (o *operator) listBuiltinAlertingRules(ctx context.Context) (
|
||||
[]*v1alpha1.GettableAlertingRule, error) {
|
||||
|
||||
ruler, err := o.getPrometheusRuler()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ruleGroups, err := o.ruleClient.PrometheusRules(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if ruler == nil {
|
||||
// for out-cluster prometheus
|
||||
return rules.ParseAlertingRules(ruleGroups, false, v1alpha1.RuleLevelCluster,
|
||||
func(group, id string, rule *customalerting.AlertingRule) bool {
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
namespace := rulerNamespace
|
||||
ruleNamespace, err := o.namespaceInformer.Lister().Get(namespace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resourceRulesMap, err := o.resourceRuleCache.ListRules(ruler, ruleNamespace, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return rules.MixAlertingRules(ruleNamespace.Name, &rules.ResourceRuleChunk{
|
||||
ResourceRulesMap: resourceRulesMap,
|
||||
Custom: false,
|
||||
Level: v1alpha1.RuleLevelCluster,
|
||||
}, ruleGroups, ruler.ExternalLabels())
|
||||
}
|
||||
|
||||
func (o *operator) getBuiltinAlertingRule(ctx context.Context, ruleId string) (*v1alpha1.GettableAlertingRule, error) {
|
||||
|
||||
ruler, err := o.getPrometheusRuler()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ruleGroups, err := o.ruleClient.PrometheusRules(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if ruler == nil {
|
||||
// for out-cluster prometheus
|
||||
alertingRules, err := rules.ParseAlertingRules(ruleGroups, false, v1alpha1.RuleLevelCluster,
|
||||
func(group, id string, rule *customalerting.AlertingRule) bool {
|
||||
return ruleId == id
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(alertingRules) == 0 {
|
||||
return nil, v1alpha1.ErrAlertingRuleNotFound
|
||||
}
|
||||
sort.Slice(alertingRules, func(i, j int) bool {
|
||||
return v1alpha1.AlertingRuleIdCompare(alertingRules[i].Id, alertingRules[j].Id)
|
||||
})
|
||||
return alertingRules[0], nil
|
||||
}
|
||||
|
||||
namespace := rulerNamespace
|
||||
ruleNamespace, err := o.namespaceInformer.Lister().Get(namespace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resourceRule, err := o.resourceRuleCache.GetRule(ruler, ruleNamespace, nil, ruleId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if resourceRule == nil {
|
||||
return nil, v1alpha1.ErrAlertingRuleNotFound
|
||||
}
|
||||
|
||||
return rules.MixAlertingRule(ruleNamespace.Name, &rules.ResourceRuleSole{
|
||||
ResourceRule: *resourceRule,
|
||||
Custom: false,
|
||||
Level: v1alpha1.RuleLevelCluster,
|
||||
}, ruleGroups, ruler.ExternalLabels())
|
||||
}
|
||||
|
||||
func (o *operator) CreateCustomAlertingRule(ctx context.Context, namespace string,
|
||||
rule *v1alpha1.PostableAlertingRule) error {
|
||||
ruler, err := o.getThanosRuler()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if ruler == nil {
|
||||
return v1alpha1.ErrThanosRulerNotEnabled
|
||||
}
|
||||
|
||||
var (
|
||||
level v1alpha1.RuleLevel
|
||||
ruleResourceLabels = make(map[string]string)
|
||||
)
|
||||
for k, v := range o.thanosRuleResourceLabels {
|
||||
ruleResourceLabels[k] = v
|
||||
}
|
||||
if namespace == "" {
|
||||
namespace = rulerNamespace
|
||||
level = v1alpha1.RuleLevelCluster
|
||||
} else {
|
||||
level = v1alpha1.RuleLevelNamespace
|
||||
expr, err := rules.InjectExprNamespaceLabel(rule.Query, namespace)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rule.Query = expr
|
||||
}
|
||||
ruleResourceLabels[customRuleResourceLabelKeyLevel] = string(level)
|
||||
|
||||
ruleNamespace, err := o.namespaceInformer.Lister().Get(namespace)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
extraRuleResourceSelector := labels.SelectorFromSet(labels.Set{customRuleResourceLabelKeyLevel: string(level)})
|
||||
resourceRule, err := o.resourceRuleCache.GetRule(ruler, ruleNamespace, extraRuleResourceSelector, rule.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if resourceRule != nil {
|
||||
return v1alpha1.ErrAlertingRuleAlreadyExists
|
||||
}
|
||||
|
||||
return ruler.AddAlertingRule(ctx, ruleNamespace, extraRuleResourceSelector,
|
||||
customRuleGroupDefault, parseToPrometheusRule(rule), ruleResourceLabels)
|
||||
}
|
||||
|
||||
func (o *operator) UpdateCustomAlertingRule(ctx context.Context, namespace, name string,
|
||||
rule *v1alpha1.PostableAlertingRule) error {
|
||||
|
||||
rule.Name = name
|
||||
|
||||
ruler, err := o.getThanosRuler()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if ruler == nil {
|
||||
return v1alpha1.ErrThanosRulerNotEnabled
|
||||
}
|
||||
|
||||
var (
|
||||
level v1alpha1.RuleLevel
|
||||
ruleResourceLabels = make(map[string]string)
|
||||
)
|
||||
for k, v := range o.thanosRuleResourceLabels {
|
||||
ruleResourceLabels[k] = v
|
||||
}
|
||||
if namespace == "" {
|
||||
namespace = rulerNamespace
|
||||
level = v1alpha1.RuleLevelCluster
|
||||
} else {
|
||||
level = v1alpha1.RuleLevelNamespace
|
||||
expr, err := rules.InjectExprNamespaceLabel(rule.Query, namespace)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rule.Query = expr
|
||||
}
|
||||
ruleResourceLabels[customRuleResourceLabelKeyLevel] = string(level)
|
||||
|
||||
ruleNamespace, err := o.namespaceInformer.Lister().Get(namespace)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
extraRuleResourceSelector := labels.SelectorFromSet(labels.Set{customRuleResourceLabelKeyLevel: string(level)})
|
||||
resourceRule, err := o.resourceRuleCache.GetRule(ruler, ruleNamespace, extraRuleResourceSelector, rule.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if resourceRule == nil {
|
||||
return v1alpha1.ErrAlertingRuleNotFound
|
||||
}
|
||||
|
||||
return ruler.UpdateAlertingRule(ctx, ruleNamespace, extraRuleResourceSelector,
|
||||
resourceRule.Group, parseToPrometheusRule(rule), ruleResourceLabels)
|
||||
}
|
||||
|
||||
func (o *operator) DeleteCustomAlertingRule(ctx context.Context, namespace, name string) error {
|
||||
ruler, err := o.getThanosRuler()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if ruler == nil {
|
||||
return v1alpha1.ErrThanosRulerNotEnabled
|
||||
}
|
||||
|
||||
var (
|
||||
level v1alpha1.RuleLevel
|
||||
)
|
||||
if namespace == "" {
|
||||
namespace = rulerNamespace
|
||||
level = v1alpha1.RuleLevelCluster
|
||||
} else {
|
||||
level = v1alpha1.RuleLevelNamespace
|
||||
}
|
||||
|
||||
ruleNamespace, err := o.namespaceInformer.Lister().Get(namespace)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
extraRuleResourceSelector := labels.SelectorFromSet(labels.Set{customRuleResourceLabelKeyLevel: string(level)})
|
||||
resourceRule, err := o.resourceRuleCache.GetRule(ruler, ruleNamespace, extraRuleResourceSelector, name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if resourceRule == nil {
|
||||
return v1alpha1.ErrAlertingRuleNotFound
|
||||
}
|
||||
|
||||
return ruler.DeleteAlertingRule(ctx, ruleNamespace, extraRuleResourceSelector, resourceRule.Group, name)
|
||||
}
|
||||
|
||||
// getPrometheusRuler gets the cluster-in prometheus
|
||||
func (o *operator) getPrometheusRuler() (rules.Ruler, error) {
|
||||
prometheuses, err := o.prometheusInformer.Lister().Prometheuses(rulerNamespace).List(labels.Everything())
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "error listing prometheuses")
|
||||
}
|
||||
if len(prometheuses) > 1 {
|
||||
// it is not supported temporarily to have multiple prometheuses in the monitoring namespace
|
||||
return nil, errors.Errorf(
|
||||
"there is more than one prometheus custom resource in %s", rulerNamespace)
|
||||
}
|
||||
if len(prometheuses) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return rules.NewPrometheusRuler(prometheuses[0], o.ruleResourceInformer, o.promResourceClient), nil
|
||||
}
|
||||
|
||||
func (o *operator) getThanosRuler() (rules.Ruler, error) {
|
||||
thanosrulers, err := o.thanosRulerInformer.Lister().ThanosRulers(rulerNamespace).List(labels.Everything())
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "error listing thanosrulers: ")
|
||||
}
|
||||
if len(thanosrulers) > 1 {
|
||||
// it is not supported temporarily to have multiple thanosrulers in the monitoring namespace
|
||||
return nil, errors.Errorf(
|
||||
"there is more than one thanosruler custom resource in %s", rulerNamespace)
|
||||
}
|
||||
if len(thanosrulers) == 0 {
|
||||
// if there is no thanos ruler, custom rules will not be supported
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return rules.NewThanosRuler(thanosrulers[0], o.ruleResourceInformer, o.promResourceClient), nil
|
||||
}
|
||||
|
||||
func parseToPrometheusRule(rule *v1alpha1.PostableAlertingRule) *promresourcesv1.Rule {
|
||||
lbls := rule.Labels
|
||||
lbls[rules.LabelKeyInternalRuleAlias] = rule.Alias
|
||||
lbls[rules.LabelKeyInternalRuleDescription] = rule.Description
|
||||
return &promresourcesv1.Rule{
|
||||
Alert: rule.Name,
|
||||
Expr: intstr.FromString(rule.Query),
|
||||
For: rule.Duration,
|
||||
Labels: lbls,
|
||||
Annotations: rule.Annotations,
|
||||
}
|
||||
}
|
||||
|
||||
func pageAlertingRules(alertingRules []*v1alpha1.GettableAlertingRule,
|
||||
queryParams *v1alpha1.AlertingRuleQueryParams) *v1alpha1.GettableAlertingRuleList {
|
||||
|
||||
alertingRules = queryParams.Filter(alertingRules)
|
||||
queryParams.Sort(alertingRules)
|
||||
|
||||
return &v1alpha1.GettableAlertingRuleList{
|
||||
Total: len(alertingRules),
|
||||
Items: queryParams.Sub(alertingRules),
|
||||
}
|
||||
}
|
||||
|
||||
func pageAlerts(alertingRules []*v1alpha1.GettableAlertingRule,
|
||||
queryParams *v1alpha1.AlertQueryParams) *v1alpha1.AlertList {
|
||||
|
||||
var alerts []*v1alpha1.Alert
|
||||
for _, rule := range alertingRules {
|
||||
alerts = append(alerts, queryParams.Filter(rule.Alerts)...)
|
||||
}
|
||||
queryParams.Sort(alerts)
|
||||
|
||||
return &v1alpha1.AlertList{
|
||||
Total: len(alerts),
|
||||
Items: queryParams.Sub(alerts),
|
||||
}
|
||||
}
|
||||
246
pkg/models/customalerting/rules/cache.go
Normal file
246
pkg/models/customalerting/rules/cache.go
Normal file
@@ -0,0 +1,246 @@
|
||||
package rules
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"sync"
|
||||
|
||||
promresourcesv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
|
||||
prominformersv1 "github.com/prometheus-operator/prometheus-operator/pkg/client/informers/externalversions/monitoring/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"kubesphere.io/kubesphere/pkg/api/customalerting/v1alpha1"
|
||||
"kubesphere.io/kubesphere/pkg/server/errors"
|
||||
)
|
||||
|
||||
// RuleCache caches all rules from the prometheusrule custom resources
|
||||
type RuleCache struct {
|
||||
lock sync.RWMutex
|
||||
namespaces map[string]*namespaceRuleCache
|
||||
}
|
||||
|
||||
func NewRuleCache(ruleResourceInformer prominformersv1.PrometheusRuleInformer) *RuleCache {
|
||||
rc := RuleCache{
|
||||
namespaces: make(map[string]*namespaceRuleCache),
|
||||
}
|
||||
ruleResourceInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
|
||||
AddFunc: rc.addCache,
|
||||
UpdateFunc: func(oldObj, newObj interface{}) {
|
||||
rc.addCache(newObj)
|
||||
},
|
||||
DeleteFunc: rc.deleteCache,
|
||||
})
|
||||
return &rc
|
||||
}
|
||||
|
||||
func (c *RuleCache) addCache(referObj interface{}) {
|
||||
pr, ok := referObj.(*promresourcesv1.PrometheusRule)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
cr := parseRuleResource(pr)
|
||||
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
|
||||
cn, ok := c.namespaces[pr.Namespace]
|
||||
if !ok || cn == nil {
|
||||
cn = &namespaceRuleCache{
|
||||
namespace: pr.Namespace,
|
||||
resources: make(map[string]*resourceRuleCache),
|
||||
}
|
||||
c.namespaces[pr.Namespace] = cn
|
||||
}
|
||||
cn.resources[pr.Name] = cr
|
||||
}
|
||||
|
||||
func (c *RuleCache) deleteCache(referObj interface{}) {
|
||||
pr, ok := referObj.(*promresourcesv1.PrometheusRule)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
|
||||
cn, ok := c.namespaces[pr.Namespace]
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
delete(cn.resources, pr.Name)
|
||||
if len(cn.resources) == 0 {
|
||||
delete(c.namespaces, pr.Namespace)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *RuleCache) getResourceRuleCaches(ruler Ruler, ruleNamespace *corev1.Namespace,
|
||||
extraRuleResourceSelector labels.Selector) (map[string]*resourceRuleCache, error) {
|
||||
|
||||
selected, err := ruleNamespaceSelected(ruler, ruleNamespace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !selected {
|
||||
return nil, nil
|
||||
}
|
||||
rSelector, err := ruler.RuleResourceSelector(extraRuleResourceSelector)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var m = make(map[string]*resourceRuleCache)
|
||||
|
||||
c.lock.RLock()
|
||||
defer c.lock.RUnlock()
|
||||
|
||||
cn, ok := c.namespaces[ruleNamespace.Name]
|
||||
if ok && cn != nil {
|
||||
for _, cr := range cn.resources {
|
||||
if rSelector.Matches(labels.Set(cr.Labels)) {
|
||||
m[cr.Name] = cr
|
||||
}
|
||||
}
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (c *RuleCache) GetRule(ruler Ruler, ruleNamespace *corev1.Namespace,
|
||||
extraRuleResourceSelector labels.Selector, idOrName string) (*ResourceRule, error) {
|
||||
|
||||
caches, err := c.getResourceRuleCaches(ruler, ruleNamespace, extraRuleResourceSelector)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(caches) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var rules []*ResourceRule
|
||||
switch ruler.(type) {
|
||||
case *PrometheusRuler:
|
||||
for rn, rc := range caches {
|
||||
if rule, ok := rc.IdRules[idOrName]; ok {
|
||||
rules = append(rules, &ResourceRule{
|
||||
Group: rule.Group,
|
||||
Id: rule.Id,
|
||||
Rule: rule.Rule.DeepCopy(),
|
||||
ResourceName: rn,
|
||||
})
|
||||
}
|
||||
}
|
||||
case *ThanosRuler:
|
||||
for rn, rc := range caches {
|
||||
if nrules, ok := rc.NameRules[idOrName]; ok {
|
||||
for _, nrule := range nrules {
|
||||
rules = append(rules, &ResourceRule{
|
||||
Group: nrule.Group,
|
||||
Id: nrule.Id,
|
||||
Rule: nrule.Rule.DeepCopy(),
|
||||
ResourceName: rn,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
default:
|
||||
return nil, errors.New("unsupported ruler type")
|
||||
}
|
||||
|
||||
if l := len(rules); l == 0 {
|
||||
return nil, nil
|
||||
} else if l > 1 {
|
||||
// guarantees the stability of the get operations.
|
||||
sort.Slice(rules, func(i, j int) bool {
|
||||
return v1alpha1.AlertingRuleIdCompare(rules[i].Id, rules[j].Id)
|
||||
})
|
||||
}
|
||||
return rules[0], nil
|
||||
}
|
||||
|
||||
func (c *RuleCache) ListRules(ruler Ruler, ruleNamespace *corev1.Namespace,
|
||||
extraRuleResourceSelector labels.Selector) (map[string]*ResourceRules, error) {
|
||||
|
||||
caches, err := c.getResourceRuleCaches(ruler, ruleNamespace, extraRuleResourceSelector)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(caches) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
ret := make(map[string]*ResourceRules)
|
||||
for rn, rc := range caches {
|
||||
rrs := &ResourceRules{
|
||||
GroupSet: make(map[string]struct{}),
|
||||
IdRules: make(map[string]*ResourceRule),
|
||||
NameRules: make(map[string][]*ResourceRule),
|
||||
}
|
||||
for name, rules := range rc.NameRules {
|
||||
for _, rule := range rules {
|
||||
rrs.GroupSet[rule.Group] = struct{}{}
|
||||
rr := &ResourceRule{
|
||||
Group: rule.Group,
|
||||
Id: rule.Id,
|
||||
Rule: rule.Rule.DeepCopy(),
|
||||
ResourceName: rn,
|
||||
}
|
||||
rrs.IdRules[rr.Id] = rr
|
||||
rrs.NameRules[name] = append(rrs.NameRules[name], rr)
|
||||
}
|
||||
}
|
||||
if len(rrs.IdRules) > 0 {
|
||||
ret[rn] = rrs
|
||||
}
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
type namespaceRuleCache struct {
|
||||
namespace string
|
||||
resources map[string]*resourceRuleCache
|
||||
}
|
||||
|
||||
type resourceRuleCache struct {
|
||||
Name string
|
||||
Labels map[string]string
|
||||
GroupSet map[string]struct{}
|
||||
IdRules map[string]*cacheRule
|
||||
NameRules map[string][]*cacheRule
|
||||
}
|
||||
|
||||
type cacheRule struct {
|
||||
Group string
|
||||
Id string
|
||||
Rule *promresourcesv1.Rule
|
||||
}
|
||||
|
||||
func parseRuleResource(pr *promresourcesv1.PrometheusRule) *resourceRuleCache {
|
||||
var (
|
||||
groupSet = make(map[string]struct{})
|
||||
idRules = make(map[string]*cacheRule)
|
||||
nameRules = make(map[string][]*cacheRule)
|
||||
)
|
||||
for i := 0; i < len(pr.Spec.Groups); i++ {
|
||||
g := pr.Spec.Groups[i]
|
||||
for j := 0; j < len(g.Rules); j++ {
|
||||
gr := g.Rules[j]
|
||||
if gr.Alert == "" {
|
||||
continue
|
||||
}
|
||||
groupSet[g.Name] = struct{}{}
|
||||
cr := &cacheRule{
|
||||
Group: g.Name,
|
||||
Id: GenResourceRuleIdIgnoreFormat(g.Name, &gr),
|
||||
Rule: &gr,
|
||||
}
|
||||
nameRules[cr.Rule.Alert] = append(nameRules[cr.Rule.Alert], cr)
|
||||
idRules[cr.Id] = cr
|
||||
}
|
||||
}
|
||||
return &resourceRuleCache{
|
||||
Name: pr.Name,
|
||||
Labels: pr.Labels,
|
||||
GroupSet: groupSet,
|
||||
IdRules: idRules,
|
||||
NameRules: nameRules,
|
||||
}
|
||||
}
|
||||
31
pkg/models/customalerting/rules/rule.go
Normal file
31
pkg/models/customalerting/rules/rule.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package rules
|
||||
|
||||
import (
|
||||
promresourcesv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
|
||||
"kubesphere.io/kubesphere/pkg/api/customalerting/v1alpha1"
|
||||
)
|
||||
|
||||
type ResourceRules struct {
|
||||
GroupSet map[string]struct{}
|
||||
IdRules map[string]*ResourceRule
|
||||
NameRules map[string][]*ResourceRule
|
||||
}
|
||||
|
||||
type ResourceRule struct {
|
||||
ResourceName string
|
||||
Group string
|
||||
Id string
|
||||
Rule *promresourcesv1.Rule
|
||||
}
|
||||
|
||||
type ResourceRuleSole struct {
|
||||
Level v1alpha1.RuleLevel
|
||||
Custom bool
|
||||
ResourceRule
|
||||
}
|
||||
|
||||
type ResourceRuleChunk struct {
|
||||
Level v1alpha1.RuleLevel
|
||||
Custom bool
|
||||
ResourceRulesMap map[string]*ResourceRules
|
||||
}
|
||||
501
pkg/models/customalerting/rules/ruler.go
Normal file
501
pkg/models/customalerting/rules/ruler.go
Normal file
@@ -0,0 +1,501 @@
|
||||
package rules
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
"github.com/pkg/errors"
|
||||
promresourcesv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
|
||||
prominformersv1 "github.com/prometheus-operator/prometheus-operator/pkg/client/informers/externalversions/monitoring/v1"
|
||||
promresourcesclient "github.com/prometheus-operator/prometheus-operator/pkg/client/versioned"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"kubesphere.io/kubesphere/pkg/api/customalerting/v1alpha1"
|
||||
)
|
||||
|
||||
const (
|
||||
customAlertingRuleResourcePrefix = "custom-alerting-rule-"
|
||||
)
|
||||
|
||||
var (
|
||||
maxSecretSize = corev1.MaxSecretSize
|
||||
maxConfigMapDataSize = int(float64(maxSecretSize) * 0.3)
|
||||
|
||||
errOutOfConfigMapSize = errors.New("out of config map size")
|
||||
)
|
||||
|
||||
type Ruler interface {
|
||||
Namespace() string
|
||||
RuleResourceNamespaceSelector() (labels.Selector, error)
|
||||
RuleResourceSelector(extraRuleResourceSelector labels.Selector) (labels.Selector, error)
|
||||
ExternalLabels() func() map[string]string
|
||||
|
||||
ListRuleResources(ruleNamespace *corev1.Namespace, extraRuleResourceSelector labels.Selector) (
|
||||
[]*promresourcesv1.PrometheusRule, error)
|
||||
|
||||
AddAlertingRule(ctx context.Context, ruleNamespace *corev1.Namespace, extraRuleResourceSelector labels.Selector,
|
||||
group string, rule *promresourcesv1.Rule, ruleResourceLabels map[string]string) error
|
||||
UpdateAlertingRule(ctx context.Context, ruleNamespace *corev1.Namespace, extraRuleResourceSelector labels.Selector,
|
||||
group string, rule *promresourcesv1.Rule, ruleResourceLabels map[string]string) error
|
||||
DeleteAlertingRule(ctx context.Context, ruleNamespace *corev1.Namespace, extraRuleResourceSelector labels.Selector,
|
||||
group string, name string) error
|
||||
}
|
||||
|
||||
type ruleResource promresourcesv1.PrometheusRule
|
||||
|
||||
// deleteAlertingRule deletes the rules with the given name.
|
||||
// If the rule is deleted, return true to indicate the resource should be updated.
|
||||
func (r *ruleResource) deleteAlertingRule(name string) (bool, error) {
|
||||
var (
|
||||
nGroups []promresourcesv1.RuleGroup
|
||||
ok bool
|
||||
)
|
||||
|
||||
for _, g := range r.Spec.Groups {
|
||||
var rules []promresourcesv1.Rule
|
||||
for _, gr := range g.Rules {
|
||||
if gr.Alert != "" && gr.Alert == name {
|
||||
ok = true
|
||||
continue
|
||||
}
|
||||
rules = append(rules, gr)
|
||||
}
|
||||
if len(rules) > 0 {
|
||||
nGroups = append(nGroups, promresourcesv1.RuleGroup{
|
||||
Name: g.Name,
|
||||
Interval: g.Interval,
|
||||
PartialResponseStrategy: g.PartialResponseStrategy,
|
||||
Rules: rules,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if ok {
|
||||
r.Spec.Groups = nGroups
|
||||
}
|
||||
return ok, nil
|
||||
}
|
||||
|
||||
// updateAlertingRule updates the rule with the given group.
|
||||
// If the rule is updated, return true to indicate the resource should be updated.
|
||||
func (r *ruleResource) updateAlertingRule(groupName string, rule *promresourcesv1.Rule) (bool, error) {
|
||||
var (
|
||||
ok bool
|
||||
pr = (promresourcesv1.PrometheusRule)(*r)
|
||||
npr = pr.DeepCopy()
|
||||
groupMap = make(map[string]*promresourcesv1.RuleGroup)
|
||||
)
|
||||
|
||||
for _, g := range npr.Spec.Groups {
|
||||
var rules []promresourcesv1.Rule
|
||||
for i, gr := range g.Rules {
|
||||
if gr.Alert != "" && gr.Alert == rule.Alert {
|
||||
ok = true
|
||||
continue
|
||||
}
|
||||
rules = append(rules, g.Rules[i])
|
||||
}
|
||||
if len(rules) > 0 {
|
||||
groupMap[g.Name] = &promresourcesv1.RuleGroup{
|
||||
Name: g.Name,
|
||||
Interval: g.Interval,
|
||||
PartialResponseStrategy: g.PartialResponseStrategy,
|
||||
Rules: rules,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ok {
|
||||
if g, exist := groupMap[groupName]; exist {
|
||||
g.Rules = append(g.Rules, *rule)
|
||||
} else {
|
||||
groupMap[groupName] = &promresourcesv1.RuleGroup{
|
||||
Name: groupName,
|
||||
Rules: []promresourcesv1.Rule{*rule},
|
||||
}
|
||||
}
|
||||
|
||||
var groups []promresourcesv1.RuleGroup
|
||||
for _, g := range groupMap {
|
||||
groups = append(groups, *g)
|
||||
}
|
||||
|
||||
npr.Spec.Groups = groups
|
||||
content, err := yaml.Marshal(npr)
|
||||
if err != nil {
|
||||
return false, errors.Wrap(err, "failed to unmarshal content")
|
||||
}
|
||||
|
||||
if len(string(content)) < maxConfigMapDataSize { // check size limit
|
||||
r.Spec.Groups = groups
|
||||
return true, nil
|
||||
}
|
||||
return false, errOutOfConfigMapSize
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (r *ruleResource) addAlertingRule(group string, rule *promresourcesv1.Rule) (bool, error) {
|
||||
var (
|
||||
err error
|
||||
pr = (promresourcesv1.PrometheusRule)(*r)
|
||||
npr = pr.DeepCopy()
|
||||
ok bool
|
||||
)
|
||||
|
||||
for i := 0; i < len(npr.Spec.Groups); i++ {
|
||||
if npr.Spec.Groups[i].Name == group {
|
||||
npr.Spec.Groups[i].Rules = append(npr.Spec.Groups[i].Rules, *rule)
|
||||
ok = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !ok { // add a group when there is no group with the specified group name
|
||||
npr.Spec.Groups = append(npr.Spec.Groups, promresourcesv1.RuleGroup{
|
||||
Name: group,
|
||||
Rules: []promresourcesv1.Rule{*rule},
|
||||
})
|
||||
}
|
||||
|
||||
content, err := yaml.Marshal(npr)
|
||||
if err != nil {
|
||||
return false, errors.Wrap(err, "failed to unmarshal content")
|
||||
}
|
||||
|
||||
if len(string(content)) < maxConfigMapDataSize { // check size limit
|
||||
r.Spec.Groups = npr.Spec.Groups
|
||||
return true, nil
|
||||
} else {
|
||||
return false, errOutOfConfigMapSize
|
||||
}
|
||||
}
|
||||
|
||||
func (r *ruleResource) commit(ctx context.Context, prometheusResourceClient promresourcesclient.Interface) error {
|
||||
var pr = (promresourcesv1.PrometheusRule)(*r)
|
||||
if len(pr.Spec.Groups) == 0 {
|
||||
return prometheusResourceClient.MonitoringV1().PrometheusRules(r.Namespace).Delete(ctx, r.Name, metav1.DeleteOptions{})
|
||||
}
|
||||
newPr, err := prometheusResourceClient.MonitoringV1().PrometheusRules(r.Namespace).Update(ctx, &pr, metav1.UpdateOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
newPr.DeepCopyInto(&pr)
|
||||
return nil
|
||||
}
|
||||
|
||||
type PrometheusRuler struct {
|
||||
resource *promresourcesv1.Prometheus
|
||||
informer prominformersv1.PrometheusRuleInformer
|
||||
client promresourcesclient.Interface
|
||||
}
|
||||
|
||||
func NewPrometheusRuler(resource *promresourcesv1.Prometheus, informer prominformersv1.PrometheusRuleInformer,
|
||||
client promresourcesclient.Interface) Ruler {
|
||||
return &PrometheusRuler{
|
||||
resource: resource,
|
||||
informer: informer,
|
||||
client: client,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *PrometheusRuler) Namespace() string {
|
||||
return r.resource.Namespace
|
||||
}
|
||||
|
||||
func (r *PrometheusRuler) RuleResourceNamespaceSelector() (labels.Selector, error) {
|
||||
if r.resource.Spec.RuleNamespaceSelector == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return metav1.LabelSelectorAsSelector(r.resource.Spec.RuleNamespaceSelector)
|
||||
}
|
||||
|
||||
func (r *PrometheusRuler) RuleResourceSelector(extraRuleResourceSelector labels.Selector) (labels.Selector, error) {
|
||||
rSelector, err := metav1.LabelSelectorAsSelector(r.resource.Spec.RuleSelector)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if extraRuleResourceSelector != nil {
|
||||
if requirements, ok := extraRuleResourceSelector.Requirements(); ok {
|
||||
rSelector = rSelector.Add(requirements...)
|
||||
}
|
||||
}
|
||||
return rSelector, nil
|
||||
}
|
||||
|
||||
func (r *PrometheusRuler) ExternalLabels() func() map[string]string {
|
||||
// ignoring the external labels because rules gotten from prometheus endpoint do not include them
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *PrometheusRuler) ListRuleResources(ruleNamespace *corev1.Namespace, extraRuleResourceSelector labels.Selector) (
|
||||
[]*promresourcesv1.PrometheusRule, error) {
|
||||
selected, err := ruleNamespaceSelected(r, ruleNamespace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !selected {
|
||||
return nil, nil
|
||||
}
|
||||
rSelector, err := r.RuleResourceSelector(extraRuleResourceSelector)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return r.informer.Lister().PrometheusRules(ruleNamespace.Name).List(rSelector)
|
||||
}
|
||||
|
||||
func (r *PrometheusRuler) AddAlertingRule(ctx context.Context, ruleNamespace *corev1.Namespace,
|
||||
extraRuleResourceSelector labels.Selector,
|
||||
group string, rule *promresourcesv1.Rule, ruleResourceLabels map[string]string) error {
|
||||
return errors.New("not supported to add rules for prometheus")
|
||||
}
|
||||
|
||||
func (r *PrometheusRuler) UpdateAlertingRule(ctx context.Context, ruleNamespace *corev1.Namespace,
|
||||
extraRuleResourceSelector labels.Selector,
|
||||
group string, rule *promresourcesv1.Rule, ruleResourceLabels map[string]string) error {
|
||||
return errors.New("not supported to update rules for prometheus")
|
||||
}
|
||||
|
||||
func (r *PrometheusRuler) DeleteAlertingRule(ctx context.Context, ruleNamespace *corev1.Namespace,
|
||||
extraRuleResourceSelector labels.Selector,
|
||||
group string, name string) error {
|
||||
return errors.New("not supported to update rules for prometheus")
|
||||
}
|
||||
|
||||
type ThanosRuler struct {
|
||||
resource *promresourcesv1.ThanosRuler
|
||||
informer prominformersv1.PrometheusRuleInformer
|
||||
client promresourcesclient.Interface
|
||||
}
|
||||
|
||||
func NewThanosRuler(resource *promresourcesv1.ThanosRuler, informer prominformersv1.PrometheusRuleInformer,
|
||||
client promresourcesclient.Interface) Ruler {
|
||||
return &ThanosRuler{
|
||||
resource: resource,
|
||||
informer: informer,
|
||||
client: client,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *ThanosRuler) Namespace() string {
|
||||
return r.resource.Namespace
|
||||
}
|
||||
|
||||
func (r *ThanosRuler) RuleResourceNamespaceSelector() (labels.Selector, error) {
|
||||
if r.resource.Spec.RuleNamespaceSelector == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return metav1.LabelSelectorAsSelector(r.resource.Spec.RuleNamespaceSelector)
|
||||
}
|
||||
|
||||
func (r *ThanosRuler) RuleResourceSelector(extraRuleSelector labels.Selector) (labels.Selector, error) {
|
||||
rSelector, err := metav1.LabelSelectorAsSelector(r.resource.Spec.RuleSelector)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if extraRuleSelector != nil {
|
||||
if requirements, ok := extraRuleSelector.Requirements(); ok {
|
||||
rSelector = rSelector.Add(requirements...)
|
||||
}
|
||||
}
|
||||
return rSelector, nil
|
||||
}
|
||||
|
||||
func (r *ThanosRuler) ExternalLabels() func() map[string]string {
|
||||
// rules gotten from thanos ruler endpoint include the labels
|
||||
lbls := make(map[string]string)
|
||||
if ls := r.resource.Spec.Labels; ls != nil {
|
||||
for k, v := range ls {
|
||||
lbls[k] = v
|
||||
}
|
||||
}
|
||||
return func() map[string]string {
|
||||
return lbls
|
||||
}
|
||||
}
|
||||
|
||||
func (r *ThanosRuler) ListRuleResources(ruleNamespace *corev1.Namespace, extraRuleSelector labels.Selector) (
|
||||
[]*promresourcesv1.PrometheusRule, error) {
|
||||
selected, err := ruleNamespaceSelected(r, ruleNamespace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !selected {
|
||||
return nil, nil
|
||||
}
|
||||
rSelector, err := r.RuleResourceSelector(extraRuleSelector)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return r.informer.Lister().PrometheusRules(ruleNamespace.Name).List(rSelector)
|
||||
}
|
||||
|
||||
func (r *ThanosRuler) AddAlertingRule(ctx context.Context, ruleNamespace *corev1.Namespace,
|
||||
extraRuleResourceSelector labels.Selector,
|
||||
group string, rule *promresourcesv1.Rule, ruleResourceLabels map[string]string) error {
|
||||
|
||||
prometheusRules, err := r.ListRuleResources(ruleNamespace, extraRuleResourceSelector)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return r.addAlertingRule(ctx, ruleNamespace, prometheusRules, nil, group, rule, ruleResourceLabels)
|
||||
}
|
||||
|
||||
func (r *ThanosRuler) addAlertingRule(ctx context.Context, ruleNamespace *corev1.Namespace,
|
||||
prometheusRules []*promresourcesv1.PrometheusRule, excludeRuleResources map[string]*ruleResource,
|
||||
group string, rule *promresourcesv1.Rule, ruleResourceLabels map[string]string) error {
|
||||
|
||||
sort.Slice(prometheusRules, func(i, j int) bool {
|
||||
return len(fmt.Sprint(prometheusRules[i])) <= len(fmt.Sprint(prometheusRules[j]))
|
||||
})
|
||||
|
||||
for _, prometheusRule := range prometheusRules {
|
||||
if len(excludeRuleResources) > 0 {
|
||||
if _, ok := excludeRuleResources[prometheusRule.Name]; ok {
|
||||
continue
|
||||
}
|
||||
}
|
||||
resource := ruleResource(*prometheusRule)
|
||||
if ok, err := resource.addAlertingRule(group, rule); err != nil {
|
||||
if err == errOutOfConfigMapSize {
|
||||
break
|
||||
}
|
||||
return err
|
||||
} else if ok {
|
||||
if err = resource.commit(ctx, r.client); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// create a new rule resource and add rule into it when all existing rule resources are full.
|
||||
newPromRule := promresourcesv1.PrometheusRule{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: ruleNamespace.Name,
|
||||
GenerateName: customAlertingRuleResourcePrefix,
|
||||
Labels: ruleResourceLabels,
|
||||
},
|
||||
Spec: promresourcesv1.PrometheusRuleSpec{
|
||||
Groups: []promresourcesv1.RuleGroup{{
|
||||
Name: group,
|
||||
Rules: []promresourcesv1.Rule{*rule},
|
||||
}},
|
||||
},
|
||||
}
|
||||
if _, err := r.client.MonitoringV1().
|
||||
PrometheusRules(ruleNamespace.Name).Create(ctx, &newPromRule, metav1.CreateOptions{}); err != nil {
|
||||
return errors.Wrapf(err, "error creating a prometheusrule resource %s/%s",
|
||||
newPromRule.Namespace, newPromRule.Name)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *ThanosRuler) UpdateAlertingRule(ctx context.Context, ruleNamespace *corev1.Namespace,
|
||||
extraRuleResourceSelector labels.Selector,
|
||||
group string, rule *promresourcesv1.Rule, ruleResourceLabels map[string]string) error {
|
||||
|
||||
prometheusRules, err := r.ListRuleResources(ruleNamespace, extraRuleResourceSelector)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var (
|
||||
found bool
|
||||
success bool
|
||||
resourcesToDelRule = make(map[string]*ruleResource)
|
||||
)
|
||||
for _, prometheusRule := range prometheusRules {
|
||||
resource := ruleResource(*prometheusRule)
|
||||
if success { // If the update has been successful, delete the possible same rule in other resources
|
||||
if ok, err := resource.deleteAlertingRule(rule.Alert); err != nil {
|
||||
return err
|
||||
} else if ok {
|
||||
if err = resource.commit(ctx, r.client); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
if ok, err := resource.updateAlertingRule(group, rule); err != nil {
|
||||
if err == errOutOfConfigMapSize {
|
||||
// updating the rule in the resource will oversize the size limit,
|
||||
// so delete it and then add the new rule to a new resource.
|
||||
resourcesToDelRule[resource.Name] = &resource
|
||||
found = true
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
} else if ok {
|
||||
if err = resource.commit(ctx, r.client); err != nil {
|
||||
return err
|
||||
}
|
||||
found = true
|
||||
success = true
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
return v1alpha1.ErrAlertingRuleNotFound
|
||||
}
|
||||
|
||||
if !success {
|
||||
err := r.addAlertingRule(ctx, ruleNamespace, prometheusRules, resourcesToDelRule, group, rule, ruleResourceLabels)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
for _, resource := range resourcesToDelRule {
|
||||
if ok, err := resource.deleteAlertingRule(rule.Alert); err != nil {
|
||||
return err
|
||||
} else if ok {
|
||||
if err = resource.commit(ctx, r.client); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *ThanosRuler) DeleteAlertingRule(ctx context.Context, ruleNamespace *corev1.Namespace,
|
||||
extraRuleResourceSelector labels.Selector, group string, name string) error {
|
||||
prometheusRules, err := r.ListRuleResources(ruleNamespace, extraRuleResourceSelector)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var success bool
|
||||
for _, prometheusRule := range prometheusRules {
|
||||
resource := ruleResource(*prometheusRule)
|
||||
if ok, err := resource.deleteAlertingRule(name); err != nil {
|
||||
return err
|
||||
} else if ok {
|
||||
if err = resource.commit(ctx, r.client); err != nil {
|
||||
return err
|
||||
}
|
||||
success = true
|
||||
}
|
||||
}
|
||||
if !success {
|
||||
return v1alpha1.ErrAlertingRuleNotFound
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func ruleNamespaceSelected(r Ruler, ruleNamespace *corev1.Namespace) (bool, error) {
|
||||
rnSelector, err := r.RuleResourceNamespaceSelector()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if rnSelector == nil { // refer to the comment of Prometheus.Spec.RuleResourceNamespaceSelector
|
||||
if r.Namespace() != ruleNamespace.Name {
|
||||
return false, nil
|
||||
}
|
||||
} else {
|
||||
if !rnSelector.Matches(labels.Set(ruleNamespace.Labels)) {
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
421
pkg/models/customalerting/rules/utils.go
Normal file
421
pkg/models/customalerting/rules/utils.go
Normal file
@@ -0,0 +1,421 @@
|
||||
package rules
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prometheus-community/prom-label-proxy/injectproxy"
|
||||
promresourcesv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
|
||||
prommodel "github.com/prometheus/common/model"
|
||||
promlabels "github.com/prometheus/prometheus/pkg/labels"
|
||||
"github.com/prometheus/prometheus/promql/parser"
|
||||
"github.com/prometheus/prometheus/rules"
|
||||
"k8s.io/klog"
|
||||
"kubesphere.io/kubesphere/pkg/api/customalerting/v1alpha1"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/customalerting"
|
||||
)
|
||||
|
||||
const (
|
||||
ErrGenRuleId = "error generating rule id"
|
||||
|
||||
LabelKeyInternalRuleGroup = "__rule_group__"
|
||||
LabelKeyInternalRuleName = "__rule_name__"
|
||||
LabelKeyInternalRuleQuery = "__rule_query__"
|
||||
LabelKeyInternalRuleDuration = "__rule_duration__"
|
||||
LabelKeyInternalRuleAlias = "__rule_alias__"
|
||||
LabelKeyInternalRuleDescription = "__rule_description__"
|
||||
)
|
||||
|
||||
func FormatExpr(expr string) (string, error) {
|
||||
parsedExpr, err := parser.ParseExpr(expr)
|
||||
if err == nil {
|
||||
return parsedExpr.String(), nil
|
||||
}
|
||||
return "", errors.Wrapf(err, "failed to parse expr: %s", expr)
|
||||
}
|
||||
|
||||
// InjectExprNamespaceLabel injects an label, whose key is "namespace" and whose value is the given namespace,
|
||||
// into the prometheus query expression, which will limit the query scope.
|
||||
func InjectExprNamespaceLabel(expr, namespace string) (string, error) {
|
||||
parsedExpr, err := parser.ParseExpr(expr)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if err = injectproxy.NewEnforcer(&promlabels.Matcher{
|
||||
Type: promlabels.MatchEqual,
|
||||
Name: "namespace",
|
||||
Value: namespace,
|
||||
}).EnforceNode(parsedExpr); err == nil {
|
||||
return parsedExpr.String(), nil
|
||||
}
|
||||
return "", err
|
||||
}
|
||||
|
||||
func FormatDuration(for_ string) (string, error) {
|
||||
var duration prommodel.Duration
|
||||
var err error
|
||||
if for_ != "" {
|
||||
duration, err = prommodel.ParseDuration(for_)
|
||||
if err != nil {
|
||||
return "", errors.Wrapf(err, "failed to parse Duration string(\"%s\") to time.Duration", for_)
|
||||
}
|
||||
}
|
||||
return duration.String(), nil
|
||||
}
|
||||
|
||||
func parseDurationSeconds(durationSeconds float64) string {
|
||||
return prommodel.Duration(int64(durationSeconds * float64(time.Second))).String()
|
||||
}
|
||||
|
||||
func GenResourceRuleIdIgnoreFormat(group string, rule *promresourcesv1.Rule) string {
|
||||
query, err := FormatExpr(rule.Expr.String())
|
||||
if err != nil {
|
||||
klog.Warning(errors.Wrapf(err, "invalid alerting rule(%s)", rule.Alert))
|
||||
query = rule.Expr.String()
|
||||
}
|
||||
duration, err := FormatDuration(rule.For)
|
||||
if err != nil {
|
||||
klog.Warning(errors.Wrapf(err, "invalid alerting rule(%s)", rule.Alert))
|
||||
duration = rule.For
|
||||
}
|
||||
|
||||
lbls := make(map[string]string)
|
||||
for k, v := range rule.Labels {
|
||||
lbls[k] = v
|
||||
}
|
||||
lbls[LabelKeyInternalRuleGroup] = group
|
||||
lbls[LabelKeyInternalRuleName] = rule.Alert
|
||||
lbls[LabelKeyInternalRuleQuery] = query
|
||||
lbls[LabelKeyInternalRuleDuration] = duration
|
||||
|
||||
return prommodel.Fingerprint(prommodel.LabelsToSignature(lbls)).String()
|
||||
}
|
||||
|
||||
func GenEndpointRuleId(group string, epRule *customalerting.AlertingRule,
|
||||
externalLabels func() map[string]string) (string, error) {
|
||||
query, err := FormatExpr(epRule.Query)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
duration := parseDurationSeconds(epRule.Duration)
|
||||
|
||||
var labelsMap map[string]string
|
||||
if externalLabels == nil {
|
||||
labelsMap = epRule.Labels
|
||||
} else {
|
||||
labelsMap = make(map[string]string)
|
||||
extLabels := externalLabels()
|
||||
for key, value := range epRule.Labels {
|
||||
if v, ok := extLabels[key]; !(ok && value == v) {
|
||||
labelsMap[key] = value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lbls := make(map[string]string)
|
||||
for k, v := range labelsMap {
|
||||
lbls[k] = v
|
||||
}
|
||||
lbls[LabelKeyInternalRuleGroup] = group
|
||||
lbls[LabelKeyInternalRuleName] = epRule.Name
|
||||
lbls[LabelKeyInternalRuleQuery] = query
|
||||
lbls[LabelKeyInternalRuleDuration] = duration
|
||||
|
||||
return prommodel.Fingerprint(prommodel.LabelsToSignature(lbls)).String(), nil
|
||||
}
|
||||
|
||||
// MixAlertingRules mix rules from prometheusrule custom resources and rules from endpoints.
|
||||
// Use rules from prometheusrule custom resources as the main reference.
|
||||
func MixAlertingRules(ruleNamespace string, ruleChunk *ResourceRuleChunk, epRuleGroups []*customalerting.RuleGroup,
|
||||
extLabels func() map[string]string) ([]*v1alpha1.GettableAlertingRule, error) {
|
||||
|
||||
var (
|
||||
idEpRules = make(map[string]*customalerting.AlertingRule)
|
||||
nameIds = make(map[string][]string)
|
||||
ret []*v1alpha1.GettableAlertingRule
|
||||
)
|
||||
for _, group := range epRuleGroups {
|
||||
fileShort := strings.TrimSuffix(filepath.Base(group.File), filepath.Ext(group.File))
|
||||
if !strings.HasPrefix(fileShort, ruleNamespace+"-") {
|
||||
continue
|
||||
}
|
||||
resourceRules, ok := ruleChunk.ResourceRulesMap[strings.TrimPrefix(fileShort, ruleNamespace+"-")]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if _, ok := resourceRules.GroupSet[group.Name]; !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, epRule := range group.Rules {
|
||||
if eid, err := GenEndpointRuleId(group.Name, epRule, extLabels); err != nil {
|
||||
return nil, errors.Wrap(err, ErrGenRuleId)
|
||||
} else {
|
||||
idEpRules[eid] = epRule
|
||||
nameIds[epRule.Name] = append(nameIds[epRule.Name], eid)
|
||||
}
|
||||
}
|
||||
}
|
||||
if ruleChunk.Custom {
|
||||
// guarantee the names of the custom alerting rules not to be repeated
|
||||
var m = make(map[string][]*ResourceRule)
|
||||
for _, resourceRules := range ruleChunk.ResourceRulesMap {
|
||||
for name, rrArr := range resourceRules.NameRules {
|
||||
m[name] = append(m[name], rrArr...)
|
||||
}
|
||||
}
|
||||
for _, rrArr := range m {
|
||||
if l := len(rrArr); l > 0 {
|
||||
if l > 1 {
|
||||
sort.Slice(rrArr, func(i, j int) bool {
|
||||
return v1alpha1.AlertingRuleIdCompare(rrArr[i].Id, rrArr[j].Id)
|
||||
})
|
||||
}
|
||||
resRule := rrArr[0]
|
||||
epRule := idEpRules[resRule.Id]
|
||||
if r := mixAlertingRule(resRule, epRule, ruleChunk.Custom, ruleChunk.Level); r != nil {
|
||||
ret = append(ret, r)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// guarantee the ids of the builtin alerting rules not to be repeated
|
||||
var m = make(map[string]*v1alpha1.GettableAlertingRule)
|
||||
for _, resourceRules := range ruleChunk.ResourceRulesMap {
|
||||
for id, rule := range resourceRules.IdRules {
|
||||
if r := mixAlertingRule(rule, idEpRules[id], ruleChunk.Custom, ruleChunk.Level); r != nil {
|
||||
m[id] = r
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, r := range m {
|
||||
ret = append(ret, r)
|
||||
}
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func MixAlertingRule(ruleNamespace string, rule *ResourceRuleSole, epRuleGroups []*customalerting.RuleGroup,
|
||||
extLabels func() map[string]string) (*v1alpha1.GettableAlertingRule, error) {
|
||||
|
||||
if rule == nil || rule.Rule == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var epRules = make(map[string]*customalerting.AlertingRule)
|
||||
for _, group := range epRuleGroups {
|
||||
fileShort := strings.TrimSuffix(filepath.Base(group.File), filepath.Ext(group.File))
|
||||
if !strings.HasPrefix(fileShort, ruleNamespace+"-") {
|
||||
continue
|
||||
}
|
||||
if strings.TrimPrefix(fileShort, ruleNamespace+"-") != rule.ResourceName {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, epRule := range group.Rules {
|
||||
if eid, err := GenEndpointRuleId(group.Name, epRule, extLabels); err != nil {
|
||||
return nil, errors.Wrap(err, ErrGenRuleId)
|
||||
} else {
|
||||
if rule.Rule.Alert == epRule.Name {
|
||||
epRules[eid] = epRule
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var epRule *customalerting.AlertingRule
|
||||
if rule.Custom {
|
||||
// guarantees the stability of the get operations.
|
||||
var ids []string
|
||||
for k, _ := range epRules {
|
||||
ids = append(ids, k)
|
||||
}
|
||||
if l := len(ids); l > 0 {
|
||||
if l > 1 {
|
||||
sort.Slice(ids, func(i, j int) bool {
|
||||
return v1alpha1.AlertingRuleIdCompare(ids[i], ids[j])
|
||||
})
|
||||
}
|
||||
epRule = epRules[ids[0]]
|
||||
}
|
||||
} else {
|
||||
epRule = epRules[rule.Id]
|
||||
}
|
||||
|
||||
return mixAlertingRule(&rule.ResourceRule, epRule, rule.Custom, rule.Level), nil
|
||||
}
|
||||
|
||||
func mixAlertingRule(resRule *ResourceRule, epRule *customalerting.AlertingRule,
|
||||
custom bool, level v1alpha1.RuleLevel) *v1alpha1.GettableAlertingRule {
|
||||
|
||||
if resRule == nil || resRule.Rule == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
alias string
|
||||
descrption string
|
||||
lbls map[string]string
|
||||
)
|
||||
if len(resRule.Rule.Labels) > 0 {
|
||||
lbls = make(map[string]string)
|
||||
for k, v := range resRule.Rule.Labels {
|
||||
switch k {
|
||||
case LabelKeyInternalRuleAlias:
|
||||
alias = v
|
||||
case LabelKeyInternalRuleDescription:
|
||||
descrption = v
|
||||
default:
|
||||
lbls[k] = v
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rule := v1alpha1.GettableAlertingRule{
|
||||
AlertingRuleQualifier: v1alpha1.AlertingRuleQualifier{
|
||||
Id: resRule.Id,
|
||||
Name: resRule.Rule.Alert,
|
||||
Custom: custom,
|
||||
Level: level,
|
||||
},
|
||||
AlertingRuleProps: v1alpha1.AlertingRuleProps{
|
||||
Query: resRule.Rule.Expr.String(),
|
||||
Duration: resRule.Rule.For,
|
||||
Labels: lbls,
|
||||
Annotations: resRule.Rule.Annotations,
|
||||
},
|
||||
Alias: alias,
|
||||
Description: descrption,
|
||||
State: stateInactiveString,
|
||||
Health: string(rules.HealthUnknown),
|
||||
}
|
||||
|
||||
if epRule != nil {
|
||||
// The state information and alerts associated with the rule are from the rule from the endpoint.
|
||||
if epRule.Health != "" {
|
||||
rule.Health = epRule.Health
|
||||
}
|
||||
rule.LastError = epRule.LastError
|
||||
rule.LastEvaluation = epRule.LastEvaluation
|
||||
rule.EvaluationDurationSeconds = epRule.EvaluationTime
|
||||
|
||||
rState := strings.ToLower(epRule.State)
|
||||
cliRuleStateEmpty := rState == ""
|
||||
if !cliRuleStateEmpty {
|
||||
rule.State = rState
|
||||
}
|
||||
for _, a := range epRule.Alerts {
|
||||
aState := strings.ToLower(a.State)
|
||||
if cliRuleStateEmpty {
|
||||
// for the rules gotten from prometheus or thanos ruler with a lower version, they may not contain
|
||||
// the state property, so compute the rule state by states of its alerts
|
||||
if alertState(rState) < alertState(aState) {
|
||||
rule.State = aState
|
||||
}
|
||||
}
|
||||
var lbls map[string]string
|
||||
if len(a.Labels) > 0 {
|
||||
lbls = make(map[string]string)
|
||||
for k, v := range a.Labels {
|
||||
switch k {
|
||||
case LabelKeyInternalRuleAlias, LabelKeyInternalRuleDescription:
|
||||
default:
|
||||
lbls[k] = v
|
||||
}
|
||||
}
|
||||
}
|
||||
rule.Alerts = append(rule.Alerts, &v1alpha1.Alert{
|
||||
ActiveAt: a.ActiveAt,
|
||||
Labels: lbls,
|
||||
Annotations: a.Annotations,
|
||||
State: aState,
|
||||
Value: a.Value,
|
||||
|
||||
Rule: &rule.AlertingRuleQualifier,
|
||||
})
|
||||
}
|
||||
}
|
||||
return &rule
|
||||
}
|
||||
|
||||
func ParseAlertingRules(epRuleGroups []*customalerting.RuleGroup, custom bool, level v1alpha1.RuleLevel,
|
||||
filterFunc func(group, ruleId string, rule *customalerting.AlertingRule) bool) ([]*v1alpha1.GettableAlertingRule, error) {
|
||||
|
||||
var ret []*v1alpha1.GettableAlertingRule
|
||||
for _, g := range epRuleGroups {
|
||||
for _, r := range g.Rules {
|
||||
id, err := GenEndpointRuleId(g.Name, r, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if filterFunc(g.Name, id, r) {
|
||||
rule := &v1alpha1.GettableAlertingRule{
|
||||
AlertingRuleQualifier: v1alpha1.AlertingRuleQualifier{
|
||||
Id: id,
|
||||
Name: r.Name,
|
||||
Custom: custom,
|
||||
Level: level,
|
||||
},
|
||||
AlertingRuleProps: v1alpha1.AlertingRuleProps{
|
||||
Query: r.Query,
|
||||
Duration: parseDurationSeconds(r.Duration),
|
||||
Labels: r.Labels,
|
||||
Annotations: r.Annotations,
|
||||
},
|
||||
State: r.State,
|
||||
Health: string(r.Health),
|
||||
LastError: r.LastError,
|
||||
LastEvaluation: r.LastEvaluation,
|
||||
EvaluationDurationSeconds: r.EvaluationTime,
|
||||
}
|
||||
if rule.Health != "" {
|
||||
rule.Health = string(rules.HealthUnknown)
|
||||
}
|
||||
ruleStateEmpty := rule.State == ""
|
||||
rule.State = stateInactiveString
|
||||
for _, a := range r.Alerts {
|
||||
aState := strings.ToLower(a.State)
|
||||
if ruleStateEmpty {
|
||||
// for the rules gotten from prometheus or thanos ruler with a lower version, they may not contain
|
||||
// the state property, so compute the rule state by states of its alerts
|
||||
if alertState(rule.State) < alertState(aState) {
|
||||
rule.State = aState
|
||||
}
|
||||
}
|
||||
rule.Alerts = append(rule.Alerts, &v1alpha1.Alert{
|
||||
ActiveAt: a.ActiveAt,
|
||||
Labels: a.Labels,
|
||||
Annotations: a.Annotations,
|
||||
State: aState,
|
||||
Value: a.Value,
|
||||
|
||||
Rule: &rule.AlertingRuleQualifier,
|
||||
})
|
||||
}
|
||||
ret = append(ret, rule)
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
var (
|
||||
statePendingString = rules.StatePending.String()
|
||||
stateFiringString = rules.StateFiring.String()
|
||||
stateInactiveString = rules.StateInactive.String()
|
||||
)
|
||||
|
||||
func alertState(state string) rules.AlertState {
|
||||
switch state {
|
||||
case statePendingString:
|
||||
return rules.StatePending
|
||||
case stateFiringString:
|
||||
return rules.StateFiring
|
||||
case stateInactiveString:
|
||||
return rules.StateInactive
|
||||
}
|
||||
return rules.StateInactive
|
||||
}
|
||||
95
pkg/models/customalerting/rules/utils_test.go
Normal file
95
pkg/models/customalerting/rules/utils_test.go
Normal file
@@ -0,0 +1,95 @@
|
||||
package rules
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
promresourcesv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
|
||||
"github.com/prometheus/prometheus/rules"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
"kubesphere.io/kubesphere/pkg/api/customalerting/v1alpha1"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/customalerting"
|
||||
)
|
||||
|
||||
func TestMixAlertingRules(t *testing.T) {
|
||||
var tests = []struct {
|
||||
description string
|
||||
ruleNamespace string
|
||||
resourceRuleChunk *ResourceRuleChunk
|
||||
ruleGroups []*customalerting.RuleGroup
|
||||
extLabels func() map[string]string
|
||||
expected []*v1alpha1.GettableAlertingRule
|
||||
}{{
|
||||
description: "mix custom rules",
|
||||
ruleNamespace: "test",
|
||||
resourceRuleChunk: &ResourceRuleChunk{
|
||||
Level: v1alpha1.RuleLevelNamespace,
|
||||
Custom: true,
|
||||
ResourceRulesMap: map[string]*ResourceRules{
|
||||
"custom-alerting-rule-jqbgn": &ResourceRules{
|
||||
GroupSet: map[string]struct{}{"alerting.custom.defaults": struct{}{}},
|
||||
NameRules: map[string][]*ResourceRule{
|
||||
"f89836879157ca88": []*ResourceRule{{
|
||||
ResourceName: "custom-alerting-rule-jqbgn",
|
||||
Group: "alerting.custom.defaults",
|
||||
Id: "f89836879157ca88",
|
||||
Rule: &promresourcesv1.Rule{
|
||||
Alert: "TestCPUUsageHigh",
|
||||
Expr: intstr.FromString(`namespace:workload_cpu_usage:sum{namespace="test"} > 1`),
|
||||
For: "1m",
|
||||
Labels: map[string]string{
|
||||
LabelKeyInternalRuleAlias: "The alias is here",
|
||||
LabelKeyInternalRuleDescription: "The description is here",
|
||||
},
|
||||
},
|
||||
}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
ruleGroups: []*customalerting.RuleGroup{{
|
||||
Name: "alerting.custom.defaults",
|
||||
File: "/etc/thanos/rules/thanos-ruler-thanos-ruler-rulefiles-0/test-custom-alerting-rule-jqbgn.yaml",
|
||||
Rules: []*customalerting.AlertingRule{{
|
||||
Name: "TestCPUUsageHigh",
|
||||
Query: `namespace:workload_cpu_usage:sum{namespace="test"} > 1`,
|
||||
Duration: 60,
|
||||
Health: string(rules.HealthGood),
|
||||
State: stateInactiveString,
|
||||
Labels: map[string]string{
|
||||
LabelKeyInternalRuleAlias: "The alias is here",
|
||||
LabelKeyInternalRuleDescription: "The description is here",
|
||||
},
|
||||
}},
|
||||
}},
|
||||
expected: []*v1alpha1.GettableAlertingRule{{
|
||||
AlertingRuleQualifier: v1alpha1.AlertingRuleQualifier{
|
||||
Id: "f89836879157ca88",
|
||||
Name: "TestCPUUsageHigh",
|
||||
Level: v1alpha1.RuleLevelNamespace,
|
||||
Custom: true,
|
||||
},
|
||||
AlertingRuleProps: v1alpha1.AlertingRuleProps{
|
||||
Query: `namespace:workload_cpu_usage:sum{namespace="test"} > 1`,
|
||||
Duration: "1m",
|
||||
Labels: map[string]string{},
|
||||
},
|
||||
Alias: "The alias is here",
|
||||
Description: "The description is here",
|
||||
Health: string(rules.HealthGood),
|
||||
State: stateInactiveString,
|
||||
}},
|
||||
}}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.description, func(t *testing.T) {
|
||||
rules, err := MixAlertingRules(test.ruleNamespace, test.resourceRuleChunk, test.ruleGroups, test.extLabels)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if diff := cmp.Diff(rules, test.expected); diff != "" {
|
||||
t.Fatalf("%T differ (-got, +want): %s", test.expected, diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -213,7 +213,7 @@ func prepare() (informers.InformerFactory, error) {
|
||||
k8sClient := fakek8s.NewSimpleClientset()
|
||||
istioClient := fakeistio.NewSimpleClientset()
|
||||
snapshotClient := fakesnapshot.NewSimpleClientset()
|
||||
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, istioClient, snapshotClient, nil)
|
||||
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, istioClient, snapshotClient, nil, nil)
|
||||
|
||||
k8sInformerFactory := fakeInformerFactory.KubernetesSharedInformerFactory()
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@ func prepare() *ResourceGetter {
|
||||
istioClient := fakeistio.NewSimpleClientset()
|
||||
snapshotClient := fakesnapshot.NewSimpleClientset()
|
||||
apiextensionsClient := fakeapiextensions.NewSimpleClientset()
|
||||
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, istioClient, snapshotClient, apiextensionsClient)
|
||||
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, istioClient, snapshotClient, apiextensionsClient, nil)
|
||||
|
||||
for _, namespace := range namespaces {
|
||||
fakeInformerFactory.KubernetesSharedInformerFactory().Core().V1().
|
||||
|
||||
@@ -491,7 +491,7 @@ func prepare() Interface {
|
||||
ksClient := fakeks.NewSimpleClientset([]runtime.Object{testWorkspace, systemWorkspace}...)
|
||||
k8sClient := fakek8s.NewSimpleClientset([]runtime.Object{testNamespace, kubesphereSystem}...)
|
||||
istioClient := fakeistio.NewSimpleClientset()
|
||||
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, istioClient, nil, nil)
|
||||
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, istioClient, nil, nil, nil)
|
||||
|
||||
for _, workspace := range workspaces {
|
||||
fakeInformerFactory.KubeSphereSharedInformerFactory().Tenant().V1alpha1().
|
||||
|
||||
66
pkg/simple/client/customalerting/options.go
Normal file
66
pkg/simple/client/customalerting/options.go
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
Copyright 2020 KubeSphere Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package customalerting
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
"kubesphere.io/kubesphere/pkg/utils/reflectutils"
|
||||
)
|
||||
|
||||
type Options struct {
|
||||
PrometheusEndpoint string `json:"prometheusEndpoint" yaml:"prometheusEndpoint"`
|
||||
ThanosRulerEndpoint string `json:"thanosRulerEndpoint" yaml:"thanosRulerEndpoint"`
|
||||
ThanosRuleResourceLabels string `json:"thanosRuleResourceLabels" yaml:"thanosRuleResourceLabels"`
|
||||
}
|
||||
|
||||
func NewOptions() *Options {
|
||||
return &Options{}
|
||||
}
|
||||
|
||||
func (o *Options) ApplyTo(options *Options) {
|
||||
reflectutils.Override(options, o)
|
||||
}
|
||||
|
||||
func (o *Options) Validate() []error {
|
||||
errs := []error{}
|
||||
|
||||
if len(o.ThanosRuleResourceLabels) > 0 {
|
||||
lblStrings := strings.Split(o.ThanosRuleResourceLabels, ",")
|
||||
for _, lblString := range lblStrings {
|
||||
if len(lblString) > 0 {
|
||||
lbl := strings.Split(lblString, "=")
|
||||
if len(lbl) != 2 {
|
||||
errs = append(errs, fmt.Errorf("invalid thanos-rule-resource-labels arg: %s", o.ThanosRuleResourceLabels))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return errs
|
||||
}
|
||||
|
||||
func (o *Options) AddFlags(fs *pflag.FlagSet, c *Options) {
|
||||
fs.StringVar(&o.PrometheusEndpoint, "prometheus-endpoint", c.PrometheusEndpoint,
|
||||
"Prometheus service endpoint from which built-in alerting rules are gotten.")
|
||||
fs.StringVar(&o.ThanosRulerEndpoint, "thanos-ruler-endpoint", c.ThanosRulerEndpoint,
|
||||
"Thanos ruler service endpoint from which custom alerting rules are gotten.")
|
||||
fs.StringVar(&o.ThanosRuleResourceLabels, "thanos-rule-resource-labels", c.ThanosRuleResourceLabels,
|
||||
"The labels will be added to prometheusrule custom resources to be selected by thanos ruler. eg: thanosruler=thanos-ruler,role=custom-alerting-rules")
|
||||
}
|
||||
173
pkg/simple/client/customalerting/rule_client.go
Normal file
173
pkg/simple/client/customalerting/rule_client.go
Normal file
@@ -0,0 +1,173 @@
|
||||
package customalerting
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/pkg/errors"
|
||||
"net/http"
|
||||
)
|
||||
import "github.com/prometheus/client_golang/api"
|
||||
|
||||
const (
|
||||
apiPrefix = "/api/v1"
|
||||
epRules = apiPrefix + "/rules"
|
||||
statusAPIError = 422
|
||||
|
||||
statusSuccess status = "success"
|
||||
statusError status = "error"
|
||||
|
||||
ErrBadData ErrorType = "bad_data"
|
||||
ErrTimeout ErrorType = "timeout"
|
||||
ErrCanceled ErrorType = "canceled"
|
||||
ErrExec ErrorType = "execution"
|
||||
ErrBadResponse ErrorType = "bad_response"
|
||||
ErrServer ErrorType = "server_error"
|
||||
ErrClient ErrorType = "client_error"
|
||||
)
|
||||
|
||||
type status string
|
||||
|
||||
type ErrorType string
|
||||
|
||||
type Error struct {
|
||||
Type ErrorType
|
||||
Msg string
|
||||
Detail string
|
||||
}
|
||||
|
||||
func (e *Error) Error() string {
|
||||
return fmt.Sprintf("%s: %s", e.Type, e.Msg)
|
||||
}
|
||||
|
||||
type response struct {
|
||||
Status status `json:"status"`
|
||||
Data json.RawMessage `json:"data,omitempty"`
|
||||
ErrorType ErrorType `json:"errorType,omitempty"`
|
||||
Error string `json:"error,omitempty"`
|
||||
Warnings []string `json:"warnings,omitempty"`
|
||||
}
|
||||
|
||||
type RuleClient interface {
|
||||
PrometheusRules(ctx context.Context) ([]*RuleGroup, error)
|
||||
ThanosRules(ctx context.Context) ([]*RuleGroup, error)
|
||||
}
|
||||
|
||||
type ruleClient struct {
|
||||
prometheus api.Client
|
||||
thanosruler api.Client
|
||||
}
|
||||
|
||||
func (c *ruleClient) PrometheusRules(ctx context.Context) ([]*RuleGroup, error) {
|
||||
if c.prometheus != nil {
|
||||
return c.rules(c.prometheus, ctx)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (c *ruleClient) ThanosRules(ctx context.Context) ([]*RuleGroup, error) {
|
||||
if c.thanosruler != nil {
|
||||
return c.rules(c.thanosruler, ctx)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (c *ruleClient) rules(client api.Client, ctx context.Context) ([]*RuleGroup, error) {
|
||||
u := client.URL(epRules, nil)
|
||||
q := u.Query()
|
||||
q.Add("type", "alert")
|
||||
u.RawQuery = q.Encode()
|
||||
|
||||
req, err := http.NewRequest(http.MethodGet, u.String(), nil)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "error creating request: ")
|
||||
}
|
||||
|
||||
_, body, _, err := c.do(client, ctx, req)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "error doing request: ")
|
||||
}
|
||||
|
||||
var result struct {
|
||||
Groups []*RuleGroup
|
||||
}
|
||||
err = json.Unmarshal(body, &result)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "")
|
||||
}
|
||||
return result.Groups, nil
|
||||
}
|
||||
|
||||
func (c *ruleClient) do(client api.Client, ctx context.Context, req *http.Request) (*http.Response, []byte, []string, error) {
|
||||
resp, body, e := client.Do(ctx, req)
|
||||
if e != nil {
|
||||
return resp, body, nil, e
|
||||
}
|
||||
|
||||
code := resp.StatusCode
|
||||
|
||||
if code/100 != 2 && !apiError(code) {
|
||||
errorType, errorMsg := errorTypeAndMsgFor(resp)
|
||||
return resp, body, nil, &Error{
|
||||
Type: errorType,
|
||||
Msg: errorMsg,
|
||||
Detail: string(body),
|
||||
}
|
||||
}
|
||||
|
||||
var result response
|
||||
if http.StatusNoContent != code {
|
||||
if jsonErr := json.Unmarshal(body, &result); jsonErr != nil {
|
||||
return resp, body, nil, &Error{
|
||||
Type: ErrBadResponse,
|
||||
Msg: jsonErr.Error(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var err error
|
||||
if apiError(code) && result.Status == "success" {
|
||||
err = &Error{
|
||||
Type: ErrBadResponse,
|
||||
Msg: "inconsistent body for response code",
|
||||
}
|
||||
}
|
||||
if result.Status == "error" {
|
||||
err = &Error{
|
||||
Type: result.ErrorType,
|
||||
Msg: result.Error,
|
||||
}
|
||||
}
|
||||
|
||||
return resp, []byte(result.Data), result.Warnings, err
|
||||
}
|
||||
|
||||
func errorTypeAndMsgFor(resp *http.Response) (ErrorType, string) {
|
||||
switch resp.StatusCode / 100 {
|
||||
case 4:
|
||||
return ErrClient, fmt.Sprintf("client error: %d", resp.StatusCode)
|
||||
case 5:
|
||||
return ErrServer, fmt.Sprintf("server error: %d", resp.StatusCode)
|
||||
}
|
||||
return ErrBadResponse, fmt.Sprintf("bad response code %d", resp.StatusCode)
|
||||
}
|
||||
|
||||
func apiError(code int) bool {
|
||||
// These are the codes that rule server sends when it returns an error.
|
||||
return code == statusAPIError || code == http.StatusBadRequest ||
|
||||
code == http.StatusServiceUnavailable || code == http.StatusInternalServerError
|
||||
}
|
||||
|
||||
func NewRuleClient(options *Options) (RuleClient, error) {
|
||||
var (
|
||||
c ruleClient
|
||||
e error
|
||||
)
|
||||
if options.PrometheusEndpoint != "" {
|
||||
c.prometheus, e = api.NewClient(api.Config{Address: options.PrometheusEndpoint})
|
||||
}
|
||||
if options.ThanosRulerEndpoint != "" {
|
||||
c.thanosruler, e = api.NewClient(api.Config{Address: options.ThanosRulerEndpoint})
|
||||
}
|
||||
return &c, e
|
||||
}
|
||||
100
pkg/simple/client/customalerting/rule_client_test.go
Normal file
100
pkg/simple/client/customalerting/rule_client_test.go
Normal file
@@ -0,0 +1,100 @@
|
||||
package customalerting
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestListRules(t *testing.T) {
|
||||
var tests = []struct {
|
||||
description string
|
||||
fakeCode int
|
||||
fakeResp string
|
||||
expectError bool
|
||||
}{{
|
||||
description: "list alerting rules from prometheus endpoint",
|
||||
expectError: false,
|
||||
fakeCode: 200,
|
||||
fakeResp: `
|
||||
{
|
||||
"status": "success",
|
||||
"data": {
|
||||
"groups": [
|
||||
{
|
||||
"name": "kubernetes-resources",
|
||||
"file": "/etc/prometheus/rules/prometheus-k8s-rulefiles-0/kubesphere-monitoring-system-prometheus-k8s-rules.yaml",
|
||||
"rules": [
|
||||
{
|
||||
"state": "firing",
|
||||
"name": "KubeCPUOvercommit",
|
||||
"query": "sum(namespace:kube_pod_container_resource_requests_cpu_cores:sum) / sum(kube_node_status_allocatable_cpu_cores) > (count(kube_node_status_allocatable_cpu_cores) - 1) / count(kube_node_status_allocatable_cpu_cores)",
|
||||
"duration": 300,
|
||||
"labels": {
|
||||
"severity": "warning"
|
||||
},
|
||||
"annotations": {
|
||||
"message": "Cluster has overcommitted CPU resource requests for Pods and cannot tolerate node failure.",
|
||||
"runbook_url": "https://github.com/kubernetes-monitoring/kubernetes-mixin/tree/master/runbook.md#alert-name-kubecpuovercommit"
|
||||
},
|
||||
"alerts": [
|
||||
{
|
||||
"labels": {
|
||||
"alertname": "KubeCPUOvercommit",
|
||||
"severity": "warning"
|
||||
},
|
||||
"annotations": {
|
||||
"message": "Cluster has overcommitted CPU resource requests for Pods and cannot tolerate node failure.",
|
||||
"runbook_url": "https://github.com/ kubernetes-monitoring/kubernetes-mixin/tree/master/runbook.md#alert-name-kubecpuovercommit"
|
||||
},
|
||||
"state": "firing",
|
||||
"activeAt": "2020-09-22T06:18:47.55260138Z",
|
||||
"value": "4.405e-01"
|
||||
}
|
||||
],
|
||||
"health": "ok",
|
||||
"evaluationTime": 0.000894038,
|
||||
"lastEvaluation": "2020-09-22T08:57:17.566233983Z",
|
||||
"type": "alerting"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
`,
|
||||
}}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.description, func(t *testing.T) {
|
||||
mock := MockService(epRules, test.fakeCode, test.fakeResp)
|
||||
defer mock.Close()
|
||||
c, e := NewRuleClient(&Options{PrometheusEndpoint: mock.URL})
|
||||
if e != nil {
|
||||
t.Fatal(e)
|
||||
}
|
||||
rgs, e := c.PrometheusRules(context.TODO())
|
||||
if test.expectError {
|
||||
} else {
|
||||
if e != nil {
|
||||
t.Fatal(e)
|
||||
} else if len(rgs) == 1 && len(rgs[0].Rules) == 1 {
|
||||
|
||||
} else {
|
||||
t.Fatalf("expect %d group and %d rule but got %d group and %d rule", 1, 1, len(rgs), len(rgs[0].Rules))
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func MockService(pattern string, fakeCode int, fakeResp string) *httptest.Server {
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc(pattern, func(res http.ResponseWriter, req *http.Request) {
|
||||
res.WriteHeader(fakeCode)
|
||||
res.Write([]byte(fakeResp))
|
||||
})
|
||||
return httptest.NewServer(mux)
|
||||
}
|
||||
40
pkg/simple/client/customalerting/types.go
Normal file
40
pkg/simple/client/customalerting/types.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package customalerting
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type RuleGroup struct {
|
||||
Name string `json:"name"`
|
||||
File string `json:"file"`
|
||||
Rules []*AlertingRule `json:"rules"`
|
||||
Interval float64 `json:"interval"`
|
||||
EvaluationTime float64 `json:"evaluationTime"`
|
||||
LastEvaluation *time.Time `json:"lastEvaluation"`
|
||||
}
|
||||
|
||||
type AlertingRule struct {
|
||||
// State can be "pending", "firing", "inactive".
|
||||
State string `json:"state"`
|
||||
Name string `json:"name"`
|
||||
Query string `json:"query"`
|
||||
Duration float64 `json:"duration"`
|
||||
Labels map[string]string `json:"labels"`
|
||||
Annotations map[string]string `json:"annotations"`
|
||||
Alerts []*Alert `json:"alerts"`
|
||||
// Health can be "ok", "err", "unknown".
|
||||
Health string `json:"health"`
|
||||
LastError string `json:"lastError,omitempty"`
|
||||
EvaluationTime float64 `json:"evaluationTime"`
|
||||
LastEvaluation *time.Time `json:"lastEvaluation"`
|
||||
// Type of an alertingRule is always "alerting".
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
type Alert struct {
|
||||
Labels map[string]string `json:"labels"`
|
||||
Annotations map[string]string `json:"annotations"`
|
||||
State string `json:"state"`
|
||||
ActiveAt *time.Time `json:"activeAt,omitempty"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
@@ -18,6 +18,7 @@ package k8s
|
||||
|
||||
import (
|
||||
snapshotclient "github.com/kubernetes-csi/external-snapshotter/client/v3/clientset/versioned"
|
||||
promresourcesclient "github.com/prometheus-operator/prometheus-operator/pkg/client/versioned"
|
||||
istioclient "istio.io/client-go/pkg/clientset/versioned"
|
||||
apiextensionsclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
|
||||
"k8s.io/client-go/discovery"
|
||||
@@ -42,6 +43,8 @@ type FakeClient struct {
|
||||
|
||||
ApiExtensionClient apiextensionsclient.Interface
|
||||
|
||||
prometheusClient promresourcesclient.Interface
|
||||
|
||||
MasterURL string
|
||||
|
||||
KubeConfig *rest.Config
|
||||
@@ -50,7 +53,8 @@ type FakeClient struct {
|
||||
func NewFakeClientSets(k8sClient kubernetes.Interface, discoveryClient *discovery.DiscoveryClient,
|
||||
kubeSphereClient kubesphere.Interface,
|
||||
istioClient istioclient.Interface, snapshotClient snapshotclient.Interface,
|
||||
apiextensionsclient apiextensionsclient.Interface, masterURL string, kubeConfig *rest.Config) Client {
|
||||
apiextensionsclient apiextensionsclient.Interface, prometheusClient promresourcesclient.Interface,
|
||||
masterURL string, kubeConfig *rest.Config) Client {
|
||||
return &FakeClient{
|
||||
K8sClient: k8sClient,
|
||||
DiscoveryClient: discoveryClient,
|
||||
@@ -58,6 +62,7 @@ func NewFakeClientSets(k8sClient kubernetes.Interface, discoveryClient *discover
|
||||
IstioClient: istioClient,
|
||||
SnapshotClient: snapshotClient,
|
||||
ApiExtensionClient: apiextensionsclient,
|
||||
prometheusClient: prometheusClient,
|
||||
MasterURL: masterURL,
|
||||
KubeConfig: kubeConfig,
|
||||
}
|
||||
@@ -87,6 +92,10 @@ func (n *FakeClient) Discovery() discovery.DiscoveryInterface {
|
||||
return n.DiscoveryClient
|
||||
}
|
||||
|
||||
func (n *FakeClient) Prometheus() promresourcesclient.Interface {
|
||||
return n.prometheusClient
|
||||
}
|
||||
|
||||
func (n *FakeClient) Master() string {
|
||||
return n.MasterURL
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ limitations under the License.
|
||||
package k8s
|
||||
|
||||
import (
|
||||
promresourcesclient "github.com/prometheus-operator/prometheus-operator/pkg/client/versioned"
|
||||
snapshotclient "github.com/kubernetes-csi/external-snapshotter/client/v3/clientset/versioned"
|
||||
istioclient "istio.io/client-go/pkg/clientset/versioned"
|
||||
apiextensionsclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
|
||||
@@ -35,6 +36,7 @@ type Client interface {
|
||||
Snapshot() snapshotclient.Interface
|
||||
ApiExtensions() apiextensionsclient.Interface
|
||||
Discovery() discovery.DiscoveryInterface
|
||||
Prometheus() promresourcesclient.Interface
|
||||
Master() string
|
||||
Config() *rest.Config
|
||||
}
|
||||
@@ -55,6 +57,8 @@ type kubernetesClient struct {
|
||||
|
||||
apiextensions apiextensionsclient.Interface
|
||||
|
||||
prometheus promresourcesclient.Interface
|
||||
|
||||
master string
|
||||
|
||||
config *rest.Config
|
||||
@@ -77,6 +81,7 @@ func NewKubernetesClientOrDie(options *KubernetesOptions) Client {
|
||||
istio: istioclient.NewForConfigOrDie(config),
|
||||
snapshot: snapshotclient.NewForConfigOrDie(config),
|
||||
apiextensions: apiextensionsclient.NewForConfigOrDie(config),
|
||||
prometheus: promresourcesclient.NewForConfigOrDie(config),
|
||||
master: config.Host,
|
||||
config: config,
|
||||
}
|
||||
@@ -135,6 +140,11 @@ func NewKubernetesClient(options *KubernetesOptions) (Client, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
k.prometheus, err = promresourcesclient.NewForConfig(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
k.master = options.Master
|
||||
k.config = config
|
||||
|
||||
@@ -165,6 +175,10 @@ func (k *kubernetesClient) ApiExtensions() apiextensionsclient.Interface {
|
||||
return k.apiextensions
|
||||
}
|
||||
|
||||
func (k *kubernetesClient) Prometheus() promresourcesclient.Interface {
|
||||
return k.prometheus
|
||||
}
|
||||
|
||||
// master address used to generate kubeconfig for downloading
|
||||
func (k *kubernetesClient) Master() string {
|
||||
return k.master
|
||||
|
||||
@@ -17,6 +17,7 @@ limitations under the License.
|
||||
package k8s
|
||||
|
||||
import (
|
||||
promresourcesclient "github.com/prometheus-operator/prometheus-operator/pkg/client/versioned"
|
||||
snapshotclient "github.com/kubernetes-csi/external-snapshotter/client/v3/clientset/versioned"
|
||||
istio "istio.io/client-go/pkg/clientset/versioned"
|
||||
apiextensionsclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
|
||||
@@ -57,6 +58,10 @@ func (n nullClient) Discovery() discovery.DiscoveryInterface {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *nullClient) Prometheus() promresourcesclient.Interface {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n nullClient) Master() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ import (
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
clusterkapisv1alpha1 "kubesphere.io/kubesphere/pkg/kapis/cluster/v1alpha1"
|
||||
customalertingv1alpha1 "kubesphere.io/kubesphere/pkg/kapis/customalerting/v1alpha1"
|
||||
devopsv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/devops/v1alpha2"
|
||||
devopsv1alpha3 "kubesphere.io/kubesphere/pkg/kapis/devops/v1alpha3"
|
||||
iamv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/iam/v1alpha2"
|
||||
@@ -128,6 +129,7 @@ func generateSwaggerJson() []byte {
|
||||
urlruntime.Must(terminalv1alpha2.AddToContainer(container, clientsets.Kubernetes(), nil))
|
||||
urlruntime.Must(metricsv1alpha2.AddToContainer(container))
|
||||
urlruntime.Must(networkv1alpha2.AddToContainer(container, ""))
|
||||
urlruntime.Must(customalertingv1alpha1.AddToContainer(container, informerFactory, nil, nil, nil))
|
||||
|
||||
config := restfulspec.Config{
|
||||
WebServices: container.RegisteredWebServices(),
|
||||
|
||||
8
vendor/github.com/edsrzf/mmap-go/.gitignore
generated
vendored
Normal file
8
vendor/github.com/edsrzf/mmap-go/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
*.out
|
||||
*.5
|
||||
*.6
|
||||
*.8
|
||||
*.swp
|
||||
_obj
|
||||
_test
|
||||
testdata
|
||||
25
vendor/github.com/edsrzf/mmap-go/LICENSE
generated
vendored
Normal file
25
vendor/github.com/edsrzf/mmap-go/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
Copyright (c) 2011, Evan Shaw <edsrzf@gmail.com>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
12
vendor/github.com/edsrzf/mmap-go/README.md
generated
vendored
Normal file
12
vendor/github.com/edsrzf/mmap-go/README.md
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
mmap-go
|
||||
=======
|
||||
|
||||
mmap-go is a portable mmap package for the [Go programming language](http://golang.org).
|
||||
It has been tested on Linux (386, amd64), OS X, and Windows (386). It should also
|
||||
work on other Unix-like platforms, but hasn't been tested with them. I'm interested
|
||||
to hear about the results.
|
||||
|
||||
I haven't been able to add more features without adding significant complexity,
|
||||
so mmap-go doesn't support mprotect, mincore, and maybe a few other things.
|
||||
If you're running on a Unix-like platform and need some of these features,
|
||||
I suggest Gustavo Niemeyer's [gommap](http://labix.org/gommap).
|
||||
117
vendor/github.com/edsrzf/mmap-go/mmap.go
generated
vendored
Normal file
117
vendor/github.com/edsrzf/mmap-go/mmap.go
generated
vendored
Normal file
@@ -0,0 +1,117 @@
|
||||
// Copyright 2011 Evan Shaw. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// This file defines the common package interface and contains a little bit of
|
||||
// factored out logic.
|
||||
|
||||
// Package mmap allows mapping files into memory. It tries to provide a simple, reasonably portable interface,
|
||||
// but doesn't go out of its way to abstract away every little platform detail.
|
||||
// This specifically means:
|
||||
// * forked processes may or may not inherit mappings
|
||||
// * a file's timestamp may or may not be updated by writes through mappings
|
||||
// * specifying a size larger than the file's actual size can increase the file's size
|
||||
// * If the mapped file is being modified by another process while your program's running, don't expect consistent results between platforms
|
||||
package mmap
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"reflect"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
// RDONLY maps the memory read-only.
|
||||
// Attempts to write to the MMap object will result in undefined behavior.
|
||||
RDONLY = 0
|
||||
// RDWR maps the memory as read-write. Writes to the MMap object will update the
|
||||
// underlying file.
|
||||
RDWR = 1 << iota
|
||||
// COPY maps the memory as copy-on-write. Writes to the MMap object will affect
|
||||
// memory, but the underlying file will remain unchanged.
|
||||
COPY
|
||||
// If EXEC is set, the mapped memory is marked as executable.
|
||||
EXEC
|
||||
)
|
||||
|
||||
const (
|
||||
// If the ANON flag is set, the mapped memory will not be backed by a file.
|
||||
ANON = 1 << iota
|
||||
)
|
||||
|
||||
// MMap represents a file mapped into memory.
|
||||
type MMap []byte
|
||||
|
||||
// Map maps an entire file into memory.
|
||||
// If ANON is set in flags, f is ignored.
|
||||
func Map(f *os.File, prot, flags int) (MMap, error) {
|
||||
return MapRegion(f, -1, prot, flags, 0)
|
||||
}
|
||||
|
||||
// MapRegion maps part of a file into memory.
|
||||
// The offset parameter must be a multiple of the system's page size.
|
||||
// If length < 0, the entire file will be mapped.
|
||||
// If ANON is set in flags, f is ignored.
|
||||
func MapRegion(f *os.File, length int, prot, flags int, offset int64) (MMap, error) {
|
||||
if offset%int64(os.Getpagesize()) != 0 {
|
||||
return nil, errors.New("offset parameter must be a multiple of the system's page size")
|
||||
}
|
||||
|
||||
var fd uintptr
|
||||
if flags&ANON == 0 {
|
||||
fd = uintptr(f.Fd())
|
||||
if length < 0 {
|
||||
fi, err := f.Stat()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
length = int(fi.Size())
|
||||
}
|
||||
} else {
|
||||
if length <= 0 {
|
||||
return nil, errors.New("anonymous mapping requires non-zero length")
|
||||
}
|
||||
fd = ^uintptr(0)
|
||||
}
|
||||
return mmap(length, uintptr(prot), uintptr(flags), fd, offset)
|
||||
}
|
||||
|
||||
func (m *MMap) header() *reflect.SliceHeader {
|
||||
return (*reflect.SliceHeader)(unsafe.Pointer(m))
|
||||
}
|
||||
|
||||
func (m *MMap) addrLen() (uintptr, uintptr) {
|
||||
header := m.header()
|
||||
return header.Data, uintptr(header.Len)
|
||||
}
|
||||
|
||||
// Lock keeps the mapped region in physical memory, ensuring that it will not be
|
||||
// swapped out.
|
||||
func (m MMap) Lock() error {
|
||||
return m.lock()
|
||||
}
|
||||
|
||||
// Unlock reverses the effect of Lock, allowing the mapped region to potentially
|
||||
// be swapped out.
|
||||
// If m is already unlocked, aan error will result.
|
||||
func (m MMap) Unlock() error {
|
||||
return m.unlock()
|
||||
}
|
||||
|
||||
// Flush synchronizes the mapping's contents to the file's contents on disk.
|
||||
func (m MMap) Flush() error {
|
||||
return m.flush()
|
||||
}
|
||||
|
||||
// Unmap deletes the memory mapped region, flushes any remaining changes, and sets
|
||||
// m to nil.
|
||||
// Trying to read or write any remaining references to m after Unmap is called will
|
||||
// result in undefined behavior.
|
||||
// Unmap should only be called on the slice value that was originally returned from
|
||||
// a call to Map. Calling Unmap on a derived slice may cause errors.
|
||||
func (m *MMap) Unmap() error {
|
||||
err := m.unmap()
|
||||
*m = nil
|
||||
return err
|
||||
}
|
||||
51
vendor/github.com/edsrzf/mmap-go/mmap_unix.go
generated
vendored
Normal file
51
vendor/github.com/edsrzf/mmap-go/mmap_unix.go
generated
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
// Copyright 2011 Evan Shaw. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build darwin dragonfly freebsd linux openbsd solaris netbsd
|
||||
|
||||
package mmap
|
||||
|
||||
import (
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func mmap(len int, inprot, inflags, fd uintptr, off int64) ([]byte, error) {
|
||||
flags := unix.MAP_SHARED
|
||||
prot := unix.PROT_READ
|
||||
switch {
|
||||
case inprot© != 0:
|
||||
prot |= unix.PROT_WRITE
|
||||
flags = unix.MAP_PRIVATE
|
||||
case inprot&RDWR != 0:
|
||||
prot |= unix.PROT_WRITE
|
||||
}
|
||||
if inprot&EXEC != 0 {
|
||||
prot |= unix.PROT_EXEC
|
||||
}
|
||||
if inflags&ANON != 0 {
|
||||
flags |= unix.MAP_ANON
|
||||
}
|
||||
|
||||
b, err := unix.Mmap(int(fd), off, len, prot, flags)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func (m MMap) flush() error {
|
||||
return unix.Msync([]byte(m), unix.MS_SYNC)
|
||||
}
|
||||
|
||||
func (m MMap) lock() error {
|
||||
return unix.Mlock([]byte(m))
|
||||
}
|
||||
|
||||
func (m MMap) unlock() error {
|
||||
return unix.Munlock([]byte(m))
|
||||
}
|
||||
|
||||
func (m MMap) unmap() error {
|
||||
return unix.Munmap([]byte(m))
|
||||
}
|
||||
143
vendor/github.com/edsrzf/mmap-go/mmap_windows.go
generated
vendored
Normal file
143
vendor/github.com/edsrzf/mmap-go/mmap_windows.go
generated
vendored
Normal file
@@ -0,0 +1,143 @@
|
||||
// Copyright 2011 Evan Shaw. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package mmap
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"sync"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
// mmap on Windows is a two-step process.
|
||||
// First, we call CreateFileMapping to get a handle.
|
||||
// Then, we call MapviewToFile to get an actual pointer into memory.
|
||||
// Because we want to emulate a POSIX-style mmap, we don't want to expose
|
||||
// the handle -- only the pointer. We also want to return only a byte slice,
|
||||
// not a struct, so it's convenient to manipulate.
|
||||
|
||||
// We keep this map so that we can get back the original handle from the memory address.
|
||||
|
||||
type addrinfo struct {
|
||||
file windows.Handle
|
||||
mapview windows.Handle
|
||||
}
|
||||
|
||||
var handleLock sync.Mutex
|
||||
var handleMap = map[uintptr]*addrinfo{}
|
||||
|
||||
func mmap(len int, prot, flags, hfile uintptr, off int64) ([]byte, error) {
|
||||
flProtect := uint32(windows.PAGE_READONLY)
|
||||
dwDesiredAccess := uint32(windows.FILE_MAP_READ)
|
||||
switch {
|
||||
case prot© != 0:
|
||||
flProtect = windows.PAGE_WRITECOPY
|
||||
dwDesiredAccess = windows.FILE_MAP_COPY
|
||||
case prot&RDWR != 0:
|
||||
flProtect = windows.PAGE_READWRITE
|
||||
dwDesiredAccess = windows.FILE_MAP_WRITE
|
||||
}
|
||||
if prot&EXEC != 0 {
|
||||
flProtect <<= 4
|
||||
dwDesiredAccess |= windows.FILE_MAP_EXECUTE
|
||||
}
|
||||
|
||||
// The maximum size is the area of the file, starting from 0,
|
||||
// that we wish to allow to be mappable. It is the sum of
|
||||
// the length the user requested, plus the offset where that length
|
||||
// is starting from. This does not map the data into memory.
|
||||
maxSizeHigh := uint32((off + int64(len)) >> 32)
|
||||
maxSizeLow := uint32((off + int64(len)) & 0xFFFFFFFF)
|
||||
// TODO: Do we need to set some security attributes? It might help portability.
|
||||
h, errno := windows.CreateFileMapping(windows.Handle(hfile), nil, flProtect, maxSizeHigh, maxSizeLow, nil)
|
||||
if h == 0 {
|
||||
return nil, os.NewSyscallError("CreateFileMapping", errno)
|
||||
}
|
||||
|
||||
// Actually map a view of the data into memory. The view's size
|
||||
// is the length the user requested.
|
||||
fileOffsetHigh := uint32(off >> 32)
|
||||
fileOffsetLow := uint32(off & 0xFFFFFFFF)
|
||||
addr, errno := windows.MapViewOfFile(h, dwDesiredAccess, fileOffsetHigh, fileOffsetLow, uintptr(len))
|
||||
if addr == 0 {
|
||||
return nil, os.NewSyscallError("MapViewOfFile", errno)
|
||||
}
|
||||
handleLock.Lock()
|
||||
handleMap[addr] = &addrinfo{
|
||||
file: windows.Handle(hfile),
|
||||
mapview: h,
|
||||
}
|
||||
handleLock.Unlock()
|
||||
|
||||
m := MMap{}
|
||||
dh := m.header()
|
||||
dh.Data = addr
|
||||
dh.Len = len
|
||||
dh.Cap = dh.Len
|
||||
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (m MMap) flush() error {
|
||||
addr, len := m.addrLen()
|
||||
errno := windows.FlushViewOfFile(addr, len)
|
||||
if errno != nil {
|
||||
return os.NewSyscallError("FlushViewOfFile", errno)
|
||||
}
|
||||
|
||||
handleLock.Lock()
|
||||
defer handleLock.Unlock()
|
||||
handle, ok := handleMap[addr]
|
||||
if !ok {
|
||||
// should be impossible; we would've errored above
|
||||
return errors.New("unknown base address")
|
||||
}
|
||||
|
||||
errno = windows.FlushFileBuffers(handle.file)
|
||||
return os.NewSyscallError("FlushFileBuffers", errno)
|
||||
}
|
||||
|
||||
func (m MMap) lock() error {
|
||||
addr, len := m.addrLen()
|
||||
errno := windows.VirtualLock(addr, len)
|
||||
return os.NewSyscallError("VirtualLock", errno)
|
||||
}
|
||||
|
||||
func (m MMap) unlock() error {
|
||||
addr, len := m.addrLen()
|
||||
errno := windows.VirtualUnlock(addr, len)
|
||||
return os.NewSyscallError("VirtualUnlock", errno)
|
||||
}
|
||||
|
||||
func (m MMap) unmap() error {
|
||||
err := m.flush()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
addr := m.header().Data
|
||||
// Lock the UnmapViewOfFile along with the handleMap deletion.
|
||||
// As soon as we unmap the view, the OS is free to give the
|
||||
// same addr to another new map. We don't want another goroutine
|
||||
// to insert and remove the same addr into handleMap while
|
||||
// we're trying to remove our old addr/handle pair.
|
||||
handleLock.Lock()
|
||||
defer handleLock.Unlock()
|
||||
err = windows.UnmapViewOfFile(addr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
handle, ok := handleMap[addr]
|
||||
if !ok {
|
||||
// should be impossible; we would've errored above
|
||||
return errors.New("unknown base address")
|
||||
}
|
||||
delete(handleMap, addr)
|
||||
|
||||
e := windows.CloseHandle(windows.Handle(handle.mapview))
|
||||
return os.NewSyscallError("CloseHandle", e)
|
||||
}
|
||||
16
vendor/github.com/golang/snappy/.gitignore
generated
vendored
Normal file
16
vendor/github.com/golang/snappy/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
cmd/snappytool/snappytool
|
||||
testdata/bench
|
||||
|
||||
# These explicitly listed benchmark data files are for an obsolete version of
|
||||
# snappy_test.go.
|
||||
testdata/alice29.txt
|
||||
testdata/asyoulik.txt
|
||||
testdata/fireworks.jpeg
|
||||
testdata/geo.protodata
|
||||
testdata/html
|
||||
testdata/html_x_4
|
||||
testdata/kppkn.gtb
|
||||
testdata/lcet10.txt
|
||||
testdata/paper-100k.pdf
|
||||
testdata/plrabn12.txt
|
||||
testdata/urls.10K
|
||||
15
vendor/github.com/golang/snappy/AUTHORS
generated
vendored
Normal file
15
vendor/github.com/golang/snappy/AUTHORS
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
# This is the official list of Snappy-Go authors for copyright purposes.
|
||||
# This file is distinct from the CONTRIBUTORS files.
|
||||
# See the latter for an explanation.
|
||||
|
||||
# Names should be added to this file as
|
||||
# Name or Organization <email address>
|
||||
# The email address is not required for organizations.
|
||||
|
||||
# Please keep the list sorted.
|
||||
|
||||
Damian Gryski <dgryski@gmail.com>
|
||||
Google Inc.
|
||||
Jan Mercl <0xjnml@gmail.com>
|
||||
Rodolfo Carvalho <rhcarvalho@gmail.com>
|
||||
Sebastien Binet <seb.binet@gmail.com>
|
||||
37
vendor/github.com/golang/snappy/CONTRIBUTORS
generated
vendored
Normal file
37
vendor/github.com/golang/snappy/CONTRIBUTORS
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
# This is the official list of people who can contribute
|
||||
# (and typically have contributed) code to the Snappy-Go repository.
|
||||
# The AUTHORS file lists the copyright holders; this file
|
||||
# lists people. For example, Google employees are listed here
|
||||
# but not in AUTHORS, because Google holds the copyright.
|
||||
#
|
||||
# The submission process automatically checks to make sure
|
||||
# that people submitting code are listed in this file (by email address).
|
||||
#
|
||||
# Names should be added to this file only after verifying that
|
||||
# the individual or the individual's organization has agreed to
|
||||
# the appropriate Contributor License Agreement, found here:
|
||||
#
|
||||
# http://code.google.com/legal/individual-cla-v1.0.html
|
||||
# http://code.google.com/legal/corporate-cla-v1.0.html
|
||||
#
|
||||
# The agreement for individuals can be filled out on the web.
|
||||
#
|
||||
# When adding J Random Contributor's name to this file,
|
||||
# either J's name or J's organization's name should be
|
||||
# added to the AUTHORS file, depending on whether the
|
||||
# individual or corporate CLA was used.
|
||||
|
||||
# Names should be added to this file like so:
|
||||
# Name <email address>
|
||||
|
||||
# Please keep the list sorted.
|
||||
|
||||
Damian Gryski <dgryski@gmail.com>
|
||||
Jan Mercl <0xjnml@gmail.com>
|
||||
Kai Backman <kaib@golang.org>
|
||||
Marc-Antoine Ruel <maruel@chromium.org>
|
||||
Nigel Tao <nigeltao@golang.org>
|
||||
Rob Pike <r@golang.org>
|
||||
Rodolfo Carvalho <rhcarvalho@gmail.com>
|
||||
Russ Cox <rsc@golang.org>
|
||||
Sebastien Binet <seb.binet@gmail.com>
|
||||
27
vendor/github.com/golang/snappy/LICENSE
generated
vendored
Normal file
27
vendor/github.com/golang/snappy/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
Copyright (c) 2011 The Snappy-Go Authors. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
107
vendor/github.com/golang/snappy/README
generated
vendored
Normal file
107
vendor/github.com/golang/snappy/README
generated
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
The Snappy compression format in the Go programming language.
|
||||
|
||||
To download and install from source:
|
||||
$ go get github.com/golang/snappy
|
||||
|
||||
Unless otherwise noted, the Snappy-Go source files are distributed
|
||||
under the BSD-style license found in the LICENSE file.
|
||||
|
||||
|
||||
|
||||
Benchmarks.
|
||||
|
||||
The golang/snappy benchmarks include compressing (Z) and decompressing (U) ten
|
||||
or so files, the same set used by the C++ Snappy code (github.com/google/snappy
|
||||
and note the "google", not "golang"). On an "Intel(R) Core(TM) i7-3770 CPU @
|
||||
3.40GHz", Go's GOARCH=amd64 numbers as of 2016-05-29:
|
||||
|
||||
"go test -test.bench=."
|
||||
|
||||
_UFlat0-8 2.19GB/s ± 0% html
|
||||
_UFlat1-8 1.41GB/s ± 0% urls
|
||||
_UFlat2-8 23.5GB/s ± 2% jpg
|
||||
_UFlat3-8 1.91GB/s ± 0% jpg_200
|
||||
_UFlat4-8 14.0GB/s ± 1% pdf
|
||||
_UFlat5-8 1.97GB/s ± 0% html4
|
||||
_UFlat6-8 814MB/s ± 0% txt1
|
||||
_UFlat7-8 785MB/s ± 0% txt2
|
||||
_UFlat8-8 857MB/s ± 0% txt3
|
||||
_UFlat9-8 719MB/s ± 1% txt4
|
||||
_UFlat10-8 2.84GB/s ± 0% pb
|
||||
_UFlat11-8 1.05GB/s ± 0% gaviota
|
||||
|
||||
_ZFlat0-8 1.04GB/s ± 0% html
|
||||
_ZFlat1-8 534MB/s ± 0% urls
|
||||
_ZFlat2-8 15.7GB/s ± 1% jpg
|
||||
_ZFlat3-8 740MB/s ± 3% jpg_200
|
||||
_ZFlat4-8 9.20GB/s ± 1% pdf
|
||||
_ZFlat5-8 991MB/s ± 0% html4
|
||||
_ZFlat6-8 379MB/s ± 0% txt1
|
||||
_ZFlat7-8 352MB/s ± 0% txt2
|
||||
_ZFlat8-8 396MB/s ± 1% txt3
|
||||
_ZFlat9-8 327MB/s ± 1% txt4
|
||||
_ZFlat10-8 1.33GB/s ± 1% pb
|
||||
_ZFlat11-8 605MB/s ± 1% gaviota
|
||||
|
||||
|
||||
|
||||
"go test -test.bench=. -tags=noasm"
|
||||
|
||||
_UFlat0-8 621MB/s ± 2% html
|
||||
_UFlat1-8 494MB/s ± 1% urls
|
||||
_UFlat2-8 23.2GB/s ± 1% jpg
|
||||
_UFlat3-8 1.12GB/s ± 1% jpg_200
|
||||
_UFlat4-8 4.35GB/s ± 1% pdf
|
||||
_UFlat5-8 609MB/s ± 0% html4
|
||||
_UFlat6-8 296MB/s ± 0% txt1
|
||||
_UFlat7-8 288MB/s ± 0% txt2
|
||||
_UFlat8-8 309MB/s ± 1% txt3
|
||||
_UFlat9-8 280MB/s ± 1% txt4
|
||||
_UFlat10-8 753MB/s ± 0% pb
|
||||
_UFlat11-8 400MB/s ± 0% gaviota
|
||||
|
||||
_ZFlat0-8 409MB/s ± 1% html
|
||||
_ZFlat1-8 250MB/s ± 1% urls
|
||||
_ZFlat2-8 12.3GB/s ± 1% jpg
|
||||
_ZFlat3-8 132MB/s ± 0% jpg_200
|
||||
_ZFlat4-8 2.92GB/s ± 0% pdf
|
||||
_ZFlat5-8 405MB/s ± 1% html4
|
||||
_ZFlat6-8 179MB/s ± 1% txt1
|
||||
_ZFlat7-8 170MB/s ± 1% txt2
|
||||
_ZFlat8-8 189MB/s ± 1% txt3
|
||||
_ZFlat9-8 164MB/s ± 1% txt4
|
||||
_ZFlat10-8 479MB/s ± 1% pb
|
||||
_ZFlat11-8 270MB/s ± 1% gaviota
|
||||
|
||||
|
||||
|
||||
For comparison (Go's encoded output is byte-for-byte identical to C++'s), here
|
||||
are the numbers from C++ Snappy's
|
||||
|
||||
make CXXFLAGS="-O2 -DNDEBUG -g" clean snappy_unittest.log && cat snappy_unittest.log
|
||||
|
||||
BM_UFlat/0 2.4GB/s html
|
||||
BM_UFlat/1 1.4GB/s urls
|
||||
BM_UFlat/2 21.8GB/s jpg
|
||||
BM_UFlat/3 1.5GB/s jpg_200
|
||||
BM_UFlat/4 13.3GB/s pdf
|
||||
BM_UFlat/5 2.1GB/s html4
|
||||
BM_UFlat/6 1.0GB/s txt1
|
||||
BM_UFlat/7 959.4MB/s txt2
|
||||
BM_UFlat/8 1.0GB/s txt3
|
||||
BM_UFlat/9 864.5MB/s txt4
|
||||
BM_UFlat/10 2.9GB/s pb
|
||||
BM_UFlat/11 1.2GB/s gaviota
|
||||
|
||||
BM_ZFlat/0 944.3MB/s html (22.31 %)
|
||||
BM_ZFlat/1 501.6MB/s urls (47.78 %)
|
||||
BM_ZFlat/2 14.3GB/s jpg (99.95 %)
|
||||
BM_ZFlat/3 538.3MB/s jpg_200 (73.00 %)
|
||||
BM_ZFlat/4 8.3GB/s pdf (83.30 %)
|
||||
BM_ZFlat/5 903.5MB/s html4 (22.52 %)
|
||||
BM_ZFlat/6 336.0MB/s txt1 (57.88 %)
|
||||
BM_ZFlat/7 312.3MB/s txt2 (61.91 %)
|
||||
BM_ZFlat/8 353.1MB/s txt3 (54.99 %)
|
||||
BM_ZFlat/9 289.9MB/s txt4 (66.26 %)
|
||||
BM_ZFlat/10 1.2GB/s pb (19.68 %)
|
||||
BM_ZFlat/11 527.4MB/s gaviota (37.72 %)
|
||||
237
vendor/github.com/golang/snappy/decode.go
generated
vendored
Normal file
237
vendor/github.com/golang/snappy/decode.go
generated
vendored
Normal file
@@ -0,0 +1,237 @@
|
||||
// Copyright 2011 The Snappy-Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package snappy
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"io"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrCorrupt reports that the input is invalid.
|
||||
ErrCorrupt = errors.New("snappy: corrupt input")
|
||||
// ErrTooLarge reports that the uncompressed length is too large.
|
||||
ErrTooLarge = errors.New("snappy: decoded block is too large")
|
||||
// ErrUnsupported reports that the input isn't supported.
|
||||
ErrUnsupported = errors.New("snappy: unsupported input")
|
||||
|
||||
errUnsupportedLiteralLength = errors.New("snappy: unsupported literal length")
|
||||
)
|
||||
|
||||
// DecodedLen returns the length of the decoded block.
|
||||
func DecodedLen(src []byte) (int, error) {
|
||||
v, _, err := decodedLen(src)
|
||||
return v, err
|
||||
}
|
||||
|
||||
// decodedLen returns the length of the decoded block and the number of bytes
|
||||
// that the length header occupied.
|
||||
func decodedLen(src []byte) (blockLen, headerLen int, err error) {
|
||||
v, n := binary.Uvarint(src)
|
||||
if n <= 0 || v > 0xffffffff {
|
||||
return 0, 0, ErrCorrupt
|
||||
}
|
||||
|
||||
const wordSize = 32 << (^uint(0) >> 32 & 1)
|
||||
if wordSize == 32 && v > 0x7fffffff {
|
||||
return 0, 0, ErrTooLarge
|
||||
}
|
||||
return int(v), n, nil
|
||||
}
|
||||
|
||||
const (
|
||||
decodeErrCodeCorrupt = 1
|
||||
decodeErrCodeUnsupportedLiteralLength = 2
|
||||
)
|
||||
|
||||
// Decode returns the decoded form of src. The returned slice may be a sub-
|
||||
// slice of dst if dst was large enough to hold the entire decoded block.
|
||||
// Otherwise, a newly allocated slice will be returned.
|
||||
//
|
||||
// The dst and src must not overlap. It is valid to pass a nil dst.
|
||||
func Decode(dst, src []byte) ([]byte, error) {
|
||||
dLen, s, err := decodedLen(src)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if dLen <= len(dst) {
|
||||
dst = dst[:dLen]
|
||||
} else {
|
||||
dst = make([]byte, dLen)
|
||||
}
|
||||
switch decode(dst, src[s:]) {
|
||||
case 0:
|
||||
return dst, nil
|
||||
case decodeErrCodeUnsupportedLiteralLength:
|
||||
return nil, errUnsupportedLiteralLength
|
||||
}
|
||||
return nil, ErrCorrupt
|
||||
}
|
||||
|
||||
// NewReader returns a new Reader that decompresses from r, using the framing
|
||||
// format described at
|
||||
// https://github.com/google/snappy/blob/master/framing_format.txt
|
||||
func NewReader(r io.Reader) *Reader {
|
||||
return &Reader{
|
||||
r: r,
|
||||
decoded: make([]byte, maxBlockSize),
|
||||
buf: make([]byte, maxEncodedLenOfMaxBlockSize+checksumSize),
|
||||
}
|
||||
}
|
||||
|
||||
// Reader is an io.Reader that can read Snappy-compressed bytes.
|
||||
type Reader struct {
|
||||
r io.Reader
|
||||
err error
|
||||
decoded []byte
|
||||
buf []byte
|
||||
// decoded[i:j] contains decoded bytes that have not yet been passed on.
|
||||
i, j int
|
||||
readHeader bool
|
||||
}
|
||||
|
||||
// Reset discards any buffered data, resets all state, and switches the Snappy
|
||||
// reader to read from r. This permits reusing a Reader rather than allocating
|
||||
// a new one.
|
||||
func (r *Reader) Reset(reader io.Reader) {
|
||||
r.r = reader
|
||||
r.err = nil
|
||||
r.i = 0
|
||||
r.j = 0
|
||||
r.readHeader = false
|
||||
}
|
||||
|
||||
func (r *Reader) readFull(p []byte, allowEOF bool) (ok bool) {
|
||||
if _, r.err = io.ReadFull(r.r, p); r.err != nil {
|
||||
if r.err == io.ErrUnexpectedEOF || (r.err == io.EOF && !allowEOF) {
|
||||
r.err = ErrCorrupt
|
||||
}
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Read satisfies the io.Reader interface.
|
||||
func (r *Reader) Read(p []byte) (int, error) {
|
||||
if r.err != nil {
|
||||
return 0, r.err
|
||||
}
|
||||
for {
|
||||
if r.i < r.j {
|
||||
n := copy(p, r.decoded[r.i:r.j])
|
||||
r.i += n
|
||||
return n, nil
|
||||
}
|
||||
if !r.readFull(r.buf[:4], true) {
|
||||
return 0, r.err
|
||||
}
|
||||
chunkType := r.buf[0]
|
||||
if !r.readHeader {
|
||||
if chunkType != chunkTypeStreamIdentifier {
|
||||
r.err = ErrCorrupt
|
||||
return 0, r.err
|
||||
}
|
||||
r.readHeader = true
|
||||
}
|
||||
chunkLen := int(r.buf[1]) | int(r.buf[2])<<8 | int(r.buf[3])<<16
|
||||
if chunkLen > len(r.buf) {
|
||||
r.err = ErrUnsupported
|
||||
return 0, r.err
|
||||
}
|
||||
|
||||
// The chunk types are specified at
|
||||
// https://github.com/google/snappy/blob/master/framing_format.txt
|
||||
switch chunkType {
|
||||
case chunkTypeCompressedData:
|
||||
// Section 4.2. Compressed data (chunk type 0x00).
|
||||
if chunkLen < checksumSize {
|
||||
r.err = ErrCorrupt
|
||||
return 0, r.err
|
||||
}
|
||||
buf := r.buf[:chunkLen]
|
||||
if !r.readFull(buf, false) {
|
||||
return 0, r.err
|
||||
}
|
||||
checksum := uint32(buf[0]) | uint32(buf[1])<<8 | uint32(buf[2])<<16 | uint32(buf[3])<<24
|
||||
buf = buf[checksumSize:]
|
||||
|
||||
n, err := DecodedLen(buf)
|
||||
if err != nil {
|
||||
r.err = err
|
||||
return 0, r.err
|
||||
}
|
||||
if n > len(r.decoded) {
|
||||
r.err = ErrCorrupt
|
||||
return 0, r.err
|
||||
}
|
||||
if _, err := Decode(r.decoded, buf); err != nil {
|
||||
r.err = err
|
||||
return 0, r.err
|
||||
}
|
||||
if crc(r.decoded[:n]) != checksum {
|
||||
r.err = ErrCorrupt
|
||||
return 0, r.err
|
||||
}
|
||||
r.i, r.j = 0, n
|
||||
continue
|
||||
|
||||
case chunkTypeUncompressedData:
|
||||
// Section 4.3. Uncompressed data (chunk type 0x01).
|
||||
if chunkLen < checksumSize {
|
||||
r.err = ErrCorrupt
|
||||
return 0, r.err
|
||||
}
|
||||
buf := r.buf[:checksumSize]
|
||||
if !r.readFull(buf, false) {
|
||||
return 0, r.err
|
||||
}
|
||||
checksum := uint32(buf[0]) | uint32(buf[1])<<8 | uint32(buf[2])<<16 | uint32(buf[3])<<24
|
||||
// Read directly into r.decoded instead of via r.buf.
|
||||
n := chunkLen - checksumSize
|
||||
if n > len(r.decoded) {
|
||||
r.err = ErrCorrupt
|
||||
return 0, r.err
|
||||
}
|
||||
if !r.readFull(r.decoded[:n], false) {
|
||||
return 0, r.err
|
||||
}
|
||||
if crc(r.decoded[:n]) != checksum {
|
||||
r.err = ErrCorrupt
|
||||
return 0, r.err
|
||||
}
|
||||
r.i, r.j = 0, n
|
||||
continue
|
||||
|
||||
case chunkTypeStreamIdentifier:
|
||||
// Section 4.1. Stream identifier (chunk type 0xff).
|
||||
if chunkLen != len(magicBody) {
|
||||
r.err = ErrCorrupt
|
||||
return 0, r.err
|
||||
}
|
||||
if !r.readFull(r.buf[:len(magicBody)], false) {
|
||||
return 0, r.err
|
||||
}
|
||||
for i := 0; i < len(magicBody); i++ {
|
||||
if r.buf[i] != magicBody[i] {
|
||||
r.err = ErrCorrupt
|
||||
return 0, r.err
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if chunkType <= 0x7f {
|
||||
// Section 4.5. Reserved unskippable chunks (chunk types 0x02-0x7f).
|
||||
r.err = ErrUnsupported
|
||||
return 0, r.err
|
||||
}
|
||||
// Section 4.4 Padding (chunk type 0xfe).
|
||||
// Section 4.6. Reserved skippable chunks (chunk types 0x80-0xfd).
|
||||
if !r.readFull(r.buf[:chunkLen], false) {
|
||||
return 0, r.err
|
||||
}
|
||||
}
|
||||
}
|
||||
14
vendor/github.com/golang/snappy/decode_amd64.go
generated
vendored
Normal file
14
vendor/github.com/golang/snappy/decode_amd64.go
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
// Copyright 2016 The Snappy-Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !appengine
|
||||
// +build gc
|
||||
// +build !noasm
|
||||
|
||||
package snappy
|
||||
|
||||
// decode has the same semantics as in decode_other.go.
|
||||
//
|
||||
//go:noescape
|
||||
func decode(dst, src []byte) int
|
||||
490
vendor/github.com/golang/snappy/decode_amd64.s
generated
vendored
Normal file
490
vendor/github.com/golang/snappy/decode_amd64.s
generated
vendored
Normal file
@@ -0,0 +1,490 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !appengine
|
||||
// +build gc
|
||||
// +build !noasm
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// The asm code generally follows the pure Go code in decode_other.go, except
|
||||
// where marked with a "!!!".
|
||||
|
||||
// func decode(dst, src []byte) int
|
||||
//
|
||||
// All local variables fit into registers. The non-zero stack size is only to
|
||||
// spill registers and push args when issuing a CALL. The register allocation:
|
||||
// - AX scratch
|
||||
// - BX scratch
|
||||
// - CX length or x
|
||||
// - DX offset
|
||||
// - SI &src[s]
|
||||
// - DI &dst[d]
|
||||
// + R8 dst_base
|
||||
// + R9 dst_len
|
||||
// + R10 dst_base + dst_len
|
||||
// + R11 src_base
|
||||
// + R12 src_len
|
||||
// + R13 src_base + src_len
|
||||
// - R14 used by doCopy
|
||||
// - R15 used by doCopy
|
||||
//
|
||||
// The registers R8-R13 (marked with a "+") are set at the start of the
|
||||
// function, and after a CALL returns, and are not otherwise modified.
|
||||
//
|
||||
// The d variable is implicitly DI - R8, and len(dst)-d is R10 - DI.
|
||||
// The s variable is implicitly SI - R11, and len(src)-s is R13 - SI.
|
||||
TEXT ·decode(SB), NOSPLIT, $48-56
|
||||
// Initialize SI, DI and R8-R13.
|
||||
MOVQ dst_base+0(FP), R8
|
||||
MOVQ dst_len+8(FP), R9
|
||||
MOVQ R8, DI
|
||||
MOVQ R8, R10
|
||||
ADDQ R9, R10
|
||||
MOVQ src_base+24(FP), R11
|
||||
MOVQ src_len+32(FP), R12
|
||||
MOVQ R11, SI
|
||||
MOVQ R11, R13
|
||||
ADDQ R12, R13
|
||||
|
||||
loop:
|
||||
// for s < len(src)
|
||||
CMPQ SI, R13
|
||||
JEQ end
|
||||
|
||||
// CX = uint32(src[s])
|
||||
//
|
||||
// switch src[s] & 0x03
|
||||
MOVBLZX (SI), CX
|
||||
MOVL CX, BX
|
||||
ANDL $3, BX
|
||||
CMPL BX, $1
|
||||
JAE tagCopy
|
||||
|
||||
// ----------------------------------------
|
||||
// The code below handles literal tags.
|
||||
|
||||
// case tagLiteral:
|
||||
// x := uint32(src[s] >> 2)
|
||||
// switch
|
||||
SHRL $2, CX
|
||||
CMPL CX, $60
|
||||
JAE tagLit60Plus
|
||||
|
||||
// case x < 60:
|
||||
// s++
|
||||
INCQ SI
|
||||
|
||||
doLit:
|
||||
// This is the end of the inner "switch", when we have a literal tag.
|
||||
//
|
||||
// We assume that CX == x and x fits in a uint32, where x is the variable
|
||||
// used in the pure Go decode_other.go code.
|
||||
|
||||
// length = int(x) + 1
|
||||
//
|
||||
// Unlike the pure Go code, we don't need to check if length <= 0 because
|
||||
// CX can hold 64 bits, so the increment cannot overflow.
|
||||
INCQ CX
|
||||
|
||||
// Prepare to check if copying length bytes will run past the end of dst or
|
||||
// src.
|
||||
//
|
||||
// AX = len(dst) - d
|
||||
// BX = len(src) - s
|
||||
MOVQ R10, AX
|
||||
SUBQ DI, AX
|
||||
MOVQ R13, BX
|
||||
SUBQ SI, BX
|
||||
|
||||
// !!! Try a faster technique for short (16 or fewer bytes) copies.
|
||||
//
|
||||
// if length > 16 || len(dst)-d < 16 || len(src)-s < 16 {
|
||||
// goto callMemmove // Fall back on calling runtime·memmove.
|
||||
// }
|
||||
//
|
||||
// The C++ snappy code calls this TryFastAppend. It also checks len(src)-s
|
||||
// against 21 instead of 16, because it cannot assume that all of its input
|
||||
// is contiguous in memory and so it needs to leave enough source bytes to
|
||||
// read the next tag without refilling buffers, but Go's Decode assumes
|
||||
// contiguousness (the src argument is a []byte).
|
||||
CMPQ CX, $16
|
||||
JGT callMemmove
|
||||
CMPQ AX, $16
|
||||
JLT callMemmove
|
||||
CMPQ BX, $16
|
||||
JLT callMemmove
|
||||
|
||||
// !!! Implement the copy from src to dst as a 16-byte load and store.
|
||||
// (Decode's documentation says that dst and src must not overlap.)
|
||||
//
|
||||
// This always copies 16 bytes, instead of only length bytes, but that's
|
||||
// OK. If the input is a valid Snappy encoding then subsequent iterations
|
||||
// will fix up the overrun. Otherwise, Decode returns a nil []byte (and a
|
||||
// non-nil error), so the overrun will be ignored.
|
||||
//
|
||||
// Note that on amd64, it is legal and cheap to issue unaligned 8-byte or
|
||||
// 16-byte loads and stores. This technique probably wouldn't be as
|
||||
// effective on architectures that are fussier about alignment.
|
||||
MOVOU 0(SI), X0
|
||||
MOVOU X0, 0(DI)
|
||||
|
||||
// d += length
|
||||
// s += length
|
||||
ADDQ CX, DI
|
||||
ADDQ CX, SI
|
||||
JMP loop
|
||||
|
||||
callMemmove:
|
||||
// if length > len(dst)-d || length > len(src)-s { etc }
|
||||
CMPQ CX, AX
|
||||
JGT errCorrupt
|
||||
CMPQ CX, BX
|
||||
JGT errCorrupt
|
||||
|
||||
// copy(dst[d:], src[s:s+length])
|
||||
//
|
||||
// This means calling runtime·memmove(&dst[d], &src[s], length), so we push
|
||||
// DI, SI and CX as arguments. Coincidentally, we also need to spill those
|
||||
// three registers to the stack, to save local variables across the CALL.
|
||||
MOVQ DI, 0(SP)
|
||||
MOVQ SI, 8(SP)
|
||||
MOVQ CX, 16(SP)
|
||||
MOVQ DI, 24(SP)
|
||||
MOVQ SI, 32(SP)
|
||||
MOVQ CX, 40(SP)
|
||||
CALL runtime·memmove(SB)
|
||||
|
||||
// Restore local variables: unspill registers from the stack and
|
||||
// re-calculate R8-R13.
|
||||
MOVQ 24(SP), DI
|
||||
MOVQ 32(SP), SI
|
||||
MOVQ 40(SP), CX
|
||||
MOVQ dst_base+0(FP), R8
|
||||
MOVQ dst_len+8(FP), R9
|
||||
MOVQ R8, R10
|
||||
ADDQ R9, R10
|
||||
MOVQ src_base+24(FP), R11
|
||||
MOVQ src_len+32(FP), R12
|
||||
MOVQ R11, R13
|
||||
ADDQ R12, R13
|
||||
|
||||
// d += length
|
||||
// s += length
|
||||
ADDQ CX, DI
|
||||
ADDQ CX, SI
|
||||
JMP loop
|
||||
|
||||
tagLit60Plus:
|
||||
// !!! This fragment does the
|
||||
//
|
||||
// s += x - 58; if uint(s) > uint(len(src)) { etc }
|
||||
//
|
||||
// checks. In the asm version, we code it once instead of once per switch case.
|
||||
ADDQ CX, SI
|
||||
SUBQ $58, SI
|
||||
MOVQ SI, BX
|
||||
SUBQ R11, BX
|
||||
CMPQ BX, R12
|
||||
JA errCorrupt
|
||||
|
||||
// case x == 60:
|
||||
CMPL CX, $61
|
||||
JEQ tagLit61
|
||||
JA tagLit62Plus
|
||||
|
||||
// x = uint32(src[s-1])
|
||||
MOVBLZX -1(SI), CX
|
||||
JMP doLit
|
||||
|
||||
tagLit61:
|
||||
// case x == 61:
|
||||
// x = uint32(src[s-2]) | uint32(src[s-1])<<8
|
||||
MOVWLZX -2(SI), CX
|
||||
JMP doLit
|
||||
|
||||
tagLit62Plus:
|
||||
CMPL CX, $62
|
||||
JA tagLit63
|
||||
|
||||
// case x == 62:
|
||||
// x = uint32(src[s-3]) | uint32(src[s-2])<<8 | uint32(src[s-1])<<16
|
||||
MOVWLZX -3(SI), CX
|
||||
MOVBLZX -1(SI), BX
|
||||
SHLL $16, BX
|
||||
ORL BX, CX
|
||||
JMP doLit
|
||||
|
||||
tagLit63:
|
||||
// case x == 63:
|
||||
// x = uint32(src[s-4]) | uint32(src[s-3])<<8 | uint32(src[s-2])<<16 | uint32(src[s-1])<<24
|
||||
MOVL -4(SI), CX
|
||||
JMP doLit
|
||||
|
||||
// The code above handles literal tags.
|
||||
// ----------------------------------------
|
||||
// The code below handles copy tags.
|
||||
|
||||
tagCopy4:
|
||||
// case tagCopy4:
|
||||
// s += 5
|
||||
ADDQ $5, SI
|
||||
|
||||
// if uint(s) > uint(len(src)) { etc }
|
||||
MOVQ SI, BX
|
||||
SUBQ R11, BX
|
||||
CMPQ BX, R12
|
||||
JA errCorrupt
|
||||
|
||||
// length = 1 + int(src[s-5])>>2
|
||||
SHRQ $2, CX
|
||||
INCQ CX
|
||||
|
||||
// offset = int(uint32(src[s-4]) | uint32(src[s-3])<<8 | uint32(src[s-2])<<16 | uint32(src[s-1])<<24)
|
||||
MOVLQZX -4(SI), DX
|
||||
JMP doCopy
|
||||
|
||||
tagCopy2:
|
||||
// case tagCopy2:
|
||||
// s += 3
|
||||
ADDQ $3, SI
|
||||
|
||||
// if uint(s) > uint(len(src)) { etc }
|
||||
MOVQ SI, BX
|
||||
SUBQ R11, BX
|
||||
CMPQ BX, R12
|
||||
JA errCorrupt
|
||||
|
||||
// length = 1 + int(src[s-3])>>2
|
||||
SHRQ $2, CX
|
||||
INCQ CX
|
||||
|
||||
// offset = int(uint32(src[s-2]) | uint32(src[s-1])<<8)
|
||||
MOVWQZX -2(SI), DX
|
||||
JMP doCopy
|
||||
|
||||
tagCopy:
|
||||
// We have a copy tag. We assume that:
|
||||
// - BX == src[s] & 0x03
|
||||
// - CX == src[s]
|
||||
CMPQ BX, $2
|
||||
JEQ tagCopy2
|
||||
JA tagCopy4
|
||||
|
||||
// case tagCopy1:
|
||||
// s += 2
|
||||
ADDQ $2, SI
|
||||
|
||||
// if uint(s) > uint(len(src)) { etc }
|
||||
MOVQ SI, BX
|
||||
SUBQ R11, BX
|
||||
CMPQ BX, R12
|
||||
JA errCorrupt
|
||||
|
||||
// offset = int(uint32(src[s-2])&0xe0<<3 | uint32(src[s-1]))
|
||||
MOVQ CX, DX
|
||||
ANDQ $0xe0, DX
|
||||
SHLQ $3, DX
|
||||
MOVBQZX -1(SI), BX
|
||||
ORQ BX, DX
|
||||
|
||||
// length = 4 + int(src[s-2])>>2&0x7
|
||||
SHRQ $2, CX
|
||||
ANDQ $7, CX
|
||||
ADDQ $4, CX
|
||||
|
||||
doCopy:
|
||||
// This is the end of the outer "switch", when we have a copy tag.
|
||||
//
|
||||
// We assume that:
|
||||
// - CX == length && CX > 0
|
||||
// - DX == offset
|
||||
|
||||
// if offset <= 0 { etc }
|
||||
CMPQ DX, $0
|
||||
JLE errCorrupt
|
||||
|
||||
// if d < offset { etc }
|
||||
MOVQ DI, BX
|
||||
SUBQ R8, BX
|
||||
CMPQ BX, DX
|
||||
JLT errCorrupt
|
||||
|
||||
// if length > len(dst)-d { etc }
|
||||
MOVQ R10, BX
|
||||
SUBQ DI, BX
|
||||
CMPQ CX, BX
|
||||
JGT errCorrupt
|
||||
|
||||
// forwardCopy(dst[d:d+length], dst[d-offset:]); d += length
|
||||
//
|
||||
// Set:
|
||||
// - R14 = len(dst)-d
|
||||
// - R15 = &dst[d-offset]
|
||||
MOVQ R10, R14
|
||||
SUBQ DI, R14
|
||||
MOVQ DI, R15
|
||||
SUBQ DX, R15
|
||||
|
||||
// !!! Try a faster technique for short (16 or fewer bytes) forward copies.
|
||||
//
|
||||
// First, try using two 8-byte load/stores, similar to the doLit technique
|
||||
// above. Even if dst[d:d+length] and dst[d-offset:] can overlap, this is
|
||||
// still OK if offset >= 8. Note that this has to be two 8-byte load/stores
|
||||
// and not one 16-byte load/store, and the first store has to be before the
|
||||
// second load, due to the overlap if offset is in the range [8, 16).
|
||||
//
|
||||
// if length > 16 || offset < 8 || len(dst)-d < 16 {
|
||||
// goto slowForwardCopy
|
||||
// }
|
||||
// copy 16 bytes
|
||||
// d += length
|
||||
CMPQ CX, $16
|
||||
JGT slowForwardCopy
|
||||
CMPQ DX, $8
|
||||
JLT slowForwardCopy
|
||||
CMPQ R14, $16
|
||||
JLT slowForwardCopy
|
||||
MOVQ 0(R15), AX
|
||||
MOVQ AX, 0(DI)
|
||||
MOVQ 8(R15), BX
|
||||
MOVQ BX, 8(DI)
|
||||
ADDQ CX, DI
|
||||
JMP loop
|
||||
|
||||
slowForwardCopy:
|
||||
// !!! If the forward copy is longer than 16 bytes, or if offset < 8, we
|
||||
// can still try 8-byte load stores, provided we can overrun up to 10 extra
|
||||
// bytes. As above, the overrun will be fixed up by subsequent iterations
|
||||
// of the outermost loop.
|
||||
//
|
||||
// The C++ snappy code calls this technique IncrementalCopyFastPath. Its
|
||||
// commentary says:
|
||||
//
|
||||
// ----
|
||||
//
|
||||
// The main part of this loop is a simple copy of eight bytes at a time
|
||||
// until we've copied (at least) the requested amount of bytes. However,
|
||||
// if d and d-offset are less than eight bytes apart (indicating a
|
||||
// repeating pattern of length < 8), we first need to expand the pattern in
|
||||
// order to get the correct results. For instance, if the buffer looks like
|
||||
// this, with the eight-byte <d-offset> and <d> patterns marked as
|
||||
// intervals:
|
||||
//
|
||||
// abxxxxxxxxxxxx
|
||||
// [------] d-offset
|
||||
// [------] d
|
||||
//
|
||||
// a single eight-byte copy from <d-offset> to <d> will repeat the pattern
|
||||
// once, after which we can move <d> two bytes without moving <d-offset>:
|
||||
//
|
||||
// ababxxxxxxxxxx
|
||||
// [------] d-offset
|
||||
// [------] d
|
||||
//
|
||||
// and repeat the exercise until the two no longer overlap.
|
||||
//
|
||||
// This allows us to do very well in the special case of one single byte
|
||||
// repeated many times, without taking a big hit for more general cases.
|
||||
//
|
||||
// The worst case of extra writing past the end of the match occurs when
|
||||
// offset == 1 and length == 1; the last copy will read from byte positions
|
||||
// [0..7] and write to [4..11], whereas it was only supposed to write to
|
||||
// position 1. Thus, ten excess bytes.
|
||||
//
|
||||
// ----
|
||||
//
|
||||
// That "10 byte overrun" worst case is confirmed by Go's
|
||||
// TestSlowForwardCopyOverrun, which also tests the fixUpSlowForwardCopy
|
||||
// and finishSlowForwardCopy algorithm.
|
||||
//
|
||||
// if length > len(dst)-d-10 {
|
||||
// goto verySlowForwardCopy
|
||||
// }
|
||||
SUBQ $10, R14
|
||||
CMPQ CX, R14
|
||||
JGT verySlowForwardCopy
|
||||
|
||||
makeOffsetAtLeast8:
|
||||
// !!! As above, expand the pattern so that offset >= 8 and we can use
|
||||
// 8-byte load/stores.
|
||||
//
|
||||
// for offset < 8 {
|
||||
// copy 8 bytes from dst[d-offset:] to dst[d:]
|
||||
// length -= offset
|
||||
// d += offset
|
||||
// offset += offset
|
||||
// // The two previous lines together means that d-offset, and therefore
|
||||
// // R15, is unchanged.
|
||||
// }
|
||||
CMPQ DX, $8
|
||||
JGE fixUpSlowForwardCopy
|
||||
MOVQ (R15), BX
|
||||
MOVQ BX, (DI)
|
||||
SUBQ DX, CX
|
||||
ADDQ DX, DI
|
||||
ADDQ DX, DX
|
||||
JMP makeOffsetAtLeast8
|
||||
|
||||
fixUpSlowForwardCopy:
|
||||
// !!! Add length (which might be negative now) to d (implied by DI being
|
||||
// &dst[d]) so that d ends up at the right place when we jump back to the
|
||||
// top of the loop. Before we do that, though, we save DI to AX so that, if
|
||||
// length is positive, copying the remaining length bytes will write to the
|
||||
// right place.
|
||||
MOVQ DI, AX
|
||||
ADDQ CX, DI
|
||||
|
||||
finishSlowForwardCopy:
|
||||
// !!! Repeat 8-byte load/stores until length <= 0. Ending with a negative
|
||||
// length means that we overrun, but as above, that will be fixed up by
|
||||
// subsequent iterations of the outermost loop.
|
||||
CMPQ CX, $0
|
||||
JLE loop
|
||||
MOVQ (R15), BX
|
||||
MOVQ BX, (AX)
|
||||
ADDQ $8, R15
|
||||
ADDQ $8, AX
|
||||
SUBQ $8, CX
|
||||
JMP finishSlowForwardCopy
|
||||
|
||||
verySlowForwardCopy:
|
||||
// verySlowForwardCopy is a simple implementation of forward copy. In C
|
||||
// parlance, this is a do/while loop instead of a while loop, since we know
|
||||
// that length > 0. In Go syntax:
|
||||
//
|
||||
// for {
|
||||
// dst[d] = dst[d - offset]
|
||||
// d++
|
||||
// length--
|
||||
// if length == 0 {
|
||||
// break
|
||||
// }
|
||||
// }
|
||||
MOVB (R15), BX
|
||||
MOVB BX, (DI)
|
||||
INCQ R15
|
||||
INCQ DI
|
||||
DECQ CX
|
||||
JNZ verySlowForwardCopy
|
||||
JMP loop
|
||||
|
||||
// The code above handles copy tags.
|
||||
// ----------------------------------------
|
||||
|
||||
end:
|
||||
// This is the end of the "for s < len(src)".
|
||||
//
|
||||
// if d != len(dst) { etc }
|
||||
CMPQ DI, R10
|
||||
JNE errCorrupt
|
||||
|
||||
// return 0
|
||||
MOVQ $0, ret+48(FP)
|
||||
RET
|
||||
|
||||
errCorrupt:
|
||||
// return decodeErrCodeCorrupt
|
||||
MOVQ $1, ret+48(FP)
|
||||
RET
|
||||
101
vendor/github.com/golang/snappy/decode_other.go
generated
vendored
Normal file
101
vendor/github.com/golang/snappy/decode_other.go
generated
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
// Copyright 2016 The Snappy-Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !amd64 appengine !gc noasm
|
||||
|
||||
package snappy
|
||||
|
||||
// decode writes the decoding of src to dst. It assumes that the varint-encoded
|
||||
// length of the decompressed bytes has already been read, and that len(dst)
|
||||
// equals that length.
|
||||
//
|
||||
// It returns 0 on success or a decodeErrCodeXxx error code on failure.
|
||||
func decode(dst, src []byte) int {
|
||||
var d, s, offset, length int
|
||||
for s < len(src) {
|
||||
switch src[s] & 0x03 {
|
||||
case tagLiteral:
|
||||
x := uint32(src[s] >> 2)
|
||||
switch {
|
||||
case x < 60:
|
||||
s++
|
||||
case x == 60:
|
||||
s += 2
|
||||
if uint(s) > uint(len(src)) { // The uint conversions catch overflow from the previous line.
|
||||
return decodeErrCodeCorrupt
|
||||
}
|
||||
x = uint32(src[s-1])
|
||||
case x == 61:
|
||||
s += 3
|
||||
if uint(s) > uint(len(src)) { // The uint conversions catch overflow from the previous line.
|
||||
return decodeErrCodeCorrupt
|
||||
}
|
||||
x = uint32(src[s-2]) | uint32(src[s-1])<<8
|
||||
case x == 62:
|
||||
s += 4
|
||||
if uint(s) > uint(len(src)) { // The uint conversions catch overflow from the previous line.
|
||||
return decodeErrCodeCorrupt
|
||||
}
|
||||
x = uint32(src[s-3]) | uint32(src[s-2])<<8 | uint32(src[s-1])<<16
|
||||
case x == 63:
|
||||
s += 5
|
||||
if uint(s) > uint(len(src)) { // The uint conversions catch overflow from the previous line.
|
||||
return decodeErrCodeCorrupt
|
||||
}
|
||||
x = uint32(src[s-4]) | uint32(src[s-3])<<8 | uint32(src[s-2])<<16 | uint32(src[s-1])<<24
|
||||
}
|
||||
length = int(x) + 1
|
||||
if length <= 0 {
|
||||
return decodeErrCodeUnsupportedLiteralLength
|
||||
}
|
||||
if length > len(dst)-d || length > len(src)-s {
|
||||
return decodeErrCodeCorrupt
|
||||
}
|
||||
copy(dst[d:], src[s:s+length])
|
||||
d += length
|
||||
s += length
|
||||
continue
|
||||
|
||||
case tagCopy1:
|
||||
s += 2
|
||||
if uint(s) > uint(len(src)) { // The uint conversions catch overflow from the previous line.
|
||||
return decodeErrCodeCorrupt
|
||||
}
|
||||
length = 4 + int(src[s-2])>>2&0x7
|
||||
offset = int(uint32(src[s-2])&0xe0<<3 | uint32(src[s-1]))
|
||||
|
||||
case tagCopy2:
|
||||
s += 3
|
||||
if uint(s) > uint(len(src)) { // The uint conversions catch overflow from the previous line.
|
||||
return decodeErrCodeCorrupt
|
||||
}
|
||||
length = 1 + int(src[s-3])>>2
|
||||
offset = int(uint32(src[s-2]) | uint32(src[s-1])<<8)
|
||||
|
||||
case tagCopy4:
|
||||
s += 5
|
||||
if uint(s) > uint(len(src)) { // The uint conversions catch overflow from the previous line.
|
||||
return decodeErrCodeCorrupt
|
||||
}
|
||||
length = 1 + int(src[s-5])>>2
|
||||
offset = int(uint32(src[s-4]) | uint32(src[s-3])<<8 | uint32(src[s-2])<<16 | uint32(src[s-1])<<24)
|
||||
}
|
||||
|
||||
if offset <= 0 || d < offset || length > len(dst)-d {
|
||||
return decodeErrCodeCorrupt
|
||||
}
|
||||
// Copy from an earlier sub-slice of dst to a later sub-slice. Unlike
|
||||
// the built-in copy function, this byte-by-byte copy always runs
|
||||
// forwards, even if the slices overlap. Conceptually, this is:
|
||||
//
|
||||
// d += forwardCopy(dst[d:d+length], dst[d-offset:])
|
||||
for end := d + length; d != end; d++ {
|
||||
dst[d] = dst[d-offset]
|
||||
}
|
||||
}
|
||||
if d != len(dst) {
|
||||
return decodeErrCodeCorrupt
|
||||
}
|
||||
return 0
|
||||
}
|
||||
285
vendor/github.com/golang/snappy/encode.go
generated
vendored
Normal file
285
vendor/github.com/golang/snappy/encode.go
generated
vendored
Normal file
@@ -0,0 +1,285 @@
|
||||
// Copyright 2011 The Snappy-Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package snappy
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"io"
|
||||
)
|
||||
|
||||
// Encode returns the encoded form of src. The returned slice may be a sub-
|
||||
// slice of dst if dst was large enough to hold the entire encoded block.
|
||||
// Otherwise, a newly allocated slice will be returned.
|
||||
//
|
||||
// The dst and src must not overlap. It is valid to pass a nil dst.
|
||||
func Encode(dst, src []byte) []byte {
|
||||
if n := MaxEncodedLen(len(src)); n < 0 {
|
||||
panic(ErrTooLarge)
|
||||
} else if len(dst) < n {
|
||||
dst = make([]byte, n)
|
||||
}
|
||||
|
||||
// The block starts with the varint-encoded length of the decompressed bytes.
|
||||
d := binary.PutUvarint(dst, uint64(len(src)))
|
||||
|
||||
for len(src) > 0 {
|
||||
p := src
|
||||
src = nil
|
||||
if len(p) > maxBlockSize {
|
||||
p, src = p[:maxBlockSize], p[maxBlockSize:]
|
||||
}
|
||||
if len(p) < minNonLiteralBlockSize {
|
||||
d += emitLiteral(dst[d:], p)
|
||||
} else {
|
||||
d += encodeBlock(dst[d:], p)
|
||||
}
|
||||
}
|
||||
return dst[:d]
|
||||
}
|
||||
|
||||
// inputMargin is the minimum number of extra input bytes to keep, inside
|
||||
// encodeBlock's inner loop. On some architectures, this margin lets us
|
||||
// implement a fast path for emitLiteral, where the copy of short (<= 16 byte)
|
||||
// literals can be implemented as a single load to and store from a 16-byte
|
||||
// register. That literal's actual length can be as short as 1 byte, so this
|
||||
// can copy up to 15 bytes too much, but that's OK as subsequent iterations of
|
||||
// the encoding loop will fix up the copy overrun, and this inputMargin ensures
|
||||
// that we don't overrun the dst and src buffers.
|
||||
const inputMargin = 16 - 1
|
||||
|
||||
// minNonLiteralBlockSize is the minimum size of the input to encodeBlock that
|
||||
// could be encoded with a copy tag. This is the minimum with respect to the
|
||||
// algorithm used by encodeBlock, not a minimum enforced by the file format.
|
||||
//
|
||||
// The encoded output must start with at least a 1 byte literal, as there are
|
||||
// no previous bytes to copy. A minimal (1 byte) copy after that, generated
|
||||
// from an emitCopy call in encodeBlock's main loop, would require at least
|
||||
// another inputMargin bytes, for the reason above: we want any emitLiteral
|
||||
// calls inside encodeBlock's main loop to use the fast path if possible, which
|
||||
// requires being able to overrun by inputMargin bytes. Thus,
|
||||
// minNonLiteralBlockSize equals 1 + 1 + inputMargin.
|
||||
//
|
||||
// The C++ code doesn't use this exact threshold, but it could, as discussed at
|
||||
// https://groups.google.com/d/topic/snappy-compression/oGbhsdIJSJ8/discussion
|
||||
// The difference between Go (2+inputMargin) and C++ (inputMargin) is purely an
|
||||
// optimization. It should not affect the encoded form. This is tested by
|
||||
// TestSameEncodingAsCppShortCopies.
|
||||
const minNonLiteralBlockSize = 1 + 1 + inputMargin
|
||||
|
||||
// MaxEncodedLen returns the maximum length of a snappy block, given its
|
||||
// uncompressed length.
|
||||
//
|
||||
// It will return a negative value if srcLen is too large to encode.
|
||||
func MaxEncodedLen(srcLen int) int {
|
||||
n := uint64(srcLen)
|
||||
if n > 0xffffffff {
|
||||
return -1
|
||||
}
|
||||
// Compressed data can be defined as:
|
||||
// compressed := item* literal*
|
||||
// item := literal* copy
|
||||
//
|
||||
// The trailing literal sequence has a space blowup of at most 62/60
|
||||
// since a literal of length 60 needs one tag byte + one extra byte
|
||||
// for length information.
|
||||
//
|
||||
// Item blowup is trickier to measure. Suppose the "copy" op copies
|
||||
// 4 bytes of data. Because of a special check in the encoding code,
|
||||
// we produce a 4-byte copy only if the offset is < 65536. Therefore
|
||||
// the copy op takes 3 bytes to encode, and this type of item leads
|
||||
// to at most the 62/60 blowup for representing literals.
|
||||
//
|
||||
// Suppose the "copy" op copies 5 bytes of data. If the offset is big
|
||||
// enough, it will take 5 bytes to encode the copy op. Therefore the
|
||||
// worst case here is a one-byte literal followed by a five-byte copy.
|
||||
// That is, 6 bytes of input turn into 7 bytes of "compressed" data.
|
||||
//
|
||||
// This last factor dominates the blowup, so the final estimate is:
|
||||
n = 32 + n + n/6
|
||||
if n > 0xffffffff {
|
||||
return -1
|
||||
}
|
||||
return int(n)
|
||||
}
|
||||
|
||||
var errClosed = errors.New("snappy: Writer is closed")
|
||||
|
||||
// NewWriter returns a new Writer that compresses to w.
|
||||
//
|
||||
// The Writer returned does not buffer writes. There is no need to Flush or
|
||||
// Close such a Writer.
|
||||
//
|
||||
// Deprecated: the Writer returned is not suitable for many small writes, only
|
||||
// for few large writes. Use NewBufferedWriter instead, which is efficient
|
||||
// regardless of the frequency and shape of the writes, and remember to Close
|
||||
// that Writer when done.
|
||||
func NewWriter(w io.Writer) *Writer {
|
||||
return &Writer{
|
||||
w: w,
|
||||
obuf: make([]byte, obufLen),
|
||||
}
|
||||
}
|
||||
|
||||
// NewBufferedWriter returns a new Writer that compresses to w, using the
|
||||
// framing format described at
|
||||
// https://github.com/google/snappy/blob/master/framing_format.txt
|
||||
//
|
||||
// The Writer returned buffers writes. Users must call Close to guarantee all
|
||||
// data has been forwarded to the underlying io.Writer. They may also call
|
||||
// Flush zero or more times before calling Close.
|
||||
func NewBufferedWriter(w io.Writer) *Writer {
|
||||
return &Writer{
|
||||
w: w,
|
||||
ibuf: make([]byte, 0, maxBlockSize),
|
||||
obuf: make([]byte, obufLen),
|
||||
}
|
||||
}
|
||||
|
||||
// Writer is an io.Writer that can write Snappy-compressed bytes.
|
||||
type Writer struct {
|
||||
w io.Writer
|
||||
err error
|
||||
|
||||
// ibuf is a buffer for the incoming (uncompressed) bytes.
|
||||
//
|
||||
// Its use is optional. For backwards compatibility, Writers created by the
|
||||
// NewWriter function have ibuf == nil, do not buffer incoming bytes, and
|
||||
// therefore do not need to be Flush'ed or Close'd.
|
||||
ibuf []byte
|
||||
|
||||
// obuf is a buffer for the outgoing (compressed) bytes.
|
||||
obuf []byte
|
||||
|
||||
// wroteStreamHeader is whether we have written the stream header.
|
||||
wroteStreamHeader bool
|
||||
}
|
||||
|
||||
// Reset discards the writer's state and switches the Snappy writer to write to
|
||||
// w. This permits reusing a Writer rather than allocating a new one.
|
||||
func (w *Writer) Reset(writer io.Writer) {
|
||||
w.w = writer
|
||||
w.err = nil
|
||||
if w.ibuf != nil {
|
||||
w.ibuf = w.ibuf[:0]
|
||||
}
|
||||
w.wroteStreamHeader = false
|
||||
}
|
||||
|
||||
// Write satisfies the io.Writer interface.
|
||||
func (w *Writer) Write(p []byte) (nRet int, errRet error) {
|
||||
if w.ibuf == nil {
|
||||
// Do not buffer incoming bytes. This does not perform or compress well
|
||||
// if the caller of Writer.Write writes many small slices. This
|
||||
// behavior is therefore deprecated, but still supported for backwards
|
||||
// compatibility with code that doesn't explicitly Flush or Close.
|
||||
return w.write(p)
|
||||
}
|
||||
|
||||
// The remainder of this method is based on bufio.Writer.Write from the
|
||||
// standard library.
|
||||
|
||||
for len(p) > (cap(w.ibuf)-len(w.ibuf)) && w.err == nil {
|
||||
var n int
|
||||
if len(w.ibuf) == 0 {
|
||||
// Large write, empty buffer.
|
||||
// Write directly from p to avoid copy.
|
||||
n, _ = w.write(p)
|
||||
} else {
|
||||
n = copy(w.ibuf[len(w.ibuf):cap(w.ibuf)], p)
|
||||
w.ibuf = w.ibuf[:len(w.ibuf)+n]
|
||||
w.Flush()
|
||||
}
|
||||
nRet += n
|
||||
p = p[n:]
|
||||
}
|
||||
if w.err != nil {
|
||||
return nRet, w.err
|
||||
}
|
||||
n := copy(w.ibuf[len(w.ibuf):cap(w.ibuf)], p)
|
||||
w.ibuf = w.ibuf[:len(w.ibuf)+n]
|
||||
nRet += n
|
||||
return nRet, nil
|
||||
}
|
||||
|
||||
func (w *Writer) write(p []byte) (nRet int, errRet error) {
|
||||
if w.err != nil {
|
||||
return 0, w.err
|
||||
}
|
||||
for len(p) > 0 {
|
||||
obufStart := len(magicChunk)
|
||||
if !w.wroteStreamHeader {
|
||||
w.wroteStreamHeader = true
|
||||
copy(w.obuf, magicChunk)
|
||||
obufStart = 0
|
||||
}
|
||||
|
||||
var uncompressed []byte
|
||||
if len(p) > maxBlockSize {
|
||||
uncompressed, p = p[:maxBlockSize], p[maxBlockSize:]
|
||||
} else {
|
||||
uncompressed, p = p, nil
|
||||
}
|
||||
checksum := crc(uncompressed)
|
||||
|
||||
// Compress the buffer, discarding the result if the improvement
|
||||
// isn't at least 12.5%.
|
||||
compressed := Encode(w.obuf[obufHeaderLen:], uncompressed)
|
||||
chunkType := uint8(chunkTypeCompressedData)
|
||||
chunkLen := 4 + len(compressed)
|
||||
obufEnd := obufHeaderLen + len(compressed)
|
||||
if len(compressed) >= len(uncompressed)-len(uncompressed)/8 {
|
||||
chunkType = chunkTypeUncompressedData
|
||||
chunkLen = 4 + len(uncompressed)
|
||||
obufEnd = obufHeaderLen
|
||||
}
|
||||
|
||||
// Fill in the per-chunk header that comes before the body.
|
||||
w.obuf[len(magicChunk)+0] = chunkType
|
||||
w.obuf[len(magicChunk)+1] = uint8(chunkLen >> 0)
|
||||
w.obuf[len(magicChunk)+2] = uint8(chunkLen >> 8)
|
||||
w.obuf[len(magicChunk)+3] = uint8(chunkLen >> 16)
|
||||
w.obuf[len(magicChunk)+4] = uint8(checksum >> 0)
|
||||
w.obuf[len(magicChunk)+5] = uint8(checksum >> 8)
|
||||
w.obuf[len(magicChunk)+6] = uint8(checksum >> 16)
|
||||
w.obuf[len(magicChunk)+7] = uint8(checksum >> 24)
|
||||
|
||||
if _, err := w.w.Write(w.obuf[obufStart:obufEnd]); err != nil {
|
||||
w.err = err
|
||||
return nRet, err
|
||||
}
|
||||
if chunkType == chunkTypeUncompressedData {
|
||||
if _, err := w.w.Write(uncompressed); err != nil {
|
||||
w.err = err
|
||||
return nRet, err
|
||||
}
|
||||
}
|
||||
nRet += len(uncompressed)
|
||||
}
|
||||
return nRet, nil
|
||||
}
|
||||
|
||||
// Flush flushes the Writer to its underlying io.Writer.
|
||||
func (w *Writer) Flush() error {
|
||||
if w.err != nil {
|
||||
return w.err
|
||||
}
|
||||
if len(w.ibuf) == 0 {
|
||||
return nil
|
||||
}
|
||||
w.write(w.ibuf)
|
||||
w.ibuf = w.ibuf[:0]
|
||||
return w.err
|
||||
}
|
||||
|
||||
// Close calls Flush and then closes the Writer.
|
||||
func (w *Writer) Close() error {
|
||||
w.Flush()
|
||||
ret := w.err
|
||||
if w.err == nil {
|
||||
w.err = errClosed
|
||||
}
|
||||
return ret
|
||||
}
|
||||
29
vendor/github.com/golang/snappy/encode_amd64.go
generated
vendored
Normal file
29
vendor/github.com/golang/snappy/encode_amd64.go
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
// Copyright 2016 The Snappy-Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !appengine
|
||||
// +build gc
|
||||
// +build !noasm
|
||||
|
||||
package snappy
|
||||
|
||||
// emitLiteral has the same semantics as in encode_other.go.
|
||||
//
|
||||
//go:noescape
|
||||
func emitLiteral(dst, lit []byte) int
|
||||
|
||||
// emitCopy has the same semantics as in encode_other.go.
|
||||
//
|
||||
//go:noescape
|
||||
func emitCopy(dst []byte, offset, length int) int
|
||||
|
||||
// extendMatch has the same semantics as in encode_other.go.
|
||||
//
|
||||
//go:noescape
|
||||
func extendMatch(src []byte, i, j int) int
|
||||
|
||||
// encodeBlock has the same semantics as in encode_other.go.
|
||||
//
|
||||
//go:noescape
|
||||
func encodeBlock(dst, src []byte) (d int)
|
||||
730
vendor/github.com/golang/snappy/encode_amd64.s
generated
vendored
Normal file
730
vendor/github.com/golang/snappy/encode_amd64.s
generated
vendored
Normal file
@@ -0,0 +1,730 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !appengine
|
||||
// +build gc
|
||||
// +build !noasm
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// The XXX lines assemble on Go 1.4, 1.5 and 1.7, but not 1.6, due to a
|
||||
// Go toolchain regression. See https://github.com/golang/go/issues/15426 and
|
||||
// https://github.com/golang/snappy/issues/29
|
||||
//
|
||||
// As a workaround, the package was built with a known good assembler, and
|
||||
// those instructions were disassembled by "objdump -d" to yield the
|
||||
// 4e 0f b7 7c 5c 78 movzwq 0x78(%rsp,%r11,2),%r15
|
||||
// style comments, in AT&T asm syntax. Note that rsp here is a physical
|
||||
// register, not Go/asm's SP pseudo-register (see https://golang.org/doc/asm).
|
||||
// The instructions were then encoded as "BYTE $0x.." sequences, which assemble
|
||||
// fine on Go 1.6.
|
||||
|
||||
// The asm code generally follows the pure Go code in encode_other.go, except
|
||||
// where marked with a "!!!".
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// func emitLiteral(dst, lit []byte) int
|
||||
//
|
||||
// All local variables fit into registers. The register allocation:
|
||||
// - AX len(lit)
|
||||
// - BX n
|
||||
// - DX return value
|
||||
// - DI &dst[i]
|
||||
// - R10 &lit[0]
|
||||
//
|
||||
// The 24 bytes of stack space is to call runtime·memmove.
|
||||
//
|
||||
// The unusual register allocation of local variables, such as R10 for the
|
||||
// source pointer, matches the allocation used at the call site in encodeBlock,
|
||||
// which makes it easier to manually inline this function.
|
||||
TEXT ·emitLiteral(SB), NOSPLIT, $24-56
|
||||
MOVQ dst_base+0(FP), DI
|
||||
MOVQ lit_base+24(FP), R10
|
||||
MOVQ lit_len+32(FP), AX
|
||||
MOVQ AX, DX
|
||||
MOVL AX, BX
|
||||
SUBL $1, BX
|
||||
|
||||
CMPL BX, $60
|
||||
JLT oneByte
|
||||
CMPL BX, $256
|
||||
JLT twoBytes
|
||||
|
||||
threeBytes:
|
||||
MOVB $0xf4, 0(DI)
|
||||
MOVW BX, 1(DI)
|
||||
ADDQ $3, DI
|
||||
ADDQ $3, DX
|
||||
JMP memmove
|
||||
|
||||
twoBytes:
|
||||
MOVB $0xf0, 0(DI)
|
||||
MOVB BX, 1(DI)
|
||||
ADDQ $2, DI
|
||||
ADDQ $2, DX
|
||||
JMP memmove
|
||||
|
||||
oneByte:
|
||||
SHLB $2, BX
|
||||
MOVB BX, 0(DI)
|
||||
ADDQ $1, DI
|
||||
ADDQ $1, DX
|
||||
|
||||
memmove:
|
||||
MOVQ DX, ret+48(FP)
|
||||
|
||||
// copy(dst[i:], lit)
|
||||
//
|
||||
// This means calling runtime·memmove(&dst[i], &lit[0], len(lit)), so we push
|
||||
// DI, R10 and AX as arguments.
|
||||
MOVQ DI, 0(SP)
|
||||
MOVQ R10, 8(SP)
|
||||
MOVQ AX, 16(SP)
|
||||
CALL runtime·memmove(SB)
|
||||
RET
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// func emitCopy(dst []byte, offset, length int) int
|
||||
//
|
||||
// All local variables fit into registers. The register allocation:
|
||||
// - AX length
|
||||
// - SI &dst[0]
|
||||
// - DI &dst[i]
|
||||
// - R11 offset
|
||||
//
|
||||
// The unusual register allocation of local variables, such as R11 for the
|
||||
// offset, matches the allocation used at the call site in encodeBlock, which
|
||||
// makes it easier to manually inline this function.
|
||||
TEXT ·emitCopy(SB), NOSPLIT, $0-48
|
||||
MOVQ dst_base+0(FP), DI
|
||||
MOVQ DI, SI
|
||||
MOVQ offset+24(FP), R11
|
||||
MOVQ length+32(FP), AX
|
||||
|
||||
loop0:
|
||||
// for length >= 68 { etc }
|
||||
CMPL AX, $68
|
||||
JLT step1
|
||||
|
||||
// Emit a length 64 copy, encoded as 3 bytes.
|
||||
MOVB $0xfe, 0(DI)
|
||||
MOVW R11, 1(DI)
|
||||
ADDQ $3, DI
|
||||
SUBL $64, AX
|
||||
JMP loop0
|
||||
|
||||
step1:
|
||||
// if length > 64 { etc }
|
||||
CMPL AX, $64
|
||||
JLE step2
|
||||
|
||||
// Emit a length 60 copy, encoded as 3 bytes.
|
||||
MOVB $0xee, 0(DI)
|
||||
MOVW R11, 1(DI)
|
||||
ADDQ $3, DI
|
||||
SUBL $60, AX
|
||||
|
||||
step2:
|
||||
// if length >= 12 || offset >= 2048 { goto step3 }
|
||||
CMPL AX, $12
|
||||
JGE step3
|
||||
CMPL R11, $2048
|
||||
JGE step3
|
||||
|
||||
// Emit the remaining copy, encoded as 2 bytes.
|
||||
MOVB R11, 1(DI)
|
||||
SHRL $8, R11
|
||||
SHLB $5, R11
|
||||
SUBB $4, AX
|
||||
SHLB $2, AX
|
||||
ORB AX, R11
|
||||
ORB $1, R11
|
||||
MOVB R11, 0(DI)
|
||||
ADDQ $2, DI
|
||||
|
||||
// Return the number of bytes written.
|
||||
SUBQ SI, DI
|
||||
MOVQ DI, ret+40(FP)
|
||||
RET
|
||||
|
||||
step3:
|
||||
// Emit the remaining copy, encoded as 3 bytes.
|
||||
SUBL $1, AX
|
||||
SHLB $2, AX
|
||||
ORB $2, AX
|
||||
MOVB AX, 0(DI)
|
||||
MOVW R11, 1(DI)
|
||||
ADDQ $3, DI
|
||||
|
||||
// Return the number of bytes written.
|
||||
SUBQ SI, DI
|
||||
MOVQ DI, ret+40(FP)
|
||||
RET
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// func extendMatch(src []byte, i, j int) int
|
||||
//
|
||||
// All local variables fit into registers. The register allocation:
|
||||
// - DX &src[0]
|
||||
// - SI &src[j]
|
||||
// - R13 &src[len(src) - 8]
|
||||
// - R14 &src[len(src)]
|
||||
// - R15 &src[i]
|
||||
//
|
||||
// The unusual register allocation of local variables, such as R15 for a source
|
||||
// pointer, matches the allocation used at the call site in encodeBlock, which
|
||||
// makes it easier to manually inline this function.
|
||||
TEXT ·extendMatch(SB), NOSPLIT, $0-48
|
||||
MOVQ src_base+0(FP), DX
|
||||
MOVQ src_len+8(FP), R14
|
||||
MOVQ i+24(FP), R15
|
||||
MOVQ j+32(FP), SI
|
||||
ADDQ DX, R14
|
||||
ADDQ DX, R15
|
||||
ADDQ DX, SI
|
||||
MOVQ R14, R13
|
||||
SUBQ $8, R13
|
||||
|
||||
cmp8:
|
||||
// As long as we are 8 or more bytes before the end of src, we can load and
|
||||
// compare 8 bytes at a time. If those 8 bytes are equal, repeat.
|
||||
CMPQ SI, R13
|
||||
JA cmp1
|
||||
MOVQ (R15), AX
|
||||
MOVQ (SI), BX
|
||||
CMPQ AX, BX
|
||||
JNE bsf
|
||||
ADDQ $8, R15
|
||||
ADDQ $8, SI
|
||||
JMP cmp8
|
||||
|
||||
bsf:
|
||||
// If those 8 bytes were not equal, XOR the two 8 byte values, and return
|
||||
// the index of the first byte that differs. The BSF instruction finds the
|
||||
// least significant 1 bit, the amd64 architecture is little-endian, and
|
||||
// the shift by 3 converts a bit index to a byte index.
|
||||
XORQ AX, BX
|
||||
BSFQ BX, BX
|
||||
SHRQ $3, BX
|
||||
ADDQ BX, SI
|
||||
|
||||
// Convert from &src[ret] to ret.
|
||||
SUBQ DX, SI
|
||||
MOVQ SI, ret+40(FP)
|
||||
RET
|
||||
|
||||
cmp1:
|
||||
// In src's tail, compare 1 byte at a time.
|
||||
CMPQ SI, R14
|
||||
JAE extendMatchEnd
|
||||
MOVB (R15), AX
|
||||
MOVB (SI), BX
|
||||
CMPB AX, BX
|
||||
JNE extendMatchEnd
|
||||
ADDQ $1, R15
|
||||
ADDQ $1, SI
|
||||
JMP cmp1
|
||||
|
||||
extendMatchEnd:
|
||||
// Convert from &src[ret] to ret.
|
||||
SUBQ DX, SI
|
||||
MOVQ SI, ret+40(FP)
|
||||
RET
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// func encodeBlock(dst, src []byte) (d int)
|
||||
//
|
||||
// All local variables fit into registers, other than "var table". The register
|
||||
// allocation:
|
||||
// - AX . .
|
||||
// - BX . .
|
||||
// - CX 56 shift (note that amd64 shifts by non-immediates must use CX).
|
||||
// - DX 64 &src[0], tableSize
|
||||
// - SI 72 &src[s]
|
||||
// - DI 80 &dst[d]
|
||||
// - R9 88 sLimit
|
||||
// - R10 . &src[nextEmit]
|
||||
// - R11 96 prevHash, currHash, nextHash, offset
|
||||
// - R12 104 &src[base], skip
|
||||
// - R13 . &src[nextS], &src[len(src) - 8]
|
||||
// - R14 . len(src), bytesBetweenHashLookups, &src[len(src)], x
|
||||
// - R15 112 candidate
|
||||
//
|
||||
// The second column (56, 64, etc) is the stack offset to spill the registers
|
||||
// when calling other functions. We could pack this slightly tighter, but it's
|
||||
// simpler to have a dedicated spill map independent of the function called.
|
||||
//
|
||||
// "var table [maxTableSize]uint16" takes up 32768 bytes of stack space. An
|
||||
// extra 56 bytes, to call other functions, and an extra 64 bytes, to spill
|
||||
// local variables (registers) during calls gives 32768 + 56 + 64 = 32888.
|
||||
TEXT ·encodeBlock(SB), 0, $32888-56
|
||||
MOVQ dst_base+0(FP), DI
|
||||
MOVQ src_base+24(FP), SI
|
||||
MOVQ src_len+32(FP), R14
|
||||
|
||||
// shift, tableSize := uint32(32-8), 1<<8
|
||||
MOVQ $24, CX
|
||||
MOVQ $256, DX
|
||||
|
||||
calcShift:
|
||||
// for ; tableSize < maxTableSize && tableSize < len(src); tableSize *= 2 {
|
||||
// shift--
|
||||
// }
|
||||
CMPQ DX, $16384
|
||||
JGE varTable
|
||||
CMPQ DX, R14
|
||||
JGE varTable
|
||||
SUBQ $1, CX
|
||||
SHLQ $1, DX
|
||||
JMP calcShift
|
||||
|
||||
varTable:
|
||||
// var table [maxTableSize]uint16
|
||||
//
|
||||
// In the asm code, unlike the Go code, we can zero-initialize only the
|
||||
// first tableSize elements. Each uint16 element is 2 bytes and each MOVOU
|
||||
// writes 16 bytes, so we can do only tableSize/8 writes instead of the
|
||||
// 2048 writes that would zero-initialize all of table's 32768 bytes.
|
||||
SHRQ $3, DX
|
||||
LEAQ table-32768(SP), BX
|
||||
PXOR X0, X0
|
||||
|
||||
memclr:
|
||||
MOVOU X0, 0(BX)
|
||||
ADDQ $16, BX
|
||||
SUBQ $1, DX
|
||||
JNZ memclr
|
||||
|
||||
// !!! DX = &src[0]
|
||||
MOVQ SI, DX
|
||||
|
||||
// sLimit := len(src) - inputMargin
|
||||
MOVQ R14, R9
|
||||
SUBQ $15, R9
|
||||
|
||||
// !!! Pre-emptively spill CX, DX and R9 to the stack. Their values don't
|
||||
// change for the rest of the function.
|
||||
MOVQ CX, 56(SP)
|
||||
MOVQ DX, 64(SP)
|
||||
MOVQ R9, 88(SP)
|
||||
|
||||
// nextEmit := 0
|
||||
MOVQ DX, R10
|
||||
|
||||
// s := 1
|
||||
ADDQ $1, SI
|
||||
|
||||
// nextHash := hash(load32(src, s), shift)
|
||||
MOVL 0(SI), R11
|
||||
IMULL $0x1e35a7bd, R11
|
||||
SHRL CX, R11
|
||||
|
||||
outer:
|
||||
// for { etc }
|
||||
|
||||
// skip := 32
|
||||
MOVQ $32, R12
|
||||
|
||||
// nextS := s
|
||||
MOVQ SI, R13
|
||||
|
||||
// candidate := 0
|
||||
MOVQ $0, R15
|
||||
|
||||
inner0:
|
||||
// for { etc }
|
||||
|
||||
// s := nextS
|
||||
MOVQ R13, SI
|
||||
|
||||
// bytesBetweenHashLookups := skip >> 5
|
||||
MOVQ R12, R14
|
||||
SHRQ $5, R14
|
||||
|
||||
// nextS = s + bytesBetweenHashLookups
|
||||
ADDQ R14, R13
|
||||
|
||||
// skip += bytesBetweenHashLookups
|
||||
ADDQ R14, R12
|
||||
|
||||
// if nextS > sLimit { goto emitRemainder }
|
||||
MOVQ R13, AX
|
||||
SUBQ DX, AX
|
||||
CMPQ AX, R9
|
||||
JA emitRemainder
|
||||
|
||||
// candidate = int(table[nextHash])
|
||||
// XXX: MOVWQZX table-32768(SP)(R11*2), R15
|
||||
// XXX: 4e 0f b7 7c 5c 78 movzwq 0x78(%rsp,%r11,2),%r15
|
||||
BYTE $0x4e
|
||||
BYTE $0x0f
|
||||
BYTE $0xb7
|
||||
BYTE $0x7c
|
||||
BYTE $0x5c
|
||||
BYTE $0x78
|
||||
|
||||
// table[nextHash] = uint16(s)
|
||||
MOVQ SI, AX
|
||||
SUBQ DX, AX
|
||||
|
||||
// XXX: MOVW AX, table-32768(SP)(R11*2)
|
||||
// XXX: 66 42 89 44 5c 78 mov %ax,0x78(%rsp,%r11,2)
|
||||
BYTE $0x66
|
||||
BYTE $0x42
|
||||
BYTE $0x89
|
||||
BYTE $0x44
|
||||
BYTE $0x5c
|
||||
BYTE $0x78
|
||||
|
||||
// nextHash = hash(load32(src, nextS), shift)
|
||||
MOVL 0(R13), R11
|
||||
IMULL $0x1e35a7bd, R11
|
||||
SHRL CX, R11
|
||||
|
||||
// if load32(src, s) != load32(src, candidate) { continue } break
|
||||
MOVL 0(SI), AX
|
||||
MOVL (DX)(R15*1), BX
|
||||
CMPL AX, BX
|
||||
JNE inner0
|
||||
|
||||
fourByteMatch:
|
||||
// As per the encode_other.go code:
|
||||
//
|
||||
// A 4-byte match has been found. We'll later see etc.
|
||||
|
||||
// !!! Jump to a fast path for short (<= 16 byte) literals. See the comment
|
||||
// on inputMargin in encode.go.
|
||||
MOVQ SI, AX
|
||||
SUBQ R10, AX
|
||||
CMPQ AX, $16
|
||||
JLE emitLiteralFastPath
|
||||
|
||||
// ----------------------------------------
|
||||
// Begin inline of the emitLiteral call.
|
||||
//
|
||||
// d += emitLiteral(dst[d:], src[nextEmit:s])
|
||||
|
||||
MOVL AX, BX
|
||||
SUBL $1, BX
|
||||
|
||||
CMPL BX, $60
|
||||
JLT inlineEmitLiteralOneByte
|
||||
CMPL BX, $256
|
||||
JLT inlineEmitLiteralTwoBytes
|
||||
|
||||
inlineEmitLiteralThreeBytes:
|
||||
MOVB $0xf4, 0(DI)
|
||||
MOVW BX, 1(DI)
|
||||
ADDQ $3, DI
|
||||
JMP inlineEmitLiteralMemmove
|
||||
|
||||
inlineEmitLiteralTwoBytes:
|
||||
MOVB $0xf0, 0(DI)
|
||||
MOVB BX, 1(DI)
|
||||
ADDQ $2, DI
|
||||
JMP inlineEmitLiteralMemmove
|
||||
|
||||
inlineEmitLiteralOneByte:
|
||||
SHLB $2, BX
|
||||
MOVB BX, 0(DI)
|
||||
ADDQ $1, DI
|
||||
|
||||
inlineEmitLiteralMemmove:
|
||||
// Spill local variables (registers) onto the stack; call; unspill.
|
||||
//
|
||||
// copy(dst[i:], lit)
|
||||
//
|
||||
// This means calling runtime·memmove(&dst[i], &lit[0], len(lit)), so we push
|
||||
// DI, R10 and AX as arguments.
|
||||
MOVQ DI, 0(SP)
|
||||
MOVQ R10, 8(SP)
|
||||
MOVQ AX, 16(SP)
|
||||
ADDQ AX, DI // Finish the "d +=" part of "d += emitLiteral(etc)".
|
||||
MOVQ SI, 72(SP)
|
||||
MOVQ DI, 80(SP)
|
||||
MOVQ R15, 112(SP)
|
||||
CALL runtime·memmove(SB)
|
||||
MOVQ 56(SP), CX
|
||||
MOVQ 64(SP), DX
|
||||
MOVQ 72(SP), SI
|
||||
MOVQ 80(SP), DI
|
||||
MOVQ 88(SP), R9
|
||||
MOVQ 112(SP), R15
|
||||
JMP inner1
|
||||
|
||||
inlineEmitLiteralEnd:
|
||||
// End inline of the emitLiteral call.
|
||||
// ----------------------------------------
|
||||
|
||||
emitLiteralFastPath:
|
||||
// !!! Emit the 1-byte encoding "uint8(len(lit)-1)<<2".
|
||||
MOVB AX, BX
|
||||
SUBB $1, BX
|
||||
SHLB $2, BX
|
||||
MOVB BX, (DI)
|
||||
ADDQ $1, DI
|
||||
|
||||
// !!! Implement the copy from lit to dst as a 16-byte load and store.
|
||||
// (Encode's documentation says that dst and src must not overlap.)
|
||||
//
|
||||
// This always copies 16 bytes, instead of only len(lit) bytes, but that's
|
||||
// OK. Subsequent iterations will fix up the overrun.
|
||||
//
|
||||
// Note that on amd64, it is legal and cheap to issue unaligned 8-byte or
|
||||
// 16-byte loads and stores. This technique probably wouldn't be as
|
||||
// effective on architectures that are fussier about alignment.
|
||||
MOVOU 0(R10), X0
|
||||
MOVOU X0, 0(DI)
|
||||
ADDQ AX, DI
|
||||
|
||||
inner1:
|
||||
// for { etc }
|
||||
|
||||
// base := s
|
||||
MOVQ SI, R12
|
||||
|
||||
// !!! offset := base - candidate
|
||||
MOVQ R12, R11
|
||||
SUBQ R15, R11
|
||||
SUBQ DX, R11
|
||||
|
||||
// ----------------------------------------
|
||||
// Begin inline of the extendMatch call.
|
||||
//
|
||||
// s = extendMatch(src, candidate+4, s+4)
|
||||
|
||||
// !!! R14 = &src[len(src)]
|
||||
MOVQ src_len+32(FP), R14
|
||||
ADDQ DX, R14
|
||||
|
||||
// !!! R13 = &src[len(src) - 8]
|
||||
MOVQ R14, R13
|
||||
SUBQ $8, R13
|
||||
|
||||
// !!! R15 = &src[candidate + 4]
|
||||
ADDQ $4, R15
|
||||
ADDQ DX, R15
|
||||
|
||||
// !!! s += 4
|
||||
ADDQ $4, SI
|
||||
|
||||
inlineExtendMatchCmp8:
|
||||
// As long as we are 8 or more bytes before the end of src, we can load and
|
||||
// compare 8 bytes at a time. If those 8 bytes are equal, repeat.
|
||||
CMPQ SI, R13
|
||||
JA inlineExtendMatchCmp1
|
||||
MOVQ (R15), AX
|
||||
MOVQ (SI), BX
|
||||
CMPQ AX, BX
|
||||
JNE inlineExtendMatchBSF
|
||||
ADDQ $8, R15
|
||||
ADDQ $8, SI
|
||||
JMP inlineExtendMatchCmp8
|
||||
|
||||
inlineExtendMatchBSF:
|
||||
// If those 8 bytes were not equal, XOR the two 8 byte values, and return
|
||||
// the index of the first byte that differs. The BSF instruction finds the
|
||||
// least significant 1 bit, the amd64 architecture is little-endian, and
|
||||
// the shift by 3 converts a bit index to a byte index.
|
||||
XORQ AX, BX
|
||||
BSFQ BX, BX
|
||||
SHRQ $3, BX
|
||||
ADDQ BX, SI
|
||||
JMP inlineExtendMatchEnd
|
||||
|
||||
inlineExtendMatchCmp1:
|
||||
// In src's tail, compare 1 byte at a time.
|
||||
CMPQ SI, R14
|
||||
JAE inlineExtendMatchEnd
|
||||
MOVB (R15), AX
|
||||
MOVB (SI), BX
|
||||
CMPB AX, BX
|
||||
JNE inlineExtendMatchEnd
|
||||
ADDQ $1, R15
|
||||
ADDQ $1, SI
|
||||
JMP inlineExtendMatchCmp1
|
||||
|
||||
inlineExtendMatchEnd:
|
||||
// End inline of the extendMatch call.
|
||||
// ----------------------------------------
|
||||
|
||||
// ----------------------------------------
|
||||
// Begin inline of the emitCopy call.
|
||||
//
|
||||
// d += emitCopy(dst[d:], base-candidate, s-base)
|
||||
|
||||
// !!! length := s - base
|
||||
MOVQ SI, AX
|
||||
SUBQ R12, AX
|
||||
|
||||
inlineEmitCopyLoop0:
|
||||
// for length >= 68 { etc }
|
||||
CMPL AX, $68
|
||||
JLT inlineEmitCopyStep1
|
||||
|
||||
// Emit a length 64 copy, encoded as 3 bytes.
|
||||
MOVB $0xfe, 0(DI)
|
||||
MOVW R11, 1(DI)
|
||||
ADDQ $3, DI
|
||||
SUBL $64, AX
|
||||
JMP inlineEmitCopyLoop0
|
||||
|
||||
inlineEmitCopyStep1:
|
||||
// if length > 64 { etc }
|
||||
CMPL AX, $64
|
||||
JLE inlineEmitCopyStep2
|
||||
|
||||
// Emit a length 60 copy, encoded as 3 bytes.
|
||||
MOVB $0xee, 0(DI)
|
||||
MOVW R11, 1(DI)
|
||||
ADDQ $3, DI
|
||||
SUBL $60, AX
|
||||
|
||||
inlineEmitCopyStep2:
|
||||
// if length >= 12 || offset >= 2048 { goto inlineEmitCopyStep3 }
|
||||
CMPL AX, $12
|
||||
JGE inlineEmitCopyStep3
|
||||
CMPL R11, $2048
|
||||
JGE inlineEmitCopyStep3
|
||||
|
||||
// Emit the remaining copy, encoded as 2 bytes.
|
||||
MOVB R11, 1(DI)
|
||||
SHRL $8, R11
|
||||
SHLB $5, R11
|
||||
SUBB $4, AX
|
||||
SHLB $2, AX
|
||||
ORB AX, R11
|
||||
ORB $1, R11
|
||||
MOVB R11, 0(DI)
|
||||
ADDQ $2, DI
|
||||
JMP inlineEmitCopyEnd
|
||||
|
||||
inlineEmitCopyStep3:
|
||||
// Emit the remaining copy, encoded as 3 bytes.
|
||||
SUBL $1, AX
|
||||
SHLB $2, AX
|
||||
ORB $2, AX
|
||||
MOVB AX, 0(DI)
|
||||
MOVW R11, 1(DI)
|
||||
ADDQ $3, DI
|
||||
|
||||
inlineEmitCopyEnd:
|
||||
// End inline of the emitCopy call.
|
||||
// ----------------------------------------
|
||||
|
||||
// nextEmit = s
|
||||
MOVQ SI, R10
|
||||
|
||||
// if s >= sLimit { goto emitRemainder }
|
||||
MOVQ SI, AX
|
||||
SUBQ DX, AX
|
||||
CMPQ AX, R9
|
||||
JAE emitRemainder
|
||||
|
||||
// As per the encode_other.go code:
|
||||
//
|
||||
// We could immediately etc.
|
||||
|
||||
// x := load64(src, s-1)
|
||||
MOVQ -1(SI), R14
|
||||
|
||||
// prevHash := hash(uint32(x>>0), shift)
|
||||
MOVL R14, R11
|
||||
IMULL $0x1e35a7bd, R11
|
||||
SHRL CX, R11
|
||||
|
||||
// table[prevHash] = uint16(s-1)
|
||||
MOVQ SI, AX
|
||||
SUBQ DX, AX
|
||||
SUBQ $1, AX
|
||||
|
||||
// XXX: MOVW AX, table-32768(SP)(R11*2)
|
||||
// XXX: 66 42 89 44 5c 78 mov %ax,0x78(%rsp,%r11,2)
|
||||
BYTE $0x66
|
||||
BYTE $0x42
|
||||
BYTE $0x89
|
||||
BYTE $0x44
|
||||
BYTE $0x5c
|
||||
BYTE $0x78
|
||||
|
||||
// currHash := hash(uint32(x>>8), shift)
|
||||
SHRQ $8, R14
|
||||
MOVL R14, R11
|
||||
IMULL $0x1e35a7bd, R11
|
||||
SHRL CX, R11
|
||||
|
||||
// candidate = int(table[currHash])
|
||||
// XXX: MOVWQZX table-32768(SP)(R11*2), R15
|
||||
// XXX: 4e 0f b7 7c 5c 78 movzwq 0x78(%rsp,%r11,2),%r15
|
||||
BYTE $0x4e
|
||||
BYTE $0x0f
|
||||
BYTE $0xb7
|
||||
BYTE $0x7c
|
||||
BYTE $0x5c
|
||||
BYTE $0x78
|
||||
|
||||
// table[currHash] = uint16(s)
|
||||
ADDQ $1, AX
|
||||
|
||||
// XXX: MOVW AX, table-32768(SP)(R11*2)
|
||||
// XXX: 66 42 89 44 5c 78 mov %ax,0x78(%rsp,%r11,2)
|
||||
BYTE $0x66
|
||||
BYTE $0x42
|
||||
BYTE $0x89
|
||||
BYTE $0x44
|
||||
BYTE $0x5c
|
||||
BYTE $0x78
|
||||
|
||||
// if uint32(x>>8) == load32(src, candidate) { continue }
|
||||
MOVL (DX)(R15*1), BX
|
||||
CMPL R14, BX
|
||||
JEQ inner1
|
||||
|
||||
// nextHash = hash(uint32(x>>16), shift)
|
||||
SHRQ $8, R14
|
||||
MOVL R14, R11
|
||||
IMULL $0x1e35a7bd, R11
|
||||
SHRL CX, R11
|
||||
|
||||
// s++
|
||||
ADDQ $1, SI
|
||||
|
||||
// break out of the inner1 for loop, i.e. continue the outer loop.
|
||||
JMP outer
|
||||
|
||||
emitRemainder:
|
||||
// if nextEmit < len(src) { etc }
|
||||
MOVQ src_len+32(FP), AX
|
||||
ADDQ DX, AX
|
||||
CMPQ R10, AX
|
||||
JEQ encodeBlockEnd
|
||||
|
||||
// d += emitLiteral(dst[d:], src[nextEmit:])
|
||||
//
|
||||
// Push args.
|
||||
MOVQ DI, 0(SP)
|
||||
MOVQ $0, 8(SP) // Unnecessary, as the callee ignores it, but conservative.
|
||||
MOVQ $0, 16(SP) // Unnecessary, as the callee ignores it, but conservative.
|
||||
MOVQ R10, 24(SP)
|
||||
SUBQ R10, AX
|
||||
MOVQ AX, 32(SP)
|
||||
MOVQ AX, 40(SP) // Unnecessary, as the callee ignores it, but conservative.
|
||||
|
||||
// Spill local variables (registers) onto the stack; call; unspill.
|
||||
MOVQ DI, 80(SP)
|
||||
CALL ·emitLiteral(SB)
|
||||
MOVQ 80(SP), DI
|
||||
|
||||
// Finish the "d +=" part of "d += emitLiteral(etc)".
|
||||
ADDQ 48(SP), DI
|
||||
|
||||
encodeBlockEnd:
|
||||
MOVQ dst_base+0(FP), AX
|
||||
SUBQ AX, DI
|
||||
MOVQ DI, d+48(FP)
|
||||
RET
|
||||
238
vendor/github.com/golang/snappy/encode_other.go
generated
vendored
Normal file
238
vendor/github.com/golang/snappy/encode_other.go
generated
vendored
Normal file
@@ -0,0 +1,238 @@
|
||||
// Copyright 2016 The Snappy-Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !amd64 appengine !gc noasm
|
||||
|
||||
package snappy
|
||||
|
||||
func load32(b []byte, i int) uint32 {
|
||||
b = b[i : i+4 : len(b)] // Help the compiler eliminate bounds checks on the next line.
|
||||
return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
|
||||
}
|
||||
|
||||
func load64(b []byte, i int) uint64 {
|
||||
b = b[i : i+8 : len(b)] // Help the compiler eliminate bounds checks on the next line.
|
||||
return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 |
|
||||
uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
|
||||
}
|
||||
|
||||
// emitLiteral writes a literal chunk and returns the number of bytes written.
|
||||
//
|
||||
// It assumes that:
|
||||
// dst is long enough to hold the encoded bytes
|
||||
// 1 <= len(lit) && len(lit) <= 65536
|
||||
func emitLiteral(dst, lit []byte) int {
|
||||
i, n := 0, uint(len(lit)-1)
|
||||
switch {
|
||||
case n < 60:
|
||||
dst[0] = uint8(n)<<2 | tagLiteral
|
||||
i = 1
|
||||
case n < 1<<8:
|
||||
dst[0] = 60<<2 | tagLiteral
|
||||
dst[1] = uint8(n)
|
||||
i = 2
|
||||
default:
|
||||
dst[0] = 61<<2 | tagLiteral
|
||||
dst[1] = uint8(n)
|
||||
dst[2] = uint8(n >> 8)
|
||||
i = 3
|
||||
}
|
||||
return i + copy(dst[i:], lit)
|
||||
}
|
||||
|
||||
// emitCopy writes a copy chunk and returns the number of bytes written.
|
||||
//
|
||||
// It assumes that:
|
||||
// dst is long enough to hold the encoded bytes
|
||||
// 1 <= offset && offset <= 65535
|
||||
// 4 <= length && length <= 65535
|
||||
func emitCopy(dst []byte, offset, length int) int {
|
||||
i := 0
|
||||
// The maximum length for a single tagCopy1 or tagCopy2 op is 64 bytes. The
|
||||
// threshold for this loop is a little higher (at 68 = 64 + 4), and the
|
||||
// length emitted down below is is a little lower (at 60 = 64 - 4), because
|
||||
// it's shorter to encode a length 67 copy as a length 60 tagCopy2 followed
|
||||
// by a length 7 tagCopy1 (which encodes as 3+2 bytes) than to encode it as
|
||||
// a length 64 tagCopy2 followed by a length 3 tagCopy2 (which encodes as
|
||||
// 3+3 bytes). The magic 4 in the 64±4 is because the minimum length for a
|
||||
// tagCopy1 op is 4 bytes, which is why a length 3 copy has to be an
|
||||
// encodes-as-3-bytes tagCopy2 instead of an encodes-as-2-bytes tagCopy1.
|
||||
for length >= 68 {
|
||||
// Emit a length 64 copy, encoded as 3 bytes.
|
||||
dst[i+0] = 63<<2 | tagCopy2
|
||||
dst[i+1] = uint8(offset)
|
||||
dst[i+2] = uint8(offset >> 8)
|
||||
i += 3
|
||||
length -= 64
|
||||
}
|
||||
if length > 64 {
|
||||
// Emit a length 60 copy, encoded as 3 bytes.
|
||||
dst[i+0] = 59<<2 | tagCopy2
|
||||
dst[i+1] = uint8(offset)
|
||||
dst[i+2] = uint8(offset >> 8)
|
||||
i += 3
|
||||
length -= 60
|
||||
}
|
||||
if length >= 12 || offset >= 2048 {
|
||||
// Emit the remaining copy, encoded as 3 bytes.
|
||||
dst[i+0] = uint8(length-1)<<2 | tagCopy2
|
||||
dst[i+1] = uint8(offset)
|
||||
dst[i+2] = uint8(offset >> 8)
|
||||
return i + 3
|
||||
}
|
||||
// Emit the remaining copy, encoded as 2 bytes.
|
||||
dst[i+0] = uint8(offset>>8)<<5 | uint8(length-4)<<2 | tagCopy1
|
||||
dst[i+1] = uint8(offset)
|
||||
return i + 2
|
||||
}
|
||||
|
||||
// extendMatch returns the largest k such that k <= len(src) and that
|
||||
// src[i:i+k-j] and src[j:k] have the same contents.
|
||||
//
|
||||
// It assumes that:
|
||||
// 0 <= i && i < j && j <= len(src)
|
||||
func extendMatch(src []byte, i, j int) int {
|
||||
for ; j < len(src) && src[i] == src[j]; i, j = i+1, j+1 {
|
||||
}
|
||||
return j
|
||||
}
|
||||
|
||||
func hash(u, shift uint32) uint32 {
|
||||
return (u * 0x1e35a7bd) >> shift
|
||||
}
|
||||
|
||||
// encodeBlock encodes a non-empty src to a guaranteed-large-enough dst. It
|
||||
// assumes that the varint-encoded length of the decompressed bytes has already
|
||||
// been written.
|
||||
//
|
||||
// It also assumes that:
|
||||
// len(dst) >= MaxEncodedLen(len(src)) &&
|
||||
// minNonLiteralBlockSize <= len(src) && len(src) <= maxBlockSize
|
||||
func encodeBlock(dst, src []byte) (d int) {
|
||||
// Initialize the hash table. Its size ranges from 1<<8 to 1<<14 inclusive.
|
||||
// The table element type is uint16, as s < sLimit and sLimit < len(src)
|
||||
// and len(src) <= maxBlockSize and maxBlockSize == 65536.
|
||||
const (
|
||||
maxTableSize = 1 << 14
|
||||
// tableMask is redundant, but helps the compiler eliminate bounds
|
||||
// checks.
|
||||
tableMask = maxTableSize - 1
|
||||
)
|
||||
shift := uint32(32 - 8)
|
||||
for tableSize := 1 << 8; tableSize < maxTableSize && tableSize < len(src); tableSize *= 2 {
|
||||
shift--
|
||||
}
|
||||
// In Go, all array elements are zero-initialized, so there is no advantage
|
||||
// to a smaller tableSize per se. However, it matches the C++ algorithm,
|
||||
// and in the asm versions of this code, we can get away with zeroing only
|
||||
// the first tableSize elements.
|
||||
var table [maxTableSize]uint16
|
||||
|
||||
// sLimit is when to stop looking for offset/length copies. The inputMargin
|
||||
// lets us use a fast path for emitLiteral in the main loop, while we are
|
||||
// looking for copies.
|
||||
sLimit := len(src) - inputMargin
|
||||
|
||||
// nextEmit is where in src the next emitLiteral should start from.
|
||||
nextEmit := 0
|
||||
|
||||
// The encoded form must start with a literal, as there are no previous
|
||||
// bytes to copy, so we start looking for hash matches at s == 1.
|
||||
s := 1
|
||||
nextHash := hash(load32(src, s), shift)
|
||||
|
||||
for {
|
||||
// Copied from the C++ snappy implementation:
|
||||
//
|
||||
// Heuristic match skipping: If 32 bytes are scanned with no matches
|
||||
// found, start looking only at every other byte. If 32 more bytes are
|
||||
// scanned (or skipped), look at every third byte, etc.. When a match
|
||||
// is found, immediately go back to looking at every byte. This is a
|
||||
// small loss (~5% performance, ~0.1% density) for compressible data
|
||||
// due to more bookkeeping, but for non-compressible data (such as
|
||||
// JPEG) it's a huge win since the compressor quickly "realizes" the
|
||||
// data is incompressible and doesn't bother looking for matches
|
||||
// everywhere.
|
||||
//
|
||||
// The "skip" variable keeps track of how many bytes there are since
|
||||
// the last match; dividing it by 32 (ie. right-shifting by five) gives
|
||||
// the number of bytes to move ahead for each iteration.
|
||||
skip := 32
|
||||
|
||||
nextS := s
|
||||
candidate := 0
|
||||
for {
|
||||
s = nextS
|
||||
bytesBetweenHashLookups := skip >> 5
|
||||
nextS = s + bytesBetweenHashLookups
|
||||
skip += bytesBetweenHashLookups
|
||||
if nextS > sLimit {
|
||||
goto emitRemainder
|
||||
}
|
||||
candidate = int(table[nextHash&tableMask])
|
||||
table[nextHash&tableMask] = uint16(s)
|
||||
nextHash = hash(load32(src, nextS), shift)
|
||||
if load32(src, s) == load32(src, candidate) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// A 4-byte match has been found. We'll later see if more than 4 bytes
|
||||
// match. But, prior to the match, src[nextEmit:s] are unmatched. Emit
|
||||
// them as literal bytes.
|
||||
d += emitLiteral(dst[d:], src[nextEmit:s])
|
||||
|
||||
// Call emitCopy, and then see if another emitCopy could be our next
|
||||
// move. Repeat until we find no match for the input immediately after
|
||||
// what was consumed by the last emitCopy call.
|
||||
//
|
||||
// If we exit this loop normally then we need to call emitLiteral next,
|
||||
// though we don't yet know how big the literal will be. We handle that
|
||||
// by proceeding to the next iteration of the main loop. We also can
|
||||
// exit this loop via goto if we get close to exhausting the input.
|
||||
for {
|
||||
// Invariant: we have a 4-byte match at s, and no need to emit any
|
||||
// literal bytes prior to s.
|
||||
base := s
|
||||
|
||||
// Extend the 4-byte match as long as possible.
|
||||
//
|
||||
// This is an inlined version of:
|
||||
// s = extendMatch(src, candidate+4, s+4)
|
||||
s += 4
|
||||
for i := candidate + 4; s < len(src) && src[i] == src[s]; i, s = i+1, s+1 {
|
||||
}
|
||||
|
||||
d += emitCopy(dst[d:], base-candidate, s-base)
|
||||
nextEmit = s
|
||||
if s >= sLimit {
|
||||
goto emitRemainder
|
||||
}
|
||||
|
||||
// We could immediately start working at s now, but to improve
|
||||
// compression we first update the hash table at s-1 and at s. If
|
||||
// another emitCopy is not our next move, also calculate nextHash
|
||||
// at s+1. At least on GOARCH=amd64, these three hash calculations
|
||||
// are faster as one load64 call (with some shifts) instead of
|
||||
// three load32 calls.
|
||||
x := load64(src, s-1)
|
||||
prevHash := hash(uint32(x>>0), shift)
|
||||
table[prevHash&tableMask] = uint16(s - 1)
|
||||
currHash := hash(uint32(x>>8), shift)
|
||||
candidate = int(table[currHash&tableMask])
|
||||
table[currHash&tableMask] = uint16(s)
|
||||
if uint32(x>>8) != load32(src, candidate) {
|
||||
nextHash = hash(uint32(x>>16), shift)
|
||||
s++
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
emitRemainder:
|
||||
if nextEmit < len(src) {
|
||||
d += emitLiteral(dst[d:], src[nextEmit:])
|
||||
}
|
||||
return d
|
||||
}
|
||||
1
vendor/github.com/golang/snappy/go.mod
generated
vendored
Normal file
1
vendor/github.com/golang/snappy/go.mod
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
module github.com/golang/snappy
|
||||
98
vendor/github.com/golang/snappy/snappy.go
generated
vendored
Normal file
98
vendor/github.com/golang/snappy/snappy.go
generated
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
// Copyright 2011 The Snappy-Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package snappy implements the Snappy compression format. It aims for very
|
||||
// high speeds and reasonable compression.
|
||||
//
|
||||
// There are actually two Snappy formats: block and stream. They are related,
|
||||
// but different: trying to decompress block-compressed data as a Snappy stream
|
||||
// will fail, and vice versa. The block format is the Decode and Encode
|
||||
// functions and the stream format is the Reader and Writer types.
|
||||
//
|
||||
// The block format, the more common case, is used when the complete size (the
|
||||
// number of bytes) of the original data is known upfront, at the time
|
||||
// compression starts. The stream format, also known as the framing format, is
|
||||
// for when that isn't always true.
|
||||
//
|
||||
// The canonical, C++ implementation is at https://github.com/google/snappy and
|
||||
// it only implements the block format.
|
||||
package snappy // import "github.com/golang/snappy"
|
||||
|
||||
import (
|
||||
"hash/crc32"
|
||||
)
|
||||
|
||||
/*
|
||||
Each encoded block begins with the varint-encoded length of the decoded data,
|
||||
followed by a sequence of chunks. Chunks begin and end on byte boundaries. The
|
||||
first byte of each chunk is broken into its 2 least and 6 most significant bits
|
||||
called l and m: l ranges in [0, 4) and m ranges in [0, 64). l is the chunk tag.
|
||||
Zero means a literal tag. All other values mean a copy tag.
|
||||
|
||||
For literal tags:
|
||||
- If m < 60, the next 1 + m bytes are literal bytes.
|
||||
- Otherwise, let n be the little-endian unsigned integer denoted by the next
|
||||
m - 59 bytes. The next 1 + n bytes after that are literal bytes.
|
||||
|
||||
For copy tags, length bytes are copied from offset bytes ago, in the style of
|
||||
Lempel-Ziv compression algorithms. In particular:
|
||||
- For l == 1, the offset ranges in [0, 1<<11) and the length in [4, 12).
|
||||
The length is 4 + the low 3 bits of m. The high 3 bits of m form bits 8-10
|
||||
of the offset. The next byte is bits 0-7 of the offset.
|
||||
- For l == 2, the offset ranges in [0, 1<<16) and the length in [1, 65).
|
||||
The length is 1 + m. The offset is the little-endian unsigned integer
|
||||
denoted by the next 2 bytes.
|
||||
- For l == 3, this tag is a legacy format that is no longer issued by most
|
||||
encoders. Nonetheless, the offset ranges in [0, 1<<32) and the length in
|
||||
[1, 65). The length is 1 + m. The offset is the little-endian unsigned
|
||||
integer denoted by the next 4 bytes.
|
||||
*/
|
||||
const (
|
||||
tagLiteral = 0x00
|
||||
tagCopy1 = 0x01
|
||||
tagCopy2 = 0x02
|
||||
tagCopy4 = 0x03
|
||||
)
|
||||
|
||||
const (
|
||||
checksumSize = 4
|
||||
chunkHeaderSize = 4
|
||||
magicChunk = "\xff\x06\x00\x00" + magicBody
|
||||
magicBody = "sNaPpY"
|
||||
|
||||
// maxBlockSize is the maximum size of the input to encodeBlock. It is not
|
||||
// part of the wire format per se, but some parts of the encoder assume
|
||||
// that an offset fits into a uint16.
|
||||
//
|
||||
// Also, for the framing format (Writer type instead of Encode function),
|
||||
// https://github.com/google/snappy/blob/master/framing_format.txt says
|
||||
// that "the uncompressed data in a chunk must be no longer than 65536
|
||||
// bytes".
|
||||
maxBlockSize = 65536
|
||||
|
||||
// maxEncodedLenOfMaxBlockSize equals MaxEncodedLen(maxBlockSize), but is
|
||||
// hard coded to be a const instead of a variable, so that obufLen can also
|
||||
// be a const. Their equivalence is confirmed by
|
||||
// TestMaxEncodedLenOfMaxBlockSize.
|
||||
maxEncodedLenOfMaxBlockSize = 76490
|
||||
|
||||
obufHeaderLen = len(magicChunk) + checksumSize + chunkHeaderSize
|
||||
obufLen = obufHeaderLen + maxEncodedLenOfMaxBlockSize
|
||||
)
|
||||
|
||||
const (
|
||||
chunkTypeCompressedData = 0x00
|
||||
chunkTypeUncompressedData = 0x01
|
||||
chunkTypePadding = 0xfe
|
||||
chunkTypeStreamIdentifier = 0xff
|
||||
)
|
||||
|
||||
var crcTable = crc32.MakeTable(crc32.Castagnoli)
|
||||
|
||||
// crc implements the checksum specified in section 3 of
|
||||
// https://github.com/google/snappy/blob/master/framing_format.txt
|
||||
func crc(b []byte) uint32 {
|
||||
c := crc32.Update(0, crcTable, b)
|
||||
return uint32(c>>15|c<<17) + 0xa282ead8
|
||||
}
|
||||
201
vendor/github.com/kubernetes-csi/external-snapshotter/v2/LICENSE
generated
vendored
Normal file
201
vendor/github.com/kubernetes-csi/external-snapshotter/v2/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
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.
|
||||
20
vendor/github.com/kubernetes-csi/external-snapshotter/v2/pkg/apis/volumesnapshot/v1beta1/doc.go
generated
vendored
Normal file
20
vendor/github.com/kubernetes-csi/external-snapshotter/v2/pkg/apis/volumesnapshot/v1beta1/doc.go
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// +k8s:deepcopy-gen=package
|
||||
// +groupName=snapshot.storage.k8s.io
|
||||
|
||||
package v1beta1
|
||||
58
vendor/github.com/kubernetes-csi/external-snapshotter/v2/pkg/apis/volumesnapshot/v1beta1/register.go
generated
vendored
Normal file
58
vendor/github.com/kubernetes-csi/external-snapshotter/v2/pkg/apis/volumesnapshot/v1beta1/register.go
generated
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
// GroupName is the group name use in this package.
|
||||
const GroupName = "snapshot.storage.k8s.io"
|
||||
|
||||
var (
|
||||
// SchemeBuilder is the new scheme builder
|
||||
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
|
||||
// AddToScheme adds to scheme
|
||||
AddToScheme = SchemeBuilder.AddToScheme
|
||||
// SchemeGroupVersion is the group version used to register these objects.
|
||||
SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1beta1"}
|
||||
)
|
||||
|
||||
// Resource takes an unqualified resource and returns a Group-qualified GroupResource.
|
||||
func Resource(resource string) schema.GroupResource {
|
||||
return SchemeGroupVersion.WithResource(resource).GroupResource()
|
||||
}
|
||||
|
||||
func init() {
|
||||
// We only register manually written functions here. The registration of the
|
||||
// generated functions takes place in the generated files. The separation
|
||||
// makes the code compile even when the generated files are missing.
|
||||
SchemeBuilder.Register(addKnownTypes)
|
||||
}
|
||||
|
||||
// addKnownTypes adds the set of types defined in this package to the supplied scheme.
|
||||
func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&VolumeSnapshotClass{},
|
||||
&VolumeSnapshotClassList{},
|
||||
&VolumeSnapshot{},
|
||||
&VolumeSnapshotList{},
|
||||
&VolumeSnapshotContent{},
|
||||
&VolumeSnapshotContentList{},
|
||||
)
|
||||
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
|
||||
return nil
|
||||
}
|
||||
395
vendor/github.com/kubernetes-csi/external-snapshotter/v2/pkg/apis/volumesnapshot/v1beta1/types.go
generated
vendored
Normal file
395
vendor/github.com/kubernetes-csi/external-snapshotter/v2/pkg/apis/volumesnapshot/v1beta1/types.go
generated
vendored
Normal file
@@ -0,0 +1,395 @@
|
||||
/*
|
||||
Copyright 2019 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// +kubebuilder:object:generate=true
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
core_v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// +genclient
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// VolumeSnapshot is a user's request for either creating a point-in-time
|
||||
// snapshot of a persistent volume, or binding to a pre-existing snapshot.
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:resource:scope=Namespaced
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:printcolumn:name="ReadyToUse",type=boolean,JSONPath=`.status.readyToUse`,description="Indicates if a snapshot is ready to be used to restore a volume."
|
||||
// +kubebuilder:printcolumn:name="SourcePVC",type=string,JSONPath=`.spec.source.persistentVolumeClaimName`,description="Name of the source PVC from where a dynamically taken snapshot will be created."
|
||||
// +kubebuilder:printcolumn:name="SourceSnapshotContent",type=string,JSONPath=`.spec.source.volumeSnapshotContentName`,description="Name of the VolumeSnapshotContent which represents a pre-provisioned snapshot."
|
||||
// +kubebuilder:printcolumn:name="RestoreSize",type=string,JSONPath=`.status.restoreSize`,description="Represents the complete size of the snapshot."
|
||||
// +kubebuilder:printcolumn:name="SnapshotClass",type=string,JSONPath=`.spec.volumeSnapshotClassName`,description="The name of the VolumeSnapshotClass requested by the VolumeSnapshot."
|
||||
// +kubebuilder:printcolumn:name="SnapshotContent",type=string,JSONPath=`.status.boundVolumeSnapshotContentName`,description="The name of the VolumeSnapshotContent to which this VolumeSnapshot is bound."
|
||||
// +kubebuilder:printcolumn:name="CreationTime",type=date,JSONPath=`.status.creationTime`,description="Timestamp when the point-in-time snapshot is taken by the underlying storage system."
|
||||
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
|
||||
type VolumeSnapshot struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
// Standard object's metadata.
|
||||
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata
|
||||
// +optional
|
||||
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
|
||||
|
||||
// spec defines the desired characteristics of a snapshot requested by a user.
|
||||
// More info: https://kubernetes.io/docs/concepts/storage/volume-snapshots#volumesnapshots
|
||||
// Required.
|
||||
Spec VolumeSnapshotSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"`
|
||||
|
||||
// status represents the current information of a snapshot.
|
||||
// NOTE: status can be modified by sources other than system controllers,
|
||||
// and must not be depended upon for accuracy.
|
||||
// Controllers should only use information from the VolumeSnapshotContent object
|
||||
// after verifying that the binding is accurate and complete.
|
||||
// +optional
|
||||
Status *VolumeSnapshotStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
// VolumeSnapshotList is a list of VolumeSnapshot objects
|
||||
type VolumeSnapshotList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
// +optional
|
||||
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
|
||||
|
||||
// List of VolumeSnapshots
|
||||
Items []VolumeSnapshot `json:"items" protobuf:"bytes,2,rep,name=items"`
|
||||
}
|
||||
|
||||
// VolumeSnapshotSpec describes the common attributes of a volume snapshot.
|
||||
type VolumeSnapshotSpec struct {
|
||||
// source specifies where a snapshot will be created from.
|
||||
// This field is immutable after creation.
|
||||
// Required.
|
||||
Source VolumeSnapshotSource `json:"source" protobuf:"bytes,1,opt,name=source"`
|
||||
|
||||
// volumeSnapshotClassName is the name of the VolumeSnapshotClass requested by the VolumeSnapshot.
|
||||
// If not specified, the default snapshot class will be used if one exists.
|
||||
// If not specified, and there is no default snapshot class, dynamic snapshot creation will fail.
|
||||
// Empty string is not allowed for this field.
|
||||
// TODO(xiangqian): a webhook validation on empty string.
|
||||
// More info: https://kubernetes.io/docs/concepts/storage/volume-snapshot-classes
|
||||
// +optional
|
||||
VolumeSnapshotClassName *string `json:"volumeSnapshotClassName,omitempty" protobuf:"bytes,2,opt,name=volumeSnapshotClassName"`
|
||||
}
|
||||
|
||||
// VolumeSnapshotSource specifies whether the underlying snapshot should be
|
||||
// dynamically taken upon creation or if a pre-existing VolumeSnapshotContent
|
||||
// object should be used.
|
||||
// Exactly one of its members must be set.
|
||||
// Members in VolumeSnapshotSource are immutable.
|
||||
// TODO(xiangqian): Add a webhook to ensure that VolumeSnapshotSource members
|
||||
// will not be updated once specified.
|
||||
type VolumeSnapshotSource struct {
|
||||
// persistentVolumeClaimName specifies the name of the PersistentVolumeClaim
|
||||
// object in the same namespace as the VolumeSnapshot object where the
|
||||
// snapshot should be dynamically taken from.
|
||||
// This field is immutable.
|
||||
// +optional
|
||||
PersistentVolumeClaimName *string `json:"persistentVolumeClaimName,omitempty" protobuf:"bytes,1,opt,name=persistentVolumeClaimName"`
|
||||
|
||||
// volumeSnapshotContentName specifies the name of a pre-existing VolumeSnapshotContent
|
||||
// object.
|
||||
// This field is immutable.
|
||||
// +optional
|
||||
VolumeSnapshotContentName *string `json:"volumeSnapshotContentName,omitempty" protobuf:"bytes,2,opt,name=volumeSnapshotContentName"`
|
||||
}
|
||||
|
||||
// VolumeSnapshotStatus is the status of the VolumeSnapshot
|
||||
type VolumeSnapshotStatus struct {
|
||||
// boundVolumeSnapshotContentName represents the name of the VolumeSnapshotContent
|
||||
// object to which the VolumeSnapshot object is bound.
|
||||
// If not specified, it indicates that the VolumeSnapshot object has not been
|
||||
// successfully bound to a VolumeSnapshotContent object yet.
|
||||
// NOTE: Specified boundVolumeSnapshotContentName alone does not mean binding
|
||||
// is valid. Controllers MUST always verify bidirectional binding between
|
||||
// VolumeSnapshot and VolumeSnapshotContent to avoid possible security issues.
|
||||
// +optional
|
||||
BoundVolumeSnapshotContentName *string `json:"boundVolumeSnapshotContentName,omitempty" protobuf:"bytes,1,opt,name=boundVolumeSnapshotContentName"`
|
||||
|
||||
// creationTime is the timestamp when the point-in-time snapshot is taken
|
||||
// by the underlying storage system.
|
||||
// In dynamic snapshot creation case, this field will be filled in with the
|
||||
// "creation_time" value returned from CSI "CreateSnapshotRequest" gRPC call.
|
||||
// For a pre-existing snapshot, this field will be filled with the "creation_time"
|
||||
// value returned from the CSI "ListSnapshots" gRPC call if the driver supports it.
|
||||
// If not specified, it indicates that the creation time of the snapshot is unknown.
|
||||
// +optional
|
||||
CreationTime *metav1.Time `json:"creationTime,omitempty" protobuf:"bytes,2,opt,name=creationTime"`
|
||||
|
||||
// readyToUse indicates if a snapshot is ready to be used to restore a volume.
|
||||
// In dynamic snapshot creation case, this field will be filled in with the
|
||||
// "ready_to_use" value returned from CSI "CreateSnapshotRequest" gRPC call.
|
||||
// For a pre-existing snapshot, this field will be filled with the "ready_to_use"
|
||||
// value returned from the CSI "ListSnapshots" gRPC call if the driver supports it,
|
||||
// otherwise, this field will be set to "True".
|
||||
// If not specified, it means the readiness of a snapshot is unknown.
|
||||
// +optional
|
||||
ReadyToUse *bool `json:"readyToUse,omitempty" protobuf:"varint,3,opt,name=readyToUse"`
|
||||
|
||||
// restoreSize represents the complete size of the snapshot in bytes.
|
||||
// In dynamic snapshot creation case, this field will be filled in with the
|
||||
// "size_bytes" value returned from CSI "CreateSnapshotRequest" gRPC call.
|
||||
// For a pre-existing snapshot, this field will be filled with the "size_bytes"
|
||||
// value returned from the CSI "ListSnapshots" gRPC call if the driver supports it.
|
||||
// When restoring a volume from this snapshot, the size of the volume MUST NOT
|
||||
// be smaller than the restoreSize if it is specified, otherwise the restoration will fail.
|
||||
// If not specified, it indicates that the size is unknown.
|
||||
// +optional
|
||||
RestoreSize *resource.Quantity `json:"restoreSize,omitempty" protobuf:"bytes,4,opt,name=restoreSize"`
|
||||
|
||||
// error is the last observed error during snapshot creation, if any.
|
||||
// This field could be helpful to upper level controllers(i.e., application controller)
|
||||
// to decide whether they should continue on waiting for the snapshot to be created
|
||||
// based on the type of error reported.
|
||||
// +optional
|
||||
Error *VolumeSnapshotError `json:"error,omitempty" protobuf:"bytes,5,opt,name=error,casttype=VolumeSnapshotError"`
|
||||
}
|
||||
|
||||
// +genclient
|
||||
// +genclient:nonNamespaced
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// VolumeSnapshotClass specifies parameters that a underlying storage system uses when
|
||||
// creating a volume snapshot. A specific VolumeSnapshotClass is used by specifying its
|
||||
// name in a VolumeSnapshot object.
|
||||
// VolumeSnapshotClasses are non-namespaced
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:resource:scope=Cluster
|
||||
// +kubebuilder:printcolumn:name="Driver",type=string,JSONPath=`.driver`
|
||||
// +kubebuilder:printcolumn:name="DeletionPolicy",type=string,JSONPath=`.deletionPolicy`,description="Determines whether a VolumeSnapshotContent created through the VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted."
|
||||
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
|
||||
type VolumeSnapshotClass struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
// Standard object's metadata.
|
||||
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata
|
||||
// +optional
|
||||
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
|
||||
|
||||
// driver is the name of the storage driver that handles this VolumeSnapshotClass.
|
||||
// Required.
|
||||
Driver string `json:"driver" protobuf:"bytes,2,opt,name=driver"`
|
||||
|
||||
// parameters is a key-value map with storage driver specific parameters for creating snapshots.
|
||||
// These values are opaque to Kubernetes.
|
||||
// +optional
|
||||
Parameters map[string]string `json:"parameters,omitempty" protobuf:"bytes,3,rep,name=parameters"`
|
||||
|
||||
// deletionPolicy determines whether a VolumeSnapshotContent created through
|
||||
// the VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted.
|
||||
// Supported values are "Retain" and "Delete".
|
||||
// "Retain" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are kept.
|
||||
// "Delete" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are deleted.
|
||||
// Required.
|
||||
DeletionPolicy DeletionPolicy `json:"deletionPolicy" protobuf:"bytes,4,opt,name=deletionPolicy"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// VolumeSnapshotClassList is a collection of VolumeSnapshotClasses.
|
||||
// +kubebuilder:object:root=true
|
||||
type VolumeSnapshotClassList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
// Standard list metadata
|
||||
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata
|
||||
// +optional
|
||||
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
|
||||
|
||||
// items is the list of VolumeSnapshotClasses
|
||||
Items []VolumeSnapshotClass `json:"items" protobuf:"bytes,2,rep,name=items"`
|
||||
}
|
||||
|
||||
// +genclient
|
||||
// +genclient:nonNamespaced
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// VolumeSnapshotContent represents the actual "on-disk" snapshot object in the
|
||||
// underlying storage system
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:resource:scope=Cluster
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:printcolumn:name="ReadyToUse",type=boolean,JSONPath=`.status.readyToUse`,description="Indicates if a snapshot is ready to be used to restore a volume."
|
||||
// +kubebuilder:printcolumn:name="RestoreSize",type=integer,JSONPath=`.status.restoreSize`,description="Represents the complete size of the snapshot in bytes"
|
||||
// +kubebuilder:printcolumn:name="DeletionPolicy",type=string,JSONPath=`.spec.deletionPolicy`,description="Determines whether this VolumeSnapshotContent and its physical snapshot on the underlying storage system should be deleted when its bound VolumeSnapshot is deleted."
|
||||
// +kubebuilder:printcolumn:name="Driver",type=string,JSONPath=`.spec.driver`,description="Name of the CSI driver used to create the physical snapshot on the underlying storage system."
|
||||
// +kubebuilder:printcolumn:name="VolumeSnapshotClass",type=string,JSONPath=`.spec.volumeSnapshotClassName`,description="Name of the VolumeSnapshotClass to which this snapshot belongs."
|
||||
// +kubebuilder:printcolumn:name="VolumeSnapshot",type=string,JSONPath=`.spec.volumeSnapshotRef.name`,description="Name of the VolumeSnapshot object to which this VolumeSnapshotContent object is bound."
|
||||
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
|
||||
type VolumeSnapshotContent struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
// Standard object's metadata.
|
||||
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata
|
||||
// +optional
|
||||
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
|
||||
|
||||
// spec defines properties of a VolumeSnapshotContent created by the underlying storage system.
|
||||
// Required.
|
||||
Spec VolumeSnapshotContentSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"`
|
||||
|
||||
// status represents the current information of a snapshot.
|
||||
// +optional
|
||||
Status *VolumeSnapshotContentStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// VolumeSnapshotContentList is a list of VolumeSnapshotContent objects
|
||||
// +kubebuilder:object:root=true
|
||||
type VolumeSnapshotContentList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
// +optional
|
||||
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
|
||||
|
||||
// items is the list of VolumeSnapshotContents
|
||||
Items []VolumeSnapshotContent `json:"items" protobuf:"bytes,2,rep,name=items"`
|
||||
}
|
||||
|
||||
// VolumeSnapshotContentSpec is the specification of a VolumeSnapshotContent
|
||||
type VolumeSnapshotContentSpec struct {
|
||||
// volumeSnapshotRef specifies the VolumeSnapshot object to which this
|
||||
// VolumeSnapshotContent object is bound.
|
||||
// VolumeSnapshot.Spec.VolumeSnapshotContentName field must reference to
|
||||
// this VolumeSnapshotContent's name for the bidirectional binding to be valid.
|
||||
// For a pre-existing VolumeSnapshotContent object, name and namespace of the
|
||||
// VolumeSnapshot object MUST be provided for binding to happen.
|
||||
// This field is immutable after creation.
|
||||
// Required.
|
||||
VolumeSnapshotRef core_v1.ObjectReference `json:"volumeSnapshotRef" protobuf:"bytes,1,opt,name=volumeSnapshotRef"`
|
||||
|
||||
// deletionPolicy determines whether this VolumeSnapshotContent and its physical snapshot on
|
||||
// the underlying storage system should be deleted when its bound VolumeSnapshot is deleted.
|
||||
// Supported values are "Retain" and "Delete".
|
||||
// "Retain" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are kept.
|
||||
// "Delete" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are deleted.
|
||||
// In dynamic snapshot creation case, this field will be filled in with the "DeletionPolicy" field defined in the
|
||||
// VolumeSnapshotClass the VolumeSnapshot refers to.
|
||||
// For pre-existing snapshots, users MUST specify this field when creating the VolumeSnapshotContent object.
|
||||
// Required.
|
||||
DeletionPolicy DeletionPolicy `json:"deletionPolicy" protobuf:"bytes,2,opt,name=deletionPolicy"`
|
||||
|
||||
// driver is the name of the CSI driver used to create the physical snapshot on
|
||||
// the underlying storage system.
|
||||
// This MUST be the same as the name returned by the CSI GetPluginName() call for
|
||||
// that driver.
|
||||
// Required.
|
||||
Driver string `json:"driver" protobuf:"bytes,3,opt,name=driver"`
|
||||
|
||||
// name of the VolumeSnapshotClass to which this snapshot belongs.
|
||||
// +optional
|
||||
VolumeSnapshotClassName *string `json:"volumeSnapshotClassName,omitempty" protobuf:"bytes,4,opt,name=volumeSnapshotClassName"`
|
||||
|
||||
// source specifies from where a snapshot will be created.
|
||||
// This field is immutable after creation.
|
||||
// Required.
|
||||
Source VolumeSnapshotContentSource `json:"source" protobuf:"bytes,5,opt,name=source"`
|
||||
}
|
||||
|
||||
// VolumeSnapshotContentSource represents the CSI source of a snapshot.
|
||||
// Exactly one of its members must be set.
|
||||
// Members in VolumeSnapshotContentSource are immutable.
|
||||
// TODO(xiangqian): Add a webhook to ensure that VolumeSnapshotContentSource members
|
||||
// will be immutable once specified.
|
||||
type VolumeSnapshotContentSource struct {
|
||||
// volumeHandle specifies the CSI "volume_id" of the volume from which a snapshot
|
||||
// should be dynamically taken from.
|
||||
// This field is immutable.
|
||||
// +optional
|
||||
VolumeHandle *string `json:"volumeHandle,omitempty" protobuf:"bytes,1,opt,name=volumeHandle"`
|
||||
|
||||
// snapshotHandle specifies the CSI "snapshot_id" of a pre-existing snapshot on
|
||||
// the underlying storage system.
|
||||
// This field is immutable.
|
||||
// +optional
|
||||
SnapshotHandle *string `json:"snapshotHandle,omitempty" protobuf:"bytes,2,opt,name=snapshotHandle"`
|
||||
}
|
||||
|
||||
// VolumeSnapshotContentStatus is the status of a VolumeSnapshotContent object
|
||||
type VolumeSnapshotContentStatus struct {
|
||||
// snapshotHandle is the CSI "snapshot_id" of a snapshot on the underlying storage system.
|
||||
// If not specified, it indicates that dynamic snapshot creation has either failed
|
||||
// or it is still in progress.
|
||||
// +optional
|
||||
SnapshotHandle *string `json:"snapshotHandle,omitempty" protobuf:"bytes,1,opt,name=snapshotHandle"`
|
||||
|
||||
// creationTime is the timestamp when the point-in-time snapshot is taken
|
||||
// by the underlying storage system.
|
||||
// In dynamic snapshot creation case, this field will be filled in with the
|
||||
// "creation_time" value returned from CSI "CreateSnapshotRequest" gRPC call.
|
||||
// For a pre-existing snapshot, this field will be filled with the "creation_time"
|
||||
// value returned from the CSI "ListSnapshots" gRPC call if the driver supports it.
|
||||
// If not specified, it indicates the creation time is unknown.
|
||||
// The format of this field is a Unix nanoseconds time encoded as an int64.
|
||||
// On Unix, the command `date +%s%N` returns the current time in nanoseconds
|
||||
// since 1970-01-01 00:00:00 UTC.
|
||||
// +optional
|
||||
CreationTime *int64 `json:"creationTime,omitempty" protobuf:"varint,2,opt,name=creationTime"`
|
||||
|
||||
// restoreSize represents the complete size of the snapshot in bytes.
|
||||
// In dynamic snapshot creation case, this field will be filled in with the
|
||||
// "size_bytes" value returned from CSI "CreateSnapshotRequest" gRPC call.
|
||||
// For a pre-existing snapshot, this field will be filled with the "size_bytes"
|
||||
// value returned from the CSI "ListSnapshots" gRPC call if the driver supports it.
|
||||
// When restoring a volume from this snapshot, the size of the volume MUST NOT
|
||||
// be smaller than the restoreSize if it is specified, otherwise the restoration will fail.
|
||||
// If not specified, it indicates that the size is unknown.
|
||||
// +kubebuilder:validation:Minimum=0
|
||||
// +optional
|
||||
RestoreSize *int64 `json:"restoreSize,omitempty" protobuf:"bytes,3,opt,name=restoreSize"`
|
||||
|
||||
// readyToUse indicates if a snapshot is ready to be used to restore a volume.
|
||||
// In dynamic snapshot creation case, this field will be filled in with the
|
||||
// "ready_to_use" value returned from CSI "CreateSnapshotRequest" gRPC call.
|
||||
// For a pre-existing snapshot, this field will be filled with the "ready_to_use"
|
||||
// value returned from the CSI "ListSnapshots" gRPC call if the driver supports it,
|
||||
// otherwise, this field will be set to "True".
|
||||
// If not specified, it means the readiness of a snapshot is unknown.
|
||||
// +optional.
|
||||
ReadyToUse *bool `json:"readyToUse,omitempty" protobuf:"varint,4,opt,name=readyToUse"`
|
||||
|
||||
// error is the latest observed error during snapshot creation, if any.
|
||||
// +optional
|
||||
Error *VolumeSnapshotError `json:"error,omitempty" protobuf:"bytes,5,opt,name=error,casttype=VolumeSnapshotError"`
|
||||
}
|
||||
|
||||
// DeletionPolicy describes a policy for end-of-life maintenance of volume snapshot contents
|
||||
// +kubebuilder:validation:Enum=Delete;Retain
|
||||
type DeletionPolicy string
|
||||
|
||||
const (
|
||||
// volumeSnapshotContentDelete means the snapshot will be deleted from the
|
||||
// underlying storage system on release from its volume snapshot.
|
||||
VolumeSnapshotContentDelete DeletionPolicy = "Delete"
|
||||
|
||||
// volumeSnapshotContentRetain means the snapshot will be left in its current
|
||||
// state on release from its volume snapshot.
|
||||
VolumeSnapshotContentRetain DeletionPolicy = "Retain"
|
||||
)
|
||||
|
||||
// VolumeSnapshotError describes an error encountered during snapshot creation.
|
||||
type VolumeSnapshotError struct {
|
||||
// time is the timestamp when the error was encountered.
|
||||
// +optional
|
||||
Time *metav1.Time `json:"time,omitempty" protobuf:"bytes,1,opt,name=time"`
|
||||
|
||||
// message is a string detailing the encountered error during snapshot
|
||||
// creation if specified.
|
||||
// NOTE: message may be logged, and it should not contain sensitive
|
||||
// information.
|
||||
// +optional
|
||||
Message *string `json:"message,omitempty" protobuf:"bytes,2,opt,name=message"`
|
||||
}
|
||||
424
vendor/github.com/kubernetes-csi/external-snapshotter/v2/pkg/apis/volumesnapshot/v1beta1/zz_generated.deepcopy.go
generated
vendored
Normal file
424
vendor/github.com/kubernetes-csi/external-snapshotter/v2/pkg/apis/volumesnapshot/v1beta1/zz_generated.deepcopy.go
generated
vendored
Normal file
@@ -0,0 +1,424 @@
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright 2019 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by deepcopy-gen. DO NOT EDIT.
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
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 *VolumeSnapshot) DeepCopyInto(out *VolumeSnapshot) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
if in.Status != nil {
|
||||
in, out := &in.Status, &out.Status
|
||||
*out = new(VolumeSnapshotStatus)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeSnapshot.
|
||||
func (in *VolumeSnapshot) DeepCopy() *VolumeSnapshot {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(VolumeSnapshot)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *VolumeSnapshot) 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 *VolumeSnapshotClass) DeepCopyInto(out *VolumeSnapshotClass) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
if in.Parameters != nil {
|
||||
in, out := &in.Parameters, &out.Parameters
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeSnapshotClass.
|
||||
func (in *VolumeSnapshotClass) DeepCopy() *VolumeSnapshotClass {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(VolumeSnapshotClass)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *VolumeSnapshotClass) 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 *VolumeSnapshotClassList) DeepCopyInto(out *VolumeSnapshotClassList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]VolumeSnapshotClass, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeSnapshotClassList.
|
||||
func (in *VolumeSnapshotClassList) DeepCopy() *VolumeSnapshotClassList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(VolumeSnapshotClassList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *VolumeSnapshotClassList) 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 *VolumeSnapshotContent) DeepCopyInto(out *VolumeSnapshotContent) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
if in.Status != nil {
|
||||
in, out := &in.Status, &out.Status
|
||||
*out = new(VolumeSnapshotContentStatus)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeSnapshotContent.
|
||||
func (in *VolumeSnapshotContent) DeepCopy() *VolumeSnapshotContent {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(VolumeSnapshotContent)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *VolumeSnapshotContent) 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 *VolumeSnapshotContentList) DeepCopyInto(out *VolumeSnapshotContentList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]VolumeSnapshotContent, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeSnapshotContentList.
|
||||
func (in *VolumeSnapshotContentList) DeepCopy() *VolumeSnapshotContentList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(VolumeSnapshotContentList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *VolumeSnapshotContentList) 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 *VolumeSnapshotContentSource) DeepCopyInto(out *VolumeSnapshotContentSource) {
|
||||
*out = *in
|
||||
if in.VolumeHandle != nil {
|
||||
in, out := &in.VolumeHandle, &out.VolumeHandle
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.SnapshotHandle != nil {
|
||||
in, out := &in.SnapshotHandle, &out.SnapshotHandle
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeSnapshotContentSource.
|
||||
func (in *VolumeSnapshotContentSource) DeepCopy() *VolumeSnapshotContentSource {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(VolumeSnapshotContentSource)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *VolumeSnapshotContentSpec) DeepCopyInto(out *VolumeSnapshotContentSpec) {
|
||||
*out = *in
|
||||
out.VolumeSnapshotRef = in.VolumeSnapshotRef
|
||||
if in.VolumeSnapshotClassName != nil {
|
||||
in, out := &in.VolumeSnapshotClassName, &out.VolumeSnapshotClassName
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
in.Source.DeepCopyInto(&out.Source)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeSnapshotContentSpec.
|
||||
func (in *VolumeSnapshotContentSpec) DeepCopy() *VolumeSnapshotContentSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(VolumeSnapshotContentSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *VolumeSnapshotContentStatus) DeepCopyInto(out *VolumeSnapshotContentStatus) {
|
||||
*out = *in
|
||||
if in.SnapshotHandle != nil {
|
||||
in, out := &in.SnapshotHandle, &out.SnapshotHandle
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.CreationTime != nil {
|
||||
in, out := &in.CreationTime, &out.CreationTime
|
||||
*out = new(int64)
|
||||
**out = **in
|
||||
}
|
||||
if in.RestoreSize != nil {
|
||||
in, out := &in.RestoreSize, &out.RestoreSize
|
||||
*out = new(int64)
|
||||
**out = **in
|
||||
}
|
||||
if in.ReadyToUse != nil {
|
||||
in, out := &in.ReadyToUse, &out.ReadyToUse
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
if in.Error != nil {
|
||||
in, out := &in.Error, &out.Error
|
||||
*out = new(VolumeSnapshotError)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeSnapshotContentStatus.
|
||||
func (in *VolumeSnapshotContentStatus) DeepCopy() *VolumeSnapshotContentStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(VolumeSnapshotContentStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *VolumeSnapshotError) DeepCopyInto(out *VolumeSnapshotError) {
|
||||
*out = *in
|
||||
if in.Time != nil {
|
||||
in, out := &in.Time, &out.Time
|
||||
*out = (*in).DeepCopy()
|
||||
}
|
||||
if in.Message != nil {
|
||||
in, out := &in.Message, &out.Message
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeSnapshotError.
|
||||
func (in *VolumeSnapshotError) DeepCopy() *VolumeSnapshotError {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(VolumeSnapshotError)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *VolumeSnapshotList) DeepCopyInto(out *VolumeSnapshotList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]VolumeSnapshot, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeSnapshotList.
|
||||
func (in *VolumeSnapshotList) DeepCopy() *VolumeSnapshotList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(VolumeSnapshotList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *VolumeSnapshotList) 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 *VolumeSnapshotSource) DeepCopyInto(out *VolumeSnapshotSource) {
|
||||
*out = *in
|
||||
if in.PersistentVolumeClaimName != nil {
|
||||
in, out := &in.PersistentVolumeClaimName, &out.PersistentVolumeClaimName
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.VolumeSnapshotContentName != nil {
|
||||
in, out := &in.VolumeSnapshotContentName, &out.VolumeSnapshotContentName
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeSnapshotSource.
|
||||
func (in *VolumeSnapshotSource) DeepCopy() *VolumeSnapshotSource {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(VolumeSnapshotSource)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *VolumeSnapshotSpec) DeepCopyInto(out *VolumeSnapshotSpec) {
|
||||
*out = *in
|
||||
in.Source.DeepCopyInto(&out.Source)
|
||||
if in.VolumeSnapshotClassName != nil {
|
||||
in, out := &in.VolumeSnapshotClassName, &out.VolumeSnapshotClassName
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeSnapshotSpec.
|
||||
func (in *VolumeSnapshotSpec) DeepCopy() *VolumeSnapshotSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(VolumeSnapshotSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *VolumeSnapshotStatus) DeepCopyInto(out *VolumeSnapshotStatus) {
|
||||
*out = *in
|
||||
if in.BoundVolumeSnapshotContentName != nil {
|
||||
in, out := &in.BoundVolumeSnapshotContentName, &out.BoundVolumeSnapshotContentName
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.CreationTime != nil {
|
||||
in, out := &in.CreationTime, &out.CreationTime
|
||||
*out = (*in).DeepCopy()
|
||||
}
|
||||
if in.ReadyToUse != nil {
|
||||
in, out := &in.ReadyToUse, &out.ReadyToUse
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
if in.RestoreSize != nil {
|
||||
in, out := &in.RestoreSize, &out.RestoreSize
|
||||
x := (*in).DeepCopy()
|
||||
*out = &x
|
||||
}
|
||||
if in.Error != nil {
|
||||
in, out := &in.Error, &out.Error
|
||||
*out = new(VolumeSnapshotError)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeSnapshotStatus.
|
||||
func (in *VolumeSnapshotStatus) DeepCopy() *VolumeSnapshotStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(VolumeSnapshotStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
97
vendor/github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/clientset/versioned/clientset.go
generated
vendored
Normal file
97
vendor/github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/clientset/versioned/clientset.go
generated
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
Copyright 2019 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package versioned
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
snapshotv1beta1 "github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/clientset/versioned/typed/volumesnapshot/v1beta1"
|
||||
discovery "k8s.io/client-go/discovery"
|
||||
rest "k8s.io/client-go/rest"
|
||||
flowcontrol "k8s.io/client-go/util/flowcontrol"
|
||||
)
|
||||
|
||||
type Interface interface {
|
||||
Discovery() discovery.DiscoveryInterface
|
||||
SnapshotV1beta1() snapshotv1beta1.SnapshotV1beta1Interface
|
||||
}
|
||||
|
||||
// Clientset contains the clients for groups. Each group has exactly one
|
||||
// version included in a Clientset.
|
||||
type Clientset struct {
|
||||
*discovery.DiscoveryClient
|
||||
snapshotV1beta1 *snapshotv1beta1.SnapshotV1beta1Client
|
||||
}
|
||||
|
||||
// SnapshotV1beta1 retrieves the SnapshotV1beta1Client
|
||||
func (c *Clientset) SnapshotV1beta1() snapshotv1beta1.SnapshotV1beta1Interface {
|
||||
return c.snapshotV1beta1
|
||||
}
|
||||
|
||||
// Discovery retrieves the DiscoveryClient
|
||||
func (c *Clientset) Discovery() discovery.DiscoveryInterface {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.DiscoveryClient
|
||||
}
|
||||
|
||||
// NewForConfig creates a new Clientset for the given config.
|
||||
// If config's RateLimiter is not set and QPS and Burst are acceptable,
|
||||
// NewForConfig will generate a rate-limiter in configShallowCopy.
|
||||
func NewForConfig(c *rest.Config) (*Clientset, error) {
|
||||
configShallowCopy := *c
|
||||
if configShallowCopy.RateLimiter == nil && configShallowCopy.QPS > 0 {
|
||||
if configShallowCopy.Burst <= 0 {
|
||||
return nil, fmt.Errorf("Burst is required to be greater than 0 when RateLimiter is not set and QPS is set to greater than 0")
|
||||
}
|
||||
configShallowCopy.RateLimiter = flowcontrol.NewTokenBucketRateLimiter(configShallowCopy.QPS, configShallowCopy.Burst)
|
||||
}
|
||||
var cs Clientset
|
||||
var err error
|
||||
cs.snapshotV1beta1, err = snapshotv1beta1.NewForConfig(&configShallowCopy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfig(&configShallowCopy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &cs, nil
|
||||
}
|
||||
|
||||
// NewForConfigOrDie creates a new Clientset for the given config and
|
||||
// panics if there is an error in the config.
|
||||
func NewForConfigOrDie(c *rest.Config) *Clientset {
|
||||
var cs Clientset
|
||||
cs.snapshotV1beta1 = snapshotv1beta1.NewForConfigOrDie(c)
|
||||
|
||||
cs.DiscoveryClient = discovery.NewDiscoveryClientForConfigOrDie(c)
|
||||
return &cs
|
||||
}
|
||||
|
||||
// New creates a new Clientset for the given RESTClient.
|
||||
func New(c rest.Interface) *Clientset {
|
||||
var cs Clientset
|
||||
cs.snapshotV1beta1 = snapshotv1beta1.New(c)
|
||||
|
||||
cs.DiscoveryClient = discovery.NewDiscoveryClient(c)
|
||||
return &cs
|
||||
}
|
||||
20
vendor/github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/clientset/versioned/doc.go
generated
vendored
Normal file
20
vendor/github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/clientset/versioned/doc.go
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
Copyright 2019 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
// This package has the automatically generated clientset.
|
||||
package versioned
|
||||
20
vendor/github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/clientset/versioned/scheme/doc.go
generated
vendored
Normal file
20
vendor/github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/clientset/versioned/scheme/doc.go
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
Copyright 2019 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
// This package contains the scheme of the automatically generated clientset.
|
||||
package scheme
|
||||
56
vendor/github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/clientset/versioned/scheme/register.go
generated
vendored
Normal file
56
vendor/github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/clientset/versioned/scheme/register.go
generated
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
Copyright 2019 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package scheme
|
||||
|
||||
import (
|
||||
snapshotv1beta1 "github.com/kubernetes-csi/external-snapshotter/v2/pkg/apis/volumesnapshot/v1beta1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
serializer "k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
)
|
||||
|
||||
var Scheme = runtime.NewScheme()
|
||||
var Codecs = serializer.NewCodecFactory(Scheme)
|
||||
var ParameterCodec = runtime.NewParameterCodec(Scheme)
|
||||
var localSchemeBuilder = runtime.SchemeBuilder{
|
||||
snapshotv1beta1.AddToScheme,
|
||||
}
|
||||
|
||||
// AddToScheme adds all types of this clientset into the given scheme. This allows composition
|
||||
// of clientsets, like in:
|
||||
//
|
||||
// import (
|
||||
// "k8s.io/client-go/kubernetes"
|
||||
// clientsetscheme "k8s.io/client-go/kubernetes/scheme"
|
||||
// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme"
|
||||
// )
|
||||
//
|
||||
// kclientset, _ := kubernetes.NewForConfig(c)
|
||||
// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme)
|
||||
//
|
||||
// After this, RawExtensions in Kubernetes types will serialize kube-aggregator types
|
||||
// correctly.
|
||||
var AddToScheme = localSchemeBuilder.AddToScheme
|
||||
|
||||
func init() {
|
||||
v1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: "v1"})
|
||||
utilruntime.Must(AddToScheme(Scheme))
|
||||
}
|
||||
20
vendor/github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/clientset/versioned/typed/volumesnapshot/v1beta1/doc.go
generated
vendored
Normal file
20
vendor/github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/clientset/versioned/typed/volumesnapshot/v1beta1/doc.go
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
Copyright 2019 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
// This package has the automatically generated typed clients.
|
||||
package v1beta1
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
Copyright 2019 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1beta1
|
||||
|
||||
type VolumeSnapshotExpansion interface{}
|
||||
|
||||
type VolumeSnapshotClassExpansion interface{}
|
||||
|
||||
type VolumeSnapshotContentExpansion interface{}
|
||||
191
vendor/github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/clientset/versioned/typed/volumesnapshot/v1beta1/volumesnapshot.go
generated
vendored
Normal file
191
vendor/github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/clientset/versioned/typed/volumesnapshot/v1beta1/volumesnapshot.go
generated
vendored
Normal file
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
Copyright 2019 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
v1beta1 "github.com/kubernetes-csi/external-snapshotter/v2/pkg/apis/volumesnapshot/v1beta1"
|
||||
scheme "github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/clientset/versioned/scheme"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
rest "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
// VolumeSnapshotsGetter has a method to return a VolumeSnapshotInterface.
|
||||
// A group's client should implement this interface.
|
||||
type VolumeSnapshotsGetter interface {
|
||||
VolumeSnapshots(namespace string) VolumeSnapshotInterface
|
||||
}
|
||||
|
||||
// VolumeSnapshotInterface has methods to work with VolumeSnapshot resources.
|
||||
type VolumeSnapshotInterface interface {
|
||||
Create(*v1beta1.VolumeSnapshot) (*v1beta1.VolumeSnapshot, error)
|
||||
Update(*v1beta1.VolumeSnapshot) (*v1beta1.VolumeSnapshot, error)
|
||||
UpdateStatus(*v1beta1.VolumeSnapshot) (*v1beta1.VolumeSnapshot, error)
|
||||
Delete(name string, options *v1.DeleteOptions) error
|
||||
DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error
|
||||
Get(name string, options v1.GetOptions) (*v1beta1.VolumeSnapshot, error)
|
||||
List(opts v1.ListOptions) (*v1beta1.VolumeSnapshotList, error)
|
||||
Watch(opts v1.ListOptions) (watch.Interface, error)
|
||||
Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1beta1.VolumeSnapshot, err error)
|
||||
VolumeSnapshotExpansion
|
||||
}
|
||||
|
||||
// volumeSnapshots implements VolumeSnapshotInterface
|
||||
type volumeSnapshots struct {
|
||||
client rest.Interface
|
||||
ns string
|
||||
}
|
||||
|
||||
// newVolumeSnapshots returns a VolumeSnapshots
|
||||
func newVolumeSnapshots(c *SnapshotV1beta1Client, namespace string) *volumeSnapshots {
|
||||
return &volumeSnapshots{
|
||||
client: c.RESTClient(),
|
||||
ns: namespace,
|
||||
}
|
||||
}
|
||||
|
||||
// Get takes name of the volumeSnapshot, and returns the corresponding volumeSnapshot object, and an error if there is any.
|
||||
func (c *volumeSnapshots) Get(name string, options v1.GetOptions) (result *v1beta1.VolumeSnapshot, err error) {
|
||||
result = &v1beta1.VolumeSnapshot{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("volumesnapshots").
|
||||
Name(name).
|
||||
VersionedParams(&options, scheme.ParameterCodec).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of VolumeSnapshots that match those selectors.
|
||||
func (c *volumeSnapshots) List(opts v1.ListOptions) (result *v1beta1.VolumeSnapshotList, err error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
result = &v1beta1.VolumeSnapshotList{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("volumesnapshots").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested volumeSnapshots.
|
||||
func (c *volumeSnapshots) Watch(opts v1.ListOptions) (watch.Interface, error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
opts.Watch = true
|
||||
return c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("volumesnapshots").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Watch()
|
||||
}
|
||||
|
||||
// Create takes the representation of a volumeSnapshot and creates it. Returns the server's representation of the volumeSnapshot, and an error, if there is any.
|
||||
func (c *volumeSnapshots) Create(volumeSnapshot *v1beta1.VolumeSnapshot) (result *v1beta1.VolumeSnapshot, err error) {
|
||||
result = &v1beta1.VolumeSnapshot{}
|
||||
err = c.client.Post().
|
||||
Namespace(c.ns).
|
||||
Resource("volumesnapshots").
|
||||
Body(volumeSnapshot).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a volumeSnapshot and updates it. Returns the server's representation of the volumeSnapshot, and an error, if there is any.
|
||||
func (c *volumeSnapshots) Update(volumeSnapshot *v1beta1.VolumeSnapshot) (result *v1beta1.VolumeSnapshot, err error) {
|
||||
result = &v1beta1.VolumeSnapshot{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("volumesnapshots").
|
||||
Name(volumeSnapshot.Name).
|
||||
Body(volumeSnapshot).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateStatus was generated because the type contains a Status member.
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
||||
|
||||
func (c *volumeSnapshots) UpdateStatus(volumeSnapshot *v1beta1.VolumeSnapshot) (result *v1beta1.VolumeSnapshot, err error) {
|
||||
result = &v1beta1.VolumeSnapshot{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("volumesnapshots").
|
||||
Name(volumeSnapshot.Name).
|
||||
SubResource("status").
|
||||
Body(volumeSnapshot).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the volumeSnapshot and deletes it. Returns an error if one occurs.
|
||||
func (c *volumeSnapshots) Delete(name string, options *v1.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("volumesnapshots").
|
||||
Name(name).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *volumeSnapshots) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
|
||||
var timeout time.Duration
|
||||
if listOptions.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second
|
||||
}
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("volumesnapshots").
|
||||
VersionedParams(&listOptions, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched volumeSnapshot.
|
||||
func (c *volumeSnapshots) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1beta1.VolumeSnapshot, err error) {
|
||||
result = &v1beta1.VolumeSnapshot{}
|
||||
err = c.client.Patch(pt).
|
||||
Namespace(c.ns).
|
||||
Resource("volumesnapshots").
|
||||
SubResource(subresources...).
|
||||
Name(name).
|
||||
Body(data).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
Copyright 2019 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
v1beta1 "github.com/kubernetes-csi/external-snapshotter/v2/pkg/apis/volumesnapshot/v1beta1"
|
||||
"github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/clientset/versioned/scheme"
|
||||
rest "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
type SnapshotV1beta1Interface interface {
|
||||
RESTClient() rest.Interface
|
||||
VolumeSnapshotsGetter
|
||||
VolumeSnapshotClassesGetter
|
||||
VolumeSnapshotContentsGetter
|
||||
}
|
||||
|
||||
// SnapshotV1beta1Client is used to interact with features provided by the snapshot.storage.k8s.io group.
|
||||
type SnapshotV1beta1Client struct {
|
||||
restClient rest.Interface
|
||||
}
|
||||
|
||||
func (c *SnapshotV1beta1Client) VolumeSnapshots(namespace string) VolumeSnapshotInterface {
|
||||
return newVolumeSnapshots(c, namespace)
|
||||
}
|
||||
|
||||
func (c *SnapshotV1beta1Client) VolumeSnapshotClasses() VolumeSnapshotClassInterface {
|
||||
return newVolumeSnapshotClasses(c)
|
||||
}
|
||||
|
||||
func (c *SnapshotV1beta1Client) VolumeSnapshotContents() VolumeSnapshotContentInterface {
|
||||
return newVolumeSnapshotContents(c)
|
||||
}
|
||||
|
||||
// NewForConfig creates a new SnapshotV1beta1Client for the given config.
|
||||
func NewForConfig(c *rest.Config) (*SnapshotV1beta1Client, error) {
|
||||
config := *c
|
||||
if err := setConfigDefaults(&config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client, err := rest.RESTClientFor(&config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &SnapshotV1beta1Client{client}, nil
|
||||
}
|
||||
|
||||
// NewForConfigOrDie creates a new SnapshotV1beta1Client for the given config and
|
||||
// panics if there is an error in the config.
|
||||
func NewForConfigOrDie(c *rest.Config) *SnapshotV1beta1Client {
|
||||
client, err := NewForConfig(c)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
// New creates a new SnapshotV1beta1Client for the given RESTClient.
|
||||
func New(c rest.Interface) *SnapshotV1beta1Client {
|
||||
return &SnapshotV1beta1Client{c}
|
||||
}
|
||||
|
||||
func setConfigDefaults(config *rest.Config) error {
|
||||
gv := v1beta1.SchemeGroupVersion
|
||||
config.GroupVersion = &gv
|
||||
config.APIPath = "/apis"
|
||||
config.NegotiatedSerializer = scheme.Codecs.WithoutConversion()
|
||||
|
||||
if config.UserAgent == "" {
|
||||
config.UserAgent = rest.DefaultKubernetesUserAgent()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RESTClient returns a RESTClient that is used to communicate
|
||||
// with API server by this client implementation.
|
||||
func (c *SnapshotV1beta1Client) RESTClient() rest.Interface {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.restClient
|
||||
}
|
||||
164
vendor/github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/clientset/versioned/typed/volumesnapshot/v1beta1/volumesnapshotclass.go
generated
vendored
Normal file
164
vendor/github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/clientset/versioned/typed/volumesnapshot/v1beta1/volumesnapshotclass.go
generated
vendored
Normal file
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
Copyright 2019 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
v1beta1 "github.com/kubernetes-csi/external-snapshotter/v2/pkg/apis/volumesnapshot/v1beta1"
|
||||
scheme "github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/clientset/versioned/scheme"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
rest "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
// VolumeSnapshotClassesGetter has a method to return a VolumeSnapshotClassInterface.
|
||||
// A group's client should implement this interface.
|
||||
type VolumeSnapshotClassesGetter interface {
|
||||
VolumeSnapshotClasses() VolumeSnapshotClassInterface
|
||||
}
|
||||
|
||||
// VolumeSnapshotClassInterface has methods to work with VolumeSnapshotClass resources.
|
||||
type VolumeSnapshotClassInterface interface {
|
||||
Create(*v1beta1.VolumeSnapshotClass) (*v1beta1.VolumeSnapshotClass, error)
|
||||
Update(*v1beta1.VolumeSnapshotClass) (*v1beta1.VolumeSnapshotClass, error)
|
||||
Delete(name string, options *v1.DeleteOptions) error
|
||||
DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error
|
||||
Get(name string, options v1.GetOptions) (*v1beta1.VolumeSnapshotClass, error)
|
||||
List(opts v1.ListOptions) (*v1beta1.VolumeSnapshotClassList, error)
|
||||
Watch(opts v1.ListOptions) (watch.Interface, error)
|
||||
Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1beta1.VolumeSnapshotClass, err error)
|
||||
VolumeSnapshotClassExpansion
|
||||
}
|
||||
|
||||
// volumeSnapshotClasses implements VolumeSnapshotClassInterface
|
||||
type volumeSnapshotClasses struct {
|
||||
client rest.Interface
|
||||
}
|
||||
|
||||
// newVolumeSnapshotClasses returns a VolumeSnapshotClasses
|
||||
func newVolumeSnapshotClasses(c *SnapshotV1beta1Client) *volumeSnapshotClasses {
|
||||
return &volumeSnapshotClasses{
|
||||
client: c.RESTClient(),
|
||||
}
|
||||
}
|
||||
|
||||
// Get takes name of the volumeSnapshotClass, and returns the corresponding volumeSnapshotClass object, and an error if there is any.
|
||||
func (c *volumeSnapshotClasses) Get(name string, options v1.GetOptions) (result *v1beta1.VolumeSnapshotClass, err error) {
|
||||
result = &v1beta1.VolumeSnapshotClass{}
|
||||
err = c.client.Get().
|
||||
Resource("volumesnapshotclasses").
|
||||
Name(name).
|
||||
VersionedParams(&options, scheme.ParameterCodec).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of VolumeSnapshotClasses that match those selectors.
|
||||
func (c *volumeSnapshotClasses) List(opts v1.ListOptions) (result *v1beta1.VolumeSnapshotClassList, err error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
result = &v1beta1.VolumeSnapshotClassList{}
|
||||
err = c.client.Get().
|
||||
Resource("volumesnapshotclasses").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested volumeSnapshotClasses.
|
||||
func (c *volumeSnapshotClasses) Watch(opts v1.ListOptions) (watch.Interface, error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
opts.Watch = true
|
||||
return c.client.Get().
|
||||
Resource("volumesnapshotclasses").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Watch()
|
||||
}
|
||||
|
||||
// Create takes the representation of a volumeSnapshotClass and creates it. Returns the server's representation of the volumeSnapshotClass, and an error, if there is any.
|
||||
func (c *volumeSnapshotClasses) Create(volumeSnapshotClass *v1beta1.VolumeSnapshotClass) (result *v1beta1.VolumeSnapshotClass, err error) {
|
||||
result = &v1beta1.VolumeSnapshotClass{}
|
||||
err = c.client.Post().
|
||||
Resource("volumesnapshotclasses").
|
||||
Body(volumeSnapshotClass).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a volumeSnapshotClass and updates it. Returns the server's representation of the volumeSnapshotClass, and an error, if there is any.
|
||||
func (c *volumeSnapshotClasses) Update(volumeSnapshotClass *v1beta1.VolumeSnapshotClass) (result *v1beta1.VolumeSnapshotClass, err error) {
|
||||
result = &v1beta1.VolumeSnapshotClass{}
|
||||
err = c.client.Put().
|
||||
Resource("volumesnapshotclasses").
|
||||
Name(volumeSnapshotClass.Name).
|
||||
Body(volumeSnapshotClass).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the volumeSnapshotClass and deletes it. Returns an error if one occurs.
|
||||
func (c *volumeSnapshotClasses) Delete(name string, options *v1.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Resource("volumesnapshotclasses").
|
||||
Name(name).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *volumeSnapshotClasses) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
|
||||
var timeout time.Duration
|
||||
if listOptions.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second
|
||||
}
|
||||
return c.client.Delete().
|
||||
Resource("volumesnapshotclasses").
|
||||
VersionedParams(&listOptions, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched volumeSnapshotClass.
|
||||
func (c *volumeSnapshotClasses) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1beta1.VolumeSnapshotClass, err error) {
|
||||
result = &v1beta1.VolumeSnapshotClass{}
|
||||
err = c.client.Patch(pt).
|
||||
Resource("volumesnapshotclasses").
|
||||
SubResource(subresources...).
|
||||
Name(name).
|
||||
Body(data).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
Copyright 2019 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
v1beta1 "github.com/kubernetes-csi/external-snapshotter/v2/pkg/apis/volumesnapshot/v1beta1"
|
||||
scheme "github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/clientset/versioned/scheme"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
rest "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
// VolumeSnapshotContentsGetter has a method to return a VolumeSnapshotContentInterface.
|
||||
// A group's client should implement this interface.
|
||||
type VolumeSnapshotContentsGetter interface {
|
||||
VolumeSnapshotContents() VolumeSnapshotContentInterface
|
||||
}
|
||||
|
||||
// VolumeSnapshotContentInterface has methods to work with VolumeSnapshotContent resources.
|
||||
type VolumeSnapshotContentInterface interface {
|
||||
Create(*v1beta1.VolumeSnapshotContent) (*v1beta1.VolumeSnapshotContent, error)
|
||||
Update(*v1beta1.VolumeSnapshotContent) (*v1beta1.VolumeSnapshotContent, error)
|
||||
UpdateStatus(*v1beta1.VolumeSnapshotContent) (*v1beta1.VolumeSnapshotContent, error)
|
||||
Delete(name string, options *v1.DeleteOptions) error
|
||||
DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error
|
||||
Get(name string, options v1.GetOptions) (*v1beta1.VolumeSnapshotContent, error)
|
||||
List(opts v1.ListOptions) (*v1beta1.VolumeSnapshotContentList, error)
|
||||
Watch(opts v1.ListOptions) (watch.Interface, error)
|
||||
Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1beta1.VolumeSnapshotContent, err error)
|
||||
VolumeSnapshotContentExpansion
|
||||
}
|
||||
|
||||
// volumeSnapshotContents implements VolumeSnapshotContentInterface
|
||||
type volumeSnapshotContents struct {
|
||||
client rest.Interface
|
||||
}
|
||||
|
||||
// newVolumeSnapshotContents returns a VolumeSnapshotContents
|
||||
func newVolumeSnapshotContents(c *SnapshotV1beta1Client) *volumeSnapshotContents {
|
||||
return &volumeSnapshotContents{
|
||||
client: c.RESTClient(),
|
||||
}
|
||||
}
|
||||
|
||||
// Get takes name of the volumeSnapshotContent, and returns the corresponding volumeSnapshotContent object, and an error if there is any.
|
||||
func (c *volumeSnapshotContents) Get(name string, options v1.GetOptions) (result *v1beta1.VolumeSnapshotContent, err error) {
|
||||
result = &v1beta1.VolumeSnapshotContent{}
|
||||
err = c.client.Get().
|
||||
Resource("volumesnapshotcontents").
|
||||
Name(name).
|
||||
VersionedParams(&options, scheme.ParameterCodec).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of VolumeSnapshotContents that match those selectors.
|
||||
func (c *volumeSnapshotContents) List(opts v1.ListOptions) (result *v1beta1.VolumeSnapshotContentList, err error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
result = &v1beta1.VolumeSnapshotContentList{}
|
||||
err = c.client.Get().
|
||||
Resource("volumesnapshotcontents").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested volumeSnapshotContents.
|
||||
func (c *volumeSnapshotContents) Watch(opts v1.ListOptions) (watch.Interface, error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
opts.Watch = true
|
||||
return c.client.Get().
|
||||
Resource("volumesnapshotcontents").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Watch()
|
||||
}
|
||||
|
||||
// Create takes the representation of a volumeSnapshotContent and creates it. Returns the server's representation of the volumeSnapshotContent, and an error, if there is any.
|
||||
func (c *volumeSnapshotContents) Create(volumeSnapshotContent *v1beta1.VolumeSnapshotContent) (result *v1beta1.VolumeSnapshotContent, err error) {
|
||||
result = &v1beta1.VolumeSnapshotContent{}
|
||||
err = c.client.Post().
|
||||
Resource("volumesnapshotcontents").
|
||||
Body(volumeSnapshotContent).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a volumeSnapshotContent and updates it. Returns the server's representation of the volumeSnapshotContent, and an error, if there is any.
|
||||
func (c *volumeSnapshotContents) Update(volumeSnapshotContent *v1beta1.VolumeSnapshotContent) (result *v1beta1.VolumeSnapshotContent, err error) {
|
||||
result = &v1beta1.VolumeSnapshotContent{}
|
||||
err = c.client.Put().
|
||||
Resource("volumesnapshotcontents").
|
||||
Name(volumeSnapshotContent.Name).
|
||||
Body(volumeSnapshotContent).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateStatus was generated because the type contains a Status member.
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
||||
|
||||
func (c *volumeSnapshotContents) UpdateStatus(volumeSnapshotContent *v1beta1.VolumeSnapshotContent) (result *v1beta1.VolumeSnapshotContent, err error) {
|
||||
result = &v1beta1.VolumeSnapshotContent{}
|
||||
err = c.client.Put().
|
||||
Resource("volumesnapshotcontents").
|
||||
Name(volumeSnapshotContent.Name).
|
||||
SubResource("status").
|
||||
Body(volumeSnapshotContent).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the volumeSnapshotContent and deletes it. Returns an error if one occurs.
|
||||
func (c *volumeSnapshotContents) Delete(name string, options *v1.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Resource("volumesnapshotcontents").
|
||||
Name(name).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *volumeSnapshotContents) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
|
||||
var timeout time.Duration
|
||||
if listOptions.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second
|
||||
}
|
||||
return c.client.Delete().
|
||||
Resource("volumesnapshotcontents").
|
||||
VersionedParams(&listOptions, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched volumeSnapshotContent.
|
||||
func (c *volumeSnapshotContents) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1beta1.VolumeSnapshotContent, err error) {
|
||||
result = &v1beta1.VolumeSnapshotContent{}
|
||||
err = c.client.Patch(pt).
|
||||
Resource("volumesnapshotcontents").
|
||||
SubResource(subresources...).
|
||||
Name(name).
|
||||
Body(data).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
180
vendor/github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/informers/externalversions/factory.go
generated
vendored
Normal file
180
vendor/github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/informers/externalversions/factory.go
generated
vendored
Normal file
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
Copyright 2019 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package externalversions
|
||||
|
||||
import (
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
time "time"
|
||||
|
||||
versioned "github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/clientset/versioned"
|
||||
internalinterfaces "github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/informers/externalversions/internalinterfaces"
|
||||
volumesnapshot "github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/informers/externalversions/volumesnapshot"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
cache "k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// SharedInformerOption defines the functional option type for SharedInformerFactory.
|
||||
type SharedInformerOption func(*sharedInformerFactory) *sharedInformerFactory
|
||||
|
||||
type sharedInformerFactory struct {
|
||||
client versioned.Interface
|
||||
namespace string
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
lock sync.Mutex
|
||||
defaultResync time.Duration
|
||||
customResync map[reflect.Type]time.Duration
|
||||
|
||||
informers map[reflect.Type]cache.SharedIndexInformer
|
||||
// startedInformers is used for tracking which informers have been started.
|
||||
// This allows Start() to be called multiple times safely.
|
||||
startedInformers map[reflect.Type]bool
|
||||
}
|
||||
|
||||
// WithCustomResyncConfig sets a custom resync period for the specified informer types.
|
||||
func WithCustomResyncConfig(resyncConfig map[v1.Object]time.Duration) SharedInformerOption {
|
||||
return func(factory *sharedInformerFactory) *sharedInformerFactory {
|
||||
for k, v := range resyncConfig {
|
||||
factory.customResync[reflect.TypeOf(k)] = v
|
||||
}
|
||||
return factory
|
||||
}
|
||||
}
|
||||
|
||||
// WithTweakListOptions sets a custom filter on all listers of the configured SharedInformerFactory.
|
||||
func WithTweakListOptions(tweakListOptions internalinterfaces.TweakListOptionsFunc) SharedInformerOption {
|
||||
return func(factory *sharedInformerFactory) *sharedInformerFactory {
|
||||
factory.tweakListOptions = tweakListOptions
|
||||
return factory
|
||||
}
|
||||
}
|
||||
|
||||
// WithNamespace limits the SharedInformerFactory to the specified namespace.
|
||||
func WithNamespace(namespace string) SharedInformerOption {
|
||||
return func(factory *sharedInformerFactory) *sharedInformerFactory {
|
||||
factory.namespace = namespace
|
||||
return factory
|
||||
}
|
||||
}
|
||||
|
||||
// NewSharedInformerFactory constructs a new instance of sharedInformerFactory for all namespaces.
|
||||
func NewSharedInformerFactory(client versioned.Interface, defaultResync time.Duration) SharedInformerFactory {
|
||||
return NewSharedInformerFactoryWithOptions(client, defaultResync)
|
||||
}
|
||||
|
||||
// NewFilteredSharedInformerFactory constructs a new instance of sharedInformerFactory.
|
||||
// Listers obtained via this SharedInformerFactory will be subject to the same filters
|
||||
// as specified here.
|
||||
// Deprecated: Please use NewSharedInformerFactoryWithOptions instead
|
||||
func NewFilteredSharedInformerFactory(client versioned.Interface, defaultResync time.Duration, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) SharedInformerFactory {
|
||||
return NewSharedInformerFactoryWithOptions(client, defaultResync, WithNamespace(namespace), WithTweakListOptions(tweakListOptions))
|
||||
}
|
||||
|
||||
// NewSharedInformerFactoryWithOptions constructs a new instance of a SharedInformerFactory with additional options.
|
||||
func NewSharedInformerFactoryWithOptions(client versioned.Interface, defaultResync time.Duration, options ...SharedInformerOption) SharedInformerFactory {
|
||||
factory := &sharedInformerFactory{
|
||||
client: client,
|
||||
namespace: v1.NamespaceAll,
|
||||
defaultResync: defaultResync,
|
||||
informers: make(map[reflect.Type]cache.SharedIndexInformer),
|
||||
startedInformers: make(map[reflect.Type]bool),
|
||||
customResync: make(map[reflect.Type]time.Duration),
|
||||
}
|
||||
|
||||
// Apply all options
|
||||
for _, opt := range options {
|
||||
factory = opt(factory)
|
||||
}
|
||||
|
||||
return factory
|
||||
}
|
||||
|
||||
// Start initializes all requested informers.
|
||||
func (f *sharedInformerFactory) Start(stopCh <-chan struct{}) {
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
|
||||
for informerType, informer := range f.informers {
|
||||
if !f.startedInformers[informerType] {
|
||||
go informer.Run(stopCh)
|
||||
f.startedInformers[informerType] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WaitForCacheSync waits for all started informers' cache were synced.
|
||||
func (f *sharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool {
|
||||
informers := func() map[reflect.Type]cache.SharedIndexInformer {
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
|
||||
informers := map[reflect.Type]cache.SharedIndexInformer{}
|
||||
for informerType, informer := range f.informers {
|
||||
if f.startedInformers[informerType] {
|
||||
informers[informerType] = informer
|
||||
}
|
||||
}
|
||||
return informers
|
||||
}()
|
||||
|
||||
res := map[reflect.Type]bool{}
|
||||
for informType, informer := range informers {
|
||||
res[informType] = cache.WaitForCacheSync(stopCh, informer.HasSynced)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// InternalInformerFor returns the SharedIndexInformer for obj using an internal
|
||||
// client.
|
||||
func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internalinterfaces.NewInformerFunc) cache.SharedIndexInformer {
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
|
||||
informerType := reflect.TypeOf(obj)
|
||||
informer, exists := f.informers[informerType]
|
||||
if exists {
|
||||
return informer
|
||||
}
|
||||
|
||||
resyncPeriod, exists := f.customResync[informerType]
|
||||
if !exists {
|
||||
resyncPeriod = f.defaultResync
|
||||
}
|
||||
|
||||
informer = newFunc(f.client, resyncPeriod)
|
||||
f.informers[informerType] = informer
|
||||
|
||||
return informer
|
||||
}
|
||||
|
||||
// SharedInformerFactory provides shared informers for resources in all known
|
||||
// API group versions.
|
||||
type SharedInformerFactory interface {
|
||||
internalinterfaces.SharedInformerFactory
|
||||
ForResource(resource schema.GroupVersionResource) (GenericInformer, error)
|
||||
WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool
|
||||
|
||||
Snapshot() volumesnapshot.Interface
|
||||
}
|
||||
|
||||
func (f *sharedInformerFactory) Snapshot() volumesnapshot.Interface {
|
||||
return volumesnapshot.New(f, f.namespace, f.tweakListOptions)
|
||||
}
|
||||
66
vendor/github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/informers/externalversions/generic.go
generated
vendored
Normal file
66
vendor/github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/informers/externalversions/generic.go
generated
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
Copyright 2019 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package externalversions
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
v1beta1 "github.com/kubernetes-csi/external-snapshotter/v2/pkg/apis/volumesnapshot/v1beta1"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
cache "k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// GenericInformer is type of SharedIndexInformer which will locate and delegate to other
|
||||
// sharedInformers based on type
|
||||
type GenericInformer interface {
|
||||
Informer() cache.SharedIndexInformer
|
||||
Lister() cache.GenericLister
|
||||
}
|
||||
|
||||
type genericInformer struct {
|
||||
informer cache.SharedIndexInformer
|
||||
resource schema.GroupResource
|
||||
}
|
||||
|
||||
// Informer returns the SharedIndexInformer.
|
||||
func (f *genericInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.informer
|
||||
}
|
||||
|
||||
// Lister returns the GenericLister.
|
||||
func (f *genericInformer) Lister() cache.GenericLister {
|
||||
return cache.NewGenericLister(f.Informer().GetIndexer(), f.resource)
|
||||
}
|
||||
|
||||
// ForResource gives generic access to a shared informer of the matching type
|
||||
// TODO extend this to unknown resources with a client pool
|
||||
func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource) (GenericInformer, error) {
|
||||
switch resource {
|
||||
// Group=snapshot.storage.k8s.io, Version=v1beta1
|
||||
case v1beta1.SchemeGroupVersion.WithResource("volumesnapshots"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Snapshot().V1beta1().VolumeSnapshots().Informer()}, nil
|
||||
case v1beta1.SchemeGroupVersion.WithResource("volumesnapshotclasses"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Snapshot().V1beta1().VolumeSnapshotClasses().Informer()}, nil
|
||||
case v1beta1.SchemeGroupVersion.WithResource("volumesnapshotcontents"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Snapshot().V1beta1().VolumeSnapshotContents().Informer()}, nil
|
||||
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("no informer found for %v", resource)
|
||||
}
|
||||
40
vendor/github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/informers/externalversions/internalinterfaces/factory_interfaces.go
generated
vendored
Normal file
40
vendor/github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/informers/externalversions/internalinterfaces/factory_interfaces.go
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
Copyright 2019 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package internalinterfaces
|
||||
|
||||
import (
|
||||
time "time"
|
||||
|
||||
versioned "github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/clientset/versioned"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
cache "k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// NewInformerFunc takes versioned.Interface and time.Duration to return a SharedIndexInformer.
|
||||
type NewInformerFunc func(versioned.Interface, time.Duration) cache.SharedIndexInformer
|
||||
|
||||
// SharedInformerFactory a small interface to allow for adding an informer without an import cycle
|
||||
type SharedInformerFactory interface {
|
||||
Start(stopCh <-chan struct{})
|
||||
InformerFor(obj runtime.Object, newFunc NewInformerFunc) cache.SharedIndexInformer
|
||||
}
|
||||
|
||||
// TweakListOptionsFunc is a function that transforms a v1.ListOptions.
|
||||
type TweakListOptionsFunc func(*v1.ListOptions)
|
||||
46
vendor/github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/informers/externalversions/volumesnapshot/interface.go
generated
vendored
Normal file
46
vendor/github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/informers/externalversions/volumesnapshot/interface.go
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
Copyright 2019 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package volumesnapshot
|
||||
|
||||
import (
|
||||
internalinterfaces "github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/informers/externalversions/internalinterfaces"
|
||||
v1beta1 "github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/informers/externalversions/volumesnapshot/v1beta1"
|
||||
)
|
||||
|
||||
// Interface provides access to each of this group's versions.
|
||||
type Interface interface {
|
||||
// V1beta1 provides access to shared informers for resources in V1beta1.
|
||||
V1beta1() v1beta1.Interface
|
||||
}
|
||||
|
||||
type group struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
namespace string
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
}
|
||||
|
||||
// New returns a new Interface.
|
||||
func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {
|
||||
return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
|
||||
}
|
||||
|
||||
// V1beta1 returns a new v1beta1.Interface.
|
||||
func (g *group) V1beta1() v1beta1.Interface {
|
||||
return v1beta1.New(g.factory, g.namespace, g.tweakListOptions)
|
||||
}
|
||||
59
vendor/github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/informers/externalversions/volumesnapshot/v1beta1/interface.go
generated
vendored
Normal file
59
vendor/github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/informers/externalversions/volumesnapshot/v1beta1/interface.go
generated
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
Copyright 2019 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
internalinterfaces "github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/informers/externalversions/internalinterfaces"
|
||||
)
|
||||
|
||||
// Interface provides access to all the informers in this group version.
|
||||
type Interface interface {
|
||||
// VolumeSnapshots returns a VolumeSnapshotInformer.
|
||||
VolumeSnapshots() VolumeSnapshotInformer
|
||||
// VolumeSnapshotClasses returns a VolumeSnapshotClassInformer.
|
||||
VolumeSnapshotClasses() VolumeSnapshotClassInformer
|
||||
// VolumeSnapshotContents returns a VolumeSnapshotContentInformer.
|
||||
VolumeSnapshotContents() VolumeSnapshotContentInformer
|
||||
}
|
||||
|
||||
type version struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
namespace string
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
}
|
||||
|
||||
// New returns a new Interface.
|
||||
func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {
|
||||
return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
|
||||
}
|
||||
|
||||
// VolumeSnapshots returns a VolumeSnapshotInformer.
|
||||
func (v *version) VolumeSnapshots() VolumeSnapshotInformer {
|
||||
return &volumeSnapshotInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
|
||||
}
|
||||
|
||||
// VolumeSnapshotClasses returns a VolumeSnapshotClassInformer.
|
||||
func (v *version) VolumeSnapshotClasses() VolumeSnapshotClassInformer {
|
||||
return &volumeSnapshotClassInformer{factory: v.factory, tweakListOptions: v.tweakListOptions}
|
||||
}
|
||||
|
||||
// VolumeSnapshotContents returns a VolumeSnapshotContentInformer.
|
||||
func (v *version) VolumeSnapshotContents() VolumeSnapshotContentInformer {
|
||||
return &volumeSnapshotContentInformer{factory: v.factory, tweakListOptions: v.tweakListOptions}
|
||||
}
|
||||
89
vendor/github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/informers/externalversions/volumesnapshot/v1beta1/volumesnapshot.go
generated
vendored
Normal file
89
vendor/github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/informers/externalversions/volumesnapshot/v1beta1/volumesnapshot.go
generated
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
Copyright 2019 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
time "time"
|
||||
|
||||
volumesnapshotv1beta1 "github.com/kubernetes-csi/external-snapshotter/v2/pkg/apis/volumesnapshot/v1beta1"
|
||||
versioned "github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/clientset/versioned"
|
||||
internalinterfaces "github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/informers/externalversions/internalinterfaces"
|
||||
v1beta1 "github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/listers/volumesnapshot/v1beta1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
cache "k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// VolumeSnapshotInformer provides access to a shared informer and lister for
|
||||
// VolumeSnapshots.
|
||||
type VolumeSnapshotInformer interface {
|
||||
Informer() cache.SharedIndexInformer
|
||||
Lister() v1beta1.VolumeSnapshotLister
|
||||
}
|
||||
|
||||
type volumeSnapshotInformer struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
namespace string
|
||||
}
|
||||
|
||||
// NewVolumeSnapshotInformer constructs a new informer for VolumeSnapshot type.
|
||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||
// one. This reduces memory footprint and number of connections to the server.
|
||||
func NewVolumeSnapshotInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
|
||||
return NewFilteredVolumeSnapshotInformer(client, namespace, resyncPeriod, indexers, nil)
|
||||
}
|
||||
|
||||
// NewFilteredVolumeSnapshotInformer constructs a new informer for VolumeSnapshot type.
|
||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||
// one. This reduces memory footprint and number of connections to the server.
|
||||
func NewFilteredVolumeSnapshotInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
return cache.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.SnapshotV1beta1().VolumeSnapshots(namespace).List(options)
|
||||
},
|
||||
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.SnapshotV1beta1().VolumeSnapshots(namespace).Watch(options)
|
||||
},
|
||||
},
|
||||
&volumesnapshotv1beta1.VolumeSnapshot{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
}
|
||||
|
||||
func (f *volumeSnapshotInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
|
||||
return NewFilteredVolumeSnapshotInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
|
||||
}
|
||||
|
||||
func (f *volumeSnapshotInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&volumesnapshotv1beta1.VolumeSnapshot{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *volumeSnapshotInformer) Lister() v1beta1.VolumeSnapshotLister {
|
||||
return v1beta1.NewVolumeSnapshotLister(f.Informer().GetIndexer())
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
Copyright 2019 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
time "time"
|
||||
|
||||
volumesnapshotv1beta1 "github.com/kubernetes-csi/external-snapshotter/v2/pkg/apis/volumesnapshot/v1beta1"
|
||||
versioned "github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/clientset/versioned"
|
||||
internalinterfaces "github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/informers/externalversions/internalinterfaces"
|
||||
v1beta1 "github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/listers/volumesnapshot/v1beta1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
cache "k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// VolumeSnapshotClassInformer provides access to a shared informer and lister for
|
||||
// VolumeSnapshotClasses.
|
||||
type VolumeSnapshotClassInformer interface {
|
||||
Informer() cache.SharedIndexInformer
|
||||
Lister() v1beta1.VolumeSnapshotClassLister
|
||||
}
|
||||
|
||||
type volumeSnapshotClassInformer struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
}
|
||||
|
||||
// NewVolumeSnapshotClassInformer constructs a new informer for VolumeSnapshotClass type.
|
||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||
// one. This reduces memory footprint and number of connections to the server.
|
||||
func NewVolumeSnapshotClassInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
|
||||
return NewFilteredVolumeSnapshotClassInformer(client, resyncPeriod, indexers, nil)
|
||||
}
|
||||
|
||||
// NewFilteredVolumeSnapshotClassInformer constructs a new informer for VolumeSnapshotClass type.
|
||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||
// one. This reduces memory footprint and number of connections to the server.
|
||||
func NewFilteredVolumeSnapshotClassInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
return cache.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.SnapshotV1beta1().VolumeSnapshotClasses().List(options)
|
||||
},
|
||||
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.SnapshotV1beta1().VolumeSnapshotClasses().Watch(options)
|
||||
},
|
||||
},
|
||||
&volumesnapshotv1beta1.VolumeSnapshotClass{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
}
|
||||
|
||||
func (f *volumeSnapshotClassInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
|
||||
return NewFilteredVolumeSnapshotClassInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
|
||||
}
|
||||
|
||||
func (f *volumeSnapshotClassInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&volumesnapshotv1beta1.VolumeSnapshotClass{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *volumeSnapshotClassInformer) Lister() v1beta1.VolumeSnapshotClassLister {
|
||||
return v1beta1.NewVolumeSnapshotClassLister(f.Informer().GetIndexer())
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
Copyright 2019 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
time "time"
|
||||
|
||||
volumesnapshotv1beta1 "github.com/kubernetes-csi/external-snapshotter/v2/pkg/apis/volumesnapshot/v1beta1"
|
||||
versioned "github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/clientset/versioned"
|
||||
internalinterfaces "github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/informers/externalversions/internalinterfaces"
|
||||
v1beta1 "github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/listers/volumesnapshot/v1beta1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
cache "k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// VolumeSnapshotContentInformer provides access to a shared informer and lister for
|
||||
// VolumeSnapshotContents.
|
||||
type VolumeSnapshotContentInformer interface {
|
||||
Informer() cache.SharedIndexInformer
|
||||
Lister() v1beta1.VolumeSnapshotContentLister
|
||||
}
|
||||
|
||||
type volumeSnapshotContentInformer struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
}
|
||||
|
||||
// NewVolumeSnapshotContentInformer constructs a new informer for VolumeSnapshotContent type.
|
||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||
// one. This reduces memory footprint and number of connections to the server.
|
||||
func NewVolumeSnapshotContentInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
|
||||
return NewFilteredVolumeSnapshotContentInformer(client, resyncPeriod, indexers, nil)
|
||||
}
|
||||
|
||||
// NewFilteredVolumeSnapshotContentInformer constructs a new informer for VolumeSnapshotContent type.
|
||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||
// one. This reduces memory footprint and number of connections to the server.
|
||||
func NewFilteredVolumeSnapshotContentInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
return cache.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.SnapshotV1beta1().VolumeSnapshotContents().List(options)
|
||||
},
|
||||
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.SnapshotV1beta1().VolumeSnapshotContents().Watch(options)
|
||||
},
|
||||
},
|
||||
&volumesnapshotv1beta1.VolumeSnapshotContent{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
}
|
||||
|
||||
func (f *volumeSnapshotContentInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
|
||||
return NewFilteredVolumeSnapshotContentInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
|
||||
}
|
||||
|
||||
func (f *volumeSnapshotContentInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&volumesnapshotv1beta1.VolumeSnapshotContent{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *volumeSnapshotContentInformer) Lister() v1beta1.VolumeSnapshotContentLister {
|
||||
return v1beta1.NewVolumeSnapshotContentLister(f.Informer().GetIndexer())
|
||||
}
|
||||
35
vendor/github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/listers/volumesnapshot/v1beta1/expansion_generated.go
generated
vendored
Normal file
35
vendor/github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/listers/volumesnapshot/v1beta1/expansion_generated.go
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
Copyright 2019 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by lister-gen. DO NOT EDIT.
|
||||
|
||||
package v1beta1
|
||||
|
||||
// VolumeSnapshotListerExpansion allows custom methods to be added to
|
||||
// VolumeSnapshotLister.
|
||||
type VolumeSnapshotListerExpansion interface{}
|
||||
|
||||
// VolumeSnapshotNamespaceListerExpansion allows custom methods to be added to
|
||||
// VolumeSnapshotNamespaceLister.
|
||||
type VolumeSnapshotNamespaceListerExpansion interface{}
|
||||
|
||||
// VolumeSnapshotClassListerExpansion allows custom methods to be added to
|
||||
// VolumeSnapshotClassLister.
|
||||
type VolumeSnapshotClassListerExpansion interface{}
|
||||
|
||||
// VolumeSnapshotContentListerExpansion allows custom methods to be added to
|
||||
// VolumeSnapshotContentLister.
|
||||
type VolumeSnapshotContentListerExpansion interface{}
|
||||
94
vendor/github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/listers/volumesnapshot/v1beta1/volumesnapshot.go
generated
vendored
Normal file
94
vendor/github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/listers/volumesnapshot/v1beta1/volumesnapshot.go
generated
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
Copyright 2019 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by lister-gen. DO NOT EDIT.
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
v1beta1 "github.com/kubernetes-csi/external-snapshotter/v2/pkg/apis/volumesnapshot/v1beta1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// VolumeSnapshotLister helps list VolumeSnapshots.
|
||||
type VolumeSnapshotLister interface {
|
||||
// List lists all VolumeSnapshots in the indexer.
|
||||
List(selector labels.Selector) (ret []*v1beta1.VolumeSnapshot, err error)
|
||||
// VolumeSnapshots returns an object that can list and get VolumeSnapshots.
|
||||
VolumeSnapshots(namespace string) VolumeSnapshotNamespaceLister
|
||||
VolumeSnapshotListerExpansion
|
||||
}
|
||||
|
||||
// volumeSnapshotLister implements the VolumeSnapshotLister interface.
|
||||
type volumeSnapshotLister struct {
|
||||
indexer cache.Indexer
|
||||
}
|
||||
|
||||
// NewVolumeSnapshotLister returns a new VolumeSnapshotLister.
|
||||
func NewVolumeSnapshotLister(indexer cache.Indexer) VolumeSnapshotLister {
|
||||
return &volumeSnapshotLister{indexer: indexer}
|
||||
}
|
||||
|
||||
// List lists all VolumeSnapshots in the indexer.
|
||||
func (s *volumeSnapshotLister) List(selector labels.Selector) (ret []*v1beta1.VolumeSnapshot, err error) {
|
||||
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v1beta1.VolumeSnapshot))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// VolumeSnapshots returns an object that can list and get VolumeSnapshots.
|
||||
func (s *volumeSnapshotLister) VolumeSnapshots(namespace string) VolumeSnapshotNamespaceLister {
|
||||
return volumeSnapshotNamespaceLister{indexer: s.indexer, namespace: namespace}
|
||||
}
|
||||
|
||||
// VolumeSnapshotNamespaceLister helps list and get VolumeSnapshots.
|
||||
type VolumeSnapshotNamespaceLister interface {
|
||||
// List lists all VolumeSnapshots in the indexer for a given namespace.
|
||||
List(selector labels.Selector) (ret []*v1beta1.VolumeSnapshot, err error)
|
||||
// Get retrieves the VolumeSnapshot from the indexer for a given namespace and name.
|
||||
Get(name string) (*v1beta1.VolumeSnapshot, error)
|
||||
VolumeSnapshotNamespaceListerExpansion
|
||||
}
|
||||
|
||||
// volumeSnapshotNamespaceLister implements the VolumeSnapshotNamespaceLister
|
||||
// interface.
|
||||
type volumeSnapshotNamespaceLister struct {
|
||||
indexer cache.Indexer
|
||||
namespace string
|
||||
}
|
||||
|
||||
// List lists all VolumeSnapshots in the indexer for a given namespace.
|
||||
func (s volumeSnapshotNamespaceLister) List(selector labels.Selector) (ret []*v1beta1.VolumeSnapshot, err error) {
|
||||
err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v1beta1.VolumeSnapshot))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Get retrieves the VolumeSnapshot from the indexer for a given namespace and name.
|
||||
func (s volumeSnapshotNamespaceLister) Get(name string) (*v1beta1.VolumeSnapshot, error) {
|
||||
obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !exists {
|
||||
return nil, errors.NewNotFound(v1beta1.Resource("volumesnapshot"), name)
|
||||
}
|
||||
return obj.(*v1beta1.VolumeSnapshot), nil
|
||||
}
|
||||
65
vendor/github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/listers/volumesnapshot/v1beta1/volumesnapshotclass.go
generated
vendored
Normal file
65
vendor/github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/listers/volumesnapshot/v1beta1/volumesnapshotclass.go
generated
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
Copyright 2019 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by lister-gen. DO NOT EDIT.
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
v1beta1 "github.com/kubernetes-csi/external-snapshotter/v2/pkg/apis/volumesnapshot/v1beta1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// VolumeSnapshotClassLister helps list VolumeSnapshotClasses.
|
||||
type VolumeSnapshotClassLister interface {
|
||||
// List lists all VolumeSnapshotClasses in the indexer.
|
||||
List(selector labels.Selector) (ret []*v1beta1.VolumeSnapshotClass, err error)
|
||||
// Get retrieves the VolumeSnapshotClass from the index for a given name.
|
||||
Get(name string) (*v1beta1.VolumeSnapshotClass, error)
|
||||
VolumeSnapshotClassListerExpansion
|
||||
}
|
||||
|
||||
// volumeSnapshotClassLister implements the VolumeSnapshotClassLister interface.
|
||||
type volumeSnapshotClassLister struct {
|
||||
indexer cache.Indexer
|
||||
}
|
||||
|
||||
// NewVolumeSnapshotClassLister returns a new VolumeSnapshotClassLister.
|
||||
func NewVolumeSnapshotClassLister(indexer cache.Indexer) VolumeSnapshotClassLister {
|
||||
return &volumeSnapshotClassLister{indexer: indexer}
|
||||
}
|
||||
|
||||
// List lists all VolumeSnapshotClasses in the indexer.
|
||||
func (s *volumeSnapshotClassLister) List(selector labels.Selector) (ret []*v1beta1.VolumeSnapshotClass, err error) {
|
||||
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v1beta1.VolumeSnapshotClass))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Get retrieves the VolumeSnapshotClass from the index for a given name.
|
||||
func (s *volumeSnapshotClassLister) Get(name string) (*v1beta1.VolumeSnapshotClass, error) {
|
||||
obj, exists, err := s.indexer.GetByKey(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !exists {
|
||||
return nil, errors.NewNotFound(v1beta1.Resource("volumesnapshotclass"), name)
|
||||
}
|
||||
return obj.(*v1beta1.VolumeSnapshotClass), nil
|
||||
}
|
||||
65
vendor/github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/listers/volumesnapshot/v1beta1/volumesnapshotcontent.go
generated
vendored
Normal file
65
vendor/github.com/kubernetes-csi/external-snapshotter/v2/pkg/client/listers/volumesnapshot/v1beta1/volumesnapshotcontent.go
generated
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
Copyright 2019 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by lister-gen. DO NOT EDIT.
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
v1beta1 "github.com/kubernetes-csi/external-snapshotter/v2/pkg/apis/volumesnapshot/v1beta1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// VolumeSnapshotContentLister helps list VolumeSnapshotContents.
|
||||
type VolumeSnapshotContentLister interface {
|
||||
// List lists all VolumeSnapshotContents in the indexer.
|
||||
List(selector labels.Selector) (ret []*v1beta1.VolumeSnapshotContent, err error)
|
||||
// Get retrieves the VolumeSnapshotContent from the index for a given name.
|
||||
Get(name string) (*v1beta1.VolumeSnapshotContent, error)
|
||||
VolumeSnapshotContentListerExpansion
|
||||
}
|
||||
|
||||
// volumeSnapshotContentLister implements the VolumeSnapshotContentLister interface.
|
||||
type volumeSnapshotContentLister struct {
|
||||
indexer cache.Indexer
|
||||
}
|
||||
|
||||
// NewVolumeSnapshotContentLister returns a new VolumeSnapshotContentLister.
|
||||
func NewVolumeSnapshotContentLister(indexer cache.Indexer) VolumeSnapshotContentLister {
|
||||
return &volumeSnapshotContentLister{indexer: indexer}
|
||||
}
|
||||
|
||||
// List lists all VolumeSnapshotContents in the indexer.
|
||||
func (s *volumeSnapshotContentLister) List(selector labels.Selector) (ret []*v1beta1.VolumeSnapshotContent, err error) {
|
||||
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v1beta1.VolumeSnapshotContent))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Get retrieves the VolumeSnapshotContent from the index for a given name.
|
||||
func (s *volumeSnapshotContentLister) Get(name string) (*v1beta1.VolumeSnapshotContent, error) {
|
||||
obj, exists, err := s.indexer.GetByKey(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !exists {
|
||||
return nil, errors.NewNotFound(v1beta1.Resource("volumesnapshotcontent"), name)
|
||||
}
|
||||
return obj.(*v1beta1.VolumeSnapshotContent), nil
|
||||
}
|
||||
29
vendor/github.com/oklog/ulid/.gitignore
generated
vendored
Normal file
29
vendor/github.com/oklog/ulid/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
#### joe made this: http://goel.io/joe
|
||||
|
||||
#####=== Go ===#####
|
||||
|
||||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
[568vq].out
|
||||
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
*.exe
|
||||
*.test
|
||||
*.prof
|
||||
|
||||
16
vendor/github.com/oklog/ulid/.travis.yml
generated
vendored
Normal file
16
vendor/github.com/oklog/ulid/.travis.yml
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
language: go
|
||||
sudo: false
|
||||
go:
|
||||
- 1.10.x
|
||||
install:
|
||||
- go get -v github.com/golang/lint/golint
|
||||
- go get golang.org/x/tools/cmd/cover
|
||||
- go get github.com/mattn/goveralls
|
||||
- go get -d -t -v ./...
|
||||
- go build -v ./...
|
||||
script:
|
||||
- go vet ./...
|
||||
- $HOME/gopath/bin/golint .
|
||||
- go test -v -race ./...
|
||||
- go test -v -covermode=count -coverprofile=cov.out
|
||||
- $HOME/gopath/bin/goveralls -coverprofile=cov.out -service=travis-ci -repotoken "$COVERALLS_TOKEN" || true
|
||||
2
vendor/github.com/oklog/ulid/AUTHORS.md
generated
vendored
Normal file
2
vendor/github.com/oklog/ulid/AUTHORS.md
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
- Peter Bourgon (@peterbourgon)
|
||||
- Tomás Senart (@tsenart)
|
||||
33
vendor/github.com/oklog/ulid/CHANGELOG.md
generated
vendored
Normal file
33
vendor/github.com/oklog/ulid/CHANGELOG.md
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
## 1.3.1 / 2018-10-02
|
||||
|
||||
* Use underlying entropy source for random increments in Monotonic (#32)
|
||||
|
||||
## 1.3.0 / 2018-09-29
|
||||
|
||||
* Monotonic entropy support (#31)
|
||||
|
||||
## 1.2.0 / 2018-09-09
|
||||
|
||||
* Add a function to convert Unix time in milliseconds back to time.Time (#30)
|
||||
|
||||
## 1.1.0 / 2018-08-15
|
||||
|
||||
* Ensure random part is always read from the entropy reader in full (#28)
|
||||
|
||||
## 1.0.0 / 2018-07-29
|
||||
|
||||
* Add ParseStrict and MustParseStrict functions (#26)
|
||||
* Enforce overflow checking when parsing (#20)
|
||||
|
||||
## 0.3.0 / 2017-01-03
|
||||
|
||||
* Implement ULID.Compare method
|
||||
|
||||
## 0.2.0 / 2016-12-13
|
||||
|
||||
* Remove year 2262 Timestamp bug. (#1)
|
||||
* Gracefully handle invalid encodings when parsing.
|
||||
|
||||
## 0.1.0 / 2016-12-06
|
||||
|
||||
* First ULID release
|
||||
17
vendor/github.com/oklog/ulid/CONTRIBUTING.md
generated
vendored
Normal file
17
vendor/github.com/oklog/ulid/CONTRIBUTING.md
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
# Contributing
|
||||
|
||||
We use GitHub to manage reviews of pull requests.
|
||||
|
||||
* If you have a trivial fix or improvement, go ahead and create a pull
|
||||
request, addressing (with `@...`) one or more of the maintainers
|
||||
(see [AUTHORS.md](AUTHORS.md)) in the description of the pull request.
|
||||
|
||||
* If you plan to do something more involved, first propose your ideas
|
||||
in a Github issue. This will avoid unnecessary work and surely give
|
||||
you and us a good deal of inspiration.
|
||||
|
||||
* Relevant coding style guidelines are the [Go Code Review
|
||||
Comments](https://code.google.com/p/go-wiki/wiki/CodeReviewComments)
|
||||
and the _Formatting and style_ section of Peter Bourgon's [Go: Best
|
||||
Practices for Production
|
||||
Environments](http://peter.bourgon.org/go-in-production/#formatting-and-style).
|
||||
15
vendor/github.com/oklog/ulid/Gopkg.lock
generated
vendored
Normal file
15
vendor/github.com/oklog/ulid/Gopkg.lock
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
|
||||
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/pborman/getopt"
|
||||
packages = ["v2"]
|
||||
revision = "7148bc3a4c3008adfcab60cbebfd0576018f330b"
|
||||
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
inputs-digest = "6779b05abd5cd429c5393641d2453005a3cb74a400d161b2b5c5d0ca2e10e116"
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
||||
26
vendor/github.com/oklog/ulid/Gopkg.toml
generated
vendored
Normal file
26
vendor/github.com/oklog/ulid/Gopkg.toml
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
|
||||
# Gopkg.toml example
|
||||
#
|
||||
# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
|
||||
# for detailed Gopkg.toml documentation.
|
||||
#
|
||||
# required = ["github.com/user/thing/cmd/thing"]
|
||||
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
|
||||
#
|
||||
# [[constraint]]
|
||||
# name = "github.com/user/project"
|
||||
# version = "1.0.0"
|
||||
#
|
||||
# [[constraint]]
|
||||
# name = "github.com/user/project2"
|
||||
# branch = "dev"
|
||||
# source = "github.com/myfork/project2"
|
||||
#
|
||||
# [[override]]
|
||||
# name = "github.com/x/y"
|
||||
# version = "2.4.0"
|
||||
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/pborman/getopt"
|
||||
201
vendor/github.com/oklog/ulid/LICENSE
generated
vendored
Normal file
201
vendor/github.com/oklog/ulid/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
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.
|
||||
150
vendor/github.com/oklog/ulid/README.md
generated
vendored
Normal file
150
vendor/github.com/oklog/ulid/README.md
generated
vendored
Normal file
@@ -0,0 +1,150 @@
|
||||
# Universally Unique Lexicographically Sortable Identifier
|
||||
|
||||

|
||||
[](http://travis-ci.org/oklog/ulid)
|
||||
[](https://goreportcard.com/report/oklog/ulid)
|
||||
[](https://coveralls.io/github/oklog/ulid?branch=master)
|
||||
[](https://godoc.org/github.com/oklog/ulid)
|
||||
[](https://raw.githubusercontent.com/oklog/ulid/master/LICENSE)
|
||||
|
||||
A Go port of [alizain/ulid](https://github.com/alizain/ulid) with binary format implemented.
|
||||
|
||||
## Background
|
||||
|
||||
A GUID/UUID can be suboptimal for many use-cases because:
|
||||
|
||||
- It isn't the most character efficient way of encoding 128 bits
|
||||
- UUID v1/v2 is impractical in many environments, as it requires access to a unique, stable MAC address
|
||||
- UUID v3/v5 requires a unique seed and produces randomly distributed IDs, which can cause fragmentation in many data structures
|
||||
- UUID v4 provides no other information than randomness which can cause fragmentation in many data structures
|
||||
|
||||
A ULID however:
|
||||
|
||||
- Is compatible with UUID/GUID's
|
||||
- 1.21e+24 unique ULIDs per millisecond (1,208,925,819,614,629,174,706,176 to be exact)
|
||||
- Lexicographically sortable
|
||||
- Canonically encoded as a 26 character string, as opposed to the 36 character UUID
|
||||
- Uses Crockford's base32 for better efficiency and readability (5 bits per character)
|
||||
- Case insensitive
|
||||
- No special characters (URL safe)
|
||||
- Monotonic sort order (correctly detects and handles the same millisecond)
|
||||
|
||||
## Install
|
||||
|
||||
```shell
|
||||
go get github.com/oklog/ulid
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
An ULID is constructed with a `time.Time` and an `io.Reader` entropy source.
|
||||
This design allows for greater flexibility in choosing your trade-offs.
|
||||
|
||||
Please note that `rand.Rand` from the `math` package is *not* safe for concurrent use.
|
||||
Instantiate one per long living go-routine or use a `sync.Pool` if you want to avoid the potential contention of a locked `rand.Source` as its been frequently observed in the package level functions.
|
||||
|
||||
|
||||
```go
|
||||
func ExampleULID() {
|
||||
t := time.Unix(1000000, 0)
|
||||
entropy := ulid.Monotonic(rand.New(rand.NewSource(t.UnixNano())), 0)
|
||||
fmt.Println(ulid.MustNew(ulid.Timestamp(t), entropy))
|
||||
// Output: 0000XSNJG0MQJHBF4QX1EFD6Y3
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Specification
|
||||
|
||||
Below is the current specification of ULID as implemented in this repository.
|
||||
|
||||
### Components
|
||||
|
||||
**Timestamp**
|
||||
- 48 bits
|
||||
- UNIX-time in milliseconds
|
||||
- Won't run out of space till the year 10895 AD
|
||||
|
||||
**Entropy**
|
||||
- 80 bits
|
||||
- User defined entropy source.
|
||||
- Monotonicity within the same millisecond with [`ulid.Monotonic`](https://godoc.org/github.com/oklog/ulid#Monotonic)
|
||||
|
||||
### Encoding
|
||||
|
||||
[Crockford's Base32](http://www.crockford.com/wrmg/base32.html) is used as shown.
|
||||
This alphabet excludes the letters I, L, O, and U to avoid confusion and abuse.
|
||||
|
||||
```
|
||||
0123456789ABCDEFGHJKMNPQRSTVWXYZ
|
||||
```
|
||||
|
||||
### Binary Layout and Byte Order
|
||||
|
||||
The components are encoded as 16 octets. Each component is encoded with the Most Significant Byte first (network byte order).
|
||||
|
||||
```
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| 32_bit_uint_time_high |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| 16_bit_uint_time_low | 16_bit_uint_random |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| 32_bit_uint_random |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| 32_bit_uint_random |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
```
|
||||
|
||||
### String Representation
|
||||
|
||||
```
|
||||
01AN4Z07BY 79KA1307SR9X4MV3
|
||||
|----------| |----------------|
|
||||
Timestamp Entropy
|
||||
10 chars 16 chars
|
||||
48bits 80bits
|
||||
base32 base32
|
||||
```
|
||||
|
||||
## Test
|
||||
|
||||
```shell
|
||||
go test ./...
|
||||
```
|
||||
|
||||
## Benchmarks
|
||||
|
||||
On a Intel Core i7 Ivy Bridge 2.7 GHz, MacOS 10.12.1 and Go 1.8.0beta1
|
||||
|
||||
```
|
||||
BenchmarkNew/WithCryptoEntropy-8 2000000 771 ns/op 20.73 MB/s 16 B/op 1 allocs/op
|
||||
BenchmarkNew/WithEntropy-8 20000000 65.8 ns/op 243.01 MB/s 16 B/op 1 allocs/op
|
||||
BenchmarkNew/WithoutEntropy-8 50000000 30.0 ns/op 534.06 MB/s 16 B/op 1 allocs/op
|
||||
BenchmarkMustNew/WithCryptoEntropy-8 2000000 781 ns/op 20.48 MB/s 16 B/op 1 allocs/op
|
||||
BenchmarkMustNew/WithEntropy-8 20000000 70.0 ns/op 228.51 MB/s 16 B/op 1 allocs/op
|
||||
BenchmarkMustNew/WithoutEntropy-8 50000000 34.6 ns/op 462.98 MB/s 16 B/op 1 allocs/op
|
||||
BenchmarkParse-8 50000000 30.0 ns/op 866.16 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkMustParse-8 50000000 35.2 ns/op 738.94 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkString-8 20000000 64.9 ns/op 246.40 MB/s 32 B/op 1 allocs/op
|
||||
BenchmarkMarshal/Text-8 20000000 55.8 ns/op 286.84 MB/s 32 B/op 1 allocs/op
|
||||
BenchmarkMarshal/TextTo-8 100000000 22.4 ns/op 714.91 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkMarshal/Binary-8 300000000 4.02 ns/op 3981.77 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkMarshal/BinaryTo-8 2000000000 1.18 ns/op 13551.75 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkUnmarshal/Text-8 100000000 20.5 ns/op 1265.27 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkUnmarshal/Binary-8 300000000 4.94 ns/op 3240.01 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkNow-8 100000000 15.1 ns/op 528.09 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkTimestamp-8 2000000000 0.29 ns/op 27271.59 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkTime-8 2000000000 0.58 ns/op 13717.80 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkSetTime-8 2000000000 0.89 ns/op 9023.95 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkEntropy-8 200000000 7.62 ns/op 1311.66 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkSetEntropy-8 2000000000 0.88 ns/op 11376.54 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkCompare-8 200000000 7.34 ns/op 4359.23 MB/s 0 B/op 0 allocs/op
|
||||
```
|
||||
|
||||
## Prior Art
|
||||
|
||||
- [alizain/ulid](https://github.com/alizain/ulid)
|
||||
- [RobThree/NUlid](https://github.com/RobThree/NUlid)
|
||||
- [imdario/go-ulid](https://github.com/imdario/go-ulid)
|
||||
614
vendor/github.com/oklog/ulid/ulid.go
generated
vendored
Normal file
614
vendor/github.com/oklog/ulid/ulid.go
generated
vendored
Normal file
@@ -0,0 +1,614 @@
|
||||
// Copyright 2016 The Oklog Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package ulid
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"database/sql/driver"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"io"
|
||||
"math"
|
||||
"math/bits"
|
||||
"math/rand"
|
||||
"time"
|
||||
)
|
||||
|
||||
/*
|
||||
An ULID is a 16 byte Universally Unique Lexicographically Sortable Identifier
|
||||
|
||||
The components are encoded as 16 octets.
|
||||
Each component is encoded with the MSB first (network byte order).
|
||||
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| 32_bit_uint_time_high |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| 16_bit_uint_time_low | 16_bit_uint_random |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| 32_bit_uint_random |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| 32_bit_uint_random |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
type ULID [16]byte
|
||||
|
||||
var (
|
||||
// ErrDataSize is returned when parsing or unmarshaling ULIDs with the wrong
|
||||
// data size.
|
||||
ErrDataSize = errors.New("ulid: bad data size when unmarshaling")
|
||||
|
||||
// ErrInvalidCharacters is returned when parsing or unmarshaling ULIDs with
|
||||
// invalid Base32 encodings.
|
||||
ErrInvalidCharacters = errors.New("ulid: bad data characters when unmarshaling")
|
||||
|
||||
// ErrBufferSize is returned when marshalling ULIDs to a buffer of insufficient
|
||||
// size.
|
||||
ErrBufferSize = errors.New("ulid: bad buffer size when marshaling")
|
||||
|
||||
// ErrBigTime is returned when constructing an ULID with a time that is larger
|
||||
// than MaxTime.
|
||||
ErrBigTime = errors.New("ulid: time too big")
|
||||
|
||||
// ErrOverflow is returned when unmarshaling a ULID whose first character is
|
||||
// larger than 7, thereby exceeding the valid bit depth of 128.
|
||||
ErrOverflow = errors.New("ulid: overflow when unmarshaling")
|
||||
|
||||
// ErrMonotonicOverflow is returned by a Monotonic entropy source when
|
||||
// incrementing the previous ULID's entropy bytes would result in overflow.
|
||||
ErrMonotonicOverflow = errors.New("ulid: monotonic entropy overflow")
|
||||
|
||||
// ErrScanValue is returned when the value passed to scan cannot be unmarshaled
|
||||
// into the ULID.
|
||||
ErrScanValue = errors.New("ulid: source value must be a string or byte slice")
|
||||
)
|
||||
|
||||
// New returns an ULID with the given Unix milliseconds timestamp and an
|
||||
// optional entropy source. Use the Timestamp function to convert
|
||||
// a time.Time to Unix milliseconds.
|
||||
//
|
||||
// ErrBigTime is returned when passing a timestamp bigger than MaxTime.
|
||||
// Reading from the entropy source may also return an error.
|
||||
func New(ms uint64, entropy io.Reader) (id ULID, err error) {
|
||||
if err = id.SetTime(ms); err != nil {
|
||||
return id, err
|
||||
}
|
||||
|
||||
switch e := entropy.(type) {
|
||||
case nil:
|
||||
return id, err
|
||||
case *monotonic:
|
||||
err = e.MonotonicRead(ms, id[6:])
|
||||
default:
|
||||
_, err = io.ReadFull(e, id[6:])
|
||||
}
|
||||
|
||||
return id, err
|
||||
}
|
||||
|
||||
// MustNew is a convenience function equivalent to New that panics on failure
|
||||
// instead of returning an error.
|
||||
func MustNew(ms uint64, entropy io.Reader) ULID {
|
||||
id, err := New(ms, entropy)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
// Parse parses an encoded ULID, returning an error in case of failure.
|
||||
//
|
||||
// ErrDataSize is returned if the len(ulid) is different from an encoded
|
||||
// ULID's length. Invalid encodings produce undefined ULIDs. For a version that
|
||||
// returns an error instead, see ParseStrict.
|
||||
func Parse(ulid string) (id ULID, err error) {
|
||||
return id, parse([]byte(ulid), false, &id)
|
||||
}
|
||||
|
||||
// ParseStrict parses an encoded ULID, returning an error in case of failure.
|
||||
//
|
||||
// It is like Parse, but additionally validates that the parsed ULID consists
|
||||
// only of valid base32 characters. It is slightly slower than Parse.
|
||||
//
|
||||
// ErrDataSize is returned if the len(ulid) is different from an encoded
|
||||
// ULID's length. Invalid encodings return ErrInvalidCharacters.
|
||||
func ParseStrict(ulid string) (id ULID, err error) {
|
||||
return id, parse([]byte(ulid), true, &id)
|
||||
}
|
||||
|
||||
func parse(v []byte, strict bool, id *ULID) error {
|
||||
// Check if a base32 encoded ULID is the right length.
|
||||
if len(v) != EncodedSize {
|
||||
return ErrDataSize
|
||||
}
|
||||
|
||||
// Check if all the characters in a base32 encoded ULID are part of the
|
||||
// expected base32 character set.
|
||||
if strict &&
|
||||
(dec[v[0]] == 0xFF ||
|
||||
dec[v[1]] == 0xFF ||
|
||||
dec[v[2]] == 0xFF ||
|
||||
dec[v[3]] == 0xFF ||
|
||||
dec[v[4]] == 0xFF ||
|
||||
dec[v[5]] == 0xFF ||
|
||||
dec[v[6]] == 0xFF ||
|
||||
dec[v[7]] == 0xFF ||
|
||||
dec[v[8]] == 0xFF ||
|
||||
dec[v[9]] == 0xFF ||
|
||||
dec[v[10]] == 0xFF ||
|
||||
dec[v[11]] == 0xFF ||
|
||||
dec[v[12]] == 0xFF ||
|
||||
dec[v[13]] == 0xFF ||
|
||||
dec[v[14]] == 0xFF ||
|
||||
dec[v[15]] == 0xFF ||
|
||||
dec[v[16]] == 0xFF ||
|
||||
dec[v[17]] == 0xFF ||
|
||||
dec[v[18]] == 0xFF ||
|
||||
dec[v[19]] == 0xFF ||
|
||||
dec[v[20]] == 0xFF ||
|
||||
dec[v[21]] == 0xFF ||
|
||||
dec[v[22]] == 0xFF ||
|
||||
dec[v[23]] == 0xFF ||
|
||||
dec[v[24]] == 0xFF ||
|
||||
dec[v[25]] == 0xFF) {
|
||||
return ErrInvalidCharacters
|
||||
}
|
||||
|
||||
// Check if the first character in a base32 encoded ULID will overflow. This
|
||||
// happens because the base32 representation encodes 130 bits, while the
|
||||
// ULID is only 128 bits.
|
||||
//
|
||||
// See https://github.com/oklog/ulid/issues/9 for details.
|
||||
if v[0] > '7' {
|
||||
return ErrOverflow
|
||||
}
|
||||
|
||||
// Use an optimized unrolled loop (from https://github.com/RobThree/NUlid)
|
||||
// to decode a base32 ULID.
|
||||
|
||||
// 6 bytes timestamp (48 bits)
|
||||
(*id)[0] = ((dec[v[0]] << 5) | dec[v[1]])
|
||||
(*id)[1] = ((dec[v[2]] << 3) | (dec[v[3]] >> 2))
|
||||
(*id)[2] = ((dec[v[3]] << 6) | (dec[v[4]] << 1) | (dec[v[5]] >> 4))
|
||||
(*id)[3] = ((dec[v[5]] << 4) | (dec[v[6]] >> 1))
|
||||
(*id)[4] = ((dec[v[6]] << 7) | (dec[v[7]] << 2) | (dec[v[8]] >> 3))
|
||||
(*id)[5] = ((dec[v[8]] << 5) | dec[v[9]])
|
||||
|
||||
// 10 bytes of entropy (80 bits)
|
||||
(*id)[6] = ((dec[v[10]] << 3) | (dec[v[11]] >> 2))
|
||||
(*id)[7] = ((dec[v[11]] << 6) | (dec[v[12]] << 1) | (dec[v[13]] >> 4))
|
||||
(*id)[8] = ((dec[v[13]] << 4) | (dec[v[14]] >> 1))
|
||||
(*id)[9] = ((dec[v[14]] << 7) | (dec[v[15]] << 2) | (dec[v[16]] >> 3))
|
||||
(*id)[10] = ((dec[v[16]] << 5) | dec[v[17]])
|
||||
(*id)[11] = ((dec[v[18]] << 3) | dec[v[19]]>>2)
|
||||
(*id)[12] = ((dec[v[19]] << 6) | (dec[v[20]] << 1) | (dec[v[21]] >> 4))
|
||||
(*id)[13] = ((dec[v[21]] << 4) | (dec[v[22]] >> 1))
|
||||
(*id)[14] = ((dec[v[22]] << 7) | (dec[v[23]] << 2) | (dec[v[24]] >> 3))
|
||||
(*id)[15] = ((dec[v[24]] << 5) | dec[v[25]])
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MustParse is a convenience function equivalent to Parse that panics on failure
|
||||
// instead of returning an error.
|
||||
func MustParse(ulid string) ULID {
|
||||
id, err := Parse(ulid)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
// MustParseStrict is a convenience function equivalent to ParseStrict that
|
||||
// panics on failure instead of returning an error.
|
||||
func MustParseStrict(ulid string) ULID {
|
||||
id, err := ParseStrict(ulid)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
// String returns a lexicographically sortable string encoded ULID
|
||||
// (26 characters, non-standard base 32) e.g. 01AN4Z07BY79KA1307SR9X4MV3
|
||||
// Format: tttttttttteeeeeeeeeeeeeeee where t is time and e is entropy
|
||||
func (id ULID) String() string {
|
||||
ulid := make([]byte, EncodedSize)
|
||||
_ = id.MarshalTextTo(ulid)
|
||||
return string(ulid)
|
||||
}
|
||||
|
||||
// MarshalBinary implements the encoding.BinaryMarshaler interface by
|
||||
// returning the ULID as a byte slice.
|
||||
func (id ULID) MarshalBinary() ([]byte, error) {
|
||||
ulid := make([]byte, len(id))
|
||||
return ulid, id.MarshalBinaryTo(ulid)
|
||||
}
|
||||
|
||||
// MarshalBinaryTo writes the binary encoding of the ULID to the given buffer.
|
||||
// ErrBufferSize is returned when the len(dst) != 16.
|
||||
func (id ULID) MarshalBinaryTo(dst []byte) error {
|
||||
if len(dst) != len(id) {
|
||||
return ErrBufferSize
|
||||
}
|
||||
|
||||
copy(dst, id[:])
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface by
|
||||
// copying the passed data and converting it to an ULID. ErrDataSize is
|
||||
// returned if the data length is different from ULID length.
|
||||
func (id *ULID) UnmarshalBinary(data []byte) error {
|
||||
if len(data) != len(*id) {
|
||||
return ErrDataSize
|
||||
}
|
||||
|
||||
copy((*id)[:], data)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Encoding is the base 32 encoding alphabet used in ULID strings.
|
||||
const Encoding = "0123456789ABCDEFGHJKMNPQRSTVWXYZ"
|
||||
|
||||
// MarshalText implements the encoding.TextMarshaler interface by
|
||||
// returning the string encoded ULID.
|
||||
func (id ULID) MarshalText() ([]byte, error) {
|
||||
ulid := make([]byte, EncodedSize)
|
||||
return ulid, id.MarshalTextTo(ulid)
|
||||
}
|
||||
|
||||
// MarshalTextTo writes the ULID as a string to the given buffer.
|
||||
// ErrBufferSize is returned when the len(dst) != 26.
|
||||
func (id ULID) MarshalTextTo(dst []byte) error {
|
||||
// Optimized unrolled loop ahead.
|
||||
// From https://github.com/RobThree/NUlid
|
||||
|
||||
if len(dst) != EncodedSize {
|
||||
return ErrBufferSize
|
||||
}
|
||||
|
||||
// 10 byte timestamp
|
||||
dst[0] = Encoding[(id[0]&224)>>5]
|
||||
dst[1] = Encoding[id[0]&31]
|
||||
dst[2] = Encoding[(id[1]&248)>>3]
|
||||
dst[3] = Encoding[((id[1]&7)<<2)|((id[2]&192)>>6)]
|
||||
dst[4] = Encoding[(id[2]&62)>>1]
|
||||
dst[5] = Encoding[((id[2]&1)<<4)|((id[3]&240)>>4)]
|
||||
dst[6] = Encoding[((id[3]&15)<<1)|((id[4]&128)>>7)]
|
||||
dst[7] = Encoding[(id[4]&124)>>2]
|
||||
dst[8] = Encoding[((id[4]&3)<<3)|((id[5]&224)>>5)]
|
||||
dst[9] = Encoding[id[5]&31]
|
||||
|
||||
// 16 bytes of entropy
|
||||
dst[10] = Encoding[(id[6]&248)>>3]
|
||||
dst[11] = Encoding[((id[6]&7)<<2)|((id[7]&192)>>6)]
|
||||
dst[12] = Encoding[(id[7]&62)>>1]
|
||||
dst[13] = Encoding[((id[7]&1)<<4)|((id[8]&240)>>4)]
|
||||
dst[14] = Encoding[((id[8]&15)<<1)|((id[9]&128)>>7)]
|
||||
dst[15] = Encoding[(id[9]&124)>>2]
|
||||
dst[16] = Encoding[((id[9]&3)<<3)|((id[10]&224)>>5)]
|
||||
dst[17] = Encoding[id[10]&31]
|
||||
dst[18] = Encoding[(id[11]&248)>>3]
|
||||
dst[19] = Encoding[((id[11]&7)<<2)|((id[12]&192)>>6)]
|
||||
dst[20] = Encoding[(id[12]&62)>>1]
|
||||
dst[21] = Encoding[((id[12]&1)<<4)|((id[13]&240)>>4)]
|
||||
dst[22] = Encoding[((id[13]&15)<<1)|((id[14]&128)>>7)]
|
||||
dst[23] = Encoding[(id[14]&124)>>2]
|
||||
dst[24] = Encoding[((id[14]&3)<<3)|((id[15]&224)>>5)]
|
||||
dst[25] = Encoding[id[15]&31]
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Byte to index table for O(1) lookups when unmarshaling.
|
||||
// We use 0xFF as sentinel value for invalid indexes.
|
||||
var dec = [...]byte{
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01,
|
||||
0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
|
||||
0x0F, 0x10, 0x11, 0xFF, 0x12, 0x13, 0xFF, 0x14, 0x15, 0xFF,
|
||||
0x16, 0x17, 0x18, 0x19, 0x1A, 0xFF, 0x1B, 0x1C, 0x1D, 0x1E,
|
||||
0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0A, 0x0B, 0x0C,
|
||||
0x0D, 0x0E, 0x0F, 0x10, 0x11, 0xFF, 0x12, 0x13, 0xFF, 0x14,
|
||||
0x15, 0xFF, 0x16, 0x17, 0x18, 0x19, 0x1A, 0xFF, 0x1B, 0x1C,
|
||||
0x1D, 0x1E, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
}
|
||||
|
||||
// EncodedSize is the length of a text encoded ULID.
|
||||
const EncodedSize = 26
|
||||
|
||||
// UnmarshalText implements the encoding.TextUnmarshaler interface by
|
||||
// parsing the data as string encoded ULID.
|
||||
//
|
||||
// ErrDataSize is returned if the len(v) is different from an encoded
|
||||
// ULID's length. Invalid encodings produce undefined ULIDs.
|
||||
func (id *ULID) UnmarshalText(v []byte) error {
|
||||
return parse(v, false, id)
|
||||
}
|
||||
|
||||
// Time returns the Unix time in milliseconds encoded in the ULID.
|
||||
// Use the top level Time function to convert the returned value to
|
||||
// a time.Time.
|
||||
func (id ULID) Time() uint64 {
|
||||
return uint64(id[5]) | uint64(id[4])<<8 |
|
||||
uint64(id[3])<<16 | uint64(id[2])<<24 |
|
||||
uint64(id[1])<<32 | uint64(id[0])<<40
|
||||
}
|
||||
|
||||
// maxTime is the maximum Unix time in milliseconds that can be
|
||||
// represented in an ULID.
|
||||
var maxTime = ULID{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}.Time()
|
||||
|
||||
// MaxTime returns the maximum Unix time in milliseconds that
|
||||
// can be encoded in an ULID.
|
||||
func MaxTime() uint64 { return maxTime }
|
||||
|
||||
// Now is a convenience function that returns the current
|
||||
// UTC time in Unix milliseconds. Equivalent to:
|
||||
// Timestamp(time.Now().UTC())
|
||||
func Now() uint64 { return Timestamp(time.Now().UTC()) }
|
||||
|
||||
// Timestamp converts a time.Time to Unix milliseconds.
|
||||
//
|
||||
// Because of the way ULID stores time, times from the year
|
||||
// 10889 produces undefined results.
|
||||
func Timestamp(t time.Time) uint64 {
|
||||
return uint64(t.Unix())*1000 +
|
||||
uint64(t.Nanosecond()/int(time.Millisecond))
|
||||
}
|
||||
|
||||
// Time converts Unix milliseconds in the format
|
||||
// returned by the Timestamp function to a time.Time.
|
||||
func Time(ms uint64) time.Time {
|
||||
s := int64(ms / 1e3)
|
||||
ns := int64((ms % 1e3) * 1e6)
|
||||
return time.Unix(s, ns)
|
||||
}
|
||||
|
||||
// SetTime sets the time component of the ULID to the given Unix time
|
||||
// in milliseconds.
|
||||
func (id *ULID) SetTime(ms uint64) error {
|
||||
if ms > maxTime {
|
||||
return ErrBigTime
|
||||
}
|
||||
|
||||
(*id)[0] = byte(ms >> 40)
|
||||
(*id)[1] = byte(ms >> 32)
|
||||
(*id)[2] = byte(ms >> 24)
|
||||
(*id)[3] = byte(ms >> 16)
|
||||
(*id)[4] = byte(ms >> 8)
|
||||
(*id)[5] = byte(ms)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Entropy returns the entropy from the ULID.
|
||||
func (id ULID) Entropy() []byte {
|
||||
e := make([]byte, 10)
|
||||
copy(e, id[6:])
|
||||
return e
|
||||
}
|
||||
|
||||
// SetEntropy sets the ULID entropy to the passed byte slice.
|
||||
// ErrDataSize is returned if len(e) != 10.
|
||||
func (id *ULID) SetEntropy(e []byte) error {
|
||||
if len(e) != 10 {
|
||||
return ErrDataSize
|
||||
}
|
||||
|
||||
copy((*id)[6:], e)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Compare returns an integer comparing id and other lexicographically.
|
||||
// The result will be 0 if id==other, -1 if id < other, and +1 if id > other.
|
||||
func (id ULID) Compare(other ULID) int {
|
||||
return bytes.Compare(id[:], other[:])
|
||||
}
|
||||
|
||||
// Scan implements the sql.Scanner interface. It supports scanning
|
||||
// a string or byte slice.
|
||||
func (id *ULID) Scan(src interface{}) error {
|
||||
switch x := src.(type) {
|
||||
case nil:
|
||||
return nil
|
||||
case string:
|
||||
return id.UnmarshalText([]byte(x))
|
||||
case []byte:
|
||||
return id.UnmarshalBinary(x)
|
||||
}
|
||||
|
||||
return ErrScanValue
|
||||
}
|
||||
|
||||
// Value implements the sql/driver.Valuer interface. This returns the value
|
||||
// represented as a byte slice. If instead a string is desirable, a wrapper
|
||||
// type can be created that calls String().
|
||||
//
|
||||
// // stringValuer wraps a ULID as a string-based driver.Valuer.
|
||||
// type stringValuer ULID
|
||||
//
|
||||
// func (id stringValuer) Value() (driver.Value, error) {
|
||||
// return ULID(id).String(), nil
|
||||
// }
|
||||
//
|
||||
// // Example usage.
|
||||
// db.Exec("...", stringValuer(id))
|
||||
func (id ULID) Value() (driver.Value, error) {
|
||||
return id.MarshalBinary()
|
||||
}
|
||||
|
||||
// Monotonic returns an entropy source that is guaranteed to yield
|
||||
// strictly increasing entropy bytes for the same ULID timestamp.
|
||||
// On conflicts, the previous ULID entropy is incremented with a
|
||||
// random number between 1 and `inc` (inclusive).
|
||||
//
|
||||
// The provided entropy source must actually yield random bytes or else
|
||||
// monotonic reads are not guaranteed to terminate, since there isn't
|
||||
// enough randomness to compute an increment number.
|
||||
//
|
||||
// When `inc == 0`, it'll be set to a secure default of `math.MaxUint32`.
|
||||
// The lower the value of `inc`, the easier the next ULID within the
|
||||
// same millisecond is to guess. If your code depends on ULIDs having
|
||||
// secure entropy bytes, then don't go under this default unless you know
|
||||
// what you're doing.
|
||||
//
|
||||
// The returned io.Reader isn't safe for concurrent use.
|
||||
func Monotonic(entropy io.Reader, inc uint64) io.Reader {
|
||||
m := monotonic{
|
||||
Reader: bufio.NewReader(entropy),
|
||||
inc: inc,
|
||||
}
|
||||
|
||||
if m.inc == 0 {
|
||||
m.inc = math.MaxUint32
|
||||
}
|
||||
|
||||
if rng, ok := entropy.(*rand.Rand); ok {
|
||||
m.rng = rng
|
||||
}
|
||||
|
||||
return &m
|
||||
}
|
||||
|
||||
type monotonic struct {
|
||||
io.Reader
|
||||
ms uint64
|
||||
inc uint64
|
||||
entropy uint80
|
||||
rand [8]byte
|
||||
rng *rand.Rand
|
||||
}
|
||||
|
||||
func (m *monotonic) MonotonicRead(ms uint64, entropy []byte) (err error) {
|
||||
if !m.entropy.IsZero() && m.ms == ms {
|
||||
err = m.increment()
|
||||
m.entropy.AppendTo(entropy)
|
||||
} else if _, err = io.ReadFull(m.Reader, entropy); err == nil {
|
||||
m.ms = ms
|
||||
m.entropy.SetBytes(entropy)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// increment the previous entropy number with a random number
|
||||
// of up to m.inc (inclusive).
|
||||
func (m *monotonic) increment() error {
|
||||
if inc, err := m.random(); err != nil {
|
||||
return err
|
||||
} else if m.entropy.Add(inc) {
|
||||
return ErrMonotonicOverflow
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// random returns a uniform random value in [1, m.inc), reading entropy
|
||||
// from m.Reader. When m.inc == 0 || m.inc == 1, it returns 1.
|
||||
// Adapted from: https://golang.org/pkg/crypto/rand/#Int
|
||||
func (m *monotonic) random() (inc uint64, err error) {
|
||||
if m.inc <= 1 {
|
||||
return 1, nil
|
||||
}
|
||||
|
||||
// Fast path for using a underlying rand.Rand directly.
|
||||
if m.rng != nil {
|
||||
// Range: [1, m.inc)
|
||||
return 1 + uint64(m.rng.Int63n(int64(m.inc))), nil
|
||||
}
|
||||
|
||||
// bitLen is the maximum bit length needed to encode a value < m.inc.
|
||||
bitLen := bits.Len64(m.inc)
|
||||
|
||||
// byteLen is the maximum byte length needed to encode a value < m.inc.
|
||||
byteLen := uint(bitLen+7) / 8
|
||||
|
||||
// msbitLen is the number of bits in the most significant byte of m.inc-1.
|
||||
msbitLen := uint(bitLen % 8)
|
||||
if msbitLen == 0 {
|
||||
msbitLen = 8
|
||||
}
|
||||
|
||||
for inc == 0 || inc >= m.inc {
|
||||
if _, err = io.ReadFull(m.Reader, m.rand[:byteLen]); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// Clear bits in the first byte to increase the probability
|
||||
// that the candidate is < m.inc.
|
||||
m.rand[0] &= uint8(int(1<<msbitLen) - 1)
|
||||
|
||||
// Convert the read bytes into an uint64 with byteLen
|
||||
// Optimized unrolled loop.
|
||||
switch byteLen {
|
||||
case 1:
|
||||
inc = uint64(m.rand[0])
|
||||
case 2:
|
||||
inc = uint64(binary.LittleEndian.Uint16(m.rand[:2]))
|
||||
case 3, 4:
|
||||
inc = uint64(binary.LittleEndian.Uint32(m.rand[:4]))
|
||||
case 5, 6, 7, 8:
|
||||
inc = uint64(binary.LittleEndian.Uint64(m.rand[:8]))
|
||||
}
|
||||
}
|
||||
|
||||
// Range: [1, m.inc)
|
||||
return 1 + inc, nil
|
||||
}
|
||||
|
||||
type uint80 struct {
|
||||
Hi uint16
|
||||
Lo uint64
|
||||
}
|
||||
|
||||
func (u *uint80) SetBytes(bs []byte) {
|
||||
u.Hi = binary.BigEndian.Uint16(bs[:2])
|
||||
u.Lo = binary.BigEndian.Uint64(bs[2:])
|
||||
}
|
||||
|
||||
func (u *uint80) AppendTo(bs []byte) {
|
||||
binary.BigEndian.PutUint16(bs[:2], u.Hi)
|
||||
binary.BigEndian.PutUint64(bs[2:], u.Lo)
|
||||
}
|
||||
|
||||
func (u *uint80) Add(n uint64) (overflow bool) {
|
||||
lo, hi := u.Lo, u.Hi
|
||||
if u.Lo += n; u.Lo < lo {
|
||||
u.Hi++
|
||||
}
|
||||
return u.Hi < hi
|
||||
}
|
||||
|
||||
func (u uint80) IsZero() bool {
|
||||
return u.Hi == 0 && u.Lo == 0
|
||||
}
|
||||
1
vendor/github.com/opentracing/opentracing-go/.gitignore
generated
vendored
Normal file
1
vendor/github.com/opentracing/opentracing-go/.gitignore
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
coverage.txt
|
||||
20
vendor/github.com/opentracing/opentracing-go/.travis.yml
generated
vendored
Normal file
20
vendor/github.com/opentracing/opentracing-go/.travis.yml
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
language: go
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- go: "1.11.x"
|
||||
- go: "1.12.x"
|
||||
- go: "tip"
|
||||
env:
|
||||
- LINT=true
|
||||
- COVERAGE=true
|
||||
|
||||
install:
|
||||
- if [ "$LINT" == true ]; then go get -u golang.org/x/lint/golint/... ; else echo 'skipping lint'; fi
|
||||
- go get -u github.com/stretchr/testify/...
|
||||
|
||||
script:
|
||||
- make test
|
||||
- go build ./...
|
||||
- if [ "$LINT" == true ]; then make lint ; else echo 'skipping lint'; fi
|
||||
- if [ "$COVERAGE" == true ]; then make cover && bash <(curl -s https://codecov.io/bash) ; else echo 'skipping coverage'; fi
|
||||
46
vendor/github.com/opentracing/opentracing-go/CHANGELOG.md
generated
vendored
Normal file
46
vendor/github.com/opentracing/opentracing-go/CHANGELOG.md
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
Changes by Version
|
||||
==================
|
||||
|
||||
1.1.0 (2019-03-23)
|
||||
-------------------
|
||||
|
||||
Notable changes:
|
||||
- The library is now released under Apache 2.0 license
|
||||
- Use Set() instead of Add() in HTTPHeadersCarrier is functionally a breaking change (fixes issue [#159](https://github.com/opentracing/opentracing-go/issues/159))
|
||||
- 'golang.org/x/net/context' is replaced with 'context' from the standard library
|
||||
|
||||
List of all changes:
|
||||
|
||||
- Export StartSpanFromContextWithTracer (#214) <Aaron Delaney>
|
||||
- Add IsGlobalTracerRegistered() to indicate if a tracer has been registered (#201) <Mike Goldsmith>
|
||||
- Use Set() instead of Add() in HTTPHeadersCarrier (#191) <jeremyxu2010>
|
||||
- Update license to Apache 2.0 (#181) <Andrea Kao>
|
||||
- Replace 'golang.org/x/net/context' with 'context' (#176) <Tony Ghita>
|
||||
- Port of Python opentracing/harness/api_check.py to Go (#146) <chris erway>
|
||||
- Fix race condition in MockSpan.Context() (#170) <Brad>
|
||||
- Add PeerHostIPv4.SetString() (#155) <NeoCN>
|
||||
- Add a Noop log field type to log to allow for optional fields (#150) <Matt Ho>
|
||||
|
||||
|
||||
1.0.2 (2017-04-26)
|
||||
-------------------
|
||||
|
||||
- Add more semantic tags (#139) <Rustam Zagirov>
|
||||
|
||||
|
||||
1.0.1 (2017-02-06)
|
||||
-------------------
|
||||
|
||||
- Correct spelling in comments <Ben Sigelman>
|
||||
- Address race in nextMockID() (#123) <bill fumerola>
|
||||
- log: avoid panic marshaling nil error (#131) <Anthony Voutas>
|
||||
- Deprecate InitGlobalTracer in favor of SetGlobalTracer (#128) <Yuri Shkuro>
|
||||
- Drop Go 1.5 that fails in Travis (#129) <Yuri Shkuro>
|
||||
- Add convenience methods Key() and Value() to log.Field <Ben Sigelman>
|
||||
- Add convenience methods to log.Field (2 years, 6 months ago) <Radu Berinde>
|
||||
|
||||
1.0.0 (2016-09-26)
|
||||
-------------------
|
||||
|
||||
- This release implements OpenTracing Specification 1.0 (https://opentracing.io/spec)
|
||||
|
||||
201
vendor/github.com/opentracing/opentracing-go/LICENSE
generated
vendored
Normal file
201
vendor/github.com/opentracing/opentracing-go/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2016 The OpenTracing Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
20
vendor/github.com/opentracing/opentracing-go/Makefile
generated
vendored
Normal file
20
vendor/github.com/opentracing/opentracing-go/Makefile
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
.DEFAULT_GOAL := test-and-lint
|
||||
|
||||
.PHONY: test-and-lint
|
||||
test-and-lint: test lint
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
go test -v -cover -race ./...
|
||||
|
||||
.PHONY: cover
|
||||
cover:
|
||||
go test -v -coverprofile=coverage.txt -covermode=atomic -race ./...
|
||||
|
||||
.PHONY: lint
|
||||
lint:
|
||||
go fmt ./...
|
||||
golint ./...
|
||||
@# Run again with magic to exit non-zero if golint outputs anything.
|
||||
@! (golint ./... | read dummy)
|
||||
go vet ./...
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user