47
go.mod
47
go.mod
@@ -8,7 +8,9 @@ go 1.13
|
||||
|
||||
require (
|
||||
code.cloudfoundry.org/bytefmt v0.0.0-20190710193110-1eb035ffe2b6
|
||||
github.com/MakeNowJust/heredoc v0.0.0-20171113091838-e9091a26100e // indirect
|
||||
github.com/Masterminds/semver/v3 v3.1.0
|
||||
github.com/Microsoft/go-winio v0.4.12 // indirect
|
||||
github.com/PuerkitoBio/goquery v1.5.0
|
||||
github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535
|
||||
github.com/aws/aws-sdk-go v1.33.12
|
||||
@@ -21,6 +23,7 @@ require (
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
||||
github.com/docker/distribution v2.7.1+incompatible
|
||||
github.com/docker/docker v1.4.2-0.20200203170920-46ec8731fbce
|
||||
github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c // indirect
|
||||
github.com/elastic/go-elasticsearch/v5 v5.6.1
|
||||
github.com/elastic/go-elasticsearch/v6 v6.8.2
|
||||
github.com/elastic/go-elasticsearch/v7 v7.3.0
|
||||
@@ -44,6 +47,7 @@ require (
|
||||
github.com/google/go-cmp v0.5.0
|
||||
github.com/google/uuid v1.1.1
|
||||
github.com/gorilla/websocket v1.4.1
|
||||
github.com/gregjones/httpcache v0.0.0-20181110185634-c63ab54fda8f // indirect
|
||||
github.com/hashicorp/golang-lru v0.5.4
|
||||
github.com/json-iterator/go v1.1.10
|
||||
github.com/jszwec/csvutil v1.5.0
|
||||
@@ -65,14 +69,13 @@ require (
|
||||
github.com/prometheus/client_golang v1.7.1
|
||||
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/sony/sonyflake v0.0.0-20181109022403-6d5bd6181009
|
||||
github.com/speps/go-hashids v2.0.0+incompatible
|
||||
github.com/spf13/cobra v1.0.0
|
||||
github.com/spf13/pflag v1.0.5
|
||||
github.com/spf13/viper v1.4.0
|
||||
github.com/stretchr/testify v1.6.1
|
||||
github.com/xanzy/ssh-agent v0.2.1 // indirect
|
||||
go.etcd.io/etcd v3.3.17+incompatible // indirect
|
||||
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de
|
||||
golang.org/x/net v0.0.0-20201224014010-6772e930b67b
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
|
||||
@@ -140,7 +143,6 @@ replace (
|
||||
github.com/Knetic/govaluate => github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible
|
||||
github.com/MakeNowJust/heredoc => github.com/MakeNowJust/heredoc v0.0.0-20171113091838-e9091a26100e
|
||||
github.com/Masterminds/goutils => github.com/Masterminds/goutils v1.1.0
|
||||
github.com/Masterminds/semver => github.com/Masterminds/semver v1.5.0
|
||||
github.com/Masterminds/semver/v3 => github.com/Masterminds/semver/v3 v3.0.1
|
||||
github.com/Masterminds/sprig/v3 => github.com/Masterminds/sprig/v3 v3.0.0
|
||||
github.com/Masterminds/squirrel => github.com/Masterminds/squirrel v0.0.0-20161115235646-20f192218cf5
|
||||
@@ -156,7 +158,6 @@ replace (
|
||||
github.com/Shopify/logrus-bugsnag => github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d
|
||||
github.com/Shopify/sarama => github.com/Shopify/sarama v1.19.0
|
||||
github.com/Shopify/toxiproxy => github.com/Shopify/toxiproxy v2.1.4+incompatible
|
||||
github.com/StackExchange/wmi => github.com/StackExchange/wmi v0.0.0-20170410192909-ea383cf3ba6e
|
||||
github.com/VividCortex/gohistogram => github.com/VividCortex/gohistogram v1.0.0
|
||||
github.com/afex/hystrix-go => github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5
|
||||
github.com/agnivade/levenshtein => github.com/agnivade/levenshtein v1.0.1
|
||||
@@ -205,7 +206,6 @@ replace (
|
||||
github.com/cespare/xxhash => github.com/cespare/xxhash v1.1.0
|
||||
github.com/cespare/xxhash/v2 => github.com/cespare/xxhash/v2 v2.1.1
|
||||
github.com/chai2010/gettext-go => github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5
|
||||
github.com/chai2010/jsonmap => github.com/chai2010/jsonmap v1.0.0
|
||||
github.com/chromedp/cdproto => github.com/chromedp/cdproto v0.0.0-20200424080200-0de008e41fa0
|
||||
github.com/chromedp/chromedp => github.com/chromedp/chromedp v0.5.3
|
||||
github.com/chzyer/logex => github.com/chzyer/logex v1.1.10
|
||||
@@ -252,7 +252,6 @@ replace (
|
||||
github.com/dgryski/go-bitstream => github.com/dgryski/go-bitstream v0.0.0-20180413035011-3522498ce2c8
|
||||
github.com/dgryski/go-sip13 => github.com/dgryski/go-sip13 v0.0.0-20190329191031-25c5027a8c7b
|
||||
github.com/dhui/dktest => github.com/dhui/dktest v0.3.0
|
||||
github.com/disintegration/imaging => github.com/disintegration/imaging v1.6.1
|
||||
github.com/docker/cli => github.com/docker/cli v0.0.0-20190506213505-d88565df0c2d
|
||||
github.com/docker/distribution => github.com/docker/distribution v2.7.1+incompatible
|
||||
github.com/docker/docker => github.com/docker/engine v1.4.2-0.20200203170920-46ec8731fbce
|
||||
@@ -282,7 +281,6 @@ replace (
|
||||
github.com/emirpasic/gods => github.com/emirpasic/gods v1.12.0
|
||||
github.com/envoyproxy/go-control-plane => github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473
|
||||
github.com/envoyproxy/protoc-gen-validate => github.com/envoyproxy/protoc-gen-validate v0.1.0
|
||||
github.com/erikstmartin/go-testdb => github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5
|
||||
github.com/evanphx/json-patch => github.com/evanphx/json-patch v4.9.0+incompatible
|
||||
github.com/evanphx/json-patch/v5 => github.com/evanphx/json-patch/v5 v5.0.0
|
||||
github.com/exponent-io/jsonpath => github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d
|
||||
@@ -301,8 +299,6 @@ replace (
|
||||
github.com/fsouza/fake-gcs-server => github.com/fsouza/fake-gcs-server v1.7.0
|
||||
github.com/garyburd/redigo => github.com/garyburd/redigo v1.6.0
|
||||
github.com/ghodss/yaml => github.com/ghodss/yaml v1.0.0
|
||||
github.com/gin-contrib/sse => github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3
|
||||
github.com/gin-gonic/gin => github.com/gin-gonic/gin v1.4.0
|
||||
github.com/gliderlabs/ssh => github.com/gliderlabs/ssh v0.1.1
|
||||
github.com/glycerine/go-unsnap-stream => github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd
|
||||
github.com/glycerine/goconvey => github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31
|
||||
@@ -311,7 +307,6 @@ replace (
|
||||
github.com/go-logfmt/logfmt => github.com/go-logfmt/logfmt v0.5.0
|
||||
github.com/go-logr/logr => github.com/go-logr/logr v0.1.0
|
||||
github.com/go-logr/zapr => github.com/go-logr/zapr v0.1.1
|
||||
github.com/go-ole/go-ole => github.com/go-ole/go-ole v1.2.1
|
||||
github.com/go-openapi/analysis => github.com/go-openapi/analysis v0.19.10
|
||||
github.com/go-openapi/errors => github.com/go-openapi/errors v0.19.4
|
||||
github.com/go-openapi/jsonpointer => github.com/go-openapi/jsonpointer v0.19.3
|
||||
@@ -325,6 +320,7 @@ replace (
|
||||
github.com/go-playground/locales => github.com/go-playground/locales v0.12.1
|
||||
github.com/go-playground/universal-translator => github.com/go-playground/universal-translator v0.0.0-20170327191703-71201497bace
|
||||
github.com/go-redis/redis => github.com/go-redis/redis v6.15.2+incompatible
|
||||
github.com/go-resty/resty/v2 => github.com/go-resty/resty/v2 v2.5.0
|
||||
github.com/go-sql-driver/mysql => github.com/go-sql-driver/mysql v1.5.0
|
||||
github.com/go-stack/stack => github.com/go-stack/stack v1.8.0
|
||||
github.com/gobuffalo/attrs => github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd
|
||||
@@ -346,6 +342,7 @@ replace (
|
||||
github.com/gocql/gocql => github.com/gocql/gocql v0.0.0-20200526081602-cd04bd7f22a7
|
||||
github.com/gocraft/dbr => github.com/gocraft/dbr v0.0.0-20180507214907-a0fd650918f6
|
||||
github.com/godbus/dbus => github.com/godbus/dbus v0.0.0-20190402143921-271e53dc4968
|
||||
github.com/godror/godror => github.com/godror/godror v0.13.3
|
||||
github.com/gofrs/flock => github.com/gofrs/flock v0.7.1
|
||||
github.com/gofrs/uuid => github.com/gofrs/uuid v3.2.0+incompatible
|
||||
github.com/gogo/googleapis => github.com/gogo/googleapis v1.1.0
|
||||
@@ -372,7 +369,6 @@ replace (
|
||||
github.com/google/go-github => github.com/google/go-github v17.0.0+incompatible
|
||||
github.com/google/go-querystring => github.com/google/go-querystring v1.0.0
|
||||
github.com/google/gofuzz => github.com/google/gofuzz v1.1.0
|
||||
github.com/google/gops => github.com/google/gops v0.3.6
|
||||
github.com/google/martian => github.com/google/martian v2.1.0+incompatible
|
||||
github.com/google/pprof => github.com/google/pprof v0.0.0-20200417002340-c6e0a841f49a
|
||||
github.com/google/renameio => github.com/google/renameio v0.1.0
|
||||
@@ -431,10 +427,8 @@ replace (
|
||||
github.com/jackc/pgx => github.com/jackc/pgx v3.2.0+incompatible
|
||||
github.com/jbenet/go-context => github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99
|
||||
github.com/jessevdk/go-flags => github.com/jessevdk/go-flags v1.4.0
|
||||
github.com/jinzhu/gorm => github.com/jinzhu/gorm v1.9.2
|
||||
github.com/jinzhu/inflection => github.com/jinzhu/inflection v0.0.0-20180308033659-04140366298a
|
||||
github.com/jinzhu/now => github.com/jinzhu/now v1.0.0
|
||||
github.com/jmespath/go-jmespath => github.com/jmespath/go-jmespath v0.3.0
|
||||
github.com/jmoiron/sqlx => github.com/jmoiron/sqlx v1.2.0
|
||||
github.com/joeshaw/multierror => github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901
|
||||
github.com/joho/godotenv => github.com/joho/godotenv v1.3.0
|
||||
github.com/jonboulle/clockwork => github.com/jonboulle/clockwork v0.1.0
|
||||
@@ -443,6 +437,7 @@ replace (
|
||||
github.com/json-iterator/go => github.com/json-iterator/go v1.1.10
|
||||
github.com/jstemmer/go-junit-report => github.com/jstemmer/go-junit-report v0.9.1
|
||||
github.com/jsternberg/zap-logfmt => github.com/jsternberg/zap-logfmt v1.0.0
|
||||
github.com/jszwec/csvutil => github.com/jszwec/csvutil v1.5.0
|
||||
github.com/jtolds/gls => github.com/jtolds/gls v4.20.0+incompatible
|
||||
github.com/julienschmidt/httprouter => github.com/julienschmidt/httprouter v1.3.0
|
||||
github.com/jung-kurt/gofpdf => github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5
|
||||
@@ -451,7 +446,6 @@ replace (
|
||||
github.com/karrick/godirwalk => github.com/karrick/godirwalk v1.10.3
|
||||
github.com/kelseyhightower/envconfig => github.com/kelseyhightower/envconfig v1.4.0
|
||||
github.com/kevinburke/ssh_config => github.com/kevinburke/ssh_config v0.0.0-20180830205328-81db2a75821e
|
||||
github.com/keybase/go-ps => github.com/keybase/go-ps v0.0.0-20161005175911-668c8856d999
|
||||
github.com/kisielk/errcheck => github.com/kisielk/errcheck v1.2.0
|
||||
github.com/kisielk/gotool => github.com/kisielk/gotool v1.0.0
|
||||
github.com/klauspost/compress => github.com/klauspost/compress v1.9.5
|
||||
@@ -459,7 +453,6 @@ replace (
|
||||
github.com/klauspost/crc32 => github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6
|
||||
github.com/klauspost/pgzip => github.com/klauspost/pgzip v1.0.2-0.20170402124221-0bf5dcad4ada
|
||||
github.com/knq/sysutil => github.com/knq/sysutil v0.0.0-20191005231841-15668db23d08
|
||||
github.com/koding/multiconfig => github.com/koding/multiconfig v0.0.0-20171124222453-69c27309b2d7
|
||||
github.com/konsorten/go-windows-terminal-sequences => github.com/konsorten/go-windows-terminal-sequences v1.0.2
|
||||
github.com/kr/pretty => github.com/kr/pretty v0.2.0
|
||||
github.com/kr/pty => github.com/kr/pty v1.1.5
|
||||
@@ -484,6 +477,7 @@ replace (
|
||||
github.com/mattn/go-colorable => github.com/mattn/go-colorable v0.1.6
|
||||
github.com/mattn/go-ieproxy => github.com/mattn/go-ieproxy v0.0.0-20191113090002-7c0f6868bffe
|
||||
github.com/mattn/go-isatty => github.com/mattn/go-isatty v0.0.12
|
||||
github.com/mattn/go-oci8 => github.com/mattn/go-oci8 v0.0.7
|
||||
github.com/mattn/go-runewidth => github.com/mattn/go-runewidth v0.0.4
|
||||
github.com/mattn/go-shellwords => github.com/mattn/go-shellwords v1.0.5
|
||||
github.com/mattn/go-sqlite3 => github.com/mattn/go-sqlite3 v1.11.0
|
||||
@@ -580,11 +574,11 @@ replace (
|
||||
github.com/rafaeljusto/redigomock => github.com/rafaeljusto/redigomock v0.0.0-20190202135759-257e089e14a1
|
||||
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 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/rubenv/sql-migrate => github.com/rubenv/sql-migrate v0.0.0-20200616145509-8d140a17f351
|
||||
github.com/russross/blackfriday => github.com/russross/blackfriday v1.5.2
|
||||
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
|
||||
@@ -595,8 +589,6 @@ replace (
|
||||
github.com/segmentio/kafka-go => github.com/segmentio/kafka-go v0.2.0
|
||||
github.com/sercand/kuberesolver => github.com/sercand/kuberesolver v2.4.0+incompatible
|
||||
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/shopspring/decimal => github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24
|
||||
github.com/shurcooL/httpfs => github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749
|
||||
github.com/shurcooL/vfsgen => github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd
|
||||
@@ -629,7 +621,6 @@ replace (
|
||||
github.com/uber/jaeger-client-go => github.com/uber/jaeger-client-go v2.23.0+incompatible
|
||||
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.20.0
|
||||
github.com/vektah/gqlparser => github.com/vektah/gqlparser v1.1.2
|
||||
github.com/weaveworks/common => github.com/weaveworks/common v0.0.0-20200820123129-280614068c5e
|
||||
@@ -651,6 +642,7 @@ replace (
|
||||
github.com/yvasiyarov/go-metrics => github.com/yvasiyarov/go-metrics v0.0.0-20150112132944-c25f46c4b940
|
||||
github.com/yvasiyarov/gorelic => github.com/yvasiyarov/gorelic v0.0.6
|
||||
github.com/yvasiyarov/newrelic_platform_go => github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f
|
||||
github.com/ziutek/mymysql => github.com/ziutek/mymysql v1.5.4
|
||||
gitlab.com/nyarla/go-crypt => gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b
|
||||
go.elastic.co/apm => go.elastic.co/apm v1.5.0
|
||||
go.elastic.co/apm/module/apmhttp => go.elastic.co/apm/module/apmhttp v1.5.0
|
||||
@@ -690,7 +682,6 @@ replace (
|
||||
google.golang.org/protobuf => google.golang.org/protobuf v1.23.0
|
||||
gopkg.in/airbrake/gobrake.v2 => gopkg.in/airbrake/gobrake.v2 v2.0.9
|
||||
gopkg.in/alecthomas/kingpin.v2 => gopkg.in/alecthomas/kingpin.v2 v2.2.6
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 => gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc
|
||||
gopkg.in/asn1-ber.v1 => gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d
|
||||
gopkg.in/cas.v2 => gopkg.in/cas.v2 v2.2.0
|
||||
gopkg.in/check.v1 => gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15
|
||||
@@ -701,12 +692,10 @@ replace (
|
||||
gopkg.in/gcfg.v1 => gopkg.in/gcfg.v1 v1.2.3
|
||||
gopkg.in/gemnasium/logrus-airbrake-hook.v2 => gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2
|
||||
gopkg.in/go-playground/assert.v1 => gopkg.in/go-playground/assert.v1 v1.2.1
|
||||
gopkg.in/go-playground/validator.v8 => gopkg.in/go-playground/validator.v8 v8.18.2
|
||||
gopkg.in/go-playground/validator.v9 => gopkg.in/go-playground/validator.v9 v9.27.0
|
||||
gopkg.in/gomail.v2 => gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
|
||||
gopkg.in/gorp.v1 => gopkg.in/gorp.v1 v1.7.2
|
||||
gopkg.in/inf.v0 => gopkg.in/inf.v0 v0.9.1
|
||||
gopkg.in/ini.v1 => gopkg.in/ini.v1 v1.57.0
|
||||
gopkg.in/mail.v2 => gopkg.in/mail.v2 v2.3.1
|
||||
gopkg.in/natefinch/lumberjack.v2 => gopkg.in/natefinch/lumberjack.v2 v2.0.0
|
||||
gopkg.in/square/go-jose.v1 => gopkg.in/square/go-jose.v1 v1.1.2
|
||||
gopkg.in/square/go-jose.v2 => gopkg.in/square/go-jose.v2 v2.4.0
|
||||
@@ -742,14 +731,8 @@ replace (
|
||||
k8s.io/metrics => k8s.io/metrics v0.18.6
|
||||
k8s.io/utils => k8s.io/utils v0.0.0-20200603063816-c1c6865ac451
|
||||
kubesphere.io/client-go => ./staging/src/kubesphere.io/client-go
|
||||
kubesphere.io/im => kubesphere.io/im v0.1.0
|
||||
openpitrix.io/iam => openpitrix.io/iam v0.1.0
|
||||
openpitrix.io/libqueue => openpitrix.io/libqueue v0.4.1
|
||||
openpitrix.io/logger => openpitrix.io/logger v0.1.0
|
||||
openpitrix.io/notification => openpitrix.io/notification v0.2.2
|
||||
openpitrix.io/openpitrix => openpitrix.io/openpitrix v0.4.9-0.20200611125425-ae07f141e797
|
||||
kubesphere.io/monitoring-dashboard => kubesphere.io/monitoring-dashboard v0.1.2
|
||||
rsc.io/binaryregexp => rsc.io/binaryregexp v0.2.0
|
||||
rsc.io/goversion => rsc.io/goversion v1.0.0
|
||||
rsc.io/letsencrypt => rsc.io/letsencrypt v0.0.1
|
||||
rsc.io/pdf => rsc.io/pdf v0.1.1
|
||||
rsc.io/quote/v3 => rsc.io/quote/v3 v3.1.0
|
||||
@@ -765,4 +748,4 @@ replace (
|
||||
sigs.k8s.io/yaml => sigs.k8s.io/yaml v1.2.0
|
||||
sourcegraph.com/sourcegraph/appdash => sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0
|
||||
vbom.ml/util => vbom.ml/util v0.0.0-20160121211510-db5cfe13f5cc
|
||||
)
|
||||
)
|
||||
|
||||
30
vendor/github.com/go-resty/resty/v2/.gitignore
generated
vendored
Normal file
30
vendor/github.com/go-resty/resty/v2/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
# 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
|
||||
|
||||
coverage.out
|
||||
coverage.txt
|
||||
|
||||
# Exclude intellij IDE folders
|
||||
.idea/*
|
||||
21
vendor/github.com/go-resty/resty/v2/.travis.yml
generated
vendored
Normal file
21
vendor/github.com/go-resty/resty/v2/.travis.yml
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
language: go
|
||||
|
||||
os: linux
|
||||
|
||||
go: # use travis ci resource effectively, keep always latest 2 versions and tip :)
|
||||
- 1.15.x
|
||||
- 1.14.x
|
||||
- tip
|
||||
|
||||
install:
|
||||
- go get -v -t ./...
|
||||
|
||||
script:
|
||||
- go test ./... -race -coverprofile=coverage.txt -covermode=atomic
|
||||
|
||||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
|
||||
jobs:
|
||||
allow_failures:
|
||||
- go: tip
|
||||
36
vendor/github.com/go-resty/resty/v2/BUILD.bazel
generated
vendored
Normal file
36
vendor/github.com/go-resty/resty/v2/BUILD.bazel
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
package(default_visibility = ["//visibility:private"])
|
||||
|
||||
load("@bazel_gazelle//:def.bzl", "gazelle")
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||
|
||||
gazelle(
|
||||
name = "gazelle",
|
||||
command = "fix",
|
||||
prefix = "github.com/go-resty/resty/v2",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = glob(
|
||||
["*.go"],
|
||||
exclude = ["*_test.go"],
|
||||
),
|
||||
importpath = "github.com/go-resty/resty/v2",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = ["@org_golang_x_net//publicsuffix:go_default_library"],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs =
|
||||
glob(
|
||||
["*_test.go"],
|
||||
exclude = ["example_test.go"],
|
||||
),
|
||||
data = glob([".testdata/*"]),
|
||||
embed = [":go_default_library"],
|
||||
importpath = "github.com/go-resty/resty/v2",
|
||||
deps = [
|
||||
"@org_golang_x_net//proxy:go_default_library",
|
||||
],
|
||||
)
|
||||
21
vendor/github.com/go-resty/resty/v2/LICENSE
generated
vendored
Normal file
21
vendor/github.com/go-resty/resty/v2/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015-2020 Jeevanandam M., https://myjeeva.com <jeeva@myjeeva.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
886
vendor/github.com/go-resty/resty/v2/README.md
generated
vendored
Normal file
886
vendor/github.com/go-resty/resty/v2/README.md
generated
vendored
Normal file
@@ -0,0 +1,886 @@
|
||||
<p align="center">
|
||||
<h1 align="center">Resty</h1>
|
||||
<p align="center">Simple HTTP and REST client library for Go (inspired by Ruby rest-client)</p>
|
||||
<p align="center"><a href="#features">Features</a> section describes in detail about Resty capabilities</p>
|
||||
</p>
|
||||
<p align="center">
|
||||
<p align="center"><a href="https://travis-ci.org/go-resty/resty"><img src="https://travis-ci.org/go-resty/resty.svg?branch=master" alt="Build Status"></a> <a href="https://codecov.io/gh/go-resty/resty/branch/master"><img src="https://codecov.io/gh/go-resty/resty/branch/master/graph/badge.svg" alt="Code Coverage"></a> <a href="https://goreportcard.com/report/go-resty/resty"><img src="https://goreportcard.com/badge/go-resty/resty" alt="Go Report Card"></a> <a href="https://github.com/go-resty/resty/releases/latest"><img src="https://img.shields.io/badge/version-2.5.0-blue.svg" alt="Release Version"></a> <a href="https://pkg.go.dev/github.com/go-resty/resty/v2"><img src="https://godoc.org/github.com/go-resty/resty?status.svg" alt="GoDoc"></a> <a href="LICENSE"><img src="https://img.shields.io/github/license/go-resty/resty.svg" alt="License"></a> <a href="https://github.com/avelino/awesome-go"><img src="https://awesome.re/mentioned-badge.svg" alt="Mentioned in Awesome Go"></a></p>
|
||||
</p>
|
||||
<p align="center">
|
||||
<h4 align="center">Resty Communication Channels</h4>
|
||||
<p align="center"><a href="https://gitter.im/go_resty/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge"><img src="https://badges.gitter.im/go_resty/community.svg" alt="Chat on Gitter - Resty Community"></a> <a href="https://twitter.com/go_resty"><img src="https://img.shields.io/badge/twitter-@go__resty-55acee.svg" alt="Twitter @go_resty"></a></p>
|
||||
</p>
|
||||
|
||||
## News
|
||||
|
||||
* v2.5.0 [released](https://github.com/go-resty/resty/releases/tag/v2.5.0) and tagged on Feb 11, 2021.
|
||||
* v2.0.0 [released](https://github.com/go-resty/resty/releases/tag/v2.0.0) and tagged on Jul 16, 2019.
|
||||
* v1.12.0 [released](https://github.com/go-resty/resty/releases/tag/v1.12.0) and tagged on Feb 27, 2019.
|
||||
* v1.0 released and tagged on Sep 25, 2017. - Resty's first version was released on Sep 15, 2015 then it grew gradually as a very handy and helpful library. Its been a two years since first release. I'm very thankful to Resty users and its [contributors](https://github.com/go-resty/resty/graphs/contributors).
|
||||
|
||||
## Features
|
||||
|
||||
* GET, POST, PUT, DELETE, HEAD, PATCH, OPTIONS, etc.
|
||||
* Simple and chainable methods for settings and request
|
||||
* [Request](https://godoc.org/github.com/go-resty/resty#Request) Body can be `string`, `[]byte`, `struct`, `map`, `slice` and `io.Reader` too
|
||||
* Auto detects `Content-Type`
|
||||
* Buffer less processing for `io.Reader`
|
||||
* Native `*http.Request` instance may be accessed during middleware and request execution via `Request.RawRequest`
|
||||
* Request Body can be read multiple times via `Request.RawRequest.GetBody()`
|
||||
* [Response](https://godoc.org/github.com/go-resty/resty#Response) object gives you more possibility
|
||||
* Access as `[]byte` array - `response.Body()` OR Access as `string` - `response.String()`
|
||||
* Know your `response.Time()` and when we `response.ReceivedAt()`
|
||||
* Automatic marshal and unmarshal for `JSON` and `XML` content type
|
||||
* Default is `JSON`, if you supply `struct/map` without header `Content-Type`
|
||||
* For auto-unmarshal, refer to -
|
||||
- Success scenario [Request.SetResult()](https://godoc.org/github.com/go-resty/resty#Request.SetResult) and [Response.Result()](https://godoc.org/github.com/go-resty/resty#Response.Result).
|
||||
- Error scenario [Request.SetError()](https://godoc.org/github.com/go-resty/resty#Request.SetError) and [Response.Error()](https://godoc.org/github.com/go-resty/resty#Response.Error).
|
||||
- Supports [RFC7807](https://tools.ietf.org/html/rfc7807) - `application/problem+json` & `application/problem+xml`
|
||||
* Easy to upload one or more file(s) via `multipart/form-data`
|
||||
* Auto detects file content type
|
||||
* Request URL [Path Params (aka URI Params)](https://godoc.org/github.com/go-resty/resty#Request.SetPathParams)
|
||||
* Backoff Retry Mechanism with retry condition function [reference](retry_test.go)
|
||||
* Resty client HTTP & REST [Request](https://godoc.org/github.com/go-resty/resty#Client.OnBeforeRequest) and [Response](https://godoc.org/github.com/go-resty/resty#Client.OnAfterResponse) middlewares
|
||||
* `Request.SetContext` supported
|
||||
* Authorization option of `BasicAuth` and `Bearer` token
|
||||
* Set request `ContentLength` value for all request or particular request
|
||||
* Custom [Root Certificates](https://godoc.org/github.com/go-resty/resty#Client.SetRootCertificate) and Client [Certificates](https://godoc.org/github.com/go-resty/resty#Client.SetCertificates)
|
||||
* Download/Save HTTP response directly into File, like `curl -o` flag. See [SetOutputDirectory](https://godoc.org/github.com/go-resty/resty#Client.SetOutputDirectory) & [SetOutput](https://godoc.org/github.com/go-resty/resty#Request.SetOutput).
|
||||
* Cookies for your request and CookieJar support
|
||||
* SRV Record based request instead of Host URL
|
||||
* Client settings like `Timeout`, `RedirectPolicy`, `Proxy`, `TLSClientConfig`, `Transport`, etc.
|
||||
* Optionally allows GET request with payload, see [SetAllowGetMethodPayload](https://godoc.org/github.com/go-resty/resty#Client.SetAllowGetMethodPayload)
|
||||
* Supports registering external JSON library into resty, see [how to use](https://github.com/go-resty/resty/issues/76#issuecomment-314015250)
|
||||
* Exposes Response reader without reading response (no auto-unmarshaling) if need be, see [how to use](https://github.com/go-resty/resty/issues/87#issuecomment-322100604)
|
||||
* Option to specify expected `Content-Type` when response `Content-Type` header missing. Refer to [#92](https://github.com/go-resty/resty/issues/92)
|
||||
* Resty design
|
||||
* Have client level settings & options and also override at Request level if you want to
|
||||
* Request and Response middleware
|
||||
* Create Multiple clients if you want to `resty.New()`
|
||||
* Supports `http.RoundTripper` implementation, see [SetTransport](https://godoc.org/github.com/go-resty/resty#Client.SetTransport)
|
||||
* goroutine concurrent safe
|
||||
* Resty Client trace, see [Client.EnableTrace](https://godoc.org/github.com/go-resty/resty#Client.EnableTrace) and [Request.EnableTrace](https://godoc.org/github.com/go-resty/resty#Request.EnableTrace)
|
||||
* Since v2.4.0, trace info contains a `RequestAttempt` value, and the `Request` object contains an `Attempt` attribute
|
||||
* Debug mode - clean and informative logging presentation
|
||||
* Gzip - Go does it automatically also resty has fallback handling too
|
||||
* Works fine with `HTTP/2` and `HTTP/1.1`
|
||||
* [Bazel support](#bazel-support)
|
||||
* Easily mock Resty for testing, [for e.g.](#mocking-http-requests-using-httpmock-library)
|
||||
* Well tested client library
|
||||
|
||||
### Included Batteries
|
||||
|
||||
* Redirect Policies - see [how to use](#redirect-policy)
|
||||
* NoRedirectPolicy
|
||||
* FlexibleRedirectPolicy
|
||||
* DomainCheckRedirectPolicy
|
||||
* etc. [more info](redirect.go)
|
||||
* Retry Mechanism [how to use](#retries)
|
||||
* Backoff Retry
|
||||
* Conditional Retry
|
||||
* SRV Record based request instead of Host URL [how to use](resty_test.go#L1412)
|
||||
* etc (upcoming - throw your idea's [here](https://github.com/go-resty/resty/issues)).
|
||||
|
||||
|
||||
#### Supported Go Versions
|
||||
|
||||
Initially Resty started supporting `go modules` since `v1.10.0` release.
|
||||
|
||||
Starting Resty v2 and higher versions, it fully embraces [go modules](https://github.com/golang/go/wiki/Modules) package release. It requires a Go version capable of understanding `/vN` suffixed imports:
|
||||
|
||||
- 1.9.7+
|
||||
- 1.10.3+
|
||||
- 1.11+
|
||||
|
||||
|
||||
## It might be beneficial for your project :smile:
|
||||
|
||||
Resty author also published following projects for Go Community.
|
||||
|
||||
* [aah framework](https://aahframework.org) - A secure, flexible, rapid Go web framework.
|
||||
* [THUMBAI](https://thumbai.app) - Go Mod Repository, Go Vanity Service and Simple Proxy Server.
|
||||
* [go-model](https://github.com/jeevatkm/go-model) - Robust & Easy to use model mapper and utility methods for Go `struct`.
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
# Go Modules
|
||||
require github.com/go-resty/resty/v2 v2.4.0
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
The following samples will assist you to become as comfortable as possible with resty library.
|
||||
|
||||
```go
|
||||
// Import resty into your code and refer it as `resty`.
|
||||
import "github.com/go-resty/resty/v2"
|
||||
```
|
||||
|
||||
#### Simple GET
|
||||
|
||||
```go
|
||||
// Create a Resty Client
|
||||
client := resty.New()
|
||||
|
||||
resp, err := client.R().
|
||||
EnableTrace().
|
||||
Get("https://httpbin.org/get")
|
||||
|
||||
// Explore response object
|
||||
fmt.Println("Response Info:")
|
||||
fmt.Println(" Error :", err)
|
||||
fmt.Println(" Status Code:", resp.StatusCode())
|
||||
fmt.Println(" Status :", resp.Status())
|
||||
fmt.Println(" Proto :", resp.Proto())
|
||||
fmt.Println(" Time :", resp.Time())
|
||||
fmt.Println(" Received At:", resp.ReceivedAt())
|
||||
fmt.Println(" Body :\n", resp)
|
||||
fmt.Println()
|
||||
|
||||
// Explore trace info
|
||||
fmt.Println("Request Trace Info:")
|
||||
ti := resp.Request.TraceInfo()
|
||||
fmt.Println(" DNSLookup :", ti.DNSLookup)
|
||||
fmt.Println(" ConnTime :", ti.ConnTime)
|
||||
fmt.Println(" TCPConnTime :", ti.TCPConnTime)
|
||||
fmt.Println(" TLSHandshake :", ti.TLSHandshake)
|
||||
fmt.Println(" ServerTime :", ti.ServerTime)
|
||||
fmt.Println(" ResponseTime :", ti.ResponseTime)
|
||||
fmt.Println(" TotalTime :", ti.TotalTime)
|
||||
fmt.Println(" IsConnReused :", ti.IsConnReused)
|
||||
fmt.Println(" IsConnWasIdle :", ti.IsConnWasIdle)
|
||||
fmt.Println(" ConnIdleTime :", ti.ConnIdleTime)
|
||||
fmt.Println(" RequestAttempt:", ti.RequestAttempt)
|
||||
fmt.Println(" RemoteAddr :", ti.RemoteAddr.String())
|
||||
|
||||
/* Output
|
||||
Response Info:
|
||||
Error : <nil>
|
||||
Status Code: 200
|
||||
Status : 200 OK
|
||||
Proto : HTTP/2.0
|
||||
Time : 457.034718ms
|
||||
Received At: 2020-09-14 15:35:29.784681 -0700 PDT m=+0.458137045
|
||||
Body :
|
||||
{
|
||||
"args": {},
|
||||
"headers": {
|
||||
"Accept-Encoding": "gzip",
|
||||
"Host": "httpbin.org",
|
||||
"User-Agent": "go-resty/2.4.0 (https://github.com/go-resty/resty)",
|
||||
"X-Amzn-Trace-Id": "Root=1-5f5ff031-000ff6292204aa6898e4de49"
|
||||
},
|
||||
"origin": "0.0.0.0",
|
||||
"url": "https://httpbin.org/get"
|
||||
}
|
||||
|
||||
Request Trace Info:
|
||||
DNSLookup : 4.074657ms
|
||||
ConnTime : 381.709936ms
|
||||
TCPConnTime : 77.428048ms
|
||||
TLSHandshake : 299.623597ms
|
||||
ServerTime : 75.414703ms
|
||||
ResponseTime : 79.337µs
|
||||
TotalTime : 457.034718ms
|
||||
IsConnReused : false
|
||||
IsConnWasIdle : false
|
||||
ConnIdleTime : 0s
|
||||
RequestAttempt: 1
|
||||
RemoteAddr : 3.221.81.55:443
|
||||
*/
|
||||
```
|
||||
|
||||
#### Enhanced GET
|
||||
|
||||
```go
|
||||
// Create a Resty Client
|
||||
client := resty.New()
|
||||
|
||||
resp, err := client.R().
|
||||
SetQueryParams(map[string]string{
|
||||
"page_no": "1",
|
||||
"limit": "20",
|
||||
"sort":"name",
|
||||
"order": "asc",
|
||||
"random":strconv.FormatInt(time.Now().Unix(), 10),
|
||||
}).
|
||||
SetHeader("Accept", "application/json").
|
||||
SetAuthToken("BC594900518B4F7EAC75BD37F019E08FBC594900518B4F7EAC75BD37F019E08F").
|
||||
Get("/search_result")
|
||||
|
||||
|
||||
// Sample of using Request.SetQueryString method
|
||||
resp, err := client.R().
|
||||
SetQueryString("productId=232&template=fresh-sample&cat=resty&source=google&kw=buy a lot more").
|
||||
SetHeader("Accept", "application/json").
|
||||
SetAuthToken("BC594900518B4F7EAC75BD37F019E08FBC594900518B4F7EAC75BD37F019E08F").
|
||||
Get("/show_product")
|
||||
|
||||
|
||||
// If necessary, you can force response content type to tell Resty to parse a JSON response into your struct
|
||||
resp, err := client.R().
|
||||
SetResult(result).
|
||||
ForceContentType("application/json").
|
||||
Get("v2/alpine/manifests/latest")
|
||||
```
|
||||
|
||||
#### Various POST method combinations
|
||||
|
||||
```go
|
||||
// Create a Resty Client
|
||||
client := resty.New()
|
||||
|
||||
// POST JSON string
|
||||
// No need to set content type, if you have client level setting
|
||||
resp, err := client.R().
|
||||
SetHeader("Content-Type", "application/json").
|
||||
SetBody(`{"username":"testuser", "password":"testpass"}`).
|
||||
SetResult(&AuthSuccess{}). // or SetResult(AuthSuccess{}).
|
||||
Post("https://myapp.com/login")
|
||||
|
||||
// POST []byte array
|
||||
// No need to set content type, if you have client level setting
|
||||
resp, err := client.R().
|
||||
SetHeader("Content-Type", "application/json").
|
||||
SetBody([]byte(`{"username":"testuser", "password":"testpass"}`)).
|
||||
SetResult(&AuthSuccess{}). // or SetResult(AuthSuccess{}).
|
||||
Post("https://myapp.com/login")
|
||||
|
||||
// POST Struct, default is JSON content type. No need to set one
|
||||
resp, err := client.R().
|
||||
SetBody(User{Username: "testuser", Password: "testpass"}).
|
||||
SetResult(&AuthSuccess{}). // or SetResult(AuthSuccess{}).
|
||||
SetError(&AuthError{}). // or SetError(AuthError{}).
|
||||
Post("https://myapp.com/login")
|
||||
|
||||
// POST Map, default is JSON content type. No need to set one
|
||||
resp, err := client.R().
|
||||
SetBody(map[string]interface{}{"username": "testuser", "password": "testpass"}).
|
||||
SetResult(&AuthSuccess{}). // or SetResult(AuthSuccess{}).
|
||||
SetError(&AuthError{}). // or SetError(AuthError{}).
|
||||
Post("https://myapp.com/login")
|
||||
|
||||
// POST of raw bytes for file upload. For example: upload file to Dropbox
|
||||
fileBytes, _ := ioutil.ReadFile("/Users/jeeva/mydocument.pdf")
|
||||
|
||||
// See we are not setting content-type header, since go-resty automatically detects Content-Type for you
|
||||
resp, err := client.R().
|
||||
SetBody(fileBytes).
|
||||
SetContentLength(true). // Dropbox expects this value
|
||||
SetAuthToken("<your-auth-token>").
|
||||
SetError(&DropboxError{}). // or SetError(DropboxError{}).
|
||||
Post("https://content.dropboxapi.com/1/files_put/auto/resty/mydocument.pdf") // for upload Dropbox supports PUT too
|
||||
|
||||
// Note: resty detects Content-Type for request body/payload if content type header is not set.
|
||||
// * For struct and map data type defaults to 'application/json'
|
||||
// * Fallback is plain text content type
|
||||
```
|
||||
|
||||
#### Sample PUT
|
||||
|
||||
You can use various combinations of `PUT` method call like demonstrated for `POST`.
|
||||
|
||||
```go
|
||||
// Note: This is one sample of PUT method usage, refer POST for more combination
|
||||
|
||||
// Create a Resty Client
|
||||
client := resty.New()
|
||||
|
||||
// Request goes as JSON content type
|
||||
// No need to set auth token, error, if you have client level settings
|
||||
resp, err := client.R().
|
||||
SetBody(Article{
|
||||
Title: "go-resty",
|
||||
Content: "This is my article content, oh ya!",
|
||||
Author: "Jeevanandam M",
|
||||
Tags: []string{"article", "sample", "resty"},
|
||||
}).
|
||||
SetAuthToken("C6A79608-782F-4ED0-A11D-BD82FAD829CD").
|
||||
SetError(&Error{}). // or SetError(Error{}).
|
||||
Put("https://myapp.com/article/1234")
|
||||
```
|
||||
|
||||
#### Sample PATCH
|
||||
|
||||
You can use various combinations of `PATCH` method call like demonstrated for `POST`.
|
||||
|
||||
```go
|
||||
// Note: This is one sample of PUT method usage, refer POST for more combination
|
||||
|
||||
// Create a Resty Client
|
||||
client := resty.New()
|
||||
|
||||
// Request goes as JSON content type
|
||||
// No need to set auth token, error, if you have client level settings
|
||||
resp, err := client.R().
|
||||
SetBody(Article{
|
||||
Tags: []string{"new tag1", "new tag2"},
|
||||
}).
|
||||
SetAuthToken("C6A79608-782F-4ED0-A11D-BD82FAD829CD").
|
||||
SetError(&Error{}). // or SetError(Error{}).
|
||||
Patch("https://myapp.com/articles/1234")
|
||||
```
|
||||
|
||||
#### Sample DELETE, HEAD, OPTIONS
|
||||
|
||||
```go
|
||||
// Create a Resty Client
|
||||
client := resty.New()
|
||||
|
||||
// DELETE a article
|
||||
// No need to set auth token, error, if you have client level settings
|
||||
resp, err := client.R().
|
||||
SetAuthToken("C6A79608-782F-4ED0-A11D-BD82FAD829CD").
|
||||
SetError(&Error{}). // or SetError(Error{}).
|
||||
Delete("https://myapp.com/articles/1234")
|
||||
|
||||
// DELETE a articles with payload/body as a JSON string
|
||||
// No need to set auth token, error, if you have client level settings
|
||||
resp, err := client.R().
|
||||
SetAuthToken("C6A79608-782F-4ED0-A11D-BD82FAD829CD").
|
||||
SetError(&Error{}). // or SetError(Error{}).
|
||||
SetHeader("Content-Type", "application/json").
|
||||
SetBody(`{article_ids: [1002, 1006, 1007, 87683, 45432] }`).
|
||||
Delete("https://myapp.com/articles")
|
||||
|
||||
// HEAD of resource
|
||||
// No need to set auth token, if you have client level settings
|
||||
resp, err := client.R().
|
||||
SetAuthToken("C6A79608-782F-4ED0-A11D-BD82FAD829CD").
|
||||
Head("https://myapp.com/videos/hi-res-video")
|
||||
|
||||
// OPTIONS of resource
|
||||
// No need to set auth token, if you have client level settings
|
||||
resp, err := client.R().
|
||||
SetAuthToken("C6A79608-782F-4ED0-A11D-BD82FAD829CD").
|
||||
Options("https://myapp.com/servers/nyc-dc-01")
|
||||
```
|
||||
|
||||
### Multipart File(s) upload
|
||||
|
||||
#### Using io.Reader
|
||||
|
||||
```go
|
||||
profileImgBytes, _ := ioutil.ReadFile("/Users/jeeva/test-img.png")
|
||||
notesBytes, _ := ioutil.ReadFile("/Users/jeeva/text-file.txt")
|
||||
|
||||
// Create a Resty Client
|
||||
client := resty.New()
|
||||
|
||||
resp, err := client.R().
|
||||
SetFileReader("profile_img", "test-img.png", bytes.NewReader(profileImgBytes)).
|
||||
SetFileReader("notes", "text-file.txt", bytes.NewReader(notesBytes)).
|
||||
SetFormData(map[string]string{
|
||||
"first_name": "Jeevanandam",
|
||||
"last_name": "M",
|
||||
}).
|
||||
Post("http://myapp.com/upload")
|
||||
```
|
||||
|
||||
#### Using File directly from Path
|
||||
|
||||
```go
|
||||
// Create a Resty Client
|
||||
client := resty.New()
|
||||
|
||||
// Single file scenario
|
||||
resp, err := client.R().
|
||||
SetFile("profile_img", "/Users/jeeva/test-img.png").
|
||||
Post("http://myapp.com/upload")
|
||||
|
||||
// Multiple files scenario
|
||||
resp, err := client.R().
|
||||
SetFiles(map[string]string{
|
||||
"profile_img": "/Users/jeeva/test-img.png",
|
||||
"notes": "/Users/jeeva/text-file.txt",
|
||||
}).
|
||||
Post("http://myapp.com/upload")
|
||||
|
||||
// Multipart of form fields and files
|
||||
resp, err := client.R().
|
||||
SetFiles(map[string]string{
|
||||
"profile_img": "/Users/jeeva/test-img.png",
|
||||
"notes": "/Users/jeeva/text-file.txt",
|
||||
}).
|
||||
SetFormData(map[string]string{
|
||||
"first_name": "Jeevanandam",
|
||||
"last_name": "M",
|
||||
"zip_code": "00001",
|
||||
"city": "my city",
|
||||
"access_token": "C6A79608-782F-4ED0-A11D-BD82FAD829CD",
|
||||
}).
|
||||
Post("http://myapp.com/profile")
|
||||
```
|
||||
|
||||
#### Sample Form submission
|
||||
|
||||
```go
|
||||
// Create a Resty Client
|
||||
client := resty.New()
|
||||
|
||||
// just mentioning about POST as an example with simple flow
|
||||
// User Login
|
||||
resp, err := client.R().
|
||||
SetFormData(map[string]string{
|
||||
"username": "jeeva",
|
||||
"password": "mypass",
|
||||
}).
|
||||
Post("http://myapp.com/login")
|
||||
|
||||
// Followed by profile update
|
||||
resp, err := client.R().
|
||||
SetFormData(map[string]string{
|
||||
"first_name": "Jeevanandam",
|
||||
"last_name": "M",
|
||||
"zip_code": "00001",
|
||||
"city": "new city update",
|
||||
}).
|
||||
Post("http://myapp.com/profile")
|
||||
|
||||
// Multi value form data
|
||||
criteria := url.Values{
|
||||
"search_criteria": []string{"book", "glass", "pencil"},
|
||||
}
|
||||
resp, err := client.R().
|
||||
SetFormDataFromValues(criteria).
|
||||
Post("http://myapp.com/search")
|
||||
```
|
||||
|
||||
#### Save HTTP Response into File
|
||||
|
||||
```go
|
||||
// Create a Resty Client
|
||||
client := resty.New()
|
||||
|
||||
// Setting output directory path, If directory not exists then resty creates one!
|
||||
// This is optional one, if you're planning using absoule path in
|
||||
// `Request.SetOutput` and can used together.
|
||||
client.SetOutputDirectory("/Users/jeeva/Downloads")
|
||||
|
||||
// HTTP response gets saved into file, similar to curl -o flag
|
||||
_, err := client.R().
|
||||
SetOutput("plugin/ReplyWithHeader-v5.1-beta.zip").
|
||||
Get("http://bit.ly/1LouEKr")
|
||||
|
||||
// OR using absolute path
|
||||
// Note: output directory path is not used for absolute path
|
||||
_, err := client.R().
|
||||
SetOutput("/MyDownloads/plugin/ReplyWithHeader-v5.1-beta.zip").
|
||||
Get("http://bit.ly/1LouEKr")
|
||||
```
|
||||
|
||||
#### Request URL Path Params
|
||||
|
||||
Resty provides easy to use dynamic request URL path params. Params can be set at client and request level. Client level params value can be overridden at request level.
|
||||
|
||||
```go
|
||||
// Create a Resty Client
|
||||
client := resty.New()
|
||||
|
||||
client.R().SetPathParams(map[string]string{
|
||||
"userId": "sample@sample.com",
|
||||
"subAccountId": "100002",
|
||||
}).
|
||||
Get("/v1/users/{userId}/{subAccountId}/details")
|
||||
|
||||
// Result:
|
||||
// Composed URL - /v1/users/sample@sample.com/100002/details
|
||||
```
|
||||
|
||||
#### Request and Response Middleware
|
||||
|
||||
Resty provides middleware ability to manipulate for Request and Response. It is more flexible than callback approach.
|
||||
|
||||
```go
|
||||
// Create a Resty Client
|
||||
client := resty.New()
|
||||
|
||||
// Registering Request Middleware
|
||||
client.OnBeforeRequest(func(c *resty.Client, req *resty.Request) error {
|
||||
// Now you have access to Client and current Request object
|
||||
// manipulate it as per your need
|
||||
|
||||
return nil // if its success otherwise return error
|
||||
})
|
||||
|
||||
// Registering Response Middleware
|
||||
client.OnAfterResponse(func(c *resty.Client, resp *resty.Response) error {
|
||||
// Now you have access to Client and current Response object
|
||||
// manipulate it as per your need
|
||||
|
||||
return nil // if its success otherwise return error
|
||||
})
|
||||
```
|
||||
|
||||
#### OnError Hooks
|
||||
|
||||
Resty provides OnError hooks that may be called because:
|
||||
|
||||
- The client failed to send the request due to connection timeout, TLS handshake failure, etc...
|
||||
- The request was retried the maximum amount of times, and still failed.
|
||||
|
||||
If there was a response from the server, the original error will be wrapped in `*resty.ResponseError` which contains the last response received.
|
||||
|
||||
```go
|
||||
// Create a Resty Client
|
||||
client := resty.New()
|
||||
|
||||
client.OnError(func(req *resty.Request, err error) {
|
||||
if v, ok := err.(*resty.ResponseError); ok {
|
||||
// v.Response contains the last response from the server
|
||||
// v.Err contains the original error
|
||||
}
|
||||
// Log the error, increment a metric, etc...
|
||||
})
|
||||
```
|
||||
|
||||
#### Redirect Policy
|
||||
|
||||
Resty provides few ready to use redirect policy(s) also it supports multiple policies together.
|
||||
|
||||
```go
|
||||
// Create a Resty Client
|
||||
client := resty.New()
|
||||
|
||||
// Assign Client Redirect Policy. Create one as per you need
|
||||
client.SetRedirectPolicy(resty.FlexibleRedirectPolicy(15))
|
||||
|
||||
// Wanna multiple policies such as redirect count, domain name check, etc
|
||||
client.SetRedirectPolicy(resty.FlexibleRedirectPolicy(20),
|
||||
resty.DomainCheckRedirectPolicy("host1.com", "host2.org", "host3.net"))
|
||||
```
|
||||
|
||||
##### Custom Redirect Policy
|
||||
|
||||
Implement [RedirectPolicy](redirect.go#L20) interface and register it with resty client. Have a look [redirect.go](redirect.go) for more information.
|
||||
|
||||
```go
|
||||
// Create a Resty Client
|
||||
client := resty.New()
|
||||
|
||||
// Using raw func into resty.SetRedirectPolicy
|
||||
client.SetRedirectPolicy(resty.RedirectPolicyFunc(func(req *http.Request, via []*http.Request) error {
|
||||
// Implement your logic here
|
||||
|
||||
// return nil for continue redirect otherwise return error to stop/prevent redirect
|
||||
return nil
|
||||
}))
|
||||
|
||||
//---------------------------------------------------
|
||||
|
||||
// Using struct create more flexible redirect policy
|
||||
type CustomRedirectPolicy struct {
|
||||
// variables goes here
|
||||
}
|
||||
|
||||
func (c *CustomRedirectPolicy) Apply(req *http.Request, via []*http.Request) error {
|
||||
// Implement your logic here
|
||||
|
||||
// return nil for continue redirect otherwise return error to stop/prevent redirect
|
||||
return nil
|
||||
}
|
||||
|
||||
// Registering in resty
|
||||
client.SetRedirectPolicy(CustomRedirectPolicy{/* initialize variables */})
|
||||
```
|
||||
|
||||
#### Custom Root Certificates and Client Certificates
|
||||
|
||||
```go
|
||||
// Create a Resty Client
|
||||
client := resty.New()
|
||||
|
||||
// Custom Root certificates, just supply .pem file.
|
||||
// you can add one or more root certificates, its get appended
|
||||
client.SetRootCertificate("/path/to/root/pemFile1.pem")
|
||||
client.SetRootCertificate("/path/to/root/pemFile2.pem")
|
||||
// ... and so on!
|
||||
|
||||
// Adding Client Certificates, you add one or more certificates
|
||||
// Sample for creating certificate object
|
||||
// Parsing public/private key pair from a pair of files. The files must contain PEM encoded data.
|
||||
cert1, err := tls.LoadX509KeyPair("certs/client.pem", "certs/client.key")
|
||||
if err != nil {
|
||||
log.Fatalf("ERROR client certificate: %s", err)
|
||||
}
|
||||
// ...
|
||||
|
||||
// You add one or more certificates
|
||||
client.SetCertificates(cert1, cert2, cert3)
|
||||
```
|
||||
|
||||
#### Custom Root Certificates and Client Certificates from string
|
||||
|
||||
```go
|
||||
// Custom Root certificates from string
|
||||
// You can pass you certificates throught env variables as strings
|
||||
// you can add one or more root certificates, its get appended
|
||||
client.SetRootCertificateFromString("-----BEGIN CERTIFICATE-----content-----END CERTIFICATE-----")
|
||||
client.SetRootCertificateFromString("-----BEGIN CERTIFICATE-----content-----END CERTIFICATE-----")
|
||||
// ... and so on!
|
||||
|
||||
// Adding Client Certificates, you add one or more certificates
|
||||
// Sample for creating certificate object
|
||||
// Parsing public/private key pair from a pair of files. The files must contain PEM encoded data.
|
||||
cert1, err := tls.X509KeyPair([]byte("-----BEGIN CERTIFICATE-----content-----END CERTIFICATE-----"), []byte("-----BEGIN CERTIFICATE-----content-----END CERTIFICATE-----"))
|
||||
if err != nil {
|
||||
log.Fatalf("ERROR client certificate: %s", err)
|
||||
}
|
||||
// ...
|
||||
|
||||
// You add one or more certificates
|
||||
client.SetCertificates(cert1, cert2, cert3)
|
||||
```
|
||||
|
||||
#### Proxy Settings - Client as well as at Request Level
|
||||
|
||||
Default `Go` supports Proxy via environment variable `HTTP_PROXY`. Resty provides support via `SetProxy` & `RemoveProxy`.
|
||||
Choose as per your need.
|
||||
|
||||
**Client Level Proxy** settings applied to all the request
|
||||
|
||||
```go
|
||||
// Create a Resty Client
|
||||
client := resty.New()
|
||||
|
||||
// Setting a Proxy URL and Port
|
||||
client.SetProxy("http://proxyserver:8888")
|
||||
|
||||
// Want to remove proxy setting
|
||||
client.RemoveProxy()
|
||||
```
|
||||
|
||||
#### Retries
|
||||
|
||||
Resty uses [backoff](http://www.awsarchitectureblog.com/2015/03/backoff.html)
|
||||
to increase retry intervals after each attempt.
|
||||
|
||||
Usage example:
|
||||
|
||||
```go
|
||||
// Create a Resty Client
|
||||
client := resty.New()
|
||||
|
||||
// Retries are configured per client
|
||||
client.
|
||||
// Set retry count to non zero to enable retries
|
||||
SetRetryCount(3).
|
||||
// You can override initial retry wait time.
|
||||
// Default is 100 milliseconds.
|
||||
SetRetryWaitTime(5 * time.Second).
|
||||
// MaxWaitTime can be overridden as well.
|
||||
// Default is 2 seconds.
|
||||
SetRetryMaxWaitTime(20 * time.Second).
|
||||
// SetRetryAfter sets callback to calculate wait time between retries.
|
||||
// Default (nil) implies exponential backoff with jitter
|
||||
SetRetryAfter(func(client *resty.Client, resp *resty.Response) (time.Duration, error) {
|
||||
return 0, errors.New("quota exceeded")
|
||||
})
|
||||
```
|
||||
|
||||
Above setup will result in resty retrying requests returned non nil error up to
|
||||
3 times with delay increased after each attempt.
|
||||
|
||||
You can optionally provide client with [custom retry conditions](https://pkg.go.dev/github.com/go-resty/resty/v2#RetryConditionFunc):
|
||||
|
||||
```go
|
||||
// Create a Resty Client
|
||||
client := resty.New()
|
||||
|
||||
client.AddRetryCondition(
|
||||
// RetryConditionFunc type is for retry condition function
|
||||
// input: non-nil Response OR request execution error
|
||||
func(r *resty.Response, err error) bool {
|
||||
return r.StatusCode() == http.StatusTooManyRequests
|
||||
},
|
||||
)
|
||||
```
|
||||
|
||||
Above example will make resty retry requests ended with `429 Too Many Requests`
|
||||
status code.
|
||||
|
||||
Multiple retry conditions can be added.
|
||||
|
||||
It is also possible to use `resty.Backoff(...)` to get arbitrary retry scenarios
|
||||
implemented. [Reference](retry_test.go).
|
||||
|
||||
#### Allow GET request with Payload
|
||||
|
||||
```go
|
||||
// Create a Resty Client
|
||||
client := resty.New()
|
||||
|
||||
// Allow GET request with Payload. This is disabled by default.
|
||||
client.SetAllowGetMethodPayload(true)
|
||||
```
|
||||
|
||||
#### Wanna Multiple Clients
|
||||
|
||||
```go
|
||||
// Here you go!
|
||||
// Client 1
|
||||
client1 := resty.New()
|
||||
client1.R().Get("http://httpbin.org")
|
||||
// ...
|
||||
|
||||
// Client 2
|
||||
client2 := resty.New()
|
||||
client2.R().Head("http://httpbin.org")
|
||||
// ...
|
||||
|
||||
// Bend it as per your need!!!
|
||||
```
|
||||
|
||||
#### Remaining Client Settings & its Options
|
||||
|
||||
```go
|
||||
// Create a Resty Client
|
||||
client := resty.New()
|
||||
|
||||
// Unique settings at Client level
|
||||
//--------------------------------
|
||||
// Enable debug mode
|
||||
client.SetDebug(true)
|
||||
|
||||
// Assign Client TLSClientConfig
|
||||
// One can set custom root-certificate. Refer: http://golang.org/pkg/crypto/tls/#example_Dial
|
||||
client.SetTLSClientConfig(&tls.Config{ RootCAs: roots })
|
||||
|
||||
// or One can disable security check (https)
|
||||
client.SetTLSClientConfig(&tls.Config{ InsecureSkipVerify: true })
|
||||
|
||||
// Set client timeout as per your need
|
||||
client.SetTimeout(1 * time.Minute)
|
||||
|
||||
|
||||
// You can override all below settings and options at request level if you want to
|
||||
//--------------------------------------------------------------------------------
|
||||
// Host URL for all request. So you can use relative URL in the request
|
||||
client.SetHostURL("http://httpbin.org")
|
||||
|
||||
// Headers for all request
|
||||
client.SetHeader("Accept", "application/json")
|
||||
client.SetHeaders(map[string]string{
|
||||
"Content-Type": "application/json",
|
||||
"User-Agent": "My custom User Agent String",
|
||||
})
|
||||
|
||||
// Cookies for all request
|
||||
client.SetCookie(&http.Cookie{
|
||||
Name:"go-resty",
|
||||
Value:"This is cookie value",
|
||||
Path: "/",
|
||||
Domain: "sample.com",
|
||||
MaxAge: 36000,
|
||||
HttpOnly: true,
|
||||
Secure: false,
|
||||
})
|
||||
client.SetCookies(cookies)
|
||||
|
||||
// URL query parameters for all request
|
||||
client.SetQueryParam("user_id", "00001")
|
||||
client.SetQueryParams(map[string]string{ // sample of those who use this manner
|
||||
"api_key": "api-key-here",
|
||||
"api_secert": "api-secert",
|
||||
})
|
||||
client.R().SetQueryString("productId=232&template=fresh-sample&cat=resty&source=google&kw=buy a lot more")
|
||||
|
||||
// Form data for all request. Typically used with POST and PUT
|
||||
client.SetFormData(map[string]string{
|
||||
"access_token": "BC594900-518B-4F7E-AC75-BD37F019E08F",
|
||||
})
|
||||
|
||||
// Basic Auth for all request
|
||||
client.SetBasicAuth("myuser", "mypass")
|
||||
|
||||
// Bearer Auth Token for all request
|
||||
client.SetAuthToken("BC594900518B4F7EAC75BD37F019E08FBC594900518B4F7EAC75BD37F019E08F")
|
||||
|
||||
// Enabling Content length value for all request
|
||||
client.SetContentLength(true)
|
||||
|
||||
// Registering global Error object structure for JSON/XML request
|
||||
client.SetError(&Error{}) // or resty.SetError(Error{})
|
||||
```
|
||||
|
||||
#### Unix Socket
|
||||
|
||||
```go
|
||||
unixSocket := "/var/run/my_socket.sock"
|
||||
|
||||
// Create a Go's http.Transport so we can set it in resty.
|
||||
transport := http.Transport{
|
||||
Dial: func(_, _ string) (net.Conn, error) {
|
||||
return net.Dial("unix", unixSocket)
|
||||
},
|
||||
}
|
||||
|
||||
// Create a Resty Client
|
||||
client := resty.New()
|
||||
|
||||
// Set the previous transport that we created, set the scheme of the communication to the
|
||||
// socket and set the unixSocket as the HostURL.
|
||||
client.SetTransport(&transport).SetScheme("http").SetHostURL(unixSocket)
|
||||
|
||||
// No need to write the host's URL on the request, just the path.
|
||||
client.R().Get("/index.html")
|
||||
```
|
||||
|
||||
#### Bazel support
|
||||
|
||||
Resty can be built, tested and depended upon via [Bazel](https://bazel.build).
|
||||
For example, to run all tests:
|
||||
|
||||
```shell
|
||||
bazel test :go_default_test
|
||||
```
|
||||
|
||||
#### Mocking http requests using [httpmock](https://github.com/jarcoal/httpmock) library
|
||||
|
||||
In order to mock the http requests when testing your application you
|
||||
could use the `httpmock` library.
|
||||
|
||||
When using the default resty client, you should pass the client to the library as follow:
|
||||
|
||||
```go
|
||||
// Create a Resty Client
|
||||
client := resty.New()
|
||||
|
||||
// Get the underlying HTTP Client and set it to Mock
|
||||
httpmock.ActivateNonDefault(client.GetClient())
|
||||
```
|
||||
|
||||
More detailed example of mocking resty http requests using ginko could be found [here](https://github.com/jarcoal/httpmock#ginkgo--resty-example).
|
||||
|
||||
## Versioning
|
||||
|
||||
Resty releases versions according to [Semantic Versioning](http://semver.org)
|
||||
|
||||
* Resty v2 does not use `gopkg.in` service for library versioning.
|
||||
* Resty fully adapted to `go mod` capabilities since `v1.10.0` release.
|
||||
* Resty v1 series was using `gopkg.in` to provide versioning. `gopkg.in/resty.vX` points to appropriate tagged versions; `X` denotes version series number and it's a stable release for production use. For e.g. `gopkg.in/resty.v0`.
|
||||
* Development takes place at the master branch. Although the code in master should always compile and test successfully, it might break API's. I aim to maintain backwards compatibility, but sometimes API's and behavior might be changed to fix a bug.
|
||||
|
||||
## Contribution
|
||||
|
||||
I would welcome your contribution! If you find any improvement or issue you want to fix, feel free to send a pull request, I like pull requests that include test cases for fix/enhancement. I have done my best to bring pretty good code coverage. Feel free to write tests.
|
||||
|
||||
BTW, I'd like to know what you think about `Resty`. Kindly open an issue or send me an email; it'd mean a lot to me.
|
||||
|
||||
## Creator
|
||||
|
||||
[Jeevanandam M.](https://github.com/jeevatkm) (jeeva@myjeeva.com)
|
||||
|
||||
## Core Team
|
||||
|
||||
Have a look on [Members](https://github.com/orgs/go-resty/teams/core/members) page.
|
||||
|
||||
## Contributors
|
||||
|
||||
Have a look on [Contributors](https://github.com/go-resty/resty/graphs/contributors) page.
|
||||
|
||||
## License
|
||||
|
||||
Resty released under MIT license, refer [LICENSE](LICENSE) file.
|
||||
27
vendor/github.com/go-resty/resty/v2/WORKSPACE
generated
vendored
Normal file
27
vendor/github.com/go-resty/resty/v2/WORKSPACE
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
workspace(name = "resty")
|
||||
|
||||
git_repository(
|
||||
name = "io_bazel_rules_go",
|
||||
remote = "https://github.com/bazelbuild/rules_go.git",
|
||||
tag = "0.13.0",
|
||||
)
|
||||
|
||||
git_repository(
|
||||
name = "bazel_gazelle",
|
||||
remote = "https://github.com/bazelbuild/bazel-gazelle.git",
|
||||
tag = "0.13.0",
|
||||
)
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_rules_dependencies",
|
||||
"go_register_toolchains",
|
||||
)
|
||||
|
||||
go_rules_dependencies()
|
||||
|
||||
go_register_toolchains()
|
||||
|
||||
load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies")
|
||||
|
||||
gazelle_dependencies()
|
||||
1051
vendor/github.com/go-resty/resty/v2/client.go
generated
vendored
Normal file
1051
vendor/github.com/go-resty/resty/v2/client.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
5
vendor/github.com/go-resty/resty/v2/go.mod
generated
vendored
Normal file
5
vendor/github.com/go-resty/resty/v2/go.mod
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
module github.com/go-resty/resty/v2
|
||||
|
||||
require golang.org/x/net v0.0.0-20201224014010-6772e930b67b
|
||||
|
||||
go 1.11
|
||||
6
vendor/github.com/go-resty/resty/v2/go.sum
generated
vendored
Normal file
6
vendor/github.com/go-resty/resty/v2/go.sum
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
golang.org/x/net v0.0.0-20201224014010-6772e930b67b h1:iFwSg7t5GZmB/Q5TjiEAsdoLDrdJRC1RiF2WhuV29Qw=
|
||||
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
545
vendor/github.com/go-resty/resty/v2/middleware.go
generated
vendored
Normal file
545
vendor/github.com/go-resty/resty/v2/middleware.go
generated
vendored
Normal file
@@ -0,0 +1,545 @@
|
||||
// Copyright (c) 2015-2020 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// resty source code and usage is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package resty
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/xml"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
const debugRequestLogKey = "__restyDebugRequestLog"
|
||||
|
||||
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
// Request Middleware(s)
|
||||
//_______________________________________________________________________
|
||||
|
||||
func parseRequestURL(c *Client, r *Request) error {
|
||||
// GitHub #103 Path Params
|
||||
if len(r.pathParams) > 0 {
|
||||
for p, v := range r.pathParams {
|
||||
r.URL = strings.Replace(r.URL, "{"+p+"}", url.PathEscape(v), -1)
|
||||
}
|
||||
}
|
||||
if len(c.pathParams) > 0 {
|
||||
for p, v := range c.pathParams {
|
||||
r.URL = strings.Replace(r.URL, "{"+p+"}", url.PathEscape(v), -1)
|
||||
}
|
||||
}
|
||||
|
||||
// Parsing request URL
|
||||
reqURL, err := url.Parse(r.URL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// If Request.URL is relative path then added c.HostURL into
|
||||
// the request URL otherwise Request.URL will be used as-is
|
||||
if !reqURL.IsAbs() {
|
||||
r.URL = reqURL.String()
|
||||
if len(r.URL) > 0 && r.URL[0] != '/' {
|
||||
r.URL = "/" + r.URL
|
||||
}
|
||||
|
||||
reqURL, err = url.Parse(c.HostURL + r.URL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Adding Query Param
|
||||
query := make(url.Values)
|
||||
for k, v := range c.QueryParam {
|
||||
for _, iv := range v {
|
||||
query.Add(k, iv)
|
||||
}
|
||||
}
|
||||
|
||||
for k, v := range r.QueryParam {
|
||||
// remove query param from client level by key
|
||||
// since overrides happens for that key in the request
|
||||
query.Del(k)
|
||||
|
||||
for _, iv := range v {
|
||||
query.Add(k, iv)
|
||||
}
|
||||
}
|
||||
|
||||
// GitHub #123 Preserve query string order partially.
|
||||
// Since not feasible in `SetQuery*` resty methods, because
|
||||
// standard package `url.Encode(...)` sorts the query params
|
||||
// alphabetically
|
||||
if len(query) > 0 {
|
||||
if IsStringEmpty(reqURL.RawQuery) {
|
||||
reqURL.RawQuery = query.Encode()
|
||||
} else {
|
||||
reqURL.RawQuery = reqURL.RawQuery + "&" + query.Encode()
|
||||
}
|
||||
}
|
||||
|
||||
r.URL = reqURL.String()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseRequestHeader(c *Client, r *Request) error {
|
||||
hdr := make(http.Header)
|
||||
for k := range c.Header {
|
||||
hdr[k] = append(hdr[k], c.Header[k]...)
|
||||
}
|
||||
|
||||
for k := range r.Header {
|
||||
hdr.Del(k)
|
||||
hdr[k] = append(hdr[k], r.Header[k]...)
|
||||
}
|
||||
|
||||
if IsStringEmpty(hdr.Get(hdrUserAgentKey)) {
|
||||
hdr.Set(hdrUserAgentKey, hdrUserAgentValue)
|
||||
}
|
||||
|
||||
ct := hdr.Get(hdrContentTypeKey)
|
||||
if IsStringEmpty(hdr.Get(hdrAcceptKey)) && !IsStringEmpty(ct) &&
|
||||
(IsJSONType(ct) || IsXMLType(ct)) {
|
||||
hdr.Set(hdrAcceptKey, hdr.Get(hdrContentTypeKey))
|
||||
}
|
||||
|
||||
r.Header = hdr
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseRequestBody(c *Client, r *Request) (err error) {
|
||||
if isPayloadSupported(r.Method, c.AllowGetMethodPayload) {
|
||||
// Handling Multipart
|
||||
if r.isMultiPart && !(r.Method == MethodPatch) {
|
||||
if err = handleMultipart(c, r); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
goto CL
|
||||
}
|
||||
|
||||
// Handling Form Data
|
||||
if len(c.FormData) > 0 || len(r.FormData) > 0 {
|
||||
handleFormData(c, r)
|
||||
|
||||
goto CL
|
||||
}
|
||||
|
||||
// Handling Request body
|
||||
if r.Body != nil {
|
||||
handleContentType(c, r)
|
||||
|
||||
if err = handleRequestBody(c, r); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CL:
|
||||
// by default resty won't set content length, you can if you want to :)
|
||||
if (c.setContentLength || r.setContentLength) && r.bodyBuf != nil {
|
||||
r.Header.Set(hdrContentLengthKey, fmt.Sprintf("%d", r.bodyBuf.Len()))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func createHTTPRequest(c *Client, r *Request) (err error) {
|
||||
if r.bodyBuf == nil {
|
||||
if reader, ok := r.Body.(io.Reader); ok {
|
||||
r.RawRequest, err = http.NewRequest(r.Method, r.URL, reader)
|
||||
} else if c.setContentLength || r.setContentLength {
|
||||
r.RawRequest, err = http.NewRequest(r.Method, r.URL, http.NoBody)
|
||||
} else {
|
||||
r.RawRequest, err = http.NewRequest(r.Method, r.URL, nil)
|
||||
}
|
||||
} else {
|
||||
r.RawRequest, err = http.NewRequest(r.Method, r.URL, r.bodyBuf)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Assign close connection option
|
||||
r.RawRequest.Close = c.closeConnection
|
||||
|
||||
// Add headers into http request
|
||||
r.RawRequest.Header = r.Header
|
||||
|
||||
// Add cookies from client instance into http request
|
||||
for _, cookie := range c.Cookies {
|
||||
r.RawRequest.AddCookie(cookie)
|
||||
}
|
||||
|
||||
// Add cookies from request instance into http request
|
||||
for _, cookie := range r.Cookies {
|
||||
r.RawRequest.AddCookie(cookie)
|
||||
}
|
||||
|
||||
// it's for non-http scheme option
|
||||
if r.RawRequest.URL != nil && r.RawRequest.URL.Scheme == "" {
|
||||
r.RawRequest.URL.Scheme = c.scheme
|
||||
r.RawRequest.URL.Host = r.URL
|
||||
}
|
||||
|
||||
// Enable trace
|
||||
if c.trace || r.trace {
|
||||
r.clientTrace = &clientTrace{}
|
||||
r.ctx = r.clientTrace.createContext(r.Context())
|
||||
}
|
||||
|
||||
// Use context if it was specified
|
||||
if r.ctx != nil {
|
||||
r.RawRequest = r.RawRequest.WithContext(r.ctx)
|
||||
}
|
||||
|
||||
bodyCopy, err := getBodyCopy(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// assign get body func for the underlying raw request instance
|
||||
r.RawRequest.GetBody = func() (io.ReadCloser, error) {
|
||||
if bodyCopy != nil {
|
||||
return ioutil.NopCloser(bytes.NewReader(bodyCopy.Bytes())), nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func addCredentials(c *Client, r *Request) error {
|
||||
var isBasicAuth bool
|
||||
// Basic Auth
|
||||
if r.UserInfo != nil { // takes precedence
|
||||
r.RawRequest.SetBasicAuth(r.UserInfo.Username, r.UserInfo.Password)
|
||||
isBasicAuth = true
|
||||
} else if c.UserInfo != nil {
|
||||
r.RawRequest.SetBasicAuth(c.UserInfo.Username, c.UserInfo.Password)
|
||||
isBasicAuth = true
|
||||
}
|
||||
|
||||
if !c.DisableWarn {
|
||||
if isBasicAuth && !strings.HasPrefix(r.URL, "https") {
|
||||
c.log.Warnf("Using Basic Auth in HTTP mode is not secure, use HTTPS")
|
||||
}
|
||||
}
|
||||
|
||||
// Set the Authorization Header Scheme
|
||||
var authScheme string
|
||||
if !IsStringEmpty(r.AuthScheme) {
|
||||
authScheme = r.AuthScheme
|
||||
} else if !IsStringEmpty(c.AuthScheme) {
|
||||
authScheme = c.AuthScheme
|
||||
} else {
|
||||
authScheme = "Bearer"
|
||||
}
|
||||
|
||||
// Build the Token Auth header
|
||||
if !IsStringEmpty(r.Token) { // takes precedence
|
||||
r.RawRequest.Header.Set(c.HeaderAuthorizationKey, authScheme+" "+r.Token)
|
||||
} else if !IsStringEmpty(c.Token) {
|
||||
r.RawRequest.Header.Set(c.HeaderAuthorizationKey, authScheme+" "+c.Token)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func requestLogger(c *Client, r *Request) error {
|
||||
if c.Debug {
|
||||
rr := r.RawRequest
|
||||
rl := &RequestLog{Header: copyHeaders(rr.Header), Body: r.fmtBodyString(c.debugBodySizeLimit)}
|
||||
if c.requestLog != nil {
|
||||
if err := c.requestLog(rl); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// fmt.Sprintf("COOKIES:\n%s\n", composeCookies(c.GetClient().Jar, *rr.URL)) +
|
||||
|
||||
reqLog := "\n==============================================================================\n" +
|
||||
"~~~ REQUEST ~~~\n" +
|
||||
fmt.Sprintf("%s %s %s\n", r.Method, rr.URL.RequestURI(), rr.Proto) +
|
||||
fmt.Sprintf("HOST : %s\n", rr.URL.Host) +
|
||||
fmt.Sprintf("HEADERS:\n%s\n", composeHeaders(c, r, rl.Header)) +
|
||||
fmt.Sprintf("BODY :\n%v\n", rl.Body) +
|
||||
"------------------------------------------------------------------------------\n"
|
||||
|
||||
r.initValuesMap()
|
||||
r.values[debugRequestLogKey] = reqLog
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
// Response Middleware(s)
|
||||
//_______________________________________________________________________
|
||||
|
||||
func responseLogger(c *Client, res *Response) error {
|
||||
if c.Debug {
|
||||
rl := &ResponseLog{Header: copyHeaders(res.Header()), Body: res.fmtBodyString(c.debugBodySizeLimit)}
|
||||
if c.responseLog != nil {
|
||||
if err := c.responseLog(rl); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
debugLog := res.Request.values[debugRequestLogKey].(string)
|
||||
debugLog += "~~~ RESPONSE ~~~\n" +
|
||||
fmt.Sprintf("STATUS : %s\n", res.Status()) +
|
||||
fmt.Sprintf("PROTO : %s\n", res.RawResponse.Proto) +
|
||||
fmt.Sprintf("RECEIVED AT : %v\n", res.ReceivedAt().Format(time.RFC3339Nano)) +
|
||||
fmt.Sprintf("TIME DURATION: %v\n", res.Time()) +
|
||||
"HEADERS :\n" +
|
||||
composeHeaders(c, res.Request, rl.Header) + "\n"
|
||||
if res.Request.isSaveResponse {
|
||||
debugLog += "BODY :\n***** RESPONSE WRITTEN INTO FILE *****\n"
|
||||
} else {
|
||||
debugLog += fmt.Sprintf("BODY :\n%v\n", rl.Body)
|
||||
}
|
||||
debugLog += "==============================================================================\n"
|
||||
|
||||
c.log.Debugf("%s", debugLog)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseResponseBody(c *Client, res *Response) (err error) {
|
||||
if res.StatusCode() == http.StatusNoContent {
|
||||
return
|
||||
}
|
||||
// Handles only JSON or XML content type
|
||||
ct := firstNonEmpty(res.Request.forceContentType, res.Header().Get(hdrContentTypeKey), res.Request.fallbackContentType)
|
||||
if IsJSONType(ct) || IsXMLType(ct) {
|
||||
// HTTP status code > 199 and < 300, considered as Result
|
||||
if res.IsSuccess() {
|
||||
res.Request.Error = nil
|
||||
if res.Request.Result != nil {
|
||||
err = Unmarshalc(c, ct, res.body, res.Request.Result)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// HTTP status code > 399, considered as Error
|
||||
if res.IsError() {
|
||||
// global error interface
|
||||
if res.Request.Error == nil && c.Error != nil {
|
||||
res.Request.Error = reflect.New(c.Error).Interface()
|
||||
}
|
||||
|
||||
if res.Request.Error != nil {
|
||||
err = Unmarshalc(c, ct, res.body, res.Request.Error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func handleMultipart(c *Client, r *Request) (err error) {
|
||||
r.bodyBuf = acquireBuffer()
|
||||
w := multipart.NewWriter(r.bodyBuf)
|
||||
|
||||
for k, v := range c.FormData {
|
||||
for _, iv := range v {
|
||||
if err = w.WriteField(k, iv); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for k, v := range r.FormData {
|
||||
for _, iv := range v {
|
||||
if strings.HasPrefix(k, "@") { // file
|
||||
err = addFile(w, k[1:], iv)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
} else { // form value
|
||||
if err = w.WriteField(k, iv); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// #21 - adding io.Reader support
|
||||
if len(r.multipartFiles) > 0 {
|
||||
for _, f := range r.multipartFiles {
|
||||
err = addFileReader(w, f)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// GitHub #130 adding multipart field support with content type
|
||||
if len(r.multipartFields) > 0 {
|
||||
for _, mf := range r.multipartFields {
|
||||
if err = addMultipartFormField(w, mf); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
r.Header.Set(hdrContentTypeKey, w.FormDataContentType())
|
||||
err = w.Close()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func handleFormData(c *Client, r *Request) {
|
||||
formData := url.Values{}
|
||||
|
||||
for k, v := range c.FormData {
|
||||
for _, iv := range v {
|
||||
formData.Add(k, iv)
|
||||
}
|
||||
}
|
||||
|
||||
for k, v := range r.FormData {
|
||||
// remove form data field from client level by key
|
||||
// since overrides happens for that key in the request
|
||||
formData.Del(k)
|
||||
|
||||
for _, iv := range v {
|
||||
formData.Add(k, iv)
|
||||
}
|
||||
}
|
||||
|
||||
r.bodyBuf = bytes.NewBuffer([]byte(formData.Encode()))
|
||||
r.Header.Set(hdrContentTypeKey, formContentType)
|
||||
r.isFormData = true
|
||||
}
|
||||
|
||||
func handleContentType(c *Client, r *Request) {
|
||||
contentType := r.Header.Get(hdrContentTypeKey)
|
||||
if IsStringEmpty(contentType) {
|
||||
contentType = DetectContentType(r.Body)
|
||||
r.Header.Set(hdrContentTypeKey, contentType)
|
||||
}
|
||||
}
|
||||
|
||||
func handleRequestBody(c *Client, r *Request) (err error) {
|
||||
var bodyBytes []byte
|
||||
contentType := r.Header.Get(hdrContentTypeKey)
|
||||
kind := kindOf(r.Body)
|
||||
r.bodyBuf = nil
|
||||
|
||||
if reader, ok := r.Body.(io.Reader); ok {
|
||||
if c.setContentLength || r.setContentLength { // keep backward compatibility
|
||||
r.bodyBuf = acquireBuffer()
|
||||
_, err = r.bodyBuf.ReadFrom(reader)
|
||||
r.Body = nil
|
||||
} else {
|
||||
// Otherwise buffer less processing for `io.Reader`, sounds good.
|
||||
return
|
||||
}
|
||||
} else if b, ok := r.Body.([]byte); ok {
|
||||
bodyBytes = b
|
||||
} else if s, ok := r.Body.(string); ok {
|
||||
bodyBytes = []byte(s)
|
||||
} else if IsJSONType(contentType) &&
|
||||
(kind == reflect.Struct || kind == reflect.Map || kind == reflect.Slice) {
|
||||
bodyBytes, err = jsonMarshal(c, r, r.Body)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
} else if IsXMLType(contentType) && (kind == reflect.Struct) {
|
||||
bodyBytes, err = xml.Marshal(r.Body)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if bodyBytes == nil && r.bodyBuf == nil {
|
||||
err = errors.New("unsupported 'Body' type/value")
|
||||
}
|
||||
|
||||
// if any errors during body bytes handling, return it
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// []byte into Buffer
|
||||
if bodyBytes != nil && r.bodyBuf == nil {
|
||||
r.bodyBuf = acquireBuffer()
|
||||
_, _ = r.bodyBuf.Write(bodyBytes)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func saveResponseIntoFile(c *Client, res *Response) error {
|
||||
if res.Request.isSaveResponse {
|
||||
file := ""
|
||||
|
||||
if len(c.outputDirectory) > 0 && !filepath.IsAbs(res.Request.outputFile) {
|
||||
file += c.outputDirectory + string(filepath.Separator)
|
||||
}
|
||||
|
||||
file = filepath.Clean(file + res.Request.outputFile)
|
||||
if err := createDirectory(filepath.Dir(file)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
outFile, err := os.Create(file)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closeq(outFile)
|
||||
|
||||
// io.Copy reads maximum 32kb size, it is perfect for large file download too
|
||||
defer closeq(res.RawResponse.Body)
|
||||
|
||||
written, err := io.Copy(outFile, res.RawResponse.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
res.size = written
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getBodyCopy(r *Request) (*bytes.Buffer, error) {
|
||||
// If r.bodyBuf present, return the copy
|
||||
if r.bodyBuf != nil {
|
||||
return bytes.NewBuffer(r.bodyBuf.Bytes()), nil
|
||||
}
|
||||
|
||||
// Maybe body is `io.Reader`.
|
||||
// Note: Resty user have to watchout for large body size of `io.Reader`
|
||||
if r.RawRequest.Body != nil {
|
||||
b, err := ioutil.ReadAll(r.RawRequest.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Restore the Body
|
||||
closeq(r.RawRequest.Body)
|
||||
r.RawRequest.Body = ioutil.NopCloser(bytes.NewBuffer(b))
|
||||
|
||||
// Return the Body bytes
|
||||
return bytes.NewBuffer(b), nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
101
vendor/github.com/go-resty/resty/v2/redirect.go
generated
vendored
Normal file
101
vendor/github.com/go-resty/resty/v2/redirect.go
generated
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
// Copyright (c) 2015-2020 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// resty source code and usage is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package resty
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type (
|
||||
// RedirectPolicy to regulate the redirects in the resty client.
|
||||
// Objects implementing the RedirectPolicy interface can be registered as
|
||||
//
|
||||
// Apply function should return nil to continue the redirect jounery, otherwise
|
||||
// return error to stop the redirect.
|
||||
RedirectPolicy interface {
|
||||
Apply(req *http.Request, via []*http.Request) error
|
||||
}
|
||||
|
||||
// The RedirectPolicyFunc type is an adapter to allow the use of ordinary functions as RedirectPolicy.
|
||||
// If f is a function with the appropriate signature, RedirectPolicyFunc(f) is a RedirectPolicy object that calls f.
|
||||
RedirectPolicyFunc func(*http.Request, []*http.Request) error
|
||||
)
|
||||
|
||||
// Apply calls f(req, via).
|
||||
func (f RedirectPolicyFunc) Apply(req *http.Request, via []*http.Request) error {
|
||||
return f(req, via)
|
||||
}
|
||||
|
||||
// NoRedirectPolicy is used to disable redirects in the HTTP client
|
||||
// resty.SetRedirectPolicy(NoRedirectPolicy())
|
||||
func NoRedirectPolicy() RedirectPolicy {
|
||||
return RedirectPolicyFunc(func(req *http.Request, via []*http.Request) error {
|
||||
return errors.New("auto redirect is disabled")
|
||||
})
|
||||
}
|
||||
|
||||
// FlexibleRedirectPolicy is convenient method to create No of redirect policy for HTTP client.
|
||||
// resty.SetRedirectPolicy(FlexibleRedirectPolicy(20))
|
||||
func FlexibleRedirectPolicy(noOfRedirect int) RedirectPolicy {
|
||||
return RedirectPolicyFunc(func(req *http.Request, via []*http.Request) error {
|
||||
if len(via) >= noOfRedirect {
|
||||
return fmt.Errorf("stopped after %d redirects", noOfRedirect)
|
||||
}
|
||||
checkHostAndAddHeaders(req, via[0])
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// DomainCheckRedirectPolicy is convenient method to define domain name redirect rule in resty client.
|
||||
// Redirect is allowed for only mentioned host in the policy.
|
||||
// resty.SetRedirectPolicy(DomainCheckRedirectPolicy("host1.com", "host2.org", "host3.net"))
|
||||
func DomainCheckRedirectPolicy(hostnames ...string) RedirectPolicy {
|
||||
hosts := make(map[string]bool)
|
||||
for _, h := range hostnames {
|
||||
hosts[strings.ToLower(h)] = true
|
||||
}
|
||||
|
||||
fn := RedirectPolicyFunc(func(req *http.Request, via []*http.Request) error {
|
||||
if ok := hosts[getHostname(req.URL.Host)]; !ok {
|
||||
return errors.New("redirect is not allowed as per DomainCheckRedirectPolicy")
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
return fn
|
||||
}
|
||||
|
||||
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
// Package Unexported methods
|
||||
//_______________________________________________________________________
|
||||
|
||||
func getHostname(host string) (hostname string) {
|
||||
if strings.Index(host, ":") > 0 {
|
||||
host, _, _ = net.SplitHostPort(host)
|
||||
}
|
||||
hostname = strings.ToLower(host)
|
||||
return
|
||||
}
|
||||
|
||||
// By default Golang will not redirect request headers
|
||||
// after go throughing various discussion comments from thread
|
||||
// https://github.com/golang/go/issues/4800
|
||||
// Resty will add all the headers during a redirect for the same host
|
||||
func checkHostAndAddHeaders(cur *http.Request, pre *http.Request) {
|
||||
curHostname := getHostname(cur.URL.Host)
|
||||
preHostname := getHostname(pre.URL.Host)
|
||||
if strings.EqualFold(curHostname, preHostname) {
|
||||
for key, val := range pre.Header {
|
||||
cur.Header[key] = val
|
||||
}
|
||||
} else { // only library User-Agent header is added
|
||||
cur.Header.Set(hdrUserAgentKey, hdrUserAgentValue)
|
||||
}
|
||||
}
|
||||
848
vendor/github.com/go-resty/resty/v2/request.go
generated
vendored
Normal file
848
vendor/github.com/go-resty/resty/v2/request.go
generated
vendored
Normal file
@@ -0,0 +1,848 @@
|
||||
// Copyright (c) 2015-2020 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// resty source code and usage is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package resty
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
// Request struct and methods
|
||||
//_______________________________________________________________________
|
||||
|
||||
// Request struct is used to compose and fire individual request from
|
||||
// resty client. Request provides an options to override client level
|
||||
// settings and also an options for the request composition.
|
||||
type Request struct {
|
||||
URL string
|
||||
Method string
|
||||
Token string
|
||||
AuthScheme string
|
||||
QueryParam url.Values
|
||||
FormData url.Values
|
||||
Header http.Header
|
||||
Time time.Time
|
||||
Body interface{}
|
||||
Result interface{}
|
||||
Error interface{}
|
||||
RawRequest *http.Request
|
||||
SRV *SRVRecord
|
||||
UserInfo *User
|
||||
Cookies []*http.Cookie
|
||||
|
||||
// Attempt is to represent the request attempt made during a Resty
|
||||
// request execution flow, including retry count.
|
||||
//
|
||||
// Since v2.4.0
|
||||
Attempt int
|
||||
|
||||
isMultiPart bool
|
||||
isFormData bool
|
||||
setContentLength bool
|
||||
isSaveResponse bool
|
||||
notParseResponse bool
|
||||
jsonEscapeHTML bool
|
||||
trace bool
|
||||
outputFile string
|
||||
fallbackContentType string
|
||||
forceContentType string
|
||||
ctx context.Context
|
||||
pathParams map[string]string
|
||||
values map[string]interface{}
|
||||
client *Client
|
||||
bodyBuf *bytes.Buffer
|
||||
clientTrace *clientTrace
|
||||
multipartFiles []*File
|
||||
multipartFields []*MultipartField
|
||||
}
|
||||
|
||||
// Context method returns the Context if its already set in request
|
||||
// otherwise it creates new one using `context.Background()`.
|
||||
func (r *Request) Context() context.Context {
|
||||
if r.ctx == nil {
|
||||
return context.Background()
|
||||
}
|
||||
return r.ctx
|
||||
}
|
||||
|
||||
// SetContext method sets the context.Context for current Request. It allows
|
||||
// to interrupt the request execution if ctx.Done() channel is closed.
|
||||
// See https://blog.golang.org/context article and the "context" package
|
||||
// documentation.
|
||||
func (r *Request) SetContext(ctx context.Context) *Request {
|
||||
r.ctx = ctx
|
||||
return r
|
||||
}
|
||||
|
||||
// SetHeader method is to set a single header field and its value in the current request.
|
||||
//
|
||||
// For Example: To set `Content-Type` and `Accept` as `application/json`.
|
||||
// client.R().
|
||||
// SetHeader("Content-Type", "application/json").
|
||||
// SetHeader("Accept", "application/json")
|
||||
//
|
||||
// Also you can override header value, which was set at client instance level.
|
||||
func (r *Request) SetHeader(header, value string) *Request {
|
||||
r.Header.Set(header, value)
|
||||
return r
|
||||
}
|
||||
|
||||
// SetHeaders method sets multiple headers field and its values at one go in the current request.
|
||||
//
|
||||
// For Example: To set `Content-Type` and `Accept` as `application/json`
|
||||
//
|
||||
// client.R().
|
||||
// SetHeaders(map[string]string{
|
||||
// "Content-Type": "application/json",
|
||||
// "Accept": "application/json",
|
||||
// })
|
||||
// Also you can override header value, which was set at client instance level.
|
||||
func (r *Request) SetHeaders(headers map[string]string) *Request {
|
||||
for h, v := range headers {
|
||||
r.SetHeader(h, v)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// SetQueryParam method sets single parameter and its value in the current request.
|
||||
// It will be formed as query string for the request.
|
||||
//
|
||||
// For Example: `search=kitchen%20papers&size=large` in the URL after `?` mark.
|
||||
// client.R().
|
||||
// SetQueryParam("search", "kitchen papers").
|
||||
// SetQueryParam("size", "large")
|
||||
// Also you can override query params value, which was set at client instance level.
|
||||
func (r *Request) SetQueryParam(param, value string) *Request {
|
||||
r.QueryParam.Set(param, value)
|
||||
return r
|
||||
}
|
||||
|
||||
// SetQueryParams method sets multiple parameters and its values at one go in the current request.
|
||||
// It will be formed as query string for the request.
|
||||
//
|
||||
// For Example: `search=kitchen%20papers&size=large` in the URL after `?` mark.
|
||||
// client.R().
|
||||
// SetQueryParams(map[string]string{
|
||||
// "search": "kitchen papers",
|
||||
// "size": "large",
|
||||
// })
|
||||
// Also you can override query params value, which was set at client instance level.
|
||||
func (r *Request) SetQueryParams(params map[string]string) *Request {
|
||||
for p, v := range params {
|
||||
r.SetQueryParam(p, v)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// SetQueryParamsFromValues method appends multiple parameters with multi-value
|
||||
// (`url.Values`) at one go in the current request. It will be formed as
|
||||
// query string for the request.
|
||||
//
|
||||
// For Example: `status=pending&status=approved&status=open` in the URL after `?` mark.
|
||||
// client.R().
|
||||
// SetQueryParamsFromValues(url.Values{
|
||||
// "status": []string{"pending", "approved", "open"},
|
||||
// })
|
||||
// Also you can override query params value, which was set at client instance level.
|
||||
func (r *Request) SetQueryParamsFromValues(params url.Values) *Request {
|
||||
for p, v := range params {
|
||||
for _, pv := range v {
|
||||
r.QueryParam.Add(p, pv)
|
||||
}
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// SetQueryString method provides ability to use string as an input to set URL query string for the request.
|
||||
//
|
||||
// Using String as an input
|
||||
// client.R().
|
||||
// SetQueryString("productId=232&template=fresh-sample&cat=resty&source=google&kw=buy a lot more")
|
||||
func (r *Request) SetQueryString(query string) *Request {
|
||||
params, err := url.ParseQuery(strings.TrimSpace(query))
|
||||
if err == nil {
|
||||
for p, v := range params {
|
||||
for _, pv := range v {
|
||||
r.QueryParam.Add(p, pv)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
r.client.log.Errorf("%v", err)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// SetFormData method sets Form parameters and their values in the current request.
|
||||
// It's applicable only HTTP method `POST` and `PUT` and requests content type would be set as
|
||||
// `application/x-www-form-urlencoded`.
|
||||
// client.R().
|
||||
// SetFormData(map[string]string{
|
||||
// "access_token": "BC594900-518B-4F7E-AC75-BD37F019E08F",
|
||||
// "user_id": "3455454545",
|
||||
// })
|
||||
// Also you can override form data value, which was set at client instance level.
|
||||
func (r *Request) SetFormData(data map[string]string) *Request {
|
||||
for k, v := range data {
|
||||
r.FormData.Set(k, v)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// SetFormDataFromValues method appends multiple form parameters with multi-value
|
||||
// (`url.Values`) at one go in the current request.
|
||||
// client.R().
|
||||
// SetFormDataFromValues(url.Values{
|
||||
// "search_criteria": []string{"book", "glass", "pencil"},
|
||||
// })
|
||||
// Also you can override form data value, which was set at client instance level.
|
||||
func (r *Request) SetFormDataFromValues(data url.Values) *Request {
|
||||
for k, v := range data {
|
||||
for _, kv := range v {
|
||||
r.FormData.Add(k, kv)
|
||||
}
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// SetBody method sets the request body for the request. It supports various realtime needs as easy.
|
||||
// We can say its quite handy or powerful. Supported request body data types is `string`,
|
||||
// `[]byte`, `struct`, `map`, `slice` and `io.Reader`. Body value can be pointer or non-pointer.
|
||||
// Automatic marshalling for JSON and XML content type, if it is `struct`, `map`, or `slice`.
|
||||
//
|
||||
// Note: `io.Reader` is processed as bufferless mode while sending request.
|
||||
//
|
||||
// For Example: Struct as a body input, based on content type, it will be marshalled.
|
||||
// client.R().
|
||||
// SetBody(User{
|
||||
// Username: "jeeva@myjeeva.com",
|
||||
// Password: "welcome2resty",
|
||||
// })
|
||||
//
|
||||
// Map as a body input, based on content type, it will be marshalled.
|
||||
// client.R().
|
||||
// SetBody(map[string]interface{}{
|
||||
// "username": "jeeva@myjeeva.com",
|
||||
// "password": "welcome2resty",
|
||||
// "address": &Address{
|
||||
// Address1: "1111 This is my street",
|
||||
// Address2: "Apt 201",
|
||||
// City: "My City",
|
||||
// State: "My State",
|
||||
// ZipCode: 00000,
|
||||
// },
|
||||
// })
|
||||
//
|
||||
// String as a body input. Suitable for any need as a string input.
|
||||
// client.R().
|
||||
// SetBody(`{
|
||||
// "username": "jeeva@getrightcare.com",
|
||||
// "password": "admin"
|
||||
// }`)
|
||||
//
|
||||
// []byte as a body input. Suitable for raw request such as file upload, serialize & deserialize, etc.
|
||||
// client.R().
|
||||
// SetBody([]byte("This is my raw request, sent as-is"))
|
||||
func (r *Request) SetBody(body interface{}) *Request {
|
||||
r.Body = body
|
||||
return r
|
||||
}
|
||||
|
||||
// SetResult method is to register the response `Result` object for automatic unmarshalling for the request,
|
||||
// if response status code is between 200 and 299 and content type either JSON or XML.
|
||||
//
|
||||
// Note: Result object can be pointer or non-pointer.
|
||||
// client.R().SetResult(&AuthToken{})
|
||||
// // OR
|
||||
// client.R().SetResult(AuthToken{})
|
||||
//
|
||||
// Accessing a result value from response instance.
|
||||
// response.Result().(*AuthToken)
|
||||
func (r *Request) SetResult(res interface{}) *Request {
|
||||
r.Result = getPointer(res)
|
||||
return r
|
||||
}
|
||||
|
||||
// SetError method is to register the request `Error` object for automatic unmarshalling for the request,
|
||||
// if response status code is greater than 399 and content type either JSON or XML.
|
||||
//
|
||||
// Note: Error object can be pointer or non-pointer.
|
||||
// client.R().SetError(&AuthError{})
|
||||
// // OR
|
||||
// client.R().SetError(AuthError{})
|
||||
//
|
||||
// Accessing a error value from response instance.
|
||||
// response.Error().(*AuthError)
|
||||
func (r *Request) SetError(err interface{}) *Request {
|
||||
r.Error = getPointer(err)
|
||||
return r
|
||||
}
|
||||
|
||||
// SetFile method is to set single file field name and its path for multipart upload.
|
||||
// client.R().
|
||||
// SetFile("my_file", "/Users/jeeva/Gas Bill - Sep.pdf")
|
||||
func (r *Request) SetFile(param, filePath string) *Request {
|
||||
r.isMultiPart = true
|
||||
r.FormData.Set("@"+param, filePath)
|
||||
return r
|
||||
}
|
||||
|
||||
// SetFiles method is to set multiple file field name and its path for multipart upload.
|
||||
// client.R().
|
||||
// SetFiles(map[string]string{
|
||||
// "my_file1": "/Users/jeeva/Gas Bill - Sep.pdf",
|
||||
// "my_file2": "/Users/jeeva/Electricity Bill - Sep.pdf",
|
||||
// "my_file3": "/Users/jeeva/Water Bill - Sep.pdf",
|
||||
// })
|
||||
func (r *Request) SetFiles(files map[string]string) *Request {
|
||||
r.isMultiPart = true
|
||||
for f, fp := range files {
|
||||
r.FormData.Set("@"+f, fp)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// SetFileReader method is to set single file using io.Reader for multipart upload.
|
||||
// client.R().
|
||||
// SetFileReader("profile_img", "my-profile-img.png", bytes.NewReader(profileImgBytes)).
|
||||
// SetFileReader("notes", "user-notes.txt", bytes.NewReader(notesBytes))
|
||||
func (r *Request) SetFileReader(param, fileName string, reader io.Reader) *Request {
|
||||
r.isMultiPart = true
|
||||
r.multipartFiles = append(r.multipartFiles, &File{
|
||||
Name: fileName,
|
||||
ParamName: param,
|
||||
Reader: reader,
|
||||
})
|
||||
return r
|
||||
}
|
||||
|
||||
// SetMultipartFormData method allows simple form data to be attached to the request as `multipart:form-data`
|
||||
func (r *Request) SetMultipartFormData(data map[string]string) *Request {
|
||||
for k, v := range data {
|
||||
r = r.SetMultipartField(k, "", "", strings.NewReader(v))
|
||||
}
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
// SetMultipartField method is to set custom data using io.Reader for multipart upload.
|
||||
func (r *Request) SetMultipartField(param, fileName, contentType string, reader io.Reader) *Request {
|
||||
r.isMultiPart = true
|
||||
r.multipartFields = append(r.multipartFields, &MultipartField{
|
||||
Param: param,
|
||||
FileName: fileName,
|
||||
ContentType: contentType,
|
||||
Reader: reader,
|
||||
})
|
||||
return r
|
||||
}
|
||||
|
||||
// SetMultipartFields method is to set multiple data fields using io.Reader for multipart upload.
|
||||
//
|
||||
// For Example:
|
||||
// client.R().SetMultipartFields(
|
||||
// &resty.MultipartField{
|
||||
// Param: "uploadManifest1",
|
||||
// FileName: "upload-file-1.json",
|
||||
// ContentType: "application/json",
|
||||
// Reader: strings.NewReader(`{"input": {"name": "Uploaded document 1", "_filename" : ["file1.txt"]}}`),
|
||||
// },
|
||||
// &resty.MultipartField{
|
||||
// Param: "uploadManifest2",
|
||||
// FileName: "upload-file-2.json",
|
||||
// ContentType: "application/json",
|
||||
// Reader: strings.NewReader(`{"input": {"name": "Uploaded document 2", "_filename" : ["file2.txt"]}}`),
|
||||
// })
|
||||
//
|
||||
// If you have slice already, then simply call-
|
||||
// client.R().SetMultipartFields(fields...)
|
||||
func (r *Request) SetMultipartFields(fields ...*MultipartField) *Request {
|
||||
r.isMultiPart = true
|
||||
r.multipartFields = append(r.multipartFields, fields...)
|
||||
return r
|
||||
}
|
||||
|
||||
// SetContentLength method sets the HTTP header `Content-Length` value for current request.
|
||||
// By default Resty won't set `Content-Length`. Also you have an option to enable for every
|
||||
// request.
|
||||
//
|
||||
// See `Client.SetContentLength`
|
||||
// client.R().SetContentLength(true)
|
||||
func (r *Request) SetContentLength(l bool) *Request {
|
||||
r.setContentLength = l
|
||||
return r
|
||||
}
|
||||
|
||||
// SetBasicAuth method sets the basic authentication header in the current HTTP request.
|
||||
//
|
||||
// For Example:
|
||||
// Authorization: Basic <base64-encoded-value>
|
||||
//
|
||||
// To set the header for username "go-resty" and password "welcome"
|
||||
// client.R().SetBasicAuth("go-resty", "welcome")
|
||||
//
|
||||
// This method overrides the credentials set by method `Client.SetBasicAuth`.
|
||||
func (r *Request) SetBasicAuth(username, password string) *Request {
|
||||
r.UserInfo = &User{Username: username, Password: password}
|
||||
return r
|
||||
}
|
||||
|
||||
// SetAuthToken method sets the auth token header(Default Scheme: Bearer) in the current HTTP request. Header example:
|
||||
// Authorization: Bearer <auth-token-value-comes-here>
|
||||
//
|
||||
// For Example: To set auth token BC594900518B4F7EAC75BD37F019E08FBC594900518B4F7EAC75BD37F019E08F
|
||||
//
|
||||
// client.R().SetAuthToken("BC594900518B4F7EAC75BD37F019E08FBC594900518B4F7EAC75BD37F019E08F")
|
||||
//
|
||||
// This method overrides the Auth token set by method `Client.SetAuthToken`.
|
||||
func (r *Request) SetAuthToken(token string) *Request {
|
||||
r.Token = token
|
||||
return r
|
||||
}
|
||||
|
||||
// SetAuthScheme method sets the auth token scheme type in the HTTP request. For Example:
|
||||
// Authorization: <auth-scheme-value-set-here> <auth-token-value>
|
||||
//
|
||||
// For Example: To set the scheme to use OAuth
|
||||
//
|
||||
// client.R().SetAuthScheme("OAuth")
|
||||
//
|
||||
// This auth header scheme gets added to all the request rasied from this client instance.
|
||||
// Also it can be overridden or set one at the request level is supported.
|
||||
//
|
||||
// Information about Auth schemes can be found in RFC7235 which is linked to below along with the page containing
|
||||
// the currently defined official authentication schemes:
|
||||
// https://tools.ietf.org/html/rfc7235
|
||||
// https://www.iana.org/assignments/http-authschemes/http-authschemes.xhtml#authschemes
|
||||
//
|
||||
// This method overrides the Authorization scheme set by method `Client.SetAuthScheme`.
|
||||
func (r *Request) SetAuthScheme(scheme string) *Request {
|
||||
r.AuthScheme = scheme
|
||||
return r
|
||||
}
|
||||
|
||||
// SetOutput method sets the output file for current HTTP request. Current HTTP response will be
|
||||
// saved into given file. It is similar to `curl -o` flag. Absolute path or relative path can be used.
|
||||
// If is it relative path then output file goes under the output directory, as mentioned
|
||||
// in the `Client.SetOutputDirectory`.
|
||||
// client.R().
|
||||
// SetOutput("/Users/jeeva/Downloads/ReplyWithHeader-v5.1-beta.zip").
|
||||
// Get("http://bit.ly/1LouEKr")
|
||||
//
|
||||
// Note: In this scenario `Response.Body` might be nil.
|
||||
func (r *Request) SetOutput(file string) *Request {
|
||||
r.outputFile = file
|
||||
r.isSaveResponse = true
|
||||
return r
|
||||
}
|
||||
|
||||
// SetSRV method sets the details to query the service SRV record and execute the
|
||||
// request.
|
||||
// client.R().
|
||||
// SetSRV(SRVRecord{"web", "testservice.com"}).
|
||||
// Get("/get")
|
||||
func (r *Request) SetSRV(srv *SRVRecord) *Request {
|
||||
r.SRV = srv
|
||||
return r
|
||||
}
|
||||
|
||||
// SetDoNotParseResponse method instructs `Resty` not to parse the response body automatically.
|
||||
// Resty exposes the raw response body as `io.ReadCloser`. Also do not forget to close the body,
|
||||
// otherwise you might get into connection leaks, no connection reuse.
|
||||
//
|
||||
// Note: Response middlewares are not applicable, if you use this option. Basically you have
|
||||
// taken over the control of response parsing from `Resty`.
|
||||
func (r *Request) SetDoNotParseResponse(parse bool) *Request {
|
||||
r.notParseResponse = parse
|
||||
return r
|
||||
}
|
||||
|
||||
// SetPathParam method sets single URL path key-value pair in the
|
||||
// Resty current request instance.
|
||||
// client.R().SetPathParam("userId", "sample@sample.com")
|
||||
//
|
||||
// Result:
|
||||
// URL - /v1/users/{userId}/details
|
||||
// Composed URL - /v1/users/sample@sample.com/details
|
||||
// It replaces the value of the key while composing the request URL. Also you can
|
||||
// override Path Params value, which was set at client instance level.
|
||||
func (r *Request) SetPathParam(param, value string) *Request {
|
||||
r.pathParams[param] = value
|
||||
return r
|
||||
}
|
||||
|
||||
// SetPathParams method sets multiple URL path key-value pairs at one go in the
|
||||
// Resty current request instance.
|
||||
// client.R().SetPathParams(map[string]string{
|
||||
// "userId": "sample@sample.com",
|
||||
// "subAccountId": "100002",
|
||||
// })
|
||||
//
|
||||
// Result:
|
||||
// URL - /v1/users/{userId}/{subAccountId}/details
|
||||
// Composed URL - /v1/users/sample@sample.com/100002/details
|
||||
// It replaces the value of the key while composing request URL. Also you can
|
||||
// override Path Params value, which was set at client instance level.
|
||||
func (r *Request) SetPathParams(params map[string]string) *Request {
|
||||
for p, v := range params {
|
||||
r.SetPathParam(p, v)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// ExpectContentType method allows to provide fallback `Content-Type` for automatic unmarshalling
|
||||
// when `Content-Type` response header is unavailable.
|
||||
func (r *Request) ExpectContentType(contentType string) *Request {
|
||||
r.fallbackContentType = contentType
|
||||
return r
|
||||
}
|
||||
|
||||
// ForceContentType method provides a strong sense of response `Content-Type` for automatic unmarshalling.
|
||||
// Resty gives this a higher priority than the `Content-Type` response header. This means that if both
|
||||
// `Request.ForceContentType` is set and the response `Content-Type` is available, `ForceContentType` will win.
|
||||
func (r *Request) ForceContentType(contentType string) *Request {
|
||||
r.forceContentType = contentType
|
||||
return r
|
||||
}
|
||||
|
||||
// SetJSONEscapeHTML method is to enable/disable the HTML escape on JSON marshal.
|
||||
//
|
||||
// Note: This option only applicable to standard JSON Marshaller.
|
||||
func (r *Request) SetJSONEscapeHTML(b bool) *Request {
|
||||
r.jsonEscapeHTML = b
|
||||
return r
|
||||
}
|
||||
|
||||
// SetCookie method appends a single cookie in the current request instance.
|
||||
// client.R().SetCookie(&http.Cookie{
|
||||
// Name:"go-resty",
|
||||
// Value:"This is cookie value",
|
||||
// })
|
||||
//
|
||||
// Note: Method appends the Cookie value into existing Cookie if already existing.
|
||||
//
|
||||
// Since v2.1.0
|
||||
func (r *Request) SetCookie(hc *http.Cookie) *Request {
|
||||
r.Cookies = append(r.Cookies, hc)
|
||||
return r
|
||||
}
|
||||
|
||||
// SetCookies method sets an array of cookies in the current request instance.
|
||||
// cookies := []*http.Cookie{
|
||||
// &http.Cookie{
|
||||
// Name:"go-resty-1",
|
||||
// Value:"This is cookie 1 value",
|
||||
// },
|
||||
// &http.Cookie{
|
||||
// Name:"go-resty-2",
|
||||
// Value:"This is cookie 2 value",
|
||||
// },
|
||||
// }
|
||||
//
|
||||
// // Setting a cookies into resty's current request
|
||||
// client.R().SetCookies(cookies)
|
||||
//
|
||||
// Note: Method appends the Cookie value into existing Cookie if already existing.
|
||||
//
|
||||
// Since v2.1.0
|
||||
func (r *Request) SetCookies(rs []*http.Cookie) *Request {
|
||||
r.Cookies = append(r.Cookies, rs...)
|
||||
return r
|
||||
}
|
||||
|
||||
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
// HTTP request tracing
|
||||
//_______________________________________________________________________
|
||||
|
||||
// EnableTrace method enables trace for the current request
|
||||
// using `httptrace.ClientTrace` and provides insights.
|
||||
//
|
||||
// client := resty.New()
|
||||
//
|
||||
// resp, err := client.R().EnableTrace().Get("https://httpbin.org/get")
|
||||
// fmt.Println("Error:", err)
|
||||
// fmt.Println("Trace Info:", resp.Request.TraceInfo())
|
||||
//
|
||||
// See `Client.EnableTrace` available too to get trace info for all requests.
|
||||
//
|
||||
// Since v2.0.0
|
||||
func (r *Request) EnableTrace() *Request {
|
||||
r.trace = true
|
||||
return r
|
||||
}
|
||||
|
||||
// TraceInfo method returns the trace info for the request.
|
||||
// If either the Client or Request EnableTrace function has not been called
|
||||
// prior to the request being made, an empty TraceInfo object will be returned.
|
||||
//
|
||||
// Since v2.0.0
|
||||
func (r *Request) TraceInfo() TraceInfo {
|
||||
ct := r.clientTrace
|
||||
|
||||
if ct == nil {
|
||||
return TraceInfo{}
|
||||
}
|
||||
|
||||
ti := TraceInfo{
|
||||
DNSLookup: ct.dnsDone.Sub(ct.dnsStart),
|
||||
TLSHandshake: ct.tlsHandshakeDone.Sub(ct.tlsHandshakeStart),
|
||||
ServerTime: ct.gotFirstResponseByte.Sub(ct.gotConn),
|
||||
IsConnReused: ct.gotConnInfo.Reused,
|
||||
IsConnWasIdle: ct.gotConnInfo.WasIdle,
|
||||
ConnIdleTime: ct.gotConnInfo.IdleTime,
|
||||
RequestAttempt: r.Attempt,
|
||||
}
|
||||
|
||||
// Calculate the total time accordingly,
|
||||
// when connection is reused
|
||||
if ct.gotConnInfo.Reused {
|
||||
ti.TotalTime = ct.endTime.Sub(ct.getConn)
|
||||
} else {
|
||||
ti.TotalTime = ct.endTime.Sub(ct.dnsStart)
|
||||
}
|
||||
|
||||
// Only calculate on successful connections
|
||||
if !ct.connectDone.IsZero() {
|
||||
ti.TCPConnTime = ct.connectDone.Sub(ct.dnsDone)
|
||||
}
|
||||
|
||||
// Only calculate on successful connections
|
||||
if !ct.gotConn.IsZero() {
|
||||
ti.ConnTime = ct.gotConn.Sub(ct.getConn)
|
||||
}
|
||||
|
||||
// Only calculate on successful connections
|
||||
if !ct.gotFirstResponseByte.IsZero() {
|
||||
ti.ResponseTime = ct.endTime.Sub(ct.gotFirstResponseByte)
|
||||
}
|
||||
|
||||
// Capture remote address info when connection is non-nil
|
||||
if ct.gotConnInfo.Conn != nil {
|
||||
ti.RemoteAddr = ct.gotConnInfo.Conn.RemoteAddr()
|
||||
}
|
||||
|
||||
return ti
|
||||
}
|
||||
|
||||
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
// HTTP verb method starts here
|
||||
//_______________________________________________________________________
|
||||
|
||||
// Get method does GET HTTP request. It's defined in section 4.3.1 of RFC7231.
|
||||
func (r *Request) Get(url string) (*Response, error) {
|
||||
return r.Execute(MethodGet, url)
|
||||
}
|
||||
|
||||
// Head method does HEAD HTTP request. It's defined in section 4.3.2 of RFC7231.
|
||||
func (r *Request) Head(url string) (*Response, error) {
|
||||
return r.Execute(MethodHead, url)
|
||||
}
|
||||
|
||||
// Post method does POST HTTP request. It's defined in section 4.3.3 of RFC7231.
|
||||
func (r *Request) Post(url string) (*Response, error) {
|
||||
return r.Execute(MethodPost, url)
|
||||
}
|
||||
|
||||
// Put method does PUT HTTP request. It's defined in section 4.3.4 of RFC7231.
|
||||
func (r *Request) Put(url string) (*Response, error) {
|
||||
return r.Execute(MethodPut, url)
|
||||
}
|
||||
|
||||
// Delete method does DELETE HTTP request. It's defined in section 4.3.5 of RFC7231.
|
||||
func (r *Request) Delete(url string) (*Response, error) {
|
||||
return r.Execute(MethodDelete, url)
|
||||
}
|
||||
|
||||
// Options method does OPTIONS HTTP request. It's defined in section 4.3.7 of RFC7231.
|
||||
func (r *Request) Options(url string) (*Response, error) {
|
||||
return r.Execute(MethodOptions, url)
|
||||
}
|
||||
|
||||
// Patch method does PATCH HTTP request. It's defined in section 2 of RFC5789.
|
||||
func (r *Request) Patch(url string) (*Response, error) {
|
||||
return r.Execute(MethodPatch, url)
|
||||
}
|
||||
|
||||
// Send method performs the HTTP request using the method and URL already defined
|
||||
// for current `Request`.
|
||||
// req := client.R()
|
||||
// req.Method = resty.GET
|
||||
// req.URL = "http://httpbin.org/get"
|
||||
// resp, err := client.R().Send()
|
||||
func (r *Request) Send() (*Response, error) {
|
||||
return r.Execute(r.Method, r.URL)
|
||||
}
|
||||
|
||||
// Execute method performs the HTTP request with given HTTP method and URL
|
||||
// for current `Request`.
|
||||
// resp, err := client.R().Execute(resty.GET, "http://httpbin.org/get")
|
||||
func (r *Request) Execute(method, url string) (*Response, error) {
|
||||
var addrs []*net.SRV
|
||||
var resp *Response
|
||||
var err error
|
||||
|
||||
if r.isMultiPart && !(method == MethodPost || method == MethodPut || method == MethodPatch) {
|
||||
// No OnError hook here since this is a request validation error
|
||||
return nil, fmt.Errorf("multipart content is not allowed in HTTP verb [%v]", method)
|
||||
}
|
||||
|
||||
if r.SRV != nil {
|
||||
_, addrs, err = net.LookupSRV(r.SRV.Service, "tcp", r.SRV.Domain)
|
||||
if err != nil {
|
||||
r.client.onErrorHooks(r, nil, err)
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
r.Method = method
|
||||
r.URL = r.selectAddr(addrs, url, 0)
|
||||
|
||||
if r.client.RetryCount == 0 {
|
||||
r.Attempt = 1
|
||||
resp, err = r.client.execute(r)
|
||||
r.client.onErrorHooks(r, resp, unwrapNoRetryErr(err))
|
||||
return resp, unwrapNoRetryErr(err)
|
||||
}
|
||||
|
||||
err = Backoff(
|
||||
func() (*Response, error) {
|
||||
r.Attempt++
|
||||
|
||||
r.URL = r.selectAddr(addrs, url, r.Attempt)
|
||||
|
||||
resp, err = r.client.execute(r)
|
||||
if err != nil {
|
||||
r.client.log.Errorf("%v, Attempt %v", err, r.Attempt)
|
||||
}
|
||||
|
||||
return resp, err
|
||||
},
|
||||
Retries(r.client.RetryCount),
|
||||
WaitTime(r.client.RetryWaitTime),
|
||||
MaxWaitTime(r.client.RetryMaxWaitTime),
|
||||
RetryConditions(r.client.RetryConditions),
|
||||
)
|
||||
|
||||
r.client.onErrorHooks(r, resp, unwrapNoRetryErr(err))
|
||||
|
||||
return resp, unwrapNoRetryErr(err)
|
||||
}
|
||||
|
||||
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
// SRVRecord struct
|
||||
//_______________________________________________________________________
|
||||
|
||||
// SRVRecord struct holds the data to query the SRV record for the
|
||||
// following service.
|
||||
type SRVRecord struct {
|
||||
Service string
|
||||
Domain string
|
||||
}
|
||||
|
||||
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
// Request Unexported methods
|
||||
//_______________________________________________________________________
|
||||
|
||||
func (r *Request) fmtBodyString(sl int64) (body string) {
|
||||
body = "***** NO CONTENT *****"
|
||||
if !isPayloadSupported(r.Method, r.client.AllowGetMethodPayload) {
|
||||
return
|
||||
}
|
||||
|
||||
if _, ok := r.Body.(io.Reader); ok {
|
||||
body = "***** BODY IS io.Reader *****"
|
||||
return
|
||||
}
|
||||
|
||||
// multipart or form-data
|
||||
if r.isMultiPart || r.isFormData {
|
||||
bodySize := int64(r.bodyBuf.Len())
|
||||
if bodySize > sl {
|
||||
body = fmt.Sprintf("***** REQUEST TOO LARGE (size - %d) *****", bodySize)
|
||||
return
|
||||
}
|
||||
body = r.bodyBuf.String()
|
||||
return
|
||||
}
|
||||
|
||||
// request body data
|
||||
if r.Body == nil {
|
||||
return
|
||||
}
|
||||
var prtBodyBytes []byte
|
||||
var err error
|
||||
|
||||
contentType := r.Header.Get(hdrContentTypeKey)
|
||||
kind := kindOf(r.Body)
|
||||
if canJSONMarshal(contentType, kind) {
|
||||
prtBodyBytes, err = json.MarshalIndent(&r.Body, "", " ")
|
||||
} else if IsXMLType(contentType) && (kind == reflect.Struct) {
|
||||
prtBodyBytes, err = xml.MarshalIndent(&r.Body, "", " ")
|
||||
} else if b, ok := r.Body.(string); ok {
|
||||
if IsJSONType(contentType) {
|
||||
bodyBytes := []byte(b)
|
||||
out := acquireBuffer()
|
||||
defer releaseBuffer(out)
|
||||
if err = json.Indent(out, bodyBytes, "", " "); err == nil {
|
||||
prtBodyBytes = out.Bytes()
|
||||
}
|
||||
} else {
|
||||
body = b
|
||||
}
|
||||
} else if b, ok := r.Body.([]byte); ok {
|
||||
body = fmt.Sprintf("***** BODY IS byte(s) (size - %d) *****", len(b))
|
||||
return
|
||||
}
|
||||
|
||||
if prtBodyBytes != nil && err == nil {
|
||||
body = string(prtBodyBytes)
|
||||
}
|
||||
|
||||
if len(body) > 0 {
|
||||
bodySize := int64(len([]byte(body)))
|
||||
if bodySize > sl {
|
||||
body = fmt.Sprintf("***** REQUEST TOO LARGE (size - %d) *****", bodySize)
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (r *Request) selectAddr(addrs []*net.SRV, path string, attempt int) string {
|
||||
if addrs == nil {
|
||||
return path
|
||||
}
|
||||
|
||||
idx := attempt % len(addrs)
|
||||
domain := strings.TrimRight(addrs[idx].Target, ".")
|
||||
path = strings.TrimLeft(path, "/")
|
||||
|
||||
return fmt.Sprintf("%s://%s:%d/%s", r.client.scheme, domain, addrs[idx].Port, path)
|
||||
}
|
||||
|
||||
func (r *Request) initValuesMap() {
|
||||
if r.values == nil {
|
||||
r.values = make(map[string]interface{})
|
||||
}
|
||||
}
|
||||
|
||||
var noescapeJSONMarshal = func(v interface{}) ([]byte, error) {
|
||||
buf := acquireBuffer()
|
||||
defer releaseBuffer(buf)
|
||||
encoder := json.NewEncoder(buf)
|
||||
encoder.SetEscapeHTML(false)
|
||||
err := encoder.Encode(v)
|
||||
return buf.Bytes(), err
|
||||
}
|
||||
175
vendor/github.com/go-resty/resty/v2/response.go
generated
vendored
Normal file
175
vendor/github.com/go-resty/resty/v2/response.go
generated
vendored
Normal file
@@ -0,0 +1,175 @@
|
||||
// Copyright (c) 2015-2020 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// resty source code and usage is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package resty
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
// Response struct and methods
|
||||
//_______________________________________________________________________
|
||||
|
||||
// Response struct holds response values of executed request.
|
||||
type Response struct {
|
||||
Request *Request
|
||||
RawResponse *http.Response
|
||||
|
||||
body []byte
|
||||
size int64
|
||||
receivedAt time.Time
|
||||
}
|
||||
|
||||
// Body method returns HTTP response as []byte array for the executed request.
|
||||
//
|
||||
// Note: `Response.Body` might be nil, if `Request.SetOutput` is used.
|
||||
func (r *Response) Body() []byte {
|
||||
if r.RawResponse == nil {
|
||||
return []byte{}
|
||||
}
|
||||
return r.body
|
||||
}
|
||||
|
||||
// Status method returns the HTTP status string for the executed request.
|
||||
// Example: 200 OK
|
||||
func (r *Response) Status() string {
|
||||
if r.RawResponse == nil {
|
||||
return ""
|
||||
}
|
||||
return r.RawResponse.Status
|
||||
}
|
||||
|
||||
// StatusCode method returns the HTTP status code for the executed request.
|
||||
// Example: 200
|
||||
func (r *Response) StatusCode() int {
|
||||
if r.RawResponse == nil {
|
||||
return 0
|
||||
}
|
||||
return r.RawResponse.StatusCode
|
||||
}
|
||||
|
||||
// Proto method returns the HTTP response protocol used for the request.
|
||||
func (r *Response) Proto() string {
|
||||
if r.RawResponse == nil {
|
||||
return ""
|
||||
}
|
||||
return r.RawResponse.Proto
|
||||
}
|
||||
|
||||
// Result method returns the response value as an object if it has one
|
||||
func (r *Response) Result() interface{} {
|
||||
return r.Request.Result
|
||||
}
|
||||
|
||||
// Error method returns the error object if it has one
|
||||
func (r *Response) Error() interface{} {
|
||||
return r.Request.Error
|
||||
}
|
||||
|
||||
// Header method returns the response headers
|
||||
func (r *Response) Header() http.Header {
|
||||
if r.RawResponse == nil {
|
||||
return http.Header{}
|
||||
}
|
||||
return r.RawResponse.Header
|
||||
}
|
||||
|
||||
// Cookies method to access all the response cookies
|
||||
func (r *Response) Cookies() []*http.Cookie {
|
||||
if r.RawResponse == nil {
|
||||
return make([]*http.Cookie, 0)
|
||||
}
|
||||
return r.RawResponse.Cookies()
|
||||
}
|
||||
|
||||
// String method returns the body of the server response as String.
|
||||
func (r *Response) String() string {
|
||||
if r.body == nil {
|
||||
return ""
|
||||
}
|
||||
return strings.TrimSpace(string(r.body))
|
||||
}
|
||||
|
||||
// Time method returns the time of HTTP response time that from request we sent and received a request.
|
||||
//
|
||||
// See `Response.ReceivedAt` to know when client received response and see `Response.Request.Time` to know
|
||||
// when client sent a request.
|
||||
func (r *Response) Time() time.Duration {
|
||||
if r.Request.clientTrace != nil {
|
||||
return r.Request.TraceInfo().TotalTime
|
||||
}
|
||||
return r.receivedAt.Sub(r.Request.Time)
|
||||
}
|
||||
|
||||
// ReceivedAt method returns when response got received from server for the request.
|
||||
func (r *Response) ReceivedAt() time.Time {
|
||||
return r.receivedAt
|
||||
}
|
||||
|
||||
// Size method returns the HTTP response size in bytes. Ya, you can relay on HTTP `Content-Length` header,
|
||||
// however it won't be good for chucked transfer/compressed response. Since Resty calculates response size
|
||||
// at the client end. You will get actual size of the http response.
|
||||
func (r *Response) Size() int64 {
|
||||
return r.size
|
||||
}
|
||||
|
||||
// RawBody method exposes the HTTP raw response body. Use this method in-conjunction with `SetDoNotParseResponse`
|
||||
// option otherwise you get an error as `read err: http: read on closed response body`.
|
||||
//
|
||||
// Do not forget to close the body, otherwise you might get into connection leaks, no connection reuse.
|
||||
// Basically you have taken over the control of response parsing from `Resty`.
|
||||
func (r *Response) RawBody() io.ReadCloser {
|
||||
if r.RawResponse == nil {
|
||||
return nil
|
||||
}
|
||||
return r.RawResponse.Body
|
||||
}
|
||||
|
||||
// IsSuccess method returns true if HTTP status `code >= 200 and <= 299` otherwise false.
|
||||
func (r *Response) IsSuccess() bool {
|
||||
return r.StatusCode() > 199 && r.StatusCode() < 300
|
||||
}
|
||||
|
||||
// IsError method returns true if HTTP status `code >= 400` otherwise false.
|
||||
func (r *Response) IsError() bool {
|
||||
return r.StatusCode() > 399
|
||||
}
|
||||
|
||||
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
// Response Unexported methods
|
||||
//_______________________________________________________________________
|
||||
|
||||
func (r *Response) setReceivedAt() {
|
||||
r.receivedAt = time.Now()
|
||||
if r.Request.clientTrace != nil {
|
||||
r.Request.clientTrace.endTime = r.receivedAt
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Response) fmtBodyString(sl int64) string {
|
||||
if r.body != nil {
|
||||
if int64(len(r.body)) > sl {
|
||||
return fmt.Sprintf("***** RESPONSE TOO LARGE (size - %d) *****", len(r.body))
|
||||
}
|
||||
ct := r.Header().Get(hdrContentTypeKey)
|
||||
if IsJSONType(ct) {
|
||||
out := acquireBuffer()
|
||||
defer releaseBuffer(out)
|
||||
err := json.Indent(out, r.body, "", " ")
|
||||
if err != nil {
|
||||
return fmt.Sprintf("*** Error: Unable to format response body - \"%s\" ***\n\nLog Body as-is:\n%s", err, r.String())
|
||||
}
|
||||
return out.String()
|
||||
}
|
||||
return r.String()
|
||||
}
|
||||
|
||||
return "***** NO CONTENT *****"
|
||||
}
|
||||
40
vendor/github.com/go-resty/resty/v2/resty.go
generated
vendored
Normal file
40
vendor/github.com/go-resty/resty/v2/resty.go
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
// Copyright (c) 2015-2020 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// resty source code and usage is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package resty provides Simple HTTP and REST client library for Go.
|
||||
package resty
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/cookiejar"
|
||||
|
||||
"golang.org/x/net/publicsuffix"
|
||||
)
|
||||
|
||||
// Version # of resty
|
||||
const Version = "2.6.0"
|
||||
|
||||
// New method creates a new Resty client.
|
||||
func New() *Client {
|
||||
cookieJar, _ := cookiejar.New(&cookiejar.Options{PublicSuffixList: publicsuffix.List})
|
||||
return createClient(&http.Client{
|
||||
Jar: cookieJar,
|
||||
})
|
||||
}
|
||||
|
||||
// NewWithClient method creates a new Resty client with given `http.Client`.
|
||||
func NewWithClient(hc *http.Client) *Client {
|
||||
return createClient(hc)
|
||||
}
|
||||
|
||||
// NewWithLocalAddr method creates a new Resty client with given Local Address
|
||||
// to dial from.
|
||||
func NewWithLocalAddr(localAddr net.Addr) *Client {
|
||||
cookieJar, _ := cookiejar.New(&cookiejar.Options{PublicSuffixList: publicsuffix.List})
|
||||
return createClient(&http.Client{
|
||||
Jar: cookieJar,
|
||||
Transport: createTransport(localAddr),
|
||||
})
|
||||
}
|
||||
178
vendor/github.com/go-resty/resty/v2/retry.go
generated
vendored
Normal file
178
vendor/github.com/go-resty/resty/v2/retry.go
generated
vendored
Normal file
@@ -0,0 +1,178 @@
|
||||
// Copyright (c) 2015-2020 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// resty source code and usage is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package resty
|
||||
|
||||
import (
|
||||
"context"
|
||||
"math"
|
||||
"math/rand"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultMaxRetries = 3
|
||||
defaultWaitTime = time.Duration(100) * time.Millisecond
|
||||
defaultMaxWaitTime = time.Duration(2000) * time.Millisecond
|
||||
)
|
||||
|
||||
type (
|
||||
// Option is to create convenient retry options like wait time, max retries, etc.
|
||||
Option func(*Options)
|
||||
|
||||
// RetryConditionFunc type is for retry condition function
|
||||
// input: non-nil Response OR request execution error
|
||||
RetryConditionFunc func(*Response, error) bool
|
||||
|
||||
// RetryAfterFunc returns time to wait before retry
|
||||
// For example, it can parse HTTP Retry-After header
|
||||
// https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
|
||||
// Non-nil error is returned if it is found that request is not retryable
|
||||
// (0, nil) is a special result means 'use default algorithm'
|
||||
RetryAfterFunc func(*Client, *Response) (time.Duration, error)
|
||||
|
||||
// Options struct is used to hold retry settings.
|
||||
Options struct {
|
||||
maxRetries int
|
||||
waitTime time.Duration
|
||||
maxWaitTime time.Duration
|
||||
retryConditions []RetryConditionFunc
|
||||
}
|
||||
)
|
||||
|
||||
// Retries sets the max number of retries
|
||||
func Retries(value int) Option {
|
||||
return func(o *Options) {
|
||||
o.maxRetries = value
|
||||
}
|
||||
}
|
||||
|
||||
// WaitTime sets the default wait time to sleep between requests
|
||||
func WaitTime(value time.Duration) Option {
|
||||
return func(o *Options) {
|
||||
o.waitTime = value
|
||||
}
|
||||
}
|
||||
|
||||
// MaxWaitTime sets the max wait time to sleep between requests
|
||||
func MaxWaitTime(value time.Duration) Option {
|
||||
return func(o *Options) {
|
||||
o.maxWaitTime = value
|
||||
}
|
||||
}
|
||||
|
||||
// RetryConditions sets the conditions that will be checked for retry.
|
||||
func RetryConditions(conditions []RetryConditionFunc) Option {
|
||||
return func(o *Options) {
|
||||
o.retryConditions = conditions
|
||||
}
|
||||
}
|
||||
|
||||
// Backoff retries with increasing timeout duration up until X amount of retries
|
||||
// (Default is 3 attempts, Override with option Retries(n))
|
||||
func Backoff(operation func() (*Response, error), options ...Option) error {
|
||||
// Defaults
|
||||
opts := Options{
|
||||
maxRetries: defaultMaxRetries,
|
||||
waitTime: defaultWaitTime,
|
||||
maxWaitTime: defaultMaxWaitTime,
|
||||
retryConditions: []RetryConditionFunc{},
|
||||
}
|
||||
|
||||
for _, o := range options {
|
||||
o(&opts)
|
||||
}
|
||||
|
||||
var (
|
||||
resp *Response
|
||||
err error
|
||||
)
|
||||
|
||||
for attempt := 0; attempt <= opts.maxRetries; attempt++ {
|
||||
resp, err = operation()
|
||||
ctx := context.Background()
|
||||
if resp != nil && resp.Request.ctx != nil {
|
||||
ctx = resp.Request.ctx
|
||||
}
|
||||
if ctx.Err() != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err1 := unwrapNoRetryErr(err) // raw error, it used for return users callback.
|
||||
needsRetry := err != nil && err == err1 // retry on a few operation errors by default
|
||||
|
||||
for _, condition := range opts.retryConditions {
|
||||
needsRetry = condition(resp, err1)
|
||||
if needsRetry {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !needsRetry {
|
||||
return err
|
||||
}
|
||||
|
||||
waitTime, err2 := sleepDuration(resp, opts.waitTime, opts.maxWaitTime, attempt)
|
||||
if err2 != nil {
|
||||
if err == nil {
|
||||
err = err2
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
select {
|
||||
case <-time.After(waitTime):
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func sleepDuration(resp *Response, min, max time.Duration, attempt int) (time.Duration, error) {
|
||||
const maxInt = 1<<31 - 1 // max int for arch 386
|
||||
|
||||
if max < 0 {
|
||||
max = maxInt
|
||||
}
|
||||
|
||||
if resp == nil {
|
||||
goto defaultCase
|
||||
}
|
||||
|
||||
// 1. Check for custom callback
|
||||
if retryAfterFunc := resp.Request.client.RetryAfter; retryAfterFunc != nil {
|
||||
result, err := retryAfterFunc(resp.Request.client, resp)
|
||||
if err != nil {
|
||||
return 0, err // i.e. 'API quota exceeded'
|
||||
}
|
||||
if result == 0 {
|
||||
goto defaultCase
|
||||
}
|
||||
if result < 0 || max < result {
|
||||
result = max
|
||||
}
|
||||
if result < min {
|
||||
result = min
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// 2. Return capped exponential backoff with jitter
|
||||
// http://www.awsarchitectureblog.com/2015/03/backoff.html
|
||||
defaultCase:
|
||||
base := float64(min)
|
||||
capLevel := float64(max)
|
||||
|
||||
temp := math.Min(capLevel, base*math.Exp2(float64(attempt)))
|
||||
ri := int64(temp / 2)
|
||||
result := time.Duration(math.Abs(float64(ri + rand.Int63n(ri))))
|
||||
|
||||
if result < min {
|
||||
result = min
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
130
vendor/github.com/go-resty/resty/v2/trace.go
generated
vendored
Normal file
130
vendor/github.com/go-resty/resty/v2/trace.go
generated
vendored
Normal file
@@ -0,0 +1,130 @@
|
||||
// Copyright (c) 2015-2020 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// resty source code and usage is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package resty
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"net"
|
||||
"net/http/httptrace"
|
||||
"time"
|
||||
)
|
||||
|
||||
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
// TraceInfo struct
|
||||
//_______________________________________________________________________
|
||||
|
||||
// TraceInfo struct is used provide request trace info such as DNS lookup
|
||||
// duration, Connection obtain duration, Server processing duration, etc.
|
||||
//
|
||||
// Since v2.0.0
|
||||
type TraceInfo struct {
|
||||
// DNSLookup is a duration that transport took to perform
|
||||
// DNS lookup.
|
||||
DNSLookup time.Duration
|
||||
|
||||
// ConnTime is a duration that took to obtain a successful connection.
|
||||
ConnTime time.Duration
|
||||
|
||||
// TCPConnTime is a duration that took to obtain the TCP connection.
|
||||
TCPConnTime time.Duration
|
||||
|
||||
// TLSHandshake is a duration that TLS handshake took place.
|
||||
TLSHandshake time.Duration
|
||||
|
||||
// ServerTime is a duration that server took to respond first byte.
|
||||
ServerTime time.Duration
|
||||
|
||||
// ResponseTime is a duration since first response byte from server to
|
||||
// request completion.
|
||||
ResponseTime time.Duration
|
||||
|
||||
// TotalTime is a duration that total request took end-to-end.
|
||||
TotalTime time.Duration
|
||||
|
||||
// IsConnReused is whether this connection has been previously
|
||||
// used for another HTTP request.
|
||||
IsConnReused bool
|
||||
|
||||
// IsConnWasIdle is whether this connection was obtained from an
|
||||
// idle pool.
|
||||
IsConnWasIdle bool
|
||||
|
||||
// ConnIdleTime is a duration how long the connection was previously
|
||||
// idle, if IsConnWasIdle is true.
|
||||
ConnIdleTime time.Duration
|
||||
|
||||
// RequestAttempt is to represent the request attempt made during a Resty
|
||||
// request execution flow, including retry count.
|
||||
RequestAttempt int
|
||||
|
||||
// RemoteAddr returns the remote network address.
|
||||
RemoteAddr net.Addr
|
||||
}
|
||||
|
||||
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
// ClientTrace struct and its methods
|
||||
//_______________________________________________________________________
|
||||
|
||||
// tracer struct maps the `httptrace.ClientTrace` hooks into Fields
|
||||
// with same naming for easy understanding. Plus additional insights
|
||||
// Request.
|
||||
type clientTrace struct {
|
||||
getConn time.Time
|
||||
dnsStart time.Time
|
||||
dnsDone time.Time
|
||||
connectDone time.Time
|
||||
tlsHandshakeStart time.Time
|
||||
tlsHandshakeDone time.Time
|
||||
gotConn time.Time
|
||||
gotFirstResponseByte time.Time
|
||||
endTime time.Time
|
||||
gotConnInfo httptrace.GotConnInfo
|
||||
}
|
||||
|
||||
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
// Trace unexported methods
|
||||
//_______________________________________________________________________
|
||||
|
||||
func (t *clientTrace) createContext(ctx context.Context) context.Context {
|
||||
return httptrace.WithClientTrace(
|
||||
ctx,
|
||||
&httptrace.ClientTrace{
|
||||
DNSStart: func(_ httptrace.DNSStartInfo) {
|
||||
t.dnsStart = time.Now()
|
||||
},
|
||||
DNSDone: func(_ httptrace.DNSDoneInfo) {
|
||||
t.dnsDone = time.Now()
|
||||
},
|
||||
ConnectStart: func(_, _ string) {
|
||||
if t.dnsDone.IsZero() {
|
||||
t.dnsDone = time.Now()
|
||||
}
|
||||
if t.dnsStart.IsZero() {
|
||||
t.dnsStart = t.dnsDone
|
||||
}
|
||||
},
|
||||
ConnectDone: func(net, addr string, err error) {
|
||||
t.connectDone = time.Now()
|
||||
},
|
||||
GetConn: func(_ string) {
|
||||
t.getConn = time.Now()
|
||||
},
|
||||
GotConn: func(ci httptrace.GotConnInfo) {
|
||||
t.gotConn = time.Now()
|
||||
t.gotConnInfo = ci
|
||||
},
|
||||
GotFirstResponseByte: func() {
|
||||
t.gotFirstResponseByte = time.Now()
|
||||
},
|
||||
TLSHandshakeStart: func() {
|
||||
t.tlsHandshakeStart = time.Now()
|
||||
},
|
||||
TLSHandshakeDone: func(_ tls.ConnectionState, _ error) {
|
||||
t.tlsHandshakeDone = time.Now()
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
35
vendor/github.com/go-resty/resty/v2/transport.go
generated
vendored
Normal file
35
vendor/github.com/go-resty/resty/v2/transport.go
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
// +build go1.13
|
||||
|
||||
// Copyright (c) 2015-2020 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// resty source code and usage is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package resty
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/http"
|
||||
"runtime"
|
||||
"time"
|
||||
)
|
||||
|
||||
func createTransport(localAddr net.Addr) *http.Transport {
|
||||
dialer := &net.Dialer{
|
||||
Timeout: 30 * time.Second,
|
||||
KeepAlive: 30 * time.Second,
|
||||
DualStack: true,
|
||||
}
|
||||
if localAddr != nil {
|
||||
dialer.LocalAddr = localAddr
|
||||
}
|
||||
return &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
DialContext: dialer.DialContext,
|
||||
ForceAttemptHTTP2: true,
|
||||
MaxIdleConns: 100,
|
||||
IdleConnTimeout: 90 * time.Second,
|
||||
TLSHandshakeTimeout: 10 * time.Second,
|
||||
ExpectContinueTimeout: 1 * time.Second,
|
||||
MaxIdleConnsPerHost: runtime.GOMAXPROCS(0) + 1,
|
||||
}
|
||||
}
|
||||
34
vendor/github.com/go-resty/resty/v2/transport112.go
generated
vendored
Normal file
34
vendor/github.com/go-resty/resty/v2/transport112.go
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
// +build !go1.13
|
||||
|
||||
// Copyright (c) 2015-2020 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// resty source code and usage is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package resty
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/http"
|
||||
"runtime"
|
||||
"time"
|
||||
)
|
||||
|
||||
func createTransport(localAddr net.Addr) *http.Transport {
|
||||
dialer := &net.Dialer{
|
||||
Timeout: 30 * time.Second,
|
||||
KeepAlive: 30 * time.Second,
|
||||
DualStack: true,
|
||||
}
|
||||
if localAddr != nil {
|
||||
dialer.LocalAddr = localAddr
|
||||
}
|
||||
return &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
DialContext: dialer.DialContext,
|
||||
MaxIdleConns: 100,
|
||||
IdleConnTimeout: 90 * time.Second,
|
||||
TLSHandshakeTimeout: 10 * time.Second,
|
||||
ExpectContinueTimeout: 1 * time.Second,
|
||||
MaxIdleConnsPerHost: runtime.GOMAXPROCS(0) + 1,
|
||||
}
|
||||
}
|
||||
357
vendor/github.com/go-resty/resty/v2/util.go
generated
vendored
Normal file
357
vendor/github.com/go-resty/resty/v2/util.go
generated
vendored
Normal file
@@ -0,0 +1,357 @@
|
||||
// Copyright (c) 2015-2020 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// resty source code and usage is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package resty
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"net/textproto"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
// Logger interface
|
||||
//_______________________________________________________________________
|
||||
|
||||
// Logger interface is to abstract the logging from Resty. Gives control to
|
||||
// the Resty users, choice of the logger.
|
||||
type Logger interface {
|
||||
Errorf(format string, v ...interface{})
|
||||
Warnf(format string, v ...interface{})
|
||||
Debugf(format string, v ...interface{})
|
||||
}
|
||||
|
||||
func createLogger() *logger {
|
||||
l := &logger{l: log.New(os.Stderr, "", log.Ldate|log.Lmicroseconds)}
|
||||
return l
|
||||
}
|
||||
|
||||
var _ Logger = (*logger)(nil)
|
||||
|
||||
type logger struct {
|
||||
l *log.Logger
|
||||
}
|
||||
|
||||
func (l *logger) Errorf(format string, v ...interface{}) {
|
||||
l.output("ERROR RESTY "+format, v...)
|
||||
}
|
||||
|
||||
func (l *logger) Warnf(format string, v ...interface{}) {
|
||||
l.output("WARN RESTY "+format, v...)
|
||||
}
|
||||
|
||||
func (l *logger) Debugf(format string, v ...interface{}) {
|
||||
l.output("DEBUG RESTY "+format, v...)
|
||||
}
|
||||
|
||||
func (l *logger) output(format string, v ...interface{}) {
|
||||
if len(v) == 0 {
|
||||
l.l.Print(format)
|
||||
return
|
||||
}
|
||||
l.l.Printf(format, v...)
|
||||
}
|
||||
|
||||
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
// Package Helper methods
|
||||
//_______________________________________________________________________
|
||||
|
||||
// IsStringEmpty method tells whether given string is empty or not
|
||||
func IsStringEmpty(str string) bool {
|
||||
return len(strings.TrimSpace(str)) == 0
|
||||
}
|
||||
|
||||
// DetectContentType method is used to figure out `Request.Body` content type for request header
|
||||
func DetectContentType(body interface{}) string {
|
||||
contentType := plainTextType
|
||||
kind := kindOf(body)
|
||||
switch kind {
|
||||
case reflect.Struct, reflect.Map:
|
||||
contentType = jsonContentType
|
||||
case reflect.String:
|
||||
contentType = plainTextType
|
||||
default:
|
||||
if b, ok := body.([]byte); ok {
|
||||
contentType = http.DetectContentType(b)
|
||||
} else if kind == reflect.Slice {
|
||||
contentType = jsonContentType
|
||||
}
|
||||
}
|
||||
|
||||
return contentType
|
||||
}
|
||||
|
||||
// IsJSONType method is to check JSON content type or not
|
||||
func IsJSONType(ct string) bool {
|
||||
return jsonCheck.MatchString(ct)
|
||||
}
|
||||
|
||||
// IsXMLType method is to check XML content type or not
|
||||
func IsXMLType(ct string) bool {
|
||||
return xmlCheck.MatchString(ct)
|
||||
}
|
||||
|
||||
// Unmarshalc content into object from JSON or XML
|
||||
func Unmarshalc(c *Client, ct string, b []byte, d interface{}) (err error) {
|
||||
if IsJSONType(ct) {
|
||||
err = c.JSONUnmarshal(b, d)
|
||||
} else if IsXMLType(ct) {
|
||||
err = xml.Unmarshal(b, d)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
// RequestLog and ResponseLog type
|
||||
//_______________________________________________________________________
|
||||
|
||||
// RequestLog struct is used to collected information from resty request
|
||||
// instance for debug logging. It sent to request log callback before resty
|
||||
// actually logs the information.
|
||||
type RequestLog struct {
|
||||
Header http.Header
|
||||
Body string
|
||||
}
|
||||
|
||||
// ResponseLog struct is used to collected information from resty response
|
||||
// instance for debug logging. It sent to response log callback before resty
|
||||
// actually logs the information.
|
||||
type ResponseLog struct {
|
||||
Header http.Header
|
||||
Body string
|
||||
}
|
||||
|
||||
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
// Package Unexported methods
|
||||
//_______________________________________________________________________
|
||||
|
||||
// way to disable the HTML escape as opt-in
|
||||
func jsonMarshal(c *Client, r *Request, d interface{}) ([]byte, error) {
|
||||
if !r.jsonEscapeHTML {
|
||||
return noescapeJSONMarshal(d)
|
||||
} else if !c.jsonEscapeHTML {
|
||||
return noescapeJSONMarshal(d)
|
||||
}
|
||||
return c.JSONMarshal(d)
|
||||
}
|
||||
|
||||
func firstNonEmpty(v ...string) string {
|
||||
for _, s := range v {
|
||||
if !IsStringEmpty(s) {
|
||||
return s
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
var quoteEscaper = strings.NewReplacer("\\", "\\\\", `"`, "\\\"")
|
||||
|
||||
func escapeQuotes(s string) string {
|
||||
return quoteEscaper.Replace(s)
|
||||
}
|
||||
|
||||
func createMultipartHeader(param, fileName, contentType string) textproto.MIMEHeader {
|
||||
hdr := make(textproto.MIMEHeader)
|
||||
|
||||
var contentDispositionValue string
|
||||
if IsStringEmpty(fileName) {
|
||||
contentDispositionValue = fmt.Sprintf(`form-data; name="%s"`, param)
|
||||
} else {
|
||||
contentDispositionValue = fmt.Sprintf(`form-data; name="%s"; filename="%s"`,
|
||||
param, escapeQuotes(fileName))
|
||||
}
|
||||
hdr.Set("Content-Disposition", contentDispositionValue)
|
||||
|
||||
if !IsStringEmpty(contentType) {
|
||||
hdr.Set(hdrContentTypeKey, contentType)
|
||||
}
|
||||
return hdr
|
||||
}
|
||||
|
||||
func addMultipartFormField(w *multipart.Writer, mf *MultipartField) error {
|
||||
partWriter, err := w.CreatePart(createMultipartHeader(mf.Param, mf.FileName, mf.ContentType))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = io.Copy(partWriter, mf.Reader)
|
||||
return err
|
||||
}
|
||||
|
||||
func writeMultipartFormFile(w *multipart.Writer, fieldName, fileName string, r io.Reader) error {
|
||||
// Auto detect actual multipart content type
|
||||
cbuf := make([]byte, 512)
|
||||
size, err := r.Read(cbuf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
partWriter, err := w.CreatePart(createMultipartHeader(fieldName, fileName, http.DetectContentType(cbuf)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err = partWriter.Write(cbuf[:size]); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = io.Copy(partWriter, r)
|
||||
return err
|
||||
}
|
||||
|
||||
func addFile(w *multipart.Writer, fieldName, path string) error {
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closeq(file)
|
||||
return writeMultipartFormFile(w, fieldName, filepath.Base(path), file)
|
||||
}
|
||||
|
||||
func addFileReader(w *multipart.Writer, f *File) error {
|
||||
return writeMultipartFormFile(w, f.ParamName, f.Name, f.Reader)
|
||||
}
|
||||
|
||||
func getPointer(v interface{}) interface{} {
|
||||
vv := valueOf(v)
|
||||
if vv.Kind() == reflect.Ptr {
|
||||
return v
|
||||
}
|
||||
return reflect.New(vv.Type()).Interface()
|
||||
}
|
||||
|
||||
func isPayloadSupported(m string, allowMethodGet bool) bool {
|
||||
return !(m == MethodHead || m == MethodOptions || (m == MethodGet && !allowMethodGet))
|
||||
}
|
||||
|
||||
func typeOf(i interface{}) reflect.Type {
|
||||
return indirect(valueOf(i)).Type()
|
||||
}
|
||||
|
||||
func valueOf(i interface{}) reflect.Value {
|
||||
return reflect.ValueOf(i)
|
||||
}
|
||||
|
||||
func indirect(v reflect.Value) reflect.Value {
|
||||
return reflect.Indirect(v)
|
||||
}
|
||||
|
||||
func kindOf(v interface{}) reflect.Kind {
|
||||
return typeOf(v).Kind()
|
||||
}
|
||||
|
||||
func createDirectory(dir string) (err error) {
|
||||
if _, err = os.Stat(dir); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
if err = os.MkdirAll(dir, 0755); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func canJSONMarshal(contentType string, kind reflect.Kind) bool {
|
||||
return IsJSONType(contentType) && (kind == reflect.Struct || kind == reflect.Map || kind == reflect.Slice)
|
||||
}
|
||||
|
||||
func functionName(i interface{}) string {
|
||||
return runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name()
|
||||
}
|
||||
|
||||
func acquireBuffer() *bytes.Buffer {
|
||||
return bufPool.Get().(*bytes.Buffer)
|
||||
}
|
||||
|
||||
func releaseBuffer(buf *bytes.Buffer) {
|
||||
if buf != nil {
|
||||
buf.Reset()
|
||||
bufPool.Put(buf)
|
||||
}
|
||||
}
|
||||
|
||||
func closeq(v interface{}) {
|
||||
if c, ok := v.(io.Closer); ok {
|
||||
silently(c.Close())
|
||||
}
|
||||
}
|
||||
|
||||
func silently(_ ...interface{}) {}
|
||||
|
||||
func composeHeaders(c *Client, r *Request, hdrs http.Header) string {
|
||||
str := make([]string, 0, len(hdrs))
|
||||
for _, k := range sortHeaderKeys(hdrs) {
|
||||
var v string
|
||||
if k == "Cookie" {
|
||||
cv := strings.TrimSpace(strings.Join(hdrs[k], ", "))
|
||||
if c.GetClient().Jar != nil {
|
||||
for _, c := range c.GetClient().Jar.Cookies(r.RawRequest.URL) {
|
||||
if cv != "" {
|
||||
cv = cv + "; " + c.String()
|
||||
} else {
|
||||
cv = c.String()
|
||||
}
|
||||
}
|
||||
}
|
||||
v = strings.TrimSpace(fmt.Sprintf("%25s: %s", k, cv))
|
||||
} else {
|
||||
v = strings.TrimSpace(fmt.Sprintf("%25s: %s", k, strings.Join(hdrs[k], ", ")))
|
||||
}
|
||||
if v != "" {
|
||||
str = append(str, "\t"+v)
|
||||
}
|
||||
}
|
||||
return strings.Join(str, "\n")
|
||||
}
|
||||
|
||||
func sortHeaderKeys(hdrs http.Header) []string {
|
||||
keys := make([]string, 0, len(hdrs))
|
||||
for key := range hdrs {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
return keys
|
||||
}
|
||||
|
||||
func copyHeaders(hdrs http.Header) http.Header {
|
||||
nh := http.Header{}
|
||||
for k, v := range hdrs {
|
||||
nh[k] = v
|
||||
}
|
||||
return nh
|
||||
}
|
||||
|
||||
type noRetryErr struct {
|
||||
err error
|
||||
}
|
||||
|
||||
func (e *noRetryErr) Error() string {
|
||||
return e.err.Error()
|
||||
}
|
||||
|
||||
func wrapNoRetryErr(err error) error {
|
||||
if err != nil {
|
||||
err = &noRetryErr{err: err}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func unwrapNoRetryErr(err error) error {
|
||||
if e, ok := err.(*noRetryErr); ok {
|
||||
err = e.err
|
||||
}
|
||||
return err
|
||||
}
|
||||
181
vendor/golang.org/x/net/publicsuffix/list.go
generated
vendored
Normal file
181
vendor/golang.org/x/net/publicsuffix/list.go
generated
vendored
Normal file
@@ -0,0 +1,181 @@
|
||||
// Copyright 2012 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.
|
||||
|
||||
//go:generate go run gen.go
|
||||
|
||||
// Package publicsuffix provides a public suffix list based on data from
|
||||
// https://publicsuffix.org/
|
||||
//
|
||||
// A public suffix is one under which Internet users can directly register
|
||||
// names. It is related to, but different from, a TLD (top level domain).
|
||||
//
|
||||
// "com" is a TLD (top level domain). Top level means it has no dots.
|
||||
//
|
||||
// "com" is also a public suffix. Amazon and Google have registered different
|
||||
// siblings under that domain: "amazon.com" and "google.com".
|
||||
//
|
||||
// "au" is another TLD, again because it has no dots. But it's not "amazon.au".
|
||||
// Instead, it's "amazon.com.au".
|
||||
//
|
||||
// "com.au" isn't an actual TLD, because it's not at the top level (it has
|
||||
// dots). But it is an eTLD (effective TLD), because that's the branching point
|
||||
// for domain name registrars.
|
||||
//
|
||||
// Another name for "an eTLD" is "a public suffix". Often, what's more of
|
||||
// interest is the eTLD+1, or one more label than the public suffix. For
|
||||
// example, browsers partition read/write access to HTTP cookies according to
|
||||
// the eTLD+1. Web pages served from "amazon.com.au" can't read cookies from
|
||||
// "google.com.au", but web pages served from "maps.google.com" can share
|
||||
// cookies from "www.google.com", so you don't have to sign into Google Maps
|
||||
// separately from signing into Google Web Search. Note that all four of those
|
||||
// domains have 3 labels and 2 dots. The first two domains are each an eTLD+1,
|
||||
// the last two are not (but share the same eTLD+1: "google.com").
|
||||
//
|
||||
// All of these domains have the same eTLD+1:
|
||||
// - "www.books.amazon.co.uk"
|
||||
// - "books.amazon.co.uk"
|
||||
// - "amazon.co.uk"
|
||||
// Specifically, the eTLD+1 is "amazon.co.uk", because the eTLD is "co.uk".
|
||||
//
|
||||
// There is no closed form algorithm to calculate the eTLD of a domain.
|
||||
// Instead, the calculation is data driven. This package provides a
|
||||
// pre-compiled snapshot of Mozilla's PSL (Public Suffix List) data at
|
||||
// https://publicsuffix.org/
|
||||
package publicsuffix // import "golang.org/x/net/publicsuffix"
|
||||
|
||||
// TODO: specify case sensitivity and leading/trailing dot behavior for
|
||||
// func PublicSuffix and func EffectiveTLDPlusOne.
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http/cookiejar"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// List implements the cookiejar.PublicSuffixList interface by calling the
|
||||
// PublicSuffix function.
|
||||
var List cookiejar.PublicSuffixList = list{}
|
||||
|
||||
type list struct{}
|
||||
|
||||
func (list) PublicSuffix(domain string) string {
|
||||
ps, _ := PublicSuffix(domain)
|
||||
return ps
|
||||
}
|
||||
|
||||
func (list) String() string {
|
||||
return version
|
||||
}
|
||||
|
||||
// PublicSuffix returns the public suffix of the domain using a copy of the
|
||||
// publicsuffix.org database compiled into the library.
|
||||
//
|
||||
// icann is whether the public suffix is managed by the Internet Corporation
|
||||
// for Assigned Names and Numbers. If not, the public suffix is either a
|
||||
// privately managed domain (and in practice, not a top level domain) or an
|
||||
// unmanaged top level domain (and not explicitly mentioned in the
|
||||
// publicsuffix.org list). For example, "foo.org" and "foo.co.uk" are ICANN
|
||||
// domains, "foo.dyndns.org" and "foo.blogspot.co.uk" are private domains and
|
||||
// "cromulent" is an unmanaged top level domain.
|
||||
//
|
||||
// Use cases for distinguishing ICANN domains like "foo.com" from private
|
||||
// domains like "foo.appspot.com" can be found at
|
||||
// https://wiki.mozilla.org/Public_Suffix_List/Use_Cases
|
||||
func PublicSuffix(domain string) (publicSuffix string, icann bool) {
|
||||
lo, hi := uint32(0), uint32(numTLD)
|
||||
s, suffix, icannNode, wildcard := domain, len(domain), false, false
|
||||
loop:
|
||||
for {
|
||||
dot := strings.LastIndex(s, ".")
|
||||
if wildcard {
|
||||
icann = icannNode
|
||||
suffix = 1 + dot
|
||||
}
|
||||
if lo == hi {
|
||||
break
|
||||
}
|
||||
f := find(s[1+dot:], lo, hi)
|
||||
if f == notFound {
|
||||
break
|
||||
}
|
||||
|
||||
u := nodes[f] >> (nodesBitsTextOffset + nodesBitsTextLength)
|
||||
icannNode = u&(1<<nodesBitsICANN-1) != 0
|
||||
u >>= nodesBitsICANN
|
||||
u = children[u&(1<<nodesBitsChildren-1)]
|
||||
lo = u & (1<<childrenBitsLo - 1)
|
||||
u >>= childrenBitsLo
|
||||
hi = u & (1<<childrenBitsHi - 1)
|
||||
u >>= childrenBitsHi
|
||||
switch u & (1<<childrenBitsNodeType - 1) {
|
||||
case nodeTypeNormal:
|
||||
suffix = 1 + dot
|
||||
case nodeTypeException:
|
||||
suffix = 1 + len(s)
|
||||
break loop
|
||||
}
|
||||
u >>= childrenBitsNodeType
|
||||
wildcard = u&(1<<childrenBitsWildcard-1) != 0
|
||||
if !wildcard {
|
||||
icann = icannNode
|
||||
}
|
||||
|
||||
if dot == -1 {
|
||||
break
|
||||
}
|
||||
s = s[:dot]
|
||||
}
|
||||
if suffix == len(domain) {
|
||||
// If no rules match, the prevailing rule is "*".
|
||||
return domain[1+strings.LastIndex(domain, "."):], icann
|
||||
}
|
||||
return domain[suffix:], icann
|
||||
}
|
||||
|
||||
const notFound uint32 = 1<<32 - 1
|
||||
|
||||
// find returns the index of the node in the range [lo, hi) whose label equals
|
||||
// label, or notFound if there is no such node. The range is assumed to be in
|
||||
// strictly increasing node label order.
|
||||
func find(label string, lo, hi uint32) uint32 {
|
||||
for lo < hi {
|
||||
mid := lo + (hi-lo)/2
|
||||
s := nodeLabel(mid)
|
||||
if s < label {
|
||||
lo = mid + 1
|
||||
} else if s == label {
|
||||
return mid
|
||||
} else {
|
||||
hi = mid
|
||||
}
|
||||
}
|
||||
return notFound
|
||||
}
|
||||
|
||||
// nodeLabel returns the label for the i'th node.
|
||||
func nodeLabel(i uint32) string {
|
||||
x := nodes[i]
|
||||
length := x & (1<<nodesBitsTextLength - 1)
|
||||
x >>= nodesBitsTextLength
|
||||
offset := x & (1<<nodesBitsTextOffset - 1)
|
||||
return text[offset : offset+length]
|
||||
}
|
||||
|
||||
// EffectiveTLDPlusOne returns the effective top level domain plus one more
|
||||
// label. For example, the eTLD+1 for "foo.bar.golang.org" is "golang.org".
|
||||
func EffectiveTLDPlusOne(domain string) (string, error) {
|
||||
if strings.HasPrefix(domain, ".") || strings.HasSuffix(domain, ".") || strings.Contains(domain, "..") {
|
||||
return "", fmt.Errorf("publicsuffix: empty label in domain %q", domain)
|
||||
}
|
||||
|
||||
suffix, _ := PublicSuffix(domain)
|
||||
if len(domain) <= len(suffix) {
|
||||
return "", fmt.Errorf("publicsuffix: cannot derive eTLD+1 for domain %q", domain)
|
||||
}
|
||||
i := len(domain) - len(suffix) - 1
|
||||
if domain[i] != '.' {
|
||||
return "", fmt.Errorf("publicsuffix: invalid public suffix %q for domain %q", suffix, domain)
|
||||
}
|
||||
return domain[1+strings.LastIndex(domain[:i], "."):], nil
|
||||
}
|
||||
9962
vendor/golang.org/x/net/publicsuffix/table.go
generated
vendored
Normal file
9962
vendor/golang.org/x/net/publicsuffix/table.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
106
vendor/helm.sh/helm/v3/pkg/release/hook.go
vendored
Normal file
106
vendor/helm.sh/helm/v3/pkg/release/hook.go
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
Copyright The Helm 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 release
|
||||
|
||||
import (
|
||||
"helm.sh/helm/v3/pkg/time"
|
||||
)
|
||||
|
||||
// HookEvent specifies the hook event
|
||||
type HookEvent string
|
||||
|
||||
// Hook event types
|
||||
const (
|
||||
HookPreInstall HookEvent = "pre-install"
|
||||
HookPostInstall HookEvent = "post-install"
|
||||
HookPreDelete HookEvent = "pre-delete"
|
||||
HookPostDelete HookEvent = "post-delete"
|
||||
HookPreUpgrade HookEvent = "pre-upgrade"
|
||||
HookPostUpgrade HookEvent = "post-upgrade"
|
||||
HookPreRollback HookEvent = "pre-rollback"
|
||||
HookPostRollback HookEvent = "post-rollback"
|
||||
HookTest HookEvent = "test"
|
||||
)
|
||||
|
||||
func (x HookEvent) String() string { return string(x) }
|
||||
|
||||
// HookDeletePolicy specifies the hook delete policy
|
||||
type HookDeletePolicy string
|
||||
|
||||
// Hook delete policy types
|
||||
const (
|
||||
HookSucceeded HookDeletePolicy = "hook-succeeded"
|
||||
HookFailed HookDeletePolicy = "hook-failed"
|
||||
HookBeforeHookCreation HookDeletePolicy = "before-hook-creation"
|
||||
)
|
||||
|
||||
func (x HookDeletePolicy) String() string { return string(x) }
|
||||
|
||||
// HookAnnotation is the label name for a hook
|
||||
const HookAnnotation = "helm.sh/hook"
|
||||
|
||||
// HookWeightAnnotation is the label name for a hook weight
|
||||
const HookWeightAnnotation = "helm.sh/hook-weight"
|
||||
|
||||
// HookDeleteAnnotation is the label name for the delete policy for a hook
|
||||
const HookDeleteAnnotation = "helm.sh/hook-delete-policy"
|
||||
|
||||
// Hook defines a hook object.
|
||||
type Hook struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
// Kind is the Kubernetes kind.
|
||||
Kind string `json:"kind,omitempty"`
|
||||
// Path is the chart-relative path to the template.
|
||||
Path string `json:"path,omitempty"`
|
||||
// Manifest is the manifest contents.
|
||||
Manifest string `json:"manifest,omitempty"`
|
||||
// Events are the events that this hook fires on.
|
||||
Events []HookEvent `json:"events,omitempty"`
|
||||
// LastRun indicates the date/time this was last run.
|
||||
LastRun HookExecution `json:"last_run,omitempty"`
|
||||
// Weight indicates the sort order for execution among similar Hook type
|
||||
Weight int `json:"weight,omitempty"`
|
||||
// DeletePolicies are the policies that indicate when to delete the hook
|
||||
DeletePolicies []HookDeletePolicy `json:"delete_policies,omitempty"`
|
||||
}
|
||||
|
||||
// A HookExecution records the result for the last execution of a hook for a given release.
|
||||
type HookExecution struct {
|
||||
// StartedAt indicates the date/time this hook was started
|
||||
StartedAt time.Time `json:"started_at,omitempty"`
|
||||
// CompletedAt indicates the date/time this hook was completed.
|
||||
CompletedAt time.Time `json:"completed_at,omitempty"`
|
||||
// Phase indicates whether the hook completed successfully
|
||||
Phase HookPhase `json:"phase"`
|
||||
}
|
||||
|
||||
// A HookPhase indicates the state of a hook execution
|
||||
type HookPhase string
|
||||
|
||||
const (
|
||||
// HookPhaseUnknown indicates that a hook is in an unknown state
|
||||
HookPhaseUnknown HookPhase = "Unknown"
|
||||
// HookPhaseRunning indicates that a hook is currently executing
|
||||
HookPhaseRunning HookPhase = "Running"
|
||||
// HookPhaseSucceeded indicates that hook execution succeeded
|
||||
HookPhaseSucceeded HookPhase = "Succeeded"
|
||||
// HookPhaseFailed indicates that hook execution failed
|
||||
HookPhaseFailed HookPhase = "Failed"
|
||||
)
|
||||
|
||||
// Strng converts a hook phase to a printable string
|
||||
func (x HookPhase) String() string { return string(x) }
|
||||
36
vendor/helm.sh/helm/v3/pkg/release/info.go
vendored
Normal file
36
vendor/helm.sh/helm/v3/pkg/release/info.go
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
Copyright The Helm 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 release
|
||||
|
||||
import (
|
||||
"helm.sh/helm/v3/pkg/time"
|
||||
)
|
||||
|
||||
// Info describes release information.
|
||||
type Info struct {
|
||||
// FirstDeployed is when the release was first deployed.
|
||||
FirstDeployed time.Time `json:"first_deployed,omitempty"`
|
||||
// LastDeployed is when the release was last deployed.
|
||||
LastDeployed time.Time `json:"last_deployed,omitempty"`
|
||||
// Deleted tracks when this object was deleted.
|
||||
Deleted time.Time `json:"deleted"`
|
||||
// Description is human-friendly "log entry" about this release.
|
||||
Description string `json:"description,omitempty"`
|
||||
// Status is the current state of the release
|
||||
Status Status `json:"status,omitempty"`
|
||||
// Contains the rendered templates/NOTES.txt if available
|
||||
Notes string `json:"notes,omitempty"`
|
||||
}
|
||||
115
vendor/helm.sh/helm/v3/pkg/release/mock.go
vendored
Normal file
115
vendor/helm.sh/helm/v3/pkg/release/mock.go
vendored
Normal file
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
Copyright The Helm 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 release
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
|
||||
"helm.sh/helm/v3/pkg/chart"
|
||||
"helm.sh/helm/v3/pkg/time"
|
||||
)
|
||||
|
||||
// MockHookTemplate is the hook template used for all mock release objects.
|
||||
var MockHookTemplate = `apiVersion: v1
|
||||
kind: Job
|
||||
metadata:
|
||||
annotations:
|
||||
"helm.sh/hook": pre-install
|
||||
`
|
||||
|
||||
// MockManifest is the manifest used for all mock release objects.
|
||||
var MockManifest = `apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: fixture
|
||||
`
|
||||
|
||||
// MockReleaseOptions allows for user-configurable options on mock release objects.
|
||||
type MockReleaseOptions struct {
|
||||
Name string
|
||||
Version int
|
||||
Chart *chart.Chart
|
||||
Status Status
|
||||
Namespace string
|
||||
}
|
||||
|
||||
// Mock creates a mock release object based on options set by MockReleaseOptions. This function should typically not be used outside of testing.
|
||||
func Mock(opts *MockReleaseOptions) *Release {
|
||||
date := time.Unix(242085845, 0).UTC()
|
||||
|
||||
name := opts.Name
|
||||
if name == "" {
|
||||
name = "testrelease-" + string(rand.Intn(100))
|
||||
}
|
||||
|
||||
version := 1
|
||||
if opts.Version != 0 {
|
||||
version = opts.Version
|
||||
}
|
||||
|
||||
namespace := opts.Namespace
|
||||
if namespace == "" {
|
||||
namespace = "default"
|
||||
}
|
||||
|
||||
ch := opts.Chart
|
||||
if opts.Chart == nil {
|
||||
ch = &chart.Chart{
|
||||
Metadata: &chart.Metadata{
|
||||
Name: "foo",
|
||||
Version: "0.1.0-beta.1",
|
||||
AppVersion: "1.0",
|
||||
},
|
||||
Templates: []*chart.File{
|
||||
{Name: "templates/foo.tpl", Data: []byte(MockManifest)},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
scode := StatusDeployed
|
||||
if len(opts.Status) > 0 {
|
||||
scode = opts.Status
|
||||
}
|
||||
|
||||
info := &Info{
|
||||
FirstDeployed: date,
|
||||
LastDeployed: date,
|
||||
Status: scode,
|
||||
Description: "Release mock",
|
||||
Notes: "Some mock release notes!",
|
||||
}
|
||||
|
||||
return &Release{
|
||||
Name: name,
|
||||
Info: info,
|
||||
Chart: ch,
|
||||
Config: map[string]interface{}{"name": "value"},
|
||||
Version: version,
|
||||
Namespace: namespace,
|
||||
Hooks: []*Hook{
|
||||
{
|
||||
Name: "pre-install-hook",
|
||||
Kind: "Job",
|
||||
Path: "pre-install-hook.yaml",
|
||||
Manifest: MockHookTemplate,
|
||||
LastRun: HookExecution{},
|
||||
Events: []HookEvent{HookPreInstall},
|
||||
},
|
||||
},
|
||||
Manifest: MockManifest,
|
||||
}
|
||||
}
|
||||
46
vendor/helm.sh/helm/v3/pkg/release/release.go
vendored
Normal file
46
vendor/helm.sh/helm/v3/pkg/release/release.go
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
Copyright The Helm 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 release
|
||||
|
||||
import "helm.sh/helm/v3/pkg/chart"
|
||||
|
||||
// Release describes a deployment of a chart, together with the chart
|
||||
// and the variables used to deploy that chart.
|
||||
type Release struct {
|
||||
// Name is the name of the release
|
||||
Name string `json:"name,omitempty"`
|
||||
// Info provides information about a release
|
||||
Info *Info `json:"info,omitempty"`
|
||||
// Chart is the chart that was released.
|
||||
Chart *chart.Chart `json:"chart,omitempty"`
|
||||
// Config is the set of extra Values added to the chart.
|
||||
// These values override the default values inside of the chart.
|
||||
Config map[string]interface{} `json:"config,omitempty"`
|
||||
// Manifest is the string representation of the rendered template.
|
||||
Manifest string `json:"manifest,omitempty"`
|
||||
// Hooks are all of the hooks declared for this release.
|
||||
Hooks []*Hook `json:"hooks,omitempty"`
|
||||
// Version is an int which represents the revision of the release.
|
||||
Version int `json:"version,omitempty"`
|
||||
// Namespace is the kubernetes namespace of the release.
|
||||
Namespace string `json:"namespace,omitempty"`
|
||||
}
|
||||
|
||||
// SetStatus is a helper for setting the status on a release.
|
||||
func (r *Release) SetStatus(status Status, msg string) {
|
||||
r.Info.Status = status
|
||||
r.Info.Description = msg
|
||||
}
|
||||
24
vendor/helm.sh/helm/v3/pkg/release/responses.go
vendored
Normal file
24
vendor/helm.sh/helm/v3/pkg/release/responses.go
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
Copyright The Helm 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 release
|
||||
|
||||
// UninstallReleaseResponse represents a successful response to an uninstall request.
|
||||
type UninstallReleaseResponse struct {
|
||||
// Release is the release that was marked deleted.
|
||||
Release *Release `json:"release,omitempty"`
|
||||
// Info is an uninstall message
|
||||
Info string `json:"info,omitempty"`
|
||||
}
|
||||
44
vendor/helm.sh/helm/v3/pkg/release/status.go
vendored
Normal file
44
vendor/helm.sh/helm/v3/pkg/release/status.go
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
Copyright The Helm 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 release
|
||||
|
||||
// Status is the status of a release
|
||||
type Status string
|
||||
|
||||
// Describe the status of a release
|
||||
// NOTE: Make sure to update cmd/helm/status.go when adding or modifying any of these statuses.
|
||||
const (
|
||||
// StatusUnknown indicates that a release is in an uncertain state.
|
||||
StatusUnknown Status = "unknown"
|
||||
// StatusDeployed indicates that the release has been pushed to Kubernetes.
|
||||
StatusDeployed Status = "deployed"
|
||||
// StatusUninstalled indicates that a release has been uninstalled from Kubernetes.
|
||||
StatusUninstalled Status = "uninstalled"
|
||||
// StatusSuperseded indicates that this release object is outdated and a newer one exists.
|
||||
StatusSuperseded Status = "superseded"
|
||||
// StatusFailed indicates that the release was not successfully deployed.
|
||||
StatusFailed Status = "failed"
|
||||
// StatusUninstalling indicates that a uninstall operation is underway.
|
||||
StatusUninstalling Status = "uninstalling"
|
||||
// StatusPendingInstall indicates that an install operation is underway.
|
||||
StatusPendingInstall Status = "pending-install"
|
||||
// StatusPendingUpgrade indicates that an upgrade operation is underway.
|
||||
StatusPendingUpgrade Status = "pending-upgrade"
|
||||
// StatusPendingRollback indicates that an rollback operation is underway.
|
||||
StatusPendingRollback Status = "pending-rollback"
|
||||
)
|
||||
|
||||
func (x Status) String() string { return string(x) }
|
||||
91
vendor/helm.sh/helm/v3/pkg/time/time.go
vendored
Normal file
91
vendor/helm.sh/helm/v3/pkg/time/time.go
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
Copyright The Helm 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 time contains a wrapper for time.Time in the standard library and
|
||||
// associated methods. This package mainly exists to workaround an issue in Go
|
||||
// where the serializer doesn't omit an empty value for time:
|
||||
// https://github.com/golang/go/issues/11939. As such, this can be removed if a
|
||||
// proposal is ever accepted for Go
|
||||
package time
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"time"
|
||||
)
|
||||
|
||||
// emptyString contains an empty JSON string value to be used as output
|
||||
var emptyString = `""`
|
||||
|
||||
// Time is a convenience wrapper around stdlib time, but with different
|
||||
// marshalling and unmarshaling for zero values
|
||||
type Time struct {
|
||||
time.Time
|
||||
}
|
||||
|
||||
// Now returns the current time. It is a convenience wrapper around time.Now()
|
||||
func Now() Time {
|
||||
return Time{time.Now()}
|
||||
}
|
||||
|
||||
func (t Time) MarshalJSON() ([]byte, error) {
|
||||
if t.Time.IsZero() {
|
||||
return []byte(emptyString), nil
|
||||
}
|
||||
|
||||
return t.Time.MarshalJSON()
|
||||
}
|
||||
|
||||
func (t *Time) UnmarshalJSON(b []byte) error {
|
||||
if bytes.Equal(b, []byte("null")) {
|
||||
return nil
|
||||
}
|
||||
// If it is empty, we don't have to set anything since time.Time is not a
|
||||
// pointer and will be set to the zero value
|
||||
if bytes.Equal([]byte(emptyString), b) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return t.Time.UnmarshalJSON(b)
|
||||
}
|
||||
|
||||
func Parse(layout, value string) (Time, error) {
|
||||
t, err := time.Parse(layout, value)
|
||||
return Time{Time: t}, err
|
||||
}
|
||||
func ParseInLocation(layout, value string, loc *time.Location) (Time, error) {
|
||||
t, err := time.ParseInLocation(layout, value, loc)
|
||||
return Time{Time: t}, err
|
||||
}
|
||||
|
||||
func Date(year int, month time.Month, day, hour, min, sec, nsec int, loc *time.Location) Time {
|
||||
return Time{Time: time.Date(year, month, day, hour, min, sec, nsec, loc)}
|
||||
}
|
||||
|
||||
func Unix(sec int64, nsec int64) Time { return Time{Time: time.Unix(sec, nsec)} }
|
||||
|
||||
func (t Time) Add(d time.Duration) Time { return Time{Time: t.Time.Add(d)} }
|
||||
func (t Time) AddDate(years int, months int, days int) Time {
|
||||
return Time{Time: t.Time.AddDate(years, months, days)}
|
||||
}
|
||||
func (t Time) After(u Time) bool { return t.Time.After(u.Time) }
|
||||
func (t Time) Before(u Time) bool { return t.Time.Before(u.Time) }
|
||||
func (t Time) Equal(u Time) bool { return t.Time.Equal(u.Time) }
|
||||
func (t Time) In(loc *time.Location) Time { return Time{Time: t.Time.In(loc)} }
|
||||
func (t Time) Local() Time { return Time{Time: t.Time.Local()} }
|
||||
func (t Time) Round(d time.Duration) Time { return Time{Time: t.Time.Round(d)} }
|
||||
func (t Time) Sub(u Time) time.Duration { return t.Time.Sub(u.Time) }
|
||||
func (t Time) Truncate(d time.Duration) Time { return Time{Time: t.Time.Truncate(d)} }
|
||||
func (t Time) UTC() Time { return Time{Time: t.Time.UTC()} }
|
||||
1
vendor/kubesphere.io/client-go
generated
vendored
Symbolic link
1
vendor/kubesphere.io/client-go
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../../staging/src/kubesphere.io/client-go
|
||||
201
vendor/kubesphere.io/client-go/LICENSE
generated
vendored
201
vendor/kubesphere.io/client-go/LICENSE
generated
vendored
@@ -1,201 +0,0 @@
|
||||
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.
|
||||
158
vendor/kubesphere.io/client-go/client/clientCache.go
generated
vendored
158
vendor/kubesphere.io/client-go/client/clientCache.go
generated
vendored
@@ -1,158 +0,0 @@
|
||||
/*
|
||||
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 client
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
"k8s.io/client-go/rest"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
|
||||
)
|
||||
|
||||
type ClientCache interface {
|
||||
GetObjMeta(obj runtime.Object) (*ObjMeta, error)
|
||||
GetResource(obj runtime.Object) (*ResourceMeta, error)
|
||||
}
|
||||
|
||||
func NewClientCache(config *rest.Config, options Options) ClientCache {
|
||||
|
||||
cc := &clientCache{
|
||||
config: config,
|
||||
scheme: options.Scheme,
|
||||
mapper: options.Mapper,
|
||||
codecs: serializer.NewCodecFactory(options.Scheme),
|
||||
resourceByType: make(map[schema.GroupVersionKind]*ResourceMeta),
|
||||
}
|
||||
|
||||
return cc
|
||||
}
|
||||
|
||||
// clientCache creates and caches rest clients and metadata for Kubernetes types
|
||||
type clientCache struct {
|
||||
// config is the rest.Config to talk to an apiserver
|
||||
config *rest.Config
|
||||
|
||||
// scheme maps go structs to GroupVersionKinds
|
||||
scheme *runtime.Scheme
|
||||
|
||||
// mapper maps GroupVersionKinds to Resources
|
||||
mapper meta.RESTMapper
|
||||
|
||||
// codecs are used to create a REST client for a gvk
|
||||
codecs serializer.CodecFactory
|
||||
|
||||
// resourceByType caches type metadata
|
||||
resourceByType map[schema.GroupVersionKind]*ResourceMeta
|
||||
mu sync.RWMutex
|
||||
}
|
||||
|
||||
// newResource maps obj to a Kubernetes Resource and constructs a client for that Resource.
|
||||
// If the object is a list, the resource represents the item's type instead.
|
||||
func (c *clientCache) newResource(gvk schema.GroupVersionKind, isList bool) (*ResourceMeta, error) {
|
||||
if strings.HasSuffix(gvk.Kind, "List") && isList {
|
||||
// if this was a list, treat it as a request for the item's resource
|
||||
gvk.Kind = gvk.Kind[:len(gvk.Kind)-4]
|
||||
}
|
||||
|
||||
client, err := apiutil.RESTClientForGVK(gvk, c.config, c.codecs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mapping, err := c.mapper.RESTMapping(gvk.GroupKind(), gvk.Version)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ResourceMeta{Interface: client, mapping: mapping, gvk: gvk}, nil
|
||||
}
|
||||
|
||||
// GetResource returns the resource meta information for the given type of object.
|
||||
// If the object is a list, the resource represents the item's type instead.
|
||||
func (c *clientCache) GetResource(obj runtime.Object) (*ResourceMeta, error) {
|
||||
gvk, err := apiutil.GVKForObject(obj, c.scheme)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// It's better to do creation work twice than to not let multiple
|
||||
// people make requests at once
|
||||
c.mu.RLock()
|
||||
r, known := c.resourceByType[gvk]
|
||||
c.mu.RUnlock()
|
||||
|
||||
if known {
|
||||
return r, nil
|
||||
}
|
||||
|
||||
// Initialize a new Client
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
r, err = c.newResource(gvk, meta.IsListType(obj))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.resourceByType[gvk] = r
|
||||
return r, err
|
||||
}
|
||||
|
||||
// getObjMeta returns ObjMeta containing both type and object metadata and state
|
||||
func (c *clientCache) GetObjMeta(obj runtime.Object) (*ObjMeta, error) {
|
||||
r, err := c.GetResource(obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m, err := meta.Accessor(obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ObjMeta{ResourceMeta: r, Object: m}, err
|
||||
}
|
||||
|
||||
// ResourceMeta caches state for a Kubernetes type.
|
||||
type ResourceMeta struct {
|
||||
// client is the rest client used to talk to the apiserver
|
||||
rest.Interface
|
||||
// gvk is the GroupVersionKind of the ResourceMeta
|
||||
gvk schema.GroupVersionKind
|
||||
// mapping is the rest mapping
|
||||
mapping *meta.RESTMapping
|
||||
}
|
||||
|
||||
// IsNamespaced returns true if the type is namespaced
|
||||
func (r *ResourceMeta) IsNamespaced() bool {
|
||||
return r.mapping.Scope.Name() != meta.RESTScopeNameRoot
|
||||
|
||||
}
|
||||
|
||||
// resource returns the resource name of the type
|
||||
func (r *ResourceMeta) Resource() string {
|
||||
return r.mapping.Resource.Resource
|
||||
}
|
||||
|
||||
// ObjMeta stores type and object information about a Kubernetes type
|
||||
type ObjMeta struct {
|
||||
// ResourceMeta contains type information for the object
|
||||
*ResourceMeta
|
||||
|
||||
// Object contains meta data for the object instance
|
||||
metav1.Object
|
||||
}
|
||||
40
vendor/kubesphere.io/client-go/client/codec.go
generated
vendored
40
vendor/kubesphere.io/client-go/client/codec.go
generated
vendored
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
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 client
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/url"
|
||||
|
||||
"k8s.io/apimachinery/pkg/conversion/queryparams"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
var _ runtime.ParameterCodec = NoConversionParamCodec{}
|
||||
|
||||
// NoConversionParamCodec is a no-conversion codec for serializing parameters into URL query strings.
|
||||
// it's useful in scenarios with the unstructured client and arbitrary resouces.
|
||||
type NoConversionParamCodec struct{}
|
||||
|
||||
func (NoConversionParamCodec) EncodeParameters(obj runtime.Object, to schema.GroupVersion) (url.Values, error) {
|
||||
return queryparams.Convert(obj)
|
||||
}
|
||||
|
||||
func (NoConversionParamCodec) DecodeParameters(parameters url.Values, from schema.GroupVersion, into runtime.Object) error {
|
||||
return errors.New("DecodeParameters not implemented on noConversionParamCodec")
|
||||
}
|
||||
199
vendor/kubesphere.io/client-go/client/generic/genericclient.go
generated
vendored
199
vendor/kubesphere.io/client-go/client/generic/genericclient.go
generated
vendored
@@ -1,199 +0,0 @@
|
||||
/*
|
||||
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 generic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"k8s.io/client-go/rest"
|
||||
"kubesphere.io/client-go/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
|
||||
)
|
||||
|
||||
// New returns a new Client using the provided config and Options.
|
||||
// The returned client reads *and* writes directly from the server
|
||||
// (it doesn't use object caches). It understands how to work with
|
||||
// normal types (both custom resources and aggregated/built-in resources),
|
||||
// as well as unstructured types.
|
||||
//
|
||||
// In the case of normal types, the scheme will be used to look up the
|
||||
// corresponding group, version, and kind for the given type. In the
|
||||
// case of unstructured types, the group, version, and kind will be extracted
|
||||
// from the corresponding fields on the object.
|
||||
func New(config *rest.Config, options client.Options) (client.Client, error) {
|
||||
if config == nil {
|
||||
return nil, fmt.Errorf("must provide non-nil rest.Config to client.New")
|
||||
}
|
||||
|
||||
// Init a scheme if none provided
|
||||
if options.Scheme == nil {
|
||||
options.Scheme = scheme.Scheme
|
||||
}
|
||||
|
||||
// Init a Mapper if none provided
|
||||
if options.Mapper == nil {
|
||||
var err error
|
||||
options.Mapper, err = apiutil.NewDynamicRESTMapper(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
clientcache := client.NewClientCache(config, options)
|
||||
|
||||
c := &genericClient{
|
||||
typedClient: typedClient{
|
||||
cache: clientcache,
|
||||
paramCodec: runtime.NewParameterCodec(options.Scheme),
|
||||
},
|
||||
unstructuredClient: unstructuredClient{
|
||||
cache: clientcache,
|
||||
paramCodec: client.NoConversionParamCodec{},
|
||||
},
|
||||
}
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func NewForConfigOrDie(config *rest.Config, options client.Options) client.Client {
|
||||
client, err := New(config, options)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
var _ client.Client = &genericClient{}
|
||||
|
||||
// genericClient is a client.Client that reads and writes directly from/to an KubeSphere API server. It lazily initializes
|
||||
// new clients at the time they are used, and caches the client.
|
||||
type genericClient struct {
|
||||
typedClient typedClient
|
||||
unstructuredClient unstructuredClient
|
||||
}
|
||||
|
||||
// resetGroupVersionKind is a helper function to restore and preserve GroupVersionKind on an object.
|
||||
func (c *genericClient) resetGroupVersionKind(obj runtime.Object, gvk schema.GroupVersionKind) {
|
||||
if gvk != schema.EmptyObjectKind.GroupVersionKind() {
|
||||
if v, ok := obj.(schema.ObjectKind); ok {
|
||||
v.SetGroupVersionKind(gvk)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create implements client.Client
|
||||
func (c *genericClient) Create(ctx context.Context, obj runtime.Object, opts ...client.CreateOption) error {
|
||||
_, ok := obj.(*unstructured.Unstructured)
|
||||
if ok {
|
||||
return c.unstructuredClient.Create(ctx, obj, opts...)
|
||||
}
|
||||
return c.typedClient.Create(ctx, obj, opts...)
|
||||
}
|
||||
|
||||
// Update implements client.Client
|
||||
func (c *genericClient) Update(ctx context.Context, obj runtime.Object, opts ...client.UpdateOption) error {
|
||||
defer c.resetGroupVersionKind(obj, obj.GetObjectKind().GroupVersionKind())
|
||||
_, ok := obj.(*unstructured.Unstructured)
|
||||
if ok {
|
||||
return c.unstructuredClient.Update(ctx, obj, opts...)
|
||||
}
|
||||
return c.typedClient.Update(ctx, obj, opts...)
|
||||
}
|
||||
|
||||
// Delete implements client.Client
|
||||
func (c *genericClient) Delete(ctx context.Context, obj runtime.Object, opts ...client.DeleteOption) error {
|
||||
_, ok := obj.(*unstructured.Unstructured)
|
||||
if ok {
|
||||
return c.unstructuredClient.Delete(ctx, obj, opts...)
|
||||
}
|
||||
return c.typedClient.Delete(ctx, obj, opts...)
|
||||
}
|
||||
|
||||
// DeleteAllOf implements client.Client
|
||||
func (c *genericClient) DeleteAllOf(ctx context.Context, obj runtime.Object, opts ...client.DeleteAllOfOption) error {
|
||||
_, ok := obj.(*unstructured.Unstructured)
|
||||
if ok {
|
||||
return c.unstructuredClient.DeleteAllOf(ctx, obj, opts...)
|
||||
}
|
||||
return c.typedClient.DeleteAllOf(ctx, obj, opts...)
|
||||
}
|
||||
|
||||
// Patch implements client.Client
|
||||
func (c *genericClient) Patch(ctx context.Context, obj runtime.Object, patch client.Patch, opts ...client.PatchOption) error {
|
||||
defer c.resetGroupVersionKind(obj, obj.GetObjectKind().GroupVersionKind())
|
||||
_, ok := obj.(*unstructured.Unstructured)
|
||||
if ok {
|
||||
return c.unstructuredClient.Patch(ctx, obj, patch, opts...)
|
||||
}
|
||||
return c.typedClient.Patch(ctx, obj, patch, opts...)
|
||||
}
|
||||
|
||||
// Get implements client.Client
|
||||
func (c *genericClient) Get(ctx context.Context, key client.ObjectKey, obj runtime.Object, opts ...client.GetOption) error {
|
||||
_, ok := obj.(*unstructured.Unstructured)
|
||||
if ok {
|
||||
return c.unstructuredClient.Get(ctx, key, obj, opts...)
|
||||
}
|
||||
return c.typedClient.Get(ctx, key, obj, opts...)
|
||||
}
|
||||
|
||||
// List implements client.Client
|
||||
func (c *genericClient) List(ctx context.Context, obj runtime.Object, opts ...client.ListOption) error {
|
||||
_, ok := obj.(*unstructured.UnstructuredList)
|
||||
if ok {
|
||||
return c.unstructuredClient.List(ctx, obj, opts...)
|
||||
}
|
||||
return c.typedClient.List(ctx, obj, opts...)
|
||||
}
|
||||
|
||||
// Status implements client.StatusClient
|
||||
func (c *genericClient) Status() client.StatusWriter {
|
||||
return &statusWriter{client: c}
|
||||
}
|
||||
|
||||
// statusWriter is client.StatusWriter that writes status subresource
|
||||
type statusWriter struct {
|
||||
client *genericClient
|
||||
}
|
||||
|
||||
// ensure statusWriter implements client.StatusWriter
|
||||
var _ client.StatusWriter = &statusWriter{}
|
||||
|
||||
// Update implements client.StatusWriter
|
||||
func (sw *statusWriter) Update(ctx context.Context, obj runtime.Object, opts ...client.UpdateOption) error {
|
||||
defer sw.client.resetGroupVersionKind(obj, obj.GetObjectKind().GroupVersionKind())
|
||||
_, ok := obj.(*unstructured.Unstructured)
|
||||
if ok {
|
||||
return sw.client.unstructuredClient.UpdateStatus(ctx, obj, opts...)
|
||||
}
|
||||
return sw.client.typedClient.UpdateStatus(ctx, obj, opts...)
|
||||
}
|
||||
|
||||
// Patch implements client.Client
|
||||
func (sw *statusWriter) Patch(ctx context.Context, obj runtime.Object, patch client.Patch, opts ...client.PatchOption) error {
|
||||
defer sw.client.resetGroupVersionKind(obj, obj.GetObjectKind().GroupVersionKind())
|
||||
_, ok := obj.(*unstructured.Unstructured)
|
||||
if ok {
|
||||
return sw.client.unstructuredClient.PatchStatus(ctx, obj, patch, opts...)
|
||||
}
|
||||
return sw.client.typedClient.PatchStatus(ctx, obj, patch, opts...)
|
||||
}
|
||||
281
vendor/kubesphere.io/client-go/client/generic/typedClient.go
generated
vendored
281
vendor/kubesphere.io/client-go/client/generic/typedClient.go
generated
vendored
@@ -1,281 +0,0 @@
|
||||
/*
|
||||
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 generic
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"kubesphere.io/client-go/client"
|
||||
)
|
||||
|
||||
// client is a client.Client that reads and writes directly from/to an API server. It lazily initializes
|
||||
// new clients at the time they are used, and caches the client.
|
||||
type typedClient struct {
|
||||
cache client.ClientCache
|
||||
paramCodec runtime.ParameterCodec
|
||||
}
|
||||
|
||||
// Create implements client.Client
|
||||
func (c *typedClient) Create(ctx context.Context, obj runtime.Object, opts ...client.CreateOption) error {
|
||||
o, err := c.cache.GetObjMeta(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
createOpts := &client.CreateOptions{}
|
||||
createOpts.ApplyOptions(opts)
|
||||
|
||||
req := o.Post().
|
||||
Body(obj).
|
||||
VersionedParams(createOpts.AsCreateOptions(), c.paramCodec)
|
||||
|
||||
// Overwrites GVK based URL when has URLOption
|
||||
if createOpts.URLOption != nil {
|
||||
absPath := createOpts.URLOption.URL()
|
||||
if createOpts.Workspace != nil {
|
||||
absPath = append(absPath, "workspaces", createOpts.Workspace.Name)
|
||||
}
|
||||
req = req.AbsPath(absPath...)
|
||||
}
|
||||
if createOpts.URLOption == nil || createOpts.URLOption.AbsPath == "" {
|
||||
req = req.NamespaceIfScoped(o.GetNamespace(), o.IsNamespaced()).
|
||||
Resource(o.Resource())
|
||||
}
|
||||
|
||||
return req.
|
||||
Do(ctx).
|
||||
Into(obj)
|
||||
}
|
||||
|
||||
// Update implements client.Client
|
||||
func (c *typedClient) Update(ctx context.Context, obj runtime.Object, opts ...client.UpdateOption) error {
|
||||
o, err := c.cache.GetObjMeta(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
updateOpts := &client.UpdateOptions{}
|
||||
updateOpts.ApplyOptions(opts)
|
||||
|
||||
req := o.Put()
|
||||
|
||||
// Overwrites GVK based URL when has URLOption
|
||||
if updateOpts.URLOption != nil {
|
||||
absPath := updateOpts.URLOption.URL()
|
||||
if updateOpts.Workspace != nil {
|
||||
absPath = append(absPath, "workspaces", updateOpts.Workspace.Name)
|
||||
}
|
||||
req = req.AbsPath(absPath...)
|
||||
}
|
||||
if updateOpts.URLOption == nil || updateOpts.URLOption.AbsPath == "" {
|
||||
req = req.NamespaceIfScoped(o.GetNamespace(), o.IsNamespaced()).
|
||||
Resource(o.Resource()).
|
||||
Name(o.GetName())
|
||||
}
|
||||
|
||||
return req.Body(obj).
|
||||
VersionedParams(updateOpts.AsUpdateOptions(), c.paramCodec).
|
||||
Do(ctx).
|
||||
Into(obj)
|
||||
}
|
||||
|
||||
// Delete implements client.Client
|
||||
func (c *typedClient) Delete(ctx context.Context, obj runtime.Object, opts ...client.DeleteOption) error {
|
||||
o, err := c.cache.GetObjMeta(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
deleteOpts := client.DeleteOptions{}
|
||||
deleteOpts.ApplyOptions(opts)
|
||||
|
||||
req := o.Delete()
|
||||
|
||||
// Overwrites GVK based URL when has URLOption
|
||||
if deleteOpts.URLOption != nil {
|
||||
absPath := deleteOpts.URLOption.URL()
|
||||
if deleteOpts.Workspace != nil {
|
||||
absPath = append(absPath, "workspaces", deleteOpts.Workspace.Name)
|
||||
}
|
||||
req = req.AbsPath(absPath...)
|
||||
}
|
||||
if deleteOpts.URLOption == nil || deleteOpts.URLOption.AbsPath == "" {
|
||||
req = req.NamespaceIfScoped(o.GetNamespace(), o.IsNamespaced()).
|
||||
Resource(o.Resource()).
|
||||
Name(o.GetName())
|
||||
}
|
||||
|
||||
return req.Body(deleteOpts.AsDeleteOptions()).
|
||||
Do(ctx).
|
||||
Error()
|
||||
}
|
||||
|
||||
// Patch implements client.Client
|
||||
func (c *typedClient) Patch(ctx context.Context, obj runtime.Object, patch client.Patch, opts ...client.PatchOption) error {
|
||||
o, err := c.cache.GetObjMeta(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
data, err := patch.Data(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
patchOpts := &client.PatchOptions{}
|
||||
|
||||
req := o.Patch(patch.Type())
|
||||
// Overwrites GVK based URL when has URLOption
|
||||
if patchOpts.URLOption != nil {
|
||||
absPath := patchOpts.URLOption.URL()
|
||||
if patchOpts.Workspace != nil {
|
||||
absPath = append(absPath, "workspaces", patchOpts.Workspace.Name)
|
||||
}
|
||||
req = req.AbsPath(absPath...)
|
||||
}
|
||||
if patchOpts.URLOption == nil || patchOpts.URLOption.AbsPath == "" {
|
||||
req.NamespaceIfScoped(o.GetNamespace(), o.IsNamespaced()).
|
||||
Resource(o.Resource()).
|
||||
Name(o.GetName())
|
||||
}
|
||||
|
||||
return req.VersionedParams(patchOpts.ApplyOptions(opts).AsPatchOptions(), c.paramCodec).
|
||||
Body(data).
|
||||
Do(ctx).
|
||||
Into(obj)
|
||||
}
|
||||
|
||||
// Get implements client.Client
|
||||
func (c *typedClient) Get(ctx context.Context, key client.ObjectKey, obj runtime.Object, opts ...client.GetOption) error {
|
||||
r, err := c.cache.GetResource(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
getOpts := client.GetOptions{}
|
||||
getOpts.ApplyOptions(opts)
|
||||
|
||||
req := r.Get()
|
||||
// Overwrites GVK based URL when has URLOption
|
||||
if getOpts.URLOption != nil {
|
||||
absPath := getOpts.URLOption.URL()
|
||||
if getOpts.Workspace != nil {
|
||||
absPath = append(absPath, "workspaces", getOpts.Workspace.Name)
|
||||
}
|
||||
}
|
||||
if getOpts.URLOption == nil || getOpts.URLOption.AbsPath == "" {
|
||||
req = req.NamespaceIfScoped(key.Namespace, r.IsNamespaced()).
|
||||
Resource(r.Resource()).
|
||||
Name(key.Name)
|
||||
}
|
||||
|
||||
return req.
|
||||
Do(ctx).
|
||||
Into(obj)
|
||||
}
|
||||
|
||||
// List implements client.Client
|
||||
func (c *typedClient) List(ctx context.Context, obj runtime.Object, opts ...client.ListOption) error {
|
||||
r, err := c.cache.GetResource(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
listOpts := client.ListOptions{}
|
||||
listOpts.ApplyOptions(opts)
|
||||
|
||||
req := r.Get()
|
||||
|
||||
// Overwrites GVK based URL when has URLOption
|
||||
if listOpts.URLOption != nil {
|
||||
absPath := listOpts.URLOption.URL()
|
||||
if listOpts.Workspace != nil {
|
||||
absPath = append(absPath, "workspaces", listOpts.Workspace.Name)
|
||||
}
|
||||
}
|
||||
if listOpts.URLOption == nil || listOpts.URLOption.AbsPath == "" {
|
||||
req = req.NamespaceIfScoped(listOpts.Namespace, r.IsNamespaced()).
|
||||
Resource(r.Resource()).
|
||||
VersionedParams(listOpts.AsListOptions(), c.paramCodec)
|
||||
}
|
||||
|
||||
return req.
|
||||
Do(ctx).
|
||||
Into(obj)
|
||||
}
|
||||
|
||||
// UpdateStatus used by StatusWriter to write status.
|
||||
func (c *typedClient) UpdateStatus(ctx context.Context, obj runtime.Object, opts ...client.UpdateOption) error {
|
||||
o, err := c.cache.GetObjMeta(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// It will be nice to receive an error saying the object doesn't implement
|
||||
// status subresource and check CRD definition
|
||||
return o.Put().
|
||||
NamespaceIfScoped(o.GetNamespace(), o.IsNamespaced()).
|
||||
Resource(o.Resource()).
|
||||
Name(o.GetName()).
|
||||
SubResource("status").
|
||||
Body(obj).
|
||||
VersionedParams((&client.UpdateOptions{}).ApplyOptions(opts).AsUpdateOptions(), c.paramCodec).
|
||||
Do(ctx).
|
||||
Into(obj)
|
||||
}
|
||||
|
||||
// PatchStatus used by StatusWriter to write status.
|
||||
func (c *typedClient) PatchStatus(ctx context.Context, obj runtime.Object, patch client.Patch, opts ...client.PatchOption) error {
|
||||
o, err := c.cache.GetObjMeta(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
data, err := patch.Data(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
patchOpts := &client.PatchOptions{}
|
||||
return o.Patch(patch.Type()).
|
||||
NamespaceIfScoped(o.GetNamespace(), o.IsNamespaced()).
|
||||
Resource(o.Resource()).
|
||||
Name(o.GetName()).
|
||||
SubResource("status").
|
||||
Body(data).
|
||||
VersionedParams(patchOpts.ApplyOptions(opts).AsPatchOptions(), c.paramCodec).
|
||||
Do(ctx).
|
||||
Into(obj)
|
||||
}
|
||||
|
||||
// DeleteAllOf implements client.Client
|
||||
func (c *typedClient) DeleteAllOf(ctx context.Context, obj runtime.Object, opts ...client.DeleteAllOfOption) error {
|
||||
o, err := c.cache.GetObjMeta(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
deleteAllOfOpts := client.DeleteAllOfOptions{}
|
||||
deleteAllOfOpts.ApplyOptions(opts)
|
||||
|
||||
return o.Delete().
|
||||
NamespaceIfScoped(deleteAllOfOpts.ListOptions.Namespace, o.IsNamespaced()).
|
||||
Resource(o.Resource()).
|
||||
VersionedParams(deleteAllOfOpts.AsListOptions(), c.paramCodec).
|
||||
Body(deleteAllOfOpts.AsDeleteOptions()).
|
||||
Do(ctx).
|
||||
Error()
|
||||
}
|
||||
274
vendor/kubesphere.io/client-go/client/generic/unstructuredClient.go
generated
vendored
274
vendor/kubesphere.io/client-go/client/generic/unstructuredClient.go
generated
vendored
@@ -1,274 +0,0 @@
|
||||
/*
|
||||
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 generic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"kubesphere.io/client-go/client"
|
||||
)
|
||||
|
||||
// client is a client.Client that reads and writes directly from/to an API server. It lazily initializes
|
||||
// new clients at the time they are used, and caches the client.
|
||||
type unstructuredClient struct {
|
||||
cache client.ClientCache
|
||||
paramCodec runtime.ParameterCodec
|
||||
}
|
||||
|
||||
// Create implements client.Client
|
||||
func (uc *unstructuredClient) Create(ctx context.Context, obj runtime.Object, opts ...client.CreateOption) error {
|
||||
u, ok := obj.(*unstructured.Unstructured)
|
||||
if !ok {
|
||||
return fmt.Errorf("unstructured client did not understand object: %T", obj)
|
||||
}
|
||||
|
||||
gvk := u.GroupVersionKind()
|
||||
|
||||
o, err := uc.cache.GetObjMeta(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
createOpts := &client.CreateOptions{}
|
||||
createOpts.ApplyOptions(opts)
|
||||
result := o.Post().
|
||||
NamespaceIfScoped(o.GetNamespace(), o.IsNamespaced()).
|
||||
Resource(o.Resource()).
|
||||
Body(obj).
|
||||
VersionedParams(createOpts.AsCreateOptions(), uc.paramCodec).
|
||||
Do(ctx).
|
||||
Into(obj)
|
||||
|
||||
u.SetGroupVersionKind(gvk)
|
||||
return result
|
||||
}
|
||||
|
||||
// Update implements client.Client
|
||||
func (uc *unstructuredClient) Update(ctx context.Context, obj runtime.Object, opts ...client.UpdateOption) error {
|
||||
u, ok := obj.(*unstructured.Unstructured)
|
||||
if !ok {
|
||||
return fmt.Errorf("unstructured client did not understand object: %T", obj)
|
||||
}
|
||||
|
||||
gvk := u.GroupVersionKind()
|
||||
|
||||
o, err := uc.cache.GetObjMeta(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
updateOpts := client.UpdateOptions{}
|
||||
updateOpts.ApplyOptions(opts)
|
||||
result := o.Put().
|
||||
NamespaceIfScoped(o.GetNamespace(), o.IsNamespaced()).
|
||||
Resource(o.Resource()).
|
||||
Name(o.GetName()).
|
||||
Body(obj).
|
||||
VersionedParams(updateOpts.AsUpdateOptions(), uc.paramCodec).
|
||||
Do(ctx).
|
||||
Into(obj)
|
||||
|
||||
u.SetGroupVersionKind(gvk)
|
||||
return result
|
||||
}
|
||||
|
||||
// Delete implements client.Client
|
||||
func (uc *unstructuredClient) Delete(ctx context.Context, obj runtime.Object, opts ...client.DeleteOption) error {
|
||||
_, ok := obj.(*unstructured.Unstructured)
|
||||
if !ok {
|
||||
return fmt.Errorf("unstructured client did not understand object: %T", obj)
|
||||
}
|
||||
|
||||
o, err := uc.cache.GetObjMeta(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
deleteOpts := client.DeleteOptions{}
|
||||
deleteOpts.ApplyOptions(opts)
|
||||
return o.Delete().
|
||||
NamespaceIfScoped(o.GetNamespace(), o.IsNamespaced()).
|
||||
Resource(o.Resource()).
|
||||
Name(o.GetName()).
|
||||
Body(deleteOpts.AsDeleteOptions()).
|
||||
Do(ctx).
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteAllOf implements client.Client
|
||||
func (uc *unstructuredClient) DeleteAllOf(ctx context.Context, obj runtime.Object, opts ...client.DeleteAllOfOption) error {
|
||||
_, ok := obj.(*unstructured.Unstructured)
|
||||
if !ok {
|
||||
return fmt.Errorf("unstructured client did not understand object: %T", obj)
|
||||
}
|
||||
|
||||
o, err := uc.cache.GetObjMeta(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
deleteAllOfOpts := client.DeleteAllOfOptions{}
|
||||
deleteAllOfOpts.ApplyOptions(opts)
|
||||
return o.Delete().
|
||||
NamespaceIfScoped(deleteAllOfOpts.ListOptions.Namespace, o.IsNamespaced()).
|
||||
Resource(o.Resource()).
|
||||
VersionedParams(deleteAllOfOpts.AsListOptions(), uc.paramCodec).
|
||||
Body(deleteAllOfOpts.AsDeleteOptions()).
|
||||
Do(ctx).
|
||||
Error()
|
||||
}
|
||||
|
||||
// Patch implements client.Client
|
||||
func (uc *unstructuredClient) Patch(ctx context.Context, obj runtime.Object, patch client.Patch, opts ...client.PatchOption) error {
|
||||
_, ok := obj.(*unstructured.Unstructured)
|
||||
if !ok {
|
||||
return fmt.Errorf("unstructured client did not understand object: %T", obj)
|
||||
}
|
||||
|
||||
o, err := uc.cache.GetObjMeta(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
data, err := patch.Data(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
patchOpts := &client.PatchOptions{}
|
||||
return o.Patch(patch.Type()).
|
||||
NamespaceIfScoped(o.GetNamespace(), o.IsNamespaced()).
|
||||
Resource(o.Resource()).
|
||||
Name(o.GetName()).
|
||||
VersionedParams(patchOpts.ApplyOptions(opts).AsPatchOptions(), uc.paramCodec).
|
||||
Body(data).
|
||||
Do(ctx).
|
||||
Into(obj)
|
||||
}
|
||||
|
||||
// Get implements client.Client
|
||||
func (uc *unstructuredClient) Get(ctx context.Context, key client.ObjectKey, obj runtime.Object, opts ...client.GetOption) error {
|
||||
u, ok := obj.(*unstructured.Unstructured)
|
||||
if !ok {
|
||||
return fmt.Errorf("unstructured client did not understand object: %T", obj)
|
||||
}
|
||||
|
||||
gvk := u.GroupVersionKind()
|
||||
|
||||
r, err := uc.cache.GetResource(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
result := r.Get().
|
||||
NamespaceIfScoped(key.Namespace, r.IsNamespaced()).
|
||||
Resource(r.Resource()).
|
||||
Name(key.Name).
|
||||
Do(ctx).
|
||||
Into(obj)
|
||||
|
||||
u.SetGroupVersionKind(gvk)
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// List implements client.Client
|
||||
func (uc *unstructuredClient) List(ctx context.Context, obj runtime.Object, opts ...client.ListOption) error {
|
||||
u, ok := obj.(*unstructured.UnstructuredList)
|
||||
if !ok {
|
||||
return fmt.Errorf("unstructured client did not understand object: %T", obj)
|
||||
}
|
||||
|
||||
gvk := u.GroupVersionKind()
|
||||
if strings.HasSuffix(gvk.Kind, "List") {
|
||||
gvk.Kind = gvk.Kind[:len(gvk.Kind)-4]
|
||||
}
|
||||
|
||||
listOpts := client.ListOptions{}
|
||||
listOpts.ApplyOptions(opts)
|
||||
|
||||
r, err := uc.cache.GetResource(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return r.Get().
|
||||
NamespaceIfScoped(listOpts.Namespace, r.IsNamespaced()).
|
||||
Resource(r.Resource()).
|
||||
VersionedParams(listOpts.AsListOptions(), uc.paramCodec).
|
||||
Do(ctx).
|
||||
Into(obj)
|
||||
}
|
||||
|
||||
func (uc *unstructuredClient) UpdateStatus(ctx context.Context, obj runtime.Object, opts ...client.UpdateOption) error {
|
||||
_, ok := obj.(*unstructured.Unstructured)
|
||||
if !ok {
|
||||
return fmt.Errorf("unstructured client did not understand object: %T", obj)
|
||||
}
|
||||
|
||||
o, err := uc.cache.GetObjMeta(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return o.Put().
|
||||
NamespaceIfScoped(o.GetNamespace(), o.IsNamespaced()).
|
||||
Resource(o.Resource()).
|
||||
Name(o.GetName()).
|
||||
SubResource("status").
|
||||
Body(obj).
|
||||
VersionedParams((&client.UpdateOptions{}).ApplyOptions(opts).AsUpdateOptions(), uc.paramCodec).
|
||||
Do(ctx).
|
||||
Into(obj)
|
||||
}
|
||||
|
||||
func (uc *unstructuredClient) PatchStatus(ctx context.Context, obj runtime.Object, patch client.Patch, opts ...client.PatchOption) error {
|
||||
u, ok := obj.(*unstructured.Unstructured)
|
||||
if !ok {
|
||||
return fmt.Errorf("unstructured client did not understand object: %T", obj)
|
||||
}
|
||||
|
||||
gvk := u.GroupVersionKind()
|
||||
|
||||
o, err := uc.cache.GetObjMeta(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
data, err := patch.Data(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
patchOpts := &client.PatchOptions{}
|
||||
result := o.Patch(patch.Type()).
|
||||
NamespaceIfScoped(o.GetNamespace(), o.IsNamespaced()).
|
||||
Resource(o.Resource()).
|
||||
Name(o.GetName()).
|
||||
SubResource("status").
|
||||
Body(data).
|
||||
VersionedParams(patchOpts.ApplyOptions(opts).AsPatchOptions(), uc.paramCodec).
|
||||
Do(ctx).
|
||||
Into(u)
|
||||
|
||||
u.SetGroupVersionKind(gvk)
|
||||
return result
|
||||
}
|
||||
115
vendor/kubesphere.io/client-go/client/interface.go
generated
vendored
115
vendor/kubesphere.io/client-go/client/interface.go
generated
vendored
@@ -1,115 +0,0 @@
|
||||
/*
|
||||
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 client
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
)
|
||||
|
||||
// ObjectKey identifies a Kubernetes Object.
|
||||
type ObjectKey = types.NamespacedName
|
||||
|
||||
// ObjectKeyFromObject returns the ObjectKey given a runtime.Object
|
||||
func ObjectKeyFromObject(obj runtime.Object) (ObjectKey, error) {
|
||||
accessor, err := meta.Accessor(obj)
|
||||
if err != nil {
|
||||
return ObjectKey{}, err
|
||||
}
|
||||
return ObjectKey{Namespace: accessor.GetNamespace(), Name: accessor.GetName()}, nil
|
||||
}
|
||||
|
||||
// Patch is a patch that can be applied to a Kubernetes object.
|
||||
type Patch interface {
|
||||
// Type is the PatchType of the patch.
|
||||
Type() types.PatchType
|
||||
// Data is the raw data representing the patch.
|
||||
Data(obj runtime.Object) ([]byte, error)
|
||||
}
|
||||
|
||||
// Reader knows how to read and list Kubernetes objects.
|
||||
type Reader interface {
|
||||
// Get retrieves an obj for the given object key from the Kubernetes Cluster.
|
||||
// obj must be a struct pointer so that obj can be updated with the response
|
||||
// returned by the Server.
|
||||
Get(ctx context.Context, key ObjectKey, obj runtime.Object, opts ...GetOption) error
|
||||
|
||||
// List retrieves list of objects for a given namespace and list options. On a
|
||||
// successful call, Items field in the list will be populated with the
|
||||
// result returned from the server.
|
||||
List(ctx context.Context, list runtime.Object, opts ...ListOption) error
|
||||
}
|
||||
|
||||
// Writer knows how to create, delete, and update Kubernetes objects.
|
||||
type Writer interface {
|
||||
// Create saves the object obj in the Kubernetes cluster.
|
||||
Create(ctx context.Context, obj runtime.Object, opts ...CreateOption) error
|
||||
|
||||
// Delete deletes the given obj from Kubernetes cluster.
|
||||
Delete(ctx context.Context, obj runtime.Object, opts ...DeleteOption) error
|
||||
|
||||
// Update updates the given obj in the Kubernetes cluster. obj must be a
|
||||
// struct pointer so that obj can be updated with the content returned by the Server.
|
||||
Update(ctx context.Context, obj runtime.Object, opts ...UpdateOption) error
|
||||
|
||||
// Patch patches the given obj in the Kubernetes cluster. obj must be a
|
||||
// struct pointer so that obj can be updated with the content returned by the Server.
|
||||
Patch(ctx context.Context, obj runtime.Object, patch Patch, opts ...PatchOption) error
|
||||
|
||||
// DeleteAllOf deletes all objects of the given type matching the given options.
|
||||
DeleteAllOf(ctx context.Context, obj runtime.Object, opts ...DeleteAllOfOption) error
|
||||
}
|
||||
|
||||
// StatusClient knows how to create a client which can update status subresource
|
||||
// for kubernetes objects.
|
||||
type StatusClient interface {
|
||||
Status() StatusWriter
|
||||
}
|
||||
|
||||
// StatusWriter knows how to update status subresource of a Kubernetes object.
|
||||
type StatusWriter interface {
|
||||
// Update updates the fields corresponding to the status subresource for the
|
||||
// given obj. obj must be a struct pointer so that obj can be updated
|
||||
// with the content returned by the Server.
|
||||
Update(ctx context.Context, obj runtime.Object, opts ...UpdateOption) error
|
||||
|
||||
// Patch patches the given object's subresource. obj must be a struct
|
||||
// pointer so that obj can be updated with the content returned by the
|
||||
// Server.
|
||||
Patch(ctx context.Context, obj runtime.Object, patch Patch, opts ...PatchOption) error
|
||||
}
|
||||
|
||||
// Client knows how to perform CRUD operations on Kubernetes objects.
|
||||
type Client interface {
|
||||
Reader
|
||||
Writer
|
||||
StatusClient
|
||||
}
|
||||
|
||||
// IgnoreNotFound returns nil on NotFound errors.
|
||||
// All other values that are not NotFound errors or nil are returned unmodified.
|
||||
func IgnoreNotFound(err error) error {
|
||||
if apierrors.IsNotFound(err) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
902
vendor/kubesphere.io/client-go/client/options.go
generated
vendored
902
vendor/kubesphere.io/client-go/client/options.go
generated
vendored
@@ -1,902 +0,0 @@
|
||||
/*
|
||||
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 client
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/fields"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/selection"
|
||||
)
|
||||
|
||||
// Options are creation options for a Client
|
||||
type Options struct {
|
||||
// Scheme, if provided, will be used to map go structs to GroupVersionKinds
|
||||
Scheme *runtime.Scheme
|
||||
|
||||
// Mapper, if provided, will be used to map GroupVersionKinds to Resources
|
||||
Mapper meta.RESTMapper
|
||||
}
|
||||
|
||||
// {{{ "Functional" Option Interfaces
|
||||
|
||||
// CreateOption is some configuration that modifies options for a create request.
|
||||
type CreateOption interface {
|
||||
// ApplyToCreate applies this configuration to the given create options.
|
||||
ApplyToCreate(*CreateOptions)
|
||||
}
|
||||
|
||||
// DeleteOption is some configuration that modifies options for a delete request.
|
||||
type DeleteOption interface {
|
||||
// ApplyToDelete applies this configuration to the given delete options.
|
||||
ApplyToDelete(*DeleteOptions)
|
||||
}
|
||||
|
||||
// ListOption is some configuration that modifies options for a list request.
|
||||
type ListOption interface {
|
||||
// ApplyToList applies this configuration to the given list options.
|
||||
ApplyToList(*ListOptions)
|
||||
}
|
||||
|
||||
// GetOption is some configuration that modifies options for a get request.
|
||||
type GetOption interface {
|
||||
// ApplyToGet applies this configuration to the given get options.
|
||||
ApplyToGet(*GetOptions)
|
||||
}
|
||||
|
||||
// UpdateOption is some configuration that modifies options for a update request.
|
||||
type UpdateOption interface {
|
||||
// ApplyToUpdate applies this configuration to the given update options.
|
||||
ApplyToUpdate(*UpdateOptions)
|
||||
}
|
||||
|
||||
// PatchOption is some configuration that modifies options for a patch request.
|
||||
type PatchOption interface {
|
||||
// ApplyToPatch applies this configuration to the given patch options.
|
||||
ApplyToPatch(*PatchOptions)
|
||||
}
|
||||
|
||||
// DeleteAllOfOption is some configuration that modifies options for a delete request.
|
||||
type DeleteAllOfOption interface {
|
||||
// ApplyToDeleteAllOf applies this configuration to the given deletecollection options.
|
||||
ApplyToDeleteAllOf(*DeleteAllOfOptions)
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
// {{{ Multi-Type Options
|
||||
|
||||
// DryRunAll sets the "dry run" option to "all", executing all
|
||||
// validation, etc without persisting the change to storage.
|
||||
var DryRunAll = dryRunAll{}
|
||||
|
||||
type dryRunAll struct{}
|
||||
|
||||
// ApplyToCreate applies this configuration to the given create options.
|
||||
func (dryRunAll) ApplyToCreate(opts *CreateOptions) {
|
||||
opts.DryRun = []string{metav1.DryRunAll}
|
||||
}
|
||||
|
||||
// ApplyToUpdate applies this configuration to the given update options.
|
||||
func (dryRunAll) ApplyToUpdate(opts *UpdateOptions) {
|
||||
opts.DryRun = []string{metav1.DryRunAll}
|
||||
}
|
||||
|
||||
// ApplyToPatch applies this configuration to the given patch options.
|
||||
func (dryRunAll) ApplyToPatch(opts *PatchOptions) {
|
||||
opts.DryRun = []string{metav1.DryRunAll}
|
||||
}
|
||||
|
||||
// ApplyToPatch applies this configuration to the given delete options.
|
||||
func (dryRunAll) ApplyToDelete(opts *DeleteOptions) {
|
||||
opts.DryRun = []string{metav1.DryRunAll}
|
||||
}
|
||||
func (dryRunAll) ApplyToDeleteAllOf(opts *DeleteAllOfOptions) {
|
||||
opts.DryRun = []string{metav1.DryRunAll}
|
||||
}
|
||||
|
||||
// FieldOwner set the field manager name for the given server-side apply patch.
|
||||
type FieldOwner string
|
||||
|
||||
// ApplyToPatch applies this configuration to the given patch options.
|
||||
func (f FieldOwner) ApplyToPatch(opts *PatchOptions) {
|
||||
opts.FieldManager = string(f)
|
||||
}
|
||||
|
||||
// ApplyToCreate applies this configuration to the given create options.
|
||||
func (f FieldOwner) ApplyToCreate(opts *CreateOptions) {
|
||||
opts.FieldManager = string(f)
|
||||
}
|
||||
|
||||
// ApplyToUpdate applies this configuration to the given update options.
|
||||
func (f FieldOwner) ApplyToUpdate(opts *UpdateOptions) {
|
||||
opts.FieldManager = string(f)
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
// {{{ Create Options
|
||||
|
||||
// CreateOptions contains options for create requests. It's generally a subset
|
||||
// of metav1.CreateOptions.
|
||||
type CreateOptions struct {
|
||||
// When present, indicates that modifications should not be
|
||||
// persisted. An invalid or unrecognized dryRun directive will
|
||||
// result in an error response and no further processing of the
|
||||
// request. Valid values are:
|
||||
// - All: all dry run stages will be processed
|
||||
DryRun []string
|
||||
|
||||
// FieldManager is the name of the user or component submitting
|
||||
// this request. It must be set with server-side apply.
|
||||
FieldManager string
|
||||
|
||||
// URLOption ov
|
||||
URLOption *URLOptions
|
||||
|
||||
Workspace *WorkspaceOptions
|
||||
|
||||
// Raw represents raw CreateOptions, as passed to the API server.
|
||||
Raw *metav1.CreateOptions
|
||||
}
|
||||
|
||||
// AsCreateOptions returns these options as a metav1.CreateOptions.
|
||||
// This may mutate the Raw field.
|
||||
func (o *CreateOptions) AsCreateOptions() *metav1.CreateOptions {
|
||||
if o == nil {
|
||||
return &metav1.CreateOptions{}
|
||||
}
|
||||
if o.Raw == nil {
|
||||
o.Raw = &metav1.CreateOptions{}
|
||||
}
|
||||
|
||||
o.Raw.DryRun = o.DryRun
|
||||
o.Raw.FieldManager = o.FieldManager
|
||||
return o.Raw
|
||||
}
|
||||
|
||||
// ApplyOptions applies the given create options on these options,
|
||||
// and then returns itself (for convenient chaining).
|
||||
func (o *CreateOptions) ApplyOptions(opts []CreateOption) *CreateOptions {
|
||||
for _, opt := range opts {
|
||||
opt.ApplyToCreate(o)
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
// ApplyToCreate implements CreateOption
|
||||
func (o *CreateOptions) ApplyToCreate(co *CreateOptions) {
|
||||
if o.DryRun != nil {
|
||||
co.DryRun = o.DryRun
|
||||
}
|
||||
if o.FieldManager != "" {
|
||||
co.FieldManager = o.FieldManager
|
||||
}
|
||||
if o.Raw != nil {
|
||||
co.Raw = o.Raw
|
||||
}
|
||||
if o.URLOption != nil {
|
||||
co.URLOption = o.URLOption
|
||||
}
|
||||
if o.Workspace != nil {
|
||||
co.Workspace = o.Workspace
|
||||
}
|
||||
}
|
||||
|
||||
var _ CreateOption = &CreateOptions{}
|
||||
|
||||
// CreateDryRunAll sets the "dry run" option to "all".
|
||||
//
|
||||
// Deprecated: Use DryRunAll
|
||||
var CreateDryRunAll = DryRunAll
|
||||
|
||||
// }}}
|
||||
|
||||
// {{{ Delete Options
|
||||
|
||||
// DeleteOptions contains options for delete requests. It's generally a subset
|
||||
// of metav1.DeleteOptions.
|
||||
type DeleteOptions struct {
|
||||
// GracePeriodSeconds is the duration in seconds before the object should be
|
||||
// deleted. Value must be non-negative integer. The value zero indicates
|
||||
// delete immediately. If this value is nil, the default grace period for the
|
||||
// specified type will be used.
|
||||
GracePeriodSeconds *int64
|
||||
|
||||
// Preconditions must be fulfilled before a deletion is carried out. If not
|
||||
// possible, a 409 Conflict status will be returned.
|
||||
Preconditions *metav1.Preconditions
|
||||
|
||||
// PropagationPolicy determined whether and how garbage collection will be
|
||||
// performed. Either this field or OrphanDependents may be set, but not both.
|
||||
// The default policy is decided by the existing finalizer set in the
|
||||
// metadata.finalizers and the resource-specific default policy.
|
||||
// Acceptable values are: 'Orphan' - orphan the dependents; 'Background' -
|
||||
// allow the garbage collector to delete the dependents in the background;
|
||||
// 'Foreground' - a cascading policy that deletes all dependents in the
|
||||
// foreground.
|
||||
PropagationPolicy *metav1.DeletionPropagation
|
||||
|
||||
// Raw represents raw DeleteOptions, as passed to the API server.
|
||||
Raw *metav1.DeleteOptions
|
||||
|
||||
// When present, indicates that modifications should not be
|
||||
// persisted. An invalid or unrecognized dryRun directive will
|
||||
// result in an error response and no further processing of the
|
||||
// request. Valid values are:
|
||||
// - All: all dry run stages will be processed
|
||||
DryRun []string
|
||||
|
||||
// URLOption overwrites an GVK based API URL.
|
||||
URLOption *URLOptions
|
||||
|
||||
// Workspace represents the workspace for object that deleting.
|
||||
Workspace *WorkspaceOptions
|
||||
}
|
||||
|
||||
// AsDeleteOptions returns these options as a metav1.DeleteOptions.
|
||||
// This may mutate the Raw field.
|
||||
func (o *DeleteOptions) AsDeleteOptions() *metav1.DeleteOptions {
|
||||
if o == nil {
|
||||
return &metav1.DeleteOptions{}
|
||||
}
|
||||
if o.Raw == nil {
|
||||
o.Raw = &metav1.DeleteOptions{}
|
||||
}
|
||||
|
||||
o.Raw.GracePeriodSeconds = o.GracePeriodSeconds
|
||||
o.Raw.Preconditions = o.Preconditions
|
||||
o.Raw.PropagationPolicy = o.PropagationPolicy
|
||||
o.Raw.DryRun = o.DryRun
|
||||
return o.Raw
|
||||
}
|
||||
|
||||
// ApplyOptions applies the given delete options on these options,
|
||||
// and then returns itself (for convenient chaining).
|
||||
func (o *DeleteOptions) ApplyOptions(opts []DeleteOption) *DeleteOptions {
|
||||
for _, opt := range opts {
|
||||
opt.ApplyToDelete(o)
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
var _ DeleteOption = &DeleteOptions{}
|
||||
|
||||
// ApplyToDelete implements DeleteOption
|
||||
func (o *DeleteOptions) ApplyToDelete(do *DeleteOptions) {
|
||||
if o.GracePeriodSeconds != nil {
|
||||
do.GracePeriodSeconds = o.GracePeriodSeconds
|
||||
}
|
||||
if o.Preconditions != nil {
|
||||
do.Preconditions = o.Preconditions
|
||||
}
|
||||
if o.PropagationPolicy != nil {
|
||||
do.PropagationPolicy = o.PropagationPolicy
|
||||
}
|
||||
if o.Raw != nil {
|
||||
do.Raw = o.Raw
|
||||
}
|
||||
if o.DryRun != nil {
|
||||
do.DryRun = o.DryRun
|
||||
}
|
||||
if o.URLOption != nil {
|
||||
do.URLOption = o.URLOption
|
||||
}
|
||||
if o.Workspace != nil {
|
||||
do.Workspace = o.Workspace
|
||||
}
|
||||
}
|
||||
|
||||
// GracePeriodSeconds sets the grace period for the deletion
|
||||
// to the given number of seconds.
|
||||
type GracePeriodSeconds int64
|
||||
|
||||
// ApplyToDelete applies this configuration to the given delete options.
|
||||
func (s GracePeriodSeconds) ApplyToDelete(opts *DeleteOptions) {
|
||||
secs := int64(s)
|
||||
opts.GracePeriodSeconds = &secs
|
||||
}
|
||||
|
||||
// ApplyToDeleteAllOf applies this configuration to the given an List options.
|
||||
func (s GracePeriodSeconds) ApplyToDeleteAllOf(opts *DeleteAllOfOptions) {
|
||||
s.ApplyToDelete(&opts.DeleteOptions)
|
||||
}
|
||||
|
||||
// Preconditions must be fulfilled before an operation (update, delete, etc.) is carried out.
|
||||
type Preconditions metav1.Preconditions
|
||||
|
||||
// ApplyToDelete applies this configuration to the given delete options.
|
||||
func (p Preconditions) ApplyToDelete(opts *DeleteOptions) {
|
||||
preconds := metav1.Preconditions(p)
|
||||
opts.Preconditions = &preconds
|
||||
}
|
||||
|
||||
// ApplyToDeleteAllOf applies this configuration to the given an List options.
|
||||
func (p Preconditions) ApplyToDeleteAllOf(opts *DeleteAllOfOptions) {
|
||||
p.ApplyToDelete(&opts.DeleteOptions)
|
||||
}
|
||||
|
||||
// PropagationPolicy determined whether and how garbage collection will be
|
||||
// performed. Either this field or OrphanDependents may be set, but not both.
|
||||
// The default policy is decided by the existing finalizer set in the
|
||||
// metadata.finalizers and the resource-specific default policy.
|
||||
// Acceptable values are: 'Orphan' - orphan the dependents; 'Background' -
|
||||
// allow the garbage collector to delete the dependents in the background;
|
||||
// 'Foreground' - a cascading policy that deletes all dependents in the
|
||||
// foreground.
|
||||
type PropagationPolicy metav1.DeletionPropagation
|
||||
|
||||
// ApplyToDelete applies the given delete options on these options.
|
||||
// It will propagate to the dependents of the object to let the garbage collector handle it.
|
||||
func (p PropagationPolicy) ApplyToDelete(opts *DeleteOptions) {
|
||||
policy := metav1.DeletionPropagation(p)
|
||||
opts.PropagationPolicy = &policy
|
||||
}
|
||||
|
||||
// ApplyToDeleteAllOf applies this configuration to the given an List options.
|
||||
func (p PropagationPolicy) ApplyToDeleteAllOf(opts *DeleteAllOfOptions) {
|
||||
p.ApplyToDelete(&opts.DeleteOptions)
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
// {{{ WorkSpace Options
|
||||
type WorkspaceOptions struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
// ApplyToList applies this configuration to the given list options.
|
||||
func (w *WorkspaceOptions) ApplyToList(opts *ListOptions) {
|
||||
opts.Workspace = w
|
||||
}
|
||||
|
||||
// ApplyToCreate applies this configuration to the given create options.
|
||||
func (w *WorkspaceOptions) ApplyToCreate(opts *CreateOptions) {
|
||||
opts.Workspace = w
|
||||
}
|
||||
|
||||
// ApplyToGet applies this configuration to the given get options.
|
||||
func (w *WorkspaceOptions) ApplyToGet(opts *GetOptions) {
|
||||
opts.Workspace = w
|
||||
}
|
||||
|
||||
// ApplyToGet applies this configuration to the given get options.
|
||||
func (w *WorkspaceOptions) ApplyToDelete(opts *DeleteOptions) {
|
||||
opts.Workspace = w
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
// {{{ URLOption Options
|
||||
|
||||
type URLOptions struct {
|
||||
Group string
|
||||
Version string
|
||||
//AbsPath overwrites all of other url options with the url provided.
|
||||
AbsPath string
|
||||
}
|
||||
|
||||
func (w *URLOptions) URL() []string {
|
||||
if w.AbsPath != "" {
|
||||
return []string{w.AbsPath}
|
||||
}
|
||||
|
||||
absPath := []string{"kapis", w.Group, w.Version}
|
||||
return absPath
|
||||
}
|
||||
|
||||
// ApplyToList applies this configuration to the given list options.
|
||||
func (m *URLOptions) ApplyToList(opts *ListOptions) {
|
||||
opts.URLOption = m
|
||||
}
|
||||
|
||||
// ApplyToCreate applies this configuration to the given create options.
|
||||
func (m *URLOptions) ApplyToCreate(opts *CreateOptions) {
|
||||
opts.URLOption = m
|
||||
}
|
||||
|
||||
// ApplyToGet applies this configuration to the given get options.
|
||||
func (m *URLOptions) ApplyToGet(opts *GetOptions) {
|
||||
opts.URLOption = m
|
||||
}
|
||||
|
||||
// ApplyToGet applies this configuration to the given get options.
|
||||
func (m *URLOptions) ApplyToDelete(opts *DeleteOptions) {
|
||||
opts.URLOption = m
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
// {{{ List Options
|
||||
|
||||
// ListOptions contains options for limiting or filtering results.
|
||||
// It's generally a subset of metav1.ListOptions, with support for
|
||||
// pre-parsed selectors (since generally, selectors will be executed
|
||||
// against the cache).
|
||||
type ListOptions struct {
|
||||
// LabelSelector filters results by label. Use SetLabelSelector to
|
||||
// set from raw string form.
|
||||
LabelSelector labels.Selector
|
||||
// FieldSelector filters results by a particular field. In order
|
||||
// to use this with cache-based implementations, restrict usage to
|
||||
// a single field-value pair that's been added to the indexers.
|
||||
FieldSelector fields.Selector
|
||||
|
||||
// Namespace represents the namespace to list for, or empty for
|
||||
// non-namespaced objects, or to list across all namespaces.
|
||||
Namespace string
|
||||
|
||||
// Limit specifies the maximum number of results to return from the server. The server may
|
||||
// not support this field on all resource types, but if it does and more results remain it
|
||||
// will set the continue field on the returned list object. This field is not supported if watch
|
||||
// is true in the Raw ListOptions.
|
||||
Limit int64
|
||||
// Continue is a token returned by the server that lets a client retrieve chunks of results
|
||||
// from the server by specifying limit. The server may reject requests for continuation tokens
|
||||
// it does not recognize and will return a 410 error if the token can no longer be used because
|
||||
// it has expired. This field is not supported if watch is true in the Raw ListOptions.
|
||||
Continue string
|
||||
|
||||
// Raw represents raw ListOptions, as passed to the API server. Note
|
||||
// that these may not be respected by all implementations of interface,
|
||||
// and the LabelSelector, FieldSelector, Limit and Continue fields are ignored.
|
||||
Raw *metav1.ListOptions
|
||||
|
||||
// URLOption overwrites an GVK based API URL.
|
||||
URLOption *URLOptions
|
||||
|
||||
// Workspace represents the workspace to list for.
|
||||
Workspace *WorkspaceOptions
|
||||
}
|
||||
|
||||
var _ ListOption = &ListOptions{}
|
||||
|
||||
// ApplyToList implements ListOption for ListOptions
|
||||
func (o *ListOptions) ApplyToList(lo *ListOptions) {
|
||||
if o.LabelSelector != nil {
|
||||
lo.LabelSelector = o.LabelSelector
|
||||
}
|
||||
if o.FieldSelector != nil {
|
||||
lo.FieldSelector = o.FieldSelector
|
||||
}
|
||||
if o.Namespace != "" {
|
||||
lo.Namespace = o.Namespace
|
||||
}
|
||||
if o.Raw != nil {
|
||||
lo.Raw = o.Raw
|
||||
}
|
||||
if o.Limit > 0 {
|
||||
lo.Limit = o.Limit
|
||||
}
|
||||
if o.Continue != "" {
|
||||
lo.Continue = o.Continue
|
||||
}
|
||||
if o.URLOption != nil {
|
||||
lo.URLOption = o.URLOption
|
||||
}
|
||||
if o.Workspace != nil {
|
||||
lo.Workspace = o.Workspace
|
||||
}
|
||||
}
|
||||
|
||||
// AsListOptions returns these options as a flattened metav1.ListOptions.
|
||||
// This may mutate the Raw field.
|
||||
func (o *ListOptions) AsListOptions() *metav1.ListOptions {
|
||||
if o == nil {
|
||||
return &metav1.ListOptions{}
|
||||
}
|
||||
if o.Raw == nil {
|
||||
o.Raw = &metav1.ListOptions{}
|
||||
}
|
||||
if o.LabelSelector != nil {
|
||||
o.Raw.LabelSelector = o.LabelSelector.String()
|
||||
}
|
||||
if o.FieldSelector != nil {
|
||||
o.Raw.FieldSelector = o.FieldSelector.String()
|
||||
}
|
||||
if !o.Raw.Watch {
|
||||
o.Raw.Limit = o.Limit
|
||||
o.Raw.Continue = o.Continue
|
||||
}
|
||||
return o.Raw
|
||||
}
|
||||
|
||||
// ApplyOptions applies the given list options on these options,
|
||||
// and then returns itself (for convenient chaining).
|
||||
func (o *ListOptions) ApplyOptions(opts []ListOption) *ListOptions {
|
||||
for _, opt := range opts {
|
||||
opt.ApplyToList(o)
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
// MatchingLabels filters the list/delete operation on the given set of labels.
|
||||
type MatchingLabels map[string]string
|
||||
|
||||
// ApplyToList applies this configuration to the given list options.
|
||||
func (m MatchingLabels) ApplyToList(opts *ListOptions) {
|
||||
// TODO(directxman12): can we avoid reserializing this over and over?
|
||||
sel := labels.SelectorFromValidatedSet(map[string]string(m))
|
||||
opts.LabelSelector = sel
|
||||
}
|
||||
|
||||
// ApplyToDeleteAllOf applies this configuration to the given an List options.
|
||||
func (m MatchingLabels) ApplyToDeleteAllOf(opts *DeleteAllOfOptions) {
|
||||
m.ApplyToList(&opts.ListOptions)
|
||||
}
|
||||
|
||||
// HasLabels filters the list/delete operation checking if the set of labels exists
|
||||
// without checking their values.
|
||||
type HasLabels []string
|
||||
|
||||
// ApplyToList applies this configuration to the given list options.
|
||||
func (m HasLabels) ApplyToList(opts *ListOptions) {
|
||||
sel := labels.NewSelector()
|
||||
for _, label := range m {
|
||||
r, err := labels.NewRequirement(label, selection.Exists, nil)
|
||||
if err == nil {
|
||||
sel = sel.Add(*r)
|
||||
}
|
||||
}
|
||||
opts.LabelSelector = sel
|
||||
}
|
||||
|
||||
// ApplyToDeleteAllOf applies this configuration to the given an List options.
|
||||
func (m HasLabels) ApplyToDeleteAllOf(opts *DeleteAllOfOptions) {
|
||||
m.ApplyToList(&opts.ListOptions)
|
||||
}
|
||||
|
||||
// MatchingLabelsSelector filters the list/delete operation on the given label
|
||||
// selector (or index in the case of cached lists). A struct is used because
|
||||
// labels.Selector is an interface, which cannot be aliased.
|
||||
type MatchingLabelsSelector struct {
|
||||
labels.Selector
|
||||
}
|
||||
|
||||
// ApplyToList applies this configuration to the given list options.
|
||||
func (m MatchingLabelsSelector) ApplyToList(opts *ListOptions) {
|
||||
opts.LabelSelector = m
|
||||
}
|
||||
|
||||
// ApplyToDeleteAllOf applies this configuration to the given an List options.
|
||||
func (m MatchingLabelsSelector) ApplyToDeleteAllOf(opts *DeleteAllOfOptions) {
|
||||
m.ApplyToList(&opts.ListOptions)
|
||||
}
|
||||
|
||||
// MatchingField filters the list operation on the given field selector
|
||||
// (or index in the case of cached lists).
|
||||
//
|
||||
// Deprecated: Use MatchingFields
|
||||
func MatchingField(name, val string) MatchingFields {
|
||||
return MatchingFields{name: val}
|
||||
}
|
||||
|
||||
// MatchingFields filters the list/delete operation on the given field Set
|
||||
// (or index in the case of cached lists).
|
||||
type MatchingFields fields.Set
|
||||
|
||||
// ApplyToList applies this configuration to the given list options.
|
||||
func (m MatchingFields) ApplyToList(opts *ListOptions) {
|
||||
// TODO(directxman12): can we avoid re-serializing this?
|
||||
sel := fields.Set(m).AsSelector()
|
||||
opts.FieldSelector = sel
|
||||
}
|
||||
|
||||
// ApplyToDeleteAllOf applies this configuration to the given an List options.
|
||||
func (m MatchingFields) ApplyToDeleteAllOf(opts *DeleteAllOfOptions) {
|
||||
m.ApplyToList(&opts.ListOptions)
|
||||
}
|
||||
|
||||
// MatchingFieldsSelector filters the list/delete operation on the given field
|
||||
// selector (or index in the case of cached lists). A struct is used because
|
||||
// fields.Selector is an interface, which cannot be aliased.
|
||||
type MatchingFieldsSelector struct {
|
||||
fields.Selector
|
||||
}
|
||||
|
||||
// ApplyToList applies this configuration to the given list options.
|
||||
func (m MatchingFieldsSelector) ApplyToList(opts *ListOptions) {
|
||||
opts.FieldSelector = m
|
||||
}
|
||||
|
||||
// ApplyToDeleteAllOf applies this configuration to the given an List options.
|
||||
func (m MatchingFieldsSelector) ApplyToDeleteAllOf(opts *DeleteAllOfOptions) {
|
||||
m.ApplyToList(&opts.ListOptions)
|
||||
}
|
||||
|
||||
// InNamespace restricts the list/delete operation to the given namespace.
|
||||
type InNamespace string
|
||||
|
||||
// ApplyToList applies this configuration to the given list options.
|
||||
func (n InNamespace) ApplyToList(opts *ListOptions) {
|
||||
opts.Namespace = string(n)
|
||||
}
|
||||
|
||||
// ApplyToDeleteAllOf applies this configuration to the given an List options.
|
||||
func (n InNamespace) ApplyToDeleteAllOf(opts *DeleteAllOfOptions) {
|
||||
n.ApplyToList(&opts.ListOptions)
|
||||
}
|
||||
|
||||
// Limit specifies the maximum number of results to return from the server.
|
||||
// Limit does not implement DeleteAllOfOption interface because the server
|
||||
// does not support setting it for deletecollection operations.
|
||||
type Limit int64
|
||||
|
||||
// ApplyToList applies this configuration to the given an list options.
|
||||
func (l Limit) ApplyToList(opts *ListOptions) {
|
||||
opts.Limit = int64(l)
|
||||
}
|
||||
|
||||
// Continue sets a continuation token to retrieve chunks of results when using limit.
|
||||
// Continue does not implement DeleteAllOfOption interface because the server
|
||||
// does not support setting it for deletecollection operations.
|
||||
type Continue string
|
||||
|
||||
// ApplyToList applies this configuration to the given an List options.
|
||||
func (c Continue) ApplyToList(opts *ListOptions) {
|
||||
opts.Continue = string(c)
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
// {{{ Get Options
|
||||
|
||||
// ListOptions contains options for limiting or filtering results.
|
||||
// It's generally a subset of metav1.ListOptions, with support for
|
||||
// pre-parsed selectors (since generally, selectors will be executed
|
||||
// against the cache).
|
||||
type GetOptions struct {
|
||||
|
||||
// Namespace represents the namespace to list for, or empty for
|
||||
// non-namespaced objects, or to list across all namespaces.
|
||||
Namespace string
|
||||
|
||||
// URLOption overwrites an GVK based API URL.
|
||||
URLOption *URLOptions
|
||||
|
||||
// Workspace represents the workspace that get object for.
|
||||
Workspace *WorkspaceOptions
|
||||
}
|
||||
|
||||
// ApplyOptions applies the given list options on these options,
|
||||
// and then returns itself (for convenient chaining).
|
||||
func (o *GetOptions) ApplyOptions(opts []GetOption) *GetOptions {
|
||||
for _, opt := range opts {
|
||||
opt.ApplyToGet(o)
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
var _ ListOption = &ListOptions{}
|
||||
|
||||
// ApplyToList implements ListOption for ListOptions
|
||||
func (o *GetOptions) ApplyToGet(lo *GetOptions) {
|
||||
if o.Namespace != "" {
|
||||
lo.Namespace = o.Namespace
|
||||
}
|
||||
if o.URLOption != nil {
|
||||
lo.URLOption = o.URLOption
|
||||
}
|
||||
if o.Workspace != nil {
|
||||
lo.Workspace = o.Workspace
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
// {{{ Update Options
|
||||
|
||||
// UpdateOptions contains options for create requests. It's generally a subset
|
||||
// of metav1.UpdateOptions.
|
||||
type UpdateOptions struct {
|
||||
// When present, indicates that modifications should not be
|
||||
// persisted. An invalid or unrecognized dryRun directive will
|
||||
// result in an error response and no further processing of the
|
||||
// request. Valid values are:
|
||||
// - All: all dry run stages will be processed
|
||||
DryRun []string
|
||||
|
||||
// FieldManager is the name of the user or component submitting
|
||||
// this request. It must be set with server-side apply.
|
||||
FieldManager string
|
||||
|
||||
// Raw represents raw UpdateOptions, as passed to the API server.
|
||||
Raw *metav1.UpdateOptions
|
||||
|
||||
// URLOption overwrites an GVK based API URL.
|
||||
URLOption *URLOptions
|
||||
|
||||
// Workspace represents the workspace for object that updating.
|
||||
Workspace *WorkspaceOptions
|
||||
}
|
||||
|
||||
// AsUpdateOptions returns these options as a metav1.UpdateOptions.
|
||||
// This may mutate the Raw field.
|
||||
func (o *UpdateOptions) AsUpdateOptions() *metav1.UpdateOptions {
|
||||
if o == nil {
|
||||
return &metav1.UpdateOptions{}
|
||||
}
|
||||
if o.Raw == nil {
|
||||
o.Raw = &metav1.UpdateOptions{}
|
||||
}
|
||||
|
||||
o.Raw.DryRun = o.DryRun
|
||||
o.Raw.FieldManager = o.FieldManager
|
||||
return o.Raw
|
||||
}
|
||||
|
||||
// ApplyOptions applies the given update options on these options,
|
||||
// and then returns itself (for convenient chaining).
|
||||
func (o *UpdateOptions) ApplyOptions(opts []UpdateOption) *UpdateOptions {
|
||||
for _, opt := range opts {
|
||||
opt.ApplyToUpdate(o)
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
var _ UpdateOption = &UpdateOptions{}
|
||||
|
||||
// ApplyToUpdate implements UpdateOption
|
||||
func (o *UpdateOptions) ApplyToUpdate(uo *UpdateOptions) {
|
||||
if o.DryRun != nil {
|
||||
uo.DryRun = o.DryRun
|
||||
}
|
||||
if o.FieldManager != "" {
|
||||
uo.FieldManager = o.FieldManager
|
||||
}
|
||||
if o.Raw != nil {
|
||||
uo.Raw = o.Raw
|
||||
}
|
||||
}
|
||||
|
||||
// UpdateDryRunAll sets the "dry run" option to "all".
|
||||
//
|
||||
// Deprecated: Use DryRunAll
|
||||
var UpdateDryRunAll = DryRunAll
|
||||
|
||||
// }}}
|
||||
|
||||
// {{{ Patch Options
|
||||
|
||||
// PatchOptions contains options for patch requests.
|
||||
type PatchOptions struct {
|
||||
// When present, indicates that modifications should not be
|
||||
// persisted. An invalid or unrecognized dryRun directive will
|
||||
// result in an error response and no further processing of the
|
||||
// request. Valid values are:
|
||||
// - All: all dry run stages will be processed
|
||||
DryRun []string
|
||||
|
||||
// Force is going to "force" Apply requests. It means user will
|
||||
// re-acquire conflicting fields owned by other people. Force
|
||||
// flag must be unset for non-apply patch requests.
|
||||
// +optional
|
||||
Force *bool
|
||||
|
||||
// FieldManager is the name of the user or component submitting
|
||||
// this request. It must be set with server-side apply.
|
||||
FieldManager string
|
||||
|
||||
// Raw represents raw PatchOptions, as passed to the API server.
|
||||
Raw *metav1.PatchOptions
|
||||
|
||||
// URLOption overwrites an GVK based API URL.
|
||||
URLOption *URLOptions
|
||||
|
||||
// Workspace represents the workspace for object that patching.
|
||||
Workspace *WorkspaceOptions
|
||||
}
|
||||
|
||||
// ApplyOptions applies the given patch options on these options,
|
||||
// and then returns itself (for convenient chaining).
|
||||
func (o *PatchOptions) ApplyOptions(opts []PatchOption) *PatchOptions {
|
||||
for _, opt := range opts {
|
||||
opt.ApplyToPatch(o)
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
// AsPatchOptions returns these options as a metav1.PatchOptions.
|
||||
// This may mutate the Raw field.
|
||||
func (o *PatchOptions) AsPatchOptions() *metav1.PatchOptions {
|
||||
if o == nil {
|
||||
return &metav1.PatchOptions{}
|
||||
}
|
||||
if o.Raw == nil {
|
||||
o.Raw = &metav1.PatchOptions{}
|
||||
}
|
||||
|
||||
o.Raw.DryRun = o.DryRun
|
||||
o.Raw.Force = o.Force
|
||||
o.Raw.FieldManager = o.FieldManager
|
||||
return o.Raw
|
||||
}
|
||||
|
||||
var _ PatchOption = &PatchOptions{}
|
||||
|
||||
// ApplyToPatch implements PatchOptions
|
||||
func (o *PatchOptions) ApplyToPatch(po *PatchOptions) {
|
||||
if o.DryRun != nil {
|
||||
po.DryRun = o.DryRun
|
||||
}
|
||||
if o.Force != nil {
|
||||
po.Force = o.Force
|
||||
}
|
||||
if o.FieldManager != "" {
|
||||
po.FieldManager = o.FieldManager
|
||||
}
|
||||
if o.Raw != nil {
|
||||
po.Raw = o.Raw
|
||||
}
|
||||
if o.URLOption != nil {
|
||||
po.URLOption = o.URLOption
|
||||
}
|
||||
if o.Workspace != nil {
|
||||
po.Workspace = o.Workspace
|
||||
}
|
||||
}
|
||||
|
||||
// ForceOwnership indicates that in case of conflicts with server-side apply,
|
||||
// the client should acquire ownership of the conflicting field. Most
|
||||
// controllers should use this.
|
||||
var ForceOwnership = forceOwnership{}
|
||||
|
||||
type forceOwnership struct{}
|
||||
|
||||
func (forceOwnership) ApplyToPatch(opts *PatchOptions) {
|
||||
definitelyTrue := true
|
||||
opts.Force = &definitelyTrue
|
||||
}
|
||||
|
||||
// PatchDryRunAll sets the "dry run" option to "all".
|
||||
//
|
||||
// Deprecated: Use DryRunAll
|
||||
var PatchDryRunAll = DryRunAll
|
||||
|
||||
// }}}
|
||||
|
||||
// {{{ DeleteAllOf Options
|
||||
|
||||
// these are all just delete options and list options
|
||||
|
||||
// DeleteAllOfOptions contains options for deletecollection (deleteallof) requests.
|
||||
// It's just list and delete options smooshed together.
|
||||
type DeleteAllOfOptions struct {
|
||||
ListOptions
|
||||
DeleteOptions
|
||||
}
|
||||
|
||||
// ApplyOptions applies the given deleteallof options on these options,
|
||||
// and then returns itself (for convenient chaining).
|
||||
func (o *DeleteAllOfOptions) ApplyOptions(opts []DeleteAllOfOption) *DeleteAllOfOptions {
|
||||
for _, opt := range opts {
|
||||
opt.ApplyToDeleteAllOf(o)
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
var _ DeleteAllOfOption = &DeleteAllOfOptions{}
|
||||
|
||||
// ApplyToDeleteAllOf implements DeleteAllOfOption
|
||||
func (o *DeleteAllOfOptions) ApplyToDeleteAllOf(do *DeleteAllOfOptions) {
|
||||
o.ApplyToList(&do.ListOptions)
|
||||
o.ApplyToDelete(&do.DeleteOptions)
|
||||
}
|
||||
|
||||
// }}}
|
||||
26
vendor/modules.txt
vendored
26
vendor/modules.txt
vendored
@@ -5,11 +5,11 @@ github.com/Azure/go-ansiterm
|
||||
github.com/Azure/go-ansiterm/winterm
|
||||
# github.com/BurntSushi/toml v0.3.1 => github.com/BurntSushi/toml v0.3.1
|
||||
github.com/BurntSushi/toml
|
||||
# github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd => github.com/MakeNowJust/heredoc v0.0.0-20171113091838-e9091a26100e
|
||||
# github.com/MakeNowJust/heredoc v0.0.0-20171113091838-e9091a26100e => github.com/MakeNowJust/heredoc v0.0.0-20171113091838-e9091a26100e
|
||||
github.com/MakeNowJust/heredoc
|
||||
# github.com/Masterminds/semver/v3 v3.1.0 => github.com/Masterminds/semver/v3 v3.0.1
|
||||
github.com/Masterminds/semver/v3
|
||||
# github.com/Microsoft/go-winio v0.4.11 => github.com/Microsoft/go-winio v0.4.12
|
||||
# github.com/Microsoft/go-winio v0.4.12 => github.com/Microsoft/go-winio v0.4.12
|
||||
github.com/Microsoft/go-winio
|
||||
# github.com/NYTimes/gziphandler v1.1.1 => github.com/NYTimes/gziphandler v1.1.1
|
||||
github.com/NYTimes/gziphandler
|
||||
@@ -139,7 +139,7 @@ github.com/docker/go-connections/sockets
|
||||
github.com/docker/go-connections/tlsconfig
|
||||
# github.com/docker/go-units v0.4.0 => github.com/docker/go-units v0.4.0
|
||||
github.com/docker/go-units
|
||||
# github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96 => github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c
|
||||
# github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c => github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c
|
||||
github.com/docker/spdystream
|
||||
github.com/docker/spdystream/spdy
|
||||
# github.com/edsrzf/mmap-go v1.0.0 => github.com/edsrzf/mmap-go v1.0.0
|
||||
@@ -161,9 +161,9 @@ github.com/elastic/go-elasticsearch/v7/estransport
|
||||
github.com/elastic/go-elasticsearch/v7/internal/version
|
||||
# github.com/emicklei/go-restful v2.14.3+incompatible => github.com/emicklei/go-restful v2.14.3+incompatible
|
||||
github.com/emicklei/go-restful
|
||||
github.com/emicklei/go-restful/log
|
||||
# github.com/emicklei/go-restful-openapi v1.4.1 => github.com/emicklei/go-restful-openapi v1.4.1
|
||||
github.com/emicklei/go-restful-openapi
|
||||
github.com/emicklei/go-restful/log
|
||||
# github.com/emirpasic/gods v1.12.0 => github.com/emirpasic/gods v1.12.0
|
||||
github.com/emirpasic/gods/containers
|
||||
github.com/emirpasic/gods/lists
|
||||
@@ -228,7 +228,7 @@ github.com/go-redis/redis/internal/hashtag
|
||||
github.com/go-redis/redis/internal/pool
|
||||
github.com/go-redis/redis/internal/proto
|
||||
github.com/go-redis/redis/internal/util
|
||||
# github.com/go-resty/resty/v2 v2.5.0
|
||||
# github.com/go-resty/resty/v2 v2.5.0 => github.com/go-resty/resty/v2 v2.5.0
|
||||
github.com/go-resty/resty/v2
|
||||
# github.com/go-sql-driver/mysql v1.5.0 => github.com/go-sql-driver/mysql v1.5.0
|
||||
github.com/go-sql-driver/mysql
|
||||
@@ -291,7 +291,7 @@ github.com/googleapis/gnostic/compiler
|
||||
github.com/googleapis/gnostic/extensions
|
||||
# github.com/gorilla/websocket v1.4.1 => github.com/gorilla/websocket v1.4.1
|
||||
github.com/gorilla/websocket
|
||||
# github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 => github.com/gregjones/httpcache v0.0.0-20181110185634-c63ab54fda8f
|
||||
# github.com/gregjones/httpcache v0.0.0-20181110185634-c63ab54fda8f => github.com/gregjones/httpcache v0.0.0-20181110185634-c63ab54fda8f
|
||||
github.com/gregjones/httpcache
|
||||
github.com/gregjones/httpcache/diskcache
|
||||
# github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 => github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
|
||||
@@ -320,7 +320,7 @@ github.com/jbenet/go-context/io
|
||||
github.com/jmespath/go-jmespath
|
||||
# github.com/json-iterator/go v1.1.10 => github.com/json-iterator/go v1.1.10
|
||||
github.com/json-iterator/go
|
||||
# github.com/jszwec/csvutil v1.5.0
|
||||
# github.com/jszwec/csvutil v1.5.0 => github.com/jszwec/csvutil v1.5.0
|
||||
github.com/jszwec/csvutil
|
||||
# github.com/kevinburke/ssh_config v0.0.0-20180830205328-81db2a75821e => github.com/kevinburke/ssh_config v0.0.0-20180830205328-81db2a75821e
|
||||
github.com/kevinburke/ssh_config
|
||||
@@ -494,6 +494,9 @@ github.com/projectcalico/libcalico-go/lib/set
|
||||
# github.com/prometheus-community/prom-label-proxy v0.2.0 => github.com/prometheus-community/prom-label-proxy v0.2.0
|
||||
github.com/prometheus-community/prom-label-proxy/injectproxy
|
||||
# github.com/prometheus-operator/prometheus-operator v0.42.2-0.20200928114327-fbd01683839a => 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-operator/prometheus-operator/pkg/apis/monitoring v0.42.1
|
||||
github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring
|
||||
github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1
|
||||
github.com/prometheus-operator/prometheus-operator/pkg/client/informers/externalversions
|
||||
github.com/prometheus-operator/prometheus-operator/pkg/client/informers/externalversions/internalinterfaces
|
||||
github.com/prometheus-operator/prometheus-operator/pkg/client/informers/externalversions/monitoring
|
||||
@@ -504,9 +507,6 @@ github.com/prometheus-operator/prometheus-operator/pkg/client/versioned/fake
|
||||
github.com/prometheus-operator/prometheus-operator/pkg/client/versioned/scheme
|
||||
github.com/prometheus-operator/prometheus-operator/pkg/client/versioned/typed/monitoring/v1
|
||||
github.com/prometheus-operator/prometheus-operator/pkg/client/versioned/typed/monitoring/v1/fake
|
||||
# github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.42.1 => github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.42.1
|
||||
github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring
|
||||
github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1
|
||||
# github.com/prometheus/alertmanager v0.21.0 => github.com/prometheus/alertmanager v0.20.0
|
||||
github.com/prometheus/alertmanager/api/v2/client
|
||||
github.com/prometheus/alertmanager/api/v2/client/alert
|
||||
@@ -571,7 +571,7 @@ github.com/russross/blackfriday
|
||||
github.com/sergi/go-diff/diffmatchpatch
|
||||
# github.com/sirupsen/logrus v1.6.0 => github.com/sirupsen/logrus v1.4.2
|
||||
github.com/sirupsen/logrus
|
||||
# github.com/sony/sonyflake v1.0.0 => github.com/sony/sonyflake v0.0.0-20181109022403-6d5bd6181009
|
||||
# github.com/sony/sonyflake v0.0.0-20181109022403-6d5bd6181009 => github.com/sony/sonyflake v0.0.0-20181109022403-6d5bd6181009
|
||||
github.com/sony/sonyflake
|
||||
# github.com/speps/go-hashids v2.0.0+incompatible => github.com/speps/go-hashids v2.0.0+incompatible
|
||||
github.com/speps/go-hashids
|
||||
@@ -614,7 +614,7 @@ github.com/uber/jaeger-lib/metrics
|
||||
github.com/xanzy/ssh-agent
|
||||
# github.com/yashtewari/glob-intersection v0.0.0-20180916065949-5c77d914dd0b => github.com/yashtewari/glob-intersection v0.0.0-20180916065949-5c77d914dd0b
|
||||
github.com/yashtewari/glob-intersection
|
||||
# go.etcd.io/etcd v3.3.17+incompatible => go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738
|
||||
# go.etcd.io/etcd v0.5.0-alpha.5.0.20200520232829-54ba9589114f => go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738
|
||||
go.etcd.io/etcd/auth/authpb
|
||||
go.etcd.io/etcd/clientv3
|
||||
go.etcd.io/etcd/clientv3/balancer
|
||||
@@ -1585,7 +1585,7 @@ kubesphere.io/client-go/client
|
||||
kubesphere.io/client-go/client/generic
|
||||
kubesphere.io/client-go/restclient
|
||||
kubesphere.io/client-go/restclient/versioned/iam/v1alpha2
|
||||
# kubesphere.io/monitoring-dashboard v0.1.2
|
||||
# kubesphere.io/monitoring-dashboard v0.1.2 => kubesphere.io/monitoring-dashboard v0.1.2
|
||||
kubesphere.io/monitoring-dashboard/api/v1alpha1
|
||||
kubesphere.io/monitoring-dashboard/api/v1alpha1/panels
|
||||
# sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.7 => sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.7
|
||||
|
||||
Reference in New Issue
Block a user