Merge pull request #589 from XiShanYongYe-Chang/cluster-api-v4
add cluster-api schemes
This commit is contained in:
commit
300d37e911
10
go.mod
10
go.mod
|
@ -9,7 +9,7 @@ require (
|
|||
github.com/kr/pretty v0.3.0
|
||||
github.com/onsi/ginkgo v1.16.4
|
||||
github.com/onsi/gomega v1.14.0
|
||||
github.com/spf13/cobra v1.1.1
|
||||
github.com/spf13/cobra v1.1.3
|
||||
github.com/spf13/pflag v1.0.5
|
||||
k8s.io/api v0.21.3
|
||||
k8s.io/apiextensions-apiserver v0.21.3
|
||||
|
@ -19,18 +19,20 @@ require (
|
|||
k8s.io/code-generator v0.21.3
|
||||
k8s.io/component-base v0.21.3
|
||||
k8s.io/component-helpers v0.21.3
|
||||
k8s.io/klog/v2 v2.8.0
|
||||
k8s.io/klog/v2 v2.9.0
|
||||
k8s.io/kubernetes v1.20.6
|
||||
k8s.io/utils v0.0.0-20210722164352-7f3ee0f31471
|
||||
sigs.k8s.io/cluster-api v0.4.0
|
||||
sigs.k8s.io/controller-runtime v0.9.5
|
||||
sigs.k8s.io/kind v0.10.0
|
||||
sigs.k8s.io/mcs-api v0.1.0
|
||||
)
|
||||
|
||||
// controller-runtime@v0.8.3 uses gnostic@v0.5.1 which not compatible with kubernetes@v1.20.6.
|
||||
// kubernetes@v1.20.6 using gnostic@v0.4.1.
|
||||
replace (
|
||||
// kubernetes@v1.21.3 requires gnostic@v0.4.1 which is not compatible with gnostic@v0.5.1 that controller-runtime@v0.9.5 requires.
|
||||
github.com/googleapis/gnostic => github.com/googleapis/gnostic v0.4.1
|
||||
// kubernete@v1.21.3 requires grpc@v1.27.1 which is not compatible with grpc@v1.39.x that cluster-api@v0.4.0 requires.
|
||||
google.golang.org/grpc => google.golang.org/grpc v1.27.1
|
||||
k8s.io/api => k8s.io/api v0.21.3
|
||||
k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.21.3
|
||||
k8s.io/apimachinery => k8s.io/apimachinery v0.21.3
|
||||
|
|
214
go.sum
214
go.sum
|
@ -11,18 +11,33 @@ cloud.google.com/go v0.51.0/go.mod h1:hWtGJ6gnXH+KgDv+V0zFGDvpi07n3z8ZNj3T1RW0Gc
|
|||
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
|
||||
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
|
||||
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
|
||||
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
|
||||
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
|
||||
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
|
||||
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
|
||||
cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
|
||||
cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
|
||||
cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=
|
||||
cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=
|
||||
cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
||||
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
|
||||
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
|
||||
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
|
||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
||||
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
||||
cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
|
||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
|
||||
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
|
||||
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
|
||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
||||
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
|
||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/azure-sdk-for-go v43.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
|
@ -46,6 +61,7 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym
|
|||
github.com/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20200415212048-7901bc822317/go.mod h1:DF8FZRxMHMGv/vP2lQP6h+dYzzjpuRn24VeRiYn3qjQ=
|
||||
github.com/JeffAshton/win_pdh v0.0.0-20161109143554-76bb4ee9f0ab/go.mod h1:3VYc5hodBMJ5+l/7J4xAyMeuM2PNuepvHlGs8yilUCA=
|
||||
github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E=
|
||||
github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE=
|
||||
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
|
||||
github.com/Microsoft/go-winio v0.4.15/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
|
||||
github.com/Microsoft/hcsshim v0.8.10-0.20200715222032-5eafd1556990/go.mod h1:ay/0dTb7NsG8QMDfsRfLHgZo/6xAJShLe1+ePPflihk=
|
||||
|
@ -69,6 +85,7 @@ github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk5
|
|||
github.com/alessio/shellescape v1.2.2 h1:8LnL+ncxhWT2TR00dfJRT25JWWrhkMZXneHVWnetDZg=
|
||||
github.com/alessio/shellescape v1.2.2/go.mod h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30=
|
||||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
|
||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||
|
@ -88,6 +105,7 @@ github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kB
|
|||
github.com/bifurcation/mint v0.0.0-20180715133206-93c51c6ce115/go.mod h1:zVt7zX3K/aDCk9Tj+VM7YymsX66ERvzCJzw8rFCX2JU=
|
||||
github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA=
|
||||
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
|
||||
github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM=
|
||||
github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
||||
github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=
|
||||
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
||||
|
@ -114,6 +132,9 @@ github.com/cilium/ebpf v0.0.0-20200110133405-4032b1d8aae3/go.mod h1:MA5e5Lr8slmE
|
|||
github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLIdUjrmSXlK9pkrsDlLHbO8jiB8X8JnOc=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/clusterhq/flocker-go v0.0.0-20160920122132-2b8b7259d313/go.mod h1:P1wt9Z3DP8O6W3rvwCt0REIlshg1InHImaLW0t3ObY0=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa h1:OaNxuTZr7kxeODyLWsRMC+OD03aFUH+mW6r2d+MWa5Y=
|
||||
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
|
||||
github.com/codegangsta/negroni v1.0.0/go.mod h1:v0y3T5G7Y1UlFfyxFn/QLRU4a2EuNau2iZY63YTKWo0=
|
||||
|
@ -131,7 +152,9 @@ github.com/containerd/ttrpc v1.0.2/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8h
|
|||
github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc=
|
||||
github.com/containerd/typeurl v1.0.1/go.mod h1:TB1hUtrpaiO88KEK56ijojHS1+NeF0izUACaJW2mdXg=
|
||||
github.com/containernetworking/cni v0.8.0/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
|
||||
github.com/coredns/caddy v1.1.0/go.mod h1:A6ntJQlAWuQfFlsd9hvigKbo2WS0VUs2l1e2F+BawD4=
|
||||
github.com/coredns/corefile-migration v1.0.10/go.mod h1:RMy/mXdeDlYwzt0vdMEJvT2hGJ2I86/eO0UdXmH9XNI=
|
||||
github.com/coredns/corefile-migration v1.0.12/go.mod h1:NJOI8ceUF/NTgEwtjD+TUq3/BnH/GF7WAM3RzCa3hBo=
|
||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
|
@ -145,6 +168,7 @@ github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9
|
|||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
|
||||
github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
|
||||
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg=
|
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
|
@ -177,6 +201,7 @@ github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDD
|
|||
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=
|
||||
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
|
||||
github.com/drone/envsubst/v2 v2.0.0-20210615175204-7bf45dbf5372/go.mod h1:esf2rsHFNlZlxsqsZDojNBcnNs5REqIvRrWRHqX0vEU=
|
||||
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
|
@ -184,7 +209,12 @@ github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkg
|
|||
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
|
||||
github.com/emicklei/go-restful v2.9.5+incompatible h1:spTtZBk5DYEvbxMVutUuTyh1Ao2r4iyvLdACqsl/Ljk=
|
||||
github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/euank/go-kmsg-parser v2.0.0+incompatible/go.mod h1:MhmAMZ8V4CYH4ybgdRwPr2TU5ThnS43puaKEMpja1uw=
|
||||
github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ=
|
||||
|
@ -198,10 +228,12 @@ github.com/evanphx/json-patch/v5 v5.1.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2Vvl
|
|||
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4=
|
||||
github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
|
||||
github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
||||
github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
|
||||
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
||||
github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
|
@ -281,8 +313,11 @@ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/me
|
|||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I=
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||
github.com/gobuffalo/flect v0.2.0/go.mod h1:W3K3X9ksuZfir8f/LrfVtWmCDQFfayuylOJ7sz/Fj80=
|
||||
github.com/gobuffalo/flect v0.2.3 h1:f/ZukRnSNA/DUpSNDadko7Qc0PhGvsew35p/2tu+CRY=
|
||||
github.com/gobuffalo/flect v0.2.3/go.mod h1:vmkQwuZYhN5Pc4ljYQZzP+1sq+NEkK+lh20jmEmX3jc=
|
||||
github.com/gobuffalo/here v0.6.0/go.mod h1:wAG085dHOYqUpf+Ap+WOdrPTp5IYcDAs/x7PLa8Y5fM=
|
||||
github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||
|
@ -297,12 +332,16 @@ github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4er
|
|||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
||||
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
||||
github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
|
@ -318,6 +357,7 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD
|
|||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
|
||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e/go.mod h1:0AA//k/eakGydO4jKRoRL2j92ZKSzTgj9tclaCrvXHk=
|
||||
|
@ -330,20 +370,37 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a
|
|||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-github/v33 v33.0.0/go.mod h1:GMdDnVZY/2TsWgp/lkYnpSAh6TrzhANBBwm6k6TTEXg=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
|
||||
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
||||
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
|
||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
|
@ -363,6 +420,7 @@ github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY
|
|||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gosuri/uitable v0.0.4/go.mod h1:tKR86bXuXPZazfOTG1FIzvjIdXzd0mo4Vtn16vt0PJo=
|
||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4 h1:z53tR0945TRRQO/fLEVPI6SMv7ZflF0TEaTAoU7tOzg=
|
||||
|
@ -372,6 +430,7 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf
|
|||
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.5 h1:UImYN5qQ8tuGpGE16ZmjvcTtTw24zw1QAp/SlnNrZhI=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
|
||||
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
|
@ -399,6 +458,7 @@ github.com/heketi/heketi v9.0.1-0.20190917153846-c2e2a4ab7ab9+incompatible/go.mo
|
|||
github.com/heketi/tests v0.0.0-20151005000721-f3775cbcefd6/go.mod h1:xGMAM8JLi7UkZt1i4FQeQy0R2T8GLUwQhOP5M1gBhy4=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
|
||||
|
@ -434,6 +494,7 @@ github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgo
|
|||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
|
@ -455,6 +516,7 @@ github.com/lucas-clemente/quic-go v0.10.2/go.mod h1:hvaRS9IHjFLMq76puFJeWNfmn+H7
|
|||
github.com/lucas-clemente/quic-go-certificates v0.0.0-20160823095156-d2f86524cced/go.mod h1:NCcRLrOTZbzhZvixZLlERbJtDtYsmMw8Jc4vS8Z0g58=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
|
||||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
|
@ -466,6 +528,7 @@ github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHef
|
|||
github.com/marten-seemann/qtls v0.2.3/go.mod h1:xzjG7avBwGGbdZ8dTGxlBnLArsVKLvwmjgmPuiQEcYk=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
|
@ -473,6 +536,7 @@ github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHX
|
|||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||
|
@ -491,6 +555,7 @@ github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS4
|
|||
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
|
||||
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A=
|
||||
github.com/moby/ipvs v1.0.1/go.mod h1:2pngiyseZbIKXNv7hsKj3O9UEz30c53MT9005gt2hxQ=
|
||||
github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
|
||||
|
@ -530,6 +595,7 @@ github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W
|
|||
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
|
||||
github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E=
|
||||
github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
|
||||
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
|
||||
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
|
@ -538,6 +604,7 @@ github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1Cpa
|
|||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/onsi/gomega v1.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY=
|
||||
github.com/onsi/gomega v1.14.0 h1:ep6kpPVwmr/nTbklSx2nrLNSIO62DoYAhnPNIMhK8gI=
|
||||
github.com/onsi/gomega v1.14.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0=
|
||||
github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
|
@ -555,11 +622,14 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9
|
|||
github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE=
|
||||
github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM=
|
||||
github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
|
||||
github.com/pelletier/go-toml v1.9.3 h1:zeC5b1GviRUyKYd6OJPvBU/mcVDVoL1OhT17FCt5dSQ=
|
||||
github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
||||
|
@ -599,6 +669,7 @@ github.com/quobyte/api v0.1.8/go.mod h1:jL7lIHrmqQ7yh05OJ+eEEdHr0u/kmT1Ff9iHd+4H
|
|||
github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M=
|
||||
github.com/robfig/cron v1.1.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
|
@ -628,12 +699,16 @@ github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasO
|
|||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||
github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc=
|
||||
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
||||
github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
|
||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
||||
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
|
||||
github.com/spf13/cobra v1.1.1 h1:KfztREH0tPxJJ+geloSLaAkaPkr4ki2Er5quFV1TDo4=
|
||||
github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI=
|
||||
github.com/spf13/cobra v1.1.3 h1:xghbfqPkxzxP3C/f3n5DdpAbdKLj4ZE4BWQI362l53M=
|
||||
github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo=
|
||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
||||
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
|
@ -644,6 +719,7 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An
|
|||
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
||||
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
|
||||
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
|
||||
github.com/spf13/viper v1.8.0/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns=
|
||||
github.com/storageos/go-api v2.2.0+incompatible/go.mod h1:ZrLn+e0ZuF3Y65PNF6dIwbJPZqfmtCXxFm9ckv0agOY=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
|
@ -678,8 +754,11 @@ github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5
|
|||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg=
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs=
|
||||
github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA=
|
||||
github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg=
|
||||
|
@ -689,6 +768,10 @@ go.etcd.io/bbolt v1.3.5 h1:XAzx9gjCb0Rxj7EoqcClPD1d5ZBxZJk0jbuoPHenBt0=
|
|||
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
|
||||
go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489 h1:1JFLBqwIgdyHN1ZtgjTBwO+blA6gVOmZurpiMEsETKo=
|
||||
go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg=
|
||||
go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
|
||||
go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ=
|
||||
go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lLS/oTh0=
|
||||
go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
|
||||
go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
|
||||
go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
|
||||
|
@ -696,6 +779,9 @@ go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
|||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
|
||||
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
|
||||
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
|
@ -707,6 +793,7 @@ go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/
|
|||
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
|
||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
|
||||
go.uber.org/zap v1.18.1 h1:CSUJ2mjFszzEWt4CdKISEuChVIXGBn3lAPwkRGyVrc4=
|
||||
go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
|
@ -721,6 +808,7 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U
|
|||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
|
@ -755,6 +843,8 @@ golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRu
|
|||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
|
@ -765,6 +855,10 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449 h1:xUIPaMhvROX9dhPvRCenIJtU78+lbEenGbgqB5hfHCQ=
|
||||
golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
|
@ -786,6 +880,7 @@ golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR
|
|||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
|
@ -797,11 +892,23 @@ golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLL
|
|||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210224082022-3d97a244fca7/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0=
|
||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
|
@ -810,15 +917,28 @@ golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4Iltr
|
|||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210615190721-d04028783cf1 h1:x622Z2o4hgCr/4CiKWc51jHVKaWdtVpBNmEI8wI9Qns=
|
||||
golang.org/x/oauth2 v0.0.0-20210615190721-d04028783cf1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a h1:DcqTD9SDLc+1P/r1EmRBwnVsrOwW+kk2vWf9n+1sGhs=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
|
@ -868,21 +988,37 @@ golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200928205150-006507a75852/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201110211018-35f3e6cf4a65/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
|
@ -896,6 +1032,7 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3
|
|||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
|
@ -904,6 +1041,7 @@ golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxb
|
|||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20210611083556-38a9dc6acbc6/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs=
|
||||
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
|
@ -947,13 +1085,30 @@ golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapK
|
|||
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
||||
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
|
||||
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/tools v0.1.2 h1:kRBLX7v7Af8W7Gdbbc908OJcdgtK8bOz9Uaj8/F1ACA=
|
||||
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
@ -979,12 +1134,25 @@ google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsb
|
|||
google.golang.org/api v0.15.1-0.20200106000736-b8fc810ca6b5/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
|
||||
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
|
||||
google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
|
||||
google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
|
||||
google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
|
||||
google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=
|
||||
google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=
|
||||
google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8/go.mod h1:0H1ncTHf11KCFhTc/+EFRbzSCOZx+VUbRMk55Yv5MYk=
|
||||
|
@ -1006,10 +1174,33 @@ google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvx
|
|||
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
|
||||
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
|
||||
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a h1:pOwg4OoaRYScjmR4LlLgdtnyoHYTSAVhhqe5uPdpII8=
|
||||
google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
|
||||
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c h1:wtujag7C+4D6KMoulW9YauvK2lgdvCMS260jsqqBXr0=
|
||||
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
|
||||
google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
|
@ -1017,10 +1208,24 @@ google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ij
|
|||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.1 h1:zvIju4sqAGvwKspUQOhwnpcqSbzi7/H6QomNNjTL4sk=
|
||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
|
||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
|
||||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
||||
google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
|
||||
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.38.0 h1:/9BgsAsa5nWe26HqOlvlgJnqBuktYOLCgjCPqsa56W0=
|
||||
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
|
@ -1048,6 +1253,7 @@ gopkg.in/gcfg.v1 v1.2.0/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
|
|||
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/mcuadros/go-syslog.v2 v2.2.1/go.mod h1:l5LPIyOOyIdQquNg+oU6Z3524YwrcqEm0aKH+5zpt2U=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||
|
@ -1058,6 +1264,7 @@ gopkg.in/warnings.v0 v0.1.1/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRN
|
|||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
|
@ -1080,6 +1287,7 @@ honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWh
|
|||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
k8s.io/api v0.21.3 h1:cblWILbLO8ar+Fj6xdDGr603HRsf8Wu9E9rngJeprZQ=
|
||||
k8s.io/api v0.21.3/go.mod h1:hUgeYHUbBp23Ue4qdX9tR8/ANi/g3ehylAqDn9NWVOg=
|
||||
k8s.io/apiextensions-apiserver v0.21.3 h1:+B6biyUWpqt41kz5x6peIsljlsuwvNAp/oFax/j2/aY=
|
||||
|
@ -1112,6 +1320,8 @@ k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
|||
k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
||||
k8s.io/klog/v2 v2.8.0 h1:Q3gmuM9hKEjefWFFYF0Mat+YyFJvsUyYuwyNNJ5C9Ts=
|
||||
k8s.io/klog/v2 v2.8.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
|
||||
k8s.io/klog/v2 v2.9.0 h1:D7HV+n1V57XeZ0m6tdRkfknthUaM06VFbWldOFh8kzM=
|
||||
k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
|
||||
k8s.io/kube-aggregator v0.21.3/go.mod h1:9OIUuR5KIsNZYP/Xsh4HBsaqbS7ICJpRz3XSKtKajRc=
|
||||
k8s.io/kube-controller-manager v0.21.3/go.mod h1:O2HROjiyr1+L/YqnMabe4axJ6b3lhVqICA0PZc24uF4=
|
||||
k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM=
|
||||
|
@ -1131,6 +1341,7 @@ k8s.io/sample-apiserver v0.21.3/go.mod h1:H6DD20JK4QGmW5MGJc/sWbQxbGY5TIjbpwjUOv
|
|||
k8s.io/system-validators v1.2.0/go.mod h1:bPldcLgkIUK22ALflnsXk8pvkTEndYdNuaHH6gRrl0Q=
|
||||
k8s.io/utils v0.0.0-20200603063816-c1c6865ac451/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
k8s.io/utils v0.0.0-20210527160623-6fdb442a123b/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
k8s.io/utils v0.0.0-20210722164352-7f3ee0f31471 h1:DnzUXII7sVg1FJ/4JX6YDRJfLNAC7idRatPwe07suiI=
|
||||
k8s.io/utils v0.0.0-20210722164352-7f3ee0f31471/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw=
|
||||
|
@ -1144,7 +1355,10 @@ rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
|||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.19 h1:0jaDAAxtqIrrqas4vtTqxct4xS5kHfRNycTRLTyJmVM=
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.19/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
|
||||
sigs.k8s.io/cluster-api v0.4.0 h1:y9MxtU1uW9r9JtDyOQ/9BRXZEau2PGl2yOIozaxXO0E=
|
||||
sigs.k8s.io/cluster-api v0.4.0/go.mod h1:9ALETQ/6KGZ/kYiqvQGfjOx0CfVGE39d4VP3UrS5B24=
|
||||
sigs.k8s.io/controller-runtime v0.6.1/go.mod h1:XRYBPdbf5XJu9kpS84VJiZ7h/u1hF3gEORz0efEja7A=
|
||||
sigs.k8s.io/controller-runtime v0.9.1/go.mod h1:cTqsgnwSOsYS03XwySYZj8k6vf0+eC4FJRcCgQ9elb4=
|
||||
sigs.k8s.io/controller-runtime v0.9.5 h1:WThcFE6cqctTn2jCZprLICO6BaKZfhsT37uAapTNfxc=
|
||||
sigs.k8s.io/controller-runtime v0.9.5/go.mod h1:q6PpkM5vqQubEKUKOM6qr06oXGzOBcCby1DA9FbyZeA=
|
||||
sigs.k8s.io/controller-tools v0.3.0/go.mod h1:enhtKGfxZD1GFEoMgP8Fdbu+uKQ/cq1/WGJhdVChfvI=
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"k8s.io/client-go/rest"
|
||||
clusterapiv1alpha4 "sigs.k8s.io/cluster-api/api/v1alpha4"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
mcsv1alpha1 "sigs.k8s.io/mcs-api/pkg/apis/v1alpha1"
|
||||
|
||||
|
@ -16,11 +17,12 @@ import (
|
|||
var aggregatedScheme = runtime.NewScheme()
|
||||
|
||||
func init() {
|
||||
var _ = scheme.AddToScheme(aggregatedScheme) // add Kubernetes schemes
|
||||
var _ = clusterv1alpha1.AddToScheme(aggregatedScheme) // add cluster schemes
|
||||
var _ = policyv1alpha1.AddToScheme(aggregatedScheme) // add propagation schemes
|
||||
var _ = workv1alpha1.AddToScheme(aggregatedScheme) // add work schemes
|
||||
var _ = mcsv1alpha1.AddToScheme(aggregatedScheme) // add mcs-api schemes
|
||||
var _ = scheme.AddToScheme(aggregatedScheme) // add Kubernetes schemes
|
||||
var _ = clusterv1alpha1.AddToScheme(aggregatedScheme) // add cluster schemes
|
||||
var _ = policyv1alpha1.AddToScheme(aggregatedScheme) // add propagation schemes
|
||||
var _ = workv1alpha1.AddToScheme(aggregatedScheme) // add work schemes
|
||||
var _ = mcsv1alpha1.AddToScheme(aggregatedScheme) // add mcs-api schemes
|
||||
var _ = clusterapiv1alpha4.AddToScheme(aggregatedScheme) // add cluster-api v1alpha4 schemes
|
||||
}
|
||||
|
||||
// NewSchema returns a singleton schema set which aggregated Kubernetes's schemes and extended schemes.
|
||||
|
|
|
@ -315,7 +315,7 @@ func (tf Transform) Option() Option { return tf.trans }
|
|||
// pops the address from the stack. Thus, when traversing into a pointer from
|
||||
// reflect.Ptr, reflect.Slice element, or reflect.Map, we can detect cycles
|
||||
// by checking whether the pointer has already been visited. The cycle detection
|
||||
// uses a seperate stack for the x and y values.
|
||||
// uses a separate stack for the x and y values.
|
||||
//
|
||||
// If a cycle is detected we need to determine whether the two pointers
|
||||
// should be considered equal. The definition of equality chosen by Equal
|
||||
|
|
|
@ -7,6 +7,7 @@ package cmp
|
|||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"math"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
@ -96,15 +97,16 @@ func (opts formatOptions) FormatDiffSlice(v *valueNode) textNode {
|
|||
}
|
||||
|
||||
// Auto-detect the type of the data.
|
||||
var isLinedText, isText, isBinary bool
|
||||
var sx, sy string
|
||||
var ssx, ssy []string
|
||||
var isString, isMostlyText, isPureLinedText, isBinary bool
|
||||
switch {
|
||||
case t.Kind() == reflect.String:
|
||||
sx, sy = vx.String(), vy.String()
|
||||
isText = true // Initial estimate, verify later
|
||||
isString = true
|
||||
case t.Kind() == reflect.Slice && t.Elem() == reflect.TypeOf(byte(0)):
|
||||
sx, sy = string(vx.Bytes()), string(vy.Bytes())
|
||||
isBinary = true // Initial estimate, verify later
|
||||
isString = true
|
||||
case t.Kind() == reflect.Array:
|
||||
// Arrays need to be addressable for slice operations to work.
|
||||
vx2, vy2 := reflect.New(t).Elem(), reflect.New(t).Elem()
|
||||
|
@ -112,13 +114,12 @@ func (opts formatOptions) FormatDiffSlice(v *valueNode) textNode {
|
|||
vy2.Set(vy)
|
||||
vx, vy = vx2, vy2
|
||||
}
|
||||
if isText || isBinary {
|
||||
var numLines, lastLineIdx, maxLineLen int
|
||||
isBinary = !utf8.ValidString(sx) || !utf8.ValidString(sy)
|
||||
if isString {
|
||||
var numTotalRunes, numValidRunes, numLines, lastLineIdx, maxLineLen int
|
||||
for i, r := range sx + sy {
|
||||
if !(unicode.IsPrint(r) || unicode.IsSpace(r)) || r == utf8.RuneError {
|
||||
isBinary = true
|
||||
break
|
||||
numTotalRunes++
|
||||
if (unicode.IsPrint(r) || unicode.IsSpace(r)) && r != utf8.RuneError {
|
||||
numValidRunes++
|
||||
}
|
||||
if r == '\n' {
|
||||
if maxLineLen < i-lastLineIdx {
|
||||
|
@ -128,8 +129,26 @@ func (opts formatOptions) FormatDiffSlice(v *valueNode) textNode {
|
|||
numLines++
|
||||
}
|
||||
}
|
||||
isText = !isBinary
|
||||
isLinedText = isText && numLines >= 4 && maxLineLen <= 1024
|
||||
isPureText := numValidRunes == numTotalRunes
|
||||
isMostlyText = float64(numValidRunes) > math.Floor(0.90*float64(numTotalRunes))
|
||||
isPureLinedText = isPureText && numLines >= 4 && maxLineLen <= 1024
|
||||
isBinary = !isMostlyText
|
||||
|
||||
// Avoid diffing by lines if it produces a significantly more complex
|
||||
// edit script than diffing by bytes.
|
||||
if isPureLinedText {
|
||||
ssx = strings.Split(sx, "\n")
|
||||
ssy = strings.Split(sy, "\n")
|
||||
esLines := diff.Difference(len(ssx), len(ssy), func(ix, iy int) diff.Result {
|
||||
return diff.BoolResult(ssx[ix] == ssy[iy])
|
||||
})
|
||||
esBytes := diff.Difference(len(sx), len(sy), func(ix, iy int) diff.Result {
|
||||
return diff.BoolResult(sx[ix] == sy[iy])
|
||||
})
|
||||
efficiencyLines := float64(esLines.Dist()) / float64(len(esLines))
|
||||
efficiencyBytes := float64(esBytes.Dist()) / float64(len(esBytes))
|
||||
isPureLinedText = efficiencyLines < 4*efficiencyBytes
|
||||
}
|
||||
}
|
||||
|
||||
// Format the string into printable records.
|
||||
|
@ -138,9 +157,7 @@ func (opts formatOptions) FormatDiffSlice(v *valueNode) textNode {
|
|||
switch {
|
||||
// If the text appears to be multi-lined text,
|
||||
// then perform differencing across individual lines.
|
||||
case isLinedText:
|
||||
ssx := strings.Split(sx, "\n")
|
||||
ssy := strings.Split(sy, "\n")
|
||||
case isPureLinedText:
|
||||
list = opts.formatDiffSlice(
|
||||
reflect.ValueOf(ssx), reflect.ValueOf(ssy), 1, "line",
|
||||
func(v reflect.Value, d diffMode) textRecord {
|
||||
|
@ -229,7 +246,7 @@ func (opts formatOptions) FormatDiffSlice(v *valueNode) textNode {
|
|||
// If the text appears to be single-lined text,
|
||||
// then perform differencing in approximately fixed-sized chunks.
|
||||
// The output is printed as quoted strings.
|
||||
case isText:
|
||||
case isMostlyText:
|
||||
list = opts.formatDiffSlice(
|
||||
reflect.ValueOf(sx), reflect.ValueOf(sy), 64, "byte",
|
||||
func(v reflect.Value, d diffMode) textRecord {
|
||||
|
@ -237,7 +254,6 @@ func (opts formatOptions) FormatDiffSlice(v *valueNode) textNode {
|
|||
return textRecord{Diff: d, Value: textLine(s)}
|
||||
},
|
||||
)
|
||||
delim = ""
|
||||
|
||||
// If the text appears to be binary data,
|
||||
// then perform differencing in approximately fixed-sized chunks.
|
||||
|
@ -299,7 +315,7 @@ func (opts formatOptions) FormatDiffSlice(v *valueNode) textNode {
|
|||
|
||||
// Wrap the output with appropriate type information.
|
||||
var out textNode = &textWrap{Prefix: "{", Value: list, Suffix: "}"}
|
||||
if !isText {
|
||||
if !isMostlyText {
|
||||
// The "{...}" byte-sequence literal is not valid Go syntax for strings.
|
||||
// Emit the type for extra clarity (e.g. "string{...}").
|
||||
if t.Kind() == reflect.String {
|
||||
|
@ -338,8 +354,11 @@ func (opts formatOptions) formatDiffSlice(
|
|||
vx, vy reflect.Value, chunkSize int, name string,
|
||||
makeRec func(reflect.Value, diffMode) textRecord,
|
||||
) (list textList) {
|
||||
es := diff.Difference(vx.Len(), vy.Len(), func(ix int, iy int) diff.Result {
|
||||
return diff.BoolResult(vx.Index(ix).Interface() == vy.Index(iy).Interface())
|
||||
eq := func(ix, iy int) bool {
|
||||
return vx.Index(ix).Interface() == vy.Index(iy).Interface()
|
||||
}
|
||||
es := diff.Difference(vx.Len(), vy.Len(), func(ix, iy int) diff.Result {
|
||||
return diff.BoolResult(eq(ix, iy))
|
||||
})
|
||||
|
||||
appendChunks := func(v reflect.Value, d diffMode) int {
|
||||
|
@ -364,6 +383,7 @@ func (opts formatOptions) formatDiffSlice(
|
|||
|
||||
groups := coalesceAdjacentEdits(name, es)
|
||||
groups = coalesceInterveningIdentical(groups, chunkSize/4)
|
||||
groups = cleanupSurroundingIdentical(groups, eq)
|
||||
maxGroup := diffStats{Name: name}
|
||||
for i, ds := range groups {
|
||||
if maxLen >= 0 && numDiffs >= maxLen {
|
||||
|
@ -416,25 +436,36 @@ func (opts formatOptions) formatDiffSlice(
|
|||
|
||||
// coalesceAdjacentEdits coalesces the list of edits into groups of adjacent
|
||||
// equal or unequal counts.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// Input: "..XXY...Y"
|
||||
// Output: [
|
||||
// {NumIdentical: 2},
|
||||
// {NumRemoved: 2, NumInserted 1},
|
||||
// {NumIdentical: 3},
|
||||
// {NumInserted: 1},
|
||||
// ]
|
||||
//
|
||||
func coalesceAdjacentEdits(name string, es diff.EditScript) (groups []diffStats) {
|
||||
var prevCase int // Arbitrary index into which case last occurred
|
||||
lastStats := func(i int) *diffStats {
|
||||
if prevCase != i {
|
||||
var prevMode byte
|
||||
lastStats := func(mode byte) *diffStats {
|
||||
if prevMode != mode {
|
||||
groups = append(groups, diffStats{Name: name})
|
||||
prevCase = i
|
||||
prevMode = mode
|
||||
}
|
||||
return &groups[len(groups)-1]
|
||||
}
|
||||
for _, e := range es {
|
||||
switch e {
|
||||
case diff.Identity:
|
||||
lastStats(1).NumIdentical++
|
||||
lastStats('=').NumIdentical++
|
||||
case diff.UniqueX:
|
||||
lastStats(2).NumRemoved++
|
||||
lastStats('!').NumRemoved++
|
||||
case diff.UniqueY:
|
||||
lastStats(2).NumInserted++
|
||||
lastStats('!').NumInserted++
|
||||
case diff.Modified:
|
||||
lastStats(2).NumModified++
|
||||
lastStats('!').NumModified++
|
||||
}
|
||||
}
|
||||
return groups
|
||||
|
@ -444,6 +475,35 @@ func coalesceAdjacentEdits(name string, es diff.EditScript) (groups []diffStats)
|
|||
// equal groups into adjacent unequal groups that currently result in a
|
||||
// dual inserted/removed printout. This acts as a high-pass filter to smooth
|
||||
// out high-frequency changes within the windowSize.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// WindowSize: 16,
|
||||
// Input: [
|
||||
// {NumIdentical: 61}, // group 0
|
||||
// {NumRemoved: 3, NumInserted: 1}, // group 1
|
||||
// {NumIdentical: 6}, // ├── coalesce
|
||||
// {NumInserted: 2}, // ├── coalesce
|
||||
// {NumIdentical: 1}, // ├── coalesce
|
||||
// {NumRemoved: 9}, // └── coalesce
|
||||
// {NumIdentical: 64}, // group 2
|
||||
// {NumRemoved: 3, NumInserted: 1}, // group 3
|
||||
// {NumIdentical: 6}, // ├── coalesce
|
||||
// {NumInserted: 2}, // ├── coalesce
|
||||
// {NumIdentical: 1}, // ├── coalesce
|
||||
// {NumRemoved: 7}, // ├── coalesce
|
||||
// {NumIdentical: 1}, // ├── coalesce
|
||||
// {NumRemoved: 2}, // └── coalesce
|
||||
// {NumIdentical: 63}, // group 4
|
||||
// ]
|
||||
// Output: [
|
||||
// {NumIdentical: 61},
|
||||
// {NumIdentical: 7, NumRemoved: 12, NumInserted: 3},
|
||||
// {NumIdentical: 64},
|
||||
// {NumIdentical: 8, NumRemoved: 12, NumInserted: 3},
|
||||
// {NumIdentical: 63},
|
||||
// ]
|
||||
//
|
||||
func coalesceInterveningIdentical(groups []diffStats, windowSize int) []diffStats {
|
||||
groups, groupsOrig := groups[:0], groups
|
||||
for i, ds := range groupsOrig {
|
||||
|
@ -463,3 +523,91 @@ func coalesceInterveningIdentical(groups []diffStats, windowSize int) []diffStat
|
|||
}
|
||||
return groups
|
||||
}
|
||||
|
||||
// cleanupSurroundingIdentical scans through all unequal groups, and
|
||||
// moves any leading sequence of equal elements to the preceding equal group and
|
||||
// moves and trailing sequence of equal elements to the succeeding equal group.
|
||||
//
|
||||
// This is necessary since coalesceInterveningIdentical may coalesce edit groups
|
||||
// together such that leading/trailing spans of equal elements becomes possible.
|
||||
// Note that this can occur even with an optimal diffing algorithm.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// Input: [
|
||||
// {NumIdentical: 61},
|
||||
// {NumIdentical: 1 , NumRemoved: 11, NumInserted: 2}, // assume 3 leading identical elements
|
||||
// {NumIdentical: 67},
|
||||
// {NumIdentical: 7, NumRemoved: 12, NumInserted: 3}, // assume 10 trailing identical elements
|
||||
// {NumIdentical: 54},
|
||||
// ]
|
||||
// Output: [
|
||||
// {NumIdentical: 64}, // incremented by 3
|
||||
// {NumRemoved: 9},
|
||||
// {NumIdentical: 67},
|
||||
// {NumRemoved: 9},
|
||||
// {NumIdentical: 64}, // incremented by 10
|
||||
// ]
|
||||
//
|
||||
func cleanupSurroundingIdentical(groups []diffStats, eq func(i, j int) bool) []diffStats {
|
||||
var ix, iy int // indexes into sequence x and y
|
||||
for i, ds := range groups {
|
||||
// Handle equal group.
|
||||
if ds.NumDiff() == 0 {
|
||||
ix += ds.NumIdentical
|
||||
iy += ds.NumIdentical
|
||||
continue
|
||||
}
|
||||
|
||||
// Handle unequal group.
|
||||
nx := ds.NumIdentical + ds.NumRemoved + ds.NumModified
|
||||
ny := ds.NumIdentical + ds.NumInserted + ds.NumModified
|
||||
var numLeadingIdentical, numTrailingIdentical int
|
||||
for i := 0; i < nx && i < ny && eq(ix+i, iy+i); i++ {
|
||||
numLeadingIdentical++
|
||||
}
|
||||
for i := 0; i < nx && i < ny && eq(ix+nx-1-i, iy+ny-1-i); i++ {
|
||||
numTrailingIdentical++
|
||||
}
|
||||
if numIdentical := numLeadingIdentical + numTrailingIdentical; numIdentical > 0 {
|
||||
if numLeadingIdentical > 0 {
|
||||
// Remove leading identical span from this group and
|
||||
// insert it into the preceding group.
|
||||
if i-1 >= 0 {
|
||||
groups[i-1].NumIdentical += numLeadingIdentical
|
||||
} else {
|
||||
// No preceding group exists, so prepend a new group,
|
||||
// but do so after we finish iterating over all groups.
|
||||
defer func() {
|
||||
groups = append([]diffStats{{Name: groups[0].Name, NumIdentical: numLeadingIdentical}}, groups...)
|
||||
}()
|
||||
}
|
||||
// Increment indexes since the preceding group would have handled this.
|
||||
ix += numLeadingIdentical
|
||||
iy += numLeadingIdentical
|
||||
}
|
||||
if numTrailingIdentical > 0 {
|
||||
// Remove trailing identical span from this group and
|
||||
// insert it into the succeeding group.
|
||||
if i+1 < len(groups) {
|
||||
groups[i+1].NumIdentical += numTrailingIdentical
|
||||
} else {
|
||||
// No succeeding group exists, so append a new group,
|
||||
// but do so after we finish iterating over all groups.
|
||||
defer func() {
|
||||
groups = append(groups, diffStats{Name: groups[len(groups)-1].Name, NumIdentical: numTrailingIdentical})
|
||||
}()
|
||||
}
|
||||
// Do not increment indexes since the succeeding group will handle this.
|
||||
}
|
||||
|
||||
// Update this group since some identical elements were removed.
|
||||
nx -= numIdentical
|
||||
ny -= numIdentical
|
||||
groups[i] = diffStats{Name: ds.Name, NumRemoved: nx, NumInserted: ny}
|
||||
}
|
||||
ix += nx
|
||||
iy += ny
|
||||
}
|
||||
return groups
|
||||
}
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
language: go
|
||||
|
||||
go:
|
||||
- 1.4
|
||||
- 1.3
|
||||
- 1.2
|
||||
- tip
|
||||
|
||||
install:
|
||||
- if ! go get code.google.com/p/go.tools/cmd/cover; then go get golang.org/x/tools/cmd/cover; fi
|
||||
- 1.11.x
|
||||
- 1.12.x
|
||||
- 1.13.x
|
||||
- master
|
||||
|
||||
script:
|
||||
- go test -cover
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# How to contribute #
|
||||
|
||||
We'd love to accept your patches and contributions to this project. There are
|
||||
a just a few small guidelines you need to follow.
|
||||
just a few small guidelines you need to follow.
|
||||
|
||||
|
||||
## Contributor License Agreement ##
|
||||
|
|
|
@ -68,4 +68,22 @@ f.Fuzz(&myObject) // Type will correspond to whether A or B info is set.
|
|||
|
||||
See more examples in ```example_test.go```.
|
||||
|
||||
You can use this library for easier [go-fuzz](https://github.com/dvyukov/go-fuzz)ing.
|
||||
go-fuzz provides the user a byte-slice, which should be converted to different inputs
|
||||
for the tested function. This library can help convert the byte slice. Consider for
|
||||
example a fuzz test for a the function `mypackage.MyFunc` that takes an int arguments:
|
||||
```go
|
||||
// +build gofuzz
|
||||
package mypackage
|
||||
|
||||
import fuzz "github.com/google/gofuzz"
|
||||
|
||||
func Fuzz(data []byte) int {
|
||||
var i int
|
||||
fuzz.NewFromGoFuzz(data).Fuzz(&i)
|
||||
MyFunc(i)
|
||||
return 0
|
||||
}
|
||||
```
|
||||
|
||||
Happy testing!
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
Copyright 2014 Google Inc. All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package bytesource provides a rand.Source64 that is determined by a slice of bytes.
|
||||
package bytesource
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"io"
|
||||
"math/rand"
|
||||
)
|
||||
|
||||
// ByteSource implements rand.Source64 determined by a slice of bytes. The random numbers are
|
||||
// generated from each 8 bytes in the slice, until the last bytes are consumed, from which a
|
||||
// fallback pseudo random source is created in case more random numbers are required.
|
||||
// It also exposes a `bytes.Reader` API, which lets callers consume the bytes directly.
|
||||
type ByteSource struct {
|
||||
*bytes.Reader
|
||||
fallback rand.Source
|
||||
}
|
||||
|
||||
// New returns a new ByteSource from a given slice of bytes.
|
||||
func New(input []byte) *ByteSource {
|
||||
s := &ByteSource{
|
||||
Reader: bytes.NewReader(input),
|
||||
fallback: rand.NewSource(0),
|
||||
}
|
||||
if len(input) > 0 {
|
||||
s.fallback = rand.NewSource(int64(s.consumeUint64()))
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *ByteSource) Uint64() uint64 {
|
||||
// Return from input if it was not exhausted.
|
||||
if s.Len() > 0 {
|
||||
return s.consumeUint64()
|
||||
}
|
||||
|
||||
// Input was exhausted, return random number from fallback (in this case fallback should not be
|
||||
// nil). Try first having a Uint64 output (Should work in current rand implementation),
|
||||
// otherwise return a conversion of Int63.
|
||||
if s64, ok := s.fallback.(rand.Source64); ok {
|
||||
return s64.Uint64()
|
||||
}
|
||||
return uint64(s.fallback.Int63())
|
||||
}
|
||||
|
||||
func (s *ByteSource) Int63() int64 {
|
||||
return int64(s.Uint64() >> 1)
|
||||
}
|
||||
|
||||
func (s *ByteSource) Seed(seed int64) {
|
||||
s.fallback = rand.NewSource(seed)
|
||||
s.Reader = bytes.NewReader(nil)
|
||||
}
|
||||
|
||||
// consumeUint64 reads 8 bytes from the input and convert them to a uint64. It assumes that the the
|
||||
// bytes reader is not empty.
|
||||
func (s *ByteSource) consumeUint64() uint64 {
|
||||
var bytes [8]byte
|
||||
_, err := s.Read(bytes[:])
|
||||
if err != nil && err != io.EOF {
|
||||
panic("failed reading source") // Should not happen.
|
||||
}
|
||||
return binary.BigEndian.Uint64(bytes[:])
|
||||
}
|
|
@ -22,6 +22,9 @@ import (
|
|||
"reflect"
|
||||
"regexp"
|
||||
"time"
|
||||
|
||||
"github.com/google/gofuzz/bytesource"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// fuzzFuncMap is a map from a type to a fuzzFunc that handles that type.
|
||||
|
@ -61,6 +64,34 @@ func NewWithSeed(seed int64) *Fuzzer {
|
|||
return f
|
||||
}
|
||||
|
||||
// NewFromGoFuzz is a helper function that enables using gofuzz (this
|
||||
// project) with go-fuzz (https://github.com/dvyukov/go-fuzz) for continuous
|
||||
// fuzzing. Essentially, it enables translating the fuzzing bytes from
|
||||
// go-fuzz to any Go object using this library.
|
||||
//
|
||||
// This implementation promises a constant translation from a given slice of
|
||||
// bytes to the fuzzed objects. This promise will remain over future
|
||||
// versions of Go and of this library.
|
||||
//
|
||||
// Note: the returned Fuzzer should not be shared between multiple goroutines,
|
||||
// as its deterministic output will no longer be available.
|
||||
//
|
||||
// Example: use go-fuzz to test the function `MyFunc(int)` in the package
|
||||
// `mypackage`. Add the file: "mypacakge_fuzz.go" with the content:
|
||||
//
|
||||
// // +build gofuzz
|
||||
// package mypacakge
|
||||
// import fuzz "github.com/google/gofuzz"
|
||||
// func Fuzz(data []byte) int {
|
||||
// var i int
|
||||
// fuzz.NewFromGoFuzz(data).Fuzz(&i)
|
||||
// MyFunc(i)
|
||||
// return 0
|
||||
// }
|
||||
func NewFromGoFuzz(data []byte) *Fuzzer {
|
||||
return New().RandSource(bytesource.New(data))
|
||||
}
|
||||
|
||||
// Funcs adds each entry in fuzzFuncs as a custom fuzzing function.
|
||||
//
|
||||
// Each entry in fuzzFuncs must be a function taking two parameters.
|
||||
|
@ -141,7 +172,7 @@ func (f *Fuzzer) genElementCount() int {
|
|||
}
|
||||
|
||||
func (f *Fuzzer) genShouldFill() bool {
|
||||
return f.r.Float64() > f.nilChance
|
||||
return f.r.Float64() >= f.nilChance
|
||||
}
|
||||
|
||||
// MaxDepth sets the maximum number of recursive fuzz calls that will be made
|
||||
|
@ -240,6 +271,7 @@ func (fc *fuzzerContext) doFuzz(v reflect.Value, flags uint64) {
|
|||
fn(v, fc.fuzzer.r)
|
||||
return
|
||||
}
|
||||
|
||||
switch v.Kind() {
|
||||
case reflect.Map:
|
||||
if fc.fuzzer.genShouldFill() {
|
||||
|
@ -450,10 +482,10 @@ var fillFuncMap = map[reflect.Kind]func(reflect.Value, *rand.Rand){
|
|||
v.SetFloat(r.Float64())
|
||||
},
|
||||
reflect.Complex64: func(v reflect.Value, r *rand.Rand) {
|
||||
panic("unimplemented")
|
||||
v.SetComplex(complex128(complex(r.Float32(), r.Float32())))
|
||||
},
|
||||
reflect.Complex128: func(v reflect.Value, r *rand.Rand) {
|
||||
panic("unimplemented")
|
||||
v.SetComplex(complex(r.Float64(), r.Float64()))
|
||||
},
|
||||
reflect.String: func(v reflect.Value, r *rand.Rand) {
|
||||
v.SetString(randString(r))
|
||||
|
@ -465,38 +497,105 @@ var fillFuncMap = map[reflect.Kind]func(reflect.Value, *rand.Rand){
|
|||
|
||||
// randBool returns true or false randomly.
|
||||
func randBool(r *rand.Rand) bool {
|
||||
if r.Int()&1 == 1 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
return r.Int31()&(1<<30) == 0
|
||||
}
|
||||
|
||||
type charRange struct {
|
||||
first, last rune
|
||||
type int63nPicker interface {
|
||||
Int63n(int64) int64
|
||||
}
|
||||
|
||||
// UnicodeRange describes a sequential range of unicode characters.
|
||||
// Last must be numerically greater than First.
|
||||
type UnicodeRange struct {
|
||||
First, Last rune
|
||||
}
|
||||
|
||||
// UnicodeRanges describes an arbitrary number of sequential ranges of unicode characters.
|
||||
// To be useful, each range must have at least one character (First <= Last) and
|
||||
// there must be at least one range.
|
||||
type UnicodeRanges []UnicodeRange
|
||||
|
||||
// choose returns a random unicode character from the given range, using the
|
||||
// given randomness source.
|
||||
func (r *charRange) choose(rand *rand.Rand) rune {
|
||||
count := int64(r.last - r.first)
|
||||
return r.first + rune(rand.Int63n(count))
|
||||
func (ur UnicodeRange) choose(r int63nPicker) rune {
|
||||
count := int64(ur.Last - ur.First + 1)
|
||||
return ur.First + rune(r.Int63n(count))
|
||||
}
|
||||
|
||||
var unicodeRanges = []charRange{
|
||||
// CustomStringFuzzFunc constructs a FuzzFunc which produces random strings.
|
||||
// Each character is selected from the range ur. If there are no characters
|
||||
// in the range (cr.Last < cr.First), this will panic.
|
||||
func (ur UnicodeRange) CustomStringFuzzFunc() func(s *string, c Continue) {
|
||||
ur.check()
|
||||
return func(s *string, c Continue) {
|
||||
*s = ur.randString(c.Rand)
|
||||
}
|
||||
}
|
||||
|
||||
// check is a function that used to check whether the first of ur(UnicodeRange)
|
||||
// is greater than the last one.
|
||||
func (ur UnicodeRange) check() {
|
||||
if ur.Last < ur.First {
|
||||
panic("The last encoding must be greater than the first one.")
|
||||
}
|
||||
}
|
||||
|
||||
// randString of UnicodeRange makes a random string up to 20 characters long.
|
||||
// Each character is selected form ur(UnicodeRange).
|
||||
func (ur UnicodeRange) randString(r *rand.Rand) string {
|
||||
n := r.Intn(20)
|
||||
sb := strings.Builder{}
|
||||
sb.Grow(n)
|
||||
for i := 0; i < n; i++ {
|
||||
sb.WriteRune(ur.choose(r))
|
||||
}
|
||||
return sb.String()
|
||||
}
|
||||
|
||||
// defaultUnicodeRanges sets a default unicode range when user do not set
|
||||
// CustomStringFuzzFunc() but wants fuzz string.
|
||||
var defaultUnicodeRanges = UnicodeRanges{
|
||||
{' ', '~'}, // ASCII characters
|
||||
{'\u00a0', '\u02af'}, // Multi-byte encoded characters
|
||||
{'\u4e00', '\u9fff'}, // Common CJK (even longer encodings)
|
||||
}
|
||||
|
||||
// CustomStringFuzzFunc constructs a FuzzFunc which produces random strings.
|
||||
// Each character is selected from one of the ranges of ur(UnicodeRanges).
|
||||
// Each range has an equal probability of being chosen. If there are no ranges,
|
||||
// or a selected range has no characters (.Last < .First), this will panic.
|
||||
// Do not modify any of the ranges in ur after calling this function.
|
||||
func (ur UnicodeRanges) CustomStringFuzzFunc() func(s *string, c Continue) {
|
||||
// Check unicode ranges slice is empty.
|
||||
if len(ur) == 0 {
|
||||
panic("UnicodeRanges is empty.")
|
||||
}
|
||||
// if not empty, each range should be checked.
|
||||
for i := range ur {
|
||||
ur[i].check()
|
||||
}
|
||||
return func(s *string, c Continue) {
|
||||
*s = ur.randString(c.Rand)
|
||||
}
|
||||
}
|
||||
|
||||
// randString of UnicodeRanges makes a random string up to 20 characters long.
|
||||
// Each character is selected form one of the ranges of ur(UnicodeRanges),
|
||||
// and each range has an equal probability of being chosen.
|
||||
func (ur UnicodeRanges) randString(r *rand.Rand) string {
|
||||
n := r.Intn(20)
|
||||
sb := strings.Builder{}
|
||||
sb.Grow(n)
|
||||
for i := 0; i < n; i++ {
|
||||
sb.WriteRune(ur[r.Intn(len(ur))].choose(r))
|
||||
}
|
||||
return sb.String()
|
||||
}
|
||||
|
||||
// randString makes a random string up to 20 characters long. The returned string
|
||||
// may include a variety of (valid) UTF-8 encodings.
|
||||
func randString(r *rand.Rand) string {
|
||||
n := r.Intn(20)
|
||||
runes := make([]rune, n)
|
||||
for i := range runes {
|
||||
runes[i] = unicodeRanges[r.Intn(len(unicodeRanges))].choose(r)
|
||||
}
|
||||
return string(runes)
|
||||
return defaultUnicodeRanges.randString(r)
|
||||
}
|
||||
|
||||
// randUint64 makes random 64 bit numbers.
|
||||
|
|
|
@ -28,7 +28,7 @@ improve the documentation. Fix a typo, clarify an interface, add an
|
|||
example, anything goes!
|
||||
|
||||
The documentation is present in the [README][readme] and thorough the
|
||||
source code. On release, it gets updated on [GoDoc][godoc]. To make a
|
||||
source code. On release, it gets updated on [pkg.go.dev][pkg.go.dev]. To make a
|
||||
change to the documentation, create a pull request with your proposed
|
||||
changes. For simple changes like that, the easiest way to go is probably
|
||||
the "Fork this project and edit the file" button on Github, displayed at
|
||||
|
@ -123,7 +123,7 @@ Checklist:
|
|||
|
||||
[issues-tracker]: https://github.com/pelletier/go-toml/issues
|
||||
[bug-report]: https://github.com/pelletier/go-toml/issues/new?template=bug_report.md
|
||||
[godoc]: https://godoc.org/github.com/pelletier/go-toml
|
||||
[pkg.go.dev]: https://pkg.go.dev/github.com/pelletier/go-toml
|
||||
[readme]: ./README.md
|
||||
[fork]: https://help.github.com/articles/fork-a-repo
|
||||
[pull-request]: https://help.github.com/en/articles/creating-a-pull-request
|
||||
|
|
|
@ -1,6 +1,16 @@
|
|||
The bulk of github.com/pelletier/go-toml is distributed under the MIT license
|
||||
(see below), with the exception of localtime.go and localtime.test.go.
|
||||
Those two files have been copied over from Google's civil library at revision
|
||||
ed46f5086358513cf8c25f8e3f022cb838a49d66, and are distributed under the Apache
|
||||
2.0 license (see below).
|
||||
|
||||
|
||||
github.com/pelletier/go-toml:
|
||||
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013 - 2017 Thomas Pelletier, Eric Anderton
|
||||
Copyright (c) 2013 - 2021 Thomas Pelletier, Eric Anderton
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -19,3 +29,219 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
|
||||
localtime.go, localtime_test.go:
|
||||
|
||||
Originals:
|
||||
https://raw.githubusercontent.com/googleapis/google-cloud-go/ed46f5086358513cf8c25f8e3f022cb838a49d66/civil/civil.go
|
||||
https://raw.githubusercontent.com/googleapis/google-cloud-go/ed46f5086358513cf8c25f8e3f022cb838a49d66/civil/civil_test.go
|
||||
Changes:
|
||||
* Renamed files from civil* to localtime*.
|
||||
* Package changed from civil to toml.
|
||||
* 'Local' prefix added to all structs.
|
||||
License:
|
||||
https://raw.githubusercontent.com/googleapis/google-cloud-go/ed46f5086358513cf8c25f8e3f022cb838a49d66/LICENSE
|
||||
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
|
|
@ -1,17 +1,42 @@
|
|||
# go-toml
|
||||
|
||||
Go library for the [TOML](https://github.com/mojombo/toml) format.
|
||||
Go library for the [TOML](https://toml.io/) format.
|
||||
|
||||
This library supports TOML version
|
||||
[v1.0.0-rc.1](https://github.com/toml-lang/toml/blob/master/versions/en/toml-v1.0.0-rc.1.md)
|
||||
[v1.0.0-rc.3](https://toml.io/en/v1.0.0-rc.3)
|
||||
|
||||
[](http://godoc.org/github.com/pelletier/go-toml)
|
||||
[](https://pkg.go.dev/github.com/pelletier/go-toml)
|
||||
[](https://github.com/pelletier/go-toml/blob/master/LICENSE)
|
||||
[](https://dev.azure.com/pelletierthomas/go-toml-ci/_build/latest?definitionId=1&branchName=master)
|
||||
[](https://codecov.io/gh/pelletier/go-toml)
|
||||
[](https://goreportcard.com/report/github.com/pelletier/go-toml)
|
||||
[](https://app.fossa.io/projects/git%2Bgithub.com%2Fpelletier%2Fgo-toml?ref=badge_shield)
|
||||
|
||||
|
||||
## Development status
|
||||
|
||||
**ℹ️ Consider go-toml v2!**
|
||||
|
||||
The next version of go-toml is in [active development][v2-dev], and
|
||||
[nearing completion][v2-map].
|
||||
|
||||
Though technically in beta, v2 is already more tested, [fixes bugs][v1-bugs],
|
||||
and [much faster][v2-bench]. If you only need reading and writing TOML documents
|
||||
(majority of cases), those features are implemented and the API unlikely to
|
||||
change.
|
||||
|
||||
The remaining features (Document structure editing and tooling) will be added
|
||||
shortly. While pull-requests are welcome on v1, no active development is
|
||||
expected on it. When v2.0.0 is released, v1 will be deprecated.
|
||||
|
||||
👉 [go-toml v2][v2]
|
||||
|
||||
[v2]: https://github.com/pelletier/go-toml/tree/v2
|
||||
[v2-map]: https://github.com/pelletier/go-toml/discussions/506
|
||||
[v2-dev]: https://github.com/pelletier/go-toml/tree/v2
|
||||
[v1-bugs]: https://github.com/pelletier/go-toml/issues?q=is%3Aissue+is%3Aopen+label%3Av2-fixed
|
||||
[v2-bench]: https://github.com/pelletier/go-toml/tree/v2#benchmarks
|
||||
|
||||
## Features
|
||||
|
||||
Go-toml provides the following features for using data parsed from TOML documents:
|
||||
|
@ -81,11 +106,11 @@ for ii, item := range results.Values() {
|
|||
## Documentation
|
||||
|
||||
The documentation and additional examples are available at
|
||||
[godoc.org](http://godoc.org/github.com/pelletier/go-toml).
|
||||
[pkg.go.dev](https://pkg.go.dev/github.com/pelletier/go-toml).
|
||||
|
||||
## Tools
|
||||
|
||||
Go-toml provides two handy command line tools:
|
||||
Go-toml provides three handy command line tools:
|
||||
|
||||
* `tomll`: Reads TOML files and lints them.
|
||||
|
||||
|
@ -109,7 +134,7 @@ Go-toml provides two handy command line tools:
|
|||
|
||||
### Docker image
|
||||
|
||||
Those tools are also availble as a Docker image from
|
||||
Those tools are also available as a Docker image from
|
||||
[dockerhub](https://hub.docker.com/r/pelletier/go-toml). For example, to
|
||||
use `tomljson`:
|
||||
|
||||
|
@ -148,4 +173,4 @@ this document. The last two major versions of Go are supported
|
|||
|
||||
## License
|
||||
|
||||
The MIT License (MIT). Read [LICENSE](LICENSE).
|
||||
The MIT License (MIT) + Apache 2.0. Read [LICENSE](LICENSE).
|
||||
|
|
|
@ -2,30 +2,6 @@ trigger:
|
|||
- master
|
||||
|
||||
stages:
|
||||
- stage: fuzzit
|
||||
displayName: "Run Fuzzit"
|
||||
dependsOn: []
|
||||
condition: and(succeeded(), eq(variables['Build.SourceBranchName'], 'master'))
|
||||
jobs:
|
||||
- job: submit
|
||||
displayName: "Submit"
|
||||
pool:
|
||||
vmImage: ubuntu-latest
|
||||
steps:
|
||||
- task: GoTool@0
|
||||
displayName: "Install Go 1.15"
|
||||
inputs:
|
||||
version: "1.15"
|
||||
- script: echo "##vso[task.setvariable variable=PATH]${PATH}:/home/vsts/go/bin/"
|
||||
- script: mkdir -p ${HOME}/go/src/github.com/pelletier/go-toml
|
||||
- script: cp -R . ${HOME}/go/src/github.com/pelletier/go-toml
|
||||
- task: Bash@3
|
||||
inputs:
|
||||
filePath: './fuzzit.sh'
|
||||
env:
|
||||
TYPE: fuzzing
|
||||
FUZZIT_API_KEY: $(FUZZIT_API_KEY)
|
||||
|
||||
- stage: run_checks
|
||||
displayName: "Check"
|
||||
dependsOn: []
|
||||
|
@ -36,9 +12,9 @@ stages:
|
|||
vmImage: ubuntu-latest
|
||||
steps:
|
||||
- task: GoTool@0
|
||||
displayName: "Install Go 1.15"
|
||||
displayName: "Install Go 1.16"
|
||||
inputs:
|
||||
version: "1.15"
|
||||
version: "1.16"
|
||||
- task: Go@0
|
||||
displayName: "go fmt ./..."
|
||||
inputs:
|
||||
|
@ -51,9 +27,9 @@ stages:
|
|||
vmImage: ubuntu-latest
|
||||
steps:
|
||||
- task: GoTool@0
|
||||
displayName: "Install Go 1.15"
|
||||
displayName: "Install Go 1.16"
|
||||
inputs:
|
||||
version: "1.15"
|
||||
version: "1.16"
|
||||
- task: Go@0
|
||||
displayName: "Generate coverage"
|
||||
inputs:
|
||||
|
@ -71,37 +47,28 @@ stages:
|
|||
vmImage: ubuntu-latest
|
||||
steps:
|
||||
- task: GoTool@0
|
||||
displayName: "Install Go 1.15"
|
||||
displayName: "Install Go 1.16"
|
||||
inputs:
|
||||
version: "1.15"
|
||||
version: "1.16"
|
||||
- script: echo "##vso[task.setvariable variable=PATH]${PATH}:/home/vsts/go/bin/"
|
||||
- task: Bash@3
|
||||
inputs:
|
||||
filePath: './benchmark.sh'
|
||||
arguments: "master $(Build.Repository.Uri)"
|
||||
|
||||
- job: fuzzing
|
||||
displayName: "fuzzing"
|
||||
pool:
|
||||
vmImage: ubuntu-latest
|
||||
steps:
|
||||
- task: GoTool@0
|
||||
displayName: "Install Go 1.15"
|
||||
inputs:
|
||||
version: "1.15"
|
||||
- script: echo "##vso[task.setvariable variable=PATH]${PATH}:/home/vsts/go/bin/"
|
||||
- script: mkdir -p ${HOME}/go/src/github.com/pelletier/go-toml
|
||||
- script: cp -R . ${HOME}/go/src/github.com/pelletier/go-toml
|
||||
- task: Bash@3
|
||||
inputs:
|
||||
filePath: './fuzzit.sh'
|
||||
env:
|
||||
TYPE: local-regression
|
||||
|
||||
- job: go_unit_tests
|
||||
displayName: "unit tests"
|
||||
strategy:
|
||||
matrix:
|
||||
linux 1.16:
|
||||
goVersion: '1.16'
|
||||
imageName: 'ubuntu-latest'
|
||||
mac 1.16:
|
||||
goVersion: '1.16'
|
||||
imageName: 'macOS-latest'
|
||||
windows 1.16:
|
||||
goVersion: '1.16'
|
||||
imageName: 'windows-latest'
|
||||
linux 1.15:
|
||||
goVersion: '1.15'
|
||||
imageName: 'ubuntu-latest'
|
||||
|
@ -111,15 +78,6 @@ stages:
|
|||
windows 1.15:
|
||||
goVersion: '1.15'
|
||||
imageName: 'windows-latest'
|
||||
linux 1.14:
|
||||
goVersion: '1.14'
|
||||
imageName: 'ubuntu-latest'
|
||||
mac 1.14:
|
||||
goVersion: '1.14'
|
||||
imageName: 'macOS-latest'
|
||||
windows 1.14:
|
||||
goVersion: '1.14'
|
||||
imageName: 'windows-latest'
|
||||
pool:
|
||||
vmImage: $(imageName)
|
||||
steps:
|
||||
|
@ -155,7 +113,7 @@ stages:
|
|||
- task: GoTool@0
|
||||
displayName: "Install Go"
|
||||
inputs:
|
||||
version: 1.15
|
||||
version: 1.16
|
||||
- task: Bash@3
|
||||
inputs:
|
||||
targetType: inline
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
#!/bin/bash
|
||||
set -xe
|
||||
|
||||
# go-fuzz doesn't support modules yet, so ensure we do everything
|
||||
# in the old style GOPATH way
|
||||
export GO111MODULE="off"
|
||||
|
||||
# install go-fuzz
|
||||
go get -u github.com/dvyukov/go-fuzz/go-fuzz github.com/dvyukov/go-fuzz/go-fuzz-build
|
||||
|
||||
# target name can only contain lower-case letters (a-z), digits (0-9) and a dash (-)
|
||||
# to add another target, make sure to create it with `fuzzit create target`
|
||||
# before using `fuzzit create job`
|
||||
TARGET=toml-fuzzer
|
||||
|
||||
go-fuzz-build -libfuzzer -o ${TARGET}.a github.com/pelletier/go-toml
|
||||
clang -fsanitize=fuzzer ${TARGET}.a -o ${TARGET}
|
||||
|
||||
# install fuzzit for talking to fuzzit.dev service
|
||||
# or latest version:
|
||||
# https://github.com/fuzzitdev/fuzzit/releases/latest/download/fuzzit_Linux_x86_64
|
||||
wget -q -O fuzzit https://github.com/fuzzitdev/fuzzit/releases/download/v2.4.52/fuzzit_Linux_x86_64
|
||||
chmod a+x fuzzit
|
||||
|
||||
# TODO: change kkowalczyk to go-toml and create toml-fuzzer target there
|
||||
./fuzzit create job --type $TYPE go-toml/${TARGET} ${TARGET}
|
|
@ -1,5 +1,3 @@
|
|||
module github.com/pelletier/go-toml
|
||||
|
||||
go 1.12
|
||||
|
||||
require github.com/davecgh/go-spew v1.1.1
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.3 h1:fvjTMHxHEw/mxHbtzPi3JCcKXQRAnQTBRo6YCJSVHKI=
|
||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.5 h1:ymVxjfMaHvXD8RqPRmzHHsB3VvucivSkIAvJFDI5O3c=
|
||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo=
|
||||
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
@ -9,13 +9,10 @@ import (
|
|||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var dateRegexp *regexp.Regexp
|
||||
|
||||
// Define state functions
|
||||
type tomlLexStateFn func() tomlLexStateFn
|
||||
|
||||
|
@ -216,18 +213,12 @@ func (l *tomlLexer) lexRvalue() tomlLexStateFn {
|
|||
break
|
||||
}
|
||||
|
||||
possibleDate := l.peekString(35)
|
||||
dateSubmatches := dateRegexp.FindStringSubmatch(possibleDate)
|
||||
if dateSubmatches != nil && dateSubmatches[0] != "" {
|
||||
l.fastForward(len(dateSubmatches[0]))
|
||||
if dateSubmatches[2] == "" { // no timezone information => local date
|
||||
return l.lexLocalDate
|
||||
}
|
||||
return l.lexDate
|
||||
if next == '+' || next == '-' {
|
||||
return l.lexNumber
|
||||
}
|
||||
|
||||
if next == '+' || next == '-' || isDigit(next) {
|
||||
return l.lexNumber
|
||||
if isDigit(next) {
|
||||
return l.lexDateTimeOrNumber
|
||||
}
|
||||
|
||||
return l.errorf("no value can start with %c", next)
|
||||
|
@ -237,6 +228,32 @@ func (l *tomlLexer) lexRvalue() tomlLexStateFn {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (l *tomlLexer) lexDateTimeOrNumber() tomlLexStateFn {
|
||||
// Could be either a date/time, or a digit.
|
||||
// The options for date/times are:
|
||||
// YYYY-... => date or date-time
|
||||
// HH:... => time
|
||||
// Anything else should be a number.
|
||||
|
||||
lookAhead := l.peekString(5)
|
||||
if len(lookAhead) < 3 {
|
||||
return l.lexNumber()
|
||||
}
|
||||
|
||||
for idx, r := range lookAhead {
|
||||
if !isDigit(r) {
|
||||
if idx == 2 && r == ':' {
|
||||
return l.lexDateTimeOrTime()
|
||||
}
|
||||
if idx == 4 && r == '-' {
|
||||
return l.lexDateTimeOrTime()
|
||||
}
|
||||
return l.lexNumber()
|
||||
}
|
||||
}
|
||||
return l.lexNumber()
|
||||
}
|
||||
|
||||
func (l *tomlLexer) lexLeftCurlyBrace() tomlLexStateFn {
|
||||
l.next()
|
||||
l.emit(tokenLeftCurlyBrace)
|
||||
|
@ -254,14 +271,245 @@ func (l *tomlLexer) lexRightCurlyBrace() tomlLexStateFn {
|
|||
return l.lexRvalue
|
||||
}
|
||||
|
||||
func (l *tomlLexer) lexDate() tomlLexStateFn {
|
||||
l.emit(tokenDate)
|
||||
func (l *tomlLexer) lexDateTimeOrTime() tomlLexStateFn {
|
||||
// Example matches:
|
||||
// 1979-05-27T07:32:00Z
|
||||
// 1979-05-27T00:32:00-07:00
|
||||
// 1979-05-27T00:32:00.999999-07:00
|
||||
// 1979-05-27 07:32:00Z
|
||||
// 1979-05-27 00:32:00-07:00
|
||||
// 1979-05-27 00:32:00.999999-07:00
|
||||
// 1979-05-27T07:32:00
|
||||
// 1979-05-27T00:32:00.999999
|
||||
// 1979-05-27 07:32:00
|
||||
// 1979-05-27 00:32:00.999999
|
||||
// 1979-05-27
|
||||
// 07:32:00
|
||||
// 00:32:00.999999
|
||||
|
||||
// we already know those two are digits
|
||||
l.next()
|
||||
l.next()
|
||||
|
||||
// Got 2 digits. At that point it could be either a time or a date(-time).
|
||||
|
||||
r := l.next()
|
||||
if r == ':' {
|
||||
return l.lexTime()
|
||||
}
|
||||
|
||||
return l.lexDateTime()
|
||||
}
|
||||
|
||||
func (l *tomlLexer) lexDateTime() tomlLexStateFn {
|
||||
// This state accepts an offset date-time, a local date-time, or a local date.
|
||||
//
|
||||
// v--- cursor
|
||||
// 1979-05-27T07:32:00Z
|
||||
// 1979-05-27T00:32:00-07:00
|
||||
// 1979-05-27T00:32:00.999999-07:00
|
||||
// 1979-05-27 07:32:00Z
|
||||
// 1979-05-27 00:32:00-07:00
|
||||
// 1979-05-27 00:32:00.999999-07:00
|
||||
// 1979-05-27T07:32:00
|
||||
// 1979-05-27T00:32:00.999999
|
||||
// 1979-05-27 07:32:00
|
||||
// 1979-05-27 00:32:00.999999
|
||||
// 1979-05-27
|
||||
|
||||
// date
|
||||
|
||||
// already checked by lexRvalue
|
||||
l.next() // digit
|
||||
l.next() // -
|
||||
|
||||
for i := 0; i < 2; i++ {
|
||||
r := l.next()
|
||||
if !isDigit(r) {
|
||||
return l.errorf("invalid month digit in date: %c", r)
|
||||
}
|
||||
}
|
||||
|
||||
r := l.next()
|
||||
if r != '-' {
|
||||
return l.errorf("expected - to separate month of a date, not %c", r)
|
||||
}
|
||||
|
||||
for i := 0; i < 2; i++ {
|
||||
r := l.next()
|
||||
if !isDigit(r) {
|
||||
return l.errorf("invalid day digit in date: %c", r)
|
||||
}
|
||||
}
|
||||
|
||||
l.emit(tokenLocalDate)
|
||||
|
||||
r = l.peek()
|
||||
|
||||
if r == eof {
|
||||
|
||||
return l.lexRvalue
|
||||
}
|
||||
|
||||
if r != ' ' && r != 'T' {
|
||||
return l.errorf("incorrect date/time separation character: %c", r)
|
||||
}
|
||||
|
||||
if r == ' ' {
|
||||
lookAhead := l.peekString(3)[1:]
|
||||
if len(lookAhead) < 2 {
|
||||
return l.lexRvalue
|
||||
}
|
||||
for _, r := range lookAhead {
|
||||
if !isDigit(r) {
|
||||
return l.lexRvalue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
l.skip() // skip the T or ' '
|
||||
|
||||
// time
|
||||
|
||||
for i := 0; i < 2; i++ {
|
||||
r := l.next()
|
||||
if !isDigit(r) {
|
||||
return l.errorf("invalid hour digit in time: %c", r)
|
||||
}
|
||||
}
|
||||
|
||||
r = l.next()
|
||||
if r != ':' {
|
||||
return l.errorf("time hour/minute separator should be :, not %c", r)
|
||||
}
|
||||
|
||||
for i := 0; i < 2; i++ {
|
||||
r := l.next()
|
||||
if !isDigit(r) {
|
||||
return l.errorf("invalid minute digit in time: %c", r)
|
||||
}
|
||||
}
|
||||
|
||||
r = l.next()
|
||||
if r != ':' {
|
||||
return l.errorf("time minute/second separator should be :, not %c", r)
|
||||
}
|
||||
|
||||
for i := 0; i < 2; i++ {
|
||||
r := l.next()
|
||||
if !isDigit(r) {
|
||||
return l.errorf("invalid second digit in time: %c", r)
|
||||
}
|
||||
}
|
||||
|
||||
r = l.peek()
|
||||
if r == '.' {
|
||||
l.next()
|
||||
r := l.next()
|
||||
if !isDigit(r) {
|
||||
return l.errorf("expected at least one digit in time's fraction, not %c", r)
|
||||
}
|
||||
|
||||
for {
|
||||
r := l.peek()
|
||||
if !isDigit(r) {
|
||||
break
|
||||
}
|
||||
l.next()
|
||||
}
|
||||
}
|
||||
|
||||
l.emit(tokenLocalTime)
|
||||
|
||||
return l.lexTimeOffset
|
||||
|
||||
}
|
||||
|
||||
func (l *tomlLexer) lexTimeOffset() tomlLexStateFn {
|
||||
// potential offset
|
||||
|
||||
// Z
|
||||
// -07:00
|
||||
// +07:00
|
||||
// nothing
|
||||
|
||||
r := l.peek()
|
||||
|
||||
if r == 'Z' {
|
||||
l.next()
|
||||
l.emit(tokenTimeOffset)
|
||||
} else if r == '+' || r == '-' {
|
||||
l.next()
|
||||
|
||||
for i := 0; i < 2; i++ {
|
||||
r := l.next()
|
||||
if !isDigit(r) {
|
||||
return l.errorf("invalid hour digit in time offset: %c", r)
|
||||
}
|
||||
}
|
||||
|
||||
r = l.next()
|
||||
if r != ':' {
|
||||
return l.errorf("time offset hour/minute separator should be :, not %c", r)
|
||||
}
|
||||
|
||||
for i := 0; i < 2; i++ {
|
||||
r := l.next()
|
||||
if !isDigit(r) {
|
||||
return l.errorf("invalid minute digit in time offset: %c", r)
|
||||
}
|
||||
}
|
||||
|
||||
l.emit(tokenTimeOffset)
|
||||
}
|
||||
|
||||
return l.lexRvalue
|
||||
}
|
||||
|
||||
func (l *tomlLexer) lexLocalDate() tomlLexStateFn {
|
||||
l.emit(tokenLocalDate)
|
||||
func (l *tomlLexer) lexTime() tomlLexStateFn {
|
||||
// v--- cursor
|
||||
// 07:32:00
|
||||
// 00:32:00.999999
|
||||
|
||||
for i := 0; i < 2; i++ {
|
||||
r := l.next()
|
||||
if !isDigit(r) {
|
||||
return l.errorf("invalid minute digit in time: %c", r)
|
||||
}
|
||||
}
|
||||
|
||||
r := l.next()
|
||||
if r != ':' {
|
||||
return l.errorf("time minute/second separator should be :, not %c", r)
|
||||
}
|
||||
|
||||
for i := 0; i < 2; i++ {
|
||||
r := l.next()
|
||||
if !isDigit(r) {
|
||||
return l.errorf("invalid second digit in time: %c", r)
|
||||
}
|
||||
}
|
||||
|
||||
r = l.peek()
|
||||
if r == '.' {
|
||||
l.next()
|
||||
r := l.next()
|
||||
if !isDigit(r) {
|
||||
return l.errorf("expected at least one digit in time's fraction, not %c", r)
|
||||
}
|
||||
|
||||
for {
|
||||
r := l.peek()
|
||||
if !isDigit(r) {
|
||||
break
|
||||
}
|
||||
l.next()
|
||||
}
|
||||
}
|
||||
|
||||
l.emit(tokenLocalTime)
|
||||
return l.lexRvalue
|
||||
|
||||
}
|
||||
|
||||
func (l *tomlLexer) lexTrue() tomlLexStateFn {
|
||||
|
@ -767,30 +1015,6 @@ func (l *tomlLexer) run() {
|
|||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
// Regexp for all date/time formats supported by TOML.
|
||||
// Group 1: nano precision
|
||||
// Group 2: timezone
|
||||
//
|
||||
// /!\ also matches the empty string
|
||||
//
|
||||
// Example matches:
|
||||
// 1979-05-27T07:32:00Z
|
||||
// 1979-05-27T00:32:00-07:00
|
||||
// 1979-05-27T00:32:00.999999-07:00
|
||||
// 1979-05-27 07:32:00Z
|
||||
// 1979-05-27 00:32:00-07:00
|
||||
// 1979-05-27 00:32:00.999999-07:00
|
||||
// 1979-05-27T07:32:00
|
||||
// 1979-05-27T00:32:00.999999
|
||||
// 1979-05-27 07:32:00
|
||||
// 1979-05-27 00:32:00.999999
|
||||
// 1979-05-27
|
||||
// 07:32:00
|
||||
// 00:32:00.999999
|
||||
dateRegexp = regexp.MustCompile(`^(?:\d{1,4}-\d{2}-\d{2})?(?:[T ]?\d{2}:\d{2}:\d{2}(\.\d{1,9})?(Z|[+-]\d{2}:\d{2})?)?`)
|
||||
}
|
||||
|
||||
// Entry point
|
||||
func lexToml(inputBytes []byte) []token {
|
||||
runes := bytes.Runes(inputBytes)
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
// Implementation of TOML's local date/time.
|
||||
// Copied over from https://github.com/googleapis/google-cloud-go/blob/master/civil/civil.go
|
||||
// to avoid pulling all the Google dependencies.
|
||||
//
|
||||
// Copied over from Google's civil to avoid pulling all the Google dependencies.
|
||||
// Originals:
|
||||
// https://raw.githubusercontent.com/googleapis/google-cloud-go/ed46f5086358513cf8c25f8e3f022cb838a49d66/civil/civil.go
|
||||
// Changes:
|
||||
// * Renamed files from civil* to localtime*.
|
||||
// * Package changed from civil to toml.
|
||||
// * 'Local' prefix added to all structs.
|
||||
//
|
||||
// Copyright 2016 Google LLC
|
||||
//
|
||||
|
|
|
@ -18,6 +18,7 @@ const (
|
|||
tagFieldComment = "comment"
|
||||
tagCommented = "commented"
|
||||
tagMultiline = "multiline"
|
||||
tagLiteral = "literal"
|
||||
tagDefault = "default"
|
||||
)
|
||||
|
||||
|
@ -27,6 +28,7 @@ type tomlOpts struct {
|
|||
comment string
|
||||
commented bool
|
||||
multiline bool
|
||||
literal bool
|
||||
include bool
|
||||
omitempty bool
|
||||
defaultValue string
|
||||
|
@ -46,6 +48,7 @@ type annotation struct {
|
|||
comment string
|
||||
commented string
|
||||
multiline string
|
||||
literal string
|
||||
defaultValue string
|
||||
}
|
||||
|
||||
|
@ -54,15 +57,16 @@ var annotationDefault = annotation{
|
|||
comment: tagFieldComment,
|
||||
commented: tagCommented,
|
||||
multiline: tagMultiline,
|
||||
literal: tagLiteral,
|
||||
defaultValue: tagDefault,
|
||||
}
|
||||
|
||||
type marshalOrder int
|
||||
type MarshalOrder int
|
||||
|
||||
// Orders the Encoder can write the fields to the output stream.
|
||||
const (
|
||||
// Sort fields alphabetically.
|
||||
OrderAlphabetical marshalOrder = iota + 1
|
||||
OrderAlphabetical MarshalOrder = iota + 1
|
||||
// Preserve the order the fields are encountered. For example, the order of fields in
|
||||
// a struct.
|
||||
OrderPreserve
|
||||
|
@ -254,11 +258,12 @@ type Encoder struct {
|
|||
w io.Writer
|
||||
encOpts
|
||||
annotation
|
||||
line int
|
||||
col int
|
||||
order marshalOrder
|
||||
promoteAnon bool
|
||||
indentation string
|
||||
line int
|
||||
col int
|
||||
order MarshalOrder
|
||||
promoteAnon bool
|
||||
compactComments bool
|
||||
indentation string
|
||||
}
|
||||
|
||||
// NewEncoder returns a new encoder that writes to w.
|
||||
|
@ -317,7 +322,7 @@ func (e *Encoder) ArraysWithOneElementPerLine(v bool) *Encoder {
|
|||
}
|
||||
|
||||
// Order allows to change in which order fields will be written to the output stream.
|
||||
func (e *Encoder) Order(ord marshalOrder) *Encoder {
|
||||
func (e *Encoder) Order(ord MarshalOrder) *Encoder {
|
||||
e.order = ord
|
||||
return e
|
||||
}
|
||||
|
@ -365,6 +370,12 @@ func (e *Encoder) PromoteAnonymous(promote bool) *Encoder {
|
|||
return e
|
||||
}
|
||||
|
||||
// CompactComments removes the new line before each comment in the tree.
|
||||
func (e *Encoder) CompactComments(cc bool) *Encoder {
|
||||
e.compactComments = cc
|
||||
return e
|
||||
}
|
||||
|
||||
func (e *Encoder) marshal(v interface{}) ([]byte, error) {
|
||||
// Check if indentation is valid
|
||||
for _, char := range e.indentation {
|
||||
|
@ -404,7 +415,7 @@ func (e *Encoder) marshal(v interface{}) ([]byte, error) {
|
|||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
_, err = t.writeToOrdered(&buf, "", "", 0, e.arraysOneElementPerLine, e.order, e.indentation, false)
|
||||
_, err = t.writeToOrdered(&buf, "", "", 0, e.arraysOneElementPerLine, e.order, e.indentation, e.compactComments, false)
|
||||
|
||||
return buf.Bytes(), err
|
||||
}
|
||||
|
@ -442,6 +453,7 @@ func (e *Encoder) valueToTree(mtype reflect.Type, mval reflect.Value) (*Tree, er
|
|||
Comment: opts.comment,
|
||||
Commented: opts.commented,
|
||||
Multiline: opts.multiline,
|
||||
Literal: opts.literal,
|
||||
}, val)
|
||||
}
|
||||
}
|
||||
|
@ -586,6 +598,7 @@ func (e *Encoder) wrapTomlValue(val interface{}, parent *Tree) interface{} {
|
|||
_, isTree := val.(*Tree)
|
||||
_, isTreeS := val.([]*Tree)
|
||||
if isTree || isTreeS {
|
||||
e.line++
|
||||
return val
|
||||
}
|
||||
|
||||
|
@ -830,7 +843,21 @@ func (d *Decoder) valueFromTree(mtype reflect.Type, tval *Tree, mval1 *reflect.V
|
|||
case reflect.Int32:
|
||||
val, err = strconv.ParseInt(opts.defaultValue, 10, 32)
|
||||
case reflect.Int64:
|
||||
val, err = strconv.ParseInt(opts.defaultValue, 10, 64)
|
||||
// Check if the provided number has a non-numeric extension.
|
||||
var hasExtension bool
|
||||
if len(opts.defaultValue) > 0 {
|
||||
lastChar := opts.defaultValue[len(opts.defaultValue)-1]
|
||||
if lastChar < '0' || lastChar > '9' {
|
||||
hasExtension = true
|
||||
}
|
||||
}
|
||||
// If the value is a time.Duration with extension, parse as duration.
|
||||
// If the value is an int64 or a time.Duration without extension, parse as number.
|
||||
if hasExtension && mvalf.Type().String() == "time.Duration" {
|
||||
val, err = time.ParseDuration(opts.defaultValue)
|
||||
} else {
|
||||
val, err = strconv.ParseInt(opts.defaultValue, 10, 64)
|
||||
}
|
||||
case reflect.Float32:
|
||||
val, err = strconv.ParseFloat(opts.defaultValue, 32)
|
||||
case reflect.Float64:
|
||||
|
@ -1004,8 +1031,18 @@ func (d *Decoder) valueFromToml(mtype reflect.Type, tval interface{}, mval1 *ref
|
|||
return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to a slice", tval, tval)
|
||||
default:
|
||||
d.visitor.visit()
|
||||
mvalPtr := reflect.New(mtype)
|
||||
|
||||
// Check if pointer to value implements the Unmarshaler interface.
|
||||
if isCustomUnmarshaler(mvalPtr.Type()) {
|
||||
if err := callCustomUnmarshaler(mvalPtr, tval); err != nil {
|
||||
return reflect.ValueOf(nil), fmt.Errorf("unmarshal toml: %v", err)
|
||||
}
|
||||
return mvalPtr.Elem(), nil
|
||||
}
|
||||
|
||||
// Check if pointer to value implements the encoding.TextUnmarshaler.
|
||||
if mvalPtr := reflect.New(mtype); isTextUnmarshaler(mvalPtr.Type()) && !isTimeType(mtype) {
|
||||
if isTextUnmarshaler(mvalPtr.Type()) && !isTimeType(mtype) {
|
||||
if err := d.unmarshalText(tval, mvalPtr); err != nil {
|
||||
return reflect.ValueOf(nil), fmt.Errorf("unmarshal text: %v", err)
|
||||
}
|
||||
|
@ -1144,6 +1181,7 @@ func tomlOptions(vf reflect.StructField, an annotation) tomlOpts {
|
|||
}
|
||||
commented, _ := strconv.ParseBool(vf.Tag.Get(an.commented))
|
||||
multiline, _ := strconv.ParseBool(vf.Tag.Get(an.multiline))
|
||||
literal, _ := strconv.ParseBool(vf.Tag.Get(an.literal))
|
||||
defaultValue := vf.Tag.Get(tagDefault)
|
||||
result := tomlOpts{
|
||||
name: vf.Name,
|
||||
|
@ -1151,6 +1189,7 @@ func tomlOptions(vf reflect.StructField, an annotation) tomlOpts {
|
|||
comment: comment,
|
||||
commented: commented,
|
||||
multiline: multiline,
|
||||
literal: literal,
|
||||
include: true,
|
||||
omitempty: false,
|
||||
defaultValue: defaultValue,
|
||||
|
|
|
@ -7,7 +7,6 @@ import (
|
|||
"fmt"
|
||||
"math"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
@ -231,19 +230,38 @@ func (p *tomlParser) parseAssign() tomlParserStateFn {
|
|||
return p.parseStart
|
||||
}
|
||||
|
||||
var numberUnderscoreInvalidRegexp *regexp.Regexp
|
||||
var hexNumberUnderscoreInvalidRegexp *regexp.Regexp
|
||||
var errInvalidUnderscore = errors.New("invalid use of _ in number")
|
||||
|
||||
func numberContainsInvalidUnderscore(value string) error {
|
||||
if numberUnderscoreInvalidRegexp.MatchString(value) {
|
||||
return errors.New("invalid use of _ in number")
|
||||
// For large numbers, you may use underscores between digits to enhance
|
||||
// readability. Each underscore must be surrounded by at least one digit on
|
||||
// each side.
|
||||
|
||||
hasBefore := false
|
||||
for idx, r := range value {
|
||||
if r == '_' {
|
||||
if !hasBefore || idx+1 >= len(value) {
|
||||
// can't end with an underscore
|
||||
return errInvalidUnderscore
|
||||
}
|
||||
}
|
||||
hasBefore = isDigit(r)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var errInvalidUnderscoreHex = errors.New("invalid use of _ in hex number")
|
||||
|
||||
func hexNumberContainsInvalidUnderscore(value string) error {
|
||||
if hexNumberUnderscoreInvalidRegexp.MatchString(value) {
|
||||
return errors.New("invalid use of _ in hex number")
|
||||
hasBefore := false
|
||||
for idx, r := range value {
|
||||
if r == '_' {
|
||||
if !hasBefore || idx+1 >= len(value) {
|
||||
// can't end with an underscore
|
||||
return errInvalidUnderscoreHex
|
||||
}
|
||||
}
|
||||
hasBefore = isHexDigit(r)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -322,42 +340,44 @@ func (p *tomlParser) parseRvalue() interface{} {
|
|||
p.raiseError(tok, "%s", err)
|
||||
}
|
||||
return val
|
||||
case tokenDate:
|
||||
layout := time.RFC3339Nano
|
||||
if !strings.Contains(tok.val, "T") {
|
||||
layout = strings.Replace(layout, "T", " ", 1)
|
||||
}
|
||||
val, err := time.ParseInLocation(layout, tok.val, time.UTC)
|
||||
case tokenLocalTime:
|
||||
val, err := ParseLocalTime(tok.val)
|
||||
if err != nil {
|
||||
p.raiseError(tok, "%s", err)
|
||||
}
|
||||
return val
|
||||
case tokenLocalDate:
|
||||
v := strings.Replace(tok.val, " ", "T", -1)
|
||||
isDateTime := false
|
||||
isTime := false
|
||||
for _, c := range v {
|
||||
if c == 'T' || c == 't' {
|
||||
isDateTime = true
|
||||
break
|
||||
}
|
||||
if c == ':' {
|
||||
isTime = true
|
||||
break
|
||||
// a local date may be followed by:
|
||||
// * nothing: this is a local date
|
||||
// * a local time: this is a local date-time
|
||||
|
||||
next := p.peek()
|
||||
if next == nil || next.typ != tokenLocalTime {
|
||||
val, err := ParseLocalDate(tok.val)
|
||||
if err != nil {
|
||||
p.raiseError(tok, "%s", err)
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
var val interface{}
|
||||
var err error
|
||||
localDate := tok
|
||||
localTime := p.getToken()
|
||||
|
||||
if isDateTime {
|
||||
val, err = ParseLocalDateTime(v)
|
||||
} else if isTime {
|
||||
val, err = ParseLocalTime(v)
|
||||
} else {
|
||||
val, err = ParseLocalDate(v)
|
||||
next = p.peek()
|
||||
if next == nil || next.typ != tokenTimeOffset {
|
||||
v := localDate.val + "T" + localTime.val
|
||||
val, err := ParseLocalDateTime(v)
|
||||
if err != nil {
|
||||
p.raiseError(tok, "%s", err)
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
offset := p.getToken()
|
||||
|
||||
layout := time.RFC3339Nano
|
||||
v := localDate.val + "T" + localTime.val + offset.val
|
||||
val, err := time.ParseInLocation(layout, v, time.UTC)
|
||||
if err != nil {
|
||||
p.raiseError(tok, "%s", err)
|
||||
}
|
||||
|
@ -370,10 +390,10 @@ func (p *tomlParser) parseRvalue() interface{} {
|
|||
p.raiseError(tok, "cannot have multiple equals for the same key")
|
||||
case tokenError:
|
||||
p.raiseError(tok, "%s", tok)
|
||||
default:
|
||||
panic(fmt.Errorf("unhandled token: %v", tok))
|
||||
}
|
||||
|
||||
p.raiseError(tok, "never reached")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -486,8 +506,3 @@ func parseToml(flow []token) *Tree {
|
|||
parser.run()
|
||||
return result
|
||||
}
|
||||
|
||||
func init() {
|
||||
numberUnderscoreInvalidRegexp = regexp.MustCompile(`([^\d]_|_[^\d])|_$|^_`)
|
||||
hexNumberUnderscoreInvalidRegexp = regexp.MustCompile(`(^0x_)|([^\da-f]_|_[^\da-f])|_$|^_`)
|
||||
}
|
||||
|
|
|
@ -30,8 +30,9 @@ const (
|
|||
tokenRightParen
|
||||
tokenDoubleLeftBracket
|
||||
tokenDoubleRightBracket
|
||||
tokenDate
|
||||
tokenLocalDate
|
||||
tokenLocalTime
|
||||
tokenTimeOffset
|
||||
tokenKeyGroup
|
||||
tokenKeyGroupArray
|
||||
tokenComma
|
||||
|
@ -66,7 +67,8 @@ var tokenTypeNames = []string{
|
|||
"]]",
|
||||
"[[",
|
||||
"LocalDate",
|
||||
"LocalDate",
|
||||
"LocalTime",
|
||||
"TimeOffset",
|
||||
"KeyGroup",
|
||||
"KeyGroupArray",
|
||||
",",
|
||||
|
|
|
@ -15,6 +15,7 @@ type tomlValue struct {
|
|||
comment string
|
||||
commented bool
|
||||
multiline bool
|
||||
literal bool
|
||||
position Position
|
||||
}
|
||||
|
||||
|
@ -314,6 +315,7 @@ type SetOptions struct {
|
|||
Comment string
|
||||
Commented bool
|
||||
Multiline bool
|
||||
Literal bool
|
||||
}
|
||||
|
||||
// SetWithOptions is the same as Set, but allows you to provide formatting
|
||||
|
@ -362,12 +364,14 @@ func (t *Tree) SetPathWithOptions(keys []string, opts SetOptions, value interfac
|
|||
v.comment = opts.Comment
|
||||
v.commented = opts.Commented
|
||||
v.multiline = opts.Multiline
|
||||
v.literal = opts.Literal
|
||||
toInsert = v
|
||||
default:
|
||||
toInsert = &tomlValue{value: value,
|
||||
comment: opts.Comment,
|
||||
commented: opts.Commented,
|
||||
multiline: opts.Multiline,
|
||||
literal: opts.Literal,
|
||||
position: Position{Line: subtree.position.Line + len(subtree.values) + 1, Col: subtree.position.Col}}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
package toml
|
||||
|
||||
// PubTOMLValue wrapping tomlValue in order to access all properties from outside.
|
||||
type PubTOMLValue = tomlValue
|
||||
|
||||
func (ptv *PubTOMLValue) Value() interface{} {
|
||||
return ptv.value
|
||||
}
|
||||
func (ptv *PubTOMLValue) Comment() string {
|
||||
return ptv.comment
|
||||
}
|
||||
func (ptv *PubTOMLValue) Commented() bool {
|
||||
return ptv.commented
|
||||
}
|
||||
func (ptv *PubTOMLValue) Multiline() bool {
|
||||
return ptv.multiline
|
||||
}
|
||||
func (ptv *PubTOMLValue) Position() Position {
|
||||
return ptv.position
|
||||
}
|
||||
|
||||
func (ptv *PubTOMLValue) SetValue(v interface{}) {
|
||||
ptv.value = v
|
||||
}
|
||||
func (ptv *PubTOMLValue) SetComment(s string) {
|
||||
ptv.comment = s
|
||||
}
|
||||
func (ptv *PubTOMLValue) SetCommented(c bool) {
|
||||
ptv.commented = c
|
||||
}
|
||||
func (ptv *PubTOMLValue) SetMultiline(m bool) {
|
||||
ptv.multiline = m
|
||||
}
|
||||
func (ptv *PubTOMLValue) SetPosition(p Position) {
|
||||
ptv.position = p
|
||||
}
|
||||
|
||||
// PubTree wrapping Tree in order to access all properties from outside.
|
||||
type PubTree = Tree
|
||||
|
||||
func (pt *PubTree) Values() map[string]interface{} {
|
||||
return pt.values
|
||||
}
|
||||
|
||||
func (pt *PubTree) Comment() string {
|
||||
return pt.comment
|
||||
}
|
||||
|
||||
func (pt *PubTree) Commented() bool {
|
||||
return pt.commented
|
||||
}
|
||||
|
||||
func (pt *PubTree) Inline() bool {
|
||||
return pt.inline
|
||||
}
|
||||
|
||||
func (pt *PubTree) SetValues(v map[string]interface{}) {
|
||||
pt.values = v
|
||||
}
|
||||
|
||||
func (pt *PubTree) SetComment(c string) {
|
||||
pt.comment = c
|
||||
}
|
||||
|
||||
func (pt *PubTree) SetCommented(c bool) {
|
||||
pt.commented = c
|
||||
}
|
||||
|
||||
func (pt *PubTree) SetInline(i bool) {
|
||||
pt.inline = i
|
||||
}
|
|
@ -103,7 +103,7 @@ func encodeTomlString(value string) string {
|
|||
return b.String()
|
||||
}
|
||||
|
||||
func tomlTreeStringRepresentation(t *Tree, ord marshalOrder) (string, error) {
|
||||
func tomlTreeStringRepresentation(t *Tree, ord MarshalOrder) (string, error) {
|
||||
var orderedVals []sortNode
|
||||
switch ord {
|
||||
case OrderPreserve:
|
||||
|
@ -126,7 +126,7 @@ func tomlTreeStringRepresentation(t *Tree, ord marshalOrder) (string, error) {
|
|||
return "{ " + strings.Join(values, ", ") + " }", nil
|
||||
}
|
||||
|
||||
func tomlValueStringRepresentation(v interface{}, commented string, indent string, ord marshalOrder, arraysOneElementPerLine bool) (string, error) {
|
||||
func tomlValueStringRepresentation(v interface{}, commented string, indent string, ord MarshalOrder, arraysOneElementPerLine bool) (string, error) {
|
||||
// this interface check is added to dereference the change made in the writeTo function.
|
||||
// That change was made to allow this function to see formatting options.
|
||||
tv, ok := v.(*tomlValue)
|
||||
|
@ -158,7 +158,15 @@ func tomlValueStringRepresentation(v interface{}, commented string, indent strin
|
|||
return strings.ToLower(strconv.FormatFloat(value, 'f', -1, bits)), nil
|
||||
case string:
|
||||
if tv.multiline {
|
||||
return "\"\"\"\n" + encodeMultilineTomlString(value, commented) + "\"\"\"", nil
|
||||
if tv.literal {
|
||||
b := strings.Builder{}
|
||||
b.WriteString("'''\n")
|
||||
b.Write([]byte(value))
|
||||
b.WriteString("\n'''")
|
||||
return b.String(), nil
|
||||
} else {
|
||||
return "\"\"\"\n" + encodeMultilineTomlString(value, commented) + "\"\"\"", nil
|
||||
}
|
||||
}
|
||||
return "\"" + encodeTomlString(value) + "\"", nil
|
||||
case []byte:
|
||||
|
@ -218,7 +226,9 @@ func tomlValueStringRepresentation(v interface{}, commented string, indent strin
|
|||
}
|
||||
|
||||
func getTreeArrayLine(trees []*Tree) (line int) {
|
||||
// get lowest line number that is not 0
|
||||
// Prevent returning 0 for empty trees
|
||||
line = int(^uint(0) >> 1)
|
||||
// get lowest line number >= 0
|
||||
for _, tv := range trees {
|
||||
if tv.position.Line < line || line == 0 {
|
||||
line = tv.position.Line
|
||||
|
@ -307,10 +317,10 @@ func sortAlphabetical(t *Tree) (vals []sortNode) {
|
|||
}
|
||||
|
||||
func (t *Tree) writeTo(w io.Writer, indent, keyspace string, bytesCount int64, arraysOneElementPerLine bool) (int64, error) {
|
||||
return t.writeToOrdered(w, indent, keyspace, bytesCount, arraysOneElementPerLine, OrderAlphabetical, " ", false)
|
||||
return t.writeToOrdered(w, indent, keyspace, bytesCount, arraysOneElementPerLine, OrderAlphabetical, " ", false, false)
|
||||
}
|
||||
|
||||
func (t *Tree) writeToOrdered(w io.Writer, indent, keyspace string, bytesCount int64, arraysOneElementPerLine bool, ord marshalOrder, indentString string, parentCommented bool) (int64, error) {
|
||||
func (t *Tree) writeToOrdered(w io.Writer, indent, keyspace string, bytesCount int64, arraysOneElementPerLine bool, ord MarshalOrder, indentString string, compactComments, parentCommented bool) (int64, error) {
|
||||
var orderedVals []sortNode
|
||||
|
||||
switch ord {
|
||||
|
@ -360,7 +370,7 @@ func (t *Tree) writeToOrdered(w io.Writer, indent, keyspace string, bytesCount i
|
|||
if err != nil {
|
||||
return bytesCount, err
|
||||
}
|
||||
bytesCount, err = node.writeToOrdered(w, indent+indentString, combinedKey, bytesCount, arraysOneElementPerLine, ord, indentString, parentCommented || t.commented || tv.commented)
|
||||
bytesCount, err = node.writeToOrdered(w, indent+indentString, combinedKey, bytesCount, arraysOneElementPerLine, ord, indentString, compactComments, parentCommented || t.commented || tv.commented)
|
||||
if err != nil {
|
||||
return bytesCount, err
|
||||
}
|
||||
|
@ -376,7 +386,7 @@ func (t *Tree) writeToOrdered(w io.Writer, indent, keyspace string, bytesCount i
|
|||
return bytesCount, err
|
||||
}
|
||||
|
||||
bytesCount, err = subTree.writeToOrdered(w, indent+indentString, combinedKey, bytesCount, arraysOneElementPerLine, ord, indentString, parentCommented || t.commented || subTree.commented)
|
||||
bytesCount, err = subTree.writeToOrdered(w, indent+indentString, combinedKey, bytesCount, arraysOneElementPerLine, ord, indentString, compactComments, parentCommented || t.commented || subTree.commented)
|
||||
if err != nil {
|
||||
return bytesCount, err
|
||||
}
|
||||
|
@ -404,7 +414,14 @@ func (t *Tree) writeToOrdered(w io.Writer, indent, keyspace string, bytesCount i
|
|||
if strings.HasPrefix(comment, "#") {
|
||||
start = ""
|
||||
}
|
||||
writtenBytesCountComment, errc := writeStrings(w, "\n", indent, start, comment, "\n")
|
||||
if !compactComments {
|
||||
writtenBytesCountComment, errc := writeStrings(w, "\n")
|
||||
bytesCount += int64(writtenBytesCountComment)
|
||||
if errc != nil {
|
||||
return bytesCount, errc
|
||||
}
|
||||
}
|
||||
writtenBytesCountComment, errc := writeStrings(w, indent, start, comment, "\n")
|
||||
bytesCount += int64(writtenBytesCountComment)
|
||||
if errc != nil {
|
||||
return bytesCount, errc
|
||||
|
@ -510,8 +527,26 @@ func (t *Tree) ToMap() map[string]interface{} {
|
|||
case *Tree:
|
||||
result[k] = node.ToMap()
|
||||
case *tomlValue:
|
||||
result[k] = node.value
|
||||
result[k] = tomlValueToGo(node.value)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func tomlValueToGo(v interface{}) interface{} {
|
||||
if tree, ok := v.(*Tree); ok {
|
||||
return tree.ToMap()
|
||||
}
|
||||
|
||||
rv := reflect.ValueOf(v)
|
||||
|
||||
if rv.Kind() != reflect.Slice {
|
||||
return v
|
||||
}
|
||||
values := make([]interface{}, rv.Len())
|
||||
for i := 0; i < rv.Len(); i++ {
|
||||
item := rv.Index(i).Interface()
|
||||
values[i] = tomlValueToGo(item)
|
||||
}
|
||||
return values
|
||||
}
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
package toml
|
||||
|
||||
// ValueStringRepresentation transforms an interface{} value into its toml string representation.
|
||||
func ValueStringRepresentation(v interface{}, commented string, indent string, ord MarshalOrder, arraysOneElementPerLine bool) (string, error) {
|
||||
return tomlValueStringRepresentation(v, commented, indent, ord, arraysOneElementPerLine)
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
run:
|
||||
deadline: 5m
|
||||
|
||||
linters:
|
||||
disable-all: true
|
||||
enable:
|
||||
#- bodyclose
|
||||
- deadcode
|
||||
#- depguard
|
||||
#- dogsled
|
||||
#- dupl
|
||||
- errcheck
|
||||
#- exhaustive
|
||||
#- funlen
|
||||
- gas
|
||||
#- gochecknoinits
|
||||
- goconst
|
||||
#- gocritic
|
||||
#- gocyclo
|
||||
#- gofmt
|
||||
- goimports
|
||||
- golint
|
||||
#- gomnd
|
||||
#- goprintffuncname
|
||||
#- gosec
|
||||
#- gosimple
|
||||
- govet
|
||||
- ineffassign
|
||||
- interfacer
|
||||
#- lll
|
||||
- maligned
|
||||
- megacheck
|
||||
#- misspell
|
||||
#- nakedret
|
||||
#- noctx
|
||||
#- nolintlint
|
||||
#- rowserrcheck
|
||||
#- scopelint
|
||||
#- staticcheck
|
||||
- structcheck
|
||||
#- stylecheck
|
||||
#- typecheck
|
||||
- unconvert
|
||||
#- unparam
|
||||
#- unused
|
||||
- varcheck
|
||||
#- whitespace
|
||||
fast: false
|
|
@ -1,7 +1,6 @@
|
|||
language: go
|
||||
|
||||
stages:
|
||||
- diff
|
||||
- test
|
||||
- build
|
||||
|
||||
|
@ -10,20 +9,20 @@ go:
|
|||
- 1.13.x
|
||||
- tip
|
||||
|
||||
env: GO111MODULE=on
|
||||
|
||||
before_install:
|
||||
- go get -u github.com/kyoh86/richgo
|
||||
- go get -u github.com/mitchellh/gox
|
||||
- curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin latest
|
||||
|
||||
matrix:
|
||||
allow_failures:
|
||||
- go: tip
|
||||
include:
|
||||
- stage: diff
|
||||
go: 1.13.x
|
||||
script: make fmt
|
||||
- stage: build
|
||||
go: 1.13.x
|
||||
script: make cobra_generator
|
||||
|
||||
script:
|
||||
script:
|
||||
- make test
|
||||
|
|
|
@ -1,11 +1,40 @@
|
|||
# Cobra Changelog
|
||||
|
||||
## Pending
|
||||
* Fix man page doc generation - no auto generated tag when `cmd.DisableAutoGenTag = true` @jpmcb
|
||||
## v1.1.3
|
||||
|
||||
* **Fix:** release-branch.cobra1.1 only: Revert "Deprecate Go < 1.14" to maintain backward compatibility
|
||||
|
||||
## v1.1.2
|
||||
|
||||
### Notable Changes
|
||||
|
||||
* Bump license year to 2021 in golden files (#1309) @Bowbaq
|
||||
* Enhance PowerShell completion with custom comp (#1208) @Luap99
|
||||
* Update gopkg.in/yaml.v2 to v2.4.0: The previous breaking change in yaml.v2 v2.3.0 has been reverted, see go-yaml/yaml#670
|
||||
* Documentation readability improvements (#1228 etc.) @zaataylor etc.
|
||||
* Use golangci-lint: Repair warnings and errors resulting from linting (#1044) @umarcor
|
||||
|
||||
## v1.1.1
|
||||
|
||||
* **Fix:** yaml.v2 2.3.0 contained a unintended breaking change. This release reverts to yaml.v2 v2.2.8 which has recent critical CVE fixes, but does not have the breaking changes. See https://github.com/spf13/cobra/pull/1259 for context.
|
||||
* **Fix:** correct internal formatting for go-md2man v2 (which caused man page generation to be broken). See https://github.com/spf13/cobra/issues/1049 for context.
|
||||
|
||||
## v1.1.0
|
||||
|
||||
### Notable Changes
|
||||
|
||||
* Extend Go completions and revamp zsh comp (#1070)
|
||||
* Fix man page doc generation - no auto generated tag when `cmd.DisableAutoGenTag = true` (#1104) @jpmcb
|
||||
* Add completion for help command (#1136)
|
||||
* Complete subcommands when TraverseChildren is set (#1171)
|
||||
* Fix stderr printing functions (#894)
|
||||
* fix: fish output redirection (#1247)
|
||||
|
||||
## v1.0.0
|
||||
|
||||
Announcing v1.0.0 of Cobra. 🎉
|
||||
**Notable Changes**
|
||||
|
||||
### Notable Changes
|
||||
* Fish completion (including support for Go custom completion) @marckhouzam
|
||||
* API (urgent): Rename BashCompDirectives to ShellCompDirectives @marckhouzam
|
||||
* Remove/replace SetOutput on Command - deprecated @jpmcb
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
## Cobra User Contract
|
||||
|
||||
### Versioning
|
||||
Cobra will follow a steady release cadence. Non breaking changes will be released as minor versions quarterly. Patch bug releases are at the discretion of the maintainers. Users can expect security patch fixes to be released within relatively short order of a CVE becoming known. For more information on security patch fixes see the CVE section below. Releases will follow [Semantic Versioning](https://semver.org/). Users tracking the Master branch should expect unpredictable breaking changes as the project continues to move forward. For stability, it is highly recommended to use a release.
|
||||
|
||||
### Backward Compatibility
|
||||
We will maintain two major releases in a moving window. The N-1 release will only receive bug fixes and security updates and will be dropped once N+1 is released.
|
||||
|
||||
### Deprecation
|
||||
Deprecation of Go versions or dependent packages will only occur in major releases. To reduce the change of this taking users by surprise, any large deprecation will be preceded by an announcement in the [#cobra slack channel](https://gophers.slack.com/archives/CD3LP1199) and an Issue on Github.
|
||||
|
||||
### CVE
|
||||
Maintainers will make every effort to release security patches in the case of a medium to high severity CVE directly impacting the library. The speed in which these patches reach a release is up to the discretion of the maintainers. A low severity CVE may be a lower priority than a high severity one.
|
||||
|
||||
### Communication
|
||||
Cobra maintainers will use GitHub issues and the [#cobra slack channel](https://gophers.slack.com/archives/CD3LP1199) as the primary means of communication with the community. This is to foster open communication with all users and contributors.
|
||||
|
||||
### Breaking Changes
|
||||
Breaking changes are generally allowed in the master branch, as this is the branch used to develop the next release of Cobra.
|
||||
|
||||
There may be times, however, when master is closed for breaking changes. This is likely to happen as we near the release of a new version.
|
||||
|
||||
Breaking changes are not allowed in release branches, as these represent minor versions that have already been released. These version have consumers who expect the APIs, behaviors, etc, to remain stable during the lifetime of the patch stream for the minor release.
|
||||
|
||||
Examples of breaking changes include:
|
||||
- Removing or renaming exported constant, variable, type, or function.
|
||||
- Updating the version of critical libraries such as `spf13/pflag`, `spf13/viper` etc...
|
||||
- Some version updates may be acceptable for picking up bug fixes, but maintainers must exercise caution when reviewing.
|
||||
|
||||
There may, at times, need to be exceptions where breaking changes are allowed in release branches. These are at the discretion of the project's maintainers, and must be carefully considered before merging.
|
||||
|
||||
### CI Testing
|
||||
Maintainers will ensure the Cobra test suite utilizes the current supported versions of Golang.
|
||||
|
||||
### Disclaimer
|
||||
Changes to this document and the contents therein are at the discretion of the maintainers.
|
||||
None of the contents of this document are legally binding in any way to the maintainers or the users.
|
|
@ -1,21 +1,29 @@
|
|||
BIN="./bin"
|
||||
SRC=$(shell find . -name "*.go")
|
||||
|
||||
ifeq (, $(shell which golangci-lint))
|
||||
$(warning "could not find golangci-lint in $(PATH), run: curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh")
|
||||
endif
|
||||
|
||||
ifeq (, $(shell which richgo))
|
||||
$(warning "could not find richgo in $(PATH), run: go get github.com/kyoh86/richgo")
|
||||
endif
|
||||
|
||||
.PHONY: fmt vet test cobra_generator install_deps clean
|
||||
.PHONY: fmt lint test cobra_generator install_deps clean
|
||||
|
||||
default: all
|
||||
|
||||
all: fmt vet test cobra_generator
|
||||
all: fmt test cobra_generator
|
||||
|
||||
fmt:
|
||||
$(info ******************** checking formatting ********************)
|
||||
@test -z $(shell gofmt -l $(SRC)) || (gofmt -d $(SRC); exit 1)
|
||||
|
||||
test: install_deps vet
|
||||
lint:
|
||||
$(info ******************** running lint tools ********************)
|
||||
golangci-lint run -v
|
||||
|
||||
test: install_deps lint
|
||||
$(info ******************** running tests ********************)
|
||||
richgo test -v ./...
|
||||
|
||||
|
@ -28,9 +36,5 @@ install_deps:
|
|||
$(info ******************** downloading dependencies ********************)
|
||||
go get -v ./...
|
||||
|
||||
vet:
|
||||
$(info ******************** vetting ********************)
|
||||
go vet ./...
|
||||
|
||||
clean:
|
||||
rm -rf $(BIN)
|
||||
|
|
|
@ -6,6 +6,7 @@ Cobra is used in many Go projects such as [Kubernetes](http://kubernetes.io/),
|
|||
[Hugo](https://gohugo.io), and [Github CLI](https://github.com/cli/cli) to
|
||||
name a few. [This list](./projects_using_cobra.md) contains a more extensive list of projects using Cobra.
|
||||
|
||||
[](https://github.com/spf13/cobra/actions?query=workflow%3ATest)
|
||||
[](https://travis-ci.org/spf13/cobra)
|
||||
[](https://godoc.org/github.com/spf13/cobra)
|
||||
[](https://goreportcard.com/report/github.com/spf13/cobra)
|
||||
|
@ -62,8 +63,8 @@ Cobra is built on a structure of commands, arguments & flags.
|
|||
|
||||
**Commands** represent actions, **Args** are things and **Flags** are modifiers for those actions.
|
||||
|
||||
The best applications will read like sentences when used. Users will know how
|
||||
to use the application because they will natively understand how to use it.
|
||||
The best applications read like sentences when used, and as a result, users
|
||||
intuitively know how to interact with them.
|
||||
|
||||
The pattern to follow is
|
||||
`APPNAME VERB NOUN --ADJECTIVE.`
|
||||
|
@ -234,11 +235,6 @@ func init() {
|
|||
rootCmd.AddCommand(initCmd)
|
||||
}
|
||||
|
||||
func er(msg interface{}) {
|
||||
fmt.Println("Error:", msg)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func initConfig() {
|
||||
if cfgFile != "" {
|
||||
// Use config file from the flag.
|
||||
|
@ -246,9 +242,7 @@ func initConfig() {
|
|||
} else {
|
||||
// Find home directory.
|
||||
home, err := homedir.Dir()
|
||||
if err != nil {
|
||||
er(err)
|
||||
}
|
||||
cobra.CheckErr(err)
|
||||
|
||||
// Search config in home directory with name ".cobra" (without extension).
|
||||
viper.AddConfigPath(home)
|
||||
|
@ -268,7 +262,7 @@ func initConfig() {
|
|||
With the root command you need to have your main function execute it.
|
||||
Execute should be run on the root for clarity, though it can be called on any command.
|
||||
|
||||
In a Cobra app, typically the main.go file is very bare. It serves, one purpose, to initialize Cobra.
|
||||
In a Cobra app, typically the main.go file is very bare. It serves one purpose: to initialize Cobra.
|
||||
|
||||
```go
|
||||
package main
|
||||
|
@ -363,7 +357,7 @@ There are two different approaches to assign a flag.
|
|||
|
||||
### Persistent Flags
|
||||
|
||||
A flag can be 'persistent' meaning that this flag will be available to the
|
||||
A flag can be 'persistent', meaning that this flag will be available to the
|
||||
command it's assigned to as well as every command under that command. For
|
||||
global flags, assign a flag as a persistent flag on the root.
|
||||
|
||||
|
@ -373,7 +367,7 @@ rootCmd.PersistentFlags().BoolVarP(&Verbose, "verbose", "v", false, "verbose out
|
|||
|
||||
### Local Flags
|
||||
|
||||
A flag can also be assigned locally which will only apply to that specific command.
|
||||
A flag can also be assigned locally, which will only apply to that specific command.
|
||||
|
||||
```go
|
||||
localCmd.Flags().StringVarP(&Source, "source", "s", "", "Source directory to read from")
|
||||
|
@ -381,8 +375,8 @@ localCmd.Flags().StringVarP(&Source, "source", "s", "", "Source directory to rea
|
|||
|
||||
### Local Flag on Parent Commands
|
||||
|
||||
By default Cobra only parses local flags on the target command, any local flags on
|
||||
parent commands are ignored. By enabling `Command.TraverseChildren` Cobra will
|
||||
By default, Cobra only parses local flags on the target command, and any local flags on
|
||||
parent commands are ignored. By enabling `Command.TraverseChildren`, Cobra will
|
||||
parse local flags on each command before executing the target command.
|
||||
|
||||
```go
|
||||
|
@ -404,8 +398,8 @@ func init() {
|
|||
}
|
||||
```
|
||||
|
||||
In this example the persistent flag `author` is bound with `viper`.
|
||||
**Note**, that the variable `author` will not be set to the value from config,
|
||||
In this example, the persistent flag `author` is bound with `viper`.
|
||||
**Note**: the variable `author` will not be set to the value from config,
|
||||
when the `--author` flag is not provided by user.
|
||||
|
||||
More in [viper documentation](https://github.com/spf13/viper#working-with-flags).
|
||||
|
@ -465,7 +459,7 @@ var cmd = &cobra.Command{
|
|||
|
||||
In the example below, we have defined three commands. Two are at the top level
|
||||
and one (cmdTimes) is a child of one of the top commands. In this case the root
|
||||
is not executable meaning that a subcommand is required. This is accomplished
|
||||
is not executable, meaning that a subcommand is required. This is accomplished
|
||||
by not providing a 'Run' for the 'rootCmd'.
|
||||
|
||||
We have only defined one flag for a single command.
|
||||
|
@ -759,7 +753,7 @@ Cobra can generate documentation based on subcommands, flags, etc. Read more abo
|
|||
|
||||
## Generating shell completions
|
||||
|
||||
Cobra can generate a shell-completion file for the following shells: Bash, Zsh, Fish, Powershell. If you add more information to your commands, these completions can be amazingly powerful and flexible. Read more about it in [Shell Completions](shell_completions.md).
|
||||
Cobra can generate a shell-completion file for the following shells: bash, zsh, fish, PowerShell. If you add more information to your commands, these completions can be amazingly powerful and flexible. Read more about it in [Shell Completions](shell_completions.md).
|
||||
|
||||
# License
|
||||
|
||||
|
|
|
@ -19,9 +19,9 @@ const (
|
|||
BashCompSubdirsInDir = "cobra_annotation_bash_completion_subdirs_in_dir"
|
||||
)
|
||||
|
||||
func writePreamble(buf *bytes.Buffer, name string) {
|
||||
buf.WriteString(fmt.Sprintf("# bash completion for %-36s -*- shell-script -*-\n", name))
|
||||
buf.WriteString(fmt.Sprintf(`
|
||||
func writePreamble(buf io.StringWriter, name string) {
|
||||
WriteStringAndCheck(buf, fmt.Sprintf("# bash completion for %-36s -*- shell-script -*-\n", name))
|
||||
WriteStringAndCheck(buf, fmt.Sprintf(`
|
||||
__%[1]s_debug()
|
||||
{
|
||||
if [[ -n ${BASH_COMP_DEBUG_FILE} ]]; then
|
||||
|
@ -380,10 +380,10 @@ __%[1]s_handle_word()
|
|||
ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs))
|
||||
}
|
||||
|
||||
func writePostscript(buf *bytes.Buffer, name string) {
|
||||
func writePostscript(buf io.StringWriter, name string) {
|
||||
name = strings.Replace(name, ":", "__", -1)
|
||||
buf.WriteString(fmt.Sprintf("__start_%s()\n", name))
|
||||
buf.WriteString(fmt.Sprintf(`{
|
||||
WriteStringAndCheck(buf, fmt.Sprintf("__start_%s()\n", name))
|
||||
WriteStringAndCheck(buf, fmt.Sprintf(`{
|
||||
local cur prev words cword
|
||||
declare -A flaghash 2>/dev/null || :
|
||||
declare -A aliashash 2>/dev/null || :
|
||||
|
@ -410,33 +410,33 @@ func writePostscript(buf *bytes.Buffer, name string) {
|
|||
}
|
||||
|
||||
`, name))
|
||||
buf.WriteString(fmt.Sprintf(`if [[ $(type -t compopt) = "builtin" ]]; then
|
||||
WriteStringAndCheck(buf, fmt.Sprintf(`if [[ $(type -t compopt) = "builtin" ]]; then
|
||||
complete -o default -F __start_%s %s
|
||||
else
|
||||
complete -o default -o nospace -F __start_%s %s
|
||||
fi
|
||||
|
||||
`, name, name, name, name))
|
||||
buf.WriteString("# ex: ts=4 sw=4 et filetype=sh\n")
|
||||
WriteStringAndCheck(buf, "# ex: ts=4 sw=4 et filetype=sh\n")
|
||||
}
|
||||
|
||||
func writeCommands(buf *bytes.Buffer, cmd *Command) {
|
||||
buf.WriteString(" commands=()\n")
|
||||
func writeCommands(buf io.StringWriter, cmd *Command) {
|
||||
WriteStringAndCheck(buf, " commands=()\n")
|
||||
for _, c := range cmd.Commands() {
|
||||
if !c.IsAvailableCommand() && c != cmd.helpCommand {
|
||||
continue
|
||||
}
|
||||
buf.WriteString(fmt.Sprintf(" commands+=(%q)\n", c.Name()))
|
||||
WriteStringAndCheck(buf, fmt.Sprintf(" commands+=(%q)\n", c.Name()))
|
||||
writeCmdAliases(buf, c)
|
||||
}
|
||||
buf.WriteString("\n")
|
||||
WriteStringAndCheck(buf, "\n")
|
||||
}
|
||||
|
||||
func writeFlagHandler(buf *bytes.Buffer, name string, annotations map[string][]string, cmd *Command) {
|
||||
func writeFlagHandler(buf io.StringWriter, name string, annotations map[string][]string, cmd *Command) {
|
||||
for key, value := range annotations {
|
||||
switch key {
|
||||
case BashCompFilenameExt:
|
||||
buf.WriteString(fmt.Sprintf(" flags_with_completion+=(%q)\n", name))
|
||||
WriteStringAndCheck(buf, fmt.Sprintf(" flags_with_completion+=(%q)\n", name))
|
||||
|
||||
var ext string
|
||||
if len(value) > 0 {
|
||||
|
@ -444,17 +444,18 @@ func writeFlagHandler(buf *bytes.Buffer, name string, annotations map[string][]s
|
|||
} else {
|
||||
ext = "_filedir"
|
||||
}
|
||||
buf.WriteString(fmt.Sprintf(" flags_completion+=(%q)\n", ext))
|
||||
WriteStringAndCheck(buf, fmt.Sprintf(" flags_completion+=(%q)\n", ext))
|
||||
case BashCompCustom:
|
||||
buf.WriteString(fmt.Sprintf(" flags_with_completion+=(%q)\n", name))
|
||||
WriteStringAndCheck(buf, fmt.Sprintf(" flags_with_completion+=(%q)\n", name))
|
||||
|
||||
if len(value) > 0 {
|
||||
handlers := strings.Join(value, "; ")
|
||||
buf.WriteString(fmt.Sprintf(" flags_completion+=(%q)\n", handlers))
|
||||
WriteStringAndCheck(buf, fmt.Sprintf(" flags_completion+=(%q)\n", handlers))
|
||||
} else {
|
||||
buf.WriteString(" flags_completion+=(:)\n")
|
||||
WriteStringAndCheck(buf, " flags_completion+=(:)\n")
|
||||
}
|
||||
case BashCompSubdirsInDir:
|
||||
buf.WriteString(fmt.Sprintf(" flags_with_completion+=(%q)\n", name))
|
||||
WriteStringAndCheck(buf, fmt.Sprintf(" flags_with_completion+=(%q)\n", name))
|
||||
|
||||
var ext string
|
||||
if len(value) == 1 {
|
||||
|
@ -462,46 +463,48 @@ func writeFlagHandler(buf *bytes.Buffer, name string, annotations map[string][]s
|
|||
} else {
|
||||
ext = "_filedir -d"
|
||||
}
|
||||
buf.WriteString(fmt.Sprintf(" flags_completion+=(%q)\n", ext))
|
||||
WriteStringAndCheck(buf, fmt.Sprintf(" flags_completion+=(%q)\n", ext))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func writeShortFlag(buf *bytes.Buffer, flag *pflag.Flag, cmd *Command) {
|
||||
const cbn = "\")\n"
|
||||
|
||||
func writeShortFlag(buf io.StringWriter, flag *pflag.Flag, cmd *Command) {
|
||||
name := flag.Shorthand
|
||||
format := " "
|
||||
if len(flag.NoOptDefVal) == 0 {
|
||||
format += "two_word_"
|
||||
}
|
||||
format += "flags+=(\"-%s\")\n"
|
||||
buf.WriteString(fmt.Sprintf(format, name))
|
||||
format += "flags+=(\"-%s" + cbn
|
||||
WriteStringAndCheck(buf, fmt.Sprintf(format, name))
|
||||
writeFlagHandler(buf, "-"+name, flag.Annotations, cmd)
|
||||
}
|
||||
|
||||
func writeFlag(buf *bytes.Buffer, flag *pflag.Flag, cmd *Command) {
|
||||
func writeFlag(buf io.StringWriter, flag *pflag.Flag, cmd *Command) {
|
||||
name := flag.Name
|
||||
format := " flags+=(\"--%s"
|
||||
if len(flag.NoOptDefVal) == 0 {
|
||||
format += "="
|
||||
}
|
||||
format += "\")\n"
|
||||
buf.WriteString(fmt.Sprintf(format, name))
|
||||
format += cbn
|
||||
WriteStringAndCheck(buf, fmt.Sprintf(format, name))
|
||||
if len(flag.NoOptDefVal) == 0 {
|
||||
format = " two_word_flags+=(\"--%s\")\n"
|
||||
buf.WriteString(fmt.Sprintf(format, name))
|
||||
format = " two_word_flags+=(\"--%s" + cbn
|
||||
WriteStringAndCheck(buf, fmt.Sprintf(format, name))
|
||||
}
|
||||
writeFlagHandler(buf, "--"+name, flag.Annotations, cmd)
|
||||
}
|
||||
|
||||
func writeLocalNonPersistentFlag(buf *bytes.Buffer, flag *pflag.Flag) {
|
||||
func writeLocalNonPersistentFlag(buf io.StringWriter, flag *pflag.Flag) {
|
||||
name := flag.Name
|
||||
format := " local_nonpersistent_flags+=(\"--%[1]s\")\n"
|
||||
format := " local_nonpersistent_flags+=(\"--%[1]s" + cbn
|
||||
if len(flag.NoOptDefVal) == 0 {
|
||||
format += " local_nonpersistent_flags+=(\"--%[1]s=\")\n"
|
||||
format += " local_nonpersistent_flags+=(\"--%[1]s=" + cbn
|
||||
}
|
||||
buf.WriteString(fmt.Sprintf(format, name))
|
||||
WriteStringAndCheck(buf, fmt.Sprintf(format, name))
|
||||
if len(flag.Shorthand) > 0 {
|
||||
buf.WriteString(fmt.Sprintf(" local_nonpersistent_flags+=(\"-%s\")\n", flag.Shorthand))
|
||||
WriteStringAndCheck(buf, fmt.Sprintf(" local_nonpersistent_flags+=(\"-%s\")\n", flag.Shorthand))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -519,9 +522,9 @@ func prepareCustomAnnotationsForFlags(cmd *Command) {
|
|||
}
|
||||
}
|
||||
|
||||
func writeFlags(buf *bytes.Buffer, cmd *Command) {
|
||||
func writeFlags(buf io.StringWriter, cmd *Command) {
|
||||
prepareCustomAnnotationsForFlags(cmd)
|
||||
buf.WriteString(` flags=()
|
||||
WriteStringAndCheck(buf, ` flags=()
|
||||
two_word_flags=()
|
||||
local_nonpersistent_flags=()
|
||||
flags_with_completion=()
|
||||
|
@ -553,11 +556,11 @@ func writeFlags(buf *bytes.Buffer, cmd *Command) {
|
|||
}
|
||||
})
|
||||
|
||||
buf.WriteString("\n")
|
||||
WriteStringAndCheck(buf, "\n")
|
||||
}
|
||||
|
||||
func writeRequiredFlag(buf *bytes.Buffer, cmd *Command) {
|
||||
buf.WriteString(" must_have_one_flag=()\n")
|
||||
func writeRequiredFlag(buf io.StringWriter, cmd *Command) {
|
||||
WriteStringAndCheck(buf, " must_have_one_flag=()\n")
|
||||
flags := cmd.NonInheritedFlags()
|
||||
flags.VisitAll(func(flag *pflag.Flag) {
|
||||
if nonCompletableFlag(flag) {
|
||||
|
@ -570,55 +573,55 @@ func writeRequiredFlag(buf *bytes.Buffer, cmd *Command) {
|
|||
if flag.Value.Type() != "bool" {
|
||||
format += "="
|
||||
}
|
||||
format += "\")\n"
|
||||
buf.WriteString(fmt.Sprintf(format, flag.Name))
|
||||
format += cbn
|
||||
WriteStringAndCheck(buf, fmt.Sprintf(format, flag.Name))
|
||||
|
||||
if len(flag.Shorthand) > 0 {
|
||||
buf.WriteString(fmt.Sprintf(" must_have_one_flag+=(\"-%s\")\n", flag.Shorthand))
|
||||
WriteStringAndCheck(buf, fmt.Sprintf(" must_have_one_flag+=(\"-%s"+cbn, flag.Shorthand))
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func writeRequiredNouns(buf *bytes.Buffer, cmd *Command) {
|
||||
buf.WriteString(" must_have_one_noun=()\n")
|
||||
sort.Sort(sort.StringSlice(cmd.ValidArgs))
|
||||
func writeRequiredNouns(buf io.StringWriter, cmd *Command) {
|
||||
WriteStringAndCheck(buf, " must_have_one_noun=()\n")
|
||||
sort.Strings(cmd.ValidArgs)
|
||||
for _, value := range cmd.ValidArgs {
|
||||
// Remove any description that may be included following a tab character.
|
||||
// Descriptions are not supported by bash completion.
|
||||
value = strings.Split(value, "\t")[0]
|
||||
buf.WriteString(fmt.Sprintf(" must_have_one_noun+=(%q)\n", value))
|
||||
WriteStringAndCheck(buf, fmt.Sprintf(" must_have_one_noun+=(%q)\n", value))
|
||||
}
|
||||
if cmd.ValidArgsFunction != nil {
|
||||
buf.WriteString(" has_completion_function=1\n")
|
||||
WriteStringAndCheck(buf, " has_completion_function=1\n")
|
||||
}
|
||||
}
|
||||
|
||||
func writeCmdAliases(buf *bytes.Buffer, cmd *Command) {
|
||||
func writeCmdAliases(buf io.StringWriter, cmd *Command) {
|
||||
if len(cmd.Aliases) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
sort.Sort(sort.StringSlice(cmd.Aliases))
|
||||
sort.Strings(cmd.Aliases)
|
||||
|
||||
buf.WriteString(fmt.Sprint(` if [[ -z "${BASH_VERSION}" || "${BASH_VERSINFO[0]}" -gt 3 ]]; then`, "\n"))
|
||||
WriteStringAndCheck(buf, fmt.Sprint(` if [[ -z "${BASH_VERSION}" || "${BASH_VERSINFO[0]}" -gt 3 ]]; then`, "\n"))
|
||||
for _, value := range cmd.Aliases {
|
||||
buf.WriteString(fmt.Sprintf(" command_aliases+=(%q)\n", value))
|
||||
buf.WriteString(fmt.Sprintf(" aliashash[%q]=%q\n", value, cmd.Name()))
|
||||
WriteStringAndCheck(buf, fmt.Sprintf(" command_aliases+=(%q)\n", value))
|
||||
WriteStringAndCheck(buf, fmt.Sprintf(" aliashash[%q]=%q\n", value, cmd.Name()))
|
||||
}
|
||||
buf.WriteString(` fi`)
|
||||
buf.WriteString("\n")
|
||||
WriteStringAndCheck(buf, ` fi`)
|
||||
WriteStringAndCheck(buf, "\n")
|
||||
}
|
||||
func writeArgAliases(buf *bytes.Buffer, cmd *Command) {
|
||||
buf.WriteString(" noun_aliases=()\n")
|
||||
sort.Sort(sort.StringSlice(cmd.ArgAliases))
|
||||
func writeArgAliases(buf io.StringWriter, cmd *Command) {
|
||||
WriteStringAndCheck(buf, " noun_aliases=()\n")
|
||||
sort.Strings(cmd.ArgAliases)
|
||||
for _, value := range cmd.ArgAliases {
|
||||
buf.WriteString(fmt.Sprintf(" noun_aliases+=(%q)\n", value))
|
||||
WriteStringAndCheck(buf, fmt.Sprintf(" noun_aliases+=(%q)\n", value))
|
||||
}
|
||||
}
|
||||
|
||||
func gen(buf *bytes.Buffer, cmd *Command) {
|
||||
func gen(buf io.StringWriter, cmd *Command) {
|
||||
for _, c := range cmd.Commands() {
|
||||
if !c.IsAvailableCommand() && c != cmd.helpCommand {
|
||||
continue
|
||||
|
@ -630,22 +633,22 @@ func gen(buf *bytes.Buffer, cmd *Command) {
|
|||
commandName = strings.Replace(commandName, ":", "__", -1)
|
||||
|
||||
if cmd.Root() == cmd {
|
||||
buf.WriteString(fmt.Sprintf("_%s_root_command()\n{\n", commandName))
|
||||
WriteStringAndCheck(buf, fmt.Sprintf("_%s_root_command()\n{\n", commandName))
|
||||
} else {
|
||||
buf.WriteString(fmt.Sprintf("_%s()\n{\n", commandName))
|
||||
WriteStringAndCheck(buf, fmt.Sprintf("_%s()\n{\n", commandName))
|
||||
}
|
||||
|
||||
buf.WriteString(fmt.Sprintf(" last_command=%q\n", commandName))
|
||||
buf.WriteString("\n")
|
||||
buf.WriteString(" command_aliases=()\n")
|
||||
buf.WriteString("\n")
|
||||
WriteStringAndCheck(buf, fmt.Sprintf(" last_command=%q\n", commandName))
|
||||
WriteStringAndCheck(buf, "\n")
|
||||
WriteStringAndCheck(buf, " command_aliases=()\n")
|
||||
WriteStringAndCheck(buf, "\n")
|
||||
|
||||
writeCommands(buf, cmd)
|
||||
writeFlags(buf, cmd)
|
||||
writeRequiredFlag(buf, cmd)
|
||||
writeRequiredNouns(buf, cmd)
|
||||
writeArgAliases(buf, cmd)
|
||||
buf.WriteString("}\n\n")
|
||||
WriteStringAndCheck(buf, "}\n\n")
|
||||
}
|
||||
|
||||
// GenBashCompletion generates bash completion file and writes to the passed writer.
|
||||
|
|
|
@ -4,7 +4,7 @@ Please refer to [Shell Completions](shell_completions.md) for details.
|
|||
|
||||
## Bash legacy dynamic completions
|
||||
|
||||
For backwards-compatibility, Cobra still supports its legacy dynamic completion solution (described below). Unlike the `ValidArgsFunction` solution, the legacy solution will only work for Bash shell-completion and not for other shells. This legacy solution can be used along-side `ValidArgsFunction` and `RegisterFlagCompletionFunc()`, as long as both solutions are not used for the same command. This provides a path to gradually migrate from the legacy solution to the new solution.
|
||||
For backward compatibility, Cobra still supports its legacy dynamic completion solution (described below). Unlike the `ValidArgsFunction` solution, the legacy solution will only work for Bash shell-completion and not for other shells. This legacy solution can be used along-side `ValidArgsFunction` and `RegisterFlagCompletionFunc()`, as long as both solutions are not used for the same command. This provides a path to gradually migrate from the legacy solution to the new solution.
|
||||
|
||||
The legacy solution allows you to inject bash functions into the bash completion script. Those bash functions are responsible for providing the completion choices for your own completions.
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ package cobra
|
|||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
@ -205,3 +206,17 @@ func stringInSlice(a string, list []string) bool {
|
|||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// CheckErr prints the msg with the prefix 'Error:' and exits with error code 1. If the msg is nil, it does nothing.
|
||||
func CheckErr(msg interface{}) {
|
||||
if msg != nil {
|
||||
fmt.Fprintln(os.Stderr, "Error:", msg)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
// WriteStringAndCheck writes a string into a buffer, and checks if the error is not nil.
|
||||
func WriteStringAndCheck(b io.StringWriter, s string) {
|
||||
_, err := b.WriteString(s)
|
||||
CheckErr(err)
|
||||
}
|
||||
|
|
|
@ -84,9 +84,6 @@ type Command struct {
|
|||
// Deprecated defines, if this command is deprecated and should print this string when used.
|
||||
Deprecated string
|
||||
|
||||
// Hidden defines, if this command is hidden and should NOT show up in the list of available commands.
|
||||
Hidden bool
|
||||
|
||||
// Annotations are key/value pairs that can be used by applications to identify or
|
||||
// group commands.
|
||||
Annotations map[string]string
|
||||
|
@ -126,55 +123,6 @@ type Command struct {
|
|||
// PersistentPostRunE: PersistentPostRun but returns an error.
|
||||
PersistentPostRunE func(cmd *Command, args []string) error
|
||||
|
||||
// SilenceErrors is an option to quiet errors down stream.
|
||||
SilenceErrors bool
|
||||
|
||||
// SilenceUsage is an option to silence usage when an error occurs.
|
||||
SilenceUsage bool
|
||||
|
||||
// DisableFlagParsing disables the flag parsing.
|
||||
// If this is true all flags will be passed to the command as arguments.
|
||||
DisableFlagParsing bool
|
||||
|
||||
// DisableAutoGenTag defines, if gen tag ("Auto generated by spf13/cobra...")
|
||||
// will be printed by generating docs for this command.
|
||||
DisableAutoGenTag bool
|
||||
|
||||
// DisableFlagsInUseLine will disable the addition of [flags] to the usage
|
||||
// line of a command when printing help or generating docs
|
||||
DisableFlagsInUseLine bool
|
||||
|
||||
// DisableSuggestions disables the suggestions based on Levenshtein distance
|
||||
// that go along with 'unknown command' messages.
|
||||
DisableSuggestions bool
|
||||
// SuggestionsMinimumDistance defines minimum levenshtein distance to display suggestions.
|
||||
// Must be > 0.
|
||||
SuggestionsMinimumDistance int
|
||||
|
||||
// TraverseChildren parses flags on all parents before executing child command.
|
||||
TraverseChildren bool
|
||||
|
||||
// FParseErrWhitelist flag parse errors to be ignored
|
||||
FParseErrWhitelist FParseErrWhitelist
|
||||
|
||||
ctx context.Context
|
||||
|
||||
// commands is the list of commands supported by this program.
|
||||
commands []*Command
|
||||
// parent is a parent command for this command.
|
||||
parent *Command
|
||||
// Max lengths of commands' string lengths for use in padding.
|
||||
commandsMaxUseLen int
|
||||
commandsMaxCommandPathLen int
|
||||
commandsMaxNameLen int
|
||||
// commandsAreSorted defines, if command slice are sorted or not.
|
||||
commandsAreSorted bool
|
||||
// commandCalledAs is the name or alias value used to call this command.
|
||||
commandCalledAs struct {
|
||||
name string
|
||||
called bool
|
||||
}
|
||||
|
||||
// args is actual args parsed from flags.
|
||||
args []string
|
||||
// flagErrorBuf contains all error messages from pflag.
|
||||
|
@ -216,6 +164,60 @@ type Command struct {
|
|||
outWriter io.Writer
|
||||
// errWriter is a writer defined by the user that replaces stderr
|
||||
errWriter io.Writer
|
||||
|
||||
//FParseErrWhitelist flag parse errors to be ignored
|
||||
FParseErrWhitelist FParseErrWhitelist
|
||||
|
||||
// commandsAreSorted defines, if command slice are sorted or not.
|
||||
commandsAreSorted bool
|
||||
// commandCalledAs is the name or alias value used to call this command.
|
||||
commandCalledAs struct {
|
||||
name string
|
||||
called bool
|
||||
}
|
||||
|
||||
ctx context.Context
|
||||
|
||||
// commands is the list of commands supported by this program.
|
||||
commands []*Command
|
||||
// parent is a parent command for this command.
|
||||
parent *Command
|
||||
// Max lengths of commands' string lengths for use in padding.
|
||||
commandsMaxUseLen int
|
||||
commandsMaxCommandPathLen int
|
||||
commandsMaxNameLen int
|
||||
|
||||
// TraverseChildren parses flags on all parents before executing child command.
|
||||
TraverseChildren bool
|
||||
|
||||
// Hidden defines, if this command is hidden and should NOT show up in the list of available commands.
|
||||
Hidden bool
|
||||
|
||||
// SilenceErrors is an option to quiet errors down stream.
|
||||
SilenceErrors bool
|
||||
|
||||
// SilenceUsage is an option to silence usage when an error occurs.
|
||||
SilenceUsage bool
|
||||
|
||||
// DisableFlagParsing disables the flag parsing.
|
||||
// If this is true all flags will be passed to the command as arguments.
|
||||
DisableFlagParsing bool
|
||||
|
||||
// DisableAutoGenTag defines, if gen tag ("Auto generated by spf13/cobra...")
|
||||
// will be printed by generating docs for this command.
|
||||
DisableAutoGenTag bool
|
||||
|
||||
// DisableFlagsInUseLine will disable the addition of [flags] to the usage
|
||||
// line of a command when printing help or generating docs
|
||||
DisableFlagsInUseLine bool
|
||||
|
||||
// DisableSuggestions disables the suggestions based on Levenshtein distance
|
||||
// that go along with 'unknown command' messages.
|
||||
DisableSuggestions bool
|
||||
|
||||
// SuggestionsMinimumDistance defines minimum levenshtein distance to display suggestions.
|
||||
// Must be > 0.
|
||||
SuggestionsMinimumDistance int
|
||||
}
|
||||
|
||||
// Context returns underlying command context. If command wasn't
|
||||
|
@ -418,7 +420,7 @@ func (c *Command) UsageString() string {
|
|||
c.outWriter = bb
|
||||
c.errWriter = bb
|
||||
|
||||
c.Usage()
|
||||
CheckErr(c.Usage())
|
||||
|
||||
// Setting things back to normal
|
||||
c.outWriter = tmpOutput
|
||||
|
@ -964,13 +966,13 @@ func (c *Command) ExecuteC() (cmd *Command, err error) {
|
|||
return cmd, nil
|
||||
}
|
||||
|
||||
// If root command has SilentErrors flagged,
|
||||
// If root command has SilenceErrors flagged,
|
||||
// all subcommands should respect it
|
||||
if !cmd.SilenceErrors && !c.SilenceErrors {
|
||||
c.PrintErrln("Error:", err.Error())
|
||||
}
|
||||
|
||||
// If root command has SilentUsage flagged,
|
||||
// If root command has SilenceUsage flagged,
|
||||
// all subcommands should respect it
|
||||
if !cmd.SilenceUsage && !c.SilenceUsage {
|
||||
c.Println(cmd.UsageString())
|
||||
|
@ -1087,10 +1089,10 @@ Simply type ` + c.Name() + ` help [path to command] for full details.`,
|
|||
cmd, _, e := c.Root().Find(args)
|
||||
if cmd == nil || e != nil {
|
||||
c.Printf("Unknown help topic %#q\n", args)
|
||||
c.Root().Usage()
|
||||
CheckErr(c.Root().Usage())
|
||||
} else {
|
||||
cmd.InitDefaultHelpFlag() // make possible 'help' flag to be shown
|
||||
cmd.Help()
|
||||
CheckErr(cmd.Help())
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -527,13 +527,13 @@ func CompDebug(msg string, printToStdErr bool) {
|
|||
os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||
if err == nil {
|
||||
defer f.Close()
|
||||
f.WriteString(msg)
|
||||
WriteStringAndCheck(f, msg)
|
||||
}
|
||||
}
|
||||
|
||||
if printToStdErr {
|
||||
// Must print to stderr for this not to be read by the completion script.
|
||||
fmt.Fprintf(os.Stderr, msg)
|
||||
fmt.Fprint(os.Stderr, msg)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
func genFishComp(buf *bytes.Buffer, name string, includeDesc bool) {
|
||||
func genFishComp(buf io.StringWriter, name string, includeDesc bool) {
|
||||
// Variables should not contain a '-' or ':' character
|
||||
nameForVar := name
|
||||
nameForVar = strings.Replace(nameForVar, "-", "_", -1)
|
||||
|
@ -18,8 +18,8 @@ func genFishComp(buf *bytes.Buffer, name string, includeDesc bool) {
|
|||
if !includeDesc {
|
||||
compCmd = ShellCompNoDescRequestCmd
|
||||
}
|
||||
buf.WriteString(fmt.Sprintf("# fish completion for %-36s -*- shell-script -*-\n", name))
|
||||
buf.WriteString(fmt.Sprintf(`
|
||||
WriteStringAndCheck(buf, fmt.Sprintf("# fish completion for %-36s -*- shell-script -*-\n", name))
|
||||
WriteStringAndCheck(buf, fmt.Sprintf(`
|
||||
function __%[1]s_debug
|
||||
set file "$BASH_COMP_DEBUG_FILE"
|
||||
if test -n "$file"
|
||||
|
|
|
@ -8,5 +8,5 @@ require (
|
|||
github.com/mitchellh/go-homedir v1.1.0
|
||||
github.com/spf13/pflag v1.0.5
|
||||
github.com/spf13/viper v1.7.0
|
||||
gopkg.in/yaml.v2 v2.2.8
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
)
|
||||
|
|
|
@ -304,8 +304,8 @@ gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
|||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
// PowerShell completions are based on the amazing work from clap:
|
||||
// https://github.com/clap-rs/clap/blob/3294d18efe5f264d12c9035f404c7d189d4824e1/src/completions/powershell.rs
|
||||
//
|
||||
// The generated scripts require PowerShell v5.0+ (which comes Windows 10, but
|
||||
// can be downloaded separately for windows 7 or 8.1).
|
||||
|
||||
|
@ -11,90 +8,278 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
var powerShellCompletionTemplate = `using namespace System.Management.Automation
|
||||
using namespace System.Management.Automation.Language
|
||||
Register-ArgumentCompleter -Native -CommandName '%s' -ScriptBlock {
|
||||
param($wordToComplete, $commandAst, $cursorPosition)
|
||||
$commandElements = $commandAst.CommandElements
|
||||
$command = @(
|
||||
'%s'
|
||||
for ($i = 1; $i -lt $commandElements.Count; $i++) {
|
||||
$element = $commandElements[$i]
|
||||
if ($element -isnot [StringConstantExpressionAst] -or
|
||||
$element.StringConstantType -ne [StringConstantType]::BareWord -or
|
||||
$element.Value.StartsWith('-')) {
|
||||
break
|
||||
}
|
||||
$element.Value
|
||||
func genPowerShellComp(buf io.StringWriter, name string, includeDesc bool) {
|
||||
compCmd := ShellCompRequestCmd
|
||||
if !includeDesc {
|
||||
compCmd = ShellCompNoDescRequestCmd
|
||||
}
|
||||
WriteStringAndCheck(buf, fmt.Sprintf(`# powershell completion for %-36[1]s -*- shell-script -*-
|
||||
|
||||
function __%[1]s_debug {
|
||||
if ($env:BASH_COMP_DEBUG_FILE) {
|
||||
"$args" | Out-File -Append -FilePath "$env:BASH_COMP_DEBUG_FILE"
|
||||
}
|
||||
}
|
||||
|
||||
filter __%[1]s_escapeStringWithSpecialChars {
|
||||
`+" $_ -replace '\\s|#|@|\\$|;|,|''|\\{|\\}|\\(|\\)|\"|`|\\||<|>|&','`$&'"+`
|
||||
}
|
||||
|
||||
Register-ArgumentCompleter -CommandName '%[1]s' -ScriptBlock {
|
||||
param(
|
||||
$WordToComplete,
|
||||
$CommandAst,
|
||||
$CursorPosition
|
||||
)
|
||||
|
||||
# Get the current command line and convert into a string
|
||||
$Command = $CommandAst.CommandElements
|
||||
$Command = "$Command"
|
||||
|
||||
__%[1]s_debug ""
|
||||
__%[1]s_debug "========= starting completion logic =========="
|
||||
__%[1]s_debug "WordToComplete: $WordToComplete Command: $Command CursorPosition: $CursorPosition"
|
||||
|
||||
# The user could have moved the cursor backwards on the command-line.
|
||||
# We need to trigger completion from the $CursorPosition location, so we need
|
||||
# to truncate the command-line ($Command) up to the $CursorPosition location.
|
||||
# Make sure the $Command is longer then the $CursorPosition before we truncate.
|
||||
# This happens because the $Command does not include the last space.
|
||||
if ($Command.Length -gt $CursorPosition) {
|
||||
$Command=$Command.Substring(0,$CursorPosition)
|
||||
}
|
||||
__%[1]s_debug "Truncated command: $Command"
|
||||
|
||||
$ShellCompDirectiveError=%[3]d
|
||||
$ShellCompDirectiveNoSpace=%[4]d
|
||||
$ShellCompDirectiveNoFileComp=%[5]d
|
||||
$ShellCompDirectiveFilterFileExt=%[6]d
|
||||
$ShellCompDirectiveFilterDirs=%[7]d
|
||||
|
||||
# Prepare the command to request completions for the program.
|
||||
# Split the command at the first space to separate the program and arguments.
|
||||
$Program,$Arguments = $Command.Split(" ",2)
|
||||
$RequestComp="$Program %[2]s $Arguments"
|
||||
__%[1]s_debug "RequestComp: $RequestComp"
|
||||
|
||||
# we cannot use $WordToComplete because it
|
||||
# has the wrong values if the cursor was moved
|
||||
# so use the last argument
|
||||
if ($WordToComplete -ne "" ) {
|
||||
$WordToComplete = $Arguments.Split(" ")[-1]
|
||||
}
|
||||
__%[1]s_debug "New WordToComplete: $WordToComplete"
|
||||
|
||||
|
||||
# Check for flag with equal sign
|
||||
$IsEqualFlag = ($WordToComplete -Like "--*=*" )
|
||||
if ( $IsEqualFlag ) {
|
||||
__%[1]s_debug "Completing equal sign flag"
|
||||
# Remove the flag part
|
||||
$Flag,$WordToComplete = $WordToComplete.Split("=",2)
|
||||
}
|
||||
|
||||
if ( $WordToComplete -eq "" -And ( -Not $IsEqualFlag )) {
|
||||
# If the last parameter is complete (there is a space following it)
|
||||
# We add an extra empty parameter so we can indicate this to the go method.
|
||||
__%[1]s_debug "Adding extra empty parameter"
|
||||
`+" # We need to use `\"`\" to pass an empty argument a \"\" or '' does not work!!!"+`
|
||||
`+" $RequestComp=\"$RequestComp\" + ' `\"`\"' "+`
|
||||
}
|
||||
|
||||
__%[1]s_debug "Calling $RequestComp"
|
||||
#call the command store the output in $out and redirect stderr and stdout to null
|
||||
# $Out is an array contains each line per element
|
||||
Invoke-Expression -OutVariable out "$RequestComp" 2>&1 | Out-Null
|
||||
|
||||
|
||||
# get directive from last line
|
||||
[int]$Directive = $Out[-1].TrimStart(':')
|
||||
if ($Directive -eq "") {
|
||||
# There is no directive specified
|
||||
$Directive = 0
|
||||
}
|
||||
__%[1]s_debug "The completion directive is: $Directive"
|
||||
|
||||
# remove directive (last element) from out
|
||||
$Out = $Out | Where-Object { $_ -ne $Out[-1] }
|
||||
__%[1]s_debug "The completions are: $Out"
|
||||
|
||||
if (($Directive -band $ShellCompDirectiveError) -ne 0 ) {
|
||||
# Error code. No completion.
|
||||
__%[1]s_debug "Received error from custom completion go code"
|
||||
return
|
||||
}
|
||||
|
||||
$Longest = 0
|
||||
$Values = $Out | ForEach-Object {
|
||||
#Split the output in name and description
|
||||
`+" $Name, $Description = $_.Split(\"`t\",2)"+`
|
||||
__%[1]s_debug "Name: $Name Description: $Description"
|
||||
|
||||
# Look for the longest completion so that we can format things nicely
|
||||
if ($Longest -lt $Name.Length) {
|
||||
$Longest = $Name.Length
|
||||
}
|
||||
) -join ';'
|
||||
$completions = @(switch ($command) {%s
|
||||
})
|
||||
$completions.Where{ $_.CompletionText -like "$wordToComplete*" } |
|
||||
Sort-Object -Property ListItemText
|
||||
}`
|
||||
|
||||
func generatePowerShellSubcommandCases(out io.Writer, cmd *Command, previousCommandName string) {
|
||||
var cmdName string
|
||||
if previousCommandName == "" {
|
||||
cmdName = cmd.Name()
|
||||
} else {
|
||||
cmdName = fmt.Sprintf("%s;%s", previousCommandName, cmd.Name())
|
||||
}
|
||||
# Set the description to a one space string if there is none set.
|
||||
# This is needed because the CompletionResult does not accept an empty string as argument
|
||||
if (-Not $Description) {
|
||||
$Description = " "
|
||||
}
|
||||
@{Name="$Name";Description="$Description"}
|
||||
}
|
||||
|
||||
fmt.Fprintf(out, "\n '%s' {", cmdName)
|
||||
|
||||
cmd.Flags().VisitAll(func(flag *pflag.Flag) {
|
||||
if nonCompletableFlag(flag) {
|
||||
return
|
||||
}
|
||||
usage := escapeStringForPowerShell(flag.Usage)
|
||||
if len(flag.Shorthand) > 0 {
|
||||
fmt.Fprintf(out, "\n [CompletionResult]::new('-%s', '%s', [CompletionResultType]::ParameterName, '%s')", flag.Shorthand, flag.Shorthand, usage)
|
||||
}
|
||||
fmt.Fprintf(out, "\n [CompletionResult]::new('--%s', '%s', [CompletionResultType]::ParameterName, '%s')", flag.Name, flag.Name, usage)
|
||||
})
|
||||
$Space = " "
|
||||
if (($Directive -band $ShellCompDirectiveNoSpace) -ne 0 ) {
|
||||
# remove the space here
|
||||
__%[1]s_debug "ShellCompDirectiveNoSpace is called"
|
||||
$Space = ""
|
||||
}
|
||||
|
||||
for _, subCmd := range cmd.Commands() {
|
||||
usage := escapeStringForPowerShell(subCmd.Short)
|
||||
fmt.Fprintf(out, "\n [CompletionResult]::new('%s', '%s', [CompletionResultType]::ParameterValue, '%s')", subCmd.Name(), subCmd.Name(), usage)
|
||||
}
|
||||
if (($Directive -band $ShellCompDirectiveNoFileComp) -ne 0 ) {
|
||||
__%[1]s_debug "ShellCompDirectiveNoFileComp is called"
|
||||
|
||||
fmt.Fprint(out, "\n break\n }")
|
||||
if ($Values.Length -eq 0) {
|
||||
# Just print an empty string here so the
|
||||
# shell does not start to complete paths.
|
||||
# We cannot use CompletionResult here because
|
||||
# it does not accept an empty string as argument.
|
||||
""
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
for _, subCmd := range cmd.Commands() {
|
||||
generatePowerShellSubcommandCases(out, subCmd, cmdName)
|
||||
}
|
||||
if ((($Directive -band $ShellCompDirectiveFilterFileExt) -ne 0 ) -or
|
||||
(($Directive -band $ShellCompDirectiveFilterDirs) -ne 0 )) {
|
||||
__%[1]s_debug "ShellCompDirectiveFilterFileExt ShellCompDirectiveFilterDirs are not supported"
|
||||
|
||||
# return here to prevent the completion of the extensions
|
||||
return
|
||||
}
|
||||
|
||||
$Values = $Values | Where-Object {
|
||||
# filter the result
|
||||
$_.Name -like "$WordToComplete*"
|
||||
|
||||
# Join the flag back if we have a equal sign flag
|
||||
if ( $IsEqualFlag ) {
|
||||
__%[1]s_debug "Join the equal sign flag back to the completion value"
|
||||
$_.Name = $Flag + "=" + $_.Name
|
||||
}
|
||||
}
|
||||
|
||||
# Get the current mode
|
||||
$Mode = (Get-PSReadLineKeyHandler | Where-Object {$_.Key -eq "Tab" }).Function
|
||||
__%[1]s_debug "Mode: $Mode"
|
||||
|
||||
$Values | ForEach-Object {
|
||||
|
||||
# store temporay because switch will overwrite $_
|
||||
$comp = $_
|
||||
|
||||
# PowerShell supports three different completion modes
|
||||
# - TabCompleteNext (default windows style - on each key press the next option is displayed)
|
||||
# - Complete (works like bash)
|
||||
# - MenuComplete (works like zsh)
|
||||
# You set the mode with Set-PSReadLineKeyHandler -Key Tab -Function <mode>
|
||||
|
||||
# CompletionResult Arguments:
|
||||
# 1) CompletionText text to be used as the auto completion result
|
||||
# 2) ListItemText text to be displayed in the suggestion list
|
||||
# 3) ResultType type of completion result
|
||||
# 4) ToolTip text for the tooltip with details about the object
|
||||
|
||||
switch ($Mode) {
|
||||
|
||||
# bash like
|
||||
"Complete" {
|
||||
|
||||
if ($Values.Length -eq 1) {
|
||||
__%[1]s_debug "Only one completion left"
|
||||
|
||||
# insert space after value
|
||||
[System.Management.Automation.CompletionResult]::new($($comp.Name | __%[1]s_escapeStringWithSpecialChars) + $Space, "$($comp.Name)", 'ParameterValue', "$($comp.Description)")
|
||||
|
||||
} else {
|
||||
# Add the proper number of spaces to align the descriptions
|
||||
while($comp.Name.Length -lt $Longest) {
|
||||
$comp.Name = $comp.Name + " "
|
||||
}
|
||||
|
||||
# Check for empty description and only add parentheses if needed
|
||||
if ($($comp.Description) -eq " " ) {
|
||||
$Description = ""
|
||||
} else {
|
||||
$Description = " ($($comp.Description))"
|
||||
}
|
||||
|
||||
[System.Management.Automation.CompletionResult]::new("$($comp.Name)$Description", "$($comp.Name)$Description", 'ParameterValue', "$($comp.Description)")
|
||||
}
|
||||
}
|
||||
|
||||
# zsh like
|
||||
"MenuComplete" {
|
||||
# insert space after value
|
||||
# MenuComplete will automatically show the ToolTip of
|
||||
# the highlighted value at the bottom of the suggestions.
|
||||
[System.Management.Automation.CompletionResult]::new($($comp.Name | __%[1]s_escapeStringWithSpecialChars) + $Space, "$($comp.Name)", 'ParameterValue', "$($comp.Description)")
|
||||
}
|
||||
|
||||
# TabCompleteNext and in case we get something unknown
|
||||
Default {
|
||||
# Like MenuComplete but we don't want to add a space here because
|
||||
# the user need to press space anyway to get the completion.
|
||||
# Description will not be shown because thats not possible with TabCompleteNext
|
||||
[System.Management.Automation.CompletionResult]::new($($comp.Name | __%[1]s_escapeStringWithSpecialChars), "$($comp.Name)", 'ParameterValue', "$($comp.Description)")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
`, name, compCmd,
|
||||
ShellCompDirectiveError, ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp,
|
||||
ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs))
|
||||
}
|
||||
|
||||
func escapeStringForPowerShell(s string) string {
|
||||
return strings.Replace(s, "'", "''", -1)
|
||||
}
|
||||
|
||||
// GenPowerShellCompletion generates PowerShell completion file and writes to the passed writer.
|
||||
func (c *Command) GenPowerShellCompletion(w io.Writer) error {
|
||||
func (c *Command) genPowerShellCompletion(w io.Writer, includeDesc bool) error {
|
||||
buf := new(bytes.Buffer)
|
||||
|
||||
var subCommandCases bytes.Buffer
|
||||
generatePowerShellSubcommandCases(&subCommandCases, c, "")
|
||||
fmt.Fprintf(buf, powerShellCompletionTemplate, c.Name(), c.Name(), subCommandCases.String())
|
||||
|
||||
genPowerShellComp(buf, c.Name(), includeDesc)
|
||||
_, err := buf.WriteTo(w)
|
||||
return err
|
||||
}
|
||||
|
||||
// GenPowerShellCompletionFile generates PowerShell completion file.
|
||||
func (c *Command) GenPowerShellCompletionFile(filename string) error {
|
||||
func (c *Command) genPowerShellCompletionFile(filename string, includeDesc bool) error {
|
||||
outFile, err := os.Create(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer outFile.Close()
|
||||
|
||||
return c.GenPowerShellCompletion(outFile)
|
||||
return c.genPowerShellCompletion(outFile, includeDesc)
|
||||
}
|
||||
|
||||
// GenPowerShellCompletionFile generates powershell completion file without descriptions.
|
||||
func (c *Command) GenPowerShellCompletionFile(filename string) error {
|
||||
return c.genPowerShellCompletionFile(filename, false)
|
||||
}
|
||||
|
||||
// GenPowerShellCompletion generates powershell completion file without descriptions
|
||||
// and writes it to the passed writer.
|
||||
func (c *Command) GenPowerShellCompletion(w io.Writer) error {
|
||||
return c.genPowerShellCompletion(w, false)
|
||||
}
|
||||
|
||||
// GenPowerShellCompletionFileWithDesc generates powershell completion file with descriptions.
|
||||
func (c *Command) GenPowerShellCompletionFileWithDesc(filename string) error {
|
||||
return c.genPowerShellCompletionFile(filename, true)
|
||||
}
|
||||
|
||||
// GenPowerShellCompletionWithDesc generates powershell completion file with descriptions
|
||||
// and writes it to the passed writer.
|
||||
func (c *Command) GenPowerShellCompletionWithDesc(w io.Writer) error {
|
||||
return c.genPowerShellCompletion(w, true)
|
||||
}
|
||||
|
|
|
@ -1,16 +1,3 @@
|
|||
# Generating PowerShell Completions For Your Own cobra.Command
|
||||
|
||||
Cobra can generate PowerShell completion scripts. Users need PowerShell version 5.0 or above, which comes with Windows 10 and can be downloaded separately for Windows 7 or 8.1. They can then write the completions to a file and source this file from their PowerShell profile, which is referenced by the `$Profile` environment variable. See `Get-Help about_Profiles` for more info about PowerShell profiles.
|
||||
|
||||
*Note*: PowerShell completions have not (yet?) been aligned to Cobra's generic shell completion support. This implies the PowerShell completions are not as rich as for other shells (see [What's not yet supported](#whats-not-yet-supported)), and may behave slightly differently. They are still very useful for PowerShell users.
|
||||
|
||||
# What's supported
|
||||
|
||||
- Completion for subcommands using their `.Short` description
|
||||
- Completion for non-hidden flags using their `.Name` and `.Shorthand`
|
||||
|
||||
# What's not yet supported
|
||||
|
||||
- Command aliases
|
||||
- Required, filename or custom flags (they will work like normal flags)
|
||||
- Custom completion scripts
|
||||
Please refer to [Shell Completions](shell_completions.md#powershell-completions) for details.
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
- [Moby (former Docker)](https://github.com/moby/moby)
|
||||
- [Nanobox](https://github.com/nanobox-io/nanobox)/[Nanopack](https://github.com/nanopack)
|
||||
- [OpenShift](https://www.openshift.com/)
|
||||
- [Ory Hydra](https://github.com/ory/hydra)
|
||||
- [Ory Kratos](https://github.com/ory/kratos)
|
||||
- [Pouch](https://github.com/alibaba/pouch)
|
||||
- [ProjectAtomic (enterprise)](http://www.projectatomic.io/)
|
||||
- [Prototool](https://github.com/uber/prototool)
|
||||
|
@ -32,4 +34,5 @@
|
|||
- [Rclone](https://rclone.org/)
|
||||
- [Skaffold](https://skaffold.dev/)
|
||||
- [Tendermint](https://github.com/tendermint/tendermint)
|
||||
- [Twitch CLI](https://github.com/twitchdev/twitch-cli)
|
||||
- [Werf](https://werf.io/)
|
||||
|
|
|
@ -4,10 +4,10 @@ Cobra can generate shell completions for multiple shells.
|
|||
The currently supported shells are:
|
||||
- Bash
|
||||
- Zsh
|
||||
- Fish
|
||||
- fish
|
||||
- PowerShell
|
||||
|
||||
If you are using the generator you can create a completion command by running
|
||||
If you are using the generator, you can create a completion command by running
|
||||
|
||||
```bash
|
||||
cobra add completion
|
||||
|
@ -17,38 +17,46 @@ and then modifying the generated `cmd/completion.go` file to look something like
|
|||
|
||||
```go
|
||||
var completionCmd = &cobra.Command{
|
||||
Use: "completion [bash|zsh|fish|powershell]",
|
||||
Short: "Generate completion script",
|
||||
Use: "completion [bash|zsh|fish|powershell]",
|
||||
Short: "Generate completion script",
|
||||
Long: `To load completions:
|
||||
|
||||
Bash:
|
||||
|
||||
$ source <(yourprogram completion bash)
|
||||
$ source <(yourprogram completion bash)
|
||||
|
||||
# To load completions for each session, execute once:
|
||||
Linux:
|
||||
# To load completions for each session, execute once:
|
||||
# Linux:
|
||||
$ yourprogram completion bash > /etc/bash_completion.d/yourprogram
|
||||
MacOS:
|
||||
# macOS:
|
||||
$ yourprogram completion bash > /usr/local/etc/bash_completion.d/yourprogram
|
||||
|
||||
Zsh:
|
||||
|
||||
# If shell completion is not already enabled in your environment you will need
|
||||
# to enable it. You can execute the following once:
|
||||
# If shell completion is not already enabled in your environment,
|
||||
# you will need to enable it. You can execute the following once:
|
||||
|
||||
$ echo "autoload -U compinit; compinit" >> ~/.zshrc
|
||||
$ echo "autoload -U compinit; compinit" >> ~/.zshrc
|
||||
|
||||
# To load completions for each session, execute once:
|
||||
$ yourprogram completion zsh > "${fpath[1]}/_yourprogram"
|
||||
# To load completions for each session, execute once:
|
||||
$ yourprogram completion zsh > "${fpath[1]}/_yourprogram"
|
||||
|
||||
# You will need to start a new shell for this setup to take effect.
|
||||
# You will need to start a new shell for this setup to take effect.
|
||||
|
||||
Fish:
|
||||
fish:
|
||||
|
||||
$ yourprogram completion fish | source
|
||||
$ yourprogram completion fish | source
|
||||
|
||||
# To load completions for each session, execute once:
|
||||
$ yourprogram completion fish > ~/.config/fish/completions/yourprogram.fish
|
||||
# To load completions for each session, execute once:
|
||||
$ yourprogram completion fish > ~/.config/fish/completions/yourprogram.fish
|
||||
|
||||
PowerShell:
|
||||
|
||||
PS> yourprogram completion powershell | Out-String | Invoke-Expression
|
||||
|
||||
# To load completions for every new session, run:
|
||||
PS> yourprogram completion powershell > yourprogram.ps1
|
||||
# and source this file from your PowerShell profile.
|
||||
`,
|
||||
DisableFlagsInUseLine: true,
|
||||
ValidArgs: []string{"bash", "zsh", "fish", "powershell"},
|
||||
|
@ -68,7 +76,7 @@ $ yourprogram completion fish > ~/.config/fish/completions/yourprogram.fish
|
|||
}
|
||||
```
|
||||
|
||||
**Note:** The cobra generator may include messages printed to stdout for example if the config file is loaded, this will break the auto complete script so must be removed.
|
||||
**Note:** The cobra generator may include messages printed to stdout, for example, if the config file is loaded; this will break the auto-completion script so must be removed.
|
||||
|
||||
# Customizing completions
|
||||
|
||||
|
@ -91,8 +99,7 @@ cmd := &cobra.Command{
|
|||
Long: get_long,
|
||||
Example: get_example,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
err := RunGet(f, out, cmd, args)
|
||||
util.CheckErr(err)
|
||||
cobra.CheckErr(RunGet(f, out, cmd, args))
|
||||
},
|
||||
ValidArgs: validArgs,
|
||||
}
|
||||
|
@ -124,7 +131,7 @@ the completion algorithm if entered manually, e.g. in:
|
|||
|
||||
```bash
|
||||
$ kubectl get rc [tab][tab]
|
||||
backend frontend database
|
||||
backend frontend database
|
||||
```
|
||||
|
||||
Note that without declaring `rc` as an alias, the completion algorithm would not know to show the list of
|
||||
|
@ -246,7 +253,7 @@ and you'll get something like
|
|||
|
||||
```bash
|
||||
$ kubectl exec [tab][tab]
|
||||
-c --container= -p --pod=
|
||||
-c --container= -p --pod=
|
||||
```
|
||||
|
||||
### Specify dynamic flag completion
|
||||
|
@ -316,7 +323,7 @@ cmd.RegisterFlagCompletionFunc(flagName, func(cmd *cobra.Command, args []string,
|
|||
```
|
||||
### Descriptions for completions
|
||||
|
||||
Both `zsh` and `fish` allow for descriptions to annotate completion choices. For commands and flags, Cobra will provide the descriptions automatically, based on usage information. For example, using zsh:
|
||||
`zsh`, `fish` and `powershell` allow for descriptions to annotate completion choices. For commands and flags, Cobra will provide the descriptions automatically, based on usage information. For example, using zsh:
|
||||
```
|
||||
$ helm s[tab]
|
||||
search -- search for a keyword in charts
|
||||
|
@ -361,12 +368,12 @@ completion firstcommand secondcommand
|
|||
```
|
||||
### Bash legacy dynamic completions
|
||||
|
||||
For backwards-compatibility, Cobra still supports its bash legacy dynamic completion solution.
|
||||
For backward compatibility, Cobra still supports its bash legacy dynamic completion solution.
|
||||
Please refer to [Bash Completions](bash_completions.md) for details.
|
||||
|
||||
## Zsh completions
|
||||
|
||||
Cobra supports native Zsh completion generated from the root `cobra.Command`.
|
||||
Cobra supports native zsh completion generated from the root `cobra.Command`.
|
||||
The generated completion script should be put somewhere in your `$fpath` and be named
|
||||
`_<yourProgram>`. You will need to start a new shell for the completions to become available.
|
||||
|
||||
|
@ -385,23 +392,23 @@ status -- displays the status of the named release
|
|||
$ helm s[tab]
|
||||
search show status
|
||||
```
|
||||
*Note*: Because of backwards-compatibility requirements, we were forced to have a different API to disable completion descriptions between `Zsh` and `Fish`.
|
||||
*Note*: Because of backward-compatibility requirements, we were forced to have a different API to disable completion descriptions between `zsh` and `fish`.
|
||||
|
||||
### Limitations
|
||||
|
||||
* Custom completions implemented in Bash scripting (legacy) are not supported and will be ignored for `zsh` (including the use of the `BashCompCustom` flag annotation).
|
||||
* You should instead use `ValidArgsFunction` and `RegisterFlagCompletionFunc()` which are portable to the different shells (`bash`, `zsh`, `fish`).
|
||||
* You should instead use `ValidArgsFunction` and `RegisterFlagCompletionFunc()` which are portable to the different shells (`bash`, `zsh`, `fish`, `powershell`).
|
||||
* The function `MarkFlagCustom()` is not supported and will be ignored for `zsh`.
|
||||
* You should instead use `RegisterFlagCompletionFunc()`.
|
||||
|
||||
### Zsh completions standardization
|
||||
|
||||
Cobra 1.1 standardized its zsh completion support to align it with its other shell completions. Although the API was kept backwards-compatible, some small changes in behavior were introduced.
|
||||
Cobra 1.1 standardized its zsh completion support to align it with its other shell completions. Although the API was kept backward-compatible, some small changes in behavior were introduced.
|
||||
Please refer to [Zsh Completions](zsh_completions.md) for details.
|
||||
|
||||
## Fish completions
|
||||
## fish completions
|
||||
|
||||
Cobra supports native Fish completions generated from the root `cobra.Command`. You can use the `command.GenFishCompletion()` or `command.GenFishCompletionFile()` functions. You must provide these functions with a parameter indicating if the completions should be annotated with a description; Cobra will provide the description automatically based on usage information. You can choose to make this option configurable by your users.
|
||||
Cobra supports native fish completions generated from the root `cobra.Command`. You can use the `command.GenFishCompletion()` or `command.GenFishCompletionFile()` functions. You must provide these functions with a parameter indicating if the completions should be annotated with a description; Cobra will provide the description automatically based on usage information. You can choose to make this option configurable by your users.
|
||||
```
|
||||
# With descriptions
|
||||
$ helm s[tab]
|
||||
|
@ -411,12 +418,12 @@ search (search for a keyword in charts) show (show information of a chart) s
|
|||
$ helm s[tab]
|
||||
search show status
|
||||
```
|
||||
*Note*: Because of backwards-compatibility requirements, we were forced to have a different API to disable completion descriptions between `Zsh` and `Fish`.
|
||||
*Note*: Because of backward-compatibility requirements, we were forced to have a different API to disable completion descriptions between `zsh` and `fish`.
|
||||
|
||||
### Limitations
|
||||
|
||||
* Custom completions implemented in Bash scripting (legacy) are not supported and will be ignored for `fish` (including the use of the `BashCompCustom` flag annotation).
|
||||
* You should instead use `ValidArgsFunction` and `RegisterFlagCompletionFunc()` which are portable to the different shells (`bash`, `zsh`, `fish`).
|
||||
* Custom completions implemented in bash scripting (legacy) are not supported and will be ignored for `fish` (including the use of the `BashCompCustom` flag annotation).
|
||||
* You should instead use `ValidArgsFunction` and `RegisterFlagCompletionFunc()` which are portable to the different shells (`bash`, `zsh`, `fish`, `powershell`).
|
||||
* The function `MarkFlagCustom()` is not supported and will be ignored for `fish`.
|
||||
* You should instead use `RegisterFlagCompletionFunc()`.
|
||||
* The following flag completion annotations are not supported and will be ignored for `fish`:
|
||||
|
@ -431,4 +438,46 @@ search show status
|
|||
|
||||
## PowerShell completions
|
||||
|
||||
Please refer to [PowerShell Completions](powershell_completions.md) for details.
|
||||
Cobra supports native PowerShell completions generated from the root `cobra.Command`. You can use the `command.GenPowerShellCompletion()` or `command.GenPowerShellCompletionFile()` functions. To include descriptions use `command.GenPowerShellCompletionWithDesc()` and `command.GenPowerShellCompletionFileWithDesc()`. Cobra will provide the description automatically based on usage information. You can choose to make this option configurable by your users.
|
||||
|
||||
The script is designed to support all three PowerShell completion modes:
|
||||
|
||||
* TabCompleteNext (default windows style - on each key press the next option is displayed)
|
||||
* Complete (works like bash)
|
||||
* MenuComplete (works like zsh)
|
||||
|
||||
You set the mode with `Set-PSReadLineKeyHandler -Key Tab -Function <mode>`. Descriptions are only displayed when using the `Complete` or `MenuComplete` mode.
|
||||
|
||||
Users need PowerShell version 5.0 or above, which comes with Windows 10 and can be downloaded separately for Windows 7 or 8.1. They can then write the completions to a file and source this file from their PowerShell profile, which is referenced by the `$Profile` environment variable. See `Get-Help about_Profiles` for more info about PowerShell profiles.
|
||||
|
||||
```
|
||||
# With descriptions and Mode 'Complete'
|
||||
$ helm s[tab]
|
||||
search (search for a keyword in charts) show (show information of a chart) status (displays the status of the named release)
|
||||
|
||||
# With descriptions and Mode 'MenuComplete' The description of the current selected value will be displayed below the suggestions.
|
||||
$ helm s[tab]
|
||||
search show status
|
||||
|
||||
search for a keyword in charts
|
||||
|
||||
# Without descriptions
|
||||
$ helm s[tab]
|
||||
search show status
|
||||
```
|
||||
|
||||
### Limitations
|
||||
|
||||
* Custom completions implemented in bash scripting (legacy) are not supported and will be ignored for `powershell` (including the use of the `BashCompCustom` flag annotation).
|
||||
* You should instead use `ValidArgsFunction` and `RegisterFlagCompletionFunc()` which are portable to the different shells (`bash`, `zsh`, `fish`, `powershell`).
|
||||
* The function `MarkFlagCustom()` is not supported and will be ignored for `powershell`.
|
||||
* You should instead use `RegisterFlagCompletionFunc()`.
|
||||
* The following flag completion annotations are not supported and will be ignored for `powershell`:
|
||||
* `BashCompFilenameExt` (filtering by file extension)
|
||||
* `BashCompSubdirsInDir` (filtering by directory)
|
||||
* The functions corresponding to the above annotations are consequently not supported and will be ignored for `powershell`:
|
||||
* `MarkFlagFilename()` and `MarkPersistentFlagFilename()` (filtering by file extension)
|
||||
* `MarkFlagDirname()` and `MarkPersistentFlagDirname()` (filtering by directory)
|
||||
* Similarly, the following completion directives are not supported and will be ignored for `powershell`:
|
||||
* `ShellCompDirectiveFilterFileExt` (filtering by file extension)
|
||||
* `ShellCompDirectiveFilterDirs` (filtering by directory)
|
||||
|
|
|
@ -70,12 +70,12 @@ func (c *Command) genZshCompletion(w io.Writer, includeDesc bool) error {
|
|||
return err
|
||||
}
|
||||
|
||||
func genZshComp(buf *bytes.Buffer, name string, includeDesc bool) {
|
||||
func genZshComp(buf io.StringWriter, name string, includeDesc bool) {
|
||||
compCmd := ShellCompRequestCmd
|
||||
if !includeDesc {
|
||||
compCmd = ShellCompNoDescRequestCmd
|
||||
}
|
||||
buf.WriteString(fmt.Sprintf(`#compdef _%[1]s %[1]s
|
||||
WriteStringAndCheck(buf, fmt.Sprintf(`#compdef _%[1]s %[1]s
|
||||
|
||||
# zsh completion for %-36[1]s -*- shell-script -*-
|
||||
|
||||
|
|
|
@ -224,12 +224,16 @@ func firstPathOK(r rune) bool {
|
|||
'a' <= r && r <= 'z'
|
||||
}
|
||||
|
||||
// pathOK reports whether r can appear in an import path element.
|
||||
// modPathOK reports whether r can appear in a module path element.
|
||||
// Paths can be ASCII letters, ASCII digits, and limited ASCII punctuation: - . _ and ~.
|
||||
// This matches what "go get" has historically recognized in import paths.
|
||||
//
|
||||
// This matches what "go get" has historically recognized in import paths,
|
||||
// and avoids confusing sequences like '%20' or '+' that would change meaning
|
||||
// if used in a URL.
|
||||
//
|
||||
// TODO(rsc): We would like to allow Unicode letters, but that requires additional
|
||||
// care in the safe encoding (see "escaped paths" above).
|
||||
func pathOK(r rune) bool {
|
||||
func modPathOK(r rune) bool {
|
||||
if r < utf8.RuneSelf {
|
||||
return r == '-' || r == '.' || r == '_' || r == '~' ||
|
||||
'0' <= r && r <= '9' ||
|
||||
|
@ -239,6 +243,17 @@ func pathOK(r rune) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
// modPathOK reports whether r can appear in a package import path element.
|
||||
//
|
||||
// Import paths are intermediate between module paths and file paths: we allow
|
||||
// disallow characters that would be confusing or ambiguous as arguments to
|
||||
// 'go get' (such as '@' and ' ' ), but allow certain characters that are
|
||||
// otherwise-unambiguous on the command line and historically used for some
|
||||
// binary names (such as '++' as a suffix for compiler binaries and wrappers).
|
||||
func importPathOK(r rune) bool {
|
||||
return modPathOK(r) || r == '+'
|
||||
}
|
||||
|
||||
// fileNameOK reports whether r can appear in a file name.
|
||||
// For now we allow all Unicode letters but otherwise limit to pathOK plus a few more punctuation characters.
|
||||
// If we expand the set of allowed characters here, we have to
|
||||
|
@ -270,7 +285,7 @@ func fileNameOK(r rune) bool {
|
|||
|
||||
// CheckPath checks that a module path is valid.
|
||||
// A valid module path is a valid import path, as checked by CheckImportPath,
|
||||
// with two additional constraints.
|
||||
// with three additional constraints.
|
||||
// First, the leading path element (up to the first slash, if any),
|
||||
// by convention a domain name, must contain only lower-case ASCII letters,
|
||||
// ASCII digits, dots (U+002E), and dashes (U+002D);
|
||||
|
@ -280,8 +295,9 @@ func fileNameOK(r rune) bool {
|
|||
// and must not contain any dots. For paths beginning with "gopkg.in/",
|
||||
// this second requirement is replaced by a requirement that the path
|
||||
// follow the gopkg.in server's conventions.
|
||||
// Third, no path element may begin with a dot.
|
||||
func CheckPath(path string) error {
|
||||
if err := checkPath(path, false); err != nil {
|
||||
if err := checkPath(path, modulePath); err != nil {
|
||||
return fmt.Errorf("malformed module path %q: %v", path, err)
|
||||
}
|
||||
i := strings.Index(path, "/")
|
||||
|
@ -315,7 +331,7 @@ func CheckPath(path string) error {
|
|||
//
|
||||
// A valid path element is a non-empty string made up of
|
||||
// ASCII letters, ASCII digits, and limited ASCII punctuation: - . _ and ~.
|
||||
// It must not begin or end with a dot (U+002E), nor contain two dots in a row.
|
||||
// It must not end with a dot (U+002E), nor contain two dots in a row.
|
||||
//
|
||||
// The element prefix up to the first dot must not be a reserved file name
|
||||
// on Windows, regardless of case (CON, com1, NuL, and so on). The element
|
||||
|
@ -326,19 +342,29 @@ func CheckPath(path string) error {
|
|||
// top-level package documentation for additional information about
|
||||
// subtleties of Unicode.
|
||||
func CheckImportPath(path string) error {
|
||||
if err := checkPath(path, false); err != nil {
|
||||
if err := checkPath(path, importPath); err != nil {
|
||||
return fmt.Errorf("malformed import path %q: %v", path, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// pathKind indicates what kind of path we're checking. Module paths,
|
||||
// import paths, and file paths have different restrictions.
|
||||
type pathKind int
|
||||
|
||||
const (
|
||||
modulePath pathKind = iota
|
||||
importPath
|
||||
filePath
|
||||
)
|
||||
|
||||
// checkPath checks that a general path is valid.
|
||||
// It returns an error describing why but not mentioning path.
|
||||
// Because these checks apply to both module paths and import paths,
|
||||
// the caller is expected to add the "malformed ___ path %q: " prefix.
|
||||
// fileName indicates whether the final element of the path is a file name
|
||||
// (as opposed to a directory name).
|
||||
func checkPath(path string, fileName bool) error {
|
||||
func checkPath(path string, kind pathKind) error {
|
||||
if !utf8.ValidString(path) {
|
||||
return fmt.Errorf("invalid UTF-8")
|
||||
}
|
||||
|
@ -357,39 +383,45 @@ func checkPath(path string, fileName bool) error {
|
|||
elemStart := 0
|
||||
for i, r := range path {
|
||||
if r == '/' {
|
||||
if err := checkElem(path[elemStart:i], fileName); err != nil {
|
||||
if err := checkElem(path[elemStart:i], kind); err != nil {
|
||||
return err
|
||||
}
|
||||
elemStart = i + 1
|
||||
}
|
||||
}
|
||||
if err := checkElem(path[elemStart:], fileName); err != nil {
|
||||
if err := checkElem(path[elemStart:], kind); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// checkElem checks whether an individual path element is valid.
|
||||
// fileName indicates whether the element is a file name (not a directory name).
|
||||
func checkElem(elem string, fileName bool) error {
|
||||
func checkElem(elem string, kind pathKind) error {
|
||||
if elem == "" {
|
||||
return fmt.Errorf("empty path element")
|
||||
}
|
||||
if strings.Count(elem, ".") == len(elem) {
|
||||
return fmt.Errorf("invalid path element %q", elem)
|
||||
}
|
||||
if elem[0] == '.' && !fileName {
|
||||
if elem[0] == '.' && kind == modulePath {
|
||||
return fmt.Errorf("leading dot in path element")
|
||||
}
|
||||
if elem[len(elem)-1] == '.' {
|
||||
return fmt.Errorf("trailing dot in path element")
|
||||
}
|
||||
charOK := pathOK
|
||||
if fileName {
|
||||
charOK = fileNameOK
|
||||
}
|
||||
for _, r := range elem {
|
||||
if !charOK(r) {
|
||||
ok := false
|
||||
switch kind {
|
||||
case modulePath:
|
||||
ok = modPathOK(r)
|
||||
case importPath:
|
||||
ok = importPathOK(r)
|
||||
case filePath:
|
||||
ok = fileNameOK(r)
|
||||
default:
|
||||
panic(fmt.Sprintf("internal error: invalid kind %v", kind))
|
||||
}
|
||||
if !ok {
|
||||
return fmt.Errorf("invalid char %q", r)
|
||||
}
|
||||
}
|
||||
|
@ -406,7 +438,7 @@ func checkElem(elem string, fileName bool) error {
|
|||
}
|
||||
}
|
||||
|
||||
if fileName {
|
||||
if kind == filePath {
|
||||
// don't check for Windows short-names in file names. They're
|
||||
// only an issue for import paths.
|
||||
return nil
|
||||
|
@ -444,7 +476,7 @@ func checkElem(elem string, fileName bool) error {
|
|||
// top-level package documentation for additional information about
|
||||
// subtleties of Unicode.
|
||||
func CheckFilePath(path string) error {
|
||||
if err := checkPath(path, true); err != nil {
|
||||
if err := checkPath(path, filePath); err != nil {
|
||||
return fmt.Errorf("malformed file path %q: %v", path, err)
|
||||
}
|
||||
return nil
|
||||
|
@ -647,7 +679,7 @@ func EscapePath(path string) (escaped string, err error) {
|
|||
// Versions are allowed to be in non-semver form but must be valid file names
|
||||
// and not contain exclamation marks.
|
||||
func EscapeVersion(v string) (escaped string, err error) {
|
||||
if err := checkElem(v, true); err != nil || strings.Contains(v, "!") {
|
||||
if err := checkElem(v, filePath); err != nil || strings.Contains(v, "!") {
|
||||
return "", &InvalidVersionError{
|
||||
Version: v,
|
||||
Err: fmt.Errorf("disallowed version string"),
|
||||
|
@ -706,7 +738,7 @@ func UnescapeVersion(escaped string) (v string, err error) {
|
|||
if !ok {
|
||||
return "", fmt.Errorf("invalid escaped version %q", escaped)
|
||||
}
|
||||
if err := checkElem(v, true); err != nil {
|
||||
if err := checkElem(v, filePath); err != nil {
|
||||
return "", fmt.Errorf("invalid escaped version %q: %v", v, err)
|
||||
}
|
||||
return v, nil
|
||||
|
|
|
@ -138,6 +138,9 @@ func Compare(v, w string) int {
|
|||
|
||||
// Max canonicalizes its arguments and then returns the version string
|
||||
// that compares greater.
|
||||
//
|
||||
// Deprecated: use Compare instead. In most cases, returning a canonicalized
|
||||
// version is not expected or desired.
|
||||
func Max(v, w string) string {
|
||||
v = Canonical(v)
|
||||
w = Canonical(w)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# OAuth2 for Go
|
||||
|
||||
[](https://pkg.go.dev/golang.org/x/oauth2)
|
||||
[](https://travis-ci.org/golang/oauth2)
|
||||
[](https://godoc.org/golang.org/x/oauth2)
|
||||
|
||||
oauth2 package contains a client implementation for OAuth 2.0 spec.
|
||||
|
||||
|
@ -14,17 +14,17 @@ go get golang.org/x/oauth2
|
|||
Or you can manually git clone the repository to
|
||||
`$(go env GOPATH)/src/golang.org/x/oauth2`.
|
||||
|
||||
See godoc for further documentation and examples.
|
||||
See pkg.go.dev for further documentation and examples.
|
||||
|
||||
* [godoc.org/golang.org/x/oauth2](https://godoc.org/golang.org/x/oauth2)
|
||||
* [godoc.org/golang.org/x/oauth2/google](https://godoc.org/golang.org/x/oauth2/google)
|
||||
* [pkg.go.dev/golang.org/x/oauth2](https://pkg.go.dev/golang.org/x/oauth2)
|
||||
* [pkg.go.dev/golang.org/x/oauth2/google](https://pkg.go.dev/golang.org/x/oauth2/google)
|
||||
|
||||
## Policy for new packages
|
||||
|
||||
We no longer accept new provider-specific packages in this repo if all
|
||||
they do is add a single endpoint variable. If you just want to add a
|
||||
single endpoint, add it to the
|
||||
[godoc.org/golang.org/x/oauth2/endpoints](https://godoc.org/golang.org/x/oauth2/endpoints)
|
||||
[pkg.go.dev/golang.org/x/oauth2/endpoints](https://pkg.go.dev/golang.org/x/oauth2/endpoints)
|
||||
package.
|
||||
|
||||
## Report Issues / Send Patches
|
||||
|
|
|
@ -3,8 +3,7 @@ module golang.org/x/oauth2
|
|||
go 1.11
|
||||
|
||||
require (
|
||||
cloud.google.com/go v0.34.0
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 // indirect
|
||||
google.golang.org/appengine v1.4.0
|
||||
cloud.google.com/go v0.65.0
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202
|
||||
google.golang.org/appengine v1.6.6
|
||||
)
|
||||
|
|
|
@ -1,12 +1,361 @@
|
|||
cloud.google.com/go v0.34.0 h1:eOI3/cP2VTU6uZLDYAoic+eyzzB9YyGmJ7eIjl8rOPg=
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
|
||||
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
||||
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
|
||||
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
||||
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
|
||||
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
|
||||
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
|
||||
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
|
||||
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
|
||||
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
|
||||
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
|
||||
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
|
||||
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
|
||||
cloud.google.com/go v0.65.0 h1:Dg9iHVQfrhq82rUNu9ZxUDrJLaxFUe/HlCVaLyRruq8=
|
||||
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
||||
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
|
||||
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
|
||||
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
|
||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
||||
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
|
||||
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
|
||||
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
|
||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
||||
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
|
||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
||||
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.1 h1:JFrFEBb2xKufg6XkJsJr+WbKb4FQlURi5RUcBveYu9k=
|
||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
|
||||
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
|
||||
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e h1:bRhVy7zSSasaqNksaRZiA5EEI+Ei4I1nO5Jh72wfHlg=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/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-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
||||
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
||||
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
|
||||
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc=
|
||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
||||
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
|
||||
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
|
||||
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
|
||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build appengine
|
||||
// +build appengine
|
||||
|
||||
package internal
|
||||
|
|
|
@ -96,6 +96,8 @@ func Of64(k Key, v uint64) Label { return Label{key: k, packed: v} }
|
|||
// access should be done with the From method of the key.
|
||||
func (t Label) Unpack64() uint64 { return t.packed }
|
||||
|
||||
type stringptr unsafe.Pointer
|
||||
|
||||
// OfString creates a new label from a key and a string.
|
||||
// This method is for implementing new key types, label creation should
|
||||
// normally be done with the Of method of the key.
|
||||
|
@ -104,7 +106,7 @@ func OfString(k Key, v string) Label {
|
|||
return Label{
|
||||
key: k,
|
||||
packed: uint64(hdr.Len),
|
||||
untyped: unsafe.Pointer(hdr.Data),
|
||||
untyped: stringptr(hdr.Data),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -115,9 +117,9 @@ func OfString(k Key, v string) Label {
|
|||
func (t Label) UnpackString() string {
|
||||
var v string
|
||||
hdr := (*reflect.StringHeader)(unsafe.Pointer(&v))
|
||||
hdr.Data = uintptr(t.untyped.(unsafe.Pointer))
|
||||
hdr.Data = uintptr(t.untyped.(stringptr))
|
||||
hdr.Len = int(t.packed)
|
||||
return *(*string)(unsafe.Pointer(hdr))
|
||||
return v
|
||||
}
|
||||
|
||||
// Valid returns true if the Label is a valid one (it has a key).
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build freebsd || openbsd || netbsd
|
||||
// +build freebsd openbsd netbsd
|
||||
|
||||
package fastwalk
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build (linux || darwin) && !appengine
|
||||
// +build linux darwin
|
||||
// +build !appengine
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build darwin || freebsd || openbsd || netbsd
|
||||
// +build darwin freebsd openbsd netbsd
|
||||
|
||||
package fastwalk
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build linux
|
||||
// +build !appengine
|
||||
//go:build linux && !appengine
|
||||
// +build linux,!appengine
|
||||
|
||||
package fastwalk
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build appengine || (!linux && !darwin && !freebsd && !openbsd && !netbsd)
|
||||
// +build appengine !linux,!darwin,!freebsd,!openbsd,!netbsd
|
||||
|
||||
package fastwalk
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build (linux || darwin || freebsd || openbsd || netbsd) && !appengine
|
||||
// +build linux darwin freebsd openbsd netbsd
|
||||
// +build !appengine
|
||||
|
||||
|
@ -21,7 +22,7 @@ const blockSize = 8 << 10
|
|||
const unknownFileMode os.FileMode = os.ModeNamedPipe | os.ModeSocket | os.ModeDevice
|
||||
|
||||
func readDir(dirName string, fn func(dirName, entName string, typ os.FileMode) error) error {
|
||||
fd, err := syscall.Open(dirName, 0, 0)
|
||||
fd, err := open(dirName, 0, 0)
|
||||
if err != nil {
|
||||
return &os.PathError{Op: "open", Path: dirName, Err: err}
|
||||
}
|
||||
|
@ -35,7 +36,7 @@ func readDir(dirName string, fn func(dirName, entName string, typ os.FileMode) e
|
|||
for {
|
||||
if bufp >= nbuf {
|
||||
bufp = 0
|
||||
nbuf, err = syscall.ReadDirent(fd, buf)
|
||||
nbuf, err = readDirent(fd, buf)
|
||||
if err != nil {
|
||||
return os.NewSyscallError("readdirent", err)
|
||||
}
|
||||
|
@ -126,3 +127,27 @@ func parseDirEnt(buf []byte) (consumed int, name string, typ os.FileMode) {
|
|||
}
|
||||
return
|
||||
}
|
||||
|
||||
// According to https://golang.org/doc/go1.14#runtime
|
||||
// A consequence of the implementation of preemption is that on Unix systems, including Linux and macOS
|
||||
// systems, programs built with Go 1.14 will receive more signals than programs built with earlier releases.
|
||||
//
|
||||
// This causes syscall.Open and syscall.ReadDirent sometimes fail with EINTR errors.
|
||||
// We need to retry in this case.
|
||||
func open(path string, mode int, perm uint32) (fd int, err error) {
|
||||
for {
|
||||
fd, err := syscall.Open(path, mode, perm)
|
||||
if err != syscall.EINTR {
|
||||
return fd, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func readDirent(fd int, buf []byte) (n int, err error) {
|
||||
for {
|
||||
nbuf, err := syscall.ReadDirent(fd, buf)
|
||||
if err != syscall.EINTR {
|
||||
return nbuf, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"golang.org/x/mod/semver"
|
||||
)
|
||||
|
@ -19,11 +20,15 @@ import (
|
|||
// ModuleJSON holds information about a module.
|
||||
type ModuleJSON struct {
|
||||
Path string // module path
|
||||
Version string // module version
|
||||
Versions []string // available module versions (with -versions)
|
||||
Replace *ModuleJSON // replaced by this module
|
||||
Time *time.Time // time version was created
|
||||
Update *ModuleJSON // available update, if any (with -u)
|
||||
Main bool // is this the main module?
|
||||
Indirect bool // is this module only an indirect dependency of main module?
|
||||
Dir string // directory holding files for this module, if any
|
||||
GoMod string // path to go.mod file for this module, if any
|
||||
GoMod string // path to go.mod file used when loading this module, if any
|
||||
GoVersion string // go version used in module
|
||||
}
|
||||
|
||||
|
|
|
@ -89,8 +89,10 @@ func (r *ModuleResolver) init() error {
|
|||
err := r.initAllMods()
|
||||
// We expect an error when running outside of a module with
|
||||
// GO111MODULE=on. Other errors are fatal.
|
||||
if err != nil && !strings.Contains(err.Error(), "working directory is not part of a module") {
|
||||
return err
|
||||
if err != nil {
|
||||
if errMsg := err.Error(); !strings.Contains(errMsg, "working directory is not part of a module") && !strings.Contains(errMsg, "go.mod file not found") {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -974,13 +974,29 @@ var stdlib = map[string][]string{
|
|||
"DF_STATIC_TLS",
|
||||
"DF_SYMBOLIC",
|
||||
"DF_TEXTREL",
|
||||
"DT_ADDRRNGHI",
|
||||
"DT_ADDRRNGLO",
|
||||
"DT_AUDIT",
|
||||
"DT_AUXILIARY",
|
||||
"DT_BIND_NOW",
|
||||
"DT_CHECKSUM",
|
||||
"DT_CONFIG",
|
||||
"DT_DEBUG",
|
||||
"DT_DEPAUDIT",
|
||||
"DT_ENCODING",
|
||||
"DT_FEATURE",
|
||||
"DT_FILTER",
|
||||
"DT_FINI",
|
||||
"DT_FINI_ARRAY",
|
||||
"DT_FINI_ARRAYSZ",
|
||||
"DT_FLAGS",
|
||||
"DT_FLAGS_1",
|
||||
"DT_GNU_CONFLICT",
|
||||
"DT_GNU_CONFLICTSZ",
|
||||
"DT_GNU_HASH",
|
||||
"DT_GNU_LIBLIST",
|
||||
"DT_GNU_LIBLISTSZ",
|
||||
"DT_GNU_PRELINKED",
|
||||
"DT_HASH",
|
||||
"DT_HIOS",
|
||||
"DT_HIPROC",
|
||||
|
@ -990,28 +1006,100 @@ var stdlib = map[string][]string{
|
|||
"DT_JMPREL",
|
||||
"DT_LOOS",
|
||||
"DT_LOPROC",
|
||||
"DT_MIPS_AUX_DYNAMIC",
|
||||
"DT_MIPS_BASE_ADDRESS",
|
||||
"DT_MIPS_COMPACT_SIZE",
|
||||
"DT_MIPS_CONFLICT",
|
||||
"DT_MIPS_CONFLICTNO",
|
||||
"DT_MIPS_CXX_FLAGS",
|
||||
"DT_MIPS_DELTA_CLASS",
|
||||
"DT_MIPS_DELTA_CLASSSYM",
|
||||
"DT_MIPS_DELTA_CLASSSYM_NO",
|
||||
"DT_MIPS_DELTA_CLASS_NO",
|
||||
"DT_MIPS_DELTA_INSTANCE",
|
||||
"DT_MIPS_DELTA_INSTANCE_NO",
|
||||
"DT_MIPS_DELTA_RELOC",
|
||||
"DT_MIPS_DELTA_RELOC_NO",
|
||||
"DT_MIPS_DELTA_SYM",
|
||||
"DT_MIPS_DELTA_SYM_NO",
|
||||
"DT_MIPS_DYNSTR_ALIGN",
|
||||
"DT_MIPS_FLAGS",
|
||||
"DT_MIPS_GOTSYM",
|
||||
"DT_MIPS_GP_VALUE",
|
||||
"DT_MIPS_HIDDEN_GOTIDX",
|
||||
"DT_MIPS_HIPAGENO",
|
||||
"DT_MIPS_ICHECKSUM",
|
||||
"DT_MIPS_INTERFACE",
|
||||
"DT_MIPS_INTERFACE_SIZE",
|
||||
"DT_MIPS_IVERSION",
|
||||
"DT_MIPS_LIBLIST",
|
||||
"DT_MIPS_LIBLISTNO",
|
||||
"DT_MIPS_LOCALPAGE_GOTIDX",
|
||||
"DT_MIPS_LOCAL_GOTIDX",
|
||||
"DT_MIPS_LOCAL_GOTNO",
|
||||
"DT_MIPS_MSYM",
|
||||
"DT_MIPS_OPTIONS",
|
||||
"DT_MIPS_PERF_SUFFIX",
|
||||
"DT_MIPS_PIXIE_INIT",
|
||||
"DT_MIPS_PLTGOT",
|
||||
"DT_MIPS_PROTECTED_GOTIDX",
|
||||
"DT_MIPS_RLD_MAP",
|
||||
"DT_MIPS_RLD_MAP_REL",
|
||||
"DT_MIPS_RLD_TEXT_RESOLVE_ADDR",
|
||||
"DT_MIPS_RLD_VERSION",
|
||||
"DT_MIPS_RWPLT",
|
||||
"DT_MIPS_SYMBOL_LIB",
|
||||
"DT_MIPS_SYMTABNO",
|
||||
"DT_MIPS_TIME_STAMP",
|
||||
"DT_MIPS_UNREFEXTNO",
|
||||
"DT_MOVEENT",
|
||||
"DT_MOVESZ",
|
||||
"DT_MOVETAB",
|
||||
"DT_NEEDED",
|
||||
"DT_NULL",
|
||||
"DT_PLTGOT",
|
||||
"DT_PLTPAD",
|
||||
"DT_PLTPADSZ",
|
||||
"DT_PLTREL",
|
||||
"DT_PLTRELSZ",
|
||||
"DT_POSFLAG_1",
|
||||
"DT_PPC64_GLINK",
|
||||
"DT_PPC64_OPD",
|
||||
"DT_PPC64_OPDSZ",
|
||||
"DT_PPC64_OPT",
|
||||
"DT_PPC_GOT",
|
||||
"DT_PPC_OPT",
|
||||
"DT_PREINIT_ARRAY",
|
||||
"DT_PREINIT_ARRAYSZ",
|
||||
"DT_REL",
|
||||
"DT_RELA",
|
||||
"DT_RELACOUNT",
|
||||
"DT_RELAENT",
|
||||
"DT_RELASZ",
|
||||
"DT_RELCOUNT",
|
||||
"DT_RELENT",
|
||||
"DT_RELSZ",
|
||||
"DT_RPATH",
|
||||
"DT_RUNPATH",
|
||||
"DT_SONAME",
|
||||
"DT_SPARC_REGISTER",
|
||||
"DT_STRSZ",
|
||||
"DT_STRTAB",
|
||||
"DT_SYMBOLIC",
|
||||
"DT_SYMENT",
|
||||
"DT_SYMINENT",
|
||||
"DT_SYMINFO",
|
||||
"DT_SYMINSZ",
|
||||
"DT_SYMTAB",
|
||||
"DT_SYMTAB_SHNDX",
|
||||
"DT_TEXTREL",
|
||||
"DT_TLSDESC_GOT",
|
||||
"DT_TLSDESC_PLT",
|
||||
"DT_USED",
|
||||
"DT_VALRNGHI",
|
||||
"DT_VALRNGLO",
|
||||
"DT_VERDEF",
|
||||
"DT_VERDEFNUM",
|
||||
"DT_VERNEED",
|
||||
"DT_VERNEEDNUM",
|
||||
"DT_VERSYM",
|
||||
|
@ -1271,17 +1359,38 @@ var stdlib = map[string][]string{
|
|||
"PF_R",
|
||||
"PF_W",
|
||||
"PF_X",
|
||||
"PT_AARCH64_ARCHEXT",
|
||||
"PT_AARCH64_UNWIND",
|
||||
"PT_ARM_ARCHEXT",
|
||||
"PT_ARM_EXIDX",
|
||||
"PT_DYNAMIC",
|
||||
"PT_GNU_EH_FRAME",
|
||||
"PT_GNU_MBIND_HI",
|
||||
"PT_GNU_MBIND_LO",
|
||||
"PT_GNU_PROPERTY",
|
||||
"PT_GNU_RELRO",
|
||||
"PT_GNU_STACK",
|
||||
"PT_HIOS",
|
||||
"PT_HIPROC",
|
||||
"PT_INTERP",
|
||||
"PT_LOAD",
|
||||
"PT_LOOS",
|
||||
"PT_LOPROC",
|
||||
"PT_MIPS_ABIFLAGS",
|
||||
"PT_MIPS_OPTIONS",
|
||||
"PT_MIPS_REGINFO",
|
||||
"PT_MIPS_RTPROC",
|
||||
"PT_NOTE",
|
||||
"PT_NULL",
|
||||
"PT_OPENBSD_BOOTDATA",
|
||||
"PT_OPENBSD_RANDOMIZE",
|
||||
"PT_OPENBSD_WXNEEDED",
|
||||
"PT_PAX_FLAGS",
|
||||
"PT_PHDR",
|
||||
"PT_S390_PGSTE",
|
||||
"PT_SHLIB",
|
||||
"PT_SUNWSTACK",
|
||||
"PT_SUNW_EH_FRAME",
|
||||
"PT_TLS",
|
||||
"Prog",
|
||||
"Prog32",
|
||||
|
@ -2445,6 +2554,9 @@ var stdlib = map[string][]string{
|
|||
"SectionHeader",
|
||||
"Sym",
|
||||
},
|
||||
"embed": []string{
|
||||
"FS",
|
||||
},
|
||||
"encoding": []string{
|
||||
"BinaryMarshaler",
|
||||
"BinaryUnmarshaler",
|
||||
|
@ -2680,6 +2792,7 @@ var stdlib = map[string][]string{
|
|||
"FlagSet",
|
||||
"Float64",
|
||||
"Float64Var",
|
||||
"Func",
|
||||
"Getter",
|
||||
"Int",
|
||||
"Int64",
|
||||
|
@ -2853,6 +2966,18 @@ var stdlib = map[string][]string{
|
|||
"Package",
|
||||
"ToolDir",
|
||||
},
|
||||
"go/build/constraint": []string{
|
||||
"AndExpr",
|
||||
"Expr",
|
||||
"IsGoBuild",
|
||||
"IsPlusBuild",
|
||||
"NotExpr",
|
||||
"OrExpr",
|
||||
"Parse",
|
||||
"PlusBuildLines",
|
||||
"SyntaxError",
|
||||
"TagExpr",
|
||||
},
|
||||
"go/constant": []string{
|
||||
"BinaryOp",
|
||||
"BitLen",
|
||||
|
@ -3273,6 +3398,7 @@ var stdlib = map[string][]string{
|
|||
"Must",
|
||||
"New",
|
||||
"OK",
|
||||
"ParseFS",
|
||||
"ParseFiles",
|
||||
"ParseGlob",
|
||||
"Srcset",
|
||||
|
@ -3432,6 +3558,7 @@ var stdlib = map[string][]string{
|
|||
"Copy",
|
||||
"CopyBuffer",
|
||||
"CopyN",
|
||||
"Discard",
|
||||
"EOF",
|
||||
"ErrClosedPipe",
|
||||
"ErrNoProgress",
|
||||
|
@ -3443,12 +3570,15 @@ var stdlib = map[string][]string{
|
|||
"MultiReader",
|
||||
"MultiWriter",
|
||||
"NewSectionReader",
|
||||
"NopCloser",
|
||||
"Pipe",
|
||||
"PipeReader",
|
||||
"PipeWriter",
|
||||
"ReadAll",
|
||||
"ReadAtLeast",
|
||||
"ReadCloser",
|
||||
"ReadFull",
|
||||
"ReadSeekCloser",
|
||||
"ReadSeeker",
|
||||
"ReadWriteCloser",
|
||||
"ReadWriteSeeker",
|
||||
|
@ -3472,6 +3602,49 @@ var stdlib = map[string][]string{
|
|||
"WriterAt",
|
||||
"WriterTo",
|
||||
},
|
||||
"io/fs": []string{
|
||||
"DirEntry",
|
||||
"ErrClosed",
|
||||
"ErrExist",
|
||||
"ErrInvalid",
|
||||
"ErrNotExist",
|
||||
"ErrPermission",
|
||||
"FS",
|
||||
"File",
|
||||
"FileInfo",
|
||||
"FileMode",
|
||||
"Glob",
|
||||
"GlobFS",
|
||||
"ModeAppend",
|
||||
"ModeCharDevice",
|
||||
"ModeDevice",
|
||||
"ModeDir",
|
||||
"ModeExclusive",
|
||||
"ModeIrregular",
|
||||
"ModeNamedPipe",
|
||||
"ModePerm",
|
||||
"ModeSetgid",
|
||||
"ModeSetuid",
|
||||
"ModeSocket",
|
||||
"ModeSticky",
|
||||
"ModeSymlink",
|
||||
"ModeTemporary",
|
||||
"ModeType",
|
||||
"PathError",
|
||||
"ReadDir",
|
||||
"ReadDirFS",
|
||||
"ReadDirFile",
|
||||
"ReadFile",
|
||||
"ReadFileFS",
|
||||
"SkipDir",
|
||||
"Stat",
|
||||
"StatFS",
|
||||
"Sub",
|
||||
"SubFS",
|
||||
"ValidPath",
|
||||
"WalkDir",
|
||||
"WalkDirFunc",
|
||||
},
|
||||
"io/ioutil": []string{
|
||||
"Discard",
|
||||
"NopCloser",
|
||||
|
@ -3483,6 +3656,7 @@ var stdlib = map[string][]string{
|
|||
"WriteFile",
|
||||
},
|
||||
"log": []string{
|
||||
"Default",
|
||||
"Fatal",
|
||||
"Fatalf",
|
||||
"Fatalln",
|
||||
|
@ -3819,6 +3993,7 @@ var stdlib = map[string][]string{
|
|||
"DialUDP",
|
||||
"DialUnix",
|
||||
"Dialer",
|
||||
"ErrClosed",
|
||||
"ErrWriteToConnected",
|
||||
"Error",
|
||||
"FileConn",
|
||||
|
@ -3938,6 +4113,7 @@ var stdlib = map[string][]string{
|
|||
"ErrUseLastResponse",
|
||||
"ErrWriteAfterFlush",
|
||||
"Error",
|
||||
"FS",
|
||||
"File",
|
||||
"FileServer",
|
||||
"FileSystem",
|
||||
|
@ -4234,7 +4410,10 @@ var stdlib = map[string][]string{
|
|||
"Chtimes",
|
||||
"Clearenv",
|
||||
"Create",
|
||||
"CreateTemp",
|
||||
"DevNull",
|
||||
"DirEntry",
|
||||
"DirFS",
|
||||
"Environ",
|
||||
"ErrClosed",
|
||||
"ErrDeadlineExceeded",
|
||||
|
@ -4243,6 +4422,7 @@ var stdlib = map[string][]string{
|
|||
"ErrNoDeadline",
|
||||
"ErrNotExist",
|
||||
"ErrPermission",
|
||||
"ErrProcessDone",
|
||||
"Executable",
|
||||
"Exit",
|
||||
"Expand",
|
||||
|
@ -4276,6 +4456,7 @@ var stdlib = map[string][]string{
|
|||
"Lstat",
|
||||
"Mkdir",
|
||||
"MkdirAll",
|
||||
"MkdirTemp",
|
||||
"ModeAppend",
|
||||
"ModeCharDevice",
|
||||
"ModeDevice",
|
||||
|
@ -4310,6 +4491,8 @@ var stdlib = map[string][]string{
|
|||
"ProcAttr",
|
||||
"Process",
|
||||
"ProcessState",
|
||||
"ReadDir",
|
||||
"ReadFile",
|
||||
"Readlink",
|
||||
"Remove",
|
||||
"RemoveAll",
|
||||
|
@ -4333,6 +4516,7 @@ var stdlib = map[string][]string{
|
|||
"UserCacheDir",
|
||||
"UserConfigDir",
|
||||
"UserHomeDir",
|
||||
"WriteFile",
|
||||
},
|
||||
"os/exec": []string{
|
||||
"Cmd",
|
||||
|
@ -4347,6 +4531,7 @@ var stdlib = map[string][]string{
|
|||
"Ignore",
|
||||
"Ignored",
|
||||
"Notify",
|
||||
"NotifyContext",
|
||||
"Reset",
|
||||
"Stop",
|
||||
},
|
||||
|
@ -4397,6 +4582,7 @@ var stdlib = map[string][]string{
|
|||
"ToSlash",
|
||||
"VolumeName",
|
||||
"Walk",
|
||||
"WalkDir",
|
||||
"WalkFunc",
|
||||
},
|
||||
"plugin": []string{
|
||||
|
@ -4629,6 +4815,19 @@ var stdlib = map[string][]string{
|
|||
"Stack",
|
||||
"WriteHeapDump",
|
||||
},
|
||||
"runtime/metrics": []string{
|
||||
"All",
|
||||
"Description",
|
||||
"Float64Histogram",
|
||||
"KindBad",
|
||||
"KindFloat64",
|
||||
"KindFloat64Histogram",
|
||||
"KindUint64",
|
||||
"Read",
|
||||
"Sample",
|
||||
"Value",
|
||||
"ValueKind",
|
||||
},
|
||||
"runtime/pprof": []string{
|
||||
"Do",
|
||||
"ForLabels",
|
||||
|
@ -5012,6 +5211,8 @@ var stdlib = map[string][]string{
|
|||
"AddrinfoW",
|
||||
"Adjtime",
|
||||
"Adjtimex",
|
||||
"AllThreadsSyscall",
|
||||
"AllThreadsSyscall6",
|
||||
"AttachLsf",
|
||||
"B0",
|
||||
"B1000000",
|
||||
|
@ -10010,13 +10211,20 @@ var stdlib = map[string][]string{
|
|||
"TB",
|
||||
"Verbose",
|
||||
},
|
||||
"testing/fstest": []string{
|
||||
"MapFS",
|
||||
"MapFile",
|
||||
"TestFS",
|
||||
},
|
||||
"testing/iotest": []string{
|
||||
"DataErrReader",
|
||||
"ErrReader",
|
||||
"ErrTimeout",
|
||||
"HalfReader",
|
||||
"NewReadLogger",
|
||||
"NewWriteLogger",
|
||||
"OneByteReader",
|
||||
"TestReader",
|
||||
"TimeoutReader",
|
||||
"TruncateWriter",
|
||||
},
|
||||
|
@ -10076,6 +10284,7 @@ var stdlib = map[string][]string{
|
|||
"JSEscaper",
|
||||
"Must",
|
||||
"New",
|
||||
"ParseFS",
|
||||
"ParseFiles",
|
||||
"ParseGlob",
|
||||
"Template",
|
||||
|
@ -10087,12 +10296,14 @@ var stdlib = map[string][]string{
|
|||
"BranchNode",
|
||||
"ChainNode",
|
||||
"CommandNode",
|
||||
"CommentNode",
|
||||
"DotNode",
|
||||
"FieldNode",
|
||||
"IdentifierNode",
|
||||
"IfNode",
|
||||
"IsEmptyTree",
|
||||
"ListNode",
|
||||
"Mode",
|
||||
"New",
|
||||
"NewIdentifier",
|
||||
"NilNode",
|
||||
|
@ -10101,6 +10312,7 @@ var stdlib = map[string][]string{
|
|||
"NodeBool",
|
||||
"NodeChain",
|
||||
"NodeCommand",
|
||||
"NodeComment",
|
||||
"NodeDot",
|
||||
"NodeField",
|
||||
"NodeIdentifier",
|
||||
|
@ -10118,6 +10330,7 @@ var stdlib = map[string][]string{
|
|||
"NodeWith",
|
||||
"NumberNode",
|
||||
"Parse",
|
||||
"ParseComments",
|
||||
"PipeNode",
|
||||
"Pos",
|
||||
"RangeNode",
|
||||
|
@ -10230,6 +10443,7 @@ var stdlib = map[string][]string{
|
|||
"Chakma",
|
||||
"Cham",
|
||||
"Cherokee",
|
||||
"Chorasmian",
|
||||
"Co",
|
||||
"Common",
|
||||
"Coptic",
|
||||
|
@ -10243,6 +10457,7 @@ var stdlib = map[string][]string{
|
|||
"Devanagari",
|
||||
"Diacritic",
|
||||
"Digit",
|
||||
"Dives_Akuru",
|
||||
"Dogra",
|
||||
"Duployan",
|
||||
"Egyptian_Hieroglyphs",
|
||||
|
@ -10300,6 +10515,7 @@ var stdlib = map[string][]string{
|
|||
"Katakana",
|
||||
"Kayah_Li",
|
||||
"Kharoshthi",
|
||||
"Khitan_Small_Script",
|
||||
"Khmer",
|
||||
"Khojki",
|
||||
"Khudawadi",
|
||||
|
@ -10472,6 +10688,7 @@ var stdlib = map[string][]string{
|
|||
"Wancho",
|
||||
"Warang_Citi",
|
||||
"White_Space",
|
||||
"Yezidi",
|
||||
"Yi",
|
||||
"Z",
|
||||
"Zanabazar_Square",
|
||||
|
|
|
@ -284,6 +284,7 @@ func (m *moduleSpec) Get() interface{} {
|
|||
|
||||
var errVmoduleSyntax = errors.New("syntax error: expect comma-separated list of filename=N")
|
||||
|
||||
// Set will sets module value
|
||||
// Syntax: -vmodule=recordio=2,file=1,gfs*=3
|
||||
func (m *moduleSpec) Set(value string) error {
|
||||
var filter []modulePat
|
||||
|
@ -362,6 +363,7 @@ func (t *traceLocation) Get() interface{} {
|
|||
|
||||
var errTraceSyntax = errors.New("syntax error: expect file.go:234")
|
||||
|
||||
// Set will sets backtrace value
|
||||
// Syntax: -log_backtrace_at=gopherflakes.go:234
|
||||
// Note that unlike vmodule the file extension is included here.
|
||||
func (t *traceLocation) Set(value string) error {
|
||||
|
@ -708,7 +710,7 @@ func (l *loggingT) println(s severity, logr logr.Logger, filter LogFilter, args
|
|||
args = filter.Filter(args)
|
||||
}
|
||||
fmt.Fprintln(buf, args...)
|
||||
l.output(s, logr, buf, file, line, false)
|
||||
l.output(s, logr, buf, 0 /* depth */, file, line, false)
|
||||
}
|
||||
|
||||
func (l *loggingT) print(s severity, logr logr.Logger, filter LogFilter, args ...interface{}) {
|
||||
|
@ -730,7 +732,7 @@ func (l *loggingT) printDepth(s severity, logr logr.Logger, filter LogFilter, de
|
|||
if buf.Bytes()[buf.Len()-1] != '\n' {
|
||||
buf.WriteByte('\n')
|
||||
}
|
||||
l.output(s, logr, buf, file, line, false)
|
||||
l.output(s, logr, buf, depth, file, line, false)
|
||||
}
|
||||
|
||||
func (l *loggingT) printf(s severity, logr logr.Logger, filter LogFilter, format string, args ...interface{}) {
|
||||
|
@ -748,7 +750,7 @@ func (l *loggingT) printf(s severity, logr logr.Logger, filter LogFilter, format
|
|||
if buf.Bytes()[buf.Len()-1] != '\n' {
|
||||
buf.WriteByte('\n')
|
||||
}
|
||||
l.output(s, logr, buf, file, line, false)
|
||||
l.output(s, logr, buf, 0 /* depth */, file, line, false)
|
||||
}
|
||||
|
||||
// printWithFileLine behaves like print but uses the provided file and line number. If
|
||||
|
@ -769,7 +771,7 @@ func (l *loggingT) printWithFileLine(s severity, logr logr.Logger, filter LogFil
|
|||
if buf.Bytes()[buf.Len()-1] != '\n' {
|
||||
buf.WriteByte('\n')
|
||||
}
|
||||
l.output(s, logr, buf, file, line, alsoToStderr)
|
||||
l.output(s, logr, buf, 2 /* depth */, file, line, alsoToStderr)
|
||||
}
|
||||
|
||||
// if loggr is specified, will call loggr.Error, otherwise output with logging module.
|
||||
|
@ -778,7 +780,7 @@ func (l *loggingT) errorS(err error, loggr logr.Logger, filter LogFilter, depth
|
|||
msg, keysAndValues = filter.FilterS(msg, keysAndValues)
|
||||
}
|
||||
if loggr != nil {
|
||||
loggr.Error(err, msg, keysAndValues...)
|
||||
logr.WithCallDepth(loggr, depth+2).Error(err, msg, keysAndValues...)
|
||||
return
|
||||
}
|
||||
l.printS(err, errorLog, depth+1, msg, keysAndValues...)
|
||||
|
@ -790,7 +792,7 @@ func (l *loggingT) infoS(loggr logr.Logger, filter LogFilter, depth int, msg str
|
|||
msg, keysAndValues = filter.FilterS(msg, keysAndValues)
|
||||
}
|
||||
if loggr != nil {
|
||||
loggr.Info(msg, keysAndValues...)
|
||||
logr.WithCallDepth(loggr, depth+2).Info(msg, keysAndValues...)
|
||||
return
|
||||
}
|
||||
l.printS(nil, infoLog, depth+1, msg, keysAndValues...)
|
||||
|
@ -825,6 +827,8 @@ func kvListFormat(b *bytes.Buffer, keysAndValues ...interface{}) {
|
|||
switch v.(type) {
|
||||
case string, error:
|
||||
b.WriteString(fmt.Sprintf("%s=%q", k, v))
|
||||
case []byte:
|
||||
b.WriteString(fmt.Sprintf("%s=%+q", k, v))
|
||||
default:
|
||||
if _, ok := v.(fmt.Stringer); ok {
|
||||
b.WriteString(fmt.Sprintf("%s=%q", k, v))
|
||||
|
@ -855,12 +859,13 @@ func (rb *redirectBuffer) Write(bytes []byte) (n int, err error) {
|
|||
// SetLogger will set the backing logr implementation for klog.
|
||||
// If set, all log lines will be suppressed from the regular Output, and
|
||||
// redirected to the logr implementation.
|
||||
// All log lines include the 'severity', 'file' and 'line' values attached as
|
||||
// structured logging values.
|
||||
// Use as:
|
||||
// ...
|
||||
// klog.SetLogger(zapr.NewLogger(zapLog))
|
||||
func SetLogger(logr logr.Logger) {
|
||||
logging.mu.Lock()
|
||||
defer logging.mu.Unlock()
|
||||
|
||||
logging.logr = logr
|
||||
}
|
||||
|
||||
|
@ -899,7 +904,7 @@ func LogToStderr(stderr bool) {
|
|||
}
|
||||
|
||||
// output writes the data to the log files and releases the buffer.
|
||||
func (l *loggingT) output(s severity, log logr.Logger, buf *buffer, file string, line int, alsoToStderr bool) {
|
||||
func (l *loggingT) output(s severity, log logr.Logger, buf *buffer, depth int, file string, line int, alsoToStderr bool) {
|
||||
l.mu.Lock()
|
||||
if l.traceLocation.isSet() {
|
||||
if l.traceLocation.match(file, line) {
|
||||
|
@ -911,9 +916,9 @@ func (l *loggingT) output(s severity, log logr.Logger, buf *buffer, file string,
|
|||
// TODO: set 'severity' and caller information as structured log info
|
||||
// keysAndValues := []interface{}{"severity", severityName[s], "file", file, "line", line}
|
||||
if s == errorLog {
|
||||
l.logr.Error(nil, string(data))
|
||||
logr.WithCallDepth(l.logr, depth+3).Error(nil, string(data))
|
||||
} else {
|
||||
log.Info(string(data))
|
||||
logr.WithCallDepth(log, depth+3).Info(string(data))
|
||||
}
|
||||
} else if l.toStderr {
|
||||
os.Stderr.Write(data)
|
||||
|
|
|
@ -54,7 +54,7 @@ github.com/gogo/protobuf/gogoproto
|
|||
github.com/gogo/protobuf/proto
|
||||
github.com/gogo/protobuf/protoc-gen-gogo/descriptor
|
||||
github.com/gogo/protobuf/sortkeys
|
||||
# github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e
|
||||
# github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da
|
||||
github.com/golang/groupcache/lru
|
||||
# github.com/golang/protobuf v1.5.2
|
||||
github.com/golang/protobuf/proto
|
||||
|
@ -62,14 +62,15 @@ github.com/golang/protobuf/ptypes
|
|||
github.com/golang/protobuf/ptypes/any
|
||||
github.com/golang/protobuf/ptypes/duration
|
||||
github.com/golang/protobuf/ptypes/timestamp
|
||||
# github.com/google/go-cmp v0.5.5
|
||||
# github.com/google/go-cmp v0.5.6
|
||||
github.com/google/go-cmp/cmp
|
||||
github.com/google/go-cmp/cmp/internal/diff
|
||||
github.com/google/go-cmp/cmp/internal/flags
|
||||
github.com/google/go-cmp/cmp/internal/function
|
||||
github.com/google/go-cmp/cmp/internal/value
|
||||
# github.com/google/gofuzz v1.1.0
|
||||
# github.com/google/gofuzz v1.2.0
|
||||
github.com/google/gofuzz
|
||||
github.com/google/gofuzz/bytesource
|
||||
# github.com/google/uuid v1.1.2
|
||||
## explicit
|
||||
github.com/google/uuid
|
||||
|
@ -160,7 +161,7 @@ github.com/onsi/gomega/matchers/support/goraph/util
|
|||
github.com/onsi/gomega/types
|
||||
# github.com/opencontainers/go-digest v1.0.0
|
||||
github.com/opencontainers/go-digest
|
||||
# github.com/pelletier/go-toml v1.8.1
|
||||
# github.com/pelletier/go-toml v1.9.3
|
||||
github.com/pelletier/go-toml
|
||||
# github.com/pkg/errors v0.9.1
|
||||
github.com/pkg/errors
|
||||
|
@ -183,7 +184,7 @@ github.com/prometheus/procfs/internal/fs
|
|||
github.com/prometheus/procfs/internal/util
|
||||
# github.com/rogpeppe/go-internal v1.6.1
|
||||
github.com/rogpeppe/go-internal/fmtsort
|
||||
# github.com/spf13/cobra v1.1.1
|
||||
# github.com/spf13/cobra v1.1.3
|
||||
## explicit
|
||||
github.com/spf13/cobra
|
||||
# github.com/spf13/pflag v1.0.5
|
||||
|
@ -223,7 +224,7 @@ go.uber.org/zap/internal/bufferpool
|
|||
go.uber.org/zap/internal/color
|
||||
go.uber.org/zap/internal/exit
|
||||
go.uber.org/zap/zapcore
|
||||
# golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449
|
||||
# golang.org/x/mod v0.4.2
|
||||
golang.org/x/mod/module
|
||||
golang.org/x/mod/semver
|
||||
# golang.org/x/net v0.0.0-20210428140749-89ef3d95e781
|
||||
|
@ -239,10 +240,10 @@ golang.org/x/net/idna
|
|||
golang.org/x/net/internal/timeseries
|
||||
golang.org/x/net/trace
|
||||
golang.org/x/net/websocket
|
||||
# golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
|
||||
# golang.org/x/oauth2 v0.0.0-20210615190721-d04028783cf1
|
||||
golang.org/x/oauth2
|
||||
golang.org/x/oauth2/internal
|
||||
# golang.org/x/sync v0.0.0-20201207232520-09787c993a3a
|
||||
# golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
|
||||
golang.org/x/sync/singleflight
|
||||
# golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c
|
||||
golang.org/x/sys/execabs
|
||||
|
@ -276,7 +277,7 @@ golang.org/x/text/unicode/norm
|
|||
golang.org/x/text/width
|
||||
# golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac
|
||||
golang.org/x/time/rate
|
||||
# golang.org/x/tools v0.1.0
|
||||
# golang.org/x/tools v0.1.2
|
||||
golang.org/x/tools/go/ast/astutil
|
||||
golang.org/x/tools/go/ast/inspector
|
||||
golang.org/x/tools/imports
|
||||
|
@ -301,9 +302,9 @@ google.golang.org/appengine/internal/log
|
|||
google.golang.org/appengine/internal/remote_api
|
||||
google.golang.org/appengine/internal/urlfetch
|
||||
google.golang.org/appengine/urlfetch
|
||||
# google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a
|
||||
# google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c
|
||||
google.golang.org/genproto/googleapis/rpc/status
|
||||
# google.golang.org/grpc v1.27.1
|
||||
# google.golang.org/grpc v1.38.0 => google.golang.org/grpc v1.27.1
|
||||
google.golang.org/grpc
|
||||
google.golang.org/grpc/attributes
|
||||
google.golang.org/grpc/backoff
|
||||
|
@ -882,7 +883,7 @@ k8s.io/gengo/generator
|
|||
k8s.io/gengo/namer
|
||||
k8s.io/gengo/parser
|
||||
k8s.io/gengo/types
|
||||
# k8s.io/klog/v2 v2.8.0
|
||||
# k8s.io/klog/v2 v2.9.0
|
||||
## explicit
|
||||
k8s.io/klog/v2
|
||||
# k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7
|
||||
|
@ -917,6 +918,11 @@ k8s.io/utils/trace
|
|||
# sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.19
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client
|
||||
# sigs.k8s.io/cluster-api v0.4.0
|
||||
## explicit
|
||||
sigs.k8s.io/cluster-api/api/v1alpha4
|
||||
sigs.k8s.io/cluster-api/errors
|
||||
sigs.k8s.io/cluster-api/util/version
|
||||
# sigs.k8s.io/controller-runtime v0.9.5
|
||||
## explicit
|
||||
sigs.k8s.io/controller-runtime
|
||||
|
@ -1008,6 +1014,7 @@ sigs.k8s.io/structured-merge-diff/v4/value
|
|||
# sigs.k8s.io/yaml v1.2.0
|
||||
sigs.k8s.io/yaml
|
||||
# github.com/googleapis/gnostic => github.com/googleapis/gnostic v0.4.1
|
||||
# google.golang.org/grpc => google.golang.org/grpc v1.27.1
|
||||
# k8s.io/api => k8s.io/api v0.21.3
|
||||
# k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.21.3
|
||||
# k8s.io/apimachinery => k8s.io/apimachinery v0.21.3
|
||||
|
|
|
@ -0,0 +1,201 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
55
vendor/sigs.k8s.io/cluster-api/api/v1alpha4/cluster_phase_types.go
generated
vendored
Normal file
55
vendor/sigs.k8s.io/cluster-api/api/v1alpha4/cluster_phase_types.go
generated
vendored
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha4
|
||||
|
||||
// ClusterPhase is a string representation of a Cluster Phase.
|
||||
//
|
||||
// This type is a high-level indicator of the status of the Cluster as it is provisioned,
|
||||
// from the API user’s perspective.
|
||||
//
|
||||
// The value should not be interpreted by any software components as a reliable indication
|
||||
// of the actual state of the Cluster, and controllers should not use the Cluster Phase field
|
||||
// value when making decisions about what action to take.
|
||||
//
|
||||
// Controllers should always look at the actual state of the Cluster’s fields to make those decisions.
|
||||
type ClusterPhase string
|
||||
|
||||
const (
|
||||
// ClusterPhasePending is the first state a Cluster is assigned by
|
||||
// Cluster API Cluster controller after being created.
|
||||
ClusterPhasePending = ClusterPhase("Pending")
|
||||
|
||||
// ClusterPhaseProvisioning is the state when the Cluster has a provider infrastructure
|
||||
// object associated and can start provisioning.
|
||||
ClusterPhaseProvisioning = ClusterPhase("Provisioning")
|
||||
|
||||
// ClusterPhaseProvisioned is the state when its
|
||||
// infrastructure has been created and configured.
|
||||
ClusterPhaseProvisioned = ClusterPhase("Provisioned")
|
||||
|
||||
// ClusterPhaseDeleting is the Cluster state when a delete
|
||||
// request has been sent to the API Server,
|
||||
// but its infrastructure has not yet been fully deleted.
|
||||
ClusterPhaseDeleting = ClusterPhase("Deleting")
|
||||
|
||||
// ClusterPhaseFailed is the Cluster state when the system
|
||||
// might require user intervention.
|
||||
ClusterPhaseFailed = ClusterPhase("Failed")
|
||||
|
||||
// ClusterPhaseUnknown is returned if the Cluster state cannot be determined.
|
||||
ClusterPhaseUnknown = ClusterPhase("Unknown")
|
||||
)
|
|
@ -0,0 +1,355 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha4
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/utils/pointer"
|
||||
|
||||
capierrors "sigs.k8s.io/cluster-api/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
// ClusterFinalizer is the finalizer used by the cluster controller to
|
||||
// cleanup the cluster resources when a Cluster is being deleted.
|
||||
ClusterFinalizer = "cluster.cluster.x-k8s.io"
|
||||
)
|
||||
|
||||
// ANCHOR: ClusterSpec
|
||||
|
||||
// ClusterSpec defines the desired state of Cluster.
|
||||
type ClusterSpec struct {
|
||||
// Paused can be used to prevent controllers from processing the Cluster and all its associated objects.
|
||||
// +optional
|
||||
Paused bool `json:"paused,omitempty"`
|
||||
|
||||
// Cluster network configuration.
|
||||
// +optional
|
||||
ClusterNetwork *ClusterNetwork `json:"clusterNetwork,omitempty"`
|
||||
|
||||
// ControlPlaneEndpoint represents the endpoint used to communicate with the control plane.
|
||||
// +optional
|
||||
ControlPlaneEndpoint APIEndpoint `json:"controlPlaneEndpoint"`
|
||||
|
||||
// ControlPlaneRef is an optional reference to a provider-specific resource that holds
|
||||
// the details for provisioning the Control Plane for a Cluster.
|
||||
// +optional
|
||||
ControlPlaneRef *corev1.ObjectReference `json:"controlPlaneRef,omitempty"`
|
||||
|
||||
// InfrastructureRef is a reference to a provider-specific resource that holds the details
|
||||
// for provisioning infrastructure for a cluster in said provider.
|
||||
// +optional
|
||||
InfrastructureRef *corev1.ObjectReference `json:"infrastructureRef,omitempty"`
|
||||
}
|
||||
|
||||
// ANCHOR_END: ClusterSpec
|
||||
|
||||
// ANCHOR: ClusterNetwork
|
||||
|
||||
// ClusterNetwork specifies the different networking
|
||||
// parameters for a cluster.
|
||||
type ClusterNetwork struct {
|
||||
// APIServerPort specifies the port the API Server should bind to.
|
||||
// Defaults to 6443.
|
||||
// +optional
|
||||
APIServerPort *int32 `json:"apiServerPort,omitempty"`
|
||||
|
||||
// The network ranges from which service VIPs are allocated.
|
||||
// +optional
|
||||
Services *NetworkRanges `json:"services,omitempty"`
|
||||
|
||||
// The network ranges from which Pod networks are allocated.
|
||||
// +optional
|
||||
Pods *NetworkRanges `json:"pods,omitempty"`
|
||||
|
||||
// Domain name for services.
|
||||
// +optional
|
||||
ServiceDomain string `json:"serviceDomain,omitempty"`
|
||||
}
|
||||
|
||||
// ANCHOR_END: ClusterNetwork
|
||||
|
||||
// ANCHOR: NetworkRanges
|
||||
|
||||
// NetworkRanges represents ranges of network addresses.
|
||||
type NetworkRanges struct {
|
||||
CIDRBlocks []string `json:"cidrBlocks"`
|
||||
}
|
||||
|
||||
func (n *NetworkRanges) String() string {
|
||||
if n == nil {
|
||||
return ""
|
||||
}
|
||||
return strings.Join(n.CIDRBlocks, ",")
|
||||
}
|
||||
|
||||
// ANCHOR_END: NetworkRanges
|
||||
|
||||
// ANCHOR: ClusterStatus
|
||||
|
||||
// ClusterStatus defines the observed state of Cluster.
|
||||
type ClusterStatus struct {
|
||||
// FailureDomains is a slice of failure domain objects synced from the infrastructure provider.
|
||||
FailureDomains FailureDomains `json:"failureDomains,omitempty"`
|
||||
|
||||
// FailureReason indicates that there is a fatal problem reconciling the
|
||||
// state, and will be set to a token value suitable for
|
||||
// programmatic interpretation.
|
||||
// +optional
|
||||
FailureReason *capierrors.ClusterStatusError `json:"failureReason,omitempty"`
|
||||
|
||||
// FailureMessage indicates that there is a fatal problem reconciling the
|
||||
// state, and will be set to a descriptive error message.
|
||||
// +optional
|
||||
FailureMessage *string `json:"failureMessage,omitempty"`
|
||||
|
||||
// Phase represents the current phase of cluster actuation.
|
||||
// E.g. Pending, Running, Terminating, Failed etc.
|
||||
// +optional
|
||||
Phase string `json:"phase,omitempty"`
|
||||
|
||||
// InfrastructureReady is the state of the infrastructure provider.
|
||||
// +optional
|
||||
InfrastructureReady bool `json:"infrastructureReady"`
|
||||
|
||||
// ControlPlaneReady defines if the control plane is ready.
|
||||
// +optional
|
||||
ControlPlaneReady bool `json:"controlPlaneReady,omitempty"`
|
||||
|
||||
// Conditions defines current service state of the cluster.
|
||||
// +optional
|
||||
Conditions Conditions `json:"conditions,omitempty"`
|
||||
|
||||
// ObservedGeneration is the latest generation observed by the controller.
|
||||
// +optional
|
||||
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
|
||||
}
|
||||
|
||||
// ANCHOR_END: ClusterStatus
|
||||
|
||||
// SetTypedPhase sets the Phase field to the string representation of ClusterPhase.
|
||||
func (c *ClusterStatus) SetTypedPhase(p ClusterPhase) {
|
||||
c.Phase = string(p)
|
||||
}
|
||||
|
||||
// GetTypedPhase attempts to parse the Phase field and return
|
||||
// the typed ClusterPhase representation as described in `machine_phase_types.go`.
|
||||
func (c *ClusterStatus) GetTypedPhase() ClusterPhase {
|
||||
switch phase := ClusterPhase(c.Phase); phase {
|
||||
case
|
||||
ClusterPhasePending,
|
||||
ClusterPhaseProvisioning,
|
||||
ClusterPhaseProvisioned,
|
||||
ClusterPhaseDeleting,
|
||||
ClusterPhaseFailed:
|
||||
return phase
|
||||
default:
|
||||
return ClusterPhaseUnknown
|
||||
}
|
||||
}
|
||||
|
||||
// ANCHOR: APIEndpoint
|
||||
|
||||
// APIEndpoint represents a reachable Kubernetes API endpoint.
|
||||
type APIEndpoint struct {
|
||||
// The hostname on which the API server is serving.
|
||||
Host string `json:"host"`
|
||||
|
||||
// The port on which the API server is serving.
|
||||
Port int32 `json:"port"`
|
||||
}
|
||||
|
||||
// IsZero returns true if both host and port are zero values.
|
||||
func (v APIEndpoint) IsZero() bool {
|
||||
return v.Host == "" && v.Port == 0
|
||||
}
|
||||
|
||||
// IsValid returns true if both host and port are non-zero values.
|
||||
func (v APIEndpoint) IsValid() bool {
|
||||
return v.Host != "" && v.Port != 0
|
||||
}
|
||||
|
||||
// String returns a formatted version HOST:PORT of this APIEndpoint.
|
||||
func (v APIEndpoint) String() string {
|
||||
return net.JoinHostPort(v.Host, fmt.Sprintf("%d", v.Port))
|
||||
}
|
||||
|
||||
// ANCHOR_END: APIEndpoint
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:resource:path=clusters,shortName=cl,scope=Namespaced,categories=cluster-api
|
||||
// +kubebuilder:storageversion
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:printcolumn:name="Phase",type="string",JSONPath=".status.phase",description="Cluster status such as Pending/Provisioning/Provisioned/Deleting/Failed"
|
||||
|
||||
// Cluster is the Schema for the clusters API.
|
||||
type Cluster struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec ClusterSpec `json:"spec,omitempty"`
|
||||
Status ClusterStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// GetConditions returns the set of conditions for this object.
|
||||
func (c *Cluster) GetConditions() Conditions {
|
||||
return c.Status.Conditions
|
||||
}
|
||||
|
||||
// SetConditions sets the conditions on this object.
|
||||
func (c *Cluster) SetConditions(conditions Conditions) {
|
||||
c.Status.Conditions = conditions
|
||||
}
|
||||
|
||||
// GetIPFamily returns a ClusterIPFamily from the configuration provided.
|
||||
func (c *Cluster) GetIPFamily() (ClusterIPFamily, error) {
|
||||
var podCIDRs, serviceCIDRs []string
|
||||
if c.Spec.ClusterNetwork != nil {
|
||||
if c.Spec.ClusterNetwork.Pods != nil {
|
||||
podCIDRs = c.Spec.ClusterNetwork.Pods.CIDRBlocks
|
||||
}
|
||||
if c.Spec.ClusterNetwork.Services != nil {
|
||||
serviceCIDRs = c.Spec.ClusterNetwork.Services.CIDRBlocks
|
||||
}
|
||||
}
|
||||
if len(podCIDRs) == 0 && len(serviceCIDRs) == 0 {
|
||||
return IPv4IPFamily, nil
|
||||
}
|
||||
|
||||
podsIPFamily, err := ipFamilyForCIDRStrings(podCIDRs)
|
||||
if err != nil {
|
||||
return InvalidIPFamily, fmt.Errorf("pods: %s", err)
|
||||
}
|
||||
if len(serviceCIDRs) == 0 {
|
||||
return podsIPFamily, nil
|
||||
}
|
||||
|
||||
servicesIPFamily, err := ipFamilyForCIDRStrings(serviceCIDRs)
|
||||
if err != nil {
|
||||
return InvalidIPFamily, fmt.Errorf("services: %s", err)
|
||||
}
|
||||
if len(podCIDRs) == 0 {
|
||||
return servicesIPFamily, nil
|
||||
}
|
||||
|
||||
if podsIPFamily == DualStackIPFamily {
|
||||
return DualStackIPFamily, nil
|
||||
} else if podsIPFamily != servicesIPFamily {
|
||||
return InvalidIPFamily, errors.New("pods and services IP family mismatch")
|
||||
}
|
||||
|
||||
return podsIPFamily, nil
|
||||
}
|
||||
|
||||
func ipFamilyForCIDRStrings(cidrs []string) (ClusterIPFamily, error) {
|
||||
if len(cidrs) > 2 {
|
||||
return InvalidIPFamily, errors.New("too many CIDRs specified")
|
||||
}
|
||||
var foundIPv4 bool
|
||||
var foundIPv6 bool
|
||||
for _, cidr := range cidrs {
|
||||
ip, _, err := net.ParseCIDR(cidr)
|
||||
if err != nil {
|
||||
return InvalidIPFamily, fmt.Errorf("could not parse CIDR: %s", err)
|
||||
}
|
||||
if ip.To4() != nil {
|
||||
foundIPv4 = true
|
||||
} else {
|
||||
foundIPv6 = true
|
||||
}
|
||||
}
|
||||
switch {
|
||||
case foundIPv4 && foundIPv6:
|
||||
return DualStackIPFamily, nil
|
||||
case foundIPv4:
|
||||
return IPv4IPFamily, nil
|
||||
case foundIPv6:
|
||||
return IPv6IPFamily, nil
|
||||
default:
|
||||
return InvalidIPFamily, nil
|
||||
}
|
||||
}
|
||||
|
||||
// ClusterIPFamily defines the types of supported IP families.
|
||||
type ClusterIPFamily int
|
||||
|
||||
// Define the ClusterIPFamily constants.
|
||||
const (
|
||||
InvalidIPFamily ClusterIPFamily = iota
|
||||
IPv4IPFamily
|
||||
IPv6IPFamily
|
||||
DualStackIPFamily
|
||||
)
|
||||
|
||||
func (f ClusterIPFamily) String() string {
|
||||
return [...]string{"InvalidIPFamily", "IPv4IPFamily", "IPv6IPFamily", "DualStackIPFamily"}[f]
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
// ClusterList contains a list of Cluster.
|
||||
type ClusterList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []Cluster `json:"items"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&Cluster{}, &ClusterList{})
|
||||
}
|
||||
|
||||
// FailureDomains is a slice of FailureDomains.
|
||||
type FailureDomains map[string]FailureDomainSpec
|
||||
|
||||
// FilterControlPlane returns a FailureDomain slice containing only the domains suitable to be used
|
||||
// for control plane nodes.
|
||||
func (in FailureDomains) FilterControlPlane() FailureDomains {
|
||||
res := make(FailureDomains)
|
||||
for id, spec := range in {
|
||||
if spec.ControlPlane {
|
||||
res[id] = spec
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// GetIDs returns a slice containing the ids for failure domains.
|
||||
func (in FailureDomains) GetIDs() []*string {
|
||||
ids := make([]*string, 0, len(in))
|
||||
for id := range in {
|
||||
ids = append(ids, pointer.StringPtr(id))
|
||||
}
|
||||
return ids
|
||||
}
|
||||
|
||||
// FailureDomainSpec is the Schema for Cluster API failure domains.
|
||||
// It allows controllers to understand how many failure domains a cluster can optionally span across.
|
||||
type FailureDomainSpec struct {
|
||||
// ControlPlane determines if this failure domain is suitable for use by control plane machines.
|
||||
// +optional
|
||||
ControlPlane bool `json:"controlPlane"`
|
||||
|
||||
// Attributes is a free form map of attributes an infrastructure provider might use or require.
|
||||
// +optional
|
||||
Attributes map[string]string `json:"attributes,omitempty"`
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha4
|
||||
|
||||
import (
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook"
|
||||
)
|
||||
|
||||
func (c *Cluster) SetupWebhookWithManager(mgr ctrl.Manager) error {
|
||||
return ctrl.NewWebhookManagedBy(mgr).
|
||||
For(c).
|
||||
Complete()
|
||||
}
|
||||
|
||||
// +kubebuilder:webhook:verbs=create;update,path=/validate-cluster-x-k8s-io-v1alpha4-cluster,mutating=false,failurePolicy=fail,matchPolicy=Equivalent,groups=cluster.x-k8s.io,resources=clusters,versions=v1alpha4,name=validation.cluster.cluster.x-k8s.io,sideEffects=None,admissionReviewVersions=v1beta1
|
||||
// +kubebuilder:webhook:verbs=create;update,path=/mutate-cluster-x-k8s-io-v1alpha4-cluster,mutating=true,failurePolicy=fail,matchPolicy=Equivalent,groups=cluster.x-k8s.io,resources=clusters,versions=v1alpha4,name=default.cluster.cluster.x-k8s.io,sideEffects=None,admissionReviewVersions=v1beta1
|
||||
|
||||
var _ webhook.Defaulter = &Cluster{}
|
||||
var _ webhook.Validator = &Cluster{}
|
||||
|
||||
// Default satisfies the defaulting webhook interface.
|
||||
func (c *Cluster) Default() {
|
||||
if c.Spec.InfrastructureRef != nil && len(c.Spec.InfrastructureRef.Namespace) == 0 {
|
||||
c.Spec.InfrastructureRef.Namespace = c.Namespace
|
||||
}
|
||||
|
||||
if c.Spec.ControlPlaneRef != nil && len(c.Spec.ControlPlaneRef.Namespace) == 0 {
|
||||
c.Spec.ControlPlaneRef.Namespace = c.Namespace
|
||||
}
|
||||
}
|
||||
|
||||
// ValidateCreate implements webhook.Validator so a webhook will be registered for the type.
|
||||
func (c *Cluster) ValidateCreate() error {
|
||||
return c.validate()
|
||||
}
|
||||
|
||||
// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type.
|
||||
func (c *Cluster) ValidateUpdate(old runtime.Object) error {
|
||||
return c.validate()
|
||||
}
|
||||
|
||||
// ValidateDelete implements webhook.Validator so a webhook will be registered for the type.
|
||||
func (c *Cluster) ValidateDelete() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Cluster) validate() error {
|
||||
var allErrs field.ErrorList
|
||||
if c.Spec.InfrastructureRef != nil && c.Spec.InfrastructureRef.Namespace != c.Namespace {
|
||||
allErrs = append(
|
||||
allErrs,
|
||||
field.Invalid(
|
||||
field.NewPath("spec", "infrastructureRef", "namespace"),
|
||||
c.Spec.InfrastructureRef.Namespace,
|
||||
"must match metadata.namespace",
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
if c.Spec.ControlPlaneRef != nil && c.Spec.ControlPlaneRef.Namespace != c.Namespace {
|
||||
allErrs = append(
|
||||
allErrs,
|
||||
field.Invalid(
|
||||
field.NewPath("spec", "controlPlaneRef", "namespace"),
|
||||
c.Spec.ControlPlaneRef.Namespace,
|
||||
"must match metadata.namespace",
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
if len(allErrs) == 0 {
|
||||
return nil
|
||||
}
|
||||
return apierrors.NewInvalid(GroupVersion.WithKind("Cluster").GroupKind(), c.Name, allErrs)
|
||||
}
|
|
@ -0,0 +1,166 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha4
|
||||
|
||||
import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
const (
|
||||
// ClusterLabelName is the label set on machines linked to a cluster and
|
||||
// external objects(bootstrap and infrastructure providers).
|
||||
ClusterLabelName = "cluster.x-k8s.io/cluster-name"
|
||||
|
||||
// ProviderLabelName is the label set on components in the provider manifest.
|
||||
// This label allows to easily identify all the components belonging to a provider; the clusterctl
|
||||
// tool uses this label for implementing provider's lifecycle operations.
|
||||
ProviderLabelName = "cluster.x-k8s.io/provider"
|
||||
|
||||
// ClusterNameAnnotation is the annotation set on nodes identifying the name of the cluster the node belongs to.
|
||||
ClusterNameAnnotation = "cluster.x-k8s.io/cluster-name"
|
||||
|
||||
// ClusterNamespaceAnnotation is the annotation set on nodes identifying the namespace of the cluster the node belongs to.
|
||||
ClusterNamespaceAnnotation = "cluster.x-k8s.io/cluster-namespace"
|
||||
|
||||
// MachineAnnotation is the annotation set on nodes identifying the machine the node belongs to.
|
||||
MachineAnnotation = "cluster.x-k8s.io/machine"
|
||||
|
||||
// OwnerKindAnnotation is the annotation set on nodes identifying the owner kind.
|
||||
OwnerKindAnnotation = "cluster.x-k8s.io/owner-kind"
|
||||
|
||||
// OwnerNameAnnotation is the annotation set on nodes identifying the owner name.
|
||||
OwnerNameAnnotation = "cluster.x-k8s.io/owner-name"
|
||||
|
||||
// PausedAnnotation is an annotation that can be applied to any Cluster API
|
||||
// object to prevent a controller from processing a resource.
|
||||
//
|
||||
// Controllers working with Cluster API objects must check the existence of this annotation
|
||||
// on the reconciled object.
|
||||
PausedAnnotation = "cluster.x-k8s.io/paused"
|
||||
|
||||
// DisableMachineCreate is an annotation that can be used to signal a MachineSet to stop creating new machines.
|
||||
// It is utilized in the OnDelete MachineDeploymentStrategy to allow the MachineDeployment controller to scale down
|
||||
// older MachineSets when Machines are deleted and add the new replicas to the latest MachineSet.
|
||||
DisableMachineCreate = "cluster.x-k8s.io/disable-machine-create"
|
||||
|
||||
// WatchLabel is a label othat can be applied to any Cluster API object.
|
||||
//
|
||||
// Controllers which allow for selective reconciliation may check this label and proceed
|
||||
// with reconciliation of the object only if this label and a configured value is present.
|
||||
WatchLabel = "cluster.x-k8s.io/watch-filter"
|
||||
|
||||
// DeleteMachineAnnotation marks control plane and worker nodes that will be given priority for deletion
|
||||
// when KCP or a machineset scales down. This annotation is given top priority on all delete policies.
|
||||
DeleteMachineAnnotation = "cluster.x-k8s.io/delete-machine"
|
||||
|
||||
// TemplateClonedFromNameAnnotation is the infrastructure machine annotation that stores the name of the infrastructure template resource
|
||||
// that was cloned for the machine. This annotation is set only during cloning a template. Older/adopted machines will not have this annotation.
|
||||
TemplateClonedFromNameAnnotation = "cluster.x-k8s.io/cloned-from-name"
|
||||
|
||||
// TemplateClonedFromGroupKindAnnotation is the infrastructure machine annotation that stores the group-kind of the infrastructure template resource
|
||||
// that was cloned for the machine. This annotation is set only during cloning a template. Older/adopted machines will not have this annotation.
|
||||
TemplateClonedFromGroupKindAnnotation = "cluster.x-k8s.io/cloned-from-groupkind"
|
||||
|
||||
// MachineSkipRemediationAnnotation is the annotation used to mark the machines that should not be considered for remediation by MachineHealthCheck reconciler.
|
||||
MachineSkipRemediationAnnotation = "cluster.x-k8s.io/skip-remediation"
|
||||
|
||||
// ClusterSecretType defines the type of secret created by core components.
|
||||
ClusterSecretType corev1.SecretType = "cluster.x-k8s.io/secret" //nolint:gosec
|
||||
|
||||
// InterruptibleLabel is the label used to mark the nodes that run on interruptible instances.
|
||||
InterruptibleLabel = "cluster.x-k8s.io/interruptible"
|
||||
|
||||
// ManagedByAnnotation is an annotation that can be applied to InfraCluster resources to signify that
|
||||
// some external system is managing the cluster infrastructure.
|
||||
//
|
||||
// Provider InfraCluster controllers will ignore resources with this annotation.
|
||||
// An external controller must fulfill the contract of the InfraCluster resource.
|
||||
// External infrastructure providers should ensure that the annotation, once set, cannot be removed.
|
||||
ManagedByAnnotation = "cluster.x-k8s.io/managed-by"
|
||||
)
|
||||
|
||||
var (
|
||||
// ZeroDuration is a zero value of the metav1.Duration type.
|
||||
ZeroDuration = metav1.Duration{}
|
||||
)
|
||||
|
||||
const (
|
||||
// MachineNodeNameIndex is used by the Machine Controller to index Machines by Node name, and add a watch on Nodes.
|
||||
MachineNodeNameIndex = "status.nodeRef.name"
|
||||
)
|
||||
|
||||
// MachineAddressType describes a valid MachineAddress type.
|
||||
type MachineAddressType string
|
||||
|
||||
// Define the MachineAddressType constants.
|
||||
const (
|
||||
MachineHostName MachineAddressType = "Hostname"
|
||||
MachineExternalIP MachineAddressType = "ExternalIP"
|
||||
MachineInternalIP MachineAddressType = "InternalIP"
|
||||
MachineExternalDNS MachineAddressType = "ExternalDNS"
|
||||
MachineInternalDNS MachineAddressType = "InternalDNS"
|
||||
)
|
||||
|
||||
// MachineAddress contains information for the node's address.
|
||||
type MachineAddress struct {
|
||||
// Machine address type, one of Hostname, ExternalIP or InternalIP.
|
||||
Type MachineAddressType `json:"type"`
|
||||
|
||||
// The machine address.
|
||||
Address string `json:"address"`
|
||||
}
|
||||
|
||||
// MachineAddresses is a slice of MachineAddress items to be used by infrastructure providers.
|
||||
type MachineAddresses []MachineAddress
|
||||
|
||||
// ObjectMeta is metadata that all persisted resources must have, which includes all objects
|
||||
// users must create. This is a copy of customizable fields from metav1.ObjectMeta.
|
||||
//
|
||||
// ObjectMeta is embedded in `Machine.Spec`, `MachineDeployment.Template` and `MachineSet.Template`,
|
||||
// which are not top-level Kubernetes objects. Given that metav1.ObjectMeta has lots of special cases
|
||||
// and read-only fields which end up in the generated CRD validation, having it as a subset simplifies
|
||||
// the API and some issues that can impact user experience.
|
||||
//
|
||||
// During the [upgrade to controller-tools@v2](https://github.com/kubernetes-sigs/cluster-api/pull/1054)
|
||||
// for v1alpha2, we noticed a failure would occur running Cluster API test suite against the new CRDs,
|
||||
// specifically `spec.metadata.creationTimestamp in body must be of type string: "null"`.
|
||||
// The investigation showed that `controller-tools@v2` behaves differently than its previous version
|
||||
// when handling types from [metav1](k8s.io/apimachinery/pkg/apis/meta/v1) package.
|
||||
//
|
||||
// In more details, we found that embedded (non-top level) types that embedded `metav1.ObjectMeta`
|
||||
// had validation properties, including for `creationTimestamp` (metav1.Time).
|
||||
// The `metav1.Time` type specifies a custom json marshaller that, when IsZero() is true, returns `null`
|
||||
// which breaks validation because the field isn't marked as nullable.
|
||||
//
|
||||
// In future versions, controller-tools@v2 might allow overriding the type and validation for embedded
|
||||
// types. When that happens, this hack should be revisited.
|
||||
type ObjectMeta struct {
|
||||
// Map of string keys and values that can be used to organize and categorize
|
||||
// (scope and select) objects. May match selectors of replication controllers
|
||||
// and services.
|
||||
// More info: http://kubernetes.io/docs/user-guide/labels
|
||||
// +optional
|
||||
Labels map[string]string `json:"labels,omitempty"`
|
||||
|
||||
// Annotations is an unstructured key value map stored with a resource that may be
|
||||
// set by external tools to store and retrieve arbitrary metadata. They are not
|
||||
// queryable and should be preserved when modifying objects.
|
||||
// More info: http://kubernetes.io/docs/user-guide/annotations
|
||||
// +optional
|
||||
Annotations map[string]string `json:"annotations,omitempty"`
|
||||
}
|
|
@ -0,0 +1,203 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha4
|
||||
|
||||
// ANCHOR: CommonConditions
|
||||
|
||||
// Common ConditionTypes used by Cluster API objects.
|
||||
const (
|
||||
// ReadyCondition defines the Ready condition type that summarizes the operational state of a Cluster API object.
|
||||
ReadyCondition ConditionType = "Ready"
|
||||
)
|
||||
|
||||
// Common ConditionReason used by Cluster API objects.
|
||||
const (
|
||||
// DeletingReason (Severity=Info) documents an condition not in Status=True because the underlying object it is currently being deleted.
|
||||
DeletingReason = "Deleting"
|
||||
|
||||
// DeletionFailedReason (Severity=Warning) documents an condition not in Status=True because the underlying object
|
||||
// encountered problems during deletion. This is a warning because the reconciler will retry deletion.
|
||||
DeletionFailedReason = "DeletionFailed"
|
||||
|
||||
// DeletedReason (Severity=Info) documents an condition not in Status=True because the underlying object was deleted.
|
||||
DeletedReason = "Deleted"
|
||||
|
||||
// IncorrectExternalRefReason (Severity=Error) documents a CAPI object with an incorrect external object reference.
|
||||
IncorrectExternalRefReason = "IncorrectExternalRef"
|
||||
)
|
||||
|
||||
const (
|
||||
// InfrastructureReadyCondition reports a summary of current status of the infrastructure object defined for this cluster/machine/machinepool.
|
||||
// This condition is mirrored from the Ready condition in the infrastructure ref object, and
|
||||
// the absence of this condition might signal problems in the reconcile external loops or the fact that
|
||||
// the infrastructure provider does not implement the Ready condition yet.
|
||||
InfrastructureReadyCondition ConditionType = "InfrastructureReady"
|
||||
|
||||
// WaitingForInfrastructureFallbackReason (Severity=Info) documents a cluster/machine/machinepool waiting for the underlying infrastructure
|
||||
// to be available.
|
||||
// NOTE: This reason is used only as a fallback when the infrastructure object is not reporting its own ready condition.
|
||||
WaitingForInfrastructureFallbackReason = "WaitingForInfrastructure"
|
||||
)
|
||||
|
||||
// ANCHOR_END: CommonConditions
|
||||
|
||||
// Conditions and condition Reasons for the Cluster object
|
||||
|
||||
const (
|
||||
// ControlPlaneInitializedCondition reports if the cluster's control plane has been initialized such that the
|
||||
// cluster's apiserver is reachable and at least one control plane Machine has a node reference. Once this
|
||||
// condition is marked true, its value is never changed. See the ControlPlaneReady condition for an indication of
|
||||
// the current readiness of the cluster's control plane.
|
||||
ControlPlaneInitializedCondition ConditionType = "ControlPlaneInitialized"
|
||||
|
||||
// MissingNodeRefReason (Severity=Info) documents a cluster waiting for at least one control plane Machine to have
|
||||
// its node reference populated.
|
||||
MissingNodeRefReason = "MissingNodeRef"
|
||||
|
||||
// WaitingForControlPlaneProviderInitializedReason (Severity=Info) documents a cluster waiting for the control plane
|
||||
// provider to report successful control plane initialization.
|
||||
WaitingForControlPlaneProviderInitializedReason = "WaitingForControlPlaneProviderInitialized"
|
||||
|
||||
// ControlPlaneReadyCondition reports the ready condition from the control plane object defined for this cluster.
|
||||
// This condition is mirrored from the Ready condition in the control plane ref object, and
|
||||
// the absence of this condition might signal problems in the reconcile external loops or the fact that
|
||||
// the control plane provider does not not implements the Ready condition yet.
|
||||
ControlPlaneReadyCondition ConditionType = "ControlPlaneReady"
|
||||
|
||||
// WaitingForControlPlaneFallbackReason (Severity=Info) documents a cluster waiting for the control plane
|
||||
// to be available.
|
||||
// NOTE: This reason is used only as a fallback when the control plane object is not reporting its own ready condition.
|
||||
WaitingForControlPlaneFallbackReason = "WaitingForControlPlane"
|
||||
|
||||
// WaitingForControlPlaneAvailableReason (Severity=Info) documents a Cluster API object
|
||||
// waiting for the control plane machine to be available.
|
||||
//
|
||||
// NOTE: Having the control plane machine available is a pre-condition for joining additional control planes
|
||||
// or workers nodes.
|
||||
WaitingForControlPlaneAvailableReason = "WaitingForControlPlaneAvailable"
|
||||
)
|
||||
|
||||
// Conditions and condition Reasons for the Machine object
|
||||
|
||||
const (
|
||||
// BootstrapReadyCondition reports a summary of current status of the bootstrap object defined for this machine.
|
||||
// This condition is mirrored from the Ready condition in the bootstrap ref object, and
|
||||
// the absence of this condition might signal problems in the reconcile external loops or the fact that
|
||||
// the bootstrap provider does not implement the Ready condition yet.
|
||||
BootstrapReadyCondition ConditionType = "BootstrapReady"
|
||||
|
||||
// WaitingForDataSecretFallbackReason (Severity=Info) documents a machine waiting for the bootstrap data secret
|
||||
// to be available.
|
||||
// NOTE: This reason is used only as a fallback when the bootstrap object is not reporting its own ready condition.
|
||||
WaitingForDataSecretFallbackReason = "WaitingForDataSecret"
|
||||
|
||||
// DrainingSucceededCondition provide evidence of the status of the node drain operation which happens during the machine
|
||||
// deletion process.
|
||||
DrainingSucceededCondition ConditionType = "DrainingSucceeded"
|
||||
|
||||
// DrainingReason (Severity=Info) documents a machine node being drained.
|
||||
DrainingReason = "Draining"
|
||||
|
||||
// DrainingFailedReason (Severity=Warning) documents a machine node drain operation failed.
|
||||
DrainingFailedReason = "DrainingFailed"
|
||||
|
||||
// PreDrainDeleteHookSucceededCondition reports a machine waiting for a PreDrainDeleteHook before being delete.
|
||||
PreDrainDeleteHookSucceededCondition ConditionType = "PreDrainDeleteHookSucceeded"
|
||||
|
||||
// PreTerminateDeleteHookSucceededCondition reports a machine waiting for a PreDrainDeleteHook before being delete.
|
||||
PreTerminateDeleteHookSucceededCondition ConditionType = "PreTerminateDeleteHookSucceeded"
|
||||
|
||||
// WaitingExternalHookReason (Severity=Info) provide evidence that we are waiting for an external hook to complete.
|
||||
WaitingExternalHookReason = "WaitingExternalHook"
|
||||
)
|
||||
|
||||
const (
|
||||
// MachineHealthCheckSuccededCondition is set on machines that have passed a healthcheck by the MachineHealthCheck controller.
|
||||
// In the event that the health check fails it will be set to False.
|
||||
MachineHealthCheckSuccededCondition ConditionType = "HealthCheckSucceeded"
|
||||
|
||||
// MachineHasFailureReason is the reason used when a machine has either a FailureReason or a FailureMessage set on its status.
|
||||
MachineHasFailureReason = "MachineHasFailure"
|
||||
|
||||
// NodeStartupTimeoutReason is the reason used when a machine's node does not appear within the specified timeout.
|
||||
NodeStartupTimeoutReason = "NodeStartupTimeout"
|
||||
|
||||
// UnhealthyNodeConditionReason is the reason used when a machine's node has one of the MachineHealthCheck's unhealthy conditions.
|
||||
UnhealthyNodeConditionReason = "UnhealthyNode"
|
||||
)
|
||||
|
||||
const (
|
||||
// MachineOwnerRemediatedCondition is set on machines that have failed a healthcheck by the MachineHealthCheck controller.
|
||||
// MachineOwnerRemediatedCondition is set to False after a health check fails, but should be changed to True by the owning controller after remediation succeeds.
|
||||
MachineOwnerRemediatedCondition ConditionType = "OwnerRemediated"
|
||||
|
||||
// WaitingForRemediationReason is the reason used when a machine fails a health check and remediation is needed.
|
||||
WaitingForRemediationReason = "WaitingForRemediation"
|
||||
|
||||
// RemediationFailedReason is the reason used when a remediation owner fails to remediate an unhealthy machine.
|
||||
RemediationFailedReason = "RemediationFailed"
|
||||
|
||||
// RemediationInProgressReason is the reason used when an unhealthy machine is being remediated by the remediation owner.
|
||||
RemediationInProgressReason = "RemediationInProgress"
|
||||
|
||||
// ExternalRemediationTemplateAvailable is set on machinehealthchecks when MachineHealthCheck controller uses external remediation.
|
||||
// ExternalRemediationTemplateAvailable is set to false if external remediation template is not found.
|
||||
ExternalRemediationTemplateAvailable ConditionType = "ExternalRemediationTemplateAvailable"
|
||||
|
||||
// ExternalRemediationTemplateNotFound is the reason used when a machine health check fails to find external remediation template.
|
||||
ExternalRemediationTemplateNotFound = "ExternalRemediationTemplateNotFound"
|
||||
|
||||
// ExternalRemediationRequestAvailable is set on machinehealthchecks when MachineHealthCheck controller uses external remediation.
|
||||
// ExternalRemediationRequestAvailable is set to false if creating external remediation request fails.
|
||||
ExternalRemediationRequestAvailable ConditionType = "ExternalRemediationRequestAvailable"
|
||||
|
||||
// ExternalRemediationRequestCreationFailed is the reason used when a machine health check fails to create external remediation request.
|
||||
ExternalRemediationRequestCreationFailed = "ExternalRemediationRequestCreationFailed"
|
||||
)
|
||||
|
||||
// Conditions and condition Reasons for the Machine's Node object.
|
||||
const (
|
||||
// MachineNodeHealthyCondition provides info about the operational state of the Kubernetes node hosted on the machine by summarizing node conditions.
|
||||
// If the conditions defined in a Kubernetes node (i.e., NodeReady, NodeMemoryPressure, NodeDiskPressure, NodePIDPressure, and NodeNetworkUnavailable) are in a healthy state, it will be set to True.
|
||||
MachineNodeHealthyCondition ConditionType = "NodeHealthy"
|
||||
|
||||
// WaitingForNodeRefReason (Severity=Info) documents a machine.spec.providerId is not assigned yet.
|
||||
WaitingForNodeRefReason = "WaitingForNodeRef"
|
||||
|
||||
// NodeProvisioningReason (Severity=Info) documents machine in the process of provisioning a node.
|
||||
// NB. provisioning --> NodeRef == "".
|
||||
NodeProvisioningReason = "NodeProvisioning"
|
||||
|
||||
// NodeNotFoundReason (Severity=Error) documents a machine's node has previously been observed but is now gone.
|
||||
// NB. provisioned --> NodeRef != "".
|
||||
NodeNotFoundReason = "NodeNotFound"
|
||||
|
||||
// NodeConditionsFailedReason (Severity=Warning) documents a node is not in a healthy state due to the failed state of at least 1 Kubelet condition.
|
||||
NodeConditionsFailedReason = "NodeConditionsFailed"
|
||||
)
|
||||
|
||||
// Conditions and condition Reasons for the MachineHealthCheck object
|
||||
|
||||
const (
|
||||
// RemediationAllowedCondition is set on MachineHealthChecks to show the status of whether the MachineHealthCheck is
|
||||
// allowed to remediate any Machines or whether it is blocked from remediating any further.
|
||||
RemediationAllowedCondition ConditionType = "RemediationAllowed"
|
||||
|
||||
// TooManyUnhealthyReason is the reason used when too many Machines are unhealthy and the MachineHealthCheck is blocked
|
||||
// from making any further remediations.
|
||||
TooManyUnhealthyReason = "TooManyUnhealthy"
|
||||
)
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha4
|
||||
|
||||
import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// ANCHOR: ConditionSeverity
|
||||
|
||||
// ConditionSeverity expresses the severity of a Condition Type failing.
|
||||
type ConditionSeverity string
|
||||
|
||||
const (
|
||||
// ConditionSeverityError specifies that a condition with `Status=False` is an error.
|
||||
ConditionSeverityError ConditionSeverity = "Error"
|
||||
|
||||
// ConditionSeverityWarning specifies that a condition with `Status=False` is a warning.
|
||||
ConditionSeverityWarning ConditionSeverity = "Warning"
|
||||
|
||||
// ConditionSeverityInfo specifies that a condition with `Status=False` is informative.
|
||||
ConditionSeverityInfo ConditionSeverity = "Info"
|
||||
|
||||
// ConditionSeverityNone should apply only to conditions with `Status=True`.
|
||||
ConditionSeverityNone ConditionSeverity = ""
|
||||
)
|
||||
|
||||
// ANCHOR_END: ConditionSeverity
|
||||
|
||||
// ANCHOR: ConditionType
|
||||
|
||||
// ConditionType is a valid value for Condition.Type.
|
||||
type ConditionType string
|
||||
|
||||
// ANCHOR_END: ConditionType
|
||||
|
||||
// ANCHOR: Condition
|
||||
|
||||
// Condition defines an observation of a Cluster API resource operational state.
|
||||
type Condition struct {
|
||||
// Type of condition in CamelCase or in foo.example.com/CamelCase.
|
||||
// Many .condition.type values are consistent across resources like Available, but because arbitrary conditions
|
||||
// can be useful (see .node.status.conditions), the ability to deconflict is important.
|
||||
// +required
|
||||
Type ConditionType `json:"type"`
|
||||
|
||||
// Status of the condition, one of True, False, Unknown.
|
||||
// +required
|
||||
Status corev1.ConditionStatus `json:"status"`
|
||||
|
||||
// Severity provides an explicit classification of Reason code, so the users or machines can immediately
|
||||
// understand the current situation and act accordingly.
|
||||
// The Severity field MUST be set only when Status=False.
|
||||
// +optional
|
||||
Severity ConditionSeverity `json:"severity,omitempty"`
|
||||
|
||||
// Last time the condition transitioned from one status to another.
|
||||
// This should be when the underlying condition changed. If that is not known, then using the time when
|
||||
// the API field changed is acceptable.
|
||||
// +required
|
||||
LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty"`
|
||||
|
||||
// The reason for the condition's last transition in CamelCase.
|
||||
// The specific API may choose whether or not this field is considered a guaranteed API.
|
||||
// This field may not be empty.
|
||||
// +optional
|
||||
Reason string `json:"reason,omitempty"`
|
||||
|
||||
// A human readable message indicating details about the transition.
|
||||
// This field may be empty.
|
||||
// +optional
|
||||
Message string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
// ANCHOR_END: Condition
|
||||
|
||||
// ANCHOR: Conditions
|
||||
|
||||
// Conditions provide observations of the operational state of a Cluster API resource.
|
||||
type Conditions []Condition
|
||||
|
||||
// ANCHOR_END: Conditions
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha4
|
||||
|
||||
func (*Cluster) Hub() {}
|
||||
func (*ClusterList) Hub() {}
|
||||
func (*Machine) Hub() {}
|
||||
func (*MachineList) Hub() {}
|
||||
func (*MachineSet) Hub() {}
|
||||
func (*MachineSetList) Hub() {}
|
||||
func (*MachineDeployment) Hub() {}
|
||||
func (*MachineDeploymentList) Hub() {}
|
||||
func (*MachineHealthCheck) Hub() {}
|
||||
func (*MachineHealthCheckList) Hub() {}
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha4
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package v1alpha4 contains API Schema definitions for the cluster v1alpha4 API group
|
||||
// +kubebuilder:object:generate=true
|
||||
// +groupName=cluster.x-k8s.io
|
||||
package v1alpha4
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"sigs.k8s.io/controller-runtime/pkg/scheme"
|
||||
)
|
||||
|
||||
var (
|
||||
// GroupVersion is group version used to register these objects.
|
||||
GroupVersion = schema.GroupVersion{Group: "cluster.x-k8s.io", Version: "v1alpha4"}
|
||||
|
||||
// SchemeBuilder is used to add go types to the GroupVersionKind scheme.
|
||||
SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
|
||||
|
||||
// AddToScheme adds the types in this group-version to the given scheme.
|
||||
AddToScheme = SchemeBuilder.AddToScheme
|
||||
)
|
64
vendor/sigs.k8s.io/cluster-api/api/v1alpha4/machine_phase_types.go
generated
vendored
Normal file
64
vendor/sigs.k8s.io/cluster-api/api/v1alpha4/machine_phase_types.go
generated
vendored
Normal file
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha4
|
||||
|
||||
// MachinePhase is a string representation of a Machine Phase.
|
||||
//
|
||||
// This type is a high-level indicator of the status of the Machine as it is provisioned,
|
||||
// from the API user’s perspective.
|
||||
//
|
||||
// The value should not be interpreted by any software components as a reliable indication
|
||||
// of the actual state of the Machine, and controllers should not use the Machine Phase field
|
||||
// value when making decisions about what action to take.
|
||||
//
|
||||
// Controllers should always look at the actual state of the Machine’s fields to make those decisions.
|
||||
type MachinePhase string
|
||||
|
||||
const (
|
||||
// MachinePhasePending is the first state a Machine is assigned by
|
||||
// Cluster API Machine controller after being created.
|
||||
MachinePhasePending = MachinePhase("Pending")
|
||||
|
||||
// MachinePhaseProvisioning is the state when the
|
||||
// Machine infrastructure is being created.
|
||||
MachinePhaseProvisioning = MachinePhase("Provisioning")
|
||||
|
||||
// MachinePhaseProvisioned is the state when its
|
||||
// infrastructure has been created and configured.
|
||||
MachinePhaseProvisioned = MachinePhase("Provisioned")
|
||||
|
||||
// MachinePhaseRunning is the Machine state when it has
|
||||
// become a Kubernetes Node in a Ready state.
|
||||
MachinePhaseRunning = MachinePhase("Running")
|
||||
|
||||
// MachinePhaseDeleting is the Machine state when a delete
|
||||
// request has been sent to the API Server,
|
||||
// but its infrastructure has not yet been fully deleted.
|
||||
MachinePhaseDeleting = MachinePhase("Deleting")
|
||||
|
||||
// MachinePhaseDeleted is the Machine state when the object
|
||||
// and the related infrastructure is deleted and
|
||||
// ready to be garbage collected by the API Server.
|
||||
MachinePhaseDeleted = MachinePhase("Deleted")
|
||||
|
||||
// MachinePhaseFailed is the Machine state when the system
|
||||
// might require user intervention.
|
||||
MachinePhaseFailed = MachinePhase("Failed")
|
||||
|
||||
// MachinePhaseUnknown is returned if the Machine state cannot be determined.
|
||||
MachinePhaseUnknown = MachinePhase("Unknown")
|
||||
)
|
|
@ -0,0 +1,269 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha4
|
||||
|
||||
import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
capierrors "sigs.k8s.io/cluster-api/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
// MachineFinalizer is set on PrepareForCreate callback.
|
||||
MachineFinalizer = "machine.cluster.x-k8s.io"
|
||||
|
||||
// MachineControlPlaneLabelName is the label set on machines or related objects that are part of a control plane.
|
||||
MachineControlPlaneLabelName = "cluster.x-k8s.io/control-plane"
|
||||
|
||||
// ExcludeNodeDrainingAnnotation annotation explicitly skips node draining if set.
|
||||
ExcludeNodeDrainingAnnotation = "machine.cluster.x-k8s.io/exclude-node-draining"
|
||||
|
||||
// MachineSetLabelName is the label set on machines if they're controlled by MachineSet.
|
||||
MachineSetLabelName = "cluster.x-k8s.io/set-name"
|
||||
|
||||
// MachineDeploymentLabelName is the label set on machines if they're controlled by MachineDeployment.
|
||||
MachineDeploymentLabelName = "cluster.x-k8s.io/deployment-name"
|
||||
|
||||
// PreDrainDeleteHookAnnotationPrefix annotation specifies the prefix we
|
||||
// search each annotation for during the pre-drain.delete lifecycle hook
|
||||
// to pause reconciliation of deletion. These hooks will prevent removal of
|
||||
// draining the associated node until all are removed.
|
||||
PreDrainDeleteHookAnnotationPrefix = "pre-drain.delete.hook.machine.cluster.x-k8s.io"
|
||||
|
||||
// PreTerminateDeleteHookAnnotationPrefix annotation specifies the prefix we
|
||||
// search each annotation for during the pre-terminate.delete lifecycle hook
|
||||
// to pause reconciliation of deletion. These hooks will prevent removal of
|
||||
// an instance from an infrastructure provider until all are removed.
|
||||
PreTerminateDeleteHookAnnotationPrefix = "pre-terminate.delete.hook.machine.cluster.x-k8s.io"
|
||||
)
|
||||
|
||||
// ANCHOR: MachineSpec
|
||||
|
||||
// MachineSpec defines the desired state of Machine.
|
||||
type MachineSpec struct {
|
||||
// ClusterName is the name of the Cluster this object belongs to.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
ClusterName string `json:"clusterName"`
|
||||
|
||||
// Bootstrap is a reference to a local struct which encapsulates
|
||||
// fields to configure the Machine’s bootstrapping mechanism.
|
||||
Bootstrap Bootstrap `json:"bootstrap"`
|
||||
|
||||
// InfrastructureRef is a required reference to a custom resource
|
||||
// offered by an infrastructure provider.
|
||||
InfrastructureRef corev1.ObjectReference `json:"infrastructureRef"`
|
||||
|
||||
// Version defines the desired Kubernetes version.
|
||||
// This field is meant to be optionally used by bootstrap providers.
|
||||
// +optional
|
||||
Version *string `json:"version,omitempty"`
|
||||
|
||||
// ProviderID is the identification ID of the machine provided by the provider.
|
||||
// This field must match the provider ID as seen on the node object corresponding to this machine.
|
||||
// This field is required by higher level consumers of cluster-api. Example use case is cluster autoscaler
|
||||
// with cluster-api as provider. Clean-up logic in the autoscaler compares machines to nodes to find out
|
||||
// machines at provider which could not get registered as Kubernetes nodes. With cluster-api as a
|
||||
// generic out-of-tree provider for autoscaler, this field is required by autoscaler to be
|
||||
// able to have a provider view of the list of machines. Another list of nodes is queried from the k8s apiserver
|
||||
// and then a comparison is done to find out unregistered machines and are marked for delete.
|
||||
// This field will be set by the actuators and consumed by higher level entities like autoscaler that will
|
||||
// be interfacing with cluster-api as generic provider.
|
||||
// +optional
|
||||
ProviderID *string `json:"providerID,omitempty"`
|
||||
|
||||
// FailureDomain is the failure domain the machine will be created in.
|
||||
// Must match a key in the FailureDomains map stored on the cluster object.
|
||||
// +optional
|
||||
FailureDomain *string `json:"failureDomain,omitempty"`
|
||||
|
||||
// NodeDrainTimeout is the total amount of time that the controller will spend on draining a node.
|
||||
// The default value is 0, meaning that the node can be drained without any time limitations.
|
||||
// NOTE: NodeDrainTimeout is different from `kubectl drain --timeout`
|
||||
// +optional
|
||||
NodeDrainTimeout *metav1.Duration `json:"nodeDrainTimeout,omitempty"`
|
||||
}
|
||||
|
||||
// ANCHOR_END: MachineSpec
|
||||
|
||||
// ANCHOR: MachineStatus
|
||||
|
||||
// MachineStatus defines the observed state of Machine.
|
||||
type MachineStatus struct {
|
||||
// NodeRef will point to the corresponding Node if it exists.
|
||||
// +optional
|
||||
NodeRef *corev1.ObjectReference `json:"nodeRef,omitempty"`
|
||||
|
||||
// LastUpdated identifies when the phase of the Machine last transitioned.
|
||||
// +optional
|
||||
LastUpdated *metav1.Time `json:"lastUpdated,omitempty"`
|
||||
|
||||
// Version specifies the current version of Kubernetes running
|
||||
// on the corresponding Node. This is meant to be a means of bubbling
|
||||
// up status from the Node to the Machine.
|
||||
// It is entirely optional, but useful for end-user UX if it’s present.
|
||||
// +optional
|
||||
Version *string `json:"version,omitempty"`
|
||||
|
||||
// FailureReason will be set in the event that there is a terminal problem
|
||||
// reconciling the Machine and will contain a succinct value suitable
|
||||
// for machine interpretation.
|
||||
//
|
||||
// This field should not be set for transitive errors that a controller
|
||||
// faces that are expected to be fixed automatically over
|
||||
// time (like service outages), but instead indicate that something is
|
||||
// fundamentally wrong with the Machine's spec or the configuration of
|
||||
// the controller, and that manual intervention is required. Examples
|
||||
// of terminal errors would be invalid combinations of settings in the
|
||||
// spec, values that are unsupported by the controller, or the
|
||||
// responsible controller itself being critically misconfigured.
|
||||
//
|
||||
// Any transient errors that occur during the reconciliation of Machines
|
||||
// can be added as events to the Machine object and/or logged in the
|
||||
// controller's output.
|
||||
// +optional
|
||||
FailureReason *capierrors.MachineStatusError `json:"failureReason,omitempty"`
|
||||
|
||||
// FailureMessage will be set in the event that there is a terminal problem
|
||||
// reconciling the Machine and will contain a more verbose string suitable
|
||||
// for logging and human consumption.
|
||||
//
|
||||
// This field should not be set for transitive errors that a controller
|
||||
// faces that are expected to be fixed automatically over
|
||||
// time (like service outages), but instead indicate that something is
|
||||
// fundamentally wrong with the Machine's spec or the configuration of
|
||||
// the controller, and that manual intervention is required. Examples
|
||||
// of terminal errors would be invalid combinations of settings in the
|
||||
// spec, values that are unsupported by the controller, or the
|
||||
// responsible controller itself being critically misconfigured.
|
||||
//
|
||||
// Any transient errors that occur during the reconciliation of Machines
|
||||
// can be added as events to the Machine object and/or logged in the
|
||||
// controller's output.
|
||||
// +optional
|
||||
FailureMessage *string `json:"failureMessage,omitempty"`
|
||||
|
||||
// Addresses is a list of addresses assigned to the machine.
|
||||
// This field is copied from the infrastructure provider reference.
|
||||
// +optional
|
||||
Addresses MachineAddresses `json:"addresses,omitempty"`
|
||||
|
||||
// Phase represents the current phase of machine actuation.
|
||||
// E.g. Pending, Running, Terminating, Failed etc.
|
||||
// +optional
|
||||
Phase string `json:"phase,omitempty"`
|
||||
|
||||
// BootstrapReady is the state of the bootstrap provider.
|
||||
// +optional
|
||||
BootstrapReady bool `json:"bootstrapReady"`
|
||||
|
||||
// InfrastructureReady is the state of the infrastructure provider.
|
||||
// +optional
|
||||
InfrastructureReady bool `json:"infrastructureReady"`
|
||||
|
||||
// ObservedGeneration is the latest generation observed by the controller.
|
||||
// +optional
|
||||
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
|
||||
|
||||
// Conditions defines current service state of the Machine.
|
||||
// +optional
|
||||
Conditions Conditions `json:"conditions,omitempty"`
|
||||
}
|
||||
|
||||
// ANCHOR_END: MachineStatus
|
||||
|
||||
// SetTypedPhase sets the Phase field to the string representation of MachinePhase.
|
||||
func (m *MachineStatus) SetTypedPhase(p MachinePhase) {
|
||||
m.Phase = string(p)
|
||||
}
|
||||
|
||||
// GetTypedPhase attempts to parse the Phase field and return
|
||||
// the typed MachinePhase representation as described in `machine_phase_types.go`.
|
||||
func (m *MachineStatus) GetTypedPhase() MachinePhase {
|
||||
switch phase := MachinePhase(m.Phase); phase {
|
||||
case
|
||||
MachinePhasePending,
|
||||
MachinePhaseProvisioning,
|
||||
MachinePhaseProvisioned,
|
||||
MachinePhaseRunning,
|
||||
MachinePhaseDeleting,
|
||||
MachinePhaseDeleted,
|
||||
MachinePhaseFailed:
|
||||
return phase
|
||||
default:
|
||||
return MachinePhaseUnknown
|
||||
}
|
||||
}
|
||||
|
||||
// ANCHOR: Bootstrap
|
||||
|
||||
// Bootstrap encapsulates fields to configure the Machine’s bootstrapping mechanism.
|
||||
type Bootstrap struct {
|
||||
// ConfigRef is a reference to a bootstrap provider-specific resource
|
||||
// that holds configuration details. The reference is optional to
|
||||
// allow users/operators to specify Bootstrap.DataSecretName without
|
||||
// the need of a controller.
|
||||
// +optional
|
||||
ConfigRef *corev1.ObjectReference `json:"configRef,omitempty"`
|
||||
|
||||
// DataSecretName is the name of the secret that stores the bootstrap data script.
|
||||
// If nil, the Machine should remain in the Pending state.
|
||||
// +optional
|
||||
DataSecretName *string `json:"dataSecretName,omitempty"`
|
||||
}
|
||||
|
||||
// ANCHOR_END: Bootstrap
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:resource:path=machines,shortName=ma,scope=Namespaced,categories=cluster-api
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:storageversion
|
||||
// +kubebuilder:printcolumn:name="ProviderID",type="string",JSONPath=".spec.providerID",description="Provider ID"
|
||||
// +kubebuilder:printcolumn:name="Phase",type="string",JSONPath=".status.phase",description="Machine status such as Terminating/Pending/Running/Failed etc"
|
||||
// +kubebuilder:printcolumn:name="Version",type="string",JSONPath=".spec.version",description="Kubernetes version associated with this Machine"
|
||||
// +kubebuilder:printcolumn:name="NodeName",type="string",JSONPath=".status.nodeRef.name",description="Node name associated with this machine",priority=1
|
||||
|
||||
// Machine is the Schema for the machines API.
|
||||
type Machine struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec MachineSpec `json:"spec,omitempty"`
|
||||
Status MachineStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// GetConditions returns the set of conditions for this object.
|
||||
func (m *Machine) GetConditions() Conditions {
|
||||
return m.Status.Conditions
|
||||
}
|
||||
|
||||
// SetConditions sets the conditions on this object.
|
||||
func (m *Machine) SetConditions(conditions Conditions) {
|
||||
m.Status.Conditions = conditions
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
// MachineList contains a list of Machine.
|
||||
type MachineList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []Machine `json:"items"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&Machine{}, &MachineList{})
|
||||
}
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha4
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"sigs.k8s.io/cluster-api/util/version"
|
||||
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook"
|
||||
)
|
||||
|
||||
func (m *Machine) SetupWebhookWithManager(mgr ctrl.Manager) error {
|
||||
return ctrl.NewWebhookManagedBy(mgr).
|
||||
For(m).
|
||||
Complete()
|
||||
}
|
||||
|
||||
// +kubebuilder:webhook:verbs=create;update,path=/validate-cluster-x-k8s-io-v1alpha4-machine,mutating=false,failurePolicy=fail,matchPolicy=Equivalent,groups=cluster.x-k8s.io,resources=machines,versions=v1alpha4,name=validation.machine.cluster.x-k8s.io,sideEffects=None,admissionReviewVersions=v1beta1
|
||||
// +kubebuilder:webhook:verbs=create;update,path=/mutate-cluster-x-k8s-io-v1alpha4-machine,mutating=true,failurePolicy=fail,matchPolicy=Equivalent,groups=cluster.x-k8s.io,resources=machines,versions=v1alpha4,name=default.machine.cluster.x-k8s.io,sideEffects=None,admissionReviewVersions=v1beta1
|
||||
|
||||
var _ webhook.Validator = &Machine{}
|
||||
var _ webhook.Defaulter = &Machine{}
|
||||
|
||||
// Default implements webhook.Defaulter so a webhook will be registered for the type.
|
||||
func (m *Machine) Default() {
|
||||
if m.Labels == nil {
|
||||
m.Labels = make(map[string]string)
|
||||
}
|
||||
m.Labels[ClusterLabelName] = m.Spec.ClusterName
|
||||
|
||||
if m.Spec.Bootstrap.ConfigRef != nil && len(m.Spec.Bootstrap.ConfigRef.Namespace) == 0 {
|
||||
m.Spec.Bootstrap.ConfigRef.Namespace = m.Namespace
|
||||
}
|
||||
|
||||
if len(m.Spec.InfrastructureRef.Namespace) == 0 {
|
||||
m.Spec.InfrastructureRef.Namespace = m.Namespace
|
||||
}
|
||||
|
||||
if m.Spec.Version != nil && !strings.HasPrefix(*m.Spec.Version, "v") {
|
||||
normalizedVersion := "v" + *m.Spec.Version
|
||||
m.Spec.Version = &normalizedVersion
|
||||
}
|
||||
}
|
||||
|
||||
// ValidateCreate implements webhook.Validator so a webhook will be registered for the type.
|
||||
func (m *Machine) ValidateCreate() error {
|
||||
return m.validate(nil)
|
||||
}
|
||||
|
||||
// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type.
|
||||
func (m *Machine) ValidateUpdate(old runtime.Object) error {
|
||||
oldM, ok := old.(*Machine)
|
||||
if !ok {
|
||||
return apierrors.NewBadRequest(fmt.Sprintf("expected a Machine but got a %T", old))
|
||||
}
|
||||
return m.validate(oldM)
|
||||
}
|
||||
|
||||
// ValidateDelete implements webhook.Validator so a webhook will be registered for the type.
|
||||
func (m *Machine) ValidateDelete() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Machine) validate(old *Machine) error {
|
||||
var allErrs field.ErrorList
|
||||
if m.Spec.Bootstrap.ConfigRef == nil && m.Spec.Bootstrap.DataSecretName == nil {
|
||||
allErrs = append(
|
||||
allErrs,
|
||||
field.Required(
|
||||
field.NewPath("spec", "bootstrap", "data"),
|
||||
"expected either spec.bootstrap.dataSecretName or spec.bootstrap.configRef to be populated",
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
if m.Spec.Bootstrap.ConfigRef != nil && m.Spec.Bootstrap.ConfigRef.Namespace != m.Namespace {
|
||||
allErrs = append(
|
||||
allErrs,
|
||||
field.Invalid(
|
||||
field.NewPath("spec", "bootstrap", "configRef", "namespace"),
|
||||
m.Spec.Bootstrap.ConfigRef.Namespace,
|
||||
"must match metadata.namespace",
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
if m.Spec.InfrastructureRef.Namespace != m.Namespace {
|
||||
allErrs = append(
|
||||
allErrs,
|
||||
field.Invalid(
|
||||
field.NewPath("spec", "infrastructureRef", "namespace"),
|
||||
m.Spec.InfrastructureRef.Namespace,
|
||||
"must match metadata.namespace",
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
if old != nil && old.Spec.ClusterName != m.Spec.ClusterName {
|
||||
allErrs = append(
|
||||
allErrs,
|
||||
field.Invalid(field.NewPath("spec", "clusterName"), m.Spec.ClusterName, "field is immutable"),
|
||||
)
|
||||
}
|
||||
|
||||
if m.Spec.Version != nil {
|
||||
if !version.KubeSemver.MatchString(*m.Spec.Version) {
|
||||
allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "version"), *m.Spec.Version, "must be a valid semantic version"))
|
||||
}
|
||||
}
|
||||
|
||||
if len(allErrs) == 0 {
|
||||
return nil
|
||||
}
|
||||
return apierrors.NewInvalid(GroupVersion.WithKind("Machine").GroupKind(), m.Name, allErrs)
|
||||
}
|
289
vendor/sigs.k8s.io/cluster-api/api/v1alpha4/machinedeployment_types.go
generated
vendored
Normal file
289
vendor/sigs.k8s.io/cluster-api/api/v1alpha4/machinedeployment_types.go
generated
vendored
Normal file
|
@ -0,0 +1,289 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha4
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
)
|
||||
|
||||
// MachineDeploymentStrategyType defines the type of MachineDeployment rollout strategies.
|
||||
type MachineDeploymentStrategyType string
|
||||
|
||||
const (
|
||||
// RollingUpdateMachineDeploymentStrategyType replaces the old MachineSet by new one using rolling update
|
||||
// i.e. gradually scale down the old MachineSet and scale up the new one.
|
||||
RollingUpdateMachineDeploymentStrategyType MachineDeploymentStrategyType = "RollingUpdate"
|
||||
|
||||
// OnDeleteMachineDeploymentStrategyType replaces old MachineSets when the deletion of the associated machines are completed.
|
||||
OnDeleteMachineDeploymentStrategyType MachineDeploymentStrategyType = "OnDelete"
|
||||
|
||||
// RevisionAnnotation is the revision annotation of a machine deployment's machine sets which records its rollout sequence.
|
||||
RevisionAnnotation = "machinedeployment.clusters.x-k8s.io/revision"
|
||||
|
||||
// RevisionHistoryAnnotation maintains the history of all old revisions that a machine set has served for a machine deployment.
|
||||
RevisionHistoryAnnotation = "machinedeployment.clusters.x-k8s.io/revision-history"
|
||||
|
||||
// DesiredReplicasAnnotation is the desired replicas for a machine deployment recorded as an annotation
|
||||
// in its machine sets. Helps in separating scaling events from the rollout process and for
|
||||
// determining if the new machine set for a deployment is really saturated.
|
||||
DesiredReplicasAnnotation = "machinedeployment.clusters.x-k8s.io/desired-replicas"
|
||||
|
||||
// MaxReplicasAnnotation is the maximum replicas a deployment can have at a given point, which
|
||||
// is machinedeployment.spec.replicas + maxSurge. Used by the underlying machine sets to estimate their
|
||||
// proportions in case the deployment has surge replicas.
|
||||
MaxReplicasAnnotation = "machinedeployment.clusters.x-k8s.io/max-replicas"
|
||||
)
|
||||
|
||||
// ANCHOR: MachineDeploymentSpec
|
||||
|
||||
// MachineDeploymentSpec defines the desired state of MachineDeployment.
|
||||
type MachineDeploymentSpec struct {
|
||||
// ClusterName is the name of the Cluster this object belongs to.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
ClusterName string `json:"clusterName"`
|
||||
|
||||
// Number of desired machines. Defaults to 1.
|
||||
// This is a pointer to distinguish between explicit zero and not specified.
|
||||
// +optional
|
||||
// +kubebuilder:default=1
|
||||
Replicas *int32 `json:"replicas,omitempty"`
|
||||
|
||||
// Label selector for machines. Existing MachineSets whose machines are
|
||||
// selected by this will be the ones affected by this deployment.
|
||||
// It must match the machine template's labels.
|
||||
Selector metav1.LabelSelector `json:"selector"`
|
||||
|
||||
// Template describes the machines that will be created.
|
||||
Template MachineTemplateSpec `json:"template"`
|
||||
|
||||
// The deployment strategy to use to replace existing machines with
|
||||
// new ones.
|
||||
// +optional
|
||||
Strategy *MachineDeploymentStrategy `json:"strategy,omitempty"`
|
||||
|
||||
// Minimum number of seconds for which a newly created machine should
|
||||
// be ready.
|
||||
// Defaults to 0 (machine will be considered available as soon as it
|
||||
// is ready)
|
||||
// +optional
|
||||
MinReadySeconds *int32 `json:"minReadySeconds,omitempty"`
|
||||
|
||||
// The number of old MachineSets to retain to allow rollback.
|
||||
// This is a pointer to distinguish between explicit zero and not specified.
|
||||
// Defaults to 1.
|
||||
// +optional
|
||||
RevisionHistoryLimit *int32 `json:"revisionHistoryLimit,omitempty"`
|
||||
|
||||
// Indicates that the deployment is paused.
|
||||
// +optional
|
||||
Paused bool `json:"paused,omitempty"`
|
||||
|
||||
// The maximum time in seconds for a deployment to make progress before it
|
||||
// is considered to be failed. The deployment controller will continue to
|
||||
// process failed deployments and a condition with a ProgressDeadlineExceeded
|
||||
// reason will be surfaced in the deployment status. Note that progress will
|
||||
// not be estimated during the time a deployment is paused. Defaults to 600s.
|
||||
ProgressDeadlineSeconds *int32 `json:"progressDeadlineSeconds,omitempty"`
|
||||
}
|
||||
|
||||
// ANCHOR_END: MachineDeploymentSpec
|
||||
|
||||
// ANCHOR: MachineDeploymentStrategy
|
||||
|
||||
// MachineDeploymentStrategy describes how to replace existing machines
|
||||
// with new ones.
|
||||
type MachineDeploymentStrategy struct {
|
||||
// Type of deployment.
|
||||
// Default is RollingUpdate.
|
||||
// +kubebuilder:validation:Enum=RollingUpdate;OnDelete
|
||||
// +optional
|
||||
Type MachineDeploymentStrategyType `json:"type,omitempty"`
|
||||
|
||||
// Rolling update config params. Present only if
|
||||
// MachineDeploymentStrategyType = RollingUpdate.
|
||||
// +optional
|
||||
RollingUpdate *MachineRollingUpdateDeployment `json:"rollingUpdate,omitempty"`
|
||||
}
|
||||
|
||||
// ANCHOR_END: MachineDeploymentStrategy
|
||||
|
||||
// ANCHOR: MachineRollingUpdateDeployment
|
||||
|
||||
// MachineRollingUpdateDeployment is used to control the desired behavior of rolling update.
|
||||
type MachineRollingUpdateDeployment struct {
|
||||
// The maximum number of machines that can be unavailable during the update.
|
||||
// Value can be an absolute number (ex: 5) or a percentage of desired
|
||||
// machines (ex: 10%).
|
||||
// Absolute number is calculated from percentage by rounding down.
|
||||
// This can not be 0 if MaxSurge is 0.
|
||||
// Defaults to 0.
|
||||
// Example: when this is set to 30%, the old MachineSet can be scaled
|
||||
// down to 70% of desired machines immediately when the rolling update
|
||||
// starts. Once new machines are ready, old MachineSet can be scaled
|
||||
// down further, followed by scaling up the new MachineSet, ensuring
|
||||
// that the total number of machines available at all times
|
||||
// during the update is at least 70% of desired machines.
|
||||
// +optional
|
||||
MaxUnavailable *intstr.IntOrString `json:"maxUnavailable,omitempty"`
|
||||
|
||||
// The maximum number of machines that can be scheduled above the
|
||||
// desired number of machines.
|
||||
// Value can be an absolute number (ex: 5) or a percentage of
|
||||
// desired machines (ex: 10%).
|
||||
// This can not be 0 if MaxUnavailable is 0.
|
||||
// Absolute number is calculated from percentage by rounding up.
|
||||
// Defaults to 1.
|
||||
// Example: when this is set to 30%, the new MachineSet can be scaled
|
||||
// up immediately when the rolling update starts, such that the total
|
||||
// number of old and new machines do not exceed 130% of desired
|
||||
// machines. Once old machines have been killed, new MachineSet can
|
||||
// be scaled up further, ensuring that total number of machines running
|
||||
// at any time during the update is at most 130% of desired machines.
|
||||
// +optional
|
||||
MaxSurge *intstr.IntOrString `json:"maxSurge,omitempty"`
|
||||
|
||||
// DeletePolicy defines the policy used by the MachineDeployment to identify nodes to delete when downscaling.
|
||||
// Valid values are "Random, "Newest", "Oldest"
|
||||
// When no value is supplied, the default DeletePolicy of MachineSet is used
|
||||
// +kubebuilder:validation:Enum=Random;Newest;Oldest
|
||||
// +optional
|
||||
DeletePolicy *string `json:"deletePolicy,omitempty"`
|
||||
}
|
||||
|
||||
// ANCHOR_END: MachineRollingUpdateDeployment
|
||||
|
||||
// ANCHOR: MachineDeploymentStatus
|
||||
|
||||
// MachineDeploymentStatus defines the observed state of MachineDeployment.
|
||||
type MachineDeploymentStatus struct {
|
||||
// The generation observed by the deployment controller.
|
||||
// +optional
|
||||
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
|
||||
|
||||
// Selector is the same as the label selector but in the string format to avoid introspection
|
||||
// by clients. The string will be in the same format as the query-param syntax.
|
||||
// More info about label selectors: http://kubernetes.io/docs/user-guide/labels#label-selectors
|
||||
// +optional
|
||||
Selector string `json:"selector,omitempty"`
|
||||
|
||||
// Total number of non-terminated machines targeted by this deployment
|
||||
// (their labels match the selector).
|
||||
// +optional
|
||||
Replicas int32 `json:"replicas,omitempty"`
|
||||
|
||||
// Total number of non-terminated machines targeted by this deployment
|
||||
// that have the desired template spec.
|
||||
// +optional
|
||||
UpdatedReplicas int32 `json:"updatedReplicas,omitempty"`
|
||||
|
||||
// Total number of ready machines targeted by this deployment.
|
||||
// +optional
|
||||
ReadyReplicas int32 `json:"readyReplicas,omitempty"`
|
||||
|
||||
// Total number of available machines (ready for at least minReadySeconds)
|
||||
// targeted by this deployment.
|
||||
// +optional
|
||||
AvailableReplicas int32 `json:"availableReplicas,omitempty"`
|
||||
|
||||
// Total number of unavailable machines targeted by this deployment.
|
||||
// This is the total number of machines that are still required for
|
||||
// the deployment to have 100% available capacity. They may either
|
||||
// be machines that are running but not yet available or machines
|
||||
// that still have not been created.
|
||||
// +optional
|
||||
UnavailableReplicas int32 `json:"unavailableReplicas,omitempty"`
|
||||
|
||||
// Phase represents the current phase of a MachineDeployment (ScalingUp, ScalingDown, Running, Failed, or Unknown).
|
||||
// +optional
|
||||
Phase string `json:"phase,omitempty"`
|
||||
}
|
||||
|
||||
// ANCHOR_END: MachineDeploymentStatus
|
||||
|
||||
// MachineDeploymentPhase indicates the progress of the machine deployment.
|
||||
type MachineDeploymentPhase string
|
||||
|
||||
const (
|
||||
// MachineDeploymentPhaseScalingUp indicates the MachineDeployment is scaling up.
|
||||
MachineDeploymentPhaseScalingUp = MachineDeploymentPhase("ScalingUp")
|
||||
|
||||
// MachineDeploymentPhaseScalingDown indicates the MachineDeployment is scaling down.
|
||||
MachineDeploymentPhaseScalingDown = MachineDeploymentPhase("ScalingDown")
|
||||
|
||||
// MachineDeploymentPhaseRunning indicates scaling has completed and all Machines are running.
|
||||
MachineDeploymentPhaseRunning = MachineDeploymentPhase("Running")
|
||||
|
||||
// MachineDeploymentPhaseFailed indicates there was a problem scaling and user intervention might be required.
|
||||
MachineDeploymentPhaseFailed = MachineDeploymentPhase("Failed")
|
||||
|
||||
// MachineDeploymentPhaseUnknown indicates the state of the MachineDeployment cannot be determined.
|
||||
MachineDeploymentPhaseUnknown = MachineDeploymentPhase("Unknown")
|
||||
)
|
||||
|
||||
// SetTypedPhase sets the Phase field to the string representation of MachineDeploymentPhase.
|
||||
func (md *MachineDeploymentStatus) SetTypedPhase(p MachineDeploymentPhase) {
|
||||
md.Phase = string(p)
|
||||
}
|
||||
|
||||
// GetTypedPhase attempts to parse the Phase field and return
|
||||
// the typed MachineDeploymentPhase representation.
|
||||
func (md *MachineDeploymentStatus) GetTypedPhase() MachineDeploymentPhase {
|
||||
switch phase := MachineDeploymentPhase(md.Phase); phase {
|
||||
case
|
||||
MachineDeploymentPhaseScalingDown,
|
||||
MachineDeploymentPhaseScalingUp,
|
||||
MachineDeploymentPhaseRunning,
|
||||
MachineDeploymentPhaseFailed:
|
||||
return phase
|
||||
default:
|
||||
return MachineDeploymentPhaseUnknown
|
||||
}
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:resource:path=machinedeployments,shortName=md,scope=Namespaced,categories=cluster-api
|
||||
// +kubebuilder:storageversion
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:subresource:scale:specpath=.spec.replicas,statuspath=.status.replicas,selectorpath=.status.selector
|
||||
// +kubebuilder:printcolumn:name="Phase",type="string",JSONPath=".status.phase",description="MachineDeployment status such as ScalingUp/ScalingDown/Running/Failed/Unknown"
|
||||
// +kubebuilder:printcolumn:name="Replicas",type="integer",JSONPath=".status.replicas",description="Total number of non-terminated machines targeted by this MachineDeployment"
|
||||
// +kubebuilder:printcolumn:name="Ready",type="integer",JSONPath=".status.readyReplicas",description="Total number of ready machines targeted by this MachineDeployment"
|
||||
// +kubebuilder:printcolumn:name="Updated",type=integer,JSONPath=".status.updatedReplicas",description="Total number of non-terminated machines targeted by this deployment that have the desired template spec"
|
||||
// +kubebuilder:printcolumn:name="Unavailable",type=integer,JSONPath=".status.unavailableReplicas",description="Total number of unavailable machines targeted by this MachineDeployment"
|
||||
|
||||
// MachineDeployment is the Schema for the machinedeployments API.
|
||||
type MachineDeployment struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec MachineDeploymentSpec `json:"spec,omitempty"`
|
||||
Status MachineDeploymentStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
// MachineDeploymentList contains a list of MachineDeployment.
|
||||
type MachineDeploymentList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []MachineDeployment `json:"items"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&MachineDeployment{}, &MachineDeploymentList{})
|
||||
}
|
202
vendor/sigs.k8s.io/cluster-api/api/v1alpha4/machinedeployment_webhook.go
generated
vendored
Normal file
202
vendor/sigs.k8s.io/cluster-api/api/v1alpha4/machinedeployment_webhook.go
generated
vendored
Normal file
|
@ -0,0 +1,202 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha4
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
"k8s.io/utils/pointer"
|
||||
"sigs.k8s.io/cluster-api/util/version"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook"
|
||||
)
|
||||
|
||||
func (m *MachineDeployment) SetupWebhookWithManager(mgr ctrl.Manager) error {
|
||||
return ctrl.NewWebhookManagedBy(mgr).
|
||||
For(m).
|
||||
Complete()
|
||||
}
|
||||
|
||||
// +kubebuilder:webhook:verbs=create;update,path=/validate-cluster-x-k8s-io-v1alpha4-machinedeployment,mutating=false,failurePolicy=fail,matchPolicy=Equivalent,groups=cluster.x-k8s.io,resources=machinedeployments,versions=v1alpha4,name=validation.machinedeployment.cluster.x-k8s.io,sideEffects=None,admissionReviewVersions=v1beta1
|
||||
// +kubebuilder:webhook:verbs=create;update,path=/mutate-cluster-x-k8s-io-v1alpha4-machinedeployment,mutating=true,failurePolicy=fail,matchPolicy=Equivalent,groups=cluster.x-k8s.io,resources=machinedeployments,versions=v1alpha4,name=default.machinedeployment.cluster.x-k8s.io,sideEffects=None,admissionReviewVersions=v1beta1
|
||||
|
||||
var _ webhook.Defaulter = &MachineDeployment{}
|
||||
var _ webhook.Validator = &MachineDeployment{}
|
||||
|
||||
// Default implements webhook.Defaulter so a webhook will be registered for the type.
|
||||
func (m *MachineDeployment) Default() {
|
||||
PopulateDefaultsMachineDeployment(m)
|
||||
// tolerate version strings without a "v" prefix: prepend it if it's not there
|
||||
if m.Spec.Template.Spec.Version != nil && !strings.HasPrefix(*m.Spec.Template.Spec.Version, "v") {
|
||||
normalizedVersion := "v" + *m.Spec.Template.Spec.Version
|
||||
m.Spec.Template.Spec.Version = &normalizedVersion
|
||||
}
|
||||
}
|
||||
|
||||
// ValidateCreate implements webhook.Validator so a webhook will be registered for the type.
|
||||
func (m *MachineDeployment) ValidateCreate() error {
|
||||
return m.validate(nil)
|
||||
}
|
||||
|
||||
// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type.
|
||||
func (m *MachineDeployment) ValidateUpdate(old runtime.Object) error {
|
||||
oldMD, ok := old.(*MachineDeployment)
|
||||
if !ok {
|
||||
return apierrors.NewBadRequest(fmt.Sprintf("expected a MachineDeployment but got a %T", old))
|
||||
}
|
||||
return m.validate(oldMD)
|
||||
}
|
||||
|
||||
// ValidateDelete implements webhook.Validator so a webhook will be registered for the type.
|
||||
func (m *MachineDeployment) ValidateDelete() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MachineDeployment) validate(old *MachineDeployment) error {
|
||||
var allErrs field.ErrorList
|
||||
selector, err := metav1.LabelSelectorAsSelector(&m.Spec.Selector)
|
||||
if err != nil {
|
||||
allErrs = append(
|
||||
allErrs,
|
||||
field.Invalid(field.NewPath("spec", "selector"), m.Spec.Selector, err.Error()),
|
||||
)
|
||||
} else if !selector.Matches(labels.Set(m.Spec.Template.Labels)) {
|
||||
allErrs = append(
|
||||
allErrs,
|
||||
field.Invalid(
|
||||
field.NewPath("spec", "template", "labels"),
|
||||
m.Spec.Template.Labels,
|
||||
fmt.Sprintf("must match spec.selector %q", selector.String()),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
if old != nil && old.Spec.ClusterName != m.Spec.ClusterName {
|
||||
allErrs = append(
|
||||
allErrs,
|
||||
field.Invalid(field.NewPath("spec", "clusterName"), m.Spec.ClusterName, "field is immutable"),
|
||||
)
|
||||
}
|
||||
|
||||
if m.Spec.Strategy != nil && m.Spec.Strategy.RollingUpdate != nil {
|
||||
total := 1
|
||||
if m.Spec.Replicas != nil {
|
||||
total = int(*m.Spec.Replicas)
|
||||
}
|
||||
|
||||
if m.Spec.Strategy.RollingUpdate.MaxSurge != nil {
|
||||
if _, err := intstr.GetScaledValueFromIntOrPercent(m.Spec.Strategy.RollingUpdate.MaxSurge, total, true); err != nil {
|
||||
allErrs = append(
|
||||
allErrs,
|
||||
field.Invalid(field.NewPath("spec", "strategy", "rollingUpdate", "maxSurge"),
|
||||
m.Spec.Strategy.RollingUpdate.MaxSurge, fmt.Sprintf("must be either an int or a percentage: %v", err.Error())),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if m.Spec.Strategy.RollingUpdate.MaxUnavailable != nil {
|
||||
if _, err := intstr.GetScaledValueFromIntOrPercent(m.Spec.Strategy.RollingUpdate.MaxUnavailable, total, true); err != nil {
|
||||
allErrs = append(
|
||||
allErrs,
|
||||
field.Invalid(field.NewPath("spec", "strategy", "rollingUpdate", "maxUnavailable"),
|
||||
m.Spec.Strategy.RollingUpdate.MaxUnavailable, fmt.Sprintf("must be either an int or a percentage: %v", err.Error())),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if m.Spec.Template.Spec.Version != nil {
|
||||
if !version.KubeSemver.MatchString(*m.Spec.Template.Spec.Version) {
|
||||
allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "template", "spec", "version"), *m.Spec.Template.Spec.Version, "must be a valid semantic version"))
|
||||
}
|
||||
}
|
||||
|
||||
if len(allErrs) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return apierrors.NewInvalid(GroupVersion.WithKind("MachineDeployment").GroupKind(), m.Name, allErrs)
|
||||
}
|
||||
|
||||
// PopulateDefaultsMachineDeployment fills in default field values.
|
||||
// This is also called during MachineDeployment sync.
|
||||
func PopulateDefaultsMachineDeployment(d *MachineDeployment) {
|
||||
if d.Labels == nil {
|
||||
d.Labels = make(map[string]string)
|
||||
}
|
||||
d.Labels[ClusterLabelName] = d.Spec.ClusterName
|
||||
|
||||
if d.Spec.MinReadySeconds == nil {
|
||||
d.Spec.MinReadySeconds = pointer.Int32Ptr(0)
|
||||
}
|
||||
|
||||
if d.Spec.RevisionHistoryLimit == nil {
|
||||
d.Spec.RevisionHistoryLimit = pointer.Int32Ptr(1)
|
||||
}
|
||||
|
||||
if d.Spec.ProgressDeadlineSeconds == nil {
|
||||
d.Spec.ProgressDeadlineSeconds = pointer.Int32Ptr(600)
|
||||
}
|
||||
|
||||
if d.Spec.Selector.MatchLabels == nil {
|
||||
d.Spec.Selector.MatchLabels = make(map[string]string)
|
||||
}
|
||||
|
||||
if d.Spec.Strategy == nil {
|
||||
d.Spec.Strategy = &MachineDeploymentStrategy{}
|
||||
}
|
||||
|
||||
if d.Spec.Strategy.Type == "" {
|
||||
d.Spec.Strategy.Type = RollingUpdateMachineDeploymentStrategyType
|
||||
}
|
||||
|
||||
if d.Spec.Template.Labels == nil {
|
||||
d.Spec.Template.Labels = make(map[string]string)
|
||||
}
|
||||
|
||||
// Default RollingUpdate strategy only if strategy type is RollingUpdate.
|
||||
if d.Spec.Strategy.Type == RollingUpdateMachineDeploymentStrategyType {
|
||||
if d.Spec.Strategy.RollingUpdate == nil {
|
||||
d.Spec.Strategy.RollingUpdate = &MachineRollingUpdateDeployment{}
|
||||
}
|
||||
if d.Spec.Strategy.RollingUpdate.MaxSurge == nil {
|
||||
ios1 := intstr.FromInt(1)
|
||||
d.Spec.Strategy.RollingUpdate.MaxSurge = &ios1
|
||||
}
|
||||
if d.Spec.Strategy.RollingUpdate.MaxUnavailable == nil {
|
||||
ios0 := intstr.FromInt(0)
|
||||
d.Spec.Strategy.RollingUpdate.MaxUnavailable = &ios0
|
||||
}
|
||||
}
|
||||
|
||||
// If no selector has been provided, add label and selector for the
|
||||
// MachineDeployment's name as a default way of providing uniqueness.
|
||||
if len(d.Spec.Selector.MatchLabels) == 0 && len(d.Spec.Selector.MatchExpressions) == 0 {
|
||||
d.Spec.Selector.MatchLabels[MachineDeploymentLabelName] = d.Name
|
||||
d.Spec.Template.Labels[MachineDeploymentLabelName] = d.Name
|
||||
}
|
||||
// Make sure selector and template to be in the same cluster.
|
||||
d.Spec.Selector.MatchLabels[ClusterLabelName] = d.Spec.ClusterName
|
||||
d.Spec.Template.Labels[ClusterLabelName] = d.Spec.ClusterName
|
||||
}
|
168
vendor/sigs.k8s.io/cluster-api/api/v1alpha4/machinehealthcheck_types.go
generated
vendored
Normal file
168
vendor/sigs.k8s.io/cluster-api/api/v1alpha4/machinehealthcheck_types.go
generated
vendored
Normal file
|
@ -0,0 +1,168 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha4
|
||||
|
||||
import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
)
|
||||
|
||||
// ANCHOR: MachineHealthCheckSpec
|
||||
|
||||
// MachineHealthCheckSpec defines the desired state of MachineHealthCheck.
|
||||
type MachineHealthCheckSpec struct {
|
||||
// ClusterName is the name of the Cluster this object belongs to.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
ClusterName string `json:"clusterName"`
|
||||
|
||||
// Label selector to match machines whose health will be exercised
|
||||
Selector metav1.LabelSelector `json:"selector"`
|
||||
|
||||
// UnhealthyConditions contains a list of the conditions that determine
|
||||
// whether a node is considered unhealthy. The conditions are combined in a
|
||||
// logical OR, i.e. if any of the conditions is met, the node is unhealthy.
|
||||
//
|
||||
// +kubebuilder:validation:MinItems=1
|
||||
UnhealthyConditions []UnhealthyCondition `json:"unhealthyConditions"`
|
||||
|
||||
// Any further remediation is only allowed if at most "MaxUnhealthy" machines selected by
|
||||
// "selector" are not healthy.
|
||||
// +optional
|
||||
MaxUnhealthy *intstr.IntOrString `json:"maxUnhealthy,omitempty"`
|
||||
|
||||
// Any further remediation is only allowed if the number of machines selected by "selector" as not healthy
|
||||
// is within the range of "UnhealthyRange". Takes precedence over MaxUnhealthy.
|
||||
// Eg. "[3-5]" - This means that remediation will be allowed only when:
|
||||
// (a) there are at least 3 unhealthy machines (and)
|
||||
// (b) there are at most 5 unhealthy machines
|
||||
// +optional
|
||||
// +kubebuilder:validation:Pattern=^\[[0-9]+-[0-9]+\]$
|
||||
UnhealthyRange *string `json:"unhealthyRange,omitempty"`
|
||||
|
||||
// Machines older than this duration without a node will be considered to have
|
||||
// failed and will be remediated.
|
||||
// If not set, this value is defaulted to 10 minutes.
|
||||
// If you wish to disable this feature, set the value explicitly to 0.
|
||||
// +optional
|
||||
NodeStartupTimeout *metav1.Duration `json:"nodeStartupTimeout,omitempty"`
|
||||
|
||||
// RemediationTemplate is a reference to a remediation template
|
||||
// provided by an infrastructure provider.
|
||||
//
|
||||
// This field is completely optional, when filled, the MachineHealthCheck controller
|
||||
// creates a new object from the template referenced and hands off remediation of the machine to
|
||||
// a controller that lives outside of Cluster API.
|
||||
// +optional
|
||||
RemediationTemplate *corev1.ObjectReference `json:"remediationTemplate,omitempty"`
|
||||
}
|
||||
|
||||
// ANCHOR_END: MachineHealthCHeckSpec
|
||||
|
||||
// ANCHOR: UnhealthyCondition
|
||||
|
||||
// UnhealthyCondition represents a Node condition type and value with a timeout
|
||||
// specified as a duration. When the named condition has been in the given
|
||||
// status for at least the timeout value, a node is considered unhealthy.
|
||||
type UnhealthyCondition struct {
|
||||
// +kubebuilder:validation:Type=string
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
Type corev1.NodeConditionType `json:"type"`
|
||||
|
||||
// +kubebuilder:validation:Type=string
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
Status corev1.ConditionStatus `json:"status"`
|
||||
|
||||
Timeout metav1.Duration `json:"timeout"`
|
||||
}
|
||||
|
||||
// ANCHOR_END: UnhealthyCondition
|
||||
|
||||
// ANCHOR: MachineHealthCheckStatus
|
||||
|
||||
// MachineHealthCheckStatus defines the observed state of MachineHealthCheck.
|
||||
type MachineHealthCheckStatus struct {
|
||||
// total number of machines counted by this machine health check
|
||||
// +kubebuilder:validation:Minimum=0
|
||||
ExpectedMachines int32 `json:"expectedMachines,omitempty"`
|
||||
|
||||
// total number of healthy machines counted by this machine health check
|
||||
// +kubebuilder:validation:Minimum=0
|
||||
CurrentHealthy int32 `json:"currentHealthy,omitempty"`
|
||||
|
||||
// RemediationsAllowed is the number of further remediations allowed by this machine health check before
|
||||
// maxUnhealthy short circuiting will be applied
|
||||
// +kubebuilder:validation:Minimum=0
|
||||
RemediationsAllowed int32 `json:"remediationsAllowed,omitempty"`
|
||||
|
||||
// ObservedGeneration is the latest generation observed by the controller.
|
||||
// +optional
|
||||
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
|
||||
|
||||
// Targets shows the current list of machines the machine health check is watching
|
||||
// +optional
|
||||
Targets []string `json:"targets,omitempty"`
|
||||
|
||||
// Conditions defines current service state of the MachineHealthCheck.
|
||||
// +optional
|
||||
Conditions Conditions `json:"conditions,omitempty"`
|
||||
}
|
||||
|
||||
// ANCHOR_END: MachineHealthCheckStatus
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:resource:path=machinehealthchecks,shortName=mhc;mhcs,scope=Namespaced,categories=cluster-api
|
||||
// +kubebuilder:storageversion
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:printcolumn:name="MaxUnhealthy",type="string",JSONPath=".spec.maxUnhealthy",description="Maximum number of unhealthy machines allowed"
|
||||
// +kubebuilder:printcolumn:name="ExpectedMachines",type="integer",JSONPath=".status.expectedMachines",description="Number of machines currently monitored"
|
||||
// +kubebuilder:printcolumn:name="CurrentHealthy",type="integer",JSONPath=".status.currentHealthy",description="Current observed healthy machines"
|
||||
|
||||
// MachineHealthCheck is the Schema for the machinehealthchecks API.
|
||||
type MachineHealthCheck struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Specification of machine health check policy
|
||||
Spec MachineHealthCheckSpec `json:"spec,omitempty"`
|
||||
|
||||
// Most recently observed status of MachineHealthCheck resource
|
||||
Status MachineHealthCheckStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// GetConditions returns the set of conditions for this object.
|
||||
func (m *MachineHealthCheck) GetConditions() Conditions {
|
||||
return m.Status.Conditions
|
||||
}
|
||||
|
||||
// SetConditions sets the conditions on this object.
|
||||
func (m *MachineHealthCheck) SetConditions(conditions Conditions) {
|
||||
m.Status.Conditions = conditions
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
// MachineHealthCheckList contains a list of MachineHealthCheck.
|
||||
type MachineHealthCheckList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []MachineHealthCheck `json:"items"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&MachineHealthCheck{}, &MachineHealthCheckList{})
|
||||
}
|
156
vendor/sigs.k8s.io/cluster-api/api/v1alpha4/machinehealthcheck_webhook.go
generated
vendored
Normal file
156
vendor/sigs.k8s.io/cluster-api/api/v1alpha4/machinehealthcheck_webhook.go
generated
vendored
Normal file
|
@ -0,0 +1,156 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha4
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook"
|
||||
)
|
||||
|
||||
var (
|
||||
// DefaultNodeStartupTimeout is the time allowed for a node to start up.
|
||||
// Can be made longer as part of spec if required for particular provider.
|
||||
// 10 minutes should allow the instance to start and the node to join the
|
||||
// cluster on most providers.
|
||||
DefaultNodeStartupTimeout = metav1.Duration{Duration: 10 * time.Minute}
|
||||
// Minimum time allowed for a node to start up.
|
||||
minNodeStartupTimeout = metav1.Duration{Duration: 30 * time.Second}
|
||||
// We allow users to disable the nodeStartupTimeout by setting the duration to 0.
|
||||
disabledNodeStartupTimeout = ZeroDuration
|
||||
)
|
||||
|
||||
// SetMinNodeStartupTimeout allows users to optionally set a custom timeout
|
||||
// for the validation webhook.
|
||||
//
|
||||
// This function is mostly used within envtest (integration tests), and should
|
||||
// never be used in a production environment.
|
||||
func SetMinNodeStartupTimeout(d metav1.Duration) {
|
||||
minNodeStartupTimeout = d
|
||||
}
|
||||
|
||||
func (m *MachineHealthCheck) SetupWebhookWithManager(mgr ctrl.Manager) error {
|
||||
return ctrl.NewWebhookManagedBy(mgr).
|
||||
For(m).
|
||||
Complete()
|
||||
}
|
||||
|
||||
// +kubebuilder:webhook:verbs=create;update,path=/validate-cluster-x-k8s-io-v1alpha4-machinehealthcheck,mutating=false,failurePolicy=fail,matchPolicy=Equivalent,groups=cluster.x-k8s.io,resources=machinehealthchecks,versions=v1alpha4,name=validation.machinehealthcheck.cluster.x-k8s.io,sideEffects=None,admissionReviewVersions=v1beta1
|
||||
// +kubebuilder:webhook:verbs=create;update,path=/mutate-cluster-x-k8s-io-v1alpha4-machinehealthcheck,mutating=true,failurePolicy=fail,matchPolicy=Equivalent,groups=cluster.x-k8s.io,resources=machinehealthchecks,versions=v1alpha4,name=default.machinehealthcheck.cluster.x-k8s.io,sideEffects=None,admissionReviewVersions=v1beta1
|
||||
|
||||
var _ webhook.Defaulter = &MachineHealthCheck{}
|
||||
var _ webhook.Validator = &MachineHealthCheck{}
|
||||
|
||||
// Default implements webhook.Defaulter so a webhook will be registered for the type.
|
||||
func (m *MachineHealthCheck) Default() {
|
||||
if m.Labels == nil {
|
||||
m.Labels = make(map[string]string)
|
||||
}
|
||||
m.Labels[ClusterLabelName] = m.Spec.ClusterName
|
||||
|
||||
if m.Spec.MaxUnhealthy == nil {
|
||||
defaultMaxUnhealthy := intstr.FromString("100%")
|
||||
m.Spec.MaxUnhealthy = &defaultMaxUnhealthy
|
||||
}
|
||||
|
||||
if m.Spec.NodeStartupTimeout == nil {
|
||||
m.Spec.NodeStartupTimeout = &DefaultNodeStartupTimeout
|
||||
}
|
||||
}
|
||||
|
||||
// ValidateCreate implements webhook.Validator so a webhook will be registered for the type.
|
||||
func (m *MachineHealthCheck) ValidateCreate() error {
|
||||
return m.validate(nil)
|
||||
}
|
||||
|
||||
// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type.
|
||||
func (m *MachineHealthCheck) ValidateUpdate(old runtime.Object) error {
|
||||
mhc, ok := old.(*MachineHealthCheck)
|
||||
if !ok {
|
||||
return apierrors.NewBadRequest(fmt.Sprintf("expected a MachineHealthCheck but got a %T", old))
|
||||
}
|
||||
return m.validate(mhc)
|
||||
}
|
||||
|
||||
// ValidateDelete implements webhook.Validator so a webhook will be registered for the type.
|
||||
func (m *MachineHealthCheck) ValidateDelete() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MachineHealthCheck) validate(old *MachineHealthCheck) error {
|
||||
var allErrs field.ErrorList
|
||||
|
||||
// Validate selector parses as Selector
|
||||
selector, err := metav1.LabelSelectorAsSelector(&m.Spec.Selector)
|
||||
if err != nil {
|
||||
allErrs = append(
|
||||
allErrs,
|
||||
field.Invalid(field.NewPath("spec", "selector"), m.Spec.Selector, err.Error()),
|
||||
)
|
||||
}
|
||||
|
||||
// Validate that the selector isn't empty.
|
||||
if selector != nil && selector.Empty() {
|
||||
allErrs = append(
|
||||
allErrs,
|
||||
field.Invalid(field.NewPath("spec", "selector"), m.Spec.Selector, "selector must not be empty"),
|
||||
)
|
||||
}
|
||||
|
||||
if clusterName, ok := m.Spec.Selector.MatchLabels[ClusterLabelName]; ok && clusterName != m.Spec.ClusterName {
|
||||
allErrs = append(
|
||||
allErrs,
|
||||
field.Invalid(field.NewPath("spec", "selector"), m.Spec.Selector, "cannot specify a cluster selector other than the one specified by ClusterName"))
|
||||
}
|
||||
|
||||
if old != nil && old.Spec.ClusterName != m.Spec.ClusterName {
|
||||
allErrs = append(
|
||||
allErrs,
|
||||
field.Invalid(field.NewPath("spec", "clusterName"), m.Spec.ClusterName, "field is immutable"),
|
||||
)
|
||||
}
|
||||
|
||||
if m.Spec.NodeStartupTimeout != nil &&
|
||||
m.Spec.NodeStartupTimeout.Seconds() != disabledNodeStartupTimeout.Seconds() &&
|
||||
m.Spec.NodeStartupTimeout.Seconds() < minNodeStartupTimeout.Seconds() {
|
||||
allErrs = append(
|
||||
allErrs,
|
||||
field.Invalid(field.NewPath("spec", "nodeStartupTimeout"), m.Spec.NodeStartupTimeout.Seconds(), "must be at least 30s"),
|
||||
)
|
||||
}
|
||||
|
||||
if m.Spec.MaxUnhealthy != nil {
|
||||
if _, err := intstr.GetScaledValueFromIntOrPercent(m.Spec.MaxUnhealthy, 0, false); err != nil {
|
||||
allErrs = append(
|
||||
allErrs,
|
||||
field.Invalid(field.NewPath("spec", "maxUnhealthy"), m.Spec.MaxUnhealthy, fmt.Sprintf("must be either an int or a percentage: %v", err.Error())),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if len(allErrs) == 0 {
|
||||
return nil
|
||||
}
|
||||
return apierrors.NewInvalid(GroupVersion.WithKind("MachineHealthCheck").GroupKind(), m.Name, allErrs)
|
||||
}
|
|
@ -0,0 +1,216 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha4
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
metav1validation "k8s.io/apimachinery/pkg/apis/meta/v1/validation"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
capierrors "sigs.k8s.io/cluster-api/errors"
|
||||
)
|
||||
|
||||
// ANCHOR: MachineSetSpec
|
||||
|
||||
// MachineSetSpec defines the desired state of MachineSet.
|
||||
type MachineSetSpec struct {
|
||||
// ClusterName is the name of the Cluster this object belongs to.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
ClusterName string `json:"clusterName"`
|
||||
|
||||
// Replicas is the number of desired replicas.
|
||||
// This is a pointer to distinguish between explicit zero and unspecified.
|
||||
// Defaults to 1.
|
||||
// +optional
|
||||
// +kubebuilder:default=1
|
||||
Replicas *int32 `json:"replicas,omitempty"`
|
||||
|
||||
// MinReadySeconds is the minimum number of seconds for which a newly created machine should be ready.
|
||||
// Defaults to 0 (machine will be considered available as soon as it is ready)
|
||||
// +optional
|
||||
MinReadySeconds int32 `json:"minReadySeconds,omitempty"`
|
||||
|
||||
// DeletePolicy defines the policy used to identify nodes to delete when downscaling.
|
||||
// Defaults to "Random". Valid values are "Random, "Newest", "Oldest"
|
||||
// +kubebuilder:validation:Enum=Random;Newest;Oldest
|
||||
DeletePolicy string `json:"deletePolicy,omitempty"`
|
||||
|
||||
// Selector is a label query over machines that should match the replica count.
|
||||
// Label keys and values that must match in order to be controlled by this MachineSet.
|
||||
// It must match the machine template's labels.
|
||||
// More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors
|
||||
Selector metav1.LabelSelector `json:"selector"`
|
||||
|
||||
// Template is the object that describes the machine that will be created if
|
||||
// insufficient replicas are detected.
|
||||
// Object references to custom resources resources are treated as templates.
|
||||
// +optional
|
||||
Template MachineTemplateSpec `json:"template,omitempty"`
|
||||
}
|
||||
|
||||
// ANCHOR_END: MachineSetSpec
|
||||
|
||||
// ANCHOR: MachineTemplateSpec
|
||||
|
||||
// MachineTemplateSpec describes the data needed to create a Machine from a template.
|
||||
type MachineTemplateSpec struct {
|
||||
// Standard object's metadata.
|
||||
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
|
||||
// +optional
|
||||
ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Specification of the desired behavior of the machine.
|
||||
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
|
||||
// +optional
|
||||
Spec MachineSpec `json:"spec,omitempty"`
|
||||
}
|
||||
|
||||
// ANCHOR_END: MachineTemplateSpec
|
||||
|
||||
// MachineSetDeletePolicy defines how priority is assigned to nodes to delete when
|
||||
// downscaling a MachineSet. Defaults to "Random".
|
||||
type MachineSetDeletePolicy string
|
||||
|
||||
const (
|
||||
// RandomMachineSetDeletePolicy prioritizes both Machines that have the annotation
|
||||
// "cluster.x-k8s.io/delete-machine=yes" and Machines that are unhealthy
|
||||
// (Status.FailureReason or Status.FailureMessage are set to a non-empty value).
|
||||
// Finally, it picks Machines at random to delete.
|
||||
RandomMachineSetDeletePolicy MachineSetDeletePolicy = "Random"
|
||||
|
||||
// NewestMachineSetDeletePolicy prioritizes both Machines that have the annotation
|
||||
// "cluster.x-k8s.io/delete-machine=yes" and Machines that are unhealthy
|
||||
// (Status.FailureReason or Status.FailureMessage are set to a non-empty value).
|
||||
// It then prioritizes the newest Machines for deletion based on the Machine's CreationTimestamp.
|
||||
NewestMachineSetDeletePolicy MachineSetDeletePolicy = "Newest"
|
||||
|
||||
// OldestMachineSetDeletePolicy prioritizes both Machines that have the annotation
|
||||
// "cluster.x-k8s.io/delete-machine=yes" and Machines that are unhealthy
|
||||
// (Status.FailureReason or Status.FailureMessage are set to a non-empty value).
|
||||
// It then prioritizes the oldest Machines for deletion based on the Machine's CreationTimestamp.
|
||||
OldestMachineSetDeletePolicy MachineSetDeletePolicy = "Oldest"
|
||||
)
|
||||
|
||||
// ANCHOR: MachineSetStatus
|
||||
|
||||
// MachineSetStatus defines the observed state of MachineSet.
|
||||
type MachineSetStatus struct {
|
||||
// Selector is the same as the label selector but in the string format to avoid introspection
|
||||
// by clients. The string will be in the same format as the query-param syntax.
|
||||
// More info about label selectors: http://kubernetes.io/docs/user-guide/labels#label-selectors
|
||||
// +optional
|
||||
Selector string `json:"selector,omitempty"`
|
||||
|
||||
// Replicas is the most recently observed number of replicas.
|
||||
// +optional
|
||||
Replicas int32 `json:"replicas,omitempty"`
|
||||
|
||||
// The number of replicas that have labels matching the labels of the machine template of the MachineSet.
|
||||
// +optional
|
||||
FullyLabeledReplicas int32 `json:"fullyLabeledReplicas,omitempty"`
|
||||
|
||||
// The number of ready replicas for this MachineSet. A machine is considered ready when the node has been created and is "Ready".
|
||||
// +optional
|
||||
ReadyReplicas int32 `json:"readyReplicas,omitempty"`
|
||||
|
||||
// The number of available replicas (ready for at least minReadySeconds) for this MachineSet.
|
||||
// +optional
|
||||
AvailableReplicas int32 `json:"availableReplicas,omitempty"`
|
||||
|
||||
// ObservedGeneration reflects the generation of the most recently observed MachineSet.
|
||||
// +optional
|
||||
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
|
||||
|
||||
// In the event that there is a terminal problem reconciling the
|
||||
// replicas, both FailureReason and FailureMessage will be set. FailureReason
|
||||
// will be populated with a succinct value suitable for machine
|
||||
// interpretation, while FailureMessage will contain a more verbose
|
||||
// string suitable for logging and human consumption.
|
||||
//
|
||||
// These fields should not be set for transitive errors that a
|
||||
// controller faces that are expected to be fixed automatically over
|
||||
// time (like service outages), but instead indicate that something is
|
||||
// fundamentally wrong with the MachineTemplate's spec or the configuration of
|
||||
// the machine controller, and that manual intervention is required. Examples
|
||||
// of terminal errors would be invalid combinations of settings in the
|
||||
// spec, values that are unsupported by the machine controller, or the
|
||||
// responsible machine controller itself being critically misconfigured.
|
||||
//
|
||||
// Any transient errors that occur during the reconciliation of Machines
|
||||
// can be added as events to the MachineSet object and/or logged in the
|
||||
// controller's output.
|
||||
// +optional
|
||||
FailureReason *capierrors.MachineSetStatusError `json:"failureReason,omitempty"`
|
||||
// +optional
|
||||
FailureMessage *string `json:"failureMessage,omitempty"`
|
||||
}
|
||||
|
||||
// ANCHOR_END: MachineSetStatus
|
||||
|
||||
// Validate validates the MachineSet fields.
|
||||
func (m *MachineSet) Validate() field.ErrorList {
|
||||
errors := field.ErrorList{}
|
||||
|
||||
// validate spec.selector and spec.template.labels
|
||||
fldPath := field.NewPath("spec")
|
||||
errors = append(errors, metav1validation.ValidateLabelSelector(&m.Spec.Selector, fldPath.Child("selector"))...)
|
||||
if len(m.Spec.Selector.MatchLabels)+len(m.Spec.Selector.MatchExpressions) == 0 {
|
||||
errors = append(errors, field.Invalid(fldPath.Child("selector"), m.Spec.Selector, "empty selector is not valid for MachineSet."))
|
||||
}
|
||||
selector, err := metav1.LabelSelectorAsSelector(&m.Spec.Selector)
|
||||
if err != nil {
|
||||
errors = append(errors, field.Invalid(fldPath.Child("selector"), m.Spec.Selector, "invalid label selector."))
|
||||
} else {
|
||||
labels := labels.Set(m.Spec.Template.Labels)
|
||||
if !selector.Matches(labels) {
|
||||
errors = append(errors, field.Invalid(fldPath.Child("template", "metadata", "labels"), m.Spec.Template.Labels, "`selector` does not match template `labels`"))
|
||||
}
|
||||
}
|
||||
|
||||
return errors
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:resource:path=machinesets,shortName=ms,scope=Namespaced,categories=cluster-api
|
||||
// +kubebuilder:storageversion
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:subresource:scale:specpath=.spec.replicas,statuspath=.status.replicas,selectorpath=.status.selector
|
||||
// +kubebuilder:printcolumn:name="Replicas",type="integer",JSONPath=".status.replicas",description="Total number of non-terminated machines targeted by this machineset"
|
||||
// +kubebuilder:printcolumn:name="Available",type="integer",JSONPath=".status.availableReplicas",description="Total number of available machines (ready for at least minReadySeconds)"
|
||||
// +kubebuilder:printcolumn:name="Ready",type="integer",JSONPath=".status.readyReplicas",description="Total number of ready machines targeted by this machineset."
|
||||
|
||||
// MachineSet is the Schema for the machinesets API.
|
||||
type MachineSet struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec MachineSetSpec `json:"spec,omitempty"`
|
||||
Status MachineSetStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
// MachineSetList contains a list of MachineSet.
|
||||
type MachineSetList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []MachineSet `json:"items"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&MachineSet{}, &MachineSetList{})
|
||||
}
|
119
vendor/sigs.k8s.io/cluster-api/api/v1alpha4/machineset_webhook.go
generated
vendored
Normal file
119
vendor/sigs.k8s.io/cluster-api/api/v1alpha4/machineset_webhook.go
generated
vendored
Normal file
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha4
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook"
|
||||
)
|
||||
|
||||
func (m *MachineSet) SetupWebhookWithManager(mgr ctrl.Manager) error {
|
||||
return ctrl.NewWebhookManagedBy(mgr).
|
||||
For(m).
|
||||
Complete()
|
||||
}
|
||||
|
||||
// +kubebuilder:webhook:verbs=create;update,path=/validate-cluster-x-k8s-io-v1alpha4-machineset,mutating=false,failurePolicy=fail,matchPolicy=Equivalent,groups=cluster.x-k8s.io,resources=machinesets,versions=v1alpha4,name=validation.machineset.cluster.x-k8s.io,sideEffects=None,admissionReviewVersions=v1beta1
|
||||
// +kubebuilder:webhook:verbs=create;update,path=/mutate-cluster-x-k8s-io-v1alpha4-machineset,mutating=true,failurePolicy=fail,matchPolicy=Equivalent,groups=cluster.x-k8s.io,resources=machinesets,versions=v1alpha4,name=default.machineset.cluster.x-k8s.io,sideEffects=None,admissionReviewVersions=v1beta1
|
||||
|
||||
var _ webhook.Defaulter = &MachineSet{}
|
||||
var _ webhook.Validator = &MachineSet{}
|
||||
|
||||
// Default sets default MachineSet field values.
|
||||
func (m *MachineSet) Default() {
|
||||
if m.Labels == nil {
|
||||
m.Labels = make(map[string]string)
|
||||
}
|
||||
m.Labels[ClusterLabelName] = m.Spec.ClusterName
|
||||
|
||||
if m.Spec.DeletePolicy == "" {
|
||||
randomPolicy := string(RandomMachineSetDeletePolicy)
|
||||
m.Spec.DeletePolicy = randomPolicy
|
||||
}
|
||||
|
||||
if m.Spec.Selector.MatchLabels == nil {
|
||||
m.Spec.Selector.MatchLabels = make(map[string]string)
|
||||
}
|
||||
|
||||
if m.Spec.Template.Labels == nil {
|
||||
m.Spec.Template.Labels = make(map[string]string)
|
||||
}
|
||||
|
||||
if len(m.Spec.Selector.MatchLabels) == 0 && len(m.Spec.Selector.MatchExpressions) == 0 {
|
||||
m.Spec.Selector.MatchLabels[MachineSetLabelName] = m.Name
|
||||
m.Spec.Template.Labels[MachineSetLabelName] = m.Name
|
||||
}
|
||||
}
|
||||
|
||||
// ValidateCreate implements webhook.Validator so a webhook will be registered for the type.
|
||||
func (m *MachineSet) ValidateCreate() error {
|
||||
return m.validate(nil)
|
||||
}
|
||||
|
||||
// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type.
|
||||
func (m *MachineSet) ValidateUpdate(old runtime.Object) error {
|
||||
oldMS, ok := old.(*MachineSet)
|
||||
if !ok {
|
||||
return apierrors.NewBadRequest(fmt.Sprintf("expected a MachineSet but got a %T", old))
|
||||
}
|
||||
return m.validate(oldMS)
|
||||
}
|
||||
|
||||
// ValidateDelete implements webhook.Validator so a webhook will be registered for the type.
|
||||
func (m *MachineSet) ValidateDelete() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MachineSet) validate(old *MachineSet) error {
|
||||
var allErrs field.ErrorList
|
||||
selector, err := metav1.LabelSelectorAsSelector(&m.Spec.Selector)
|
||||
if err != nil {
|
||||
allErrs = append(
|
||||
allErrs,
|
||||
field.Invalid(field.NewPath("spec", "selector"), m.Spec.Selector, err.Error()),
|
||||
)
|
||||
} else if !selector.Matches(labels.Set(m.Spec.Template.Labels)) {
|
||||
allErrs = append(
|
||||
allErrs,
|
||||
field.Invalid(
|
||||
field.NewPath("spec", "template", "labels"),
|
||||
m.Spec.Template.Labels,
|
||||
fmt.Sprintf("must match spec.selector %q", selector.String()),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
if old != nil && old.Spec.ClusterName != m.Spec.ClusterName {
|
||||
allErrs = append(
|
||||
allErrs,
|
||||
field.Invalid(field.NewPath("spec", "clusterName"), m.Spec.ClusterName, "field is immutable"),
|
||||
)
|
||||
}
|
||||
|
||||
if len(allErrs) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return apierrors.NewInvalid(GroupVersion.WithKind("MachineSet").GroupKind(), m.Name, allErrs)
|
||||
}
|
970
vendor/sigs.k8s.io/cluster-api/api/v1alpha4/zz_generated.deepcopy.go
generated
vendored
Normal file
970
vendor/sigs.k8s.io/cluster-api/api/v1alpha4/zz_generated.deepcopy.go
generated
vendored
Normal file
|
@ -0,0 +1,970 @@
|
|||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by controller-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha4
|
||||
|
||||
import (
|
||||
"k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
"sigs.k8s.io/cluster-api/errors"
|
||||
)
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *APIEndpoint) DeepCopyInto(out *APIEndpoint) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new APIEndpoint.
|
||||
func (in *APIEndpoint) DeepCopy() *APIEndpoint {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(APIEndpoint)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Bootstrap) DeepCopyInto(out *Bootstrap) {
|
||||
*out = *in
|
||||
if in.ConfigRef != nil {
|
||||
in, out := &in.ConfigRef, &out.ConfigRef
|
||||
*out = new(v1.ObjectReference)
|
||||
**out = **in
|
||||
}
|
||||
if in.DataSecretName != nil {
|
||||
in, out := &in.DataSecretName, &out.DataSecretName
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Bootstrap.
|
||||
func (in *Bootstrap) DeepCopy() *Bootstrap {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Bootstrap)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Cluster) DeepCopyInto(out *Cluster) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
in.Status.DeepCopyInto(&out.Status)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Cluster.
|
||||
func (in *Cluster) DeepCopy() *Cluster {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Cluster)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *Cluster) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ClusterList) DeepCopyInto(out *ClusterList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]Cluster, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterList.
|
||||
func (in *ClusterList) DeepCopy() *ClusterList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ClusterList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *ClusterList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ClusterNetwork) DeepCopyInto(out *ClusterNetwork) {
|
||||
*out = *in
|
||||
if in.APIServerPort != nil {
|
||||
in, out := &in.APIServerPort, &out.APIServerPort
|
||||
*out = new(int32)
|
||||
**out = **in
|
||||
}
|
||||
if in.Services != nil {
|
||||
in, out := &in.Services, &out.Services
|
||||
*out = new(NetworkRanges)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.Pods != nil {
|
||||
in, out := &in.Pods, &out.Pods
|
||||
*out = new(NetworkRanges)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterNetwork.
|
||||
func (in *ClusterNetwork) DeepCopy() *ClusterNetwork {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ClusterNetwork)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ClusterSpec) DeepCopyInto(out *ClusterSpec) {
|
||||
*out = *in
|
||||
if in.ClusterNetwork != nil {
|
||||
in, out := &in.ClusterNetwork, &out.ClusterNetwork
|
||||
*out = new(ClusterNetwork)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
out.ControlPlaneEndpoint = in.ControlPlaneEndpoint
|
||||
if in.ControlPlaneRef != nil {
|
||||
in, out := &in.ControlPlaneRef, &out.ControlPlaneRef
|
||||
*out = new(v1.ObjectReference)
|
||||
**out = **in
|
||||
}
|
||||
if in.InfrastructureRef != nil {
|
||||
in, out := &in.InfrastructureRef, &out.InfrastructureRef
|
||||
*out = new(v1.ObjectReference)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterSpec.
|
||||
func (in *ClusterSpec) DeepCopy() *ClusterSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ClusterSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ClusterStatus) DeepCopyInto(out *ClusterStatus) {
|
||||
*out = *in
|
||||
if in.FailureDomains != nil {
|
||||
in, out := &in.FailureDomains, &out.FailureDomains
|
||||
*out = make(FailureDomains, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = *val.DeepCopy()
|
||||
}
|
||||
}
|
||||
if in.FailureReason != nil {
|
||||
in, out := &in.FailureReason, &out.FailureReason
|
||||
*out = new(errors.ClusterStatusError)
|
||||
**out = **in
|
||||
}
|
||||
if in.FailureMessage != nil {
|
||||
in, out := &in.FailureMessage, &out.FailureMessage
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.Conditions != nil {
|
||||
in, out := &in.Conditions, &out.Conditions
|
||||
*out = make(Conditions, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterStatus.
|
||||
func (in *ClusterStatus) DeepCopy() *ClusterStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ClusterStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Condition) DeepCopyInto(out *Condition) {
|
||||
*out = *in
|
||||
in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Condition.
|
||||
func (in *Condition) DeepCopy() *Condition {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Condition)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in Conditions) DeepCopyInto(out *Conditions) {
|
||||
{
|
||||
in := &in
|
||||
*out = make(Conditions, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Conditions.
|
||||
func (in Conditions) DeepCopy() Conditions {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Conditions)
|
||||
in.DeepCopyInto(out)
|
||||
return *out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *FailureDomainSpec) DeepCopyInto(out *FailureDomainSpec) {
|
||||
*out = *in
|
||||
if in.Attributes != nil {
|
||||
in, out := &in.Attributes, &out.Attributes
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FailureDomainSpec.
|
||||
func (in *FailureDomainSpec) DeepCopy() *FailureDomainSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(FailureDomainSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in FailureDomains) DeepCopyInto(out *FailureDomains) {
|
||||
{
|
||||
in := &in
|
||||
*out = make(FailureDomains, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = *val.DeepCopy()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FailureDomains.
|
||||
func (in FailureDomains) DeepCopy() FailureDomains {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(FailureDomains)
|
||||
in.DeepCopyInto(out)
|
||||
return *out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Machine) DeepCopyInto(out *Machine) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
in.Status.DeepCopyInto(&out.Status)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Machine.
|
||||
func (in *Machine) DeepCopy() *Machine {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Machine)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *Machine) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *MachineAddress) DeepCopyInto(out *MachineAddress) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineAddress.
|
||||
func (in *MachineAddress) DeepCopy() *MachineAddress {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(MachineAddress)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in MachineAddresses) DeepCopyInto(out *MachineAddresses) {
|
||||
{
|
||||
in := &in
|
||||
*out = make(MachineAddresses, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineAddresses.
|
||||
func (in MachineAddresses) DeepCopy() MachineAddresses {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(MachineAddresses)
|
||||
in.DeepCopyInto(out)
|
||||
return *out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *MachineDeployment) DeepCopyInto(out *MachineDeployment) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
out.Status = in.Status
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineDeployment.
|
||||
func (in *MachineDeployment) DeepCopy() *MachineDeployment {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(MachineDeployment)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *MachineDeployment) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *MachineDeploymentList) DeepCopyInto(out *MachineDeploymentList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]MachineDeployment, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineDeploymentList.
|
||||
func (in *MachineDeploymentList) DeepCopy() *MachineDeploymentList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(MachineDeploymentList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *MachineDeploymentList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *MachineDeploymentSpec) DeepCopyInto(out *MachineDeploymentSpec) {
|
||||
*out = *in
|
||||
if in.Replicas != nil {
|
||||
in, out := &in.Replicas, &out.Replicas
|
||||
*out = new(int32)
|
||||
**out = **in
|
||||
}
|
||||
in.Selector.DeepCopyInto(&out.Selector)
|
||||
in.Template.DeepCopyInto(&out.Template)
|
||||
if in.Strategy != nil {
|
||||
in, out := &in.Strategy, &out.Strategy
|
||||
*out = new(MachineDeploymentStrategy)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.MinReadySeconds != nil {
|
||||
in, out := &in.MinReadySeconds, &out.MinReadySeconds
|
||||
*out = new(int32)
|
||||
**out = **in
|
||||
}
|
||||
if in.RevisionHistoryLimit != nil {
|
||||
in, out := &in.RevisionHistoryLimit, &out.RevisionHistoryLimit
|
||||
*out = new(int32)
|
||||
**out = **in
|
||||
}
|
||||
if in.ProgressDeadlineSeconds != nil {
|
||||
in, out := &in.ProgressDeadlineSeconds, &out.ProgressDeadlineSeconds
|
||||
*out = new(int32)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineDeploymentSpec.
|
||||
func (in *MachineDeploymentSpec) DeepCopy() *MachineDeploymentSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(MachineDeploymentSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *MachineDeploymentStatus) DeepCopyInto(out *MachineDeploymentStatus) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineDeploymentStatus.
|
||||
func (in *MachineDeploymentStatus) DeepCopy() *MachineDeploymentStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(MachineDeploymentStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *MachineDeploymentStrategy) DeepCopyInto(out *MachineDeploymentStrategy) {
|
||||
*out = *in
|
||||
if in.RollingUpdate != nil {
|
||||
in, out := &in.RollingUpdate, &out.RollingUpdate
|
||||
*out = new(MachineRollingUpdateDeployment)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineDeploymentStrategy.
|
||||
func (in *MachineDeploymentStrategy) DeepCopy() *MachineDeploymentStrategy {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(MachineDeploymentStrategy)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *MachineHealthCheck) DeepCopyInto(out *MachineHealthCheck) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
in.Status.DeepCopyInto(&out.Status)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineHealthCheck.
|
||||
func (in *MachineHealthCheck) DeepCopy() *MachineHealthCheck {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(MachineHealthCheck)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *MachineHealthCheck) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *MachineHealthCheckList) DeepCopyInto(out *MachineHealthCheckList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]MachineHealthCheck, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineHealthCheckList.
|
||||
func (in *MachineHealthCheckList) DeepCopy() *MachineHealthCheckList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(MachineHealthCheckList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *MachineHealthCheckList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *MachineHealthCheckSpec) DeepCopyInto(out *MachineHealthCheckSpec) {
|
||||
*out = *in
|
||||
in.Selector.DeepCopyInto(&out.Selector)
|
||||
if in.UnhealthyConditions != nil {
|
||||
in, out := &in.UnhealthyConditions, &out.UnhealthyConditions
|
||||
*out = make([]UnhealthyCondition, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.MaxUnhealthy != nil {
|
||||
in, out := &in.MaxUnhealthy, &out.MaxUnhealthy
|
||||
*out = new(intstr.IntOrString)
|
||||
**out = **in
|
||||
}
|
||||
if in.UnhealthyRange != nil {
|
||||
in, out := &in.UnhealthyRange, &out.UnhealthyRange
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.NodeStartupTimeout != nil {
|
||||
in, out := &in.NodeStartupTimeout, &out.NodeStartupTimeout
|
||||
*out = new(metav1.Duration)
|
||||
**out = **in
|
||||
}
|
||||
if in.RemediationTemplate != nil {
|
||||
in, out := &in.RemediationTemplate, &out.RemediationTemplate
|
||||
*out = new(v1.ObjectReference)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineHealthCheckSpec.
|
||||
func (in *MachineHealthCheckSpec) DeepCopy() *MachineHealthCheckSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(MachineHealthCheckSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *MachineHealthCheckStatus) DeepCopyInto(out *MachineHealthCheckStatus) {
|
||||
*out = *in
|
||||
if in.Targets != nil {
|
||||
in, out := &in.Targets, &out.Targets
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Conditions != nil {
|
||||
in, out := &in.Conditions, &out.Conditions
|
||||
*out = make(Conditions, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineHealthCheckStatus.
|
||||
func (in *MachineHealthCheckStatus) DeepCopy() *MachineHealthCheckStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(MachineHealthCheckStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *MachineList) DeepCopyInto(out *MachineList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]Machine, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineList.
|
||||
func (in *MachineList) DeepCopy() *MachineList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(MachineList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *MachineList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *MachineRollingUpdateDeployment) DeepCopyInto(out *MachineRollingUpdateDeployment) {
|
||||
*out = *in
|
||||
if in.MaxUnavailable != nil {
|
||||
in, out := &in.MaxUnavailable, &out.MaxUnavailable
|
||||
*out = new(intstr.IntOrString)
|
||||
**out = **in
|
||||
}
|
||||
if in.MaxSurge != nil {
|
||||
in, out := &in.MaxSurge, &out.MaxSurge
|
||||
*out = new(intstr.IntOrString)
|
||||
**out = **in
|
||||
}
|
||||
if in.DeletePolicy != nil {
|
||||
in, out := &in.DeletePolicy, &out.DeletePolicy
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineRollingUpdateDeployment.
|
||||
func (in *MachineRollingUpdateDeployment) DeepCopy() *MachineRollingUpdateDeployment {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(MachineRollingUpdateDeployment)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *MachineSet) DeepCopyInto(out *MachineSet) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
in.Status.DeepCopyInto(&out.Status)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineSet.
|
||||
func (in *MachineSet) DeepCopy() *MachineSet {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(MachineSet)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *MachineSet) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *MachineSetList) DeepCopyInto(out *MachineSetList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]MachineSet, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineSetList.
|
||||
func (in *MachineSetList) DeepCopy() *MachineSetList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(MachineSetList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *MachineSetList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *MachineSetSpec) DeepCopyInto(out *MachineSetSpec) {
|
||||
*out = *in
|
||||
if in.Replicas != nil {
|
||||
in, out := &in.Replicas, &out.Replicas
|
||||
*out = new(int32)
|
||||
**out = **in
|
||||
}
|
||||
in.Selector.DeepCopyInto(&out.Selector)
|
||||
in.Template.DeepCopyInto(&out.Template)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineSetSpec.
|
||||
func (in *MachineSetSpec) DeepCopy() *MachineSetSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(MachineSetSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *MachineSetStatus) DeepCopyInto(out *MachineSetStatus) {
|
||||
*out = *in
|
||||
if in.FailureReason != nil {
|
||||
in, out := &in.FailureReason, &out.FailureReason
|
||||
*out = new(errors.MachineSetStatusError)
|
||||
**out = **in
|
||||
}
|
||||
if in.FailureMessage != nil {
|
||||
in, out := &in.FailureMessage, &out.FailureMessage
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineSetStatus.
|
||||
func (in *MachineSetStatus) DeepCopy() *MachineSetStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(MachineSetStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *MachineSpec) DeepCopyInto(out *MachineSpec) {
|
||||
*out = *in
|
||||
in.Bootstrap.DeepCopyInto(&out.Bootstrap)
|
||||
out.InfrastructureRef = in.InfrastructureRef
|
||||
if in.Version != nil {
|
||||
in, out := &in.Version, &out.Version
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.ProviderID != nil {
|
||||
in, out := &in.ProviderID, &out.ProviderID
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.FailureDomain != nil {
|
||||
in, out := &in.FailureDomain, &out.FailureDomain
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.NodeDrainTimeout != nil {
|
||||
in, out := &in.NodeDrainTimeout, &out.NodeDrainTimeout
|
||||
*out = new(metav1.Duration)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineSpec.
|
||||
func (in *MachineSpec) DeepCopy() *MachineSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(MachineSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *MachineStatus) DeepCopyInto(out *MachineStatus) {
|
||||
*out = *in
|
||||
if in.NodeRef != nil {
|
||||
in, out := &in.NodeRef, &out.NodeRef
|
||||
*out = new(v1.ObjectReference)
|
||||
**out = **in
|
||||
}
|
||||
if in.LastUpdated != nil {
|
||||
in, out := &in.LastUpdated, &out.LastUpdated
|
||||
*out = (*in).DeepCopy()
|
||||
}
|
||||
if in.Version != nil {
|
||||
in, out := &in.Version, &out.Version
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.FailureReason != nil {
|
||||
in, out := &in.FailureReason, &out.FailureReason
|
||||
*out = new(errors.MachineStatusError)
|
||||
**out = **in
|
||||
}
|
||||
if in.FailureMessage != nil {
|
||||
in, out := &in.FailureMessage, &out.FailureMessage
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.Addresses != nil {
|
||||
in, out := &in.Addresses, &out.Addresses
|
||||
*out = make(MachineAddresses, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Conditions != nil {
|
||||
in, out := &in.Conditions, &out.Conditions
|
||||
*out = make(Conditions, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineStatus.
|
||||
func (in *MachineStatus) DeepCopy() *MachineStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(MachineStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *MachineTemplateSpec) DeepCopyInto(out *MachineTemplateSpec) {
|
||||
*out = *in
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineTemplateSpec.
|
||||
func (in *MachineTemplateSpec) DeepCopy() *MachineTemplateSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(MachineTemplateSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *NetworkRanges) DeepCopyInto(out *NetworkRanges) {
|
||||
*out = *in
|
||||
if in.CIDRBlocks != nil {
|
||||
in, out := &in.CIDRBlocks, &out.CIDRBlocks
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetworkRanges.
|
||||
func (in *NetworkRanges) DeepCopy() *NetworkRanges {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(NetworkRanges)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ObjectMeta) DeepCopyInto(out *ObjectMeta) {
|
||||
*out = *in
|
||||
if in.Labels != nil {
|
||||
in, out := &in.Labels, &out.Labels
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.Annotations != nil {
|
||||
in, out := &in.Annotations, &out.Annotations
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ObjectMeta.
|
||||
func (in *ObjectMeta) DeepCopy() *ObjectMeta {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ObjectMeta)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *UnhealthyCondition) DeepCopyInto(out *UnhealthyCondition) {
|
||||
*out = *in
|
||||
out.Timeout = in.Timeout
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UnhealthyCondition.
|
||||
func (in *UnhealthyCondition) DeepCopy() *UnhealthyCondition {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(UnhealthyCondition)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package errors
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// ClusterError is a more descriptive kind of error that represents an error condition that
|
||||
// should be set in the Cluster.Status. The "Reason" field is meant for short,
|
||||
// enum-style constants meant to be interpreted by clusters. The "Message"
|
||||
// field is meant to be read by humans.
|
||||
type ClusterError struct {
|
||||
Reason ClusterStatusError
|
||||
Message string
|
||||
}
|
||||
|
||||
func (e *ClusterError) Error() string {
|
||||
return e.Message
|
||||
}
|
||||
|
||||
// Some error builders for ease of use. They set the appropriate "Reason"
|
||||
// value, and all arguments are Printf-style varargs fed into Sprintf to
|
||||
// construct the Message.
|
||||
|
||||
// InvalidClusterConfiguration creates a new error for when the cluster configuration is invalid.
|
||||
func InvalidClusterConfiguration(format string, args ...interface{}) *ClusterError {
|
||||
return &ClusterError{
|
||||
Reason: InvalidConfigurationClusterError,
|
||||
Message: fmt.Sprintf(format, args...),
|
||||
}
|
||||
}
|
||||
|
||||
// CreateCluster creates a new error for when creating a cluster.
|
||||
func CreateCluster(format string, args ...interface{}) *ClusterError {
|
||||
return &ClusterError{
|
||||
Reason: CreateClusterError,
|
||||
Message: fmt.Sprintf(format, args...),
|
||||
}
|
||||
}
|
||||
|
||||
// DeleteCluster creates a new error for when deleting a cluster.
|
||||
func DeleteCluster(format string, args ...interface{}) *ClusterError {
|
||||
return &ClusterError{
|
||||
Reason: DeleteClusterError,
|
||||
Message: fmt.Sprintf(format, args...),
|
||||
}
|
||||
}
|
|
@ -0,0 +1,158 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package errors
|
||||
|
||||
// MachineStatusError defines errors states for Machine objects.
|
||||
type MachineStatusError string
|
||||
|
||||
// Constants aren't automatically generated for unversioned packages.
|
||||
// Instead share the same constant for all versioned packages.
|
||||
|
||||
const (
|
||||
// InvalidConfigurationMachineError represents that the combination
|
||||
// of configuration in the MachineSpec is not supported by this cluster.
|
||||
// This is not a transient error, but
|
||||
// indicates a state that must be fixed before progress can be made.
|
||||
//
|
||||
// Example: the ProviderSpec specifies an instance type that doesn't exist,.
|
||||
InvalidConfigurationMachineError MachineStatusError = "InvalidConfiguration"
|
||||
|
||||
// UnsupportedChangeMachineError indicates that the MachineSpec has been updated in a way that
|
||||
// is not supported for reconciliation on this cluster. The spec may be
|
||||
// completely valid from a configuration standpoint, but the controller
|
||||
// does not support changing the real world state to match the new
|
||||
// spec.
|
||||
//
|
||||
// Example: the responsible controller is not capable of changing the
|
||||
// container runtime from docker to rkt.
|
||||
UnsupportedChangeMachineError MachineStatusError = "UnsupportedChange"
|
||||
|
||||
// InsufficientResourcesMachineError generally refers to exceeding one's quota in a cloud provider,
|
||||
// or running out of physical machines in an on-premise environment.
|
||||
InsufficientResourcesMachineError MachineStatusError = "InsufficientResources"
|
||||
|
||||
// CreateMachineError indicates an error while trying to create a Node to match this
|
||||
// Machine. This may indicate a transient problem that will be fixed
|
||||
// automatically with time, such as a service outage, or a terminal
|
||||
// error during creation that doesn't match a more specific
|
||||
// MachineStatusError value.
|
||||
//
|
||||
// Example: timeout trying to connect to GCE.
|
||||
CreateMachineError MachineStatusError = "CreateError"
|
||||
|
||||
// UpdateMachineError indicates an error while trying to update a Node that this
|
||||
// Machine represents. This may indicate a transient problem that will be
|
||||
// fixed automatically with time, such as a service outage,
|
||||
//
|
||||
// Example: error updating load balancers.
|
||||
UpdateMachineError MachineStatusError = "UpdateError"
|
||||
|
||||
// DeleteMachineError indicates an error was encountered while trying to delete the Node that this
|
||||
// Machine represents. This could be a transient or terminal error, but
|
||||
// will only be observable if the provider's Machine controller has
|
||||
// added a finalizer to the object to more gracefully handle deletions.
|
||||
//
|
||||
// Example: cannot resolve EC2 IP address.
|
||||
DeleteMachineError MachineStatusError = "DeleteError"
|
||||
|
||||
// JoinClusterTimeoutMachineError indicates that the machine did not join the cluster
|
||||
// as a new node within the expected timeframe after instance
|
||||
// creation at the provider succeeded
|
||||
//
|
||||
// Example use case: A controller that deletes Machines which do
|
||||
// not result in a Node joining the cluster within a given timeout
|
||||
// and that are managed by a MachineSet.
|
||||
JoinClusterTimeoutMachineError = "JoinClusterTimeoutError"
|
||||
)
|
||||
|
||||
// ClusterStatusError defines errors states for Cluster objects.
|
||||
type ClusterStatusError string
|
||||
|
||||
const (
|
||||
// InvalidConfigurationClusterError indicates that the cluster
|
||||
// configuration is invalid.
|
||||
InvalidConfigurationClusterError ClusterStatusError = "InvalidConfiguration"
|
||||
|
||||
// UnsupportedChangeClusterError indicates that the cluster
|
||||
// spec has been updated in an unsupported way. That cannot be
|
||||
// reconciled.
|
||||
UnsupportedChangeClusterError ClusterStatusError = "UnsupportedChange"
|
||||
|
||||
// CreateClusterError indicates that an error was encountered
|
||||
// when trying to create the cluster.
|
||||
CreateClusterError ClusterStatusError = "CreateError"
|
||||
|
||||
// UpdateClusterError indicates that an error was encountered
|
||||
// when trying to update the cluster.
|
||||
UpdateClusterError ClusterStatusError = "UpdateError"
|
||||
|
||||
// DeleteClusterError indicates that an error was encountered
|
||||
// when trying to delete the cluster.
|
||||
DeleteClusterError ClusterStatusError = "DeleteError"
|
||||
)
|
||||
|
||||
// MachineSetStatusError defines errors states for MachineSet objects.
|
||||
type MachineSetStatusError string
|
||||
|
||||
const (
|
||||
// InvalidConfigurationMachineSetError represents
|
||||
// the combination of configuration in the MachineTemplateSpec
|
||||
// is not supported by this cluster. This is not a transient error, but
|
||||
// indicates a state that must be fixed before progress can be made.
|
||||
//
|
||||
// Example: the ProviderSpec specifies an instance type that doesn't exist.
|
||||
InvalidConfigurationMachineSetError MachineSetStatusError = "InvalidConfiguration"
|
||||
)
|
||||
|
||||
// MachinePoolStatusFailure defines errors states for MachinePool objects.
|
||||
type MachinePoolStatusFailure string
|
||||
|
||||
const (
|
||||
// InvalidConfigurationMachinePoolError represemts
|
||||
// the combination of configuration in the MachineTemplateSpec
|
||||
// is not supported by this cluster. This is not a transient error, but
|
||||
// indicates a state that must be fixed before progress can be made.
|
||||
//
|
||||
// Example: the ProviderSpec specifies an instance type that doesn't exist.
|
||||
InvalidConfigurationMachinePoolError MachinePoolStatusFailure = "InvalidConfiguration"
|
||||
)
|
||||
|
||||
// KubeadmControlPlaneStatusError defines errors states for KubeadmControlPlane objects.
|
||||
type KubeadmControlPlaneStatusError string
|
||||
|
||||
const (
|
||||
// InvalidConfigurationKubeadmControlPlaneError indicates that the kubeadm control plane
|
||||
// configuration is invalid.
|
||||
InvalidConfigurationKubeadmControlPlaneError KubeadmControlPlaneStatusError = "InvalidConfiguration"
|
||||
|
||||
// UnsupportedChangeKubeadmControlPlaneError indicates that the kubeadm control plane
|
||||
// spec has been updated in an unsupported way that cannot be
|
||||
// reconciled.
|
||||
UnsupportedChangeKubeadmControlPlaneError KubeadmControlPlaneStatusError = "UnsupportedChange"
|
||||
|
||||
// CreateKubeadmControlPlaneError indicates that an error was encountered
|
||||
// when trying to create the kubeadm control plane.
|
||||
CreateKubeadmControlPlaneError KubeadmControlPlaneStatusError = "CreateError"
|
||||
|
||||
// UpdateKubeadmControlPlaneError indicates that an error was encountered
|
||||
// when trying to update the kubeadm control plane.
|
||||
UpdateKubeadmControlPlaneError KubeadmControlPlaneStatusError = "UpdateError"
|
||||
|
||||
// DeleteKubeadmControlPlaneError indicates that an error was encountered
|
||||
// when trying to delete the kubeadm control plane.
|
||||
DeleteKubeadmControlPlaneError KubeadmControlPlaneStatusError = "DeleteError"
|
||||
)
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
Copyright 2021 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package errors implements error functionality.
|
||||
package errors
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package errors
|
||||
|
||||
// KubeadmControlPlaneError is a more descriptive kind of error that represents an error condition that
|
||||
// should be set in the KubeadmControlPlane.Status. The "Reason" field is meant for short,
|
||||
// enum-style constants meant to be interpreted by control planes. The "Message"
|
||||
// field is meant to be read by humans.
|
||||
type KubeadmControlPlaneError struct {
|
||||
Reason KubeadmControlPlaneStatusError
|
||||
Message string
|
||||
}
|
||||
|
||||
// Error satisfies the error interface.
|
||||
func (e *KubeadmControlPlaneError) Error() string {
|
||||
return e.Message
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package errors
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// MachineError is a more descriptive kind of error that represents an error condition that
|
||||
// should be set in the Machine.Status. The "Reason" field is meant for short,
|
||||
// enum-style constants meant to be interpreted by machines. The "Message"
|
||||
// field is meant to be read by humans.
|
||||
type MachineError struct {
|
||||
Reason MachineStatusError
|
||||
Message string
|
||||
}
|
||||
|
||||
func (e *MachineError) Error() string {
|
||||
return e.Message
|
||||
}
|
||||
|
||||
// Some error builders for ease of use. They set the appropriate "Reason"
|
||||
// value, and all arguments are Printf-style varargs fed into Sprintf to
|
||||
// construct the Message.
|
||||
|
||||
// InvalidMachineConfiguration creates a new error when a Machine has invalid configuration.
|
||||
func InvalidMachineConfiguration(msg string, args ...interface{}) *MachineError {
|
||||
return &MachineError{
|
||||
Reason: InvalidConfigurationMachineError,
|
||||
Message: fmt.Sprintf(msg, args...),
|
||||
}
|
||||
}
|
||||
|
||||
// CreateMachine creates a new error for when creating a Machine.
|
||||
func CreateMachine(msg string, args ...interface{}) *MachineError {
|
||||
return &MachineError{
|
||||
Reason: CreateMachineError,
|
||||
Message: fmt.Sprintf(msg, args...),
|
||||
}
|
||||
}
|
||||
|
||||
// UpdateMachine creates a new error for when updating a Machine.
|
||||
func UpdateMachine(msg string, args ...interface{}) *MachineError {
|
||||
return &MachineError{
|
||||
Reason: UpdateMachineError,
|
||||
Message: fmt.Sprintf(msg, args...),
|
||||
}
|
||||
}
|
||||
|
||||
// DeleteMachine creates a new error for when deleting a Machine.
|
||||
func DeleteMachine(msg string, args ...interface{}) *MachineError {
|
||||
return &MachineError{
|
||||
Reason: DeleteMachineError,
|
||||
Message: fmt.Sprintf(msg, args...),
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package errors
|
||||
|
||||
// MachineStatusErrorPtr converts a MachineStatusError to a pointer.
|
||||
func MachineStatusErrorPtr(v MachineStatusError) *MachineStatusError {
|
||||
return &v
|
||||
}
|
||||
|
||||
// MachinePoolStatusErrorPtr converts a MachinePoolStatusError to a pointer.
|
||||
func MachinePoolStatusErrorPtr(v MachinePoolStatusFailure) *MachinePoolStatusFailure {
|
||||
return &v
|
||||
}
|
||||
|
||||
// ClusterStatusErrorPtr converts a MachineStatusError to a pointer.
|
||||
func ClusterStatusErrorPtr(v ClusterStatusError) *ClusterStatusError {
|
||||
return &v
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
Copyright 2021 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package version implements version handling.
|
||||
package version
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strconv"
|
||||
|
||||
"github.com/blang/semver"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
// KubeSemver is the regex for Kubernetes versions. It requires the "v" prefix.
|
||||
KubeSemver = regexp.MustCompile(`^v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)([-0-9a-zA-Z_\.+]*)?$`)
|
||||
// KubeSemverTolerant is the regex for Kubernetes versions with an optional "v" prefix.
|
||||
KubeSemverTolerant = regexp.MustCompile(`^v?(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)([-0-9a-zA-Z_\.+]*)?$`)
|
||||
)
|
||||
|
||||
// ParseMajorMinorPatch returns a semver.Version from the string provided
|
||||
// by looking only at major.minor.patch and stripping everything else out.
|
||||
// It requires the version to have a "v" prefix.
|
||||
func ParseMajorMinorPatch(version string) (semver.Version, error) {
|
||||
return parseMajorMinorPatch(version, false)
|
||||
}
|
||||
|
||||
// ParseMajorMinorPatchTolerant returns a semver.Version from the string provided
|
||||
// by looking only at major.minor.patch and stripping everything else out.
|
||||
// It does not require the version to have a "v" prefix.
|
||||
func ParseMajorMinorPatchTolerant(version string) (semver.Version, error) {
|
||||
return parseMajorMinorPatch(version, true)
|
||||
}
|
||||
|
||||
// parseMajorMinorPatch returns a semver.Version from the string provided
|
||||
// by looking only at major.minor.patch and stripping everything else out.
|
||||
func parseMajorMinorPatch(version string, tolerant bool) (semver.Version, error) {
|
||||
groups := KubeSemver.FindStringSubmatch(version)
|
||||
if tolerant {
|
||||
groups = KubeSemverTolerant.FindStringSubmatch(version)
|
||||
}
|
||||
if len(groups) < 4 {
|
||||
return semver.Version{}, errors.Errorf("failed to parse major.minor.patch from %q", version)
|
||||
}
|
||||
major, err := strconv.ParseUint(groups[1], 10, 64)
|
||||
if err != nil {
|
||||
return semver.Version{}, errors.Wrapf(err, "failed to parse major version from %q", version)
|
||||
}
|
||||
minor, err := strconv.ParseUint(groups[2], 10, 64)
|
||||
if err != nil {
|
||||
return semver.Version{}, errors.Wrapf(err, "failed to parse minor version from %q", version)
|
||||
}
|
||||
patch, err := strconv.ParseUint(groups[3], 10, 64)
|
||||
if err != nil {
|
||||
return semver.Version{}, errors.Wrapf(err, "failed to parse patch version from %q", version)
|
||||
}
|
||||
return semver.Version{
|
||||
Major: major,
|
||||
Minor: minor,
|
||||
Patch: patch,
|
||||
}, nil
|
||||
}
|
Loading…
Reference in New Issue