refactor(serving): KnClient interface for single point of cluster access (#134)

* fix(serving): Remove hardcoded GVK and look it up from schema

Fixes #133.

* chore(serving): Add test for "WaitForService()"

* refactor(service): Add listRoutes() to client + generic way for list options

* chore(serving): Fixing rebase conflicts
This commit is contained in:
Roland Huß 2019-07-08 19:08:34 +02:00 committed by Knative Prow Robot
parent 0cbc4e1b18
commit 98184eafbc
44 changed files with 1745 additions and 617 deletions

25
go.mod
View File

@ -2,25 +2,23 @@ module github.com/knative/client
require ( require (
github.com/cpuguy83/go-md2man v1.0.10 // indirect github.com/cpuguy83/go-md2man v1.0.10 // indirect
github.com/evanphx/json-patch v4.2.0+incompatible // indirect github.com/evanphx/json-patch v4.5.0+incompatible // indirect
github.com/ghodss/yaml v1.0.0 // indirect github.com/ghodss/yaml v1.0.0 // indirect
github.com/gogo/protobuf v1.2.1 // indirect github.com/gogo/protobuf v1.2.1 // indirect
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect
github.com/golang/protobuf v1.3.1 // indirect github.com/golang/protobuf v1.3.1 // indirect
github.com/google/btree v1.0.0 // indirect github.com/google/btree v1.0.0 // indirect
github.com/google/go-cmp v0.3.0 // indirect github.com/google/go-cmp v0.3.0 // indirect
github.com/google/go-containerregistry v0.0.0-20190503220729-1c6c7f61e8a5 // indirect github.com/google/go-containerregistry v0.0.0-20190623150931-ca8b66cb1b79 // indirect
github.com/google/gofuzz v1.0.0 // indirect github.com/google/gofuzz v1.0.0 // indirect
github.com/google/licenseclassifier v0.0.0-20190501212618-47b603fe1b8c // indirect github.com/googleapis/gnostic v0.3.0 // indirect
github.com/googleapis/gnostic v0.2.0 // indirect github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
github.com/gregjones/httpcache v0.0.0-20190212212710-3befbb6ad0cc // indirect
github.com/hashicorp/golang-lru v0.5.1 // indirect github.com/hashicorp/golang-lru v0.5.1 // indirect
github.com/imdario/mergo v0.3.7 // indirect github.com/imdario/mergo v0.3.7 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/json-iterator/go v1.1.6 // indirect github.com/json-iterator/go v1.1.6 // indirect
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024 // indirect github.com/knative/build v0.7.0 // indirect
github.com/knative/build v0.6.0 // indirect github.com/knative/pkg v0.0.0-20190617142447-13b093adc272
github.com/knative/pkg v0.0.0-20190518173526-34792a92cec2
github.com/knative/serving v0.6.0 github.com/knative/serving v0.6.0
github.com/knative/test-infra v0.0.0-20190702025031-91d37e4abc30 github.com/knative/test-infra v0.0.0-20190702025031-91d37e4abc30
github.com/mattbaird/jsonpatch v0.0.0-20171005235357-81af80346b1a // indirect github.com/mattbaird/jsonpatch v0.0.0-20171005235357-81af80346b1a // indirect
@ -31,20 +29,15 @@ require (
github.com/spf13/cobra v0.0.3 github.com/spf13/cobra v0.0.3
github.com/spf13/pflag v1.0.3 github.com/spf13/pflag v1.0.3
github.com/spf13/viper v1.3.1 github.com/spf13/viper v1.3.1
github.com/stretchr/objx v0.2.0 // indirect golang.org/x/net v0.0.0-20190628185345-da137c7871d7 // indirect
go.uber.org/atomic v1.4.0 // indirect golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 // indirect
go.uber.org/multierr v1.1.0 // indirect
go.uber.org/zap v1.10.0 // indirect
golang.org/x/net v0.0.0-20190514140710-3ec191127204 // indirect
golang.org/x/oauth2 v0.0.0-20190517181255-950ef44c6e07 // indirect
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect
golang.org/x/tools v0.0.0-20190628034336-212fb13d595e // indirect
gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect
gotest.tools v2.2.0+incompatible gotest.tools v2.2.0+incompatible
k8s.io/api v0.0.0-20190226173710-145d52631d00 k8s.io/api v0.0.0-20190226173710-145d52631d00
k8s.io/apimachinery v0.0.0-20190221084156-01f179d85dbc k8s.io/apimachinery v0.0.0-20190221084156-01f179d85dbc
k8s.io/cli-runtime v0.0.0-20190325194458-f2b4781c3ae1 k8s.io/cli-runtime v0.0.0-20190325194458-f2b4781c3ae1
k8s.io/client-go v0.0.0-20190226174127-78295b709ec6 k8s.io/client-go v0.0.0-20190226174127-78295b709ec6
k8s.io/kube-openapi v0.0.0-20190510232812-a01b7d5d6c22 // indirect k8s.io/kube-openapi v0.0.0-20190603182131-db7b694dc208 // indirect
sigs.k8s.io/yaml v1.1.0 sigs.k8s.io/yaml v1.1.0
) )

19
go.sum
View File

@ -47,6 +47,8 @@ github.com/evanphx/json-patch v4.1.0+incompatible h1:K1MDoo4AZ4wU0GIU/fPmtZg7Vpz
github.com/evanphx/json-patch v4.1.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.1.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/evanphx/json-patch v4.2.0+incompatible h1:fUDGZCv/7iAN7u0puUVhvKCcsR6vRfwrJatElLBEf0I= github.com/evanphx/json-patch v4.2.0+incompatible h1:fUDGZCv/7iAN7u0puUVhvKCcsR6vRfwrJatElLBEf0I=
github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
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/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680 h1:ZktWZesgun21uEDrwW7iEV1zPCGQldM2atlJZ3TdvVM= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680 h1:ZktWZesgun21uEDrwW7iEV1zPCGQldM2atlJZ3TdvVM=
@ -93,6 +95,8 @@ github.com/google/go-containerregistry v0.0.0-20190424210018-7d6d1d3cd63b h1:3Kv
github.com/google/go-containerregistry v0.0.0-20190424210018-7d6d1d3cd63b/go.mod h1:yZAFP63pRshzrEYLXLGPmUt0Ay+2zdjmMN1loCnRLUk= github.com/google/go-containerregistry v0.0.0-20190424210018-7d6d1d3cd63b/go.mod h1:yZAFP63pRshzrEYLXLGPmUt0Ay+2zdjmMN1loCnRLUk=
github.com/google/go-containerregistry v0.0.0-20190503220729-1c6c7f61e8a5 h1:wXZCVr9/0naJbZhAzKDzj/sgnduf8qn9ldjkI/CND9k= github.com/google/go-containerregistry v0.0.0-20190503220729-1c6c7f61e8a5 h1:wXZCVr9/0naJbZhAzKDzj/sgnduf8qn9ldjkI/CND9k=
github.com/google/go-containerregistry v0.0.0-20190503220729-1c6c7f61e8a5/go.mod h1:yZAFP63pRshzrEYLXLGPmUt0Ay+2zdjmMN1loCnRLUk= github.com/google/go-containerregistry v0.0.0-20190503220729-1c6c7f61e8a5/go.mod h1:yZAFP63pRshzrEYLXLGPmUt0Ay+2zdjmMN1loCnRLUk=
github.com/google/go-containerregistry v0.0.0-20190623150931-ca8b66cb1b79 h1:iObax0KHGJG3zG66UocaycSspWe9P7OT0SA9dL759sM=
github.com/google/go-containerregistry v0.0.0-20190623150931-ca8b66cb1b79/go.mod h1:yZAFP63pRshzrEYLXLGPmUt0Ay+2zdjmMN1loCnRLUk=
github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
@ -105,10 +109,14 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+
github.com/googleapis/gnostic v0.0.0-20170426233943-68f4ded48ba9/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.0.0-20170426233943-68f4ded48ba9/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
github.com/googleapis/gnostic v0.2.0 h1:l6N3VoaVzTncYYW+9yOz2LJJammFZGBO13sqgEhpy9g= github.com/googleapis/gnostic v0.2.0 h1:l6N3VoaVzTncYYW+9yOz2LJJammFZGBO13sqgEhpy9g=
github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
github.com/googleapis/gnostic v0.3.0 h1:CcQijm0XKekKjP/YCz28LXVSpgguuB+nCxaSjCe09y0=
github.com/googleapis/gnostic v0.3.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gregjones/httpcache v0.0.0-20190212212710-3befbb6ad0cc h1:f8eY6cV/x1x+HLjOp4r72s/31/V2aTUtg5oKRRPf8/Q= github.com/gregjones/httpcache v0.0.0-20190212212710-3befbb6ad0cc h1:f8eY6cV/x1x+HLjOp4r72s/31/V2aTUtg5oKRRPf8/Q=
github.com/gregjones/httpcache v0.0.0-20190212212710-3befbb6ad0cc/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/gregjones/httpcache v0.0.0-20190212212710-3befbb6ad0cc/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA=
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/grpc-ecosystem/grpc-gateway v1.8.5 h1:2+KSC78XiO6Qy0hIjfc1OD9H+hsaJdJlb8Kqsd41CTE= github.com/grpc-ecosystem/grpc-gateway v1.8.5 h1:2+KSC78XiO6Qy0hIjfc1OD9H+hsaJdJlb8Kqsd41CTE=
github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo= github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo=
@ -137,10 +145,14 @@ github.com/knative/build v0.5.0 h1:q2W4+BmT3jEOSOXZ44UXndJUAHLWUd20QtMQAFGWzsU=
github.com/knative/build v0.5.0/go.mod h1:/sU74ZQkwlYA5FwYDJhYTy61i/Kn+5eWfln2jDbw3Qo= github.com/knative/build v0.5.0/go.mod h1:/sU74ZQkwlYA5FwYDJhYTy61i/Kn+5eWfln2jDbw3Qo=
github.com/knative/build v0.6.0 h1:tAhqGbRL3/wFOfEc4srO8XDNV8DxUE+z6TzKW0JPWsE= github.com/knative/build v0.6.0 h1:tAhqGbRL3/wFOfEc4srO8XDNV8DxUE+z6TzKW0JPWsE=
github.com/knative/build v0.6.0/go.mod h1:/sU74ZQkwlYA5FwYDJhYTy61i/Kn+5eWfln2jDbw3Qo= github.com/knative/build v0.6.0/go.mod h1:/sU74ZQkwlYA5FwYDJhYTy61i/Kn+5eWfln2jDbw3Qo=
github.com/knative/build v0.7.0 h1:YqqiShED6wILhPRZyUJjTX2B6OgbgEqWe1WNrAcDclw=
github.com/knative/build v0.7.0/go.mod h1:/sU74ZQkwlYA5FwYDJhYTy61i/Kn+5eWfln2jDbw3Qo=
github.com/knative/pkg v0.0.0-20190329155329-916205998db9 h1:DnGe2nwEq+ibifGZt4HoD4akmX1K9Tcx3CjNwFpSZow= github.com/knative/pkg v0.0.0-20190329155329-916205998db9 h1:DnGe2nwEq+ibifGZt4HoD4akmX1K9Tcx3CjNwFpSZow=
github.com/knative/pkg v0.0.0-20190329155329-916205998db9/go.mod h1:7Ijfhw7rfB+H9VtosIsDYvZQ+qYTz7auK3fHW/5z4ww= github.com/knative/pkg v0.0.0-20190329155329-916205998db9/go.mod h1:7Ijfhw7rfB+H9VtosIsDYvZQ+qYTz7auK3fHW/5z4ww=
github.com/knative/pkg v0.0.0-20190518173526-34792a92cec2 h1:OA4f02os85BMZbC6DxNL5gbGHRxPgjQW+IDENES7QFc= github.com/knative/pkg v0.0.0-20190518173526-34792a92cec2 h1:OA4f02os85BMZbC6DxNL5gbGHRxPgjQW+IDENES7QFc=
github.com/knative/pkg v0.0.0-20190518173526-34792a92cec2/go.mod h1:7Ijfhw7rfB+H9VtosIsDYvZQ+qYTz7auK3fHW/5z4ww= github.com/knative/pkg v0.0.0-20190518173526-34792a92cec2/go.mod h1:7Ijfhw7rfB+H9VtosIsDYvZQ+qYTz7auK3fHW/5z4ww=
github.com/knative/pkg v0.0.0-20190617142447-13b093adc272 h1:8reWGJv6V0UUy8XFclP1uHEypLKPGvN9wEk4uhQVGAg=
github.com/knative/pkg v0.0.0-20190617142447-13b093adc272/go.mod h1:7Ijfhw7rfB+H9VtosIsDYvZQ+qYTz7auK3fHW/5z4ww=
github.com/knative/serving v0.5.2 h1:jsmeIN7B6oDHrK0jmtFRf7hWWr+KrjXVHuArK8jo5Nw= github.com/knative/serving v0.5.2 h1:jsmeIN7B6oDHrK0jmtFRf7hWWr+KrjXVHuArK8jo5Nw=
github.com/knative/serving v0.5.2/go.mod h1:ljvMfwQy2qanaM/8xnBSK4Mz3Vv2NawC2fo5kFRJS1A= github.com/knative/serving v0.5.2/go.mod h1:ljvMfwQy2qanaM/8xnBSK4Mz3Vv2NawC2fo5kFRJS1A=
github.com/knative/serving v0.6.0 h1:2SOr1jAvrUPO1y0mJvpiTe3bJTSMd2tKXflmHCM0MAA= github.com/knative/serving v0.6.0 h1:2SOr1jAvrUPO1y0mJvpiTe3bJTSMd2tKXflmHCM0MAA=
@ -290,6 +302,8 @@ golang.org/x/net v0.0.0-20190424112056-4829fb13d2c6 h1:FP8hkuE6yUEaJnK7O2eTuejKW
golang.org/x/net v0.0.0-20190424112056-4829fb13d2c6/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190424112056-4829fb13d2c6/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190514140710-3ec191127204 h1:4yG6GqBtw9C+UrLp6s2wtSniayy/Vd/3F7ffLE427XI= golang.org/x/net v0.0.0-20190514140710-3ec191127204 h1:4yG6GqBtw9C+UrLp6s2wtSniayy/Vd/3F7ffLE427XI=
golang.org/x/net v0.0.0-20190514140710-3ec191127204/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190514140710-3ec191127204/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190628185345-da137c7871d7 h1:rTIdg5QFRR7XCaK4LCjBiPbx8j4DQRpdYMnGn/bJUEU=
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= 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-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190319182350-c85d3e98c914/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190319182350-c85d3e98c914/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -297,6 +311,8 @@ golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a h1:tImsplftrFpALCYumobsd0
golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190517181255-950ef44c6e07 h1:XC1K3wNjuz44KaI+cj85C9TW85w/46RH7J+DTXNH5Wk= golang.org/x/oauth2 v0.0.0-20190517181255-950ef44c6e07 h1:XC1K3wNjuz44KaI+cj85C9TW85w/46RH7J+DTXNH5Wk=
golang.org/x/oauth2 v0.0.0-20190517181255-950ef44c6e07/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190517181255-950ef44c6e07/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 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-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
@ -385,7 +401,10 @@ k8s.io/kube-openapi v0.0.0-20190418160015-6b3d3b2d5666 h1:hlzz2EvLPcefAcG/j0tOZp
k8s.io/kube-openapi v0.0.0-20190418160015-6b3d3b2d5666/go.mod h1:jqYp7BKXW0Jl+F1dWXBieUmcHKMPpGHGWA0uqfpOZZ4= k8s.io/kube-openapi v0.0.0-20190418160015-6b3d3b2d5666/go.mod h1:jqYp7BKXW0Jl+F1dWXBieUmcHKMPpGHGWA0uqfpOZZ4=
k8s.io/kube-openapi v0.0.0-20190510232812-a01b7d5d6c22 h1:f0BTap/vrgs21vVbJ1ySdsNtcivpA1x4ut6Wla9HKKw= k8s.io/kube-openapi v0.0.0-20190510232812-a01b7d5d6c22 h1:f0BTap/vrgs21vVbJ1ySdsNtcivpA1x4ut6Wla9HKKw=
k8s.io/kube-openapi v0.0.0-20190510232812-a01b7d5d6c22/go.mod h1:iU+ZGYsNlvU9XKUSso6SQfKTCCw7lFduMZy26Mgr2Fw= k8s.io/kube-openapi v0.0.0-20190510232812-a01b7d5d6c22/go.mod h1:iU+ZGYsNlvU9XKUSso6SQfKTCCw7lFduMZy26Mgr2Fw=
k8s.io/kube-openapi v0.0.0-20190603182131-db7b694dc208 h1:5sW+fEHvlJI3Ngolx30CmubFulwH28DhKjGf70Xmtco=
k8s.io/kube-openapi v0.0.0-20190603182131-db7b694dc208/go.mod h1:nfDlWeOsu3pUf4yWGL+ERqohP4YsZcBJXWMK+gkzOA4=
sigs.k8s.io/structured-merge-diff v0.0.0-20181214233322-d43a45b8663b/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= sigs.k8s.io/structured-merge-diff v0.0.0-20181214233322-d43a45b8663b/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
sigs.k8s.io/structured-merge-diff v0.0.0-20190426204423-ea680f03cc65/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= sigs.k8s.io/structured-merge-diff v0.0.0-20190426204423-ea680f03cc65/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs= sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=

View File

@ -40,7 +40,7 @@ func AddNamespaceFlags(flags *pflag.FlagSet, allowAll bool) {
} }
// GetNamespace returns namespace from command specified by flag // GetNamespace returns namespace from command specified by flag
func (kn *KnParams) GetNamespace(cmd *cobra.Command) (string, error) { func (params *KnParams) GetNamespace(cmd *cobra.Command) (string, error) {
namespace := cmd.Flag("namespace").Value.String() namespace := cmd.Flag("namespace").Value.String()
// check value of all-namepace only if its defined // check value of all-namepace only if its defined
if cmd.Flags().Lookup("all-namespaces") != nil { if cmd.Flags().Lookup("all-namespaces") != nil {
@ -55,10 +55,21 @@ func (kn *KnParams) GetNamespace(cmd *cobra.Command) (string, error) {
// if all-namepaces=False or namespace not given, use default namespace // if all-namepaces=False or namespace not given, use default namespace
if namespace == "" { if namespace == "" {
var err error var err error
namespace, err = kn.NamespaceFactory() namespace, err = params.CurrentNamespace()
if err != nil { if err != nil {
return "", err return "", err
} }
} }
return namespace, nil return namespace, nil
} }
func (params *KnParams) CurrentNamespace() (string, error) {
if params.fixedCurrentNamespace != "" {
return params.fixedCurrentNamespace, nil
}
if params.ClientConfig == nil {
params.ClientConfig = params.GetClientConfig()
}
name, _, err := params.ClientConfig.Namespace()
return name, err
}

View File

@ -37,7 +37,7 @@ func TestGetNamespaceSample(t *testing.T) {
expectedNamespace := "test1" expectedNamespace := "test1"
testCmd.SetArgs([]string{"--namespace", expectedNamespace}) testCmd.SetArgs([]string{"--namespace", expectedNamespace})
testCmd.Execute() testCmd.Execute()
kp := &KnParams{NamespaceFactory: func() (string, error) { return FakeNamespace, nil }} kp := &KnParams{fixedCurrentNamespace: FakeNamespace}
actualNamespace, err := kp.GetNamespace(testCmd) actualNamespace, err := kp.GetNamespace(testCmd)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@ -52,7 +52,7 @@ func TestGetNamespaceDefault(t *testing.T) {
testCmd := testCommandGenerator(true) testCmd := testCommandGenerator(true)
expectedNamespace := "current" expectedNamespace := "current"
testCmd.Execute() testCmd.Execute()
kp := &KnParams{NamespaceFactory: func() (string, error) { return FakeNamespace, nil }} kp := &KnParams{fixedCurrentNamespace: FakeNamespace}
actualNamespace, err := kp.GetNamespace(testCmd) actualNamespace, err := kp.GetNamespace(testCmd)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@ -70,7 +70,7 @@ func TestGetNamespaceAllNamespacesSet(t *testing.T) {
sampleNamespace := "test1" sampleNamespace := "test1"
testCmd.SetArgs([]string{"--namespace", sampleNamespace, "--all-namespaces"}) testCmd.SetArgs([]string{"--namespace", sampleNamespace, "--all-namespaces"})
testCmd.Execute() testCmd.Execute()
kp := &KnParams{NamespaceFactory: func() (string, error) { return FakeNamespace, nil }} kp := &KnParams{fixedCurrentNamespace: FakeNamespace}
actualNamespace, err := kp.GetNamespace(testCmd) actualNamespace, err := kp.GetNamespace(testCmd)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@ -87,7 +87,7 @@ func TestGetNamespaceDefaultAllNamespacesUnset(t *testing.T) {
expectedNamespace := "" expectedNamespace := ""
testCmd.SetArgs([]string{"--all-namespaces"}) testCmd.SetArgs([]string{"--all-namespaces"})
testCmd.Execute() testCmd.Execute()
kp := &KnParams{NamespaceFactory: func() (string, error) { return FakeNamespace, nil }} kp := &KnParams{fixedCurrentNamespace: FakeNamespace}
actualNamespace, err := kp.GetNamespace(testCmd) actualNamespace, err := kp.GetNamespace(testCmd)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@ -103,7 +103,7 @@ func TestGetNamespaceAllNamespacesNotDefined(t *testing.T) {
expectedNamespace := "test1" expectedNamespace := "test1"
testCmd.SetArgs([]string{"--namespace", expectedNamespace}) testCmd.SetArgs([]string{"--namespace", expectedNamespace})
testCmd.Execute() testCmd.Execute()
kp := &KnParams{NamespaceFactory: func() (string, error) { return FakeNamespace, nil }} kp := &KnParams{fixedCurrentNamespace: FakeNamespace}
actualNamespace, err := kp.GetNamespace(testCmd) actualNamespace, err := kp.GetNamespace(testCmd)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)

View File

@ -18,9 +18,9 @@ import (
"errors" "errors"
"fmt" "fmt"
"github.com/knative/client/pkg/kn/commands"
"github.com/spf13/cobra" "github.com/spf13/cobra"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/knative/client/pkg/kn/commands"
) )
// NewRevisionDeleteCommand represent 'revision delete' command // NewRevisionDeleteCommand represent 'revision delete' command
@ -35,18 +35,15 @@ func NewRevisionDeleteCommand(p *commands.KnParams) *cobra.Command {
if len(args) != 1 { if len(args) != 1 {
return errors.New("'revision delete' requires the revision name given as single argument") return errors.New("'revision delete' requires the revision name given as single argument")
} }
client, err := p.ServingFactory()
if err != nil {
return err
}
namespace, err := p.GetNamespace(cmd) namespace, err := p.GetNamespace(cmd)
if err != nil { if err != nil {
return err return err
} }
err = client.Revisions(namespace).Delete( client, err := p.NewClient(namespace)
args[0], if err != nil {
&metav1.DeleteOptions{}, return err
) }
err = client.DeleteRevision(args[0])
if err != nil { if err != nil {
return err return err
} }

View File

@ -19,8 +19,6 @@ import (
"github.com/knative/client/pkg/kn/commands" "github.com/knative/client/pkg/kn/commands"
"github.com/spf13/cobra" "github.com/spf13/cobra"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/cli-runtime/pkg/genericclioptions" "k8s.io/cli-runtime/pkg/genericclioptions"
) )
@ -34,16 +32,16 @@ func NewRevisionDescribeCommand(p *commands.KnParams) *cobra.Command {
return errors.New("requires the revision name.") return errors.New("requires the revision name.")
} }
client, err := p.ServingFactory()
if err != nil {
return err
}
namespace, err := p.GetNamespace(cmd) namespace, err := p.GetNamespace(cmd)
if err != nil { if err != nil {
return err return err
} }
revision, err := client.Revisions(namespace).Get(args[0], v1.GetOptions{}) client, err := p.NewClient(namespace)
if err != nil {
return err
}
revision, err := client.GetRevision(args[0])
if err != nil { if err != nil {
return err return err
} }
@ -52,10 +50,7 @@ func NewRevisionDescribeCommand(p *commands.KnParams) *cobra.Command {
if err != nil { if err != nil {
return err return err
} }
revision.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{
Group: "knative.dev",
Version: "v1alpha1",
Kind: "Revision"})
err = printer.PrintObj(revision, cmd.OutOrStdout()) err = printer.PrintObj(revision, cmd.OutOrStdout())
if err != nil { if err != nil {
return err return err

View File

@ -17,12 +17,11 @@ package revision
import ( import (
"fmt" "fmt"
"github.com/knative/client/pkg/kn/commands" "github.com/knative/serving/pkg/apis/serving/v1alpha1"
"github.com/knative/serving/pkg/apis/serving"
"github.com/spf13/cobra" "github.com/spf13/cobra"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels" "github.com/knative/client/pkg/kn/commands"
"k8s.io/apimachinery/pkg/runtime/schema" v1alpha12 "github.com/knative/client/pkg/serving/v1alpha1"
) )
// NewRevisionListCommand represents 'kn revision list' command // NewRevisionListCommand represents 'kn revision list' command
@ -40,42 +39,47 @@ func NewRevisionListCommand(p *commands.KnParams) *cobra.Command {
# List revisions for a service 'svc1' in namespace 'myapp' # List revisions for a service 'svc1' in namespace 'myapp'
kn revision list -s svc1 -n myapp`, kn revision list -s svc1 -n myapp`,
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
client, err := p.ServingFactory()
if err != nil {
return err
}
namespace, err := p.GetNamespace(cmd) namespace, err := p.GetNamespace(cmd)
if err != nil { if err != nil {
return err return err
} }
listOptions := v1.ListOptions{} client, err := p.NewClient(namespace)
if err != nil {
return err
}
var revisionList *v1alpha1.RevisionList
if cmd.Flags().Changed("service") { if cmd.Flags().Changed("service") {
service := cmd.Flag("service").Value.String() serviceName := cmd.Flag("service").Value.String()
// Ensure requested service exist
_, err := client.Services(namespace).Get(service, v1.GetOptions{}) // Verify that service exists
_, err := client.GetService(serviceName)
if err != nil { if err != nil {
return err return err
} }
listOptions.LabelSelector = labels.Set( revisionList, err = client.ListRevisions(v1alpha12.WithService(serviceName))
map[string]string{serving.ServiceLabelKey: service}).String()
}
revision, err := client.Revisions(namespace).List(listOptions)
if err != nil { if err != nil {
return err return err
} }
if len(revision.Items) == 0 { if len(revisionList.Items) == 0 {
fmt.Fprintf(cmd.OutOrStdout(), "No resources found.\n") fmt.Fprintf(cmd.OutOrStdout(), "No revisions found for service '%s'.\n", serviceName)
return nil return nil
} }
revision.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{ } else {
Group: "knative.dev", revisionList, err = client.ListRevisions()
Version: "v1alpha1", if err != nil {
Kind: "revision"}) return err
}
if len(revisionList.Items) == 0 {
fmt.Fprintf(cmd.OutOrStdout(), "No revisions found.\n")
return nil
}
}
printer, err := revisionListFlags.ToPrinter() printer, err := revisionListFlags.ToPrinter()
if err != nil { if err != nil {
return err return err
} }
err = printer.PrintObj(revision, cmd.OutOrStdout()) err = printer.PrintObj(revisionList, cmd.OutOrStdout())
if err != nil { if err != nil {
return err return err
} }

View File

@ -18,14 +18,15 @@ import (
"strings" "strings"
"testing" "testing"
"github.com/knative/client/pkg/kn/commands" "github.com/knative/serving/pkg/apis/serving"
"github.com/knative/client/pkg/util" "github.com/knative/serving/pkg/apis/serving/v1alpha1"
serving "github.com/knative/serving/pkg/apis/serving"
v1alpha1 "github.com/knative/serving/pkg/apis/serving/v1alpha1"
"gotest.tools/assert" "gotest.tools/assert"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
client_testing "k8s.io/client-go/testing" client_testing "k8s.io/client-go/testing"
"github.com/knative/client/pkg/kn/commands"
"github.com/knative/client/pkg/util"
) )
func fakeRevisionList(args []string, response *v1alpha1.RevisionList) (action client_testing.Action, output []string, err error) { func fakeRevisionList(args []string, response *v1alpha1.RevisionList) (action client_testing.Action, output []string, err error) {
@ -55,7 +56,7 @@ func TestRevisionListEmpty(t *testing.T) {
t.Errorf("No action") t.Errorf("No action")
} else if !action.Matches("list", "revisions") { } else if !action.Matches("list", "revisions") {
t.Errorf("Bad action %v", action) t.Errorf("Bad action %v", action)
} else if output[0] != "No resources found." { } else if output[0] != "No revisions found." {
t.Errorf("Bad output %s", output[0]) t.Errorf("Bad output %s", output[0])
} }
} }
@ -115,11 +116,11 @@ func TestRevisionListForService(t *testing.T) {
} }
if action == nil { if action == nil {
t.Errorf("No action") t.Errorf("No action")
} else if !action.Matches("list", "revisions") {
t.Errorf("Bad action %v", action)
} else if !strings.Contains(output[0], "No resources found.") {
t.Errorf("Bad output %s", output[0])
} }
if !action.Matches("list", "revisions") {
t.Errorf("Bad action %v", action)
}
assert.Assert(t, util.ContainsAll(output[0], "No", "revisions", "svc3"), "no revisions")
} }
func createMockRevisionWithParams(name, svcName string) *v1alpha1.Revision { func createMockRevisionWithParams(name, svcName string) *v1alpha1.Revision {

View File

@ -18,10 +18,10 @@ import (
"fmt" "fmt"
"github.com/knative/client/pkg/kn/commands" "github.com/knative/client/pkg/kn/commands"
v1alpha12 "github.com/knative/client/pkg/serving/v1alpha1"
"github.com/knative/serving/pkg/apis/serving/v1alpha1"
"github.com/spf13/cobra" "github.com/spf13/cobra"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/runtime/schema"
) )
// NewrouteListCommand represents 'kn route list' command // NewrouteListCommand represents 'kn route list' command
@ -40,41 +40,37 @@ func NewRouteListCommand(p *commands.KnParams) *cobra.Command {
# List all routes in yaml format # List all routes in yaml format
kn route list -o yaml`, kn route list -o yaml`,
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
client, err := p.ServingFactory()
if err != nil {
return err
}
namespace, err := p.GetNamespace(cmd) namespace, err := p.GetNamespace(cmd)
if err != nil { if err != nil {
return err return err
} }
var listOptions v1.ListOptions client, err := p.NewClient(namespace)
switch len(args) {
case 0:
listOptions = v1.ListOptions{}
case 1:
listOptions.FieldSelector = fields.Set(map[string]string{"metadata.name": args[0]}).String()
default:
return fmt.Errorf("'kn route list' accepts maximum 1 argument.")
}
route, err := client.Routes(namespace).List(listOptions)
if err != nil { if err != nil {
return err return err
} }
if len(route.Items) == 0 {
var routeList *v1alpha1.RouteList
switch len(args) {
case 0:
routeList, err = client.ListRoutes()
case 1:
routeList, err = client.ListRoutes(v1alpha12.WithName(args[0]))
default:
return fmt.Errorf("'kn route list' accepts maximum 1 argument.")
}
if err != nil {
return err
}
if len(routeList.Items) == 0 {
fmt.Fprintf(cmd.OutOrStdout(), "No resources found.\n") fmt.Fprintf(cmd.OutOrStdout(), "No resources found.\n")
return nil return nil
} }
route.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{
Group: "knative.dev",
Version: "v1alpha1",
Kind: "route",
})
printer, err := routeListFlags.ToPrinter() printer, err := routeListFlags.ToPrinter()
if err != nil { if err != nil {
return err return err
} }
err = printer.PrintObj(route, cmd.OutOrStdout()) err = printer.PrintObj(routeList, cmd.OutOrStdout())
if err != nil { if err != nil {
return err return err
} }

View File

@ -21,14 +21,14 @@ import (
"time" "time"
"github.com/knative/client/pkg/kn/commands" "github.com/knative/client/pkg/kn/commands"
"github.com/knative/client/pkg/serving/v1alpha1"
serving_v1alpha1_api "github.com/knative/serving/pkg/apis/serving/v1alpha1" serving_v1alpha1_api "github.com/knative/serving/pkg/apis/serving/v1alpha1"
serving_v1alpha1_client "github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1"
"github.com/spf13/cobra" "github.com/spf13/cobra"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
api_errors "k8s.io/apimachinery/pkg/api/errors" api_errors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
) )
func NewServiceCreateCommand(p *commands.KnParams) *cobra.Command { func NewServiceCreateCommand(p *commands.KnParams) *cobra.Command {
@ -79,7 +79,7 @@ func NewServiceCreateCommand(p *commands.KnParams) *cobra.Command {
return err return err
} }
client, err := p.ServingFactory() client, err := p.NewClient(namespace)
if err != nil { if err != nil {
return err return err
} }
@ -104,8 +104,7 @@ func NewServiceCreateCommand(p *commands.KnParams) *cobra.Command {
} }
if !waitFlags.Async { if !waitFlags.Async {
waitForReady := newServiceWaitForReady(client, namespace) err := client.WaitForService(name, time.Duration(waitFlags.TimeoutInSeconds)*time.Second, cmd.OutOrStdout())
err := waitForReady.Wait(name, time.Duration(waitFlags.TimeoutInSeconds)*time.Second, cmd.OutOrStdout())
if err != nil { if err != nil {
return err return err
} }
@ -121,8 +120,8 @@ func NewServiceCreateCommand(p *commands.KnParams) *cobra.Command {
return serviceCreateCommand return serviceCreateCommand
} }
func createService(client serving_v1alpha1_client.ServingV1alpha1Interface, service *serving_v1alpha1_api.Service, namespace string, out io.Writer) error { func createService(client v1alpha1.KnClient, service *serving_v1alpha1_api.Service, namespace string, out io.Writer) error {
_, err := client.Services(namespace).Create(service) err := client.CreateService(service)
if err != nil { if err != nil {
return err return err
} }
@ -130,13 +129,13 @@ func createService(client serving_v1alpha1_client.ServingV1alpha1Interface, serv
return nil return nil
} }
func replaceService(client serving_v1alpha1_client.ServingV1alpha1Interface, service *serving_v1alpha1_api.Service, namespace string, out io.Writer) error { func replaceService(client v1alpha1.KnClient, service *serving_v1alpha1_api.Service, namespace string, out io.Writer) error {
existingService, err := client.Services(namespace).Get(service.Name, v1.GetOptions{}) existingService, err := client.GetService(service.Name)
if err != nil { if err != nil {
return err return err
} }
service.ResourceVersion = existingService.ResourceVersion service.ResourceVersion = existingService.ResourceVersion
_, err = client.Services(namespace).Update(service) err = client.UpdateService(service)
if err != nil { if err != nil {
return err return err
} }
@ -144,8 +143,8 @@ func replaceService(client serving_v1alpha1_client.ServingV1alpha1Interface, ser
return nil return nil
} }
func serviceExists(client serving_v1alpha1_client.ServingV1alpha1Interface, name string, namespace string) (bool, error) { func serviceExists(client v1alpha1.KnClient, name string, namespace string) (bool, error) {
_, err := client.Services(namespace).Get(name, v1.GetOptions{}) _, err := client.GetService(name)
if api_errors.IsNotFound(err) { if api_errors.IsNotFound(err) {
return false, nil return false, nil
} }
@ -184,8 +183,8 @@ func constructService(cmd *cobra.Command, editFlags ConfigurationEditFlags, name
return &service, nil return &service, nil
} }
func showUrl(client serving_v1alpha1_client.ServingV1alpha1Interface, serviceName string, namespace string, out io.Writer) error { func showUrl(client v1alpha1.KnClient, serviceName string, namespace string, out io.Writer) error {
service, err := client.Services(namespace).Get(serviceName, v1.GetOptions{}) service, err := client.GetService(serviceName)
if err != nil { if err != nil {
return fmt.Errorf("cannot fetch service '%s' in namespace '%s' for extracting the URL: %v", serviceName, namespace, err) return fmt.Errorf("cannot fetch service '%s' in namespace '%s' for extracting the URL: %v", serviceName, namespace, err)
} }

View File

@ -86,7 +86,7 @@ func fakeServiceCreate(args []string, withExistingService bool, sync bool) (
if !found { if !found {
return true, nil, errors.New("no field selector on metadata.name found") return true, nil, errors.New("no field selector on metadata.name found")
} }
w := wait.NewFakeWatch(getServiceEvents()) w := wait.NewFakeWatch(getServiceEvents("test-service"))
w.Start() w.Start()
return true, w, nil return true, w, nil
}) })
@ -105,11 +105,11 @@ func fakeServiceCreate(args []string, withExistingService bool, sync bool) (
return return
} }
func getServiceEvents() []watch.Event { func getServiceEvents(name string) []watch.Event {
return []watch.Event{ return []watch.Event{
{watch.Added, wait.CreateTestServiceWithConditions(corev1.ConditionUnknown, corev1.ConditionUnknown, "")}, {watch.Added, wait.CreateTestServiceWithConditions(name, corev1.ConditionUnknown, corev1.ConditionUnknown, "")},
{watch.Modified, wait.CreateTestServiceWithConditions(corev1.ConditionUnknown, corev1.ConditionTrue, "")}, {watch.Modified, wait.CreateTestServiceWithConditions(name, corev1.ConditionUnknown, corev1.ConditionTrue, "")},
{watch.Modified, wait.CreateTestServiceWithConditions(corev1.ConditionTrue, corev1.ConditionTrue, "")}, {watch.Modified, wait.CreateTestServiceWithConditions(name, corev1.ConditionTrue, corev1.ConditionTrue, "")},
} }
} }

View File

@ -20,7 +20,6 @@ import (
"github.com/knative/client/pkg/kn/commands" "github.com/knative/client/pkg/kn/commands"
"github.com/spf13/cobra" "github.com/spf13/cobra"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
) )
// NewServiceDeleteCommand represent 'service delete' command // NewServiceDeleteCommand represent 'service delete' command
@ -39,19 +38,16 @@ func NewServiceDeleteCommand(p *commands.KnParams) *cobra.Command {
if len(args) != 1 { if len(args) != 1 {
return errors.New("requires the service name.") return errors.New("requires the service name.")
} }
client, err := p.ServingFactory()
if err != nil {
return err
}
namespace, err := p.GetNamespace(cmd) namespace, err := p.GetNamespace(cmd)
if err != nil { if err != nil {
return err return err
} }
client, err := p.NewClient(namespace)
if err != nil {
return err
}
err = client.Services(namespace).Delete( err = client.DeleteService(args[0])
args[0],
&v1.DeleteOptions{},
)
if err != nil { if err != nil {
return err return err
} }

View File

@ -19,8 +19,6 @@ import (
"github.com/knative/client/pkg/kn/commands" "github.com/knative/client/pkg/kn/commands"
"github.com/spf13/cobra" "github.com/spf13/cobra"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/cli-runtime/pkg/genericclioptions" "k8s.io/cli-runtime/pkg/genericclioptions"
) )
@ -33,16 +31,17 @@ func NewServiceDescribeCommand(p *commands.KnParams) *cobra.Command {
if len(args) < 1 { if len(args) < 1 {
return errors.New("requires the service name.") return errors.New("requires the service name.")
} }
client, err := p.ServingFactory()
if err != nil {
return err
}
namespace, err := p.GetNamespace(cmd) namespace, err := p.GetNamespace(cmd)
if err != nil { if err != nil {
return err return err
} }
describeService, err := client.Services(namespace).Get(args[0], v1.GetOptions{})
client, err := p.NewClient(namespace)
if err != nil {
return err
}
describeService, err := client.GetService(args[0])
if err != nil { if err != nil {
return err return err
} }
@ -51,10 +50,6 @@ func NewServiceDescribeCommand(p *commands.KnParams) *cobra.Command {
if err != nil { if err != nil {
return err return err
} }
describeService.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{
Group: "knative.dev",
Version: "v1alpha1",
Kind: "Service"})
err = printer.PrintObj(describeService, cmd.OutOrStdout()) err = printer.PrintObj(describeService, cmd.OutOrStdout())
if err != nil { if err != nil {
return err return err

View File

@ -19,8 +19,6 @@ import (
"github.com/knative/client/pkg/kn/commands" "github.com/knative/client/pkg/kn/commands"
"github.com/spf13/cobra" "github.com/spf13/cobra"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
) )
// NewServiceListCommand represents 'kn service list' command // NewServiceListCommand represents 'kn service list' command
@ -31,33 +29,28 @@ func NewServiceListCommand(p *commands.KnParams) *cobra.Command {
Use: "list", Use: "list",
Short: "List available services.", Short: "List available services.",
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
client, err := p.ServingFactory()
if err != nil {
return err
}
namespace, err := p.GetNamespace(cmd) namespace, err := p.GetNamespace(cmd)
if err != nil { if err != nil {
return err return err
} }
service, err := client.Services(namespace).List(v1.ListOptions{}) client, err := p.NewClient(namespace)
if err != nil { if err != nil {
return err return err
} }
if len(service.Items) == 0 { serviceList, err := client.ListServices()
if err != nil {
return err
}
if len(serviceList.Items) == 0 {
fmt.Fprintf(cmd.OutOrStdout(), "No resources found.\n") fmt.Fprintf(cmd.OutOrStdout(), "No resources found.\n")
return nil return nil
} }
service.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{
Group: "knative.dev",
Version: "v1alpha1",
Kind: "Service"})
printer, err := serviceListFlags.ToPrinter() printer, err := serviceListFlags.ToPrinter()
if err != nil { if err != nil {
return err return err
} }
err = printer.PrintObj(service, cmd.OutOrStdout()) err = printer.PrintObj(serviceList, cmd.OutOrStdout())
if err != nil { if err != nil {
return err return err
} }

View File

@ -21,7 +21,7 @@ import (
"github.com/knative/client/pkg/kn/commands" "github.com/knative/client/pkg/kn/commands"
"github.com/knative/client/pkg/util" "github.com/knative/client/pkg/util"
duckv1beta1 "github.com/knative/pkg/apis/duck/v1beta1" duckv1beta1 "github.com/knative/pkg/apis/duck/v1beta1"
v1alpha1 "github.com/knative/serving/pkg/apis/serving/v1alpha1" "github.com/knative/serving/pkg/apis/serving/v1alpha1"
"gotest.tools/assert" "gotest.tools/assert"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"

View File

@ -20,7 +20,6 @@ import (
"github.com/knative/client/pkg/kn/commands" "github.com/knative/client/pkg/kn/commands"
"github.com/spf13/cobra" "github.com/spf13/cobra"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
) )
func NewServiceUpdateCommand(p *commands.KnParams) *cobra.Command { func NewServiceUpdateCommand(p *commands.KnParams) *cobra.Command {
@ -48,12 +47,12 @@ func NewServiceUpdateCommand(p *commands.KnParams) *cobra.Command {
return err return err
} }
client, err := p.ServingFactory() client, err := p.NewClient(namespace)
if err != nil { if err != nil {
return err return err
} }
service, err := client.Services(namespace).Get(args[0], v1.GetOptions{}) service, err := client.GetService(args[0])
if err != nil { if err != nil {
return err return err
} }
@ -64,7 +63,7 @@ func NewServiceUpdateCommand(p *commands.KnParams) *cobra.Command {
return err return err
} }
_, err = client.Services(namespace).Update(service) err = client.UpdateService(service)
if err != nil { if err != nil {
return err return err
} }

View File

@ -18,7 +18,7 @@ import (
"bytes" "bytes"
"flag" "flag"
serving "github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1" "github.com/knative/client/pkg/serving/v1alpha1"
"github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/fake" "github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/fake"
"github.com/spf13/cobra" "github.com/spf13/cobra"
client_testing "k8s.io/client-go/testing" client_testing "k8s.io/client-go/testing"
@ -30,8 +30,10 @@ func CreateTestKnCommand(cmd *cobra.Command, knParams *KnParams) (*cobra.Command
buf := new(bytes.Buffer) buf := new(bytes.Buffer)
fakeServing := &fake.FakeServingV1alpha1{&client_testing.Fake{}} fakeServing := &fake.FakeServingV1alpha1{&client_testing.Fake{}}
knParams.Output = buf knParams.Output = buf
knParams.ServingFactory = func() (serving.ServingV1alpha1Interface, error) { return fakeServing, nil } knParams.NewClient = func(namespace string) (v1alpha1.KnClient, error) {
knParams.NamespaceFactory = func() (string, error) { return FakeNamespace, nil } return v1alpha1.NewKnServingClient(fakeServing, namespace), nil
}
knParams.fixedCurrentNamespace = FakeNamespace
knCommand := newKnCommand(cmd, knParams) knCommand := newKnCommand(cmd, knParams)
return knCommand, fakeServing, buf return knCommand, fakeServing, buf
} }

View File

@ -17,7 +17,9 @@ package commands
import ( import (
"io" "io"
serving "github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1" serving_kn_v1alpha1 "github.com/knative/client/pkg/serving/v1alpha1"
serving_v1alpha1_client "github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1"
"k8s.io/client-go/tools/clientcmd" "k8s.io/client-go/tools/clientcmd"
) )
@ -27,50 +29,44 @@ var CfgFile string
// Parameters for creating commands. Useful for inserting mocks for testing. // Parameters for creating commands. Useful for inserting mocks for testing.
type KnParams struct { type KnParams struct {
Output io.Writer Output io.Writer
ServingFactory func() (serving.ServingV1alpha1Interface, error)
NamespaceFactory func() (string, error)
KubeCfgPath string KubeCfgPath string
ClientConfig clientcmd.ClientConfig ClientConfig clientcmd.ClientConfig
NewClient func(namespace string) (serving_kn_v1alpha1.KnClient, error)
// Set this if you want to nail down the namespace
fixedCurrentNamespace string
} }
func (c *KnParams) Initialize() { func (params *KnParams) Initialize() {
if c.ServingFactory == nil { if params.NewClient == nil {
c.ServingFactory = c.GetConfig params.NewClient = params.newClient
}
if c.NamespaceFactory == nil {
c.NamespaceFactory = c.CurrentNamespace
} }
} }
func (c *KnParams) CurrentNamespace() (string, error) { func (params *KnParams) newClient(namespace string) (serving_kn_v1alpha1.KnClient, error) {
if c.ClientConfig == nil { client, err := params.GetConfig()
c.ClientConfig = c.GetClientConfig() if err != nil {
return nil, err
} }
name, _, err := c.ClientConfig.Namespace() return serving_kn_v1alpha1.NewKnServingClient(client, namespace), nil
return name, err
} }
func (c *KnParams) GetConfig() (serving.ServingV1alpha1Interface, error) { func (params *KnParams) GetConfig() (serving_v1alpha1_client.ServingV1alpha1Interface, error) {
if c.ClientConfig == nil { if params.ClientConfig == nil {
c.ClientConfig = c.GetClientConfig() params.ClientConfig = params.GetClientConfig()
} }
var err error var err error
config, err := c.ClientConfig.ClientConfig() config, err := params.ClientConfig.ClientConfig()
if err != nil { if err != nil {
return nil, err return nil, err
} }
client, err := serving.NewForConfig(config) return serving_v1alpha1_client.NewForConfig(config)
if err != nil {
return nil, err
}
return client, nil
} }
func (c *KnParams) GetClientConfig() clientcmd.ClientConfig { func (params *KnParams) GetClientConfig() clientcmd.ClientConfig {
loadingRules := clientcmd.NewDefaultClientConfigLoadingRules() loadingRules := clientcmd.NewDefaultClientConfigLoadingRules()
if len(c.KubeCfgPath) > 0 { if len(params.KubeCfgPath) > 0 {
loadingRules.ExplicitPath = c.KubeCfgPath loadingRules.ExplicitPath = params.KubeCfgPath
} }
return clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, &clientcmd.ConfigOverrides{}) return clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, &clientcmd.ConfigOverrides{})
} }

View File

@ -25,13 +25,16 @@ import (
"github.com/knative/client/pkg/kn/commands/revision" "github.com/knative/client/pkg/kn/commands/revision"
"github.com/knative/client/pkg/kn/commands/route" "github.com/knative/client/pkg/kn/commands/route"
"github.com/knative/client/pkg/kn/commands/service" "github.com/knative/client/pkg/kn/commands/service"
homedir "github.com/mitchellh/go-homedir" "github.com/mitchellh/go-homedir"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper" "github.com/spf13/viper"
_ "k8s.io/client-go/plugin/pkg/client/auth/gcp" _ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
_ "k8s.io/client-go/plugin/pkg/client/auth/oidc" _ "k8s.io/client-go/plugin/pkg/client/auth/oidc"
) )
var cfgFile string
var kubeCfgFile string
// NewKnCommand creates new rootCmd represents the base command when called without any subcommands // NewKnCommand creates new rootCmd represents the base command when called without any subcommands
func NewKnCommand(params ...commands.KnParams) *cobra.Command { func NewKnCommand(params ...commands.KnParams) *cobra.Command {
var p *commands.KnParams var p *commands.KnParams

View File

@ -0,0 +1,48 @@
// Copyright © 2019 The Knative 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 serving
import (
"errors"
"fmt"
"github.com/knative/serving/pkg/client/clientset/versioned/scheme"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
)
// Update the GVK on the given object, based on the GVK registered in into the serving scheme
// for the given GroupVersion
func UpdateGroupVersionKind(obj runtime.Object, gv schema.GroupVersion) error {
gvk, err := GetGroupVersionKind(obj, gv)
if err != nil {
return err
}
obj.GetObjectKind().SetGroupVersionKind(*gvk)
return nil
}
func GetGroupVersionKind(obj runtime.Object, gv schema.GroupVersion) (*schema.GroupVersionKind, error) {
gvks, _, err := scheme.Scheme.ObjectKinds(obj)
if err != nil {
return nil, err
}
for _, gvk := range gvks {
if gvk.GroupVersion() == gv {
return &gvk, nil
}
}
return nil, errors.New(fmt.Sprintf("no group version %s registered in %s", gv, scheme.Scheme.Name()))
}

View File

@ -0,0 +1,44 @@
// Copyright © 2019 The Knative 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 serving
import (
"testing"
"github.com/knative/serving/pkg/apis/serving/v1alpha1"
"k8s.io/apimachinery/pkg/runtime/schema"
)
func TestGVKUpdate(t *testing.T) {
service := v1alpha1.Service{}
err := UpdateGroupVersionKind(&service, v1alpha1.SchemeGroupVersion)
if err != nil {
t.Fatalf("cannot update GVK to a service %v", err)
}
if service.Kind != "Service" {
t.Fatalf("wrong kind '%s'", service.Kind)
}
if service.APIVersion != v1alpha1.SchemeGroupVersion.Group+"/"+v1alpha1.SchemeGroupVersion.Version {
t.Fatalf("wrong version '%s'", service.APIVersion)
}
}
func TestGVKUpdateNegative(t *testing.T) {
service := v1alpha1.Service{}
err := UpdateGroupVersionKind(&service, schema.GroupVersion{Group: "bla", Version: "blub"})
if err == nil {
t.Fatal("expect an error for an unregistered group version")
}
}

View File

@ -0,0 +1,295 @@
// Copyright © 2019 The Knative Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package v1alpha1
import (
"fmt"
"io"
"time"
"github.com/knative/pkg/apis"
"k8s.io/apimachinery/pkg/fields"
"github.com/knative/client/pkg/serving"
"github.com/knative/client/pkg/wait"
api_serving "github.com/knative/serving/pkg/apis/serving"
"github.com/knative/serving/pkg/apis/serving/v1alpha1"
client_v1alpha1 "github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
)
// Kn interface to serving. All methods are relative to the
// namespace specified during construction
type KnClient interface {
// Get a service by its unique name
GetService(name string) (*v1alpha1.Service, error)
// List services
ListServices(opts ...ListConfig) (*v1alpha1.ServiceList, error)
// Create a new service
CreateService(service *v1alpha1.Service) error
// Update the given service
UpdateService(service *v1alpha1.Service) error
// Delete a service by name
DeleteService(name string) error
// Wait for a service to become ready, but not longer than provided timeout
WaitForService(name string, timeout time.Duration, out io.Writer) error
// Get a revision by name
GetRevision(name string) (*v1alpha1.Revision, error)
// List revisions
ListRevisions(opts ...ListConfig) (*v1alpha1.RevisionList, error)
// Delete a revision
DeleteRevision(name string) error
// List routes
ListRoutes(opts ...ListConfig) (*v1alpha1.RouteList, error)
}
type listConfig struct {
// Labels to filter on
Labels labels.Set
// Labels to filter on
Fields fields.Set
}
// Config function for builder pattern
type ListConfig func(config *listConfig)
type ListConfigs []ListConfig
// add selectors to a list options
func (opts ListConfigs) toListOptions() v1.ListOptions {
listConfig := listConfig{labels.Set{}, fields.Set{}}
for _, f := range opts {
f(&listConfig)
}
options := v1.ListOptions{}
if len(listConfig.Fields) > 0 {
options.FieldSelector = listConfig.Fields.String()
}
if len(listConfig.Labels) > 0 {
options.LabelSelector = listConfig.Labels.String()
}
return options
}
// Filter list on the provided name
func WithName(name string) ListConfig {
return func(lo *listConfig) {
lo.Fields["metadata.name"] = name
}
}
// Filter on the service name
func WithService(service string) ListConfig {
return func(lo *listConfig) {
lo.Labels[api_serving.ServiceLabelKey] = service
}
}
type knClient struct {
client client_v1alpha1.ServingV1alpha1Interface
namespace string
}
// Create a new client facade for the provided namespace
func NewKnServingClient(client client_v1alpha1.ServingV1alpha1Interface, namespace string) KnClient {
return &knClient{
client: client,
namespace: namespace,
}
}
// Get a service by its unique name
func (cl *knClient) GetService(name string) (*v1alpha1.Service, error) {
service, err := cl.client.Services(cl.namespace).Get(name, v1.GetOptions{})
if err != nil {
return nil, err
}
err = serving.UpdateGroupVersionKind(service, v1alpha1.SchemeGroupVersion)
if err != nil {
return nil, err
}
return service, nil
}
// List services
func (cl *knClient) ListServices(config ...ListConfig) (*v1alpha1.ServiceList, error) {
serviceList, err := cl.client.Services(cl.namespace).List(ListConfigs(config).toListOptions())
if err != nil {
return nil, err
}
serviceListNew := serviceList.DeepCopy()
err = updateServingGvk(serviceListNew)
if err != nil {
return nil, err
}
serviceListNew.Items = make([]v1alpha1.Service, len(serviceList.Items))
for idx, service := range serviceList.Items {
serviceClone := service.DeepCopy()
err := updateServingGvk(serviceClone)
if err != nil {
return nil, err
}
serviceListNew.Items[idx] = *serviceClone
}
return serviceListNew, nil
}
// Create a new service
func (cl *knClient) CreateService(service *v1alpha1.Service) error {
_, err := cl.client.Services(cl.namespace).Create(service)
if err != nil {
return err
}
return updateServingGvk(service)
}
// Update the given service
func (cl *knClient) UpdateService(service *v1alpha1.Service) error {
_, err := cl.client.Services(cl.namespace).Update(service)
if err != nil {
return err
}
return updateServingGvk(service)
}
// Delete a service by name
func (cl *knClient) DeleteService(serviceName string) error {
return cl.client.Services(cl.namespace).Delete(
serviceName,
&v1.DeleteOptions{},
)
}
// Wait for a service to become ready, but not longer than provided timeout
func (cl *knClient) WaitForService(name string, timeout time.Duration, out io.Writer) error {
waitForReady := newServiceWaitForReady(cl.client.Services(cl.namespace).Watch)
return waitForReady.Wait(name, timeout, out)
}
// Get a revision by name
func (cl *knClient) GetRevision(name string) (*v1alpha1.Revision, error) {
revision, err := cl.client.Revisions(cl.namespace).Get(name, v1.GetOptions{})
if err != nil {
return nil, err
}
err = updateServingGvk(revision)
if err != nil {
return nil, err
}
return revision, nil
}
// Delete a revision by name
func (cl *knClient) DeleteRevision(name string) error {
return cl.client.Revisions(cl.namespace).Delete(name, &v1.DeleteOptions{})
}
// List revisions
func (cl *knClient) ListRevisions(config ...ListConfig) (*v1alpha1.RevisionList, error) {
revisionList, err := cl.client.Revisions(cl.namespace).List(ListConfigs(config).toListOptions())
if err != nil {
return nil, err
}
return updateServingGvkForRevisionList(revisionList)
}
// List routes
func (cl *knClient) ListRoutes(config ...ListConfig) (*v1alpha1.RouteList, error) {
routeList, err := cl.client.Routes(cl.namespace).List(ListConfigs(config).toListOptions())
if err != nil {
return nil, err
}
return updateServingGvkForRouteList(routeList)
}
// update all the list + all items contained in the list with
// the proper GroupVersionKind specific to Knative serving
func updateServingGvkForRevisionList(revisionList *v1alpha1.RevisionList) (*v1alpha1.RevisionList, error) {
revisionListNew := revisionList.DeepCopy()
err := updateServingGvk(revisionListNew)
if err != nil {
return nil, err
}
revisionListNew.Items = make([]v1alpha1.Revision, len(revisionList.Items))
for idx := range revisionList.Items {
revision := revisionList.Items[idx].DeepCopy()
err := updateServingGvk(revision)
if err != nil {
return nil, err
}
revisionListNew.Items[idx] = *revision
}
return revisionListNew, nil
}
// update all the list + all items contained in the list with
// the proper GroupVersionKind specific to Knative serving
func updateServingGvkForRouteList(routeList *v1alpha1.RouteList) (*v1alpha1.RouteList, error) {
routeListNew := routeList.DeepCopy()
err := updateServingGvk(routeListNew)
if err != nil {
return nil, err
}
routeListNew.Items = make([]v1alpha1.Route, len(routeList.Items))
for idx := range routeList.Items {
revision := routeList.Items[idx].DeepCopy()
err := updateServingGvk(revision)
if err != nil {
return nil, err
}
routeListNew.Items[idx] = *revision
}
return routeListNew, nil
}
// update with the v1alpha1 group + version
func updateServingGvk(obj runtime.Object) error {
return serving.UpdateGroupVersionKind(obj, v1alpha1.SchemeGroupVersion)
}
// Create wait arguments for a Knative service which can be used to wait for
// a create/update options to be finished
// Can be used by `service_create` and `service_update`, hence this extra file
func newServiceWaitForReady(watch wait.WatchFunc) wait.WaitForReady {
return wait.NewWaitForReady(
"service",
watch,
serviceConditionExtractor)
}
func serviceConditionExtractor(obj runtime.Object) (apis.Conditions, error) {
service, ok := obj.(*v1alpha1.Service)
if !ok {
return nil, fmt.Errorf("%v is not a service", obj)
}
return apis.Conditions(service.Status.Conditions), nil
}

View File

@ -0,0 +1,399 @@
// Copyright © 2019 The Knative Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package v1alpha1
import (
"bytes"
"fmt"
"testing"
"time"
"gotest.tools/assert"
"gotest.tools/assert/cmp"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/watch"
serving_api "github.com/knative/serving/pkg/apis/serving"
"github.com/knative/serving/pkg/apis/serving/v1alpha1"
"github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/fake"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
client_testing "k8s.io/client-go/testing"
"github.com/knative/client/pkg/serving"
"github.com/knative/client/pkg/wait"
)
var testNamespace = "test-ns"
func setup() (serving fake.FakeServingV1alpha1, client KnClient) {
serving = fake.FakeServingV1alpha1{Fake: &client_testing.Fake{}}
client = NewKnServingClient(&serving, testNamespace)
return
}
func TestGetService(t *testing.T) {
serving, client := setup()
serviceName := "test-service"
serving.AddReactor("get", "services",
func(a client_testing.Action) (bool, runtime.Object, error) {
service := newService(serviceName)
name := a.(client_testing.GetAction).GetName()
// Sanity check
assert.Assert(t, name != "")
assert.Equal(t, testNamespace, a.GetNamespace())
if name == serviceName {
return true, service, nil
}
return true, nil, errors.NewNotFound(v1alpha1.Resource("service"), name)
})
t.Run("get known service by name returns service", func(t *testing.T) {
service, err := client.GetService(serviceName)
assert.NilError(t, err)
assert.Equal(t, serviceName, service.Name, "service name should be equal")
validateGroupVersionKind(t, service)
})
t.Run("get unknown service name returns error", func(t *testing.T) {
nonExistingServiceName := "service-that-does-not-exist"
service, err := client.GetService(nonExistingServiceName)
assert.Assert(t, service == nil, "no service should be returned")
assert.ErrorContains(t, err, "not found")
assert.ErrorContains(t, err, nonExistingServiceName)
})
}
func TestListService(t *testing.T) {
serving, client := setup()
t.Run("list service returns a list of services", func(t *testing.T) {
service1 := newService("service-1")
service2 := newService("service-2")
serving.AddReactor("list", "services",
func(a client_testing.Action) (bool, runtime.Object, error) {
assert.Equal(t, testNamespace, a.GetNamespace())
return true, &v1alpha1.ServiceList{Items: []v1alpha1.Service{*service1, *service2}}, nil
})
listServices, err := client.ListServices()
assert.NilError(t, err)
assert.Assert(t, len(listServices.Items) == 2)
assert.Equal(t, listServices.Items[0].Name, "service-1")
assert.Equal(t, listServices.Items[1].Name, "service-2")
validateGroupVersionKind(t, listServices)
validateGroupVersionKind(t, &listServices.Items[0])
validateGroupVersionKind(t, &listServices.Items[1])
})
}
func TestCreateService(t *testing.T) {
serving, client := setup()
serviceNew := newService("new-service")
serving.AddReactor("create", "services",
func(a client_testing.Action) (bool, runtime.Object, error) {
assert.Equal(t, testNamespace, a.GetNamespace())
name := a.(client_testing.CreateAction).GetObject().(metav1.Object).GetName()
if name == serviceNew.Name {
serviceNew.Generation = 2
return true, serviceNew, nil
}
return true, nil, fmt.Errorf("error while creating service %s", name)
})
t.Run("create service without error creates a new service", func(t *testing.T) {
err := client.CreateService(serviceNew)
assert.NilError(t, err)
assert.Equal(t, serviceNew.Generation, int64(2))
validateGroupVersionKind(t, serviceNew)
})
t.Run("create service with an error returns an error object", func(t *testing.T) {
err := client.CreateService(newService("unknown"))
assert.ErrorContains(t, err, "unknown")
})
}
func TestUpdateService(t *testing.T) {
serving, client := setup()
serviceUpdate := newService("update-service")
serving.AddReactor("update", "services",
func(a client_testing.Action) (bool, runtime.Object, error) {
assert.Equal(t, testNamespace, a.GetNamespace())
name := a.(client_testing.UpdateAction).GetObject().(metav1.Object).GetName()
if name == serviceUpdate.Name {
serviceUpdate.Generation = 3
return true, serviceUpdate, nil
}
return true, nil, fmt.Errorf("error while updating service %s", name)
})
t.Run("updating a service without error", func(t *testing.T) {
err := client.UpdateService(serviceUpdate)
assert.NilError(t, err)
assert.Equal(t, int64(3), serviceUpdate.Generation)
validateGroupVersionKind(t, serviceUpdate)
})
t.Run("updating a service with error", func(t *testing.T) {
err := client.UpdateService(newService("unknown"))
assert.ErrorContains(t, err, "unknown")
})
}
func TestDeleteService(t *testing.T) {
serving, client := setup()
const (
serviceName = "test-service"
nonExistingServiceName = "no-service"
)
serving.AddReactor("delete", "services",
func(a client_testing.Action) (bool, runtime.Object, error) {
name := a.(client_testing.DeleteAction).GetName()
// Sanity check
assert.Assert(t, name != "")
assert.Equal(t, testNamespace, a.GetNamespace())
if name == serviceName {
return true, nil, nil
}
return true, nil, errors.NewNotFound(v1alpha1.Resource("service"), name)
})
t.Run("delete existing service returns no error", func(t *testing.T) {
err := client.DeleteService(serviceName)
assert.NilError(t, err)
})
t.Run("trying to delete non-existing service returns error", func(t *testing.T) {
err := client.DeleteService(nonExistingServiceName)
assert.ErrorContains(t, err, "not found")
assert.ErrorContains(t, err, nonExistingServiceName)
})
}
func TestGetRevision(t *testing.T) {
serving, client := setup()
const (
revisionName = "test-revision"
notExistingRevisionName = "no-revision"
)
serving.AddReactor("get", "revisions",
func(a client_testing.Action) (bool, runtime.Object, error) {
revision := newRevision(revisionName)
name := a.(client_testing.GetAction).GetName()
// Sanity check
assert.Assert(t, name != "")
assert.Equal(t, testNamespace, a.GetNamespace())
if name == revisionName {
return true, revision, nil
}
return true, nil, errors.NewNotFound(v1alpha1.Resource("revision"), name)
})
t.Run("get existing revision returns revision and no error", func(t *testing.T) {
revision, err := client.GetRevision(revisionName)
assert.NilError(t, err)
assert.Equal(t, revisionName, revision.Name)
validateGroupVersionKind(t, revision)
})
t.Run("trying to get a revision with a name that does not exist returns an error", func(t *testing.T) {
revision, err := client.GetRevision(notExistingRevisionName)
assert.Assert(t, revision == nil)
assert.ErrorContains(t, err, notExistingRevisionName)
assert.ErrorContains(t, err, "not found")
})
}
func TestListRevisions(t *testing.T) {
serving, client := setup()
revisions := []v1alpha1.Revision{*newRevision("revision-1"), *newRevision("revision-2")}
serving.AddReactor("list", "revisions",
func(a client_testing.Action) (bool, runtime.Object, error) {
assert.Equal(t, testNamespace, a.GetNamespace())
return true, &v1alpha1.RevisionList{Items: revisions}, nil
})
t.Run("list revisions returns a list of revisions and no error", func(t *testing.T) {
revisions, err := client.ListRevisions()
assert.NilError(t, err)
assert.Assert(t, len(revisions.Items) == 2)
assert.Equal(t, revisions.Items[0].Name, "revision-1")
assert.Equal(t, revisions.Items[1].Name, "revision-2")
validateGroupVersionKind(t, revisions)
validateGroupVersionKind(t, &revisions.Items[0])
validateGroupVersionKind(t, &revisions.Items[1])
})
}
func TestListRevisionForService(t *testing.T) {
serving, client := setup()
serviceName := "service"
serving.AddReactor("list", "revisions",
func(a client_testing.Action) (bool, runtime.Object, error) {
revisions := []v1alpha1.Revision{
*newRevision("revision-1", serving_api.ServiceLabelKey, "service"),
*newRevision("revision-2"),
}
lAction := a.(client_testing.ListAction)
assert.Equal(t, testNamespace, a.GetNamespace())
restrictions := lAction.GetListRestrictions()
assert.Check(t, restrictions.Fields.Empty())
servicesLabels := labels.Set{serving_api.ServiceLabelKey: serviceName}
assert.Check(t, restrictions.Labels.Matches(servicesLabels))
return true, &v1alpha1.RevisionList{Items: revisions}, nil
})
t.Run("list revisions for a service returns a list of revisions associated with this this service and no error",
func(t *testing.T) {
revisions, err := client.ListRevisions(WithService(serviceName))
assert.NilError(t, err)
assert.Assert(t, cmp.Len(revisions.Items, 1))
assert.Equal(t, revisions.Items[0].Name, "revision-1")
assert.Equal(t, revisions.Items[0].Labels[serving_api.ServiceLabelKey], "service")
validateGroupVersionKind(t, revisions)
validateGroupVersionKind(t, &revisions.Items[0])
})
}
func TestListRoutes(t *testing.T) {
serving, client := setup()
singleRouteName := "route-2"
singleRoute := *newRoute(singleRouteName)
routes := []v1alpha1.Route{*newRoute("route-1"), singleRoute, *newRoute("route-3")}
serving.AddReactor("list", "routes",
func(a client_testing.Action) (bool, runtime.Object, error) {
assert.Equal(t, testNamespace, a.GetNamespace())
lAction := a.(client_testing.ListAction)
restrictions := lAction.GetListRestrictions()
assert.Assert(t, restrictions.Labels.Empty())
if !restrictions.Fields.Empty() {
nameField := fields.Set{"metadata.name": singleRouteName}
assert.Check(t, restrictions.Labels.Matches(nameField))
return true, &v1alpha1.RouteList{Items: []v1alpha1.Route{singleRoute}}, nil
}
return true, &v1alpha1.RouteList{Items: routes}, nil
})
t.Run("list routes returns a list of routes and no error", func(t *testing.T) {
routes, err := client.ListRoutes()
assert.NilError(t, err)
assert.Assert(t, len(routes.Items) == 3)
assert.Equal(t, routes.Items[0].Name, "route-1")
assert.Equal(t, routes.Items[1].Name, singleRouteName)
assert.Equal(t, routes.Items[2].Name, "route-3")
validateGroupVersionKind(t, routes)
for i := 0; i < len(routes.Items); i++ {
validateGroupVersionKind(t, &routes.Items[i])
}
})
t.Run("list routes with a name filter a list with one route and no error", func(t *testing.T) {
routes, err := client.ListRoutes(WithName(singleRouteName))
assert.NilError(t, err)
assert.Assert(t, len(routes.Items) == 1)
assert.Equal(t, routes.Items[0].Name, singleRouteName)
validateGroupVersionKind(t, routes)
validateGroupVersionKind(t, &routes.Items[0])
})
}
func TestWaitForService(t *testing.T) {
serving, client := setup()
serviceName := "test-service"
serving.AddWatchReactor("services",
func(a client_testing.Action) (bool, watch.Interface, error) {
watchAction := a.(client_testing.WatchAction)
_, found := watchAction.GetWatchRestrictions().Fields.RequiresExactMatch("metadata.name")
if !found {
return true, nil, fmt.Errorf("no field selector on metadata.name found")
}
w := wait.NewFakeWatch(getServiceEvents(serviceName))
w.Start()
return true, w, nil
})
serving.AddReactor("get", "services",
func(a client_testing.Action) (bool, runtime.Object, error) {
getAction := a.(client_testing.GetAction)
assert.Equal(t, getAction.GetName(), serviceName)
return true, newService(serviceName), nil
})
t.Run("wait on a service to become ready with success", func(t *testing.T) {
buf := new(bytes.Buffer)
err := client.WaitForService(serviceName, 60*time.Second, buf)
assert.NilError(t, err)
})
}
func validateGroupVersionKind(t *testing.T, obj runtime.Object) {
gvkExpected, err := serving.GetGroupVersionKind(obj, v1alpha1.SchemeGroupVersion)
assert.NilError(t, err)
gvkGiven := obj.GetObjectKind().GroupVersionKind()
assert.Equal(t, *gvkExpected, gvkGiven, "GVK should be the same")
}
func newService(name string) *v1alpha1.Service {
return &v1alpha1.Service{ObjectMeta: metav1.ObjectMeta{Name: name, Namespace: testNamespace}}
}
func newRevision(name string, labels ...string) *v1alpha1.Revision {
rev := &v1alpha1.Revision{ObjectMeta: metav1.ObjectMeta{Name: name, Namespace: testNamespace}}
labelMap := make(map[string]string)
if len(labels) > 0 {
for i := 0; i < len(labels); i += 2 {
labelMap[labels[i]] = labels[i+1]
}
rev.Labels = labelMap
}
return rev
}
func newRoute(name string) *v1alpha1.Route {
return &v1alpha1.Route{ObjectMeta: metav1.ObjectMeta{Name: name, Namespace: testNamespace}}
}
func getServiceEvents(name string) []watch.Event {
return []watch.Event{
{watch.Added, wait.CreateTestServiceWithConditions(name, corev1.ConditionUnknown, corev1.ConditionUnknown, "")},
{watch.Modified, wait.CreateTestServiceWithConditions(name, corev1.ConditionUnknown, corev1.ConditionTrue, "")},
{watch.Modified, wait.CreateTestServiceWithConditions(name, corev1.ConditionTrue, corev1.ConditionTrue, "")},
}
}

View File

@ -0,0 +1,15 @@
// Copyright © 2019 The Knative Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package v1alpha1

View File

@ -18,6 +18,7 @@ import (
"github.com/knative/pkg/apis" "github.com/knative/pkg/apis"
"github.com/knative/serving/pkg/apis/serving/v1alpha1" "github.com/knative/serving/pkg/apis/serving/v1alpha1"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/watch" "k8s.io/apimachinery/pkg/watch"
) )
@ -61,9 +62,9 @@ func (f *FakeWatch) fireEvents() {
} }
} }
// Create a service skeletion with a given ConditionReady status and all other statuses set to otherReadyStatus. Optionally a single generation can be added. // Create a service skeleton with a given ConditionReady status and all other statuses set to otherReadyStatus. Optionally a single generation can be added.
func CreateTestServiceWithConditions(readyStatus corev1.ConditionStatus, otherReadyStatus corev1.ConditionStatus, reason string, generations ...int64) runtime.Object { func CreateTestServiceWithConditions(name string, readyStatus corev1.ConditionStatus, otherReadyStatus corev1.ConditionStatus, reason string, generations ...int64) runtime.Object {
service := v1alpha1.Service{} service := v1alpha1.Service{ObjectMeta: metav1.ObjectMeta{Name: name}}
if len(generations) == 2 { if len(generations) == 2 {
service.Generation = generations[0] service.Generation = generations[0]
service.Status.ObservedGeneration = generations[1] service.Status.ObservedGeneration = generations[1]

View File

@ -37,7 +37,7 @@ type waitForReadyTestCase struct {
func TestAddWaitForReady(t *testing.T) { func TestAddWaitForReady(t *testing.T) {
for i, tc := range prepareTestCases() { for i, tc := range prepareTestCases("test-service") {
fakeWatchApi := NewFakeWatch(tc.events) fakeWatchApi := NewFakeWatch(tc.events)
outBuffer := new(bytes.Buffer) outBuffer := new(bytes.Buffer)
@ -79,41 +79,41 @@ func TestAddWaitForReady(t *testing.T) {
} }
// Test cases which consists of a series of events to send and the expected behaviour. // Test cases which consists of a series of events to send and the expected behaviour.
func prepareTestCases() []waitForReadyTestCase { func prepareTestCases(name string) []waitForReadyTestCase {
return []waitForReadyTestCase{ return []waitForReadyTestCase{
{peNormal(), time.Second, false, []string{"OK", "foobar", "blub"}}, {peNormal(name), time.Second, false, []string{"OK", "foobar", "blub"}},
{peError(), time.Second, true, []string{"FakeError"}}, {peError(name), time.Second, true, []string{"FakeError"}},
{peTimeout(), time.Second, true, []string{"timeout"}}, {peTimeout(name), time.Second, true, []string{"timeout"}},
{peWrongGeneration(), time.Second, true, []string{"timeout"}}, {peWrongGeneration(name), time.Second, true, []string{"timeout"}},
} }
} }
// ============================================================================= // =============================================================================
func peNormal() []watch.Event { func peNormal(name string) []watch.Event {
return []watch.Event{ return []watch.Event{
{watch.Added, CreateTestServiceWithConditions(corev1.ConditionUnknown, corev1.ConditionUnknown, "")}, {watch.Added, CreateTestServiceWithConditions(name, corev1.ConditionUnknown, corev1.ConditionUnknown, "")},
{watch.Modified, CreateTestServiceWithConditions(corev1.ConditionUnknown, corev1.ConditionTrue, "")}, {watch.Modified, CreateTestServiceWithConditions(name, corev1.ConditionUnknown, corev1.ConditionTrue, "")},
{watch.Modified, CreateTestServiceWithConditions(corev1.ConditionTrue, corev1.ConditionTrue, "")}, {watch.Modified, CreateTestServiceWithConditions(name, corev1.ConditionTrue, corev1.ConditionTrue, "")},
} }
} }
func peError() []watch.Event { func peError(name string) []watch.Event {
return []watch.Event{ return []watch.Event{
{watch.Added, CreateTestServiceWithConditions(corev1.ConditionUnknown, corev1.ConditionUnknown, "")}, {watch.Added, CreateTestServiceWithConditions(name, corev1.ConditionUnknown, corev1.ConditionUnknown, "")},
{watch.Modified, CreateTestServiceWithConditions(corev1.ConditionFalse, corev1.ConditionTrue, "FakeError")}, {watch.Modified, CreateTestServiceWithConditions(name, corev1.ConditionFalse, corev1.ConditionTrue, "FakeError")},
} }
} }
func peTimeout() []watch.Event { func peTimeout(name string) []watch.Event {
return []watch.Event{ return []watch.Event{
{watch.Added, CreateTestServiceWithConditions(corev1.ConditionUnknown, corev1.ConditionUnknown, "")}, {watch.Added, CreateTestServiceWithConditions(name, corev1.ConditionUnknown, corev1.ConditionUnknown, "")},
} }
} }
func peWrongGeneration() []watch.Event { func peWrongGeneration(name string) []watch.Event {
return []watch.Event{ return []watch.Event{
{watch.Added, CreateTestServiceWithConditions(corev1.ConditionUnknown, corev1.ConditionUnknown, "")}, {watch.Added, CreateTestServiceWithConditions(name, corev1.ConditionUnknown, corev1.ConditionUnknown, "")},
{watch.Modified, CreateTestServiceWithConditions(corev1.ConditionTrue, corev1.ConditionTrue, "", 1, 2)}, {watch.Modified, CreateTestServiceWithConditions(name, corev1.ConditionTrue, corev1.ConditionTrue, "", 1, 2)},
} }
} }

View File

@ -118,7 +118,7 @@ func testServiceDescribe(t *testing.T, k kn, serviceName string) {
t.Fatalf(fmt.Sprintf("Error executing 'kn service describe' command. Error: %s", err.Error())) t.Fatalf(fmt.Sprintf("Error executing 'kn service describe' command. Error: %s", err.Error()))
} }
expectedOutputHeader := `apiVersion: knative.dev/v1alpha1 expectedOutputHeader := `apiVersion: serving.knative.dev/v1alpha1
kind: Service kind: Service
metadata:` metadata:`
if !strings.Contains(out, expectedOutputHeader) { if !strings.Contains(out, expectedOutputHeader) {

View File

@ -6,6 +6,8 @@ import (
"fmt" "fmt"
"strconv" "strconv"
"strings" "strings"
"github.com/pkg/errors"
) )
const ( const (
@ -24,6 +26,14 @@ var (
AccumulatedCopySizeLimit int64 = 0 AccumulatedCopySizeLimit int64 = 0
) )
var (
ErrTestFailed = errors.New("test failed")
ErrMissing = errors.New("missing value")
ErrUnknownType = errors.New("unknown object type")
ErrInvalid = errors.New("invalid state detected")
ErrInvalidIndex = errors.New("invalid index referenced")
)
type lazyNode struct { type lazyNode struct {
raw *json.RawMessage raw *json.RawMessage
doc partialDoc doc partialDoc
@ -31,10 +41,11 @@ type lazyNode struct {
which int which int
} }
type operation map[string]*json.RawMessage // Operation is a single JSON-Patch step, such as a single 'add' operation.
type Operation map[string]*json.RawMessage
// Patch is an ordered collection of operations. // Patch is an ordered collection of Operations.
type Patch []operation type Patch []Operation
type partialDoc map[string]*lazyNode type partialDoc map[string]*lazyNode
type partialArray []*lazyNode type partialArray []*lazyNode
@ -59,7 +70,7 @@ func (n *lazyNode) MarshalJSON() ([]byte, error) {
case eAry: case eAry:
return json.Marshal(n.ary) return json.Marshal(n.ary)
default: default:
return nil, fmt.Errorf("Unknown type") return nil, ErrUnknownType
} }
} }
@ -91,7 +102,7 @@ func (n *lazyNode) intoDoc() (*partialDoc, error) {
} }
if n.raw == nil { if n.raw == nil {
return nil, fmt.Errorf("Unable to unmarshal nil pointer as partial document") return nil, ErrInvalid
} }
err := json.Unmarshal(*n.raw, &n.doc) err := json.Unmarshal(*n.raw, &n.doc)
@ -110,7 +121,7 @@ func (n *lazyNode) intoAry() (*partialArray, error) {
} }
if n.raw == nil { if n.raw == nil {
return nil, fmt.Errorf("Unable to unmarshal nil pointer as partial array") return nil, ErrInvalid
} }
err := json.Unmarshal(*n.raw, &n.ary) err := json.Unmarshal(*n.raw, &n.ary)
@ -227,7 +238,8 @@ func (n *lazyNode) equal(o *lazyNode) bool {
return true return true
} }
func (o operation) kind() string { // Kind reads the "op" field of the Operation.
func (o Operation) Kind() string {
if obj, ok := o["op"]; ok && obj != nil { if obj, ok := o["op"]; ok && obj != nil {
var op string var op string
@ -243,39 +255,41 @@ func (o operation) kind() string {
return "unknown" return "unknown"
} }
func (o operation) path() string { // Path reads the "path" field of the Operation.
func (o Operation) Path() (string, error) {
if obj, ok := o["path"]; ok && obj != nil { if obj, ok := o["path"]; ok && obj != nil {
var op string var op string
err := json.Unmarshal(*obj, &op) err := json.Unmarshal(*obj, &op)
if err != nil { if err != nil {
return "unknown" return "unknown", err
} }
return op return op, nil
} }
return "unknown" return "unknown", errors.Wrapf(ErrMissing, "operation missing path field")
} }
func (o operation) from() string { // From reads the "from" field of the Operation.
func (o Operation) From() (string, error) {
if obj, ok := o["from"]; ok && obj != nil { if obj, ok := o["from"]; ok && obj != nil {
var op string var op string
err := json.Unmarshal(*obj, &op) err := json.Unmarshal(*obj, &op)
if err != nil { if err != nil {
return "unknown" return "unknown", err
} }
return op return op, nil
} }
return "unknown" return "unknown", errors.Wrapf(ErrMissing, "operation, missing from field")
} }
func (o operation) value() *lazyNode { func (o Operation) value() *lazyNode {
if obj, ok := o["value"]; ok { if obj, ok := o["value"]; ok {
return newLazyNode(obj) return newLazyNode(obj)
} }
@ -283,6 +297,23 @@ func (o operation) value() *lazyNode {
return nil return nil
} }
// ValueInterface decodes the operation value into an interface.
func (o Operation) ValueInterface() (interface{}, error) {
if obj, ok := o["value"]; ok && obj != nil {
var v interface{}
err := json.Unmarshal(*obj, &v)
if err != nil {
return nil, err
}
return v, nil
}
return nil, errors.Wrapf(ErrMissing, "operation, missing value field")
}
func isArray(buf []byte) bool { func isArray(buf []byte) bool {
Loop: Loop:
for _, c := range buf { for _, c := range buf {
@ -359,7 +390,7 @@ func (d *partialDoc) get(key string) (*lazyNode, error) {
func (d *partialDoc) remove(key string) error { func (d *partialDoc) remove(key string) error {
_, ok := (*d)[key] _, ok := (*d)[key]
if !ok { if !ok {
return fmt.Errorf("Unable to remove nonexistent key: %s", key) return errors.Wrapf(ErrMissing, "Unable to remove nonexistent key: %s", key)
} }
delete(*d, key) delete(*d, key)
@ -385,7 +416,7 @@ func (d *partialArray) add(key string, val *lazyNode) error {
idx, err := strconv.Atoi(key) idx, err := strconv.Atoi(key)
if err != nil { if err != nil {
return err return errors.Wrapf(err, "value was not a proper array index: '%s'", key)
} }
sz := len(*d) + 1 sz := len(*d) + 1
@ -395,12 +426,12 @@ func (d *partialArray) add(key string, val *lazyNode) error {
cur := *d cur := *d
if idx >= len(ary) { if idx >= len(ary) {
return fmt.Errorf("Unable to access invalid index: %d", idx) return errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx)
} }
if SupportNegativeIndices { if SupportNegativeIndices {
if idx < -len(ary) { if idx < -len(ary) {
return fmt.Errorf("Unable to access invalid index: %d", idx) return errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx)
} }
if idx < 0 { if idx < 0 {
@ -424,7 +455,7 @@ func (d *partialArray) get(key string) (*lazyNode, error) {
} }
if idx >= len(*d) { if idx >= len(*d) {
return nil, fmt.Errorf("Unable to access invalid index: %d", idx) return nil, errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx)
} }
return (*d)[idx], nil return (*d)[idx], nil
@ -439,12 +470,12 @@ func (d *partialArray) remove(key string) error {
cur := *d cur := *d
if idx >= len(cur) { if idx >= len(cur) {
return fmt.Errorf("Unable to access invalid index: %d", idx) return errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx)
} }
if SupportNegativeIndices { if SupportNegativeIndices {
if idx < -len(cur) { if idx < -len(cur) {
return fmt.Errorf("Unable to access invalid index: %d", idx) return errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx)
} }
if idx < 0 { if idx < 0 {
@ -462,140 +493,189 @@ func (d *partialArray) remove(key string) error {
} }
func (p Patch) add(doc *container, op operation) error { func (p Patch) add(doc *container, op Operation) error {
path := op.path() path, err := op.Path()
con, key := findObject(doc, path)
if con == nil {
return fmt.Errorf("jsonpatch add operation does not apply: doc is missing path: \"%s\"", path)
}
return con.add(key, op.value())
}
func (p Patch) remove(doc *container, op operation) error {
path := op.path()
con, key := findObject(doc, path)
if con == nil {
return fmt.Errorf("jsonpatch remove operation does not apply: doc is missing path: \"%s\"", path)
}
return con.remove(key)
}
func (p Patch) replace(doc *container, op operation) error {
path := op.path()
con, key := findObject(doc, path)
if con == nil {
return fmt.Errorf("jsonpatch replace operation does not apply: doc is missing path: %s", path)
}
_, ok := con.get(key)
if ok != nil {
return fmt.Errorf("jsonpatch replace operation does not apply: doc is missing key: %s", path)
}
return con.set(key, op.value())
}
func (p Patch) move(doc *container, op operation) error {
from := op.from()
con, key := findObject(doc, from)
if con == nil {
return fmt.Errorf("jsonpatch move operation does not apply: doc is missing from path: %s", from)
}
val, err := con.get(key)
if err != nil { if err != nil {
return err return errors.Wrapf(ErrMissing, "add operation failed to decode path")
}
con, key := findObject(doc, path)
if con == nil {
return errors.Wrapf(ErrMissing, "add operation does not apply: doc is missing path: \"%s\"", path)
}
err = con.add(key, op.value())
if err != nil {
return errors.Wrapf(err, "error in add for path: '%s'", path)
}
return nil
}
func (p Patch) remove(doc *container, op Operation) error {
path, err := op.Path()
if err != nil {
return errors.Wrapf(ErrMissing, "remove operation failed to decode path")
}
con, key := findObject(doc, path)
if con == nil {
return errors.Wrapf(ErrMissing, "remove operation does not apply: doc is missing path: \"%s\"", path)
} }
err = con.remove(key) err = con.remove(key)
if err != nil { if err != nil {
return err return errors.Wrapf(err, "error in remove for path: '%s'", path)
} }
path := op.path() return nil
con, key = findObject(doc, path)
if con == nil {
return fmt.Errorf("jsonpatch move operation does not apply: doc is missing destination path: %s", path)
}
return con.add(key, val)
} }
func (p Patch) test(doc *container, op operation) error { func (p Patch) replace(doc *container, op Operation) error {
path := op.path() path, err := op.Path()
if err != nil {
return errors.Wrapf(err, "replace operation failed to decode path")
}
con, key := findObject(doc, path) con, key := findObject(doc, path)
if con == nil { if con == nil {
return fmt.Errorf("jsonpatch test operation does not apply: is missing path: %s", path) return errors.Wrapf(ErrMissing, "replace operation does not apply: doc is missing path: %s", path)
}
_, ok := con.get(key)
if ok != nil {
return errors.Wrapf(ErrMissing, "replace operation does not apply: doc is missing key: %s", path)
}
err = con.set(key, op.value())
if err != nil {
return errors.Wrapf(err, "error in remove for path: '%s'", path)
}
return nil
}
func (p Patch) move(doc *container, op Operation) error {
from, err := op.From()
if err != nil {
return errors.Wrapf(err, "move operation failed to decode from")
}
con, key := findObject(doc, from)
if con == nil {
return errors.Wrapf(ErrMissing, "move operation does not apply: doc is missing from path: %s", from)
} }
val, err := con.get(key) val, err := con.get(key)
if err != nil { if err != nil {
return err return errors.Wrapf(err, "error in move for path: '%s'", key)
}
err = con.remove(key)
if err != nil {
return errors.Wrapf(err, "error in move for path: '%s'", key)
}
path, err := op.Path()
if err != nil {
return errors.Wrapf(err, "move operation failed to decode path")
}
con, key = findObject(doc, path)
if con == nil {
return errors.Wrapf(ErrMissing, "move operation does not apply: doc is missing destination path: %s", path)
}
err = con.add(key, val)
if err != nil {
return errors.Wrapf(err, "error in move for path: '%s'", path)
}
return nil
}
func (p Patch) test(doc *container, op Operation) error {
path, err := op.Path()
if err != nil {
return errors.Wrapf(err, "test operation failed to decode path")
}
con, key := findObject(doc, path)
if con == nil {
return errors.Wrapf(ErrMissing, "test operation does not apply: is missing path: %s", path)
}
val, err := con.get(key)
if err != nil {
return errors.Wrapf(err, "error in test for path: '%s'", path)
} }
if val == nil { if val == nil {
if op.value().raw == nil { if op.value().raw == nil {
return nil return nil
} }
return fmt.Errorf("Testing value %s failed", path) return errors.Wrapf(ErrTestFailed, "testing value %s failed", path)
} else if op.value() == nil { } else if op.value() == nil {
return fmt.Errorf("Testing value %s failed", path) return errors.Wrapf(ErrTestFailed, "testing value %s failed", path)
} }
if val.equal(op.value()) { if val.equal(op.value()) {
return nil return nil
} }
return fmt.Errorf("Testing value %s failed", path) return errors.Wrapf(ErrTestFailed, "testing value %s failed", path)
} }
func (p Patch) copy(doc *container, op operation, accumulatedCopySize *int64) error { func (p Patch) copy(doc *container, op Operation, accumulatedCopySize *int64) error {
from := op.from() from, err := op.From()
if err != nil {
return errors.Wrapf(err, "copy operation failed to decode from")
}
con, key := findObject(doc, from) con, key := findObject(doc, from)
if con == nil { if con == nil {
return fmt.Errorf("jsonpatch copy operation does not apply: doc is missing from path: %s", from) return errors.Wrapf(ErrMissing, "copy operation does not apply: doc is missing from path: %s", from)
} }
val, err := con.get(key) val, err := con.get(key)
if err != nil { if err != nil {
return err return errors.Wrapf(err, "error in copy for from: '%s'", from)
} }
path := op.path() path, err := op.Path()
if err != nil {
return errors.Wrapf(ErrMissing, "copy operation failed to decode path")
}
con, key = findObject(doc, path) con, key = findObject(doc, path)
if con == nil { if con == nil {
return fmt.Errorf("jsonpatch copy operation does not apply: doc is missing destination path: %s", path) return errors.Wrapf(ErrMissing, "copy operation does not apply: doc is missing destination path: %s", path)
} }
valCopy, sz, err := deepCopy(val) valCopy, sz, err := deepCopy(val)
if err != nil { if err != nil {
return err return errors.Wrapf(err, "error while performing deep copy")
} }
(*accumulatedCopySize) += int64(sz) (*accumulatedCopySize) += int64(sz)
if AccumulatedCopySizeLimit > 0 && *accumulatedCopySize > AccumulatedCopySizeLimit { if AccumulatedCopySizeLimit > 0 && *accumulatedCopySize > AccumulatedCopySizeLimit {
return NewAccumulatedCopySizeError(AccumulatedCopySizeLimit, *accumulatedCopySize) return NewAccumulatedCopySizeError(AccumulatedCopySizeLimit, *accumulatedCopySize)
} }
return con.add(key, valCopy) err = con.add(key, valCopy)
if err != nil {
return errors.Wrapf(err, "error while adding value during copy")
}
return nil
} }
// Equal indicates if 2 JSON documents have the same structural equality. // Equal indicates if 2 JSON documents have the same structural equality.
@ -651,7 +731,7 @@ func (p Patch) ApplyIndent(doc []byte, indent string) ([]byte, error) {
var accumulatedCopySize int64 var accumulatedCopySize int64
for _, op := range p { for _, op := range p {
switch op.kind() { switch op.Kind() {
case "add": case "add":
err = p.add(&pd, op) err = p.add(&pd, op)
case "remove": case "remove":
@ -665,7 +745,7 @@ func (p Patch) ApplyIndent(doc []byte, indent string) ([]byte, error) {
case "copy": case "copy":
err = p.copy(&pd, op, &accumulatedCopySize) err = p.copy(&pd, op, &accumulatedCopySize)
default: default:
err = fmt.Errorf("Unexpected kind: %s", op.kind()) err = fmt.Errorf("Unexpected kind: %s", op.Kind())
} }
if err != nil { if err != nil {

View File

@ -7105,15 +7105,15 @@ func (m *Any) ToRawInfo() interface{} {
// ToRawInfo returns a description of ApiKeySecurity suitable for JSON or YAML export. // ToRawInfo returns a description of ApiKeySecurity suitable for JSON or YAML export.
func (m *ApiKeySecurity) ToRawInfo() interface{} { func (m *ApiKeySecurity) ToRawInfo() interface{} {
info := yaml.MapSlice{} info := yaml.MapSlice{}
if m.Type != "" { if m == nil {
return info
}
// always include this required field.
info = append(info, yaml.MapItem{Key: "type", Value: m.Type}) info = append(info, yaml.MapItem{Key: "type", Value: m.Type})
} // always include this required field.
if m.Name != "" {
info = append(info, yaml.MapItem{Key: "name", Value: m.Name}) info = append(info, yaml.MapItem{Key: "name", Value: m.Name})
} // always include this required field.
if m.In != "" {
info = append(info, yaml.MapItem{Key: "in", Value: m.In}) info = append(info, yaml.MapItem{Key: "in", Value: m.In})
}
if m.Description != "" { if m.Description != "" {
info = append(info, yaml.MapItem{Key: "description", Value: m.Description}) info = append(info, yaml.MapItem{Key: "description", Value: m.Description})
} }
@ -7129,9 +7129,11 @@ func (m *ApiKeySecurity) ToRawInfo() interface{} {
// ToRawInfo returns a description of BasicAuthenticationSecurity suitable for JSON or YAML export. // ToRawInfo returns a description of BasicAuthenticationSecurity suitable for JSON or YAML export.
func (m *BasicAuthenticationSecurity) ToRawInfo() interface{} { func (m *BasicAuthenticationSecurity) ToRawInfo() interface{} {
info := yaml.MapSlice{} info := yaml.MapSlice{}
if m.Type != "" { if m == nil {
info = append(info, yaml.MapItem{Key: "type", Value: m.Type}) return info
} }
// always include this required field.
info = append(info, yaml.MapItem{Key: "type", Value: m.Type})
if m.Description != "" { if m.Description != "" {
info = append(info, yaml.MapItem{Key: "description", Value: m.Description}) info = append(info, yaml.MapItem{Key: "description", Value: m.Description})
} }
@ -7147,21 +7149,21 @@ func (m *BasicAuthenticationSecurity) ToRawInfo() interface{} {
// ToRawInfo returns a description of BodyParameter suitable for JSON or YAML export. // ToRawInfo returns a description of BodyParameter suitable for JSON or YAML export.
func (m *BodyParameter) ToRawInfo() interface{} { func (m *BodyParameter) ToRawInfo() interface{} {
info := yaml.MapSlice{} info := yaml.MapSlice{}
if m == nil {
return info
}
if m.Description != "" { if m.Description != "" {
info = append(info, yaml.MapItem{Key: "description", Value: m.Description}) info = append(info, yaml.MapItem{Key: "description", Value: m.Description})
} }
if m.Name != "" { // always include this required field.
info = append(info, yaml.MapItem{Key: "name", Value: m.Name}) info = append(info, yaml.MapItem{Key: "name", Value: m.Name})
} // always include this required field.
if m.In != "" {
info = append(info, yaml.MapItem{Key: "in", Value: m.In}) info = append(info, yaml.MapItem{Key: "in", Value: m.In})
}
if m.Required != false { if m.Required != false {
info = append(info, yaml.MapItem{Key: "required", Value: m.Required}) info = append(info, yaml.MapItem{Key: "required", Value: m.Required})
} }
if m.Schema != nil { // always include this required field.
info = append(info, yaml.MapItem{Key: "schema", Value: m.Schema.ToRawInfo()}) info = append(info, yaml.MapItem{Key: "schema", Value: m.Schema.ToRawInfo()})
}
// &{Name:schema Type:Schema StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} // &{Name:schema Type:Schema StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}
if m.VendorExtension != nil { if m.VendorExtension != nil {
for _, item := range m.VendorExtension { for _, item := range m.VendorExtension {
@ -7175,6 +7177,9 @@ func (m *BodyParameter) ToRawInfo() interface{} {
// ToRawInfo returns a description of Contact suitable for JSON or YAML export. // ToRawInfo returns a description of Contact suitable for JSON or YAML export.
func (m *Contact) ToRawInfo() interface{} { func (m *Contact) ToRawInfo() interface{} {
info := yaml.MapSlice{} info := yaml.MapSlice{}
if m == nil {
return info
}
if m.Name != "" { if m.Name != "" {
info = append(info, yaml.MapItem{Key: "name", Value: m.Name}) info = append(info, yaml.MapItem{Key: "name", Value: m.Name})
} }
@ -7196,6 +7201,9 @@ func (m *Contact) ToRawInfo() interface{} {
// ToRawInfo returns a description of Default suitable for JSON or YAML export. // ToRawInfo returns a description of Default suitable for JSON or YAML export.
func (m *Default) ToRawInfo() interface{} { func (m *Default) ToRawInfo() interface{} {
info := yaml.MapSlice{} info := yaml.MapSlice{}
if m == nil {
return info
}
if m.AdditionalProperties != nil { if m.AdditionalProperties != nil {
for _, item := range m.AdditionalProperties { for _, item := range m.AdditionalProperties {
info = append(info, yaml.MapItem{Key: item.Name, Value: item.Value.ToRawInfo()}) info = append(info, yaml.MapItem{Key: item.Name, Value: item.Value.ToRawInfo()})
@ -7208,6 +7216,9 @@ func (m *Default) ToRawInfo() interface{} {
// ToRawInfo returns a description of Definitions suitable for JSON or YAML export. // ToRawInfo returns a description of Definitions suitable for JSON or YAML export.
func (m *Definitions) ToRawInfo() interface{} { func (m *Definitions) ToRawInfo() interface{} {
info := yaml.MapSlice{} info := yaml.MapSlice{}
if m == nil {
return info
}
if m.AdditionalProperties != nil { if m.AdditionalProperties != nil {
for _, item := range m.AdditionalProperties { for _, item := range m.AdditionalProperties {
info = append(info, yaml.MapItem{Key: item.Name, Value: item.Value.ToRawInfo()}) info = append(info, yaml.MapItem{Key: item.Name, Value: item.Value.ToRawInfo()})
@ -7220,12 +7231,13 @@ func (m *Definitions) ToRawInfo() interface{} {
// ToRawInfo returns a description of Document suitable for JSON or YAML export. // ToRawInfo returns a description of Document suitable for JSON or YAML export.
func (m *Document) ToRawInfo() interface{} { func (m *Document) ToRawInfo() interface{} {
info := yaml.MapSlice{} info := yaml.MapSlice{}
if m.Swagger != "" { if m == nil {
return info
}
// always include this required field.
info = append(info, yaml.MapItem{Key: "swagger", Value: m.Swagger}) info = append(info, yaml.MapItem{Key: "swagger", Value: m.Swagger})
} // always include this required field.
if m.Info != nil {
info = append(info, yaml.MapItem{Key: "info", Value: m.Info.ToRawInfo()}) info = append(info, yaml.MapItem{Key: "info", Value: m.Info.ToRawInfo()})
}
// &{Name:info Type:Info StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} // &{Name:info Type:Info StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}
if m.Host != "" { if m.Host != "" {
info = append(info, yaml.MapItem{Key: "host", Value: m.Host}) info = append(info, yaml.MapItem{Key: "host", Value: m.Host})
@ -7242,9 +7254,8 @@ func (m *Document) ToRawInfo() interface{} {
if len(m.Produces) != 0 { if len(m.Produces) != 0 {
info = append(info, yaml.MapItem{Key: "produces", Value: m.Produces}) info = append(info, yaml.MapItem{Key: "produces", Value: m.Produces})
} }
if m.Paths != nil { // always include this required field.
info = append(info, yaml.MapItem{Key: "paths", Value: m.Paths.ToRawInfo()}) info = append(info, yaml.MapItem{Key: "paths", Value: m.Paths.ToRawInfo()})
}
// &{Name:paths Type:Paths StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} // &{Name:paths Type:Paths StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}
if m.Definitions != nil { if m.Definitions != nil {
info = append(info, yaml.MapItem{Key: "definitions", Value: m.Definitions.ToRawInfo()}) info = append(info, yaml.MapItem{Key: "definitions", Value: m.Definitions.ToRawInfo()})
@ -7294,6 +7305,9 @@ func (m *Document) ToRawInfo() interface{} {
// ToRawInfo returns a description of Examples suitable for JSON or YAML export. // ToRawInfo returns a description of Examples suitable for JSON or YAML export.
func (m *Examples) ToRawInfo() interface{} { func (m *Examples) ToRawInfo() interface{} {
info := yaml.MapSlice{} info := yaml.MapSlice{}
if m == nil {
return info
}
if m.AdditionalProperties != nil { if m.AdditionalProperties != nil {
for _, item := range m.AdditionalProperties { for _, item := range m.AdditionalProperties {
info = append(info, yaml.MapItem{Key: item.Name, Value: item.Value.ToRawInfo()}) info = append(info, yaml.MapItem{Key: item.Name, Value: item.Value.ToRawInfo()})
@ -7306,12 +7320,14 @@ func (m *Examples) ToRawInfo() interface{} {
// ToRawInfo returns a description of ExternalDocs suitable for JSON or YAML export. // ToRawInfo returns a description of ExternalDocs suitable for JSON or YAML export.
func (m *ExternalDocs) ToRawInfo() interface{} { func (m *ExternalDocs) ToRawInfo() interface{} {
info := yaml.MapSlice{} info := yaml.MapSlice{}
if m == nil {
return info
}
if m.Description != "" { if m.Description != "" {
info = append(info, yaml.MapItem{Key: "description", Value: m.Description}) info = append(info, yaml.MapItem{Key: "description", Value: m.Description})
} }
if m.Url != "" { // always include this required field.
info = append(info, yaml.MapItem{Key: "url", Value: m.Url}) info = append(info, yaml.MapItem{Key: "url", Value: m.Url})
}
if m.VendorExtension != nil { if m.VendorExtension != nil {
for _, item := range m.VendorExtension { for _, item := range m.VendorExtension {
info = append(info, yaml.MapItem{Key: item.Name, Value: item.Value.ToRawInfo()}) info = append(info, yaml.MapItem{Key: item.Name, Value: item.Value.ToRawInfo()})
@ -7324,6 +7340,9 @@ func (m *ExternalDocs) ToRawInfo() interface{} {
// ToRawInfo returns a description of FileSchema suitable for JSON or YAML export. // ToRawInfo returns a description of FileSchema suitable for JSON or YAML export.
func (m *FileSchema) ToRawInfo() interface{} { func (m *FileSchema) ToRawInfo() interface{} {
info := yaml.MapSlice{} info := yaml.MapSlice{}
if m == nil {
return info
}
if m.Format != "" { if m.Format != "" {
info = append(info, yaml.MapItem{Key: "format", Value: m.Format}) info = append(info, yaml.MapItem{Key: "format", Value: m.Format})
} }
@ -7340,9 +7359,8 @@ func (m *FileSchema) ToRawInfo() interface{} {
if len(m.Required) != 0 { if len(m.Required) != 0 {
info = append(info, yaml.MapItem{Key: "required", Value: m.Required}) info = append(info, yaml.MapItem{Key: "required", Value: m.Required})
} }
if m.Type != "" { // always include this required field.
info = append(info, yaml.MapItem{Key: "type", Value: m.Type}) info = append(info, yaml.MapItem{Key: "type", Value: m.Type})
}
if m.ReadOnly != false { if m.ReadOnly != false {
info = append(info, yaml.MapItem{Key: "readOnly", Value: m.ReadOnly}) info = append(info, yaml.MapItem{Key: "readOnly", Value: m.ReadOnly})
} }
@ -7366,6 +7384,9 @@ func (m *FileSchema) ToRawInfo() interface{} {
// ToRawInfo returns a description of FormDataParameterSubSchema suitable for JSON or YAML export. // ToRawInfo returns a description of FormDataParameterSubSchema suitable for JSON or YAML export.
func (m *FormDataParameterSubSchema) ToRawInfo() interface{} { func (m *FormDataParameterSubSchema) ToRawInfo() interface{} {
info := yaml.MapSlice{} info := yaml.MapSlice{}
if m == nil {
return info
}
if m.Required != false { if m.Required != false {
info = append(info, yaml.MapItem{Key: "required", Value: m.Required}) info = append(info, yaml.MapItem{Key: "required", Value: m.Required})
} }
@ -7451,9 +7472,11 @@ func (m *FormDataParameterSubSchema) ToRawInfo() interface{} {
// ToRawInfo returns a description of Header suitable for JSON or YAML export. // ToRawInfo returns a description of Header suitable for JSON or YAML export.
func (m *Header) ToRawInfo() interface{} { func (m *Header) ToRawInfo() interface{} {
info := yaml.MapSlice{} info := yaml.MapSlice{}
if m.Type != "" { if m == nil {
info = append(info, yaml.MapItem{Key: "type", Value: m.Type}) return info
} }
// always include this required field.
info = append(info, yaml.MapItem{Key: "type", Value: m.Type})
if m.Format != "" { if m.Format != "" {
info = append(info, yaml.MapItem{Key: "format", Value: m.Format}) info = append(info, yaml.MapItem{Key: "format", Value: m.Format})
} }
@ -7524,6 +7547,9 @@ func (m *Header) ToRawInfo() interface{} {
// ToRawInfo returns a description of HeaderParameterSubSchema suitable for JSON or YAML export. // ToRawInfo returns a description of HeaderParameterSubSchema suitable for JSON or YAML export.
func (m *HeaderParameterSubSchema) ToRawInfo() interface{} { func (m *HeaderParameterSubSchema) ToRawInfo() interface{} {
info := yaml.MapSlice{} info := yaml.MapSlice{}
if m == nil {
return info
}
if m.Required != false { if m.Required != false {
info = append(info, yaml.MapItem{Key: "required", Value: m.Required}) info = append(info, yaml.MapItem{Key: "required", Value: m.Required})
} }
@ -7606,6 +7632,9 @@ func (m *HeaderParameterSubSchema) ToRawInfo() interface{} {
// ToRawInfo returns a description of Headers suitable for JSON or YAML export. // ToRawInfo returns a description of Headers suitable for JSON or YAML export.
func (m *Headers) ToRawInfo() interface{} { func (m *Headers) ToRawInfo() interface{} {
info := yaml.MapSlice{} info := yaml.MapSlice{}
if m == nil {
return info
}
if m.AdditionalProperties != nil { if m.AdditionalProperties != nil {
for _, item := range m.AdditionalProperties { for _, item := range m.AdditionalProperties {
info = append(info, yaml.MapItem{Key: item.Name, Value: item.Value.ToRawInfo()}) info = append(info, yaml.MapItem{Key: item.Name, Value: item.Value.ToRawInfo()})
@ -7618,12 +7647,13 @@ func (m *Headers) ToRawInfo() interface{} {
// ToRawInfo returns a description of Info suitable for JSON or YAML export. // ToRawInfo returns a description of Info suitable for JSON or YAML export.
func (m *Info) ToRawInfo() interface{} { func (m *Info) ToRawInfo() interface{} {
info := yaml.MapSlice{} info := yaml.MapSlice{}
if m.Title != "" { if m == nil {
return info
}
// always include this required field.
info = append(info, yaml.MapItem{Key: "title", Value: m.Title}) info = append(info, yaml.MapItem{Key: "title", Value: m.Title})
} // always include this required field.
if m.Version != "" {
info = append(info, yaml.MapItem{Key: "version", Value: m.Version}) info = append(info, yaml.MapItem{Key: "version", Value: m.Version})
}
if m.Description != "" { if m.Description != "" {
info = append(info, yaml.MapItem{Key: "description", Value: m.Description}) info = append(info, yaml.MapItem{Key: "description", Value: m.Description})
} }
@ -7650,6 +7680,9 @@ func (m *Info) ToRawInfo() interface{} {
// ToRawInfo returns a description of ItemsItem suitable for JSON or YAML export. // ToRawInfo returns a description of ItemsItem suitable for JSON or YAML export.
func (m *ItemsItem) ToRawInfo() interface{} { func (m *ItemsItem) ToRawInfo() interface{} {
info := yaml.MapSlice{} info := yaml.MapSlice{}
if m == nil {
return info
}
if len(m.Schema) != 0 { if len(m.Schema) != 0 {
items := make([]interface{}, 0) items := make([]interface{}, 0)
for _, item := range m.Schema { for _, item := range m.Schema {
@ -7664,9 +7697,11 @@ func (m *ItemsItem) ToRawInfo() interface{} {
// ToRawInfo returns a description of JsonReference suitable for JSON or YAML export. // ToRawInfo returns a description of JsonReference suitable for JSON or YAML export.
func (m *JsonReference) ToRawInfo() interface{} { func (m *JsonReference) ToRawInfo() interface{} {
info := yaml.MapSlice{} info := yaml.MapSlice{}
if m.XRef != "" { if m == nil {
info = append(info, yaml.MapItem{Key: "$ref", Value: m.XRef}) return info
} }
// always include this required field.
info = append(info, yaml.MapItem{Key: "$ref", Value: m.XRef})
if m.Description != "" { if m.Description != "" {
info = append(info, yaml.MapItem{Key: "description", Value: m.Description}) info = append(info, yaml.MapItem{Key: "description", Value: m.Description})
} }
@ -7676,9 +7711,11 @@ func (m *JsonReference) ToRawInfo() interface{} {
// ToRawInfo returns a description of License suitable for JSON or YAML export. // ToRawInfo returns a description of License suitable for JSON or YAML export.
func (m *License) ToRawInfo() interface{} { func (m *License) ToRawInfo() interface{} {
info := yaml.MapSlice{} info := yaml.MapSlice{}
if m.Name != "" { if m == nil {
info = append(info, yaml.MapItem{Key: "name", Value: m.Name}) return info
} }
// always include this required field.
info = append(info, yaml.MapItem{Key: "name", Value: m.Name})
if m.Url != "" { if m.Url != "" {
info = append(info, yaml.MapItem{Key: "url", Value: m.Url}) info = append(info, yaml.MapItem{Key: "url", Value: m.Url})
} }
@ -7694,6 +7731,9 @@ func (m *License) ToRawInfo() interface{} {
// ToRawInfo returns a description of NamedAny suitable for JSON or YAML export. // ToRawInfo returns a description of NamedAny suitable for JSON or YAML export.
func (m *NamedAny) ToRawInfo() interface{} { func (m *NamedAny) ToRawInfo() interface{} {
info := yaml.MapSlice{} info := yaml.MapSlice{}
if m == nil {
return info
}
if m.Name != "" { if m.Name != "" {
info = append(info, yaml.MapItem{Key: "name", Value: m.Name}) info = append(info, yaml.MapItem{Key: "name", Value: m.Name})
} }
@ -7704,6 +7744,9 @@ func (m *NamedAny) ToRawInfo() interface{} {
// ToRawInfo returns a description of NamedHeader suitable for JSON or YAML export. // ToRawInfo returns a description of NamedHeader suitable for JSON or YAML export.
func (m *NamedHeader) ToRawInfo() interface{} { func (m *NamedHeader) ToRawInfo() interface{} {
info := yaml.MapSlice{} info := yaml.MapSlice{}
if m == nil {
return info
}
if m.Name != "" { if m.Name != "" {
info = append(info, yaml.MapItem{Key: "name", Value: m.Name}) info = append(info, yaml.MapItem{Key: "name", Value: m.Name})
} }
@ -7714,6 +7757,9 @@ func (m *NamedHeader) ToRawInfo() interface{} {
// ToRawInfo returns a description of NamedParameter suitable for JSON or YAML export. // ToRawInfo returns a description of NamedParameter suitable for JSON or YAML export.
func (m *NamedParameter) ToRawInfo() interface{} { func (m *NamedParameter) ToRawInfo() interface{} {
info := yaml.MapSlice{} info := yaml.MapSlice{}
if m == nil {
return info
}
if m.Name != "" { if m.Name != "" {
info = append(info, yaml.MapItem{Key: "name", Value: m.Name}) info = append(info, yaml.MapItem{Key: "name", Value: m.Name})
} }
@ -7724,6 +7770,9 @@ func (m *NamedParameter) ToRawInfo() interface{} {
// ToRawInfo returns a description of NamedPathItem suitable for JSON or YAML export. // ToRawInfo returns a description of NamedPathItem suitable for JSON or YAML export.
func (m *NamedPathItem) ToRawInfo() interface{} { func (m *NamedPathItem) ToRawInfo() interface{} {
info := yaml.MapSlice{} info := yaml.MapSlice{}
if m == nil {
return info
}
if m.Name != "" { if m.Name != "" {
info = append(info, yaml.MapItem{Key: "name", Value: m.Name}) info = append(info, yaml.MapItem{Key: "name", Value: m.Name})
} }
@ -7734,6 +7783,9 @@ func (m *NamedPathItem) ToRawInfo() interface{} {
// ToRawInfo returns a description of NamedResponse suitable for JSON or YAML export. // ToRawInfo returns a description of NamedResponse suitable for JSON or YAML export.
func (m *NamedResponse) ToRawInfo() interface{} { func (m *NamedResponse) ToRawInfo() interface{} {
info := yaml.MapSlice{} info := yaml.MapSlice{}
if m == nil {
return info
}
if m.Name != "" { if m.Name != "" {
info = append(info, yaml.MapItem{Key: "name", Value: m.Name}) info = append(info, yaml.MapItem{Key: "name", Value: m.Name})
} }
@ -7744,6 +7796,9 @@ func (m *NamedResponse) ToRawInfo() interface{} {
// ToRawInfo returns a description of NamedResponseValue suitable for JSON or YAML export. // ToRawInfo returns a description of NamedResponseValue suitable for JSON or YAML export.
func (m *NamedResponseValue) ToRawInfo() interface{} { func (m *NamedResponseValue) ToRawInfo() interface{} {
info := yaml.MapSlice{} info := yaml.MapSlice{}
if m == nil {
return info
}
if m.Name != "" { if m.Name != "" {
info = append(info, yaml.MapItem{Key: "name", Value: m.Name}) info = append(info, yaml.MapItem{Key: "name", Value: m.Name})
} }
@ -7754,6 +7809,9 @@ func (m *NamedResponseValue) ToRawInfo() interface{} {
// ToRawInfo returns a description of NamedSchema suitable for JSON or YAML export. // ToRawInfo returns a description of NamedSchema suitable for JSON or YAML export.
func (m *NamedSchema) ToRawInfo() interface{} { func (m *NamedSchema) ToRawInfo() interface{} {
info := yaml.MapSlice{} info := yaml.MapSlice{}
if m == nil {
return info
}
if m.Name != "" { if m.Name != "" {
info = append(info, yaml.MapItem{Key: "name", Value: m.Name}) info = append(info, yaml.MapItem{Key: "name", Value: m.Name})
} }
@ -7764,6 +7822,9 @@ func (m *NamedSchema) ToRawInfo() interface{} {
// ToRawInfo returns a description of NamedSecurityDefinitionsItem suitable for JSON or YAML export. // ToRawInfo returns a description of NamedSecurityDefinitionsItem suitable for JSON or YAML export.
func (m *NamedSecurityDefinitionsItem) ToRawInfo() interface{} { func (m *NamedSecurityDefinitionsItem) ToRawInfo() interface{} {
info := yaml.MapSlice{} info := yaml.MapSlice{}
if m == nil {
return info
}
if m.Name != "" { if m.Name != "" {
info = append(info, yaml.MapItem{Key: "name", Value: m.Name}) info = append(info, yaml.MapItem{Key: "name", Value: m.Name})
} }
@ -7774,6 +7835,9 @@ func (m *NamedSecurityDefinitionsItem) ToRawInfo() interface{} {
// ToRawInfo returns a description of NamedString suitable for JSON or YAML export. // ToRawInfo returns a description of NamedString suitable for JSON or YAML export.
func (m *NamedString) ToRawInfo() interface{} { func (m *NamedString) ToRawInfo() interface{} {
info := yaml.MapSlice{} info := yaml.MapSlice{}
if m == nil {
return info
}
if m.Name != "" { if m.Name != "" {
info = append(info, yaml.MapItem{Key: "name", Value: m.Name}) info = append(info, yaml.MapItem{Key: "name", Value: m.Name})
} }
@ -7786,6 +7850,9 @@ func (m *NamedString) ToRawInfo() interface{} {
// ToRawInfo returns a description of NamedStringArray suitable for JSON or YAML export. // ToRawInfo returns a description of NamedStringArray suitable for JSON or YAML export.
func (m *NamedStringArray) ToRawInfo() interface{} { func (m *NamedStringArray) ToRawInfo() interface{} {
info := yaml.MapSlice{} info := yaml.MapSlice{}
if m == nil {
return info
}
if m.Name != "" { if m.Name != "" {
info = append(info, yaml.MapItem{Key: "name", Value: m.Name}) info = append(info, yaml.MapItem{Key: "name", Value: m.Name})
} }
@ -7823,22 +7890,21 @@ func (m *NonBodyParameter) ToRawInfo() interface{} {
// ToRawInfo returns a description of Oauth2AccessCodeSecurity suitable for JSON or YAML export. // ToRawInfo returns a description of Oauth2AccessCodeSecurity suitable for JSON or YAML export.
func (m *Oauth2AccessCodeSecurity) ToRawInfo() interface{} { func (m *Oauth2AccessCodeSecurity) ToRawInfo() interface{} {
info := yaml.MapSlice{} info := yaml.MapSlice{}
if m.Type != "" { if m == nil {
return info
}
// always include this required field.
info = append(info, yaml.MapItem{Key: "type", Value: m.Type}) info = append(info, yaml.MapItem{Key: "type", Value: m.Type})
} // always include this required field.
if m.Flow != "" {
info = append(info, yaml.MapItem{Key: "flow", Value: m.Flow}) info = append(info, yaml.MapItem{Key: "flow", Value: m.Flow})
}
if m.Scopes != nil { if m.Scopes != nil {
info = append(info, yaml.MapItem{Key: "scopes", Value: m.Scopes.ToRawInfo()}) info = append(info, yaml.MapItem{Key: "scopes", Value: m.Scopes.ToRawInfo()})
} }
// &{Name:scopes Type:Oauth2Scopes StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} // &{Name:scopes Type:Oauth2Scopes StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}
if m.AuthorizationUrl != "" { // always include this required field.
info = append(info, yaml.MapItem{Key: "authorizationUrl", Value: m.AuthorizationUrl}) info = append(info, yaml.MapItem{Key: "authorizationUrl", Value: m.AuthorizationUrl})
} // always include this required field.
if m.TokenUrl != "" {
info = append(info, yaml.MapItem{Key: "tokenUrl", Value: m.TokenUrl}) info = append(info, yaml.MapItem{Key: "tokenUrl", Value: m.TokenUrl})
}
if m.Description != "" { if m.Description != "" {
info = append(info, yaml.MapItem{Key: "description", Value: m.Description}) info = append(info, yaml.MapItem{Key: "description", Value: m.Description})
} }
@ -7854,19 +7920,19 @@ func (m *Oauth2AccessCodeSecurity) ToRawInfo() interface{} {
// ToRawInfo returns a description of Oauth2ApplicationSecurity suitable for JSON or YAML export. // ToRawInfo returns a description of Oauth2ApplicationSecurity suitable for JSON or YAML export.
func (m *Oauth2ApplicationSecurity) ToRawInfo() interface{} { func (m *Oauth2ApplicationSecurity) ToRawInfo() interface{} {
info := yaml.MapSlice{} info := yaml.MapSlice{}
if m.Type != "" { if m == nil {
return info
}
// always include this required field.
info = append(info, yaml.MapItem{Key: "type", Value: m.Type}) info = append(info, yaml.MapItem{Key: "type", Value: m.Type})
} // always include this required field.
if m.Flow != "" {
info = append(info, yaml.MapItem{Key: "flow", Value: m.Flow}) info = append(info, yaml.MapItem{Key: "flow", Value: m.Flow})
}
if m.Scopes != nil { if m.Scopes != nil {
info = append(info, yaml.MapItem{Key: "scopes", Value: m.Scopes.ToRawInfo()}) info = append(info, yaml.MapItem{Key: "scopes", Value: m.Scopes.ToRawInfo()})
} }
// &{Name:scopes Type:Oauth2Scopes StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} // &{Name:scopes Type:Oauth2Scopes StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}
if m.TokenUrl != "" { // always include this required field.
info = append(info, yaml.MapItem{Key: "tokenUrl", Value: m.TokenUrl}) info = append(info, yaml.MapItem{Key: "tokenUrl", Value: m.TokenUrl})
}
if m.Description != "" { if m.Description != "" {
info = append(info, yaml.MapItem{Key: "description", Value: m.Description}) info = append(info, yaml.MapItem{Key: "description", Value: m.Description})
} }
@ -7882,19 +7948,19 @@ func (m *Oauth2ApplicationSecurity) ToRawInfo() interface{} {
// ToRawInfo returns a description of Oauth2ImplicitSecurity suitable for JSON or YAML export. // ToRawInfo returns a description of Oauth2ImplicitSecurity suitable for JSON or YAML export.
func (m *Oauth2ImplicitSecurity) ToRawInfo() interface{} { func (m *Oauth2ImplicitSecurity) ToRawInfo() interface{} {
info := yaml.MapSlice{} info := yaml.MapSlice{}
if m.Type != "" { if m == nil {
return info
}
// always include this required field.
info = append(info, yaml.MapItem{Key: "type", Value: m.Type}) info = append(info, yaml.MapItem{Key: "type", Value: m.Type})
} // always include this required field.
if m.Flow != "" {
info = append(info, yaml.MapItem{Key: "flow", Value: m.Flow}) info = append(info, yaml.MapItem{Key: "flow", Value: m.Flow})
}
if m.Scopes != nil { if m.Scopes != nil {
info = append(info, yaml.MapItem{Key: "scopes", Value: m.Scopes.ToRawInfo()}) info = append(info, yaml.MapItem{Key: "scopes", Value: m.Scopes.ToRawInfo()})
} }
// &{Name:scopes Type:Oauth2Scopes StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} // &{Name:scopes Type:Oauth2Scopes StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}
if m.AuthorizationUrl != "" { // always include this required field.
info = append(info, yaml.MapItem{Key: "authorizationUrl", Value: m.AuthorizationUrl}) info = append(info, yaml.MapItem{Key: "authorizationUrl", Value: m.AuthorizationUrl})
}
if m.Description != "" { if m.Description != "" {
info = append(info, yaml.MapItem{Key: "description", Value: m.Description}) info = append(info, yaml.MapItem{Key: "description", Value: m.Description})
} }
@ -7910,19 +7976,19 @@ func (m *Oauth2ImplicitSecurity) ToRawInfo() interface{} {
// ToRawInfo returns a description of Oauth2PasswordSecurity suitable for JSON or YAML export. // ToRawInfo returns a description of Oauth2PasswordSecurity suitable for JSON or YAML export.
func (m *Oauth2PasswordSecurity) ToRawInfo() interface{} { func (m *Oauth2PasswordSecurity) ToRawInfo() interface{} {
info := yaml.MapSlice{} info := yaml.MapSlice{}
if m.Type != "" { if m == nil {
return info
}
// always include this required field.
info = append(info, yaml.MapItem{Key: "type", Value: m.Type}) info = append(info, yaml.MapItem{Key: "type", Value: m.Type})
} // always include this required field.
if m.Flow != "" {
info = append(info, yaml.MapItem{Key: "flow", Value: m.Flow}) info = append(info, yaml.MapItem{Key: "flow", Value: m.Flow})
}
if m.Scopes != nil { if m.Scopes != nil {
info = append(info, yaml.MapItem{Key: "scopes", Value: m.Scopes.ToRawInfo()}) info = append(info, yaml.MapItem{Key: "scopes", Value: m.Scopes.ToRawInfo()})
} }
// &{Name:scopes Type:Oauth2Scopes StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} // &{Name:scopes Type:Oauth2Scopes StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}
if m.TokenUrl != "" { // always include this required field.
info = append(info, yaml.MapItem{Key: "tokenUrl", Value: m.TokenUrl}) info = append(info, yaml.MapItem{Key: "tokenUrl", Value: m.TokenUrl})
}
if m.Description != "" { if m.Description != "" {
info = append(info, yaml.MapItem{Key: "description", Value: m.Description}) info = append(info, yaml.MapItem{Key: "description", Value: m.Description})
} }
@ -7938,6 +8004,9 @@ func (m *Oauth2PasswordSecurity) ToRawInfo() interface{} {
// ToRawInfo returns a description of Oauth2Scopes suitable for JSON or YAML export. // ToRawInfo returns a description of Oauth2Scopes suitable for JSON or YAML export.
func (m *Oauth2Scopes) ToRawInfo() interface{} { func (m *Oauth2Scopes) ToRawInfo() interface{} {
info := yaml.MapSlice{} info := yaml.MapSlice{}
if m == nil {
return info
}
// &{Name:additionalProperties Type:NamedString StringEnumValues:[] MapType:string Repeated:true Pattern: Implicit:true Description:} // &{Name:additionalProperties Type:NamedString StringEnumValues:[] MapType:string Repeated:true Pattern: Implicit:true Description:}
return info return info
} }
@ -7945,6 +8014,9 @@ func (m *Oauth2Scopes) ToRawInfo() interface{} {
// ToRawInfo returns a description of Operation suitable for JSON or YAML export. // ToRawInfo returns a description of Operation suitable for JSON or YAML export.
func (m *Operation) ToRawInfo() interface{} { func (m *Operation) ToRawInfo() interface{} {
info := yaml.MapSlice{} info := yaml.MapSlice{}
if m == nil {
return info
}
if len(m.Tags) != 0 { if len(m.Tags) != 0 {
info = append(info, yaml.MapItem{Key: "tags", Value: m.Tags}) info = append(info, yaml.MapItem{Key: "tags", Value: m.Tags})
} }
@ -7975,9 +8047,8 @@ func (m *Operation) ToRawInfo() interface{} {
info = append(info, yaml.MapItem{Key: "parameters", Value: items}) info = append(info, yaml.MapItem{Key: "parameters", Value: items})
} }
// &{Name:parameters Type:ParametersItem StringEnumValues:[] MapType: Repeated:true Pattern: Implicit:false Description:The parameters needed to send a valid API call.} // &{Name:parameters Type:ParametersItem StringEnumValues:[] MapType: Repeated:true Pattern: Implicit:false Description:The parameters needed to send a valid API call.}
if m.Responses != nil { // always include this required field.
info = append(info, yaml.MapItem{Key: "responses", Value: m.Responses.ToRawInfo()}) info = append(info, yaml.MapItem{Key: "responses", Value: m.Responses.ToRawInfo()})
}
// &{Name:responses Type:Responses StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} // &{Name:responses Type:Responses StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}
if len(m.Schemes) != 0 { if len(m.Schemes) != 0 {
info = append(info, yaml.MapItem{Key: "schemes", Value: m.Schemes}) info = append(info, yaml.MapItem{Key: "schemes", Value: m.Schemes})
@ -8022,6 +8093,9 @@ func (m *Parameter) ToRawInfo() interface{} {
// ToRawInfo returns a description of ParameterDefinitions suitable for JSON or YAML export. // ToRawInfo returns a description of ParameterDefinitions suitable for JSON or YAML export.
func (m *ParameterDefinitions) ToRawInfo() interface{} { func (m *ParameterDefinitions) ToRawInfo() interface{} {
info := yaml.MapSlice{} info := yaml.MapSlice{}
if m == nil {
return info
}
if m.AdditionalProperties != nil { if m.AdditionalProperties != nil {
for _, item := range m.AdditionalProperties { for _, item := range m.AdditionalProperties {
info = append(info, yaml.MapItem{Key: item.Name, Value: item.Value.ToRawInfo()}) info = append(info, yaml.MapItem{Key: item.Name, Value: item.Value.ToRawInfo()})
@ -8051,6 +8125,9 @@ func (m *ParametersItem) ToRawInfo() interface{} {
// ToRawInfo returns a description of PathItem suitable for JSON or YAML export. // ToRawInfo returns a description of PathItem suitable for JSON or YAML export.
func (m *PathItem) ToRawInfo() interface{} { func (m *PathItem) ToRawInfo() interface{} {
info := yaml.MapSlice{} info := yaml.MapSlice{}
if m == nil {
return info
}
if m.XRef != "" { if m.XRef != "" {
info = append(info, yaml.MapItem{Key: "$ref", Value: m.XRef}) info = append(info, yaml.MapItem{Key: "$ref", Value: m.XRef})
} }
@ -8102,9 +8179,11 @@ func (m *PathItem) ToRawInfo() interface{} {
// ToRawInfo returns a description of PathParameterSubSchema suitable for JSON or YAML export. // ToRawInfo returns a description of PathParameterSubSchema suitable for JSON or YAML export.
func (m *PathParameterSubSchema) ToRawInfo() interface{} { func (m *PathParameterSubSchema) ToRawInfo() interface{} {
info := yaml.MapSlice{} info := yaml.MapSlice{}
if m.Required != false { if m == nil {
info = append(info, yaml.MapItem{Key: "required", Value: m.Required}) return info
} }
// always include this required field.
info = append(info, yaml.MapItem{Key: "required", Value: m.Required})
if m.In != "" { if m.In != "" {
info = append(info, yaml.MapItem{Key: "in", Value: m.In}) info = append(info, yaml.MapItem{Key: "in", Value: m.In})
} }
@ -8184,6 +8263,9 @@ func (m *PathParameterSubSchema) ToRawInfo() interface{} {
// ToRawInfo returns a description of Paths suitable for JSON or YAML export. // ToRawInfo returns a description of Paths suitable for JSON or YAML export.
func (m *Paths) ToRawInfo() interface{} { func (m *Paths) ToRawInfo() interface{} {
info := yaml.MapSlice{} info := yaml.MapSlice{}
if m == nil {
return info
}
if m.VendorExtension != nil { if m.VendorExtension != nil {
for _, item := range m.VendorExtension { for _, item := range m.VendorExtension {
info = append(info, yaml.MapItem{Key: item.Name, Value: item.Value.ToRawInfo()}) info = append(info, yaml.MapItem{Key: item.Name, Value: item.Value.ToRawInfo()})
@ -8202,6 +8284,9 @@ func (m *Paths) ToRawInfo() interface{} {
// ToRawInfo returns a description of PrimitivesItems suitable for JSON or YAML export. // ToRawInfo returns a description of PrimitivesItems suitable for JSON or YAML export.
func (m *PrimitivesItems) ToRawInfo() interface{} { func (m *PrimitivesItems) ToRawInfo() interface{} {
info := yaml.MapSlice{} info := yaml.MapSlice{}
if m == nil {
return info
}
if m.Type != "" { if m.Type != "" {
info = append(info, yaml.MapItem{Key: "type", Value: m.Type}) info = append(info, yaml.MapItem{Key: "type", Value: m.Type})
} }
@ -8272,6 +8357,9 @@ func (m *PrimitivesItems) ToRawInfo() interface{} {
// ToRawInfo returns a description of Properties suitable for JSON or YAML export. // ToRawInfo returns a description of Properties suitable for JSON or YAML export.
func (m *Properties) ToRawInfo() interface{} { func (m *Properties) ToRawInfo() interface{} {
info := yaml.MapSlice{} info := yaml.MapSlice{}
if m == nil {
return info
}
if m.AdditionalProperties != nil { if m.AdditionalProperties != nil {
for _, item := range m.AdditionalProperties { for _, item := range m.AdditionalProperties {
info = append(info, yaml.MapItem{Key: item.Name, Value: item.Value.ToRawInfo()}) info = append(info, yaml.MapItem{Key: item.Name, Value: item.Value.ToRawInfo()})
@ -8284,6 +8372,9 @@ func (m *Properties) ToRawInfo() interface{} {
// ToRawInfo returns a description of QueryParameterSubSchema suitable for JSON or YAML export. // ToRawInfo returns a description of QueryParameterSubSchema suitable for JSON or YAML export.
func (m *QueryParameterSubSchema) ToRawInfo() interface{} { func (m *QueryParameterSubSchema) ToRawInfo() interface{} {
info := yaml.MapSlice{} info := yaml.MapSlice{}
if m == nil {
return info
}
if m.Required != false { if m.Required != false {
info = append(info, yaml.MapItem{Key: "required", Value: m.Required}) info = append(info, yaml.MapItem{Key: "required", Value: m.Required})
} }
@ -8369,9 +8460,11 @@ func (m *QueryParameterSubSchema) ToRawInfo() interface{} {
// ToRawInfo returns a description of Response suitable for JSON or YAML export. // ToRawInfo returns a description of Response suitable for JSON or YAML export.
func (m *Response) ToRawInfo() interface{} { func (m *Response) ToRawInfo() interface{} {
info := yaml.MapSlice{} info := yaml.MapSlice{}
if m.Description != "" { if m == nil {
info = append(info, yaml.MapItem{Key: "description", Value: m.Description}) return info
} }
// always include this required field.
info = append(info, yaml.MapItem{Key: "description", Value: m.Description})
if m.Schema != nil { if m.Schema != nil {
info = append(info, yaml.MapItem{Key: "schema", Value: m.Schema.ToRawInfo()}) info = append(info, yaml.MapItem{Key: "schema", Value: m.Schema.ToRawInfo()})
} }
@ -8396,6 +8489,9 @@ func (m *Response) ToRawInfo() interface{} {
// ToRawInfo returns a description of ResponseDefinitions suitable for JSON or YAML export. // ToRawInfo returns a description of ResponseDefinitions suitable for JSON or YAML export.
func (m *ResponseDefinitions) ToRawInfo() interface{} { func (m *ResponseDefinitions) ToRawInfo() interface{} {
info := yaml.MapSlice{} info := yaml.MapSlice{}
if m == nil {
return info
}
if m.AdditionalProperties != nil { if m.AdditionalProperties != nil {
for _, item := range m.AdditionalProperties { for _, item := range m.AdditionalProperties {
info = append(info, yaml.MapItem{Key: item.Name, Value: item.Value.ToRawInfo()}) info = append(info, yaml.MapItem{Key: item.Name, Value: item.Value.ToRawInfo()})
@ -8425,6 +8521,9 @@ func (m *ResponseValue) ToRawInfo() interface{} {
// ToRawInfo returns a description of Responses suitable for JSON or YAML export. // ToRawInfo returns a description of Responses suitable for JSON or YAML export.
func (m *Responses) ToRawInfo() interface{} { func (m *Responses) ToRawInfo() interface{} {
info := yaml.MapSlice{} info := yaml.MapSlice{}
if m == nil {
return info
}
if m.ResponseCode != nil { if m.ResponseCode != nil {
for _, item := range m.ResponseCode { for _, item := range m.ResponseCode {
info = append(info, yaml.MapItem{Key: item.Name, Value: item.Value.ToRawInfo()}) info = append(info, yaml.MapItem{Key: item.Name, Value: item.Value.ToRawInfo()})
@ -8443,6 +8542,9 @@ func (m *Responses) ToRawInfo() interface{} {
// ToRawInfo returns a description of Schema suitable for JSON or YAML export. // ToRawInfo returns a description of Schema suitable for JSON or YAML export.
func (m *Schema) ToRawInfo() interface{} { func (m *Schema) ToRawInfo() interface{} {
info := yaml.MapSlice{} info := yaml.MapSlice{}
if m == nil {
return info
}
if m.XRef != "" { if m.XRef != "" {
info = append(info, yaml.MapItem{Key: "$ref", Value: m.XRef}) info = append(info, yaml.MapItem{Key: "$ref", Value: m.XRef})
} }
@ -8588,6 +8690,9 @@ func (m *SchemaItem) ToRawInfo() interface{} {
// ToRawInfo returns a description of SecurityDefinitions suitable for JSON or YAML export. // ToRawInfo returns a description of SecurityDefinitions suitable for JSON or YAML export.
func (m *SecurityDefinitions) ToRawInfo() interface{} { func (m *SecurityDefinitions) ToRawInfo() interface{} {
info := yaml.MapSlice{} info := yaml.MapSlice{}
if m == nil {
return info
}
if m.AdditionalProperties != nil { if m.AdditionalProperties != nil {
for _, item := range m.AdditionalProperties { for _, item := range m.AdditionalProperties {
info = append(info, yaml.MapItem{Key: item.Name, Value: item.Value.ToRawInfo()}) info = append(info, yaml.MapItem{Key: item.Name, Value: item.Value.ToRawInfo()})
@ -8637,6 +8742,9 @@ func (m *SecurityDefinitionsItem) ToRawInfo() interface{} {
// ToRawInfo returns a description of SecurityRequirement suitable for JSON or YAML export. // ToRawInfo returns a description of SecurityRequirement suitable for JSON or YAML export.
func (m *SecurityRequirement) ToRawInfo() interface{} { func (m *SecurityRequirement) ToRawInfo() interface{} {
info := yaml.MapSlice{} info := yaml.MapSlice{}
if m == nil {
return info
}
if m.AdditionalProperties != nil { if m.AdditionalProperties != nil {
for _, item := range m.AdditionalProperties { for _, item := range m.AdditionalProperties {
info = append(info, yaml.MapItem{Key: item.Name, Value: item.Value.ToRawInfo()}) info = append(info, yaml.MapItem{Key: item.Name, Value: item.Value.ToRawInfo()})
@ -8654,9 +8762,11 @@ func (m *StringArray) ToRawInfo() interface{} {
// ToRawInfo returns a description of Tag suitable for JSON or YAML export. // ToRawInfo returns a description of Tag suitable for JSON or YAML export.
func (m *Tag) ToRawInfo() interface{} { func (m *Tag) ToRawInfo() interface{} {
info := yaml.MapSlice{} info := yaml.MapSlice{}
if m.Name != "" { if m == nil {
info = append(info, yaml.MapItem{Key: "name", Value: m.Name}) return info
} }
// always include this required field.
info = append(info, yaml.MapItem{Key: "name", Value: m.Name})
if m.Description != "" { if m.Description != "" {
info = append(info, yaml.MapItem{Key: "description", Value: m.Description}) info = append(info, yaml.MapItem{Key: "description", Value: m.Description})
} }
@ -8676,6 +8786,9 @@ func (m *Tag) ToRawInfo() interface{} {
// ToRawInfo returns a description of TypeItem suitable for JSON or YAML export. // ToRawInfo returns a description of TypeItem suitable for JSON or YAML export.
func (m *TypeItem) ToRawInfo() interface{} { func (m *TypeItem) ToRawInfo() interface{} {
info := yaml.MapSlice{} info := yaml.MapSlice{}
if m == nil {
return info
}
if len(m.Value) != 0 { if len(m.Value) != 0 {
info = append(info, yaml.MapItem{Key: "value", Value: m.Value}) info = append(info, yaml.MapItem{Key: "value", Value: m.Value})
} }
@ -8685,6 +8798,9 @@ func (m *TypeItem) ToRawInfo() interface{} {
// ToRawInfo returns a description of VendorExtension suitable for JSON or YAML export. // ToRawInfo returns a description of VendorExtension suitable for JSON or YAML export.
func (m *VendorExtension) ToRawInfo() interface{} { func (m *VendorExtension) ToRawInfo() interface{} {
info := yaml.MapSlice{} info := yaml.MapSlice{}
if m == nil {
return info
}
if m.AdditionalProperties != nil { if m.AdditionalProperties != nil {
for _, item := range m.AdditionalProperties { for _, item := range m.AdditionalProperties {
info = append(info, yaml.MapItem{Key: item.Name, Value: item.Value.ToRawInfo()}) info = append(info, yaml.MapItem{Key: item.Name, Value: item.Value.ToRawInfo()})
@ -8697,6 +8813,9 @@ func (m *VendorExtension) ToRawInfo() interface{} {
// ToRawInfo returns a description of Xml suitable for JSON or YAML export. // ToRawInfo returns a description of Xml suitable for JSON or YAML export.
func (m *Xml) ToRawInfo() interface{} { func (m *Xml) ToRawInfo() interface{} {
info := yaml.MapSlice{} info := yaml.MapSlice{}
if m == nil {
return info
}
if m.Name != "" { if m.Name != "" {
info = append(info, yaml.MapItem{Key: "name", Value: m.Name}) info = append(info, yaml.MapItem{Key: "name", Value: m.Name})
} }

View File

@ -17,13 +17,14 @@ package compiler
import ( import (
"errors" "errors"
"fmt" "fmt"
"gopkg.in/yaml.v2"
"io/ioutil" "io/ioutil"
"log" "log"
"net/http" "net/http"
"net/url" "net/url"
"path/filepath" "path/filepath"
"strings" "strings"
yaml "gopkg.in/yaml.v2"
) )
var fileCache map[string][]byte var fileCache map[string][]byte
@ -31,6 +32,8 @@ var infoCache map[string]interface{}
var count int64 var count int64
var verboseReader = false var verboseReader = false
var fileCacheEnable = true
var infoCacheEnable = true
func initializeFileCache() { func initializeFileCache() {
if fileCache == nil { if fileCache == nil {
@ -44,9 +47,35 @@ func initializeInfoCache() {
} }
} }
func DisableFileCache() {
fileCacheEnable = false
}
func DisableInfoCache() {
infoCacheEnable = false
}
func RemoveFromFileCache(fileurl string) {
if !fileCacheEnable {
return
}
initializeFileCache()
delete(fileCache, fileurl)
}
func RemoveFromInfoCache(filename string) {
if !infoCacheEnable {
return
}
initializeInfoCache()
delete(infoCache, filename)
}
// FetchFile gets a specified file from the local filesystem or a remote location. // FetchFile gets a specified file from the local filesystem or a remote location.
func FetchFile(fileurl string) ([]byte, error) { func FetchFile(fileurl string) ([]byte, error) {
var bytes []byte
initializeFileCache() initializeFileCache()
if fileCacheEnable {
bytes, ok := fileCache[fileurl] bytes, ok := fileCache[fileurl]
if ok { if ok {
if verboseReader { if verboseReader {
@ -57,16 +86,17 @@ func FetchFile(fileurl string) ([]byte, error) {
if verboseReader { if verboseReader {
log.Printf("Fetching %s", fileurl) log.Printf("Fetching %s", fileurl)
} }
}
response, err := http.Get(fileurl) response, err := http.Get(fileurl)
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer response.Body.Close()
if response.StatusCode != 200 { if response.StatusCode != 200 {
return nil, errors.New(fmt.Sprintf("Error downloading %s: %s", fileurl, response.Status)) return nil, errors.New(fmt.Sprintf("Error downloading %s: %s", fileurl, response.Status))
} }
defer response.Body.Close()
bytes, err = ioutil.ReadAll(response.Body) bytes, err = ioutil.ReadAll(response.Body)
if err == nil { if fileCacheEnable && err == nil {
fileCache[fileurl] = bytes fileCache[fileurl] = bytes
} }
return bytes, err return bytes, err
@ -95,6 +125,7 @@ func ReadBytesForFile(filename string) ([]byte, error) {
// ReadInfoFromBytes unmarshals a file as a yaml.MapSlice. // ReadInfoFromBytes unmarshals a file as a yaml.MapSlice.
func ReadInfoFromBytes(filename string, bytes []byte) (interface{}, error) { func ReadInfoFromBytes(filename string, bytes []byte) (interface{}, error) {
initializeInfoCache() initializeInfoCache()
if infoCacheEnable {
cachedInfo, ok := infoCache[filename] cachedInfo, ok := infoCache[filename]
if ok { if ok {
if verboseReader { if verboseReader {
@ -105,12 +136,13 @@ func ReadInfoFromBytes(filename string, bytes []byte) (interface{}, error) {
if verboseReader { if verboseReader {
log.Printf("Reading info for file %s", filename) log.Printf("Reading info for file %s", filename)
} }
}
var info yaml.MapSlice var info yaml.MapSlice
err := yaml.Unmarshal(bytes, &info) err := yaml.Unmarshal(bytes, &info)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if len(filename) > 0 { if infoCacheEnable && len(filename) > 0 {
infoCache[filename] = info infoCache[filename] = info
} }
return info, nil return info, nil
@ -119,7 +151,7 @@ func ReadInfoFromBytes(filename string, bytes []byte) (interface{}, error) {
// ReadInfoForRef reads a file and return the fragment needed to resolve a $ref. // 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) (interface{}, error) {
initializeInfoCache() initializeInfoCache()
{ if infoCacheEnable {
info, ok := infoCache[ref] info, ok := infoCache[ref]
if ok { if ok {
if verboseReader { if verboseReader {
@ -127,10 +159,10 @@ func ReadInfoForRef(basefile string, ref string) (interface{}, error) {
} }
return info, nil return info, nil
} }
}
if verboseReader { if verboseReader {
log.Printf("Reading info for ref %s#%s", basefile, ref) log.Printf("Reading info for ref %s#%s", basefile, ref)
} }
}
count = count + 1 count = count + 1
basedir, _ := filepath.Split(basefile) basedir, _ := filepath.Split(basefile)
parts := strings.Split(ref, "#") parts := strings.Split(ref, "#")
@ -170,6 +202,8 @@ func ReadInfoForRef(basefile string, ref string) (interface{}, error) {
} }
} }
} }
if infoCacheEnable {
infoCache[ref] = info infoCache[ref] = info
}
return info, nil return info, nil
} }

View File

@ -1,24 +1,12 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// source: extension.proto // source: extension.proto
/*
Package openapiextension_v1 is a generated protocol buffer package.
It is generated from these files:
extension.proto
It has these top-level messages:
Version
ExtensionHandlerRequest
ExtensionHandlerResponse
Wrapper
*/
package openapiextension_v1 package openapiextension_v1
import proto "github.com/golang/protobuf/proto" import proto "github.com/golang/protobuf/proto"
import fmt "fmt" import fmt "fmt"
import math "math" import math "math"
import google_protobuf "github.com/golang/protobuf/ptypes/any" import any "github.com/golang/protobuf/ptypes/any"
// Reference imports to suppress errors if they are not otherwise used. // Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal var _ = proto.Marshal
@ -33,18 +21,40 @@ const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
// The version number of OpenAPI compiler. // The version number of OpenAPI compiler.
type Version struct { type Version struct {
Major int32 `protobuf:"varint,1,opt,name=major" json:"major,omitempty"` Major int32 `protobuf:"varint,1,opt,name=major,proto3" json:"major,omitempty"`
Minor int32 `protobuf:"varint,2,opt,name=minor" json:"minor,omitempty"` Minor int32 `protobuf:"varint,2,opt,name=minor,proto3" json:"minor,omitempty"`
Patch int32 `protobuf:"varint,3,opt,name=patch" json:"patch,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 // A suffix for alpha, beta or rc release, e.g., "alpha-1", "rc2". It should
// be empty for mainline stable releases. // be empty for mainline stable releases.
Suffix string `protobuf:"bytes,4,opt,name=suffix" json:"suffix,omitempty"` Suffix string `protobuf:"bytes,4,opt,name=suffix,proto3" json:"suffix,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
} }
func (m *Version) Reset() { *m = Version{} } func (m *Version) Reset() { *m = Version{} }
func (m *Version) String() string { return proto.CompactTextString(m) } func (m *Version) String() string { return proto.CompactTextString(m) }
func (*Version) ProtoMessage() {} func (*Version) ProtoMessage() {}
func (*Version) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } func (*Version) Descriptor() ([]byte, []int) {
return fileDescriptor_extension_d25f09c742c58c90, []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 (dst *Version) XXX_Merge(src proto.Message) {
xxx_messageInfo_Version.Merge(dst, 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 { func (m *Version) GetMajor() int32 {
if m != nil { if m != nil {
@ -78,15 +88,37 @@ func (m *Version) GetSuffix() string {
type ExtensionHandlerRequest struct { type ExtensionHandlerRequest struct {
// The OpenAPI descriptions that were explicitly listed on the command line. // The OpenAPI descriptions that were explicitly listed on the command line.
// The specifications will appear in the order they are specified to gnostic. // The specifications will appear in the order they are specified to gnostic.
Wrapper *Wrapper `protobuf:"bytes,1,opt,name=wrapper" json:"wrapper,omitempty"` Wrapper *Wrapper `protobuf:"bytes,1,opt,name=wrapper,proto3" json:"wrapper,omitempty"`
// The version number of openapi compiler. // The version number of openapi compiler.
CompilerVersion *Version `protobuf:"bytes,3,opt,name=compiler_version,json=compilerVersion" json:"compiler_version,omitempty"` 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:"-"`
} }
func (m *ExtensionHandlerRequest) Reset() { *m = ExtensionHandlerRequest{} } func (m *ExtensionHandlerRequest) Reset() { *m = ExtensionHandlerRequest{} }
func (m *ExtensionHandlerRequest) String() string { return proto.CompactTextString(m) } func (m *ExtensionHandlerRequest) String() string { return proto.CompactTextString(m) }
func (*ExtensionHandlerRequest) ProtoMessage() {} func (*ExtensionHandlerRequest) ProtoMessage() {}
func (*ExtensionHandlerRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } func (*ExtensionHandlerRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_extension_d25f09c742c58c90, []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 (dst *ExtensionHandlerRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_ExtensionHandlerRequest.Merge(dst, 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 { func (m *ExtensionHandlerRequest) GetWrapper() *Wrapper {
if m != nil { if m != nil {
@ -105,7 +137,7 @@ func (m *ExtensionHandlerRequest) GetCompilerVersion() *Version {
// The extensions writes an encoded ExtensionHandlerResponse to stdout. // The extensions writes an encoded ExtensionHandlerResponse to stdout.
type ExtensionHandlerResponse struct { type ExtensionHandlerResponse struct {
// true if the extension is handled by the extension handler; false otherwise // true if the extension is handled by the extension handler; false otherwise
Handled bool `protobuf:"varint,1,opt,name=handled" json:"handled,omitempty"` Handled bool `protobuf:"varint,1,opt,name=handled,proto3" json:"handled,omitempty"`
// Error message. If non-empty, the extension handling failed. // Error message. If non-empty, the extension handling failed.
// The extension handler process should exit with status code zero // The extension handler process should exit with status code zero
// even if it reports an error in this way. // even if it reports an error in this way.
@ -115,15 +147,37 @@ type ExtensionHandlerResponse struct {
// itself -- such as the input Document being unparseable -- should be // itself -- such as the input Document being unparseable -- should be
// reported by writing a message to stderr and exiting with a non-zero // reported by writing a message to stderr and exiting with a non-zero
// status code. // status code.
Error []string `protobuf:"bytes,2,rep,name=error" json:"error,omitempty"` Error []string `protobuf:"bytes,2,rep,name=error,proto3" json:"error,omitempty"`
// text output // text output
Value *google_protobuf.Any `protobuf:"bytes,3,opt,name=value" json:"value,omitempty"` 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:"-"`
} }
func (m *ExtensionHandlerResponse) Reset() { *m = ExtensionHandlerResponse{} } func (m *ExtensionHandlerResponse) Reset() { *m = ExtensionHandlerResponse{} }
func (m *ExtensionHandlerResponse) String() string { return proto.CompactTextString(m) } func (m *ExtensionHandlerResponse) String() string { return proto.CompactTextString(m) }
func (*ExtensionHandlerResponse) ProtoMessage() {} func (*ExtensionHandlerResponse) ProtoMessage() {}
func (*ExtensionHandlerResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } func (*ExtensionHandlerResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_extension_d25f09c742c58c90, []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 (dst *ExtensionHandlerResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_ExtensionHandlerResponse.Merge(dst, 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 { func (m *ExtensionHandlerResponse) GetHandled() bool {
if m != nil { if m != nil {
@ -139,7 +193,7 @@ func (m *ExtensionHandlerResponse) GetError() []string {
return nil return nil
} }
func (m *ExtensionHandlerResponse) GetValue() *google_protobuf.Any { func (m *ExtensionHandlerResponse) GetValue() *any.Any {
if m != nil { if m != nil {
return m.Value return m.Value
} }
@ -148,17 +202,39 @@ func (m *ExtensionHandlerResponse) GetValue() *google_protobuf.Any {
type Wrapper struct { type Wrapper struct {
// version of the OpenAPI specification in which this extension was written. // version of the OpenAPI specification in which this extension was written.
Version string `protobuf:"bytes,1,opt,name=version" json:"version,omitempty"` 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" json:"extension_name,omitempty"` ExtensionName string `protobuf:"bytes,2,opt,name=extension_name,json=extensionName,proto3" json:"extension_name,omitempty"`
// Must be a valid yaml for the proto // Must be a valid yaml for the proto
Yaml string `protobuf:"bytes,3,opt,name=yaml" json:"yaml,omitempty"` Yaml string `protobuf:"bytes,3,opt,name=yaml,proto3" json:"yaml,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
} }
func (m *Wrapper) Reset() { *m = Wrapper{} } func (m *Wrapper) Reset() { *m = Wrapper{} }
func (m *Wrapper) String() string { return proto.CompactTextString(m) } func (m *Wrapper) String() string { return proto.CompactTextString(m) }
func (*Wrapper) ProtoMessage() {} func (*Wrapper) ProtoMessage() {}
func (*Wrapper) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} } func (*Wrapper) Descriptor() ([]byte, []int) {
return fileDescriptor_extension_d25f09c742c58c90, []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 (dst *Wrapper) XXX_Merge(src proto.Message) {
xxx_messageInfo_Wrapper.Merge(dst, 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 { func (m *Wrapper) GetVersion() string {
if m != nil { if m != nil {
@ -188,9 +264,9 @@ func init() {
proto.RegisterType((*Wrapper)(nil), "openapiextension.v1.Wrapper") proto.RegisterType((*Wrapper)(nil), "openapiextension.v1.Wrapper")
} }
func init() { proto.RegisterFile("extension.proto", fileDescriptor0) } func init() { proto.RegisterFile("extension.proto", fileDescriptor_extension_d25f09c742c58c90) }
var fileDescriptor0 = []byte{ var fileDescriptor_extension_d25f09c742c58c90 = []byte{
// 357 bytes of a gzipped FileDescriptorProto // 357 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x91, 0x4d, 0x4b, 0xc3, 0x40, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x91, 0x4d, 0x4b, 0xc3, 0x40,
0x18, 0x84, 0x49, 0xbf, 0x62, 0x56, 0x6c, 0x65, 0x2d, 0x1a, 0xc5, 0x43, 0x09, 0x08, 0x45, 0x64, 0x18, 0x84, 0x49, 0xbf, 0x62, 0x56, 0x6c, 0x65, 0x2d, 0x1a, 0xc5, 0x43, 0x09, 0x08, 0x45, 0x64,

View File

@ -7,6 +7,8 @@ Package httpcache provides a http.RoundTripper implementation that works as a mo
It is only suitable for use as a 'private' cache (i.e. for a web-browser or an API-client and not for a shared proxy). It is only suitable for use as a 'private' cache (i.e. for a web-browser or an API-client and not for a shared proxy).
This project isn't actively maintained; it works for what I, and seemingly others, want to do with it, and I consider it "done". That said, if you find any issues, please open a Pull Request and I will try to review it. Any changes now that change the public API won't be considered.
Cache Backends Cache Backends
-------------- --------------
@ -19,6 +21,8 @@ Cache Backends
- [`github.com/die-net/lrucache/twotier`](https://github.com/die-net/lrucache/tree/master/twotier) allows caches to be combined, for example to use lrucache above with a persistent disk-cache. - [`github.com/die-net/lrucache/twotier`](https://github.com/die-net/lrucache/tree/master/twotier) allows caches to be combined, for example to use lrucache above with a persistent disk-cache.
- [`github.com/birkelund/boltdbcache`](https://github.com/birkelund/boltdbcache) provides a BoltDB implementation (based on the [bbolt](https://github.com/coreos/bbolt) fork). - [`github.com/birkelund/boltdbcache`](https://github.com/birkelund/boltdbcache) provides a BoltDB implementation (based on the [bbolt](https://github.com/coreos/bbolt) fork).
If you implement any other backend and wish it to be linked here, please send a PR editing this file.
License License
------- -------

View File

@ -1,7 +1,7 @@
// +build !ignore_autogenerated // +build !ignore_autogenerated
/* /*
Copyright 2018 The Knative Authors Copyright 2019 The Knative Authors
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -16,13 +16,13 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
// This file was autogenerated by deepcopy-gen. Do not edit it manually! // Code generated by deepcopy-gen. DO NOT EDIT.
package v1alpha1 package v1alpha1
import ( import (
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime" runtime "k8s.io/apimachinery/pkg/runtime"
) )
@ -108,13 +108,9 @@ func (in *BuildSpec) DeepCopyInto(out *BuildSpec) {
*out = *in *out = *in
if in.Source != nil { if in.Source != nil {
in, out := &in.Source, &out.Source in, out := &in.Source, &out.Source
if *in == nil {
*out = nil
} else {
*out = new(SourceSpec) *out = new(SourceSpec)
(*in).DeepCopyInto(*out) (*in).DeepCopyInto(*out)
} }
}
if in.Sources != nil { if in.Sources != nil {
in, out := &in.Sources, &out.Sources in, out := &in.Sources, &out.Sources
*out = make([]SourceSpec, len(*in)) *out = make([]SourceSpec, len(*in))
@ -138,13 +134,9 @@ func (in *BuildSpec) DeepCopyInto(out *BuildSpec) {
} }
if in.Template != nil { if in.Template != nil {
in, out := &in.Template, &out.Template in, out := &in.Template, &out.Template
if *in == nil {
*out = nil
} else {
*out = new(TemplateInstantiationSpec) *out = new(TemplateInstantiationSpec)
(*in).DeepCopyInto(*out) (*in).DeepCopyInto(*out)
} }
}
if in.NodeSelector != nil { if in.NodeSelector != nil {
in, out := &in.NodeSelector, &out.NodeSelector in, out := &in.NodeSelector, &out.NodeSelector
*out = make(map[string]string, len(*in)) *out = make(map[string]string, len(*in))
@ -154,22 +146,14 @@ func (in *BuildSpec) DeepCopyInto(out *BuildSpec) {
} }
if in.Timeout != nil { if in.Timeout != nil {
in, out := &in.Timeout, &out.Timeout in, out := &in.Timeout, &out.Timeout
if *in == nil { *out = new(metav1.Duration)
*out = nil
} else {
*out = new(meta_v1.Duration)
**out = **in **out = **in
} }
}
if in.Affinity != nil { if in.Affinity != nil {
in, out := &in.Affinity, &out.Affinity in, out := &in.Affinity, &out.Affinity
if *in == nil {
*out = nil
} else {
*out = new(v1.Affinity) *out = new(v1.Affinity)
(*in).DeepCopyInto(*out) (*in).DeepCopyInto(*out)
} }
}
return return
} }
@ -189,39 +173,21 @@ func (in *BuildStatus) DeepCopyInto(out *BuildStatus) {
in.Status.DeepCopyInto(&out.Status) in.Status.DeepCopyInto(&out.Status)
if in.Cluster != nil { if in.Cluster != nil {
in, out := &in.Cluster, &out.Cluster in, out := &in.Cluster, &out.Cluster
if *in == nil {
*out = nil
} else {
*out = new(ClusterSpec) *out = new(ClusterSpec)
**out = **in **out = **in
} }
}
if in.Google != nil { if in.Google != nil {
in, out := &in.Google, &out.Google in, out := &in.Google, &out.Google
if *in == nil {
*out = nil
} else {
*out = new(GoogleSpec) *out = new(GoogleSpec)
**out = **in **out = **in
} }
}
if in.StartTime != nil { if in.StartTime != nil {
in, out := &in.StartTime, &out.StartTime in, out := &in.StartTime, &out.StartTime
if *in == nil { *out = (*in).DeepCopy()
*out = nil
} else {
*out = new(meta_v1.Time)
(*in).DeepCopyInto(*out)
}
} }
if in.CompletionTime != nil { if in.CompletionTime != nil {
in, out := &in.CompletionTime, &out.CompletionTime in, out := &in.CompletionTime, &out.CompletionTime
if *in == nil { *out = (*in).DeepCopy()
*out = nil
} else {
*out = new(meta_v1.Time)
(*in).DeepCopyInto(*out)
}
} }
if in.StepStates != nil { if in.StepStates != nil {
in, out := &in.StepStates, &out.StepStates in, out := &in.StepStates, &out.StepStates
@ -474,13 +440,9 @@ func (in *ParameterSpec) DeepCopyInto(out *ParameterSpec) {
*out = *in *out = *in
if in.Default != nil { if in.Default != nil {
in, out := &in.Default, &out.Default in, out := &in.Default, &out.Default
if *in == nil {
*out = nil
} else {
*out = new(string) *out = new(string)
**out = **in **out = **in
} }
}
return return
} }
@ -499,31 +461,19 @@ func (in *SourceSpec) DeepCopyInto(out *SourceSpec) {
*out = *in *out = *in
if in.Git != nil { if in.Git != nil {
in, out := &in.Git, &out.Git in, out := &in.Git, &out.Git
if *in == nil {
*out = nil
} else {
*out = new(GitSourceSpec) *out = new(GitSourceSpec)
**out = **in **out = **in
} }
}
if in.GCS != nil { if in.GCS != nil {
in, out := &in.GCS, &out.GCS in, out := &in.GCS, &out.GCS
if *in == nil {
*out = nil
} else {
*out = new(GCSSourceSpec) *out = new(GCSSourceSpec)
**out = **in **out = **in
} }
}
if in.Custom != nil { if in.Custom != nil {
in, out := &in.Custom, &out.Custom in, out := &in.Custom, &out.Custom
if *in == nil {
*out = nil
} else {
*out = new(v1.Container) *out = new(v1.Container)
(*in).DeepCopyInto(*out) (*in).DeepCopyInto(*out)
} }
}
return return
} }

View File

@ -1,6 +1,4 @@
# The OWNERS file is used by prow to automatically merge approved PRs. # The OWNERS file is used by prow to automatically merge approved PRs.
approvers: approvers:
- mattmoor - apis-approvers
- vaikas-google
- n3wscott

View File

@ -42,10 +42,26 @@ func IsInCreate(ctx context.Context) bool {
// the receiver being validated is being updated. // the receiver being validated is being updated.
type inUpdateKey struct{} type inUpdateKey struct{}
type updatePayload struct {
base interface{}
subresource string
}
// WithinUpdate is used to note that the webhook is calling within // WithinUpdate is used to note that the webhook is calling within
// the context of a Update operation. // the context of a Update operation.
func WithinUpdate(ctx context.Context, base interface{}) context.Context { func WithinUpdate(ctx context.Context, base interface{}) context.Context {
return context.WithValue(ctx, inUpdateKey{}, base) return context.WithValue(ctx, inUpdateKey{}, &updatePayload{
base: base,
})
}
// WithinSubResourceUpdate is used to note that the webhook is calling within
// the context of a Update operation on a subresource.
func WithinSubResourceUpdate(ctx context.Context, base interface{}, sr string) context.Context {
return context.WithValue(ctx, inUpdateKey{}, &updatePayload{
base: base,
subresource: sr,
})
} }
// IsInUpdate checks whether the context is an Update. // IsInUpdate checks whether the context is an Update.
@ -53,10 +69,24 @@ func IsInUpdate(ctx context.Context) bool {
return ctx.Value(inUpdateKey{}) != nil return ctx.Value(inUpdateKey{}) != nil
} }
// IsInStatusUpdate checks whether the context is an Update.
func IsInStatusUpdate(ctx context.Context) bool {
value := ctx.Value(inUpdateKey{})
if value == nil {
return false
}
up := value.(*updatePayload)
return up.subresource == "status"
}
// GetBaseline returns the baseline of the update, or nil when we // GetBaseline returns the baseline of the update, or nil when we
// are not within an update context. // are not within an update context.
func GetBaseline(ctx context.Context) interface{} { func GetBaseline(ctx context.Context) interface{} {
return ctx.Value(inUpdateKey{}) value := ctx.Value(inUpdateKey{})
if value == nil {
return nil
}
return value.(*updatePayload).base
} }
// This is attached to contexts passed to webhook interfaces when // This is attached to contexts passed to webhook interfaces when

View File

@ -1,5 +1,4 @@
# The OWNERS file is used by prow to automatically merge approved PRs. # The OWNERS file is used by prow to automatically merge approved PRs.
approvers: approvers:
- mattmoor - apis-duck-approvers
- vaikas-google

View File

@ -94,14 +94,7 @@ func AsStructuredWatcher(wf cache.WatchFunc, obj runtime.Object) cache.WatchFunc
go func() { go func() {
defer close(structuredCh) defer close(structuredCh)
unstructuredCh := uw.ResultChan() unstructuredCh := uw.ResultChan()
for { for ue := range unstructuredCh {
select {
case ue, ok := <-unstructuredCh:
if !ok {
// Channel is closed.
return
}
unstructuredObj, ok := ue.Object.(*unstructured.Unstructured) unstructuredObj, ok := ue.Object.(*unstructured.Unstructured)
if !ok { if !ok {
// If it isn't an unstructured object, then forward the // If it isn't an unstructured object, then forward the
@ -133,7 +126,6 @@ func AsStructuredWatcher(wf cache.WatchFunc, obj runtime.Object) cache.WatchFunc
Object: structuredObj, Object: structuredObj,
} }
} }
}
}() }()
return NewProxyWatcher(structuredCh), nil return NewProxyWatcher(structuredCh), nil

View File

@ -76,11 +76,27 @@ func (t *AddressableType) Populate() {
t.Status = AddressStatus{ t.Status = AddressStatus{
&Addressable{ &Addressable{
// Populate ALL fields // Populate ALL fields
Addressable: v1beta1.Addressable{
URL: &apis.URL{
Scheme: "http",
Host: "foo.bar.svc.cluster.local",
},
},
Hostname: "this is not empty", Hostname: "this is not empty",
}, },
} }
} }
func (a Addressable) GetURL() apis.URL {
if a.URL != nil {
return *a.URL
}
return apis.URL{
Scheme: "http",
Host: a.Hostname,
}
}
// GetListType implements apis.Listable // GetListType implements apis.Listable
func (*AddressableType) GetListType() runtime.Object { func (*AddressableType) GetListType() runtime.Object {
return &AddressableTypeList{} return &AddressableTypeList{}

View File

@ -1,5 +1,4 @@
# The OWNERS file is used by prow to automatically merge approved PRs. # The OWNERS file is used by prow to automatically merge approved PRs.
approvers: approvers:
- mattmoor - configmap-approvers
- mdemirhan

View File

@ -1,5 +1,4 @@
# The OWNERS file is used by prow to automatically merge approved PRs. # The OWNERS file is used by prow to automatically merge approved PRs.
approvers: approvers:
- mattmoor - kmeta-approvers
- jonjohnsonjr

View File

@ -273,7 +273,20 @@ func ConfigureServer(s *http.Server, conf *Server) error {
if testHookOnConn != nil { if testHookOnConn != nil {
testHookOnConn() testHookOnConn()
} }
// The TLSNextProto interface predates contexts, so
// the net/http package passes down its per-connection
// base context via an exported but unadvertised
// method on the Handler. This is for internal
// net/http<=>http2 use only.
var ctx context.Context
type baseContexter interface {
BaseContext() context.Context
}
if bc, ok := h.(baseContexter); ok {
ctx = bc.BaseContext()
}
conf.ServeConn(c, &ServeConnOpts{ conf.ServeConn(c, &ServeConnOpts{
Context: ctx,
Handler: h, Handler: h,
BaseConfig: hs, BaseConfig: hs,
}) })
@ -284,6 +297,10 @@ func ConfigureServer(s *http.Server, conf *Server) error {
// ServeConnOpts are options for the Server.ServeConn method. // ServeConnOpts are options for the Server.ServeConn method.
type ServeConnOpts struct { type ServeConnOpts struct {
// Context is the base context to use.
// If nil, context.Background is used.
Context context.Context
// BaseConfig optionally sets the base configuration // BaseConfig optionally sets the base configuration
// for values. If nil, defaults are used. // for values. If nil, defaults are used.
BaseConfig *http.Server BaseConfig *http.Server
@ -294,6 +311,13 @@ type ServeConnOpts struct {
Handler http.Handler Handler http.Handler
} }
func (o *ServeConnOpts) context() context.Context {
if o.Context != nil {
return o.Context
}
return context.Background()
}
func (o *ServeConnOpts) baseConfig() *http.Server { func (o *ServeConnOpts) baseConfig() *http.Server {
if o != nil && o.BaseConfig != nil { if o != nil && o.BaseConfig != nil {
return o.BaseConfig return o.BaseConfig
@ -439,7 +463,7 @@ func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) {
} }
func serverConnBaseContext(c net.Conn, opts *ServeConnOpts) (ctx context.Context, cancel func()) { func serverConnBaseContext(c net.Conn, opts *ServeConnOpts) (ctx context.Context, cancel func()) {
ctx, cancel = context.WithCancel(context.Background()) ctx, cancel = context.WithCancel(opts.context())
ctx = context.WithValue(ctx, http.LocalAddrContextKey, c.LocalAddr()) ctx = context.WithValue(ctx, http.LocalAddrContextKey, c.LocalAddr())
if hs := opts.baseConfig(); hs != nil { if hs := opts.baseConfig(); hs != nil {
ctx = context.WithValue(ctx, http.ServerContextKey, hs) ctx = context.WithValue(ctx, http.ServerContextKey, hs)

View File

@ -194,9 +194,16 @@ func (cs computeSource) Token() (*oauth2.Token, error) {
if res.ExpiresInSec == 0 || res.AccessToken == "" { if res.ExpiresInSec == 0 || res.AccessToken == "" {
return nil, fmt.Errorf("oauth2/google: incomplete token received from metadata") return nil, fmt.Errorf("oauth2/google: incomplete token received from metadata")
} }
return &oauth2.Token{ tok := &oauth2.Token{
AccessToken: res.AccessToken, AccessToken: res.AccessToken,
TokenType: res.TokenType, TokenType: res.TokenType,
Expiry: time.Now().Add(time.Duration(res.ExpiresInSec) * time.Second), Expiry: time.Now().Add(time.Duration(res.ExpiresInSec) * time.Second),
}, nil }
// NOTE(cbro): add hidden metadata about where the token is from.
// This is needed for detection by client libraries to know that credentials come from the metadata server.
// This may be removed in a future version of this library.
return tok.WithExtra(map[string]interface{}{
"oauth2.google.tokenSource": "compute-metadata",
"oauth2.google.serviceAccount": acct,
}), nil
} }

View File

@ -117,7 +117,7 @@ var (
// ApprovalForce forces the users to view the consent dialog // ApprovalForce forces the users to view the consent dialog
// and confirm the permissions request at the URL returned // and confirm the permissions request at the URL returned
// from AuthCodeURL, even if they've already done so. // from AuthCodeURL, even if they've already done so.
ApprovalForce AuthCodeOption = SetAuthURLParam("approval_prompt", "force") ApprovalForce AuthCodeOption = SetAuthURLParam("prompt", "consent")
) )
// An AuthCodeOption is passed to Config.AuthCodeURL. // An AuthCodeOption is passed to Config.AuthCodeURL.

24
vendor/modules.txt vendored
View File

@ -4,7 +4,7 @@ cloud.google.com/go/compute/metadata
github.com/cpuguy83/go-md2man/md2man github.com/cpuguy83/go-md2man/md2man
# github.com/davecgh/go-spew v1.1.1 # github.com/davecgh/go-spew v1.1.1
github.com/davecgh/go-spew/spew github.com/davecgh/go-spew/spew
# github.com/evanphx/json-patch v4.2.0+incompatible # github.com/evanphx/json-patch v4.5.0+incompatible
github.com/evanphx/json-patch github.com/evanphx/json-patch
# github.com/fsnotify/fsnotify v1.4.7 # github.com/fsnotify/fsnotify v1.4.7
github.com/fsnotify/fsnotify github.com/fsnotify/fsnotify
@ -29,15 +29,15 @@ github.com/google/go-cmp/cmp/internal/diff
github.com/google/go-cmp/cmp/internal/flags github.com/google/go-cmp/cmp/internal/flags
github.com/google/go-cmp/cmp/internal/function github.com/google/go-cmp/cmp/internal/function
github.com/google/go-cmp/cmp/internal/value github.com/google/go-cmp/cmp/internal/value
# github.com/google/go-containerregistry v0.0.0-20190503220729-1c6c7f61e8a5 # github.com/google/go-containerregistry v0.0.0-20190623150931-ca8b66cb1b79
github.com/google/go-containerregistry/pkg/name github.com/google/go-containerregistry/pkg/name
# github.com/google/gofuzz v1.0.0 # github.com/google/gofuzz v1.0.0
github.com/google/gofuzz github.com/google/gofuzz
# github.com/googleapis/gnostic v0.2.0 # github.com/googleapis/gnostic v0.3.0
github.com/googleapis/gnostic/OpenAPIv2 github.com/googleapis/gnostic/OpenAPIv2
github.com/googleapis/gnostic/compiler github.com/googleapis/gnostic/compiler
github.com/googleapis/gnostic/extensions github.com/googleapis/gnostic/extensions
# github.com/gregjones/httpcache v0.0.0-20190212212710-3befbb6ad0cc # github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79
github.com/gregjones/httpcache github.com/gregjones/httpcache
github.com/gregjones/httpcache/diskcache github.com/gregjones/httpcache/diskcache
# github.com/hashicorp/golang-lru v0.5.1 # github.com/hashicorp/golang-lru v0.5.1
@ -60,10 +60,10 @@ github.com/imdario/mergo
github.com/inconshreveable/mousetrap github.com/inconshreveable/mousetrap
# github.com/json-iterator/go v1.1.6 # github.com/json-iterator/go v1.1.6
github.com/json-iterator/go github.com/json-iterator/go
# github.com/knative/build v0.6.0 # github.com/knative/build v0.7.0
github.com/knative/build/pkg/apis/build/v1alpha1 github.com/knative/build/pkg/apis/build/v1alpha1
github.com/knative/build/pkg/apis/build github.com/knative/build/pkg/apis/build
# github.com/knative/pkg v0.0.0-20190518173526-34792a92cec2 # github.com/knative/pkg v0.0.0-20190617142447-13b093adc272
github.com/knative/pkg/apis github.com/knative/pkg/apis
github.com/knative/pkg/apis/duck/v1beta1 github.com/knative/pkg/apis/duck/v1beta1
github.com/knative/pkg/kmp github.com/knative/pkg/kmp
@ -122,14 +122,14 @@ github.com/spf13/pflag
github.com/spf13/viper github.com/spf13/viper
# golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 # golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2
golang.org/x/crypto/ssh/terminal golang.org/x/crypto/ssh/terminal
# golang.org/x/net v0.0.0-20190514140710-3ec191127204 # golang.org/x/net v0.0.0-20190628185345-da137c7871d7
golang.org/x/net/http2 golang.org/x/net/http2
golang.org/x/net/http/httpguts golang.org/x/net/http/httpguts
golang.org/x/net/http2/hpack golang.org/x/net/http2/hpack
golang.org/x/net/idna golang.org/x/net/idna
golang.org/x/net/context/ctxhttp golang.org/x/net/context/ctxhttp
golang.org/x/net/context golang.org/x/net/context
# golang.org/x/oauth2 v0.0.0-20190517181255-950ef44c6e07 # golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
golang.org/x/oauth2 golang.org/x/oauth2
golang.org/x/oauth2/google golang.org/x/oauth2/google
golang.org/x/oauth2/internal golang.org/x/oauth2/internal
@ -208,14 +208,14 @@ k8s.io/api/storage/v1beta1
k8s.io/apimachinery/pkg/apis/meta/v1 k8s.io/apimachinery/pkg/apis/meta/v1
k8s.io/apimachinery/pkg/util/duration k8s.io/apimachinery/pkg/util/duration
k8s.io/apimachinery/pkg/apis/meta/v1beta1 k8s.io/apimachinery/pkg/apis/meta/v1beta1
k8s.io/apimachinery/pkg/labels
k8s.io/apimachinery/pkg/runtime k8s.io/apimachinery/pkg/runtime
k8s.io/apimachinery/pkg/runtime/schema
k8s.io/apimachinery/pkg/fields
k8s.io/apimachinery/pkg/api/errors k8s.io/apimachinery/pkg/api/errors
k8s.io/apimachinery/pkg/api/resource k8s.io/apimachinery/pkg/api/resource
k8s.io/apimachinery/pkg/api/meta k8s.io/apimachinery/pkg/api/meta
k8s.io/apimachinery/pkg/util/runtime k8s.io/apimachinery/pkg/util/runtime
k8s.io/apimachinery/pkg/runtime/schema
k8s.io/apimachinery/pkg/fields
k8s.io/apimachinery/pkg/labels
k8s.io/apimachinery/pkg/watch k8s.io/apimachinery/pkg/watch
k8s.io/apimachinery/pkg/api/equality k8s.io/apimachinery/pkg/api/equality
k8s.io/apimachinery/pkg/api/validation k8s.io/apimachinery/pkg/api/validation
@ -393,7 +393,7 @@ k8s.io/client-go/listers/settings/v1alpha1
k8s.io/client-go/listers/storage/v1 k8s.io/client-go/listers/storage/v1
k8s.io/client-go/listers/storage/v1alpha1 k8s.io/client-go/listers/storage/v1alpha1
k8s.io/client-go/listers/storage/v1beta1 k8s.io/client-go/listers/storage/v1beta1
# k8s.io/kube-openapi v0.0.0-20190510232812-a01b7d5d6c22 # k8s.io/kube-openapi v0.0.0-20190603182131-db7b694dc208
k8s.io/kube-openapi/pkg/util/proto k8s.io/kube-openapi/pkg/util/proto
# sigs.k8s.io/yaml v1.1.0 # sigs.k8s.io/yaml v1.1.0
sigs.k8s.io/yaml sigs.k8s.io/yaml