mirror of https://github.com/knative/client.git
upgrade to latest dependencies (#1207)
bumping knative.dev/hack 8d623a0...8368e1f: > 8368e1f guard against set -o unset (# 49) > 2b4f6fc disable go's proxy and sumdb only for knative deps (# 47) bumping knative.dev/networking 8b522a9...e24bdfe: > e24bdfe upgrade to latest dependencies (# 350) > ab1235e Bump a few assorted dependencies to their latest versions (# 349) > 45b7ed1 Add ingress conformance test to ensure we do not add retries (# 348) >b61da13upgrade to latest dependencies (# 347) > d2088ff Update common github actions (# 346) > c069ad2 Create prober request with context right away (# 344) > 342a3fb upgrade to latest dependencies (# 342) > 94433ab upgrade to latest dependencies (# 341) bumping knative.dev/pkg 6040b3a...a02dcff: > a02dcff Bump a few assorted dependencies to their latest versions (# 2013) > 4b2ae07 Replace deprecated github.com/markbates/inflect with github.com/gobuffalo/flect (# 2014) > 8878069 upgrade to latest dependencies (# 2010) > c493a9e Update common github actions (# 2009) > 6045ed4 Allow setting DisableCompression in NewAutoTransport (# 2007) > ca02ef7 Genreconciler properly generates reconciler for Resources with Status (# 2004) > 0d31134 Fix nil pointer panic in kvstore (# 2002) bumping knative.dev/serving e61294b...8751d91: > 8751d91 Split the reconcile rollout into its own function (# 10722) > 2b95084 Optimize the execution path around logging (# 10720) > bbca20f Update net-contour nightly (# 10715) > ef39273 upgrade to latest dependencies (# 10719) > 6449fb8 upgrade to latest dependencies (# 10717) > 45a435a Update net-kourier nightly (# 10706) > 2fbef5f upgrade to latest dependencies (# 10713) > c4ea4ad Fix the analyzer config for load-testing benchmark since it must have a value (# 10709) > 6f46354 Apply k8s default values for readiness probe (# 10700) > 8c4b2ff Update net-certmanager nightly (# 10705) > b6f618b Update net-istio nightly (# 10704) > 390f2c2 bump k8s min in DEVELOPMENT.md (# 10699) > f2ccdd5 tests (# 10702) > 2090edf Update net-istio nightly (# 10695) > 789455d Update net-certmanager nightly (# 10674) > 1c61d3b Update common github actions (# 10697) > 2bc3650 Update net-kourier nightly (# 10696) > 8c64d92 Format markdown (# 10698) > 0e77ab2 Update net-kourier nightly (# 10676) > dd96a0a Update net-contour nightly (# 10686) > 8fbcfb0 Unpin the istio version and temporarily disable the error rate check analyzer (# 10655) > 58550fd Avoid adding gzip-encoding to requests implicitly (# 10691) > 60cdc35 Move Multi Container test to Beta (# 10683) > ae7b278 Update net-istio nightly (# 10687) > 7a18f38 Fix some nits in e2e tests (# 10678) > 9c572cd Allow to specify build platform for test images (# 10672) > 0ee79dd Remove the unsed struct items (# 10684) > 29da3af Improve debuggability of SKS logs (# 10679) > 8e1d587 upgrade to latest dependencies (# 10682) > aef0145 Temporarily disable auto TLS test with HTTP01 challenge (# 10685) > 32b0292 Use lister instead of client to directly get ClusterDomainClaim (# 10677) > a19ff15 Update net-istio nightly (# 10675) > 6313088 Allow kpa to work with timeout in context (# 10673) > af7af61 Perform some test helper cleanup (# 10670) >93d2449upgrade to latest dependencies (# 10671) > 888331e Remove the service name from the internal traffic target object. (# 10669) > 1901e4c Use consistent alias for autoscaler v1alpha1 everywhere (# 10666) > 1e070a3 Remove context from MakeDecider (# 10657) > 452bed5 Further remove usage of the context in the scale runner (# 10653) > a1ee2ec bump ggcr & k8schain (# 10651) > 81818f9 Fix logging of errors in stats scraper (# 10654) > 1b0f43c Hide implementation detail inside a function (# 10652) > 756fd17 Update net-istio nightly (# 10648) > 6d46d52 Add support for decoding Revision from Host. (# 10647) > 01fa1a0 Remove the time computation (# 10645) > dbccf2a Do not pass context to the scale, but logger instead (# 10646) > ab176fa Rename back to the non deprecated name (# 10640) > fae6549 Update net-contour nightly (# 10644) > 5cd4f64 Update net-istio nightly (# 10643) > fbbbb98 Make route stop using the `DeprecatedServiceName` field (# 10638) > bf35e3f 💄 updating the HPAs to v2beta2 API usage (# 10631) > 51a9c0b Update net-certmanager nightly (# 10636) > e5c5c08 Export MESH env value in test script (# 10635) > 4a3274c Remove unused constants, make some other small tidy-ups (# 10637) > b083383 fix the broken doc's link (# 10634) > aac0df2 Deprecate the service name on the revision. (# 10633) > 0aa3d0b Remove the propagation from SKS->PA->Rev.Status of the K8s service (# 10632) > db90f4f Update net-contour nightly (# 10597) > 981c601 Update net-istio nightly (# 10619) > 8922f35 Update net-kourier nightly (# 10599) > df11c15 chore: Set background to white for autoscaling diagrams ... (# 10629) > f637b5a Remove naked returns (# 10618) > 6cde241 Improve rollout test to check duration (# 10625) > 7700811 At 100ms we still see failures on prow (# 10626) > c081a82 Make the singlethreaded code simpler by using boolean guard (# 10624) > 55a7edf upgrade to latest dependencies (# 10627) > 53d4d5b Fix some annoying nits in the route e2e tests (# 10623) > 2c781c7 upgrade to latest dependencies (# 10620) > 6dba44a The year was 2021.. (# 10621) > 39d33bf upgrade to latest dependencies (# 10617) bumping golang.org/x/term 7de9c90...2321bbc: > 2321bbc Update doc to use "term" instead of "terminal" > ee85cb9 README.md: add badge to pkg.go.dev bumping knative.dev/eventing ea452b5...3fcb645: > 3fcb645 🌀 Remvoing contrib refs (# 4855) > f05561d upgrade to latest dependencies (# 4853) > 37eaf71 switch Harwayne with antoineco (# 4850) > b887ac4 upgrade to latest dependencies (# 4848) > daa085d Format markdown (# 4846) > 3d51c72 Change trigger spec to indicate assigned broker should be immutable (# 4828) > 1774243 Add immutable fields validation to v1beta1 broker (# 4816) > 935d5fb Format markdown (# 4840) > 269b061 Update common github actions (# 4839) > 152e608 upgrade to latest dependencies (# 4841) > 8171448 Adding Logline for when a cloudevent has been successfully sent from APIServerSource to the sink (# 4723) > fd2688d Use SHOULD for TriggerSpec to keep compatibility (# 4838) > 1fa597e [# 4796] Bump golang lint timeout to 10m (# 4830) > a4a9f48 Format markdown (# 4829) > d58bd38 fix the link to head (# 4826) > 39d7a9e remove unused functions (# 4824) > 6edcbdd Panic in shared main to propagate error to exit code (# 4820) > 012a9bd v1beta1.Trigger delivery should be v1.DeliverySpec (# 4822) > 321a839 Format markdown (# 4823) > ec63881 Fix spec # 4515 (# 4654) > 1528750 upgrade to latest dependencies (# 4818) > 9dc57e2 Update common github actions (# 4817) > b20c96b sinkbing implement bindable (# 4794) > 8d51418 Bump golang linter version and timeout (# 4808) > f882ff0 Add availability rate to upgrade test report (# 4555) > a6635bb Patch HPA eventing-webhook min replicas (# 4811) > d46c1d0 It is already 2021 (# 4809) > fb8fbf7 Adding new source conformance testcase for CRD RBAC (# 4787) > 1725902 Update COMMUNITY_CONTACTS.md test grid link (# 4798) > b75d03a Adding new source conformance testcase for CRD Source Registry Spec (# 4780) > 77fc350 upgrade to latest dependencies (# 4797) Signed-off-by: Knative Automation <automation@knative.team>
This commit is contained in:
parent
1499be95c7
commit
72aeb1c820
12
go.mod
12
go.mod
|
|
@ -14,7 +14,7 @@ require (
|
|||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5
|
||||
github.com/spf13/viper v1.7.0
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1
|
||||
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf
|
||||
gopkg.in/ini.v1 v1.56.0 // indirect
|
||||
gotest.tools v2.2.0+incompatible
|
||||
k8s.io/api v0.19.7
|
||||
|
|
@ -22,11 +22,11 @@ require (
|
|||
k8s.io/cli-runtime v0.19.7
|
||||
k8s.io/client-go v0.19.7
|
||||
k8s.io/code-generator v0.19.7
|
||||
knative.dev/eventing v0.20.1-0.20210127134430-ea452b5b6655
|
||||
knative.dev/hack v0.0.0-20210120165453-8d623a0af457
|
||||
knative.dev/networking v0.0.0-20210123150554-8b522a9049a1
|
||||
knative.dev/pkg v0.0.0-20210125222030-6040b3af4803
|
||||
knative.dev/serving v0.20.1-0.20210123202654-e61294b2ca32
|
||||
knative.dev/eventing v0.20.1-0.20210209112550-3fcb64522f45
|
||||
knative.dev/hack v0.0.0-20210203173706-8368e1f6eacf
|
||||
knative.dev/networking v0.0.0-20210209030528-e24bdfe91d90
|
||||
knative.dev/pkg v0.0.0-20210208175252-a02dcff9ee26
|
||||
knative.dev/serving v0.20.1-0.20210209061117-8751d9125712
|
||||
sigs.k8s.io/yaml v1.2.0
|
||||
)
|
||||
|
||||
|
|
|
|||
240
go.sum
240
go.sum
|
|
@ -41,21 +41,21 @@ contrib.go.opencensus.io/exporter/prometheus v0.2.1-0.20200609204449-6bcf6f8577f
|
|||
contrib.go.opencensus.io/exporter/prometheus v0.2.1-0.20200609204449-6bcf6f8577f0/go.mod h1:MjHoxkI7Ny27toPeFkRbXbzVjzIGkwOAptrAy8Mxtm8=
|
||||
contrib.go.opencensus.io/exporter/stackdriver v0.13.4 h1:ksUxwH3OD5sxkjzEqGxNTl+Xjsmu3BnC/300MhSVTSc=
|
||||
contrib.go.opencensus.io/exporter/stackdriver v0.13.4/go.mod h1:aXENhDJ1Y4lIg4EUaVTwzvYETVNZk10Pu26tevFKLUc=
|
||||
contrib.go.opencensus.io/exporter/stackdriver v0.13.5 h1:TNaexHK16gPUoc7uzELKOU7JULqccn1NDuqUxmxSqfo=
|
||||
contrib.go.opencensus.io/exporter/stackdriver v0.13.5/go.mod h1:aXENhDJ1Y4lIg4EUaVTwzvYETVNZk10Pu26tevFKLUc=
|
||||
contrib.go.opencensus.io/exporter/zipkin v0.1.2/go.mod h1:mP5xM3rrgOjpn79MM8fZbj3gsxcuytSqtH0dxSWW1RE=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/Azure/azure-sdk-for-go v35.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/azure-sdk-for-go v38.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/azure-sdk-for-go v42.3.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/azure-sdk-for-go v43.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/azure-sdk-for-go v50.2.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
|
||||
github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
|
||||
github.com/Azure/go-autorest/autorest v0.9.3/go.mod h1:GsRuLYvwzLjjjRoWEIyMUaYq8GNUx2nRB378IPt/1p0=
|
||||
github.com/Azure/go-autorest/autorest v0.9.6/go.mod h1:/FALq9T/kS7b5J5qsQ+RSTUdAmGFqi0vUdVNNx8q630=
|
||||
github.com/Azure/go-autorest/autorest v0.10.2/go.mod h1:/FALq9T/kS7b5J5qsQ+RSTUdAmGFqi0vUdVNNx8q630=
|
||||
github.com/Azure/go-autorest/autorest v0.11.17/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.8.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.8.2/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.10/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A=
|
||||
github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA=
|
||||
github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g=
|
||||
github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74=
|
||||
|
|
@ -65,15 +65,17 @@ github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN
|
|||
github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
|
||||
github.com/Azure/go-autorest/autorest/to v0.2.0/go.mod h1:GunWKJp1AEqgMaGLV+iocmRAJWqST1wQYhyyjXJ3SJc=
|
||||
github.com/Azure/go-autorest/autorest/to v0.3.0/go.mod h1:MgwOyqaIuKdG4TL/2ywSsIWKAfJfgHDo8ObuUk3t5sA=
|
||||
github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE=
|
||||
github.com/Azure/go-autorest/autorest/validation v0.1.0/go.mod h1:Ha3z/SqBeaalWQvokg3NZAlQTalVMtOIAs1aGK7G6u8=
|
||||
github.com/Azure/go-autorest/autorest/validation v0.2.0/go.mod h1:3EEqHnBxQGHXRYq3HT1WyXAvT7LLY3tl70hw6tQIbjI=
|
||||
github.com/Azure/go-autorest/autorest/validation v0.3.1/go.mod h1:yhLgjC0Wda5DYXl6JAsWyUe4KVNffhoDhG0zVzUMo3E=
|
||||
github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc=
|
||||
github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
|
||||
github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
|
||||
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
|
||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20190822182118-27a4ced34534/go.mod h1:iroGtC8B3tQiqtds1l+mgk/BBOrxbqjH+eUfFQYRc14=
|
||||
github.com/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20200415212048-7901bc822317/go.mod h1:DF8FZRxMHMGv/vP2lQP6h+dYzzjpuRn24VeRiYn3qjQ=
|
||||
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
|
||||
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
|
||||
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
||||
|
|
@ -113,9 +115,10 @@ github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQ
|
|||
github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/aws/aws-sdk-go v1.28.2/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/aws/aws-sdk-go v1.31.6/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
|
||||
github.com/aws/aws-sdk-go v1.31.12 h1:SxRRGyhlCagI0DYkhOg+FgdXGXzRTE3vEX/gsgFaiKQ=
|
||||
github.com/aws/aws-sdk-go v1.31.12/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
|
||||
github.com/aws/aws-sdk-go v1.37.1 h1:BTHmuN+gzhxkvU9sac2tZvaY0gV9ihbHw+KxZOecYvY=
|
||||
github.com/aws/aws-sdk-go v1.37.1/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
|
||||
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
|
|
@ -149,29 +152,26 @@ github.com/cloudevents/sdk-go/v2 v2.2.0 h1:FlBJg7W0QywbOjuZGmRXUyFk8qkCHx2euETp+
|
|||
github.com/cloudevents/sdk-go/v2 v2.2.0/go.mod h1:3CTrpB4+u7Iaj6fd7E2Xvm5IxMdRoaAhqaRVnOr2rCU=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
|
||||
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
|
||||
github.com/containerd/containerd v1.3.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.0.0-20201223015020-a9a0c2d64694/go.mod h1:E9uVkkBKf0EaC39j2JVW9EzdNhYvpz6eQIjILHebruk=
|
||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
|
||||
github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk=
|
||||
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
|
|
@ -182,11 +182,10 @@ github.com/dgryski/go-lttb v0.0.0-20180810165845-318fcdf10a77/go.mod h1:Va5MyIzk
|
|||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||
github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
|
||||
github.com/docker/cli v0.0.0-20191017083524-a8ff7f821017/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/cli v0.0.0-20200210162036-a4bedce16568/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/cli v20.10.2+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker v1.4.2-0.20190924003213-a8608b5b67c7/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker v1.13.1/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker v20.10.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y=
|
||||
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||
github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
|
|
@ -203,13 +202,15 @@ github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkg
|
|||
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
|
||||
github.com/emicklei/go-restful v2.9.5+incompatible h1:spTtZBk5DYEvbxMVutUuTyh1Ao2r4iyvLdACqsl/Ljk=
|
||||
github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
|
||||
github.com/emicklei/go-restful v2.15.0+incompatible h1:8KpYO/Xl/ZudZs5RNOEhWMBY4hmzlZhhRd9cu+jrZP4=
|
||||
github.com/emicklei/go-restful v2.15.0+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
|
||||
github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/evanphx/json-patch v0.0.0-20200808040245-162e5629780b/go.mod h1:NAJj0yf/KaRKURN6nyi7A9IZydMivZEm9oQLWNjfKDc=
|
||||
github.com/evanphx/json-patch v4.5.0+incompatible h1:ouOWdg56aJriqS0huScTkVXPC5IcNrDCXZ6OoTAWu7M=
|
||||
github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/evanphx/json-patch v4.9.0+incompatible h1:kLcOMZeuLAJvL2BPWLMIj5oaZQobrkAqrL+WFZwQses=
|
||||
|
|
@ -239,6 +240,8 @@ github.com/go-logr/logr v0.1.0 h1:M1Tv3VzNlEHg6uyACnRdtrploV2P7wZqH8BoQMtz0cg=
|
|||
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
|
||||
github.com/go-logr/logr v0.2.0 h1:QvGt2nLcHH0WK9orKa+ppBPAxREcH364nPUedEpK0TY=
|
||||
github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
|
||||
github.com/go-logr/logr v0.4.0 h1:K7/B1jt6fIBQVd4Owv2MqGQClcgf0R266+7C/QjRcLc=
|
||||
github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
|
||||
github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI=
|
||||
github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
|
||||
github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
|
||||
|
|
@ -288,13 +291,15 @@ github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LB
|
|||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/gobuffalo/envy v1.6.5/go.mod h1:N+GkhhZ/93bGZc6ZKhJLP6+m+tCNPKwgSpH9kaifseQ=
|
||||
github.com/gobuffalo/envy v1.7.1/go.mod h1:FurDp9+EDPE4aIUS3ZLyD+7/9fpx7YRt/ukY6jIHf0w=
|
||||
github.com/gobuffalo/flect v0.2.2/go.mod h1:vmkQwuZYhN5Pc4ljYQZzP+1sq+NEkK+lh20jmEmX3jc=
|
||||
github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||
github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||
github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
|
||||
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
|
|
@ -310,7 +315,6 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt
|
|||
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
||||
github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
|
|
@ -349,16 +353,19 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
|||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M=
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-containerregistry v0.2.1 h1:LLZgLTDguTVJ9eEHh/zTtr347CpFhH6MSYculNas5bY=
|
||||
github.com/google/go-containerregistry v0.2.1/go.mod h1:Ts3Wioz1r5ayWx8sS6vLcWltWcM1aqFjd/eVrkFhrWM=
|
||||
github.com/google/go-containerregistry v0.4.1-0.20210128200529-19c2b639fab1 h1:o2ykCuuhHeUwtzNg89pH2hi+821aqjLWkaREVR3ziTQ=
|
||||
github.com/google/go-containerregistry v0.4.1-0.20210128200529-19c2b639fab1/go.mod h1:GU9FUA/X9rd2cV3ZoUNaWihp27tki6/38EsVzL2Dyzc=
|
||||
github.com/google/go-containerregistry/pkg/authn/k8schain v0.0.0-20210129212729-5c4818de4025/go.mod h1:n9wRxRfKkHy6ZFyj0jJQHw11P+mGLnED4sqegwrXxDk=
|
||||
github.com/google/go-github/v27 v27.0.6/go.mod h1:/0Gr8pJ55COkmv+S/yPKCczSkUPIM/LnFyubufRNIS0=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
|
||||
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
||||
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/licenseclassifier v0.0.0-20200708223521-3d09a0ea2f39/go.mod h1:qsqn2hxC+vURpyBRygGUuinTO42MFRLcsmQ/P8v94+M=
|
||||
github.com/google/mako v0.0.0-20190821191249-122f8dcef9e3/go.mod h1:YzLcVlL+NqWnmUEPuhS1LxDDwGO9WNbVlEXaF4IH35g=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
|
|
@ -378,16 +385,15 @@ github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
|
|||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs=
|
||||
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
|
||||
github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
|
||||
github.com/googleapis/gnostic v0.2.2/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
|
||||
github.com/googleapis/gnostic v0.4.0 h1:BXDUo8p/DaxC+4FJY/SSx3gvnx9C1VdHNgaUkiEL5mk=
|
||||
github.com/googleapis/gnostic v0.4.0/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU=
|
||||
github.com/googleapis/gnostic v0.4.1 h1:DLJCy1n/vrD4HPjOvYcT8aYQXpPIzoRZONaYwyycI+I=
|
||||
github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg=
|
||||
github.com/googleapis/gnostic v0.5.3 h1:2qsuRm+bzgwSIKikigPASa2GhW8H2Dn4Qq7UxD8K/48=
|
||||
github.com/googleapis/gnostic v0.5.3/go.mod h1:TRWw1s4gxBGjSe301Dai3c7wXJAZy57+/6tawkOvqHQ=
|
||||
github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
|
|
@ -452,15 +458,17 @@ github.com/influxdata/tdigest v0.0.0-20180711151920-a7d76c6f093a/go.mod h1:9Gkys
|
|||
github.com/influxdata/tdigest v0.0.0-20181121200506-bf2b5ad3c0a9/go.mod h1:Js0mqiSBE6Ffsg94weZZ2c+v/ciT8QRHFOap7EKDrR0=
|
||||
github.com/influxdata/tdigest v0.0.0-20191024211133-5d87a7585faa/go.mod h1:Z0kXnxzbTC2qrx4NaIzYkE1k66+6oEDQTvL95hQFh5Y=
|
||||
github.com/influxdata/tdigest v0.0.1/go.mod h1:Z0kXnxzbTC2qrx4NaIzYkE1k66+6oEDQTvL95hQFh5Y=
|
||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
github.com/jmespath/go-jmespath v0.3.0 h1:OS12ieG61fsCg5+qLJ+SsW9NicxNkg3b25OyT2yCeUc=
|
||||
github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik=
|
||||
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
|
||||
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
|
||||
github.com/joefitzgerald/rainbow-reporter v0.1.0/go.mod h1:481CNgqmVHQZzdIbN52CupLJyoVwB10FQ/IQlF1pdL8=
|
||||
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
||||
github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
|
|
@ -477,6 +485,7 @@ github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dv
|
|||
github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8=
|
||||
|
|
@ -536,7 +545,6 @@ github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/f
|
|||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
|
|
@ -580,10 +588,11 @@ github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE=
|
|||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/onsi/gomega v1.10.2 h1:aY/nuoWlKJud2J6U0E3NWsjlg+0GtwXxgEqthRdzlcs=
|
||||
github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/onsi/gomega v1.10.3 h1:gph6h/qe9GSUw1NhH1gp+qb+h8rXD8Cy60Z32Qw3ELA=
|
||||
github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc=
|
||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
|
||||
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||
github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
|
||||
github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
|
||||
github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
|
||||
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
|
|
@ -612,7 +621,6 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
|
|||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
|
||||
github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
||||
|
|
@ -626,6 +634,8 @@ github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeD
|
|||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||
github.com/prometheus/client_golang v1.8.0 h1:zvJNkoCFAnYFNC24FV8nW4JdRJ3GIFcLbg65lL/JDcw=
|
||||
github.com/prometheus/client_golang v1.8.0/go.mod h1:O9VU6huf47PktckDQfMTX0Y8tY0/7TSWwj+ITvv0TnM=
|
||||
github.com/prometheus/client_golang v1.9.0 h1:Rrch9mh17XcxvEu9D9DEpb4isxjGBtcevQjKvxPRQIU=
|
||||
github.com/prometheus/client_golang v1.9.0/go.mod h1:FqZLKOZnGdFAhOK4nqGHa7D66IdsO+O441Eve7ptJDU=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
|
|
@ -669,10 +679,8 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L
|
|||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.3.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rogpeppe/go-internal v1.5.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rs/dnscache v0.0.0-20190621150935-06bb5526f76b/go.mod h1:qe5TWALJ8/a1Lqznoc5BDHpYX/8HU60Hm2AwRmqzxqA=
|
||||
github.com/rubiojr/go-vhd v0.0.0-20160810183302-0bfd3b39853c/go.mod h1:DM5xW0nvfNNm2uytzsvhI3OnX8uzaRAg8UX/CnDqbto=
|
||||
github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/rs/dnscache v0.0.0-20210201191234-295bba877686/go.mod h1:qe5TWALJ8/a1Lqznoc5BDHpYX/8HU60Hm2AwRmqzxqA=
|
||||
github.com/rubiojr/go-vhd v0.0.0-20200706105327-02e210299021/go.mod h1:DM5xW0nvfNNm2uytzsvhI3OnX8uzaRAg8UX/CnDqbto=
|
||||
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
|
|
@ -689,6 +697,8 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB
|
|||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/assertions v1.0.0 h1:UVQPSSmc3qtTi+zPPkCXvZX9VvW/xT/NsRvKfwY81a8=
|
||||
github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM=
|
||||
|
|
@ -704,7 +714,6 @@ github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkU
|
|||
github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=
|
||||
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
||||
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
|
||||
github.com/spf13/cobra v1.0.1-0.20200715031239-b95db644ed1c h1:nt+V0u9zwtHQLk4OrQxVDMwJ7ifwoUzqcrcxySbmxxY=
|
||||
github.com/spf13/cobra v1.0.1-0.20200715031239-b95db644ed1c/go.mod h1:yk5b0mALVusDL5fMM6Rd1wgnoO5jUPhwsQ6LQAJTidQ=
|
||||
|
|
@ -716,11 +725,11 @@ github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn
|
|||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
||||
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
|
||||
github.com/spf13/viper v1.7.0 h1:xVKxvI7ouOI5I+U9s2eeiUfMaWBVoXA3AWskkrqK0VM=
|
||||
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
|
||||
github.com/sqs/goreturns v0.0.0-20181028201513-538ac6014518/go.mod h1:CKI4AZ4XmGV240rTHfO0hfE83S6/a3/Q1siZJ/vXf7A=
|
||||
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
|
||||
github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
|
||||
github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
|
||||
github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
|
||||
|
|
@ -728,7 +737,6 @@ github.com/streadway/quantile v0.0.0-20150917103942-b0c588724d25/go.mod h1:lbP8t
|
|||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
|
|
@ -746,12 +754,11 @@ github.com/tsenart/go-tsz v0.0.0-20180814235614-0bd30b3df1c3/go.mod h1:SWZznP1z5
|
|||
github.com/tsenart/vegeta v12.7.1-0.20190725001342-b5f4fca92137+incompatible/go.mod h1:Smz/ZWfhKRcyDDChZkG3CyTHdj87lHzio/HOCkbndXM=
|
||||
github.com/tsenart/vegeta/v12 v12.8.4/go.mod h1:ZiJtwLn/9M4fTPdMY7bdbIeyNeFVE8/AHbWFqCsUuho=
|
||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/vdemeester/k8s-pkg-credentialprovider v1.18.1-0.20201019120933-f1d16962a4db/go.mod h1:grWy0bkr1XO6hqbaaCKaPXqkBVlMGHYG6PGykktwbJc=
|
||||
github.com/vdemeester/k8s-pkg-credentialprovider v1.19.7/go.mod h1:K2nMO14cgZitdwBqdQps9tInJgcaXcU/7q5F59lpbNI=
|
||||
github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw=
|
||||
github.com/vmware/govmomi v0.20.3/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU=
|
||||
github.com/wavesoftware/go-ensure v1.0.0/go.mod h1:K2UAFSwMTvpiRGay/M3aEYYuurcR8S4A6HkQlJPV8k4=
|
||||
|
|
@ -780,6 +787,8 @@ go.opencensus.io v0.22.4 h1:LYy1Hy3MJdrCdMwwzxA/dRok4ejH+RwNGbuoD9fCjto=
|
|||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.5 h1:dntmOdLpSpHlVqbW5Eay97DelsZHe+55D+xC6i0dDS0=
|
||||
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
|
||||
go.opencensus.io v0.22.6 h1:BdkrbWrzDlV9dnbzoP7sfN+dHheJ4J9JOaYxcUDL+ok=
|
||||
go.opencensus.io v0.22.6/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
|
||||
go.opentelemetry.io/otel v0.16.0/go.mod h1:e4GKElweB8W2gWUqbghw0B8t5MCTccc9212eNHnOHwA=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
|
|
@ -789,6 +798,7 @@ go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
|||
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/automaxprocs v1.3.0/go.mod h1:9CWT6lKIep8U41DDaPiH6eFscnTyjfTANNQNx6LrIcA=
|
||||
go.uber.org/automaxprocs v1.4.0/go.mod h1:/mTEdr7LvHhs0v7mjdxDreTz1OG5zdZGqgOnhWiR/+Q=
|
||||
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
|
||||
|
|
@ -804,7 +814,6 @@ go.uber.org/zap v1.16.0 h1:uFRZXykJGK9lLY4HtgSw44DnIcAM+kRBP7x5m+NpAOM=
|
|||
go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
|
|
@ -816,10 +825,11 @@ golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8U
|
|||
golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0 h1:hb9wdF1z5waM+dSIICn1l0DkLVDT3hqhhQsDNUmHPRE=
|
||||
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY=
|
||||
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
|
|
@ -855,7 +865,8 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB
|
|||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/mod v0.4.1 h1:Kvvh58BN8Y9/lBi7hTekvtMpm07eUZ0ck5pRHpsMWrY=
|
||||
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
|
|
@ -882,7 +893,6 @@ golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLL
|
|||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
|
|
@ -898,12 +908,15 @@ golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/
|
|||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11 h1:lwlPPsmjDKK0J6eG6xDWd5XPehI0R024zxjDnw3esPA=
|
||||
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210119194325-5f4716e94777 h1:003p0dJM77cxMSyCPFphvZf/Y5/NXf5fzg6ufd1/Oew=
|
||||
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
|
|
@ -915,6 +928,8 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ
|
|||
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5 h1:Lm4OryKCca1vehdsWogr9N4t7NfZxLbJoc/H0w4K4S4=
|
||||
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210126194326-f9ce19ea3013 h1:55H5j7lotzuFCEOKDsMch+fRNUQ9DgtyHOUP31FNqKc=
|
||||
golang.org/x/oauth2 v0.0.0-20210126194326-f9ce19ea3013/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
|
|
@ -928,7 +943,6 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324
|
|||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a h1:DcqTD9SDLc+1P/r1EmRBwnVsrOwW+kk2vWf9n+1sGhs=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
|
|
@ -937,7 +951,6 @@ golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5h
|
|||
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
|
@ -957,7 +970,7 @@ golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191113165036-4c7a9d0fe056/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
|
@ -965,6 +978,7 @@ golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
|
@ -988,9 +1002,15 @@ golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3 h1:kzM6+9dur93BcC2kVlYl34cHU+TYZLanmpSJHVMmL64=
|
||||
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c h1:VwygUrnw9jn88c4u8GD3rZQbqrP/tgas88tPUbBxQrk=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf h1:MZ2shdL+ZM/XzY3ZGOnh4Nlpnxz5GSOhOmtHo3iPU6M=
|
||||
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
|
|
@ -999,6 +1019,8 @@ golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
|
|||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc=
|
||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ=
|
||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
|
|
@ -1006,6 +1028,8 @@ golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxb
|
|||
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e h1:EHBhcS0mlXEAVwNyO2dLfjToGsyY4j24pTs2ScHnX7s=
|
||||
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324 h1:Hir2P/De0WpUhtrKGGjvSb2YxUgyZ7EFOSLIcSSpiwE=
|
||||
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
|
|
@ -1033,7 +1057,6 @@ golang.org/x/tools v0.0.0-20190706070813-72ffa07ba3db/go.mod h1:jcCCGcm9btYwXyDq
|
|||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191010075000-0337d82405ff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
|
|
@ -1061,11 +1084,13 @@ golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjs
|
|||
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
||||
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200512001501-aaeff5de670a/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200616133436-c1934b75d054/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
|
|
@ -1076,6 +1101,10 @@ golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4f
|
|||
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201211185031-d93e913c1a58 h1:1Bs6RVeBFtLZ8Yi1Hk07DiOqzvwLD/4hln4iahvFlag=
|
||||
golang.org/x/tools v0.0.0-20201211185031-d93e913c1a58/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
|
@ -1090,7 +1119,6 @@ gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6d
|
|||
gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ=
|
||||
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
google.golang.org/api v0.6.1-0.20190607001116-5213b8090861/go.mod h1:btoxGiFvQNVUZQ8W08zLtrVS08CNpINPEfxXxgJL1Q4=
|
||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
||||
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
|
|
@ -1098,6 +1126,8 @@ google.golang.org/api v0.10.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhE
|
|||
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.15.1-0.20200106000736-b8fc810ca6b5/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.15.1/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
|
|
@ -1156,10 +1186,13 @@ google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6D
|
|||
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d h1:92D1fum1bJLKSdr11OJ+54YeCMCGYIygTA7R/YZxH5M=
|
||||
google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201211151036-40ec1c210f7a h1:GnJAhasbD8HiT8DZMvsEx3QLVy/X0icq/MGr0MqRJ2M=
|
||||
google.golang.org/genproto v0.0.0-20201211151036-40ec1c210f7a/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d h1:HV9Z9qMhQEsdlvxNFELgQ11RkMzO3CMkjEySjCtuLes=
|
||||
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
|
||||
|
|
@ -1182,6 +1215,8 @@ google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM
|
|||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
||||
google.golang.org/grpc v1.34.0 h1:raiipEjMOIC/TO2AvyTxP25XFdLxNIBwzDh3FM3XztI=
|
||||
google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
|
||||
google.golang.org/grpc v1.35.0 h1:TwIQcH3es+MojMVojxxfQ3l3OF2KzlRxML2xZq0kRo8=
|
||||
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
|
|
@ -1200,6 +1235,8 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8
|
|||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U=
|
||||
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/evanphx/json-patch.v4 v4.9.0 h1:T7W7A7+DTEpLTC11pkf8yfaeRfqhRj/gOPf+LtaJdNY=
|
||||
|
|
@ -1228,10 +1265,14 @@ gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20190709130402-674ba3eaed22/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
|
||||
|
|
@ -1245,89 +1286,62 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9
|
|||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
honnef.co/go/tools v0.0.1-2020.1.5 h1:nI5egYTGJakVyOryqLs1cQO5dO0ksin5XXs2pspk75k=
|
||||
honnef.co/go/tools v0.0.1-2020.1.5/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
k8s.io/api v0.18.8/go.mod h1:d/CXqwWv+Z2XEG1LgceeDmHQwpUJhROPx16SlxJgERY=
|
||||
k8s.io/api v0.18.12 h1:97X6znOXMVgCKivTAgpBXGBGlCe3gbM++yFdldgBCaE=
|
||||
k8s.io/api v0.18.12/go.mod h1:3sS78jmUoGHwERyMbEhxP6owcQ77UxGo+Yy+dKNWrh0=
|
||||
k8s.io/api v0.19.7 h1:MpHhls03C2pyzoYcpbe4QqYiiZjdvW+tuWq6TbjV14Y=
|
||||
k8s.io/api v0.19.7/go.mod h1:KTryDUT3l6Mtv7K2J2486PNL9DBns3wOYTkGR+iz63Y=
|
||||
k8s.io/apiextensions-apiserver v0.18.12/go.mod h1:nihADkPed1L37Vxpz2/BrtxO9mCtINH23aNtUe/CRLo=
|
||||
k8s.io/apiextensions-apiserver v0.19.7/go.mod h1:XJNNtjISNNePDEUClHt/igzMpQcmjVVh88QH+PKztPU=
|
||||
k8s.io/apimachinery v0.18.8/go.mod h1:6sQd+iHEqmOtALqOFjSWp2KZ9F0wlU/nWm0ZgsYWMig=
|
||||
k8s.io/apimachinery v0.18.12 h1:bLFXU4IxOu06F6Z6PV7eqtapXFb1G2q0ni0XBNFtJH8=
|
||||
k8s.io/apimachinery v0.18.12/go.mod h1:PF5taHbXgTEJLU+xMypMmYTXTWPJ5LaW8bfsisxnEXk=
|
||||
k8s.io/apimachinery v0.19.7 h1:nTaEnYVH+i//aPgMA0zTEV2lfVLCV9LextqVd67mulc=
|
||||
k8s.io/apimachinery v0.19.7/go.mod h1:6sRbGRAVY5DOCuZwB5XkqguBqpqLU6q/kOaOdk29z6Q=
|
||||
k8s.io/apiserver v0.18.8/go.mod h1:12u5FuGql8Cc497ORNj79rhPdiXQC4bf53X/skR/1YM=
|
||||
k8s.io/apiserver v0.18.12/go.mod h1:uFOeW4LlxS6KDgLWy3n3gh0DhC6m41QIFgL33ouk+4w=
|
||||
k8s.io/apiserver v0.19.7/go.mod h1:DmWVQggNePspa+vSsVytVbS3iBSDTXdJVt0akfHacKk=
|
||||
k8s.io/cli-runtime v0.19.7 h1:VkHsqrQYCD6+yBm2k9lOxLJtfo1tmb/TdYIHQ2RSCsY=
|
||||
k8s.io/cli-runtime v0.19.7/go.mod h1:UTtbWaGV/USZSrnvuW/lRZGM5OsemAT/q/Du/Ac+wKU=
|
||||
k8s.io/client-go v0.18.8/go.mod h1:HqFqMllQ5NnQJNwjro9k5zMyfhZlOwpuTLVrxjkYSxU=
|
||||
k8s.io/client-go v0.18.12 h1:MDGRE2tGidz29g45dI4kfelJo+aRmDqWx0Way8mD88A=
|
||||
k8s.io/client-go v0.18.12/go.mod h1:0aC8XkA09dX/goYqHQJ/kVv0zL1t+weOZt3pmz9LpxA=
|
||||
k8s.io/client-go v0.19.7 h1:SoJ4mzZ9LyXBGDe8MmpMznw0CwQ1ITWgsmG7GixvhUU=
|
||||
k8s.io/client-go v0.19.7/go.mod h1:iytGI7S3kmv6bWnn+bSQUE4VlrEi4YFssvVB7J7Hvqg=
|
||||
k8s.io/cloud-provider v0.18.8/go.mod h1:cn9AlzMPVIXA4HHLVbgGUigaQlZyHSZ7WAwDEFNrQSs=
|
||||
k8s.io/code-generator v0.17.2/go.mod h1:DVmfPQgxQENqDIzVR2ddLXMH34qeszkKSdH/N+s+38s=
|
||||
k8s.io/code-generator v0.18.12 h1:/cSUfqlYZ90y0WDxxWfwfTXUGkJer2Gt1L3AIaVvviQ=
|
||||
k8s.io/code-generator v0.18.12/go.mod h1:TgNEVx9hCyPGpdtCWA34olQYLkh3ok9ar7XfSsr8b6c=
|
||||
k8s.io/cloud-provider v0.19.7/go.mod h1:aO/VpUwkG+JQN7ZXc5WBLZ5NBXuq/Y5B6vri6U94PZ8=
|
||||
k8s.io/code-generator v0.19.7 h1:kM/68Y26Z/u//TFc1ggVVcg62te8A2yQh57jBfD0FWQ=
|
||||
k8s.io/code-generator v0.19.7/go.mod h1:lwEq3YnLYb/7uVXLorOJfxg+cUu2oihFhHZ0n9NIla0=
|
||||
k8s.io/component-base v0.18.8/go.mod h1:00frPRDas29rx58pPCxNkhUfPbwajlyyvu8ruNgSErU=
|
||||
k8s.io/component-base v0.18.12/go.mod h1:pRGKXsx2KWfsJqlDi4sbCc1jpaB87rXIIqupjhr5wj0=
|
||||
k8s.io/component-base v0.19.7/go.mod h1:YX8spPBgwl3I6UGcSdQiEMAqRMSUsGQOW7SEr4+Qa3U=
|
||||
k8s.io/csi-translation-lib v0.18.8/go.mod h1:6cA6Btlzxy9s3QrS4BCZzQqclIWnTLr6Jx3H2ctAzY4=
|
||||
k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||
k8s.io/gengo v0.0.0-20190822140433-26a664648505/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||
k8s.io/gengo v0.0.0-20200114144118-36b2048a9120/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||
k8s.io/gengo v0.0.0-20200205140755-e0e292d8aa12 h1:pZzawYyz6VRNPVYpqGv61LWCimQv1BihyeqFrp50/G4=
|
||||
k8s.io/gengo v0.0.0-20200205140755-e0e292d8aa12/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||
k8s.io/csi-translation-lib v0.19.7/go.mod h1:WghizPQuzuygr2WdpgN2EjcNpDD2V4EAbxFXsgHgSBk=
|
||||
k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||
k8s.io/gengo v0.0.0-20200428234225-8167cfdcfc14 h1:t4L10Qfx/p7ASH3gXCdIUtPbbIuegCoUJf3TMSFekjw=
|
||||
k8s.io/gengo v0.0.0-20200428234225-8167cfdcfc14/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||
k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
|
||||
k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
|
||||
k8s.io/gengo v0.0.0-20201113003025-83324d819ded/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
||||
k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027 h1:Uusb3oh8XcdzDF/ndlI4ToKTYVlkCSJP39SRY2mfRAw=
|
||||
k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
||||
k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8=
|
||||
k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
|
||||
k8s.io/klog/v2 v2.0.0 h1:Foj74zO6RbjjP4hBEKjnYtjjAhGg4jNynUdYF6fJrok=
|
||||
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
|
||||
k8s.io/klog/v2 v2.2.0 h1:XRvcwJozkgZ1UQJmfMGpvRthQHOvihEhYtDfAaxMz/A=
|
||||
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
||||
k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E=
|
||||
k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E=
|
||||
k8s.io/kube-openapi v0.0.0-20200410145947-bcb3869e6f29 h1:NeQXVJ2XFSkRoPzRo8AId01ZER+j8oV4SZADT4iBOXQ=
|
||||
k8s.io/kube-openapi v0.0.0-20200410145947-bcb3869e6f29/go.mod h1:F+5wygcW0wmRTnM3cOgIqGivxkwSWIWT5YdsDbeAOaU=
|
||||
k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
||||
k8s.io/klog/v2 v2.5.0 h1:8mOnjf1RmUPW6KRqQCfYSZq/K20Unmp3IhuZUhxl8KI=
|
||||
k8s.io/klog/v2 v2.5.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
|
||||
k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6 h1:+WnxoVtG8TMiudHBSEtrVL1egv36TkkJm+bA8AxicmQ=
|
||||
k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o=
|
||||
k8s.io/legacy-cloud-providers v0.18.8/go.mod h1:tgp4xYf6lvjrWnjQwTOPvWQE9IVqSBGPF4on0IyICQE=
|
||||
k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
|
||||
k8s.io/utils v0.0.0-20200603063816-c1c6865ac451 h1:v8ud2Up6QK1lNOKFgiIVrZdMg7MpmSnvtrOieolJKoE=
|
||||
k8s.io/utils v0.0.0-20200603063816-c1c6865ac451/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
k8s.io/kube-openapi v0.0.0-20210113233702-8566a335510f h1:ZcWbnalfwIst131Zff7dGd1HQdt+NA9q7z9Fi0vbsHY=
|
||||
k8s.io/kube-openapi v0.0.0-20210113233702-8566a335510f/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM=
|
||||
k8s.io/legacy-cloud-providers v0.19.7/go.mod h1:dsZk4gH9QIwAtHQ8CK0Ps257xlfgoXE3tMkMNhW2xDU=
|
||||
k8s.io/utils v0.0.0-20200729134348-d5654de09c73 h1:uJmqzgNWG7XyClnU/mLPBWwfKKF1K8Hf8whTseBgJcg=
|
||||
k8s.io/utils v0.0.0-20200729134348-d5654de09c73/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
knative.dev/caching v0.0.0-20210120064853-cc4d11bd4274/go.mod h1:hh1afUwgK0slx19FdxznoIMYn41mYQZTPiFY7zny8oc=
|
||||
knative.dev/eventing v0.20.1-0.20210127134430-ea452b5b6655 h1:SgdJcA9eIYziiB23vt4YTBlvGhDdSHRVzncm+NPgRIo=
|
||||
knative.dev/eventing v0.20.1-0.20210127134430-ea452b5b6655/go.mod h1:7B1LW/HOtzJ4aX5yWisbW/SC0EaLeFIIUePtOcQep+A=
|
||||
knative.dev/hack v0.0.0-20201214230143-4ed1ecb8db24 h1:kIztWfvnIFV8Lhlea02K3YO2mIzcDyQNzrBLn0Oq9sA=
|
||||
knative.dev/hack v0.0.0-20201214230143-4ed1ecb8db24/go.mod h1:PHt8x8yX5Z9pPquBEfIj0X66f8iWkWfR0S/sarACJrI=
|
||||
knative.dev/hack v0.0.0-20210114150620-4422dcadb3c8 h1:N/Kt6C5zZzTtFcTntRThB+vEJ7WcLKaZ5Q2Jm7b23vw=
|
||||
knative.dev/hack v0.0.0-20210114150620-4422dcadb3c8/go.mod h1:PHt8x8yX5Z9pPquBEfIj0X66f8iWkWfR0S/sarACJrI=
|
||||
k8s.io/utils v0.0.0-20210111153108-fddb29f9d009 h1:0T5IaWHO3sJTEmCP6mUlBvMukxPKUQWqiI/YuiBNMiQ=
|
||||
k8s.io/utils v0.0.0-20210111153108-fddb29f9d009/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
knative.dev/caching v0.0.0-20210204170711-77321844ace3/go.mod h1:Sf9PzdlMYOQ9ieyan+8STfJJIzaqmd3P3Cyo8eKA38Q=
|
||||
knative.dev/eventing v0.20.1-0.20210209112550-3fcb64522f45 h1:zOce57uk3uCNr33/ii4JfY4pW2d738c/wrd9G3hZWnA=
|
||||
knative.dev/eventing v0.20.1-0.20210209112550-3fcb64522f45/go.mod h1:cNevML3a/1zuY3VP/mpnw0hQnZj344wCissYRi8B1Oo=
|
||||
knative.dev/hack v0.0.0-20210120165453-8d623a0af457 h1:jEBITgx/lQydGncM0uetpv/ZqawRzb2aSfEaYoMeDjM=
|
||||
knative.dev/hack v0.0.0-20210120165453-8d623a0af457/go.mod h1:PHt8x8yX5Z9pPquBEfIj0X66f8iWkWfR0S/sarACJrI=
|
||||
knative.dev/networking v0.0.0-20210120054853-b17f43505630 h1:nw8ius50Qp4cyqJGEGfGsmwRM23qF6Ssoa46AZllcks=
|
||||
knative.dev/networking v0.0.0-20210120054853-b17f43505630/go.mod h1:clj5nwP53Dd+nI1Z/JiLY5gJkPZpV2CNM+VtGkSQsYM=
|
||||
knative.dev/networking v0.0.0-20210123150554-8b522a9049a1 h1:l5oOSQUa8fFa0LjazjZToiTwfA/WO3YB7biB9m1CEWg=
|
||||
knative.dev/networking v0.0.0-20210123150554-8b522a9049a1/go.mod h1:hVzeezXBzGbhKxNpG66/wNjDRiLwlWrVilunogWaKlo=
|
||||
knative.dev/pkg v0.0.0-20210114223020-f0ea5e6b9c4e h1:3k5tzvlM9VGZFiXRj8UKc3CUpMGpqBlEbIY0Dp3F3NU=
|
||||
knative.dev/pkg v0.0.0-20210114223020-f0ea5e6b9c4e/go.mod h1:hckgW978SdzPA2H5EDvRPY8xsnPuDZLJLbPf8Jte7Q0=
|
||||
knative.dev/pkg v0.0.0-20210119162123-1bbf0a6436c3 h1:kvBQKadSBqhTMveExPsvlkTWNS8yQcvxes6PS5RxDQs=
|
||||
knative.dev/pkg v0.0.0-20210119162123-1bbf0a6436c3/go.mod h1:cZdMjcJE6JGSNaEypgbUigX1TjteMIwQsW2woNBPVCA=
|
||||
knative.dev/pkg v0.0.0-20210120200253-8cd47b5af35d/go.mod h1:cZdMjcJE6JGSNaEypgbUigX1TjteMIwQsW2woNBPVCA=
|
||||
knative.dev/pkg v0.0.0-20210125222030-6040b3af4803 h1:L9lY/UztepeiTWys3VyO3Y5wQmYPyYG7eOG9qib6AZY=
|
||||
knative.dev/pkg v0.0.0-20210125222030-6040b3af4803/go.mod h1:X4NPrCo8NK3hbDVan9Vm7mf5io3ZoINakAdrpSXVB08=
|
||||
knative.dev/reconciler-test v0.0.0-20210125215930-c46f01f1a397/go.mod h1:OdlBaQCO8KLNnL4wXUksWxJygpiJUxLhPwE56jxtT8s=
|
||||
knative.dev/serving v0.20.1-0.20210123202654-e61294b2ca32 h1:mebiDXqLlnGh2IgU+aR6v8slPnf6aiJuGwiUzmkKdlo=
|
||||
knative.dev/serving v0.20.1-0.20210123202654-e61294b2ca32/go.mod h1:PvcTcrNFpIlC1s5+IT4SXUTmsMnHLkLbL2K/rE9h8+k=
|
||||
knative.dev/hack v0.0.0-20210203173706-8368e1f6eacf h1:u4cY4jr2LYvhoz/1HBWEPsMiLkm0HMdDTfmmw1RE8zE=
|
||||
knative.dev/hack v0.0.0-20210203173706-8368e1f6eacf/go.mod h1:PHt8x8yX5Z9pPquBEfIj0X66f8iWkWfR0S/sarACJrI=
|
||||
knative.dev/networking v0.0.0-20210208175252-ab1235ed8672/go.mod h1:XC1mKUyd7t+UKJ7coKbGqEF0XDtEv+90KiG0Vo7TBtk=
|
||||
knative.dev/networking v0.0.0-20210209030528-e24bdfe91d90 h1:EvOTDgvPEUXu0eEap5TJvgqhT8im429epcCy6/A/wSA=
|
||||
knative.dev/networking v0.0.0-20210209030528-e24bdfe91d90/go.mod h1:NQPUbkM8iJDoeOnSq/LnLfgIq8nID5uPEjstTPWujKE=
|
||||
knative.dev/pkg v0.0.0-20210130001831-ca02ef752ac6/go.mod h1:X4NPrCo8NK3hbDVan9Vm7mf5io3ZoINakAdrpSXVB08=
|
||||
knative.dev/pkg v0.0.0-20210203171706-6045ed499615/go.mod h1:X4NPrCo8NK3hbDVan9Vm7mf5io3ZoINakAdrpSXVB08=
|
||||
knative.dev/pkg v0.0.0-20210208175252-a02dcff9ee26 h1:PkJB1M77wYBI1UF5vp8y4fRnYQDu1IkRWswp6CgRRSo=
|
||||
knative.dev/pkg v0.0.0-20210208175252-a02dcff9ee26/go.mod h1:TJSdebQOWX5N2bszohOYVi0H1QtXbtlYLuMghAFBMhY=
|
||||
knative.dev/reconciler-test v0.0.0-20210203100806-0603b747dcc9/go.mod h1:iNDjVEzkqU1BKYqoaE33uiq7IZEtlTc9gUOFdWkQtkc=
|
||||
knative.dev/serving v0.20.1-0.20210209061117-8751d9125712 h1:69I1dt1nl/sOCH4nwCA2atWXYL9XVjvOkLQfzljFHIA=
|
||||
knative.dev/serving v0.20.1-0.20210209061117-8751d9125712/go.mod h1:GcwoCcdNJbPkPdp8kodW0OSKDC+1OEDzPJyFhkN8zq4=
|
||||
modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw=
|
||||
modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk=
|
||||
modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k=
|
||||
|
|
@ -1337,19 +1351,13 @@ pgregory.net/rapid v0.3.3/go.mod h1:UYpPVyjFHzYBGHIxLFoupi8vwk6rXNzRY9OMvVxFIOU=
|
|||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.7/go.mod h1:PHgbrJT7lCHcxMU+mDHEm+nx46H4zuuHZkDP6icnhu0=
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.9/go.mod h1:dzAXnQbTRyDlZPJX2SUPEqvnB+j7AJjtlox7PEwigU0=
|
||||
sigs.k8s.io/kustomize v2.0.3+incompatible h1:JUufWFNlI44MdtnjUqVnvh29rR37PQFzPbLXqhyOyX0=
|
||||
sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU=
|
||||
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e h1:4Z09Hglb792X0kfOBBJUPFEyvVfQWrYT/l8h5EKA6JQ=
|
||||
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
|
||||
sigs.k8s.io/structured-merge-diff/v2 v2.0.1/go.mod h1:Wb7vfKAodbKgf6tn1Kl0VvGj7mRH6DGaRcixXEJXTsE=
|
||||
sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw=
|
||||
sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw=
|
||||
sigs.k8s.io/structured-merge-diff/v3 v3.0.1-0.20200706213357-43c19bbb7fba h1:AAbnc5KQuTWKuh2QSnyghKIOTFzB0Jayv7/OFDn3Cy4=
|
||||
sigs.k8s.io/structured-merge-diff/v3 v3.0.1-0.20200706213357-43c19bbb7fba/go.mod h1:V06abazjHneE37ZdSY/UUwPVgcJMKI/jU5XGUjgIKoc=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.0.1 h1:YXTMot5Qz/X1iBRJhAt+vI+HVttY0WkSqqhKxQ0xVbA=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.0.2 h1:YHQV7Dajm86OuqnIR6zAelnDWBRjo+YhYV9PmGrh1s8=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
|
||||
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
|
||||
|
|
|
|||
|
|
@ -0,0 +1,50 @@
|
|||
|
||||
This project is covered by two different licenses: MIT and Apache.
|
||||
|
||||
#### MIT License ####
|
||||
|
||||
The following files were ported to Go from C files of libyaml, and thus
|
||||
are still covered by their original MIT license, with the additional
|
||||
copyright staring in 2011 when the project was ported over:
|
||||
|
||||
apic.go emitterc.go parserc.go readerc.go scannerc.go
|
||||
writerc.go yamlh.go yamlprivateh.go
|
||||
|
||||
Copyright (c) 2006-2010 Kirill Simonov
|
||||
Copyright (c) 2006-2011 Kirill Simonov
|
||||
|
||||
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.
|
||||
|
||||
### Apache License ###
|
||||
|
||||
All the remaining project files are covered by the Apache license:
|
||||
|
||||
Copyright (c) 2011-2019 Canonical Ltd
|
||||
|
||||
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.
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
Copyright 2011-2016 Canonical Ltd.
|
||||
|
||||
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.
|
||||
|
|
@ -41,6 +41,11 @@ const (
|
|||
knativeConfigurationName = "configuration_name"
|
||||
knativeNamespaceName = "namespace_name"
|
||||
|
||||
knativeBrokerType = "knative_broker"
|
||||
knativeBrokerName = "broker_name"
|
||||
knativeTriggerType = "knative_trigger"
|
||||
knativeTriggerName = "trigger_name"
|
||||
|
||||
appEngineInstanceType = "gae_instance"
|
||||
|
||||
appEngineService = "appengine.service.id"
|
||||
|
|
@ -133,6 +138,23 @@ var knativeRevisionResourceMap = map[string]string{
|
|||
knativeNamespaceName: knativeNamespaceName,
|
||||
}
|
||||
|
||||
var knativeBrokerResourceMap = map[string]string{
|
||||
"project_id": stackdriverProjectID,
|
||||
"location": resourcekeys.CloudKeyZone,
|
||||
"cluster_name": resourcekeys.K8SKeyClusterName,
|
||||
knativeNamespaceName: knativeNamespaceName,
|
||||
knativeBrokerName: knativeBrokerName,
|
||||
}
|
||||
|
||||
var knativeTriggerResourceMap = map[string]string{
|
||||
"project_id": stackdriverProjectID,
|
||||
"location": resourcekeys.CloudKeyZone,
|
||||
"cluster_name": resourcekeys.K8SKeyClusterName,
|
||||
knativeNamespaceName: knativeNamespaceName,
|
||||
knativeBrokerName: knativeBrokerName,
|
||||
knativeTriggerName: knativeTriggerName,
|
||||
}
|
||||
|
||||
// getAutodetectedLabels returns all the labels from the Monitored Resource detected
|
||||
// from the environment by calling monitoredresource.Autodetect. If a "zone" label is detected,
|
||||
// a "location" label is added with the same value to account for differences between
|
||||
|
|
@ -213,6 +235,12 @@ func DefaultMapResource(res *resource.Resource) *monitoredrespb.MonitoredResourc
|
|||
case res.Type == knativeResType:
|
||||
result.Type = res.Type
|
||||
match = knativeRevisionResourceMap
|
||||
case res.Type == knativeBrokerType:
|
||||
result.Type = knativeBrokerType
|
||||
match = knativeBrokerResourceMap
|
||||
case res.Type == knativeTriggerType:
|
||||
result.Type = knativeTriggerType
|
||||
match = knativeTriggerResourceMap
|
||||
}
|
||||
|
||||
var missing bool
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@ import (
|
|||
"go.opencensus.io/trace"
|
||||
"golang.org/x/oauth2/google"
|
||||
"google.golang.org/api/option"
|
||||
metricpb "google.golang.org/genproto/googleapis/api/metric"
|
||||
monitoredrespb "google.golang.org/genproto/googleapis/api/monitoredres"
|
||||
|
||||
commonpb "github.com/census-instrumentation/opencensus-proto/gen-go/agent/common/v1"
|
||||
|
|
@ -469,6 +470,15 @@ func (e *Exporter) Flush() {
|
|||
e.traceExporter.Flush()
|
||||
}
|
||||
|
||||
// ViewToMetricDescriptor converts an OpenCensus view to a MetricDescriptor.
|
||||
//
|
||||
// This is useful for cases when you want to use your Go code as source of
|
||||
// truth of metric descriptors. You can extract or define views in a central
|
||||
// place, then call this method to generate MetricDescriptors.
|
||||
func (e *Exporter) ViewToMetricDescriptor(ctx context.Context, v *view.View) (*metricpb.MetricDescriptor, error) {
|
||||
return e.statsExporter.viewToMetricDescriptor(ctx, v)
|
||||
}
|
||||
|
||||
func (o Options) handleError(err error) {
|
||||
if o.OnError != nil {
|
||||
o.OnError(err)
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ type Config struct {
|
|||
|
||||
// An optional endpoint URL (hostname only or fully qualified URI)
|
||||
// that overrides the default generated endpoint for a client. Set this
|
||||
// to `nil` to use the default generated endpoint.
|
||||
// to `nil` or the value to `""` to use the default generated endpoint.
|
||||
//
|
||||
// Note: You must still provide a `Region` value when specifying an
|
||||
// endpoint for a client.
|
||||
|
|
@ -138,7 +138,7 @@ type Config struct {
|
|||
// `ExpectContinueTimeout` for information on adjusting the continue wait
|
||||
// timeout. https://golang.org/pkg/net/http/#Transport
|
||||
//
|
||||
// You should use this flag to disble 100-Continue if you experience issues
|
||||
// You should use this flag to disable 100-Continue if you experience issues
|
||||
// with proxies or third party S3 compatible services.
|
||||
S3Disable100Continue *bool
|
||||
|
||||
|
|
@ -183,7 +183,7 @@ type Config struct {
|
|||
//
|
||||
// Example:
|
||||
// sess := session.Must(session.NewSession(aws.NewConfig()
|
||||
// .WithEC2MetadataDiableTimeoutOverride(true)))
|
||||
// .WithEC2MetadataDisableTimeoutOverride(true)))
|
||||
//
|
||||
// svc := s3.New(sess)
|
||||
//
|
||||
|
|
@ -194,7 +194,7 @@ type Config struct {
|
|||
// both IPv4 and IPv6 addressing.
|
||||
//
|
||||
// Setting this for a service which does not support dual stack will fail
|
||||
// to make requets. It is not recommended to set this value on the session
|
||||
// to make requests. It is not recommended to set this value on the session
|
||||
// as it will apply to all service clients created with the session. Even
|
||||
// services which don't support dual stack endpoints.
|
||||
//
|
||||
|
|
@ -438,13 +438,6 @@ func (c *Config) WithDisableEndpointHostPrefix(t bool) *Config {
|
|||
return c
|
||||
}
|
||||
|
||||
// MergeIn merges the passed in configs into the existing config object.
|
||||
func (c *Config) MergeIn(cfgs ...*Config) {
|
||||
for _, other := range cfgs {
|
||||
mergeInConfig(c, other)
|
||||
}
|
||||
}
|
||||
|
||||
// WithSTSRegionalEndpoint will set whether or not to use regional endpoint flag
|
||||
// when resolving the endpoint for a service
|
||||
func (c *Config) WithSTSRegionalEndpoint(sre endpoints.STSRegionalEndpoint) *Config {
|
||||
|
|
@ -459,6 +452,27 @@ func (c *Config) WithS3UsEast1RegionalEndpoint(sre endpoints.S3UsEast1RegionalEn
|
|||
return c
|
||||
}
|
||||
|
||||
// WithLowerCaseHeaderMaps sets a config LowerCaseHeaderMaps value
|
||||
// returning a Config pointer for chaining.
|
||||
func (c *Config) WithLowerCaseHeaderMaps(t bool) *Config {
|
||||
c.LowerCaseHeaderMaps = &t
|
||||
return c
|
||||
}
|
||||
|
||||
// WithDisableRestProtocolURICleaning sets a config DisableRestProtocolURICleaning value
|
||||
// returning a Config pointer for chaining.
|
||||
func (c *Config) WithDisableRestProtocolURICleaning(t bool) *Config {
|
||||
c.DisableRestProtocolURICleaning = &t
|
||||
return c
|
||||
}
|
||||
|
||||
// MergeIn merges the passed in configs into the existing config object.
|
||||
func (c *Config) MergeIn(cfgs ...*Config) {
|
||||
for _, other := range cfgs {
|
||||
mergeInConfig(c, other)
|
||||
}
|
||||
}
|
||||
|
||||
func mergeInConfig(dst *Config, other *Config) {
|
||||
if other == nil {
|
||||
return
|
||||
|
|
@ -571,6 +585,10 @@ func mergeInConfig(dst *Config, other *Config) {
|
|||
if other.S3UsEast1RegionalEndpoint != endpoints.UnsetS3UsEast1Endpoint {
|
||||
dst.S3UsEast1RegionalEndpoint = other.S3UsEast1RegionalEndpoint
|
||||
}
|
||||
|
||||
if other.LowerCaseHeaderMaps != nil {
|
||||
dst.LowerCaseHeaderMaps = other.LowerCaseHeaderMaps
|
||||
}
|
||||
}
|
||||
|
||||
// Copy will return a shallow copy of the Config object. If any additional
|
||||
|
|
|
|||
|
|
@ -225,6 +225,8 @@ var ValidateEndpointHandler = request.NamedHandler{Name: "core.ValidateEndpointH
|
|||
if r.ClientInfo.SigningRegion == "" && aws.StringValue(r.Config.Region) == "" {
|
||||
r.Error = aws.ErrMissingRegion
|
||||
} else if r.ClientInfo.Endpoint == "" {
|
||||
// Was any endpoint provided by the user, or one was derived by the
|
||||
// SDK's endpoint resolver?
|
||||
r.Error = aws.ErrMissingEndpoint
|
||||
}
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ package credentials
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"sync/atomic"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
|
|
@ -173,7 +173,9 @@ type Expiry struct {
|
|||
// the expiration time given to ensure no requests are made with expired
|
||||
// tokens.
|
||||
func (e *Expiry) SetExpiration(expiration time.Time, window time.Duration) {
|
||||
e.expiration = expiration
|
||||
// Passed in expirations should have the monotonic clock values stripped.
|
||||
// This ensures time comparisons will be based on wall-time.
|
||||
e.expiration = expiration.Round(0)
|
||||
if window > 0 {
|
||||
e.expiration = e.expiration.Add(-window)
|
||||
}
|
||||
|
|
@ -205,9 +207,10 @@ func (e *Expiry) ExpiresAt() time.Time {
|
|||
// first instance of the credentials Value. All calls to Get() after that
|
||||
// will return the cached credentials Value until IsExpired() returns true.
|
||||
type Credentials struct {
|
||||
creds atomic.Value
|
||||
sf singleflight.Group
|
||||
sf singleflight.Group
|
||||
|
||||
m sync.RWMutex
|
||||
creds Value
|
||||
provider Provider
|
||||
}
|
||||
|
||||
|
|
@ -216,7 +219,6 @@ func NewCredentials(provider Provider) *Credentials {
|
|||
c := &Credentials{
|
||||
provider: provider,
|
||||
}
|
||||
c.creds.Store(Value{})
|
||||
return c
|
||||
}
|
||||
|
||||
|
|
@ -233,8 +235,17 @@ func NewCredentials(provider Provider) *Credentials {
|
|||
//
|
||||
// Passed in Context is equivalent to aws.Context, and context.Context.
|
||||
func (c *Credentials) GetWithContext(ctx Context) (Value, error) {
|
||||
if curCreds := c.creds.Load(); !c.isExpired(curCreds) {
|
||||
return curCreds.(Value), nil
|
||||
// Check if credentials are cached, and not expired.
|
||||
select {
|
||||
case curCreds, ok := <-c.asyncIsExpired():
|
||||
// ok will only be true, of the credentials were not expired. ok will
|
||||
// be false and have no value if the credentials are expired.
|
||||
if ok {
|
||||
return curCreds, nil
|
||||
}
|
||||
case <-ctx.Done():
|
||||
return Value{}, awserr.New("RequestCanceled",
|
||||
"request context canceled", ctx.Err())
|
||||
}
|
||||
|
||||
// Cannot pass context down to the actual retrieve, because the first
|
||||
|
|
@ -252,18 +263,23 @@ func (c *Credentials) GetWithContext(ctx Context) (Value, error) {
|
|||
}
|
||||
}
|
||||
|
||||
func (c *Credentials) singleRetrieve(ctx Context) (creds interface{}, err error) {
|
||||
if curCreds := c.creds.Load(); !c.isExpired(curCreds) {
|
||||
return curCreds.(Value), nil
|
||||
func (c *Credentials) singleRetrieve(ctx Context) (interface{}, error) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
if curCreds := c.creds; !c.isExpiredLocked(curCreds) {
|
||||
return curCreds, nil
|
||||
}
|
||||
|
||||
var creds Value
|
||||
var err error
|
||||
if p, ok := c.provider.(ProviderWithContext); ok {
|
||||
creds, err = p.RetrieveWithContext(ctx)
|
||||
} else {
|
||||
creds, err = c.provider.Retrieve()
|
||||
}
|
||||
if err == nil {
|
||||
c.creds.Store(creds)
|
||||
c.creds = creds
|
||||
}
|
||||
|
||||
return creds, err
|
||||
|
|
@ -288,7 +304,10 @@ func (c *Credentials) Get() (Value, error) {
|
|||
// This will override the Provider's expired state, and force Credentials
|
||||
// to call the Provider's Retrieve().
|
||||
func (c *Credentials) Expire() {
|
||||
c.creds.Store(Value{})
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.creds = Value{}
|
||||
}
|
||||
|
||||
// IsExpired returns if the credentials are no longer valid, and need
|
||||
|
|
@ -297,11 +316,32 @@ func (c *Credentials) Expire() {
|
|||
// If the Credentials were forced to be expired with Expire() this will
|
||||
// reflect that override.
|
||||
func (c *Credentials) IsExpired() bool {
|
||||
return c.isExpired(c.creds.Load())
|
||||
c.m.RLock()
|
||||
defer c.m.RUnlock()
|
||||
|
||||
return c.isExpiredLocked(c.creds)
|
||||
}
|
||||
|
||||
// isExpired helper method wrapping the definition of expired credentials.
|
||||
func (c *Credentials) isExpired(creds interface{}) bool {
|
||||
// asyncIsExpired returns a channel of credentials Value. If the channel is
|
||||
// closed the credentials are expired and credentials value are not empty.
|
||||
func (c *Credentials) asyncIsExpired() <-chan Value {
|
||||
ch := make(chan Value, 1)
|
||||
go func() {
|
||||
c.m.RLock()
|
||||
defer c.m.RUnlock()
|
||||
|
||||
if curCreds := c.creds; !c.isExpiredLocked(curCreds) {
|
||||
ch <- curCreds
|
||||
}
|
||||
|
||||
close(ch)
|
||||
}()
|
||||
|
||||
return ch
|
||||
}
|
||||
|
||||
// isExpiredLocked helper method wrapping the definition of expired credentials.
|
||||
func (c *Credentials) isExpiredLocked(creds interface{}) bool {
|
||||
return creds == nil || creds.(Value) == Value{} || c.provider.IsExpired()
|
||||
}
|
||||
|
||||
|
|
@ -309,13 +349,17 @@ func (c *Credentials) isExpired(creds interface{}) bool {
|
|||
// the underlying Provider, if it supports that interface. Otherwise, it returns
|
||||
// an error.
|
||||
func (c *Credentials) ExpiresAt() (time.Time, error) {
|
||||
c.m.RLock()
|
||||
defer c.m.RUnlock()
|
||||
|
||||
expirer, ok := c.provider.(Expirer)
|
||||
if !ok {
|
||||
return time.Time{}, awserr.New("ProviderNotExpirer",
|
||||
fmt.Sprintf("provider %s does not support ExpiresAt()", c.creds.Load().(Value).ProviderName),
|
||||
fmt.Sprintf("provider %s does not support ExpiresAt()",
|
||||
c.creds.ProviderName),
|
||||
nil)
|
||||
}
|
||||
if c.creds.Load().(Value) == (Value{}) {
|
||||
if c.creds == (Value{}) {
|
||||
// set expiration time to the distant past
|
||||
return time.Time{}, nil
|
||||
}
|
||||
|
|
|
|||
5
vendor/github.com/aws/aws-sdk-go/aws/credentials/shared_credentials_provider.go
generated
vendored
5
vendor/github.com/aws/aws-sdk-go/aws/credentials/shared_credentials_provider.go
generated
vendored
|
|
@ -17,8 +17,9 @@ var (
|
|||
ErrSharedCredentialsHomeNotFound = awserr.New("UserHomeNotFound", "user home directory not found.", nil)
|
||||
)
|
||||
|
||||
// A SharedCredentialsProvider retrieves credentials from the current user's home
|
||||
// directory, and keeps track if those credentials are expired.
|
||||
// A SharedCredentialsProvider retrieves access key pair (access key ID,
|
||||
// secret access key, and session token if present) credentials from the current
|
||||
// user's home directory, and keeps track if those credentials are expired.
|
||||
//
|
||||
// Profile ini file example: $HOME/.aws/credentials
|
||||
type SharedCredentialsProvider struct {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,60 @@
|
|||
// Package ssocreds provides a credential provider for retrieving temporary AWS credentials using an SSO access token.
|
||||
//
|
||||
// IMPORTANT: The provider in this package does not initiate or perform the AWS SSO login flow. The SDK provider
|
||||
// expects that you have already performed the SSO login flow using AWS CLI using the "aws sso login" command, or by
|
||||
// some other mechanism. The provider must find a valid non-expired access token for the AWS SSO user portal URL in
|
||||
// ~/.aws/sso/cache. If a cached token is not found, it is expired, or the file is malformed an error will be returned.
|
||||
//
|
||||
// Loading AWS SSO credentials with the AWS shared configuration file
|
||||
//
|
||||
// You can use configure AWS SSO credentials from the AWS shared configuration file by
|
||||
// providing the specifying the required keys in the profile:
|
||||
//
|
||||
// sso_account_id
|
||||
// sso_region
|
||||
// sso_role_name
|
||||
// sso_start_url
|
||||
//
|
||||
// For example, the following defines a profile "devsso" and specifies the AWS SSO parameters that defines the target
|
||||
// account, role, sign-on portal, and the region where the user portal is located. Note: all SSO arguments must be
|
||||
// provided, or an error will be returned.
|
||||
//
|
||||
// [profile devsso]
|
||||
// sso_start_url = https://my-sso-portal.awsapps.com/start
|
||||
// sso_role_name = SSOReadOnlyRole
|
||||
// sso_region = us-east-1
|
||||
// sso_account_id = 123456789012
|
||||
//
|
||||
// Using the config module, you can load the AWS SDK shared configuration, and specify that this profile be used to
|
||||
// retrieve credentials. For example:
|
||||
//
|
||||
// sess, err := session.NewSessionWithOptions(session.Options{
|
||||
// SharedConfigState: session.SharedConfigEnable,
|
||||
// Profile: "devsso",
|
||||
// })
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
//
|
||||
// Programmatically loading AWS SSO credentials directly
|
||||
//
|
||||
// You can programmatically construct the AWS SSO Provider in your application, and provide the necessary information
|
||||
// to load and retrieve temporary credentials using an access token from ~/.aws/sso/cache.
|
||||
//
|
||||
// svc := sso.New(sess, &aws.Config{
|
||||
// Region: aws.String("us-west-2"), // Client Region must correspond to the AWS SSO user portal region
|
||||
// })
|
||||
//
|
||||
// provider := ssocreds.NewCredentialsWithClient(svc, "123456789012", "SSOReadOnlyRole", "https://my-sso-portal.awsapps.com/start")
|
||||
//
|
||||
// credentials, err := provider.Get()
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
//
|
||||
// Additional Resources
|
||||
//
|
||||
// Configuring the AWS CLI to use AWS Single Sign-On: https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sso.html
|
||||
//
|
||||
// AWS Single Sign-On User Guide: https://docs.aws.amazon.com/singlesignon/latest/userguide/what-is.html
|
||||
package ssocreds
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
// +build !windows
|
||||
|
||||
package ssocreds
|
||||
|
||||
import "os"
|
||||
|
||||
func getHomeDirectory() string {
|
||||
return os.Getenv("HOME")
|
||||
}
|
||||
7
vendor/github.com/aws/aws-sdk-go/aws/credentials/ssocreds/os_windows.go
generated
vendored
Normal file
7
vendor/github.com/aws/aws-sdk-go/aws/credentials/ssocreds/os_windows.go
generated
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
package ssocreds
|
||||
|
||||
import "os"
|
||||
|
||||
func getHomeDirectory() string {
|
||||
return os.Getenv("USERPROFILE")
|
||||
}
|
||||
180
vendor/github.com/aws/aws-sdk-go/aws/credentials/ssocreds/provider.go
generated
vendored
Normal file
180
vendor/github.com/aws/aws-sdk-go/aws/credentials/ssocreds/provider.go
generated
vendored
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
package ssocreds
|
||||
|
||||
import (
|
||||
"crypto/sha1"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/client"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||
"github.com/aws/aws-sdk-go/service/sso"
|
||||
"github.com/aws/aws-sdk-go/service/sso/ssoiface"
|
||||
)
|
||||
|
||||
// ErrCodeSSOProviderInvalidToken is the code type that is returned if loaded token has expired or is otherwise invalid.
|
||||
// To refresh the SSO session run aws sso login with the corresponding profile.
|
||||
const ErrCodeSSOProviderInvalidToken = "SSOProviderInvalidToken"
|
||||
|
||||
const invalidTokenMessage = "the SSO session has expired or is invalid"
|
||||
|
||||
func init() {
|
||||
nowTime = time.Now
|
||||
defaultCacheLocation = defaultCacheLocationImpl
|
||||
}
|
||||
|
||||
var nowTime func() time.Time
|
||||
|
||||
// ProviderName is the name of the provider used to specify the source of credentials.
|
||||
const ProviderName = "SSOProvider"
|
||||
|
||||
var defaultCacheLocation func() string
|
||||
|
||||
func defaultCacheLocationImpl() string {
|
||||
return filepath.Join(getHomeDirectory(), ".aws", "sso", "cache")
|
||||
}
|
||||
|
||||
// Provider is an AWS credential provider that retrieves temporary AWS credentials by exchanging an SSO login token.
|
||||
type Provider struct {
|
||||
credentials.Expiry
|
||||
|
||||
// The Client which is configured for the AWS Region where the AWS SSO user portal is located.
|
||||
Client ssoiface.SSOAPI
|
||||
|
||||
// The AWS account that is assigned to the user.
|
||||
AccountID string
|
||||
|
||||
// The role name that is assigned to the user.
|
||||
RoleName string
|
||||
|
||||
// The URL that points to the organization's AWS Single Sign-On (AWS SSO) user portal.
|
||||
StartURL string
|
||||
}
|
||||
|
||||
// NewCredentials returns a new AWS Single Sign-On (AWS SSO) credential provider. The ConfigProvider is expected to be configured
|
||||
// for the AWS Region where the AWS SSO user portal is located.
|
||||
func NewCredentials(configProvider client.ConfigProvider, accountID, roleName, startURL string, optFns ...func(provider *Provider)) *credentials.Credentials {
|
||||
return NewCredentialsWithClient(sso.New(configProvider), accountID, roleName, startURL, optFns...)
|
||||
}
|
||||
|
||||
// NewCredentialsWithClient returns a new AWS Single Sign-On (AWS SSO) credential provider. The provided client is expected to be configured
|
||||
// for the AWS Region where the AWS SSO user portal is located.
|
||||
func NewCredentialsWithClient(client ssoiface.SSOAPI, accountID, roleName, startURL string, optFns ...func(provider *Provider)) *credentials.Credentials {
|
||||
p := &Provider{
|
||||
Client: client,
|
||||
AccountID: accountID,
|
||||
RoleName: roleName,
|
||||
StartURL: startURL,
|
||||
}
|
||||
|
||||
for _, fn := range optFns {
|
||||
fn(p)
|
||||
}
|
||||
|
||||
return credentials.NewCredentials(p)
|
||||
}
|
||||
|
||||
// Retrieve retrieves temporary AWS credentials from the configured Amazon Single Sign-On (AWS SSO) user portal
|
||||
// by exchanging the accessToken present in ~/.aws/sso/cache.
|
||||
func (p *Provider) Retrieve() (credentials.Value, error) {
|
||||
return p.RetrieveWithContext(aws.BackgroundContext())
|
||||
}
|
||||
|
||||
// RetrieveWithContext retrieves temporary AWS credentials from the configured Amazon Single Sign-On (AWS SSO) user portal
|
||||
// by exchanging the accessToken present in ~/.aws/sso/cache.
|
||||
func (p *Provider) RetrieveWithContext(ctx credentials.Context) (credentials.Value, error) {
|
||||
tokenFile, err := loadTokenFile(p.StartURL)
|
||||
if err != nil {
|
||||
return credentials.Value{}, err
|
||||
}
|
||||
|
||||
output, err := p.Client.GetRoleCredentialsWithContext(ctx, &sso.GetRoleCredentialsInput{
|
||||
AccessToken: &tokenFile.AccessToken,
|
||||
AccountId: &p.AccountID,
|
||||
RoleName: &p.RoleName,
|
||||
})
|
||||
if err != nil {
|
||||
return credentials.Value{}, err
|
||||
}
|
||||
|
||||
expireTime := time.Unix(0, aws.Int64Value(output.RoleCredentials.Expiration)*int64(time.Millisecond)).UTC()
|
||||
p.SetExpiration(expireTime, 0)
|
||||
|
||||
return credentials.Value{
|
||||
AccessKeyID: aws.StringValue(output.RoleCredentials.AccessKeyId),
|
||||
SecretAccessKey: aws.StringValue(output.RoleCredentials.SecretAccessKey),
|
||||
SessionToken: aws.StringValue(output.RoleCredentials.SessionToken),
|
||||
ProviderName: ProviderName,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func getCacheFileName(url string) (string, error) {
|
||||
hash := sha1.New()
|
||||
_, err := hash.Write([]byte(url))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return strings.ToLower(hex.EncodeToString(hash.Sum(nil))) + ".json", nil
|
||||
}
|
||||
|
||||
type rfc3339 time.Time
|
||||
|
||||
func (r *rfc3339) UnmarshalJSON(bytes []byte) error {
|
||||
var value string
|
||||
|
||||
if err := json.Unmarshal(bytes, &value); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
parse, err := time.Parse(time.RFC3339, value)
|
||||
if err != nil {
|
||||
return fmt.Errorf("expected RFC3339 timestamp: %v", err)
|
||||
}
|
||||
|
||||
*r = rfc3339(parse)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type token struct {
|
||||
AccessToken string `json:"accessToken"`
|
||||
ExpiresAt rfc3339 `json:"expiresAt"`
|
||||
Region string `json:"region,omitempty"`
|
||||
StartURL string `json:"startUrl,omitempty"`
|
||||
}
|
||||
|
||||
func (t token) Expired() bool {
|
||||
return nowTime().Round(0).After(time.Time(t.ExpiresAt))
|
||||
}
|
||||
|
||||
func loadTokenFile(startURL string) (t token, err error) {
|
||||
key, err := getCacheFileName(startURL)
|
||||
if err != nil {
|
||||
return token{}, awserr.New(ErrCodeSSOProviderInvalidToken, invalidTokenMessage, err)
|
||||
}
|
||||
|
||||
fileBytes, err := ioutil.ReadFile(filepath.Join(defaultCacheLocation(), key))
|
||||
if err != nil {
|
||||
return token{}, awserr.New(ErrCodeSSOProviderInvalidToken, invalidTokenMessage, err)
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(fileBytes, &t); err != nil {
|
||||
return token{}, awserr.New(ErrCodeSSOProviderInvalidToken, invalidTokenMessage, err)
|
||||
}
|
||||
|
||||
if len(t.AccessToken) == 0 {
|
||||
return token{}, awserr.New(ErrCodeSSOProviderInvalidToken, invalidTokenMessage, nil)
|
||||
}
|
||||
|
||||
if t.Expired() {
|
||||
return token{}, awserr.New(ErrCodeSSOProviderInvalidToken, invalidTokenMessage, nil)
|
||||
}
|
||||
|
||||
return t, nil
|
||||
}
|
||||
12
vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider.go
generated
vendored
12
vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider.go
generated
vendored
|
|
@ -244,9 +244,11 @@ type AssumeRoleProvider struct {
|
|||
MaxJitterFrac float64
|
||||
}
|
||||
|
||||
// NewCredentials returns a pointer to a new Credentials object wrapping the
|
||||
// NewCredentials returns a pointer to a new Credentials value wrapping the
|
||||
// AssumeRoleProvider. The credentials will expire every 15 minutes and the
|
||||
// role will be named after a nanosecond timestamp of this operation.
|
||||
// role will be named after a nanosecond timestamp of this operation. The
|
||||
// Credentials value will attempt to refresh the credentials using the provider
|
||||
// when Credentials.Get is called, if the cached credentials are expiring.
|
||||
//
|
||||
// Takes a Config provider to create the STS client. The ConfigProvider is
|
||||
// satisfied by the session.Session type.
|
||||
|
|
@ -268,9 +270,11 @@ func NewCredentials(c client.ConfigProvider, roleARN string, options ...func(*As
|
|||
return credentials.NewCredentials(p)
|
||||
}
|
||||
|
||||
// NewCredentialsWithClient returns a pointer to a new Credentials object wrapping the
|
||||
// NewCredentialsWithClient returns a pointer to a new Credentials value wrapping the
|
||||
// AssumeRoleProvider. The credentials will expire every 15 minutes and the
|
||||
// role will be named after a nanosecond timestamp of this operation.
|
||||
// role will be named after a nanosecond timestamp of this operation. The
|
||||
// Credentials value will attempt to refresh the credentials using the provider
|
||||
// when Credentials.Get is called, if the cached credentials are expiring.
|
||||
//
|
||||
// Takes an AssumeRoler which can be satisfied by the STS client.
|
||||
//
|
||||
|
|
|
|||
21
vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/web_identity_provider.go
generated
vendored
21
vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/web_identity_provider.go
generated
vendored
|
|
@ -52,9 +52,21 @@ type WebIdentityRoleProvider struct {
|
|||
credentials.Expiry
|
||||
PolicyArns []*sts.PolicyDescriptorType
|
||||
|
||||
client stsiface.STSAPI
|
||||
// Duration the STS credentials will be valid for. Truncated to seconds.
|
||||
// If unset, the assumed role will use AssumeRoleWithWebIdentity's default
|
||||
// expiry duration. See
|
||||
// https://docs.aws.amazon.com/sdk-for-go/api/service/sts/#STS.AssumeRoleWithWebIdentity
|
||||
// for more information.
|
||||
Duration time.Duration
|
||||
|
||||
// The amount of time the credentials will be refreshed before they expire.
|
||||
// This is useful refresh credentials before they expire to reduce risk of
|
||||
// using credentials as they expire. If unset, will default to no expiry
|
||||
// window.
|
||||
ExpiryWindow time.Duration
|
||||
|
||||
client stsiface.STSAPI
|
||||
|
||||
tokenFetcher TokenFetcher
|
||||
roleARN string
|
||||
roleSessionName string
|
||||
|
|
@ -107,11 +119,18 @@ func (p *WebIdentityRoleProvider) RetrieveWithContext(ctx credentials.Context) (
|
|||
// uses unix time in nanoseconds to uniquely identify sessions.
|
||||
sessionName = strconv.FormatInt(now().UnixNano(), 10)
|
||||
}
|
||||
|
||||
var duration *int64
|
||||
if p.Duration != 0 {
|
||||
duration = aws.Int64(int64(p.Duration / time.Second))
|
||||
}
|
||||
|
||||
req, resp := p.client.AssumeRoleWithWebIdentityRequest(&sts.AssumeRoleWithWebIdentityInput{
|
||||
PolicyArns: p.PolicyArns,
|
||||
RoleArn: &p.roleARN,
|
||||
RoleSessionName: &sessionName,
|
||||
WebIdentityToken: aws.String(string(b)),
|
||||
DurationSeconds: duration,
|
||||
})
|
||||
|
||||
req.SetContext(ctx)
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ func (c *EC2Metadata) getToken(ctx aws.Context, duration time.Duration) (tokenOu
|
|||
op := &request.Operation{
|
||||
Name: "GetToken",
|
||||
HTTPMethod: "PUT",
|
||||
HTTPPath: "/api/token",
|
||||
HTTPPath: "/latest/api/token",
|
||||
}
|
||||
|
||||
var output tokenOutput
|
||||
|
|
@ -62,7 +62,7 @@ func (c *EC2Metadata) GetMetadataWithContext(ctx aws.Context, p string) (string,
|
|||
op := &request.Operation{
|
||||
Name: "GetMetadata",
|
||||
HTTPMethod: "GET",
|
||||
HTTPPath: sdkuri.PathJoin("/meta-data", p),
|
||||
HTTPPath: sdkuri.PathJoin("/latest/meta-data", p),
|
||||
}
|
||||
output := &metadataOutput{}
|
||||
|
||||
|
|
@ -88,7 +88,7 @@ func (c *EC2Metadata) GetUserDataWithContext(ctx aws.Context) (string, error) {
|
|||
op := &request.Operation{
|
||||
Name: "GetUserData",
|
||||
HTTPMethod: "GET",
|
||||
HTTPPath: "/user-data",
|
||||
HTTPPath: "/latest/user-data",
|
||||
}
|
||||
|
||||
output := &metadataOutput{}
|
||||
|
|
@ -113,7 +113,7 @@ func (c *EC2Metadata) GetDynamicDataWithContext(ctx aws.Context, p string) (stri
|
|||
op := &request.Operation{
|
||||
Name: "GetDynamicData",
|
||||
HTTPMethod: "GET",
|
||||
HTTPPath: sdkuri.PathJoin("/dynamic", p),
|
||||
HTTPPath: sdkuri.PathJoin("/latest/dynamic", p),
|
||||
}
|
||||
|
||||
output := &metadataOutput{}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,10 @@
|
|||
// variable "AWS_EC2_METADATA_DISABLED=true". This environment variable set to
|
||||
// true instructs the SDK to disable the EC2 Metadata client. The client cannot
|
||||
// be used while the environment variable is set to true, (case insensitive).
|
||||
//
|
||||
// The endpoint of the EC2 IMDS client can be configured via the environment
|
||||
// variable, AWS_EC2_METADATA_SERVICE_ENDPOINT when creating the client with a
|
||||
// Session. See aws/session#Options.EC2IMDSEndpoint for more details.
|
||||
package ec2metadata
|
||||
|
||||
import (
|
||||
|
|
@ -12,6 +16,7 @@ import (
|
|||
"errors"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
|
@ -41,7 +46,7 @@ const (
|
|||
enableTokenProviderHandlerName = "enableTokenProviderHandler"
|
||||
|
||||
// TTL constants
|
||||
defaultTTL = 21600 * time.Second
|
||||
defaultTTL = 21600 * time.Second
|
||||
ttlExpirationWindow = 30 * time.Second
|
||||
)
|
||||
|
||||
|
|
@ -69,6 +74,9 @@ func New(p client.ConfigProvider, cfgs ...*aws.Config) *EC2Metadata {
|
|||
// a client when not using a session. Generally using just New with a session
|
||||
// is preferred.
|
||||
//
|
||||
// Will remove the URL path from the endpoint provided to ensure the EC2 IMDS
|
||||
// client is able to communicate with the EC2 IMDS API.
|
||||
//
|
||||
// If an unmodified HTTP client is provided from the stdlib default, or no client
|
||||
// the EC2RoleProvider's EC2Metadata HTTP client's timeout will be shortened.
|
||||
// To disable this set Config.EC2MetadataDisableTimeoutOverride to false. Enabled by default.
|
||||
|
|
@ -86,6 +94,15 @@ func NewClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegio
|
|||
cfg.MaxRetries = aws.Int(2)
|
||||
}
|
||||
|
||||
if u, err := url.Parse(endpoint); err == nil {
|
||||
// Remove path from the endpoint since it will be added by requests.
|
||||
// This is an artifact of the SDK adding `/latest` to the endpoint for
|
||||
// EC2 IMDS, but this is now moved to the operation definition.
|
||||
u.Path = ""
|
||||
u.RawPath = ""
|
||||
endpoint = u.String()
|
||||
}
|
||||
|
||||
svc := &EC2Metadata{
|
||||
Client: client.New(
|
||||
cfg,
|
||||
|
|
|
|||
|
|
@ -87,6 +87,7 @@ func (t *tokenProvider) enableTokenProviderHandler(r *request.Request) {
|
|||
// If the error code status is 401, we enable the token provider
|
||||
if e, ok := r.Error.(awserr.RequestFailure); ok && e != nil &&
|
||||
e.StatusCode() == http.StatusUnauthorized {
|
||||
t.token.Store(ec2Token{})
|
||||
atomic.StoreUint32(&t.disabled, 0)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -7,6 +7,8 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
var regionValidationRegex = regexp.MustCompile(`^[[:alnum:]]([[:alnum:]\-]*[[:alnum:]])?$`)
|
||||
|
||||
type partitions []partition
|
||||
|
||||
func (ps partitions) EndpointFor(service, region string, opts ...func(*Options)) (ResolvedEndpoint, error) {
|
||||
|
|
@ -124,7 +126,7 @@ func (p partition) EndpointFor(service, region string, opts ...func(*Options)) (
|
|||
|
||||
defs := []endpoint{p.Defaults, s.Defaults}
|
||||
|
||||
return e.resolve(service, p.ID, region, p.DNSSuffix, defs, opt), nil
|
||||
return e.resolve(service, p.ID, region, p.DNSSuffix, defs, opt)
|
||||
}
|
||||
|
||||
func serviceList(ss services) []string {
|
||||
|
|
@ -233,7 +235,7 @@ func getByPriority(s []string, p []string, def string) string {
|
|||
return s[0]
|
||||
}
|
||||
|
||||
func (e endpoint) resolve(service, partitionID, region, dnsSuffix string, defs []endpoint, opts Options) ResolvedEndpoint {
|
||||
func (e endpoint) resolve(service, partitionID, region, dnsSuffix string, defs []endpoint, opts Options) (ResolvedEndpoint, error) {
|
||||
var merged endpoint
|
||||
for _, def := range defs {
|
||||
merged.mergeIn(def)
|
||||
|
|
@ -260,6 +262,10 @@ func (e endpoint) resolve(service, partitionID, region, dnsSuffix string, defs [
|
|||
region = signingRegion
|
||||
}
|
||||
|
||||
if !validateInputRegion(region) {
|
||||
return ResolvedEndpoint{}, fmt.Errorf("invalid region identifier format provided")
|
||||
}
|
||||
|
||||
u := strings.Replace(hostname, "{service}", service, 1)
|
||||
u = strings.Replace(u, "{region}", region, 1)
|
||||
u = strings.Replace(u, "{dnsSuffix}", dnsSuffix, 1)
|
||||
|
|
@ -274,7 +280,7 @@ func (e endpoint) resolve(service, partitionID, region, dnsSuffix string, defs [
|
|||
SigningName: signingName,
|
||||
SigningNameDerived: signingNameDerived,
|
||||
SigningMethod: getByPriority(e.SignatureVersions, signerPriority, defaultSigner),
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
|
||||
func getEndpointScheme(protocols []string, disableSSL bool) string {
|
||||
|
|
@ -339,3 +345,7 @@ const (
|
|||
boxedFalse
|
||||
boxedTrue
|
||||
)
|
||||
|
||||
func validateInputRegion(region string) bool {
|
||||
return regionValidationRegex.MatchString(region)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,8 @@ func isErrConnectionReset(err error) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
if strings.Contains(err.Error(), "connection reset") ||
|
||||
if strings.Contains(err.Error(), "use of closed network connection") ||
|
||||
strings.Contains(err.Error(), "connection reset") ||
|
||||
strings.Contains(err.Error(), "broken pipe") {
|
||||
return true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import (
|
|||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials/processcreds"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials/ssocreds"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials/stscreds"
|
||||
"github.com/aws/aws-sdk-go/aws/defaults"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
|
|
@ -100,6 +101,9 @@ func resolveCredsFromProfile(cfg *aws.Config,
|
|||
sharedCfg.Creds,
|
||||
)
|
||||
|
||||
case sharedCfg.hasSSOConfiguration():
|
||||
creds = resolveSSOCredentials(cfg, sharedCfg, handlers)
|
||||
|
||||
case len(sharedCfg.CredentialProcess) != 0:
|
||||
// Get credentials from CredentialProcess
|
||||
creds = processcreds.NewCredentials(sharedCfg.CredentialProcess)
|
||||
|
|
@ -151,6 +155,21 @@ func resolveCredsFromProfile(cfg *aws.Config,
|
|||
return creds, nil
|
||||
}
|
||||
|
||||
func resolveSSOCredentials(cfg *aws.Config, sharedCfg sharedConfig, handlers request.Handlers) *credentials.Credentials {
|
||||
cfgCopy := cfg.Copy()
|
||||
cfgCopy.Region = &sharedCfg.SSORegion
|
||||
|
||||
return ssocreds.NewCredentials(
|
||||
&Session{
|
||||
Config: cfgCopy,
|
||||
Handlers: handlers.Copy(),
|
||||
},
|
||||
sharedCfg.SSOAccountID,
|
||||
sharedCfg.SSORoleName,
|
||||
sharedCfg.SSOStartURL,
|
||||
)
|
||||
}
|
||||
|
||||
// valid credential source values
|
||||
const (
|
||||
credSourceEc2Metadata = "Ec2InstanceMetadata"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
// +build go1.13
|
||||
|
||||
package session
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Transport that should be used when a custom CA bundle is specified with the
|
||||
// SDK.
|
||||
func getCustomTransport() *http.Transport {
|
||||
return &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
DialContext: (&net.Dialer{
|
||||
Timeout: 30 * time.Second,
|
||||
KeepAlive: 30 * time.Second,
|
||||
DualStack: true,
|
||||
}).DialContext,
|
||||
ForceAttemptHTTP2: true,
|
||||
MaxIdleConns: 100,
|
||||
IdleConnTimeout: 90 * time.Second,
|
||||
TLSHandshakeTimeout: 10 * time.Second,
|
||||
ExpectContinueTimeout: 1 * time.Second,
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// +build go1.7
|
||||
// +build !go1.13,go1.7
|
||||
|
||||
package session
|
||||
|
||||
|
|
@ -10,7 +10,7 @@ import (
|
|||
|
||||
// Transport that should be used when a custom CA bundle is specified with the
|
||||
// SDK.
|
||||
func getCABundleTransport() *http.Transport {
|
||||
func getCustomTransport() *http.Transport {
|
||||
return &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
DialContext: (&net.Dialer{
|
||||
|
|
@ -10,7 +10,7 @@ import (
|
|||
|
||||
// Transport that should be used when a custom CA bundle is specified with the
|
||||
// SDK.
|
||||
func getCABundleTransport() *http.Transport {
|
||||
func getCustomTransport() *http.Transport {
|
||||
return &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
Dial: (&net.Dialer{
|
||||
|
|
@ -10,7 +10,7 @@ import (
|
|||
|
||||
// Transport that should be used when a custom CA bundle is specified with the
|
||||
// SDK.
|
||||
func getCABundleTransport() *http.Transport {
|
||||
func getCustomTransport() *http.Transport {
|
||||
return &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
Dial: (&net.Dialer{
|
||||
|
|
@ -208,6 +208,8 @@ env values as well.
|
|||
|
||||
AWS_SDK_LOAD_CONFIG=1
|
||||
|
||||
Custom Shared Config and Credential Files
|
||||
|
||||
Shared credentials file path can be set to instruct the SDK to use an alternative
|
||||
file for the shared credentials. If not set the file will be loaded from
|
||||
$HOME/.aws/credentials on Linux/Unix based systems, and
|
||||
|
|
@ -222,6 +224,8 @@ $HOME/.aws/config on Linux/Unix based systems, and
|
|||
|
||||
AWS_CONFIG_FILE=$HOME/my_shared_config
|
||||
|
||||
Custom CA Bundle
|
||||
|
||||
Path to a custom Credentials Authority (CA) bundle PEM file that the SDK
|
||||
will use instead of the default system's root CA bundle. Use this only
|
||||
if you want to replace the CA bundle the SDK uses for TLS requests.
|
||||
|
|
@ -241,5 +245,45 @@ over the AWS_CA_BUNDLE environment variable, and will be used if both are set.
|
|||
Setting a custom HTTPClient in the aws.Config options will override this setting.
|
||||
To use this option and custom HTTP client, the HTTP client needs to be provided
|
||||
when creating the session. Not the service client.
|
||||
|
||||
Custom Client TLS Certificate
|
||||
|
||||
The SDK supports the environment and session option being configured with
|
||||
Client TLS certificates that are sent as a part of the client's TLS handshake
|
||||
for client authentication. If used, both Cert and Key values are required. If
|
||||
one is missing, or either fail to load the contents of the file an error will
|
||||
be returned.
|
||||
|
||||
HTTP Client's Transport concrete implementation must be a http.Transport
|
||||
or creating the session will fail.
|
||||
|
||||
AWS_SDK_GO_CLIENT_TLS_KEY=$HOME/my_client_key
|
||||
AWS_SDK_GO_CLIENT_TLS_CERT=$HOME/my_client_cert
|
||||
|
||||
This can also be configured via the session.Options ClientTLSCert and ClientTLSKey.
|
||||
|
||||
sess, err := session.NewSessionWithOptions(session.Options{
|
||||
ClientTLSCert: myCertFile,
|
||||
ClientTLSKey: myKeyFile,
|
||||
})
|
||||
|
||||
Custom EC2 IMDS Endpoint
|
||||
|
||||
The endpoint of the EC2 IMDS client can be configured via the environment
|
||||
variable, AWS_EC2_METADATA_SERVICE_ENDPOINT when creating the client with a
|
||||
Session. See Options.EC2IMDSEndpoint for more details.
|
||||
|
||||
AWS_EC2_METADATA_SERVICE_ENDPOINT=http://169.254.169.254
|
||||
|
||||
If using an URL with an IPv6 address literal, the IPv6 address
|
||||
component must be enclosed in square brackets.
|
||||
|
||||
AWS_EC2_METADATA_SERVICE_ENDPOINT=http://[::1]
|
||||
|
||||
The custom EC2 IMDS endpoint can also be specified via the Session options.
|
||||
|
||||
sess, err := session.NewSessionWithOptions(session.Options{
|
||||
EC2IMDSEndpoint: "http://[::1]",
|
||||
})
|
||||
*/
|
||||
package session
|
||||
|
|
|
|||
|
|
@ -101,6 +101,18 @@ type envConfig struct {
|
|||
// AWS_CA_BUNDLE=$HOME/my_custom_ca_bundle
|
||||
CustomCABundle string
|
||||
|
||||
// Sets the TLC client certificate that should be used by the SDK's HTTP transport
|
||||
// when making requests. The certificate must be paired with a TLS client key file.
|
||||
//
|
||||
// AWS_SDK_GO_CLIENT_TLS_CERT=$HOME/my_client_cert
|
||||
ClientTLSCert string
|
||||
|
||||
// Sets the TLC client key that should be used by the SDK's HTTP transport
|
||||
// when making requests. The key must be paired with a TLS client certificate file.
|
||||
//
|
||||
// AWS_SDK_GO_CLIENT_TLS_KEY=$HOME/my_client_key
|
||||
ClientTLSKey string
|
||||
|
||||
csmEnabled string
|
||||
CSMEnabled *bool
|
||||
CSMPort string
|
||||
|
|
@ -148,6 +160,11 @@ type envConfig struct {
|
|||
//
|
||||
// AWS_S3_USE_ARN_REGION=true
|
||||
S3UseARNRegion bool
|
||||
|
||||
// Specifies the alternative endpoint to use for EC2 IMDS.
|
||||
//
|
||||
// AWS_EC2_METADATA_SERVICE_ENDPOINT=http://[::1]
|
||||
EC2IMDSEndpoint string
|
||||
}
|
||||
|
||||
var (
|
||||
|
|
@ -211,6 +228,18 @@ var (
|
|||
s3UseARNRegionEnvKey = []string{
|
||||
"AWS_S3_USE_ARN_REGION",
|
||||
}
|
||||
ec2IMDSEndpointEnvKey = []string{
|
||||
"AWS_EC2_METADATA_SERVICE_ENDPOINT",
|
||||
}
|
||||
useCABundleKey = []string{
|
||||
"AWS_CA_BUNDLE",
|
||||
}
|
||||
useClientTLSCert = []string{
|
||||
"AWS_SDK_GO_CLIENT_TLS_CERT",
|
||||
}
|
||||
useClientTLSKey = []string{
|
||||
"AWS_SDK_GO_CLIENT_TLS_KEY",
|
||||
}
|
||||
)
|
||||
|
||||
// loadEnvConfig retrieves the SDK's environment configuration.
|
||||
|
|
@ -294,7 +323,9 @@ func envConfigLoad(enableSharedConfig bool) (envConfig, error) {
|
|||
cfg.SharedConfigFile = defaults.SharedConfigFilename()
|
||||
}
|
||||
|
||||
cfg.CustomCABundle = os.Getenv("AWS_CA_BUNDLE")
|
||||
setFromEnvVal(&cfg.CustomCABundle, useCABundleKey)
|
||||
setFromEnvVal(&cfg.ClientTLSCert, useClientTLSCert)
|
||||
setFromEnvVal(&cfg.ClientTLSKey, useClientTLSKey)
|
||||
|
||||
var err error
|
||||
// STS Regional Endpoint variable
|
||||
|
|
@ -332,6 +363,8 @@ func envConfigLoad(enableSharedConfig bool) (envConfig, error) {
|
|||
}
|
||||
}
|
||||
|
||||
setFromEnvVal(&cfg.EC2IMDSEndpoint, ec2IMDSEndpointEnvKey)
|
||||
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,11 +25,18 @@ const (
|
|||
// ErrCodeSharedConfig represents an error that occurs in the shared
|
||||
// configuration logic
|
||||
ErrCodeSharedConfig = "SharedConfigErr"
|
||||
|
||||
// ErrCodeLoadCustomCABundle error code for unable to load custom CA bundle.
|
||||
ErrCodeLoadCustomCABundle = "LoadCustomCABundleError"
|
||||
|
||||
// ErrCodeLoadClientTLSCert error code for unable to load client TLS
|
||||
// certificate or key
|
||||
ErrCodeLoadClientTLSCert = "LoadClientTLSCertError"
|
||||
)
|
||||
|
||||
// ErrSharedConfigSourceCollision will be returned if a section contains both
|
||||
// source_profile and credential_source
|
||||
var ErrSharedConfigSourceCollision = awserr.New(ErrCodeSharedConfig, "only source profile or credential source can be specified, not both", nil)
|
||||
var ErrSharedConfigSourceCollision = awserr.New(ErrCodeSharedConfig, "only one credential type may be specified per profile: source profile, credential source, credential process, web identity token, or sso", nil)
|
||||
|
||||
// ErrSharedConfigECSContainerEnvVarEmpty will be returned if the environment
|
||||
// variables are empty and Environment was set as the credential source
|
||||
|
|
@ -48,6 +55,8 @@ var ErrSharedConfigInvalidCredSource = awserr.New(ErrCodeSharedConfig, "credenti
|
|||
type Session struct {
|
||||
Config *aws.Config
|
||||
Handlers request.Handlers
|
||||
|
||||
options Options
|
||||
}
|
||||
|
||||
// New creates a new instance of the handlers merging in the provided configs
|
||||
|
|
@ -99,7 +108,7 @@ func New(cfgs ...*aws.Config) *Session {
|
|||
return s
|
||||
}
|
||||
|
||||
s := deprecatedNewSession(cfgs...)
|
||||
s := deprecatedNewSession(envCfg, cfgs...)
|
||||
if envErr != nil {
|
||||
msg := "failed to load env config"
|
||||
s.logDeprecatedNewSessionError(msg, envErr, cfgs)
|
||||
|
|
@ -227,22 +236,68 @@ type Options struct {
|
|||
// the SDK will use instead of the default system's root CA bundle. Use this
|
||||
// only if you want to replace the CA bundle the SDK uses for TLS requests.
|
||||
//
|
||||
// Enabling this option will attempt to merge the Transport into the SDK's HTTP
|
||||
// client. If the client's Transport is not a http.Transport an error will be
|
||||
// returned. If the Transport's TLS config is set this option will cause the SDK
|
||||
// HTTP Client's Transport concrete implementation must be a http.Transport
|
||||
// or creating the session will fail.
|
||||
//
|
||||
// If the Transport's TLS config is set this option will cause the SDK
|
||||
// to overwrite the Transport's TLS config's RootCAs value. If the CA
|
||||
// bundle reader contains multiple certificates all of them will be loaded.
|
||||
//
|
||||
// The Session option CustomCABundle is also available when creating sessions
|
||||
// to also enable this feature. CustomCABundle session option field has priority
|
||||
// over the AWS_CA_BUNDLE environment variable, and will be used if both are set.
|
||||
// Can also be specified via the environment variable:
|
||||
//
|
||||
// AWS_CA_BUNDLE=$HOME/ca_bundle
|
||||
//
|
||||
// Can also be specified via the shared config field:
|
||||
//
|
||||
// ca_bundle = $HOME/ca_bundle
|
||||
CustomCABundle io.Reader
|
||||
|
||||
// Reader for the TLC client certificate that should be used by the SDK's
|
||||
// HTTP transport when making requests. The certificate must be paired with
|
||||
// a TLS client key file. Will be ignored if both are not provided.
|
||||
//
|
||||
// HTTP Client's Transport concrete implementation must be a http.Transport
|
||||
// or creating the session will fail.
|
||||
//
|
||||
// Can also be specified via the environment variable:
|
||||
//
|
||||
// AWS_SDK_GO_CLIENT_TLS_CERT=$HOME/my_client_cert
|
||||
ClientTLSCert io.Reader
|
||||
|
||||
// Reader for the TLC client key that should be used by the SDK's HTTP
|
||||
// transport when making requests. The key must be paired with a TLS client
|
||||
// certificate file. Will be ignored if both are not provided.
|
||||
//
|
||||
// HTTP Client's Transport concrete implementation must be a http.Transport
|
||||
// or creating the session will fail.
|
||||
//
|
||||
// Can also be specified via the environment variable:
|
||||
//
|
||||
// AWS_SDK_GO_CLIENT_TLS_KEY=$HOME/my_client_key
|
||||
ClientTLSKey io.Reader
|
||||
|
||||
// The handlers that the session and all API clients will be created with.
|
||||
// This must be a complete set of handlers. Use the defaults.Handlers()
|
||||
// function to initialize this value before changing the handlers to be
|
||||
// used by the SDK.
|
||||
Handlers request.Handlers
|
||||
|
||||
// Allows specifying a custom endpoint to be used by the EC2 IMDS client
|
||||
// when making requests to the EC2 IMDS API. The must endpoint value must
|
||||
// include protocol prefix.
|
||||
//
|
||||
// If unset, will the EC2 IMDS client will use its default endpoint.
|
||||
//
|
||||
// Can also be specified via the environment variable,
|
||||
// AWS_EC2_METADATA_SERVICE_ENDPOINT.
|
||||
//
|
||||
// AWS_EC2_METADATA_SERVICE_ENDPOINT=http://169.254.169.254
|
||||
//
|
||||
// If using an URL with an IPv6 address literal, the IPv6 address
|
||||
// component must be enclosed in square brackets.
|
||||
//
|
||||
// AWS_EC2_METADATA_SERVICE_ENDPOINT=http://[::1]
|
||||
EC2IMDSEndpoint string
|
||||
}
|
||||
|
||||
// NewSessionWithOptions returns a new Session created from SDK defaults, config files,
|
||||
|
|
@ -300,17 +355,6 @@ func NewSessionWithOptions(opts Options) (*Session, error) {
|
|||
envCfg.EnableSharedConfig = true
|
||||
}
|
||||
|
||||
// Only use AWS_CA_BUNDLE if session option is not provided.
|
||||
if len(envCfg.CustomCABundle) != 0 && opts.CustomCABundle == nil {
|
||||
f, err := os.Open(envCfg.CustomCABundle)
|
||||
if err != nil {
|
||||
return nil, awserr.New("LoadCustomCABundleError",
|
||||
"failed to open custom CA bundle PEM file", err)
|
||||
}
|
||||
defer f.Close()
|
||||
opts.CustomCABundle = f
|
||||
}
|
||||
|
||||
return newSession(opts, envCfg, &opts.Config)
|
||||
}
|
||||
|
||||
|
|
@ -329,7 +373,25 @@ func Must(sess *Session, err error) *Session {
|
|||
return sess
|
||||
}
|
||||
|
||||
func deprecatedNewSession(cfgs ...*aws.Config) *Session {
|
||||
// Wraps the endpoint resolver with a resolver that will return a custom
|
||||
// endpoint for EC2 IMDS.
|
||||
func wrapEC2IMDSEndpoint(resolver endpoints.Resolver, endpoint string) endpoints.Resolver {
|
||||
return endpoints.ResolverFunc(
|
||||
func(service, region string, opts ...func(*endpoints.Options)) (
|
||||
endpoints.ResolvedEndpoint, error,
|
||||
) {
|
||||
if service == ec2MetadataServiceID {
|
||||
return endpoints.ResolvedEndpoint{
|
||||
URL: endpoint,
|
||||
SigningName: ec2MetadataServiceID,
|
||||
SigningRegion: region,
|
||||
}, nil
|
||||
}
|
||||
return resolver.EndpointFor(service, region)
|
||||
})
|
||||
}
|
||||
|
||||
func deprecatedNewSession(envCfg envConfig, cfgs ...*aws.Config) *Session {
|
||||
cfg := defaults.Config()
|
||||
handlers := defaults.Handlers()
|
||||
|
||||
|
|
@ -341,6 +403,11 @@ func deprecatedNewSession(cfgs ...*aws.Config) *Session {
|
|||
// endpoints for service client configurations.
|
||||
cfg.EndpointResolver = endpoints.DefaultResolver()
|
||||
}
|
||||
|
||||
if len(envCfg.EC2IMDSEndpoint) != 0 {
|
||||
cfg.EndpointResolver = wrapEC2IMDSEndpoint(cfg.EndpointResolver, envCfg.EC2IMDSEndpoint)
|
||||
}
|
||||
|
||||
cfg.Credentials = defaults.CredChain(cfg, handlers)
|
||||
|
||||
// Reapply any passed in configs to override credentials if set
|
||||
|
|
@ -349,6 +416,9 @@ func deprecatedNewSession(cfgs ...*aws.Config) *Session {
|
|||
s := &Session{
|
||||
Config: cfg,
|
||||
Handlers: handlers,
|
||||
options: Options{
|
||||
EC2IMDSEndpoint: envCfg.EC2IMDSEndpoint,
|
||||
},
|
||||
}
|
||||
|
||||
initHandlers(s)
|
||||
|
|
@ -415,9 +485,14 @@ func newSession(opts Options, envCfg envConfig, cfgs ...*aws.Config) (*Session,
|
|||
return nil, err
|
||||
}
|
||||
|
||||
if err := setTLSOptions(&opts, cfg, envCfg, sharedCfg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s := &Session{
|
||||
Config: cfg,
|
||||
Handlers: handlers,
|
||||
options: opts,
|
||||
}
|
||||
|
||||
initHandlers(s)
|
||||
|
|
@ -433,13 +508,6 @@ func newSession(opts Options, envCfg envConfig, cfgs ...*aws.Config) (*Session,
|
|||
}
|
||||
}
|
||||
|
||||
// Setup HTTP client with custom cert bundle if enabled
|
||||
if opts.CustomCABundle != nil {
|
||||
if err := loadCustomCABundle(s, opts.CustomCABundle); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
|
|
@ -483,22 +551,83 @@ func loadCSMConfig(envCfg envConfig, cfgFiles []string) (csmConfig, error) {
|
|||
return csmConfig{}, nil
|
||||
}
|
||||
|
||||
func loadCustomCABundle(s *Session, bundle io.Reader) error {
|
||||
func setTLSOptions(opts *Options, cfg *aws.Config, envCfg envConfig, sharedCfg sharedConfig) error {
|
||||
// CA Bundle can be specified in both environment variable shared config file.
|
||||
var caBundleFilename = envCfg.CustomCABundle
|
||||
if len(caBundleFilename) == 0 {
|
||||
caBundleFilename = sharedCfg.CustomCABundle
|
||||
}
|
||||
|
||||
// Only use environment value if session option is not provided.
|
||||
customTLSOptions := map[string]struct {
|
||||
filename string
|
||||
field *io.Reader
|
||||
errCode string
|
||||
}{
|
||||
"custom CA bundle PEM": {filename: caBundleFilename, field: &opts.CustomCABundle, errCode: ErrCodeLoadCustomCABundle},
|
||||
"custom client TLS cert": {filename: envCfg.ClientTLSCert, field: &opts.ClientTLSCert, errCode: ErrCodeLoadClientTLSCert},
|
||||
"custom client TLS key": {filename: envCfg.ClientTLSKey, field: &opts.ClientTLSKey, errCode: ErrCodeLoadClientTLSCert},
|
||||
}
|
||||
for name, v := range customTLSOptions {
|
||||
if len(v.filename) != 0 && *v.field == nil {
|
||||
f, err := os.Open(v.filename)
|
||||
if err != nil {
|
||||
return awserr.New(v.errCode, fmt.Sprintf("failed to open %s file", name), err)
|
||||
}
|
||||
defer f.Close()
|
||||
*v.field = f
|
||||
}
|
||||
}
|
||||
|
||||
// Setup HTTP client with custom cert bundle if enabled
|
||||
if opts.CustomCABundle != nil {
|
||||
if err := loadCustomCABundle(cfg.HTTPClient, opts.CustomCABundle); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Setup HTTP client TLS certificate and key for client TLS authentication.
|
||||
if opts.ClientTLSCert != nil && opts.ClientTLSKey != nil {
|
||||
if err := loadClientTLSCert(cfg.HTTPClient, opts.ClientTLSCert, opts.ClientTLSKey); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if opts.ClientTLSCert == nil && opts.ClientTLSKey == nil {
|
||||
// Do nothing if neither values are available.
|
||||
|
||||
} else {
|
||||
return awserr.New(ErrCodeLoadClientTLSCert,
|
||||
fmt.Sprintf("client TLS cert(%t) and key(%t) must both be provided",
|
||||
opts.ClientTLSCert != nil, opts.ClientTLSKey != nil), nil)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getHTTPTransport(client *http.Client) (*http.Transport, error) {
|
||||
var t *http.Transport
|
||||
switch v := s.Config.HTTPClient.Transport.(type) {
|
||||
switch v := client.Transport.(type) {
|
||||
case *http.Transport:
|
||||
t = v
|
||||
default:
|
||||
if s.Config.HTTPClient.Transport != nil {
|
||||
return awserr.New("LoadCustomCABundleError",
|
||||
"unable to load custom CA bundle, HTTPClient's transport unsupported type", nil)
|
||||
if client.Transport != nil {
|
||||
return nil, fmt.Errorf("unsupported transport, %T", client.Transport)
|
||||
}
|
||||
}
|
||||
if t == nil {
|
||||
// Nil transport implies `http.DefaultTransport` should be used. Since
|
||||
// the SDK cannot modify, nor copy the `DefaultTransport` specifying
|
||||
// the values the next closest behavior.
|
||||
t = getCABundleTransport()
|
||||
t = getCustomTransport()
|
||||
}
|
||||
|
||||
return t, nil
|
||||
}
|
||||
|
||||
func loadCustomCABundle(client *http.Client, bundle io.Reader) error {
|
||||
t, err := getHTTPTransport(client)
|
||||
if err != nil {
|
||||
return awserr.New(ErrCodeLoadCustomCABundle,
|
||||
"unable to load custom CA bundle, HTTPClient's transport unsupported type", err)
|
||||
}
|
||||
|
||||
p, err := loadCertPool(bundle)
|
||||
|
|
@ -510,7 +639,7 @@ func loadCustomCABundle(s *Session, bundle io.Reader) error {
|
|||
}
|
||||
t.TLSClientConfig.RootCAs = p
|
||||
|
||||
s.Config.HTTPClient.Transport = t
|
||||
client.Transport = t
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
@ -518,19 +647,57 @@ func loadCustomCABundle(s *Session, bundle io.Reader) error {
|
|||
func loadCertPool(r io.Reader) (*x509.CertPool, error) {
|
||||
b, err := ioutil.ReadAll(r)
|
||||
if err != nil {
|
||||
return nil, awserr.New("LoadCustomCABundleError",
|
||||
return nil, awserr.New(ErrCodeLoadCustomCABundle,
|
||||
"failed to read custom CA bundle PEM file", err)
|
||||
}
|
||||
|
||||
p := x509.NewCertPool()
|
||||
if !p.AppendCertsFromPEM(b) {
|
||||
return nil, awserr.New("LoadCustomCABundleError",
|
||||
return nil, awserr.New(ErrCodeLoadCustomCABundle,
|
||||
"failed to load custom CA bundle PEM file", err)
|
||||
}
|
||||
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func loadClientTLSCert(client *http.Client, certFile, keyFile io.Reader) error {
|
||||
t, err := getHTTPTransport(client)
|
||||
if err != nil {
|
||||
return awserr.New(ErrCodeLoadClientTLSCert,
|
||||
"unable to get usable HTTP transport from client", err)
|
||||
}
|
||||
|
||||
cert, err := ioutil.ReadAll(certFile)
|
||||
if err != nil {
|
||||
return awserr.New(ErrCodeLoadClientTLSCert,
|
||||
"unable to get read client TLS cert file", err)
|
||||
}
|
||||
|
||||
key, err := ioutil.ReadAll(keyFile)
|
||||
if err != nil {
|
||||
return awserr.New(ErrCodeLoadClientTLSCert,
|
||||
"unable to get read client TLS key file", err)
|
||||
}
|
||||
|
||||
clientCert, err := tls.X509KeyPair(cert, key)
|
||||
if err != nil {
|
||||
return awserr.New(ErrCodeLoadClientTLSCert,
|
||||
"unable to load x509 key pair from client cert", err)
|
||||
}
|
||||
|
||||
tlsCfg := t.TLSClientConfig
|
||||
if tlsCfg == nil {
|
||||
tlsCfg = &tls.Config{}
|
||||
}
|
||||
|
||||
tlsCfg.Certificates = append(tlsCfg.Certificates, clientCert)
|
||||
|
||||
t.TLSClientConfig = tlsCfg
|
||||
client.Transport = t
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func mergeConfigSrcs(cfg, userCfg *aws.Config,
|
||||
envCfg envConfig, sharedCfg sharedConfig,
|
||||
handlers request.Handlers,
|
||||
|
|
@ -570,6 +737,14 @@ func mergeConfigSrcs(cfg, userCfg *aws.Config,
|
|||
endpoints.LegacyS3UsEast1Endpoint,
|
||||
})
|
||||
|
||||
ec2IMDSEndpoint := sessOpts.EC2IMDSEndpoint
|
||||
if len(ec2IMDSEndpoint) == 0 {
|
||||
ec2IMDSEndpoint = envCfg.EC2IMDSEndpoint
|
||||
}
|
||||
if len(ec2IMDSEndpoint) != 0 {
|
||||
cfg.EndpointResolver = wrapEC2IMDSEndpoint(cfg.EndpointResolver, ec2IMDSEndpoint)
|
||||
}
|
||||
|
||||
// Configure credentials if not already set by the user when creating the
|
||||
// Session.
|
||||
if cfg.Credentials == credentials.AnonymousCredentials && userCfg.Credentials == nil {
|
||||
|
|
@ -627,6 +802,7 @@ func (s *Session) Copy(cfgs ...*aws.Config) *Session {
|
|||
newSession := &Session{
|
||||
Config: s.Config.Copy(cfgs...),
|
||||
Handlers: s.Handlers.Copy(),
|
||||
options: s.options,
|
||||
}
|
||||
|
||||
initHandlers(newSession)
|
||||
|
|
@ -665,6 +841,8 @@ func (s *Session) ClientConfig(service string, cfgs ...*aws.Config) client.Confi
|
|||
}
|
||||
}
|
||||
|
||||
const ec2MetadataServiceID = "ec2metadata"
|
||||
|
||||
func (s *Session) resolveEndpoint(service, region string, cfg *aws.Config) (endpoints.ResolvedEndpoint, error) {
|
||||
|
||||
if ep := aws.StringValue(cfg.Endpoint); len(ep) != 0 {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package session
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
|
|
@ -25,6 +26,12 @@ const (
|
|||
roleSessionNameKey = `role_session_name` // optional
|
||||
roleDurationSecondsKey = "duration_seconds" // optional
|
||||
|
||||
// AWS Single Sign-On (AWS SSO) group
|
||||
ssoAccountIDKey = "sso_account_id"
|
||||
ssoRegionKey = "sso_region"
|
||||
ssoRoleNameKey = "sso_role_name"
|
||||
ssoStartURL = "sso_start_url"
|
||||
|
||||
// CSM options
|
||||
csmEnabledKey = `csm_enabled`
|
||||
csmHostKey = `csm_host`
|
||||
|
|
@ -34,6 +41,9 @@ const (
|
|||
// Additional Config fields
|
||||
regionKey = `region`
|
||||
|
||||
// custom CA Bundle filename
|
||||
customCABundleKey = `ca_bundle`
|
||||
|
||||
// endpoint discovery group
|
||||
enableEndpointDiscoveryKey = `endpoint_discovery_enabled` // optional
|
||||
|
||||
|
|
@ -75,6 +85,11 @@ type sharedConfig struct {
|
|||
CredentialProcess string
|
||||
WebIdentityTokenFile string
|
||||
|
||||
SSOAccountID string
|
||||
SSORegion string
|
||||
SSORoleName string
|
||||
SSOStartURL string
|
||||
|
||||
RoleARN string
|
||||
RoleSessionName string
|
||||
ExternalID string
|
||||
|
|
@ -90,6 +105,15 @@ type sharedConfig struct {
|
|||
// region
|
||||
Region string
|
||||
|
||||
// CustomCABundle is the file path to a PEM file the SDK will read and
|
||||
// use to configure the HTTP transport with additional CA certs that are
|
||||
// not present in the platforms default CA store.
|
||||
//
|
||||
// This value will be ignored if the file does not exist.
|
||||
//
|
||||
// ca_bundle
|
||||
CustomCABundle string
|
||||
|
||||
// EnableEndpointDiscovery can be enabled in the shared config by setting
|
||||
// endpoint_discovery_enabled to true
|
||||
//
|
||||
|
|
@ -205,9 +229,9 @@ func (cfg *sharedConfig) setFromIniFiles(profiles map[string]struct{}, profile s
|
|||
cfg.clearAssumeRoleOptions()
|
||||
} else {
|
||||
// First time a profile has been seen, It must either be a assume role
|
||||
// or credentials. Assert if the credential type requires a role ARN,
|
||||
// the ARN is also set.
|
||||
if err := cfg.validateCredentialsRequireARN(profile); err != nil {
|
||||
// credentials, or SSO. Assert if the credential type requires a role ARN,
|
||||
// the ARN is also set, or validate that the SSO configuration is complete.
|
||||
if err := cfg.validateCredentialsConfig(profile); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
@ -276,6 +300,7 @@ func (cfg *sharedConfig) setFromIniFile(profile string, file sharedConfigFile, e
|
|||
updateString(&cfg.SourceProfileName, section, sourceProfileKey)
|
||||
updateString(&cfg.CredentialSource, section, credentialSourceKey)
|
||||
updateString(&cfg.Region, section, regionKey)
|
||||
updateString(&cfg.CustomCABundle, section, customCABundleKey)
|
||||
|
||||
if section.Has(roleDurationSecondsKey) {
|
||||
d := time.Duration(section.Int(roleDurationSecondsKey)) * time.Second
|
||||
|
|
@ -299,6 +324,12 @@ func (cfg *sharedConfig) setFromIniFile(profile string, file sharedConfigFile, e
|
|||
}
|
||||
cfg.S3UsEast1RegionalEndpoint = sre
|
||||
}
|
||||
|
||||
// AWS Single Sign-On (AWS SSO)
|
||||
updateString(&cfg.SSOAccountID, section, ssoAccountIDKey)
|
||||
updateString(&cfg.SSORegion, section, ssoRegionKey)
|
||||
updateString(&cfg.SSORoleName, section, ssoRoleNameKey)
|
||||
updateString(&cfg.SSOStartURL, section, ssoStartURL)
|
||||
}
|
||||
|
||||
updateString(&cfg.CredentialProcess, section, credentialProcessKey)
|
||||
|
|
@ -329,6 +360,18 @@ func (cfg *sharedConfig) setFromIniFile(profile string, file sharedConfigFile, e
|
|||
return nil
|
||||
}
|
||||
|
||||
func (cfg *sharedConfig) validateCredentialsConfig(profile string) error {
|
||||
if err := cfg.validateCredentialsRequireARN(profile); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := cfg.validateSSOConfiguration(profile); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cfg *sharedConfig) validateCredentialsRequireARN(profile string) error {
|
||||
var credSource string
|
||||
|
||||
|
|
@ -358,6 +401,7 @@ func (cfg *sharedConfig) validateCredentialType() error {
|
|||
len(cfg.CredentialSource) != 0,
|
||||
len(cfg.CredentialProcess) != 0,
|
||||
len(cfg.WebIdentityTokenFile) != 0,
|
||||
cfg.hasSSOConfiguration(),
|
||||
) {
|
||||
return ErrSharedConfigSourceCollision
|
||||
}
|
||||
|
|
@ -365,12 +409,43 @@ func (cfg *sharedConfig) validateCredentialType() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (cfg *sharedConfig) validateSSOConfiguration(profile string) error {
|
||||
if !cfg.hasSSOConfiguration() {
|
||||
return nil
|
||||
}
|
||||
|
||||
var missing []string
|
||||
if len(cfg.SSOAccountID) == 0 {
|
||||
missing = append(missing, ssoAccountIDKey)
|
||||
}
|
||||
|
||||
if len(cfg.SSORegion) == 0 {
|
||||
missing = append(missing, ssoRegionKey)
|
||||
}
|
||||
|
||||
if len(cfg.SSORoleName) == 0 {
|
||||
missing = append(missing, ssoRoleNameKey)
|
||||
}
|
||||
|
||||
if len(cfg.SSOStartURL) == 0 {
|
||||
missing = append(missing, ssoStartURL)
|
||||
}
|
||||
|
||||
if len(missing) > 0 {
|
||||
return fmt.Errorf("profile %q is configured to use SSO but is missing required configuration: %s",
|
||||
profile, strings.Join(missing, ", "))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cfg *sharedConfig) hasCredentials() bool {
|
||||
switch {
|
||||
case len(cfg.SourceProfileName) != 0:
|
||||
case len(cfg.CredentialSource) != 0:
|
||||
case len(cfg.CredentialProcess) != 0:
|
||||
case len(cfg.WebIdentityTokenFile) != 0:
|
||||
case cfg.hasSSOConfiguration():
|
||||
case cfg.Creds.HasKeys():
|
||||
default:
|
||||
return false
|
||||
|
|
@ -394,6 +469,18 @@ func (cfg *sharedConfig) clearAssumeRoleOptions() {
|
|||
cfg.SourceProfileName = ""
|
||||
}
|
||||
|
||||
func (cfg *sharedConfig) hasSSOConfiguration() bool {
|
||||
switch {
|
||||
case len(cfg.SSOAccountID) != 0:
|
||||
case len(cfg.SSORegion) != 0:
|
||||
case len(cfg.SSORoleName) != 0:
|
||||
case len(cfg.SSOStartURL) != 0:
|
||||
default:
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func oneOrNone(bs ...bool) bool {
|
||||
var count int
|
||||
|
||||
|
|
|
|||
|
|
@ -5,4 +5,4 @@ package aws
|
|||
const SDKName = "aws-sdk-go"
|
||||
|
||||
// SDKVersion is the version of this SDK
|
||||
const SDKVersion = "1.31.12"
|
||||
const SDKVersion = "1.37.1"
|
||||
|
|
|
|||
|
|
@ -63,9 +63,10 @@ var parseTable = map[ASTKind]map[TokenType]int{
|
|||
TokenNone: MarkCompleteState,
|
||||
},
|
||||
ASTKindEqualExpr: map[TokenType]int{
|
||||
TokenLit: ValueState,
|
||||
TokenWS: SkipTokenState,
|
||||
TokenNL: SkipState,
|
||||
TokenLit: ValueState,
|
||||
TokenWS: SkipTokenState,
|
||||
TokenNL: SkipState,
|
||||
TokenNone: SkipState,
|
||||
},
|
||||
ASTKindStatement: map[TokenType]int{
|
||||
TokenLit: SectionState,
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
package protocol
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
"net"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ValidateEndpointHostHandler is a request handler that will validate the
|
||||
|
|
@ -22,8 +23,26 @@ var ValidateEndpointHostHandler = request.NamedHandler{
|
|||
// 3986 host. Returns error if the host is not valid.
|
||||
func ValidateEndpointHost(opName, host string) error {
|
||||
paramErrs := request.ErrInvalidParams{Context: opName}
|
||||
labels := strings.Split(host, ".")
|
||||
|
||||
var hostname string
|
||||
var port string
|
||||
var err error
|
||||
|
||||
if strings.Contains(host, ":") {
|
||||
hostname, port, err = net.SplitHostPort(host)
|
||||
|
||||
if err != nil {
|
||||
paramErrs.Add(request.NewErrParamFormat("endpoint", err.Error(), host))
|
||||
}
|
||||
|
||||
if !ValidPortNumber(port) {
|
||||
paramErrs.Add(request.NewErrParamFormat("endpoint port number", "[0-65535]", port))
|
||||
}
|
||||
} else {
|
||||
hostname = host
|
||||
}
|
||||
|
||||
labels := strings.Split(hostname, ".")
|
||||
for i, label := range labels {
|
||||
if i == len(labels)-1 && len(label) == 0 {
|
||||
// Allow trailing dot for FQDN hosts.
|
||||
|
|
@ -36,7 +55,11 @@ func ValidateEndpointHost(opName, host string) error {
|
|||
}
|
||||
}
|
||||
|
||||
if len(host) > 255 {
|
||||
if len(hostname) == 0 {
|
||||
paramErrs.Add(request.NewErrParamMinLen("endpoint host", 1))
|
||||
}
|
||||
|
||||
if len(hostname) > 255 {
|
||||
paramErrs.Add(request.NewErrParamMaxLen(
|
||||
"endpoint host", 255, host,
|
||||
))
|
||||
|
|
@ -66,3 +89,16 @@ func ValidHostLabel(label string) bool {
|
|||
|
||||
return true
|
||||
}
|
||||
|
||||
// ValidPortNumber return if the port is valid RFC 3986 port
|
||||
func ValidPortNumber(port string) bool {
|
||||
i, err := strconv.Atoi(port)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if i < 0 || i > 65535 {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"math/big"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
|
|
@ -15,6 +16,8 @@ import (
|
|||
"github.com/aws/aws-sdk-go/private/protocol"
|
||||
)
|
||||
|
||||
var millisecondsFloat = new(big.Float).SetInt64(1e3)
|
||||
|
||||
// UnmarshalJSONError unmarshal's the reader's JSON document into the passed in
|
||||
// type. The value to unmarshal the json document into must be a pointer to the
|
||||
// type.
|
||||
|
|
@ -39,7 +42,9 @@ func UnmarshalJSONError(v interface{}, stream io.Reader) error {
|
|||
func UnmarshalJSON(v interface{}, stream io.Reader) error {
|
||||
var out interface{}
|
||||
|
||||
err := json.NewDecoder(stream).Decode(&out)
|
||||
decoder := json.NewDecoder(stream)
|
||||
decoder.UseNumber()
|
||||
err := decoder.Decode(&out)
|
||||
if err == io.EOF {
|
||||
return nil
|
||||
} else if err != nil {
|
||||
|
|
@ -54,7 +59,9 @@ func UnmarshalJSON(v interface{}, stream io.Reader) error {
|
|||
func UnmarshalJSONCaseInsensitive(v interface{}, stream io.Reader) error {
|
||||
var out interface{}
|
||||
|
||||
err := json.NewDecoder(stream).Decode(&out)
|
||||
decoder := json.NewDecoder(stream)
|
||||
decoder.UseNumber()
|
||||
err := decoder.Decode(&out)
|
||||
if err == io.EOF {
|
||||
return nil
|
||||
} else if err != nil {
|
||||
|
|
@ -254,16 +261,31 @@ func (u unmarshaler) unmarshalScalar(value reflect.Value, data interface{}, tag
|
|||
default:
|
||||
return fmt.Errorf("unsupported value: %v (%s)", value.Interface(), value.Type())
|
||||
}
|
||||
case float64:
|
||||
case json.Number:
|
||||
switch value.Interface().(type) {
|
||||
case *int64:
|
||||
di := int64(d)
|
||||
// Retain the old behavior where we would just truncate the float64
|
||||
// calling d.Int64() here could cause an invalid syntax error due to the usage of strconv.ParseInt
|
||||
f, err := d.Float64()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
di := int64(f)
|
||||
value.Set(reflect.ValueOf(&di))
|
||||
case *float64:
|
||||
value.Set(reflect.ValueOf(&d))
|
||||
f, err := d.Float64()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
value.Set(reflect.ValueOf(&f))
|
||||
case *time.Time:
|
||||
// Time unmarshaled from a float64 can only be epoch seconds
|
||||
t := time.Unix(int64(d), 0).UTC()
|
||||
float, ok := new(big.Float).SetString(d.String())
|
||||
if !ok {
|
||||
return fmt.Errorf("unsupported float time representation: %v", d.String())
|
||||
}
|
||||
float = float.Mul(float, millisecondsFloat)
|
||||
ms, _ := float.Int64()
|
||||
t := time.Unix(0, ms*1e6).UTC()
|
||||
value.Set(reflect.ValueOf(&t))
|
||||
default:
|
||||
return fmt.Errorf("unsupported value: %v (%s)", value.Interface(), value.Type())
|
||||
|
|
|
|||
88
vendor/github.com/aws/aws-sdk-go/private/protocol/jsonrpc/jsonrpc.go
generated
vendored
Normal file
88
vendor/github.com/aws/aws-sdk-go/private/protocol/jsonrpc/jsonrpc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
// Package jsonrpc provides JSON RPC utilities for serialization of AWS
|
||||
// requests and responses.
|
||||
package jsonrpc
|
||||
|
||||
//go:generate go run -tags codegen ../../../private/model/cli/gen-protocol-tests ../../../models/protocol_tests/input/json.json build_test.go
|
||||
//go:generate go run -tags codegen ../../../private/model/cli/gen-protocol-tests ../../../models/protocol_tests/output/json.json unmarshal_test.go
|
||||
|
||||
import (
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
"github.com/aws/aws-sdk-go/private/protocol/json/jsonutil"
|
||||
"github.com/aws/aws-sdk-go/private/protocol/rest"
|
||||
)
|
||||
|
||||
var emptyJSON = []byte("{}")
|
||||
|
||||
// BuildHandler is a named request handler for building jsonrpc protocol
|
||||
// requests
|
||||
var BuildHandler = request.NamedHandler{
|
||||
Name: "awssdk.jsonrpc.Build",
|
||||
Fn: Build,
|
||||
}
|
||||
|
||||
// UnmarshalHandler is a named request handler for unmarshaling jsonrpc
|
||||
// protocol requests
|
||||
var UnmarshalHandler = request.NamedHandler{
|
||||
Name: "awssdk.jsonrpc.Unmarshal",
|
||||
Fn: Unmarshal,
|
||||
}
|
||||
|
||||
// UnmarshalMetaHandler is a named request handler for unmarshaling jsonrpc
|
||||
// protocol request metadata
|
||||
var UnmarshalMetaHandler = request.NamedHandler{
|
||||
Name: "awssdk.jsonrpc.UnmarshalMeta",
|
||||
Fn: UnmarshalMeta,
|
||||
}
|
||||
|
||||
// Build builds a JSON payload for a JSON RPC request.
|
||||
func Build(req *request.Request) {
|
||||
var buf []byte
|
||||
var err error
|
||||
if req.ParamsFilled() {
|
||||
buf, err = jsonutil.BuildJSON(req.Params)
|
||||
if err != nil {
|
||||
req.Error = awserr.New(request.ErrCodeSerialization, "failed encoding JSON RPC request", err)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
buf = emptyJSON
|
||||
}
|
||||
|
||||
if req.ClientInfo.TargetPrefix != "" || string(buf) != "{}" {
|
||||
req.SetBufferBody(buf)
|
||||
}
|
||||
|
||||
if req.ClientInfo.TargetPrefix != "" {
|
||||
target := req.ClientInfo.TargetPrefix + "." + req.Operation.Name
|
||||
req.HTTPRequest.Header.Add("X-Amz-Target", target)
|
||||
}
|
||||
|
||||
// Only set the content type if one is not already specified and an
|
||||
// JSONVersion is specified.
|
||||
if ct, v := req.HTTPRequest.Header.Get("Content-Type"), req.ClientInfo.JSONVersion; len(ct) == 0 && len(v) != 0 {
|
||||
jsonVersion := req.ClientInfo.JSONVersion
|
||||
req.HTTPRequest.Header.Set("Content-Type", "application/x-amz-json-"+jsonVersion)
|
||||
}
|
||||
}
|
||||
|
||||
// Unmarshal unmarshals a response for a JSON RPC service.
|
||||
func Unmarshal(req *request.Request) {
|
||||
defer req.HTTPResponse.Body.Close()
|
||||
if req.DataFilled() {
|
||||
err := jsonutil.UnmarshalJSON(req.Data, req.HTTPResponse.Body)
|
||||
if err != nil {
|
||||
req.Error = awserr.NewRequestFailure(
|
||||
awserr.New(request.ErrCodeSerialization, "failed decoding JSON RPC response", err),
|
||||
req.HTTPResponse.StatusCode,
|
||||
req.RequestID,
|
||||
)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// UnmarshalMeta unmarshals headers from a response for a JSON RPC service.
|
||||
func UnmarshalMeta(req *request.Request) {
|
||||
rest.UnmarshalMeta(req)
|
||||
}
|
||||
107
vendor/github.com/aws/aws-sdk-go/private/protocol/jsonrpc/unmarshal_error.go
generated
vendored
Normal file
107
vendor/github.com/aws/aws-sdk-go/private/protocol/jsonrpc/unmarshal_error.go
generated
vendored
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
package jsonrpc
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
"github.com/aws/aws-sdk-go/private/protocol"
|
||||
"github.com/aws/aws-sdk-go/private/protocol/json/jsonutil"
|
||||
)
|
||||
|
||||
// UnmarshalTypedError provides unmarshaling errors API response errors
|
||||
// for both typed and untyped errors.
|
||||
type UnmarshalTypedError struct {
|
||||
exceptions map[string]func(protocol.ResponseMetadata) error
|
||||
}
|
||||
|
||||
// NewUnmarshalTypedError returns an UnmarshalTypedError initialized for the
|
||||
// set of exception names to the error unmarshalers
|
||||
func NewUnmarshalTypedError(exceptions map[string]func(protocol.ResponseMetadata) error) *UnmarshalTypedError {
|
||||
return &UnmarshalTypedError{
|
||||
exceptions: exceptions,
|
||||
}
|
||||
}
|
||||
|
||||
// UnmarshalError attempts to unmarshal the HTTP response error as a known
|
||||
// error type. If unable to unmarshal the error type, the generic SDK error
|
||||
// type will be used.
|
||||
func (u *UnmarshalTypedError) UnmarshalError(
|
||||
resp *http.Response,
|
||||
respMeta protocol.ResponseMetadata,
|
||||
) (error, error) {
|
||||
|
||||
var buf bytes.Buffer
|
||||
var jsonErr jsonErrorResponse
|
||||
teeReader := io.TeeReader(resp.Body, &buf)
|
||||
err := jsonutil.UnmarshalJSONError(&jsonErr, teeReader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
body := ioutil.NopCloser(&buf)
|
||||
|
||||
// Code may be separated by hash(#), with the last element being the code
|
||||
// used by the SDK.
|
||||
codeParts := strings.SplitN(jsonErr.Code, "#", 2)
|
||||
code := codeParts[len(codeParts)-1]
|
||||
msg := jsonErr.Message
|
||||
|
||||
if fn, ok := u.exceptions[code]; ok {
|
||||
// If exception code is know, use associated constructor to get a value
|
||||
// for the exception that the JSON body can be unmarshaled into.
|
||||
v := fn(respMeta)
|
||||
err := jsonutil.UnmarshalJSONCaseInsensitive(v, body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// fallback to unmodeled generic exceptions
|
||||
return awserr.NewRequestFailure(
|
||||
awserr.New(code, msg, nil),
|
||||
respMeta.StatusCode,
|
||||
respMeta.RequestID,
|
||||
), nil
|
||||
}
|
||||
|
||||
// UnmarshalErrorHandler is a named request handler for unmarshaling jsonrpc
|
||||
// protocol request errors
|
||||
var UnmarshalErrorHandler = request.NamedHandler{
|
||||
Name: "awssdk.jsonrpc.UnmarshalError",
|
||||
Fn: UnmarshalError,
|
||||
}
|
||||
|
||||
// UnmarshalError unmarshals an error response for a JSON RPC service.
|
||||
func UnmarshalError(req *request.Request) {
|
||||
defer req.HTTPResponse.Body.Close()
|
||||
|
||||
var jsonErr jsonErrorResponse
|
||||
err := jsonutil.UnmarshalJSONError(&jsonErr, req.HTTPResponse.Body)
|
||||
if err != nil {
|
||||
req.Error = awserr.NewRequestFailure(
|
||||
awserr.New(request.ErrCodeSerialization,
|
||||
"failed to unmarshal error message", err),
|
||||
req.HTTPResponse.StatusCode,
|
||||
req.RequestID,
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
codes := strings.SplitN(jsonErr.Code, "#", 2)
|
||||
req.Error = awserr.NewRequestFailure(
|
||||
awserr.New(codes[len(codes)-1], jsonErr.Message, nil),
|
||||
req.HTTPResponse.StatusCode,
|
||||
req.RequestID,
|
||||
)
|
||||
}
|
||||
|
||||
type jsonErrorResponse struct {
|
||||
Code string `json:"__type"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
59
vendor/github.com/aws/aws-sdk-go/private/protocol/restjson/restjson.go
generated
vendored
Normal file
59
vendor/github.com/aws/aws-sdk-go/private/protocol/restjson/restjson.go
generated
vendored
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
// Package restjson provides RESTful JSON serialization of AWS
|
||||
// requests and responses.
|
||||
package restjson
|
||||
|
||||
//go:generate go run -tags codegen ../../../private/model/cli/gen-protocol-tests ../../../models/protocol_tests/input/rest-json.json build_test.go
|
||||
//go:generate go run -tags codegen ../../../private/model/cli/gen-protocol-tests ../../../models/protocol_tests/output/rest-json.json unmarshal_test.go
|
||||
|
||||
import (
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
"github.com/aws/aws-sdk-go/private/protocol/jsonrpc"
|
||||
"github.com/aws/aws-sdk-go/private/protocol/rest"
|
||||
)
|
||||
|
||||
// BuildHandler is a named request handler for building restjson protocol
|
||||
// requests
|
||||
var BuildHandler = request.NamedHandler{
|
||||
Name: "awssdk.restjson.Build",
|
||||
Fn: Build,
|
||||
}
|
||||
|
||||
// UnmarshalHandler is a named request handler for unmarshaling restjson
|
||||
// protocol requests
|
||||
var UnmarshalHandler = request.NamedHandler{
|
||||
Name: "awssdk.restjson.Unmarshal",
|
||||
Fn: Unmarshal,
|
||||
}
|
||||
|
||||
// UnmarshalMetaHandler is a named request handler for unmarshaling restjson
|
||||
// protocol request metadata
|
||||
var UnmarshalMetaHandler = request.NamedHandler{
|
||||
Name: "awssdk.restjson.UnmarshalMeta",
|
||||
Fn: UnmarshalMeta,
|
||||
}
|
||||
|
||||
// Build builds a request for the REST JSON protocol.
|
||||
func Build(r *request.Request) {
|
||||
rest.Build(r)
|
||||
|
||||
if t := rest.PayloadType(r.Params); t == "structure" || t == "" {
|
||||
if v := r.HTTPRequest.Header.Get("Content-Type"); len(v) == 0 {
|
||||
r.HTTPRequest.Header.Set("Content-Type", "application/json")
|
||||
}
|
||||
jsonrpc.Build(r)
|
||||
}
|
||||
}
|
||||
|
||||
// Unmarshal unmarshals a response body for the REST JSON protocol.
|
||||
func Unmarshal(r *request.Request) {
|
||||
if t := rest.PayloadType(r.Data); t == "structure" || t == "" {
|
||||
jsonrpc.Unmarshal(r)
|
||||
} else {
|
||||
rest.Unmarshal(r)
|
||||
}
|
||||
}
|
||||
|
||||
// UnmarshalMeta unmarshals response headers for the REST JSON protocol.
|
||||
func UnmarshalMeta(r *request.Request) {
|
||||
rest.UnmarshalMeta(r)
|
||||
}
|
||||
134
vendor/github.com/aws/aws-sdk-go/private/protocol/restjson/unmarshal_error.go
generated
vendored
Normal file
134
vendor/github.com/aws/aws-sdk-go/private/protocol/restjson/unmarshal_error.go
generated
vendored
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
package restjson
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
"github.com/aws/aws-sdk-go/private/protocol"
|
||||
"github.com/aws/aws-sdk-go/private/protocol/json/jsonutil"
|
||||
"github.com/aws/aws-sdk-go/private/protocol/rest"
|
||||
)
|
||||
|
||||
const (
|
||||
errorTypeHeader = "X-Amzn-Errortype"
|
||||
errorMessageHeader = "X-Amzn-Errormessage"
|
||||
)
|
||||
|
||||
// UnmarshalTypedError provides unmarshaling errors API response errors
|
||||
// for both typed and untyped errors.
|
||||
type UnmarshalTypedError struct {
|
||||
exceptions map[string]func(protocol.ResponseMetadata) error
|
||||
}
|
||||
|
||||
// NewUnmarshalTypedError returns an UnmarshalTypedError initialized for the
|
||||
// set of exception names to the error unmarshalers
|
||||
func NewUnmarshalTypedError(exceptions map[string]func(protocol.ResponseMetadata) error) *UnmarshalTypedError {
|
||||
return &UnmarshalTypedError{
|
||||
exceptions: exceptions,
|
||||
}
|
||||
}
|
||||
|
||||
// UnmarshalError attempts to unmarshal the HTTP response error as a known
|
||||
// error type. If unable to unmarshal the error type, the generic SDK error
|
||||
// type will be used.
|
||||
func (u *UnmarshalTypedError) UnmarshalError(
|
||||
resp *http.Response,
|
||||
respMeta protocol.ResponseMetadata,
|
||||
) (error, error) {
|
||||
|
||||
code := resp.Header.Get(errorTypeHeader)
|
||||
msg := resp.Header.Get(errorMessageHeader)
|
||||
|
||||
body := resp.Body
|
||||
if len(code) == 0 {
|
||||
// If unable to get code from HTTP headers have to parse JSON message
|
||||
// to determine what kind of exception this will be.
|
||||
var buf bytes.Buffer
|
||||
var jsonErr jsonErrorResponse
|
||||
teeReader := io.TeeReader(resp.Body, &buf)
|
||||
err := jsonutil.UnmarshalJSONError(&jsonErr, teeReader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
body = ioutil.NopCloser(&buf)
|
||||
code = jsonErr.Code
|
||||
msg = jsonErr.Message
|
||||
}
|
||||
|
||||
// If code has colon separators remove them so can compare against modeled
|
||||
// exception names.
|
||||
code = strings.SplitN(code, ":", 2)[0]
|
||||
|
||||
if fn, ok := u.exceptions[code]; ok {
|
||||
// If exception code is know, use associated constructor to get a value
|
||||
// for the exception that the JSON body can be unmarshaled into.
|
||||
v := fn(respMeta)
|
||||
if err := jsonutil.UnmarshalJSONCaseInsensitive(v, body); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := rest.UnmarshalResponse(resp, v, true); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// fallback to unmodeled generic exceptions
|
||||
return awserr.NewRequestFailure(
|
||||
awserr.New(code, msg, nil),
|
||||
respMeta.StatusCode,
|
||||
respMeta.RequestID,
|
||||
), nil
|
||||
}
|
||||
|
||||
// UnmarshalErrorHandler is a named request handler for unmarshaling restjson
|
||||
// protocol request errors
|
||||
var UnmarshalErrorHandler = request.NamedHandler{
|
||||
Name: "awssdk.restjson.UnmarshalError",
|
||||
Fn: UnmarshalError,
|
||||
}
|
||||
|
||||
// UnmarshalError unmarshals a response error for the REST JSON protocol.
|
||||
func UnmarshalError(r *request.Request) {
|
||||
defer r.HTTPResponse.Body.Close()
|
||||
|
||||
var jsonErr jsonErrorResponse
|
||||
err := jsonutil.UnmarshalJSONError(&jsonErr, r.HTTPResponse.Body)
|
||||
if err != nil {
|
||||
r.Error = awserr.NewRequestFailure(
|
||||
awserr.New(request.ErrCodeSerialization,
|
||||
"failed to unmarshal response error", err),
|
||||
r.HTTPResponse.StatusCode,
|
||||
r.RequestID,
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
code := r.HTTPResponse.Header.Get(errorTypeHeader)
|
||||
if code == "" {
|
||||
code = jsonErr.Code
|
||||
}
|
||||
msg := r.HTTPResponse.Header.Get(errorMessageHeader)
|
||||
if msg == "" {
|
||||
msg = jsonErr.Message
|
||||
}
|
||||
|
||||
code = strings.SplitN(code, ":", 2)[0]
|
||||
r.Error = awserr.NewRequestFailure(
|
||||
awserr.New(code, jsonErr.Message, nil),
|
||||
r.HTTPResponse.StatusCode,
|
||||
r.RequestID,
|
||||
)
|
||||
}
|
||||
|
||||
type jsonErrorResponse struct {
|
||||
Code string `json:"code"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
|
@ -27,8 +27,8 @@ const (
|
|||
// RFC3339 a subset of the ISO8601 timestamp format. e.g 2014-04-29T18:30:38Z
|
||||
ISO8601TimeFormat = "2006-01-02T15:04:05.999999999Z"
|
||||
|
||||
// This format is used for output time without seconds precision
|
||||
ISO8601OutputTimeFormat = "2006-01-02T15:04:05Z"
|
||||
// This format is used for output time with fractional second precision up to milliseconds
|
||||
ISO8601OutputTimeFormat = "2006-01-02T15:04:05.999999999Z"
|
||||
)
|
||||
|
||||
// IsKnownTimestampFormat returns if the timestamp format name
|
||||
|
|
@ -48,7 +48,7 @@ func IsKnownTimestampFormat(name string) bool {
|
|||
|
||||
// FormatTime returns a string value of the time.
|
||||
func FormatTime(name string, t time.Time) string {
|
||||
t = t.UTC()
|
||||
t = t.UTC().Truncate(time.Millisecond)
|
||||
|
||||
switch name {
|
||||
case RFC822TimeFormatName:
|
||||
|
|
@ -56,7 +56,8 @@ func FormatTime(name string, t time.Time) string {
|
|||
case ISO8601TimeFormatName:
|
||||
return t.Format(ISO8601OutputTimeFormat)
|
||||
case UnixTimeFormatName:
|
||||
return strconv.FormatInt(t.Unix(), 10)
|
||||
ms := t.UnixNano() / int64(time.Millisecond)
|
||||
return strconv.FormatFloat(float64(ms)/1e3, 'f', -1, 64)
|
||||
default:
|
||||
panic("unknown timestamp format name, " + name)
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,44 @@
|
|||
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
|
||||
|
||||
// Package sso provides the client and types for making API
|
||||
// requests to AWS Single Sign-On.
|
||||
//
|
||||
// AWS Single Sign-On Portal is a web service that makes it easy for you to
|
||||
// assign user access to AWS SSO resources such as the user portal. Users can
|
||||
// get AWS account applications and roles assigned to them and get federated
|
||||
// into the application.
|
||||
//
|
||||
// For general information about AWS SSO, see What is AWS Single Sign-On? (https://docs.aws.amazon.com/singlesignon/latest/userguide/what-is.html)
|
||||
// in the AWS SSO User Guide.
|
||||
//
|
||||
// This API reference guide describes the AWS SSO Portal operations that you
|
||||
// can call programatically and includes detailed information on data types
|
||||
// and errors.
|
||||
//
|
||||
// AWS provides SDKs that consist of libraries and sample code for various programming
|
||||
// languages and platforms, such as Java, Ruby, .Net, iOS, or Android. The SDKs
|
||||
// provide a convenient way to create programmatic access to AWS SSO and other
|
||||
// AWS services. For more information about the AWS SDKs, including how to download
|
||||
// and install them, see Tools for Amazon Web Services (http://aws.amazon.com/tools/).
|
||||
//
|
||||
// See https://docs.aws.amazon.com/goto/WebAPI/sso-2019-06-10 for more information on this service.
|
||||
//
|
||||
// See sso package documentation for more information.
|
||||
// https://docs.aws.amazon.com/sdk-for-go/api/service/sso/
|
||||
//
|
||||
// Using the Client
|
||||
//
|
||||
// To contact AWS Single Sign-On with the SDK use the New function to create
|
||||
// a new service client. With that client you can make API requests to the service.
|
||||
// These clients are safe to use concurrently.
|
||||
//
|
||||
// See the SDK's documentation for more information on how to use the SDK.
|
||||
// https://docs.aws.amazon.com/sdk-for-go/api/
|
||||
//
|
||||
// See aws.Config documentation for more information on configuring SDK clients.
|
||||
// https://docs.aws.amazon.com/sdk-for-go/api/aws/#Config
|
||||
//
|
||||
// See the AWS Single Sign-On client SSO for more
|
||||
// information on creating client for this service.
|
||||
// https://docs.aws.amazon.com/sdk-for-go/api/service/sso/#New
|
||||
package sso
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
|
||||
|
||||
package sso
|
||||
|
||||
import (
|
||||
"github.com/aws/aws-sdk-go/private/protocol"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
// ErrCodeInvalidRequestException for service response error code
|
||||
// "InvalidRequestException".
|
||||
//
|
||||
// Indicates that a problem occurred with the input to the request. For example,
|
||||
// a required parameter might be missing or out of range.
|
||||
ErrCodeInvalidRequestException = "InvalidRequestException"
|
||||
|
||||
// ErrCodeResourceNotFoundException for service response error code
|
||||
// "ResourceNotFoundException".
|
||||
//
|
||||
// The specified resource doesn't exist.
|
||||
ErrCodeResourceNotFoundException = "ResourceNotFoundException"
|
||||
|
||||
// ErrCodeTooManyRequestsException for service response error code
|
||||
// "TooManyRequestsException".
|
||||
//
|
||||
// Indicates that the request is being made too frequently and is more than
|
||||
// what the server can handle.
|
||||
ErrCodeTooManyRequestsException = "TooManyRequestsException"
|
||||
|
||||
// ErrCodeUnauthorizedException for service response error code
|
||||
// "UnauthorizedException".
|
||||
//
|
||||
// Indicates that the request is not authorized. This can happen due to an invalid
|
||||
// access token in the request.
|
||||
ErrCodeUnauthorizedException = "UnauthorizedException"
|
||||
)
|
||||
|
||||
var exceptionFromCode = map[string]func(protocol.ResponseMetadata) error{
|
||||
"InvalidRequestException": newErrorInvalidRequestException,
|
||||
"ResourceNotFoundException": newErrorResourceNotFoundException,
|
||||
"TooManyRequestsException": newErrorTooManyRequestsException,
|
||||
"UnauthorizedException": newErrorUnauthorizedException,
|
||||
}
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
|
||||
|
||||
package sso
|
||||
|
||||
import (
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/client"
|
||||
"github.com/aws/aws-sdk-go/aws/client/metadata"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
"github.com/aws/aws-sdk-go/aws/signer/v4"
|
||||
"github.com/aws/aws-sdk-go/private/protocol"
|
||||
"github.com/aws/aws-sdk-go/private/protocol/restjson"
|
||||
)
|
||||
|
||||
// SSO provides the API operation methods for making requests to
|
||||
// AWS Single Sign-On. See this package's package overview docs
|
||||
// for details on the service.
|
||||
//
|
||||
// SSO methods are safe to use concurrently. It is not safe to
|
||||
// modify mutate any of the struct's properties though.
|
||||
type SSO struct {
|
||||
*client.Client
|
||||
}
|
||||
|
||||
// Used for custom client initialization logic
|
||||
var initClient func(*client.Client)
|
||||
|
||||
// Used for custom request initialization logic
|
||||
var initRequest func(*request.Request)
|
||||
|
||||
// Service information constants
|
||||
const (
|
||||
ServiceName = "SSO" // Name of service.
|
||||
EndpointsID = "portal.sso" // ID to lookup a service endpoint with.
|
||||
ServiceID = "SSO" // ServiceID is a unique identifier of a specific service.
|
||||
)
|
||||
|
||||
// New creates a new instance of the SSO client with a session.
|
||||
// If additional configuration is needed for the client instance use the optional
|
||||
// aws.Config parameter to add your extra config.
|
||||
//
|
||||
// Example:
|
||||
// mySession := session.Must(session.NewSession())
|
||||
//
|
||||
// // Create a SSO client from just a session.
|
||||
// svc := sso.New(mySession)
|
||||
//
|
||||
// // Create a SSO client with additional configuration
|
||||
// svc := sso.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
|
||||
func New(p client.ConfigProvider, cfgs ...*aws.Config) *SSO {
|
||||
c := p.ClientConfig(EndpointsID, cfgs...)
|
||||
if c.SigningNameDerived || len(c.SigningName) == 0 {
|
||||
c.SigningName = "awsssoportal"
|
||||
}
|
||||
return newClient(*c.Config, c.Handlers, c.PartitionID, c.Endpoint, c.SigningRegion, c.SigningName)
|
||||
}
|
||||
|
||||
// newClient creates, initializes and returns a new service client instance.
|
||||
func newClient(cfg aws.Config, handlers request.Handlers, partitionID, endpoint, signingRegion, signingName string) *SSO {
|
||||
svc := &SSO{
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: ServiceName,
|
||||
ServiceID: ServiceID,
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
PartitionID: partitionID,
|
||||
Endpoint: endpoint,
|
||||
APIVersion: "2019-06-10",
|
||||
},
|
||||
handlers,
|
||||
),
|
||||
}
|
||||
|
||||
// Handlers
|
||||
svc.Handlers.Sign.PushBackNamed(v4.SignRequestHandler)
|
||||
svc.Handlers.Build.PushBackNamed(restjson.BuildHandler)
|
||||
svc.Handlers.Unmarshal.PushBackNamed(restjson.UnmarshalHandler)
|
||||
svc.Handlers.UnmarshalMeta.PushBackNamed(restjson.UnmarshalMetaHandler)
|
||||
svc.Handlers.UnmarshalError.PushBackNamed(
|
||||
protocol.NewUnmarshalErrorHandler(restjson.NewUnmarshalTypedError(exceptionFromCode)).NamedHandler(),
|
||||
)
|
||||
|
||||
// Run custom client initialization if present
|
||||
if initClient != nil {
|
||||
initClient(svc.Client)
|
||||
}
|
||||
|
||||
return svc
|
||||
}
|
||||
|
||||
// newRequest creates a new request for a SSO operation and runs any
|
||||
// custom request initialization.
|
||||
func (c *SSO) newRequest(op *request.Operation, params, data interface{}) *request.Request {
|
||||
req := c.NewRequest(op, params, data)
|
||||
|
||||
// Run custom request initialization if present
|
||||
if initRequest != nil {
|
||||
initRequest(req)
|
||||
}
|
||||
|
||||
return req
|
||||
}
|
||||
86
vendor/github.com/aws/aws-sdk-go/service/sso/ssoiface/interface.go
generated
vendored
Normal file
86
vendor/github.com/aws/aws-sdk-go/service/sso/ssoiface/interface.go
generated
vendored
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
|
||||
|
||||
// Package ssoiface provides an interface to enable mocking the AWS Single Sign-On service client
|
||||
// for testing your code.
|
||||
//
|
||||
// It is important to note that this interface will have breaking changes
|
||||
// when the service model is updated and adds new API operations, paginators,
|
||||
// and waiters.
|
||||
package ssoiface
|
||||
|
||||
import (
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
"github.com/aws/aws-sdk-go/service/sso"
|
||||
)
|
||||
|
||||
// SSOAPI provides an interface to enable mocking the
|
||||
// sso.SSO service client's API operation,
|
||||
// paginators, and waiters. This make unit testing your code that calls out
|
||||
// to the SDK's service client's calls easier.
|
||||
//
|
||||
// The best way to use this interface is so the SDK's service client's calls
|
||||
// can be stubbed out for unit testing your code with the SDK without needing
|
||||
// to inject custom request handlers into the SDK's request pipeline.
|
||||
//
|
||||
// // myFunc uses an SDK service client to make a request to
|
||||
// // AWS Single Sign-On.
|
||||
// func myFunc(svc ssoiface.SSOAPI) bool {
|
||||
// // Make svc.GetRoleCredentials request
|
||||
// }
|
||||
//
|
||||
// func main() {
|
||||
// sess := session.New()
|
||||
// svc := sso.New(sess)
|
||||
//
|
||||
// myFunc(svc)
|
||||
// }
|
||||
//
|
||||
// In your _test.go file:
|
||||
//
|
||||
// // Define a mock struct to be used in your unit tests of myFunc.
|
||||
// type mockSSOClient struct {
|
||||
// ssoiface.SSOAPI
|
||||
// }
|
||||
// func (m *mockSSOClient) GetRoleCredentials(input *sso.GetRoleCredentialsInput) (*sso.GetRoleCredentialsOutput, error) {
|
||||
// // mock response/functionality
|
||||
// }
|
||||
//
|
||||
// func TestMyFunc(t *testing.T) {
|
||||
// // Setup Test
|
||||
// mockSvc := &mockSSOClient{}
|
||||
//
|
||||
// myfunc(mockSvc)
|
||||
//
|
||||
// // Verify myFunc's functionality
|
||||
// }
|
||||
//
|
||||
// It is important to note that this interface will have breaking changes
|
||||
// when the service model is updated and adds new API operations, paginators,
|
||||
// and waiters. Its suggested to use the pattern above for testing, or using
|
||||
// tooling to generate mocks to satisfy the interfaces.
|
||||
type SSOAPI interface {
|
||||
GetRoleCredentials(*sso.GetRoleCredentialsInput) (*sso.GetRoleCredentialsOutput, error)
|
||||
GetRoleCredentialsWithContext(aws.Context, *sso.GetRoleCredentialsInput, ...request.Option) (*sso.GetRoleCredentialsOutput, error)
|
||||
GetRoleCredentialsRequest(*sso.GetRoleCredentialsInput) (*request.Request, *sso.GetRoleCredentialsOutput)
|
||||
|
||||
ListAccountRoles(*sso.ListAccountRolesInput) (*sso.ListAccountRolesOutput, error)
|
||||
ListAccountRolesWithContext(aws.Context, *sso.ListAccountRolesInput, ...request.Option) (*sso.ListAccountRolesOutput, error)
|
||||
ListAccountRolesRequest(*sso.ListAccountRolesInput) (*request.Request, *sso.ListAccountRolesOutput)
|
||||
|
||||
ListAccountRolesPages(*sso.ListAccountRolesInput, func(*sso.ListAccountRolesOutput, bool) bool) error
|
||||
ListAccountRolesPagesWithContext(aws.Context, *sso.ListAccountRolesInput, func(*sso.ListAccountRolesOutput, bool) bool, ...request.Option) error
|
||||
|
||||
ListAccounts(*sso.ListAccountsInput) (*sso.ListAccountsOutput, error)
|
||||
ListAccountsWithContext(aws.Context, *sso.ListAccountsInput, ...request.Option) (*sso.ListAccountsOutput, error)
|
||||
ListAccountsRequest(*sso.ListAccountsInput) (*request.Request, *sso.ListAccountsOutput)
|
||||
|
||||
ListAccountsPages(*sso.ListAccountsInput, func(*sso.ListAccountsOutput, bool) bool) error
|
||||
ListAccountsPagesWithContext(aws.Context, *sso.ListAccountsInput, func(*sso.ListAccountsOutput, bool) bool, ...request.Option) error
|
||||
|
||||
Logout(*sso.LogoutInput) (*sso.LogoutOutput, error)
|
||||
LogoutWithContext(aws.Context, *sso.LogoutInput, ...request.Option) (*sso.LogoutOutput, error)
|
||||
LogoutRequest(*sso.LogoutInput) (*request.Request, *sso.LogoutOutput)
|
||||
}
|
||||
|
||||
var _ SSOAPI = (*sso.SSO)(nil)
|
||||
|
|
@ -207,6 +207,10 @@ func (c *STS) AssumeRoleRequest(input *AssumeRoleInput) (req *request.Request, o
|
|||
// and Deactivating AWS STS in an AWS Region (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html)
|
||||
// in the IAM User Guide.
|
||||
//
|
||||
// * ErrCodeExpiredTokenException "ExpiredTokenException"
|
||||
// The web identity token that was passed is expired or is not valid. Get a
|
||||
// new identity token from the identity provider and then retry the request.
|
||||
//
|
||||
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRole
|
||||
func (c *STS) AssumeRole(input *AssumeRoleInput) (*AssumeRoleOutput, error) {
|
||||
req, out := c.AssumeRoleRequest(input)
|
||||
|
|
@ -626,7 +630,7 @@ func (c *STS) AssumeRoleWithWebIdentityRequest(input *AssumeRoleWithWebIdentityI
|
|||
// * Using Web Identity Federation API Operations for Mobile Apps (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_oidc_manual.html)
|
||||
// and Federation Through a Web-based Identity Provider (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#api_assumerolewithwebidentity).
|
||||
//
|
||||
// * Web Identity Federation Playground (https://web-identity-federation-playground.s3.amazonaws.com/index.html).
|
||||
// * Web Identity Federation Playground (https://aws.amazon.com/blogs/aws/the-aws-web-identity-federation-playground/).
|
||||
// Walk through the process of authenticating through Login with Amazon,
|
||||
// Facebook, or Google, getting temporary security credentials, and then
|
||||
// using those credentials to make a request to AWS.
|
||||
|
|
@ -1788,7 +1792,7 @@ type AssumeRoleWithSAMLInput struct {
|
|||
// in the IAM User Guide.
|
||||
//
|
||||
// SAMLAssertion is a required field
|
||||
SAMLAssertion *string `min:"4" type:"string" required:"true" sensitive:"true"`
|
||||
SAMLAssertion *string `min:"4" type:"string" required:"true"`
|
||||
}
|
||||
|
||||
// String returns the string representation
|
||||
|
|
@ -2100,7 +2104,7 @@ type AssumeRoleWithWebIdentityInput struct {
|
|||
// the application makes an AssumeRoleWithWebIdentity call.
|
||||
//
|
||||
// WebIdentityToken is a required field
|
||||
WebIdentityToken *string `min:"4" type:"string" required:"true" sensitive:"true"`
|
||||
WebIdentityToken *string `min:"4" type:"string" required:"true"`
|
||||
}
|
||||
|
||||
// String returns the string representation
|
||||
|
|
|
|||
|
|
@ -3,87 +3,11 @@
|
|||
// Package sts provides the client and types for making API
|
||||
// requests to AWS Security Token Service.
|
||||
//
|
||||
// The AWS Security Token Service (STS) is a web service that enables you to
|
||||
// request temporary, limited-privilege credentials for AWS Identity and Access
|
||||
// Management (IAM) users or for users that you authenticate (federated users).
|
||||
// This guide provides descriptions of the STS API. For more detailed information
|
||||
// about using this service, go to Temporary Security Credentials (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html).
|
||||
//
|
||||
// For information about setting up signatures and authorization through the
|
||||
// API, go to Signing AWS API Requests (https://docs.aws.amazon.com/general/latest/gr/signing_aws_api_requests.html)
|
||||
// in the AWS General Reference. For general information about the Query API,
|
||||
// go to Making Query Requests (https://docs.aws.amazon.com/IAM/latest/UserGuide/IAM_UsingQueryAPI.html)
|
||||
// in Using IAM. For information about using security tokens with other AWS
|
||||
// products, go to AWS Services That Work with IAM (https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_aws-services-that-work-with-iam.html)
|
||||
// in the IAM User Guide.
|
||||
//
|
||||
// If you're new to AWS and need additional technical information about a specific
|
||||
// AWS product, you can find the product's technical documentation at http://aws.amazon.com/documentation/
|
||||
// (http://aws.amazon.com/documentation/).
|
||||
//
|
||||
// Endpoints
|
||||
//
|
||||
// By default, AWS Security Token Service (STS) is available as a global service,
|
||||
// and all AWS STS requests go to a single endpoint at https://sts.amazonaws.com.
|
||||
// Global requests map to the US East (N. Virginia) region. AWS recommends using
|
||||
// Regional AWS STS endpoints instead of the global endpoint to reduce latency,
|
||||
// build in redundancy, and increase session token validity. For more information,
|
||||
// see Managing AWS STS in an AWS Region (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html)
|
||||
// in the IAM User Guide.
|
||||
//
|
||||
// Most AWS Regions are enabled for operations in all AWS services by default.
|
||||
// Those Regions are automatically activated for use with AWS STS. Some Regions,
|
||||
// such as Asia Pacific (Hong Kong), must be manually enabled. To learn more
|
||||
// about enabling and disabling AWS Regions, see Managing AWS Regions (https://docs.aws.amazon.com/general/latest/gr/rande-manage.html)
|
||||
// in the AWS General Reference. When you enable these AWS Regions, they are
|
||||
// automatically activated for use with AWS STS. You cannot activate the STS
|
||||
// endpoint for a Region that is disabled. Tokens that are valid in all AWS
|
||||
// Regions are longer than tokens that are valid in Regions that are enabled
|
||||
// by default. Changing this setting might affect existing systems where you
|
||||
// temporarily store tokens. For more information, see Managing Global Endpoint
|
||||
// Session Tokens (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html#sts-regions-manage-tokens)
|
||||
// in the IAM User Guide.
|
||||
//
|
||||
// After you activate a Region for use with AWS STS, you can direct AWS STS
|
||||
// API calls to that Region. AWS STS recommends that you provide both the Region
|
||||
// and endpoint when you make calls to a Regional endpoint. You can provide
|
||||
// the Region alone for manually enabled Regions, such as Asia Pacific (Hong
|
||||
// Kong). In this case, the calls are directed to the STS Regional endpoint.
|
||||
// However, if you provide the Region alone for Regions enabled by default,
|
||||
// the calls are directed to the global endpoint of https://sts.amazonaws.com.
|
||||
//
|
||||
// To view the list of AWS STS endpoints and whether they are active by default,
|
||||
// see Writing Code to Use AWS STS Regions (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html#id_credentials_temp_enable-regions_writing_code)
|
||||
// in the IAM User Guide.
|
||||
//
|
||||
// Recording API requests
|
||||
//
|
||||
// STS supports AWS CloudTrail, which is a service that records AWS calls for
|
||||
// your AWS account and delivers log files to an Amazon S3 bucket. By using
|
||||
// information collected by CloudTrail, you can determine what requests were
|
||||
// successfully made to STS, who made the request, when it was made, and so
|
||||
// on.
|
||||
//
|
||||
// If you activate AWS STS endpoints in Regions other than the default global
|
||||
// endpoint, then you must also turn on CloudTrail logging in those Regions.
|
||||
// This is necessary to record any AWS STS API calls that are made in those
|
||||
// Regions. For more information, see Turning On CloudTrail in Additional Regions
|
||||
// (https://docs.aws.amazon.com/awscloudtrail/latest/userguide/aggregating_logs_regions_turn_on_ct.html)
|
||||
// in the AWS CloudTrail User Guide.
|
||||
//
|
||||
// AWS Security Token Service (STS) is a global service with a single endpoint
|
||||
// at https://sts.amazonaws.com. Calls to this endpoint are logged as calls
|
||||
// to a global service. However, because this endpoint is physically located
|
||||
// in the US East (N. Virginia) Region, your logs list us-east-1 as the event
|
||||
// Region. CloudTrail does not write these logs to the US East (Ohio) Region
|
||||
// unless you choose to include global service logs in that Region. CloudTrail
|
||||
// writes calls to all Regional endpoints to their respective Regions. For example,
|
||||
// calls to sts.us-east-2.amazonaws.com are published to the US East (Ohio)
|
||||
// Region and calls to sts.eu-central-1.amazonaws.com are published to the EU
|
||||
// (Frankfurt) Region.
|
||||
//
|
||||
// To learn more about CloudTrail, including how to turn it on and find your
|
||||
// log files, see the AWS CloudTrail User Guide (https://docs.aws.amazon.com/awscloudtrail/latest/userguide/what_is_cloud_trail_top_level.html).
|
||||
// AWS Security Token Service (STS) enables you to request temporary, limited-privilege
|
||||
// credentials for AWS Identity and Access Management (IAM) users or for users
|
||||
// that you authenticate (federated users). This guide provides descriptions
|
||||
// of the STS API. For more information about using this service, see Temporary
|
||||
// Security Credentials (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html).
|
||||
//
|
||||
// See https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15 for more information on this service.
|
||||
//
|
||||
|
|
|
|||
|
|
@ -68,3 +68,4 @@ examples/restful-html-template
|
|||
|
||||
s.html
|
||||
restful-path-tail
|
||||
.idea
|
||||
|
|
|
|||
|
|
@ -3,4 +3,11 @@ language: go
|
|||
go:
|
||||
- 1.x
|
||||
|
||||
script: go test -v
|
||||
before_install:
|
||||
- go test -v
|
||||
|
||||
script:
|
||||
- go test -race -coverprofile=coverage.txt -covermode=atomic
|
||||
|
||||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
|
|
@ -1,59 +1,100 @@
|
|||
## Change history of go-restful
|
||||
# Change history of go-restful (v2 only)
|
||||
|
||||
## v2.15.0 - 2020-11-10
|
||||
|
||||
- Add OPTIONS in Webservice
|
||||
|
||||
## v2.14.3 - 2020-08-31
|
||||
- Fixed duplicate compression in dispatch. #449
|
||||
|
||||
|
||||
v2.9.5
|
||||
## v2.14.2 - 2020-08-31
|
||||
|
||||
- Added check on writer to prevent compression of response twice. #447
|
||||
|
||||
## v2.14.0 - 2020-08-19
|
||||
|
||||
- Enable content encoding on Handle and ServeHTTP (#446)
|
||||
- List available representations in 406 body (#437)
|
||||
- Convert to string using rune() (#443)
|
||||
|
||||
## v2.13.0 - 2020-06-21
|
||||
|
||||
- 405 Method Not Allowed must have Allow header (#436)
|
||||
- add field allowedMethodsWithoutContentType (#424)
|
||||
|
||||
## v2.12.0
|
||||
|
||||
- support describing response headers (#426)
|
||||
- fix openapi examples (#425)
|
||||
- merge v3 fix (#422)
|
||||
|
||||
## v2.11.1
|
||||
|
||||
- fix WriteError return value (#415)
|
||||
|
||||
## v2.11.0
|
||||
|
||||
- allow prefix and suffix in path variable expression (#414)
|
||||
|
||||
## v2.9.6
|
||||
|
||||
- support google custome verb (#413)
|
||||
|
||||
## v2.9.5
|
||||
|
||||
- fix panic in Response.WriteError if err == nil
|
||||
|
||||
v2.9.4
|
||||
## v2.9.4
|
||||
|
||||
- fix issue #400 , parsing mime type quality
|
||||
- Route Builder added option for contentEncodingEnabled (#398)
|
||||
|
||||
v2.9.3
|
||||
## v2.9.3
|
||||
|
||||
- Avoid return of 415 Unsupported Media Type when request body is empty (#396)
|
||||
|
||||
v2.9.2
|
||||
## v2.9.2
|
||||
|
||||
- Reduce allocations in per-request methods to improve performance (#395)
|
||||
|
||||
v2.9.1
|
||||
## v2.9.1
|
||||
|
||||
- Fix issue with default responses and invalid status code 0. (#393)
|
||||
|
||||
v2.9.0
|
||||
## v2.9.0
|
||||
|
||||
- add per Route content encoding setting (overrides container setting)
|
||||
|
||||
v2.8.0
|
||||
## v2.8.0
|
||||
|
||||
- add Request.QueryParameters()
|
||||
- add json-iterator (via build tag)
|
||||
- disable vgo module (until log is moved)
|
||||
|
||||
v2.7.1
|
||||
## v2.7.1
|
||||
|
||||
- add vgo module
|
||||
|
||||
v2.6.1
|
||||
## v2.6.1
|
||||
|
||||
- add JSONNewDecoderFunc to allow custom JSON Decoder usage (go 1.10+)
|
||||
|
||||
v2.6.0
|
||||
## v2.6.0
|
||||
|
||||
- Make JSR 311 routing and path param processing consistent
|
||||
- Adding description to RouteBuilder.Reads()
|
||||
- Update example for Swagger12 and OpenAPI
|
||||
|
||||
2017-09-13
|
||||
## 2017-09-13
|
||||
|
||||
- added route condition functions using `.If(func)` in route building.
|
||||
|
||||
2017-02-16
|
||||
## 2017-02-16
|
||||
|
||||
- solved issue #304, make operation names unique
|
||||
|
||||
2017-01-30
|
||||
## 2017-01-30
|
||||
|
||||
[IMPORTANT] For swagger users, change your import statement to:
|
||||
swagger "github.com/emicklei/go-restful-swagger12"
|
||||
|
|
@ -61,60 +102,60 @@ v2.6.0
|
|||
- moved swagger 1.2 code to go-restful-swagger12
|
||||
- created TAG 2.0.0
|
||||
|
||||
2017-01-27
|
||||
## 2017-01-27
|
||||
|
||||
- remove defer request body close
|
||||
- expose Dispatch for testing filters and Routefunctions
|
||||
- swagger response model cannot be array
|
||||
- created TAG 1.0.0
|
||||
|
||||
2016-12-22
|
||||
## 2016-12-22
|
||||
|
||||
- (API change) Remove code related to caching request content. Removes SetCacheReadEntity(doCache bool)
|
||||
|
||||
2016-11-26
|
||||
## 2016-11-26
|
||||
|
||||
- Default change! now use CurlyRouter (was RouterJSR311)
|
||||
- Default change! no more caching of request content
|
||||
- Default change! do not recover from panics
|
||||
|
||||
2016-09-22
|
||||
## 2016-09-22
|
||||
|
||||
- fix the DefaultRequestContentType feature
|
||||
|
||||
2016-02-14
|
||||
## 2016-02-14
|
||||
|
||||
- take the qualify factor of the Accept header mediatype into account when deciding the contentype of the response
|
||||
- add constructors for custom entity accessors for xml and json
|
||||
|
||||
2015-09-27
|
||||
## 2015-09-27
|
||||
|
||||
- rename new WriteStatusAnd... to WriteHeaderAnd... for consistency
|
||||
|
||||
2015-09-25
|
||||
## 2015-09-25
|
||||
|
||||
- fixed problem with changing Header after WriteHeader (issue 235)
|
||||
|
||||
2015-09-14
|
||||
## 2015-09-14
|
||||
|
||||
- changed behavior of WriteHeader (immediate write) and WriteEntity (no status write)
|
||||
- added support for custom EntityReaderWriters.
|
||||
|
||||
2015-08-06
|
||||
## 2015-08-06
|
||||
|
||||
- add support for reading entities from compressed request content
|
||||
- use sync.Pool for compressors of http response and request body
|
||||
- add Description to Parameter for documentation in Swagger UI
|
||||
|
||||
2015-03-20
|
||||
## 2015-03-20
|
||||
|
||||
- add configurable logging
|
||||
|
||||
2015-03-18
|
||||
## 2015-03-18
|
||||
|
||||
- if not specified, the Operation is derived from the Route function
|
||||
|
||||
2015-03-17
|
||||
## 2015-03-17
|
||||
|
||||
- expose Parameter creation functions
|
||||
- make trace logger an interface
|
||||
|
|
@ -123,26 +164,26 @@ v2.6.0
|
|||
- JSR311 router now handles wildcards
|
||||
- add Notes to Route
|
||||
|
||||
2014-11-27
|
||||
## 2014-11-27
|
||||
|
||||
- (api add) PrettyPrint per response. (as proposed in #167)
|
||||
|
||||
2014-11-12
|
||||
## 2014-11-12
|
||||
|
||||
- (api add) ApiVersion(.) for documentation in Swagger UI
|
||||
|
||||
2014-11-10
|
||||
## 2014-11-10
|
||||
|
||||
- (api change) struct fields tagged with "description" show up in Swagger UI
|
||||
|
||||
2014-10-31
|
||||
## 2014-10-31
|
||||
|
||||
- (api change) ReturnsError -> Returns
|
||||
- (api add) RouteBuilder.Do(aBuilder) for DRY use of RouteBuilder
|
||||
- fix swagger nested structs
|
||||
- sort Swagger response messages by code
|
||||
|
||||
2014-10-23
|
||||
## 2014-10-23
|
||||
|
||||
- (api add) ReturnsError allows you to document Http codes in swagger
|
||||
- fixed problem with greedy CurlyRouter
|
||||
|
|
@ -156,73 +197,73 @@ v2.6.0
|
|||
- (api add) added AllowedDomains in CORS
|
||||
- (api add) ParameterNamed for detailed documentation
|
||||
|
||||
2014-04-16
|
||||
## 2014-04-16
|
||||
|
||||
- (api add) expose constructor of Request for testing.
|
||||
|
||||
2014-06-27
|
||||
## 2014-06-27
|
||||
|
||||
- (api add) ParameterNamed gives access to a Parameter definition and its data (for further specification).
|
||||
- (api add) SetCacheReadEntity allow scontrol over whether or not the request body is being cached (default true for compatibility reasons).
|
||||
|
||||
2014-07-03
|
||||
## 2014-07-03
|
||||
|
||||
- (api add) CORS can be configured with a list of allowed domains
|
||||
|
||||
2014-03-12
|
||||
## 2014-03-12
|
||||
|
||||
- (api add) Route path parameters can use wildcard or regular expressions. (requires CurlyRouter)
|
||||
|
||||
2014-02-26
|
||||
## 2014-02-26
|
||||
|
||||
- (api add) Request now provides information about the matched Route, see method SelectedRoutePath
|
||||
|
||||
2014-02-17
|
||||
## 2014-02-17
|
||||
|
||||
- (api change) renamed parameter constants (go-lint checks)
|
||||
|
||||
2014-01-10
|
||||
## 2014-01-10
|
||||
|
||||
- (api add) support for CloseNotify, see http://golang.org/pkg/net/http/#CloseNotifier
|
||||
|
||||
2014-01-07
|
||||
## 2014-01-07
|
||||
|
||||
- (api change) Write* methods in Response now return the error or nil.
|
||||
- added example of serving HTML from a Go template.
|
||||
- fixed comparing Allowed headers in CORS (is now case-insensitive)
|
||||
|
||||
2013-11-13
|
||||
## 2013-11-13
|
||||
|
||||
- (api add) Response knows how many bytes are written to the response body.
|
||||
|
||||
2013-10-29
|
||||
## 2013-10-29
|
||||
|
||||
- (api add) RecoverHandler(handler RecoverHandleFunction) to change how panic recovery is handled. Default behavior is to log and return a stacktrace. This may be a security issue as it exposes sourcecode information.
|
||||
|
||||
2013-10-04
|
||||
## 2013-10-04
|
||||
|
||||
- (api add) Response knows what HTTP status has been written
|
||||
- (api add) Request can have attributes (map of string->interface, also called request-scoped variables
|
||||
|
||||
2013-09-12
|
||||
## 2013-09-12
|
||||
|
||||
- (api change) Router interface simplified
|
||||
- Implemented CurlyRouter, a Router that does not use|allow regular expressions in paths
|
||||
|
||||
2013-08-05
|
||||
## 2013-08-05
|
||||
- add OPTIONS support
|
||||
- add CORS support
|
||||
|
||||
2013-08-27
|
||||
## 2013-08-27
|
||||
|
||||
- fixed some reported issues (see github)
|
||||
- (api change) deprecated use of WriteError; use WriteErrorString instead
|
||||
|
||||
2014-04-15
|
||||
## 2014-04-15
|
||||
|
||||
- (fix) v1.0.1 tag: fix Issue 111: WriteErrorString
|
||||
|
||||
2013-08-08
|
||||
## 2013-08-08
|
||||
|
||||
- (api add) Added implementation Container: a WebServices collection with its own http.ServeMux allowing multiple endpoints per program. Existing uses of go-restful will register their services to the DefaultContainer.
|
||||
- (api add) the swagger package has be extended to have a UI per container.
|
||||
|
|
@ -235,38 +276,38 @@ Important API changes:
|
|||
- (api remove) package variable EnableContentEncoding no longer works ; use restful.DefaultContainer.EnableContentEncoding(true) instead.
|
||||
|
||||
|
||||
2013-07-06
|
||||
## 2013-07-06
|
||||
|
||||
- (api add) Added support for response encoding (gzip and deflate(zlib)). This feature is disabled on default (for backwards compatibility). Use restful.EnableContentEncoding = true in your initialization to enable this feature.
|
||||
|
||||
2013-06-19
|
||||
## 2013-06-19
|
||||
|
||||
- (improve) DoNotRecover option, moved request body closer, improved ReadEntity
|
||||
|
||||
2013-06-03
|
||||
## 2013-06-03
|
||||
|
||||
- (api change) removed Dispatcher interface, hide PathExpression
|
||||
- changed receiver names of type functions to be more idiomatic Go
|
||||
|
||||
2013-06-02
|
||||
## 2013-06-02
|
||||
|
||||
- (optimize) Cache the RegExp compilation of Paths.
|
||||
|
||||
2013-05-22
|
||||
## 2013-05-22
|
||||
|
||||
- (api add) Added support for request/response filter functions
|
||||
|
||||
2013-05-18
|
||||
## 2013-05-18
|
||||
|
||||
|
||||
- (api add) Added feature to change the default Http Request Dispatch function (travis cline)
|
||||
- (api change) Moved Swagger Webservice to swagger package (see example restful-user)
|
||||
|
||||
[2012-11-14 .. 2013-05-18>
|
||||
## [2012-11-14 .. 2013-05-18>
|
||||
|
||||
- See https://github.com/emicklei/go-restful/commits
|
||||
|
||||
2012-11-14
|
||||
## 2012-11-14
|
||||
|
||||
- Initial commit
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
all: test
|
||||
|
||||
test:
|
||||
go test -v .
|
||||
|
||||
ex:
|
||||
cd examples && ls *.go | xargs go build -o /tmp/ignore
|
||||
go vet .
|
||||
go test -cover -v .
|
||||
|
|
@ -4,9 +4,10 @@ package for building REST-style Web Services using Google Go
|
|||
|
||||
[](https://travis-ci.org/emicklei/go-restful)
|
||||
[](https://goreportcard.com/report/github.com/emicklei/go-restful)
|
||||
[](https://godoc.org/github.com/emicklei/go-restful)
|
||||
[](https://pkg.go.dev/github.com/emicklei/go-restful)
|
||||
[](https://codecov.io/gh/emicklei/go-restful)
|
||||
|
||||
- [Code examples](https://github.com/emicklei/go-restful/tree/master/examples)
|
||||
- [Code examples using v3](https://github.com/emicklei/go-restful/tree/master/examples)
|
||||
|
||||
REST asks developers to use HTTP methods explicitly and in a way that's consistent with the protocol definition. This basic REST design principle establishes a one-to-one mapping between create, read, update, and delete (CRUD) operations and HTTP methods. According to this mapping:
|
||||
|
||||
|
|
@ -18,6 +19,28 @@ REST asks developers to use HTTP methods explicitly and in a way that's consiste
|
|||
- PATCH = Update partial content of a resource
|
||||
- OPTIONS = Get information about the communication options for the request URI
|
||||
|
||||
### Usage
|
||||
|
||||
#### Using Go Modules
|
||||
|
||||
As of version `v3.0.0` (on the v3 branch), this package supports Go modules.
|
||||
|
||||
```
|
||||
import (
|
||||
restful "github.com/emicklei/go-restful/v3"
|
||||
)
|
||||
```
|
||||
|
||||
#### Without Go Modules
|
||||
|
||||
All versions up to `v2.*.*` (on the master) are not supporting Go modules.
|
||||
|
||||
```
|
||||
import (
|
||||
restful "github.com/emicklei/go-restful"
|
||||
)
|
||||
```
|
||||
|
||||
### Example
|
||||
|
||||
```Go
|
||||
|
|
@ -38,14 +61,14 @@ func (u UserResource) findUser(request *restful.Request, response *restful.Respo
|
|||
...
|
||||
}
|
||||
```
|
||||
|
||||
[Full API of a UserResource](https://github.com/emicklei/go-restful/tree/master/examples/restful-user-resource.go)
|
||||
|
||||
|
||||
[Full API of a UserResource](https://github.com/emicklei/go-restful/tree/master/examples/user-resource/restful-user-resource.go)
|
||||
|
||||
### Features
|
||||
|
||||
- Routes for request → function mapping with path parameter (e.g. {id}) support
|
||||
- Routes for request → function mapping with path parameter (e.g. {id} but also prefix_{var} and {var}_suffix) support
|
||||
- Configurable router:
|
||||
- (default) Fast routing algorithm that allows static elements, regular expressions and dynamic parameters in the URL path (e.g. /meetings/{id} or /static/{subpath:*}
|
||||
- (default) Fast routing algorithm that allows static elements, [google custom method](https://cloud.google.com/apis/design/custom_methods), regular expressions and dynamic parameters in the URL path (e.g. /resource/name:customVerb, /meetings/{id} or /static/{subpath:*})
|
||||
- Routing algorithm after [JSR311](http://jsr311.java.net/nonav/releases/1.1/spec/spec.html) that is implemented using (but does **not** accept) regular expressions
|
||||
- Request API for reading structs from JSON/XML and accesing parameters (path,query,header)
|
||||
- Response API for writing structs to JSON/XML and setting headers
|
||||
|
|
@ -85,4 +108,4 @@ TODO: write examples of these.
|
|||
|
||||
Type ```git shortlog -s``` for a full list of contributors.
|
||||
|
||||
© 2012 - 2018, http://ernestmicklei.com. MIT License. Contributions are welcome.
|
||||
© 2012 - 2020, http://ernestmicklei.com. MIT License. Contributions are welcome.
|
||||
|
|
|
|||
|
|
@ -185,6 +185,11 @@ func logStackOnRecover(panicReason interface{}, httpWriter http.ResponseWriter)
|
|||
// when a ServiceError is returned during route selection. Default implementation
|
||||
// calls resp.WriteErrorString(err.Code, err.Message)
|
||||
func writeServiceError(err ServiceError, req *Request, resp *Response) {
|
||||
for header, values := range err.Header {
|
||||
for _, value := range values {
|
||||
resp.Header().Add(header, value)
|
||||
}
|
||||
}
|
||||
resp.WriteErrorString(err.Code, err.Message)
|
||||
}
|
||||
|
||||
|
|
@ -201,6 +206,7 @@ func (c *Container) Dispatch(httpWriter http.ResponseWriter, httpRequest *http.R
|
|||
|
||||
// Dispatch the incoming Http Request to a matching WebService.
|
||||
func (c *Container) dispatch(httpWriter http.ResponseWriter, httpRequest *http.Request) {
|
||||
// so we can assign a compressing one later
|
||||
writer := httpWriter
|
||||
|
||||
// CompressingResponseWriter should be closed after all operations are done
|
||||
|
|
@ -231,28 +237,8 @@ func (c *Container) dispatch(httpWriter http.ResponseWriter, httpRequest *http.R
|
|||
c.webServices,
|
||||
httpRequest)
|
||||
}()
|
||||
|
||||
// Detect if compression is needed
|
||||
// assume without compression, test for override
|
||||
contentEncodingEnabled := c.contentEncodingEnabled
|
||||
if route != nil && route.contentEncodingEnabled != nil {
|
||||
contentEncodingEnabled = *route.contentEncodingEnabled
|
||||
}
|
||||
if contentEncodingEnabled {
|
||||
doCompress, encoding := wantsCompressedResponse(httpRequest)
|
||||
if doCompress {
|
||||
var err error
|
||||
writer, err = NewCompressingResponseWriter(httpWriter, encoding)
|
||||
if err != nil {
|
||||
log.Print("unable to install compressor: ", err)
|
||||
httpWriter.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
// a non-200 response has already been written
|
||||
// a non-200 response (may be compressed) has already been written
|
||||
// run container filters anyway ; they should not touch the response...
|
||||
chain := FilterChain{Filters: c.containerFilters, Target: func(req *Request, resp *Response) {
|
||||
switch err.(type) {
|
||||
|
|
@ -265,6 +251,29 @@ func (c *Container) dispatch(httpWriter http.ResponseWriter, httpRequest *http.R
|
|||
chain.ProcessFilter(NewRequest(httpRequest), NewResponse(writer))
|
||||
return
|
||||
}
|
||||
|
||||
// Unless httpWriter is already an CompressingResponseWriter see if we need to install one
|
||||
if _, isCompressing := httpWriter.(*CompressingResponseWriter); !isCompressing {
|
||||
// Detect if compression is needed
|
||||
// assume without compression, test for override
|
||||
contentEncodingEnabled := c.contentEncodingEnabled
|
||||
if route != nil && route.contentEncodingEnabled != nil {
|
||||
contentEncodingEnabled = *route.contentEncodingEnabled
|
||||
}
|
||||
if contentEncodingEnabled {
|
||||
doCompress, encoding := wantsCompressedResponse(httpRequest)
|
||||
if doCompress {
|
||||
var err error
|
||||
writer, err = NewCompressingResponseWriter(httpWriter, encoding)
|
||||
if err != nil {
|
||||
log.Print("unable to install compressor: ", err)
|
||||
httpWriter.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pathProcessor, routerProcessesPath := c.router.(PathProcessor)
|
||||
if !routerProcessesPath {
|
||||
pathProcessor = defaultPathProcessor{}
|
||||
|
|
@ -272,16 +281,13 @@ func (c *Container) dispatch(httpWriter http.ResponseWriter, httpRequest *http.R
|
|||
pathParams := pathProcessor.ExtractParameters(route, webService, httpRequest.URL.Path)
|
||||
wrappedRequest, wrappedResponse := route.wrapRequestResponse(writer, httpRequest, pathParams)
|
||||
// pass through filters (if any)
|
||||
if len(c.containerFilters)+len(webService.filters)+len(route.Filters) > 0 {
|
||||
if size := len(c.containerFilters) + len(webService.filters) + len(route.Filters); size > 0 {
|
||||
// compose filter chain
|
||||
allFilters := []FilterFunction{}
|
||||
allFilters := make([]FilterFunction, 0, size)
|
||||
allFilters = append(allFilters, c.containerFilters...)
|
||||
allFilters = append(allFilters, webService.filters...)
|
||||
allFilters = append(allFilters, route.Filters...)
|
||||
chain := FilterChain{Filters: allFilters, Target: func(req *Request, resp *Response) {
|
||||
// handle request by route after passing all filters
|
||||
route.Function(wrappedRequest, wrappedResponse)
|
||||
}}
|
||||
chain := FilterChain{Filters: allFilters, Target: route.Function}
|
||||
chain.ProcessFilter(wrappedRequest, wrappedResponse)
|
||||
} else {
|
||||
// no filters, handle request by route
|
||||
|
|
@ -299,13 +305,75 @@ func fixedPrefixPath(pathspec string) string {
|
|||
}
|
||||
|
||||
// ServeHTTP implements net/http.Handler therefore a Container can be a Handler in a http.Server
|
||||
func (c *Container) ServeHTTP(httpwriter http.ResponseWriter, httpRequest *http.Request) {
|
||||
c.ServeMux.ServeHTTP(httpwriter, httpRequest)
|
||||
func (c *Container) ServeHTTP(httpWriter http.ResponseWriter, httpRequest *http.Request) {
|
||||
// Skip, if content encoding is disabled
|
||||
if !c.contentEncodingEnabled {
|
||||
c.ServeMux.ServeHTTP(httpWriter, httpRequest)
|
||||
return
|
||||
}
|
||||
// content encoding is enabled
|
||||
|
||||
// Skip, if httpWriter is already an CompressingResponseWriter
|
||||
if _, ok := httpWriter.(*CompressingResponseWriter); ok {
|
||||
c.ServeMux.ServeHTTP(httpWriter, httpRequest)
|
||||
return
|
||||
}
|
||||
|
||||
writer := httpWriter
|
||||
// CompressingResponseWriter should be closed after all operations are done
|
||||
defer func() {
|
||||
if compressWriter, ok := writer.(*CompressingResponseWriter); ok {
|
||||
compressWriter.Close()
|
||||
}
|
||||
}()
|
||||
|
||||
doCompress, encoding := wantsCompressedResponse(httpRequest)
|
||||
if doCompress {
|
||||
var err error
|
||||
writer, err = NewCompressingResponseWriter(httpWriter, encoding)
|
||||
if err != nil {
|
||||
log.Print("unable to install compressor: ", err)
|
||||
httpWriter.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
c.ServeMux.ServeHTTP(writer, httpRequest)
|
||||
}
|
||||
|
||||
// Handle registers the handler for the given pattern. If a handler already exists for pattern, Handle panics.
|
||||
func (c *Container) Handle(pattern string, handler http.Handler) {
|
||||
c.ServeMux.Handle(pattern, handler)
|
||||
c.ServeMux.Handle(pattern, http.HandlerFunc(func(httpWriter http.ResponseWriter, httpRequest *http.Request) {
|
||||
// Skip, if httpWriter is already an CompressingResponseWriter
|
||||
if _, ok := httpWriter.(*CompressingResponseWriter); ok {
|
||||
handler.ServeHTTP(httpWriter, httpRequest)
|
||||
return
|
||||
}
|
||||
|
||||
writer := httpWriter
|
||||
|
||||
// CompressingResponseWriter should be closed after all operations are done
|
||||
defer func() {
|
||||
if compressWriter, ok := writer.(*CompressingResponseWriter); ok {
|
||||
compressWriter.Close()
|
||||
}
|
||||
}()
|
||||
|
||||
if c.contentEncodingEnabled {
|
||||
doCompress, encoding := wantsCompressedResponse(httpRequest)
|
||||
if doCompress {
|
||||
var err error
|
||||
writer, err = NewCompressingResponseWriter(httpWriter, encoding)
|
||||
if err != nil {
|
||||
log.Print("unable to install compressor: ", err)
|
||||
httpWriter.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handler.ServeHTTP(writer, httpRequest)
|
||||
}))
|
||||
}
|
||||
|
||||
// HandleWithFilter registers the handler for the given pattern.
|
||||
|
|
@ -319,7 +387,7 @@ func (c *Container) HandleWithFilter(pattern string, handler http.Handler) {
|
|||
}
|
||||
|
||||
chain := FilterChain{Filters: c.containerFilters, Target: func(req *Request, resp *Response) {
|
||||
handler.ServeHTTP(httpResponse, httpRequest)
|
||||
handler.ServeHTTP(resp, req.Request)
|
||||
}}
|
||||
chain.ProcessFilter(NewRequest(httpRequest), NewResponse(httpResponse))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ func (c CurlyRouter) SelectRoute(
|
|||
func (c CurlyRouter) selectRoutes(ws *WebService, requestTokens []string) sortableCurlyRoutes {
|
||||
candidates := make(sortableCurlyRoutes, 0, 8)
|
||||
for _, each := range ws.routes {
|
||||
matches, paramCount, staticCount := c.matchesRouteByPathTokens(each.pathParts, requestTokens)
|
||||
matches, paramCount, staticCount := c.matchesRouteByPathTokens(each.pathParts, requestTokens, each.hasCustomVerb)
|
||||
if matches {
|
||||
candidates.add(curlyRoute{each, paramCount, staticCount}) // TODO make sure Routes() return pointers?
|
||||
}
|
||||
|
|
@ -57,7 +57,7 @@ func (c CurlyRouter) selectRoutes(ws *WebService, requestTokens []string) sortab
|
|||
}
|
||||
|
||||
// matchesRouteByPathTokens computes whether it matches, howmany parameters do match and what the number of static path elements are.
|
||||
func (c CurlyRouter) matchesRouteByPathTokens(routeTokens, requestTokens []string) (matches bool, paramCount int, staticCount int) {
|
||||
func (c CurlyRouter) matchesRouteByPathTokens(routeTokens, requestTokens []string, routeHasCustomVerb bool) (matches bool, paramCount int, staticCount int) {
|
||||
if len(routeTokens) < len(requestTokens) {
|
||||
// proceed in matching only if last routeToken is wildcard
|
||||
count := len(routeTokens)
|
||||
|
|
@ -72,6 +72,15 @@ func (c CurlyRouter) matchesRouteByPathTokens(routeTokens, requestTokens []strin
|
|||
return false, 0, 0
|
||||
}
|
||||
requestToken := requestTokens[i]
|
||||
if routeHasCustomVerb && hasCustomVerb(routeToken){
|
||||
if !isMatchCustomVerb(routeToken, requestToken) {
|
||||
return false, 0, 0
|
||||
}
|
||||
staticCount++
|
||||
requestToken = removeCustomVerb(requestToken)
|
||||
routeToken = removeCustomVerb(routeToken)
|
||||
}
|
||||
|
||||
if strings.HasPrefix(routeToken, "{") {
|
||||
paramCount++
|
||||
if colon := strings.Index(routeToken, ":"); colon != -1 {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
package restful
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
var (
|
||||
customVerbReg = regexp.MustCompile(":([A-Za-z]+)$")
|
||||
)
|
||||
|
||||
func hasCustomVerb(routeToken string) bool {
|
||||
return customVerbReg.MatchString(routeToken)
|
||||
}
|
||||
|
||||
func isMatchCustomVerb(routeToken string, pathToken string) bool {
|
||||
rs := customVerbReg.FindStringSubmatch(routeToken)
|
||||
if len(rs) < 2 {
|
||||
return false
|
||||
}
|
||||
|
||||
customVerb := rs[1]
|
||||
specificVerbReg := regexp.MustCompile(fmt.Sprintf(":%s$", customVerb))
|
||||
return specificVerbReg.MatchString(pathToken)
|
||||
}
|
||||
|
||||
func removeCustomVerb(str string) string {
|
||||
return customVerbReg.ReplaceAllString(str, "")
|
||||
}
|
||||
|
|
@ -9,6 +9,7 @@ import (
|
|||
"fmt"
|
||||
"net/http"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// RouterJSR311 implements the flow for matching Requests to Routes (and consequently Resource Functions)
|
||||
|
|
@ -98,7 +99,18 @@ func (r RouterJSR311) detectRoute(routes []Route, httpRequest *http.Request) (*R
|
|||
if trace {
|
||||
traceLogger.Printf("no Route found (in %d routes) that matches HTTP method %s\n", len(previous), httpRequest.Method)
|
||||
}
|
||||
return nil, NewError(http.StatusMethodNotAllowed, "405: Method Not Allowed")
|
||||
allowed := []string{}
|
||||
allowedLoop:
|
||||
for _, candidate := range previous {
|
||||
for _, method := range allowed {
|
||||
if method == candidate.Method {
|
||||
continue allowedLoop
|
||||
}
|
||||
}
|
||||
allowed = append(allowed, candidate.Method)
|
||||
}
|
||||
header := http.Header{"Allow": []string{strings.Join(allowed, ", ")}}
|
||||
return nil, NewErrorWithHeader(http.StatusMethodNotAllowed, "405: Method Not Allowed", header)
|
||||
}
|
||||
|
||||
// content-type
|
||||
|
|
@ -135,7 +147,14 @@ func (r RouterJSR311) detectRoute(routes []Route, httpRequest *http.Request) (*R
|
|||
if trace {
|
||||
traceLogger.Printf("no Route found (from %d) that matches HTTP Accept: %s\n", len(previous), accept)
|
||||
}
|
||||
return nil, NewError(http.StatusNotAcceptable, "406: Not Acceptable")
|
||||
available := []string{}
|
||||
for _, candidate := range previous {
|
||||
available = append(available, candidate.Produces...)
|
||||
}
|
||||
return nil, NewError(
|
||||
http.StatusNotAcceptable,
|
||||
fmt.Sprintf("406: Not Acceptable\n\nAvailable representations: %s", strings.Join(available, ", ")),
|
||||
)
|
||||
}
|
||||
// return r.bestMatchByMedia(outputMediaOk, contentType, accept), nil
|
||||
return candidates[0], nil
|
||||
|
|
|
|||
|
|
@ -29,7 +29,12 @@ func (d defaultPathProcessor) ExtractParameters(r *Route, _ *WebService, urlPath
|
|||
} else {
|
||||
value = urlParts[i]
|
||||
}
|
||||
if strings.HasPrefix(key, "{") { // path-parameter
|
||||
if r.hasCustomVerb && hasCustomVerb(key) {
|
||||
key = removeCustomVerb(key)
|
||||
value = removeCustomVerb(value)
|
||||
}
|
||||
|
||||
if strings.Index(key, "{") > -1 { // path-parameter
|
||||
if colon := strings.Index(key, ":"); colon != -1 {
|
||||
// extract by regex
|
||||
regPart := key[colon+1 : len(key)-1]
|
||||
|
|
@ -42,7 +47,13 @@ func (d defaultPathProcessor) ExtractParameters(r *Route, _ *WebService, urlPath
|
|||
}
|
||||
} else {
|
||||
// without enclosing {}
|
||||
pathParameters[key[1:len(key)-1]] = value
|
||||
startIndex := strings.Index(key, "{")
|
||||
endKeyIndex := strings.Index(key, "}")
|
||||
|
||||
suffixLength := len(key) - endKeyIndex - 1
|
||||
endValueIndex := len(value) - suffixLength
|
||||
|
||||
pathParameters[key[startIndex+1:endKeyIndex]] = value[startIndex:endValueIndex]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -174,15 +174,16 @@ func (r *Response) WriteHeaderAndJson(status int, value interface{}, contentType
|
|||
return writeJSON(r, status, contentType, value)
|
||||
}
|
||||
|
||||
// WriteError write the http status and the error string on the response. err can be nil.
|
||||
func (r *Response) WriteError(httpStatus int, err error) error {
|
||||
// WriteError writes the http status and the error string on the response. err can be nil.
|
||||
// Return an error if writing was not succesful.
|
||||
func (r *Response) WriteError(httpStatus int, err error) (writeErr error) {
|
||||
r.err = err
|
||||
if err == nil {
|
||||
r.WriteErrorString(httpStatus, "")
|
||||
writeErr = r.WriteErrorString(httpStatus, "")
|
||||
} else {
|
||||
r.WriteErrorString(httpStatus, err.Error())
|
||||
writeErr = r.WriteErrorString(httpStatus, err.Error())
|
||||
}
|
||||
return err
|
||||
return writeErr
|
||||
}
|
||||
|
||||
// WriteServiceError is a convenience method for a responding with a status and a ServiceError
|
||||
|
|
|
|||
|
|
@ -49,11 +49,20 @@ type Route struct {
|
|||
|
||||
//Overrides the container.contentEncodingEnabled
|
||||
contentEncodingEnabled *bool
|
||||
|
||||
// indicate route path has custom verb
|
||||
hasCustomVerb bool
|
||||
|
||||
// if a request does not include a content-type header then
|
||||
// depending on the method, it may return a 415 Unsupported Media
|
||||
// Must have uppercase HTTP Method names such as GET,HEAD,OPTIONS,...
|
||||
allowedMethodsWithoutContentType []string
|
||||
}
|
||||
|
||||
// Initialize for Route
|
||||
func (r *Route) postBuild() {
|
||||
r.pathParts = tokenizePath(r.Path)
|
||||
r.hasCustomVerb = hasCustomVerb(r.Path)
|
||||
}
|
||||
|
||||
// Create Request and Response from their http versions
|
||||
|
|
@ -67,17 +76,6 @@ func (r *Route) wrapRequestResponse(httpWriter http.ResponseWriter, httpRequest
|
|||
return wrappedRequest, wrappedResponse
|
||||
}
|
||||
|
||||
// dispatchWithFilters call the function after passing through its own filters
|
||||
func (r *Route) dispatchWithFilters(wrappedRequest *Request, wrappedResponse *Response) {
|
||||
if len(r.Filters) > 0 {
|
||||
chain := FilterChain{Filters: r.Filters, Target: r.Function}
|
||||
chain.ProcessFilter(wrappedRequest, wrappedResponse)
|
||||
} else {
|
||||
// unfiltered
|
||||
r.Function(wrappedRequest, wrappedResponse)
|
||||
}
|
||||
}
|
||||
|
||||
func stringTrimSpaceCutset(r rune) bool {
|
||||
return r == ' '
|
||||
}
|
||||
|
|
@ -121,8 +119,17 @@ func (r Route) matchesContentType(mimeTypes string) bool {
|
|||
if len(mimeTypes) == 0 {
|
||||
// idempotent methods with (most-likely or guaranteed) empty content match missing Content-Type
|
||||
m := r.Method
|
||||
if m == "GET" || m == "HEAD" || m == "OPTIONS" || m == "DELETE" || m == "TRACE" {
|
||||
return true
|
||||
// if route specifies less or non-idempotent methods then use that
|
||||
if len(r.allowedMethodsWithoutContentType) > 0 {
|
||||
for _, each := range r.allowedMethodsWithoutContentType {
|
||||
if m == each {
|
||||
return true
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if m == "GET" || m == "HEAD" || m == "OPTIONS" || m == "DELETE" || m == "TRACE" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
// proceed with default
|
||||
mimeTypes = MIME_OCTET
|
||||
|
|
|
|||
|
|
@ -17,14 +17,15 @@ import (
|
|||
|
||||
// RouteBuilder is a helper to construct Routes.
|
||||
type RouteBuilder struct {
|
||||
rootPath string
|
||||
currentPath string
|
||||
produces []string
|
||||
consumes []string
|
||||
httpMethod string // required
|
||||
function RouteFunction // required
|
||||
filters []FilterFunction
|
||||
conditions []RouteSelectionConditionFunction
|
||||
rootPath string
|
||||
currentPath string
|
||||
produces []string
|
||||
consumes []string
|
||||
httpMethod string // required
|
||||
function RouteFunction // required
|
||||
filters []FilterFunction
|
||||
conditions []RouteSelectionConditionFunction
|
||||
allowedMethodsWithoutContentType []string // see Route
|
||||
|
||||
typeNameHandleFunc TypeNameHandleFunction // required
|
||||
|
||||
|
|
@ -176,6 +177,15 @@ func (b *RouteBuilder) Returns(code int, message string, model interface{}) *Rou
|
|||
return b
|
||||
}
|
||||
|
||||
// ReturnsWithHeaders is similar to Returns, but can specify response headers
|
||||
func (b *RouteBuilder) ReturnsWithHeaders(code int, message string, model interface{}, headers map[string]Header) *RouteBuilder {
|
||||
b.Returns(code, message, model)
|
||||
err := b.errorMap[code]
|
||||
err.Headers = headers
|
||||
b.errorMap[code] = err
|
||||
return b
|
||||
}
|
||||
|
||||
// DefaultReturns is a special Returns call that sets the default of the response.
|
||||
func (b *RouteBuilder) DefaultReturns(message string, model interface{}) *RouteBuilder {
|
||||
b.defaultResponse = &ResponseError{
|
||||
|
|
@ -200,14 +210,41 @@ func (b *RouteBuilder) Deprecate() *RouteBuilder {
|
|||
return b
|
||||
}
|
||||
|
||||
// AllowedMethodsWithoutContentType overides the default list GET,HEAD,OPTIONS,DELETE,TRACE
|
||||
// If a request does not include a content-type header then
|
||||
// depending on the method, it may return a 415 Unsupported Media.
|
||||
// Must have uppercase HTTP Method names such as GET,HEAD,OPTIONS,...
|
||||
func (b *RouteBuilder) AllowedMethodsWithoutContentType(methods []string) *RouteBuilder {
|
||||
b.allowedMethodsWithoutContentType = methods
|
||||
return b
|
||||
}
|
||||
|
||||
// ResponseError represents a response; not necessarily an error.
|
||||
type ResponseError struct {
|
||||
Code int
|
||||
Message string
|
||||
Model interface{}
|
||||
Headers map[string]Header
|
||||
IsDefault bool
|
||||
}
|
||||
|
||||
// Header describes a header for a response of the API
|
||||
//
|
||||
// For more information: http://goo.gl/8us55a#headerObject
|
||||
type Header struct {
|
||||
*Items
|
||||
Description string
|
||||
}
|
||||
|
||||
// Items describe swagger simple schemas for headers
|
||||
type Items struct {
|
||||
Type string
|
||||
Format string
|
||||
Items *Items
|
||||
CollectionFormat string
|
||||
Default interface{}
|
||||
}
|
||||
|
||||
func (b *RouteBuilder) servicePath(path string) *RouteBuilder {
|
||||
b.rootPath = path
|
||||
return b
|
||||
|
|
@ -276,26 +313,27 @@ func (b *RouteBuilder) Build() Route {
|
|||
operationName = nameOfFunction(b.function)
|
||||
}
|
||||
route := Route{
|
||||
Method: b.httpMethod,
|
||||
Path: concatPath(b.rootPath, b.currentPath),
|
||||
Produces: b.produces,
|
||||
Consumes: b.consumes,
|
||||
Function: b.function,
|
||||
Filters: b.filters,
|
||||
If: b.conditions,
|
||||
relativePath: b.currentPath,
|
||||
pathExpr: pathExpr,
|
||||
Doc: b.doc,
|
||||
Notes: b.notes,
|
||||
Operation: operationName,
|
||||
ParameterDocs: b.parameters,
|
||||
ResponseErrors: b.errorMap,
|
||||
DefaultResponse: b.defaultResponse,
|
||||
ReadSample: b.readSample,
|
||||
WriteSample: b.writeSample,
|
||||
Metadata: b.metadata,
|
||||
Deprecated: b.deprecated,
|
||||
contentEncodingEnabled: b.contentEncodingEnabled,
|
||||
Method: b.httpMethod,
|
||||
Path: concatPath(b.rootPath, b.currentPath),
|
||||
Produces: b.produces,
|
||||
Consumes: b.consumes,
|
||||
Function: b.function,
|
||||
Filters: b.filters,
|
||||
If: b.conditions,
|
||||
relativePath: b.currentPath,
|
||||
pathExpr: pathExpr,
|
||||
Doc: b.doc,
|
||||
Notes: b.notes,
|
||||
Operation: operationName,
|
||||
ParameterDocs: b.parameters,
|
||||
ResponseErrors: b.errorMap,
|
||||
DefaultResponse: b.defaultResponse,
|
||||
ReadSample: b.readSample,
|
||||
WriteSample: b.writeSample,
|
||||
Metadata: b.metadata,
|
||||
Deprecated: b.deprecated,
|
||||
contentEncodingEnabled: b.contentEncodingEnabled,
|
||||
allowedMethodsWithoutContentType: b.allowedMethodsWithoutContentType,
|
||||
}
|
||||
route.postBuild()
|
||||
return route
|
||||
|
|
|
|||
|
|
@ -4,12 +4,16 @@ package restful
|
|||
// Use of this source code is governed by a license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// ServiceError is a transport object to pass information about a non-Http error occurred in a WebService while processing a request.
|
||||
type ServiceError struct {
|
||||
Code int
|
||||
Message string
|
||||
Header http.Header
|
||||
}
|
||||
|
||||
// NewError returns a ServiceError using the code and reason
|
||||
|
|
@ -17,6 +21,11 @@ func NewError(code int, message string) ServiceError {
|
|||
return ServiceError{Code: code, Message: message}
|
||||
}
|
||||
|
||||
// NewErrorWithHeader returns a ServiceError using the code, reason and header
|
||||
func NewErrorWithHeader(code int, message string, header http.Header) ServiceError {
|
||||
return ServiceError{Code: code, Message: message, Header: header}
|
||||
}
|
||||
|
||||
// Error returns a text representation of the service error
|
||||
func (s ServiceError) Error() string {
|
||||
return fmt.Sprintf("[ServiceError:%v] %v", s.Code, s.Message)
|
||||
|
|
|
|||
|
|
@ -188,7 +188,7 @@ func (w *WebService) RemoveRoute(path, method string) error {
|
|||
continue
|
||||
}
|
||||
newRoutes[current] = w.routes[ix]
|
||||
current = current + 1
|
||||
current++
|
||||
}
|
||||
w.routes = newRoutes
|
||||
return nil
|
||||
|
|
@ -288,3 +288,8 @@ func (w *WebService) PATCH(subPath string) *RouteBuilder {
|
|||
func (w *WebService) DELETE(subPath string) *RouteBuilder {
|
||||
return new(RouteBuilder).typeNameHandler(w.typeNameHandleFunc).servicePath(w.rootPath).Method("DELETE").Path(subPath)
|
||||
}
|
||||
|
||||
// OPTIONS is a shortcut for .Method("OPTIONS").Path(subPath)
|
||||
func (w *WebService) OPTIONS(subPath string) *RouteBuilder {
|
||||
return new(RouteBuilder).typeNameHandler(w.typeNameHandleFunc).servicePath(w.rootPath).Method("OPTIONS").Path(subPath)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,8 @@ There are implementations for the following logging libraries:
|
|||
- **log** (the Go standard library logger):
|
||||
[stdr](https://github.com/go-logr/stdr)
|
||||
- **github.com/sirupsen/logrus**: [logrusr](https://github.com/bombsimon/logrusr)
|
||||
- **github.com/wojas/genericr**: [genericr](https://github.com/wojas/genericr) (makes it easy to implement your own backend)
|
||||
- **logfmt** (Heroku style [logging](https://www.brandur.org/logfmt)): [logfmtr](https://github.com/iand/logfmtr)
|
||||
|
||||
# FAQ
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
Copyright 2020 The logr 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 logr
|
||||
|
||||
// Discard returns a valid Logger that discards all messages logged to it.
|
||||
// It can be used whenever the caller is not interested in the logs.
|
||||
func Discard() Logger {
|
||||
return DiscardLogger{}
|
||||
}
|
||||
|
||||
// DiscardLogger is a Logger that discards all messages.
|
||||
type DiscardLogger struct{}
|
||||
|
||||
func (l DiscardLogger) Enabled() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (l DiscardLogger) Info(msg string, keysAndValues ...interface{}) {
|
||||
}
|
||||
|
||||
func (l DiscardLogger) Error(err error, msg string, keysAndValues ...interface{}) {
|
||||
}
|
||||
|
||||
func (l DiscardLogger) V(level int) Logger {
|
||||
return l
|
||||
}
|
||||
|
||||
func (l DiscardLogger) WithValues(keysAndValues ...interface{}) Logger {
|
||||
return l
|
||||
}
|
||||
|
||||
func (l DiscardLogger) WithName(name string) Logger {
|
||||
return l
|
||||
}
|
||||
|
||||
// Verify that it actually implements the interface
|
||||
var _ Logger = DiscardLogger{}
|
||||
|
|
@ -14,18 +14,15 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package logr defines abstract interfaces for logging. Packages can depend on
|
||||
// these interfaces and callers can implement logging in whatever way is
|
||||
// appropriate.
|
||||
//
|
||||
// This design derives from Dave Cheney's blog:
|
||||
// http://dave.cheney.net/2015/11/05/lets-talk-about-logging
|
||||
//
|
||||
// This is a BETA grade API. Until there is a significant 2nd implementation,
|
||||
// I don't really know how it will change.
|
||||
//
|
||||
// The logging specifically makes it non-trivial to use format strings, to encourage
|
||||
// attaching structured information instead of unstructured format strings.
|
||||
|
||||
// Package logr defines abstract interfaces for logging. Packages can depend on
|
||||
// these interfaces and callers can implement logging in whatever way is
|
||||
// appropriate.
|
||||
//
|
||||
// Usage
|
||||
//
|
||||
|
|
@ -40,17 +37,16 @@ limitations under the License.
|
|||
// we want to log that we've made some decision.
|
||||
//
|
||||
// With the traditional log package, we might write:
|
||||
// log.Printf(
|
||||
// "decided to set field foo to value %q for object %s/%s",
|
||||
// log.Printf("decided to set field foo to value %q for object %s/%s",
|
||||
// targetValue, object.Namespace, object.Name)
|
||||
//
|
||||
// With logr's structured logging, we'd write:
|
||||
// // elsewhere in the file, set up the logger to log with the prefix of "reconcilers",
|
||||
// // and the named value target-type=Foo, for extra context.
|
||||
// log := mainLogger.WithName("reconcilers").WithValues("target-type", "Foo")
|
||||
// // elsewhere in the file, set up the logger to log with the prefix of
|
||||
// // "reconcilers", and the named value target-type=Foo, for extra context.
|
||||
// log := mainLogger.WithName("reconcilers").WithValues("target-type", "Foo")
|
||||
//
|
||||
// // later on...
|
||||
// log.Info("setting field foo on object", "value", targetValue, "object", object)
|
||||
// // later on...
|
||||
// log.Info("setting foo on object", "value", targetValue, "object", object)
|
||||
//
|
||||
// Depending on our logging implementation, we could then make logging decisions
|
||||
// based on field values (like only logging such events for objects in a certain
|
||||
|
|
@ -78,9 +74,9 @@ limitations under the License.
|
|||
// Each log message from a Logger has four types of context:
|
||||
// logger name, log verbosity, log message, and the named values.
|
||||
//
|
||||
// The Logger name constists of a series of name "segments" added by successive
|
||||
// The Logger name consists of a series of name "segments" added by successive
|
||||
// calls to WithName. These name segments will be joined in some way by the
|
||||
// underlying implementation. It is strongly reccomended that name segements
|
||||
// underlying implementation. It is strongly recommended that name segments
|
||||
// contain simple identifiers (letters, digits, and hyphen), and do not contain
|
||||
// characters that could muddle the log output or confuse the joining operation
|
||||
// (e.g. whitespace, commas, periods, slashes, brackets, quotes, etc).
|
||||
|
|
@ -91,8 +87,8 @@ limitations under the License.
|
|||
// and log messages for users to filter on. It's illegal to pass a log level
|
||||
// below zero.
|
||||
//
|
||||
// The log message consists of a constant message attached to the the log line.
|
||||
// This should generally be a simple description of what's occuring, and should
|
||||
// The log message consists of a constant message attached to the log line.
|
||||
// This should generally be a simple description of what's occurring, and should
|
||||
// never be a format string.
|
||||
//
|
||||
// Variable information can then be attached using named values (key/value
|
||||
|
|
@ -115,24 +111,38 @@ limitations under the License.
|
|||
// generally best to avoid using the following keys, as they're frequently used
|
||||
// by implementations:
|
||||
//
|
||||
// - `"caller"`: the calling information (file/line) of a particular log line.
|
||||
// - `"error"`: the underlying error value in the `Error` method.
|
||||
// - `"level"`: the log level.
|
||||
// - `"logger"`: the name of the associated logger.
|
||||
// - `"msg"`: the log message.
|
||||
// - `"stacktrace"`: the stack trace associated with a particular log line or
|
||||
// error (often from the `Error` message).
|
||||
// - `"ts"`: the timestamp for a log line.
|
||||
// * `"caller"`: the calling information (file/line) of a particular log line.
|
||||
// * `"error"`: the underlying error value in the `Error` method.
|
||||
// * `"level"`: the log level.
|
||||
// * `"logger"`: the name of the associated logger.
|
||||
// * `"msg"`: the log message.
|
||||
// * `"stacktrace"`: the stack trace associated with a particular log line or
|
||||
// error (often from the `Error` message).
|
||||
// * `"ts"`: the timestamp for a log line.
|
||||
//
|
||||
// Implementations are encouraged to make use of these keys to represent the
|
||||
// above concepts, when neccessary (for example, in a pure-JSON output form, it
|
||||
// above concepts, when necessary (for example, in a pure-JSON output form, it
|
||||
// would be necessary to represent at least message and timestamp as ordinary
|
||||
// named values).
|
||||
//
|
||||
// Implementations may choose to give callers access to the underlying
|
||||
// logging implementation. The recommended pattern for this is:
|
||||
// // Underlier exposes access to the underlying logging implementation.
|
||||
// // Since callers only have a logr.Logger, they have to know which
|
||||
// // implementation is in use, so this interface is less of an abstraction
|
||||
// // and more of way to test type conversion.
|
||||
// type Underlier interface {
|
||||
// GetUnderlying() <underlying-type>
|
||||
// }
|
||||
package logr
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
// TODO: consider adding back in format strings if they're really needed
|
||||
// TODO: consider other bits of zap/zapcore functionality like ObjectMarshaller (for arbitrary objects)
|
||||
// TODO: consider other bits of glog functionality like Flush, InfoDepth, OutputStats
|
||||
// TODO: consider other bits of glog functionality like Flush, OutputStats
|
||||
|
||||
// Logger represents the ability to log messages, both errors and not.
|
||||
type Logger interface {
|
||||
|
|
@ -171,8 +181,86 @@ type Logger interface {
|
|||
|
||||
// WithName adds a new element to the logger's name.
|
||||
// Successive calls with WithName continue to append
|
||||
// suffixes to the logger's name. It's strongly reccomended
|
||||
// suffixes to the logger's name. It's strongly recommended
|
||||
// that name segments contain only letters, digits, and hyphens
|
||||
// (see the package documentation for more information).
|
||||
WithName(name string) Logger
|
||||
}
|
||||
|
||||
// InfoLogger provides compatibility with code that relies on the v0.1.0
|
||||
// interface.
|
||||
//
|
||||
// Deprecated: InfoLogger is an artifact of early versions of this API. New
|
||||
// users should never use it and existing users should use Logger instead. This
|
||||
// will be removed in a future release.
|
||||
type InfoLogger = Logger
|
||||
|
||||
type contextKey struct{}
|
||||
|
||||
// FromContext returns a Logger constructed from ctx or nil if no
|
||||
// logger details are found.
|
||||
func FromContext(ctx context.Context) Logger {
|
||||
if v, ok := ctx.Value(contextKey{}).(Logger); ok {
|
||||
return v
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// FromContextOrDiscard returns a Logger constructed from ctx or a Logger
|
||||
// that discards all messages if no logger details are found.
|
||||
func FromContextOrDiscard(ctx context.Context) Logger {
|
||||
if v, ok := ctx.Value(contextKey{}).(Logger); ok {
|
||||
return v
|
||||
}
|
||||
|
||||
return Discard()
|
||||
}
|
||||
|
||||
// NewContext returns a new context derived from ctx that embeds the Logger.
|
||||
func NewContext(ctx context.Context, l Logger) context.Context {
|
||||
return context.WithValue(ctx, contextKey{}, l)
|
||||
}
|
||||
|
||||
// CallDepthLogger represents a Logger that knows how to climb the call stack
|
||||
// to identify the original call site and can offset the depth by a specified
|
||||
// number of frames. This is useful for users who have helper functions
|
||||
// between the "real" call site and the actual calls to Logger methods.
|
||||
// Implementations that log information about the call site (such as file,
|
||||
// function, or line) would otherwise log information about the intermediate
|
||||
// helper functions.
|
||||
//
|
||||
// This is an optional interface and implementations are not required to
|
||||
// support it.
|
||||
type CallDepthLogger interface {
|
||||
Logger
|
||||
|
||||
// WithCallDepth returns a Logger that will offset the call stack by the
|
||||
// specified number of frames when logging call site information. If depth
|
||||
// is 0 the attribution should be to the direct caller of this method. If
|
||||
// depth is 1 the attribution should skip 1 call frame, and so on.
|
||||
// Successive calls to this are additive.
|
||||
WithCallDepth(depth int) Logger
|
||||
}
|
||||
|
||||
// WithCallDepth returns a Logger that will offset the call stack by the
|
||||
// specified number of frames when logging call site information, if possible.
|
||||
// This is useful for users who have helper functions between the "real" call
|
||||
// site and the actual calls to Logger methods. If depth is 0 the attribution
|
||||
// should be to the direct caller of this function. If depth is 1 the
|
||||
// attribution should skip 1 call frame, and so on. Successive calls to this
|
||||
// are additive.
|
||||
//
|
||||
// If the underlying log implementation supports the CallDepthLogger interface,
|
||||
// the WithCallDepth method will be called and the result returned. If the
|
||||
// implementation does not support CallDepthLogger, the original Logger will be
|
||||
// returned.
|
||||
//
|
||||
// Callers which care about whether this was supported or not should test for
|
||||
// CallDepthLogger support themselves.
|
||||
func WithCallDepth(logger Logger, depth int) Logger {
|
||||
if decorator, ok := logger.(CallDepthLogger); ok {
|
||||
return decorator.WithCallDepth(depth)
|
||||
}
|
||||
return logger
|
||||
}
|
||||
|
|
|
|||
|
|
@ -318,7 +318,7 @@ func unescape(s string) (ch string, tail string, err error) {
|
|||
if i > utf8.MaxRune {
|
||||
return "", "", fmt.Errorf(`\%c%s is not a valid Unicode code point`, r, ss)
|
||||
}
|
||||
return string(i), s, nil
|
||||
return string(rune(i)), s, nil
|
||||
}
|
||||
return "", "", fmt.Errorf(`unknown escape \%c`, r)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,10 @@
|
|||
language: go
|
||||
|
||||
go:
|
||||
- 1.4
|
||||
- 1.3
|
||||
- 1.2
|
||||
- tip
|
||||
|
||||
install:
|
||||
- if ! go get code.google.com/p/go.tools/cmd/cover; then go get golang.org/x/tools/cmd/cover; fi
|
||||
- 1.11.x
|
||||
- 1.12.x
|
||||
- 1.13.x
|
||||
- master
|
||||
|
||||
script:
|
||||
- go test -cover
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# How to contribute #
|
||||
|
||||
We'd love to accept your patches and contributions to this project. There are
|
||||
a just a few small guidelines you need to follow.
|
||||
just a few small guidelines you need to follow.
|
||||
|
||||
|
||||
## Contributor License Agreement ##
|
||||
|
|
|
|||
|
|
@ -68,4 +68,22 @@ f.Fuzz(&myObject) // Type will correspond to whether A or B info is set.
|
|||
|
||||
See more examples in ```example_test.go```.
|
||||
|
||||
You can use this library for easier [go-fuzz](https://github.com/dvyukov/go-fuzz)ing.
|
||||
go-fuzz provides the user a byte-slice, which should be converted to different inputs
|
||||
for the tested function. This library can help convert the byte slice. Consider for
|
||||
example a fuzz test for a the function `mypackage.MyFunc` that takes an int arguments:
|
||||
```go
|
||||
// +build gofuzz
|
||||
package mypackage
|
||||
|
||||
import fuzz "github.com/google/gofuzz"
|
||||
|
||||
func Fuzz(data []byte) int {
|
||||
var i int
|
||||
fuzz.NewFromGoFuzz(data).Fuzz(&i)
|
||||
MyFunc(i)
|
||||
return 0
|
||||
}
|
||||
```
|
||||
|
||||
Happy testing!
|
||||
|
|
|
|||
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
Copyright 2014 Google Inc. All rights reserved.
|
||||
|
||||
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 bytesource provides a rand.Source64 that is determined by a slice of bytes.
|
||||
package bytesource
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"io"
|
||||
"math/rand"
|
||||
)
|
||||
|
||||
// ByteSource implements rand.Source64 determined by a slice of bytes. The random numbers are
|
||||
// generated from each 8 bytes in the slice, until the last bytes are consumed, from which a
|
||||
// fallback pseudo random source is created in case more random numbers are required.
|
||||
// It also exposes a `bytes.Reader` API, which lets callers consume the bytes directly.
|
||||
type ByteSource struct {
|
||||
*bytes.Reader
|
||||
fallback rand.Source
|
||||
}
|
||||
|
||||
// New returns a new ByteSource from a given slice of bytes.
|
||||
func New(input []byte) *ByteSource {
|
||||
s := &ByteSource{
|
||||
Reader: bytes.NewReader(input),
|
||||
fallback: rand.NewSource(0),
|
||||
}
|
||||
if len(input) > 0 {
|
||||
s.fallback = rand.NewSource(int64(s.consumeUint64()))
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *ByteSource) Uint64() uint64 {
|
||||
// Return from input if it was not exhausted.
|
||||
if s.Len() > 0 {
|
||||
return s.consumeUint64()
|
||||
}
|
||||
|
||||
// Input was exhausted, return random number from fallback (in this case fallback should not be
|
||||
// nil). Try first having a Uint64 output (Should work in current rand implementation),
|
||||
// otherwise return a conversion of Int63.
|
||||
if s64, ok := s.fallback.(rand.Source64); ok {
|
||||
return s64.Uint64()
|
||||
}
|
||||
return uint64(s.fallback.Int63())
|
||||
}
|
||||
|
||||
func (s *ByteSource) Int63() int64 {
|
||||
return int64(s.Uint64() >> 1)
|
||||
}
|
||||
|
||||
func (s *ByteSource) Seed(seed int64) {
|
||||
s.fallback = rand.NewSource(seed)
|
||||
s.Reader = bytes.NewReader(nil)
|
||||
}
|
||||
|
||||
// consumeUint64 reads 8 bytes from the input and convert them to a uint64. It assumes that the the
|
||||
// bytes reader is not empty.
|
||||
func (s *ByteSource) consumeUint64() uint64 {
|
||||
var bytes [8]byte
|
||||
_, err := s.Read(bytes[:])
|
||||
if err != nil && err != io.EOF {
|
||||
panic("failed reading source") // Should not happen.
|
||||
}
|
||||
return binary.BigEndian.Uint64(bytes[:])
|
||||
}
|
||||
|
|
@ -22,6 +22,9 @@ import (
|
|||
"reflect"
|
||||
"regexp"
|
||||
"time"
|
||||
|
||||
"github.com/google/gofuzz/bytesource"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// fuzzFuncMap is a map from a type to a fuzzFunc that handles that type.
|
||||
|
|
@ -61,6 +64,34 @@ func NewWithSeed(seed int64) *Fuzzer {
|
|||
return f
|
||||
}
|
||||
|
||||
// NewFromGoFuzz is a helper function that enables using gofuzz (this
|
||||
// project) with go-fuzz (https://github.com/dvyukov/go-fuzz) for continuous
|
||||
// fuzzing. Essentially, it enables translating the fuzzing bytes from
|
||||
// go-fuzz to any Go object using this library.
|
||||
//
|
||||
// This implementation promises a constant translation from a given slice of
|
||||
// bytes to the fuzzed objects. This promise will remain over future
|
||||
// versions of Go and of this library.
|
||||
//
|
||||
// Note: the returned Fuzzer should not be shared between multiple goroutines,
|
||||
// as its deterministic output will no longer be available.
|
||||
//
|
||||
// Example: use go-fuzz to test the function `MyFunc(int)` in the package
|
||||
// `mypackage`. Add the file: "mypacakge_fuzz.go" with the content:
|
||||
//
|
||||
// // +build gofuzz
|
||||
// package mypacakge
|
||||
// import fuzz "github.com/google/gofuzz"
|
||||
// func Fuzz(data []byte) int {
|
||||
// var i int
|
||||
// fuzz.NewFromGoFuzz(data).Fuzz(&i)
|
||||
// MyFunc(i)
|
||||
// return 0
|
||||
// }
|
||||
func NewFromGoFuzz(data []byte) *Fuzzer {
|
||||
return New().RandSource(bytesource.New(data))
|
||||
}
|
||||
|
||||
// Funcs adds each entry in fuzzFuncs as a custom fuzzing function.
|
||||
//
|
||||
// Each entry in fuzzFuncs must be a function taking two parameters.
|
||||
|
|
@ -141,7 +172,7 @@ func (f *Fuzzer) genElementCount() int {
|
|||
}
|
||||
|
||||
func (f *Fuzzer) genShouldFill() bool {
|
||||
return f.r.Float64() > f.nilChance
|
||||
return f.r.Float64() >= f.nilChance
|
||||
}
|
||||
|
||||
// MaxDepth sets the maximum number of recursive fuzz calls that will be made
|
||||
|
|
@ -240,6 +271,7 @@ func (fc *fuzzerContext) doFuzz(v reflect.Value, flags uint64) {
|
|||
fn(v, fc.fuzzer.r)
|
||||
return
|
||||
}
|
||||
|
||||
switch v.Kind() {
|
||||
case reflect.Map:
|
||||
if fc.fuzzer.genShouldFill() {
|
||||
|
|
@ -450,10 +482,10 @@ var fillFuncMap = map[reflect.Kind]func(reflect.Value, *rand.Rand){
|
|||
v.SetFloat(r.Float64())
|
||||
},
|
||||
reflect.Complex64: func(v reflect.Value, r *rand.Rand) {
|
||||
panic("unimplemented")
|
||||
v.SetComplex(complex128(complex(r.Float32(), r.Float32())))
|
||||
},
|
||||
reflect.Complex128: func(v reflect.Value, r *rand.Rand) {
|
||||
panic("unimplemented")
|
||||
v.SetComplex(complex(r.Float64(), r.Float64()))
|
||||
},
|
||||
reflect.String: func(v reflect.Value, r *rand.Rand) {
|
||||
v.SetString(randString(r))
|
||||
|
|
@ -465,38 +497,105 @@ var fillFuncMap = map[reflect.Kind]func(reflect.Value, *rand.Rand){
|
|||
|
||||
// randBool returns true or false randomly.
|
||||
func randBool(r *rand.Rand) bool {
|
||||
if r.Int()&1 == 1 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
return r.Int31()&(1<<30) == 0
|
||||
}
|
||||
|
||||
type charRange struct {
|
||||
first, last rune
|
||||
type int63nPicker interface {
|
||||
Int63n(int64) int64
|
||||
}
|
||||
|
||||
// UnicodeRange describes a sequential range of unicode characters.
|
||||
// Last must be numerically greater than First.
|
||||
type UnicodeRange struct {
|
||||
First, Last rune
|
||||
}
|
||||
|
||||
// UnicodeRanges describes an arbitrary number of sequential ranges of unicode characters.
|
||||
// To be useful, each range must have at least one character (First <= Last) and
|
||||
// there must be at least one range.
|
||||
type UnicodeRanges []UnicodeRange
|
||||
|
||||
// choose returns a random unicode character from the given range, using the
|
||||
// given randomness source.
|
||||
func (r *charRange) choose(rand *rand.Rand) rune {
|
||||
count := int64(r.last - r.first)
|
||||
return r.first + rune(rand.Int63n(count))
|
||||
func (ur UnicodeRange) choose(r int63nPicker) rune {
|
||||
count := int64(ur.Last - ur.First + 1)
|
||||
return ur.First + rune(r.Int63n(count))
|
||||
}
|
||||
|
||||
var unicodeRanges = []charRange{
|
||||
// CustomStringFuzzFunc constructs a FuzzFunc which produces random strings.
|
||||
// Each character is selected from the range ur. If there are no characters
|
||||
// in the range (cr.Last < cr.First), this will panic.
|
||||
func (ur UnicodeRange) CustomStringFuzzFunc() func(s *string, c Continue) {
|
||||
ur.check()
|
||||
return func(s *string, c Continue) {
|
||||
*s = ur.randString(c.Rand)
|
||||
}
|
||||
}
|
||||
|
||||
// check is a function that used to check whether the first of ur(UnicodeRange)
|
||||
// is greater than the last one.
|
||||
func (ur UnicodeRange) check() {
|
||||
if ur.Last < ur.First {
|
||||
panic("The last encoding must be greater than the first one.")
|
||||
}
|
||||
}
|
||||
|
||||
// randString of UnicodeRange makes a random string up to 20 characters long.
|
||||
// Each character is selected form ur(UnicodeRange).
|
||||
func (ur UnicodeRange) randString(r *rand.Rand) string {
|
||||
n := r.Intn(20)
|
||||
sb := strings.Builder{}
|
||||
sb.Grow(n)
|
||||
for i := 0; i < n; i++ {
|
||||
sb.WriteRune(ur.choose(r))
|
||||
}
|
||||
return sb.String()
|
||||
}
|
||||
|
||||
// defaultUnicodeRanges sets a default unicode range when user do not set
|
||||
// CustomStringFuzzFunc() but wants fuzz string.
|
||||
var defaultUnicodeRanges = UnicodeRanges{
|
||||
{' ', '~'}, // ASCII characters
|
||||
{'\u00a0', '\u02af'}, // Multi-byte encoded characters
|
||||
{'\u4e00', '\u9fff'}, // Common CJK (even longer encodings)
|
||||
}
|
||||
|
||||
// CustomStringFuzzFunc constructs a FuzzFunc which produces random strings.
|
||||
// Each character is selected from one of the ranges of ur(UnicodeRanges).
|
||||
// Each range has an equal probability of being chosen. If there are no ranges,
|
||||
// or a selected range has no characters (.Last < .First), this will panic.
|
||||
// Do not modify any of the ranges in ur after calling this function.
|
||||
func (ur UnicodeRanges) CustomStringFuzzFunc() func(s *string, c Continue) {
|
||||
// Check unicode ranges slice is empty.
|
||||
if len(ur) == 0 {
|
||||
panic("UnicodeRanges is empty.")
|
||||
}
|
||||
// if not empty, each range should be checked.
|
||||
for i := range ur {
|
||||
ur[i].check()
|
||||
}
|
||||
return func(s *string, c Continue) {
|
||||
*s = ur.randString(c.Rand)
|
||||
}
|
||||
}
|
||||
|
||||
// randString of UnicodeRanges makes a random string up to 20 characters long.
|
||||
// Each character is selected form one of the ranges of ur(UnicodeRanges),
|
||||
// and each range has an equal probability of being chosen.
|
||||
func (ur UnicodeRanges) randString(r *rand.Rand) string {
|
||||
n := r.Intn(20)
|
||||
sb := strings.Builder{}
|
||||
sb.Grow(n)
|
||||
for i := 0; i < n; i++ {
|
||||
sb.WriteRune(ur[r.Intn(len(ur))].choose(r))
|
||||
}
|
||||
return sb.String()
|
||||
}
|
||||
|
||||
// randString makes a random string up to 20 characters long. The returned string
|
||||
// may include a variety of (valid) UTF-8 encodings.
|
||||
func randString(r *rand.Rand) string {
|
||||
n := r.Intn(20)
|
||||
runes := make([]rune, n)
|
||||
for i := range runes {
|
||||
runes[i] = unicodeRanges[r.Intn(len(unicodeRanges))].choose(r)
|
||||
}
|
||||
return string(runes)
|
||||
return defaultUnicodeRanges.randString(r)
|
||||
}
|
||||
|
||||
// randUint64 makes random 64 bit numbers.
|
||||
|
|
|
|||
|
|
@ -26,8 +26,8 @@ var (
|
|||
// NewMD5 and NewSHA1.
|
||||
func NewHash(h hash.Hash, space UUID, data []byte, version int) UUID {
|
||||
h.Reset()
|
||||
h.Write(space[:])
|
||||
h.Write(data)
|
||||
h.Write(space[:]) //nolint:errcheck
|
||||
h.Write(data) //nolint:errcheck
|
||||
s := h.Sum(nil)
|
||||
var uuid UUID
|
||||
copy(uuid[:], s)
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import (
|
|||
"fmt"
|
||||
)
|
||||
|
||||
// Scan implements sql.Scanner so UUIDs can be read from databases transparently
|
||||
// Scan implements sql.Scanner so UUIDs can be read from databases transparently.
|
||||
// Currently, database types that map to string and []byte are supported. Please
|
||||
// consult database-specific driver documentation for matching types.
|
||||
func (uuid *UUID) Scan(src interface{}) error {
|
||||
|
|
|
|||
|
|
@ -35,6 +35,12 @@ const (
|
|||
|
||||
var rander = rand.Reader // random function
|
||||
|
||||
type invalidLengthError struct{ len int }
|
||||
|
||||
func (err invalidLengthError) Error() string {
|
||||
return fmt.Sprintf("invalid UUID length: %d", err.len)
|
||||
}
|
||||
|
||||
// Parse decodes s into a UUID or returns an error. Both the standard UUID
|
||||
// forms of xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and
|
||||
// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx are decoded as well as the
|
||||
|
|
@ -68,7 +74,7 @@ func Parse(s string) (UUID, error) {
|
|||
}
|
||||
return uuid, nil
|
||||
default:
|
||||
return uuid, fmt.Errorf("invalid UUID length: %d", len(s))
|
||||
return uuid, invalidLengthError{len(s)}
|
||||
}
|
||||
// s is now at least 36 bytes long
|
||||
// it must be of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
|
|
@ -112,7 +118,7 @@ func ParseBytes(b []byte) (UUID, error) {
|
|||
}
|
||||
return uuid, nil
|
||||
default:
|
||||
return uuid, fmt.Errorf("invalid UUID length: %d", len(b))
|
||||
return uuid, invalidLengthError{len(b)}
|
||||
}
|
||||
// s is now at least 36 bytes long
|
||||
// it must be of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
|
|
|
|||
|
|
@ -14,6 +14,14 @@ func New() UUID {
|
|||
return Must(NewRandom())
|
||||
}
|
||||
|
||||
// NewString creates a new random UUID and returns it as a string or panics.
|
||||
// NewString is equivalent to the expression
|
||||
//
|
||||
// uuid.New().String()
|
||||
func NewString() string {
|
||||
return Must(NewRandom()).String()
|
||||
}
|
||||
|
||||
// NewRandom returns a Random (Version 4) UUID.
|
||||
//
|
||||
// The strength of the UUIDs is based on the strength of the crypto/rand
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
# Compiler support code
|
||||
|
||||
This directory contains compiler support code used by Gnostic and Gnostic extensions.
|
||||
This directory contains compiler support code used by Gnostic and Gnostic
|
||||
extensions.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
// Copyright 2017 Google LLC. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
|
@ -14,30 +14,36 @@
|
|||
|
||||
package compiler
|
||||
|
||||
import (
|
||||
yaml "gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
// Context contains state of the compiler as it traverses a document.
|
||||
type Context struct {
|
||||
Parent *Context
|
||||
Name string
|
||||
Node *yaml.Node
|
||||
ExtensionHandlers *[]ExtensionHandler
|
||||
}
|
||||
|
||||
// NewContextWithExtensions returns a new object representing the compiler state
|
||||
func NewContextWithExtensions(name string, parent *Context, extensionHandlers *[]ExtensionHandler) *Context {
|
||||
return &Context{Name: name, Parent: parent, ExtensionHandlers: extensionHandlers}
|
||||
func NewContextWithExtensions(name string, node *yaml.Node, parent *Context, extensionHandlers *[]ExtensionHandler) *Context {
|
||||
return &Context{Name: name, Node: node, Parent: parent, ExtensionHandlers: extensionHandlers}
|
||||
}
|
||||
|
||||
// NewContext returns a new object representing the compiler state
|
||||
func NewContext(name string, parent *Context) *Context {
|
||||
func NewContext(name string, node *yaml.Node, parent *Context) *Context {
|
||||
if parent != nil {
|
||||
return &Context{Name: name, Parent: parent, ExtensionHandlers: parent.ExtensionHandlers}
|
||||
return &Context{Name: name, Node: node, Parent: parent, ExtensionHandlers: parent.ExtensionHandlers}
|
||||
}
|
||||
return &Context{Name: name, Parent: parent, ExtensionHandlers: nil}
|
||||
}
|
||||
|
||||
// Description returns a text description of the compiler state
|
||||
func (context *Context) Description() string {
|
||||
name := context.Name
|
||||
if context.Parent != nil {
|
||||
return context.Parent.Description() + "." + context.Name
|
||||
name = context.Parent.Description() + "." + name
|
||||
}
|
||||
return context.Name
|
||||
return name
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
// Copyright 2017 Google LLC. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
|
@ -14,6 +14,8 @@
|
|||
|
||||
package compiler
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Error represents compiler errors and their location in the document.
|
||||
type Error struct {
|
||||
Context *Context
|
||||
|
|
@ -25,12 +27,19 @@ func NewError(context *Context, message string) *Error {
|
|||
return &Error{Context: context, Message: message}
|
||||
}
|
||||
|
||||
func (err *Error) locationDescription() string {
|
||||
if err.Context.Node != nil {
|
||||
return fmt.Sprintf("[%d,%d] %s", err.Context.Node.Line, err.Context.Node.Column, err.Context.Description())
|
||||
}
|
||||
return err.Context.Description()
|
||||
}
|
||||
|
||||
// Error returns the string value of an Error.
|
||||
func (err *Error) Error() string {
|
||||
if err.Context == nil {
|
||||
return "ERROR " + err.Message
|
||||
return err.Message
|
||||
}
|
||||
return "ERROR " + err.Context.Description() + " " + err.Message
|
||||
return err.locationDescription() + " " + err.Message
|
||||
}
|
||||
|
||||
// ErrorGroup is a container for groups of Error values.
|
||||
|
|
|
|||
|
|
@ -1,101 +0,0 @@
|
|||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// 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 compiler
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
|
||||
"strings"
|
||||
|
||||
"errors"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/golang/protobuf/ptypes/any"
|
||||
ext_plugin "github.com/googleapis/gnostic/extensions"
|
||||
yaml "gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
// ExtensionHandler describes a binary that is called by the compiler to handle specification extensions.
|
||||
type ExtensionHandler struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
// HandleExtension calls a binary extension handler.
|
||||
func HandleExtension(context *Context, in interface{}, extensionName string) (bool, *any.Any, error) {
|
||||
handled := false
|
||||
var errFromPlugin error
|
||||
var outFromPlugin *any.Any
|
||||
|
||||
if context != nil && context.ExtensionHandlers != nil && len(*(context.ExtensionHandlers)) != 0 {
|
||||
for _, customAnyProtoGenerator := range *(context.ExtensionHandlers) {
|
||||
outFromPlugin, errFromPlugin = customAnyProtoGenerator.handle(in, extensionName)
|
||||
if outFromPlugin == nil {
|
||||
continue
|
||||
} else {
|
||||
handled = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return handled, outFromPlugin, errFromPlugin
|
||||
}
|
||||
|
||||
func (extensionHandlers *ExtensionHandler) handle(in interface{}, extensionName string) (*any.Any, error) {
|
||||
if extensionHandlers.Name != "" {
|
||||
binary, _ := yaml.Marshal(in)
|
||||
|
||||
request := &ext_plugin.ExtensionHandlerRequest{}
|
||||
|
||||
version := &ext_plugin.Version{}
|
||||
version.Major = 0
|
||||
version.Minor = 1
|
||||
version.Patch = 0
|
||||
request.CompilerVersion = version
|
||||
|
||||
request.Wrapper = &ext_plugin.Wrapper{}
|
||||
|
||||
request.Wrapper.Version = "v2"
|
||||
request.Wrapper.Yaml = string(binary)
|
||||
request.Wrapper.ExtensionName = extensionName
|
||||
|
||||
requestBytes, _ := proto.Marshal(request)
|
||||
cmd := exec.Command(extensionHandlers.Name)
|
||||
cmd.Stdin = bytes.NewReader(requestBytes)
|
||||
output, err := cmd.Output()
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("Error: %+v\n", err)
|
||||
return nil, err
|
||||
}
|
||||
response := &ext_plugin.ExtensionHandlerResponse{}
|
||||
err = proto.Unmarshal(output, response)
|
||||
if err != nil {
|
||||
fmt.Printf("Error: %+v\n", err)
|
||||
fmt.Printf("%s\n", string(output))
|
||||
return nil, err
|
||||
}
|
||||
if !response.Handled {
|
||||
return nil, nil
|
||||
}
|
||||
if len(response.Error) != 0 {
|
||||
message := fmt.Sprintf("Errors when parsing: %+v for field %s by vendor extension handler %s. Details %+v", in, extensionName, extensionHandlers.Name, strings.Join(response.Error, ","))
|
||||
return nil, errors.New(message)
|
||||
}
|
||||
return response.Value, nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
// Copyright 2017 Google LLC. All Rights Reserved.
|
||||
//
|
||||
// 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 compiler
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/golang/protobuf/ptypes/any"
|
||||
extensions "github.com/googleapis/gnostic/extensions"
|
||||
yaml "gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
// ExtensionHandler describes a binary that is called by the compiler to handle specification extensions.
|
||||
type ExtensionHandler struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
// CallExtension calls a binary extension handler.
|
||||
func CallExtension(context *Context, in *yaml.Node, extensionName string) (handled bool, response *any.Any, err error) {
|
||||
if context == nil || context.ExtensionHandlers == nil {
|
||||
return false, nil, nil
|
||||
}
|
||||
handled = false
|
||||
for _, handler := range *(context.ExtensionHandlers) {
|
||||
response, err = handler.handle(in, extensionName)
|
||||
if response == nil {
|
||||
continue
|
||||
} else {
|
||||
handled = true
|
||||
break
|
||||
}
|
||||
}
|
||||
return handled, response, err
|
||||
}
|
||||
|
||||
func (extensionHandlers *ExtensionHandler) handle(in *yaml.Node, extensionName string) (*any.Any, error) {
|
||||
if extensionHandlers.Name != "" {
|
||||
yamlData, _ := yaml.Marshal(in)
|
||||
request := &extensions.ExtensionHandlerRequest{
|
||||
CompilerVersion: &extensions.Version{
|
||||
Major: 0,
|
||||
Minor: 1,
|
||||
Patch: 0,
|
||||
},
|
||||
Wrapper: &extensions.Wrapper{
|
||||
Version: "unknown", // TODO: set this to the type/version of spec being parsed.
|
||||
Yaml: string(yamlData),
|
||||
ExtensionName: extensionName,
|
||||
},
|
||||
}
|
||||
requestBytes, _ := proto.Marshal(request)
|
||||
cmd := exec.Command(extensionHandlers.Name)
|
||||
cmd.Stdin = bytes.NewReader(requestBytes)
|
||||
output, err := cmd.Output()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
response := &extensions.ExtensionHandlerResponse{}
|
||||
err = proto.Unmarshal(output, response)
|
||||
if err != nil || !response.Handled {
|
||||
return nil, err
|
||||
}
|
||||
if len(response.Errors) != 0 {
|
||||
return nil, fmt.Errorf("Errors when parsing: %+v for field %s by vendor extension handler %s. Details %+v", in, extensionName, extensionHandlers.Name, strings.Join(response.Errors, ","))
|
||||
}
|
||||
return response.Value, nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
// Copyright 2017 Google LLC. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
|
@ -16,56 +16,63 @@ package compiler
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"gopkg.in/yaml.v2"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
|
||||
"github.com/googleapis/gnostic/jsonschema"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
// compiler helper functions, usually called from generated code
|
||||
|
||||
// UnpackMap gets a yaml.MapSlice if possible.
|
||||
func UnpackMap(in interface{}) (yaml.MapSlice, bool) {
|
||||
m, ok := in.(yaml.MapSlice)
|
||||
if ok {
|
||||
return m, true
|
||||
// UnpackMap gets a *yaml.Node if possible.
|
||||
func UnpackMap(in *yaml.Node) (*yaml.Node, bool) {
|
||||
if in == nil {
|
||||
return nil, false
|
||||
}
|
||||
// do we have an empty array?
|
||||
a, ok := in.([]interface{})
|
||||
if ok && len(a) == 0 {
|
||||
// if so, return an empty map
|
||||
return yaml.MapSlice{}, true
|
||||
}
|
||||
return nil, false
|
||||
return in, true
|
||||
}
|
||||
|
||||
// SortedKeysForMap returns the sorted keys of a yaml.MapSlice.
|
||||
func SortedKeysForMap(m yaml.MapSlice) []string {
|
||||
// SortedKeysForMap returns the sorted keys of a yamlv2.MapSlice.
|
||||
func SortedKeysForMap(m *yaml.Node) []string {
|
||||
keys := make([]string, 0)
|
||||
for _, item := range m {
|
||||
keys = append(keys, item.Key.(string))
|
||||
if m.Kind == yaml.MappingNode {
|
||||
for i := 0; i < len(m.Content); i += 2 {
|
||||
keys = append(keys, m.Content[i].Value)
|
||||
}
|
||||
}
|
||||
sort.Strings(keys)
|
||||
return keys
|
||||
}
|
||||
|
||||
// MapHasKey returns true if a yaml.MapSlice contains a specified key.
|
||||
func MapHasKey(m yaml.MapSlice, key string) bool {
|
||||
for _, item := range m {
|
||||
itemKey, ok := item.Key.(string)
|
||||
if ok && key == itemKey {
|
||||
return true
|
||||
// MapHasKey returns true if a yamlv2.MapSlice contains a specified key.
|
||||
func MapHasKey(m *yaml.Node, key string) bool {
|
||||
if m == nil {
|
||||
return false
|
||||
}
|
||||
if m.Kind == yaml.MappingNode {
|
||||
for i := 0; i < len(m.Content); i += 2 {
|
||||
itemKey := m.Content[i].Value
|
||||
if key == itemKey {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// MapValueForKey gets the value of a map value for a specified key.
|
||||
func MapValueForKey(m yaml.MapSlice, key string) interface{} {
|
||||
for _, item := range m {
|
||||
itemKey, ok := item.Key.(string)
|
||||
if ok && key == itemKey {
|
||||
return item.Value
|
||||
func MapValueForKey(m *yaml.Node, key string) *yaml.Node {
|
||||
if m == nil {
|
||||
return nil
|
||||
}
|
||||
if m.Kind == yaml.MappingNode {
|
||||
for i := 0; i < len(m.Content); i += 2 {
|
||||
itemKey := m.Content[i].Value
|
||||
if key == itemKey {
|
||||
return m.Content[i+1]
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
|
@ -83,8 +90,118 @@ func ConvertInterfaceArrayToStringArray(interfaceArray []interface{}) []string {
|
|||
return stringArray
|
||||
}
|
||||
|
||||
// SequenceNodeForNode returns a node if it is a SequenceNode.
|
||||
func SequenceNodeForNode(node *yaml.Node) (*yaml.Node, bool) {
|
||||
if node.Kind != yaml.SequenceNode {
|
||||
return nil, false
|
||||
}
|
||||
return node, true
|
||||
}
|
||||
|
||||
// BoolForScalarNode returns the bool value of a node.
|
||||
func BoolForScalarNode(node *yaml.Node) (bool, bool) {
|
||||
if node == nil {
|
||||
return false, false
|
||||
}
|
||||
if node.Kind == yaml.DocumentNode {
|
||||
return BoolForScalarNode(node.Content[0])
|
||||
}
|
||||
if node.Kind != yaml.ScalarNode {
|
||||
return false, false
|
||||
}
|
||||
if node.Tag != "!!bool" {
|
||||
return false, false
|
||||
}
|
||||
v, err := strconv.ParseBool(node.Value)
|
||||
if err != nil {
|
||||
return false, false
|
||||
}
|
||||
return v, true
|
||||
}
|
||||
|
||||
// IntForScalarNode returns the integer value of a node.
|
||||
func IntForScalarNode(node *yaml.Node) (int64, bool) {
|
||||
if node == nil {
|
||||
return 0, false
|
||||
}
|
||||
if node.Kind == yaml.DocumentNode {
|
||||
return IntForScalarNode(node.Content[0])
|
||||
}
|
||||
if node.Kind != yaml.ScalarNode {
|
||||
return 0, false
|
||||
}
|
||||
if node.Tag != "!!int" {
|
||||
return 0, false
|
||||
}
|
||||
v, err := strconv.ParseInt(node.Value, 10, 64)
|
||||
if err != nil {
|
||||
return 0, false
|
||||
}
|
||||
return v, true
|
||||
}
|
||||
|
||||
// FloatForScalarNode returns the float value of a node.
|
||||
func FloatForScalarNode(node *yaml.Node) (float64, bool) {
|
||||
if node == nil {
|
||||
return 0.0, false
|
||||
}
|
||||
if node.Kind == yaml.DocumentNode {
|
||||
return FloatForScalarNode(node.Content[0])
|
||||
}
|
||||
if node.Kind != yaml.ScalarNode {
|
||||
return 0.0, false
|
||||
}
|
||||
if (node.Tag != "!!int") && (node.Tag != "!!float") {
|
||||
return 0.0, false
|
||||
}
|
||||
v, err := strconv.ParseFloat(node.Value, 64)
|
||||
if err != nil {
|
||||
return 0.0, false
|
||||
}
|
||||
return v, true
|
||||
}
|
||||
|
||||
// StringForScalarNode returns the string value of a node.
|
||||
func StringForScalarNode(node *yaml.Node) (string, bool) {
|
||||
if node == nil {
|
||||
return "", false
|
||||
}
|
||||
if node.Kind == yaml.DocumentNode {
|
||||
return StringForScalarNode(node.Content[0])
|
||||
}
|
||||
switch node.Kind {
|
||||
case yaml.ScalarNode:
|
||||
switch node.Tag {
|
||||
case "!!int":
|
||||
return node.Value, true
|
||||
case "!!str":
|
||||
return node.Value, true
|
||||
case "!!timestamp":
|
||||
return node.Value, true
|
||||
case "!!null":
|
||||
return "", true
|
||||
default:
|
||||
return "", false
|
||||
}
|
||||
default:
|
||||
return "", false
|
||||
}
|
||||
}
|
||||
|
||||
// StringArrayForSequenceNode converts a sequence node to an array of strings, if possible.
|
||||
func StringArrayForSequenceNode(node *yaml.Node) []string {
|
||||
stringArray := make([]string, 0)
|
||||
for _, item := range node.Content {
|
||||
v, ok := StringForScalarNode(item)
|
||||
if ok {
|
||||
stringArray = append(stringArray, v)
|
||||
}
|
||||
}
|
||||
return stringArray
|
||||
}
|
||||
|
||||
// MissingKeysInMap identifies which keys from a list of required keys are not in a map.
|
||||
func MissingKeysInMap(m yaml.MapSlice, requiredKeys []string) []string {
|
||||
func MissingKeysInMap(m *yaml.Node, requiredKeys []string) []string {
|
||||
missingKeys := make([]string, 0)
|
||||
for _, k := range requiredKeys {
|
||||
if !MapHasKey(m, k) {
|
||||
|
|
@ -95,64 +212,109 @@ func MissingKeysInMap(m yaml.MapSlice, requiredKeys []string) []string {
|
|||
}
|
||||
|
||||
// InvalidKeysInMap returns keys in a map that don't match a list of allowed keys and patterns.
|
||||
func InvalidKeysInMap(m yaml.MapSlice, allowedKeys []string, allowedPatterns []*regexp.Regexp) []string {
|
||||
func InvalidKeysInMap(m *yaml.Node, allowedKeys []string, allowedPatterns []*regexp.Regexp) []string {
|
||||
invalidKeys := make([]string, 0)
|
||||
for _, item := range m {
|
||||
itemKey, ok := item.Key.(string)
|
||||
if ok {
|
||||
key := itemKey
|
||||
found := false
|
||||
// does the key match an allowed key?
|
||||
for _, allowedKey := range allowedKeys {
|
||||
if key == allowedKey {
|
||||
if m == nil || m.Kind != yaml.MappingNode {
|
||||
return invalidKeys
|
||||
}
|
||||
for i := 0; i < len(m.Content); i += 2 {
|
||||
key := m.Content[i].Value
|
||||
found := false
|
||||
// does the key match an allowed key?
|
||||
for _, allowedKey := range allowedKeys {
|
||||
if key == allowedKey {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
// does the key match an allowed pattern?
|
||||
for _, allowedPattern := range allowedPatterns {
|
||||
if allowedPattern.MatchString(key) {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
// does the key match an allowed pattern?
|
||||
for _, allowedPattern := range allowedPatterns {
|
||||
if allowedPattern.MatchString(key) {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
invalidKeys = append(invalidKeys, key)
|
||||
}
|
||||
invalidKeys = append(invalidKeys, key)
|
||||
}
|
||||
}
|
||||
}
|
||||
return invalidKeys
|
||||
}
|
||||
|
||||
// DescribeMap describes a map (for debugging purposes).
|
||||
func DescribeMap(in interface{}, indent string) string {
|
||||
description := ""
|
||||
m, ok := in.(map[string]interface{})
|
||||
if ok {
|
||||
keys := make([]string, 0)
|
||||
for k := range m {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
for _, k := range keys {
|
||||
v := m[k]
|
||||
description += fmt.Sprintf("%s%s:\n", indent, k)
|
||||
description += DescribeMap(v, indent+" ")
|
||||
}
|
||||
return description
|
||||
// NewNullNode creates a new Null node.
|
||||
func NewNullNode() *yaml.Node {
|
||||
node := &yaml.Node{
|
||||
Kind: yaml.ScalarNode,
|
||||
Tag: "!!null",
|
||||
}
|
||||
a, ok := in.([]interface{})
|
||||
if ok {
|
||||
for i, v := range a {
|
||||
description += fmt.Sprintf("%s%d:\n", indent, i)
|
||||
description += DescribeMap(v, indent+" ")
|
||||
}
|
||||
return description
|
||||
return node
|
||||
}
|
||||
|
||||
// NewMappingNode creates a new Mapping node.
|
||||
func NewMappingNode() *yaml.Node {
|
||||
return &yaml.Node{
|
||||
Kind: yaml.MappingNode,
|
||||
Content: make([]*yaml.Node, 0),
|
||||
}
|
||||
}
|
||||
|
||||
// NewSequenceNode creates a new Sequence node.
|
||||
func NewSequenceNode() *yaml.Node {
|
||||
node := &yaml.Node{
|
||||
Kind: yaml.SequenceNode,
|
||||
Content: make([]*yaml.Node, 0),
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
||||
// NewScalarNodeForString creates a new node to hold a string.
|
||||
func NewScalarNodeForString(s string) *yaml.Node {
|
||||
return &yaml.Node{
|
||||
Kind: yaml.ScalarNode,
|
||||
Tag: "!!str",
|
||||
Value: s,
|
||||
}
|
||||
}
|
||||
|
||||
// NewSequenceNodeForStringArray creates a new node to hold an array of strings.
|
||||
func NewSequenceNodeForStringArray(strings []string) *yaml.Node {
|
||||
node := &yaml.Node{
|
||||
Kind: yaml.SequenceNode,
|
||||
Content: make([]*yaml.Node, 0),
|
||||
}
|
||||
for _, s := range strings {
|
||||
node.Content = append(node.Content, NewScalarNodeForString(s))
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
||||
// NewScalarNodeForBool creates a new node to hold a bool.
|
||||
func NewScalarNodeForBool(b bool) *yaml.Node {
|
||||
return &yaml.Node{
|
||||
Kind: yaml.ScalarNode,
|
||||
Tag: "!!bool",
|
||||
Value: fmt.Sprintf("%t", b),
|
||||
}
|
||||
}
|
||||
|
||||
// NewScalarNodeForFloat creates a new node to hold a float.
|
||||
func NewScalarNodeForFloat(f float64) *yaml.Node {
|
||||
return &yaml.Node{
|
||||
Kind: yaml.ScalarNode,
|
||||
Tag: "!!float",
|
||||
Value: fmt.Sprintf("%g", f),
|
||||
}
|
||||
}
|
||||
|
||||
// NewScalarNodeForInt creates a new node to hold an integer.
|
||||
func NewScalarNodeForInt(i int64) *yaml.Node {
|
||||
return &yaml.Node{
|
||||
Kind: yaml.ScalarNode,
|
||||
Tag: "!!int",
|
||||
Value: fmt.Sprintf("%d", i),
|
||||
}
|
||||
description += fmt.Sprintf("%s%+v\n", indent, in)
|
||||
return description
|
||||
}
|
||||
|
||||
// PluralProperties returns the string "properties" pluralized.
|
||||
|
|
@ -195,3 +357,40 @@ func StringValue(item interface{}) (value string, ok bool) {
|
|||
}
|
||||
return "", false
|
||||
}
|
||||
|
||||
// Description returns a human-readable represention of an item.
|
||||
func Description(item interface{}) string {
|
||||
value, ok := item.(*yaml.Node)
|
||||
if ok {
|
||||
return jsonschema.Render(value)
|
||||
}
|
||||
return fmt.Sprintf("%+v", item)
|
||||
}
|
||||
|
||||
// Display returns a description of a node for use in error messages.
|
||||
func Display(node *yaml.Node) string {
|
||||
switch node.Kind {
|
||||
case yaml.ScalarNode:
|
||||
switch node.Tag {
|
||||
case "!!str":
|
||||
return fmt.Sprintf("%s (string)", node.Value)
|
||||
}
|
||||
}
|
||||
return fmt.Sprintf("%+v (%T)", node, node)
|
||||
}
|
||||
|
||||
// Marshal creates a yaml version of a structure in our preferred style
|
||||
func Marshal(in *yaml.Node) []byte {
|
||||
clearStyle(in)
|
||||
//bytes, _ := yaml.Marshal(&yaml.Node{Kind: yaml.DocumentNode, Content: []*yaml.Node{in}})
|
||||
bytes, _ := yaml.Marshal(in)
|
||||
|
||||
return bytes
|
||||
}
|
||||
|
||||
func clearStyle(node *yaml.Node) {
|
||||
node.Style = 0
|
||||
for _, c := range node.Content {
|
||||
clearStyle(c)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
// Copyright 2017 Google LLC. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
// Copyright 2017 Google LLC. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
|
@ -15,7 +15,6 @@
|
|||
package compiler
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
|
|
@ -23,18 +22,30 @@ import (
|
|||
"net/url"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
yaml "gopkg.in/yaml.v2"
|
||||
yaml "gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
var fileCache map[string][]byte
|
||||
var infoCache map[string]interface{}
|
||||
var count int64
|
||||
|
||||
var verboseReader = false
|
||||
|
||||
var fileCache map[string][]byte
|
||||
var infoCache map[string]*yaml.Node
|
||||
|
||||
var fileCacheEnable = true
|
||||
var infoCacheEnable = true
|
||||
|
||||
// These locks are used to synchronize accesses to the fileCache and infoCache
|
||||
// maps (above). They are global state and can throw thread-related errors
|
||||
// when modified from separate goroutines. The general strategy is to protect
|
||||
// all public functions in this file with mutex Lock() calls. As a result, to
|
||||
// avoid deadlock, these public functions should not call other public
|
||||
// functions, so some public functions have private equivalents.
|
||||
// In the future, we might consider replacing the maps with sync.Map and
|
||||
// eliminating these mutexes.
|
||||
var fileCacheMutex sync.Mutex
|
||||
var infoCacheMutex sync.Mutex
|
||||
|
||||
func initializeFileCache() {
|
||||
if fileCache == nil {
|
||||
fileCache = make(map[string][]byte, 0)
|
||||
|
|
@ -43,27 +54,42 @@ func initializeFileCache() {
|
|||
|
||||
func initializeInfoCache() {
|
||||
if infoCache == nil {
|
||||
infoCache = make(map[string]interface{}, 0)
|
||||
infoCache = make(map[string]*yaml.Node, 0)
|
||||
}
|
||||
}
|
||||
|
||||
// EnableFileCache turns on file caching.
|
||||
func EnableFileCache() {
|
||||
fileCacheMutex.Lock()
|
||||
defer fileCacheMutex.Unlock()
|
||||
fileCacheEnable = true
|
||||
}
|
||||
|
||||
// EnableInfoCache turns on parsed info caching.
|
||||
func EnableInfoCache() {
|
||||
infoCacheMutex.Lock()
|
||||
defer infoCacheMutex.Unlock()
|
||||
infoCacheEnable = true
|
||||
}
|
||||
|
||||
// DisableFileCache turns off file caching.
|
||||
func DisableFileCache() {
|
||||
fileCacheMutex.Lock()
|
||||
defer fileCacheMutex.Unlock()
|
||||
fileCacheEnable = false
|
||||
}
|
||||
|
||||
// DisableInfoCache turns off parsed info caching.
|
||||
func DisableInfoCache() {
|
||||
infoCacheMutex.Lock()
|
||||
defer infoCacheMutex.Unlock()
|
||||
infoCacheEnable = false
|
||||
}
|
||||
|
||||
// RemoveFromFileCache removes an entry from the file cache.
|
||||
func RemoveFromFileCache(fileurl string) {
|
||||
fileCacheMutex.Lock()
|
||||
defer fileCacheMutex.Unlock()
|
||||
if !fileCacheEnable {
|
||||
return
|
||||
}
|
||||
|
|
@ -71,7 +97,10 @@ func RemoveFromFileCache(fileurl string) {
|
|||
delete(fileCache, fileurl)
|
||||
}
|
||||
|
||||
// RemoveFromInfoCache removes an entry from the info cache.
|
||||
func RemoveFromInfoCache(filename string) {
|
||||
infoCacheMutex.Lock()
|
||||
defer infoCacheMutex.Unlock()
|
||||
if !infoCacheEnable {
|
||||
return
|
||||
}
|
||||
|
|
@ -79,21 +108,31 @@ func RemoveFromInfoCache(filename string) {
|
|||
delete(infoCache, filename)
|
||||
}
|
||||
|
||||
func GetInfoCache() map[string]interface{} {
|
||||
// GetInfoCache returns the info cache map.
|
||||
func GetInfoCache() map[string]*yaml.Node {
|
||||
infoCacheMutex.Lock()
|
||||
defer infoCacheMutex.Unlock()
|
||||
if infoCache == nil {
|
||||
initializeInfoCache()
|
||||
}
|
||||
return infoCache
|
||||
}
|
||||
|
||||
// ClearFileCache clears the file cache.
|
||||
func ClearFileCache() {
|
||||
fileCacheMutex.Lock()
|
||||
defer fileCacheMutex.Unlock()
|
||||
fileCache = make(map[string][]byte, 0)
|
||||
}
|
||||
|
||||
// ClearInfoCache clears the info cache.
|
||||
func ClearInfoCache() {
|
||||
infoCache = make(map[string]interface{})
|
||||
infoCacheMutex.Lock()
|
||||
defer infoCacheMutex.Unlock()
|
||||
infoCache = make(map[string]*yaml.Node)
|
||||
}
|
||||
|
||||
// ClearCaches clears all caches.
|
||||
func ClearCaches() {
|
||||
ClearFileCache()
|
||||
ClearInfoCache()
|
||||
|
|
@ -101,6 +140,12 @@ func ClearCaches() {
|
|||
|
||||
// FetchFile gets a specified file from the local filesystem or a remote location.
|
||||
func FetchFile(fileurl string) ([]byte, error) {
|
||||
fileCacheMutex.Lock()
|
||||
defer fileCacheMutex.Unlock()
|
||||
return fetchFile(fileurl)
|
||||
}
|
||||
|
||||
func fetchFile(fileurl string) ([]byte, error) {
|
||||
var bytes []byte
|
||||
initializeFileCache()
|
||||
if fileCacheEnable {
|
||||
|
|
@ -121,7 +166,7 @@ func FetchFile(fileurl string) ([]byte, error) {
|
|||
}
|
||||
defer response.Body.Close()
|
||||
if response.StatusCode != 200 {
|
||||
return nil, errors.New(fmt.Sprintf("Error downloading %s: %s", fileurl, response.Status))
|
||||
return nil, fmt.Errorf("Error downloading %s: %s", fileurl, response.Status)
|
||||
}
|
||||
bytes, err = ioutil.ReadAll(response.Body)
|
||||
if fileCacheEnable && err == nil {
|
||||
|
|
@ -132,11 +177,17 @@ func FetchFile(fileurl string) ([]byte, error) {
|
|||
|
||||
// ReadBytesForFile reads the bytes of a file.
|
||||
func ReadBytesForFile(filename string) ([]byte, error) {
|
||||
fileCacheMutex.Lock()
|
||||
defer fileCacheMutex.Unlock()
|
||||
return readBytesForFile(filename)
|
||||
}
|
||||
|
||||
func readBytesForFile(filename string) ([]byte, error) {
|
||||
// is the filename a url?
|
||||
fileurl, _ := url.Parse(filename)
|
||||
if fileurl.Scheme != "" {
|
||||
// yes, fetch it
|
||||
bytes, err := FetchFile(filename)
|
||||
bytes, err := fetchFile(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -150,8 +201,14 @@ func ReadBytesForFile(filename string) ([]byte, error) {
|
|||
return bytes, nil
|
||||
}
|
||||
|
||||
// ReadInfoFromBytes unmarshals a file as a yaml.MapSlice.
|
||||
func ReadInfoFromBytes(filename string, bytes []byte) (interface{}, error) {
|
||||
// ReadInfoFromBytes unmarshals a file as a *yaml.Node.
|
||||
func ReadInfoFromBytes(filename string, bytes []byte) (*yaml.Node, error) {
|
||||
infoCacheMutex.Lock()
|
||||
defer infoCacheMutex.Unlock()
|
||||
return readInfoFromBytes(filename, bytes)
|
||||
}
|
||||
|
||||
func readInfoFromBytes(filename string, bytes []byte) (*yaml.Node, error) {
|
||||
initializeInfoCache()
|
||||
if infoCacheEnable {
|
||||
cachedInfo, ok := infoCache[filename]
|
||||
|
|
@ -165,19 +222,23 @@ func ReadInfoFromBytes(filename string, bytes []byte) (interface{}, error) {
|
|||
log.Printf("Reading info for file %s", filename)
|
||||
}
|
||||
}
|
||||
var info yaml.MapSlice
|
||||
var info yaml.Node
|
||||
err := yaml.Unmarshal(bytes, &info)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if infoCacheEnable && len(filename) > 0 {
|
||||
infoCache[filename] = info
|
||||
infoCache[filename] = &info
|
||||
}
|
||||
return info, nil
|
||||
return &info, nil
|
||||
}
|
||||
|
||||
// ReadInfoForRef reads a file and return the fragment needed to resolve a $ref.
|
||||
func ReadInfoForRef(basefile string, ref string) (interface{}, error) {
|
||||
func ReadInfoForRef(basefile string, ref string) (*yaml.Node, error) {
|
||||
fileCacheMutex.Lock()
|
||||
defer fileCacheMutex.Unlock()
|
||||
infoCacheMutex.Lock()
|
||||
defer infoCacheMutex.Unlock()
|
||||
initializeInfoCache()
|
||||
if infoCacheEnable {
|
||||
info, ok := infoCache[ref]
|
||||
|
|
@ -191,7 +252,6 @@ func ReadInfoForRef(basefile string, ref string) (interface{}, error) {
|
|||
log.Printf("Reading info for ref %s#%s", basefile, ref)
|
||||
}
|
||||
}
|
||||
count = count + 1
|
||||
basedir, _ := filepath.Split(basefile)
|
||||
parts := strings.Split(ref, "#")
|
||||
var filename string
|
||||
|
|
@ -204,24 +264,30 @@ func ReadInfoForRef(basefile string, ref string) (interface{}, error) {
|
|||
} else {
|
||||
filename = basefile
|
||||
}
|
||||
bytes, err := ReadBytesForFile(filename)
|
||||
bytes, err := readBytesForFile(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
info, err := ReadInfoFromBytes(filename, bytes)
|
||||
info, err := readInfoFromBytes(filename, bytes)
|
||||
if info != nil && info.Kind == yaml.DocumentNode {
|
||||
info = info.Content[0]
|
||||
}
|
||||
if err != nil {
|
||||
log.Printf("File error: %v\n", err)
|
||||
} else {
|
||||
if info == nil {
|
||||
return nil, NewError(nil, fmt.Sprintf("could not resolve %s", ref))
|
||||
}
|
||||
if len(parts) > 1 {
|
||||
path := strings.Split(parts[1], "/")
|
||||
for i, key := range path {
|
||||
if i > 0 {
|
||||
m, ok := info.(yaml.MapSlice)
|
||||
if ok {
|
||||
m := info
|
||||
if true {
|
||||
found := false
|
||||
for _, section := range m {
|
||||
if section.Key == key {
|
||||
info = section.Value
|
||||
for i := 0; i < len(m.Content); i += 2 {
|
||||
if m.Content[i].Value == key {
|
||||
info = m.Content[i+1]
|
||||
found = true
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,13 @@
|
|||
# Extensions
|
||||
|
||||
This directory contains support code for building Gnostic extensions and associated examples.
|
||||
**Extension Support is experimental.**
|
||||
|
||||
Extensions are used to compile vendor or specification extensions into protocol buffer structures.
|
||||
This directory contains support code for building Gnostic extensio handlers and
|
||||
associated examples.
|
||||
|
||||
Extension handlers can be used to compile vendor or specification extensions
|
||||
into protocol buffer structures.
|
||||
|
||||
Like plugins, extension handlers are built as separate executables. Extension
|
||||
bodies are written to extension handlers as serialized
|
||||
ExtensionHandlerRequests.
|
||||
|
|
|
|||
|
|
@ -1,148 +1,186 @@
|
|||
// Copyright 2017 Google LLC. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.24.0
|
||||
// protoc v3.12.0
|
||||
// source: extensions/extension.proto
|
||||
|
||||
package openapiextension_v1
|
||||
package gnostic_extension_v1
|
||||
|
||||
import (
|
||||
fmt "fmt"
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
any "github.com/golang/protobuf/ptypes/any"
|
||||
math "math"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
|
||||
// This is a compile-time assertion that a sufficiently up-to-date version
|
||||
// of the legacy proto package is being used.
|
||||
const _ = proto.ProtoPackageIsVersion4
|
||||
|
||||
// The version number of OpenAPI compiler.
|
||||
// The version number of Gnostic.
|
||||
type Version struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Major int32 `protobuf:"varint,1,opt,name=major,proto3" json:"major,omitempty"`
|
||||
Minor int32 `protobuf:"varint,2,opt,name=minor,proto3" json:"minor,omitempty"`
|
||||
Patch int32 `protobuf:"varint,3,opt,name=patch,proto3" json:"patch,omitempty"`
|
||||
// A suffix for alpha, beta or rc release, e.g., "alpha-1", "rc2". It should
|
||||
// be empty for mainline stable releases.
|
||||
Suffix string `protobuf:"bytes,4,opt,name=suffix,proto3" json:"suffix,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
Suffix string `protobuf:"bytes,4,opt,name=suffix,proto3" json:"suffix,omitempty"`
|
||||
}
|
||||
|
||||
func (m *Version) Reset() { *m = Version{} }
|
||||
func (m *Version) String() string { return proto.CompactTextString(m) }
|
||||
func (*Version) ProtoMessage() {}
|
||||
func (x *Version) Reset() {
|
||||
*x = Version{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_extensions_extension_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Version) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Version) ProtoMessage() {}
|
||||
|
||||
func (x *Version) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_extensions_extension_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Version.ProtoReflect.Descriptor instead.
|
||||
func (*Version) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_661e47e790f76671, []int{0}
|
||||
return file_extensions_extension_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (m *Version) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_Version.Unmarshal(m, b)
|
||||
}
|
||||
func (m *Version) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_Version.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *Version) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_Version.Merge(m, src)
|
||||
}
|
||||
func (m *Version) XXX_Size() int {
|
||||
return xxx_messageInfo_Version.Size(m)
|
||||
}
|
||||
func (m *Version) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_Version.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_Version proto.InternalMessageInfo
|
||||
|
||||
func (m *Version) GetMajor() int32 {
|
||||
if m != nil {
|
||||
return m.Major
|
||||
func (x *Version) GetMajor() int32 {
|
||||
if x != nil {
|
||||
return x.Major
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Version) GetMinor() int32 {
|
||||
if m != nil {
|
||||
return m.Minor
|
||||
func (x *Version) GetMinor() int32 {
|
||||
if x != nil {
|
||||
return x.Minor
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Version) GetPatch() int32 {
|
||||
if m != nil {
|
||||
return m.Patch
|
||||
func (x *Version) GetPatch() int32 {
|
||||
if x != nil {
|
||||
return x.Patch
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Version) GetSuffix() string {
|
||||
if m != nil {
|
||||
return m.Suffix
|
||||
func (x *Version) GetSuffix() string {
|
||||
if x != nil {
|
||||
return x.Suffix
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// An encoded Request is written to the ExtensionHandler's stdin.
|
||||
type ExtensionHandlerRequest struct {
|
||||
// The OpenAPI descriptions that were explicitly listed on the command line.
|
||||
// The specifications will appear in the order they are specified to gnostic.
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// The extension to process.
|
||||
Wrapper *Wrapper `protobuf:"bytes,1,opt,name=wrapper,proto3" json:"wrapper,omitempty"`
|
||||
// The version number of openapi compiler.
|
||||
CompilerVersion *Version `protobuf:"bytes,3,opt,name=compiler_version,json=compilerVersion,proto3" json:"compiler_version,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
// The version number of Gnostic.
|
||||
CompilerVersion *Version `protobuf:"bytes,2,opt,name=compiler_version,json=compilerVersion,proto3" json:"compiler_version,omitempty"`
|
||||
}
|
||||
|
||||
func (m *ExtensionHandlerRequest) Reset() { *m = ExtensionHandlerRequest{} }
|
||||
func (m *ExtensionHandlerRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*ExtensionHandlerRequest) ProtoMessage() {}
|
||||
func (x *ExtensionHandlerRequest) Reset() {
|
||||
*x = ExtensionHandlerRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_extensions_extension_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ExtensionHandlerRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ExtensionHandlerRequest) ProtoMessage() {}
|
||||
|
||||
func (x *ExtensionHandlerRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_extensions_extension_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ExtensionHandlerRequest.ProtoReflect.Descriptor instead.
|
||||
func (*ExtensionHandlerRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_661e47e790f76671, []int{1}
|
||||
return file_extensions_extension_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (m *ExtensionHandlerRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_ExtensionHandlerRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *ExtensionHandlerRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_ExtensionHandlerRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *ExtensionHandlerRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_ExtensionHandlerRequest.Merge(m, src)
|
||||
}
|
||||
func (m *ExtensionHandlerRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_ExtensionHandlerRequest.Size(m)
|
||||
}
|
||||
func (m *ExtensionHandlerRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_ExtensionHandlerRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_ExtensionHandlerRequest proto.InternalMessageInfo
|
||||
|
||||
func (m *ExtensionHandlerRequest) GetWrapper() *Wrapper {
|
||||
if m != nil {
|
||||
return m.Wrapper
|
||||
func (x *ExtensionHandlerRequest) GetWrapper() *Wrapper {
|
||||
if x != nil {
|
||||
return x.Wrapper
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ExtensionHandlerRequest) GetCompilerVersion() *Version {
|
||||
if m != nil {
|
||||
return m.CompilerVersion
|
||||
func (x *ExtensionHandlerRequest) GetCompilerVersion() *Version {
|
||||
if x != nil {
|
||||
return x.CompilerVersion
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// The extensions writes an encoded ExtensionHandlerResponse to stdout.
|
||||
type ExtensionHandlerResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// true if the extension is handled by the extension handler; false otherwise
|
||||
Handled bool `protobuf:"varint,1,opt,name=handled,proto3" json:"handled,omitempty"`
|
||||
// Error message. If non-empty, the extension handling failed.
|
||||
// Error message(s). If non-empty, the extension handling failed.
|
||||
// The extension handler process should exit with status code zero
|
||||
// even if it reports an error in this way.
|
||||
//
|
||||
|
|
@ -151,150 +189,277 @@ type ExtensionHandlerResponse struct {
|
|||
// itself -- such as the input Document being unparseable -- should be
|
||||
// reported by writing a message to stderr and exiting with a non-zero
|
||||
// status code.
|
||||
Error []string `protobuf:"bytes,2,rep,name=error,proto3" json:"error,omitempty"`
|
||||
Errors []string `protobuf:"bytes,2,rep,name=errors,proto3" json:"errors,omitempty"`
|
||||
// text output
|
||||
Value *any.Any `protobuf:"bytes,3,opt,name=value,proto3" json:"value,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
Value *any.Any `protobuf:"bytes,3,opt,name=value,proto3" json:"value,omitempty"`
|
||||
}
|
||||
|
||||
func (m *ExtensionHandlerResponse) Reset() { *m = ExtensionHandlerResponse{} }
|
||||
func (m *ExtensionHandlerResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*ExtensionHandlerResponse) ProtoMessage() {}
|
||||
func (x *ExtensionHandlerResponse) Reset() {
|
||||
*x = ExtensionHandlerResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_extensions_extension_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ExtensionHandlerResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ExtensionHandlerResponse) ProtoMessage() {}
|
||||
|
||||
func (x *ExtensionHandlerResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_extensions_extension_proto_msgTypes[2]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ExtensionHandlerResponse.ProtoReflect.Descriptor instead.
|
||||
func (*ExtensionHandlerResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_661e47e790f76671, []int{2}
|
||||
return file_extensions_extension_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (m *ExtensionHandlerResponse) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_ExtensionHandlerResponse.Unmarshal(m, b)
|
||||
}
|
||||
func (m *ExtensionHandlerResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_ExtensionHandlerResponse.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *ExtensionHandlerResponse) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_ExtensionHandlerResponse.Merge(m, src)
|
||||
}
|
||||
func (m *ExtensionHandlerResponse) XXX_Size() int {
|
||||
return xxx_messageInfo_ExtensionHandlerResponse.Size(m)
|
||||
}
|
||||
func (m *ExtensionHandlerResponse) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_ExtensionHandlerResponse.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_ExtensionHandlerResponse proto.InternalMessageInfo
|
||||
|
||||
func (m *ExtensionHandlerResponse) GetHandled() bool {
|
||||
if m != nil {
|
||||
return m.Handled
|
||||
func (x *ExtensionHandlerResponse) GetHandled() bool {
|
||||
if x != nil {
|
||||
return x.Handled
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (m *ExtensionHandlerResponse) GetError() []string {
|
||||
if m != nil {
|
||||
return m.Error
|
||||
func (x *ExtensionHandlerResponse) GetErrors() []string {
|
||||
if x != nil {
|
||||
return x.Errors
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ExtensionHandlerResponse) GetValue() *any.Any {
|
||||
if m != nil {
|
||||
return m.Value
|
||||
func (x *ExtensionHandlerResponse) GetValue() *any.Any {
|
||||
if x != nil {
|
||||
return x.Value
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Wrapper struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// version of the OpenAPI specification in which this extension was written.
|
||||
Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"`
|
||||
// Name of the extension
|
||||
// Name of the extension.
|
||||
ExtensionName string `protobuf:"bytes,2,opt,name=extension_name,json=extensionName,proto3" json:"extension_name,omitempty"`
|
||||
// Must be a valid yaml for the proto
|
||||
Yaml string `protobuf:"bytes,3,opt,name=yaml,proto3" json:"yaml,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
// YAML-formatted extension value.
|
||||
Yaml string `protobuf:"bytes,3,opt,name=yaml,proto3" json:"yaml,omitempty"`
|
||||
}
|
||||
|
||||
func (m *Wrapper) Reset() { *m = Wrapper{} }
|
||||
func (m *Wrapper) String() string { return proto.CompactTextString(m) }
|
||||
func (*Wrapper) ProtoMessage() {}
|
||||
func (x *Wrapper) Reset() {
|
||||
*x = Wrapper{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_extensions_extension_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Wrapper) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Wrapper) ProtoMessage() {}
|
||||
|
||||
func (x *Wrapper) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_extensions_extension_proto_msgTypes[3]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Wrapper.ProtoReflect.Descriptor instead.
|
||||
func (*Wrapper) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_661e47e790f76671, []int{3}
|
||||
return file_extensions_extension_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
func (m *Wrapper) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_Wrapper.Unmarshal(m, b)
|
||||
}
|
||||
func (m *Wrapper) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_Wrapper.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *Wrapper) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_Wrapper.Merge(m, src)
|
||||
}
|
||||
func (m *Wrapper) XXX_Size() int {
|
||||
return xxx_messageInfo_Wrapper.Size(m)
|
||||
}
|
||||
func (m *Wrapper) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_Wrapper.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_Wrapper proto.InternalMessageInfo
|
||||
|
||||
func (m *Wrapper) GetVersion() string {
|
||||
if m != nil {
|
||||
return m.Version
|
||||
func (x *Wrapper) GetVersion() string {
|
||||
if x != nil {
|
||||
return x.Version
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Wrapper) GetExtensionName() string {
|
||||
if m != nil {
|
||||
return m.ExtensionName
|
||||
func (x *Wrapper) GetExtensionName() string {
|
||||
if x != nil {
|
||||
return x.ExtensionName
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Wrapper) GetYaml() string {
|
||||
if m != nil {
|
||||
return m.Yaml
|
||||
func (x *Wrapper) GetYaml() string {
|
||||
if x != nil {
|
||||
return x.Yaml
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*Version)(nil), "openapiextension.v1.Version")
|
||||
proto.RegisterType((*ExtensionHandlerRequest)(nil), "openapiextension.v1.ExtensionHandlerRequest")
|
||||
proto.RegisterType((*ExtensionHandlerResponse)(nil), "openapiextension.v1.ExtensionHandlerResponse")
|
||||
proto.RegisterType((*Wrapper)(nil), "openapiextension.v1.Wrapper")
|
||||
var File_extensions_extension_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_extensions_extension_proto_rawDesc = []byte{
|
||||
0x0a, 0x1a, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x65, 0x78, 0x74,
|
||||
0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x14, 0x67, 0x6e,
|
||||
0x6f, 0x73, 0x74, 0x69, 0x63, 0x2e, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x2e,
|
||||
0x76, 0x31, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x62, 0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x63, 0x0a,
|
||||
0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x61, 0x6a, 0x6f,
|
||||
0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x12, 0x14,
|
||||
0x0a, 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6d,
|
||||
0x69, 0x6e, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x18, 0x03, 0x20,
|
||||
0x01, 0x28, 0x05, 0x52, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x75,
|
||||
0x66, 0x66, 0x69, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x75, 0x66, 0x66,
|
||||
0x69, 0x78, 0x22, 0x9c, 0x01, 0x0a, 0x17, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e,
|
||||
0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x37,
|
||||
0x0a, 0x07, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
|
||||
0x1d, 0x2e, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x2e, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73,
|
||||
0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x52, 0x07,
|
||||
0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x12, 0x48, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x70, 0x69,
|
||||
0x6c, 0x65, 0x72, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x1d, 0x2e, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x2e, 0x65, 0x78, 0x74, 0x65,
|
||||
0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
|
||||
0x52, 0x0f, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f,
|
||||
0x6e, 0x22, 0x78, 0x0a, 0x18, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x48, 0x61,
|
||||
0x6e, 0x64, 0x6c, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a,
|
||||
0x07, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07,
|
||||
0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72,
|
||||
0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x12,
|
||||
0x2a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14,
|
||||
0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
|
||||
0x2e, 0x41, 0x6e, 0x79, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x5e, 0x0a, 0x07, 0x57,
|
||||
0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f,
|
||||
0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
|
||||
0x12, 0x25, 0x0a, 0x0e, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x61,
|
||||
0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73,
|
||||
0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x79, 0x61, 0x6d, 0x6c, 0x18,
|
||||
0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x79, 0x61, 0x6d, 0x6c, 0x42, 0x4b, 0x0a, 0x0e, 0x6f,
|
||||
0x72, 0x67, 0x2e, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x2e, 0x76, 0x31, 0x42, 0x10, 0x47,
|
||||
0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x50,
|
||||
0x01, 0x5a, 0x1f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x3b, 0x67, 0x6e,
|
||||
0x6f, 0x73, 0x74, 0x69, 0x63, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x5f,
|
||||
0x76, 0x31, 0xa2, 0x02, 0x03, 0x47, 0x4e, 0x58, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
func init() { proto.RegisterFile("extensions/extension.proto", fileDescriptor_661e47e790f76671) }
|
||||
var (
|
||||
file_extensions_extension_proto_rawDescOnce sync.Once
|
||||
file_extensions_extension_proto_rawDescData = file_extensions_extension_proto_rawDesc
|
||||
)
|
||||
|
||||
var fileDescriptor_661e47e790f76671 = []byte{
|
||||
// 362 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x91, 0x4d, 0x4b, 0xeb, 0x40,
|
||||
0x18, 0x85, 0x49, 0xbf, 0x72, 0x33, 0x97, 0xdb, 0x2b, 0x63, 0xd1, 0x58, 0x5c, 0x94, 0x80, 0x50,
|
||||
0x44, 0xa6, 0x54, 0xc1, 0x7d, 0x0b, 0x45, 0xdd, 0xd8, 0x32, 0x8b, 0xba, 0xb3, 0x4c, 0xd3, 0xb7,
|
||||
0x69, 0x24, 0x99, 0x19, 0x27, 0x1f, 0xb6, 0x7f, 0xc5, 0xa5, 0xbf, 0x54, 0x32, 0x93, 0xc4, 0x85,
|
||||
0xba, 0x9b, 0xf3, 0x70, 0xda, 0xf7, 0x9c, 0x13, 0xd4, 0x87, 0x7d, 0x0a, 0x3c, 0x09, 0x05, 0x4f,
|
||||
0x46, 0xf5, 0x93, 0x48, 0x25, 0x52, 0x81, 0x8f, 0x85, 0x04, 0xce, 0x64, 0xf8, 0xc5, 0xf3, 0x71,
|
||||
0xff, 0x2c, 0x10, 0x22, 0x88, 0x60, 0xa4, 0x2d, 0xeb, 0x6c, 0x3b, 0x62, 0xfc, 0x60, 0xfc, 0x9e,
|
||||
0x8f, 0xec, 0x25, 0xa8, 0xc2, 0x88, 0x7b, 0xa8, 0x1d, 0xb3, 0x17, 0xa1, 0x5c, 0x6b, 0x60, 0x0d,
|
||||
0xdb, 0xd4, 0x08, 0x4d, 0x43, 0x2e, 0x94, 0xdb, 0x28, 0x69, 0x21, 0x0a, 0x2a, 0x59, 0xea, 0xef,
|
||||
0xdc, 0xa6, 0xa1, 0x5a, 0xe0, 0x13, 0xd4, 0x49, 0xb2, 0xed, 0x36, 0xdc, 0xbb, 0xad, 0x81, 0x35,
|
||||
0x74, 0x68, 0xa9, 0xbc, 0x77, 0x0b, 0x9d, 0xce, 0xaa, 0x40, 0xf7, 0x8c, 0x6f, 0x22, 0x50, 0x14,
|
||||
0x5e, 0x33, 0x48, 0x52, 0x7c, 0x8b, 0xec, 0x37, 0xc5, 0xa4, 0x04, 0x73, 0xf7, 0xef, 0xf5, 0x39,
|
||||
0xf9, 0xa1, 0x02, 0x79, 0x32, 0x1e, 0x5a, 0x99, 0xf1, 0x1d, 0x3a, 0xf2, 0x45, 0x2c, 0xc3, 0x08,
|
||||
0xd4, 0x2a, 0x37, 0x0d, 0x74, 0x98, 0xdf, 0xfe, 0xa0, 0x6c, 0x49, 0xff, 0x57, 0xbf, 0x2a, 0x81,
|
||||
0x97, 0x23, 0xf7, 0x7b, 0xb6, 0x44, 0x0a, 0x9e, 0x00, 0x76, 0x91, 0xbd, 0xd3, 0x68, 0xa3, 0xc3,
|
||||
0xfd, 0xa1, 0x95, 0x2c, 0x06, 0x00, 0xa5, 0xf4, 0x2c, 0xcd, 0xa1, 0x43, 0x8d, 0xc0, 0x97, 0xa8,
|
||||
0x9d, 0xb3, 0x28, 0x83, 0x32, 0x49, 0x8f, 0x98, 0xe1, 0x49, 0x35, 0x3c, 0x99, 0xf0, 0x03, 0x35,
|
||||
0x16, 0xef, 0x19, 0xd9, 0x65, 0xa9, 0xe2, 0x4c, 0x55, 0xc1, 0xd2, 0xc3, 0x55, 0x12, 0x5f, 0xa0,
|
||||
0x6e, 0xdd, 0x62, 0xc5, 0x59, 0x0c, 0xfa, 0x33, 0x38, 0xf4, 0x5f, 0x4d, 0x1f, 0x59, 0x0c, 0x18,
|
||||
0xa3, 0xd6, 0x81, 0xc5, 0x91, 0x3e, 0xeb, 0x50, 0xfd, 0x9e, 0x5e, 0xa1, 0xae, 0x50, 0x01, 0x09,
|
||||
0xb8, 0x48, 0xd2, 0xd0, 0x27, 0xf9, 0x78, 0x8a, 0xe7, 0x12, 0xf8, 0x64, 0xf1, 0x50, 0xd7, 0x5d,
|
||||
0x8e, 0x17, 0xd6, 0x47, 0xa3, 0x39, 0x9f, 0xcc, 0xd6, 0x1d, 0x1d, 0xf1, 0xe6, 0x33, 0x00, 0x00,
|
||||
0xff, 0xff, 0xeb, 0xf3, 0xfa, 0x65, 0x5c, 0x02, 0x00, 0x00,
|
||||
func file_extensions_extension_proto_rawDescGZIP() []byte {
|
||||
file_extensions_extension_proto_rawDescOnce.Do(func() {
|
||||
file_extensions_extension_proto_rawDescData = protoimpl.X.CompressGZIP(file_extensions_extension_proto_rawDescData)
|
||||
})
|
||||
return file_extensions_extension_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_extensions_extension_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
|
||||
var file_extensions_extension_proto_goTypes = []interface{}{
|
||||
(*Version)(nil), // 0: gnostic.extension.v1.Version
|
||||
(*ExtensionHandlerRequest)(nil), // 1: gnostic.extension.v1.ExtensionHandlerRequest
|
||||
(*ExtensionHandlerResponse)(nil), // 2: gnostic.extension.v1.ExtensionHandlerResponse
|
||||
(*Wrapper)(nil), // 3: gnostic.extension.v1.Wrapper
|
||||
(*any.Any)(nil), // 4: google.protobuf.Any
|
||||
}
|
||||
var file_extensions_extension_proto_depIdxs = []int32{
|
||||
3, // 0: gnostic.extension.v1.ExtensionHandlerRequest.wrapper:type_name -> gnostic.extension.v1.Wrapper
|
||||
0, // 1: gnostic.extension.v1.ExtensionHandlerRequest.compiler_version:type_name -> gnostic.extension.v1.Version
|
||||
4, // 2: gnostic.extension.v1.ExtensionHandlerResponse.value:type_name -> google.protobuf.Any
|
||||
3, // [3:3] is the sub-list for method output_type
|
||||
3, // [3:3] is the sub-list for method input_type
|
||||
3, // [3:3] is the sub-list for extension type_name
|
||||
3, // [3:3] is the sub-list for extension extendee
|
||||
0, // [0:3] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_extensions_extension_proto_init() }
|
||||
func file_extensions_extension_proto_init() {
|
||||
if File_extensions_extension_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_extensions_extension_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Version); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_extensions_extension_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ExtensionHandlerRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_extensions_extension_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ExtensionHandlerResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_extensions_extension_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Wrapper); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_extensions_extension_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 4,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_extensions_extension_proto_goTypes,
|
||||
DependencyIndexes: file_extensions_extension_proto_depIdxs,
|
||||
MessageInfos: file_extensions_extension_proto_msgTypes,
|
||||
}.Build()
|
||||
File_extensions_extension_proto = out.File
|
||||
file_extensions_extension_proto_rawDesc = nil
|
||||
file_extensions_extension_proto_goTypes = nil
|
||||
file_extensions_extension_proto_depIdxs = nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
// Copyright 2017 Google LLC. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
|
@ -14,8 +14,9 @@
|
|||
|
||||
syntax = "proto3";
|
||||
|
||||
package gnostic.extension.v1;
|
||||
|
||||
import "google/protobuf/any.proto";
|
||||
package openapiextension.v1;
|
||||
|
||||
// This option lets the proto compiler generate Java code inside the package
|
||||
// name (see below) instead of inside an outer class. It creates a simpler
|
||||
|
|
@ -26,7 +27,7 @@ option java_multiple_files = true;
|
|||
// The Java outer classname should be the filename in UpperCamelCase. This
|
||||
// class is only used to hold proto descriptor, so developers don't need to
|
||||
// work with it directly.
|
||||
option java_outer_classname = "OpenAPIExtensionV1";
|
||||
option java_outer_classname = "GnosticExtension";
|
||||
|
||||
// The Java package name must be proto package name with proper prefix.
|
||||
option java_package = "org.gnostic.v1";
|
||||
|
|
@ -37,9 +38,12 @@ option java_package = "org.gnostic.v1";
|
|||
// hopefully unique enough to not conflict with things that may come along in
|
||||
// the future. 'GPB' is reserved for the protocol buffer implementation itself.
|
||||
//
|
||||
option objc_class_prefix = "OAE"; // "OpenAPI Extension"
|
||||
option objc_class_prefix = "GNX"; // "Gnostic Extension"
|
||||
|
||||
// The version number of OpenAPI compiler.
|
||||
// The Go package name.
|
||||
option go_package = "extensions;gnostic_extension_v1";
|
||||
|
||||
// The version number of Gnostic.
|
||||
message Version {
|
||||
int32 major = 1;
|
||||
int32 minor = 2;
|
||||
|
|
@ -52,12 +56,11 @@ message Version {
|
|||
// An encoded Request is written to the ExtensionHandler's stdin.
|
||||
message ExtensionHandlerRequest {
|
||||
|
||||
// The OpenAPI descriptions that were explicitly listed on the command line.
|
||||
// The specifications will appear in the order they are specified to gnostic.
|
||||
// The extension to process.
|
||||
Wrapper wrapper = 1;
|
||||
|
||||
// The version number of openapi compiler.
|
||||
Version compiler_version = 3;
|
||||
// The version number of Gnostic.
|
||||
Version compiler_version = 2;
|
||||
}
|
||||
|
||||
// The extensions writes an encoded ExtensionHandlerResponse to stdout.
|
||||
|
|
@ -66,7 +69,7 @@ message ExtensionHandlerResponse {
|
|||
// true if the extension is handled by the extension handler; false otherwise
|
||||
bool handled = 1;
|
||||
|
||||
// Error message. If non-empty, the extension handling failed.
|
||||
// Error message(s). If non-empty, the extension handling failed.
|
||||
// The extension handler process should exit with status code zero
|
||||
// even if it reports an error in this way.
|
||||
//
|
||||
|
|
@ -75,7 +78,7 @@ message ExtensionHandlerResponse {
|
|||
// itself -- such as the input Document being unparseable -- should be
|
||||
// reported by writing a message to stderr and exiting with a non-zero
|
||||
// status code.
|
||||
repeated string error = 2;
|
||||
repeated string errors = 2;
|
||||
|
||||
// text output
|
||||
google.protobuf.Any value = 3;
|
||||
|
|
@ -85,9 +88,9 @@ message Wrapper {
|
|||
// version of the OpenAPI specification in which this extension was written.
|
||||
string version = 1;
|
||||
|
||||
// Name of the extension
|
||||
// Name of the extension.
|
||||
string extension_name = 2;
|
||||
|
||||
// Must be a valid yaml for the proto
|
||||
// YAML-formatted extension value.
|
||||
string yaml = 3;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
// Copyright 2017 Google LLC. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
|
@ -12,71 +12,53 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package openapiextension_v1
|
||||
package gnostic_extension_v1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/golang/protobuf/ptypes"
|
||||
)
|
||||
|
||||
type documentHandler func(version string, extensionName string, document string)
|
||||
type extensionHandler func(name string, yamlInput string) (bool, proto.Message, error)
|
||||
|
||||
func forInputYamlFromOpenapic(handler documentHandler) {
|
||||
// Main implements the main program of an extension handler.
|
||||
func Main(handler extensionHandler) {
|
||||
// unpack the request
|
||||
data, err := ioutil.ReadAll(os.Stdin)
|
||||
if err != nil {
|
||||
fmt.Println("File error:", err.Error())
|
||||
log.Println("File error:", err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
if len(data) == 0 {
|
||||
fmt.Println("No input data.")
|
||||
log.Println("No input data.")
|
||||
os.Exit(1)
|
||||
}
|
||||
request := &ExtensionHandlerRequest{}
|
||||
err = proto.Unmarshal(data, request)
|
||||
if err != nil {
|
||||
fmt.Println("Input error:", err.Error())
|
||||
log.Println("Input error:", err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
handler(request.Wrapper.Version, request.Wrapper.ExtensionName, request.Wrapper.Yaml)
|
||||
}
|
||||
|
||||
// ProcessExtension calles the handler for a specified extension.
|
||||
func ProcessExtension(handleExtension extensionHandler) {
|
||||
response := &ExtensionHandlerResponse{}
|
||||
forInputYamlFromOpenapic(
|
||||
func(version string, extensionName string, yamlInput string) {
|
||||
var newObject proto.Message
|
||||
var err error
|
||||
|
||||
handled, newObject, err := handleExtension(extensionName, yamlInput)
|
||||
if !handled {
|
||||
responseBytes, _ := proto.Marshal(response)
|
||||
os.Stdout.Write(responseBytes)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
// If we reach here, then the extension is handled
|
||||
response.Handled = true
|
||||
if err != nil {
|
||||
response.Error = append(response.Error, err.Error())
|
||||
responseBytes, _ := proto.Marshal(response)
|
||||
os.Stdout.Write(responseBytes)
|
||||
os.Exit(0)
|
||||
}
|
||||
response.Value, err = ptypes.MarshalAny(newObject)
|
||||
if err != nil {
|
||||
response.Error = append(response.Error, err.Error())
|
||||
responseBytes, _ := proto.Marshal(response)
|
||||
os.Stdout.Write(responseBytes)
|
||||
os.Exit(0)
|
||||
}
|
||||
})
|
||||
|
||||
// call the handler
|
||||
handled, output, err := handler(request.Wrapper.ExtensionName, request.Wrapper.Yaml)
|
||||
// respond with the output of the handler
|
||||
response := &ExtensionHandlerResponse{
|
||||
Handled: false, // default assumption
|
||||
Errors: make([]string, 0),
|
||||
}
|
||||
if err != nil {
|
||||
response.Errors = append(response.Errors, err.Error())
|
||||
} else if handled {
|
||||
response.Handled = true
|
||||
response.Value, err = ptypes.MarshalAny(output)
|
||||
if err != nil {
|
||||
response.Errors = append(response.Errors, err.Error())
|
||||
}
|
||||
}
|
||||
responseBytes, _ := proto.Marshal(response)
|
||||
os.Stdout.Write(responseBytes)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
# jsonschema
|
||||
|
||||
This directory contains code for reading, writing, and manipulating JSON
|
||||
schemas.
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
|
||||
// THIS FILE IS AUTOMATICALLY GENERATED.
|
||||
|
||||
package jsonschema
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
)
|
||||
|
||||
func baseSchemaBytes() ([]byte, error){
|
||||
return base64.StdEncoding.DecodeString(
|
||||
`ewogICAgImlkIjogImh0dHA6Ly9qc29uLXNjaGVtYS5vcmcvZHJhZnQtMDQvc2NoZW1hIyIsCiAgICAi
|
||||
JHNjaGVtYSI6ICJodHRwOi8vanNvbi1zY2hlbWEub3JnL2RyYWZ0LTA0L3NjaGVtYSMiLAogICAgImRl
|
||||
c2NyaXB0aW9uIjogIkNvcmUgc2NoZW1hIG1ldGEtc2NoZW1hIiwKICAgICJkZWZpbml0aW9ucyI6IHsK
|
||||
ICAgICAgICAic2NoZW1hQXJyYXkiOiB7CiAgICAgICAgICAgICJ0eXBlIjogImFycmF5IiwKICAgICAg
|
||||
ICAgICAgIm1pbkl0ZW1zIjogMSwKICAgICAgICAgICAgIml0ZW1zIjogeyAiJHJlZiI6ICIjIiB9CiAg
|
||||
ICAgICAgfSwKICAgICAgICAicG9zaXRpdmVJbnRlZ2VyIjogewogICAgICAgICAgICAidHlwZSI6ICJp
|
||||
bnRlZ2VyIiwKICAgICAgICAgICAgIm1pbmltdW0iOiAwCiAgICAgICAgfSwKICAgICAgICAicG9zaXRp
|
||||
dmVJbnRlZ2VyRGVmYXVsdDAiOiB7CiAgICAgICAgICAgICJhbGxPZiI6IFsgeyAiJHJlZiI6ICIjL2Rl
|
||||
ZmluaXRpb25zL3Bvc2l0aXZlSW50ZWdlciIgfSwgeyAiZGVmYXVsdCI6IDAgfSBdCiAgICAgICAgfSwK
|
||||
ICAgICAgICAic2ltcGxlVHlwZXMiOiB7CiAgICAgICAgICAgICJlbnVtIjogWyAiYXJyYXkiLCAiYm9v
|
||||
bGVhbiIsICJpbnRlZ2VyIiwgIm51bGwiLCAibnVtYmVyIiwgIm9iamVjdCIsICJzdHJpbmciIF0KICAg
|
||||
ICAgICB9LAogICAgICAgICJzdHJpbmdBcnJheSI6IHsKICAgICAgICAgICAgInR5cGUiOiAiYXJyYXki
|
||||
LAogICAgICAgICAgICAiaXRlbXMiOiB7ICJ0eXBlIjogInN0cmluZyIgfSwKICAgICAgICAgICAgIm1p
|
||||
bkl0ZW1zIjogMSwKICAgICAgICAgICAgInVuaXF1ZUl0ZW1zIjogdHJ1ZQogICAgICAgIH0KICAgIH0s
|
||||
CiAgICAidHlwZSI6ICJvYmplY3QiLAogICAgInByb3BlcnRpZXMiOiB7CiAgICAgICAgImlkIjogewog
|
||||
ICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICAgICAiZm9ybWF0IjogInVyaSIKICAg
|
||||
ICAgICB9LAogICAgICAgICIkc2NoZW1hIjogewogICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciLAog
|
||||
ICAgICAgICAgICAiZm9ybWF0IjogInVyaSIKICAgICAgICB9LAogICAgICAgICJ0aXRsZSI6IHsKICAg
|
||||
ICAgICAgICAgInR5cGUiOiAic3RyaW5nIgogICAgICAgIH0sCiAgICAgICAgImRlc2NyaXB0aW9uIjog
|
||||
ewogICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciCiAgICAgICAgfSwKICAgICAgICAiZGVmYXVsdCI6
|
||||
IHt9LAogICAgICAgICJtdWx0aXBsZU9mIjogewogICAgICAgICAgICAidHlwZSI6ICJudW1iZXIiLAog
|
||||
ICAgICAgICAgICAibWluaW11bSI6IDAsCiAgICAgICAgICAgICJleGNsdXNpdmVNaW5pbXVtIjogdHJ1
|
||||
ZQogICAgICAgIH0sCiAgICAgICAgIm1heGltdW0iOiB7CiAgICAgICAgICAgICJ0eXBlIjogIm51bWJl
|
||||
ciIKICAgICAgICB9LAogICAgICAgICJleGNsdXNpdmVNYXhpbXVtIjogewogICAgICAgICAgICAidHlw
|
||||
ZSI6ICJib29sZWFuIiwKICAgICAgICAgICAgImRlZmF1bHQiOiBmYWxzZQogICAgICAgIH0sCiAgICAg
|
||||
ICAgIm1pbmltdW0iOiB7CiAgICAgICAgICAgICJ0eXBlIjogIm51bWJlciIKICAgICAgICB9LAogICAg
|
||||
ICAgICJleGNsdXNpdmVNaW5pbXVtIjogewogICAgICAgICAgICAidHlwZSI6ICJib29sZWFuIiwKICAg
|
||||
ICAgICAgICAgImRlZmF1bHQiOiBmYWxzZQogICAgICAgIH0sCiAgICAgICAgIm1heExlbmd0aCI6IHsg
|
||||
IiRyZWYiOiAiIy9kZWZpbml0aW9ucy9wb3NpdGl2ZUludGVnZXIiIH0sCiAgICAgICAgIm1pbkxlbmd0
|
||||
aCI6IHsgIiRyZWYiOiAiIy9kZWZpbml0aW9ucy9wb3NpdGl2ZUludGVnZXJEZWZhdWx0MCIgfSwKICAg
|
||||
ICAgICAicGF0dGVybiI6IHsKICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIiwKICAgICAgICAgICAg
|
||||
ImZvcm1hdCI6ICJyZWdleCIKICAgICAgICB9LAogICAgICAgICJhZGRpdGlvbmFsSXRlbXMiOiB7CiAg
|
||||
ICAgICAgICAgICJhbnlPZiI6IFsKICAgICAgICAgICAgICAgIHsgInR5cGUiOiAiYm9vbGVhbiIgfSwK
|
||||
ICAgICAgICAgICAgICAgIHsgIiRyZWYiOiAiIyIgfQogICAgICAgICAgICBdLAogICAgICAgICAgICAi
|
||||
ZGVmYXVsdCI6IHt9CiAgICAgICAgfSwKICAgICAgICAiaXRlbXMiOiB7CiAgICAgICAgICAgICJhbnlP
|
||||
ZiI6IFsKICAgICAgICAgICAgICAgIHsgIiRyZWYiOiAiIyIgfSwKICAgICAgICAgICAgICAgIHsgIiRy
|
||||
ZWYiOiAiIy9kZWZpbml0aW9ucy9zY2hlbWFBcnJheSIgfQogICAgICAgICAgICBdLAogICAgICAgICAg
|
||||
ICAiZGVmYXVsdCI6IHt9CiAgICAgICAgfSwKICAgICAgICAibWF4SXRlbXMiOiB7ICIkcmVmIjogIiMv
|
||||
ZGVmaW5pdGlvbnMvcG9zaXRpdmVJbnRlZ2VyIiB9LAogICAgICAgICJtaW5JdGVtcyI6IHsgIiRyZWYi
|
||||
OiAiIy9kZWZpbml0aW9ucy9wb3NpdGl2ZUludGVnZXJEZWZhdWx0MCIgfSwKICAgICAgICAidW5pcXVl
|
||||
SXRlbXMiOiB7CiAgICAgICAgICAgICJ0eXBlIjogImJvb2xlYW4iLAogICAgICAgICAgICAiZGVmYXVs
|
||||
dCI6IGZhbHNlCiAgICAgICAgfSwKICAgICAgICAibWF4UHJvcGVydGllcyI6IHsgIiRyZWYiOiAiIy9k
|
||||
ZWZpbml0aW9ucy9wb3NpdGl2ZUludGVnZXIiIH0sCiAgICAgICAgIm1pblByb3BlcnRpZXMiOiB7ICIk
|
||||
cmVmIjogIiMvZGVmaW5pdGlvbnMvcG9zaXRpdmVJbnRlZ2VyRGVmYXVsdDAiIH0sCiAgICAgICAgInJl
|
||||
cXVpcmVkIjogeyAiJHJlZiI6ICIjL2RlZmluaXRpb25zL3N0cmluZ0FycmF5IiB9LAogICAgICAgICJh
|
||||
ZGRpdGlvbmFsUHJvcGVydGllcyI6IHsKICAgICAgICAgICAgImFueU9mIjogWwogICAgICAgICAgICAg
|
||||
ICAgeyAidHlwZSI6ICJib29sZWFuIiB9LAogICAgICAgICAgICAgICAgeyAiJHJlZiI6ICIjIiB9CiAg
|
||||
ICAgICAgICAgIF0sCiAgICAgICAgICAgICJkZWZhdWx0Ijoge30KICAgICAgICB9LAogICAgICAgICJk
|
||||
ZWZpbml0aW9ucyI6IHsKICAgICAgICAgICAgInR5cGUiOiAib2JqZWN0IiwKICAgICAgICAgICAgImFk
|
||||
ZGl0aW9uYWxQcm9wZXJ0aWVzIjogeyAiJHJlZiI6ICIjIiB9LAogICAgICAgICAgICAiZGVmYXVsdCI6
|
||||
IHt9CiAgICAgICAgfSwKICAgICAgICAicHJvcGVydGllcyI6IHsKICAgICAgICAgICAgInR5cGUiOiAi
|
||||
b2JqZWN0IiwKICAgICAgICAgICAgImFkZGl0aW9uYWxQcm9wZXJ0aWVzIjogeyAiJHJlZiI6ICIjIiB9
|
||||
LAogICAgICAgICAgICAiZGVmYXVsdCI6IHt9CiAgICAgICAgfSwKICAgICAgICAicGF0dGVyblByb3Bl
|
||||
cnRpZXMiOiB7CiAgICAgICAgICAgICJ0eXBlIjogIm9iamVjdCIsCiAgICAgICAgICAgICJhZGRpdGlv
|
||||
bmFsUHJvcGVydGllcyI6IHsgIiRyZWYiOiAiIyIgfSwKICAgICAgICAgICAgImRlZmF1bHQiOiB7fQog
|
||||
ICAgICAgIH0sCiAgICAgICAgImRlcGVuZGVuY2llcyI6IHsKICAgICAgICAgICAgInR5cGUiOiAib2Jq
|
||||
ZWN0IiwKICAgICAgICAgICAgImFkZGl0aW9uYWxQcm9wZXJ0aWVzIjogewogICAgICAgICAgICAgICAg
|
||||
ImFueU9mIjogWwogICAgICAgICAgICAgICAgICAgIHsgIiRyZWYiOiAiIyIgfSwKICAgICAgICAgICAg
|
||||
ICAgICAgICB7ICIkcmVmIjogIiMvZGVmaW5pdGlvbnMvc3RyaW5nQXJyYXkiIH0KICAgICAgICAgICAg
|
||||
ICAgIF0KICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImVudW0iOiB7CiAgICAgICAgICAg
|
||||
ICJ0eXBlIjogImFycmF5IiwKICAgICAgICAgICAgIm1pbkl0ZW1zIjogMSwKICAgICAgICAgICAgInVu
|
||||
aXF1ZUl0ZW1zIjogdHJ1ZQogICAgICAgIH0sCiAgICAgICAgInR5cGUiOiB7CiAgICAgICAgICAgICJh
|
||||
bnlPZiI6IFsKICAgICAgICAgICAgICAgIHsgIiRyZWYiOiAiIy9kZWZpbml0aW9ucy9zaW1wbGVUeXBl
|
||||
cyIgfSwKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJhcnJheSIs
|
||||
CiAgICAgICAgICAgICAgICAgICAgIml0ZW1zIjogeyAiJHJlZiI6ICIjL2RlZmluaXRpb25zL3NpbXBs
|
||||
ZVR5cGVzIiB9LAogICAgICAgICAgICAgICAgICAgICJtaW5JdGVtcyI6IDEsCiAgICAgICAgICAgICAg
|
||||
ICAgICAgInVuaXF1ZUl0ZW1zIjogdHJ1ZQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICBdCiAg
|
||||
ICAgICAgfSwKICAgICAgICAiYWxsT2YiOiB7ICIkcmVmIjogIiMvZGVmaW5pdGlvbnMvc2NoZW1hQXJy
|
||||
YXkiIH0sCiAgICAgICAgImFueU9mIjogeyAiJHJlZiI6ICIjL2RlZmluaXRpb25zL3NjaGVtYUFycmF5
|
||||
IiB9LAogICAgICAgICJvbmVPZiI6IHsgIiRyZWYiOiAiIy9kZWZpbml0aW9ucy9zY2hlbWFBcnJheSIg
|
||||
fSwKICAgICAgICAibm90IjogeyAiJHJlZiI6ICIjIiB9CiAgICB9LAogICAgImRlcGVuZGVuY2llcyI6
|
||||
IHsKICAgICAgICAiZXhjbHVzaXZlTWF4aW11bSI6IFsgIm1heGltdW0iIF0sCiAgICAgICAgImV4Y2x1
|
||||
c2l2ZU1pbmltdW0iOiBbICJtaW5pbXVtIiBdCiAgICB9LAogICAgImRlZmF1bHQiOiB7fQp9Cg==`)}
|
||||
|
|
@ -0,0 +1,229 @@
|
|||
// Copyright 2017 Google LLC. All Rights Reserved.
|
||||
//
|
||||
// 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 jsonschema
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
//
|
||||
// DISPLAY
|
||||
// The following methods display Schemas.
|
||||
//
|
||||
|
||||
// Description returns a string representation of a string or string array.
|
||||
func (s *StringOrStringArray) Description() string {
|
||||
if s.String != nil {
|
||||
return *s.String
|
||||
}
|
||||
if s.StringArray != nil {
|
||||
return strings.Join(*s.StringArray, ", ")
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// Returns a string representation of a Schema.
|
||||
func (schema *Schema) String() string {
|
||||
return schema.describeSchema("")
|
||||
}
|
||||
|
||||
// Helper: Returns a string representation of a Schema indented by a specified string.
|
||||
func (schema *Schema) describeSchema(indent string) string {
|
||||
result := ""
|
||||
if schema.Schema != nil {
|
||||
result += indent + "$schema: " + *(schema.Schema) + "\n"
|
||||
}
|
||||
if schema.ID != nil {
|
||||
result += indent + "id: " + *(schema.ID) + "\n"
|
||||
}
|
||||
if schema.MultipleOf != nil {
|
||||
result += indent + fmt.Sprintf("multipleOf: %+v\n", *(schema.MultipleOf))
|
||||
}
|
||||
if schema.Maximum != nil {
|
||||
result += indent + fmt.Sprintf("maximum: %+v\n", *(schema.Maximum))
|
||||
}
|
||||
if schema.ExclusiveMaximum != nil {
|
||||
result += indent + fmt.Sprintf("exclusiveMaximum: %+v\n", *(schema.ExclusiveMaximum))
|
||||
}
|
||||
if schema.Minimum != nil {
|
||||
result += indent + fmt.Sprintf("minimum: %+v\n", *(schema.Minimum))
|
||||
}
|
||||
if schema.ExclusiveMinimum != nil {
|
||||
result += indent + fmt.Sprintf("exclusiveMinimum: %+v\n", *(schema.ExclusiveMinimum))
|
||||
}
|
||||
if schema.MaxLength != nil {
|
||||
result += indent + fmt.Sprintf("maxLength: %+v\n", *(schema.MaxLength))
|
||||
}
|
||||
if schema.MinLength != nil {
|
||||
result += indent + fmt.Sprintf("minLength: %+v\n", *(schema.MinLength))
|
||||
}
|
||||
if schema.Pattern != nil {
|
||||
result += indent + fmt.Sprintf("pattern: %+v\n", *(schema.Pattern))
|
||||
}
|
||||
if schema.AdditionalItems != nil {
|
||||
s := schema.AdditionalItems.Schema
|
||||
if s != nil {
|
||||
result += indent + "additionalItems:\n"
|
||||
result += s.describeSchema(indent + " ")
|
||||
} else {
|
||||
b := *(schema.AdditionalItems.Boolean)
|
||||
result += indent + fmt.Sprintf("additionalItems: %+v\n", b)
|
||||
}
|
||||
}
|
||||
if schema.Items != nil {
|
||||
result += indent + "items:\n"
|
||||
items := schema.Items
|
||||
if items.SchemaArray != nil {
|
||||
for i, s := range *(items.SchemaArray) {
|
||||
result += indent + " " + fmt.Sprintf("%d", i) + ":\n"
|
||||
result += s.describeSchema(indent + " " + " ")
|
||||
}
|
||||
} else if items.Schema != nil {
|
||||
result += items.Schema.describeSchema(indent + " " + " ")
|
||||
}
|
||||
}
|
||||
if schema.MaxItems != nil {
|
||||
result += indent + fmt.Sprintf("maxItems: %+v\n", *(schema.MaxItems))
|
||||
}
|
||||
if schema.MinItems != nil {
|
||||
result += indent + fmt.Sprintf("minItems: %+v\n", *(schema.MinItems))
|
||||
}
|
||||
if schema.UniqueItems != nil {
|
||||
result += indent + fmt.Sprintf("uniqueItems: %+v\n", *(schema.UniqueItems))
|
||||
}
|
||||
if schema.MaxProperties != nil {
|
||||
result += indent + fmt.Sprintf("maxProperties: %+v\n", *(schema.MaxProperties))
|
||||
}
|
||||
if schema.MinProperties != nil {
|
||||
result += indent + fmt.Sprintf("minProperties: %+v\n", *(schema.MinProperties))
|
||||
}
|
||||
if schema.Required != nil {
|
||||
result += indent + fmt.Sprintf("required: %+v\n", *(schema.Required))
|
||||
}
|
||||
if schema.AdditionalProperties != nil {
|
||||
s := schema.AdditionalProperties.Schema
|
||||
if s != nil {
|
||||
result += indent + "additionalProperties:\n"
|
||||
result += s.describeSchema(indent + " ")
|
||||
} else {
|
||||
b := *(schema.AdditionalProperties.Boolean)
|
||||
result += indent + fmt.Sprintf("additionalProperties: %+v\n", b)
|
||||
}
|
||||
}
|
||||
if schema.Properties != nil {
|
||||
result += indent + "properties:\n"
|
||||
for _, pair := range *(schema.Properties) {
|
||||
name := pair.Name
|
||||
s := pair.Value
|
||||
result += indent + " " + name + ":\n"
|
||||
result += s.describeSchema(indent + " " + " ")
|
||||
}
|
||||
}
|
||||
if schema.PatternProperties != nil {
|
||||
result += indent + "patternProperties:\n"
|
||||
for _, pair := range *(schema.PatternProperties) {
|
||||
name := pair.Name
|
||||
s := pair.Value
|
||||
result += indent + " " + name + ":\n"
|
||||
result += s.describeSchema(indent + " " + " ")
|
||||
}
|
||||
}
|
||||
if schema.Dependencies != nil {
|
||||
result += indent + "dependencies:\n"
|
||||
for _, pair := range *(schema.Dependencies) {
|
||||
name := pair.Name
|
||||
schemaOrStringArray := pair.Value
|
||||
s := schemaOrStringArray.Schema
|
||||
if s != nil {
|
||||
result += indent + " " + name + ":\n"
|
||||
result += s.describeSchema(indent + " " + " ")
|
||||
} else {
|
||||
a := schemaOrStringArray.StringArray
|
||||
if a != nil {
|
||||
result += indent + " " + name + ":\n"
|
||||
for _, s2 := range *a {
|
||||
result += indent + " " + " " + s2 + "\n"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if schema.Enumeration != nil {
|
||||
result += indent + "enumeration:\n"
|
||||
for _, value := range *(schema.Enumeration) {
|
||||
if value.String != nil {
|
||||
result += indent + " " + fmt.Sprintf("%+v\n", *value.String)
|
||||
} else {
|
||||
result += indent + " " + fmt.Sprintf("%+v\n", *value.Bool)
|
||||
}
|
||||
}
|
||||
}
|
||||
if schema.Type != nil {
|
||||
result += indent + fmt.Sprintf("type: %+v\n", schema.Type.Description())
|
||||
}
|
||||
if schema.AllOf != nil {
|
||||
result += indent + "allOf:\n"
|
||||
for _, s := range *(schema.AllOf) {
|
||||
result += s.describeSchema(indent + " ")
|
||||
result += indent + "-\n"
|
||||
}
|
||||
}
|
||||
if schema.AnyOf != nil {
|
||||
result += indent + "anyOf:\n"
|
||||
for _, s := range *(schema.AnyOf) {
|
||||
result += s.describeSchema(indent + " ")
|
||||
result += indent + "-\n"
|
||||
}
|
||||
}
|
||||
if schema.OneOf != nil {
|
||||
result += indent + "oneOf:\n"
|
||||
for _, s := range *(schema.OneOf) {
|
||||
result += s.describeSchema(indent + " ")
|
||||
result += indent + "-\n"
|
||||
}
|
||||
}
|
||||
if schema.Not != nil {
|
||||
result += indent + "not:\n"
|
||||
result += schema.Not.describeSchema(indent + " ")
|
||||
}
|
||||
if schema.Definitions != nil {
|
||||
result += indent + "definitions:\n"
|
||||
for _, pair := range *(schema.Definitions) {
|
||||
name := pair.Name
|
||||
s := pair.Value
|
||||
result += indent + " " + name + ":\n"
|
||||
result += s.describeSchema(indent + " " + " ")
|
||||
}
|
||||
}
|
||||
if schema.Title != nil {
|
||||
result += indent + "title: " + *(schema.Title) + "\n"
|
||||
}
|
||||
if schema.Description != nil {
|
||||
result += indent + "description: " + *(schema.Description) + "\n"
|
||||
}
|
||||
if schema.Default != nil {
|
||||
result += indent + "default:\n"
|
||||
result += indent + fmt.Sprintf(" %+v\n", *(schema.Default))
|
||||
}
|
||||
if schema.Format != nil {
|
||||
result += indent + "format: " + *(schema.Format) + "\n"
|
||||
}
|
||||
if schema.Ref != nil {
|
||||
result += indent + "$ref: " + *(schema.Ref) + "\n"
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
|
@ -0,0 +1,228 @@
|
|||
// Copyright 2017 Google LLC. All Rights Reserved.
|
||||
//
|
||||
// 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 jsonschema supports the reading, writing, and manipulation
|
||||
// of JSON Schemas.
|
||||
package jsonschema
|
||||
|
||||
import "gopkg.in/yaml.v3"
|
||||
|
||||
// The Schema struct models a JSON Schema and, because schemas are
|
||||
// defined hierarchically, contains many references to itself.
|
||||
// All fields are pointers and are nil if the associated values
|
||||
// are not specified.
|
||||
type Schema struct {
|
||||
Schema *string // $schema
|
||||
ID *string // id keyword used for $ref resolution scope
|
||||
Ref *string // $ref, i.e. JSON Pointers
|
||||
|
||||
// http://json-schema.org/latest/json-schema-validation.html
|
||||
// 5.1. Validation keywords for numeric instances (number and integer)
|
||||
MultipleOf *SchemaNumber
|
||||
Maximum *SchemaNumber
|
||||
ExclusiveMaximum *bool
|
||||
Minimum *SchemaNumber
|
||||
ExclusiveMinimum *bool
|
||||
|
||||
// 5.2. Validation keywords for strings
|
||||
MaxLength *int64
|
||||
MinLength *int64
|
||||
Pattern *string
|
||||
|
||||
// 5.3. Validation keywords for arrays
|
||||
AdditionalItems *SchemaOrBoolean
|
||||
Items *SchemaOrSchemaArray
|
||||
MaxItems *int64
|
||||
MinItems *int64
|
||||
UniqueItems *bool
|
||||
|
||||
// 5.4. Validation keywords for objects
|
||||
MaxProperties *int64
|
||||
MinProperties *int64
|
||||
Required *[]string
|
||||
AdditionalProperties *SchemaOrBoolean
|
||||
Properties *[]*NamedSchema
|
||||
PatternProperties *[]*NamedSchema
|
||||
Dependencies *[]*NamedSchemaOrStringArray
|
||||
|
||||
// 5.5. Validation keywords for any instance type
|
||||
Enumeration *[]SchemaEnumValue
|
||||
Type *StringOrStringArray
|
||||
AllOf *[]*Schema
|
||||
AnyOf *[]*Schema
|
||||
OneOf *[]*Schema
|
||||
Not *Schema
|
||||
Definitions *[]*NamedSchema
|
||||
|
||||
// 6. Metadata keywords
|
||||
Title *string
|
||||
Description *string
|
||||
Default *yaml.Node
|
||||
|
||||
// 7. Semantic validation with "format"
|
||||
Format *string
|
||||
}
|
||||
|
||||
// These helper structs represent "combination" types that generally can
|
||||
// have values of one type or another. All are used to represent parts
|
||||
// of Schemas.
|
||||
|
||||
// SchemaNumber represents a value that can be either an Integer or a Float.
|
||||
type SchemaNumber struct {
|
||||
Integer *int64
|
||||
Float *float64
|
||||
}
|
||||
|
||||
// NewSchemaNumberWithInteger creates and returns a new object
|
||||
func NewSchemaNumberWithInteger(i int64) *SchemaNumber {
|
||||
result := &SchemaNumber{}
|
||||
result.Integer = &i
|
||||
return result
|
||||
}
|
||||
|
||||
// NewSchemaNumberWithFloat creates and returns a new object
|
||||
func NewSchemaNumberWithFloat(f float64) *SchemaNumber {
|
||||
result := &SchemaNumber{}
|
||||
result.Float = &f
|
||||
return result
|
||||
}
|
||||
|
||||
// SchemaOrBoolean represents a value that can be either a Schema or a Boolean.
|
||||
type SchemaOrBoolean struct {
|
||||
Schema *Schema
|
||||
Boolean *bool
|
||||
}
|
||||
|
||||
// NewSchemaOrBooleanWithSchema creates and returns a new object
|
||||
func NewSchemaOrBooleanWithSchema(s *Schema) *SchemaOrBoolean {
|
||||
result := &SchemaOrBoolean{}
|
||||
result.Schema = s
|
||||
return result
|
||||
}
|
||||
|
||||
// NewSchemaOrBooleanWithBoolean creates and returns a new object
|
||||
func NewSchemaOrBooleanWithBoolean(b bool) *SchemaOrBoolean {
|
||||
result := &SchemaOrBoolean{}
|
||||
result.Boolean = &b
|
||||
return result
|
||||
}
|
||||
|
||||
// StringOrStringArray represents a value that can be either
|
||||
// a String or an Array of Strings.
|
||||
type StringOrStringArray struct {
|
||||
String *string
|
||||
StringArray *[]string
|
||||
}
|
||||
|
||||
// NewStringOrStringArrayWithString creates and returns a new object
|
||||
func NewStringOrStringArrayWithString(s string) *StringOrStringArray {
|
||||
result := &StringOrStringArray{}
|
||||
result.String = &s
|
||||
return result
|
||||
}
|
||||
|
||||
// NewStringOrStringArrayWithStringArray creates and returns a new object
|
||||
func NewStringOrStringArrayWithStringArray(a []string) *StringOrStringArray {
|
||||
result := &StringOrStringArray{}
|
||||
result.StringArray = &a
|
||||
return result
|
||||
}
|
||||
|
||||
// SchemaOrStringArray represents a value that can be either
|
||||
// a Schema or an Array of Strings.
|
||||
type SchemaOrStringArray struct {
|
||||
Schema *Schema
|
||||
StringArray *[]string
|
||||
}
|
||||
|
||||
// SchemaOrSchemaArray represents a value that can be either
|
||||
// a Schema or an Array of Schemas.
|
||||
type SchemaOrSchemaArray struct {
|
||||
Schema *Schema
|
||||
SchemaArray *[]*Schema
|
||||
}
|
||||
|
||||
// NewSchemaOrSchemaArrayWithSchema creates and returns a new object
|
||||
func NewSchemaOrSchemaArrayWithSchema(s *Schema) *SchemaOrSchemaArray {
|
||||
result := &SchemaOrSchemaArray{}
|
||||
result.Schema = s
|
||||
return result
|
||||
}
|
||||
|
||||
// NewSchemaOrSchemaArrayWithSchemaArray creates and returns a new object
|
||||
func NewSchemaOrSchemaArrayWithSchemaArray(a []*Schema) *SchemaOrSchemaArray {
|
||||
result := &SchemaOrSchemaArray{}
|
||||
result.SchemaArray = &a
|
||||
return result
|
||||
}
|
||||
|
||||
// SchemaEnumValue represents a value that can be part of an
|
||||
// enumeration in a Schema.
|
||||
type SchemaEnumValue struct {
|
||||
String *string
|
||||
Bool *bool
|
||||
}
|
||||
|
||||
// NamedSchema is a name-value pair that is used to emulate maps
|
||||
// with ordered keys.
|
||||
type NamedSchema struct {
|
||||
Name string
|
||||
Value *Schema
|
||||
}
|
||||
|
||||
// NewNamedSchema creates and returns a new object
|
||||
func NewNamedSchema(name string, value *Schema) *NamedSchema {
|
||||
return &NamedSchema{Name: name, Value: value}
|
||||
}
|
||||
|
||||
// NamedSchemaOrStringArray is a name-value pair that is used
|
||||
// to emulate maps with ordered keys.
|
||||
type NamedSchemaOrStringArray struct {
|
||||
Name string
|
||||
Value *SchemaOrStringArray
|
||||
}
|
||||
|
||||
// Access named subschemas by name
|
||||
|
||||
func namedSchemaArrayElementWithName(array *[]*NamedSchema, name string) *Schema {
|
||||
if array == nil {
|
||||
return nil
|
||||
}
|
||||
for _, pair := range *array {
|
||||
if pair.Name == name {
|
||||
return pair.Value
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// PropertyWithName returns the selected element.
|
||||
func (s *Schema) PropertyWithName(name string) *Schema {
|
||||
return namedSchemaArrayElementWithName(s.Properties, name)
|
||||
}
|
||||
|
||||
// PatternPropertyWithName returns the selected element.
|
||||
func (s *Schema) PatternPropertyWithName(name string) *Schema {
|
||||
return namedSchemaArrayElementWithName(s.PatternProperties, name)
|
||||
}
|
||||
|
||||
// DefinitionWithName returns the selected element.
|
||||
func (s *Schema) DefinitionWithName(name string) *Schema {
|
||||
return namedSchemaArrayElementWithName(s.Definitions, name)
|
||||
}
|
||||
|
||||
// AddProperty adds a named property.
|
||||
func (s *Schema) AddProperty(name string, property *Schema) {
|
||||
*s.Properties = append(*s.Properties, NewNamedSchema(name, property))
|
||||
}
|
||||
|
|
@ -0,0 +1,394 @@
|
|||
// Copyright 2017 Google LLC. All Rights Reserved.
|
||||
//
|
||||
// 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 jsonschema
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
)
|
||||
|
||||
//
|
||||
// OPERATIONS
|
||||
// The following methods perform operations on Schemas.
|
||||
//
|
||||
|
||||
// IsEmpty returns true if no members of the Schema are specified.
|
||||
func (schema *Schema) IsEmpty() bool {
|
||||
return (schema.Schema == nil) &&
|
||||
(schema.ID == nil) &&
|
||||
(schema.MultipleOf == nil) &&
|
||||
(schema.Maximum == nil) &&
|
||||
(schema.ExclusiveMaximum == nil) &&
|
||||
(schema.Minimum == nil) &&
|
||||
(schema.ExclusiveMinimum == nil) &&
|
||||
(schema.MaxLength == nil) &&
|
||||
(schema.MinLength == nil) &&
|
||||
(schema.Pattern == nil) &&
|
||||
(schema.AdditionalItems == nil) &&
|
||||
(schema.Items == nil) &&
|
||||
(schema.MaxItems == nil) &&
|
||||
(schema.MinItems == nil) &&
|
||||
(schema.UniqueItems == nil) &&
|
||||
(schema.MaxProperties == nil) &&
|
||||
(schema.MinProperties == nil) &&
|
||||
(schema.Required == nil) &&
|
||||
(schema.AdditionalProperties == nil) &&
|
||||
(schema.Properties == nil) &&
|
||||
(schema.PatternProperties == nil) &&
|
||||
(schema.Dependencies == nil) &&
|
||||
(schema.Enumeration == nil) &&
|
||||
(schema.Type == nil) &&
|
||||
(schema.AllOf == nil) &&
|
||||
(schema.AnyOf == nil) &&
|
||||
(schema.OneOf == nil) &&
|
||||
(schema.Not == nil) &&
|
||||
(schema.Definitions == nil) &&
|
||||
(schema.Title == nil) &&
|
||||
(schema.Description == nil) &&
|
||||
(schema.Default == nil) &&
|
||||
(schema.Format == nil) &&
|
||||
(schema.Ref == nil)
|
||||
}
|
||||
|
||||
// IsEqual returns true if two schemas are equal.
|
||||
func (schema *Schema) IsEqual(schema2 *Schema) bool {
|
||||
return schema.String() == schema2.String()
|
||||
}
|
||||
|
||||
// SchemaOperation represents a function that can be applied to a Schema.
|
||||
type SchemaOperation func(schema *Schema, context string)
|
||||
|
||||
// Applies a specified function to a Schema and all of the Schemas that it contains.
|
||||
func (schema *Schema) applyToSchemas(operation SchemaOperation, context string) {
|
||||
|
||||
if schema.AdditionalItems != nil {
|
||||
s := schema.AdditionalItems.Schema
|
||||
if s != nil {
|
||||
s.applyToSchemas(operation, "AdditionalItems")
|
||||
}
|
||||
}
|
||||
|
||||
if schema.Items != nil {
|
||||
if schema.Items.SchemaArray != nil {
|
||||
for _, s := range *(schema.Items.SchemaArray) {
|
||||
s.applyToSchemas(operation, "Items.SchemaArray")
|
||||
}
|
||||
} else if schema.Items.Schema != nil {
|
||||
schema.Items.Schema.applyToSchemas(operation, "Items.Schema")
|
||||
}
|
||||
}
|
||||
|
||||
if schema.AdditionalProperties != nil {
|
||||
s := schema.AdditionalProperties.Schema
|
||||
if s != nil {
|
||||
s.applyToSchemas(operation, "AdditionalProperties")
|
||||
}
|
||||
}
|
||||
|
||||
if schema.Properties != nil {
|
||||
for _, pair := range *(schema.Properties) {
|
||||
s := pair.Value
|
||||
s.applyToSchemas(operation, "Properties")
|
||||
}
|
||||
}
|
||||
if schema.PatternProperties != nil {
|
||||
for _, pair := range *(schema.PatternProperties) {
|
||||
s := pair.Value
|
||||
s.applyToSchemas(operation, "PatternProperties")
|
||||
}
|
||||
}
|
||||
|
||||
if schema.Dependencies != nil {
|
||||
for _, pair := range *(schema.Dependencies) {
|
||||
schemaOrStringArray := pair.Value
|
||||
s := schemaOrStringArray.Schema
|
||||
if s != nil {
|
||||
s.applyToSchemas(operation, "Dependencies")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if schema.AllOf != nil {
|
||||
for _, s := range *(schema.AllOf) {
|
||||
s.applyToSchemas(operation, "AllOf")
|
||||
}
|
||||
}
|
||||
if schema.AnyOf != nil {
|
||||
for _, s := range *(schema.AnyOf) {
|
||||
s.applyToSchemas(operation, "AnyOf")
|
||||
}
|
||||
}
|
||||
if schema.OneOf != nil {
|
||||
for _, s := range *(schema.OneOf) {
|
||||
s.applyToSchemas(operation, "OneOf")
|
||||
}
|
||||
}
|
||||
if schema.Not != nil {
|
||||
schema.Not.applyToSchemas(operation, "Not")
|
||||
}
|
||||
|
||||
if schema.Definitions != nil {
|
||||
for _, pair := range *(schema.Definitions) {
|
||||
s := pair.Value
|
||||
s.applyToSchemas(operation, "Definitions")
|
||||
}
|
||||
}
|
||||
|
||||
operation(schema, context)
|
||||
}
|
||||
|
||||
// CopyProperties copies all non-nil properties from the source Schema to the schema Schema.
|
||||
func (schema *Schema) CopyProperties(source *Schema) {
|
||||
if source.Schema != nil {
|
||||
schema.Schema = source.Schema
|
||||
}
|
||||
if source.ID != nil {
|
||||
schema.ID = source.ID
|
||||
}
|
||||
if source.MultipleOf != nil {
|
||||
schema.MultipleOf = source.MultipleOf
|
||||
}
|
||||
if source.Maximum != nil {
|
||||
schema.Maximum = source.Maximum
|
||||
}
|
||||
if source.ExclusiveMaximum != nil {
|
||||
schema.ExclusiveMaximum = source.ExclusiveMaximum
|
||||
}
|
||||
if source.Minimum != nil {
|
||||
schema.Minimum = source.Minimum
|
||||
}
|
||||
if source.ExclusiveMinimum != nil {
|
||||
schema.ExclusiveMinimum = source.ExclusiveMinimum
|
||||
}
|
||||
if source.MaxLength != nil {
|
||||
schema.MaxLength = source.MaxLength
|
||||
}
|
||||
if source.MinLength != nil {
|
||||
schema.MinLength = source.MinLength
|
||||
}
|
||||
if source.Pattern != nil {
|
||||
schema.Pattern = source.Pattern
|
||||
}
|
||||
if source.AdditionalItems != nil {
|
||||
schema.AdditionalItems = source.AdditionalItems
|
||||
}
|
||||
if source.Items != nil {
|
||||
schema.Items = source.Items
|
||||
}
|
||||
if source.MaxItems != nil {
|
||||
schema.MaxItems = source.MaxItems
|
||||
}
|
||||
if source.MinItems != nil {
|
||||
schema.MinItems = source.MinItems
|
||||
}
|
||||
if source.UniqueItems != nil {
|
||||
schema.UniqueItems = source.UniqueItems
|
||||
}
|
||||
if source.MaxProperties != nil {
|
||||
schema.MaxProperties = source.MaxProperties
|
||||
}
|
||||
if source.MinProperties != nil {
|
||||
schema.MinProperties = source.MinProperties
|
||||
}
|
||||
if source.Required != nil {
|
||||
schema.Required = source.Required
|
||||
}
|
||||
if source.AdditionalProperties != nil {
|
||||
schema.AdditionalProperties = source.AdditionalProperties
|
||||
}
|
||||
if source.Properties != nil {
|
||||
schema.Properties = source.Properties
|
||||
}
|
||||
if source.PatternProperties != nil {
|
||||
schema.PatternProperties = source.PatternProperties
|
||||
}
|
||||
if source.Dependencies != nil {
|
||||
schema.Dependencies = source.Dependencies
|
||||
}
|
||||
if source.Enumeration != nil {
|
||||
schema.Enumeration = source.Enumeration
|
||||
}
|
||||
if source.Type != nil {
|
||||
schema.Type = source.Type
|
||||
}
|
||||
if source.AllOf != nil {
|
||||
schema.AllOf = source.AllOf
|
||||
}
|
||||
if source.AnyOf != nil {
|
||||
schema.AnyOf = source.AnyOf
|
||||
}
|
||||
if source.OneOf != nil {
|
||||
schema.OneOf = source.OneOf
|
||||
}
|
||||
if source.Not != nil {
|
||||
schema.Not = source.Not
|
||||
}
|
||||
if source.Definitions != nil {
|
||||
schema.Definitions = source.Definitions
|
||||
}
|
||||
if source.Title != nil {
|
||||
schema.Title = source.Title
|
||||
}
|
||||
if source.Description != nil {
|
||||
schema.Description = source.Description
|
||||
}
|
||||
if source.Default != nil {
|
||||
schema.Default = source.Default
|
||||
}
|
||||
if source.Format != nil {
|
||||
schema.Format = source.Format
|
||||
}
|
||||
if source.Ref != nil {
|
||||
schema.Ref = source.Ref
|
||||
}
|
||||
}
|
||||
|
||||
// TypeIs returns true if the Type of a Schema includes the specified type
|
||||
func (schema *Schema) TypeIs(typeName string) bool {
|
||||
if schema.Type != nil {
|
||||
// the schema Type is either a string or an array of strings
|
||||
if schema.Type.String != nil {
|
||||
return (*(schema.Type.String) == typeName)
|
||||
} else if schema.Type.StringArray != nil {
|
||||
for _, n := range *(schema.Type.StringArray) {
|
||||
if n == typeName {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// ResolveRefs resolves "$ref" elements in a Schema and its children.
|
||||
// But if a reference refers to an object type, is inside a oneOf, or contains a oneOf,
|
||||
// the reference is kept and we expect downstream tools to separately model these
|
||||
// referenced schemas.
|
||||
func (schema *Schema) ResolveRefs() {
|
||||
rootSchema := schema
|
||||
count := 1
|
||||
for count > 0 {
|
||||
count = 0
|
||||
schema.applyToSchemas(
|
||||
func(schema *Schema, context string) {
|
||||
if schema.Ref != nil {
|
||||
resolvedRef, err := rootSchema.resolveJSONPointer(*(schema.Ref))
|
||||
if err != nil {
|
||||
log.Printf("%+v", err)
|
||||
} else if resolvedRef.TypeIs("object") {
|
||||
// don't substitute for objects, we'll model the referenced schema with a class
|
||||
} else if context == "OneOf" {
|
||||
// don't substitute for references inside oneOf declarations
|
||||
} else if resolvedRef.OneOf != nil {
|
||||
// don't substitute for references that contain oneOf declarations
|
||||
} else if resolvedRef.AdditionalProperties != nil {
|
||||
// don't substitute for references that look like objects
|
||||
} else {
|
||||
schema.Ref = nil
|
||||
schema.CopyProperties(resolvedRef)
|
||||
count++
|
||||
}
|
||||
}
|
||||
}, "")
|
||||
}
|
||||
}
|
||||
|
||||
// resolveJSONPointer resolves JSON pointers.
|
||||
// This current implementation is very crude and custom for OpenAPI 2.0 schemas.
|
||||
// It panics for any pointer that it is unable to resolve.
|
||||
func (schema *Schema) resolveJSONPointer(ref string) (result *Schema, err error) {
|
||||
parts := strings.Split(ref, "#")
|
||||
if len(parts) == 2 {
|
||||
documentName := parts[0] + "#"
|
||||
if documentName == "#" && schema.ID != nil {
|
||||
documentName = *(schema.ID)
|
||||
}
|
||||
path := parts[1]
|
||||
document := schemas[documentName]
|
||||
pathParts := strings.Split(path, "/")
|
||||
|
||||
// we currently do a very limited (hard-coded) resolution of certain paths and log errors for missed cases
|
||||
if len(pathParts) == 1 {
|
||||
return document, nil
|
||||
} else if len(pathParts) == 3 {
|
||||
switch pathParts[1] {
|
||||
case "definitions":
|
||||
dictionary := document.Definitions
|
||||
for _, pair := range *dictionary {
|
||||
if pair.Name == pathParts[2] {
|
||||
result = pair.Value
|
||||
}
|
||||
}
|
||||
case "properties":
|
||||
dictionary := document.Properties
|
||||
for _, pair := range *dictionary {
|
||||
if pair.Name == pathParts[2] {
|
||||
result = pair.Value
|
||||
}
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if result == nil {
|
||||
return nil, fmt.Errorf("unresolved pointer: %+v", ref)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// ResolveAllOfs replaces "allOf" elements by merging their properties into the parent Schema.
|
||||
func (schema *Schema) ResolveAllOfs() {
|
||||
schema.applyToSchemas(
|
||||
func(schema *Schema, context string) {
|
||||
if schema.AllOf != nil {
|
||||
for _, allOf := range *(schema.AllOf) {
|
||||
schema.CopyProperties(allOf)
|
||||
}
|
||||
schema.AllOf = nil
|
||||
}
|
||||
}, "resolveAllOfs")
|
||||
}
|
||||
|
||||
// ResolveAnyOfs replaces all "anyOf" elements with "oneOf".
|
||||
func (schema *Schema) ResolveAnyOfs() {
|
||||
schema.applyToSchemas(
|
||||
func(schema *Schema, context string) {
|
||||
if schema.AnyOf != nil {
|
||||
schema.OneOf = schema.AnyOf
|
||||
schema.AnyOf = nil
|
||||
}
|
||||
}, "resolveAnyOfs")
|
||||
}
|
||||
|
||||
// return a pointer to a copy of a passed-in string
|
||||
func stringptr(input string) (output *string) {
|
||||
return &input
|
||||
}
|
||||
|
||||
// CopyOfficialSchemaProperty copies a named property from the official JSON Schema definition
|
||||
func (schema *Schema) CopyOfficialSchemaProperty(name string) {
|
||||
*schema.Properties = append(*schema.Properties,
|
||||
NewNamedSchema(name,
|
||||
&Schema{Ref: stringptr("http://json-schema.org/draft-04/schema#/properties/" + name)}))
|
||||
}
|
||||
|
||||
// CopyOfficialSchemaProperties copies named properties from the official JSON Schema definition
|
||||
func (schema *Schema) CopyOfficialSchemaProperties(names []string) {
|
||||
for _, name := range names {
|
||||
schema.CopyOfficialSchemaProperty(name)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,442 @@
|
|||
// Copyright 2017 Google LLC. All Rights Reserved.
|
||||
//
|
||||
// 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.
|
||||
|
||||
//go:generate go run generate-base.go
|
||||
|
||||
package jsonschema
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"strconv"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
// This is a global map of all known Schemas.
|
||||
// It is initialized when the first Schema is created and inserted.
|
||||
var schemas map[string]*Schema
|
||||
|
||||
// NewBaseSchema builds a schema object from an embedded json representation.
|
||||
func NewBaseSchema() (schema *Schema, err error) {
|
||||
b, err := baseSchemaBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var node yaml.Node
|
||||
err = yaml.Unmarshal(b, &node)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewSchemaFromObject(&node), nil
|
||||
}
|
||||
|
||||
// NewSchemaFromFile reads a schema from a file.
|
||||
// Currently this assumes that schemas are stored in the source distribution of this project.
|
||||
func NewSchemaFromFile(filename string) (schema *Schema, err error) {
|
||||
file, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var node yaml.Node
|
||||
err = yaml.Unmarshal(file, &node)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewSchemaFromObject(&node), nil
|
||||
}
|
||||
|
||||
// NewSchemaFromObject constructs a schema from a parsed JSON object.
|
||||
// Due to the complexity of the schema representation, this is a
|
||||
// custom reader and not the standard Go JSON reader (encoding/json).
|
||||
func NewSchemaFromObject(jsonData *yaml.Node) *Schema {
|
||||
switch jsonData.Kind {
|
||||
case yaml.DocumentNode:
|
||||
return NewSchemaFromObject(jsonData.Content[0])
|
||||
case yaml.MappingNode:
|
||||
schema := &Schema{}
|
||||
|
||||
for i := 0; i < len(jsonData.Content); i += 2 {
|
||||
k := jsonData.Content[i].Value
|
||||
v := jsonData.Content[i+1]
|
||||
|
||||
switch k {
|
||||
case "$schema":
|
||||
schema.Schema = schema.stringValue(v)
|
||||
case "id":
|
||||
schema.ID = schema.stringValue(v)
|
||||
|
||||
case "multipleOf":
|
||||
schema.MultipleOf = schema.numberValue(v)
|
||||
case "maximum":
|
||||
schema.Maximum = schema.numberValue(v)
|
||||
case "exclusiveMaximum":
|
||||
schema.ExclusiveMaximum = schema.boolValue(v)
|
||||
case "minimum":
|
||||
schema.Minimum = schema.numberValue(v)
|
||||
case "exclusiveMinimum":
|
||||
schema.ExclusiveMinimum = schema.boolValue(v)
|
||||
|
||||
case "maxLength":
|
||||
schema.MaxLength = schema.intValue(v)
|
||||
case "minLength":
|
||||
schema.MinLength = schema.intValue(v)
|
||||
case "pattern":
|
||||
schema.Pattern = schema.stringValue(v)
|
||||
|
||||
case "additionalItems":
|
||||
schema.AdditionalItems = schema.schemaOrBooleanValue(v)
|
||||
case "items":
|
||||
schema.Items = schema.schemaOrSchemaArrayValue(v)
|
||||
case "maxItems":
|
||||
schema.MaxItems = schema.intValue(v)
|
||||
case "minItems":
|
||||
schema.MinItems = schema.intValue(v)
|
||||
case "uniqueItems":
|
||||
schema.UniqueItems = schema.boolValue(v)
|
||||
|
||||
case "maxProperties":
|
||||
schema.MaxProperties = schema.intValue(v)
|
||||
case "minProperties":
|
||||
schema.MinProperties = schema.intValue(v)
|
||||
case "required":
|
||||
schema.Required = schema.arrayOfStringsValue(v)
|
||||
case "additionalProperties":
|
||||
schema.AdditionalProperties = schema.schemaOrBooleanValue(v)
|
||||
case "properties":
|
||||
schema.Properties = schema.mapOfSchemasValue(v)
|
||||
case "patternProperties":
|
||||
schema.PatternProperties = schema.mapOfSchemasValue(v)
|
||||
case "dependencies":
|
||||
schema.Dependencies = schema.mapOfSchemasOrStringArraysValue(v)
|
||||
|
||||
case "enum":
|
||||
schema.Enumeration = schema.arrayOfEnumValuesValue(v)
|
||||
|
||||
case "type":
|
||||
schema.Type = schema.stringOrStringArrayValue(v)
|
||||
case "allOf":
|
||||
schema.AllOf = schema.arrayOfSchemasValue(v)
|
||||
case "anyOf":
|
||||
schema.AnyOf = schema.arrayOfSchemasValue(v)
|
||||
case "oneOf":
|
||||
schema.OneOf = schema.arrayOfSchemasValue(v)
|
||||
case "not":
|
||||
schema.Not = NewSchemaFromObject(v)
|
||||
case "definitions":
|
||||
schema.Definitions = schema.mapOfSchemasValue(v)
|
||||
|
||||
case "title":
|
||||
schema.Title = schema.stringValue(v)
|
||||
case "description":
|
||||
schema.Description = schema.stringValue(v)
|
||||
|
||||
case "default":
|
||||
schema.Default = v
|
||||
|
||||
case "format":
|
||||
schema.Format = schema.stringValue(v)
|
||||
case "$ref":
|
||||
schema.Ref = schema.stringValue(v)
|
||||
default:
|
||||
fmt.Printf("UNSUPPORTED (%s)\n", k)
|
||||
}
|
||||
}
|
||||
|
||||
// insert schema in global map
|
||||
if schema.ID != nil {
|
||||
if schemas == nil {
|
||||
schemas = make(map[string]*Schema, 0)
|
||||
}
|
||||
schemas[*(schema.ID)] = schema
|
||||
}
|
||||
return schema
|
||||
|
||||
default:
|
||||
fmt.Printf("schemaValue: unexpected node %+v\n", jsonData)
|
||||
return nil
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
//
|
||||
// BUILDERS
|
||||
// The following methods build elements of Schemas from interface{} values.
|
||||
// Each returns nil if it is unable to build the desired element.
|
||||
//
|
||||
|
||||
// Gets the string value of an interface{} value if possible.
|
||||
func (schema *Schema) stringValue(v *yaml.Node) *string {
|
||||
switch v.Kind {
|
||||
case yaml.ScalarNode:
|
||||
return &v.Value
|
||||
default:
|
||||
fmt.Printf("stringValue: unexpected node %+v\n", v)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Gets the numeric value of an interface{} value if possible.
|
||||
func (schema *Schema) numberValue(v *yaml.Node) *SchemaNumber {
|
||||
number := &SchemaNumber{}
|
||||
switch v.Kind {
|
||||
case yaml.ScalarNode:
|
||||
switch v.Tag {
|
||||
case "!!float":
|
||||
v2, _ := strconv.ParseFloat(v.Value, 64)
|
||||
number.Float = &v2
|
||||
return number
|
||||
case "!!int":
|
||||
v2, _ := strconv.ParseInt(v.Value, 10, 64)
|
||||
number.Integer = &v2
|
||||
return number
|
||||
default:
|
||||
fmt.Printf("stringValue: unexpected node %+v\n", v)
|
||||
}
|
||||
default:
|
||||
fmt.Printf("stringValue: unexpected node %+v\n", v)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Gets the integer value of an interface{} value if possible.
|
||||
func (schema *Schema) intValue(v *yaml.Node) *int64 {
|
||||
switch v.Kind {
|
||||
case yaml.ScalarNode:
|
||||
switch v.Tag {
|
||||
case "!!float":
|
||||
v2, _ := strconv.ParseFloat(v.Value, 64)
|
||||
v3 := int64(v2)
|
||||
return &v3
|
||||
case "!!int":
|
||||
v2, _ := strconv.ParseInt(v.Value, 10, 64)
|
||||
return &v2
|
||||
default:
|
||||
fmt.Printf("intValue: unexpected node %+v\n", v)
|
||||
}
|
||||
default:
|
||||
fmt.Printf("intValue: unexpected node %+v\n", v)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Gets the bool value of an interface{} value if possible.
|
||||
func (schema *Schema) boolValue(v *yaml.Node) *bool {
|
||||
switch v.Kind {
|
||||
case yaml.ScalarNode:
|
||||
switch v.Tag {
|
||||
case "!!bool":
|
||||
v2, _ := strconv.ParseBool(v.Value)
|
||||
return &v2
|
||||
default:
|
||||
fmt.Printf("boolValue: unexpected node %+v\n", v)
|
||||
}
|
||||
default:
|
||||
fmt.Printf("boolValue: unexpected node %+v\n", v)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Gets a map of Schemas from an interface{} value if possible.
|
||||
func (schema *Schema) mapOfSchemasValue(v *yaml.Node) *[]*NamedSchema {
|
||||
switch v.Kind {
|
||||
case yaml.MappingNode:
|
||||
m := make([]*NamedSchema, 0)
|
||||
for i := 0; i < len(v.Content); i += 2 {
|
||||
k2 := v.Content[i].Value
|
||||
v2 := v.Content[i+1]
|
||||
pair := &NamedSchema{Name: k2, Value: NewSchemaFromObject(v2)}
|
||||
m = append(m, pair)
|
||||
}
|
||||
return &m
|
||||
default:
|
||||
fmt.Printf("mapOfSchemasValue: unexpected node %+v\n", v)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Gets an array of Schemas from an interface{} value if possible.
|
||||
func (schema *Schema) arrayOfSchemasValue(v *yaml.Node) *[]*Schema {
|
||||
switch v.Kind {
|
||||
case yaml.SequenceNode:
|
||||
m := make([]*Schema, 0)
|
||||
for _, v2 := range v.Content {
|
||||
switch v2.Kind {
|
||||
case yaml.MappingNode:
|
||||
s := NewSchemaFromObject(v2)
|
||||
m = append(m, s)
|
||||
default:
|
||||
fmt.Printf("arrayOfSchemasValue: unexpected node %+v\n", v2)
|
||||
}
|
||||
}
|
||||
return &m
|
||||
case yaml.MappingNode:
|
||||
m := make([]*Schema, 0)
|
||||
s := NewSchemaFromObject(v)
|
||||
m = append(m, s)
|
||||
return &m
|
||||
default:
|
||||
fmt.Printf("arrayOfSchemasValue: unexpected node %+v\n", v)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Gets a Schema or an array of Schemas from an interface{} value if possible.
|
||||
func (schema *Schema) schemaOrSchemaArrayValue(v *yaml.Node) *SchemaOrSchemaArray {
|
||||
switch v.Kind {
|
||||
case yaml.SequenceNode:
|
||||
m := make([]*Schema, 0)
|
||||
for _, v2 := range v.Content {
|
||||
switch v2.Kind {
|
||||
case yaml.MappingNode:
|
||||
s := NewSchemaFromObject(v2)
|
||||
m = append(m, s)
|
||||
default:
|
||||
fmt.Printf("schemaOrSchemaArrayValue: unexpected node %+v\n", v2)
|
||||
}
|
||||
}
|
||||
return &SchemaOrSchemaArray{SchemaArray: &m}
|
||||
case yaml.MappingNode:
|
||||
s := NewSchemaFromObject(v)
|
||||
return &SchemaOrSchemaArray{Schema: s}
|
||||
default:
|
||||
fmt.Printf("schemaOrSchemaArrayValue: unexpected node %+v\n", v)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Gets an array of strings from an interface{} value if possible.
|
||||
func (schema *Schema) arrayOfStringsValue(v *yaml.Node) *[]string {
|
||||
switch v.Kind {
|
||||
case yaml.ScalarNode:
|
||||
a := []string{v.Value}
|
||||
return &a
|
||||
case yaml.SequenceNode:
|
||||
a := make([]string, 0)
|
||||
for _, v2 := range v.Content {
|
||||
switch v2.Kind {
|
||||
case yaml.ScalarNode:
|
||||
a = append(a, v2.Value)
|
||||
default:
|
||||
fmt.Printf("arrayOfStringsValue: unexpected node %+v\n", v2)
|
||||
}
|
||||
}
|
||||
return &a
|
||||
default:
|
||||
fmt.Printf("arrayOfStringsValue: unexpected node %+v\n", v)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Gets a string or an array of strings from an interface{} value if possible.
|
||||
func (schema *Schema) stringOrStringArrayValue(v *yaml.Node) *StringOrStringArray {
|
||||
switch v.Kind {
|
||||
case yaml.ScalarNode:
|
||||
s := &StringOrStringArray{}
|
||||
s.String = &v.Value
|
||||
return s
|
||||
case yaml.SequenceNode:
|
||||
a := make([]string, 0)
|
||||
for _, v2 := range v.Content {
|
||||
switch v2.Kind {
|
||||
case yaml.ScalarNode:
|
||||
a = append(a, v2.Value)
|
||||
default:
|
||||
fmt.Printf("arrayOfStringsValue: unexpected node %+v\n", v2)
|
||||
}
|
||||
}
|
||||
s := &StringOrStringArray{}
|
||||
s.StringArray = &a
|
||||
return s
|
||||
default:
|
||||
fmt.Printf("arrayOfStringsValue: unexpected node %+v\n", v)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Gets an array of enum values from an interface{} value if possible.
|
||||
func (schema *Schema) arrayOfEnumValuesValue(v *yaml.Node) *[]SchemaEnumValue {
|
||||
a := make([]SchemaEnumValue, 0)
|
||||
switch v.Kind {
|
||||
case yaml.SequenceNode:
|
||||
for _, v2 := range v.Content {
|
||||
switch v2.Kind {
|
||||
case yaml.ScalarNode:
|
||||
switch v2.Tag {
|
||||
case "!!str":
|
||||
a = append(a, SchemaEnumValue{String: &v2.Value})
|
||||
case "!!bool":
|
||||
v3, _ := strconv.ParseBool(v2.Value)
|
||||
a = append(a, SchemaEnumValue{Bool: &v3})
|
||||
default:
|
||||
fmt.Printf("arrayOfEnumValuesValue: unexpected type %s\n", v2.Tag)
|
||||
}
|
||||
default:
|
||||
fmt.Printf("arrayOfEnumValuesValue: unexpected node %+v\n", v2)
|
||||
}
|
||||
}
|
||||
default:
|
||||
fmt.Printf("arrayOfEnumValuesValue: unexpected node %+v\n", v)
|
||||
}
|
||||
return &a
|
||||
}
|
||||
|
||||
// Gets a map of schemas or string arrays from an interface{} value if possible.
|
||||
func (schema *Schema) mapOfSchemasOrStringArraysValue(v *yaml.Node) *[]*NamedSchemaOrStringArray {
|
||||
m := make([]*NamedSchemaOrStringArray, 0)
|
||||
switch v.Kind {
|
||||
case yaml.MappingNode:
|
||||
for i := 0; i < len(v.Content); i += 2 {
|
||||
k2 := v.Content[i].Value
|
||||
v2 := v.Content[i+1]
|
||||
switch v2.Kind {
|
||||
case yaml.SequenceNode:
|
||||
a := make([]string, 0)
|
||||
for _, v3 := range v2.Content {
|
||||
switch v3.Kind {
|
||||
case yaml.ScalarNode:
|
||||
a = append(a, v3.Value)
|
||||
default:
|
||||
fmt.Printf("mapOfSchemasOrStringArraysValue: unexpected node %+v\n", v3)
|
||||
}
|
||||
}
|
||||
s := &SchemaOrStringArray{}
|
||||
s.StringArray = &a
|
||||
pair := &NamedSchemaOrStringArray{Name: k2, Value: s}
|
||||
m = append(m, pair)
|
||||
default:
|
||||
fmt.Printf("mapOfSchemasOrStringArraysValue: unexpected node %+v\n", v2)
|
||||
}
|
||||
}
|
||||
default:
|
||||
fmt.Printf("mapOfSchemasOrStringArraysValue: unexpected node %+v\n", v)
|
||||
}
|
||||
return &m
|
||||
}
|
||||
|
||||
// Gets a schema or a boolean value from an interface{} value if possible.
|
||||
func (schema *Schema) schemaOrBooleanValue(v *yaml.Node) *SchemaOrBoolean {
|
||||
schemaOrBoolean := &SchemaOrBoolean{}
|
||||
switch v.Kind {
|
||||
case yaml.ScalarNode:
|
||||
v2, _ := strconv.ParseBool(v.Value)
|
||||
schemaOrBoolean.Boolean = &v2
|
||||
case yaml.MappingNode:
|
||||
schemaOrBoolean.Schema = NewSchemaFromObject(v)
|
||||
default:
|
||||
fmt.Printf("schemaOrBooleanValue: unexpected node %+v\n", v)
|
||||
}
|
||||
return schemaOrBoolean
|
||||
}
|
||||
|
|
@ -0,0 +1,150 @@
|
|||
{
|
||||
"id": "http://json-schema.org/draft-04/schema#",
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "Core schema meta-schema",
|
||||
"definitions": {
|
||||
"schemaArray": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": { "$ref": "#" }
|
||||
},
|
||||
"positiveInteger": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"positiveIntegerDefault0": {
|
||||
"allOf": [ { "$ref": "#/definitions/positiveInteger" }, { "default": 0 } ]
|
||||
},
|
||||
"simpleTypes": {
|
||||
"enum": [ "array", "boolean", "integer", "null", "number", "object", "string" ]
|
||||
},
|
||||
"stringArray": {
|
||||
"type": "array",
|
||||
"items": { "type": "string" },
|
||||
"minItems": 1,
|
||||
"uniqueItems": true
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"format": "uri"
|
||||
},
|
||||
"$schema": {
|
||||
"type": "string",
|
||||
"format": "uri"
|
||||
},
|
||||
"title": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"default": {},
|
||||
"multipleOf": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"exclusiveMinimum": true
|
||||
},
|
||||
"maximum": {
|
||||
"type": "number"
|
||||
},
|
||||
"exclusiveMaximum": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"minimum": {
|
||||
"type": "number"
|
||||
},
|
||||
"exclusiveMinimum": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"maxLength": { "$ref": "#/definitions/positiveInteger" },
|
||||
"minLength": { "$ref": "#/definitions/positiveIntegerDefault0" },
|
||||
"pattern": {
|
||||
"type": "string",
|
||||
"format": "regex"
|
||||
},
|
||||
"additionalItems": {
|
||||
"anyOf": [
|
||||
{ "type": "boolean" },
|
||||
{ "$ref": "#" }
|
||||
],
|
||||
"default": {}
|
||||
},
|
||||
"items": {
|
||||
"anyOf": [
|
||||
{ "$ref": "#" },
|
||||
{ "$ref": "#/definitions/schemaArray" }
|
||||
],
|
||||
"default": {}
|
||||
},
|
||||
"maxItems": { "$ref": "#/definitions/positiveInteger" },
|
||||
"minItems": { "$ref": "#/definitions/positiveIntegerDefault0" },
|
||||
"uniqueItems": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"maxProperties": { "$ref": "#/definitions/positiveInteger" },
|
||||
"minProperties": { "$ref": "#/definitions/positiveIntegerDefault0" },
|
||||
"required": { "$ref": "#/definitions/stringArray" },
|
||||
"additionalProperties": {
|
||||
"anyOf": [
|
||||
{ "type": "boolean" },
|
||||
{ "$ref": "#" }
|
||||
],
|
||||
"default": {}
|
||||
},
|
||||
"definitions": {
|
||||
"type": "object",
|
||||
"additionalProperties": { "$ref": "#" },
|
||||
"default": {}
|
||||
},
|
||||
"properties": {
|
||||
"type": "object",
|
||||
"additionalProperties": { "$ref": "#" },
|
||||
"default": {}
|
||||
},
|
||||
"patternProperties": {
|
||||
"type": "object",
|
||||
"additionalProperties": { "$ref": "#" },
|
||||
"default": {}
|
||||
},
|
||||
"dependencies": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"anyOf": [
|
||||
{ "$ref": "#" },
|
||||
{ "$ref": "#/definitions/stringArray" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"enum": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"uniqueItems": true
|
||||
},
|
||||
"type": {
|
||||
"anyOf": [
|
||||
{ "$ref": "#/definitions/simpleTypes" },
|
||||
{
|
||||
"type": "array",
|
||||
"items": { "$ref": "#/definitions/simpleTypes" },
|
||||
"minItems": 1,
|
||||
"uniqueItems": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"allOf": { "$ref": "#/definitions/schemaArray" },
|
||||
"anyOf": { "$ref": "#/definitions/schemaArray" },
|
||||
"oneOf": { "$ref": "#/definitions/schemaArray" },
|
||||
"not": { "$ref": "#" }
|
||||
},
|
||||
"dependencies": {
|
||||
"exclusiveMaximum": [ "maximum" ],
|
||||
"exclusiveMinimum": [ "minimum" ]
|
||||
},
|
||||
"default": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,369 @@
|
|||
// Copyright 2017 Google LLC. All Rights Reserved.
|
||||
//
|
||||
// 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 jsonschema
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
const indentation = " "
|
||||
|
||||
func renderMappingNode(node *yaml.Node, indent string) (result string) {
|
||||
result = "{\n"
|
||||
innerIndent := indent + indentation
|
||||
for i := 0; i < len(node.Content); i += 2 {
|
||||
// first print the key
|
||||
key := node.Content[i].Value
|
||||
result += fmt.Sprintf("%s\"%+v\": ", innerIndent, key)
|
||||
// then the value
|
||||
value := node.Content[i+1]
|
||||
switch value.Kind {
|
||||
case yaml.ScalarNode:
|
||||
result += "\"" + value.Value + "\""
|
||||
case yaml.MappingNode:
|
||||
result += renderMappingNode(value, innerIndent)
|
||||
case yaml.SequenceNode:
|
||||
result += renderSequenceNode(value, innerIndent)
|
||||
default:
|
||||
result += fmt.Sprintf("???MapItem(Key:%+v, Value:%T)", value, value)
|
||||
}
|
||||
if i < len(node.Content)-2 {
|
||||
result += ","
|
||||
}
|
||||
result += "\n"
|
||||
}
|
||||
|
||||
result += indent + "}"
|
||||
return result
|
||||
}
|
||||
|
||||
func renderSequenceNode(node *yaml.Node, indent string) (result string) {
|
||||
result = "[\n"
|
||||
innerIndent := indent + indentation
|
||||
for i := 0; i < len(node.Content); i++ {
|
||||
item := node.Content[i]
|
||||
switch item.Kind {
|
||||
case yaml.ScalarNode:
|
||||
result += innerIndent + "\"" + item.Value + "\""
|
||||
case yaml.MappingNode:
|
||||
result += innerIndent + renderMappingNode(item, innerIndent) + ""
|
||||
default:
|
||||
result += innerIndent + fmt.Sprintf("???ArrayItem(%+v)", item)
|
||||
}
|
||||
if i < len(node.Content)-1 {
|
||||
result += ","
|
||||
}
|
||||
result += "\n"
|
||||
}
|
||||
result += indent + "]"
|
||||
return result
|
||||
}
|
||||
|
||||
func renderStringArray(array []string, indent string) (result string) {
|
||||
result = "[\n"
|
||||
innerIndent := indent + indentation
|
||||
for i, item := range array {
|
||||
result += innerIndent + "\"" + item + "\""
|
||||
if i < len(array)-1 {
|
||||
result += ","
|
||||
}
|
||||
result += "\n"
|
||||
}
|
||||
result += indent + "]"
|
||||
return result
|
||||
}
|
||||
|
||||
// Render renders a yaml.Node as JSON
|
||||
func Render(node *yaml.Node) string {
|
||||
if node.Kind == yaml.DocumentNode {
|
||||
if len(node.Content) == 1 {
|
||||
return Render(node.Content[0])
|
||||
}
|
||||
} else if node.Kind == yaml.MappingNode {
|
||||
return renderMappingNode(node, "") + "\n"
|
||||
} else if node.Kind == yaml.SequenceNode {
|
||||
return renderSequenceNode(node, "") + "\n"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (object *SchemaNumber) nodeValue() *yaml.Node {
|
||||
if object.Integer != nil {
|
||||
return nodeForInt64(*object.Integer)
|
||||
} else if object.Float != nil {
|
||||
return nodeForFloat64(*object.Float)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (object *SchemaOrBoolean) nodeValue() *yaml.Node {
|
||||
if object.Schema != nil {
|
||||
return object.Schema.nodeValue()
|
||||
} else if object.Boolean != nil {
|
||||
return nodeForBoolean(*object.Boolean)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func nodeForStringArray(array []string) *yaml.Node {
|
||||
content := make([]*yaml.Node, 0)
|
||||
for _, item := range array {
|
||||
content = append(content, nodeForString(item))
|
||||
}
|
||||
return nodeForSequence(content)
|
||||
}
|
||||
|
||||
func nodeForSchemaArray(array []*Schema) *yaml.Node {
|
||||
content := make([]*yaml.Node, 0)
|
||||
for _, item := range array {
|
||||
content = append(content, item.nodeValue())
|
||||
}
|
||||
return nodeForSequence(content)
|
||||
}
|
||||
|
||||
func (object *StringOrStringArray) nodeValue() *yaml.Node {
|
||||
if object.String != nil {
|
||||
return nodeForString(*object.String)
|
||||
} else if object.StringArray != nil {
|
||||
return nodeForStringArray(*(object.StringArray))
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (object *SchemaOrStringArray) nodeValue() *yaml.Node {
|
||||
if object.Schema != nil {
|
||||
return object.Schema.nodeValue()
|
||||
} else if object.StringArray != nil {
|
||||
return nodeForStringArray(*(object.StringArray))
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (object *SchemaOrSchemaArray) nodeValue() *yaml.Node {
|
||||
if object.Schema != nil {
|
||||
return object.Schema.nodeValue()
|
||||
} else if object.SchemaArray != nil {
|
||||
return nodeForSchemaArray(*(object.SchemaArray))
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (object *SchemaEnumValue) nodeValue() *yaml.Node {
|
||||
if object.String != nil {
|
||||
return nodeForString(*object.String)
|
||||
} else if object.Bool != nil {
|
||||
return nodeForBoolean(*object.Bool)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func nodeForNamedSchemaArray(array *[]*NamedSchema) *yaml.Node {
|
||||
content := make([]*yaml.Node, 0)
|
||||
for _, pair := range *(array) {
|
||||
content = appendPair(content, pair.Name, pair.Value.nodeValue())
|
||||
}
|
||||
return nodeForMapping(content)
|
||||
}
|
||||
|
||||
func nodeForNamedSchemaOrStringArray(array *[]*NamedSchemaOrStringArray) *yaml.Node {
|
||||
content := make([]*yaml.Node, 0)
|
||||
for _, pair := range *(array) {
|
||||
content = appendPair(content, pair.Name, pair.Value.nodeValue())
|
||||
}
|
||||
return nodeForMapping(content)
|
||||
}
|
||||
|
||||
func nodeForSchemaEnumArray(array *[]SchemaEnumValue) *yaml.Node {
|
||||
content := make([]*yaml.Node, 0)
|
||||
for _, item := range *array {
|
||||
content = append(content, item.nodeValue())
|
||||
}
|
||||
return nodeForSequence(content)
|
||||
}
|
||||
|
||||
func nodeForMapping(content []*yaml.Node) *yaml.Node {
|
||||
return &yaml.Node{
|
||||
Kind: yaml.MappingNode,
|
||||
Content: content,
|
||||
}
|
||||
}
|
||||
|
||||
func nodeForSequence(content []*yaml.Node) *yaml.Node {
|
||||
return &yaml.Node{
|
||||
Kind: yaml.SequenceNode,
|
||||
Content: content,
|
||||
}
|
||||
}
|
||||
|
||||
func nodeForString(value string) *yaml.Node {
|
||||
return &yaml.Node{
|
||||
Kind: yaml.ScalarNode,
|
||||
Tag: "!!str",
|
||||
Value: value,
|
||||
}
|
||||
}
|
||||
|
||||
func nodeForBoolean(value bool) *yaml.Node {
|
||||
return &yaml.Node{
|
||||
Kind: yaml.ScalarNode,
|
||||
Tag: "!!bool",
|
||||
Value: fmt.Sprintf("%t", value),
|
||||
}
|
||||
}
|
||||
|
||||
func nodeForInt64(value int64) *yaml.Node {
|
||||
return &yaml.Node{
|
||||
Kind: yaml.ScalarNode,
|
||||
Tag: "!!int",
|
||||
Value: fmt.Sprintf("%d", value),
|
||||
}
|
||||
}
|
||||
|
||||
func nodeForFloat64(value float64) *yaml.Node {
|
||||
return &yaml.Node{
|
||||
Kind: yaml.ScalarNode,
|
||||
Tag: "!!float",
|
||||
Value: fmt.Sprintf("%f", value),
|
||||
}
|
||||
}
|
||||
|
||||
func appendPair(nodes []*yaml.Node, name string, value *yaml.Node) []*yaml.Node {
|
||||
nodes = append(nodes, nodeForString(name))
|
||||
nodes = append(nodes, value)
|
||||
return nodes
|
||||
}
|
||||
|
||||
func (schema *Schema) nodeValue() *yaml.Node {
|
||||
n := &yaml.Node{Kind: yaml.MappingNode}
|
||||
content := make([]*yaml.Node, 0)
|
||||
if schema.Title != nil {
|
||||
content = appendPair(content, "title", nodeForString(*schema.Title))
|
||||
}
|
||||
if schema.ID != nil {
|
||||
content = appendPair(content, "id", nodeForString(*schema.ID))
|
||||
}
|
||||
if schema.Schema != nil {
|
||||
content = appendPair(content, "$schema", nodeForString(*schema.Schema))
|
||||
}
|
||||
if schema.Type != nil {
|
||||
content = appendPair(content, "type", schema.Type.nodeValue())
|
||||
}
|
||||
if schema.Items != nil {
|
||||
content = appendPair(content, "items", schema.Items.nodeValue())
|
||||
}
|
||||
if schema.Description != nil {
|
||||
content = appendPair(content, "description", nodeForString(*schema.Description))
|
||||
}
|
||||
if schema.Required != nil {
|
||||
content = appendPair(content, "required", nodeForStringArray(*schema.Required))
|
||||
}
|
||||
if schema.AdditionalProperties != nil {
|
||||
content = appendPair(content, "additionalProperties", schema.AdditionalProperties.nodeValue())
|
||||
}
|
||||
if schema.PatternProperties != nil {
|
||||
content = appendPair(content, "patternProperties", nodeForNamedSchemaArray(schema.PatternProperties))
|
||||
}
|
||||
if schema.Properties != nil {
|
||||
content = appendPair(content, "properties", nodeForNamedSchemaArray(schema.Properties))
|
||||
}
|
||||
if schema.Dependencies != nil {
|
||||
content = appendPair(content, "dependencies", nodeForNamedSchemaOrStringArray(schema.Dependencies))
|
||||
}
|
||||
if schema.Ref != nil {
|
||||
content = appendPair(content, "$ref", nodeForString(*schema.Ref))
|
||||
}
|
||||
if schema.MultipleOf != nil {
|
||||
content = appendPair(content, "multipleOf", schema.MultipleOf.nodeValue())
|
||||
}
|
||||
if schema.Maximum != nil {
|
||||
content = appendPair(content, "maximum", schema.Maximum.nodeValue())
|
||||
}
|
||||
if schema.ExclusiveMaximum != nil {
|
||||
content = appendPair(content, "exclusiveMaximum", nodeForBoolean(*schema.ExclusiveMaximum))
|
||||
}
|
||||
if schema.Minimum != nil {
|
||||
content = appendPair(content, "minimum", schema.Minimum.nodeValue())
|
||||
}
|
||||
if schema.ExclusiveMinimum != nil {
|
||||
content = appendPair(content, "exclusiveMinimum", nodeForBoolean(*schema.ExclusiveMinimum))
|
||||
}
|
||||
if schema.MaxLength != nil {
|
||||
content = appendPair(content, "maxLength", nodeForInt64(*schema.MaxLength))
|
||||
}
|
||||
if schema.MinLength != nil {
|
||||
content = appendPair(content, "minLength", nodeForInt64(*schema.MinLength))
|
||||
}
|
||||
if schema.Pattern != nil {
|
||||
content = appendPair(content, "pattern", nodeForString(*schema.Pattern))
|
||||
}
|
||||
if schema.AdditionalItems != nil {
|
||||
content = appendPair(content, "additionalItems", schema.AdditionalItems.nodeValue())
|
||||
}
|
||||
if schema.MaxItems != nil {
|
||||
content = appendPair(content, "maxItems", nodeForInt64(*schema.MaxItems))
|
||||
}
|
||||
if schema.MinItems != nil {
|
||||
content = appendPair(content, "minItems", nodeForInt64(*schema.MinItems))
|
||||
}
|
||||
if schema.UniqueItems != nil {
|
||||
content = appendPair(content, "uniqueItems", nodeForBoolean(*schema.UniqueItems))
|
||||
}
|
||||
if schema.MaxProperties != nil {
|
||||
content = appendPair(content, "maxProperties", nodeForInt64(*schema.MaxProperties))
|
||||
}
|
||||
if schema.MinProperties != nil {
|
||||
content = appendPair(content, "minProperties", nodeForInt64(*schema.MinProperties))
|
||||
}
|
||||
if schema.Enumeration != nil {
|
||||
content = appendPair(content, "enum", nodeForSchemaEnumArray(schema.Enumeration))
|
||||
}
|
||||
if schema.AllOf != nil {
|
||||
content = appendPair(content, "allOf", nodeForSchemaArray(*schema.AllOf))
|
||||
}
|
||||
if schema.AnyOf != nil {
|
||||
content = appendPair(content, "anyOf", nodeForSchemaArray(*schema.AnyOf))
|
||||
}
|
||||
if schema.OneOf != nil {
|
||||
content = appendPair(content, "oneOf", nodeForSchemaArray(*schema.OneOf))
|
||||
}
|
||||
if schema.Not != nil {
|
||||
content = appendPair(content, "not", schema.Not.nodeValue())
|
||||
}
|
||||
if schema.Definitions != nil {
|
||||
content = appendPair(content, "definitions", nodeForNamedSchemaArray(schema.Definitions))
|
||||
}
|
||||
if schema.Default != nil {
|
||||
// m = append(m, yaml.MapItem{Key: "default", Value: *schema.Default})
|
||||
}
|
||||
if schema.Format != nil {
|
||||
content = appendPair(content, "format", nodeForString(*schema.Format))
|
||||
}
|
||||
n.Content = content
|
||||
return n
|
||||
}
|
||||
|
||||
// JSONString returns a json representation of a schema.
|
||||
func (schema *Schema) JSONString() string {
|
||||
node := schema.nodeValue()
|
||||
return Render(node)
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
// Copyright 2020 Google LLC. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
|
@ -41,6 +41,9 @@ option java_package = "org.openapi_v2";
|
|||
// the future. 'GPB' is reserved for the protocol buffer implementation itself.
|
||||
option objc_class_prefix = "OAS";
|
||||
|
||||
// The Go package name.
|
||||
option go_package = "openapiv2;openapi_v2";
|
||||
|
||||
message AdditionalPropertiesItem {
|
||||
oneof oneof {
|
||||
Schema schema = 1;
|
||||
|
|
@ -553,7 +556,7 @@ message Response {
|
|||
repeated NamedAny vendor_extension = 5;
|
||||
}
|
||||
|
||||
// One or more JSON representations for parameters
|
||||
// One or more JSON representations for responses
|
||||
message ResponseDefinitions {
|
||||
repeated NamedResponse additional_properties = 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,14 @@
|
|||
# OpenAPI v2 Protocol Buffer Models
|
||||
|
||||
This directory contains a Protocol Buffer-language model
|
||||
and related code for supporting OpenAPI v2.
|
||||
This directory contains a Protocol Buffer-language model and related code for
|
||||
supporting OpenAPI v2.
|
||||
|
||||
Gnostic applications and plugins can use OpenAPIv2.proto
|
||||
to generate Protocol Buffer support code for their preferred languages.
|
||||
Gnostic applications and plugins can use OpenAPIv2.proto to generate Protocol
|
||||
Buffer support code for their preferred languages.
|
||||
|
||||
OpenAPIv2.go is used by Gnostic to read JSON and YAML OpenAPI
|
||||
descriptions into the Protocol Buffer-based datastructures
|
||||
generated from OpenAPIv2.proto.
|
||||
OpenAPIv2.go is used by Gnostic to read JSON and YAML OpenAPI descriptions into
|
||||
the Protocol Buffer-based datastructures generated from OpenAPIv2.proto.
|
||||
|
||||
OpenAPIv2.proto and OpenAPIv2.go are generated by the Gnostic
|
||||
compiler generator, and OpenAPIv2.pb.go is generated by
|
||||
protoc, the Protocol Buffer compiler, and protoc-gen-go, the
|
||||
Protocol Buffer Go code generation plugin.
|
||||
OpenAPIv2.proto and OpenAPIv2.go are generated by the Gnostic compiler
|
||||
generator, and OpenAPIv2.pb.go is generated by protoc, the Protocol Buffer
|
||||
compiler, and protoc-gen-go, the Protocol Buffer Go code generation plugin.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,41 @@
|
|||
// Copyright 2020 Google LLC. All Rights Reserved.
|
||||
//
|
||||
// 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 openapi_v2
|
||||
|
||||
import (
|
||||
"github.com/googleapis/gnostic/compiler"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
// ParseDocument reads an OpenAPI v2 description from a YAML/JSON representation.
|
||||
func ParseDocument(b []byte) (*Document, error) {
|
||||
info, err := compiler.ReadInfoFromBytes("", b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
root := info.Content[0]
|
||||
return NewDocument(root, compiler.NewContextWithExtensions("$root", root, nil, nil))
|
||||
}
|
||||
|
||||
// YAMLValue produces a serialized YAML representation of the document.
|
||||
func (d *Document) YAMLValue(comment string) ([]byte, error) {
|
||||
rawInfo := d.ToRawInfo()
|
||||
rawInfo = &yaml.Node{
|
||||
Kind: yaml.DocumentNode,
|
||||
Content: []*yaml.Node{rawInfo},
|
||||
HeadComment: comment,
|
||||
}
|
||||
return yaml.Marshal(rawInfo)
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue