mirror of
https://github.com/prometheus/prometheus.git
synced 2024-12-26 06:04:05 -08:00
discovery/k8s: update client library
This commit is contained in:
parent
bd1182d29f
commit
2ff8855ae6
|
@ -23,8 +23,8 @@ import (
|
||||||
"github.com/prometheus/common/log"
|
"github.com/prometheus/common/log"
|
||||||
"github.com/prometheus/common/model"
|
"github.com/prometheus/common/model"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
apiv1 "k8s.io/client-go/1.5/pkg/api/v1"
|
apiv1 "k8s.io/client-go/pkg/api/v1"
|
||||||
"k8s.io/client-go/1.5/tools/cache"
|
"k8s.io/client-go/tools/cache"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Endpoints discovers new endpoint targets.
|
// Endpoints discovers new endpoint targets.
|
||||||
|
|
|
@ -19,8 +19,9 @@ import (
|
||||||
"github.com/prometheus/common/log"
|
"github.com/prometheus/common/log"
|
||||||
"github.com/prometheus/common/model"
|
"github.com/prometheus/common/model"
|
||||||
"github.com/prometheus/prometheus/config"
|
"github.com/prometheus/prometheus/config"
|
||||||
"k8s.io/client-go/1.5/pkg/api/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/client-go/1.5/tools/cache"
|
"k8s.io/client-go/pkg/api/v1"
|
||||||
|
"k8s.io/client-go/tools/cache"
|
||||||
)
|
)
|
||||||
|
|
||||||
func endpointsStoreKeyFunc(obj interface{}) (string, error) {
|
func endpointsStoreKeyFunc(obj interface{}) (string, error) {
|
||||||
|
@ -40,7 +41,7 @@ func makeTestEndpointsDiscovery() (*Endpoints, *fakeInformer, *fakeInformer, *fa
|
||||||
|
|
||||||
func makeEndpoints() *v1.Endpoints {
|
func makeEndpoints() *v1.Endpoints {
|
||||||
return &v1.Endpoints{
|
return &v1.Endpoints{
|
||||||
ObjectMeta: v1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "testendpoints",
|
Name: "testendpoints",
|
||||||
Namespace: "default",
|
Namespace: "default",
|
||||||
},
|
},
|
||||||
|
@ -123,7 +124,7 @@ func TestEndpointsDiscoveryInitial(t *testing.T) {
|
||||||
func TestEndpointsDiscoveryAdd(t *testing.T) {
|
func TestEndpointsDiscoveryAdd(t *testing.T) {
|
||||||
n, _, eps, pods := makeTestEndpointsDiscovery()
|
n, _, eps, pods := makeTestEndpointsDiscovery()
|
||||||
pods.GetStore().Add(&v1.Pod{
|
pods.GetStore().Add(&v1.Pod{
|
||||||
ObjectMeta: v1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "testpod",
|
Name: "testpod",
|
||||||
Namespace: "default",
|
Namespace: "default",
|
||||||
},
|
},
|
||||||
|
@ -164,7 +165,7 @@ func TestEndpointsDiscoveryAdd(t *testing.T) {
|
||||||
go func() {
|
go func() {
|
||||||
eps.Add(
|
eps.Add(
|
||||||
&v1.Endpoints{
|
&v1.Endpoints{
|
||||||
ObjectMeta: v1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "testendpoints",
|
Name: "testendpoints",
|
||||||
Namespace: "default",
|
Namespace: "default",
|
||||||
},
|
},
|
||||||
|
@ -273,7 +274,7 @@ func TestEndpointsDiscoveryUpdate(t *testing.T) {
|
||||||
afterStart: func() {
|
afterStart: func() {
|
||||||
go func() {
|
go func() {
|
||||||
eps.Update(&v1.Endpoints{
|
eps.Update(&v1.Endpoints{
|
||||||
ObjectMeta: v1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "testendpoints",
|
Name: "testendpoints",
|
||||||
Namespace: "default",
|
Namespace: "default",
|
||||||
},
|
},
|
||||||
|
|
|
@ -23,12 +23,12 @@ import (
|
||||||
"github.com/prometheus/common/log"
|
"github.com/prometheus/common/log"
|
||||||
"github.com/prometheus/common/model"
|
"github.com/prometheus/common/model"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
"k8s.io/client-go/1.5/kubernetes"
|
"k8s.io/apimachinery/pkg/util/runtime"
|
||||||
"k8s.io/client-go/1.5/pkg/api"
|
"k8s.io/client-go/kubernetes"
|
||||||
apiv1 "k8s.io/client-go/1.5/pkg/api/v1"
|
"k8s.io/client-go/pkg/api"
|
||||||
"k8s.io/client-go/1.5/pkg/util/runtime"
|
apiv1 "k8s.io/client-go/pkg/api/v1"
|
||||||
"k8s.io/client-go/1.5/rest"
|
"k8s.io/client-go/rest"
|
||||||
"k8s.io/client-go/1.5/tools/cache"
|
"k8s.io/client-go/tools/cache"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -111,8 +111,8 @@ func New(l log.Logger, conf *config.KubernetesSDConfig) (*Kubernetes, error) {
|
||||||
CAFile: conf.TLSConfig.CAFile,
|
CAFile: conf.TLSConfig.CAFile,
|
||||||
CertFile: conf.TLSConfig.CertFile,
|
CertFile: conf.TLSConfig.CertFile,
|
||||||
KeyFile: conf.TLSConfig.KeyFile,
|
KeyFile: conf.TLSConfig.KeyFile,
|
||||||
|
Insecure: conf.TLSConfig.InsecureSkipVerify,
|
||||||
},
|
},
|
||||||
Insecure: conf.TLSConfig.InsecureSkipVerify,
|
|
||||||
}
|
}
|
||||||
token := conf.BearerToken
|
token := conf.BearerToken
|
||||||
if conf.BearerTokenFile != "" {
|
if conf.BearerTokenFile != "" {
|
||||||
|
@ -147,7 +147,7 @@ const resyncPeriod = 10 * time.Minute
|
||||||
|
|
||||||
// Run implements the TargetProvider interface.
|
// Run implements the TargetProvider interface.
|
||||||
func (k *Kubernetes) Run(ctx context.Context, ch chan<- []*config.TargetGroup) {
|
func (k *Kubernetes) Run(ctx context.Context, ch chan<- []*config.TargetGroup) {
|
||||||
rclient := k.client.Core().GetRESTClient()
|
rclient := k.client.Core().RESTClient()
|
||||||
|
|
||||||
switch k.role {
|
switch k.role {
|
||||||
case "endpoints":
|
case "endpoints":
|
||||||
|
|
|
@ -23,9 +23,9 @@ import (
|
||||||
"github.com/prometheus/prometheus/config"
|
"github.com/prometheus/prometheus/config"
|
||||||
"github.com/prometheus/prometheus/util/strutil"
|
"github.com/prometheus/prometheus/util/strutil"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
"k8s.io/client-go/1.5/pkg/api"
|
"k8s.io/client-go/pkg/api"
|
||||||
apiv1 "k8s.io/client-go/1.5/pkg/api/v1"
|
apiv1 "k8s.io/client-go/pkg/api/v1"
|
||||||
"k8s.io/client-go/1.5/tools/cache"
|
"k8s.io/client-go/tools/cache"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Node discovers Kubernetes nodes.
|
// Node discovers Kubernetes nodes.
|
||||||
|
|
|
@ -25,8 +25,9 @@ import (
|
||||||
"github.com/prometheus/prometheus/config"
|
"github.com/prometheus/prometheus/config"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
"k8s.io/client-go/1.5/pkg/api/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/client-go/1.5/tools/cache"
|
"k8s.io/client-go/pkg/api/v1"
|
||||||
|
"k8s.io/client-go/tools/cache"
|
||||||
)
|
)
|
||||||
|
|
||||||
type fakeInformer struct {
|
type fakeInformer struct {
|
||||||
|
@ -46,18 +47,21 @@ func newFakeInformer(f func(obj interface{}) (string, error)) *fakeInformer {
|
||||||
return i
|
return i
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *fakeInformer) AddEventHandler(handler cache.ResourceEventHandler) error {
|
func (i *fakeInformer) AddEventHandler(h cache.ResourceEventHandler) {
|
||||||
i.handlers = append(i.handlers, handler)
|
i.handlers = append(i.handlers, h)
|
||||||
// Only now that there is a registered handler, we are able to handle deltas.
|
// Only now that there is a registered handler, we are able to handle deltas.
|
||||||
i.blockDeltas.Unlock()
|
i.blockDeltas.Unlock()
|
||||||
return nil
|
}
|
||||||
|
|
||||||
|
func (i *fakeInformer) AddEventHandlerWithResyncPeriod(h cache.ResourceEventHandler, _ time.Duration) {
|
||||||
|
i.AddEventHandler(h)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *fakeInformer) GetStore() cache.Store {
|
func (i *fakeInformer) GetStore() cache.Store {
|
||||||
return i.store
|
return i.store
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *fakeInformer) GetController() cache.ControllerInterface {
|
func (i *fakeInformer) GetController() cache.Controller {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,7 +164,7 @@ func makeTestNodeDiscovery() (*Node, *fakeInformer) {
|
||||||
|
|
||||||
func makeNode(name, address string, labels map[string]string, annotations map[string]string) *v1.Node {
|
func makeNode(name, address string, labels map[string]string, annotations map[string]string) *v1.Node {
|
||||||
return &v1.Node{
|
return &v1.Node{
|
||||||
ObjectMeta: v1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: name,
|
Name: name,
|
||||||
Labels: labels,
|
Labels: labels,
|
||||||
Annotations: annotations,
|
Annotations: annotations,
|
||||||
|
|
|
@ -24,9 +24,9 @@ import (
|
||||||
"github.com/prometheus/prometheus/config"
|
"github.com/prometheus/prometheus/config"
|
||||||
"github.com/prometheus/prometheus/util/strutil"
|
"github.com/prometheus/prometheus/util/strutil"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
"k8s.io/client-go/1.5/pkg/api"
|
"k8s.io/client-go/pkg/api"
|
||||||
apiv1 "k8s.io/client-go/1.5/pkg/api/v1"
|
apiv1 "k8s.io/client-go/pkg/api/v1"
|
||||||
"k8s.io/client-go/1.5/tools/cache"
|
"k8s.io/client-go/tools/cache"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Pod discovers new pod targets.
|
// Pod discovers new pod targets.
|
||||||
|
|
|
@ -19,8 +19,9 @@ import (
|
||||||
"github.com/prometheus/common/log"
|
"github.com/prometheus/common/log"
|
||||||
"github.com/prometheus/common/model"
|
"github.com/prometheus/common/model"
|
||||||
"github.com/prometheus/prometheus/config"
|
"github.com/prometheus/prometheus/config"
|
||||||
"k8s.io/client-go/1.5/pkg/api/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/client-go/1.5/tools/cache"
|
"k8s.io/client-go/pkg/api/v1"
|
||||||
|
"k8s.io/client-go/tools/cache"
|
||||||
)
|
)
|
||||||
|
|
||||||
func podStoreKeyFunc(obj interface{}) (string, error) {
|
func podStoreKeyFunc(obj interface{}) (string, error) {
|
||||||
|
@ -38,7 +39,7 @@ func makeTestPodDiscovery() (*Pod, *fakeInformer) {
|
||||||
|
|
||||||
func makeMultiPortPod() *v1.Pod {
|
func makeMultiPortPod() *v1.Pod {
|
||||||
return &v1.Pod{
|
return &v1.Pod{
|
||||||
ObjectMeta: v1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "testpod",
|
Name: "testpod",
|
||||||
Namespace: "default",
|
Namespace: "default",
|
||||||
Labels: map[string]string{"testlabel": "testvalue"},
|
Labels: map[string]string{"testlabel": "testvalue"},
|
||||||
|
@ -82,7 +83,7 @@ func makeMultiPortPod() *v1.Pod {
|
||||||
|
|
||||||
func makePod() *v1.Pod {
|
func makePod() *v1.Pod {
|
||||||
return &v1.Pod{
|
return &v1.Pod{
|
||||||
ObjectMeta: v1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "testpod",
|
Name: "testpod",
|
||||||
Namespace: "default",
|
Namespace: "default",
|
||||||
},
|
},
|
||||||
|
@ -266,7 +267,7 @@ func TestPodDiscoveryDeleteUnknownCacheState(t *testing.T) {
|
||||||
func TestPodDiscoveryUpdate(t *testing.T) {
|
func TestPodDiscoveryUpdate(t *testing.T) {
|
||||||
n, i := makeTestPodDiscovery()
|
n, i := makeTestPodDiscovery()
|
||||||
i.GetStore().Add(&v1.Pod{
|
i.GetStore().Add(&v1.Pod{
|
||||||
ObjectMeta: v1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "testpod",
|
Name: "testpod",
|
||||||
Namespace: "default",
|
Namespace: "default",
|
||||||
},
|
},
|
||||||
|
|
|
@ -23,8 +23,8 @@ import (
|
||||||
"github.com/prometheus/prometheus/config"
|
"github.com/prometheus/prometheus/config"
|
||||||
"github.com/prometheus/prometheus/util/strutil"
|
"github.com/prometheus/prometheus/util/strutil"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
apiv1 "k8s.io/client-go/1.5/pkg/api/v1"
|
apiv1 "k8s.io/client-go/pkg/api/v1"
|
||||||
"k8s.io/client-go/1.5/tools/cache"
|
"k8s.io/client-go/tools/cache"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Service implements discovery of Kubernetes services.
|
// Service implements discovery of Kubernetes services.
|
||||||
|
|
|
@ -20,8 +20,9 @@ import (
|
||||||
"github.com/prometheus/common/log"
|
"github.com/prometheus/common/log"
|
||||||
"github.com/prometheus/common/model"
|
"github.com/prometheus/common/model"
|
||||||
"github.com/prometheus/prometheus/config"
|
"github.com/prometheus/prometheus/config"
|
||||||
"k8s.io/client-go/1.5/pkg/api/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/client-go/1.5/tools/cache"
|
"k8s.io/client-go/pkg/api/v1"
|
||||||
|
"k8s.io/client-go/tools/cache"
|
||||||
)
|
)
|
||||||
|
|
||||||
func serviceStoreKeyFunc(obj interface{}) (string, error) {
|
func serviceStoreKeyFunc(obj interface{}) (string, error) {
|
||||||
|
@ -39,7 +40,7 @@ func makeTestServiceDiscovery() (*Service, *fakeInformer) {
|
||||||
|
|
||||||
func makeMultiPortService() *v1.Service {
|
func makeMultiPortService() *v1.Service {
|
||||||
return &v1.Service{
|
return &v1.Service{
|
||||||
ObjectMeta: v1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "testservice",
|
Name: "testservice",
|
||||||
Namespace: "default",
|
Namespace: "default",
|
||||||
Labels: map[string]string{"testlabel": "testvalue"},
|
Labels: map[string]string{"testlabel": "testvalue"},
|
||||||
|
@ -64,7 +65,7 @@ func makeMultiPortService() *v1.Service {
|
||||||
|
|
||||||
func makeSuffixedService(suffix string) *v1.Service {
|
func makeSuffixedService(suffix string) *v1.Service {
|
||||||
return &v1.Service{
|
return &v1.Service{
|
||||||
ObjectMeta: v1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: fmt.Sprintf("testservice%s", suffix),
|
Name: fmt.Sprintf("testservice%s", suffix),
|
||||||
Namespace: "default",
|
Namespace: "default",
|
||||||
},
|
},
|
||||||
|
|
22
vendor/github.com/blang/semver/LICENSE
generated
vendored
22
vendor/github.com/blang/semver/LICENSE
generated
vendored
|
@ -1,22 +0,0 @@
|
||||||
The MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2014 Benedikt Lang <github at benediktlang.de>
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
|
|
23
vendor/github.com/blang/semver/json.go
generated
vendored
23
vendor/github.com/blang/semver/json.go
generated
vendored
|
@ -1,23 +0,0 @@
|
||||||
package semver
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
)
|
|
||||||
|
|
||||||
// MarshalJSON implements the encoding/json.Marshaler interface.
|
|
||||||
func (v Version) MarshalJSON() ([]byte, error) {
|
|
||||||
return json.Marshal(v.String())
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalJSON implements the encoding/json.Unmarshaler interface.
|
|
||||||
func (v *Version) UnmarshalJSON(data []byte) (err error) {
|
|
||||||
var versionString string
|
|
||||||
|
|
||||||
if err = json.Unmarshal(data, &versionString); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
*v, err = Parse(versionString)
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
395
vendor/github.com/blang/semver/semver.go
generated
vendored
395
vendor/github.com/blang/semver/semver.go
generated
vendored
|
@ -1,395 +0,0 @@
|
||||||
package semver
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
numbers string = "0123456789"
|
|
||||||
alphas = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-"
|
|
||||||
alphanum = alphas + numbers
|
|
||||||
)
|
|
||||||
|
|
||||||
// SpecVersion is the latest fully supported spec version of semver
|
|
||||||
var SpecVersion = Version{
|
|
||||||
Major: 2,
|
|
||||||
Minor: 0,
|
|
||||||
Patch: 0,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Version represents a semver compatible version
|
|
||||||
type Version struct {
|
|
||||||
Major uint64
|
|
||||||
Minor uint64
|
|
||||||
Patch uint64
|
|
||||||
Pre []PRVersion
|
|
||||||
Build []string //No Precendence
|
|
||||||
}
|
|
||||||
|
|
||||||
// Version to string
|
|
||||||
func (v Version) String() string {
|
|
||||||
b := make([]byte, 0, 5)
|
|
||||||
b = strconv.AppendUint(b, v.Major, 10)
|
|
||||||
b = append(b, '.')
|
|
||||||
b = strconv.AppendUint(b, v.Minor, 10)
|
|
||||||
b = append(b, '.')
|
|
||||||
b = strconv.AppendUint(b, v.Patch, 10)
|
|
||||||
|
|
||||||
if len(v.Pre) > 0 {
|
|
||||||
b = append(b, '-')
|
|
||||||
b = append(b, v.Pre[0].String()...)
|
|
||||||
|
|
||||||
for _, pre := range v.Pre[1:] {
|
|
||||||
b = append(b, '.')
|
|
||||||
b = append(b, pre.String()...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(v.Build) > 0 {
|
|
||||||
b = append(b, '+')
|
|
||||||
b = append(b, v.Build[0]...)
|
|
||||||
|
|
||||||
for _, build := range v.Build[1:] {
|
|
||||||
b = append(b, '.')
|
|
||||||
b = append(b, build...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return string(b)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Equals checks if v is equal to o.
|
|
||||||
func (v Version) Equals(o Version) bool {
|
|
||||||
return (v.Compare(o) == 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// EQ checks if v is equal to o.
|
|
||||||
func (v Version) EQ(o Version) bool {
|
|
||||||
return (v.Compare(o) == 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NE checks if v is not equal to o.
|
|
||||||
func (v Version) NE(o Version) bool {
|
|
||||||
return (v.Compare(o) != 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GT checks if v is greater than o.
|
|
||||||
func (v Version) GT(o Version) bool {
|
|
||||||
return (v.Compare(o) == 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GTE checks if v is greater than or equal to o.
|
|
||||||
func (v Version) GTE(o Version) bool {
|
|
||||||
return (v.Compare(o) >= 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GE checks if v is greater than or equal to o.
|
|
||||||
func (v Version) GE(o Version) bool {
|
|
||||||
return (v.Compare(o) >= 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// LT checks if v is less than o.
|
|
||||||
func (v Version) LT(o Version) bool {
|
|
||||||
return (v.Compare(o) == -1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// LTE checks if v is less than or equal to o.
|
|
||||||
func (v Version) LTE(o Version) bool {
|
|
||||||
return (v.Compare(o) <= 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// LE checks if v is less than or equal to o.
|
|
||||||
func (v Version) LE(o Version) bool {
|
|
||||||
return (v.Compare(o) <= 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compare compares Versions v to o:
|
|
||||||
// -1 == v is less than o
|
|
||||||
// 0 == v is equal to o
|
|
||||||
// 1 == v is greater than o
|
|
||||||
func (v Version) Compare(o Version) int {
|
|
||||||
if v.Major != o.Major {
|
|
||||||
if v.Major > o.Major {
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
if v.Minor != o.Minor {
|
|
||||||
if v.Minor > o.Minor {
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
if v.Patch != o.Patch {
|
|
||||||
if v.Patch > o.Patch {
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
|
|
||||||
// Quick comparison if a version has no prerelease versions
|
|
||||||
if len(v.Pre) == 0 && len(o.Pre) == 0 {
|
|
||||||
return 0
|
|
||||||
} else if len(v.Pre) == 0 && len(o.Pre) > 0 {
|
|
||||||
return 1
|
|
||||||
} else if len(v.Pre) > 0 && len(o.Pre) == 0 {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
|
|
||||||
i := 0
|
|
||||||
for ; i < len(v.Pre) && i < len(o.Pre); i++ {
|
|
||||||
if comp := v.Pre[i].Compare(o.Pre[i]); comp == 0 {
|
|
||||||
continue
|
|
||||||
} else if comp == 1 {
|
|
||||||
return 1
|
|
||||||
} else {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If all pr versions are the equal but one has further prversion, this one greater
|
|
||||||
if i == len(v.Pre) && i == len(o.Pre) {
|
|
||||||
return 0
|
|
||||||
} else if i == len(v.Pre) && i < len(o.Pre) {
|
|
||||||
return -1
|
|
||||||
} else {
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate validates v and returns error in case
|
|
||||||
func (v Version) Validate() error {
|
|
||||||
// Major, Minor, Patch already validated using uint64
|
|
||||||
|
|
||||||
for _, pre := range v.Pre {
|
|
||||||
if !pre.IsNum { //Numeric prerelease versions already uint64
|
|
||||||
if len(pre.VersionStr) == 0 {
|
|
||||||
return fmt.Errorf("Prerelease can not be empty %q", pre.VersionStr)
|
|
||||||
}
|
|
||||||
if !containsOnly(pre.VersionStr, alphanum) {
|
|
||||||
return fmt.Errorf("Invalid character(s) found in prerelease %q", pre.VersionStr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, build := range v.Build {
|
|
||||||
if len(build) == 0 {
|
|
||||||
return fmt.Errorf("Build meta data can not be empty %q", build)
|
|
||||||
}
|
|
||||||
if !containsOnly(build, alphanum) {
|
|
||||||
return fmt.Errorf("Invalid character(s) found in build meta data %q", build)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// New is an alias for Parse and returns a pointer, parses version string and returns a validated Version or error
|
|
||||||
func New(s string) (vp *Version, err error) {
|
|
||||||
v, err := Parse(s)
|
|
||||||
vp = &v
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make is an alias for Parse, parses version string and returns a validated Version or error
|
|
||||||
func Make(s string) (Version, error) {
|
|
||||||
return Parse(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse parses version string and returns a validated Version or error
|
|
||||||
func Parse(s string) (Version, error) {
|
|
||||||
if len(s) == 0 {
|
|
||||||
return Version{}, errors.New("Version string empty")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Split into major.minor.(patch+pr+meta)
|
|
||||||
parts := strings.SplitN(s, ".", 3)
|
|
||||||
if len(parts) != 3 {
|
|
||||||
return Version{}, errors.New("No Major.Minor.Patch elements found")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Major
|
|
||||||
if !containsOnly(parts[0], numbers) {
|
|
||||||
return Version{}, fmt.Errorf("Invalid character(s) found in major number %q", parts[0])
|
|
||||||
}
|
|
||||||
if hasLeadingZeroes(parts[0]) {
|
|
||||||
return Version{}, fmt.Errorf("Major number must not contain leading zeroes %q", parts[0])
|
|
||||||
}
|
|
||||||
major, err := strconv.ParseUint(parts[0], 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return Version{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Minor
|
|
||||||
if !containsOnly(parts[1], numbers) {
|
|
||||||
return Version{}, fmt.Errorf("Invalid character(s) found in minor number %q", parts[1])
|
|
||||||
}
|
|
||||||
if hasLeadingZeroes(parts[1]) {
|
|
||||||
return Version{}, fmt.Errorf("Minor number must not contain leading zeroes %q", parts[1])
|
|
||||||
}
|
|
||||||
minor, err := strconv.ParseUint(parts[1], 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return Version{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
v := Version{}
|
|
||||||
v.Major = major
|
|
||||||
v.Minor = minor
|
|
||||||
|
|
||||||
var build, prerelease []string
|
|
||||||
patchStr := parts[2]
|
|
||||||
|
|
||||||
if buildIndex := strings.IndexRune(patchStr, '+'); buildIndex != -1 {
|
|
||||||
build = strings.Split(patchStr[buildIndex+1:], ".")
|
|
||||||
patchStr = patchStr[:buildIndex]
|
|
||||||
}
|
|
||||||
|
|
||||||
if preIndex := strings.IndexRune(patchStr, '-'); preIndex != -1 {
|
|
||||||
prerelease = strings.Split(patchStr[preIndex+1:], ".")
|
|
||||||
patchStr = patchStr[:preIndex]
|
|
||||||
}
|
|
||||||
|
|
||||||
if !containsOnly(patchStr, numbers) {
|
|
||||||
return Version{}, fmt.Errorf("Invalid character(s) found in patch number %q", patchStr)
|
|
||||||
}
|
|
||||||
if hasLeadingZeroes(patchStr) {
|
|
||||||
return Version{}, fmt.Errorf("Patch number must not contain leading zeroes %q", patchStr)
|
|
||||||
}
|
|
||||||
patch, err := strconv.ParseUint(patchStr, 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return Version{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
v.Patch = patch
|
|
||||||
|
|
||||||
// Prerelease
|
|
||||||
for _, prstr := range prerelease {
|
|
||||||
parsedPR, err := NewPRVersion(prstr)
|
|
||||||
if err != nil {
|
|
||||||
return Version{}, err
|
|
||||||
}
|
|
||||||
v.Pre = append(v.Pre, parsedPR)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build meta data
|
|
||||||
for _, str := range build {
|
|
||||||
if len(str) == 0 {
|
|
||||||
return Version{}, errors.New("Build meta data is empty")
|
|
||||||
}
|
|
||||||
if !containsOnly(str, alphanum) {
|
|
||||||
return Version{}, fmt.Errorf("Invalid character(s) found in build meta data %q", str)
|
|
||||||
}
|
|
||||||
v.Build = append(v.Build, str)
|
|
||||||
}
|
|
||||||
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// MustParse is like Parse but panics if the version cannot be parsed.
|
|
||||||
func MustParse(s string) Version {
|
|
||||||
v, err := Parse(s)
|
|
||||||
if err != nil {
|
|
||||||
panic(`semver: Parse(` + s + `): ` + err.Error())
|
|
||||||
}
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// PRVersion represents a PreRelease Version
|
|
||||||
type PRVersion struct {
|
|
||||||
VersionStr string
|
|
||||||
VersionNum uint64
|
|
||||||
IsNum bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewPRVersion creates a new valid prerelease version
|
|
||||||
func NewPRVersion(s string) (PRVersion, error) {
|
|
||||||
if len(s) == 0 {
|
|
||||||
return PRVersion{}, errors.New("Prerelease is empty")
|
|
||||||
}
|
|
||||||
v := PRVersion{}
|
|
||||||
if containsOnly(s, numbers) {
|
|
||||||
if hasLeadingZeroes(s) {
|
|
||||||
return PRVersion{}, fmt.Errorf("Numeric PreRelease version must not contain leading zeroes %q", s)
|
|
||||||
}
|
|
||||||
num, err := strconv.ParseUint(s, 10, 64)
|
|
||||||
|
|
||||||
// Might never be hit, but just in case
|
|
||||||
if err != nil {
|
|
||||||
return PRVersion{}, err
|
|
||||||
}
|
|
||||||
v.VersionNum = num
|
|
||||||
v.IsNum = true
|
|
||||||
} else if containsOnly(s, alphanum) {
|
|
||||||
v.VersionStr = s
|
|
||||||
v.IsNum = false
|
|
||||||
} else {
|
|
||||||
return PRVersion{}, fmt.Errorf("Invalid character(s) found in prerelease %q", s)
|
|
||||||
}
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsNumeric checks if prerelease-version is numeric
|
|
||||||
func (v PRVersion) IsNumeric() bool {
|
|
||||||
return v.IsNum
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compare compares two PreRelease Versions v and o:
|
|
||||||
// -1 == v is less than o
|
|
||||||
// 0 == v is equal to o
|
|
||||||
// 1 == v is greater than o
|
|
||||||
func (v PRVersion) Compare(o PRVersion) int {
|
|
||||||
if v.IsNum && !o.IsNum {
|
|
||||||
return -1
|
|
||||||
} else if !v.IsNum && o.IsNum {
|
|
||||||
return 1
|
|
||||||
} else if v.IsNum && o.IsNum {
|
|
||||||
if v.VersionNum == o.VersionNum {
|
|
||||||
return 0
|
|
||||||
} else if v.VersionNum > o.VersionNum {
|
|
||||||
return 1
|
|
||||||
} else {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
} else { // both are Alphas
|
|
||||||
if v.VersionStr == o.VersionStr {
|
|
||||||
return 0
|
|
||||||
} else if v.VersionStr > o.VersionStr {
|
|
||||||
return 1
|
|
||||||
} else {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// PreRelease version to string
|
|
||||||
func (v PRVersion) String() string {
|
|
||||||
if v.IsNum {
|
|
||||||
return strconv.FormatUint(v.VersionNum, 10)
|
|
||||||
}
|
|
||||||
return v.VersionStr
|
|
||||||
}
|
|
||||||
|
|
||||||
func containsOnly(s string, set string) bool {
|
|
||||||
return strings.IndexFunc(s, func(r rune) bool {
|
|
||||||
return !strings.ContainsRune(set, r)
|
|
||||||
}) == -1
|
|
||||||
}
|
|
||||||
|
|
||||||
func hasLeadingZeroes(s string) bool {
|
|
||||||
return len(s) > 1 && s[0] == '0'
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewBuildVersion creates a new valid build version
|
|
||||||
func NewBuildVersion(s string) (string, error) {
|
|
||||||
if len(s) == 0 {
|
|
||||||
return "", errors.New("Buildversion is empty")
|
|
||||||
}
|
|
||||||
if !containsOnly(s, alphanum) {
|
|
||||||
return "", fmt.Errorf("Invalid character(s) found in build meta data %q", s)
|
|
||||||
}
|
|
||||||
return s, nil
|
|
||||||
}
|
|
28
vendor/github.com/blang/semver/sort.go
generated
vendored
28
vendor/github.com/blang/semver/sort.go
generated
vendored
|
@ -1,28 +0,0 @@
|
||||||
package semver
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sort"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Versions represents multiple versions.
|
|
||||||
type Versions []Version
|
|
||||||
|
|
||||||
// Len returns length of version collection
|
|
||||||
func (s Versions) Len() int {
|
|
||||||
return len(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Swap swaps two versions inside the collection by its indices
|
|
||||||
func (s Versions) Swap(i, j int) {
|
|
||||||
s[i], s[j] = s[j], s[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Less checks if version at index i is less than version at index j
|
|
||||||
func (s Versions) Less(i, j int) bool {
|
|
||||||
return s[i].LT(s[j])
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sort sorts a slice of versions
|
|
||||||
func Sort(versions []Version) {
|
|
||||||
sort.Sort(Versions(versions))
|
|
||||||
}
|
|
30
vendor/github.com/blang/semver/sql.go
generated
vendored
30
vendor/github.com/blang/semver/sql.go
generated
vendored
|
@ -1,30 +0,0 @@
|
||||||
package semver
|
|
||||||
|
|
||||||
import (
|
|
||||||
"database/sql/driver"
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Scan implements the database/sql.Scanner interface.
|
|
||||||
func (v *Version) Scan(src interface{}) (err error) {
|
|
||||||
var str string
|
|
||||||
switch src := src.(type) {
|
|
||||||
case string:
|
|
||||||
str = src
|
|
||||||
case []byte:
|
|
||||||
str = string(src)
|
|
||||||
default:
|
|
||||||
return fmt.Errorf("Version.Scan: cannot convert %T to string.", src)
|
|
||||||
}
|
|
||||||
|
|
||||||
if t, err := Parse(str); err == nil {
|
|
||||||
*v = t
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Value implements the database/sql/driver.Valuer interface.
|
|
||||||
func (v Version) Value() (driver.Value, error) {
|
|
||||||
return v.String(), nil
|
|
||||||
}
|
|
202
vendor/github.com/coreos/go-oidc/LICENSE
generated
vendored
202
vendor/github.com/coreos/go-oidc/LICENSE
generated
vendored
|
@ -1,202 +0,0 @@
|
||||||
Apache License
|
|
||||||
Version 2.0, January 2004
|
|
||||||
http://www.apache.org/licenses/
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
||||||
|
|
||||||
1. Definitions.
|
|
||||||
|
|
||||||
"License" shall mean the terms and conditions for use, reproduction,
|
|
||||||
and distribution as defined by Sections 1 through 9 of this document.
|
|
||||||
|
|
||||||
"Licensor" shall mean the copyright owner or entity authorized by
|
|
||||||
the copyright owner that is granting the License.
|
|
||||||
|
|
||||||
"Legal Entity" shall mean the union of the acting entity and all
|
|
||||||
other entities that control, are controlled by, or are under common
|
|
||||||
control with that entity. For the purposes of this definition,
|
|
||||||
"control" means (i) the power, direct or indirect, to cause the
|
|
||||||
direction or management of such entity, whether by contract or
|
|
||||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
||||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
||||||
|
|
||||||
"You" (or "Your") shall mean an individual or Legal Entity
|
|
||||||
exercising permissions granted by this License.
|
|
||||||
|
|
||||||
"Source" form shall mean the preferred form for making modifications,
|
|
||||||
including but not limited to software source code, documentation
|
|
||||||
source, and configuration files.
|
|
||||||
|
|
||||||
"Object" form shall mean any form resulting from mechanical
|
|
||||||
transformation or translation of a Source form, including but
|
|
||||||
not limited to compiled object code, generated documentation,
|
|
||||||
and conversions to other media types.
|
|
||||||
|
|
||||||
"Work" shall mean the work of authorship, whether in Source or
|
|
||||||
Object form, made available under the License, as indicated by a
|
|
||||||
copyright notice that is included in or attached to the work
|
|
||||||
(an example is provided in the Appendix below).
|
|
||||||
|
|
||||||
"Derivative Works" shall mean any work, whether in Source or Object
|
|
||||||
form, that is based on (or derived from) the Work and for which the
|
|
||||||
editorial revisions, annotations, elaborations, or other modifications
|
|
||||||
represent, as a whole, an original work of authorship. For the purposes
|
|
||||||
of this License, Derivative Works shall not include works that remain
|
|
||||||
separable from, or merely link (or bind by name) to the interfaces of,
|
|
||||||
the Work and Derivative Works thereof.
|
|
||||||
|
|
||||||
"Contribution" shall mean any work of authorship, including
|
|
||||||
the original version of the Work and any modifications or additions
|
|
||||||
to that Work or Derivative Works thereof, that is intentionally
|
|
||||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
||||||
or by an individual or Legal Entity authorized to submit on behalf of
|
|
||||||
the copyright owner. For the purposes of this definition, "submitted"
|
|
||||||
means any form of electronic, verbal, or written communication sent
|
|
||||||
to the Licensor or its representatives, including but not limited to
|
|
||||||
communication on electronic mailing lists, source code control systems,
|
|
||||||
and issue tracking systems that are managed by, or on behalf of, the
|
|
||||||
Licensor for the purpose of discussing and improving the Work, but
|
|
||||||
excluding communication that is conspicuously marked or otherwise
|
|
||||||
designated in writing by the copyright owner as "Not a Contribution."
|
|
||||||
|
|
||||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
||||||
on behalf of whom a Contribution has been received by Licensor and
|
|
||||||
subsequently incorporated within the Work.
|
|
||||||
|
|
||||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
copyright license to reproduce, prepare Derivative Works of,
|
|
||||||
publicly display, publicly perform, sublicense, and distribute the
|
|
||||||
Work and such Derivative Works in Source or Object form.
|
|
||||||
|
|
||||||
3. Grant of Patent License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
(except as stated in this section) patent license to make, have made,
|
|
||||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
||||||
where such license applies only to those patent claims licensable
|
|
||||||
by such Contributor that are necessarily infringed by their
|
|
||||||
Contribution(s) alone or by combination of their Contribution(s)
|
|
||||||
with the Work to which such Contribution(s) was submitted. If You
|
|
||||||
institute patent litigation against any entity (including a
|
|
||||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
||||||
or a Contribution incorporated within the Work constitutes direct
|
|
||||||
or contributory patent infringement, then any patent licenses
|
|
||||||
granted to You under this License for that Work shall terminate
|
|
||||||
as of the date such litigation is filed.
|
|
||||||
|
|
||||||
4. Redistribution. You may reproduce and distribute copies of the
|
|
||||||
Work or Derivative Works thereof in any medium, with or without
|
|
||||||
modifications, and in Source or Object form, provided that You
|
|
||||||
meet the following conditions:
|
|
||||||
|
|
||||||
(a) You must give any other recipients of the Work or
|
|
||||||
Derivative Works a copy of this License; and
|
|
||||||
|
|
||||||
(b) You must cause any modified files to carry prominent notices
|
|
||||||
stating that You changed the files; and
|
|
||||||
|
|
||||||
(c) You must retain, in the Source form of any Derivative Works
|
|
||||||
that You distribute, all copyright, patent, trademark, and
|
|
||||||
attribution notices from the Source form of the Work,
|
|
||||||
excluding those notices that do not pertain to any part of
|
|
||||||
the Derivative Works; and
|
|
||||||
|
|
||||||
(d) If the Work includes a "NOTICE" text file as part of its
|
|
||||||
distribution, then any Derivative Works that You distribute must
|
|
||||||
include a readable copy of the attribution notices contained
|
|
||||||
within such NOTICE file, excluding those notices that do not
|
|
||||||
pertain to any part of the Derivative Works, in at least one
|
|
||||||
of the following places: within a NOTICE text file distributed
|
|
||||||
as part of the Derivative Works; within the Source form or
|
|
||||||
documentation, if provided along with the Derivative Works; or,
|
|
||||||
within a display generated by the Derivative Works, if and
|
|
||||||
wherever such third-party notices normally appear. The contents
|
|
||||||
of the NOTICE file are for informational purposes only and
|
|
||||||
do not modify the License. You may add Your own attribution
|
|
||||||
notices within Derivative Works that You distribute, alongside
|
|
||||||
or as an addendum to the NOTICE text from the Work, provided
|
|
||||||
that such additional attribution notices cannot be construed
|
|
||||||
as modifying the License.
|
|
||||||
|
|
||||||
You may add Your own copyright statement to Your modifications and
|
|
||||||
may provide additional or different license terms and conditions
|
|
||||||
for use, reproduction, or distribution of Your modifications, or
|
|
||||||
for any such Derivative Works as a whole, provided Your use,
|
|
||||||
reproduction, and distribution of the Work otherwise complies with
|
|
||||||
the conditions stated in this License.
|
|
||||||
|
|
||||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
||||||
any Contribution intentionally submitted for inclusion in the Work
|
|
||||||
by You to the Licensor shall be under the terms and conditions of
|
|
||||||
this License, without any additional terms or conditions.
|
|
||||||
Notwithstanding the above, nothing herein shall supersede or modify
|
|
||||||
the terms of any separate license agreement you may have executed
|
|
||||||
with Licensor regarding such Contributions.
|
|
||||||
|
|
||||||
6. Trademarks. This License does not grant permission to use the trade
|
|
||||||
names, trademarks, service marks, or product names of the Licensor,
|
|
||||||
except as required for reasonable and customary use in describing the
|
|
||||||
origin of the Work and reproducing the content of the NOTICE file.
|
|
||||||
|
|
||||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
||||||
agreed to in writing, Licensor provides the Work (and each
|
|
||||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
||||||
implied, including, without limitation, any warranties or conditions
|
|
||||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
||||||
appropriateness of using or redistributing the Work and assume any
|
|
||||||
risks associated with Your exercise of permissions under this License.
|
|
||||||
|
|
||||||
8. Limitation of Liability. In no event and under no legal theory,
|
|
||||||
whether in tort (including negligence), contract, or otherwise,
|
|
||||||
unless required by applicable law (such as deliberate and grossly
|
|
||||||
negligent acts) or agreed to in writing, shall any Contributor be
|
|
||||||
liable to You for damages, including any direct, indirect, special,
|
|
||||||
incidental, or consequential damages of any character arising as a
|
|
||||||
result of this License or out of the use or inability to use the
|
|
||||||
Work (including but not limited to damages for loss of goodwill,
|
|
||||||
work stoppage, computer failure or malfunction, or any and all
|
|
||||||
other commercial damages or losses), even if such Contributor
|
|
||||||
has been advised of the possibility of such damages.
|
|
||||||
|
|
||||||
9. Accepting Warranty or Additional Liability. While redistributing
|
|
||||||
the Work or Derivative Works thereof, You may choose to offer,
|
|
||||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
||||||
or other liability obligations and/or rights consistent with this
|
|
||||||
License. However, in accepting such obligations, You may act only
|
|
||||||
on Your own behalf and on Your sole responsibility, not on behalf
|
|
||||||
of any other Contributor, and only if You agree to indemnify,
|
|
||||||
defend, and hold each Contributor harmless for any liability
|
|
||||||
incurred by, or claims asserted against, such Contributor by reason
|
|
||||||
of your accepting any such warranty or additional liability.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
APPENDIX: How to apply the Apache License to your work.
|
|
||||||
|
|
||||||
To apply the Apache License to your work, attach the following
|
|
||||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
|
||||||
replaced with your own identifying information. (Don't include
|
|
||||||
the brackets!) The text should be enclosed in the appropriate
|
|
||||||
comment syntax for the file format. We also recommend that a
|
|
||||||
file or class name and description of purpose be included on the
|
|
||||||
same "printed page" as the copyright notice for easier
|
|
||||||
identification within third-party archives.
|
|
||||||
|
|
||||||
Copyright {yyyy} {name of copyright owner}
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
|
|
5
vendor/github.com/coreos/go-oidc/NOTICE
generated
vendored
5
vendor/github.com/coreos/go-oidc/NOTICE
generated
vendored
|
@ -1,5 +0,0 @@
|
||||||
CoreOS Project
|
|
||||||
Copyright 2014 CoreOS, Inc
|
|
||||||
|
|
||||||
This product includes software developed at CoreOS, Inc.
|
|
||||||
(http://www.coreos.com/).
|
|
7
vendor/github.com/coreos/go-oidc/http/client.go
generated
vendored
7
vendor/github.com/coreos/go-oidc/http/client.go
generated
vendored
|
@ -1,7 +0,0 @@
|
||||||
package http
|
|
||||||
|
|
||||||
import "net/http"
|
|
||||||
|
|
||||||
type Client interface {
|
|
||||||
Do(*http.Request) (*http.Response, error)
|
|
||||||
}
|
|
156
vendor/github.com/coreos/go-oidc/http/http.go
generated
vendored
156
vendor/github.com/coreos/go-oidc/http/http.go
generated
vendored
|
@ -1,156 +0,0 @@
|
||||||
package http
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/base64"
|
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
|
||||||
"log"
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
"path"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func WriteError(w http.ResponseWriter, code int, msg string) {
|
|
||||||
e := struct {
|
|
||||||
Error string `json:"error"`
|
|
||||||
}{
|
|
||||||
Error: msg,
|
|
||||||
}
|
|
||||||
b, err := json.Marshal(e)
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("go-oidc: failed to marshal %#v: %v", e, err)
|
|
||||||
code = http.StatusInternalServerError
|
|
||||||
b = []byte(`{"error":"server_error"}`)
|
|
||||||
}
|
|
||||||
w.Header().Set("Content-Type", "application/json")
|
|
||||||
w.WriteHeader(code)
|
|
||||||
w.Write(b)
|
|
||||||
}
|
|
||||||
|
|
||||||
// BasicAuth parses a username and password from the request's
|
|
||||||
// Authorization header. This was pulled from golang master:
|
|
||||||
// https://codereview.appspot.com/76540043
|
|
||||||
func BasicAuth(r *http.Request) (username, password string, ok bool) {
|
|
||||||
auth := r.Header.Get("Authorization")
|
|
||||||
if auth == "" {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if !strings.HasPrefix(auth, "Basic ") {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
c, err := base64.StdEncoding.DecodeString(strings.TrimPrefix(auth, "Basic "))
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
cs := string(c)
|
|
||||||
s := strings.IndexByte(cs, ':')
|
|
||||||
if s < 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return cs[:s], cs[s+1:], true
|
|
||||||
}
|
|
||||||
|
|
||||||
func cacheControlMaxAge(hdr string) (time.Duration, bool, error) {
|
|
||||||
for _, field := range strings.Split(hdr, ",") {
|
|
||||||
parts := strings.SplitN(strings.TrimSpace(field), "=", 2)
|
|
||||||
k := strings.ToLower(strings.TrimSpace(parts[0]))
|
|
||||||
if k != "max-age" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(parts) == 1 {
|
|
||||||
return 0, false, errors.New("max-age has no value")
|
|
||||||
}
|
|
||||||
|
|
||||||
v := strings.TrimSpace(parts[1])
|
|
||||||
if v == "" {
|
|
||||||
return 0, false, errors.New("max-age has empty value")
|
|
||||||
}
|
|
||||||
|
|
||||||
age, err := strconv.Atoi(v)
|
|
||||||
if err != nil {
|
|
||||||
return 0, false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if age <= 0 {
|
|
||||||
return 0, false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return time.Duration(age) * time.Second, true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0, false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func expires(date, expires string) (time.Duration, bool, error) {
|
|
||||||
if date == "" || expires == "" {
|
|
||||||
return 0, false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
te, err := time.Parse(time.RFC1123, expires)
|
|
||||||
if err != nil {
|
|
||||||
return 0, false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
td, err := time.Parse(time.RFC1123, date)
|
|
||||||
if err != nil {
|
|
||||||
return 0, false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
ttl := te.Sub(td)
|
|
||||||
|
|
||||||
// headers indicate data already expired, caller should not
|
|
||||||
// have to care about this case
|
|
||||||
if ttl <= 0 {
|
|
||||||
return 0, false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return ttl, true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func Cacheable(hdr http.Header) (time.Duration, bool, error) {
|
|
||||||
ttl, ok, err := cacheControlMaxAge(hdr.Get("Cache-Control"))
|
|
||||||
if err != nil || ok {
|
|
||||||
return ttl, ok, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return expires(hdr.Get("Date"), hdr.Get("Expires"))
|
|
||||||
}
|
|
||||||
|
|
||||||
// MergeQuery appends additional query values to an existing URL.
|
|
||||||
func MergeQuery(u url.URL, q url.Values) url.URL {
|
|
||||||
uv := u.Query()
|
|
||||||
for k, vs := range q {
|
|
||||||
for _, v := range vs {
|
|
||||||
uv.Add(k, v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
u.RawQuery = uv.Encode()
|
|
||||||
return u
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewResourceLocation appends a resource id to the end of the requested URL path.
|
|
||||||
func NewResourceLocation(reqURL *url.URL, id string) string {
|
|
||||||
var u url.URL
|
|
||||||
u = *reqURL
|
|
||||||
u.Path = path.Join(u.Path, id)
|
|
||||||
u.RawQuery = ""
|
|
||||||
u.Fragment = ""
|
|
||||||
return u.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
// CopyRequest returns a clone of the provided *http.Request.
|
|
||||||
// The returned object is a shallow copy of the struct and a
|
|
||||||
// deep copy of its Header field.
|
|
||||||
func CopyRequest(r *http.Request) *http.Request {
|
|
||||||
r2 := *r
|
|
||||||
r2.Header = make(http.Header)
|
|
||||||
for k, s := range r.Header {
|
|
||||||
r2.Header[k] = s
|
|
||||||
}
|
|
||||||
return &r2
|
|
||||||
}
|
|
29
vendor/github.com/coreos/go-oidc/http/url.go
generated
vendored
29
vendor/github.com/coreos/go-oidc/http/url.go
generated
vendored
|
@ -1,29 +0,0 @@
|
||||||
package http
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"net/url"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ParseNonEmptyURL checks that a string is a parsable URL which is also not empty
|
|
||||||
// since `url.Parse("")` does not return an error. Must contian a scheme and a host.
|
|
||||||
func ParseNonEmptyURL(u string) (*url.URL, error) {
|
|
||||||
if u == "" {
|
|
||||||
return nil, errors.New("url is empty")
|
|
||||||
}
|
|
||||||
|
|
||||||
ur, err := url.Parse(u)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if ur.Scheme == "" {
|
|
||||||
return nil, errors.New("url scheme is empty")
|
|
||||||
}
|
|
||||||
|
|
||||||
if ur.Host == "" {
|
|
||||||
return nil, errors.New("url host is empty")
|
|
||||||
}
|
|
||||||
|
|
||||||
return ur, nil
|
|
||||||
}
|
|
126
vendor/github.com/coreos/go-oidc/jose/claims.go
generated
vendored
126
vendor/github.com/coreos/go-oidc/jose/claims.go
generated
vendored
|
@ -1,126 +0,0 @@
|
||||||
package jose
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"math"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Claims map[string]interface{}
|
|
||||||
|
|
||||||
func (c Claims) Add(name string, value interface{}) {
|
|
||||||
c[name] = value
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c Claims) StringClaim(name string) (string, bool, error) {
|
|
||||||
cl, ok := c[name]
|
|
||||||
if !ok {
|
|
||||||
return "", false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
v, ok := cl.(string)
|
|
||||||
if !ok {
|
|
||||||
return "", false, fmt.Errorf("unable to parse claim as string: %v", name)
|
|
||||||
}
|
|
||||||
|
|
||||||
return v, true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c Claims) StringsClaim(name string) ([]string, bool, error) {
|
|
||||||
cl, ok := c[name]
|
|
||||||
if !ok {
|
|
||||||
return nil, false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if v, ok := cl.([]string); ok {
|
|
||||||
return v, true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// When unmarshaled, []string will become []interface{}.
|
|
||||||
if v, ok := cl.([]interface{}); ok {
|
|
||||||
var ret []string
|
|
||||||
for _, vv := range v {
|
|
||||||
str, ok := vv.(string)
|
|
||||||
if !ok {
|
|
||||||
return nil, false, fmt.Errorf("unable to parse claim as string array: %v", name)
|
|
||||||
}
|
|
||||||
ret = append(ret, str)
|
|
||||||
}
|
|
||||||
return ret, true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil, false, fmt.Errorf("unable to parse claim as string array: %v", name)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c Claims) Int64Claim(name string) (int64, bool, error) {
|
|
||||||
cl, ok := c[name]
|
|
||||||
if !ok {
|
|
||||||
return 0, false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
v, ok := cl.(int64)
|
|
||||||
if !ok {
|
|
||||||
vf, ok := cl.(float64)
|
|
||||||
if !ok {
|
|
||||||
return 0, false, fmt.Errorf("unable to parse claim as int64: %v", name)
|
|
||||||
}
|
|
||||||
v = int64(vf)
|
|
||||||
}
|
|
||||||
|
|
||||||
return v, true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c Claims) Float64Claim(name string) (float64, bool, error) {
|
|
||||||
cl, ok := c[name]
|
|
||||||
if !ok {
|
|
||||||
return 0, false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
v, ok := cl.(float64)
|
|
||||||
if !ok {
|
|
||||||
vi, ok := cl.(int64)
|
|
||||||
if !ok {
|
|
||||||
return 0, false, fmt.Errorf("unable to parse claim as float64: %v", name)
|
|
||||||
}
|
|
||||||
v = float64(vi)
|
|
||||||
}
|
|
||||||
|
|
||||||
return v, true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c Claims) TimeClaim(name string) (time.Time, bool, error) {
|
|
||||||
v, ok, err := c.Float64Claim(name)
|
|
||||||
if !ok || err != nil {
|
|
||||||
return time.Time{}, ok, err
|
|
||||||
}
|
|
||||||
|
|
||||||
s := math.Trunc(v)
|
|
||||||
ns := (v - s) * math.Pow(10, 9)
|
|
||||||
return time.Unix(int64(s), int64(ns)).UTC(), true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func decodeClaims(payload []byte) (Claims, error) {
|
|
||||||
var c Claims
|
|
||||||
if err := json.Unmarshal(payload, &c); err != nil {
|
|
||||||
return nil, fmt.Errorf("malformed JWT claims, unable to decode: %v", err)
|
|
||||||
}
|
|
||||||
return c, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func marshalClaims(c Claims) ([]byte, error) {
|
|
||||||
b, err := json.Marshal(c)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return b, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func encodeClaims(c Claims) (string, error) {
|
|
||||||
b, err := marshalClaims(c)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
return encodeSegment(b), nil
|
|
||||||
}
|
|
112
vendor/github.com/coreos/go-oidc/jose/jose.go
generated
vendored
112
vendor/github.com/coreos/go-oidc/jose/jose.go
generated
vendored
|
@ -1,112 +0,0 @@
|
||||||
package jose
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/base64"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
HeaderMediaType = "typ"
|
|
||||||
HeaderKeyAlgorithm = "alg"
|
|
||||||
HeaderKeyID = "kid"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// Encryption Algorithm Header Parameter Values for JWS
|
|
||||||
// See: https://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-40#page-6
|
|
||||||
AlgHS256 = "HS256"
|
|
||||||
AlgHS384 = "HS384"
|
|
||||||
AlgHS512 = "HS512"
|
|
||||||
AlgRS256 = "RS256"
|
|
||||||
AlgRS384 = "RS384"
|
|
||||||
AlgRS512 = "RS512"
|
|
||||||
AlgES256 = "ES256"
|
|
||||||
AlgES384 = "ES384"
|
|
||||||
AlgES512 = "ES512"
|
|
||||||
AlgPS256 = "PS256"
|
|
||||||
AlgPS384 = "PS384"
|
|
||||||
AlgPS512 = "PS512"
|
|
||||||
AlgNone = "none"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// Algorithm Header Parameter Values for JWE
|
|
||||||
// See: https://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-40#section-4.1
|
|
||||||
AlgRSA15 = "RSA1_5"
|
|
||||||
AlgRSAOAEP = "RSA-OAEP"
|
|
||||||
AlgRSAOAEP256 = "RSA-OAEP-256"
|
|
||||||
AlgA128KW = "A128KW"
|
|
||||||
AlgA192KW = "A192KW"
|
|
||||||
AlgA256KW = "A256KW"
|
|
||||||
AlgDir = "dir"
|
|
||||||
AlgECDHES = "ECDH-ES"
|
|
||||||
AlgECDHESA128KW = "ECDH-ES+A128KW"
|
|
||||||
AlgECDHESA192KW = "ECDH-ES+A192KW"
|
|
||||||
AlgECDHESA256KW = "ECDH-ES+A256KW"
|
|
||||||
AlgA128GCMKW = "A128GCMKW"
|
|
||||||
AlgA192GCMKW = "A192GCMKW"
|
|
||||||
AlgA256GCMKW = "A256GCMKW"
|
|
||||||
AlgPBES2HS256A128KW = "PBES2-HS256+A128KW"
|
|
||||||
AlgPBES2HS384A192KW = "PBES2-HS384+A192KW"
|
|
||||||
AlgPBES2HS512A256KW = "PBES2-HS512+A256KW"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// Encryption Algorithm Header Parameter Values for JWE
|
|
||||||
// See: https://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-40#page-22
|
|
||||||
EncA128CBCHS256 = "A128CBC-HS256"
|
|
||||||
EncA128CBCHS384 = "A128CBC-HS384"
|
|
||||||
EncA256CBCHS512 = "A256CBC-HS512"
|
|
||||||
EncA128GCM = "A128GCM"
|
|
||||||
EncA192GCM = "A192GCM"
|
|
||||||
EncA256GCM = "A256GCM"
|
|
||||||
)
|
|
||||||
|
|
||||||
type JOSEHeader map[string]string
|
|
||||||
|
|
||||||
func (j JOSEHeader) Validate() error {
|
|
||||||
if _, exists := j[HeaderKeyAlgorithm]; !exists {
|
|
||||||
return fmt.Errorf("header missing %q parameter", HeaderKeyAlgorithm)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func decodeHeader(seg string) (JOSEHeader, error) {
|
|
||||||
b, err := decodeSegment(seg)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var h JOSEHeader
|
|
||||||
err = json.Unmarshal(b, &h)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return h, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func encodeHeader(h JOSEHeader) (string, error) {
|
|
||||||
b, err := json.Marshal(h)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
return encodeSegment(b), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Decode JWT specific base64url encoding with padding stripped
|
|
||||||
func decodeSegment(seg string) ([]byte, error) {
|
|
||||||
if l := len(seg) % 4; l != 0 {
|
|
||||||
seg += strings.Repeat("=", 4-l)
|
|
||||||
}
|
|
||||||
return base64.URLEncoding.DecodeString(seg)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encode JWT specific base64url encoding with padding stripped
|
|
||||||
func encodeSegment(seg []byte) string {
|
|
||||||
return strings.TrimRight(base64.URLEncoding.EncodeToString(seg), "=")
|
|
||||||
}
|
|
135
vendor/github.com/coreos/go-oidc/jose/jwk.go
generated
vendored
135
vendor/github.com/coreos/go-oidc/jose/jwk.go
generated
vendored
|
@ -1,135 +0,0 @@
|
||||||
package jose
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/base64"
|
|
||||||
"encoding/binary"
|
|
||||||
"encoding/json"
|
|
||||||
"math/big"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// JSON Web Key
|
|
||||||
// https://tools.ietf.org/html/draft-ietf-jose-json-web-key-36#page-5
|
|
||||||
type JWK struct {
|
|
||||||
ID string
|
|
||||||
Type string
|
|
||||||
Alg string
|
|
||||||
Use string
|
|
||||||
Exponent int
|
|
||||||
Modulus *big.Int
|
|
||||||
Secret []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
type jwkJSON struct {
|
|
||||||
ID string `json:"kid"`
|
|
||||||
Type string `json:"kty"`
|
|
||||||
Alg string `json:"alg"`
|
|
||||||
Use string `json:"use"`
|
|
||||||
Exponent string `json:"e"`
|
|
||||||
Modulus string `json:"n"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (j *JWK) MarshalJSON() ([]byte, error) {
|
|
||||||
t := jwkJSON{
|
|
||||||
ID: j.ID,
|
|
||||||
Type: j.Type,
|
|
||||||
Alg: j.Alg,
|
|
||||||
Use: j.Use,
|
|
||||||
Exponent: encodeExponent(j.Exponent),
|
|
||||||
Modulus: encodeModulus(j.Modulus),
|
|
||||||
}
|
|
||||||
|
|
||||||
return json.Marshal(&t)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (j *JWK) UnmarshalJSON(data []byte) error {
|
|
||||||
var t jwkJSON
|
|
||||||
err := json.Unmarshal(data, &t)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
e, err := decodeExponent(t.Exponent)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
n, err := decodeModulus(t.Modulus)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
j.ID = t.ID
|
|
||||||
j.Type = t.Type
|
|
||||||
j.Alg = t.Alg
|
|
||||||
j.Use = t.Use
|
|
||||||
j.Exponent = e
|
|
||||||
j.Modulus = n
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type JWKSet struct {
|
|
||||||
Keys []JWK `json:"keys"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func decodeExponent(e string) (int, error) {
|
|
||||||
decE, err := decodeBase64URLPaddingOptional(e)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
var eBytes []byte
|
|
||||||
if len(decE) < 8 {
|
|
||||||
eBytes = make([]byte, 8-len(decE), 8)
|
|
||||||
eBytes = append(eBytes, decE...)
|
|
||||||
} else {
|
|
||||||
eBytes = decE
|
|
||||||
}
|
|
||||||
eReader := bytes.NewReader(eBytes)
|
|
||||||
var E uint64
|
|
||||||
err = binary.Read(eReader, binary.BigEndian, &E)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return int(E), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func encodeExponent(e int) string {
|
|
||||||
b := make([]byte, 8)
|
|
||||||
binary.BigEndian.PutUint64(b, uint64(e))
|
|
||||||
var idx int
|
|
||||||
for ; idx < 8; idx++ {
|
|
||||||
if b[idx] != 0x0 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return base64.URLEncoding.EncodeToString(b[idx:])
|
|
||||||
}
|
|
||||||
|
|
||||||
// Turns a URL encoded modulus of a key into a big int.
|
|
||||||
func decodeModulus(n string) (*big.Int, error) {
|
|
||||||
decN, err := decodeBase64URLPaddingOptional(n)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
N := big.NewInt(0)
|
|
||||||
N.SetBytes(decN)
|
|
||||||
return N, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func encodeModulus(n *big.Int) string {
|
|
||||||
return base64.URLEncoding.EncodeToString(n.Bytes())
|
|
||||||
}
|
|
||||||
|
|
||||||
// decodeBase64URLPaddingOptional decodes Base64 whether there is padding or not.
|
|
||||||
// The stdlib version currently doesn't handle this.
|
|
||||||
// We can get rid of this is if this bug:
|
|
||||||
// https://github.com/golang/go/issues/4237
|
|
||||||
// ever closes.
|
|
||||||
func decodeBase64URLPaddingOptional(e string) ([]byte, error) {
|
|
||||||
if m := len(e) % 4; m != 0 {
|
|
||||||
e += strings.Repeat("=", 4-m)
|
|
||||||
}
|
|
||||||
return base64.URLEncoding.DecodeString(e)
|
|
||||||
}
|
|
51
vendor/github.com/coreos/go-oidc/jose/jws.go
generated
vendored
51
vendor/github.com/coreos/go-oidc/jose/jws.go
generated
vendored
|
@ -1,51 +0,0 @@
|
||||||
package jose
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
type JWS struct {
|
|
||||||
RawHeader string
|
|
||||||
Header JOSEHeader
|
|
||||||
RawPayload string
|
|
||||||
Payload []byte
|
|
||||||
Signature []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
// Given a raw encoded JWS token parses it and verifies the structure.
|
|
||||||
func ParseJWS(raw string) (JWS, error) {
|
|
||||||
parts := strings.Split(raw, ".")
|
|
||||||
if len(parts) != 3 {
|
|
||||||
return JWS{}, fmt.Errorf("malformed JWS, only %d segments", len(parts))
|
|
||||||
}
|
|
||||||
|
|
||||||
rawSig := parts[2]
|
|
||||||
jws := JWS{
|
|
||||||
RawHeader: parts[0],
|
|
||||||
RawPayload: parts[1],
|
|
||||||
}
|
|
||||||
|
|
||||||
header, err := decodeHeader(jws.RawHeader)
|
|
||||||
if err != nil {
|
|
||||||
return JWS{}, fmt.Errorf("malformed JWS, unable to decode header, %s", err)
|
|
||||||
}
|
|
||||||
if err = header.Validate(); err != nil {
|
|
||||||
return JWS{}, fmt.Errorf("malformed JWS, %s", err)
|
|
||||||
}
|
|
||||||
jws.Header = header
|
|
||||||
|
|
||||||
payload, err := decodeSegment(jws.RawPayload)
|
|
||||||
if err != nil {
|
|
||||||
return JWS{}, fmt.Errorf("malformed JWS, unable to decode payload: %s", err)
|
|
||||||
}
|
|
||||||
jws.Payload = payload
|
|
||||||
|
|
||||||
sig, err := decodeSegment(rawSig)
|
|
||||||
if err != nil {
|
|
||||||
return JWS{}, fmt.Errorf("malformed JWS, unable to decode signature: %s", err)
|
|
||||||
}
|
|
||||||
jws.Signature = sig
|
|
||||||
|
|
||||||
return jws, nil
|
|
||||||
}
|
|
82
vendor/github.com/coreos/go-oidc/jose/jwt.go
generated
vendored
82
vendor/github.com/coreos/go-oidc/jose/jwt.go
generated
vendored
|
@ -1,82 +0,0 @@
|
||||||
package jose
|
|
||||||
|
|
||||||
import "strings"
|
|
||||||
|
|
||||||
type JWT JWS
|
|
||||||
|
|
||||||
func ParseJWT(token string) (jwt JWT, err error) {
|
|
||||||
jws, err := ParseJWS(token)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
return JWT(jws), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewJWT(header JOSEHeader, claims Claims) (jwt JWT, err error) {
|
|
||||||
jwt = JWT{}
|
|
||||||
|
|
||||||
jwt.Header = header
|
|
||||||
jwt.Header[HeaderMediaType] = "JWT"
|
|
||||||
|
|
||||||
claimBytes, err := marshalClaims(claims)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
jwt.Payload = claimBytes
|
|
||||||
|
|
||||||
eh, err := encodeHeader(header)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
jwt.RawHeader = eh
|
|
||||||
|
|
||||||
ec, err := encodeClaims(claims)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
jwt.RawPayload = ec
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (j *JWT) KeyID() (string, bool) {
|
|
||||||
kID, ok := j.Header[HeaderKeyID]
|
|
||||||
return kID, ok
|
|
||||||
}
|
|
||||||
|
|
||||||
func (j *JWT) Claims() (Claims, error) {
|
|
||||||
return decodeClaims(j.Payload)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encoded data part of the token which may be signed.
|
|
||||||
func (j *JWT) Data() string {
|
|
||||||
return strings.Join([]string{j.RawHeader, j.RawPayload}, ".")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Full encoded JWT token string in format: header.claims.signature
|
|
||||||
func (j *JWT) Encode() string {
|
|
||||||
d := j.Data()
|
|
||||||
s := encodeSegment(j.Signature)
|
|
||||||
return strings.Join([]string{d, s}, ".")
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewSignedJWT(claims Claims, s Signer) (*JWT, error) {
|
|
||||||
header := JOSEHeader{
|
|
||||||
HeaderKeyAlgorithm: s.Alg(),
|
|
||||||
HeaderKeyID: s.ID(),
|
|
||||||
}
|
|
||||||
|
|
||||||
jwt, err := NewJWT(header, claims)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
sig, err := s.Sign([]byte(jwt.Data()))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
jwt.Signature = sig
|
|
||||||
|
|
||||||
return &jwt, nil
|
|
||||||
}
|
|
24
vendor/github.com/coreos/go-oidc/jose/sig.go
generated
vendored
24
vendor/github.com/coreos/go-oidc/jose/sig.go
generated
vendored
|
@ -1,24 +0,0 @@
|
||||||
package jose
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Verifier interface {
|
|
||||||
ID() string
|
|
||||||
Alg() string
|
|
||||||
Verify(sig []byte, data []byte) error
|
|
||||||
}
|
|
||||||
|
|
||||||
type Signer interface {
|
|
||||||
Verifier
|
|
||||||
Sign(data []byte) (sig []byte, err error)
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewVerifier(jwk JWK) (Verifier, error) {
|
|
||||||
if jwk.Type != "RSA" {
|
|
||||||
return nil, fmt.Errorf("unsupported key type %q", jwk.Type)
|
|
||||||
}
|
|
||||||
|
|
||||||
return NewVerifierRSA(jwk)
|
|
||||||
}
|
|
67
vendor/github.com/coreos/go-oidc/jose/sig_hmac.go
generated
vendored
67
vendor/github.com/coreos/go-oidc/jose/sig_hmac.go
generated
vendored
|
@ -1,67 +0,0 @@
|
||||||
package jose
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"crypto"
|
|
||||||
"crypto/hmac"
|
|
||||||
_ "crypto/sha256"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
type VerifierHMAC struct {
|
|
||||||
KeyID string
|
|
||||||
Hash crypto.Hash
|
|
||||||
Secret []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
type SignerHMAC struct {
|
|
||||||
VerifierHMAC
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewVerifierHMAC(jwk JWK) (*VerifierHMAC, error) {
|
|
||||||
if jwk.Alg != "" && jwk.Alg != "HS256" {
|
|
||||||
return nil, fmt.Errorf("unsupported key algorithm %q", jwk.Alg)
|
|
||||||
}
|
|
||||||
|
|
||||||
v := VerifierHMAC{
|
|
||||||
KeyID: jwk.ID,
|
|
||||||
Secret: jwk.Secret,
|
|
||||||
Hash: crypto.SHA256,
|
|
||||||
}
|
|
||||||
|
|
||||||
return &v, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *VerifierHMAC) ID() string {
|
|
||||||
return v.KeyID
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *VerifierHMAC) Alg() string {
|
|
||||||
return "HS256"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *VerifierHMAC) Verify(sig []byte, data []byte) error {
|
|
||||||
h := hmac.New(v.Hash.New, v.Secret)
|
|
||||||
h.Write(data)
|
|
||||||
if !bytes.Equal(sig, h.Sum(nil)) {
|
|
||||||
return errors.New("invalid hmac signature")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewSignerHMAC(kid string, secret []byte) *SignerHMAC {
|
|
||||||
return &SignerHMAC{
|
|
||||||
VerifierHMAC: VerifierHMAC{
|
|
||||||
KeyID: kid,
|
|
||||||
Secret: secret,
|
|
||||||
Hash: crypto.SHA256,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *SignerHMAC) Sign(data []byte) ([]byte, error) {
|
|
||||||
h := hmac.New(s.Hash.New, s.Secret)
|
|
||||||
h.Write(data)
|
|
||||||
return h.Sum(nil), nil
|
|
||||||
}
|
|
67
vendor/github.com/coreos/go-oidc/jose/sig_rsa.go
generated
vendored
67
vendor/github.com/coreos/go-oidc/jose/sig_rsa.go
generated
vendored
|
@ -1,67 +0,0 @@
|
||||||
package jose
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto"
|
|
||||||
"crypto/rand"
|
|
||||||
"crypto/rsa"
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
type VerifierRSA struct {
|
|
||||||
KeyID string
|
|
||||||
Hash crypto.Hash
|
|
||||||
PublicKey rsa.PublicKey
|
|
||||||
}
|
|
||||||
|
|
||||||
type SignerRSA struct {
|
|
||||||
PrivateKey rsa.PrivateKey
|
|
||||||
VerifierRSA
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewVerifierRSA(jwk JWK) (*VerifierRSA, error) {
|
|
||||||
if jwk.Alg != "" && jwk.Alg != "RS256" {
|
|
||||||
return nil, fmt.Errorf("unsupported key algorithm %q", jwk.Alg)
|
|
||||||
}
|
|
||||||
|
|
||||||
v := VerifierRSA{
|
|
||||||
KeyID: jwk.ID,
|
|
||||||
PublicKey: rsa.PublicKey{
|
|
||||||
N: jwk.Modulus,
|
|
||||||
E: jwk.Exponent,
|
|
||||||
},
|
|
||||||
Hash: crypto.SHA256,
|
|
||||||
}
|
|
||||||
|
|
||||||
return &v, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewSignerRSA(kid string, key rsa.PrivateKey) *SignerRSA {
|
|
||||||
return &SignerRSA{
|
|
||||||
PrivateKey: key,
|
|
||||||
VerifierRSA: VerifierRSA{
|
|
||||||
KeyID: kid,
|
|
||||||
PublicKey: key.PublicKey,
|
|
||||||
Hash: crypto.SHA256,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *VerifierRSA) ID() string {
|
|
||||||
return v.KeyID
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *VerifierRSA) Alg() string {
|
|
||||||
return "RS256"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *VerifierRSA) Verify(sig []byte, data []byte) error {
|
|
||||||
h := v.Hash.New()
|
|
||||||
h.Write(data)
|
|
||||||
return rsa.VerifyPKCS1v15(&v.PublicKey, v.Hash, h.Sum(nil), sig)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *SignerRSA) Sign(data []byte) ([]byte, error) {
|
|
||||||
h := s.Hash.New()
|
|
||||||
h.Write(data)
|
|
||||||
return rsa.SignPKCS1v15(rand.Reader, &s.PrivateKey, s.Hash, h.Sum(nil))
|
|
||||||
}
|
|
153
vendor/github.com/coreos/go-oidc/key/key.go
generated
vendored
153
vendor/github.com/coreos/go-oidc/key/key.go
generated
vendored
|
@ -1,153 +0,0 @@
|
||||||
package key
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/rand"
|
|
||||||
"crypto/rsa"
|
|
||||||
"encoding/hex"
|
|
||||||
"encoding/json"
|
|
||||||
"io"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/coreos/go-oidc/jose"
|
|
||||||
)
|
|
||||||
|
|
||||||
func NewPublicKey(jwk jose.JWK) *PublicKey {
|
|
||||||
return &PublicKey{jwk: jwk}
|
|
||||||
}
|
|
||||||
|
|
||||||
type PublicKey struct {
|
|
||||||
jwk jose.JWK
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *PublicKey) MarshalJSON() ([]byte, error) {
|
|
||||||
return json.Marshal(&k.jwk)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *PublicKey) UnmarshalJSON(data []byte) error {
|
|
||||||
var jwk jose.JWK
|
|
||||||
if err := json.Unmarshal(data, &jwk); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
k.jwk = jwk
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *PublicKey) ID() string {
|
|
||||||
return k.jwk.ID
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *PublicKey) Verifier() (jose.Verifier, error) {
|
|
||||||
return jose.NewVerifierRSA(k.jwk)
|
|
||||||
}
|
|
||||||
|
|
||||||
type PrivateKey struct {
|
|
||||||
KeyID string
|
|
||||||
PrivateKey *rsa.PrivateKey
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *PrivateKey) ID() string {
|
|
||||||
return k.KeyID
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *PrivateKey) Signer() jose.Signer {
|
|
||||||
return jose.NewSignerRSA(k.ID(), *k.PrivateKey)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *PrivateKey) JWK() jose.JWK {
|
|
||||||
return jose.JWK{
|
|
||||||
ID: k.KeyID,
|
|
||||||
Type: "RSA",
|
|
||||||
Alg: "RS256",
|
|
||||||
Use: "sig",
|
|
||||||
Exponent: k.PrivateKey.PublicKey.E,
|
|
||||||
Modulus: k.PrivateKey.PublicKey.N,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type KeySet interface {
|
|
||||||
ExpiresAt() time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
type PublicKeySet struct {
|
|
||||||
keys []PublicKey
|
|
||||||
index map[string]*PublicKey
|
|
||||||
expiresAt time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewPublicKeySet(jwks []jose.JWK, exp time.Time) *PublicKeySet {
|
|
||||||
keys := make([]PublicKey, len(jwks))
|
|
||||||
index := make(map[string]*PublicKey)
|
|
||||||
for i, jwk := range jwks {
|
|
||||||
keys[i] = *NewPublicKey(jwk)
|
|
||||||
index[keys[i].ID()] = &keys[i]
|
|
||||||
}
|
|
||||||
return &PublicKeySet{
|
|
||||||
keys: keys,
|
|
||||||
index: index,
|
|
||||||
expiresAt: exp,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *PublicKeySet) ExpiresAt() time.Time {
|
|
||||||
return s.expiresAt
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *PublicKeySet) Keys() []PublicKey {
|
|
||||||
return s.keys
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *PublicKeySet) Key(id string) *PublicKey {
|
|
||||||
return s.index[id]
|
|
||||||
}
|
|
||||||
|
|
||||||
type PrivateKeySet struct {
|
|
||||||
keys []*PrivateKey
|
|
||||||
ActiveKeyID string
|
|
||||||
expiresAt time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewPrivateKeySet(keys []*PrivateKey, exp time.Time) *PrivateKeySet {
|
|
||||||
return &PrivateKeySet{
|
|
||||||
keys: keys,
|
|
||||||
ActiveKeyID: keys[0].ID(),
|
|
||||||
expiresAt: exp.UTC(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *PrivateKeySet) Keys() []*PrivateKey {
|
|
||||||
return s.keys
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *PrivateKeySet) ExpiresAt() time.Time {
|
|
||||||
return s.expiresAt
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *PrivateKeySet) Active() *PrivateKey {
|
|
||||||
for i, k := range s.keys {
|
|
||||||
if k.ID() == s.ActiveKeyID {
|
|
||||||
return s.keys[i]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type GeneratePrivateKeyFunc func() (*PrivateKey, error)
|
|
||||||
|
|
||||||
func GeneratePrivateKey() (*PrivateKey, error) {
|
|
||||||
pk, err := rsa.GenerateKey(rand.Reader, 2048)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
keyID := make([]byte, 20)
|
|
||||||
if _, err := io.ReadFull(rand.Reader, keyID); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
k := PrivateKey{
|
|
||||||
KeyID: hex.EncodeToString(keyID),
|
|
||||||
PrivateKey: pk,
|
|
||||||
}
|
|
||||||
|
|
||||||
return &k, nil
|
|
||||||
}
|
|
99
vendor/github.com/coreos/go-oidc/key/manager.go
generated
vendored
99
vendor/github.com/coreos/go-oidc/key/manager.go
generated
vendored
|
@ -1,99 +0,0 @@
|
||||||
package key
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/jonboulle/clockwork"
|
|
||||||
|
|
||||||
"github.com/coreos/go-oidc/jose"
|
|
||||||
"github.com/coreos/pkg/health"
|
|
||||||
)
|
|
||||||
|
|
||||||
type PrivateKeyManager interface {
|
|
||||||
ExpiresAt() time.Time
|
|
||||||
Signer() (jose.Signer, error)
|
|
||||||
JWKs() ([]jose.JWK, error)
|
|
||||||
PublicKeys() ([]PublicKey, error)
|
|
||||||
|
|
||||||
WritableKeySetRepo
|
|
||||||
health.Checkable
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewPrivateKeyManager() PrivateKeyManager {
|
|
||||||
return &privateKeyManager{
|
|
||||||
clock: clockwork.NewRealClock(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type privateKeyManager struct {
|
|
||||||
keySet *PrivateKeySet
|
|
||||||
clock clockwork.Clock
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *privateKeyManager) ExpiresAt() time.Time {
|
|
||||||
if m.keySet == nil {
|
|
||||||
return m.clock.Now().UTC()
|
|
||||||
}
|
|
||||||
|
|
||||||
return m.keySet.ExpiresAt()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *privateKeyManager) Signer() (jose.Signer, error) {
|
|
||||||
if err := m.Healthy(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return m.keySet.Active().Signer(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *privateKeyManager) JWKs() ([]jose.JWK, error) {
|
|
||||||
if err := m.Healthy(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
keys := m.keySet.Keys()
|
|
||||||
jwks := make([]jose.JWK, len(keys))
|
|
||||||
for i, k := range keys {
|
|
||||||
jwks[i] = k.JWK()
|
|
||||||
}
|
|
||||||
return jwks, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *privateKeyManager) PublicKeys() ([]PublicKey, error) {
|
|
||||||
jwks, err := m.JWKs()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
keys := make([]PublicKey, len(jwks))
|
|
||||||
for i, jwk := range jwks {
|
|
||||||
keys[i] = *NewPublicKey(jwk)
|
|
||||||
}
|
|
||||||
return keys, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *privateKeyManager) Healthy() error {
|
|
||||||
if m.keySet == nil {
|
|
||||||
return errors.New("private key manager uninitialized")
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(m.keySet.Keys()) == 0 {
|
|
||||||
return errors.New("private key manager zero keys")
|
|
||||||
}
|
|
||||||
|
|
||||||
if m.keySet.ExpiresAt().Before(m.clock.Now().UTC()) {
|
|
||||||
return errors.New("private key manager keys expired")
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *privateKeyManager) Set(keySet KeySet) error {
|
|
||||||
privKeySet, ok := keySet.(*PrivateKeySet)
|
|
||||||
if !ok {
|
|
||||||
return errors.New("unable to cast to PrivateKeySet")
|
|
||||||
}
|
|
||||||
|
|
||||||
m.keySet = privKeySet
|
|
||||||
return nil
|
|
||||||
}
|
|
55
vendor/github.com/coreos/go-oidc/key/repo.go
generated
vendored
55
vendor/github.com/coreos/go-oidc/key/repo.go
generated
vendored
|
@ -1,55 +0,0 @@
|
||||||
package key
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
var ErrorNoKeys = errors.New("no keys found")
|
|
||||||
|
|
||||||
type WritableKeySetRepo interface {
|
|
||||||
Set(KeySet) error
|
|
||||||
}
|
|
||||||
|
|
||||||
type ReadableKeySetRepo interface {
|
|
||||||
Get() (KeySet, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type PrivateKeySetRepo interface {
|
|
||||||
WritableKeySetRepo
|
|
||||||
ReadableKeySetRepo
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewPrivateKeySetRepo() PrivateKeySetRepo {
|
|
||||||
return &memPrivateKeySetRepo{}
|
|
||||||
}
|
|
||||||
|
|
||||||
type memPrivateKeySetRepo struct {
|
|
||||||
mu sync.RWMutex
|
|
||||||
pks PrivateKeySet
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *memPrivateKeySetRepo) Set(ks KeySet) error {
|
|
||||||
pks, ok := ks.(*PrivateKeySet)
|
|
||||||
if !ok {
|
|
||||||
return errors.New("unable to cast to PrivateKeySet")
|
|
||||||
} else if pks == nil {
|
|
||||||
return errors.New("nil KeySet")
|
|
||||||
}
|
|
||||||
|
|
||||||
r.mu.Lock()
|
|
||||||
defer r.mu.Unlock()
|
|
||||||
|
|
||||||
r.pks = *pks
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *memPrivateKeySetRepo) Get() (KeySet, error) {
|
|
||||||
r.mu.RLock()
|
|
||||||
defer r.mu.RUnlock()
|
|
||||||
|
|
||||||
if r.pks.keys == nil {
|
|
||||||
return nil, ErrorNoKeys
|
|
||||||
}
|
|
||||||
return KeySet(&r.pks), nil
|
|
||||||
}
|
|
159
vendor/github.com/coreos/go-oidc/key/rotate.go
generated
vendored
159
vendor/github.com/coreos/go-oidc/key/rotate.go
generated
vendored
|
@ -1,159 +0,0 @@
|
||||||
package key
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"log"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
ptime "github.com/coreos/pkg/timeutil"
|
|
||||||
"github.com/jonboulle/clockwork"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
ErrorPrivateKeysExpired = errors.New("private keys have expired")
|
|
||||||
)
|
|
||||||
|
|
||||||
func NewPrivateKeyRotator(repo PrivateKeySetRepo, ttl time.Duration) *PrivateKeyRotator {
|
|
||||||
return &PrivateKeyRotator{
|
|
||||||
repo: repo,
|
|
||||||
ttl: ttl,
|
|
||||||
|
|
||||||
keep: 2,
|
|
||||||
generateKey: GeneratePrivateKey,
|
|
||||||
clock: clockwork.NewRealClock(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type PrivateKeyRotator struct {
|
|
||||||
repo PrivateKeySetRepo
|
|
||||||
generateKey GeneratePrivateKeyFunc
|
|
||||||
clock clockwork.Clock
|
|
||||||
keep int
|
|
||||||
ttl time.Duration
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *PrivateKeyRotator) expiresAt() time.Time {
|
|
||||||
return r.clock.Now().UTC().Add(r.ttl)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *PrivateKeyRotator) Healthy() error {
|
|
||||||
pks, err := r.privateKeySet()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if r.clock.Now().After(pks.ExpiresAt()) {
|
|
||||||
return ErrorPrivateKeysExpired
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *PrivateKeyRotator) privateKeySet() (*PrivateKeySet, error) {
|
|
||||||
ks, err := r.repo.Get()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
pks, ok := ks.(*PrivateKeySet)
|
|
||||||
if !ok {
|
|
||||||
return nil, errors.New("unable to cast to PrivateKeySet")
|
|
||||||
}
|
|
||||||
return pks, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *PrivateKeyRotator) nextRotation() (time.Duration, error) {
|
|
||||||
pks, err := r.privateKeySet()
|
|
||||||
if err == ErrorNoKeys {
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
now := r.clock.Now()
|
|
||||||
|
|
||||||
// Ideally, we want to rotate after half the TTL has elapsed.
|
|
||||||
idealRotationTime := pks.ExpiresAt().Add(-r.ttl / 2)
|
|
||||||
|
|
||||||
// If we are past the ideal rotation time, rotate immediatly.
|
|
||||||
return max(0, idealRotationTime.Sub(now)), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func max(a, b time.Duration) time.Duration {
|
|
||||||
if a > b {
|
|
||||||
return a
|
|
||||||
}
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *PrivateKeyRotator) Run() chan struct{} {
|
|
||||||
attempt := func() {
|
|
||||||
k, err := r.generateKey()
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("go-oidc: failed generating signing key: %v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
exp := r.expiresAt()
|
|
||||||
if err := rotatePrivateKeys(r.repo, k, r.keep, exp); err != nil {
|
|
||||||
log.Printf("go-oidc: key rotation failed: %v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stop := make(chan struct{})
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
var nextRotation time.Duration
|
|
||||||
var sleep time.Duration
|
|
||||||
var err error
|
|
||||||
for {
|
|
||||||
if nextRotation, err = r.nextRotation(); err == nil {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
sleep = ptime.ExpBackoff(sleep, time.Minute)
|
|
||||||
log.Printf("go-oidc: error getting nextRotation, retrying in %v: %v", sleep, err)
|
|
||||||
time.Sleep(sleep)
|
|
||||||
}
|
|
||||||
|
|
||||||
select {
|
|
||||||
case <-r.clock.After(nextRotation):
|
|
||||||
attempt()
|
|
||||||
case <-stop:
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
return stop
|
|
||||||
}
|
|
||||||
|
|
||||||
func rotatePrivateKeys(repo PrivateKeySetRepo, k *PrivateKey, keep int, exp time.Time) error {
|
|
||||||
ks, err := repo.Get()
|
|
||||||
if err != nil && err != ErrorNoKeys {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var keys []*PrivateKey
|
|
||||||
if ks != nil {
|
|
||||||
pks, ok := ks.(*PrivateKeySet)
|
|
||||||
if !ok {
|
|
||||||
return errors.New("unable to cast to PrivateKeySet")
|
|
||||||
}
|
|
||||||
keys = pks.Keys()
|
|
||||||
}
|
|
||||||
|
|
||||||
keys = append([]*PrivateKey{k}, keys...)
|
|
||||||
if l := len(keys); l > keep {
|
|
||||||
keys = keys[0:keep]
|
|
||||||
}
|
|
||||||
|
|
||||||
nks := PrivateKeySet{
|
|
||||||
keys: keys,
|
|
||||||
ActiveKeyID: k.ID(),
|
|
||||||
expiresAt: exp,
|
|
||||||
}
|
|
||||||
|
|
||||||
return repo.Set(KeySet(&nks))
|
|
||||||
}
|
|
91
vendor/github.com/coreos/go-oidc/key/sync.go
generated
vendored
91
vendor/github.com/coreos/go-oidc/key/sync.go
generated
vendored
|
@ -1,91 +0,0 @@
|
||||||
package key
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"log"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/jonboulle/clockwork"
|
|
||||||
|
|
||||||
"github.com/coreos/pkg/timeutil"
|
|
||||||
)
|
|
||||||
|
|
||||||
func NewKeySetSyncer(r ReadableKeySetRepo, w WritableKeySetRepo) *KeySetSyncer {
|
|
||||||
return &KeySetSyncer{
|
|
||||||
readable: r,
|
|
||||||
writable: w,
|
|
||||||
clock: clockwork.NewRealClock(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type KeySetSyncer struct {
|
|
||||||
readable ReadableKeySetRepo
|
|
||||||
writable WritableKeySetRepo
|
|
||||||
clock clockwork.Clock
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *KeySetSyncer) Run() chan struct{} {
|
|
||||||
stop := make(chan struct{})
|
|
||||||
go func() {
|
|
||||||
var failing bool
|
|
||||||
var next time.Duration
|
|
||||||
for {
|
|
||||||
exp, err := syncKeySet(s.readable, s.writable, s.clock)
|
|
||||||
if err != nil || exp == 0 {
|
|
||||||
if !failing {
|
|
||||||
failing = true
|
|
||||||
next = time.Second
|
|
||||||
} else {
|
|
||||||
next = timeutil.ExpBackoff(next, time.Minute)
|
|
||||||
}
|
|
||||||
if exp == 0 {
|
|
||||||
log.Printf("Synced to already expired key set, retrying in %v: %v", next, err)
|
|
||||||
|
|
||||||
} else {
|
|
||||||
log.Printf("Failed syncing key set, retrying in %v: %v", next, err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
failing = false
|
|
||||||
next = exp / 2
|
|
||||||
}
|
|
||||||
|
|
||||||
select {
|
|
||||||
case <-s.clock.After(next):
|
|
||||||
continue
|
|
||||||
case <-stop:
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
return stop
|
|
||||||
}
|
|
||||||
|
|
||||||
func Sync(r ReadableKeySetRepo, w WritableKeySetRepo) (time.Duration, error) {
|
|
||||||
return syncKeySet(r, w, clockwork.NewRealClock())
|
|
||||||
}
|
|
||||||
|
|
||||||
// syncKeySet copies the keyset from r to the KeySet at w and returns the duration in which the KeySet will expire.
|
|
||||||
// If keyset has already expired, returns a zero duration.
|
|
||||||
func syncKeySet(r ReadableKeySetRepo, w WritableKeySetRepo, clock clockwork.Clock) (exp time.Duration, err error) {
|
|
||||||
var ks KeySet
|
|
||||||
ks, err = r.Get()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if ks == nil {
|
|
||||||
err = errors.New("no source KeySet")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = w.Set(ks); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
now := clock.Now()
|
|
||||||
if ks.ExpiresAt().After(now) {
|
|
||||||
exp = ks.ExpiresAt().Sub(now)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
29
vendor/github.com/coreos/go-oidc/oauth2/error.go
generated
vendored
29
vendor/github.com/coreos/go-oidc/oauth2/error.go
generated
vendored
|
@ -1,29 +0,0 @@
|
||||||
package oauth2
|
|
||||||
|
|
||||||
const (
|
|
||||||
ErrorAccessDenied = "access_denied"
|
|
||||||
ErrorInvalidClient = "invalid_client"
|
|
||||||
ErrorInvalidGrant = "invalid_grant"
|
|
||||||
ErrorInvalidRequest = "invalid_request"
|
|
||||||
ErrorServerError = "server_error"
|
|
||||||
ErrorUnauthorizedClient = "unauthorized_client"
|
|
||||||
ErrorUnsupportedGrantType = "unsupported_grant_type"
|
|
||||||
ErrorUnsupportedResponseType = "unsupported_response_type"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Error struct {
|
|
||||||
Type string `json:"error"`
|
|
||||||
Description string `json:"error_description,omitempty"`
|
|
||||||
State string `json:"state,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *Error) Error() string {
|
|
||||||
if e.Description != "" {
|
|
||||||
return e.Type + ": " + e.Description
|
|
||||||
}
|
|
||||||
return e.Type
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewError(typ string) *Error {
|
|
||||||
return &Error{Type: typ}
|
|
||||||
}
|
|
416
vendor/github.com/coreos/go-oidc/oauth2/oauth2.go
generated
vendored
416
vendor/github.com/coreos/go-oidc/oauth2/oauth2.go
generated
vendored
|
@ -1,416 +0,0 @@
|
||||||
package oauth2
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"mime"
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
"sort"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
phttp "github.com/coreos/go-oidc/http"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ResponseTypesEqual compares two response_type values. If either
|
|
||||||
// contains a space, it is treated as an unordered list. For example,
|
|
||||||
// comparing "code id_token" and "id_token code" would evaluate to true.
|
|
||||||
func ResponseTypesEqual(r1, r2 string) bool {
|
|
||||||
if !strings.Contains(r1, " ") || !strings.Contains(r2, " ") {
|
|
||||||
// fast route, no split needed
|
|
||||||
return r1 == r2
|
|
||||||
}
|
|
||||||
|
|
||||||
// split, sort, and compare
|
|
||||||
r1Fields := strings.Fields(r1)
|
|
||||||
r2Fields := strings.Fields(r2)
|
|
||||||
if len(r1Fields) != len(r2Fields) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
sort.Strings(r1Fields)
|
|
||||||
sort.Strings(r2Fields)
|
|
||||||
for i, r1Field := range r1Fields {
|
|
||||||
if r1Field != r2Fields[i] {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
// OAuth2.0 response types registered by OIDC.
|
|
||||||
//
|
|
||||||
// See: https://openid.net/specs/oauth-v2-multiple-response-types-1_0.html#RegistryContents
|
|
||||||
ResponseTypeCode = "code"
|
|
||||||
ResponseTypeCodeIDToken = "code id_token"
|
|
||||||
ResponseTypeCodeIDTokenToken = "code id_token token"
|
|
||||||
ResponseTypeIDToken = "id_token"
|
|
||||||
ResponseTypeIDTokenToken = "id_token token"
|
|
||||||
ResponseTypeToken = "token"
|
|
||||||
ResponseTypeNone = "none"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
GrantTypeAuthCode = "authorization_code"
|
|
||||||
GrantTypeClientCreds = "client_credentials"
|
|
||||||
GrantTypeUserCreds = "password"
|
|
||||||
GrantTypeImplicit = "implicit"
|
|
||||||
GrantTypeRefreshToken = "refresh_token"
|
|
||||||
|
|
||||||
AuthMethodClientSecretPost = "client_secret_post"
|
|
||||||
AuthMethodClientSecretBasic = "client_secret_basic"
|
|
||||||
AuthMethodClientSecretJWT = "client_secret_jwt"
|
|
||||||
AuthMethodPrivateKeyJWT = "private_key_jwt"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Config struct {
|
|
||||||
Credentials ClientCredentials
|
|
||||||
Scope []string
|
|
||||||
RedirectURL string
|
|
||||||
AuthURL string
|
|
||||||
TokenURL string
|
|
||||||
|
|
||||||
// Must be one of the AuthMethodXXX methods above. Right now, only
|
|
||||||
// AuthMethodClientSecretPost and AuthMethodClientSecretBasic are supported.
|
|
||||||
AuthMethod string
|
|
||||||
}
|
|
||||||
|
|
||||||
type Client struct {
|
|
||||||
hc phttp.Client
|
|
||||||
creds ClientCredentials
|
|
||||||
scope []string
|
|
||||||
authURL *url.URL
|
|
||||||
redirectURL *url.URL
|
|
||||||
tokenURL *url.URL
|
|
||||||
authMethod string
|
|
||||||
}
|
|
||||||
|
|
||||||
type ClientCredentials struct {
|
|
||||||
ID string
|
|
||||||
Secret string
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewClient(hc phttp.Client, cfg Config) (c *Client, err error) {
|
|
||||||
if len(cfg.Credentials.ID) == 0 {
|
|
||||||
err = errors.New("missing client id")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(cfg.Credentials.Secret) == 0 {
|
|
||||||
err = errors.New("missing client secret")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if cfg.AuthMethod == "" {
|
|
||||||
cfg.AuthMethod = AuthMethodClientSecretBasic
|
|
||||||
} else if cfg.AuthMethod != AuthMethodClientSecretPost && cfg.AuthMethod != AuthMethodClientSecretBasic {
|
|
||||||
err = fmt.Errorf("auth method %q is not supported", cfg.AuthMethod)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
au, err := phttp.ParseNonEmptyURL(cfg.AuthURL)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
tu, err := phttp.ParseNonEmptyURL(cfg.TokenURL)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allow empty redirect URL in the case where the client
|
|
||||||
// only needs to verify a given token.
|
|
||||||
ru, err := url.Parse(cfg.RedirectURL)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
c = &Client{
|
|
||||||
creds: cfg.Credentials,
|
|
||||||
scope: cfg.Scope,
|
|
||||||
redirectURL: ru,
|
|
||||||
authURL: au,
|
|
||||||
tokenURL: tu,
|
|
||||||
hc: hc,
|
|
||||||
authMethod: cfg.AuthMethod,
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the embedded HTTP client
|
|
||||||
func (c *Client) HttpClient() phttp.Client {
|
|
||||||
return c.hc
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate the url for initial redirect to oauth provider.
|
|
||||||
func (c *Client) AuthCodeURL(state, accessType, prompt string) string {
|
|
||||||
v := c.commonURLValues()
|
|
||||||
v.Set("state", state)
|
|
||||||
if strings.ToLower(accessType) == "offline" {
|
|
||||||
v.Set("access_type", "offline")
|
|
||||||
}
|
|
||||||
|
|
||||||
if prompt != "" {
|
|
||||||
v.Set("prompt", prompt)
|
|
||||||
}
|
|
||||||
v.Set("response_type", "code")
|
|
||||||
|
|
||||||
q := v.Encode()
|
|
||||||
u := *c.authURL
|
|
||||||
if u.RawQuery == "" {
|
|
||||||
u.RawQuery = q
|
|
||||||
} else {
|
|
||||||
u.RawQuery += "&" + q
|
|
||||||
}
|
|
||||||
return u.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Client) commonURLValues() url.Values {
|
|
||||||
return url.Values{
|
|
||||||
"redirect_uri": {c.redirectURL.String()},
|
|
||||||
"scope": {strings.Join(c.scope, " ")},
|
|
||||||
"client_id": {c.creds.ID},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Client) newAuthenticatedRequest(urlToken string, values url.Values) (*http.Request, error) {
|
|
||||||
var req *http.Request
|
|
||||||
var err error
|
|
||||||
switch c.authMethod {
|
|
||||||
case AuthMethodClientSecretPost:
|
|
||||||
values.Set("client_secret", c.creds.Secret)
|
|
||||||
req, err = http.NewRequest("POST", urlToken, strings.NewReader(values.Encode()))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
case AuthMethodClientSecretBasic:
|
|
||||||
req, err = http.NewRequest("POST", urlToken, strings.NewReader(values.Encode()))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
encodedID := url.QueryEscape(c.creds.ID)
|
|
||||||
encodedSecret := url.QueryEscape(c.creds.Secret)
|
|
||||||
req.SetBasicAuth(encodedID, encodedSecret)
|
|
||||||
default:
|
|
||||||
panic("misconfigured client: auth method not supported")
|
|
||||||
}
|
|
||||||
|
|
||||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
|
||||||
return req, nil
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// ClientCredsToken posts the client id and secret to obtain a token scoped to the OAuth2 client via the "client_credentials" grant type.
|
|
||||||
// May not be supported by all OAuth2 servers.
|
|
||||||
func (c *Client) ClientCredsToken(scope []string) (result TokenResponse, err error) {
|
|
||||||
v := url.Values{
|
|
||||||
"scope": {strings.Join(scope, " ")},
|
|
||||||
"grant_type": {GrantTypeClientCreds},
|
|
||||||
}
|
|
||||||
|
|
||||||
req, err := c.newAuthenticatedRequest(c.tokenURL.String(), v)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := c.hc.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
return parseTokenResponse(resp)
|
|
||||||
}
|
|
||||||
|
|
||||||
// UserCredsToken posts the username and password to obtain a token scoped to the OAuth2 client via the "password" grant_type
|
|
||||||
// May not be supported by all OAuth2 servers.
|
|
||||||
func (c *Client) UserCredsToken(username, password string) (result TokenResponse, err error) {
|
|
||||||
v := url.Values{
|
|
||||||
"scope": {strings.Join(c.scope, " ")},
|
|
||||||
"grant_type": {GrantTypeUserCreds},
|
|
||||||
"username": {username},
|
|
||||||
"password": {password},
|
|
||||||
}
|
|
||||||
|
|
||||||
req, err := c.newAuthenticatedRequest(c.tokenURL.String(), v)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := c.hc.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
return parseTokenResponse(resp)
|
|
||||||
}
|
|
||||||
|
|
||||||
// RequestToken requests a token from the Token Endpoint with the specified grantType.
|
|
||||||
// If 'grantType' == GrantTypeAuthCode, then 'value' should be the authorization code.
|
|
||||||
// If 'grantType' == GrantTypeRefreshToken, then 'value' should be the refresh token.
|
|
||||||
func (c *Client) RequestToken(grantType, value string) (result TokenResponse, err error) {
|
|
||||||
v := c.commonURLValues()
|
|
||||||
|
|
||||||
v.Set("grant_type", grantType)
|
|
||||||
v.Set("client_secret", c.creds.Secret)
|
|
||||||
switch grantType {
|
|
||||||
case GrantTypeAuthCode:
|
|
||||||
v.Set("code", value)
|
|
||||||
case GrantTypeRefreshToken:
|
|
||||||
v.Set("refresh_token", value)
|
|
||||||
default:
|
|
||||||
err = fmt.Errorf("unsupported grant_type: %v", grantType)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
req, err := c.newAuthenticatedRequest(c.tokenURL.String(), v)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := c.hc.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
return parseTokenResponse(resp)
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseTokenResponse(resp *http.Response) (result TokenResponse, err error) {
|
|
||||||
body, err := ioutil.ReadAll(resp.Body)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
badStatusCode := resp.StatusCode < 200 || resp.StatusCode > 299
|
|
||||||
|
|
||||||
contentType, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type"))
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
result = TokenResponse{
|
|
||||||
RawBody: body,
|
|
||||||
}
|
|
||||||
|
|
||||||
newError := func(typ, desc, state string) error {
|
|
||||||
if typ == "" {
|
|
||||||
return fmt.Errorf("unrecognized error %s", body)
|
|
||||||
}
|
|
||||||
return &Error{typ, desc, state}
|
|
||||||
}
|
|
||||||
|
|
||||||
if contentType == "application/x-www-form-urlencoded" || contentType == "text/plain" {
|
|
||||||
var vals url.Values
|
|
||||||
vals, err = url.ParseQuery(string(body))
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if error := vals.Get("error"); error != "" || badStatusCode {
|
|
||||||
err = newError(error, vals.Get("error_description"), vals.Get("state"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
e := vals.Get("expires_in")
|
|
||||||
if e == "" {
|
|
||||||
e = vals.Get("expires")
|
|
||||||
}
|
|
||||||
if e != "" {
|
|
||||||
result.Expires, err = strconv.Atoi(e)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result.AccessToken = vals.Get("access_token")
|
|
||||||
result.TokenType = vals.Get("token_type")
|
|
||||||
result.IDToken = vals.Get("id_token")
|
|
||||||
result.RefreshToken = vals.Get("refresh_token")
|
|
||||||
result.Scope = vals.Get("scope")
|
|
||||||
} else {
|
|
||||||
var r struct {
|
|
||||||
AccessToken string `json:"access_token"`
|
|
||||||
TokenType string `json:"token_type"`
|
|
||||||
IDToken string `json:"id_token"`
|
|
||||||
RefreshToken string `json:"refresh_token"`
|
|
||||||
Scope string `json:"scope"`
|
|
||||||
State string `json:"state"`
|
|
||||||
ExpiresIn json.Number `json:"expires_in"` // Azure AD returns string
|
|
||||||
Expires int `json:"expires"`
|
|
||||||
Error string `json:"error"`
|
|
||||||
Desc string `json:"error_description"`
|
|
||||||
}
|
|
||||||
if err = json.Unmarshal(body, &r); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if r.Error != "" || badStatusCode {
|
|
||||||
err = newError(r.Error, r.Desc, r.State)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
result.AccessToken = r.AccessToken
|
|
||||||
result.TokenType = r.TokenType
|
|
||||||
result.IDToken = r.IDToken
|
|
||||||
result.RefreshToken = r.RefreshToken
|
|
||||||
result.Scope = r.Scope
|
|
||||||
if expiresIn, err := r.ExpiresIn.Int64(); err != nil {
|
|
||||||
result.Expires = r.Expires
|
|
||||||
} else {
|
|
||||||
result.Expires = int(expiresIn)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
type TokenResponse struct {
|
|
||||||
AccessToken string
|
|
||||||
TokenType string
|
|
||||||
Expires int
|
|
||||||
IDToken string
|
|
||||||
RefreshToken string // OPTIONAL.
|
|
||||||
Scope string // OPTIONAL, if identical to the scope requested by the client, otherwise, REQUIRED.
|
|
||||||
RawBody []byte // In case callers need some other non-standard info from the token response
|
|
||||||
}
|
|
||||||
|
|
||||||
type AuthCodeRequest struct {
|
|
||||||
ResponseType string
|
|
||||||
ClientID string
|
|
||||||
RedirectURL *url.URL
|
|
||||||
Scope []string
|
|
||||||
State string
|
|
||||||
}
|
|
||||||
|
|
||||||
func ParseAuthCodeRequest(q url.Values) (AuthCodeRequest, error) {
|
|
||||||
acr := AuthCodeRequest{
|
|
||||||
ResponseType: q.Get("response_type"),
|
|
||||||
ClientID: q.Get("client_id"),
|
|
||||||
State: q.Get("state"),
|
|
||||||
Scope: make([]string, 0),
|
|
||||||
}
|
|
||||||
|
|
||||||
qs := strings.TrimSpace(q.Get("scope"))
|
|
||||||
if qs != "" {
|
|
||||||
acr.Scope = strings.Split(qs, " ")
|
|
||||||
}
|
|
||||||
|
|
||||||
err := func() error {
|
|
||||||
if acr.ClientID == "" {
|
|
||||||
return NewError(ErrorInvalidRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
redirectURL := q.Get("redirect_uri")
|
|
||||||
if redirectURL != "" {
|
|
||||||
ru, err := url.Parse(redirectURL)
|
|
||||||
if err != nil {
|
|
||||||
return NewError(ErrorInvalidRequest)
|
|
||||||
}
|
|
||||||
acr.RedirectURL = ru
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}()
|
|
||||||
|
|
||||||
return acr, err
|
|
||||||
}
|
|
846
vendor/github.com/coreos/go-oidc/oidc/client.go
generated
vendored
846
vendor/github.com/coreos/go-oidc/oidc/client.go
generated
vendored
|
@ -1,846 +0,0 @@
|
||||||
package oidc
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
"net/mail"
|
|
||||||
"net/url"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
phttp "github.com/coreos/go-oidc/http"
|
|
||||||
"github.com/coreos/go-oidc/jose"
|
|
||||||
"github.com/coreos/go-oidc/key"
|
|
||||||
"github.com/coreos/go-oidc/oauth2"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// amount of time that must pass after the last key sync
|
|
||||||
// completes before another attempt may begin
|
|
||||||
keySyncWindow = 5 * time.Second
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
DefaultScope = []string{"openid", "email", "profile"}
|
|
||||||
|
|
||||||
supportedAuthMethods = map[string]struct{}{
|
|
||||||
oauth2.AuthMethodClientSecretBasic: struct{}{},
|
|
||||||
oauth2.AuthMethodClientSecretPost: struct{}{},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
type ClientCredentials oauth2.ClientCredentials
|
|
||||||
|
|
||||||
type ClientIdentity struct {
|
|
||||||
Credentials ClientCredentials
|
|
||||||
Metadata ClientMetadata
|
|
||||||
}
|
|
||||||
|
|
||||||
type JWAOptions struct {
|
|
||||||
// SigningAlg specifies an JWA alg for signing JWTs.
|
|
||||||
//
|
|
||||||
// Specifying this field implies different actions depending on the context. It may
|
|
||||||
// require objects be serialized and signed as a JWT instead of plain JSON, or
|
|
||||||
// require an existing JWT object use the specified alg.
|
|
||||||
//
|
|
||||||
// See: http://openid.net/specs/openid-connect-registration-1_0.html#ClientMetadata
|
|
||||||
SigningAlg string
|
|
||||||
// EncryptionAlg, if provided, specifies that the returned or sent object be stored
|
|
||||||
// (or nested) within a JWT object and encrypted with the provided JWA alg.
|
|
||||||
EncryptionAlg string
|
|
||||||
// EncryptionEnc specifies the JWA enc algorithm to use with EncryptionAlg. If
|
|
||||||
// EncryptionAlg is provided and EncryptionEnc is omitted, this field defaults
|
|
||||||
// to A128CBC-HS256.
|
|
||||||
//
|
|
||||||
// If EncryptionEnc is provided EncryptionAlg must also be specified.
|
|
||||||
EncryptionEnc string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (opt JWAOptions) valid() error {
|
|
||||||
if opt.EncryptionEnc != "" && opt.EncryptionAlg == "" {
|
|
||||||
return errors.New("encryption encoding provided with no encryption algorithm")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (opt JWAOptions) defaults() JWAOptions {
|
|
||||||
if opt.EncryptionAlg != "" && opt.EncryptionEnc == "" {
|
|
||||||
opt.EncryptionEnc = jose.EncA128CBCHS256
|
|
||||||
}
|
|
||||||
return opt
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
// Ensure ClientMetadata satisfies these interfaces.
|
|
||||||
_ json.Marshaler = &ClientMetadata{}
|
|
||||||
_ json.Unmarshaler = &ClientMetadata{}
|
|
||||||
)
|
|
||||||
|
|
||||||
// ClientMetadata holds metadata that the authorization server associates
|
|
||||||
// with a client identifier. The fields range from human-facing display
|
|
||||||
// strings such as client name, to items that impact the security of the
|
|
||||||
// protocol, such as the list of valid redirect URIs.
|
|
||||||
//
|
|
||||||
// See http://openid.net/specs/openid-connect-registration-1_0.html#ClientMetadata
|
|
||||||
//
|
|
||||||
// TODO: support language specific claim representations
|
|
||||||
// http://openid.net/specs/openid-connect-registration-1_0.html#LanguagesAndScripts
|
|
||||||
type ClientMetadata struct {
|
|
||||||
RedirectURIs []url.URL // Required
|
|
||||||
|
|
||||||
// A list of OAuth 2.0 "response_type" values that the client wishes to restrict
|
|
||||||
// itself to. Either "code", "token", or another registered extension.
|
|
||||||
//
|
|
||||||
// If omitted, only "code" will be used.
|
|
||||||
ResponseTypes []string
|
|
||||||
// A list of OAuth 2.0 grant types the client wishes to restrict itself to.
|
|
||||||
// The grant type values used by OIDC are "authorization_code", "implicit",
|
|
||||||
// and "refresh_token".
|
|
||||||
//
|
|
||||||
// If ommitted, only "authorization_code" will be used.
|
|
||||||
GrantTypes []string
|
|
||||||
// "native" or "web". If omitted, "web".
|
|
||||||
ApplicationType string
|
|
||||||
|
|
||||||
// List of email addresses.
|
|
||||||
Contacts []mail.Address
|
|
||||||
// Name of client to be presented to the end-user.
|
|
||||||
ClientName string
|
|
||||||
// URL that references a logo for the Client application.
|
|
||||||
LogoURI *url.URL
|
|
||||||
// URL of the home page of the Client.
|
|
||||||
ClientURI *url.URL
|
|
||||||
// Profile data policies and terms of use to be provided to the end user.
|
|
||||||
PolicyURI *url.URL
|
|
||||||
TermsOfServiceURI *url.URL
|
|
||||||
|
|
||||||
// URL to or the value of the client's JSON Web Key Set document.
|
|
||||||
JWKSURI *url.URL
|
|
||||||
JWKS *jose.JWKSet
|
|
||||||
|
|
||||||
// URL referencing a flie with a single JSON array of redirect URIs.
|
|
||||||
SectorIdentifierURI *url.URL
|
|
||||||
|
|
||||||
SubjectType string
|
|
||||||
|
|
||||||
// Options to restrict the JWS alg and enc values used for server responses and requests.
|
|
||||||
IDTokenResponseOptions JWAOptions
|
|
||||||
UserInfoResponseOptions JWAOptions
|
|
||||||
RequestObjectOptions JWAOptions
|
|
||||||
|
|
||||||
// Client requested authorization method and signing options for the token endpoint.
|
|
||||||
//
|
|
||||||
// Defaults to "client_secret_basic"
|
|
||||||
TokenEndpointAuthMethod string
|
|
||||||
TokenEndpointAuthSigningAlg string
|
|
||||||
|
|
||||||
// DefaultMaxAge specifies the maximum amount of time in seconds before an authorized
|
|
||||||
// user must reauthroize.
|
|
||||||
//
|
|
||||||
// If 0, no limitation is placed on the maximum.
|
|
||||||
DefaultMaxAge int64
|
|
||||||
// RequireAuthTime specifies if the auth_time claim in the ID token is required.
|
|
||||||
RequireAuthTime bool
|
|
||||||
|
|
||||||
// Default Authentication Context Class Reference values for authentication requests.
|
|
||||||
DefaultACRValues []string
|
|
||||||
|
|
||||||
// URI that a third party can use to initiate a login by the relaying party.
|
|
||||||
//
|
|
||||||
// See: http://openid.net/specs/openid-connect-core-1_0.html#ThirdPartyInitiatedLogin
|
|
||||||
InitiateLoginURI *url.URL
|
|
||||||
// Pre-registered request_uri values that may be cached by the server.
|
|
||||||
RequestURIs []url.URL
|
|
||||||
}
|
|
||||||
|
|
||||||
// Defaults returns a shallow copy of ClientMetadata with default
|
|
||||||
// values replacing omitted fields.
|
|
||||||
func (m ClientMetadata) Defaults() ClientMetadata {
|
|
||||||
if len(m.ResponseTypes) == 0 {
|
|
||||||
m.ResponseTypes = []string{oauth2.ResponseTypeCode}
|
|
||||||
}
|
|
||||||
if len(m.GrantTypes) == 0 {
|
|
||||||
m.GrantTypes = []string{oauth2.GrantTypeAuthCode}
|
|
||||||
}
|
|
||||||
if m.ApplicationType == "" {
|
|
||||||
m.ApplicationType = "web"
|
|
||||||
}
|
|
||||||
if m.TokenEndpointAuthMethod == "" {
|
|
||||||
m.TokenEndpointAuthMethod = oauth2.AuthMethodClientSecretBasic
|
|
||||||
}
|
|
||||||
m.IDTokenResponseOptions = m.IDTokenResponseOptions.defaults()
|
|
||||||
m.UserInfoResponseOptions = m.UserInfoResponseOptions.defaults()
|
|
||||||
m.RequestObjectOptions = m.RequestObjectOptions.defaults()
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *ClientMetadata) MarshalJSON() ([]byte, error) {
|
|
||||||
e := m.toEncodableStruct()
|
|
||||||
return json.Marshal(&e)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *ClientMetadata) UnmarshalJSON(data []byte) error {
|
|
||||||
var e encodableClientMetadata
|
|
||||||
if err := json.Unmarshal(data, &e); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
meta, err := e.toStruct()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := meta.Valid(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
*m = meta
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type encodableClientMetadata struct {
|
|
||||||
RedirectURIs []string `json:"redirect_uris"` // Required
|
|
||||||
ResponseTypes []string `json:"response_types,omitempty"`
|
|
||||||
GrantTypes []string `json:"grant_types,omitempty"`
|
|
||||||
ApplicationType string `json:"application_type,omitempty"`
|
|
||||||
Contacts []string `json:"contacts,omitempty"`
|
|
||||||
ClientName string `json:"client_name,omitempty"`
|
|
||||||
LogoURI string `json:"logo_uri,omitempty"`
|
|
||||||
ClientURI string `json:"client_uri,omitempty"`
|
|
||||||
PolicyURI string `json:"policy_uri,omitempty"`
|
|
||||||
TermsOfServiceURI string `json:"tos_uri,omitempty"`
|
|
||||||
JWKSURI string `json:"jwks_uri,omitempty"`
|
|
||||||
JWKS *jose.JWKSet `json:"jwks,omitempty"`
|
|
||||||
SectorIdentifierURI string `json:"sector_identifier_uri,omitempty"`
|
|
||||||
SubjectType string `json:"subject_type,omitempty"`
|
|
||||||
IDTokenSignedResponseAlg string `json:"id_token_signed_response_alg,omitempty"`
|
|
||||||
IDTokenEncryptedResponseAlg string `json:"id_token_encrypted_response_alg,omitempty"`
|
|
||||||
IDTokenEncryptedResponseEnc string `json:"id_token_encrypted_response_enc,omitempty"`
|
|
||||||
UserInfoSignedResponseAlg string `json:"userinfo_signed_response_alg,omitempty"`
|
|
||||||
UserInfoEncryptedResponseAlg string `json:"userinfo_encrypted_response_alg,omitempty"`
|
|
||||||
UserInfoEncryptedResponseEnc string `json:"userinfo_encrypted_response_enc,omitempty"`
|
|
||||||
RequestObjectSigningAlg string `json:"request_object_signing_alg,omitempty"`
|
|
||||||
RequestObjectEncryptionAlg string `json:"request_object_encryption_alg,omitempty"`
|
|
||||||
RequestObjectEncryptionEnc string `json:"request_object_encryption_enc,omitempty"`
|
|
||||||
TokenEndpointAuthMethod string `json:"token_endpoint_auth_method,omitempty"`
|
|
||||||
TokenEndpointAuthSigningAlg string `json:"token_endpoint_auth_signing_alg,omitempty"`
|
|
||||||
DefaultMaxAge int64 `json:"default_max_age,omitempty"`
|
|
||||||
RequireAuthTime bool `json:"require_auth_time,omitempty"`
|
|
||||||
DefaultACRValues []string `json:"default_acr_values,omitempty"`
|
|
||||||
InitiateLoginURI string `json:"initiate_login_uri,omitempty"`
|
|
||||||
RequestURIs []string `json:"request_uris,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *encodableClientMetadata) toStruct() (ClientMetadata, error) {
|
|
||||||
p := stickyErrParser{}
|
|
||||||
m := ClientMetadata{
|
|
||||||
RedirectURIs: p.parseURIs(c.RedirectURIs, "redirect_uris"),
|
|
||||||
ResponseTypes: c.ResponseTypes,
|
|
||||||
GrantTypes: c.GrantTypes,
|
|
||||||
ApplicationType: c.ApplicationType,
|
|
||||||
Contacts: p.parseEmails(c.Contacts, "contacts"),
|
|
||||||
ClientName: c.ClientName,
|
|
||||||
LogoURI: p.parseURI(c.LogoURI, "logo_uri"),
|
|
||||||
ClientURI: p.parseURI(c.ClientURI, "client_uri"),
|
|
||||||
PolicyURI: p.parseURI(c.PolicyURI, "policy_uri"),
|
|
||||||
TermsOfServiceURI: p.parseURI(c.TermsOfServiceURI, "tos_uri"),
|
|
||||||
JWKSURI: p.parseURI(c.JWKSURI, "jwks_uri"),
|
|
||||||
JWKS: c.JWKS,
|
|
||||||
SectorIdentifierURI: p.parseURI(c.SectorIdentifierURI, "sector_identifier_uri"),
|
|
||||||
SubjectType: c.SubjectType,
|
|
||||||
TokenEndpointAuthMethod: c.TokenEndpointAuthMethod,
|
|
||||||
TokenEndpointAuthSigningAlg: c.TokenEndpointAuthSigningAlg,
|
|
||||||
DefaultMaxAge: c.DefaultMaxAge,
|
|
||||||
RequireAuthTime: c.RequireAuthTime,
|
|
||||||
DefaultACRValues: c.DefaultACRValues,
|
|
||||||
InitiateLoginURI: p.parseURI(c.InitiateLoginURI, "initiate_login_uri"),
|
|
||||||
RequestURIs: p.parseURIs(c.RequestURIs, "request_uris"),
|
|
||||||
IDTokenResponseOptions: JWAOptions{
|
|
||||||
c.IDTokenSignedResponseAlg,
|
|
||||||
c.IDTokenEncryptedResponseAlg,
|
|
||||||
c.IDTokenEncryptedResponseEnc,
|
|
||||||
},
|
|
||||||
UserInfoResponseOptions: JWAOptions{
|
|
||||||
c.UserInfoSignedResponseAlg,
|
|
||||||
c.UserInfoEncryptedResponseAlg,
|
|
||||||
c.UserInfoEncryptedResponseEnc,
|
|
||||||
},
|
|
||||||
RequestObjectOptions: JWAOptions{
|
|
||||||
c.RequestObjectSigningAlg,
|
|
||||||
c.RequestObjectEncryptionAlg,
|
|
||||||
c.RequestObjectEncryptionEnc,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
if p.firstErr != nil {
|
|
||||||
return ClientMetadata{}, p.firstErr
|
|
||||||
}
|
|
||||||
return m, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// stickyErrParser parses URIs and email addresses. Once it encounters
|
|
||||||
// a parse error, subsequent calls become no-op.
|
|
||||||
type stickyErrParser struct {
|
|
||||||
firstErr error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *stickyErrParser) parseURI(s, field string) *url.URL {
|
|
||||||
if p.firstErr != nil || s == "" {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
u, err := url.Parse(s)
|
|
||||||
if err == nil {
|
|
||||||
if u.Host == "" {
|
|
||||||
err = errors.New("no host in URI")
|
|
||||||
} else if u.Scheme != "http" && u.Scheme != "https" {
|
|
||||||
err = errors.New("invalid URI scheme")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
p.firstErr = fmt.Errorf("failed to parse %s: %v", field, err)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return u
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *stickyErrParser) parseURIs(s []string, field string) []url.URL {
|
|
||||||
if p.firstErr != nil || len(s) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
uris := make([]url.URL, len(s))
|
|
||||||
for i, val := range s {
|
|
||||||
if val == "" {
|
|
||||||
p.firstErr = fmt.Errorf("invalid URI in field %s", field)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if u := p.parseURI(val, field); u != nil {
|
|
||||||
uris[i] = *u
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return uris
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *stickyErrParser) parseEmails(s []string, field string) []mail.Address {
|
|
||||||
if p.firstErr != nil || len(s) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
addrs := make([]mail.Address, len(s))
|
|
||||||
for i, addr := range s {
|
|
||||||
if addr == "" {
|
|
||||||
p.firstErr = fmt.Errorf("invalid email in field %s", field)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
a, err := mail.ParseAddress(addr)
|
|
||||||
if err != nil {
|
|
||||||
p.firstErr = fmt.Errorf("invalid email in field %s: %v", field, err)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
addrs[i] = *a
|
|
||||||
}
|
|
||||||
return addrs
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *ClientMetadata) toEncodableStruct() encodableClientMetadata {
|
|
||||||
return encodableClientMetadata{
|
|
||||||
RedirectURIs: urisToStrings(m.RedirectURIs),
|
|
||||||
ResponseTypes: m.ResponseTypes,
|
|
||||||
GrantTypes: m.GrantTypes,
|
|
||||||
ApplicationType: m.ApplicationType,
|
|
||||||
Contacts: emailsToStrings(m.Contacts),
|
|
||||||
ClientName: m.ClientName,
|
|
||||||
LogoURI: uriToString(m.LogoURI),
|
|
||||||
ClientURI: uriToString(m.ClientURI),
|
|
||||||
PolicyURI: uriToString(m.PolicyURI),
|
|
||||||
TermsOfServiceURI: uriToString(m.TermsOfServiceURI),
|
|
||||||
JWKSURI: uriToString(m.JWKSURI),
|
|
||||||
JWKS: m.JWKS,
|
|
||||||
SectorIdentifierURI: uriToString(m.SectorIdentifierURI),
|
|
||||||
SubjectType: m.SubjectType,
|
|
||||||
IDTokenSignedResponseAlg: m.IDTokenResponseOptions.SigningAlg,
|
|
||||||
IDTokenEncryptedResponseAlg: m.IDTokenResponseOptions.EncryptionAlg,
|
|
||||||
IDTokenEncryptedResponseEnc: m.IDTokenResponseOptions.EncryptionEnc,
|
|
||||||
UserInfoSignedResponseAlg: m.UserInfoResponseOptions.SigningAlg,
|
|
||||||
UserInfoEncryptedResponseAlg: m.UserInfoResponseOptions.EncryptionAlg,
|
|
||||||
UserInfoEncryptedResponseEnc: m.UserInfoResponseOptions.EncryptionEnc,
|
|
||||||
RequestObjectSigningAlg: m.RequestObjectOptions.SigningAlg,
|
|
||||||
RequestObjectEncryptionAlg: m.RequestObjectOptions.EncryptionAlg,
|
|
||||||
RequestObjectEncryptionEnc: m.RequestObjectOptions.EncryptionEnc,
|
|
||||||
TokenEndpointAuthMethod: m.TokenEndpointAuthMethod,
|
|
||||||
TokenEndpointAuthSigningAlg: m.TokenEndpointAuthSigningAlg,
|
|
||||||
DefaultMaxAge: m.DefaultMaxAge,
|
|
||||||
RequireAuthTime: m.RequireAuthTime,
|
|
||||||
DefaultACRValues: m.DefaultACRValues,
|
|
||||||
InitiateLoginURI: uriToString(m.InitiateLoginURI),
|
|
||||||
RequestURIs: urisToStrings(m.RequestURIs),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func uriToString(u *url.URL) string {
|
|
||||||
if u == nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return u.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func urisToStrings(urls []url.URL) []string {
|
|
||||||
if len(urls) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
sli := make([]string, len(urls))
|
|
||||||
for i, u := range urls {
|
|
||||||
sli[i] = u.String()
|
|
||||||
}
|
|
||||||
return sli
|
|
||||||
}
|
|
||||||
|
|
||||||
func emailsToStrings(addrs []mail.Address) []string {
|
|
||||||
if len(addrs) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
sli := make([]string, len(addrs))
|
|
||||||
for i, addr := range addrs {
|
|
||||||
sli[i] = addr.String()
|
|
||||||
}
|
|
||||||
return sli
|
|
||||||
}
|
|
||||||
|
|
||||||
// Valid determines if a ClientMetadata conforms with the OIDC specification.
|
|
||||||
//
|
|
||||||
// Valid is called by UnmarshalJSON.
|
|
||||||
//
|
|
||||||
// NOTE(ericchiang): For development purposes Valid does not mandate 'https' for
|
|
||||||
// URLs fields where the OIDC spec requires it. This may change in future releases
|
|
||||||
// of this package. See: https://github.com/coreos/go-oidc/issues/34
|
|
||||||
func (m *ClientMetadata) Valid() error {
|
|
||||||
if len(m.RedirectURIs) == 0 {
|
|
||||||
return errors.New("zero redirect URLs")
|
|
||||||
}
|
|
||||||
|
|
||||||
validURI := func(u *url.URL, fieldName string) error {
|
|
||||||
if u.Host == "" {
|
|
||||||
return fmt.Errorf("no host for uri field %s", fieldName)
|
|
||||||
}
|
|
||||||
if u.Scheme != "http" && u.Scheme != "https" {
|
|
||||||
return fmt.Errorf("uri field %s scheme is not http or https", fieldName)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
uris := []struct {
|
|
||||||
val *url.URL
|
|
||||||
name string
|
|
||||||
}{
|
|
||||||
{m.LogoURI, "logo_uri"},
|
|
||||||
{m.ClientURI, "client_uri"},
|
|
||||||
{m.PolicyURI, "policy_uri"},
|
|
||||||
{m.TermsOfServiceURI, "tos_uri"},
|
|
||||||
{m.JWKSURI, "jwks_uri"},
|
|
||||||
{m.SectorIdentifierURI, "sector_identifier_uri"},
|
|
||||||
{m.InitiateLoginURI, "initiate_login_uri"},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, uri := range uris {
|
|
||||||
if uri.val == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if err := validURI(uri.val, uri.name); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uriLists := []struct {
|
|
||||||
vals []url.URL
|
|
||||||
name string
|
|
||||||
}{
|
|
||||||
{m.RedirectURIs, "redirect_uris"},
|
|
||||||
{m.RequestURIs, "request_uris"},
|
|
||||||
}
|
|
||||||
for _, list := range uriLists {
|
|
||||||
for _, uri := range list.vals {
|
|
||||||
if err := validURI(&uri, list.name); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
options := []struct {
|
|
||||||
option JWAOptions
|
|
||||||
name string
|
|
||||||
}{
|
|
||||||
{m.IDTokenResponseOptions, "id_token response"},
|
|
||||||
{m.UserInfoResponseOptions, "userinfo response"},
|
|
||||||
{m.RequestObjectOptions, "request_object"},
|
|
||||||
}
|
|
||||||
for _, option := range options {
|
|
||||||
if err := option.option.valid(); err != nil {
|
|
||||||
return fmt.Errorf("invalid JWA values for %s: %v", option.name, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type ClientRegistrationResponse struct {
|
|
||||||
ClientID string // Required
|
|
||||||
ClientSecret string
|
|
||||||
RegistrationAccessToken string
|
|
||||||
RegistrationClientURI string
|
|
||||||
// If IsZero is true, unspecified.
|
|
||||||
ClientIDIssuedAt time.Time
|
|
||||||
// Time at which the client_secret will expire.
|
|
||||||
// If IsZero is true, it will not expire.
|
|
||||||
ClientSecretExpiresAt time.Time
|
|
||||||
|
|
||||||
ClientMetadata
|
|
||||||
}
|
|
||||||
|
|
||||||
type encodableClientRegistrationResponse struct {
|
|
||||||
ClientID string `json:"client_id"` // Required
|
|
||||||
ClientSecret string `json:"client_secret,omitempty"`
|
|
||||||
RegistrationAccessToken string `json:"registration_access_token,omitempty"`
|
|
||||||
RegistrationClientURI string `json:"registration_client_uri,omitempty"`
|
|
||||||
ClientIDIssuedAt int64 `json:"client_id_issued_at,omitempty"`
|
|
||||||
// Time at which the client_secret will expire, in seconds since the epoch.
|
|
||||||
// If 0 it will not expire.
|
|
||||||
ClientSecretExpiresAt int64 `json:"client_secret_expires_at"` // Required
|
|
||||||
|
|
||||||
encodableClientMetadata
|
|
||||||
}
|
|
||||||
|
|
||||||
func unixToSec(t time.Time) int64 {
|
|
||||||
if t.IsZero() {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return t.Unix()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *ClientRegistrationResponse) MarshalJSON() ([]byte, error) {
|
|
||||||
e := encodableClientRegistrationResponse{
|
|
||||||
ClientID: c.ClientID,
|
|
||||||
ClientSecret: c.ClientSecret,
|
|
||||||
RegistrationAccessToken: c.RegistrationAccessToken,
|
|
||||||
RegistrationClientURI: c.RegistrationClientURI,
|
|
||||||
ClientIDIssuedAt: unixToSec(c.ClientIDIssuedAt),
|
|
||||||
ClientSecretExpiresAt: unixToSec(c.ClientSecretExpiresAt),
|
|
||||||
encodableClientMetadata: c.ClientMetadata.toEncodableStruct(),
|
|
||||||
}
|
|
||||||
return json.Marshal(&e)
|
|
||||||
}
|
|
||||||
|
|
||||||
func secToUnix(sec int64) time.Time {
|
|
||||||
if sec == 0 {
|
|
||||||
return time.Time{}
|
|
||||||
}
|
|
||||||
return time.Unix(sec, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *ClientRegistrationResponse) UnmarshalJSON(data []byte) error {
|
|
||||||
var e encodableClientRegistrationResponse
|
|
||||||
if err := json.Unmarshal(data, &e); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if e.ClientID == "" {
|
|
||||||
return errors.New("no client_id in client registration response")
|
|
||||||
}
|
|
||||||
metadata, err := e.encodableClientMetadata.toStruct()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
*c = ClientRegistrationResponse{
|
|
||||||
ClientID: e.ClientID,
|
|
||||||
ClientSecret: e.ClientSecret,
|
|
||||||
RegistrationAccessToken: e.RegistrationAccessToken,
|
|
||||||
RegistrationClientURI: e.RegistrationClientURI,
|
|
||||||
ClientIDIssuedAt: secToUnix(e.ClientIDIssuedAt),
|
|
||||||
ClientSecretExpiresAt: secToUnix(e.ClientSecretExpiresAt),
|
|
||||||
ClientMetadata: metadata,
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type ClientConfig struct {
|
|
||||||
HTTPClient phttp.Client
|
|
||||||
Credentials ClientCredentials
|
|
||||||
Scope []string
|
|
||||||
RedirectURL string
|
|
||||||
ProviderConfig ProviderConfig
|
|
||||||
KeySet key.PublicKeySet
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewClient(cfg ClientConfig) (*Client, error) {
|
|
||||||
// Allow empty redirect URL in the case where the client
|
|
||||||
// only needs to verify a given token.
|
|
||||||
ru, err := url.Parse(cfg.RedirectURL)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("invalid redirect URL: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
c := Client{
|
|
||||||
credentials: cfg.Credentials,
|
|
||||||
httpClient: cfg.HTTPClient,
|
|
||||||
scope: cfg.Scope,
|
|
||||||
redirectURL: ru.String(),
|
|
||||||
providerConfig: newProviderConfigRepo(cfg.ProviderConfig),
|
|
||||||
keySet: cfg.KeySet,
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.httpClient == nil {
|
|
||||||
c.httpClient = http.DefaultClient
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.scope == nil {
|
|
||||||
c.scope = make([]string, len(DefaultScope))
|
|
||||||
copy(c.scope, DefaultScope)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &c, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type Client struct {
|
|
||||||
httpClient phttp.Client
|
|
||||||
providerConfig *providerConfigRepo
|
|
||||||
credentials ClientCredentials
|
|
||||||
redirectURL string
|
|
||||||
scope []string
|
|
||||||
keySet key.PublicKeySet
|
|
||||||
providerSyncer *ProviderConfigSyncer
|
|
||||||
|
|
||||||
keySetSyncMutex sync.RWMutex
|
|
||||||
lastKeySetSync time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Client) Healthy() error {
|
|
||||||
now := time.Now().UTC()
|
|
||||||
|
|
||||||
cfg := c.providerConfig.Get()
|
|
||||||
|
|
||||||
if cfg.Empty() {
|
|
||||||
return errors.New("oidc client provider config empty")
|
|
||||||
}
|
|
||||||
|
|
||||||
if !cfg.ExpiresAt.IsZero() && cfg.ExpiresAt.Before(now) {
|
|
||||||
return errors.New("oidc client provider config expired")
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Client) OAuthClient() (*oauth2.Client, error) {
|
|
||||||
cfg := c.providerConfig.Get()
|
|
||||||
authMethod, err := chooseAuthMethod(cfg)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
ocfg := oauth2.Config{
|
|
||||||
Credentials: oauth2.ClientCredentials(c.credentials),
|
|
||||||
RedirectURL: c.redirectURL,
|
|
||||||
AuthURL: cfg.AuthEndpoint.String(),
|
|
||||||
TokenURL: cfg.TokenEndpoint.String(),
|
|
||||||
Scope: c.scope,
|
|
||||||
AuthMethod: authMethod,
|
|
||||||
}
|
|
||||||
|
|
||||||
return oauth2.NewClient(c.httpClient, ocfg)
|
|
||||||
}
|
|
||||||
|
|
||||||
func chooseAuthMethod(cfg ProviderConfig) (string, error) {
|
|
||||||
if len(cfg.TokenEndpointAuthMethodsSupported) == 0 {
|
|
||||||
return oauth2.AuthMethodClientSecretBasic, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, authMethod := range cfg.TokenEndpointAuthMethodsSupported {
|
|
||||||
if _, ok := supportedAuthMethods[authMethod]; ok {
|
|
||||||
return authMethod, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return "", errors.New("no supported auth methods")
|
|
||||||
}
|
|
||||||
|
|
||||||
// SyncProviderConfig starts the provider config syncer
|
|
||||||
func (c *Client) SyncProviderConfig(discoveryURL string) chan struct{} {
|
|
||||||
r := NewHTTPProviderConfigGetter(c.httpClient, discoveryURL)
|
|
||||||
s := NewProviderConfigSyncer(r, c.providerConfig)
|
|
||||||
stop := s.Run()
|
|
||||||
s.WaitUntilInitialSync()
|
|
||||||
return stop
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Client) maybeSyncKeys() error {
|
|
||||||
tooSoon := func() bool {
|
|
||||||
return time.Now().UTC().Before(c.lastKeySetSync.Add(keySyncWindow))
|
|
||||||
}
|
|
||||||
|
|
||||||
// ignore request to sync keys if a sync operation has been
|
|
||||||
// attempted too recently
|
|
||||||
if tooSoon() {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
c.keySetSyncMutex.Lock()
|
|
||||||
defer c.keySetSyncMutex.Unlock()
|
|
||||||
|
|
||||||
// check again, as another goroutine may have been holding
|
|
||||||
// the lock while updating the keys
|
|
||||||
if tooSoon() {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
cfg := c.providerConfig.Get()
|
|
||||||
r := NewRemotePublicKeyRepo(c.httpClient, cfg.KeysEndpoint.String())
|
|
||||||
w := &clientKeyRepo{client: c}
|
|
||||||
_, err := key.Sync(r, w)
|
|
||||||
c.lastKeySetSync = time.Now().UTC()
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
type clientKeyRepo struct {
|
|
||||||
client *Client
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *clientKeyRepo) Set(ks key.KeySet) error {
|
|
||||||
pks, ok := ks.(*key.PublicKeySet)
|
|
||||||
if !ok {
|
|
||||||
return errors.New("unable to cast to PublicKey")
|
|
||||||
}
|
|
||||||
r.client.keySet = *pks
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Client) ClientCredsToken(scope []string) (jose.JWT, error) {
|
|
||||||
cfg := c.providerConfig.Get()
|
|
||||||
|
|
||||||
if !cfg.SupportsGrantType(oauth2.GrantTypeClientCreds) {
|
|
||||||
return jose.JWT{}, fmt.Errorf("%v grant type is not supported", oauth2.GrantTypeClientCreds)
|
|
||||||
}
|
|
||||||
|
|
||||||
oac, err := c.OAuthClient()
|
|
||||||
if err != nil {
|
|
||||||
return jose.JWT{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
t, err := oac.ClientCredsToken(scope)
|
|
||||||
if err != nil {
|
|
||||||
return jose.JWT{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
jwt, err := jose.ParseJWT(t.IDToken)
|
|
||||||
if err != nil {
|
|
||||||
return jose.JWT{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return jwt, c.VerifyJWT(jwt)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ExchangeAuthCode exchanges an OAuth2 auth code for an OIDC JWT ID token.
|
|
||||||
func (c *Client) ExchangeAuthCode(code string) (jose.JWT, error) {
|
|
||||||
oac, err := c.OAuthClient()
|
|
||||||
if err != nil {
|
|
||||||
return jose.JWT{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
t, err := oac.RequestToken(oauth2.GrantTypeAuthCode, code)
|
|
||||||
if err != nil {
|
|
||||||
return jose.JWT{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
jwt, err := jose.ParseJWT(t.IDToken)
|
|
||||||
if err != nil {
|
|
||||||
return jose.JWT{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return jwt, c.VerifyJWT(jwt)
|
|
||||||
}
|
|
||||||
|
|
||||||
// RefreshToken uses a refresh token to exchange for a new OIDC JWT ID Token.
|
|
||||||
func (c *Client) RefreshToken(refreshToken string) (jose.JWT, error) {
|
|
||||||
oac, err := c.OAuthClient()
|
|
||||||
if err != nil {
|
|
||||||
return jose.JWT{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
t, err := oac.RequestToken(oauth2.GrantTypeRefreshToken, refreshToken)
|
|
||||||
if err != nil {
|
|
||||||
return jose.JWT{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
jwt, err := jose.ParseJWT(t.IDToken)
|
|
||||||
if err != nil {
|
|
||||||
return jose.JWT{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return jwt, c.VerifyJWT(jwt)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Client) VerifyJWT(jwt jose.JWT) error {
|
|
||||||
var keysFunc func() []key.PublicKey
|
|
||||||
if kID, ok := jwt.KeyID(); ok {
|
|
||||||
keysFunc = c.keysFuncWithID(kID)
|
|
||||||
} else {
|
|
||||||
keysFunc = c.keysFuncAll()
|
|
||||||
}
|
|
||||||
|
|
||||||
v := NewJWTVerifier(
|
|
||||||
c.providerConfig.Get().Issuer.String(),
|
|
||||||
c.credentials.ID,
|
|
||||||
c.maybeSyncKeys, keysFunc)
|
|
||||||
|
|
||||||
return v.Verify(jwt)
|
|
||||||
}
|
|
||||||
|
|
||||||
// keysFuncWithID returns a function that retrieves at most unexpired
|
|
||||||
// public key from the Client that matches the provided ID
|
|
||||||
func (c *Client) keysFuncWithID(kID string) func() []key.PublicKey {
|
|
||||||
return func() []key.PublicKey {
|
|
||||||
c.keySetSyncMutex.RLock()
|
|
||||||
defer c.keySetSyncMutex.RUnlock()
|
|
||||||
|
|
||||||
if c.keySet.ExpiresAt().Before(time.Now()) {
|
|
||||||
return []key.PublicKey{}
|
|
||||||
}
|
|
||||||
|
|
||||||
k := c.keySet.Key(kID)
|
|
||||||
if k == nil {
|
|
||||||
return []key.PublicKey{}
|
|
||||||
}
|
|
||||||
|
|
||||||
return []key.PublicKey{*k}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// keysFuncAll returns a function that retrieves all unexpired public
|
|
||||||
// keys from the Client
|
|
||||||
func (c *Client) keysFuncAll() func() []key.PublicKey {
|
|
||||||
return func() []key.PublicKey {
|
|
||||||
c.keySetSyncMutex.RLock()
|
|
||||||
defer c.keySetSyncMutex.RUnlock()
|
|
||||||
|
|
||||||
if c.keySet.ExpiresAt().Before(time.Now()) {
|
|
||||||
return []key.PublicKey{}
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.keySet.Keys()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type providerConfigRepo struct {
|
|
||||||
mu sync.RWMutex
|
|
||||||
config ProviderConfig // do not access directly, use Get()
|
|
||||||
}
|
|
||||||
|
|
||||||
func newProviderConfigRepo(pc ProviderConfig) *providerConfigRepo {
|
|
||||||
return &providerConfigRepo{sync.RWMutex{}, pc}
|
|
||||||
}
|
|
||||||
|
|
||||||
// returns an error to implement ProviderConfigSetter
|
|
||||||
func (r *providerConfigRepo) Set(cfg ProviderConfig) error {
|
|
||||||
r.mu.Lock()
|
|
||||||
defer r.mu.Unlock()
|
|
||||||
r.config = cfg
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *providerConfigRepo) Get() ProviderConfig {
|
|
||||||
r.mu.RLock()
|
|
||||||
defer r.mu.RUnlock()
|
|
||||||
return r.config
|
|
||||||
}
|
|
44
vendor/github.com/coreos/go-oidc/oidc/identity.go
generated
vendored
44
vendor/github.com/coreos/go-oidc/oidc/identity.go
generated
vendored
|
@ -1,44 +0,0 @@
|
||||||
package oidc
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/coreos/go-oidc/jose"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Identity struct {
|
|
||||||
ID string
|
|
||||||
Name string
|
|
||||||
Email string
|
|
||||||
ExpiresAt time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
func IdentityFromClaims(claims jose.Claims) (*Identity, error) {
|
|
||||||
if claims == nil {
|
|
||||||
return nil, errors.New("nil claim set")
|
|
||||||
}
|
|
||||||
|
|
||||||
var ident Identity
|
|
||||||
var err error
|
|
||||||
var ok bool
|
|
||||||
|
|
||||||
if ident.ID, ok, err = claims.StringClaim("sub"); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else if !ok {
|
|
||||||
return nil, errors.New("missing required claim: sub")
|
|
||||||
}
|
|
||||||
|
|
||||||
if ident.Email, _, err = claims.StringClaim("email"); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
exp, ok, err := claims.TimeClaim("exp")
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else if ok {
|
|
||||||
ident.ExpiresAt = exp
|
|
||||||
}
|
|
||||||
|
|
||||||
return &ident, nil
|
|
||||||
}
|
|
3
vendor/github.com/coreos/go-oidc/oidc/interface.go
generated
vendored
3
vendor/github.com/coreos/go-oidc/oidc/interface.go
generated
vendored
|
@ -1,3 +0,0 @@
|
||||||
package oidc
|
|
||||||
|
|
||||||
type LoginFunc func(ident Identity, sessionKey string) (redirectURL string, err error)
|
|
67
vendor/github.com/coreos/go-oidc/oidc/key.go
generated
vendored
67
vendor/github.com/coreos/go-oidc/oidc/key.go
generated
vendored
|
@ -1,67 +0,0 @@
|
||||||
package oidc
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
|
||||||
"net/http"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
phttp "github.com/coreos/go-oidc/http"
|
|
||||||
"github.com/coreos/go-oidc/jose"
|
|
||||||
"github.com/coreos/go-oidc/key"
|
|
||||||
)
|
|
||||||
|
|
||||||
// DefaultPublicKeySetTTL is the default TTL set on the PublicKeySet if no
|
|
||||||
// Cache-Control header is provided by the JWK Set document endpoint.
|
|
||||||
const DefaultPublicKeySetTTL = 24 * time.Hour
|
|
||||||
|
|
||||||
// NewRemotePublicKeyRepo is responsible for fetching the JWK Set document.
|
|
||||||
func NewRemotePublicKeyRepo(hc phttp.Client, ep string) *remotePublicKeyRepo {
|
|
||||||
return &remotePublicKeyRepo{hc: hc, ep: ep}
|
|
||||||
}
|
|
||||||
|
|
||||||
type remotePublicKeyRepo struct {
|
|
||||||
hc phttp.Client
|
|
||||||
ep string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get returns a PublicKeySet fetched from the JWK Set document endpoint. A TTL
|
|
||||||
// is set on the Key Set to avoid it having to be re-retrieved for every
|
|
||||||
// encryption event. This TTL is typically controlled by the endpoint returning
|
|
||||||
// a Cache-Control header, but defaults to 24 hours if no Cache-Control header
|
|
||||||
// is found.
|
|
||||||
func (r *remotePublicKeyRepo) Get() (key.KeySet, error) {
|
|
||||||
req, err := http.NewRequest("GET", r.ep, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := r.hc.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
var d struct {
|
|
||||||
Keys []jose.JWK `json:"keys"`
|
|
||||||
}
|
|
||||||
if err := json.NewDecoder(resp.Body).Decode(&d); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(d.Keys) == 0 {
|
|
||||||
return nil, errors.New("zero keys in response")
|
|
||||||
}
|
|
||||||
|
|
||||||
ttl, ok, err := phttp.Cacheable(resp.Header)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if !ok {
|
|
||||||
ttl = DefaultPublicKeySetTTL
|
|
||||||
}
|
|
||||||
|
|
||||||
exp := time.Now().UTC().Add(ttl)
|
|
||||||
ks := key.NewPublicKeySet(d.Keys, exp)
|
|
||||||
return ks, nil
|
|
||||||
}
|
|
690
vendor/github.com/coreos/go-oidc/oidc/provider.go
generated
vendored
690
vendor/github.com/coreos/go-oidc/oidc/provider.go
generated
vendored
|
@ -1,690 +0,0 @@
|
||||||
package oidc
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/coreos/pkg/timeutil"
|
|
||||||
"github.com/jonboulle/clockwork"
|
|
||||||
|
|
||||||
phttp "github.com/coreos/go-oidc/http"
|
|
||||||
"github.com/coreos/go-oidc/oauth2"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// Subject Identifier types defined by the OIDC spec. Specifies if the provider
|
|
||||||
// should provide the same sub claim value to all clients (public) or a unique
|
|
||||||
// value for each client (pairwise).
|
|
||||||
//
|
|
||||||
// See: http://openid.net/specs/openid-connect-core-1_0.html#SubjectIDTypes
|
|
||||||
SubjectTypePublic = "public"
|
|
||||||
SubjectTypePairwise = "pairwise"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
// Default values for omitted provider config fields.
|
|
||||||
//
|
|
||||||
// Use ProviderConfig's Defaults method to fill a provider config with these values.
|
|
||||||
DefaultGrantTypesSupported = []string{oauth2.GrantTypeAuthCode, oauth2.GrantTypeImplicit}
|
|
||||||
DefaultResponseModesSupported = []string{"query", "fragment"}
|
|
||||||
DefaultTokenEndpointAuthMethodsSupported = []string{oauth2.AuthMethodClientSecretBasic}
|
|
||||||
DefaultClaimTypesSupported = []string{"normal"}
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
MaximumProviderConfigSyncInterval = 24 * time.Hour
|
|
||||||
MinimumProviderConfigSyncInterval = time.Minute
|
|
||||||
|
|
||||||
discoveryConfigPath = "/.well-known/openid-configuration"
|
|
||||||
)
|
|
||||||
|
|
||||||
// internally configurable for tests
|
|
||||||
var minimumProviderConfigSyncInterval = MinimumProviderConfigSyncInterval
|
|
||||||
|
|
||||||
var (
|
|
||||||
// Ensure ProviderConfig satisfies these interfaces.
|
|
||||||
_ json.Marshaler = &ProviderConfig{}
|
|
||||||
_ json.Unmarshaler = &ProviderConfig{}
|
|
||||||
)
|
|
||||||
|
|
||||||
// ProviderConfig represents the OpenID Provider Metadata specifying what
|
|
||||||
// configurations a provider supports.
|
|
||||||
//
|
|
||||||
// See: http://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata
|
|
||||||
type ProviderConfig struct {
|
|
||||||
Issuer *url.URL // Required
|
|
||||||
AuthEndpoint *url.URL // Required
|
|
||||||
TokenEndpoint *url.URL // Required if grant types other than "implicit" are supported
|
|
||||||
UserInfoEndpoint *url.URL
|
|
||||||
KeysEndpoint *url.URL // Required
|
|
||||||
RegistrationEndpoint *url.URL
|
|
||||||
EndSessionEndpoint *url.URL
|
|
||||||
CheckSessionIFrame *url.URL
|
|
||||||
|
|
||||||
// Servers MAY choose not to advertise some supported scope values even when this
|
|
||||||
// parameter is used, although those defined in OpenID Core SHOULD be listed, if supported.
|
|
||||||
ScopesSupported []string
|
|
||||||
// OAuth2.0 response types supported.
|
|
||||||
ResponseTypesSupported []string // Required
|
|
||||||
// OAuth2.0 response modes supported.
|
|
||||||
//
|
|
||||||
// If omitted, defaults to DefaultResponseModesSupported.
|
|
||||||
ResponseModesSupported []string
|
|
||||||
// OAuth2.0 grant types supported.
|
|
||||||
//
|
|
||||||
// If omitted, defaults to DefaultGrantTypesSupported.
|
|
||||||
GrantTypesSupported []string
|
|
||||||
ACRValuesSupported []string
|
|
||||||
// SubjectTypesSupported specifies strategies for providing values for the sub claim.
|
|
||||||
SubjectTypesSupported []string // Required
|
|
||||||
|
|
||||||
// JWA signing and encryption algorith values supported for ID tokens.
|
|
||||||
IDTokenSigningAlgValues []string // Required
|
|
||||||
IDTokenEncryptionAlgValues []string
|
|
||||||
IDTokenEncryptionEncValues []string
|
|
||||||
|
|
||||||
// JWA signing and encryption algorith values supported for user info responses.
|
|
||||||
UserInfoSigningAlgValues []string
|
|
||||||
UserInfoEncryptionAlgValues []string
|
|
||||||
UserInfoEncryptionEncValues []string
|
|
||||||
|
|
||||||
// JWA signing and encryption algorith values supported for request objects.
|
|
||||||
ReqObjSigningAlgValues []string
|
|
||||||
ReqObjEncryptionAlgValues []string
|
|
||||||
ReqObjEncryptionEncValues []string
|
|
||||||
|
|
||||||
TokenEndpointAuthMethodsSupported []string
|
|
||||||
TokenEndpointAuthSigningAlgValuesSupported []string
|
|
||||||
DisplayValuesSupported []string
|
|
||||||
ClaimTypesSupported []string
|
|
||||||
ClaimsSupported []string
|
|
||||||
ServiceDocs *url.URL
|
|
||||||
ClaimsLocalsSupported []string
|
|
||||||
UILocalsSupported []string
|
|
||||||
ClaimsParameterSupported bool
|
|
||||||
RequestParameterSupported bool
|
|
||||||
RequestURIParamaterSupported bool
|
|
||||||
RequireRequestURIRegistration bool
|
|
||||||
|
|
||||||
Policy *url.URL
|
|
||||||
TermsOfService *url.URL
|
|
||||||
|
|
||||||
// Not part of the OpenID Provider Metadata
|
|
||||||
ExpiresAt time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
// Defaults returns a shallow copy of ProviderConfig with default
|
|
||||||
// values replacing omitted fields.
|
|
||||||
//
|
|
||||||
// var cfg oidc.ProviderConfig
|
|
||||||
// // Fill provider config with default values for omitted fields.
|
|
||||||
// cfg = cfg.Defaults()
|
|
||||||
//
|
|
||||||
func (p ProviderConfig) Defaults() ProviderConfig {
|
|
||||||
setDefault := func(val *[]string, defaultVal []string) {
|
|
||||||
if len(*val) == 0 {
|
|
||||||
*val = defaultVal
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setDefault(&p.GrantTypesSupported, DefaultGrantTypesSupported)
|
|
||||||
setDefault(&p.ResponseModesSupported, DefaultResponseModesSupported)
|
|
||||||
setDefault(&p.TokenEndpointAuthMethodsSupported, DefaultTokenEndpointAuthMethodsSupported)
|
|
||||||
setDefault(&p.ClaimTypesSupported, DefaultClaimTypesSupported)
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *ProviderConfig) MarshalJSON() ([]byte, error) {
|
|
||||||
e := p.toEncodableStruct()
|
|
||||||
return json.Marshal(&e)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *ProviderConfig) UnmarshalJSON(data []byte) error {
|
|
||||||
var e encodableProviderConfig
|
|
||||||
if err := json.Unmarshal(data, &e); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
conf, err := e.toStruct()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := conf.Valid(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
*p = conf
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type encodableProviderConfig struct {
|
|
||||||
Issuer string `json:"issuer"`
|
|
||||||
AuthEndpoint string `json:"authorization_endpoint"`
|
|
||||||
TokenEndpoint string `json:"token_endpoint"`
|
|
||||||
UserInfoEndpoint string `json:"userinfo_endpoint,omitempty"`
|
|
||||||
KeysEndpoint string `json:"jwks_uri"`
|
|
||||||
RegistrationEndpoint string `json:"registration_endpoint,omitempty"`
|
|
||||||
EndSessionEndpoint string `json:"end_session_endpoint,omitempty"`
|
|
||||||
CheckSessionIFrame string `json:"check_session_iframe,omitempty"`
|
|
||||||
|
|
||||||
// Use 'omitempty' for all slices as per OIDC spec:
|
|
||||||
// "Claims that return multiple values are represented as JSON arrays.
|
|
||||||
// Claims with zero elements MUST be omitted from the response."
|
|
||||||
// http://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationResponse
|
|
||||||
|
|
||||||
ScopesSupported []string `json:"scopes_supported,omitempty"`
|
|
||||||
ResponseTypesSupported []string `json:"response_types_supported,omitempty"`
|
|
||||||
ResponseModesSupported []string `json:"response_modes_supported,omitempty"`
|
|
||||||
GrantTypesSupported []string `json:"grant_types_supported,omitempty"`
|
|
||||||
ACRValuesSupported []string `json:"acr_values_supported,omitempty"`
|
|
||||||
SubjectTypesSupported []string `json:"subject_types_supported,omitempty"`
|
|
||||||
|
|
||||||
IDTokenSigningAlgValues []string `json:"id_token_signing_alg_values_supported,omitempty"`
|
|
||||||
IDTokenEncryptionAlgValues []string `json:"id_token_encryption_alg_values_supported,omitempty"`
|
|
||||||
IDTokenEncryptionEncValues []string `json:"id_token_encryption_enc_values_supported,omitempty"`
|
|
||||||
UserInfoSigningAlgValues []string `json:"userinfo_signing_alg_values_supported,omitempty"`
|
|
||||||
UserInfoEncryptionAlgValues []string `json:"userinfo_encryption_alg_values_supported,omitempty"`
|
|
||||||
UserInfoEncryptionEncValues []string `json:"userinfo_encryption_enc_values_supported,omitempty"`
|
|
||||||
ReqObjSigningAlgValues []string `json:"request_object_signing_alg_values_supported,omitempty"`
|
|
||||||
ReqObjEncryptionAlgValues []string `json:"request_object_encryption_alg_values_supported,omitempty"`
|
|
||||||
ReqObjEncryptionEncValues []string `json:"request_object_encryption_enc_values_supported,omitempty"`
|
|
||||||
|
|
||||||
TokenEndpointAuthMethodsSupported []string `json:"token_endpoint_auth_methods_supported,omitempty"`
|
|
||||||
TokenEndpointAuthSigningAlgValuesSupported []string `json:"token_endpoint_auth_signing_alg_values_supported,omitempty"`
|
|
||||||
|
|
||||||
DisplayValuesSupported []string `json:"display_values_supported,omitempty"`
|
|
||||||
ClaimTypesSupported []string `json:"claim_types_supported,omitempty"`
|
|
||||||
ClaimsSupported []string `json:"claims_supported,omitempty"`
|
|
||||||
ServiceDocs string `json:"service_documentation,omitempty"`
|
|
||||||
ClaimsLocalsSupported []string `json:"claims_locales_supported,omitempty"`
|
|
||||||
UILocalsSupported []string `json:"ui_locales_supported,omitempty"`
|
|
||||||
ClaimsParameterSupported bool `json:"claims_parameter_supported,omitempty"`
|
|
||||||
RequestParameterSupported bool `json:"request_parameter_supported,omitempty"`
|
|
||||||
RequestURIParamaterSupported bool `json:"request_uri_parameter_supported,omitempty"`
|
|
||||||
RequireRequestURIRegistration bool `json:"require_request_uri_registration,omitempty"`
|
|
||||||
|
|
||||||
Policy string `json:"op_policy_uri,omitempty"`
|
|
||||||
TermsOfService string `json:"op_tos_uri,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cfg ProviderConfig) toEncodableStruct() encodableProviderConfig {
|
|
||||||
return encodableProviderConfig{
|
|
||||||
Issuer: uriToString(cfg.Issuer),
|
|
||||||
AuthEndpoint: uriToString(cfg.AuthEndpoint),
|
|
||||||
TokenEndpoint: uriToString(cfg.TokenEndpoint),
|
|
||||||
UserInfoEndpoint: uriToString(cfg.UserInfoEndpoint),
|
|
||||||
KeysEndpoint: uriToString(cfg.KeysEndpoint),
|
|
||||||
RegistrationEndpoint: uriToString(cfg.RegistrationEndpoint),
|
|
||||||
EndSessionEndpoint: uriToString(cfg.EndSessionEndpoint),
|
|
||||||
CheckSessionIFrame: uriToString(cfg.CheckSessionIFrame),
|
|
||||||
ScopesSupported: cfg.ScopesSupported,
|
|
||||||
ResponseTypesSupported: cfg.ResponseTypesSupported,
|
|
||||||
ResponseModesSupported: cfg.ResponseModesSupported,
|
|
||||||
GrantTypesSupported: cfg.GrantTypesSupported,
|
|
||||||
ACRValuesSupported: cfg.ACRValuesSupported,
|
|
||||||
SubjectTypesSupported: cfg.SubjectTypesSupported,
|
|
||||||
IDTokenSigningAlgValues: cfg.IDTokenSigningAlgValues,
|
|
||||||
IDTokenEncryptionAlgValues: cfg.IDTokenEncryptionAlgValues,
|
|
||||||
IDTokenEncryptionEncValues: cfg.IDTokenEncryptionEncValues,
|
|
||||||
UserInfoSigningAlgValues: cfg.UserInfoSigningAlgValues,
|
|
||||||
UserInfoEncryptionAlgValues: cfg.UserInfoEncryptionAlgValues,
|
|
||||||
UserInfoEncryptionEncValues: cfg.UserInfoEncryptionEncValues,
|
|
||||||
ReqObjSigningAlgValues: cfg.ReqObjSigningAlgValues,
|
|
||||||
ReqObjEncryptionAlgValues: cfg.ReqObjEncryptionAlgValues,
|
|
||||||
ReqObjEncryptionEncValues: cfg.ReqObjEncryptionEncValues,
|
|
||||||
TokenEndpointAuthMethodsSupported: cfg.TokenEndpointAuthMethodsSupported,
|
|
||||||
TokenEndpointAuthSigningAlgValuesSupported: cfg.TokenEndpointAuthSigningAlgValuesSupported,
|
|
||||||
DisplayValuesSupported: cfg.DisplayValuesSupported,
|
|
||||||
ClaimTypesSupported: cfg.ClaimTypesSupported,
|
|
||||||
ClaimsSupported: cfg.ClaimsSupported,
|
|
||||||
ServiceDocs: uriToString(cfg.ServiceDocs),
|
|
||||||
ClaimsLocalsSupported: cfg.ClaimsLocalsSupported,
|
|
||||||
UILocalsSupported: cfg.UILocalsSupported,
|
|
||||||
ClaimsParameterSupported: cfg.ClaimsParameterSupported,
|
|
||||||
RequestParameterSupported: cfg.RequestParameterSupported,
|
|
||||||
RequestURIParamaterSupported: cfg.RequestURIParamaterSupported,
|
|
||||||
RequireRequestURIRegistration: cfg.RequireRequestURIRegistration,
|
|
||||||
Policy: uriToString(cfg.Policy),
|
|
||||||
TermsOfService: uriToString(cfg.TermsOfService),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e encodableProviderConfig) toStruct() (ProviderConfig, error) {
|
|
||||||
p := stickyErrParser{}
|
|
||||||
conf := ProviderConfig{
|
|
||||||
Issuer: p.parseURI(e.Issuer, "issuer"),
|
|
||||||
AuthEndpoint: p.parseURI(e.AuthEndpoint, "authorization_endpoint"),
|
|
||||||
TokenEndpoint: p.parseURI(e.TokenEndpoint, "token_endpoint"),
|
|
||||||
UserInfoEndpoint: p.parseURI(e.UserInfoEndpoint, "userinfo_endpoint"),
|
|
||||||
KeysEndpoint: p.parseURI(e.KeysEndpoint, "jwks_uri"),
|
|
||||||
RegistrationEndpoint: p.parseURI(e.RegistrationEndpoint, "registration_endpoint"),
|
|
||||||
EndSessionEndpoint: p.parseURI(e.EndSessionEndpoint, "end_session_endpoint"),
|
|
||||||
CheckSessionIFrame: p.parseURI(e.CheckSessionIFrame, "check_session_iframe"),
|
|
||||||
ScopesSupported: e.ScopesSupported,
|
|
||||||
ResponseTypesSupported: e.ResponseTypesSupported,
|
|
||||||
ResponseModesSupported: e.ResponseModesSupported,
|
|
||||||
GrantTypesSupported: e.GrantTypesSupported,
|
|
||||||
ACRValuesSupported: e.ACRValuesSupported,
|
|
||||||
SubjectTypesSupported: e.SubjectTypesSupported,
|
|
||||||
IDTokenSigningAlgValues: e.IDTokenSigningAlgValues,
|
|
||||||
IDTokenEncryptionAlgValues: e.IDTokenEncryptionAlgValues,
|
|
||||||
IDTokenEncryptionEncValues: e.IDTokenEncryptionEncValues,
|
|
||||||
UserInfoSigningAlgValues: e.UserInfoSigningAlgValues,
|
|
||||||
UserInfoEncryptionAlgValues: e.UserInfoEncryptionAlgValues,
|
|
||||||
UserInfoEncryptionEncValues: e.UserInfoEncryptionEncValues,
|
|
||||||
ReqObjSigningAlgValues: e.ReqObjSigningAlgValues,
|
|
||||||
ReqObjEncryptionAlgValues: e.ReqObjEncryptionAlgValues,
|
|
||||||
ReqObjEncryptionEncValues: e.ReqObjEncryptionEncValues,
|
|
||||||
TokenEndpointAuthMethodsSupported: e.TokenEndpointAuthMethodsSupported,
|
|
||||||
TokenEndpointAuthSigningAlgValuesSupported: e.TokenEndpointAuthSigningAlgValuesSupported,
|
|
||||||
DisplayValuesSupported: e.DisplayValuesSupported,
|
|
||||||
ClaimTypesSupported: e.ClaimTypesSupported,
|
|
||||||
ClaimsSupported: e.ClaimsSupported,
|
|
||||||
ServiceDocs: p.parseURI(e.ServiceDocs, "service_documentation"),
|
|
||||||
ClaimsLocalsSupported: e.ClaimsLocalsSupported,
|
|
||||||
UILocalsSupported: e.UILocalsSupported,
|
|
||||||
ClaimsParameterSupported: e.ClaimsParameterSupported,
|
|
||||||
RequestParameterSupported: e.RequestParameterSupported,
|
|
||||||
RequestURIParamaterSupported: e.RequestURIParamaterSupported,
|
|
||||||
RequireRequestURIRegistration: e.RequireRequestURIRegistration,
|
|
||||||
Policy: p.parseURI(e.Policy, "op_policy-uri"),
|
|
||||||
TermsOfService: p.parseURI(e.TermsOfService, "op_tos_uri"),
|
|
||||||
}
|
|
||||||
if p.firstErr != nil {
|
|
||||||
return ProviderConfig{}, p.firstErr
|
|
||||||
}
|
|
||||||
return conf, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Empty returns if a ProviderConfig holds no information.
|
|
||||||
//
|
|
||||||
// This case generally indicates a ProviderConfigGetter has experienced an error
|
|
||||||
// and has nothing to report.
|
|
||||||
func (p ProviderConfig) Empty() bool {
|
|
||||||
return p.Issuer == nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func contains(sli []string, ele string) bool {
|
|
||||||
for _, s := range sli {
|
|
||||||
if s == ele {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Valid determines if a ProviderConfig conforms with the OIDC specification.
|
|
||||||
// If Valid returns successfully it guarantees required field are non-nil and
|
|
||||||
// URLs are well formed.
|
|
||||||
//
|
|
||||||
// Valid is called by UnmarshalJSON.
|
|
||||||
//
|
|
||||||
// NOTE(ericchiang): For development purposes Valid does not mandate 'https' for
|
|
||||||
// URLs fields where the OIDC spec requires it. This may change in future releases
|
|
||||||
// of this package. See: https://github.com/coreos/go-oidc/issues/34
|
|
||||||
func (p ProviderConfig) Valid() error {
|
|
||||||
grantTypes := p.GrantTypesSupported
|
|
||||||
if len(grantTypes) == 0 {
|
|
||||||
grantTypes = DefaultGrantTypesSupported
|
|
||||||
}
|
|
||||||
implicitOnly := true
|
|
||||||
for _, grantType := range grantTypes {
|
|
||||||
if grantType != oauth2.GrantTypeImplicit {
|
|
||||||
implicitOnly = false
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(p.SubjectTypesSupported) == 0 {
|
|
||||||
return errors.New("missing required field subject_types_supported")
|
|
||||||
}
|
|
||||||
if len(p.IDTokenSigningAlgValues) == 0 {
|
|
||||||
return errors.New("missing required field id_token_signing_alg_values_supported")
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(p.ScopesSupported) != 0 && !contains(p.ScopesSupported, "openid") {
|
|
||||||
return errors.New("scoped_supported must be unspecified or include 'openid'")
|
|
||||||
}
|
|
||||||
|
|
||||||
if !contains(p.IDTokenSigningAlgValues, "RS256") {
|
|
||||||
return errors.New("id_token_signing_alg_values_supported must include 'RS256'")
|
|
||||||
}
|
|
||||||
if contains(p.TokenEndpointAuthMethodsSupported, "none") {
|
|
||||||
return errors.New("token_endpoint_auth_signing_alg_values_supported cannot include 'none'")
|
|
||||||
}
|
|
||||||
|
|
||||||
uris := []struct {
|
|
||||||
val *url.URL
|
|
||||||
name string
|
|
||||||
required bool
|
|
||||||
}{
|
|
||||||
{p.Issuer, "issuer", true},
|
|
||||||
{p.AuthEndpoint, "authorization_endpoint", true},
|
|
||||||
{p.TokenEndpoint, "token_endpoint", !implicitOnly},
|
|
||||||
{p.UserInfoEndpoint, "userinfo_endpoint", false},
|
|
||||||
{p.KeysEndpoint, "jwks_uri", true},
|
|
||||||
{p.RegistrationEndpoint, "registration_endpoint", false},
|
|
||||||
{p.EndSessionEndpoint, "end_session_endpoint", false},
|
|
||||||
{p.CheckSessionIFrame, "check_session_iframe", false},
|
|
||||||
{p.ServiceDocs, "service_documentation", false},
|
|
||||||
{p.Policy, "op_policy_uri", false},
|
|
||||||
{p.TermsOfService, "op_tos_uri", false},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, uri := range uris {
|
|
||||||
if uri.val == nil {
|
|
||||||
if !uri.required {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
return fmt.Errorf("empty value for required uri field %s", uri.name)
|
|
||||||
}
|
|
||||||
if uri.val.Host == "" {
|
|
||||||
return fmt.Errorf("no host for uri field %s", uri.name)
|
|
||||||
}
|
|
||||||
if uri.val.Scheme != "http" && uri.val.Scheme != "https" {
|
|
||||||
return fmt.Errorf("uri field %s schemeis not http or https", uri.name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Supports determines if provider supports a client given their respective metadata.
|
|
||||||
func (p ProviderConfig) Supports(c ClientMetadata) error {
|
|
||||||
if err := p.Valid(); err != nil {
|
|
||||||
return fmt.Errorf("invalid provider config: %v", err)
|
|
||||||
}
|
|
||||||
if err := c.Valid(); err != nil {
|
|
||||||
return fmt.Errorf("invalid client config: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fill default values for omitted fields
|
|
||||||
c = c.Defaults()
|
|
||||||
p = p.Defaults()
|
|
||||||
|
|
||||||
// Do the supported values list the requested one?
|
|
||||||
supports := []struct {
|
|
||||||
supported []string
|
|
||||||
requested string
|
|
||||||
name string
|
|
||||||
}{
|
|
||||||
{p.IDTokenSigningAlgValues, c.IDTokenResponseOptions.SigningAlg, "id_token_signed_response_alg"},
|
|
||||||
{p.IDTokenEncryptionAlgValues, c.IDTokenResponseOptions.EncryptionAlg, "id_token_encryption_response_alg"},
|
|
||||||
{p.IDTokenEncryptionEncValues, c.IDTokenResponseOptions.EncryptionEnc, "id_token_encryption_response_enc"},
|
|
||||||
{p.UserInfoSigningAlgValues, c.UserInfoResponseOptions.SigningAlg, "userinfo_signed_response_alg"},
|
|
||||||
{p.UserInfoEncryptionAlgValues, c.UserInfoResponseOptions.EncryptionAlg, "userinfo_encryption_response_alg"},
|
|
||||||
{p.UserInfoEncryptionEncValues, c.UserInfoResponseOptions.EncryptionEnc, "userinfo_encryption_response_enc"},
|
|
||||||
{p.ReqObjSigningAlgValues, c.RequestObjectOptions.SigningAlg, "request_object_signing_alg"},
|
|
||||||
{p.ReqObjEncryptionAlgValues, c.RequestObjectOptions.EncryptionAlg, "request_object_encryption_alg"},
|
|
||||||
{p.ReqObjEncryptionEncValues, c.RequestObjectOptions.EncryptionEnc, "request_object_encryption_enc"},
|
|
||||||
}
|
|
||||||
for _, field := range supports {
|
|
||||||
if field.requested == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if !contains(field.supported, field.requested) {
|
|
||||||
return fmt.Errorf("provider does not support requested value for field %s", field.name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stringsEqual := func(s1, s2 string) bool { return s1 == s2 }
|
|
||||||
|
|
||||||
// For lists, are the list of requested values a subset of the supported ones?
|
|
||||||
supportsAll := []struct {
|
|
||||||
supported []string
|
|
||||||
requested []string
|
|
||||||
name string
|
|
||||||
// OAuth2.0 response_type can be space separated lists where order doesn't matter.
|
|
||||||
// For example "id_token token" is the same as "token id_token"
|
|
||||||
// Support a custom compare method.
|
|
||||||
comp func(s1, s2 string) bool
|
|
||||||
}{
|
|
||||||
{p.GrantTypesSupported, c.GrantTypes, "grant_types", stringsEqual},
|
|
||||||
{p.ResponseTypesSupported, c.ResponseTypes, "response_type", oauth2.ResponseTypesEqual},
|
|
||||||
}
|
|
||||||
for _, field := range supportsAll {
|
|
||||||
requestLoop:
|
|
||||||
for _, req := range field.requested {
|
|
||||||
for _, sup := range field.supported {
|
|
||||||
if field.comp(req, sup) {
|
|
||||||
continue requestLoop
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fmt.Errorf("provider does not support requested value for field %s", field.name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(ericchiang): Are there more checks we feel comfortable with begin strict about?
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p ProviderConfig) SupportsGrantType(grantType string) bool {
|
|
||||||
var supported []string
|
|
||||||
if len(p.GrantTypesSupported) == 0 {
|
|
||||||
supported = DefaultGrantTypesSupported
|
|
||||||
} else {
|
|
||||||
supported = p.GrantTypesSupported
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, t := range supported {
|
|
||||||
if t == grantType {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
type ProviderConfigGetter interface {
|
|
||||||
Get() (ProviderConfig, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type ProviderConfigSetter interface {
|
|
||||||
Set(ProviderConfig) error
|
|
||||||
}
|
|
||||||
|
|
||||||
type ProviderConfigSyncer struct {
|
|
||||||
from ProviderConfigGetter
|
|
||||||
to ProviderConfigSetter
|
|
||||||
clock clockwork.Clock
|
|
||||||
|
|
||||||
initialSyncDone bool
|
|
||||||
initialSyncWait sync.WaitGroup
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewProviderConfigSyncer(from ProviderConfigGetter, to ProviderConfigSetter) *ProviderConfigSyncer {
|
|
||||||
return &ProviderConfigSyncer{
|
|
||||||
from: from,
|
|
||||||
to: to,
|
|
||||||
clock: clockwork.NewRealClock(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *ProviderConfigSyncer) Run() chan struct{} {
|
|
||||||
stop := make(chan struct{})
|
|
||||||
|
|
||||||
var next pcsStepper
|
|
||||||
next = &pcsStepNext{aft: time.Duration(0)}
|
|
||||||
|
|
||||||
s.initialSyncWait.Add(1)
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case <-s.clock.After(next.after()):
|
|
||||||
next = next.step(s.sync)
|
|
||||||
case <-stop:
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
return stop
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *ProviderConfigSyncer) WaitUntilInitialSync() {
|
|
||||||
s.initialSyncWait.Wait()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *ProviderConfigSyncer) sync() (time.Duration, error) {
|
|
||||||
cfg, err := s.from.Get()
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = s.to.Set(cfg); err != nil {
|
|
||||||
return 0, fmt.Errorf("error setting provider config: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !s.initialSyncDone {
|
|
||||||
s.initialSyncWait.Done()
|
|
||||||
s.initialSyncDone = true
|
|
||||||
}
|
|
||||||
|
|
||||||
return nextSyncAfter(cfg.ExpiresAt, s.clock), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type pcsStepFunc func() (time.Duration, error)
|
|
||||||
|
|
||||||
type pcsStepper interface {
|
|
||||||
after() time.Duration
|
|
||||||
step(pcsStepFunc) pcsStepper
|
|
||||||
}
|
|
||||||
|
|
||||||
type pcsStepNext struct {
|
|
||||||
aft time.Duration
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *pcsStepNext) after() time.Duration {
|
|
||||||
return n.aft
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *pcsStepNext) step(fn pcsStepFunc) (next pcsStepper) {
|
|
||||||
ttl, err := fn()
|
|
||||||
if err == nil {
|
|
||||||
next = &pcsStepNext{aft: ttl}
|
|
||||||
} else {
|
|
||||||
next = &pcsStepRetry{aft: time.Second}
|
|
||||||
log.Printf("go-oidc: provider config sync falied, retyring in %v: %v", next.after(), err)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
type pcsStepRetry struct {
|
|
||||||
aft time.Duration
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *pcsStepRetry) after() time.Duration {
|
|
||||||
return r.aft
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *pcsStepRetry) step(fn pcsStepFunc) (next pcsStepper) {
|
|
||||||
ttl, err := fn()
|
|
||||||
if err == nil {
|
|
||||||
next = &pcsStepNext{aft: ttl}
|
|
||||||
} else {
|
|
||||||
next = &pcsStepRetry{aft: timeutil.ExpBackoff(r.aft, time.Minute)}
|
|
||||||
log.Printf("go-oidc: provider config sync falied, retyring in %v: %v", next.after(), err)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func nextSyncAfter(exp time.Time, clock clockwork.Clock) time.Duration {
|
|
||||||
if exp.IsZero() {
|
|
||||||
return MaximumProviderConfigSyncInterval
|
|
||||||
}
|
|
||||||
|
|
||||||
t := exp.Sub(clock.Now()) / 2
|
|
||||||
if t > MaximumProviderConfigSyncInterval {
|
|
||||||
t = MaximumProviderConfigSyncInterval
|
|
||||||
} else if t < minimumProviderConfigSyncInterval {
|
|
||||||
t = minimumProviderConfigSyncInterval
|
|
||||||
}
|
|
||||||
|
|
||||||
return t
|
|
||||||
}
|
|
||||||
|
|
||||||
type httpProviderConfigGetter struct {
|
|
||||||
hc phttp.Client
|
|
||||||
issuerURL string
|
|
||||||
clock clockwork.Clock
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewHTTPProviderConfigGetter(hc phttp.Client, issuerURL string) *httpProviderConfigGetter {
|
|
||||||
return &httpProviderConfigGetter{
|
|
||||||
hc: hc,
|
|
||||||
issuerURL: issuerURL,
|
|
||||||
clock: clockwork.NewRealClock(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *httpProviderConfigGetter) Get() (cfg ProviderConfig, err error) {
|
|
||||||
// If the Issuer value contains a path component, any terminating / MUST be removed before
|
|
||||||
// appending /.well-known/openid-configuration.
|
|
||||||
// https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationRequest
|
|
||||||
discoveryURL := strings.TrimSuffix(r.issuerURL, "/") + discoveryConfigPath
|
|
||||||
req, err := http.NewRequest("GET", discoveryURL, nil)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := r.hc.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
if err = json.NewDecoder(resp.Body).Decode(&cfg); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var ttl time.Duration
|
|
||||||
var ok bool
|
|
||||||
ttl, ok, err = phttp.Cacheable(resp.Header)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
} else if ok {
|
|
||||||
cfg.ExpiresAt = r.clock.Now().UTC().Add(ttl)
|
|
||||||
}
|
|
||||||
|
|
||||||
// The issuer value returned MUST be identical to the Issuer URL that was directly used to retrieve the configuration information.
|
|
||||||
// http://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationValidation
|
|
||||||
if !urlEqual(cfg.Issuer.String(), r.issuerURL) {
|
|
||||||
err = fmt.Errorf(`"issuer" in config (%v) does not match provided issuer URL (%v)`, cfg.Issuer, r.issuerURL)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func FetchProviderConfig(hc phttp.Client, issuerURL string) (ProviderConfig, error) {
|
|
||||||
if hc == nil {
|
|
||||||
hc = http.DefaultClient
|
|
||||||
}
|
|
||||||
|
|
||||||
g := NewHTTPProviderConfigGetter(hc, issuerURL)
|
|
||||||
return g.Get()
|
|
||||||
}
|
|
||||||
|
|
||||||
func WaitForProviderConfig(hc phttp.Client, issuerURL string) (pcfg ProviderConfig) {
|
|
||||||
return waitForProviderConfig(hc, issuerURL, clockwork.NewRealClock())
|
|
||||||
}
|
|
||||||
|
|
||||||
func waitForProviderConfig(hc phttp.Client, issuerURL string, clock clockwork.Clock) (pcfg ProviderConfig) {
|
|
||||||
var sleep time.Duration
|
|
||||||
var err error
|
|
||||||
for {
|
|
||||||
pcfg, err = FetchProviderConfig(hc, issuerURL)
|
|
||||||
if err == nil {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
sleep = timeutil.ExpBackoff(sleep, time.Minute)
|
|
||||||
fmt.Printf("Failed fetching provider config, trying again in %v: %v\n", sleep, err)
|
|
||||||
time.Sleep(sleep)
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
88
vendor/github.com/coreos/go-oidc/oidc/transport.go
generated
vendored
88
vendor/github.com/coreos/go-oidc/oidc/transport.go
generated
vendored
|
@ -1,88 +0,0 @@
|
||||||
package oidc
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
phttp "github.com/coreos/go-oidc/http"
|
|
||||||
"github.com/coreos/go-oidc/jose"
|
|
||||||
)
|
|
||||||
|
|
||||||
type TokenRefresher interface {
|
|
||||||
// Verify checks if the provided token is currently valid or not.
|
|
||||||
Verify(jose.JWT) error
|
|
||||||
|
|
||||||
// Refresh attempts to authenticate and retrieve a new token.
|
|
||||||
Refresh() (jose.JWT, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type ClientCredsTokenRefresher struct {
|
|
||||||
Issuer string
|
|
||||||
OIDCClient *Client
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *ClientCredsTokenRefresher) Verify(jwt jose.JWT) (err error) {
|
|
||||||
_, err = VerifyClientClaims(jwt, c.Issuer)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *ClientCredsTokenRefresher) Refresh() (jwt jose.JWT, err error) {
|
|
||||||
if err = c.OIDCClient.Healthy(); err != nil {
|
|
||||||
err = fmt.Errorf("unable to authenticate, unhealthy OIDC client: %v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
jwt, err = c.OIDCClient.ClientCredsToken([]string{"openid"})
|
|
||||||
if err != nil {
|
|
||||||
err = fmt.Errorf("unable to verify auth code with issuer: %v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
type AuthenticatedTransport struct {
|
|
||||||
TokenRefresher
|
|
||||||
http.RoundTripper
|
|
||||||
|
|
||||||
mu sync.Mutex
|
|
||||||
jwt jose.JWT
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *AuthenticatedTransport) verifiedJWT() (jose.JWT, error) {
|
|
||||||
t.mu.Lock()
|
|
||||||
defer t.mu.Unlock()
|
|
||||||
|
|
||||||
if t.TokenRefresher.Verify(t.jwt) == nil {
|
|
||||||
return t.jwt, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
jwt, err := t.TokenRefresher.Refresh()
|
|
||||||
if err != nil {
|
|
||||||
return jose.JWT{}, fmt.Errorf("unable to acquire valid JWT: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
t.jwt = jwt
|
|
||||||
return t.jwt, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetJWT sets the JWT held by the Transport.
|
|
||||||
// This is useful for cases in which you want to set an initial JWT.
|
|
||||||
func (t *AuthenticatedTransport) SetJWT(jwt jose.JWT) {
|
|
||||||
t.mu.Lock()
|
|
||||||
defer t.mu.Unlock()
|
|
||||||
|
|
||||||
t.jwt = jwt
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *AuthenticatedTransport) RoundTrip(r *http.Request) (*http.Response, error) {
|
|
||||||
jwt, err := t.verifiedJWT()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
req := phttp.CopyRequest(r)
|
|
||||||
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", jwt.Encode()))
|
|
||||||
return t.RoundTripper.RoundTrip(req)
|
|
||||||
}
|
|
109
vendor/github.com/coreos/go-oidc/oidc/util.go
generated
vendored
109
vendor/github.com/coreos/go-oidc/oidc/util.go
generated
vendored
|
@ -1,109 +0,0 @@
|
||||||
package oidc
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/rand"
|
|
||||||
"encoding/base64"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"net"
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/coreos/go-oidc/jose"
|
|
||||||
)
|
|
||||||
|
|
||||||
// RequestTokenExtractor funcs extract a raw encoded token from a request.
|
|
||||||
type RequestTokenExtractor func(r *http.Request) (string, error)
|
|
||||||
|
|
||||||
// ExtractBearerToken is a RequestTokenExtractor which extracts a bearer token from a request's
|
|
||||||
// Authorization header.
|
|
||||||
func ExtractBearerToken(r *http.Request) (string, error) {
|
|
||||||
ah := r.Header.Get("Authorization")
|
|
||||||
if ah == "" {
|
|
||||||
return "", errors.New("missing Authorization header")
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(ah) <= 6 || strings.ToUpper(ah[0:6]) != "BEARER" {
|
|
||||||
return "", errors.New("should be a bearer token")
|
|
||||||
}
|
|
||||||
|
|
||||||
val := ah[7:]
|
|
||||||
if len(val) == 0 {
|
|
||||||
return "", errors.New("bearer token is empty")
|
|
||||||
}
|
|
||||||
|
|
||||||
return val, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// CookieTokenExtractor returns a RequestTokenExtractor which extracts a token from the named cookie in a request.
|
|
||||||
func CookieTokenExtractor(cookieName string) RequestTokenExtractor {
|
|
||||||
return func(r *http.Request) (string, error) {
|
|
||||||
ck, err := r.Cookie(cookieName)
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("token cookie not found in request: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if ck.Value == "" {
|
|
||||||
return "", errors.New("token cookie found but is empty")
|
|
||||||
}
|
|
||||||
|
|
||||||
return ck.Value, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewClaims(iss, sub string, aud interface{}, iat, exp time.Time) jose.Claims {
|
|
||||||
return jose.Claims{
|
|
||||||
// required
|
|
||||||
"iss": iss,
|
|
||||||
"sub": sub,
|
|
||||||
"aud": aud,
|
|
||||||
"iat": iat.Unix(),
|
|
||||||
"exp": exp.Unix(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func GenClientID(hostport string) (string, error) {
|
|
||||||
b, err := randBytes(32)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
var host string
|
|
||||||
if strings.Contains(hostport, ":") {
|
|
||||||
host, _, err = net.SplitHostPort(hostport)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
host = hostport
|
|
||||||
}
|
|
||||||
|
|
||||||
return fmt.Sprintf("%s@%s", base64.URLEncoding.EncodeToString(b), host), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func randBytes(n int) ([]byte, error) {
|
|
||||||
b := make([]byte, n)
|
|
||||||
got, err := rand.Read(b)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else if n != got {
|
|
||||||
return nil, errors.New("unable to generate enough random data")
|
|
||||||
}
|
|
||||||
return b, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// urlEqual checks two urls for equality using only the host and path portions.
|
|
||||||
func urlEqual(url1, url2 string) bool {
|
|
||||||
u1, err := url.Parse(url1)
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
u2, err := url.Parse(url2)
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return strings.ToLower(u1.Host+u1.Path) == strings.ToLower(u2.Host+u2.Path)
|
|
||||||
}
|
|
190
vendor/github.com/coreos/go-oidc/oidc/verification.go
generated
vendored
190
vendor/github.com/coreos/go-oidc/oidc/verification.go
generated
vendored
|
@ -1,190 +0,0 @@
|
||||||
package oidc
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/jonboulle/clockwork"
|
|
||||||
|
|
||||||
"github.com/coreos/go-oidc/jose"
|
|
||||||
"github.com/coreos/go-oidc/key"
|
|
||||||
)
|
|
||||||
|
|
||||||
func VerifySignature(jwt jose.JWT, keys []key.PublicKey) (bool, error) {
|
|
||||||
jwtBytes := []byte(jwt.Data())
|
|
||||||
for _, k := range keys {
|
|
||||||
v, err := k.Verifier()
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
if v.Verify(jwt.Signature, jwtBytes) == nil {
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// containsString returns true if the given string(needle) is found
|
|
||||||
// in the string array(haystack).
|
|
||||||
func containsString(needle string, haystack []string) bool {
|
|
||||||
for _, v := range haystack {
|
|
||||||
if v == needle {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify claims in accordance with OIDC spec
|
|
||||||
// http://openid.net/specs/openid-connect-basic-1_0.html#IDTokenValidation
|
|
||||||
func VerifyClaims(jwt jose.JWT, issuer, clientID string) error {
|
|
||||||
now := time.Now().UTC()
|
|
||||||
|
|
||||||
claims, err := jwt.Claims()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
ident, err := IdentityFromClaims(claims)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if ident.ExpiresAt.Before(now) {
|
|
||||||
return errors.New("token is expired")
|
|
||||||
}
|
|
||||||
|
|
||||||
// iss REQUIRED. Issuer Identifier for the Issuer of the response.
|
|
||||||
// The iss value is a case sensitive URL using the https scheme that contains scheme,
|
|
||||||
// host, and optionally, port number and path components and no query or fragment components.
|
|
||||||
if iss, exists := claims["iss"].(string); exists {
|
|
||||||
if !urlEqual(iss, issuer) {
|
|
||||||
return fmt.Errorf("invalid claim value: 'iss'. expected=%s, found=%s.", issuer, iss)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return errors.New("missing claim: 'iss'")
|
|
||||||
}
|
|
||||||
|
|
||||||
// iat REQUIRED. Time at which the JWT was issued.
|
|
||||||
// Its value is a JSON number representing the number of seconds from 1970-01-01T0:0:0Z
|
|
||||||
// as measured in UTC until the date/time.
|
|
||||||
if _, exists := claims["iat"].(float64); !exists {
|
|
||||||
return errors.New("missing claim: 'iat'")
|
|
||||||
}
|
|
||||||
|
|
||||||
// aud REQUIRED. Audience(s) that this ID Token is intended for.
|
|
||||||
// It MUST contain the OAuth 2.0 client_id of the Relying Party as an audience value.
|
|
||||||
// It MAY also contain identifiers for other audiences. In the general case, the aud
|
|
||||||
// value is an array of case sensitive strings. In the common special case when there
|
|
||||||
// is one audience, the aud value MAY be a single case sensitive string.
|
|
||||||
if aud, ok, err := claims.StringClaim("aud"); err == nil && ok {
|
|
||||||
if aud != clientID {
|
|
||||||
return fmt.Errorf("invalid claims, 'aud' claim and 'client_id' do not match, aud=%s, client_id=%s", aud, clientID)
|
|
||||||
}
|
|
||||||
} else if aud, ok, err := claims.StringsClaim("aud"); err == nil && ok {
|
|
||||||
if !containsString(clientID, aud) {
|
|
||||||
return fmt.Errorf("invalid claims, cannot find 'client_id' in 'aud' claim, aud=%v, client_id=%s", aud, clientID)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return errors.New("invalid claim value: 'aud' is required, and should be either string or string array")
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// VerifyClientClaims verifies all the required claims are valid for a "client credentials" JWT.
|
|
||||||
// Returns the client ID if valid, or an error if invalid.
|
|
||||||
func VerifyClientClaims(jwt jose.JWT, issuer string) (string, error) {
|
|
||||||
claims, err := jwt.Claims()
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("failed to parse JWT claims: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
iss, ok, err := claims.StringClaim("iss")
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("failed to parse 'iss' claim: %v", err)
|
|
||||||
} else if !ok {
|
|
||||||
return "", errors.New("missing required 'iss' claim")
|
|
||||||
} else if !urlEqual(iss, issuer) {
|
|
||||||
return "", fmt.Errorf("'iss' claim does not match expected issuer, iss=%s", iss)
|
|
||||||
}
|
|
||||||
|
|
||||||
sub, ok, err := claims.StringClaim("sub")
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("failed to parse 'sub' claim: %v", err)
|
|
||||||
} else if !ok {
|
|
||||||
return "", errors.New("missing required 'sub' claim")
|
|
||||||
}
|
|
||||||
|
|
||||||
if aud, ok, err := claims.StringClaim("aud"); err == nil && ok {
|
|
||||||
if aud != sub {
|
|
||||||
return "", fmt.Errorf("invalid claims, 'aud' claim and 'sub' claim do not match, aud=%s, sub=%s", aud, sub)
|
|
||||||
}
|
|
||||||
} else if aud, ok, err := claims.StringsClaim("aud"); err == nil && ok {
|
|
||||||
if !containsString(sub, aud) {
|
|
||||||
return "", fmt.Errorf("invalid claims, cannot find 'sud' in 'aud' claim, aud=%v, sub=%s", aud, sub)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return "", errors.New("invalid claim value: 'aud' is required, and should be either string or string array")
|
|
||||||
}
|
|
||||||
|
|
||||||
now := time.Now().UTC()
|
|
||||||
exp, ok, err := claims.TimeClaim("exp")
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("failed to parse 'exp' claim: %v", err)
|
|
||||||
} else if !ok {
|
|
||||||
return "", errors.New("missing required 'exp' claim")
|
|
||||||
} else if exp.Before(now) {
|
|
||||||
return "", fmt.Errorf("token already expired at: %v", exp)
|
|
||||||
}
|
|
||||||
|
|
||||||
return sub, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type JWTVerifier struct {
|
|
||||||
issuer string
|
|
||||||
clientID string
|
|
||||||
syncFunc func() error
|
|
||||||
keysFunc func() []key.PublicKey
|
|
||||||
clock clockwork.Clock
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewJWTVerifier(issuer, clientID string, syncFunc func() error, keysFunc func() []key.PublicKey) JWTVerifier {
|
|
||||||
return JWTVerifier{
|
|
||||||
issuer: issuer,
|
|
||||||
clientID: clientID,
|
|
||||||
syncFunc: syncFunc,
|
|
||||||
keysFunc: keysFunc,
|
|
||||||
clock: clockwork.NewRealClock(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *JWTVerifier) Verify(jwt jose.JWT) error {
|
|
||||||
// Verify claims before verifying the signature. This is an optimization to throw out
|
|
||||||
// tokens we know are invalid without undergoing an expensive signature check and
|
|
||||||
// possibly a re-sync event.
|
|
||||||
if err := VerifyClaims(jwt, v.issuer, v.clientID); err != nil {
|
|
||||||
return fmt.Errorf("oidc: JWT claims invalid: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
ok, err := VerifySignature(jwt, v.keysFunc())
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("oidc: JWT signature verification failed: %v", err)
|
|
||||||
} else if ok {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = v.syncFunc(); err != nil {
|
|
||||||
return fmt.Errorf("oidc: failed syncing KeySet: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
ok, err = VerifySignature(jwt, v.keysFunc())
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("oidc: JWT signature verification failed: %v", err)
|
|
||||||
} else if !ok {
|
|
||||||
return errors.New("oidc: unable to verify JWT signature: no matching keys")
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
202
vendor/github.com/coreos/pkg/LICENSE
generated
vendored
202
vendor/github.com/coreos/pkg/LICENSE
generated
vendored
|
@ -1,202 +0,0 @@
|
||||||
Apache License
|
|
||||||
Version 2.0, January 2004
|
|
||||||
http://www.apache.org/licenses/
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
||||||
|
|
||||||
1. Definitions.
|
|
||||||
|
|
||||||
"License" shall mean the terms and conditions for use, reproduction,
|
|
||||||
and distribution as defined by Sections 1 through 9 of this document.
|
|
||||||
|
|
||||||
"Licensor" shall mean the copyright owner or entity authorized by
|
|
||||||
the copyright owner that is granting the License.
|
|
||||||
|
|
||||||
"Legal Entity" shall mean the union of the acting entity and all
|
|
||||||
other entities that control, are controlled by, or are under common
|
|
||||||
control with that entity. For the purposes of this definition,
|
|
||||||
"control" means (i) the power, direct or indirect, to cause the
|
|
||||||
direction or management of such entity, whether by contract or
|
|
||||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
||||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
||||||
|
|
||||||
"You" (or "Your") shall mean an individual or Legal Entity
|
|
||||||
exercising permissions granted by this License.
|
|
||||||
|
|
||||||
"Source" form shall mean the preferred form for making modifications,
|
|
||||||
including but not limited to software source code, documentation
|
|
||||||
source, and configuration files.
|
|
||||||
|
|
||||||
"Object" form shall mean any form resulting from mechanical
|
|
||||||
transformation or translation of a Source form, including but
|
|
||||||
not limited to compiled object code, generated documentation,
|
|
||||||
and conversions to other media types.
|
|
||||||
|
|
||||||
"Work" shall mean the work of authorship, whether in Source or
|
|
||||||
Object form, made available under the License, as indicated by a
|
|
||||||
copyright notice that is included in or attached to the work
|
|
||||||
(an example is provided in the Appendix below).
|
|
||||||
|
|
||||||
"Derivative Works" shall mean any work, whether in Source or Object
|
|
||||||
form, that is based on (or derived from) the Work and for which the
|
|
||||||
editorial revisions, annotations, elaborations, or other modifications
|
|
||||||
represent, as a whole, an original work of authorship. For the purposes
|
|
||||||
of this License, Derivative Works shall not include works that remain
|
|
||||||
separable from, or merely link (or bind by name) to the interfaces of,
|
|
||||||
the Work and Derivative Works thereof.
|
|
||||||
|
|
||||||
"Contribution" shall mean any work of authorship, including
|
|
||||||
the original version of the Work and any modifications or additions
|
|
||||||
to that Work or Derivative Works thereof, that is intentionally
|
|
||||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
||||||
or by an individual or Legal Entity authorized to submit on behalf of
|
|
||||||
the copyright owner. For the purposes of this definition, "submitted"
|
|
||||||
means any form of electronic, verbal, or written communication sent
|
|
||||||
to the Licensor or its representatives, including but not limited to
|
|
||||||
communication on electronic mailing lists, source code control systems,
|
|
||||||
and issue tracking systems that are managed by, or on behalf of, the
|
|
||||||
Licensor for the purpose of discussing and improving the Work, but
|
|
||||||
excluding communication that is conspicuously marked or otherwise
|
|
||||||
designated in writing by the copyright owner as "Not a Contribution."
|
|
||||||
|
|
||||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
||||||
on behalf of whom a Contribution has been received by Licensor and
|
|
||||||
subsequently incorporated within the Work.
|
|
||||||
|
|
||||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
copyright license to reproduce, prepare Derivative Works of,
|
|
||||||
publicly display, publicly perform, sublicense, and distribute the
|
|
||||||
Work and such Derivative Works in Source or Object form.
|
|
||||||
|
|
||||||
3. Grant of Patent License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
(except as stated in this section) patent license to make, have made,
|
|
||||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
||||||
where such license applies only to those patent claims licensable
|
|
||||||
by such Contributor that are necessarily infringed by their
|
|
||||||
Contribution(s) alone or by combination of their Contribution(s)
|
|
||||||
with the Work to which such Contribution(s) was submitted. If You
|
|
||||||
institute patent litigation against any entity (including a
|
|
||||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
||||||
or a Contribution incorporated within the Work constitutes direct
|
|
||||||
or contributory patent infringement, then any patent licenses
|
|
||||||
granted to You under this License for that Work shall terminate
|
|
||||||
as of the date such litigation is filed.
|
|
||||||
|
|
||||||
4. Redistribution. You may reproduce and distribute copies of the
|
|
||||||
Work or Derivative Works thereof in any medium, with or without
|
|
||||||
modifications, and in Source or Object form, provided that You
|
|
||||||
meet the following conditions:
|
|
||||||
|
|
||||||
(a) You must give any other recipients of the Work or
|
|
||||||
Derivative Works a copy of this License; and
|
|
||||||
|
|
||||||
(b) You must cause any modified files to carry prominent notices
|
|
||||||
stating that You changed the files; and
|
|
||||||
|
|
||||||
(c) You must retain, in the Source form of any Derivative Works
|
|
||||||
that You distribute, all copyright, patent, trademark, and
|
|
||||||
attribution notices from the Source form of the Work,
|
|
||||||
excluding those notices that do not pertain to any part of
|
|
||||||
the Derivative Works; and
|
|
||||||
|
|
||||||
(d) If the Work includes a "NOTICE" text file as part of its
|
|
||||||
distribution, then any Derivative Works that You distribute must
|
|
||||||
include a readable copy of the attribution notices contained
|
|
||||||
within such NOTICE file, excluding those notices that do not
|
|
||||||
pertain to any part of the Derivative Works, in at least one
|
|
||||||
of the following places: within a NOTICE text file distributed
|
|
||||||
as part of the Derivative Works; within the Source form or
|
|
||||||
documentation, if provided along with the Derivative Works; or,
|
|
||||||
within a display generated by the Derivative Works, if and
|
|
||||||
wherever such third-party notices normally appear. The contents
|
|
||||||
of the NOTICE file are for informational purposes only and
|
|
||||||
do not modify the License. You may add Your own attribution
|
|
||||||
notices within Derivative Works that You distribute, alongside
|
|
||||||
or as an addendum to the NOTICE text from the Work, provided
|
|
||||||
that such additional attribution notices cannot be construed
|
|
||||||
as modifying the License.
|
|
||||||
|
|
||||||
You may add Your own copyright statement to Your modifications and
|
|
||||||
may provide additional or different license terms and conditions
|
|
||||||
for use, reproduction, or distribution of Your modifications, or
|
|
||||||
for any such Derivative Works as a whole, provided Your use,
|
|
||||||
reproduction, and distribution of the Work otherwise complies with
|
|
||||||
the conditions stated in this License.
|
|
||||||
|
|
||||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
||||||
any Contribution intentionally submitted for inclusion in the Work
|
|
||||||
by You to the Licensor shall be under the terms and conditions of
|
|
||||||
this License, without any additional terms or conditions.
|
|
||||||
Notwithstanding the above, nothing herein shall supersede or modify
|
|
||||||
the terms of any separate license agreement you may have executed
|
|
||||||
with Licensor regarding such Contributions.
|
|
||||||
|
|
||||||
6. Trademarks. This License does not grant permission to use the trade
|
|
||||||
names, trademarks, service marks, or product names of the Licensor,
|
|
||||||
except as required for reasonable and customary use in describing the
|
|
||||||
origin of the Work and reproducing the content of the NOTICE file.
|
|
||||||
|
|
||||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
||||||
agreed to in writing, Licensor provides the Work (and each
|
|
||||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
||||||
implied, including, without limitation, any warranties or conditions
|
|
||||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
||||||
appropriateness of using or redistributing the Work and assume any
|
|
||||||
risks associated with Your exercise of permissions under this License.
|
|
||||||
|
|
||||||
8. Limitation of Liability. In no event and under no legal theory,
|
|
||||||
whether in tort (including negligence), contract, or otherwise,
|
|
||||||
unless required by applicable law (such as deliberate and grossly
|
|
||||||
negligent acts) or agreed to in writing, shall any Contributor be
|
|
||||||
liable to You for damages, including any direct, indirect, special,
|
|
||||||
incidental, or consequential damages of any character arising as a
|
|
||||||
result of this License or out of the use or inability to use the
|
|
||||||
Work (including but not limited to damages for loss of goodwill,
|
|
||||||
work stoppage, computer failure or malfunction, or any and all
|
|
||||||
other commercial damages or losses), even if such Contributor
|
|
||||||
has been advised of the possibility of such damages.
|
|
||||||
|
|
||||||
9. Accepting Warranty or Additional Liability. While redistributing
|
|
||||||
the Work or Derivative Works thereof, You may choose to offer,
|
|
||||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
||||||
or other liability obligations and/or rights consistent with this
|
|
||||||
License. However, in accepting such obligations, You may act only
|
|
||||||
on Your own behalf and on Your sole responsibility, not on behalf
|
|
||||||
of any other Contributor, and only if You agree to indemnify,
|
|
||||||
defend, and hold each Contributor harmless for any liability
|
|
||||||
incurred by, or claims asserted against, such Contributor by reason
|
|
||||||
of your accepting any such warranty or additional liability.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
APPENDIX: How to apply the Apache License to your work.
|
|
||||||
|
|
||||||
To apply the Apache License to your work, attach the following
|
|
||||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
|
||||||
replaced with your own identifying information. (Don't include
|
|
||||||
the brackets!) The text should be enclosed in the appropriate
|
|
||||||
comment syntax for the file format. We also recommend that a
|
|
||||||
file or class name and description of purpose be included on the
|
|
||||||
same "printed page" as the copyright notice for easier
|
|
||||||
identification within third-party archives.
|
|
||||||
|
|
||||||
Copyright {yyyy} {name of copyright owner}
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
|
|
5
vendor/github.com/coreos/pkg/NOTICE
generated
vendored
5
vendor/github.com/coreos/pkg/NOTICE
generated
vendored
|
@ -1,5 +0,0 @@
|
||||||
CoreOS Project
|
|
||||||
Copyright 2014 CoreOS, Inc
|
|
||||||
|
|
||||||
This product includes software developed at CoreOS, Inc.
|
|
||||||
(http://www.coreos.com/).
|
|
127
vendor/github.com/coreos/pkg/health/health.go
generated
vendored
127
vendor/github.com/coreos/pkg/health/health.go
generated
vendored
|
@ -1,127 +0,0 @@
|
||||||
package health
|
|
||||||
|
|
||||||
import (
|
|
||||||
"expvar"
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/coreos/pkg/httputil"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Checkables should return nil when the thing they are checking is healthy, and an error otherwise.
|
|
||||||
type Checkable interface {
|
|
||||||
Healthy() error
|
|
||||||
}
|
|
||||||
|
|
||||||
// Checker provides a way to make an endpoint which can be probed for system health.
|
|
||||||
type Checker struct {
|
|
||||||
// Checks are the Checkables to be checked when probing.
|
|
||||||
Checks []Checkable
|
|
||||||
|
|
||||||
// Unhealthyhandler is called when one or more of the checks are unhealthy.
|
|
||||||
// If not provided DefaultUnhealthyHandler is called.
|
|
||||||
UnhealthyHandler UnhealthyHandler
|
|
||||||
|
|
||||||
// HealthyHandler is called when all checks are healthy.
|
|
||||||
// If not provided, DefaultHealthyHandler is called.
|
|
||||||
HealthyHandler http.HandlerFunc
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c Checker) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|
||||||
unhealthyHandler := c.UnhealthyHandler
|
|
||||||
if unhealthyHandler == nil {
|
|
||||||
unhealthyHandler = DefaultUnhealthyHandler
|
|
||||||
}
|
|
||||||
|
|
||||||
successHandler := c.HealthyHandler
|
|
||||||
if successHandler == nil {
|
|
||||||
successHandler = DefaultHealthyHandler
|
|
||||||
}
|
|
||||||
|
|
||||||
if r.Method != "GET" {
|
|
||||||
w.Header().Set("Allow", "GET")
|
|
||||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := Check(c.Checks); err != nil {
|
|
||||||
unhealthyHandler(w, r, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
successHandler(w, r)
|
|
||||||
}
|
|
||||||
|
|
||||||
type UnhealthyHandler func(w http.ResponseWriter, r *http.Request, err error)
|
|
||||||
|
|
||||||
type StatusResponse struct {
|
|
||||||
Status string `json:"status"`
|
|
||||||
Details *StatusResponseDetails `json:"details,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type StatusResponseDetails struct {
|
|
||||||
Code int `json:"code,omitempty"`
|
|
||||||
Message string `json:"message,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func Check(checks []Checkable) (err error) {
|
|
||||||
errs := []error{}
|
|
||||||
for _, c := range checks {
|
|
||||||
if e := c.Healthy(); e != nil {
|
|
||||||
errs = append(errs, e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch len(errs) {
|
|
||||||
case 0:
|
|
||||||
err = nil
|
|
||||||
case 1:
|
|
||||||
err = errs[0]
|
|
||||||
default:
|
|
||||||
err = fmt.Errorf("multiple health check failure: %v", errs)
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func DefaultHealthyHandler(w http.ResponseWriter, r *http.Request) {
|
|
||||||
err := httputil.WriteJSONResponse(w, http.StatusOK, StatusResponse{
|
|
||||||
Status: "ok",
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
// TODO(bobbyrullo): replace with logging from new logging pkg,
|
|
||||||
// once it lands.
|
|
||||||
log.Printf("Failed to write JSON response: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func DefaultUnhealthyHandler(w http.ResponseWriter, r *http.Request, err error) {
|
|
||||||
writeErr := httputil.WriteJSONResponse(w, http.StatusInternalServerError, StatusResponse{
|
|
||||||
Status: "error",
|
|
||||||
Details: &StatusResponseDetails{
|
|
||||||
Code: http.StatusInternalServerError,
|
|
||||||
Message: err.Error(),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if writeErr != nil {
|
|
||||||
// TODO(bobbyrullo): replace with logging from new logging pkg,
|
|
||||||
// once it lands.
|
|
||||||
log.Printf("Failed to write JSON response: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ExpvarHandler is copied from https://golang.org/src/expvar/expvar.go, where it's sadly unexported.
|
|
||||||
func ExpvarHandler(w http.ResponseWriter, r *http.Request) {
|
|
||||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
|
||||||
fmt.Fprintf(w, "{\n")
|
|
||||||
first := true
|
|
||||||
expvar.Do(func(kv expvar.KeyValue) {
|
|
||||||
if !first {
|
|
||||||
fmt.Fprintf(w, ",\n")
|
|
||||||
}
|
|
||||||
first = false
|
|
||||||
fmt.Fprintf(w, "%q: %s", kv.Key, kv.Value)
|
|
||||||
})
|
|
||||||
fmt.Fprintf(w, "\n}\n")
|
|
||||||
}
|
|
21
vendor/github.com/coreos/pkg/httputil/cookie.go
generated
vendored
21
vendor/github.com/coreos/pkg/httputil/cookie.go
generated
vendored
|
@ -1,21 +0,0 @@
|
||||||
package httputil
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// DeleteCookies effectively deletes all named cookies
|
|
||||||
// by wiping all data and setting to expire immediately.
|
|
||||||
func DeleteCookies(w http.ResponseWriter, cookieNames ...string) {
|
|
||||||
for _, n := range cookieNames {
|
|
||||||
c := &http.Cookie{
|
|
||||||
Name: n,
|
|
||||||
Value: "",
|
|
||||||
Path: "/",
|
|
||||||
MaxAge: -1,
|
|
||||||
Expires: time.Time{},
|
|
||||||
}
|
|
||||||
http.SetCookie(w, c)
|
|
||||||
}
|
|
||||||
}
|
|
27
vendor/github.com/coreos/pkg/httputil/json.go
generated
vendored
27
vendor/github.com/coreos/pkg/httputil/json.go
generated
vendored
|
@ -1,27 +0,0 @@
|
||||||
package httputil
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"net/http"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
JSONContentType = "application/json"
|
|
||||||
)
|
|
||||||
|
|
||||||
func WriteJSONResponse(w http.ResponseWriter, code int, resp interface{}) error {
|
|
||||||
enc, err := json.Marshal(resp)
|
|
||||||
if err != nil {
|
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
w.Header().Set("Content-Type", JSONContentType)
|
|
||||||
w.WriteHeader(code)
|
|
||||||
|
|
||||||
_, err = w.Write(enc)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
15
vendor/github.com/coreos/pkg/timeutil/backoff.go
generated
vendored
15
vendor/github.com/coreos/pkg/timeutil/backoff.go
generated
vendored
|
@ -1,15 +0,0 @@
|
||||||
package timeutil
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func ExpBackoff(prev, max time.Duration) time.Duration {
|
|
||||||
if prev == 0 {
|
|
||||||
return time.Second
|
|
||||||
}
|
|
||||||
if prev > max/2 {
|
|
||||||
return max
|
|
||||||
}
|
|
||||||
return 2 * prev
|
|
||||||
}
|
|
2
vendor/github.com/gogo/protobuf/proto/Makefile
generated
vendored
2
vendor/github.com/gogo/protobuf/proto/Makefile
generated
vendored
|
@ -39,5 +39,5 @@ test: install generate-test-pbs
|
||||||
generate-test-pbs:
|
generate-test-pbs:
|
||||||
make install
|
make install
|
||||||
make -C testdata
|
make -C testdata
|
||||||
protoc-min-version --version="3.0.0" --proto_path=.:../../../../ --gogo_out=. proto3_proto/proto3.proto
|
protoc-min-version --version="3.0.0" --proto_path=.:../../../../:../protobuf --gogo_out=Mtestdata/test.proto=github.com/gogo/protobuf/proto/testdata,Mgoogle/protobuf/any.proto=github.com/gogo/protobuf/types:. proto3_proto/proto3.proto
|
||||||
make
|
make
|
||||||
|
|
14
vendor/github.com/gogo/protobuf/proto/clone.go
generated
vendored
14
vendor/github.com/gogo/protobuf/proto/clone.go
generated
vendored
|
@ -84,14 +84,20 @@ func mergeStruct(out, in reflect.Value) {
|
||||||
mergeAny(out.Field(i), in.Field(i), false, sprop.Prop[i])
|
mergeAny(out.Field(i), in.Field(i), false, sprop.Prop[i])
|
||||||
}
|
}
|
||||||
|
|
||||||
if emIn, ok := in.Addr().Interface().(extensionsMap); ok {
|
if emIn, ok := in.Addr().Interface().(extensionsBytes); ok {
|
||||||
emOut := out.Addr().Interface().(extensionsMap)
|
|
||||||
mergeExtension(emOut.ExtensionMap(), emIn.ExtensionMap())
|
|
||||||
} else if emIn, ok := in.Addr().Interface().(extensionsBytes); ok {
|
|
||||||
emOut := out.Addr().Interface().(extensionsBytes)
|
emOut := out.Addr().Interface().(extensionsBytes)
|
||||||
bIn := emIn.GetExtensions()
|
bIn := emIn.GetExtensions()
|
||||||
bOut := emOut.GetExtensions()
|
bOut := emOut.GetExtensions()
|
||||||
*bOut = append(*bOut, *bIn...)
|
*bOut = append(*bOut, *bIn...)
|
||||||
|
} else if emIn, ok := extendable(in.Addr().Interface()); ok {
|
||||||
|
emOut, _ := extendable(out.Addr().Interface())
|
||||||
|
mIn, muIn := emIn.extensionsRead()
|
||||||
|
if mIn != nil {
|
||||||
|
mOut := emOut.extensionsWrite()
|
||||||
|
muIn.Lock()
|
||||||
|
mergeExtension(mOut, mIn)
|
||||||
|
muIn.Unlock()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uf := in.FieldByName("XXX_unrecognized")
|
uf := in.FieldByName("XXX_unrecognized")
|
||||||
|
|
137
vendor/github.com/gogo/protobuf/proto/decode.go
generated
vendored
137
vendor/github.com/gogo/protobuf/proto/decode.go
generated
vendored
|
@ -61,7 +61,6 @@ var ErrInternalBadWireType = errors.New("proto: internal error: bad wiretype for
|
||||||
// int32, int64, uint32, uint64, bool, and enum
|
// int32, int64, uint32, uint64, bool, and enum
|
||||||
// protocol buffer types.
|
// protocol buffer types.
|
||||||
func DecodeVarint(buf []byte) (x uint64, n int) {
|
func DecodeVarint(buf []byte) (x uint64, n int) {
|
||||||
// x, n already 0
|
|
||||||
for shift := uint(0); shift < 64; shift += 7 {
|
for shift := uint(0); shift < 64; shift += 7 {
|
||||||
if n >= len(buf) {
|
if n >= len(buf) {
|
||||||
return 0, 0
|
return 0, 0
|
||||||
|
@ -78,13 +77,7 @@ func DecodeVarint(buf []byte) (x uint64, n int) {
|
||||||
return 0, 0
|
return 0, 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// DecodeVarint reads a varint-encoded integer from the Buffer.
|
func (p *Buffer) decodeVarintSlow() (x uint64, err error) {
|
||||||
// This is the format for the
|
|
||||||
// int32, int64, uint32, uint64, bool, and enum
|
|
||||||
// protocol buffer types.
|
|
||||||
func (p *Buffer) DecodeVarint() (x uint64, err error) {
|
|
||||||
// x, err already 0
|
|
||||||
|
|
||||||
i := p.index
|
i := p.index
|
||||||
l := len(p.buf)
|
l := len(p.buf)
|
||||||
|
|
||||||
|
@ -107,6 +100,107 @@ func (p *Buffer) DecodeVarint() (x uint64, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DecodeVarint reads a varint-encoded integer from the Buffer.
|
||||||
|
// This is the format for the
|
||||||
|
// int32, int64, uint32, uint64, bool, and enum
|
||||||
|
// protocol buffer types.
|
||||||
|
func (p *Buffer) DecodeVarint() (x uint64, err error) {
|
||||||
|
i := p.index
|
||||||
|
buf := p.buf
|
||||||
|
|
||||||
|
if i >= len(buf) {
|
||||||
|
return 0, io.ErrUnexpectedEOF
|
||||||
|
} else if buf[i] < 0x80 {
|
||||||
|
p.index++
|
||||||
|
return uint64(buf[i]), nil
|
||||||
|
} else if len(buf)-i < 10 {
|
||||||
|
return p.decodeVarintSlow()
|
||||||
|
}
|
||||||
|
|
||||||
|
var b uint64
|
||||||
|
// we already checked the first byte
|
||||||
|
x = uint64(buf[i]) - 0x80
|
||||||
|
i++
|
||||||
|
|
||||||
|
b = uint64(buf[i])
|
||||||
|
i++
|
||||||
|
x += b << 7
|
||||||
|
if b&0x80 == 0 {
|
||||||
|
goto done
|
||||||
|
}
|
||||||
|
x -= 0x80 << 7
|
||||||
|
|
||||||
|
b = uint64(buf[i])
|
||||||
|
i++
|
||||||
|
x += b << 14
|
||||||
|
if b&0x80 == 0 {
|
||||||
|
goto done
|
||||||
|
}
|
||||||
|
x -= 0x80 << 14
|
||||||
|
|
||||||
|
b = uint64(buf[i])
|
||||||
|
i++
|
||||||
|
x += b << 21
|
||||||
|
if b&0x80 == 0 {
|
||||||
|
goto done
|
||||||
|
}
|
||||||
|
x -= 0x80 << 21
|
||||||
|
|
||||||
|
b = uint64(buf[i])
|
||||||
|
i++
|
||||||
|
x += b << 28
|
||||||
|
if b&0x80 == 0 {
|
||||||
|
goto done
|
||||||
|
}
|
||||||
|
x -= 0x80 << 28
|
||||||
|
|
||||||
|
b = uint64(buf[i])
|
||||||
|
i++
|
||||||
|
x += b << 35
|
||||||
|
if b&0x80 == 0 {
|
||||||
|
goto done
|
||||||
|
}
|
||||||
|
x -= 0x80 << 35
|
||||||
|
|
||||||
|
b = uint64(buf[i])
|
||||||
|
i++
|
||||||
|
x += b << 42
|
||||||
|
if b&0x80 == 0 {
|
||||||
|
goto done
|
||||||
|
}
|
||||||
|
x -= 0x80 << 42
|
||||||
|
|
||||||
|
b = uint64(buf[i])
|
||||||
|
i++
|
||||||
|
x += b << 49
|
||||||
|
if b&0x80 == 0 {
|
||||||
|
goto done
|
||||||
|
}
|
||||||
|
x -= 0x80 << 49
|
||||||
|
|
||||||
|
b = uint64(buf[i])
|
||||||
|
i++
|
||||||
|
x += b << 56
|
||||||
|
if b&0x80 == 0 {
|
||||||
|
goto done
|
||||||
|
}
|
||||||
|
x -= 0x80 << 56
|
||||||
|
|
||||||
|
b = uint64(buf[i])
|
||||||
|
i++
|
||||||
|
x += b << 63
|
||||||
|
if b&0x80 == 0 {
|
||||||
|
goto done
|
||||||
|
}
|
||||||
|
// x -= 0x80 << 63 // Always zero.
|
||||||
|
|
||||||
|
return 0, errOverflow
|
||||||
|
|
||||||
|
done:
|
||||||
|
p.index = i
|
||||||
|
return x, nil
|
||||||
|
}
|
||||||
|
|
||||||
// DecodeFixed64 reads a 64-bit integer from the Buffer.
|
// DecodeFixed64 reads a 64-bit integer from the Buffer.
|
||||||
// This is the format for the
|
// This is the format for the
|
||||||
// fixed64, sfixed64, and double protocol buffer types.
|
// fixed64, sfixed64, and double protocol buffer types.
|
||||||
|
@ -340,6 +434,8 @@ func (p *Buffer) DecodeGroup(pb Message) error {
|
||||||
// Buffer and places the decoded result in pb. If the struct
|
// Buffer and places the decoded result in pb. If the struct
|
||||||
// underlying pb does not match the data in the buffer, the results can be
|
// underlying pb does not match the data in the buffer, the results can be
|
||||||
// unpredictable.
|
// unpredictable.
|
||||||
|
//
|
||||||
|
// Unlike proto.Unmarshal, this does not reset pb before starting to unmarshal.
|
||||||
func (p *Buffer) Unmarshal(pb Message) error {
|
func (p *Buffer) Unmarshal(pb Message) error {
|
||||||
// If the object can unmarshal itself, let it.
|
// If the object can unmarshal itself, let it.
|
||||||
if u, ok := pb.(Unmarshaler); ok {
|
if u, ok := pb.(Unmarshaler); ok {
|
||||||
|
@ -378,6 +474,11 @@ func (o *Buffer) unmarshalType(st reflect.Type, prop *StructProperties, is_group
|
||||||
wire := int(u & 0x7)
|
wire := int(u & 0x7)
|
||||||
if wire == WireEndGroup {
|
if wire == WireEndGroup {
|
||||||
if is_group {
|
if is_group {
|
||||||
|
if required > 0 {
|
||||||
|
// Not enough information to determine the exact field.
|
||||||
|
// (See below.)
|
||||||
|
return &RequiredNotSetError{"{Unknown}"}
|
||||||
|
}
|
||||||
return nil // input is satisfied
|
return nil // input is satisfied
|
||||||
}
|
}
|
||||||
return fmt.Errorf("proto: %s: wiretype end group for non-group", st)
|
return fmt.Errorf("proto: %s: wiretype end group for non-group", st)
|
||||||
|
@ -390,16 +491,20 @@ func (o *Buffer) unmarshalType(st reflect.Type, prop *StructProperties, is_group
|
||||||
if !ok {
|
if !ok {
|
||||||
// Maybe it's an extension?
|
// Maybe it's an extension?
|
||||||
if prop.extendable {
|
if prop.extendable {
|
||||||
if e := structPointer_Interface(base, st).(extendableProto); isExtensionField(e, int32(tag)) {
|
if e, eok := structPointer_Interface(base, st).(extensionsBytes); eok {
|
||||||
if err = o.skip(st, tag, wire); err == nil {
|
if isExtensionField(e, int32(tag)) {
|
||||||
if ee, eok := e.(extensionsMap); eok {
|
if err = o.skip(st, tag, wire); err == nil {
|
||||||
ext := ee.ExtensionMap()[int32(tag)] // may be missing
|
ext := e.GetExtensions()
|
||||||
ext.enc = append(ext.enc, o.buf[oi:o.index]...)
|
|
||||||
ee.ExtensionMap()[int32(tag)] = ext
|
|
||||||
} else if ee, eok := e.(extensionsBytes); eok {
|
|
||||||
ext := ee.GetExtensions()
|
|
||||||
*ext = append(*ext, o.buf[oi:o.index]...)
|
*ext = append(*ext, o.buf[oi:o.index]...)
|
||||||
}
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
} else if e, _ := extendable(structPointer_Interface(base, st)); isExtensionField(e, int32(tag)) {
|
||||||
|
if err = o.skip(st, tag, wire); err == nil {
|
||||||
|
extmap := e.extensionsWrite()
|
||||||
|
ext := extmap[int32(tag)] // may be missing
|
||||||
|
ext.enc = append(ext.enc, o.buf[oi:o.index]...)
|
||||||
|
extmap[int32(tag)] = ext
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
11
vendor/github.com/gogo/protobuf/proto/decode_gogo.go
generated
vendored
11
vendor/github.com/gogo/protobuf/proto/decode_gogo.go
generated
vendored
|
@ -1,5 +1,7 @@
|
||||||
// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
|
// Protocol Buffers for Go with Gadgets
|
||||||
// http://github.com/gogo/protobuf/gogoproto
|
//
|
||||||
|
// Copyright (c) 2013, The GoGo Authors. All rights reserved.
|
||||||
|
// http://github.com/gogo/protobuf
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions are
|
// modification, are permitted provided that the following conditions are
|
||||||
|
@ -96,7 +98,7 @@ func setPtrCustomType(base structPointer, f field, v interface{}) {
|
||||||
if v == nil {
|
if v == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
structPointer_SetStructPointer(base, f, structPointer(reflect.ValueOf(v).Pointer()))
|
structPointer_SetStructPointer(base, f, toStructPointer(reflect.ValueOf(v)))
|
||||||
}
|
}
|
||||||
|
|
||||||
func setCustomType(base structPointer, f field, value interface{}) {
|
func setCustomType(base structPointer, f field, value interface{}) {
|
||||||
|
@ -163,7 +165,8 @@ func (o *Buffer) dec_custom_slice_bytes(p *Properties, base structPointer) error
|
||||||
}
|
}
|
||||||
newBas := appendStructPointer(base, p.field, p.ctype)
|
newBas := appendStructPointer(base, p.field, p.ctype)
|
||||||
|
|
||||||
setCustomType(newBas, 0, custom)
|
var zero field
|
||||||
|
setCustomType(newBas, zero, custom)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
100
vendor/github.com/gogo/protobuf/proto/duration.go
generated
vendored
Normal file
100
vendor/github.com/gogo/protobuf/proto/duration.go
generated
vendored
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
// Go support for Protocol Buffers - Google's data interchange format
|
||||||
|
//
|
||||||
|
// Copyright 2016 The Go Authors. All rights reserved.
|
||||||
|
// https://github.com/golang/protobuf
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
package proto
|
||||||
|
|
||||||
|
// This file implements conversions between google.protobuf.Duration
|
||||||
|
// and time.Duration.
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Range of a Duration in seconds, as specified in
|
||||||
|
// google/protobuf/duration.proto. This is about 10,000 years in seconds.
|
||||||
|
maxSeconds = int64(10000 * 365.25 * 24 * 60 * 60)
|
||||||
|
minSeconds = -maxSeconds
|
||||||
|
)
|
||||||
|
|
||||||
|
// validateDuration determines whether the Duration is valid according to the
|
||||||
|
// definition in google/protobuf/duration.proto. A valid Duration
|
||||||
|
// may still be too large to fit into a time.Duration (the range of Duration
|
||||||
|
// is about 10,000 years, and the range of time.Duration is about 290).
|
||||||
|
func validateDuration(d *duration) error {
|
||||||
|
if d == nil {
|
||||||
|
return errors.New("duration: nil Duration")
|
||||||
|
}
|
||||||
|
if d.Seconds < minSeconds || d.Seconds > maxSeconds {
|
||||||
|
return fmt.Errorf("duration: %#v: seconds out of range", d)
|
||||||
|
}
|
||||||
|
if d.Nanos <= -1e9 || d.Nanos >= 1e9 {
|
||||||
|
return fmt.Errorf("duration: %#v: nanos out of range", d)
|
||||||
|
}
|
||||||
|
// Seconds and Nanos must have the same sign, unless d.Nanos is zero.
|
||||||
|
if (d.Seconds < 0 && d.Nanos > 0) || (d.Seconds > 0 && d.Nanos < 0) {
|
||||||
|
return fmt.Errorf("duration: %#v: seconds and nanos have different signs", d)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DurationFromProto converts a Duration to a time.Duration. DurationFromProto
|
||||||
|
// returns an error if the Duration is invalid or is too large to be
|
||||||
|
// represented in a time.Duration.
|
||||||
|
func durationFromProto(p *duration) (time.Duration, error) {
|
||||||
|
if err := validateDuration(p); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
d := time.Duration(p.Seconds) * time.Second
|
||||||
|
if int64(d/time.Second) != p.Seconds {
|
||||||
|
return 0, fmt.Errorf("duration: %#v is out of range for time.Duration", p)
|
||||||
|
}
|
||||||
|
if p.Nanos != 0 {
|
||||||
|
d += time.Duration(p.Nanos)
|
||||||
|
if (d < 0) != (p.Nanos < 0) {
|
||||||
|
return 0, fmt.Errorf("duration: %#v is out of range for time.Duration", p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return d, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DurationProto converts a time.Duration to a Duration.
|
||||||
|
func durationProto(d time.Duration) *duration {
|
||||||
|
nanos := d.Nanoseconds()
|
||||||
|
secs := nanos / 1e9
|
||||||
|
nanos -= secs * 1e9
|
||||||
|
return &duration{
|
||||||
|
Seconds: secs,
|
||||||
|
Nanos: int32(nanos),
|
||||||
|
}
|
||||||
|
}
|
203
vendor/github.com/gogo/protobuf/proto/duration_gogo.go
generated
vendored
Normal file
203
vendor/github.com/gogo/protobuf/proto/duration_gogo.go
generated
vendored
Normal file
|
@ -0,0 +1,203 @@
|
||||||
|
// Protocol Buffers for Go with Gadgets
|
||||||
|
//
|
||||||
|
// Copyright (c) 2016, The GoGo Authors. All rights reserved.
|
||||||
|
// http://github.com/gogo/protobuf
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
package proto
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var durationType = reflect.TypeOf((*time.Duration)(nil)).Elem()
|
||||||
|
|
||||||
|
type duration struct {
|
||||||
|
Seconds int64 `protobuf:"varint,1,opt,name=seconds,proto3" json:"seconds,omitempty"`
|
||||||
|
Nanos int32 `protobuf:"varint,2,opt,name=nanos,proto3" json:"nanos,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *duration) Reset() { *m = duration{} }
|
||||||
|
func (*duration) ProtoMessage() {}
|
||||||
|
func (*duration) String() string { return "duration<string>" }
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
RegisterType((*duration)(nil), "gogo.protobuf.proto.duration")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Buffer) decDuration() (time.Duration, error) {
|
||||||
|
b, err := o.DecodeRawBytes(true)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
dproto := &duration{}
|
||||||
|
if err := Unmarshal(b, dproto); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return durationFromProto(dproto)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Buffer) dec_duration(p *Properties, base structPointer) error {
|
||||||
|
d, err := o.decDuration()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
word64_Set(structPointer_Word64(base, p.field), o, uint64(d))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Buffer) dec_ref_duration(p *Properties, base structPointer) error {
|
||||||
|
d, err := o.decDuration()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
word64Val_Set(structPointer_Word64Val(base, p.field), o, uint64(d))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Buffer) dec_slice_duration(p *Properties, base structPointer) error {
|
||||||
|
d, err := o.decDuration()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
newBas := appendStructPointer(base, p.field, reflect.SliceOf(reflect.PtrTo(durationType)))
|
||||||
|
var zero field
|
||||||
|
setPtrCustomType(newBas, zero, &d)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Buffer) dec_slice_ref_duration(p *Properties, base structPointer) error {
|
||||||
|
d, err := o.decDuration()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
structPointer_Word64Slice(base, p.field).Append(uint64(d))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func size_duration(p *Properties, base structPointer) (n int) {
|
||||||
|
structp := structPointer_GetStructPointer(base, p.field)
|
||||||
|
if structPointer_IsNil(structp) {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
dur := structPointer_Interface(structp, durationType).(*time.Duration)
|
||||||
|
d := durationProto(*dur)
|
||||||
|
size := Size(d)
|
||||||
|
return size + sizeVarint(uint64(size)) + len(p.tagcode)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Buffer) enc_duration(p *Properties, base structPointer) error {
|
||||||
|
structp := structPointer_GetStructPointer(base, p.field)
|
||||||
|
if structPointer_IsNil(structp) {
|
||||||
|
return ErrNil
|
||||||
|
}
|
||||||
|
dur := structPointer_Interface(structp, durationType).(*time.Duration)
|
||||||
|
d := durationProto(*dur)
|
||||||
|
data, err := Marshal(d)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
o.buf = append(o.buf, p.tagcode...)
|
||||||
|
o.EncodeRawBytes(data)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func size_ref_duration(p *Properties, base structPointer) (n int) {
|
||||||
|
dur := structPointer_InterfaceAt(base, p.field, durationType).(*time.Duration)
|
||||||
|
d := durationProto(*dur)
|
||||||
|
size := Size(d)
|
||||||
|
return size + sizeVarint(uint64(size)) + len(p.tagcode)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Buffer) enc_ref_duration(p *Properties, base structPointer) error {
|
||||||
|
dur := structPointer_InterfaceAt(base, p.field, durationType).(*time.Duration)
|
||||||
|
d := durationProto(*dur)
|
||||||
|
data, err := Marshal(d)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
o.buf = append(o.buf, p.tagcode...)
|
||||||
|
o.EncodeRawBytes(data)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func size_slice_duration(p *Properties, base structPointer) (n int) {
|
||||||
|
pdurs := structPointer_InterfaceAt(base, p.field, reflect.SliceOf(reflect.PtrTo(durationType))).(*[]*time.Duration)
|
||||||
|
durs := *pdurs
|
||||||
|
for i := 0; i < len(durs); i++ {
|
||||||
|
if durs[i] == nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
dproto := durationProto(*durs[i])
|
||||||
|
size := Size(dproto)
|
||||||
|
n += len(p.tagcode) + size + sizeVarint(uint64(size))
|
||||||
|
}
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Buffer) enc_slice_duration(p *Properties, base structPointer) error {
|
||||||
|
pdurs := structPointer_InterfaceAt(base, p.field, reflect.SliceOf(reflect.PtrTo(durationType))).(*[]*time.Duration)
|
||||||
|
durs := *pdurs
|
||||||
|
for i := 0; i < len(durs); i++ {
|
||||||
|
if durs[i] == nil {
|
||||||
|
return errRepeatedHasNil
|
||||||
|
}
|
||||||
|
dproto := durationProto(*durs[i])
|
||||||
|
data, err := Marshal(dproto)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
o.buf = append(o.buf, p.tagcode...)
|
||||||
|
o.EncodeRawBytes(data)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func size_slice_ref_duration(p *Properties, base structPointer) (n int) {
|
||||||
|
pdurs := structPointer_InterfaceAt(base, p.field, reflect.SliceOf(durationType)).(*[]time.Duration)
|
||||||
|
durs := *pdurs
|
||||||
|
for i := 0; i < len(durs); i++ {
|
||||||
|
dproto := durationProto(durs[i])
|
||||||
|
size := Size(dproto)
|
||||||
|
n += len(p.tagcode) + size + sizeVarint(uint64(size))
|
||||||
|
}
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Buffer) enc_slice_ref_duration(p *Properties, base structPointer) error {
|
||||||
|
pdurs := structPointer_InterfaceAt(base, p.field, reflect.SliceOf(durationType)).(*[]time.Duration)
|
||||||
|
durs := *pdurs
|
||||||
|
for i := 0; i < len(durs); i++ {
|
||||||
|
dproto := durationProto(durs[i])
|
||||||
|
data, err := Marshal(dproto)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
o.buf = append(o.buf, p.tagcode...)
|
||||||
|
o.EncodeRawBytes(data)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
73
vendor/github.com/gogo/protobuf/proto/encode.go
generated
vendored
73
vendor/github.com/gogo/protobuf/proto/encode.go
generated
vendored
|
@ -70,6 +70,10 @@ var (
|
||||||
|
|
||||||
// ErrNil is the error returned if Marshal is called with nil.
|
// ErrNil is the error returned if Marshal is called with nil.
|
||||||
ErrNil = errors.New("proto: Marshal called with nil")
|
ErrNil = errors.New("proto: Marshal called with nil")
|
||||||
|
|
||||||
|
// ErrTooLarge is the error returned if Marshal is called with a
|
||||||
|
// message that encodes to >2GB.
|
||||||
|
ErrTooLarge = errors.New("proto: message encodes to over 2 GB")
|
||||||
)
|
)
|
||||||
|
|
||||||
// The fundamental encoders that put bytes on the wire.
|
// The fundamental encoders that put bytes on the wire.
|
||||||
|
@ -78,6 +82,10 @@ var (
|
||||||
|
|
||||||
const maxVarintBytes = 10 // maximum length of a varint
|
const maxVarintBytes = 10 // maximum length of a varint
|
||||||
|
|
||||||
|
// maxMarshalSize is the largest allowed size of an encoded protobuf,
|
||||||
|
// since C++ and Java use signed int32s for the size.
|
||||||
|
const maxMarshalSize = 1<<31 - 1
|
||||||
|
|
||||||
// EncodeVarint returns the varint encoding of x.
|
// EncodeVarint returns the varint encoding of x.
|
||||||
// This is the format for the
|
// This is the format for the
|
||||||
// int32, int64, uint32, uint64, bool, and enum
|
// int32, int64, uint32, uint64, bool, and enum
|
||||||
|
@ -226,10 +234,6 @@ func Marshal(pb Message) ([]byte, error) {
|
||||||
}
|
}
|
||||||
p := NewBuffer(nil)
|
p := NewBuffer(nil)
|
||||||
err := p.Marshal(pb)
|
err := p.Marshal(pb)
|
||||||
var state errorState
|
|
||||||
if err != nil && !state.shouldContinue(err, nil) {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if p.buf == nil && err == nil {
|
if p.buf == nil && err == nil {
|
||||||
// Return a non-nil slice on success.
|
// Return a non-nil slice on success.
|
||||||
return []byte{}, nil
|
return []byte{}, nil
|
||||||
|
@ -258,11 +262,8 @@ func (p *Buffer) Marshal(pb Message) error {
|
||||||
// Can the object marshal itself?
|
// Can the object marshal itself?
|
||||||
if m, ok := pb.(Marshaler); ok {
|
if m, ok := pb.(Marshaler); ok {
|
||||||
data, err := m.Marshal()
|
data, err := m.Marshal()
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
p.buf = append(p.buf, data...)
|
p.buf = append(p.buf, data...)
|
||||||
return nil
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
t, base, err := getbase(pb)
|
t, base, err := getbase(pb)
|
||||||
|
@ -274,9 +275,12 @@ func (p *Buffer) Marshal(pb Message) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if collectStats {
|
if collectStats {
|
||||||
stats.Encode++
|
(stats).Encode++ // Parens are to work around a goimports bug.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(p.buf) > maxMarshalSize {
|
||||||
|
return ErrTooLarge
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -298,7 +302,7 @@ func Size(pb Message) (n int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if collectStats {
|
if collectStats {
|
||||||
stats.Size++
|
(stats).Size++ // Parens are to work around a goimports bug.
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
|
@ -1003,7 +1007,6 @@ func size_slice_struct_message(p *Properties, base structPointer) (n int) {
|
||||||
if p.isMarshaler {
|
if p.isMarshaler {
|
||||||
m := structPointer_Interface(structp, p.stype).(Marshaler)
|
m := structPointer_Interface(structp, p.stype).(Marshaler)
|
||||||
data, _ := m.Marshal()
|
data, _ := m.Marshal()
|
||||||
n += len(p.tagcode)
|
|
||||||
n += sizeRawBytes(data)
|
n += sizeRawBytes(data)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -1062,10 +1065,32 @@ func size_slice_struct_group(p *Properties, base structPointer) (n int) {
|
||||||
|
|
||||||
// Encode an extension map.
|
// Encode an extension map.
|
||||||
func (o *Buffer) enc_map(p *Properties, base structPointer) error {
|
func (o *Buffer) enc_map(p *Properties, base structPointer) error {
|
||||||
v := *structPointer_ExtMap(base, p.field)
|
exts := structPointer_ExtMap(base, p.field)
|
||||||
if err := encodeExtensionMap(v); err != nil {
|
if err := encodeExtensionsMap(*exts); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return o.enc_map_body(*exts)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Buffer) enc_exts(p *Properties, base structPointer) error {
|
||||||
|
exts := structPointer_Extensions(base, p.field)
|
||||||
|
|
||||||
|
v, mu := exts.extensionsRead()
|
||||||
|
if v == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
mu.Lock()
|
||||||
|
defer mu.Unlock()
|
||||||
|
if err := encodeExtensionsMap(v); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return o.enc_map_body(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Buffer) enc_map_body(v map[int32]Extension) error {
|
||||||
// Fast-path for common cases: zero or one extensions.
|
// Fast-path for common cases: zero or one extensions.
|
||||||
if len(v) <= 1 {
|
if len(v) <= 1 {
|
||||||
for _, e := range v {
|
for _, e := range v {
|
||||||
|
@ -1088,8 +1113,13 @@ func (o *Buffer) enc_map(p *Properties, base structPointer) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func size_map(p *Properties, base structPointer) int {
|
func size_map(p *Properties, base structPointer) int {
|
||||||
v := *structPointer_ExtMap(base, p.field)
|
v := structPointer_ExtMap(base, p.field)
|
||||||
return sizeExtensionMap(v)
|
return extensionsMapSize(*v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func size_exts(p *Properties, base structPointer) int {
|
||||||
|
v := structPointer_Extensions(base, p.field)
|
||||||
|
return extensionsSize(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encode a map field.
|
// Encode a map field.
|
||||||
|
@ -1118,7 +1148,7 @@ func (o *Buffer) enc_new_map(p *Properties, base structPointer) error {
|
||||||
if err := p.mkeyprop.enc(o, p.mkeyprop, keybase); err != nil {
|
if err := p.mkeyprop.enc(o, p.mkeyprop, keybase); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := p.mvalprop.enc(o, p.mvalprop, valbase); err != nil {
|
if err := p.mvalprop.enc(o, p.mvalprop, valbase); err != nil && err != ErrNil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -1128,11 +1158,6 @@ func (o *Buffer) enc_new_map(p *Properties, base structPointer) error {
|
||||||
for _, key := range v.MapKeys() {
|
for _, key := range v.MapKeys() {
|
||||||
val := v.MapIndex(key)
|
val := v.MapIndex(key)
|
||||||
|
|
||||||
// The only illegal map entry values are nil message pointers.
|
|
||||||
if val.Kind() == reflect.Ptr && val.IsNil() {
|
|
||||||
return errors.New("proto: map has nil element")
|
|
||||||
}
|
|
||||||
|
|
||||||
keycopy.Set(key)
|
keycopy.Set(key)
|
||||||
valcopy.Set(val)
|
valcopy.Set(val)
|
||||||
|
|
||||||
|
@ -1220,6 +1245,9 @@ func (o *Buffer) enc_struct(prop *StructProperties, base structPointer) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if len(o.buf) > maxMarshalSize {
|
||||||
|
return ErrTooLarge
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1236,6 +1264,9 @@ func (o *Buffer) enc_struct(prop *StructProperties, base structPointer) error {
|
||||||
// Add unrecognized fields at the end.
|
// Add unrecognized fields at the end.
|
||||||
if prop.unrecField.IsValid() {
|
if prop.unrecField.IsValid() {
|
||||||
v := *structPointer_Bytes(base, prop.unrecField)
|
v := *structPointer_Bytes(base, prop.unrecField)
|
||||||
|
if len(o.buf)+len(v) > maxMarshalSize {
|
||||||
|
return ErrTooLarge
|
||||||
|
}
|
||||||
if len(v) > 0 {
|
if len(v) > 0 {
|
||||||
o.buf = append(o.buf, v...)
|
o.buf = append(o.buf, v...)
|
||||||
}
|
}
|
||||||
|
|
22
vendor/github.com/gogo/protobuf/proto/encode_gogo.go
generated
vendored
22
vendor/github.com/gogo/protobuf/proto/encode_gogo.go
generated
vendored
|
@ -1,7 +1,7 @@
|
||||||
// Extensions for Protocol Buffers to create more go like structures.
|
// Protocol Buffers for Go with Gadgets
|
||||||
//
|
//
|
||||||
// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
|
// Copyright (c) 2013, The GoGo Authors. All rights reserved.
|
||||||
// http://github.com/gogo/protobuf/gogoproto
|
// http://github.com/gogo/protobuf
|
||||||
//
|
//
|
||||||
// Go support for Protocol Buffers - Google's data interchange format
|
// Go support for Protocol Buffers - Google's data interchange format
|
||||||
//
|
//
|
||||||
|
@ -196,12 +196,10 @@ func size_ref_struct_message(p *Properties, base structPointer) int {
|
||||||
// Encode a slice of references to message struct pointers ([]struct).
|
// Encode a slice of references to message struct pointers ([]struct).
|
||||||
func (o *Buffer) enc_slice_ref_struct_message(p *Properties, base structPointer) error {
|
func (o *Buffer) enc_slice_ref_struct_message(p *Properties, base structPointer) error {
|
||||||
var state errorState
|
var state errorState
|
||||||
ss := structPointer_GetStructPointer(base, p.field)
|
ss := structPointer_StructRefSlice(base, p.field, p.stype.Size())
|
||||||
ss1 := structPointer_GetRefStructPointer(ss, field(0))
|
l := ss.Len()
|
||||||
size := p.stype.Size()
|
|
||||||
l := structPointer_Len(base, p.field)
|
|
||||||
for i := 0; i < l; i++ {
|
for i := 0; i < l; i++ {
|
||||||
structp := structPointer_Add(ss1, field(uintptr(i)*size))
|
structp := ss.Index(i)
|
||||||
if structPointer_IsNil(structp) {
|
if structPointer_IsNil(structp) {
|
||||||
return errRepeatedHasNil
|
return errRepeatedHasNil
|
||||||
}
|
}
|
||||||
|
@ -233,13 +231,11 @@ func (o *Buffer) enc_slice_ref_struct_message(p *Properties, base structPointer)
|
||||||
|
|
||||||
//TODO this is only copied, please fix this
|
//TODO this is only copied, please fix this
|
||||||
func size_slice_ref_struct_message(p *Properties, base structPointer) (n int) {
|
func size_slice_ref_struct_message(p *Properties, base structPointer) (n int) {
|
||||||
ss := structPointer_GetStructPointer(base, p.field)
|
ss := structPointer_StructRefSlice(base, p.field, p.stype.Size())
|
||||||
ss1 := structPointer_GetRefStructPointer(ss, field(0))
|
l := ss.Len()
|
||||||
size := p.stype.Size()
|
|
||||||
l := structPointer_Len(base, p.field)
|
|
||||||
n += l * len(p.tagcode)
|
n += l * len(p.tagcode)
|
||||||
for i := 0; i < l; i++ {
|
for i := 0; i < l; i++ {
|
||||||
structp := structPointer_Add(ss1, field(uintptr(i)*size))
|
structp := ss.Index(i)
|
||||||
if structPointer_IsNil(structp) {
|
if structPointer_IsNil(structp) {
|
||||||
return // return the size up to this point
|
return // return the size up to this point
|
||||||
}
|
}
|
||||||
|
|
34
vendor/github.com/gogo/protobuf/proto/equal.go
generated
vendored
34
vendor/github.com/gogo/protobuf/proto/equal.go
generated
vendored
|
@ -54,13 +54,17 @@ Equality is defined in this way:
|
||||||
in a proto3 .proto file, fields are not "set"; specifically,
|
in a proto3 .proto file, fields are not "set"; specifically,
|
||||||
zero length proto3 "bytes" fields are equal (nil == {}).
|
zero length proto3 "bytes" fields are equal (nil == {}).
|
||||||
- Two repeated fields are equal iff their lengths are the same,
|
- Two repeated fields are equal iff their lengths are the same,
|
||||||
and their corresponding elements are equal (a "bytes" field,
|
and their corresponding elements are equal. Note a "bytes" field,
|
||||||
although represented by []byte, is not a repeated field)
|
although represented by []byte, is not a repeated field and the
|
||||||
|
rule for the scalar fields described above applies.
|
||||||
- Two unset fields are equal.
|
- Two unset fields are equal.
|
||||||
- Two unknown field sets are equal if their current
|
- Two unknown field sets are equal if their current
|
||||||
encoded state is equal.
|
encoded state is equal.
|
||||||
- Two extension sets are equal iff they have corresponding
|
- Two extension sets are equal iff they have corresponding
|
||||||
elements that are pairwise equal.
|
elements that are pairwise equal.
|
||||||
|
- Two map fields are equal iff their lengths are the same,
|
||||||
|
and they contain the same set of elements. Zero-length map
|
||||||
|
fields are equal.
|
||||||
- Every other combination of things are not equal.
|
- Every other combination of things are not equal.
|
||||||
|
|
||||||
The return value is undefined if a and b are not protocol buffers.
|
The return value is undefined if a and b are not protocol buffers.
|
||||||
|
@ -121,9 +125,16 @@ func equalStruct(v1, v2 reflect.Value) bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if em1 := v1.FieldByName("XXX_InternalExtensions"); em1.IsValid() {
|
||||||
|
em2 := v2.FieldByName("XXX_InternalExtensions")
|
||||||
|
if !equalExtensions(v1.Type(), em1.Interface().(XXX_InternalExtensions), em2.Interface().(XXX_InternalExtensions)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if em1 := v1.FieldByName("XXX_extensions"); em1.IsValid() {
|
if em1 := v1.FieldByName("XXX_extensions"); em1.IsValid() {
|
||||||
em2 := v2.FieldByName("XXX_extensions")
|
em2 := v2.FieldByName("XXX_extensions")
|
||||||
if !equalExtensions(v1.Type(), em1.Interface().(map[int32]Extension), em2.Interface().(map[int32]Extension)) {
|
if !equalExtMap(v1.Type(), em1.Interface().(map[int32]Extension), em2.Interface().(map[int32]Extension)) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -184,6 +195,13 @@ func equalAny(v1, v2 reflect.Value, prop *Properties) bool {
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
case reflect.Ptr:
|
case reflect.Ptr:
|
||||||
|
// Maps may have nil values in them, so check for nil.
|
||||||
|
if v1.IsNil() && v2.IsNil() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if v1.IsNil() != v2.IsNil() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
return equalAny(v1.Elem(), v2.Elem(), prop)
|
return equalAny(v1.Elem(), v2.Elem(), prop)
|
||||||
case reflect.Slice:
|
case reflect.Slice:
|
||||||
if v1.Type().Elem().Kind() == reflect.Uint8 {
|
if v1.Type().Elem().Kind() == reflect.Uint8 {
|
||||||
|
@ -223,8 +241,14 @@ func equalAny(v1, v2 reflect.Value, prop *Properties) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// base is the struct type that the extensions are based on.
|
// base is the struct type that the extensions are based on.
|
||||||
// em1 and em2 are extension maps.
|
// x1 and x2 are InternalExtensions.
|
||||||
func equalExtensions(base reflect.Type, em1, em2 map[int32]Extension) bool {
|
func equalExtensions(base reflect.Type, x1, x2 XXX_InternalExtensions) bool {
|
||||||
|
em1, _ := x1.extensionsRead()
|
||||||
|
em2, _ := x2.extensionsRead()
|
||||||
|
return equalExtMap(base, em1, em2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func equalExtMap(base reflect.Type, em1, em2 map[int32]Extension) bool {
|
||||||
if len(em1) != len(em2) {
|
if len(em1) != len(em2) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
413
vendor/github.com/gogo/protobuf/proto/extensions.go
generated
vendored
413
vendor/github.com/gogo/protobuf/proto/extensions.go
generated
vendored
|
@ -52,23 +52,112 @@ type ExtensionRange struct {
|
||||||
Start, End int32 // both inclusive
|
Start, End int32 // both inclusive
|
||||||
}
|
}
|
||||||
|
|
||||||
// extendableProto is an interface implemented by any protocol buffer that may be extended.
|
// extendableProto is an interface implemented by any protocol buffer generated by the current
|
||||||
|
// proto compiler that may be extended.
|
||||||
type extendableProto interface {
|
type extendableProto interface {
|
||||||
Message
|
Message
|
||||||
ExtensionRangeArray() []ExtensionRange
|
ExtensionRangeArray() []ExtensionRange
|
||||||
|
extensionsWrite() map[int32]Extension
|
||||||
|
extensionsRead() (map[int32]Extension, sync.Locker)
|
||||||
}
|
}
|
||||||
|
|
||||||
type extensionsMap interface {
|
// extendableProtoV1 is an interface implemented by a protocol buffer generated by the previous
|
||||||
extendableProto
|
// version of the proto compiler that may be extended.
|
||||||
|
type extendableProtoV1 interface {
|
||||||
|
Message
|
||||||
|
ExtensionRangeArray() []ExtensionRange
|
||||||
ExtensionMap() map[int32]Extension
|
ExtensionMap() map[int32]Extension
|
||||||
}
|
}
|
||||||
|
|
||||||
type extensionsBytes interface {
|
type extensionsBytes interface {
|
||||||
extendableProto
|
Message
|
||||||
|
ExtensionRangeArray() []ExtensionRange
|
||||||
GetExtensions() *[]byte
|
GetExtensions() *[]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// extensionAdapter is a wrapper around extendableProtoV1 that implements extendableProto.
|
||||||
|
type extensionAdapter struct {
|
||||||
|
extendableProtoV1
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e extensionAdapter) extensionsWrite() map[int32]Extension {
|
||||||
|
return e.ExtensionMap()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e extensionAdapter) extensionsRead() (map[int32]Extension, sync.Locker) {
|
||||||
|
return e.ExtensionMap(), notLocker{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// notLocker is a sync.Locker whose Lock and Unlock methods are nops.
|
||||||
|
type notLocker struct{}
|
||||||
|
|
||||||
|
func (n notLocker) Lock() {}
|
||||||
|
func (n notLocker) Unlock() {}
|
||||||
|
|
||||||
|
// extendable returns the extendableProto interface for the given generated proto message.
|
||||||
|
// If the proto message has the old extension format, it returns a wrapper that implements
|
||||||
|
// the extendableProto interface.
|
||||||
|
func extendable(p interface{}) (extendableProto, bool) {
|
||||||
|
if ep, ok := p.(extendableProto); ok {
|
||||||
|
return ep, ok
|
||||||
|
}
|
||||||
|
if ep, ok := p.(extendableProtoV1); ok {
|
||||||
|
return extensionAdapter{ep}, ok
|
||||||
|
}
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX_InternalExtensions is an internal representation of proto extensions.
|
||||||
|
//
|
||||||
|
// Each generated message struct type embeds an anonymous XXX_InternalExtensions field,
|
||||||
|
// thus gaining the unexported 'extensions' method, which can be called only from the proto package.
|
||||||
|
//
|
||||||
|
// The methods of XXX_InternalExtensions are not concurrency safe in general,
|
||||||
|
// but calls to logically read-only methods such as has and get may be executed concurrently.
|
||||||
|
type XXX_InternalExtensions struct {
|
||||||
|
// The struct must be indirect so that if a user inadvertently copies a
|
||||||
|
// generated message and its embedded XXX_InternalExtensions, they
|
||||||
|
// avoid the mayhem of a copied mutex.
|
||||||
|
//
|
||||||
|
// The mutex serializes all logically read-only operations to p.extensionMap.
|
||||||
|
// It is up to the client to ensure that write operations to p.extensionMap are
|
||||||
|
// mutually exclusive with other accesses.
|
||||||
|
p *struct {
|
||||||
|
mu sync.Mutex
|
||||||
|
extensionMap map[int32]Extension
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// extensionsWrite returns the extension map, creating it on first use.
|
||||||
|
func (e *XXX_InternalExtensions) extensionsWrite() map[int32]Extension {
|
||||||
|
if e.p == nil {
|
||||||
|
e.p = new(struct {
|
||||||
|
mu sync.Mutex
|
||||||
|
extensionMap map[int32]Extension
|
||||||
|
})
|
||||||
|
e.p.extensionMap = make(map[int32]Extension)
|
||||||
|
}
|
||||||
|
return e.p.extensionMap
|
||||||
|
}
|
||||||
|
|
||||||
|
// extensionsRead returns the extensions map for read-only use. It may be nil.
|
||||||
|
// The caller must hold the returned mutex's lock when accessing Elements within the map.
|
||||||
|
func (e *XXX_InternalExtensions) extensionsRead() (map[int32]Extension, sync.Locker) {
|
||||||
|
if e.p == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
return e.p.extensionMap, &e.p.mu
|
||||||
|
}
|
||||||
|
|
||||||
|
type extensionRange interface {
|
||||||
|
Message
|
||||||
|
ExtensionRangeArray() []ExtensionRange
|
||||||
|
}
|
||||||
|
|
||||||
var extendableProtoType = reflect.TypeOf((*extendableProto)(nil)).Elem()
|
var extendableProtoType = reflect.TypeOf((*extendableProto)(nil)).Elem()
|
||||||
|
var extendableProtoV1Type = reflect.TypeOf((*extendableProtoV1)(nil)).Elem()
|
||||||
|
var extendableBytesType = reflect.TypeOf((*extensionsBytes)(nil)).Elem()
|
||||||
|
var extensionRangeType = reflect.TypeOf((*extensionRange)(nil)).Elem()
|
||||||
|
|
||||||
// ExtensionDesc represents an extension specification.
|
// ExtensionDesc represents an extension specification.
|
||||||
// Used in generated code from the protocol compiler.
|
// Used in generated code from the protocol compiler.
|
||||||
|
@ -78,6 +167,7 @@ type ExtensionDesc struct {
|
||||||
Field int32 // field number
|
Field int32 // field number
|
||||||
Name string // fully-qualified name of extension, for text formatting
|
Name string // fully-qualified name of extension, for text formatting
|
||||||
Tag string // protobuf tag style
|
Tag string // protobuf tag style
|
||||||
|
Filename string // name of the file in which the extension is defined
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ed *ExtensionDesc) repeated() bool {
|
func (ed *ExtensionDesc) repeated() bool {
|
||||||
|
@ -101,20 +191,23 @@ type Extension struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetRawExtension is for testing only.
|
// SetRawExtension is for testing only.
|
||||||
func SetRawExtension(base extendableProto, id int32, b []byte) {
|
func SetRawExtension(base Message, id int32, b []byte) {
|
||||||
if ebase, ok := base.(extensionsMap); ok {
|
if ebase, ok := base.(extensionsBytes); ok {
|
||||||
ebase.ExtensionMap()[id] = Extension{enc: b}
|
|
||||||
} else if ebase, ok := base.(extensionsBytes); ok {
|
|
||||||
clearExtension(base, id)
|
clearExtension(base, id)
|
||||||
ext := ebase.GetExtensions()
|
ext := ebase.GetExtensions()
|
||||||
*ext = append(*ext, b...)
|
*ext = append(*ext, b...)
|
||||||
} else {
|
return
|
||||||
panic("unreachable")
|
|
||||||
}
|
}
|
||||||
|
epb, ok := extendable(base)
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
extmap := epb.extensionsWrite()
|
||||||
|
extmap[id] = Extension{enc: b}
|
||||||
}
|
}
|
||||||
|
|
||||||
// isExtensionField returns true iff the given field number is in an extension range.
|
// isExtensionField returns true iff the given field number is in an extension range.
|
||||||
func isExtensionField(pb extendableProto, field int32) bool {
|
func isExtensionField(pb extensionRange, field int32) bool {
|
||||||
for _, er := range pb.ExtensionRangeArray() {
|
for _, er := range pb.ExtensionRangeArray() {
|
||||||
if er.Start <= field && field <= er.End {
|
if er.Start <= field && field <= er.End {
|
||||||
return true
|
return true
|
||||||
|
@ -125,8 +218,12 @@ func isExtensionField(pb extendableProto, field int32) bool {
|
||||||
|
|
||||||
// checkExtensionTypes checks that the given extension is valid for pb.
|
// checkExtensionTypes checks that the given extension is valid for pb.
|
||||||
func checkExtensionTypes(pb extendableProto, extension *ExtensionDesc) error {
|
func checkExtensionTypes(pb extendableProto, extension *ExtensionDesc) error {
|
||||||
|
var pbi interface{} = pb
|
||||||
// Check the extended type.
|
// Check the extended type.
|
||||||
if a, b := reflect.TypeOf(pb), reflect.TypeOf(extension.ExtendedType); a != b {
|
if ea, ok := pbi.(extensionAdapter); ok {
|
||||||
|
pbi = ea.extendableProtoV1
|
||||||
|
}
|
||||||
|
if a, b := reflect.TypeOf(pbi), reflect.TypeOf(extension.ExtendedType); a != b {
|
||||||
return errors.New("proto: bad extended type; " + b.String() + " does not extend " + a.String())
|
return errors.New("proto: bad extended type; " + b.String() + " does not extend " + a.String())
|
||||||
}
|
}
|
||||||
// Check the range.
|
// Check the range.
|
||||||
|
@ -172,43 +269,57 @@ func extensionProperties(ed *ExtensionDesc) *Properties {
|
||||||
return prop
|
return prop
|
||||||
}
|
}
|
||||||
|
|
||||||
// encodeExtensionMap encodes any unmarshaled (unencoded) extensions in m.
|
// encode encodes any unmarshaled (unencoded) extensions in e.
|
||||||
func encodeExtensionMap(m map[int32]Extension) error {
|
func encodeExtensions(e *XXX_InternalExtensions) error {
|
||||||
|
m, mu := e.extensionsRead()
|
||||||
|
if m == nil {
|
||||||
|
return nil // fast path
|
||||||
|
}
|
||||||
|
mu.Lock()
|
||||||
|
defer mu.Unlock()
|
||||||
|
return encodeExtensionsMap(m)
|
||||||
|
}
|
||||||
|
|
||||||
|
// encode encodes any unmarshaled (unencoded) extensions in e.
|
||||||
|
func encodeExtensionsMap(m map[int32]Extension) error {
|
||||||
for k, e := range m {
|
for k, e := range m {
|
||||||
err := encodeExtension(&e)
|
if e.value == nil || e.desc == nil {
|
||||||
if err != nil {
|
// Extension is only in its encoded form.
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// We don't skip extensions that have an encoded form set,
|
||||||
|
// because the extension value may have been mutated after
|
||||||
|
// the last time this function was called.
|
||||||
|
|
||||||
|
et := reflect.TypeOf(e.desc.ExtensionType)
|
||||||
|
props := extensionProperties(e.desc)
|
||||||
|
|
||||||
|
p := NewBuffer(nil)
|
||||||
|
// If e.value has type T, the encoder expects a *struct{ X T }.
|
||||||
|
// Pass a *T with a zero field and hope it all works out.
|
||||||
|
x := reflect.New(et)
|
||||||
|
x.Elem().Set(reflect.ValueOf(e.value))
|
||||||
|
if err := props.enc(p, props, toStructPointer(x)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
e.enc = p.buf
|
||||||
m[k] = e
|
m[k] = e
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func encodeExtension(e *Extension) error {
|
func extensionsSize(e *XXX_InternalExtensions) (n int) {
|
||||||
if e.value == nil || e.desc == nil {
|
m, mu := e.extensionsRead()
|
||||||
// Extension is only in its encoded form.
|
if m == nil {
|
||||||
return nil
|
return 0
|
||||||
}
|
}
|
||||||
// We don't skip extensions that have an encoded form set,
|
mu.Lock()
|
||||||
// because the extension value may have been mutated after
|
defer mu.Unlock()
|
||||||
// the last time this function was called.
|
return extensionsMapSize(m)
|
||||||
|
|
||||||
et := reflect.TypeOf(e.desc.ExtensionType)
|
|
||||||
props := extensionProperties(e.desc)
|
|
||||||
|
|
||||||
p := NewBuffer(nil)
|
|
||||||
// If e.value has type T, the encoder expects a *struct{ X T }.
|
|
||||||
// Pass a *T with a zero field and hope it all works out.
|
|
||||||
x := reflect.New(et)
|
|
||||||
x.Elem().Set(reflect.ValueOf(e.value))
|
|
||||||
if err := props.enc(p, props, toStructPointer(x)); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
e.enc = p.buf
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func sizeExtensionMap(m map[int32]Extension) (n int) {
|
func extensionsMapSize(m map[int32]Extension) (n int) {
|
||||||
for _, e := range m {
|
for _, e := range m {
|
||||||
if e.value == nil || e.desc == nil {
|
if e.value == nil || e.desc == nil {
|
||||||
// Extension is only in its encoded form.
|
// Extension is only in its encoded form.
|
||||||
|
@ -233,12 +344,8 @@ func sizeExtensionMap(m map[int32]Extension) (n int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// HasExtension returns whether the given extension is present in pb.
|
// HasExtension returns whether the given extension is present in pb.
|
||||||
func HasExtension(pb extendableProto, extension *ExtensionDesc) bool {
|
func HasExtension(pb Message, extension *ExtensionDesc) bool {
|
||||||
// TODO: Check types, field numbers, etc.?
|
if epb, doki := pb.(extensionsBytes); doki {
|
||||||
if epb, doki := pb.(extensionsMap); doki {
|
|
||||||
_, ok := epb.ExtensionMap()[extension.Field]
|
|
||||||
return ok
|
|
||||||
} else if epb, doki := pb.(extensionsBytes); doki {
|
|
||||||
ext := epb.GetExtensions()
|
ext := epb.GetExtensions()
|
||||||
buf := *ext
|
buf := *ext
|
||||||
o := 0
|
o := 0
|
||||||
|
@ -258,7 +365,19 @@ func HasExtension(pb extendableProto, extension *ExtensionDesc) bool {
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
panic("unreachable")
|
// TODO: Check types, field numbers, etc.?
|
||||||
|
epb, ok := extendable(pb)
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
extmap, mu := epb.extensionsRead()
|
||||||
|
if extmap == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
mu.Lock()
|
||||||
|
_, ok = extmap[extension.Field]
|
||||||
|
mu.Unlock()
|
||||||
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteExtension(pb extensionsBytes, theFieldNum int32, offset int) int {
|
func deleteExtension(pb extensionsBytes, theFieldNum int32, offset int) int {
|
||||||
|
@ -281,64 +400,32 @@ func deleteExtension(pb extensionsBytes, theFieldNum int32, offset int) int {
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
func clearExtension(pb extendableProto, fieldNum int32) {
|
// ClearExtension removes the given extension from pb.
|
||||||
if epb, doki := pb.(extensionsMap); doki {
|
func ClearExtension(pb Message, extension *ExtensionDesc) {
|
||||||
delete(epb.ExtensionMap(), fieldNum)
|
clearExtension(pb, extension.Field)
|
||||||
} else if epb, doki := pb.(extensionsBytes); doki {
|
}
|
||||||
|
|
||||||
|
func clearExtension(pb Message, fieldNum int32) {
|
||||||
|
if epb, doki := pb.(extensionsBytes); doki {
|
||||||
offset := 0
|
offset := 0
|
||||||
for offset != -1 {
|
for offset != -1 {
|
||||||
offset = deleteExtension(epb, fieldNum, offset)
|
offset = deleteExtension(epb, fieldNum, offset)
|
||||||
}
|
}
|
||||||
} else {
|
return
|
||||||
panic("unreachable")
|
}
|
||||||
|
epb, ok := extendable(pb)
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// ClearExtension removes the given extension from pb.
|
|
||||||
func ClearExtension(pb extendableProto, extension *ExtensionDesc) {
|
|
||||||
// TODO: Check types, field numbers, etc.?
|
// TODO: Check types, field numbers, etc.?
|
||||||
clearExtension(pb, extension.Field)
|
extmap := epb.extensionsWrite()
|
||||||
|
delete(extmap, fieldNum)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetExtension parses and returns the given extension of pb.
|
// GetExtension parses and returns the given extension of pb.
|
||||||
// If the extension is not present it returns ErrMissingExtension.
|
// If the extension is not present and has no default value it returns ErrMissingExtension.
|
||||||
func GetExtension(pb extendableProto, extension *ExtensionDesc) (interface{}, error) {
|
func GetExtension(pb Message, extension *ExtensionDesc) (interface{}, error) {
|
||||||
if err := checkExtensionTypes(pb, extension); err != nil {
|
if epb, doki := pb.(extensionsBytes); doki {
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if epb, doki := pb.(extensionsMap); doki {
|
|
||||||
emap := epb.ExtensionMap()
|
|
||||||
e, ok := emap[extension.Field]
|
|
||||||
if !ok {
|
|
||||||
// defaultExtensionValue returns the default value or
|
|
||||||
// ErrMissingExtension if there is no default.
|
|
||||||
return defaultExtensionValue(extension)
|
|
||||||
}
|
|
||||||
if e.value != nil {
|
|
||||||
// Already decoded. Check the descriptor, though.
|
|
||||||
if e.desc != extension {
|
|
||||||
// This shouldn't happen. If it does, it means that
|
|
||||||
// GetExtension was called twice with two different
|
|
||||||
// descriptors with the same field number.
|
|
||||||
return nil, errors.New("proto: descriptor conflict")
|
|
||||||
}
|
|
||||||
return e.value, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
v, err := decodeExtension(e.enc, extension)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remember the decoded version and drop the encoded version.
|
|
||||||
// That way it is safe to mutate what we return.
|
|
||||||
e.value = v
|
|
||||||
e.desc = extension
|
|
||||||
e.enc = nil
|
|
||||||
emap[extension.Field] = e
|
|
||||||
return e.value, nil
|
|
||||||
} else if epb, doki := pb.(extensionsBytes); doki {
|
|
||||||
ext := epb.GetExtensions()
|
ext := epb.GetExtensions()
|
||||||
o := 0
|
o := 0
|
||||||
for o < len(*ext) {
|
for o < len(*ext) {
|
||||||
|
@ -360,7 +447,50 @@ func GetExtension(pb extendableProto, extension *ExtensionDesc) (interface{}, er
|
||||||
}
|
}
|
||||||
return defaultExtensionValue(extension)
|
return defaultExtensionValue(extension)
|
||||||
}
|
}
|
||||||
panic("unreachable")
|
epb, ok := extendable(pb)
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.New("proto: not an extendable proto")
|
||||||
|
}
|
||||||
|
if err := checkExtensionTypes(epb, extension); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
emap, mu := epb.extensionsRead()
|
||||||
|
if emap == nil {
|
||||||
|
return defaultExtensionValue(extension)
|
||||||
|
}
|
||||||
|
mu.Lock()
|
||||||
|
defer mu.Unlock()
|
||||||
|
e, ok := emap[extension.Field]
|
||||||
|
if !ok {
|
||||||
|
// defaultExtensionValue returns the default value or
|
||||||
|
// ErrMissingExtension if there is no default.
|
||||||
|
return defaultExtensionValue(extension)
|
||||||
|
}
|
||||||
|
|
||||||
|
if e.value != nil {
|
||||||
|
// Already decoded. Check the descriptor, though.
|
||||||
|
if e.desc != extension {
|
||||||
|
// This shouldn't happen. If it does, it means that
|
||||||
|
// GetExtension was called twice with two different
|
||||||
|
// descriptors with the same field number.
|
||||||
|
return nil, errors.New("proto: descriptor conflict")
|
||||||
|
}
|
||||||
|
return e.value, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
v, err := decodeExtension(e.enc, extension)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remember the decoded version and drop the encoded version.
|
||||||
|
// That way it is safe to mutate what we return.
|
||||||
|
e.value = v
|
||||||
|
e.desc = extension
|
||||||
|
e.enc = nil
|
||||||
|
emap[extension.Field] = e
|
||||||
|
return e.value, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// defaultExtensionValue returns the default value for extension.
|
// defaultExtensionValue returns the default value for extension.
|
||||||
|
@ -434,14 +564,9 @@ func decodeExtension(b []byte, extension *ExtensionDesc) (interface{}, error) {
|
||||||
// GetExtensions returns a slice of the extensions present in pb that are also listed in es.
|
// GetExtensions returns a slice of the extensions present in pb that are also listed in es.
|
||||||
// The returned slice has the same length as es; missing extensions will appear as nil elements.
|
// The returned slice has the same length as es; missing extensions will appear as nil elements.
|
||||||
func GetExtensions(pb Message, es []*ExtensionDesc) (extensions []interface{}, err error) {
|
func GetExtensions(pb Message, es []*ExtensionDesc) (extensions []interface{}, err error) {
|
||||||
epb, ok := pb.(extendableProto)
|
|
||||||
if !ok {
|
|
||||||
err = errors.New("proto: not an extendable proto")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
extensions = make([]interface{}, len(es))
|
extensions = make([]interface{}, len(es))
|
||||||
for i, e := range es {
|
for i, e := range es {
|
||||||
extensions[i], err = GetExtension(epb, e)
|
extensions[i], err = GetExtension(pb, e)
|
||||||
if err == ErrMissingExtension {
|
if err == ErrMissingExtension {
|
||||||
err = nil
|
err = nil
|
||||||
}
|
}
|
||||||
|
@ -452,9 +577,58 @@ func GetExtensions(pb Message, es []*ExtensionDesc) (extensions []interface{}, e
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ExtensionDescs returns a new slice containing pb's extension descriptors, in undefined order.
|
||||||
|
// For non-registered extensions, ExtensionDescs returns an incomplete descriptor containing
|
||||||
|
// just the Field field, which defines the extension's field number.
|
||||||
|
func ExtensionDescs(pb Message) ([]*ExtensionDesc, error) {
|
||||||
|
epb, ok := extendable(pb)
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("proto: %T is not an extendable proto.Message", pb)
|
||||||
|
}
|
||||||
|
registeredExtensions := RegisteredExtensions(pb)
|
||||||
|
|
||||||
|
emap, mu := epb.extensionsRead()
|
||||||
|
if emap == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
mu.Lock()
|
||||||
|
defer mu.Unlock()
|
||||||
|
extensions := make([]*ExtensionDesc, 0, len(emap))
|
||||||
|
for extid, e := range emap {
|
||||||
|
desc := e.desc
|
||||||
|
if desc == nil {
|
||||||
|
desc = registeredExtensions[extid]
|
||||||
|
if desc == nil {
|
||||||
|
desc = &ExtensionDesc{Field: extid}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extensions = append(extensions, desc)
|
||||||
|
}
|
||||||
|
return extensions, nil
|
||||||
|
}
|
||||||
|
|
||||||
// SetExtension sets the specified extension of pb to the specified value.
|
// SetExtension sets the specified extension of pb to the specified value.
|
||||||
func SetExtension(pb extendableProto, extension *ExtensionDesc, value interface{}) error {
|
func SetExtension(pb Message, extension *ExtensionDesc, value interface{}) error {
|
||||||
if err := checkExtensionTypes(pb, extension); err != nil {
|
if epb, doki := pb.(extensionsBytes); doki {
|
||||||
|
ClearExtension(pb, extension)
|
||||||
|
ext := epb.GetExtensions()
|
||||||
|
et := reflect.TypeOf(extension.ExtensionType)
|
||||||
|
props := extensionProperties(extension)
|
||||||
|
p := NewBuffer(nil)
|
||||||
|
x := reflect.New(et)
|
||||||
|
x.Elem().Set(reflect.ValueOf(value))
|
||||||
|
if err := props.enc(p, props, toStructPointer(x)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*ext = append(*ext, p.buf...)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
epb, ok := extendable(pb)
|
||||||
|
if !ok {
|
||||||
|
return errors.New("proto: not an extendable proto")
|
||||||
|
}
|
||||||
|
if err := checkExtensionTypes(epb, extension); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
typ := reflect.TypeOf(extension.ExtensionType)
|
typ := reflect.TypeOf(extension.ExtensionType)
|
||||||
|
@ -469,26 +643,27 @@ func SetExtension(pb extendableProto, extension *ExtensionDesc, value interface{
|
||||||
if reflect.ValueOf(value).IsNil() {
|
if reflect.ValueOf(value).IsNil() {
|
||||||
return fmt.Errorf("proto: SetExtension called with nil value of type %T", value)
|
return fmt.Errorf("proto: SetExtension called with nil value of type %T", value)
|
||||||
}
|
}
|
||||||
return setExtension(pb, extension, value)
|
|
||||||
|
extmap := epb.extensionsWrite()
|
||||||
|
extmap[extension.Field] = Extension{desc: extension, value: value}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func setExtension(pb extendableProto, extension *ExtensionDesc, value interface{}) error {
|
// ClearAllExtensions clears all extensions from pb.
|
||||||
if epb, doki := pb.(extensionsMap); doki {
|
func ClearAllExtensions(pb Message) {
|
||||||
epb.ExtensionMap()[extension.Field] = Extension{desc: extension, value: value}
|
if epb, doki := pb.(extensionsBytes); doki {
|
||||||
} else if epb, doki := pb.(extensionsBytes); doki {
|
|
||||||
ClearExtension(pb, extension)
|
|
||||||
ext := epb.GetExtensions()
|
ext := epb.GetExtensions()
|
||||||
et := reflect.TypeOf(extension.ExtensionType)
|
*ext = []byte{}
|
||||||
props := extensionProperties(extension)
|
return
|
||||||
p := NewBuffer(nil)
|
}
|
||||||
x := reflect.New(et)
|
epb, ok := extendable(pb)
|
||||||
x.Elem().Set(reflect.ValueOf(value))
|
if !ok {
|
||||||
if err := props.enc(p, props, toStructPointer(x)); err != nil {
|
return
|
||||||
return err
|
}
|
||||||
}
|
m := epb.extensionsWrite()
|
||||||
*ext = append(*ext, p.buf...)
|
for k := range m {
|
||||||
|
delete(m, k)
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// A global registry of extensions.
|
// A global registry of extensions.
|
||||||
|
|
88
vendor/github.com/gogo/protobuf/proto/extensions_gogo.go
generated
vendored
88
vendor/github.com/gogo/protobuf/proto/extensions_gogo.go
generated
vendored
|
@ -1,5 +1,7 @@
|
||||||
// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
|
// Protocol Buffers for Go with Gadgets
|
||||||
// http://github.com/gogo/protobuf/gogoproto
|
//
|
||||||
|
// Copyright (c) 2013, The GoGo Authors. All rights reserved.
|
||||||
|
// http://github.com/gogo/protobuf
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions are
|
// modification, are permitted provided that the following conditions are
|
||||||
|
@ -33,9 +35,10 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetBoolExtension(pb extendableProto, extension *ExtensionDesc, ifnotset bool) bool {
|
func GetBoolExtension(pb Message, extension *ExtensionDesc, ifnotset bool) bool {
|
||||||
if reflect.ValueOf(pb).IsNil() {
|
if reflect.ValueOf(pb).IsNil() {
|
||||||
return ifnotset
|
return ifnotset
|
||||||
}
|
}
|
||||||
|
@ -60,8 +63,12 @@ func (this *Extension) Compare(that *Extension) int {
|
||||||
return bytes.Compare(this.enc, that.enc)
|
return bytes.Compare(this.enc, that.enc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SizeOfInternalExtension(m extendableProto) (n int) {
|
||||||
|
return SizeOfExtensionMap(m.extensionsWrite())
|
||||||
|
}
|
||||||
|
|
||||||
func SizeOfExtensionMap(m map[int32]Extension) (n int) {
|
func SizeOfExtensionMap(m map[int32]Extension) (n int) {
|
||||||
return sizeExtensionMap(m)
|
return extensionsMapSize(m)
|
||||||
}
|
}
|
||||||
|
|
||||||
type sortableMapElem struct {
|
type sortableMapElem struct {
|
||||||
|
@ -94,6 +101,10 @@ func (this sortableExtensions) String() string {
|
||||||
return "map[" + strings.Join(ss, ",") + "]"
|
return "map[" + strings.Join(ss, ",") + "]"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func StringFromInternalExtension(m extendableProto) string {
|
||||||
|
return StringFromExtensionsMap(m.extensionsWrite())
|
||||||
|
}
|
||||||
|
|
||||||
func StringFromExtensionsMap(m map[int32]Extension) string {
|
func StringFromExtensionsMap(m map[int32]Extension) string {
|
||||||
return newSortableExtensionsFromMap(m).String()
|
return newSortableExtensionsFromMap(m).String()
|
||||||
}
|
}
|
||||||
|
@ -106,8 +117,12 @@ func StringFromExtensionsBytes(ext []byte) string {
|
||||||
return StringFromExtensionsMap(m)
|
return StringFromExtensionsMap(m)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func EncodeInternalExtension(m extendableProto, data []byte) (n int, err error) {
|
||||||
|
return EncodeExtensionMap(m.extensionsWrite(), data)
|
||||||
|
}
|
||||||
|
|
||||||
func EncodeExtensionMap(m map[int32]Extension, data []byte) (n int, err error) {
|
func EncodeExtensionMap(m map[int32]Extension, data []byte) (n int, err error) {
|
||||||
if err := encodeExtensionMap(m); err != nil {
|
if err := encodeExtensionsMap(m); err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
keys := make([]int, 0, len(m))
|
keys := make([]int, 0, len(m))
|
||||||
|
@ -125,7 +140,7 @@ func GetRawExtension(m map[int32]Extension, id int32) ([]byte, error) {
|
||||||
if m[id].value == nil || m[id].desc == nil {
|
if m[id].value == nil || m[id].desc == nil {
|
||||||
return m[id].enc, nil
|
return m[id].enc, nil
|
||||||
}
|
}
|
||||||
if err := encodeExtensionMap(m); err != nil {
|
if err := encodeExtensionsMap(m); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return m[id].enc, nil
|
return m[id].enc, nil
|
||||||
|
@ -189,15 +204,42 @@ func NewExtension(e []byte) Extension {
|
||||||
return ee
|
return ee
|
||||||
}
|
}
|
||||||
|
|
||||||
func AppendExtension(e extendableProto, tag int32, buf []byte) {
|
func AppendExtension(e Message, tag int32, buf []byte) {
|
||||||
if ee, eok := e.(extensionsMap); eok {
|
if ee, eok := e.(extensionsBytes); eok {
|
||||||
ext := ee.ExtensionMap()[int32(tag)] // may be missing
|
|
||||||
ext.enc = append(ext.enc, buf...)
|
|
||||||
ee.ExtensionMap()[int32(tag)] = ext
|
|
||||||
} else if ee, eok := e.(extensionsBytes); eok {
|
|
||||||
ext := ee.GetExtensions()
|
ext := ee.GetExtensions()
|
||||||
*ext = append(*ext, buf...)
|
*ext = append(*ext, buf...)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
if ee, eok := e.(extendableProto); eok {
|
||||||
|
m := ee.extensionsWrite()
|
||||||
|
ext := m[int32(tag)] // may be missing
|
||||||
|
ext.enc = append(ext.enc, buf...)
|
||||||
|
m[int32(tag)] = ext
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func encodeExtension(e *Extension) error {
|
||||||
|
if e.value == nil || e.desc == nil {
|
||||||
|
// Extension is only in its encoded form.
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
// We don't skip extensions that have an encoded form set,
|
||||||
|
// because the extension value may have been mutated after
|
||||||
|
// the last time this function was called.
|
||||||
|
|
||||||
|
et := reflect.TypeOf(e.desc.ExtensionType)
|
||||||
|
props := extensionProperties(e.desc)
|
||||||
|
|
||||||
|
p := NewBuffer(nil)
|
||||||
|
// If e.value has type T, the encoder expects a *struct{ X T }.
|
||||||
|
// Pass a *T with a zero field and hope it all works out.
|
||||||
|
x := reflect.New(et)
|
||||||
|
x.Elem().Set(reflect.ValueOf(e.value))
|
||||||
|
if err := props.enc(p, props, toStructPointer(x)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
e.enc = p.buf
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this Extension) GoString() string {
|
func (this Extension) GoString() string {
|
||||||
|
@ -209,7 +251,7 @@ func (this Extension) GoString() string {
|
||||||
return fmt.Sprintf("proto.NewExtension(%#v)", this.enc)
|
return fmt.Sprintf("proto.NewExtension(%#v)", this.enc)
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetUnsafeExtension(pb extendableProto, fieldNum int32, value interface{}) error {
|
func SetUnsafeExtension(pb Message, fieldNum int32, value interface{}) error {
|
||||||
typ := reflect.TypeOf(pb).Elem()
|
typ := reflect.TypeOf(pb).Elem()
|
||||||
ext, ok := extensionMaps[typ]
|
ext, ok := extensionMaps[typ]
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -219,10 +261,10 @@ func SetUnsafeExtension(pb extendableProto, fieldNum int32, value interface{}) e
|
||||||
if !ok {
|
if !ok {
|
||||||
return errors.New("proto: bad extension number; not in declared ranges")
|
return errors.New("proto: bad extension number; not in declared ranges")
|
||||||
}
|
}
|
||||||
return setExtension(pb, desc, value)
|
return SetExtension(pb, desc, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetUnsafeExtension(pb extendableProto, fieldNum int32) (interface{}, error) {
|
func GetUnsafeExtension(pb Message, fieldNum int32) (interface{}, error) {
|
||||||
typ := reflect.TypeOf(pb).Elem()
|
typ := reflect.TypeOf(pb).Elem()
|
||||||
ext, ok := extensionMaps[typ]
|
ext, ok := extensionMaps[typ]
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -234,3 +276,19 @@ func GetUnsafeExtension(pb extendableProto, fieldNum int32) (interface{}, error)
|
||||||
}
|
}
|
||||||
return GetExtension(pb, desc)
|
return GetExtension(pb, desc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewUnsafeXXX_InternalExtensions(m map[int32]Extension) XXX_InternalExtensions {
|
||||||
|
x := &XXX_InternalExtensions{
|
||||||
|
p: new(struct {
|
||||||
|
mu sync.Mutex
|
||||||
|
extensionMap map[int32]Extension
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
x.p.extensionMap = m
|
||||||
|
return *x
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetUnsafeExtensionsMap(extendable Message) map[int32]Extension {
|
||||||
|
pb := extendable.(extendableProto)
|
||||||
|
return pb.extensionsWrite()
|
||||||
|
}
|
||||||
|
|
6
vendor/github.com/gogo/protobuf/proto/lib.go
generated
vendored
6
vendor/github.com/gogo/protobuf/proto/lib.go
generated
vendored
|
@ -308,7 +308,7 @@ func GetStats() Stats { return stats }
|
||||||
// temporary Buffer and are fine for most applications.
|
// temporary Buffer and are fine for most applications.
|
||||||
type Buffer struct {
|
type Buffer struct {
|
||||||
buf []byte // encode/decode byte stream
|
buf []byte // encode/decode byte stream
|
||||||
index int // write point
|
index int // read point
|
||||||
|
|
||||||
// pools of basic types to amortize allocation.
|
// pools of basic types to amortize allocation.
|
||||||
bools []bool
|
bools []bool
|
||||||
|
@ -889,6 +889,10 @@ func isProto3Zero(v reflect.Value) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ProtoPackageIsVersion2 is referenced from generated protocol buffer files
|
||||||
|
// to assert that that code is compatible with this version of the proto package.
|
||||||
|
const GoGoProtoPackageIsVersion2 = true
|
||||||
|
|
||||||
// ProtoPackageIsVersion1 is referenced from generated protocol buffer files
|
// ProtoPackageIsVersion1 is referenced from generated protocol buffer files
|
||||||
// to assert that that code is compatible with this version of the proto package.
|
// to assert that that code is compatible with this version of the proto package.
|
||||||
const GoGoProtoPackageIsVersion1 = true
|
const GoGoProtoPackageIsVersion1 = true
|
||||||
|
|
6
vendor/github.com/gogo/protobuf/proto/lib_gogo.go
generated
vendored
6
vendor/github.com/gogo/protobuf/proto/lib_gogo.go
generated
vendored
|
@ -1,5 +1,7 @@
|
||||||
// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
|
// Protocol Buffers for Go with Gadgets
|
||||||
// http://github.com/gogo/protobuf/gogoproto
|
//
|
||||||
|
// Copyright (c) 2013, The GoGo Authors. All rights reserved.
|
||||||
|
// http://github.com/gogo/protobuf
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions are
|
// modification, are permitted provided that the following conditions are
|
||||||
|
|
43
vendor/github.com/gogo/protobuf/proto/message_set.go
generated
vendored
43
vendor/github.com/gogo/protobuf/proto/message_set.go
generated
vendored
|
@ -149,9 +149,21 @@ func skipVarint(buf []byte) []byte {
|
||||||
|
|
||||||
// MarshalMessageSet encodes the extension map represented by m in the message set wire format.
|
// MarshalMessageSet encodes the extension map represented by m in the message set wire format.
|
||||||
// It is called by generated Marshal methods on protocol buffer messages with the message_set_wire_format option.
|
// It is called by generated Marshal methods on protocol buffer messages with the message_set_wire_format option.
|
||||||
func MarshalMessageSet(m map[int32]Extension) ([]byte, error) {
|
func MarshalMessageSet(exts interface{}) ([]byte, error) {
|
||||||
if err := encodeExtensionMap(m); err != nil {
|
var m map[int32]Extension
|
||||||
return nil, err
|
switch exts := exts.(type) {
|
||||||
|
case *XXX_InternalExtensions:
|
||||||
|
if err := encodeExtensions(exts); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
m, _ = exts.extensionsRead()
|
||||||
|
case map[int32]Extension:
|
||||||
|
if err := encodeExtensionsMap(exts); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
m = exts
|
||||||
|
default:
|
||||||
|
return nil, errors.New("proto: not an extension map")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort extension IDs to provide a deterministic encoding.
|
// Sort extension IDs to provide a deterministic encoding.
|
||||||
|
@ -178,7 +190,17 @@ func MarshalMessageSet(m map[int32]Extension) ([]byte, error) {
|
||||||
|
|
||||||
// UnmarshalMessageSet decodes the extension map encoded in buf in the message set wire format.
|
// UnmarshalMessageSet decodes the extension map encoded in buf in the message set wire format.
|
||||||
// It is called by generated Unmarshal methods on protocol buffer messages with the message_set_wire_format option.
|
// It is called by generated Unmarshal methods on protocol buffer messages with the message_set_wire_format option.
|
||||||
func UnmarshalMessageSet(buf []byte, m map[int32]Extension) error {
|
func UnmarshalMessageSet(buf []byte, exts interface{}) error {
|
||||||
|
var m map[int32]Extension
|
||||||
|
switch exts := exts.(type) {
|
||||||
|
case *XXX_InternalExtensions:
|
||||||
|
m = exts.extensionsWrite()
|
||||||
|
case map[int32]Extension:
|
||||||
|
m = exts
|
||||||
|
default:
|
||||||
|
return errors.New("proto: not an extension map")
|
||||||
|
}
|
||||||
|
|
||||||
ms := new(messageSet)
|
ms := new(messageSet)
|
||||||
if err := Unmarshal(buf, ms); err != nil {
|
if err := Unmarshal(buf, ms); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -209,7 +231,16 @@ func UnmarshalMessageSet(buf []byte, m map[int32]Extension) error {
|
||||||
|
|
||||||
// MarshalMessageSetJSON encodes the extension map represented by m in JSON format.
|
// MarshalMessageSetJSON encodes the extension map represented by m in JSON format.
|
||||||
// It is called by generated MarshalJSON methods on protocol buffer messages with the message_set_wire_format option.
|
// It is called by generated MarshalJSON methods on protocol buffer messages with the message_set_wire_format option.
|
||||||
func MarshalMessageSetJSON(m map[int32]Extension) ([]byte, error) {
|
func MarshalMessageSetJSON(exts interface{}) ([]byte, error) {
|
||||||
|
var m map[int32]Extension
|
||||||
|
switch exts := exts.(type) {
|
||||||
|
case *XXX_InternalExtensions:
|
||||||
|
m, _ = exts.extensionsRead()
|
||||||
|
case map[int32]Extension:
|
||||||
|
m = exts
|
||||||
|
default:
|
||||||
|
return nil, errors.New("proto: not an extension map")
|
||||||
|
}
|
||||||
var b bytes.Buffer
|
var b bytes.Buffer
|
||||||
b.WriteByte('{')
|
b.WriteByte('{')
|
||||||
|
|
||||||
|
@ -252,7 +283,7 @@ func MarshalMessageSetJSON(m map[int32]Extension) ([]byte, error) {
|
||||||
|
|
||||||
// UnmarshalMessageSetJSON decodes the extension map encoded in buf in JSON format.
|
// UnmarshalMessageSetJSON decodes the extension map encoded in buf in JSON format.
|
||||||
// It is called by generated UnmarshalJSON methods on protocol buffer messages with the message_set_wire_format option.
|
// It is called by generated UnmarshalJSON methods on protocol buffer messages with the message_set_wire_format option.
|
||||||
func UnmarshalMessageSetJSON(buf []byte, m map[int32]Extension) error {
|
func UnmarshalMessageSetJSON(buf []byte, exts interface{}) error {
|
||||||
// Common-case fast path.
|
// Common-case fast path.
|
||||||
if len(buf) == 0 || bytes.Equal(buf, []byte("{}")) {
|
if len(buf) == 0 || bytes.Equal(buf, []byte("{}")) {
|
||||||
return nil
|
return nil
|
||||||
|
|
484
vendor/github.com/gogo/protobuf/proto/pointer_reflect.go
generated
vendored
Normal file
484
vendor/github.com/gogo/protobuf/proto/pointer_reflect.go
generated
vendored
Normal file
|
@ -0,0 +1,484 @@
|
||||||
|
// Go support for Protocol Buffers - Google's data interchange format
|
||||||
|
//
|
||||||
|
// Copyright 2012 The Go Authors. All rights reserved.
|
||||||
|
// https://github.com/golang/protobuf
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// +build appengine js
|
||||||
|
|
||||||
|
// This file contains an implementation of proto field accesses using package reflect.
|
||||||
|
// It is slower than the code in pointer_unsafe.go but it avoids package unsafe and can
|
||||||
|
// be used on App Engine.
|
||||||
|
|
||||||
|
package proto
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math"
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A structPointer is a pointer to a struct.
|
||||||
|
type structPointer struct {
|
||||||
|
v reflect.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
// toStructPointer returns a structPointer equivalent to the given reflect value.
|
||||||
|
// The reflect value must itself be a pointer to a struct.
|
||||||
|
func toStructPointer(v reflect.Value) structPointer {
|
||||||
|
return structPointer{v}
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsNil reports whether p is nil.
|
||||||
|
func structPointer_IsNil(p structPointer) bool {
|
||||||
|
return p.v.IsNil()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Interface returns the struct pointer as an interface value.
|
||||||
|
func structPointer_Interface(p structPointer, _ reflect.Type) interface{} {
|
||||||
|
return p.v.Interface()
|
||||||
|
}
|
||||||
|
|
||||||
|
// A field identifies a field in a struct, accessible from a structPointer.
|
||||||
|
// In this implementation, a field is identified by the sequence of field indices
|
||||||
|
// passed to reflect's FieldByIndex.
|
||||||
|
type field []int
|
||||||
|
|
||||||
|
// toField returns a field equivalent to the given reflect field.
|
||||||
|
func toField(f *reflect.StructField) field {
|
||||||
|
return f.Index
|
||||||
|
}
|
||||||
|
|
||||||
|
// invalidField is an invalid field identifier.
|
||||||
|
var invalidField = field(nil)
|
||||||
|
|
||||||
|
// IsValid reports whether the field identifier is valid.
|
||||||
|
func (f field) IsValid() bool { return f != nil }
|
||||||
|
|
||||||
|
// field returns the given field in the struct as a reflect value.
|
||||||
|
func structPointer_field(p structPointer, f field) reflect.Value {
|
||||||
|
// Special case: an extension map entry with a value of type T
|
||||||
|
// passes a *T to the struct-handling code with a zero field,
|
||||||
|
// expecting that it will be treated as equivalent to *struct{ X T },
|
||||||
|
// which has the same memory layout. We have to handle that case
|
||||||
|
// specially, because reflect will panic if we call FieldByIndex on a
|
||||||
|
// non-struct.
|
||||||
|
if f == nil {
|
||||||
|
return p.v.Elem()
|
||||||
|
}
|
||||||
|
|
||||||
|
return p.v.Elem().FieldByIndex(f)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ifield returns the given field in the struct as an interface value.
|
||||||
|
func structPointer_ifield(p structPointer, f field) interface{} {
|
||||||
|
return structPointer_field(p, f).Addr().Interface()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bytes returns the address of a []byte field in the struct.
|
||||||
|
func structPointer_Bytes(p structPointer, f field) *[]byte {
|
||||||
|
return structPointer_ifield(p, f).(*[]byte)
|
||||||
|
}
|
||||||
|
|
||||||
|
// BytesSlice returns the address of a [][]byte field in the struct.
|
||||||
|
func structPointer_BytesSlice(p structPointer, f field) *[][]byte {
|
||||||
|
return structPointer_ifield(p, f).(*[][]byte)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bool returns the address of a *bool field in the struct.
|
||||||
|
func structPointer_Bool(p structPointer, f field) **bool {
|
||||||
|
return structPointer_ifield(p, f).(**bool)
|
||||||
|
}
|
||||||
|
|
||||||
|
// BoolVal returns the address of a bool field in the struct.
|
||||||
|
func structPointer_BoolVal(p structPointer, f field) *bool {
|
||||||
|
return structPointer_ifield(p, f).(*bool)
|
||||||
|
}
|
||||||
|
|
||||||
|
// BoolSlice returns the address of a []bool field in the struct.
|
||||||
|
func structPointer_BoolSlice(p structPointer, f field) *[]bool {
|
||||||
|
return structPointer_ifield(p, f).(*[]bool)
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the address of a *string field in the struct.
|
||||||
|
func structPointer_String(p structPointer, f field) **string {
|
||||||
|
return structPointer_ifield(p, f).(**string)
|
||||||
|
}
|
||||||
|
|
||||||
|
// StringVal returns the address of a string field in the struct.
|
||||||
|
func structPointer_StringVal(p structPointer, f field) *string {
|
||||||
|
return structPointer_ifield(p, f).(*string)
|
||||||
|
}
|
||||||
|
|
||||||
|
// StringSlice returns the address of a []string field in the struct.
|
||||||
|
func structPointer_StringSlice(p structPointer, f field) *[]string {
|
||||||
|
return structPointer_ifield(p, f).(*[]string)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extensions returns the address of an extension map field in the struct.
|
||||||
|
func structPointer_Extensions(p structPointer, f field) *XXX_InternalExtensions {
|
||||||
|
return structPointer_ifield(p, f).(*XXX_InternalExtensions)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExtMap returns the address of an extension map field in the struct.
|
||||||
|
func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension {
|
||||||
|
return structPointer_ifield(p, f).(*map[int32]Extension)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewAt returns the reflect.Value for a pointer to a field in the struct.
|
||||||
|
func structPointer_NewAt(p structPointer, f field, typ reflect.Type) reflect.Value {
|
||||||
|
return structPointer_field(p, f).Addr()
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetStructPointer writes a *struct field in the struct.
|
||||||
|
func structPointer_SetStructPointer(p structPointer, f field, q structPointer) {
|
||||||
|
structPointer_field(p, f).Set(q.v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetStructPointer reads a *struct field in the struct.
|
||||||
|
func structPointer_GetStructPointer(p structPointer, f field) structPointer {
|
||||||
|
return structPointer{structPointer_field(p, f)}
|
||||||
|
}
|
||||||
|
|
||||||
|
// StructPointerSlice the address of a []*struct field in the struct.
|
||||||
|
func structPointer_StructPointerSlice(p structPointer, f field) structPointerSlice {
|
||||||
|
return structPointerSlice{structPointer_field(p, f)}
|
||||||
|
}
|
||||||
|
|
||||||
|
// A structPointerSlice represents the address of a slice of pointers to structs
|
||||||
|
// (themselves messages or groups). That is, v.Type() is *[]*struct{...}.
|
||||||
|
type structPointerSlice struct {
|
||||||
|
v reflect.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p structPointerSlice) Len() int { return p.v.Len() }
|
||||||
|
func (p structPointerSlice) Index(i int) structPointer { return structPointer{p.v.Index(i)} }
|
||||||
|
func (p structPointerSlice) Append(q structPointer) {
|
||||||
|
p.v.Set(reflect.Append(p.v, q.v))
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
int32Type = reflect.TypeOf(int32(0))
|
||||||
|
uint32Type = reflect.TypeOf(uint32(0))
|
||||||
|
float32Type = reflect.TypeOf(float32(0))
|
||||||
|
int64Type = reflect.TypeOf(int64(0))
|
||||||
|
uint64Type = reflect.TypeOf(uint64(0))
|
||||||
|
float64Type = reflect.TypeOf(float64(0))
|
||||||
|
)
|
||||||
|
|
||||||
|
// A word32 represents a field of type *int32, *uint32, *float32, or *enum.
|
||||||
|
// That is, v.Type() is *int32, *uint32, *float32, or *enum and v is assignable.
|
||||||
|
type word32 struct {
|
||||||
|
v reflect.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsNil reports whether p is nil.
|
||||||
|
func word32_IsNil(p word32) bool {
|
||||||
|
return p.v.IsNil()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set sets p to point at a newly allocated word with bits set to x.
|
||||||
|
func word32_Set(p word32, o *Buffer, x uint32) {
|
||||||
|
t := p.v.Type().Elem()
|
||||||
|
switch t {
|
||||||
|
case int32Type:
|
||||||
|
if len(o.int32s) == 0 {
|
||||||
|
o.int32s = make([]int32, uint32PoolSize)
|
||||||
|
}
|
||||||
|
o.int32s[0] = int32(x)
|
||||||
|
p.v.Set(reflect.ValueOf(&o.int32s[0]))
|
||||||
|
o.int32s = o.int32s[1:]
|
||||||
|
return
|
||||||
|
case uint32Type:
|
||||||
|
if len(o.uint32s) == 0 {
|
||||||
|
o.uint32s = make([]uint32, uint32PoolSize)
|
||||||
|
}
|
||||||
|
o.uint32s[0] = x
|
||||||
|
p.v.Set(reflect.ValueOf(&o.uint32s[0]))
|
||||||
|
o.uint32s = o.uint32s[1:]
|
||||||
|
return
|
||||||
|
case float32Type:
|
||||||
|
if len(o.float32s) == 0 {
|
||||||
|
o.float32s = make([]float32, uint32PoolSize)
|
||||||
|
}
|
||||||
|
o.float32s[0] = math.Float32frombits(x)
|
||||||
|
p.v.Set(reflect.ValueOf(&o.float32s[0]))
|
||||||
|
o.float32s = o.float32s[1:]
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// must be enum
|
||||||
|
p.v.Set(reflect.New(t))
|
||||||
|
p.v.Elem().SetInt(int64(int32(x)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get gets the bits pointed at by p, as a uint32.
|
||||||
|
func word32_Get(p word32) uint32 {
|
||||||
|
elem := p.v.Elem()
|
||||||
|
switch elem.Kind() {
|
||||||
|
case reflect.Int32:
|
||||||
|
return uint32(elem.Int())
|
||||||
|
case reflect.Uint32:
|
||||||
|
return uint32(elem.Uint())
|
||||||
|
case reflect.Float32:
|
||||||
|
return math.Float32bits(float32(elem.Float()))
|
||||||
|
}
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Word32 returns a reference to a *int32, *uint32, *float32, or *enum field in the struct.
|
||||||
|
func structPointer_Word32(p structPointer, f field) word32 {
|
||||||
|
return word32{structPointer_field(p, f)}
|
||||||
|
}
|
||||||
|
|
||||||
|
// A word32Val represents a field of type int32, uint32, float32, or enum.
|
||||||
|
// That is, v.Type() is int32, uint32, float32, or enum and v is assignable.
|
||||||
|
type word32Val struct {
|
||||||
|
v reflect.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set sets *p to x.
|
||||||
|
func word32Val_Set(p word32Val, x uint32) {
|
||||||
|
switch p.v.Type() {
|
||||||
|
case int32Type:
|
||||||
|
p.v.SetInt(int64(x))
|
||||||
|
return
|
||||||
|
case uint32Type:
|
||||||
|
p.v.SetUint(uint64(x))
|
||||||
|
return
|
||||||
|
case float32Type:
|
||||||
|
p.v.SetFloat(float64(math.Float32frombits(x)))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// must be enum
|
||||||
|
p.v.SetInt(int64(int32(x)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get gets the bits pointed at by p, as a uint32.
|
||||||
|
func word32Val_Get(p word32Val) uint32 {
|
||||||
|
elem := p.v
|
||||||
|
switch elem.Kind() {
|
||||||
|
case reflect.Int32:
|
||||||
|
return uint32(elem.Int())
|
||||||
|
case reflect.Uint32:
|
||||||
|
return uint32(elem.Uint())
|
||||||
|
case reflect.Float32:
|
||||||
|
return math.Float32bits(float32(elem.Float()))
|
||||||
|
}
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Word32Val returns a reference to a int32, uint32, float32, or enum field in the struct.
|
||||||
|
func structPointer_Word32Val(p structPointer, f field) word32Val {
|
||||||
|
return word32Val{structPointer_field(p, f)}
|
||||||
|
}
|
||||||
|
|
||||||
|
// A word32Slice is a slice of 32-bit values.
|
||||||
|
// That is, v.Type() is []int32, []uint32, []float32, or []enum.
|
||||||
|
type word32Slice struct {
|
||||||
|
v reflect.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p word32Slice) Append(x uint32) {
|
||||||
|
n, m := p.v.Len(), p.v.Cap()
|
||||||
|
if n < m {
|
||||||
|
p.v.SetLen(n + 1)
|
||||||
|
} else {
|
||||||
|
t := p.v.Type().Elem()
|
||||||
|
p.v.Set(reflect.Append(p.v, reflect.Zero(t)))
|
||||||
|
}
|
||||||
|
elem := p.v.Index(n)
|
||||||
|
switch elem.Kind() {
|
||||||
|
case reflect.Int32:
|
||||||
|
elem.SetInt(int64(int32(x)))
|
||||||
|
case reflect.Uint32:
|
||||||
|
elem.SetUint(uint64(x))
|
||||||
|
case reflect.Float32:
|
||||||
|
elem.SetFloat(float64(math.Float32frombits(x)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p word32Slice) Len() int {
|
||||||
|
return p.v.Len()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p word32Slice) Index(i int) uint32 {
|
||||||
|
elem := p.v.Index(i)
|
||||||
|
switch elem.Kind() {
|
||||||
|
case reflect.Int32:
|
||||||
|
return uint32(elem.Int())
|
||||||
|
case reflect.Uint32:
|
||||||
|
return uint32(elem.Uint())
|
||||||
|
case reflect.Float32:
|
||||||
|
return math.Float32bits(float32(elem.Float()))
|
||||||
|
}
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Word32Slice returns a reference to a []int32, []uint32, []float32, or []enum field in the struct.
|
||||||
|
func structPointer_Word32Slice(p structPointer, f field) word32Slice {
|
||||||
|
return word32Slice{structPointer_field(p, f)}
|
||||||
|
}
|
||||||
|
|
||||||
|
// word64 is like word32 but for 64-bit values.
|
||||||
|
type word64 struct {
|
||||||
|
v reflect.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
func word64_Set(p word64, o *Buffer, x uint64) {
|
||||||
|
t := p.v.Type().Elem()
|
||||||
|
switch t {
|
||||||
|
case int64Type:
|
||||||
|
if len(o.int64s) == 0 {
|
||||||
|
o.int64s = make([]int64, uint64PoolSize)
|
||||||
|
}
|
||||||
|
o.int64s[0] = int64(x)
|
||||||
|
p.v.Set(reflect.ValueOf(&o.int64s[0]))
|
||||||
|
o.int64s = o.int64s[1:]
|
||||||
|
return
|
||||||
|
case uint64Type:
|
||||||
|
if len(o.uint64s) == 0 {
|
||||||
|
o.uint64s = make([]uint64, uint64PoolSize)
|
||||||
|
}
|
||||||
|
o.uint64s[0] = x
|
||||||
|
p.v.Set(reflect.ValueOf(&o.uint64s[0]))
|
||||||
|
o.uint64s = o.uint64s[1:]
|
||||||
|
return
|
||||||
|
case float64Type:
|
||||||
|
if len(o.float64s) == 0 {
|
||||||
|
o.float64s = make([]float64, uint64PoolSize)
|
||||||
|
}
|
||||||
|
o.float64s[0] = math.Float64frombits(x)
|
||||||
|
p.v.Set(reflect.ValueOf(&o.float64s[0]))
|
||||||
|
o.float64s = o.float64s[1:]
|
||||||
|
return
|
||||||
|
}
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
||||||
|
|
||||||
|
func word64_IsNil(p word64) bool {
|
||||||
|
return p.v.IsNil()
|
||||||
|
}
|
||||||
|
|
||||||
|
func word64_Get(p word64) uint64 {
|
||||||
|
elem := p.v.Elem()
|
||||||
|
switch elem.Kind() {
|
||||||
|
case reflect.Int64:
|
||||||
|
return uint64(elem.Int())
|
||||||
|
case reflect.Uint64:
|
||||||
|
return elem.Uint()
|
||||||
|
case reflect.Float64:
|
||||||
|
return math.Float64bits(elem.Float())
|
||||||
|
}
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
||||||
|
|
||||||
|
func structPointer_Word64(p structPointer, f field) word64 {
|
||||||
|
return word64{structPointer_field(p, f)}
|
||||||
|
}
|
||||||
|
|
||||||
|
// word64Val is like word32Val but for 64-bit values.
|
||||||
|
type word64Val struct {
|
||||||
|
v reflect.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
func word64Val_Set(p word64Val, o *Buffer, x uint64) {
|
||||||
|
switch p.v.Type() {
|
||||||
|
case int64Type:
|
||||||
|
p.v.SetInt(int64(x))
|
||||||
|
return
|
||||||
|
case uint64Type:
|
||||||
|
p.v.SetUint(x)
|
||||||
|
return
|
||||||
|
case float64Type:
|
||||||
|
p.v.SetFloat(math.Float64frombits(x))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
||||||
|
|
||||||
|
func word64Val_Get(p word64Val) uint64 {
|
||||||
|
elem := p.v
|
||||||
|
switch elem.Kind() {
|
||||||
|
case reflect.Int64:
|
||||||
|
return uint64(elem.Int())
|
||||||
|
case reflect.Uint64:
|
||||||
|
return elem.Uint()
|
||||||
|
case reflect.Float64:
|
||||||
|
return math.Float64bits(elem.Float())
|
||||||
|
}
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
||||||
|
|
||||||
|
func structPointer_Word64Val(p structPointer, f field) word64Val {
|
||||||
|
return word64Val{structPointer_field(p, f)}
|
||||||
|
}
|
||||||
|
|
||||||
|
type word64Slice struct {
|
||||||
|
v reflect.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p word64Slice) Append(x uint64) {
|
||||||
|
n, m := p.v.Len(), p.v.Cap()
|
||||||
|
if n < m {
|
||||||
|
p.v.SetLen(n + 1)
|
||||||
|
} else {
|
||||||
|
t := p.v.Type().Elem()
|
||||||
|
p.v.Set(reflect.Append(p.v, reflect.Zero(t)))
|
||||||
|
}
|
||||||
|
elem := p.v.Index(n)
|
||||||
|
switch elem.Kind() {
|
||||||
|
case reflect.Int64:
|
||||||
|
elem.SetInt(int64(int64(x)))
|
||||||
|
case reflect.Uint64:
|
||||||
|
elem.SetUint(uint64(x))
|
||||||
|
case reflect.Float64:
|
||||||
|
elem.SetFloat(float64(math.Float64frombits(x)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p word64Slice) Len() int {
|
||||||
|
return p.v.Len()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p word64Slice) Index(i int) uint64 {
|
||||||
|
elem := p.v.Index(i)
|
||||||
|
switch elem.Kind() {
|
||||||
|
case reflect.Int64:
|
||||||
|
return uint64(elem.Int())
|
||||||
|
case reflect.Uint64:
|
||||||
|
return uint64(elem.Uint())
|
||||||
|
case reflect.Float64:
|
||||||
|
return math.Float64bits(float64(elem.Float()))
|
||||||
|
}
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
||||||
|
|
||||||
|
func structPointer_Word64Slice(p structPointer, f field) word64Slice {
|
||||||
|
return word64Slice{structPointer_field(p, f)}
|
||||||
|
}
|
85
vendor/github.com/gogo/protobuf/proto/pointer_reflect_gogo.go
generated
vendored
Normal file
85
vendor/github.com/gogo/protobuf/proto/pointer_reflect_gogo.go
generated
vendored
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
// Protocol Buffers for Go with Gadgets
|
||||||
|
//
|
||||||
|
// Copyright (c) 2016, The GoGo Authors. All rights reserved.
|
||||||
|
// http://github.com/gogo/protobuf
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// +build appengine js
|
||||||
|
|
||||||
|
package proto
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
func structPointer_FieldPointer(p structPointer, f field) structPointer {
|
||||||
|
panic("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func appendStructPointer(base structPointer, f field, typ reflect.Type) structPointer {
|
||||||
|
panic("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func structPointer_InterfaceAt(p structPointer, f field, t reflect.Type) interface{} {
|
||||||
|
panic("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func structPointer_InterfaceRef(p structPointer, f field, t reflect.Type) interface{} {
|
||||||
|
panic("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func structPointer_GetRefStructPointer(p structPointer, f field) structPointer {
|
||||||
|
panic("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func structPointer_Add(p structPointer, size field) structPointer {
|
||||||
|
panic("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func structPointer_Len(p structPointer, f field) int {
|
||||||
|
panic("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func structPointer_GetSliceHeader(p structPointer, f field) *reflect.SliceHeader {
|
||||||
|
panic("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func structPointer_Copy(oldptr structPointer, newptr structPointer, size int) {
|
||||||
|
panic("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func structPointer_StructRefSlice(p structPointer, f field, size uintptr) *structRefSlice {
|
||||||
|
panic("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
type structRefSlice struct{}
|
||||||
|
|
||||||
|
func (v *structRefSlice) Len() int {
|
||||||
|
panic("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *structRefSlice) Index(i int) structPointer {
|
||||||
|
panic("not implemented")
|
||||||
|
}
|
6
vendor/github.com/gogo/protobuf/proto/pointer_unsafe.go
generated
vendored
6
vendor/github.com/gogo/protobuf/proto/pointer_unsafe.go
generated
vendored
|
@ -29,7 +29,7 @@
|
||||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
// +build !appengine
|
// +build !appengine,!js
|
||||||
|
|
||||||
// This file contains the implementation of the proto field accesses using package unsafe.
|
// This file contains the implementation of the proto field accesses using package unsafe.
|
||||||
|
|
||||||
|
@ -126,6 +126,10 @@ func structPointer_StringSlice(p structPointer, f field) *[]string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExtMap returns the address of an extension map field in the struct.
|
// ExtMap returns the address of an extension map field in the struct.
|
||||||
|
func structPointer_Extensions(p structPointer, f field) *XXX_InternalExtensions {
|
||||||
|
return (*XXX_InternalExtensions)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||||
|
}
|
||||||
|
|
||||||
func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension {
|
func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension {
|
||||||
return (*map[int32]Extension)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
return (*map[int32]Extension)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||||
}
|
}
|
||||||
|
|
44
vendor/github.com/gogo/protobuf/proto/pointer_unsafe_gogo.go
generated
vendored
44
vendor/github.com/gogo/protobuf/proto/pointer_unsafe_gogo.go
generated
vendored
|
@ -1,5 +1,7 @@
|
||||||
// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
|
// Protocol Buffers for Go with Gadgets
|
||||||
// http://github.com/gogo/protobuf/gogoproto
|
//
|
||||||
|
// Copyright (c) 2013, The GoGo Authors. All rights reserved.
|
||||||
|
// http://github.com/gogo/protobuf
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions are
|
// modification, are permitted provided that the following conditions are
|
||||||
|
@ -24,7 +26,7 @@
|
||||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
// +build !appengine
|
// +build !appengine,!js
|
||||||
|
|
||||||
// This file contains the implementation of the proto field accesses using package unsafe.
|
// This file contains the implementation of the proto field accesses using package unsafe.
|
||||||
|
|
||||||
|
@ -70,16 +72,13 @@ func structPointer_Copy(oldptr structPointer, newptr structPointer, size int) {
|
||||||
|
|
||||||
func appendStructPointer(base structPointer, f field, typ reflect.Type) structPointer {
|
func appendStructPointer(base structPointer, f field, typ reflect.Type) structPointer {
|
||||||
size := typ.Elem().Size()
|
size := typ.Elem().Size()
|
||||||
oldHeader := structPointer_GetSliceHeader(base, f)
|
|
||||||
newLen := oldHeader.Len + 1
|
|
||||||
slice := reflect.MakeSlice(typ, newLen, newLen)
|
|
||||||
bas := toStructPointer(slice)
|
|
||||||
for i := 0; i < oldHeader.Len; i++ {
|
|
||||||
newElemptr := uintptr(bas) + uintptr(i)*size
|
|
||||||
oldElemptr := oldHeader.Data + uintptr(i)*size
|
|
||||||
copyUintPtr(oldElemptr, newElemptr, int(size))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
oldHeader := structPointer_GetSliceHeader(base, f)
|
||||||
|
oldSlice := reflect.NewAt(typ, unsafe.Pointer(oldHeader)).Elem()
|
||||||
|
newLen := oldHeader.Len + 1
|
||||||
|
newSlice := reflect.MakeSlice(typ, newLen, newLen)
|
||||||
|
reflect.Copy(newSlice, oldSlice)
|
||||||
|
bas := toStructPointer(newSlice)
|
||||||
oldHeader.Data = uintptr(bas)
|
oldHeader.Data = uintptr(bas)
|
||||||
oldHeader.Len = newLen
|
oldHeader.Len = newLen
|
||||||
oldHeader.Cap = newLen
|
oldHeader.Cap = newLen
|
||||||
|
@ -106,3 +105,24 @@ func structPointer_Add(p structPointer, size field) structPointer {
|
||||||
func structPointer_Len(p structPointer, f field) int {
|
func structPointer_Len(p structPointer, f field) int {
|
||||||
return len(*(*[]interface{})(unsafe.Pointer(structPointer_GetRefStructPointer(p, f))))
|
return len(*(*[]interface{})(unsafe.Pointer(structPointer_GetRefStructPointer(p, f))))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func structPointer_StructRefSlice(p structPointer, f field, size uintptr) *structRefSlice {
|
||||||
|
return &structRefSlice{p: p, f: f, size: size}
|
||||||
|
}
|
||||||
|
|
||||||
|
// A structRefSlice represents a slice of structs (themselves submessages or groups).
|
||||||
|
type structRefSlice struct {
|
||||||
|
p structPointer
|
||||||
|
f field
|
||||||
|
size uintptr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *structRefSlice) Len() int {
|
||||||
|
return structPointer_Len(v.p, v.f)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *structRefSlice) Index(i int) structPointer {
|
||||||
|
ss := structPointer_GetStructPointer(v.p, v.f)
|
||||||
|
ss1 := structPointer_GetRefStructPointer(ss, 0)
|
||||||
|
return structPointer_Add(ss1, field(uintptr(i)*v.size))
|
||||||
|
}
|
||||||
|
|
93
vendor/github.com/gogo/protobuf/proto/properties.go
generated
vendored
93
vendor/github.com/gogo/protobuf/proto/properties.go
generated
vendored
|
@ -1,7 +1,7 @@
|
||||||
// Extensions for Protocol Buffers to create more go like structures.
|
// Protocol Buffers for Go with Gadgets
|
||||||
//
|
//
|
||||||
// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
|
// Copyright (c) 2013, The GoGo Authors. All rights reserved.
|
||||||
// http://github.com/gogo/protobuf/gogoproto
|
// http://github.com/gogo/protobuf
|
||||||
//
|
//
|
||||||
// Go support for Protocol Buffers - Google's data interchange format
|
// Go support for Protocol Buffers - Google's data interchange format
|
||||||
//
|
//
|
||||||
|
@ -190,10 +190,11 @@ type Properties struct {
|
||||||
proto3 bool // whether this is known to be a proto3 field; set for []byte only
|
proto3 bool // whether this is known to be a proto3 field; set for []byte only
|
||||||
oneof bool // whether this is a oneof field
|
oneof bool // whether this is a oneof field
|
||||||
|
|
||||||
Default string // default value
|
Default string // default value
|
||||||
HasDefault bool // whether an explicit default was provided
|
HasDefault bool // whether an explicit default was provided
|
||||||
CustomType string
|
CustomType string
|
||||||
def_uint64 uint64
|
StdTime bool
|
||||||
|
StdDuration bool
|
||||||
|
|
||||||
enc encoder
|
enc encoder
|
||||||
valEnc valueEncoder // set for bool and numeric types only
|
valEnc valueEncoder // set for bool and numeric types only
|
||||||
|
@ -340,6 +341,10 @@ func (p *Properties) Parse(s string) {
|
||||||
p.OrigName = strings.Split(f, "=")[1]
|
p.OrigName = strings.Split(f, "=")[1]
|
||||||
case strings.HasPrefix(f, "customtype="):
|
case strings.HasPrefix(f, "customtype="):
|
||||||
p.CustomType = strings.Split(f, "=")[1]
|
p.CustomType = strings.Split(f, "=")[1]
|
||||||
|
case f == "stdtime":
|
||||||
|
p.StdTime = true
|
||||||
|
case f == "stdduration":
|
||||||
|
p.StdDuration = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -355,11 +360,22 @@ func (p *Properties) setEncAndDec(typ reflect.Type, f *reflect.StructField, lock
|
||||||
p.enc = nil
|
p.enc = nil
|
||||||
p.dec = nil
|
p.dec = nil
|
||||||
p.size = nil
|
p.size = nil
|
||||||
if len(p.CustomType) > 0 {
|
isMap := typ.Kind() == reflect.Map
|
||||||
|
if len(p.CustomType) > 0 && !isMap {
|
||||||
p.setCustomEncAndDec(typ)
|
p.setCustomEncAndDec(typ)
|
||||||
p.setTag(lockGetProp)
|
p.setTag(lockGetProp)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if p.StdTime && !isMap {
|
||||||
|
p.setTimeEncAndDec(typ)
|
||||||
|
p.setTag(lockGetProp)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if p.StdDuration && !isMap {
|
||||||
|
p.setDurationEncAndDec(typ)
|
||||||
|
p.setTag(lockGetProp)
|
||||||
|
return
|
||||||
|
}
|
||||||
switch t1 := typ; t1.Kind() {
|
switch t1 := typ; t1.Kind() {
|
||||||
default:
|
default:
|
||||||
fmt.Fprintf(os.Stderr, "proto: no coders for %v\n", t1)
|
fmt.Fprintf(os.Stderr, "proto: no coders for %v\n", t1)
|
||||||
|
@ -542,17 +558,13 @@ func (p *Properties) setEncAndDec(typ reflect.Type, f *reflect.StructField, lock
|
||||||
p.dec = (*Buffer).dec_slice_int64
|
p.dec = (*Buffer).dec_slice_int64
|
||||||
p.packedDec = (*Buffer).dec_slice_packed_int64
|
p.packedDec = (*Buffer).dec_slice_packed_int64
|
||||||
case reflect.Uint8:
|
case reflect.Uint8:
|
||||||
p.enc = (*Buffer).enc_slice_byte
|
|
||||||
p.dec = (*Buffer).dec_slice_byte
|
p.dec = (*Buffer).dec_slice_byte
|
||||||
p.size = size_slice_byte
|
if p.proto3 {
|
||||||
// This is a []byte, which is either a bytes field,
|
|
||||||
// or the value of a map field. In the latter case,
|
|
||||||
// we always encode an empty []byte, so we should not
|
|
||||||
// use the proto3 enc/size funcs.
|
|
||||||
// f == nil iff this is the key/value of a map field.
|
|
||||||
if p.proto3 && f != nil {
|
|
||||||
p.enc = (*Buffer).enc_proto3_slice_byte
|
p.enc = (*Buffer).enc_proto3_slice_byte
|
||||||
p.size = size_proto3_slice_byte
|
p.size = size_proto3_slice_byte
|
||||||
|
} else {
|
||||||
|
p.enc = (*Buffer).enc_slice_byte
|
||||||
|
p.size = size_slice_byte
|
||||||
}
|
}
|
||||||
case reflect.Float32, reflect.Float64:
|
case reflect.Float32, reflect.Float64:
|
||||||
switch t2.Bits() {
|
switch t2.Bits() {
|
||||||
|
@ -634,6 +646,10 @@ func (p *Properties) setEncAndDec(typ reflect.Type, f *reflect.StructField, lock
|
||||||
// so we need encoders for the pointer to this type.
|
// so we need encoders for the pointer to this type.
|
||||||
vtype = reflect.PtrTo(vtype)
|
vtype = reflect.PtrTo(vtype)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p.mvalprop.CustomType = p.CustomType
|
||||||
|
p.mvalprop.StdDuration = p.StdDuration
|
||||||
|
p.mvalprop.StdTime = p.StdTime
|
||||||
p.mvalprop.init(vtype, "Value", f.Tag.Get("protobuf_val"), nil, lockGetProp)
|
p.mvalprop.init(vtype, "Value", f.Tag.Get("protobuf_val"), nil, lockGetProp)
|
||||||
}
|
}
|
||||||
p.setTag(lockGetProp)
|
p.setTag(lockGetProp)
|
||||||
|
@ -744,7 +760,9 @@ func getPropertiesLocked(t reflect.Type) *StructProperties {
|
||||||
propertiesMap[t] = prop
|
propertiesMap[t] = prop
|
||||||
|
|
||||||
// build properties
|
// build properties
|
||||||
prop.extendable = reflect.PtrTo(t).Implements(extendableProtoType)
|
prop.extendable = reflect.PtrTo(t).Implements(extendableProtoType) ||
|
||||||
|
reflect.PtrTo(t).Implements(extendableProtoV1Type) ||
|
||||||
|
reflect.PtrTo(t).Implements(extendableBytesType)
|
||||||
prop.unrecField = invalidField
|
prop.unrecField = invalidField
|
||||||
prop.Prop = make([]*Properties, t.NumField())
|
prop.Prop = make([]*Properties, t.NumField())
|
||||||
prop.order = make([]int, t.NumField())
|
prop.order = make([]int, t.NumField())
|
||||||
|
@ -756,7 +774,11 @@ func getPropertiesLocked(t reflect.Type) *StructProperties {
|
||||||
name := f.Name
|
name := f.Name
|
||||||
p.init(f.Type, name, f.Tag.Get("protobuf"), &f, false)
|
p.init(f.Type, name, f.Tag.Get("protobuf"), &f, false)
|
||||||
|
|
||||||
if f.Name == "XXX_extensions" { // special case
|
if f.Name == "XXX_InternalExtensions" { // special case
|
||||||
|
p.enc = (*Buffer).enc_exts
|
||||||
|
p.dec = nil // not needed
|
||||||
|
p.size = size_exts
|
||||||
|
} else if f.Name == "XXX_extensions" { // special case
|
||||||
if len(f.Tag.Get("protobuf")) > 0 {
|
if len(f.Tag.Get("protobuf")) > 0 {
|
||||||
p.enc = (*Buffer).enc_ext_slice_byte
|
p.enc = (*Buffer).enc_ext_slice_byte
|
||||||
p.dec = nil // not needed
|
p.dec = nil // not needed
|
||||||
|
@ -766,13 +788,14 @@ func getPropertiesLocked(t reflect.Type) *StructProperties {
|
||||||
p.dec = nil // not needed
|
p.dec = nil // not needed
|
||||||
p.size = size_map
|
p.size = size_map
|
||||||
}
|
}
|
||||||
}
|
} else if f.Name == "XXX_unrecognized" { // special case
|
||||||
if f.Name == "XXX_unrecognized" { // special case
|
|
||||||
prop.unrecField = toField(&f)
|
prop.unrecField = toField(&f)
|
||||||
}
|
}
|
||||||
oneof := f.Tag.Get("protobuf_oneof") != "" // special case
|
oneof := f.Tag.Get("protobuf_oneof") // special case
|
||||||
if oneof {
|
if oneof != "" {
|
||||||
isOneofMessage = true
|
isOneofMessage = true
|
||||||
|
// Oneof fields don't use the traditional protobuf tag.
|
||||||
|
p.OrigName = oneof
|
||||||
}
|
}
|
||||||
prop.Prop[i] = p
|
prop.Prop[i] = p
|
||||||
prop.order[i] = i
|
prop.order[i] = i
|
||||||
|
@ -783,7 +806,7 @@ func getPropertiesLocked(t reflect.Type) *StructProperties {
|
||||||
}
|
}
|
||||||
print("\n")
|
print("\n")
|
||||||
}
|
}
|
||||||
if p.enc == nil && !strings.HasPrefix(f.Name, "XXX_") && !oneof {
|
if p.enc == nil && !strings.HasPrefix(f.Name, "XXX_") && oneof == "" {
|
||||||
fmt.Fprintln(os.Stderr, "proto: no encoder for", f.Name, f.Type.String(), "[GetProperties]")
|
fmt.Fprintln(os.Stderr, "proto: no encoder for", f.Name, f.Type.String(), "[GetProperties]")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -917,7 +940,29 @@ func RegisterType(x Message, name string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// MessageName returns the fully-qualified proto name for the given message type.
|
// MessageName returns the fully-qualified proto name for the given message type.
|
||||||
func MessageName(x Message) string { return revProtoTypes[reflect.TypeOf(x)] }
|
func MessageName(x Message) string {
|
||||||
|
type xname interface {
|
||||||
|
XXX_MessageName() string
|
||||||
|
}
|
||||||
|
if m, ok := x.(xname); ok {
|
||||||
|
return m.XXX_MessageName()
|
||||||
|
}
|
||||||
|
return revProtoTypes[reflect.TypeOf(x)]
|
||||||
|
}
|
||||||
|
|
||||||
// MessageType returns the message type (pointer to struct) for a named message.
|
// MessageType returns the message type (pointer to struct) for a named message.
|
||||||
func MessageType(name string) reflect.Type { return protoTypes[name] }
|
func MessageType(name string) reflect.Type { return protoTypes[name] }
|
||||||
|
|
||||||
|
// A registry of all linked proto files.
|
||||||
|
var (
|
||||||
|
protoFiles = make(map[string][]byte) // file name => fileDescriptor
|
||||||
|
)
|
||||||
|
|
||||||
|
// RegisterFile is called from generated code and maps from the
|
||||||
|
// full file name of a .proto file to its compressed FileDescriptorProto.
|
||||||
|
func RegisterFile(filename string, fileDescriptor []byte) {
|
||||||
|
protoFiles[filename] = fileDescriptor
|
||||||
|
}
|
||||||
|
|
||||||
|
// FileDescriptor returns the compressed FileDescriptorProto for a .proto file.
|
||||||
|
func FileDescriptor(filename string) []byte { return protoFiles[filename] }
|
||||||
|
|
51
vendor/github.com/gogo/protobuf/proto/properties_gogo.go
generated
vendored
51
vendor/github.com/gogo/protobuf/proto/properties_gogo.go
generated
vendored
|
@ -1,5 +1,7 @@
|
||||||
// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
|
// Protocol Buffers for Go with Gadgets
|
||||||
// http://github.com/gogo/protobuf/gogoproto
|
//
|
||||||
|
// Copyright (c) 2013, The GoGo Authors. All rights reserved.
|
||||||
|
// http://github.com/gogo/protobuf
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions are
|
// modification, are permitted provided that the following conditions are
|
||||||
|
@ -49,6 +51,51 @@ func (p *Properties) setCustomEncAndDec(typ reflect.Type) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Properties) setDurationEncAndDec(typ reflect.Type) {
|
||||||
|
if p.Repeated {
|
||||||
|
if typ.Elem().Kind() == reflect.Ptr {
|
||||||
|
p.enc = (*Buffer).enc_slice_duration
|
||||||
|
p.dec = (*Buffer).dec_slice_duration
|
||||||
|
p.size = size_slice_duration
|
||||||
|
} else {
|
||||||
|
p.enc = (*Buffer).enc_slice_ref_duration
|
||||||
|
p.dec = (*Buffer).dec_slice_ref_duration
|
||||||
|
p.size = size_slice_ref_duration
|
||||||
|
}
|
||||||
|
} else if typ.Kind() == reflect.Ptr {
|
||||||
|
p.enc = (*Buffer).enc_duration
|
||||||
|
p.dec = (*Buffer).dec_duration
|
||||||
|
p.size = size_duration
|
||||||
|
} else {
|
||||||
|
p.enc = (*Buffer).enc_ref_duration
|
||||||
|
p.dec = (*Buffer).dec_ref_duration
|
||||||
|
p.size = size_ref_duration
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Properties) setTimeEncAndDec(typ reflect.Type) {
|
||||||
|
if p.Repeated {
|
||||||
|
if typ.Elem().Kind() == reflect.Ptr {
|
||||||
|
p.enc = (*Buffer).enc_slice_time
|
||||||
|
p.dec = (*Buffer).dec_slice_time
|
||||||
|
p.size = size_slice_time
|
||||||
|
} else {
|
||||||
|
p.enc = (*Buffer).enc_slice_ref_time
|
||||||
|
p.dec = (*Buffer).dec_slice_ref_time
|
||||||
|
p.size = size_slice_ref_time
|
||||||
|
}
|
||||||
|
} else if typ.Kind() == reflect.Ptr {
|
||||||
|
p.enc = (*Buffer).enc_time
|
||||||
|
p.dec = (*Buffer).dec_time
|
||||||
|
p.size = size_time
|
||||||
|
} else {
|
||||||
|
p.enc = (*Buffer).enc_ref_time
|
||||||
|
p.dec = (*Buffer).dec_ref_time
|
||||||
|
p.size = size_ref_time
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func (p *Properties) setSliceOfNonPointerStructs(typ reflect.Type) {
|
func (p *Properties) setSliceOfNonPointerStructs(typ reflect.Type) {
|
||||||
t2 := typ.Elem()
|
t2 := typ.Elem()
|
||||||
p.sstype = typ
|
p.sstype = typ
|
||||||
|
|
6
vendor/github.com/gogo/protobuf/proto/skip_gogo.go
generated
vendored
6
vendor/github.com/gogo/protobuf/proto/skip_gogo.go
generated
vendored
|
@ -1,5 +1,7 @@
|
||||||
// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
|
// Protocol Buffers for Go with Gadgets
|
||||||
// http://github.com/gogo/protobuf/gogoproto
|
//
|
||||||
|
// Copyright (c) 2013, The GoGo Authors. All rights reserved.
|
||||||
|
// http://github.com/gogo/protobuf
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions are
|
// modification, are permitted provided that the following conditions are
|
||||||
|
|
213
vendor/github.com/gogo/protobuf/proto/text.go
generated
vendored
213
vendor/github.com/gogo/protobuf/proto/text.go
generated
vendored
|
@ -1,7 +1,7 @@
|
||||||
// Extensions for Protocol Buffers to create more go like structures.
|
// Protocol Buffers for Go with Gadgets
|
||||||
//
|
//
|
||||||
// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
|
// Copyright (c) 2013, The GoGo Authors. All rights reserved.
|
||||||
// http://github.com/gogo/protobuf/gogoproto
|
// http://github.com/gogo/protobuf
|
||||||
//
|
//
|
||||||
// Go support for Protocol Buffers - Google's data interchange format
|
// Go support for Protocol Buffers - Google's data interchange format
|
||||||
//
|
//
|
||||||
|
@ -50,6 +50,8 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -159,7 +161,7 @@ func (w *textWriter) indent() { w.ind++ }
|
||||||
|
|
||||||
func (w *textWriter) unindent() {
|
func (w *textWriter) unindent() {
|
||||||
if w.ind == 0 {
|
if w.ind == 0 {
|
||||||
log.Printf("proto: textWriter unindented too far")
|
log.Print("proto: textWriter unindented too far")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.ind--
|
w.ind--
|
||||||
|
@ -180,7 +182,93 @@ type raw interface {
|
||||||
Bytes() []byte
|
Bytes() []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeStruct(w *textWriter, sv reflect.Value) error {
|
func requiresQuotes(u string) bool {
|
||||||
|
// When type URL contains any characters except [0-9A-Za-z./\-]*, it must be quoted.
|
||||||
|
for _, ch := range u {
|
||||||
|
switch {
|
||||||
|
case ch == '.' || ch == '/' || ch == '_':
|
||||||
|
continue
|
||||||
|
case '0' <= ch && ch <= '9':
|
||||||
|
continue
|
||||||
|
case 'A' <= ch && ch <= 'Z':
|
||||||
|
continue
|
||||||
|
case 'a' <= ch && ch <= 'z':
|
||||||
|
continue
|
||||||
|
default:
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// isAny reports whether sv is a google.protobuf.Any message
|
||||||
|
func isAny(sv reflect.Value) bool {
|
||||||
|
type wkt interface {
|
||||||
|
XXX_WellKnownType() string
|
||||||
|
}
|
||||||
|
t, ok := sv.Addr().Interface().(wkt)
|
||||||
|
return ok && t.XXX_WellKnownType() == "Any"
|
||||||
|
}
|
||||||
|
|
||||||
|
// writeProto3Any writes an expanded google.protobuf.Any message.
|
||||||
|
//
|
||||||
|
// It returns (false, nil) if sv value can't be unmarshaled (e.g. because
|
||||||
|
// required messages are not linked in).
|
||||||
|
//
|
||||||
|
// It returns (true, error) when sv was written in expanded format or an error
|
||||||
|
// was encountered.
|
||||||
|
func (tm *TextMarshaler) writeProto3Any(w *textWriter, sv reflect.Value) (bool, error) {
|
||||||
|
turl := sv.FieldByName("TypeUrl")
|
||||||
|
val := sv.FieldByName("Value")
|
||||||
|
if !turl.IsValid() || !val.IsValid() {
|
||||||
|
return true, errors.New("proto: invalid google.protobuf.Any message")
|
||||||
|
}
|
||||||
|
|
||||||
|
b, ok := val.Interface().([]byte)
|
||||||
|
if !ok {
|
||||||
|
return true, errors.New("proto: invalid google.protobuf.Any message")
|
||||||
|
}
|
||||||
|
|
||||||
|
parts := strings.Split(turl.String(), "/")
|
||||||
|
mt := MessageType(parts[len(parts)-1])
|
||||||
|
if mt == nil {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
m := reflect.New(mt.Elem())
|
||||||
|
if err := Unmarshal(b, m.Interface().(Message)); err != nil {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
w.Write([]byte("["))
|
||||||
|
u := turl.String()
|
||||||
|
if requiresQuotes(u) {
|
||||||
|
writeString(w, u)
|
||||||
|
} else {
|
||||||
|
w.Write([]byte(u))
|
||||||
|
}
|
||||||
|
if w.compact {
|
||||||
|
w.Write([]byte("]:<"))
|
||||||
|
} else {
|
||||||
|
w.Write([]byte("]: <\n"))
|
||||||
|
w.ind++
|
||||||
|
}
|
||||||
|
if err := tm.writeStruct(w, m.Elem()); err != nil {
|
||||||
|
return true, err
|
||||||
|
}
|
||||||
|
if w.compact {
|
||||||
|
w.Write([]byte("> "))
|
||||||
|
} else {
|
||||||
|
w.ind--
|
||||||
|
w.Write([]byte(">\n"))
|
||||||
|
}
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tm *TextMarshaler) writeStruct(w *textWriter, sv reflect.Value) error {
|
||||||
|
if tm.ExpandAny && isAny(sv) {
|
||||||
|
if canExpand, err := tm.writeProto3Any(w, sv); canExpand {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
st := sv.Type()
|
st := sv.Type()
|
||||||
sprops := GetProperties(st)
|
sprops := GetProperties(st)
|
||||||
for i := 0; i < sv.NumField(); i++ {
|
for i := 0; i < sv.NumField(); i++ {
|
||||||
|
@ -233,10 +321,10 @@ func writeStruct(w *textWriter, sv reflect.Value) error {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if len(props.Enum) > 0 {
|
if len(props.Enum) > 0 {
|
||||||
if err := writeEnum(w, v, props); err != nil {
|
if err := tm.writeEnum(w, v, props); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else if err := writeAny(w, v, props); err != nil {
|
} else if err := tm.writeAny(w, v, props); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := w.WriteByte('\n'); err != nil {
|
if err := w.WriteByte('\n'); err != nil {
|
||||||
|
@ -278,7 +366,7 @@ func writeStruct(w *textWriter, sv reflect.Value) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err := writeAny(w, key, props.mkeyprop); err != nil {
|
if err := tm.writeAny(w, key, props.mkeyprop); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := w.WriteByte('\n'); err != nil {
|
if err := w.WriteByte('\n'); err != nil {
|
||||||
|
@ -295,7 +383,7 @@ func writeStruct(w *textWriter, sv reflect.Value) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err := writeAny(w, val, props.mvalprop); err != nil {
|
if err := tm.writeAny(w, val, props.mvalprop); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := w.WriteByte('\n'); err != nil {
|
if err := w.WriteByte('\n'); err != nil {
|
||||||
|
@ -367,10 +455,10 @@ func writeStruct(w *textWriter, sv reflect.Value) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(props.Enum) > 0 {
|
if len(props.Enum) > 0 {
|
||||||
if err := writeEnum(w, fv, props); err != nil {
|
if err := tm.writeEnum(w, fv, props); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else if err := writeAny(w, fv, props); err != nil {
|
} else if err := tm.writeAny(w, fv, props); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -387,8 +475,8 @@ func writeStruct(w *textWriter, sv reflect.Value) error {
|
||||||
pv = reflect.New(sv.Type())
|
pv = reflect.New(sv.Type())
|
||||||
pv.Elem().Set(sv)
|
pv.Elem().Set(sv)
|
||||||
}
|
}
|
||||||
if pv.Type().Implements(extendableProtoType) {
|
if pv.Type().Implements(extensionRangeType) {
|
||||||
if err := writeExtensions(w, pv); err != nil {
|
if err := tm.writeExtensions(w, pv); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -418,20 +506,45 @@ func writeRaw(w *textWriter, b []byte) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// writeAny writes an arbitrary field.
|
// writeAny writes an arbitrary field.
|
||||||
func writeAny(w *textWriter, v reflect.Value, props *Properties) error {
|
func (tm *TextMarshaler) writeAny(w *textWriter, v reflect.Value, props *Properties) error {
|
||||||
v = reflect.Indirect(v)
|
v = reflect.Indirect(v)
|
||||||
|
|
||||||
if props != nil && len(props.CustomType) > 0 {
|
if props != nil {
|
||||||
custom, ok := v.Interface().(Marshaler)
|
if len(props.CustomType) > 0 {
|
||||||
if ok {
|
custom, ok := v.Interface().(Marshaler)
|
||||||
data, err := custom.Marshal()
|
if ok {
|
||||||
|
data, err := custom.Marshal()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := writeString(w, string(data)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
} else if props.StdTime {
|
||||||
|
t, ok := v.Interface().(time.Time)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("stdtime is not time.Time, but %T", v.Interface())
|
||||||
|
}
|
||||||
|
tproto, err := timestampProto(t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := writeString(w, string(data)); err != nil {
|
props.StdTime = false
|
||||||
return err
|
err = tm.writeAny(w, reflect.ValueOf(tproto), props)
|
||||||
|
props.StdTime = true
|
||||||
|
return err
|
||||||
|
} else if props.StdDuration {
|
||||||
|
d, ok := v.Interface().(time.Duration)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("stdtime is not time.Duration, but %T", v.Interface())
|
||||||
}
|
}
|
||||||
return nil
|
dproto := durationProto(d)
|
||||||
|
props.StdDuration = false
|
||||||
|
err := tm.writeAny(w, reflect.ValueOf(dproto), props)
|
||||||
|
props.StdDuration = true
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -481,15 +594,15 @@ func writeAny(w *textWriter, v reflect.Value, props *Properties) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
w.indent()
|
w.indent()
|
||||||
if tm, ok := v.Interface().(encoding.TextMarshaler); ok {
|
if etm, ok := v.Interface().(encoding.TextMarshaler); ok {
|
||||||
text, err := tm.MarshalText()
|
text, err := etm.MarshalText()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if _, err = w.Write(text); err != nil {
|
if _, err = w.Write(text); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else if err := writeStruct(w, v); err != nil {
|
} else if err := tm.writeStruct(w, v); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
w.unindent()
|
w.unindent()
|
||||||
|
@ -633,30 +746,39 @@ func (s int32Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||||
|
|
||||||
// writeExtensions writes all the extensions in pv.
|
// writeExtensions writes all the extensions in pv.
|
||||||
// pv is assumed to be a pointer to a protocol message struct that is extendable.
|
// pv is assumed to be a pointer to a protocol message struct that is extendable.
|
||||||
func writeExtensions(w *textWriter, pv reflect.Value) error {
|
func (tm *TextMarshaler) writeExtensions(w *textWriter, pv reflect.Value) error {
|
||||||
emap := extensionMaps[pv.Type().Elem()]
|
emap := extensionMaps[pv.Type().Elem()]
|
||||||
ep := pv.Interface().(extendableProto)
|
e := pv.Interface().(Message)
|
||||||
|
|
||||||
// Order the extensions by ID.
|
|
||||||
// This isn't strictly necessary, but it will give us
|
|
||||||
// canonical output, which will also make testing easier.
|
|
||||||
var m map[int32]Extension
|
var m map[int32]Extension
|
||||||
if em, ok := ep.(extensionsMap); ok {
|
var mu sync.Locker
|
||||||
m = em.ExtensionMap()
|
if em, ok := e.(extensionsBytes); ok {
|
||||||
} else if em, ok := ep.(extensionsBytes); ok {
|
|
||||||
eb := em.GetExtensions()
|
eb := em.GetExtensions()
|
||||||
var err error
|
var err error
|
||||||
m, err = BytesToExtensionsMap(*eb)
|
m, err = BytesToExtensionsMap(*eb)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
mu = notLocker{}
|
||||||
|
} else if _, ok := e.(extendableProto); ok {
|
||||||
|
ep, _ := extendable(e)
|
||||||
|
m, mu = ep.extensionsRead()
|
||||||
|
if m == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Order the extensions by ID.
|
||||||
|
// This isn't strictly necessary, but it will give us
|
||||||
|
// canonical output, which will also make testing easier.
|
||||||
|
|
||||||
|
mu.Lock()
|
||||||
ids := make([]int32, 0, len(m))
|
ids := make([]int32, 0, len(m))
|
||||||
for id := range m {
|
for id := range m {
|
||||||
ids = append(ids, id)
|
ids = append(ids, id)
|
||||||
}
|
}
|
||||||
sort.Sort(int32Slice(ids))
|
sort.Sort(int32Slice(ids))
|
||||||
|
mu.Unlock()
|
||||||
|
|
||||||
for _, extNum := range ids {
|
for _, extNum := range ids {
|
||||||
ext := m[extNum]
|
ext := m[extNum]
|
||||||
|
@ -672,20 +794,20 @@ func writeExtensions(w *textWriter, pv reflect.Value) error {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
pb, err := GetExtension(ep, desc)
|
pb, err := GetExtension(e, desc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed getting extension: %v", err)
|
return fmt.Errorf("failed getting extension: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Repeated extensions will appear as a slice.
|
// Repeated extensions will appear as a slice.
|
||||||
if !desc.repeated() {
|
if !desc.repeated() {
|
||||||
if err := writeExtension(w, desc.Name, pb); err != nil {
|
if err := tm.writeExtension(w, desc.Name, pb); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
v := reflect.ValueOf(pb)
|
v := reflect.ValueOf(pb)
|
||||||
for i := 0; i < v.Len(); i++ {
|
for i := 0; i < v.Len(); i++ {
|
||||||
if err := writeExtension(w, desc.Name, v.Index(i).Interface()); err != nil {
|
if err := tm.writeExtension(w, desc.Name, v.Index(i).Interface()); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -694,7 +816,7 @@ func writeExtensions(w *textWriter, pv reflect.Value) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeExtension(w *textWriter, name string, pb interface{}) error {
|
func (tm *TextMarshaler) writeExtension(w *textWriter, name string, pb interface{}) error {
|
||||||
if _, err := fmt.Fprintf(w, "[%s]:", name); err != nil {
|
if _, err := fmt.Fprintf(w, "[%s]:", name); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -703,7 +825,7 @@ func writeExtension(w *textWriter, name string, pb interface{}) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err := writeAny(w, reflect.ValueOf(pb), nil); err != nil {
|
if err := tm.writeAny(w, reflect.ValueOf(pb), nil); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := w.WriteByte('\n'); err != nil {
|
if err := w.WriteByte('\n'); err != nil {
|
||||||
|
@ -730,12 +852,13 @@ func (w *textWriter) writeIndent() {
|
||||||
|
|
||||||
// TextMarshaler is a configurable text format marshaler.
|
// TextMarshaler is a configurable text format marshaler.
|
||||||
type TextMarshaler struct {
|
type TextMarshaler struct {
|
||||||
Compact bool // use compact text format (one line).
|
Compact bool // use compact text format (one line).
|
||||||
|
ExpandAny bool // expand google.protobuf.Any messages of known types
|
||||||
}
|
}
|
||||||
|
|
||||||
// Marshal writes a given protocol buffer in text format.
|
// Marshal writes a given protocol buffer in text format.
|
||||||
// The only errors returned are from w.
|
// The only errors returned are from w.
|
||||||
func (m *TextMarshaler) Marshal(w io.Writer, pb Message) error {
|
func (tm *TextMarshaler) Marshal(w io.Writer, pb Message) error {
|
||||||
val := reflect.ValueOf(pb)
|
val := reflect.ValueOf(pb)
|
||||||
if pb == nil || val.IsNil() {
|
if pb == nil || val.IsNil() {
|
||||||
w.Write([]byte("<nil>"))
|
w.Write([]byte("<nil>"))
|
||||||
|
@ -750,11 +873,11 @@ func (m *TextMarshaler) Marshal(w io.Writer, pb Message) error {
|
||||||
aw := &textWriter{
|
aw := &textWriter{
|
||||||
w: ww,
|
w: ww,
|
||||||
complete: true,
|
complete: true,
|
||||||
compact: m.Compact,
|
compact: tm.Compact,
|
||||||
}
|
}
|
||||||
|
|
||||||
if tm, ok := pb.(encoding.TextMarshaler); ok {
|
if etm, ok := pb.(encoding.TextMarshaler); ok {
|
||||||
text, err := tm.MarshalText()
|
text, err := etm.MarshalText()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -768,7 +891,7 @@ func (m *TextMarshaler) Marshal(w io.Writer, pb Message) error {
|
||||||
}
|
}
|
||||||
// Dereference the received pointer so we don't have outer < and >.
|
// Dereference the received pointer so we don't have outer < and >.
|
||||||
v := reflect.Indirect(val)
|
v := reflect.Indirect(val)
|
||||||
if err := writeStruct(aw, v); err != nil {
|
if err := tm.writeStruct(aw, v); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if bw != nil {
|
if bw != nil {
|
||||||
|
@ -778,9 +901,9 @@ func (m *TextMarshaler) Marshal(w io.Writer, pb Message) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Text is the same as Marshal, but returns the string directly.
|
// Text is the same as Marshal, but returns the string directly.
|
||||||
func (m *TextMarshaler) Text(pb Message) string {
|
func (tm *TextMarshaler) Text(pb Message) string {
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
m.Marshal(&buf, pb)
|
tm.Marshal(&buf, pb)
|
||||||
return buf.String()
|
return buf.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
12
vendor/github.com/gogo/protobuf/proto/text_gogo.go
generated
vendored
12
vendor/github.com/gogo/protobuf/proto/text_gogo.go
generated
vendored
|
@ -1,5 +1,7 @@
|
||||||
// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
|
// Protocol Buffers for Go with Gadgets
|
||||||
// http://github.com/gogo/protobuf/gogoproto
|
//
|
||||||
|
// Copyright (c) 2013, The GoGo Authors. All rights reserved.
|
||||||
|
// http://github.com/gogo/protobuf
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions are
|
// modification, are permitted provided that the following conditions are
|
||||||
|
@ -31,10 +33,10 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
)
|
)
|
||||||
|
|
||||||
func writeEnum(w *textWriter, v reflect.Value, props *Properties) error {
|
func (tm *TextMarshaler) writeEnum(w *textWriter, v reflect.Value, props *Properties) error {
|
||||||
m, ok := enumStringMaps[props.Enum]
|
m, ok := enumStringMaps[props.Enum]
|
||||||
if !ok {
|
if !ok {
|
||||||
if err := writeAny(w, v, props); err != nil {
|
if err := tm.writeAny(w, v, props); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,7 +48,7 @@ func writeEnum(w *textWriter, v reflect.Value, props *Properties) error {
|
||||||
}
|
}
|
||||||
s, ok := m[key]
|
s, ok := m[key]
|
||||||
if !ok {
|
if !ok {
|
||||||
if err := writeAny(w, v, props); err != nil {
|
if err := tm.writeAny(w, v, props); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
270
vendor/github.com/gogo/protobuf/proto/text_parser.go
generated
vendored
270
vendor/github.com/gogo/protobuf/proto/text_parser.go
generated
vendored
|
@ -1,7 +1,7 @@
|
||||||
// Extensions for Protocol Buffers to create more go like structures.
|
// Protocol Buffers for Go with Gadgets
|
||||||
//
|
//
|
||||||
// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
|
// Copyright (c) 2013, The GoGo Authors. All rights reserved.
|
||||||
// http://github.com/gogo/protobuf/gogoproto
|
// http://github.com/gogo/protobuf
|
||||||
//
|
//
|
||||||
// Go support for Protocol Buffers - Google's data interchange format
|
// Go support for Protocol Buffers - Google's data interchange format
|
||||||
//
|
//
|
||||||
|
@ -46,9 +46,13 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Error string emitted when deserializing Any and fields are already set
|
||||||
|
const anyRepeatedlyUnpacked = "Any message unpacked multiple times, or %q already set"
|
||||||
|
|
||||||
type ParseError struct {
|
type ParseError struct {
|
||||||
Message string
|
Message string
|
||||||
Line int // 1-based line number
|
Line int // 1-based line number
|
||||||
|
@ -168,7 +172,7 @@ func (p *textParser) advance() {
|
||||||
p.cur.offset, p.cur.line = p.offset, p.line
|
p.cur.offset, p.cur.line = p.offset, p.line
|
||||||
p.cur.unquoted = ""
|
p.cur.unquoted = ""
|
||||||
switch p.s[0] {
|
switch p.s[0] {
|
||||||
case '<', '>', '{', '}', ':', '[', ']', ';', ',':
|
case '<', '>', '{', '}', ':', '[', ']', ';', ',', '/':
|
||||||
// Single symbol
|
// Single symbol
|
||||||
p.cur.value, p.s = p.s[0:1], p.s[1:len(p.s)]
|
p.cur.value, p.s = p.s[0:1], p.s[1:len(p.s)]
|
||||||
case '"', '\'':
|
case '"', '\'':
|
||||||
|
@ -456,7 +460,10 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
|
||||||
fieldSet := make(map[string]bool)
|
fieldSet := make(map[string]bool)
|
||||||
// A struct is a sequence of "name: value", terminated by one of
|
// A struct is a sequence of "name: value", terminated by one of
|
||||||
// '>' or '}', or the end of the input. A name may also be
|
// '>' or '}', or the end of the input. A name may also be
|
||||||
// "[extension]".
|
// "[extension]" or "[type/url]".
|
||||||
|
//
|
||||||
|
// The whole struct can also be an expanded Any message, like:
|
||||||
|
// [type/url] < ... struct contents ... >
|
||||||
for {
|
for {
|
||||||
tok := p.next()
|
tok := p.next()
|
||||||
if tok.err != nil {
|
if tok.err != nil {
|
||||||
|
@ -466,33 +473,74 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if tok.value == "[" {
|
if tok.value == "[" {
|
||||||
// Looks like an extension.
|
// Looks like an extension or an Any.
|
||||||
//
|
//
|
||||||
// TODO: Check whether we need to handle
|
// TODO: Check whether we need to handle
|
||||||
// namespace rooted names (e.g. ".something.Foo").
|
// namespace rooted names (e.g. ".something.Foo").
|
||||||
tok = p.next()
|
extName, err := p.consumeExtName()
|
||||||
if tok.err != nil {
|
if err != nil {
|
||||||
return tok.err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if s := strings.LastIndex(extName, "/"); s >= 0 {
|
||||||
|
// If it contains a slash, it's an Any type URL.
|
||||||
|
messageName := extName[s+1:]
|
||||||
|
mt := MessageType(messageName)
|
||||||
|
if mt == nil {
|
||||||
|
return p.errorf("unrecognized message %q in google.protobuf.Any", messageName)
|
||||||
|
}
|
||||||
|
tok = p.next()
|
||||||
|
if tok.err != nil {
|
||||||
|
return tok.err
|
||||||
|
}
|
||||||
|
// consume an optional colon
|
||||||
|
if tok.value == ":" {
|
||||||
|
tok = p.next()
|
||||||
|
if tok.err != nil {
|
||||||
|
return tok.err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var terminator string
|
||||||
|
switch tok.value {
|
||||||
|
case "<":
|
||||||
|
terminator = ">"
|
||||||
|
case "{":
|
||||||
|
terminator = "}"
|
||||||
|
default:
|
||||||
|
return p.errorf("expected '{' or '<', found %q", tok.value)
|
||||||
|
}
|
||||||
|
v := reflect.New(mt.Elem())
|
||||||
|
if pe := p.readStruct(v.Elem(), terminator); pe != nil {
|
||||||
|
return pe
|
||||||
|
}
|
||||||
|
b, err := Marshal(v.Interface().(Message))
|
||||||
|
if err != nil {
|
||||||
|
return p.errorf("failed to marshal message of type %q: %v", messageName, err)
|
||||||
|
}
|
||||||
|
if fieldSet["type_url"] {
|
||||||
|
return p.errorf(anyRepeatedlyUnpacked, "type_url")
|
||||||
|
}
|
||||||
|
if fieldSet["value"] {
|
||||||
|
return p.errorf(anyRepeatedlyUnpacked, "value")
|
||||||
|
}
|
||||||
|
sv.FieldByName("TypeUrl").SetString(extName)
|
||||||
|
sv.FieldByName("Value").SetBytes(b)
|
||||||
|
fieldSet["type_url"] = true
|
||||||
|
fieldSet["value"] = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
var desc *ExtensionDesc
|
var desc *ExtensionDesc
|
||||||
// This could be faster, but it's functional.
|
// This could be faster, but it's functional.
|
||||||
// TODO: Do something smarter than a linear scan.
|
// TODO: Do something smarter than a linear scan.
|
||||||
for _, d := range RegisteredExtensions(reflect.New(st).Interface().(Message)) {
|
for _, d := range RegisteredExtensions(reflect.New(st).Interface().(Message)) {
|
||||||
if d.Name == tok.value {
|
if d.Name == extName {
|
||||||
desc = d
|
desc = d
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if desc == nil {
|
if desc == nil {
|
||||||
return p.errorf("unrecognized extension %q", tok.value)
|
return p.errorf("unrecognized extension %q", extName)
|
||||||
}
|
|
||||||
// Check the extension terminator.
|
|
||||||
tok = p.next()
|
|
||||||
if tok.err != nil {
|
|
||||||
return tok.err
|
|
||||||
}
|
|
||||||
if tok.value != "]" {
|
|
||||||
return p.errorf("unrecognized extension terminator %q", tok.value)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
props := &Properties{}
|
props := &Properties{}
|
||||||
|
@ -519,7 +567,7 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
|
||||||
}
|
}
|
||||||
reqFieldErr = err
|
reqFieldErr = err
|
||||||
}
|
}
|
||||||
ep := sv.Addr().Interface().(extendableProto)
|
ep := sv.Addr().Interface().(Message)
|
||||||
if !rep {
|
if !rep {
|
||||||
SetExtension(ep, desc, ext.Interface())
|
SetExtension(ep, desc, ext.Interface())
|
||||||
} else {
|
} else {
|
||||||
|
@ -550,7 +598,11 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
|
||||||
props = oop.Prop
|
props = oop.Prop
|
||||||
nv := reflect.New(oop.Type.Elem())
|
nv := reflect.New(oop.Type.Elem())
|
||||||
dst = nv.Elem().Field(0)
|
dst = nv.Elem().Field(0)
|
||||||
sv.Field(oop.Field).Set(nv)
|
field := sv.Field(oop.Field)
|
||||||
|
if !field.IsNil() {
|
||||||
|
return p.errorf("field '%s' would overwrite already parsed oneof '%s'", name, sv.Type().Field(oop.Field).Name)
|
||||||
|
}
|
||||||
|
field.Set(nv)
|
||||||
}
|
}
|
||||||
if !dst.IsValid() {
|
if !dst.IsValid() {
|
||||||
return p.errorf("unknown field name %q in %v", name, st)
|
return p.errorf("unknown field name %q in %v", name, st)
|
||||||
|
@ -571,8 +623,9 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
|
||||||
|
|
||||||
// The map entry should be this sequence of tokens:
|
// The map entry should be this sequence of tokens:
|
||||||
// < key : KEY value : VALUE >
|
// < key : KEY value : VALUE >
|
||||||
// Technically the "key" and "value" could come in any order,
|
// However, implementations may omit key or value, and technically
|
||||||
// but in practice they won't.
|
// we should support them in any order. See b/28924776 for a time
|
||||||
|
// this went wrong.
|
||||||
|
|
||||||
tok := p.next()
|
tok := p.next()
|
||||||
var terminator string
|
var terminator string
|
||||||
|
@ -584,32 +637,39 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
|
||||||
default:
|
default:
|
||||||
return p.errorf("expected '{' or '<', found %q", tok.value)
|
return p.errorf("expected '{' or '<', found %q", tok.value)
|
||||||
}
|
}
|
||||||
if err := p.consumeToken("key"); err != nil {
|
for {
|
||||||
return err
|
tok := p.next()
|
||||||
}
|
if tok.err != nil {
|
||||||
if err := p.consumeToken(":"); err != nil {
|
return tok.err
|
||||||
return err
|
}
|
||||||
}
|
if tok.value == terminator {
|
||||||
if err := p.readAny(key, props.mkeyprop); err != nil {
|
break
|
||||||
return err
|
}
|
||||||
}
|
switch tok.value {
|
||||||
if err := p.consumeOptionalSeparator(); err != nil {
|
case "key":
|
||||||
return err
|
if err := p.consumeToken(":"); err != nil {
|
||||||
}
|
return err
|
||||||
if err := p.consumeToken("value"); err != nil {
|
}
|
||||||
return err
|
if err := p.readAny(key, props.mkeyprop); err != nil {
|
||||||
}
|
return err
|
||||||
if err := p.checkForColon(props.mvalprop, dst.Type().Elem()); err != nil {
|
}
|
||||||
return err
|
if err := p.consumeOptionalSeparator(); err != nil {
|
||||||
}
|
return err
|
||||||
if err := p.readAny(val, props.mvalprop); err != nil {
|
}
|
||||||
return err
|
case "value":
|
||||||
}
|
if err := p.checkForColon(props.mvalprop, dst.Type().Elem()); err != nil {
|
||||||
if err := p.consumeOptionalSeparator(); err != nil {
|
return err
|
||||||
return err
|
}
|
||||||
}
|
if err := p.readAny(val, props.mvalprop); err != nil {
|
||||||
if err := p.consumeToken(terminator); err != nil {
|
return err
|
||||||
return err
|
}
|
||||||
|
if err := p.consumeOptionalSeparator(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
p.back()
|
||||||
|
return p.errorf(`expected "key", "value", or %q, found %q`, terminator, tok.value)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dst.SetMapIndex(key, val)
|
dst.SetMapIndex(key, val)
|
||||||
|
@ -632,7 +692,8 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
reqFieldErr = err
|
reqFieldErr = err
|
||||||
} else if props.Required {
|
}
|
||||||
|
if props.Required {
|
||||||
reqCount--
|
reqCount--
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -648,6 +709,35 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
|
||||||
return reqFieldErr
|
return reqFieldErr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// consumeExtName consumes extension name or expanded Any type URL and the
|
||||||
|
// following ']'. It returns the name or URL consumed.
|
||||||
|
func (p *textParser) consumeExtName() (string, error) {
|
||||||
|
tok := p.next()
|
||||||
|
if tok.err != nil {
|
||||||
|
return "", tok.err
|
||||||
|
}
|
||||||
|
|
||||||
|
// If extension name or type url is quoted, it's a single token.
|
||||||
|
if len(tok.value) > 2 && isQuote(tok.value[0]) && tok.value[len(tok.value)-1] == tok.value[0] {
|
||||||
|
name, err := unquoteC(tok.value[1:len(tok.value)-1], rune(tok.value[0]))
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return name, p.consumeToken("]")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Consume everything up to "]"
|
||||||
|
var parts []string
|
||||||
|
for tok.value != "]" {
|
||||||
|
parts = append(parts, tok.value)
|
||||||
|
tok = p.next()
|
||||||
|
if tok.err != nil {
|
||||||
|
return "", p.errorf("unrecognized type_url or extension name: %s", tok.err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return strings.Join(parts, ""), nil
|
||||||
|
}
|
||||||
|
|
||||||
// consumeOptionalSeparator consumes an optional semicolon or comma.
|
// consumeOptionalSeparator consumes an optional semicolon or comma.
|
||||||
// It is used in readStruct to provide backward compatibility.
|
// It is used in readStruct to provide backward compatibility.
|
||||||
func (p *textParser) consumeOptionalSeparator() error {
|
func (p *textParser) consumeOptionalSeparator() error {
|
||||||
|
@ -708,6 +798,80 @@ func (p *textParser) readAny(v reflect.Value, props *Properties) error {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
if props.StdTime {
|
||||||
|
fv := v
|
||||||
|
p.back()
|
||||||
|
props.StdTime = false
|
||||||
|
tproto := ×tamp{}
|
||||||
|
err := p.readAny(reflect.ValueOf(tproto).Elem(), props)
|
||||||
|
props.StdTime = true
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
tim, err := timestampFromProto(tproto)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if props.Repeated {
|
||||||
|
t := reflect.TypeOf(v.Interface())
|
||||||
|
if t.Kind() == reflect.Slice {
|
||||||
|
if t.Elem().Kind() == reflect.Ptr {
|
||||||
|
ts := fv.Interface().([]*time.Time)
|
||||||
|
ts = append(ts, &tim)
|
||||||
|
fv.Set(reflect.ValueOf(ts))
|
||||||
|
return nil
|
||||||
|
} else {
|
||||||
|
ts := fv.Interface().([]time.Time)
|
||||||
|
ts = append(ts, tim)
|
||||||
|
fv.Set(reflect.ValueOf(ts))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if reflect.TypeOf(v.Interface()).Kind() == reflect.Ptr {
|
||||||
|
v.Set(reflect.ValueOf(&tim))
|
||||||
|
} else {
|
||||||
|
v.Set(reflect.Indirect(reflect.ValueOf(&tim)))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if props.StdDuration {
|
||||||
|
fv := v
|
||||||
|
p.back()
|
||||||
|
props.StdDuration = false
|
||||||
|
dproto := &duration{}
|
||||||
|
err := p.readAny(reflect.ValueOf(dproto).Elem(), props)
|
||||||
|
props.StdDuration = true
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
dur, err := durationFromProto(dproto)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if props.Repeated {
|
||||||
|
t := reflect.TypeOf(v.Interface())
|
||||||
|
if t.Kind() == reflect.Slice {
|
||||||
|
if t.Elem().Kind() == reflect.Ptr {
|
||||||
|
ds := fv.Interface().([]*time.Duration)
|
||||||
|
ds = append(ds, &dur)
|
||||||
|
fv.Set(reflect.ValueOf(ds))
|
||||||
|
return nil
|
||||||
|
} else {
|
||||||
|
ds := fv.Interface().([]time.Duration)
|
||||||
|
ds = append(ds, dur)
|
||||||
|
fv.Set(reflect.ValueOf(ds))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if reflect.TypeOf(v.Interface()).Kind() == reflect.Ptr {
|
||||||
|
v.Set(reflect.ValueOf(&dur))
|
||||||
|
} else {
|
||||||
|
v.Set(reflect.Indirect(reflect.ValueOf(&dur)))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
switch fv := v; fv.Kind() {
|
switch fv := v; fv.Kind() {
|
||||||
case reflect.Slice:
|
case reflect.Slice:
|
||||||
at := v.Type()
|
at := v.Type()
|
||||||
|
@ -750,12 +914,12 @@ func (p *textParser) readAny(v reflect.Value, props *Properties) error {
|
||||||
fv.Set(reflect.Append(fv, reflect.New(at.Elem()).Elem()))
|
fv.Set(reflect.Append(fv, reflect.New(at.Elem()).Elem()))
|
||||||
return p.readAny(fv.Index(fv.Len()-1), props)
|
return p.readAny(fv.Index(fv.Len()-1), props)
|
||||||
case reflect.Bool:
|
case reflect.Bool:
|
||||||
// Either "true", "false", 1 or 0.
|
// true/1/t/True or false/f/0/False.
|
||||||
switch tok.value {
|
switch tok.value {
|
||||||
case "true", "1":
|
case "true", "1", "t", "True":
|
||||||
fv.SetBool(true)
|
fv.SetBool(true)
|
||||||
return nil
|
return nil
|
||||||
case "false", "0":
|
case "false", "0", "f", "False":
|
||||||
fv.SetBool(false)
|
fv.SetBool(false)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
113
vendor/github.com/gogo/protobuf/proto/timestamp.go
generated
vendored
Normal file
113
vendor/github.com/gogo/protobuf/proto/timestamp.go
generated
vendored
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
// Go support for Protocol Buffers - Google's data interchange format
|
||||||
|
//
|
||||||
|
// Copyright 2016 The Go Authors. All rights reserved.
|
||||||
|
// https://github.com/golang/protobuf
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
package proto
|
||||||
|
|
||||||
|
// This file implements operations on google.protobuf.Timestamp.
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Seconds field of the earliest valid Timestamp.
|
||||||
|
// This is time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC).Unix().
|
||||||
|
minValidSeconds = -62135596800
|
||||||
|
// Seconds field just after the latest valid Timestamp.
|
||||||
|
// This is time.Date(10000, 1, 1, 0, 0, 0, 0, time.UTC).Unix().
|
||||||
|
maxValidSeconds = 253402300800
|
||||||
|
)
|
||||||
|
|
||||||
|
// validateTimestamp determines whether a Timestamp is valid.
|
||||||
|
// A valid timestamp represents a time in the range
|
||||||
|
// [0001-01-01, 10000-01-01) and has a Nanos field
|
||||||
|
// in the range [0, 1e9).
|
||||||
|
//
|
||||||
|
// If the Timestamp is valid, validateTimestamp returns nil.
|
||||||
|
// Otherwise, it returns an error that describes
|
||||||
|
// the problem.
|
||||||
|
//
|
||||||
|
// Every valid Timestamp can be represented by a time.Time, but the converse is not true.
|
||||||
|
func validateTimestamp(ts *timestamp) error {
|
||||||
|
if ts == nil {
|
||||||
|
return errors.New("timestamp: nil Timestamp")
|
||||||
|
}
|
||||||
|
if ts.Seconds < minValidSeconds {
|
||||||
|
return fmt.Errorf("timestamp: %#v before 0001-01-01", ts)
|
||||||
|
}
|
||||||
|
if ts.Seconds >= maxValidSeconds {
|
||||||
|
return fmt.Errorf("timestamp: %#v after 10000-01-01", ts)
|
||||||
|
}
|
||||||
|
if ts.Nanos < 0 || ts.Nanos >= 1e9 {
|
||||||
|
return fmt.Errorf("timestamp: %#v: nanos not in range [0, 1e9)", ts)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// TimestampFromProto converts a google.protobuf.Timestamp proto to a time.Time.
|
||||||
|
// It returns an error if the argument is invalid.
|
||||||
|
//
|
||||||
|
// Unlike most Go functions, if Timestamp returns an error, the first return value
|
||||||
|
// is not the zero time.Time. Instead, it is the value obtained from the
|
||||||
|
// time.Unix function when passed the contents of the Timestamp, in the UTC
|
||||||
|
// locale. This may or may not be a meaningful time; many invalid Timestamps
|
||||||
|
// do map to valid time.Times.
|
||||||
|
//
|
||||||
|
// A nil Timestamp returns an error. The first return value in that case is
|
||||||
|
// undefined.
|
||||||
|
func timestampFromProto(ts *timestamp) (time.Time, error) {
|
||||||
|
// Don't return the zero value on error, because corresponds to a valid
|
||||||
|
// timestamp. Instead return whatever time.Unix gives us.
|
||||||
|
var t time.Time
|
||||||
|
if ts == nil {
|
||||||
|
t = time.Unix(0, 0).UTC() // treat nil like the empty Timestamp
|
||||||
|
} else {
|
||||||
|
t = time.Unix(ts.Seconds, int64(ts.Nanos)).UTC()
|
||||||
|
}
|
||||||
|
return t, validateTimestamp(ts)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TimestampProto converts the time.Time to a google.protobuf.Timestamp proto.
|
||||||
|
// It returns an error if the resulting Timestamp is invalid.
|
||||||
|
func timestampProto(t time.Time) (*timestamp, error) {
|
||||||
|
seconds := t.Unix()
|
||||||
|
nanos := int32(t.Sub(time.Unix(seconds, 0)))
|
||||||
|
ts := ×tamp{
|
||||||
|
Seconds: seconds,
|
||||||
|
Nanos: nanos,
|
||||||
|
}
|
||||||
|
if err := validateTimestamp(ts); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return ts, nil
|
||||||
|
}
|
229
vendor/github.com/gogo/protobuf/proto/timestamp_gogo.go
generated
vendored
Normal file
229
vendor/github.com/gogo/protobuf/proto/timestamp_gogo.go
generated
vendored
Normal file
|
@ -0,0 +1,229 @@
|
||||||
|
// Protocol Buffers for Go with Gadgets
|
||||||
|
//
|
||||||
|
// Copyright (c) 2016, The GoGo Authors. All rights reserved.
|
||||||
|
// http://github.com/gogo/protobuf
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
package proto
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var timeType = reflect.TypeOf((*time.Time)(nil)).Elem()
|
||||||
|
|
||||||
|
type timestamp struct {
|
||||||
|
Seconds int64 `protobuf:"varint,1,opt,name=seconds,proto3" json:"seconds,omitempty"`
|
||||||
|
Nanos int32 `protobuf:"varint,2,opt,name=nanos,proto3" json:"nanos,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *timestamp) Reset() { *m = timestamp{} }
|
||||||
|
func (*timestamp) ProtoMessage() {}
|
||||||
|
func (*timestamp) String() string { return "timestamp<string>" }
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
RegisterType((*timestamp)(nil), "gogo.protobuf.proto.timestamp")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Buffer) decTimestamp() (time.Time, error) {
|
||||||
|
b, err := o.DecodeRawBytes(true)
|
||||||
|
if err != nil {
|
||||||
|
return time.Time{}, err
|
||||||
|
}
|
||||||
|
tproto := ×tamp{}
|
||||||
|
if err := Unmarshal(b, tproto); err != nil {
|
||||||
|
return time.Time{}, err
|
||||||
|
}
|
||||||
|
return timestampFromProto(tproto)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Buffer) dec_time(p *Properties, base structPointer) error {
|
||||||
|
t, err := o.decTimestamp()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
setPtrCustomType(base, p.field, &t)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Buffer) dec_ref_time(p *Properties, base structPointer) error {
|
||||||
|
t, err := o.decTimestamp()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
setCustomType(base, p.field, &t)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Buffer) dec_slice_time(p *Properties, base structPointer) error {
|
||||||
|
t, err := o.decTimestamp()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
newBas := appendStructPointer(base, p.field, reflect.SliceOf(reflect.PtrTo(timeType)))
|
||||||
|
var zero field
|
||||||
|
setPtrCustomType(newBas, zero, &t)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Buffer) dec_slice_ref_time(p *Properties, base structPointer) error {
|
||||||
|
t, err := o.decTimestamp()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
newBas := appendStructPointer(base, p.field, reflect.SliceOf(timeType))
|
||||||
|
var zero field
|
||||||
|
setCustomType(newBas, zero, &t)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func size_time(p *Properties, base structPointer) (n int) {
|
||||||
|
structp := structPointer_GetStructPointer(base, p.field)
|
||||||
|
if structPointer_IsNil(structp) {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
tim := structPointer_Interface(structp, timeType).(*time.Time)
|
||||||
|
t, err := timestampProto(*tim)
|
||||||
|
if err != nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
size := Size(t)
|
||||||
|
return size + sizeVarint(uint64(size)) + len(p.tagcode)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Buffer) enc_time(p *Properties, base structPointer) error {
|
||||||
|
structp := structPointer_GetStructPointer(base, p.field)
|
||||||
|
if structPointer_IsNil(structp) {
|
||||||
|
return ErrNil
|
||||||
|
}
|
||||||
|
tim := structPointer_Interface(structp, timeType).(*time.Time)
|
||||||
|
t, err := timestampProto(*tim)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
data, err := Marshal(t)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
o.buf = append(o.buf, p.tagcode...)
|
||||||
|
o.EncodeRawBytes(data)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func size_ref_time(p *Properties, base structPointer) (n int) {
|
||||||
|
tim := structPointer_InterfaceAt(base, p.field, timeType).(*time.Time)
|
||||||
|
t, err := timestampProto(*tim)
|
||||||
|
if err != nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
size := Size(t)
|
||||||
|
return size + sizeVarint(uint64(size)) + len(p.tagcode)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Buffer) enc_ref_time(p *Properties, base structPointer) error {
|
||||||
|
tim := structPointer_InterfaceAt(base, p.field, timeType).(*time.Time)
|
||||||
|
t, err := timestampProto(*tim)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
data, err := Marshal(t)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
o.buf = append(o.buf, p.tagcode...)
|
||||||
|
o.EncodeRawBytes(data)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func size_slice_time(p *Properties, base structPointer) (n int) {
|
||||||
|
ptims := structPointer_InterfaceAt(base, p.field, reflect.SliceOf(reflect.PtrTo(timeType))).(*[]*time.Time)
|
||||||
|
tims := *ptims
|
||||||
|
for i := 0; i < len(tims); i++ {
|
||||||
|
if tims[i] == nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
tproto, err := timestampProto(*tims[i])
|
||||||
|
if err != nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
size := Size(tproto)
|
||||||
|
n += len(p.tagcode) + size + sizeVarint(uint64(size))
|
||||||
|
}
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Buffer) enc_slice_time(p *Properties, base structPointer) error {
|
||||||
|
ptims := structPointer_InterfaceAt(base, p.field, reflect.SliceOf(reflect.PtrTo(timeType))).(*[]*time.Time)
|
||||||
|
tims := *ptims
|
||||||
|
for i := 0; i < len(tims); i++ {
|
||||||
|
if tims[i] == nil {
|
||||||
|
return errRepeatedHasNil
|
||||||
|
}
|
||||||
|
tproto, err := timestampProto(*tims[i])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
data, err := Marshal(tproto)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
o.buf = append(o.buf, p.tagcode...)
|
||||||
|
o.EncodeRawBytes(data)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func size_slice_ref_time(p *Properties, base structPointer) (n int) {
|
||||||
|
ptims := structPointer_InterfaceAt(base, p.field, reflect.SliceOf(timeType)).(*[]time.Time)
|
||||||
|
tims := *ptims
|
||||||
|
for i := 0; i < len(tims); i++ {
|
||||||
|
tproto, err := timestampProto(tims[i])
|
||||||
|
if err != nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
size := Size(tproto)
|
||||||
|
n += len(p.tagcode) + size + sizeVarint(uint64(size))
|
||||||
|
}
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Buffer) enc_slice_ref_time(p *Properties, base structPointer) error {
|
||||||
|
ptims := structPointer_InterfaceAt(base, p.field, reflect.SliceOf(timeType)).(*[]time.Time)
|
||||||
|
tims := *ptims
|
||||||
|
for i := 0; i < len(tims); i++ {
|
||||||
|
tproto, err := timestampProto(tims[i])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
data, err := Marshal(tproto)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
o.buf = append(o.buf, p.tagcode...)
|
||||||
|
o.EncodeRawBytes(data)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
4
vendor/github.com/gogo/protobuf/sortkeys/sortkeys.go
generated
vendored
4
vendor/github.com/gogo/protobuf/sortkeys/sortkeys.go
generated
vendored
|
@ -1,4 +1,6 @@
|
||||||
// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
|
// Protocol Buffers for Go with Gadgets
|
||||||
|
//
|
||||||
|
// Copyright (c) 2013, The GoGo Authors. All rights reserved.
|
||||||
// http://github.com/gogo/protobuf
|
// http://github.com/gogo/protobuf
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
|
201
vendor/github.com/jonboulle/clockwork/LICENSE
generated
vendored
201
vendor/github.com/jonboulle/clockwork/LICENSE
generated
vendored
|
@ -1,201 +0,0 @@
|
||||||
Apache License
|
|
||||||
Version 2.0, January 2004
|
|
||||||
http://www.apache.org/licenses/
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
||||||
|
|
||||||
1. Definitions.
|
|
||||||
|
|
||||||
"License" shall mean the terms and conditions for use, reproduction,
|
|
||||||
and distribution as defined by Sections 1 through 9 of this document.
|
|
||||||
|
|
||||||
"Licensor" shall mean the copyright owner or entity authorized by
|
|
||||||
the copyright owner that is granting the License.
|
|
||||||
|
|
||||||
"Legal Entity" shall mean the union of the acting entity and all
|
|
||||||
other entities that control, are controlled by, or are under common
|
|
||||||
control with that entity. For the purposes of this definition,
|
|
||||||
"control" means (i) the power, direct or indirect, to cause the
|
|
||||||
direction or management of such entity, whether by contract or
|
|
||||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
||||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
||||||
|
|
||||||
"You" (or "Your") shall mean an individual or Legal Entity
|
|
||||||
exercising permissions granted by this License.
|
|
||||||
|
|
||||||
"Source" form shall mean the preferred form for making modifications,
|
|
||||||
including but not limited to software source code, documentation
|
|
||||||
source, and configuration files.
|
|
||||||
|
|
||||||
"Object" form shall mean any form resulting from mechanical
|
|
||||||
transformation or translation of a Source form, including but
|
|
||||||
not limited to compiled object code, generated documentation,
|
|
||||||
and conversions to other media types.
|
|
||||||
|
|
||||||
"Work" shall mean the work of authorship, whether in Source or
|
|
||||||
Object form, made available under the License, as indicated by a
|
|
||||||
copyright notice that is included in or attached to the work
|
|
||||||
(an example is provided in the Appendix below).
|
|
||||||
|
|
||||||
"Derivative Works" shall mean any work, whether in Source or Object
|
|
||||||
form, that is based on (or derived from) the Work and for which the
|
|
||||||
editorial revisions, annotations, elaborations, or other modifications
|
|
||||||
represent, as a whole, an original work of authorship. For the purposes
|
|
||||||
of this License, Derivative Works shall not include works that remain
|
|
||||||
separable from, or merely link (or bind by name) to the interfaces of,
|
|
||||||
the Work and Derivative Works thereof.
|
|
||||||
|
|
||||||
"Contribution" shall mean any work of authorship, including
|
|
||||||
the original version of the Work and any modifications or additions
|
|
||||||
to that Work or Derivative Works thereof, that is intentionally
|
|
||||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
||||||
or by an individual or Legal Entity authorized to submit on behalf of
|
|
||||||
the copyright owner. For the purposes of this definition, "submitted"
|
|
||||||
means any form of electronic, verbal, or written communication sent
|
|
||||||
to the Licensor or its representatives, including but not limited to
|
|
||||||
communication on electronic mailing lists, source code control systems,
|
|
||||||
and issue tracking systems that are managed by, or on behalf of, the
|
|
||||||
Licensor for the purpose of discussing and improving the Work, but
|
|
||||||
excluding communication that is conspicuously marked or otherwise
|
|
||||||
designated in writing by the copyright owner as "Not a Contribution."
|
|
||||||
|
|
||||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
||||||
on behalf of whom a Contribution has been received by Licensor and
|
|
||||||
subsequently incorporated within the Work.
|
|
||||||
|
|
||||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
copyright license to reproduce, prepare Derivative Works of,
|
|
||||||
publicly display, publicly perform, sublicense, and distribute the
|
|
||||||
Work and such Derivative Works in Source or Object form.
|
|
||||||
|
|
||||||
3. Grant of Patent License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
(except as stated in this section) patent license to make, have made,
|
|
||||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
||||||
where such license applies only to those patent claims licensable
|
|
||||||
by such Contributor that are necessarily infringed by their
|
|
||||||
Contribution(s) alone or by combination of their Contribution(s)
|
|
||||||
with the Work to which such Contribution(s) was submitted. If You
|
|
||||||
institute patent litigation against any entity (including a
|
|
||||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
||||||
or a Contribution incorporated within the Work constitutes direct
|
|
||||||
or contributory patent infringement, then any patent licenses
|
|
||||||
granted to You under this License for that Work shall terminate
|
|
||||||
as of the date such litigation is filed.
|
|
||||||
|
|
||||||
4. Redistribution. You may reproduce and distribute copies of the
|
|
||||||
Work or Derivative Works thereof in any medium, with or without
|
|
||||||
modifications, and in Source or Object form, provided that You
|
|
||||||
meet the following conditions:
|
|
||||||
|
|
||||||
(a) You must give any other recipients of the Work or
|
|
||||||
Derivative Works a copy of this License; and
|
|
||||||
|
|
||||||
(b) You must cause any modified files to carry prominent notices
|
|
||||||
stating that You changed the files; and
|
|
||||||
|
|
||||||
(c) You must retain, in the Source form of any Derivative Works
|
|
||||||
that You distribute, all copyright, patent, trademark, and
|
|
||||||
attribution notices from the Source form of the Work,
|
|
||||||
excluding those notices that do not pertain to any part of
|
|
||||||
the Derivative Works; and
|
|
||||||
|
|
||||||
(d) If the Work includes a "NOTICE" text file as part of its
|
|
||||||
distribution, then any Derivative Works that You distribute must
|
|
||||||
include a readable copy of the attribution notices contained
|
|
||||||
within such NOTICE file, excluding those notices that do not
|
|
||||||
pertain to any part of the Derivative Works, in at least one
|
|
||||||
of the following places: within a NOTICE text file distributed
|
|
||||||
as part of the Derivative Works; within the Source form or
|
|
||||||
documentation, if provided along with the Derivative Works; or,
|
|
||||||
within a display generated by the Derivative Works, if and
|
|
||||||
wherever such third-party notices normally appear. The contents
|
|
||||||
of the NOTICE file are for informational purposes only and
|
|
||||||
do not modify the License. You may add Your own attribution
|
|
||||||
notices within Derivative Works that You distribute, alongside
|
|
||||||
or as an addendum to the NOTICE text from the Work, provided
|
|
||||||
that such additional attribution notices cannot be construed
|
|
||||||
as modifying the License.
|
|
||||||
|
|
||||||
You may add Your own copyright statement to Your modifications and
|
|
||||||
may provide additional or different license terms and conditions
|
|
||||||
for use, reproduction, or distribution of Your modifications, or
|
|
||||||
for any such Derivative Works as a whole, provided Your use,
|
|
||||||
reproduction, and distribution of the Work otherwise complies with
|
|
||||||
the conditions stated in this License.
|
|
||||||
|
|
||||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
||||||
any Contribution intentionally submitted for inclusion in the Work
|
|
||||||
by You to the Licensor shall be under the terms and conditions of
|
|
||||||
this License, without any additional terms or conditions.
|
|
||||||
Notwithstanding the above, nothing herein shall supersede or modify
|
|
||||||
the terms of any separate license agreement you may have executed
|
|
||||||
with Licensor regarding such Contributions.
|
|
||||||
|
|
||||||
6. Trademarks. This License does not grant permission to use the trade
|
|
||||||
names, trademarks, service marks, or product names of the Licensor,
|
|
||||||
except as required for reasonable and customary use in describing the
|
|
||||||
origin of the Work and reproducing the content of the NOTICE file.
|
|
||||||
|
|
||||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
||||||
agreed to in writing, Licensor provides the Work (and each
|
|
||||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
||||||
implied, including, without limitation, any warranties or conditions
|
|
||||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
||||||
appropriateness of using or redistributing the Work and assume any
|
|
||||||
risks associated with Your exercise of permissions under this License.
|
|
||||||
|
|
||||||
8. Limitation of Liability. In no event and under no legal theory,
|
|
||||||
whether in tort (including negligence), contract, or otherwise,
|
|
||||||
unless required by applicable law (such as deliberate and grossly
|
|
||||||
negligent acts) or agreed to in writing, shall any Contributor be
|
|
||||||
liable to You for damages, including any direct, indirect, special,
|
|
||||||
incidental, or consequential damages of any character arising as a
|
|
||||||
result of this License or out of the use or inability to use the
|
|
||||||
Work (including but not limited to damages for loss of goodwill,
|
|
||||||
work stoppage, computer failure or malfunction, or any and all
|
|
||||||
other commercial damages or losses), even if such Contributor
|
|
||||||
has been advised of the possibility of such damages.
|
|
||||||
|
|
||||||
9. Accepting Warranty or Additional Liability. While redistributing
|
|
||||||
the Work or Derivative Works thereof, You may choose to offer,
|
|
||||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
||||||
or other liability obligations and/or rights consistent with this
|
|
||||||
License. However, in accepting such obligations, You may act only
|
|
||||||
on Your own behalf and on Your sole responsibility, not on behalf
|
|
||||||
of any other Contributor, and only if You agree to indemnify,
|
|
||||||
defend, and hold each Contributor harmless for any liability
|
|
||||||
incurred by, or claims asserted against, such Contributor by reason
|
|
||||||
of your accepting any such warranty or additional liability.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
APPENDIX: How to apply the Apache License to your work.
|
|
||||||
|
|
||||||
To apply the Apache License to your work, attach the following
|
|
||||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
|
||||||
replaced with your own identifying information. (Don't include
|
|
||||||
the brackets!) The text should be enclosed in the appropriate
|
|
||||||
comment syntax for the file format. We also recommend that a
|
|
||||||
file or class name and description of purpose be included on the
|
|
||||||
same "printed page" as the copyright notice for easier
|
|
||||||
identification within third-party archives.
|
|
||||||
|
|
||||||
Copyright {yyyy} {name of copyright owner}
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
161
vendor/github.com/jonboulle/clockwork/clockwork.go
generated
vendored
161
vendor/github.com/jonboulle/clockwork/clockwork.go
generated
vendored
|
@ -1,161 +0,0 @@
|
||||||
package clockwork
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Clock provides an interface that packages can use instead of directly
|
|
||||||
// using the time module, so that chronology-related behavior can be tested
|
|
||||||
type Clock interface {
|
|
||||||
After(d time.Duration) <-chan time.Time
|
|
||||||
Sleep(d time.Duration)
|
|
||||||
Now() time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
// FakeClock provides an interface for a clock which can be
|
|
||||||
// manually advanced through time
|
|
||||||
type FakeClock interface {
|
|
||||||
Clock
|
|
||||||
// Advance advances the FakeClock to a new point in time, ensuring any existing
|
|
||||||
// sleepers are notified appropriately before returning
|
|
||||||
Advance(d time.Duration)
|
|
||||||
// BlockUntil will block until the FakeClock has the given number of
|
|
||||||
// sleepers (callers of Sleep or After)
|
|
||||||
BlockUntil(n int)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewRealClock returns a Clock which simply delegates calls to the actual time
|
|
||||||
// package; it should be used by packages in production.
|
|
||||||
func NewRealClock() Clock {
|
|
||||||
return &realClock{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewFakeClock returns a FakeClock implementation which can be
|
|
||||||
// manually advanced through time for testing.
|
|
||||||
func NewFakeClock() FakeClock {
|
|
||||||
return &fakeClock{
|
|
||||||
l: sync.RWMutex{},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type realClock struct{}
|
|
||||||
|
|
||||||
func (rc *realClock) After(d time.Duration) <-chan time.Time {
|
|
||||||
return time.After(d)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (rc *realClock) Sleep(d time.Duration) {
|
|
||||||
time.Sleep(d)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (rc *realClock) Now() time.Time {
|
|
||||||
return time.Now()
|
|
||||||
}
|
|
||||||
|
|
||||||
type fakeClock struct {
|
|
||||||
sleepers []*sleeper
|
|
||||||
blockers []*blocker
|
|
||||||
time time.Time
|
|
||||||
|
|
||||||
l sync.RWMutex
|
|
||||||
}
|
|
||||||
|
|
||||||
// sleeper represents a caller of After or Sleep
|
|
||||||
type sleeper struct {
|
|
||||||
until time.Time
|
|
||||||
done chan time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
// blocker represents a caller of BlockUntil
|
|
||||||
type blocker struct {
|
|
||||||
count int
|
|
||||||
ch chan struct{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// After mimics time.After; it waits for the given duration to elapse on the
|
|
||||||
// fakeClock, then sends the current time on the returned channel.
|
|
||||||
func (fc *fakeClock) After(d time.Duration) <-chan time.Time {
|
|
||||||
fc.l.Lock()
|
|
||||||
defer fc.l.Unlock()
|
|
||||||
now := fc.time
|
|
||||||
done := make(chan time.Time, 1)
|
|
||||||
if d.Nanoseconds() == 0 {
|
|
||||||
// special case - trigger immediately
|
|
||||||
done <- now
|
|
||||||
} else {
|
|
||||||
// otherwise, add to the set of sleepers
|
|
||||||
s := &sleeper{
|
|
||||||
until: now.Add(d),
|
|
||||||
done: done,
|
|
||||||
}
|
|
||||||
fc.sleepers = append(fc.sleepers, s)
|
|
||||||
// and notify any blockers
|
|
||||||
fc.blockers = notifyBlockers(fc.blockers, len(fc.sleepers))
|
|
||||||
}
|
|
||||||
return done
|
|
||||||
}
|
|
||||||
|
|
||||||
// notifyBlockers notifies all the blockers waiting until the
|
|
||||||
// given number of sleepers are waiting on the fakeClock. It
|
|
||||||
// returns an updated slice of blockers (i.e. those still waiting)
|
|
||||||
func notifyBlockers(blockers []*blocker, count int) (newBlockers []*blocker) {
|
|
||||||
for _, b := range blockers {
|
|
||||||
if b.count == count {
|
|
||||||
close(b.ch)
|
|
||||||
} else {
|
|
||||||
newBlockers = append(newBlockers, b)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sleep blocks until the given duration has passed on the fakeClock
|
|
||||||
func (fc *fakeClock) Sleep(d time.Duration) {
|
|
||||||
<-fc.After(d)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Time returns the current time of the fakeClock
|
|
||||||
func (fc *fakeClock) Now() time.Time {
|
|
||||||
fc.l.Lock()
|
|
||||||
defer fc.l.Unlock()
|
|
||||||
return fc.time
|
|
||||||
}
|
|
||||||
|
|
||||||
// Advance advances fakeClock to a new point in time, ensuring channels from any
|
|
||||||
// previous invocations of After are notified appropriately before returning
|
|
||||||
func (fc *fakeClock) Advance(d time.Duration) {
|
|
||||||
fc.l.Lock()
|
|
||||||
defer fc.l.Unlock()
|
|
||||||
end := fc.time.Add(d)
|
|
||||||
var newSleepers []*sleeper
|
|
||||||
for _, s := range fc.sleepers {
|
|
||||||
if end.Sub(s.until) >= 0 {
|
|
||||||
s.done <- end
|
|
||||||
} else {
|
|
||||||
newSleepers = append(newSleepers, s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fc.sleepers = newSleepers
|
|
||||||
fc.blockers = notifyBlockers(fc.blockers, len(fc.sleepers))
|
|
||||||
fc.time = end
|
|
||||||
}
|
|
||||||
|
|
||||||
// BlockUntil will block until the fakeClock has the given number of sleepers
|
|
||||||
// (callers of Sleep or After)
|
|
||||||
func (fc *fakeClock) BlockUntil(n int) {
|
|
||||||
fc.l.Lock()
|
|
||||||
// Fast path: current number of sleepers is what we're looking for
|
|
||||||
if len(fc.sleepers) == n {
|
|
||||||
fc.l.Unlock()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// Otherwise, set up a new blocker
|
|
||||||
b := &blocker{
|
|
||||||
count: n,
|
|
||||||
ch: make(chan struct{}),
|
|
||||||
}
|
|
||||||
fc.blockers = append(fc.blockers, b)
|
|
||||||
fc.l.Unlock()
|
|
||||||
<-b.ch
|
|
||||||
}
|
|
1
vendor/github.com/pborman/uuid/CONTRIBUTORS
generated
vendored
1
vendor/github.com/pborman/uuid/CONTRIBUTORS
generated
vendored
|
@ -1 +0,0 @@
|
||||||
Paul Borman <borman@google.com>
|
|
27
vendor/github.com/pborman/uuid/LICENSE
generated
vendored
27
vendor/github.com/pborman/uuid/LICENSE
generated
vendored
|
@ -1,27 +0,0 @@
|
||||||
Copyright (c) 2009,2014 Google Inc. All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are
|
|
||||||
met:
|
|
||||||
|
|
||||||
* Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
* Redistributions in binary form must reproduce the above
|
|
||||||
copyright notice, this list of conditions and the following disclaimer
|
|
||||||
in the documentation and/or other materials provided with the
|
|
||||||
distribution.
|
|
||||||
* Neither the name of Google Inc. nor the names of its
|
|
||||||
contributors may be used to endorse or promote products derived from
|
|
||||||
this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
84
vendor/github.com/pborman/uuid/dce.go
generated
vendored
84
vendor/github.com/pborman/uuid/dce.go
generated
vendored
|
@ -1,84 +0,0 @@
|
||||||
// Copyright 2011 Google Inc. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package uuid
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/binary"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
)
|
|
||||||
|
|
||||||
// A Domain represents a Version 2 domain
|
|
||||||
type Domain byte
|
|
||||||
|
|
||||||
// Domain constants for DCE Security (Version 2) UUIDs.
|
|
||||||
const (
|
|
||||||
Person = Domain(0)
|
|
||||||
Group = Domain(1)
|
|
||||||
Org = Domain(2)
|
|
||||||
)
|
|
||||||
|
|
||||||
// NewDCESecurity returns a DCE Security (Version 2) UUID.
|
|
||||||
//
|
|
||||||
// The domain should be one of Person, Group or Org.
|
|
||||||
// On a POSIX system the id should be the users UID for the Person
|
|
||||||
// domain and the users GID for the Group. The meaning of id for
|
|
||||||
// the domain Org or on non-POSIX systems is site defined.
|
|
||||||
//
|
|
||||||
// For a given domain/id pair the same token may be returned for up to
|
|
||||||
// 7 minutes and 10 seconds.
|
|
||||||
func NewDCESecurity(domain Domain, id uint32) UUID {
|
|
||||||
uuid := NewUUID()
|
|
||||||
if uuid != nil {
|
|
||||||
uuid[6] = (uuid[6] & 0x0f) | 0x20 // Version 2
|
|
||||||
uuid[9] = byte(domain)
|
|
||||||
binary.BigEndian.PutUint32(uuid[0:], id)
|
|
||||||
}
|
|
||||||
return uuid
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewDCEPerson returns a DCE Security (Version 2) UUID in the person
|
|
||||||
// domain with the id returned by os.Getuid.
|
|
||||||
//
|
|
||||||
// NewDCEPerson(Person, uint32(os.Getuid()))
|
|
||||||
func NewDCEPerson() UUID {
|
|
||||||
return NewDCESecurity(Person, uint32(os.Getuid()))
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewDCEGroup returns a DCE Security (Version 2) UUID in the group
|
|
||||||
// domain with the id returned by os.Getgid.
|
|
||||||
//
|
|
||||||
// NewDCEGroup(Group, uint32(os.Getgid()))
|
|
||||||
func NewDCEGroup() UUID {
|
|
||||||
return NewDCESecurity(Group, uint32(os.Getgid()))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Domain returns the domain for a Version 2 UUID or false.
|
|
||||||
func (uuid UUID) Domain() (Domain, bool) {
|
|
||||||
if v, _ := uuid.Version(); v != 2 {
|
|
||||||
return 0, false
|
|
||||||
}
|
|
||||||
return Domain(uuid[9]), true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Id returns the id for a Version 2 UUID or false.
|
|
||||||
func (uuid UUID) Id() (uint32, bool) {
|
|
||||||
if v, _ := uuid.Version(); v != 2 {
|
|
||||||
return 0, false
|
|
||||||
}
|
|
||||||
return binary.BigEndian.Uint32(uuid[0:4]), true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d Domain) String() string {
|
|
||||||
switch d {
|
|
||||||
case Person:
|
|
||||||
return "Person"
|
|
||||||
case Group:
|
|
||||||
return "Group"
|
|
||||||
case Org:
|
|
||||||
return "Org"
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("Domain%d", int(d))
|
|
||||||
}
|
|
8
vendor/github.com/pborman/uuid/doc.go
generated
vendored
8
vendor/github.com/pborman/uuid/doc.go
generated
vendored
|
@ -1,8 +0,0 @@
|
||||||
// Copyright 2011 Google Inc. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// The uuid package generates and inspects UUIDs.
|
|
||||||
//
|
|
||||||
// UUIDs are based on RFC 4122 and DCE 1.1: Authentication and Security Services.
|
|
||||||
package uuid
|
|
53
vendor/github.com/pborman/uuid/hash.go
generated
vendored
53
vendor/github.com/pborman/uuid/hash.go
generated
vendored
|
@ -1,53 +0,0 @@
|
||||||
// Copyright 2011 Google Inc. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package uuid
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/md5"
|
|
||||||
"crypto/sha1"
|
|
||||||
"hash"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Well known Name Space IDs and UUIDs
|
|
||||||
var (
|
|
||||||
NameSpace_DNS = Parse("6ba7b810-9dad-11d1-80b4-00c04fd430c8")
|
|
||||||
NameSpace_URL = Parse("6ba7b811-9dad-11d1-80b4-00c04fd430c8")
|
|
||||||
NameSpace_OID = Parse("6ba7b812-9dad-11d1-80b4-00c04fd430c8")
|
|
||||||
NameSpace_X500 = Parse("6ba7b814-9dad-11d1-80b4-00c04fd430c8")
|
|
||||||
NIL = Parse("00000000-0000-0000-0000-000000000000")
|
|
||||||
)
|
|
||||||
|
|
||||||
// NewHash returns a new UUID dervied from the hash of space concatenated with
|
|
||||||
// data generated by h. The hash should be at least 16 byte in length. The
|
|
||||||
// first 16 bytes of the hash are used to form the UUID. The version of the
|
|
||||||
// UUID will be the lower 4 bits of version. NewHash is used to implement
|
|
||||||
// NewMD5 and NewSHA1.
|
|
||||||
func NewHash(h hash.Hash, space UUID, data []byte, version int) UUID {
|
|
||||||
h.Reset()
|
|
||||||
h.Write(space)
|
|
||||||
h.Write([]byte(data))
|
|
||||||
s := h.Sum(nil)
|
|
||||||
uuid := make([]byte, 16)
|
|
||||||
copy(uuid, s)
|
|
||||||
uuid[6] = (uuid[6] & 0x0f) | uint8((version&0xf)<<4)
|
|
||||||
uuid[8] = (uuid[8] & 0x3f) | 0x80 // RFC 4122 variant
|
|
||||||
return uuid
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewMD5 returns a new MD5 (Version 3) UUID based on the
|
|
||||||
// supplied name space and data.
|
|
||||||
//
|
|
||||||
// NewHash(md5.New(), space, data, 3)
|
|
||||||
func NewMD5(space UUID, data []byte) UUID {
|
|
||||||
return NewHash(md5.New(), space, data, 3)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewSHA1 returns a new SHA1 (Version 5) UUID based on the
|
|
||||||
// supplied name space and data.
|
|
||||||
//
|
|
||||||
// NewHash(sha1.New(), space, data, 5)
|
|
||||||
func NewSHA1(space UUID, data []byte) UUID {
|
|
||||||
return NewHash(sha1.New(), space, data, 5)
|
|
||||||
}
|
|
30
vendor/github.com/pborman/uuid/json.go
generated
vendored
30
vendor/github.com/pborman/uuid/json.go
generated
vendored
|
@ -1,30 +0,0 @@
|
||||||
// Copyright 2014 Google Inc. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package uuid
|
|
||||||
|
|
||||||
import "errors"
|
|
||||||
|
|
||||||
func (u UUID) MarshalJSON() ([]byte, error) {
|
|
||||||
if len(u) == 0 {
|
|
||||||
return []byte(`""`), nil
|
|
||||||
}
|
|
||||||
return []byte(`"` + u.String() + `"`), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *UUID) UnmarshalJSON(data []byte) error {
|
|
||||||
if len(data) == 0 || string(data) == `""` {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if len(data) < 2 || data[0] != '"' || data[len(data)-1] != '"' {
|
|
||||||
return errors.New("invalid UUID format")
|
|
||||||
}
|
|
||||||
data = data[1 : len(data)-1]
|
|
||||||
uu := Parse(string(data))
|
|
||||||
if uu == nil {
|
|
||||||
return errors.New("invalid UUID format")
|
|
||||||
}
|
|
||||||
*u = uu
|
|
||||||
return nil
|
|
||||||
}
|
|
101
vendor/github.com/pborman/uuid/node.go
generated
vendored
101
vendor/github.com/pborman/uuid/node.go
generated
vendored
|
@ -1,101 +0,0 @@
|
||||||
// Copyright 2011 Google Inc. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package uuid
|
|
||||||
|
|
||||||
import "net"
|
|
||||||
|
|
||||||
var (
|
|
||||||
interfaces []net.Interface // cached list of interfaces
|
|
||||||
ifname string // name of interface being used
|
|
||||||
nodeID []byte // hardware for version 1 UUIDs
|
|
||||||
)
|
|
||||||
|
|
||||||
// NodeInterface returns the name of the interface from which the NodeID was
|
|
||||||
// derived. The interface "user" is returned if the NodeID was set by
|
|
||||||
// SetNodeID.
|
|
||||||
func NodeInterface() string {
|
|
||||||
return ifname
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetNodeInterface selects the hardware address to be used for Version 1 UUIDs.
|
|
||||||
// If name is "" then the first usable interface found will be used or a random
|
|
||||||
// Node ID will be generated. If a named interface cannot be found then false
|
|
||||||
// is returned.
|
|
||||||
//
|
|
||||||
// SetNodeInterface never fails when name is "".
|
|
||||||
func SetNodeInterface(name string) bool {
|
|
||||||
if interfaces == nil {
|
|
||||||
var err error
|
|
||||||
interfaces, err = net.Interfaces()
|
|
||||||
if err != nil && name != "" {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, ifs := range interfaces {
|
|
||||||
if len(ifs.HardwareAddr) >= 6 && (name == "" || name == ifs.Name) {
|
|
||||||
if setNodeID(ifs.HardwareAddr) {
|
|
||||||
ifname = ifs.Name
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// We found no interfaces with a valid hardware address. If name
|
|
||||||
// does not specify a specific interface generate a random Node ID
|
|
||||||
// (section 4.1.6)
|
|
||||||
if name == "" {
|
|
||||||
if nodeID == nil {
|
|
||||||
nodeID = make([]byte, 6)
|
|
||||||
}
|
|
||||||
randomBits(nodeID)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// NodeID returns a slice of a copy of the current Node ID, setting the Node ID
|
|
||||||
// if not already set.
|
|
||||||
func NodeID() []byte {
|
|
||||||
if nodeID == nil {
|
|
||||||
SetNodeInterface("")
|
|
||||||
}
|
|
||||||
nid := make([]byte, 6)
|
|
||||||
copy(nid, nodeID)
|
|
||||||
return nid
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetNodeID sets the Node ID to be used for Version 1 UUIDs. The first 6 bytes
|
|
||||||
// of id are used. If id is less than 6 bytes then false is returned and the
|
|
||||||
// Node ID is not set.
|
|
||||||
func SetNodeID(id []byte) bool {
|
|
||||||
if setNodeID(id) {
|
|
||||||
ifname = "user"
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func setNodeID(id []byte) bool {
|
|
||||||
if len(id) < 6 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if nodeID == nil {
|
|
||||||
nodeID = make([]byte, 6)
|
|
||||||
}
|
|
||||||
copy(nodeID, id)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// NodeID returns the 6 byte node id encoded in uuid. It returns nil if uuid is
|
|
||||||
// not valid. The NodeID is only well defined for version 1 and 2 UUIDs.
|
|
||||||
func (uuid UUID) NodeID() []byte {
|
|
||||||
if len(uuid) != 16 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
node := make([]byte, 6)
|
|
||||||
copy(node, uuid[10:])
|
|
||||||
return node
|
|
||||||
}
|
|
132
vendor/github.com/pborman/uuid/time.go
generated
vendored
132
vendor/github.com/pborman/uuid/time.go
generated
vendored
|
@ -1,132 +0,0 @@
|
||||||
// Copyright 2014 Google Inc. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package uuid
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/binary"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// A Time represents a time as the number of 100's of nanoseconds since 15 Oct
|
|
||||||
// 1582.
|
|
||||||
type Time int64
|
|
||||||
|
|
||||||
const (
|
|
||||||
lillian = 2299160 // Julian day of 15 Oct 1582
|
|
||||||
unix = 2440587 // Julian day of 1 Jan 1970
|
|
||||||
epoch = unix - lillian // Days between epochs
|
|
||||||
g1582 = epoch * 86400 // seconds between epochs
|
|
||||||
g1582ns100 = g1582 * 10000000 // 100s of a nanoseconds between epochs
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
mu sync.Mutex
|
|
||||||
lasttime uint64 // last time we returned
|
|
||||||
clock_seq uint16 // clock sequence for this run
|
|
||||||
|
|
||||||
timeNow = time.Now // for testing
|
|
||||||
)
|
|
||||||
|
|
||||||
// UnixTime converts t the number of seconds and nanoseconds using the Unix
|
|
||||||
// epoch of 1 Jan 1970.
|
|
||||||
func (t Time) UnixTime() (sec, nsec int64) {
|
|
||||||
sec = int64(t - g1582ns100)
|
|
||||||
nsec = (sec % 10000000) * 100
|
|
||||||
sec /= 10000000
|
|
||||||
return sec, nsec
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetTime returns the current Time (100s of nanoseconds since 15 Oct 1582) and
|
|
||||||
// clock sequence as well as adjusting the clock sequence as needed. An error
|
|
||||||
// is returned if the current time cannot be determined.
|
|
||||||
func GetTime() (Time, uint16, error) {
|
|
||||||
defer mu.Unlock()
|
|
||||||
mu.Lock()
|
|
||||||
return getTime()
|
|
||||||
}
|
|
||||||
|
|
||||||
func getTime() (Time, uint16, error) {
|
|
||||||
t := timeNow()
|
|
||||||
|
|
||||||
// If we don't have a clock sequence already, set one.
|
|
||||||
if clock_seq == 0 {
|
|
||||||
setClockSequence(-1)
|
|
||||||
}
|
|
||||||
now := uint64(t.UnixNano()/100) + g1582ns100
|
|
||||||
|
|
||||||
// If time has gone backwards with this clock sequence then we
|
|
||||||
// increment the clock sequence
|
|
||||||
if now <= lasttime {
|
|
||||||
clock_seq = ((clock_seq + 1) & 0x3fff) | 0x8000
|
|
||||||
}
|
|
||||||
lasttime = now
|
|
||||||
return Time(now), clock_seq, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ClockSequence returns the current clock sequence, generating one if not
|
|
||||||
// already set. The clock sequence is only used for Version 1 UUIDs.
|
|
||||||
//
|
|
||||||
// The uuid package does not use global static storage for the clock sequence or
|
|
||||||
// the last time a UUID was generated. Unless SetClockSequence a new random
|
|
||||||
// clock sequence is generated the first time a clock sequence is requested by
|
|
||||||
// ClockSequence, GetTime, or NewUUID. (section 4.2.1.1) sequence is generated
|
|
||||||
// for
|
|
||||||
func ClockSequence() int {
|
|
||||||
defer mu.Unlock()
|
|
||||||
mu.Lock()
|
|
||||||
return clockSequence()
|
|
||||||
}
|
|
||||||
|
|
||||||
func clockSequence() int {
|
|
||||||
if clock_seq == 0 {
|
|
||||||
setClockSequence(-1)
|
|
||||||
}
|
|
||||||
return int(clock_seq & 0x3fff)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetClockSeq sets the clock sequence to the lower 14 bits of seq. Setting to
|
|
||||||
// -1 causes a new sequence to be generated.
|
|
||||||
func SetClockSequence(seq int) {
|
|
||||||
defer mu.Unlock()
|
|
||||||
mu.Lock()
|
|
||||||
setClockSequence(seq)
|
|
||||||
}
|
|
||||||
|
|
||||||
func setClockSequence(seq int) {
|
|
||||||
if seq == -1 {
|
|
||||||
var b [2]byte
|
|
||||||
randomBits(b[:]) // clock sequence
|
|
||||||
seq = int(b[0])<<8 | int(b[1])
|
|
||||||
}
|
|
||||||
old_seq := clock_seq
|
|
||||||
clock_seq = uint16(seq&0x3fff) | 0x8000 // Set our variant
|
|
||||||
if old_seq != clock_seq {
|
|
||||||
lasttime = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Time returns the time in 100s of nanoseconds since 15 Oct 1582 encoded in
|
|
||||||
// uuid. It returns false if uuid is not valid. The time is only well defined
|
|
||||||
// for version 1 and 2 UUIDs.
|
|
||||||
func (uuid UUID) Time() (Time, bool) {
|
|
||||||
if len(uuid) != 16 {
|
|
||||||
return 0, false
|
|
||||||
}
|
|
||||||
time := int64(binary.BigEndian.Uint32(uuid[0:4]))
|
|
||||||
time |= int64(binary.BigEndian.Uint16(uuid[4:6])) << 32
|
|
||||||
time |= int64(binary.BigEndian.Uint16(uuid[6:8])&0xfff) << 48
|
|
||||||
return Time(time), true
|
|
||||||
}
|
|
||||||
|
|
||||||
// ClockSequence returns the clock sequence encoded in uuid. It returns false
|
|
||||||
// if uuid is not valid. The clock sequence is only well defined for version 1
|
|
||||||
// and 2 UUIDs.
|
|
||||||
func (uuid UUID) ClockSequence() (int, bool) {
|
|
||||||
if len(uuid) != 16 {
|
|
||||||
return 0, false
|
|
||||||
}
|
|
||||||
return int(binary.BigEndian.Uint16(uuid[8:10])) & 0x3fff, true
|
|
||||||
}
|
|
43
vendor/github.com/pborman/uuid/util.go
generated
vendored
43
vendor/github.com/pborman/uuid/util.go
generated
vendored
|
@ -1,43 +0,0 @@
|
||||||
// Copyright 2011 Google Inc. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package uuid
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
)
|
|
||||||
|
|
||||||
// randomBits completely fills slice b with random data.
|
|
||||||
func randomBits(b []byte) {
|
|
||||||
if _, err := io.ReadFull(rander, b); err != nil {
|
|
||||||
panic(err.Error()) // rand should never fail
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// xvalues returns the value of a byte as a hexadecimal digit or 255.
|
|
||||||
var xvalues = []byte{
|
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
|
||||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255, 255,
|
|
||||||
255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
|
||||||
255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
|
||||||
}
|
|
||||||
|
|
||||||
// xtob converts the the first two hex bytes of x into a byte.
|
|
||||||
func xtob(x string) (byte, bool) {
|
|
||||||
b1 := xvalues[x[0]]
|
|
||||||
b2 := xvalues[x[1]]
|
|
||||||
return (b1 << 4) | b2, b1 != 255 && b2 != 255
|
|
||||||
}
|
|
163
vendor/github.com/pborman/uuid/uuid.go
generated
vendored
163
vendor/github.com/pborman/uuid/uuid.go
generated
vendored
|
@ -1,163 +0,0 @@
|
||||||
// Copyright 2011 Google Inc. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package uuid
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"crypto/rand"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// A UUID is a 128 bit (16 byte) Universal Unique IDentifier as defined in RFC
|
|
||||||
// 4122.
|
|
||||||
type UUID []byte
|
|
||||||
|
|
||||||
// A Version represents a UUIDs version.
|
|
||||||
type Version byte
|
|
||||||
|
|
||||||
// A Variant represents a UUIDs variant.
|
|
||||||
type Variant byte
|
|
||||||
|
|
||||||
// Constants returned by Variant.
|
|
||||||
const (
|
|
||||||
Invalid = Variant(iota) // Invalid UUID
|
|
||||||
RFC4122 // The variant specified in RFC4122
|
|
||||||
Reserved // Reserved, NCS backward compatibility.
|
|
||||||
Microsoft // Reserved, Microsoft Corporation backward compatibility.
|
|
||||||
Future // Reserved for future definition.
|
|
||||||
)
|
|
||||||
|
|
||||||
var rander = rand.Reader // random function
|
|
||||||
|
|
||||||
// New returns a new random (version 4) UUID as a string. It is a convenience
|
|
||||||
// function for NewRandom().String().
|
|
||||||
func New() string {
|
|
||||||
return NewRandom().String()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse decodes s into a UUID or returns nil. Both the UUID form of
|
|
||||||
// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and
|
|
||||||
// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx are decoded.
|
|
||||||
func Parse(s string) UUID {
|
|
||||||
if len(s) == 36+9 {
|
|
||||||
if strings.ToLower(s[:9]) != "urn:uuid:" {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
s = s[9:]
|
|
||||||
} else if len(s) != 36 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
uuid := make([]byte, 16)
|
|
||||||
for i, x := range []int{
|
|
||||||
0, 2, 4, 6,
|
|
||||||
9, 11,
|
|
||||||
14, 16,
|
|
||||||
19, 21,
|
|
||||||
24, 26, 28, 30, 32, 34} {
|
|
||||||
if v, ok := xtob(s[x:]); !ok {
|
|
||||||
return nil
|
|
||||||
} else {
|
|
||||||
uuid[i] = v
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return uuid
|
|
||||||
}
|
|
||||||
|
|
||||||
// Equal returns true if uuid1 and uuid2 are equal.
|
|
||||||
func Equal(uuid1, uuid2 UUID) bool {
|
|
||||||
return bytes.Equal(uuid1, uuid2)
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the string form of uuid, xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
|
||||||
// , or "" if uuid is invalid.
|
|
||||||
func (uuid UUID) String() string {
|
|
||||||
if uuid == nil || len(uuid) != 16 {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
b := []byte(uuid)
|
|
||||||
return fmt.Sprintf("%08x-%04x-%04x-%04x-%012x",
|
|
||||||
b[:4], b[4:6], b[6:8], b[8:10], b[10:])
|
|
||||||
}
|
|
||||||
|
|
||||||
// URN returns the RFC 2141 URN form of uuid,
|
|
||||||
// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, or "" if uuid is invalid.
|
|
||||||
func (uuid UUID) URN() string {
|
|
||||||
if uuid == nil || len(uuid) != 16 {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
b := []byte(uuid)
|
|
||||||
return fmt.Sprintf("urn:uuid:%08x-%04x-%04x-%04x-%012x",
|
|
||||||
b[:4], b[4:6], b[6:8], b[8:10], b[10:])
|
|
||||||
}
|
|
||||||
|
|
||||||
// Variant returns the variant encoded in uuid. It returns Invalid if
|
|
||||||
// uuid is invalid.
|
|
||||||
func (uuid UUID) Variant() Variant {
|
|
||||||
if len(uuid) != 16 {
|
|
||||||
return Invalid
|
|
||||||
}
|
|
||||||
switch {
|
|
||||||
case (uuid[8] & 0xc0) == 0x80:
|
|
||||||
return RFC4122
|
|
||||||
case (uuid[8] & 0xe0) == 0xc0:
|
|
||||||
return Microsoft
|
|
||||||
case (uuid[8] & 0xe0) == 0xe0:
|
|
||||||
return Future
|
|
||||||
default:
|
|
||||||
return Reserved
|
|
||||||
}
|
|
||||||
panic("unreachable")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Version returns the verison of uuid. It returns false if uuid is not
|
|
||||||
// valid.
|
|
||||||
func (uuid UUID) Version() (Version, bool) {
|
|
||||||
if len(uuid) != 16 {
|
|
||||||
return 0, false
|
|
||||||
}
|
|
||||||
return Version(uuid[6] >> 4), true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v Version) String() string {
|
|
||||||
if v > 15 {
|
|
||||||
return fmt.Sprintf("BAD_VERSION_%d", v)
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("VERSION_%d", v)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v Variant) String() string {
|
|
||||||
switch v {
|
|
||||||
case RFC4122:
|
|
||||||
return "RFC4122"
|
|
||||||
case Reserved:
|
|
||||||
return "Reserved"
|
|
||||||
case Microsoft:
|
|
||||||
return "Microsoft"
|
|
||||||
case Future:
|
|
||||||
return "Future"
|
|
||||||
case Invalid:
|
|
||||||
return "Invalid"
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("BadVariant%d", int(v))
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetRand sets the random number generator to r, which implents io.Reader.
|
|
||||||
// If r.Read returns an error when the package requests random data then
|
|
||||||
// a panic will be issued.
|
|
||||||
//
|
|
||||||
// Calling SetRand with nil sets the random number generator to the default
|
|
||||||
// generator.
|
|
||||||
func SetRand(r io.Reader) {
|
|
||||||
if r == nil {
|
|
||||||
rander = rand.Reader
|
|
||||||
return
|
|
||||||
}
|
|
||||||
rander = r
|
|
||||||
}
|
|
41
vendor/github.com/pborman/uuid/version1.go
generated
vendored
41
vendor/github.com/pborman/uuid/version1.go
generated
vendored
|
@ -1,41 +0,0 @@
|
||||||
// Copyright 2011 Google Inc. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package uuid
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/binary"
|
|
||||||
)
|
|
||||||
|
|
||||||
// NewUUID returns a Version 1 UUID based on the current NodeID and clock
|
|
||||||
// sequence, and the current time. If the NodeID has not been set by SetNodeID
|
|
||||||
// or SetNodeInterface then it will be set automatically. If the NodeID cannot
|
|
||||||
// be set NewUUID returns nil. If clock sequence has not been set by
|
|
||||||
// SetClockSequence then it will be set automatically. If GetTime fails to
|
|
||||||
// return the current NewUUID returns nil.
|
|
||||||
func NewUUID() UUID {
|
|
||||||
if nodeID == nil {
|
|
||||||
SetNodeInterface("")
|
|
||||||
}
|
|
||||||
|
|
||||||
now, seq, err := GetTime()
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
uuid := make([]byte, 16)
|
|
||||||
|
|
||||||
time_low := uint32(now & 0xffffffff)
|
|
||||||
time_mid := uint16((now >> 32) & 0xffff)
|
|
||||||
time_hi := uint16((now >> 48) & 0x0fff)
|
|
||||||
time_hi |= 0x1000 // Version 1
|
|
||||||
|
|
||||||
binary.BigEndian.PutUint32(uuid[0:], time_low)
|
|
||||||
binary.BigEndian.PutUint16(uuid[4:], time_mid)
|
|
||||||
binary.BigEndian.PutUint16(uuid[6:], time_hi)
|
|
||||||
binary.BigEndian.PutUint16(uuid[8:], seq)
|
|
||||||
copy(uuid[10:], nodeID)
|
|
||||||
|
|
||||||
return uuid
|
|
||||||
}
|
|
25
vendor/github.com/pborman/uuid/version4.go
generated
vendored
25
vendor/github.com/pborman/uuid/version4.go
generated
vendored
|
@ -1,25 +0,0 @@
|
||||||
// Copyright 2011 Google Inc. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package uuid
|
|
||||||
|
|
||||||
// Random returns a Random (Version 4) UUID or panics.
|
|
||||||
//
|
|
||||||
// The strength of the UUIDs is based on the strength of the crypto/rand
|
|
||||||
// package.
|
|
||||||
//
|
|
||||||
// A note about uniqueness derived from from the UUID Wikipedia entry:
|
|
||||||
//
|
|
||||||
// Randomly generated UUIDs have 122 random bits. One's annual risk of being
|
|
||||||
// hit by a meteorite is estimated to be one chance in 17 billion, that
|
|
||||||
// means the probability is about 0.00000000006 (6 × 10−11),
|
|
||||||
// equivalent to the odds of creating a few tens of trillions of UUIDs in a
|
|
||||||
// year and having one duplicate.
|
|
||||||
func NewRandom() UUID {
|
|
||||||
uuid := make([]byte, 16)
|
|
||||||
randomBits([]byte(uuid))
|
|
||||||
uuid[6] = (uuid[6] & 0x0f) | 0x40 // Version 4
|
|
||||||
uuid[8] = (uuid[8] & 0x3f) | 0x80 // Variant is 10
|
|
||||||
return uuid
|
|
||||||
}
|
|
2
vendor/k8s.io/client-go/1.5/LICENSE → vendor/k8s.io/apimachinery/LICENSE
generated
vendored
2
vendor/k8s.io/client-go/1.5/LICENSE → vendor/k8s.io/apimachinery/LICENSE
generated
vendored
|
@ -187,7 +187,7 @@
|
||||||
same "printed page" as the copyright notice for easier
|
same "printed page" as the copyright notice for easier
|
||||||
identification within third-party archives.
|
identification within third-party archives.
|
||||||
|
|
||||||
Copyright 2014 The Kubernetes Authors.
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
27
vendor/k8s.io/apimachinery/pkg/api/errors/OWNERS
generated
vendored
Executable file
27
vendor/k8s.io/apimachinery/pkg/api/errors/OWNERS
generated
vendored
Executable file
|
@ -0,0 +1,27 @@
|
||||||
|
reviewers:
|
||||||
|
- thockin
|
||||||
|
- lavalamp
|
||||||
|
- smarterclayton
|
||||||
|
- wojtek-t
|
||||||
|
- deads2k
|
||||||
|
- brendandburns
|
||||||
|
- derekwaynecarr
|
||||||
|
- caesarxuchao
|
||||||
|
- mikedanese
|
||||||
|
- liggitt
|
||||||
|
- nikhiljindal
|
||||||
|
- gmarek
|
||||||
|
- erictune
|
||||||
|
- saad-ali
|
||||||
|
- janetkuo
|
||||||
|
- timstclair
|
||||||
|
- eparis
|
||||||
|
- timothysc
|
||||||
|
- dims
|
||||||
|
- spxtr
|
||||||
|
- hongchaodeng
|
||||||
|
- krousey
|
||||||
|
- satnam6502
|
||||||
|
- cjcullen
|
||||||
|
- david-mcmahon
|
||||||
|
- goltermann
|
|
@ -15,4 +15,4 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Package errors provides detailed error types for api field validation.
|
// Package errors provides detailed error types for api field validation.
|
||||||
package errors
|
package errors // import "k8s.io/apimachinery/pkg/api/errors"
|
|
@ -22,33 +22,32 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"k8s.io/client-go/1.5/pkg/api/unversioned"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/client-go/1.5/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/client-go/1.5/pkg/util/validation/field"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
|
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||||
)
|
)
|
||||||
|
|
||||||
// HTTP Status codes not in the golang http package.
|
// HTTP Status codes not in the golang http package.
|
||||||
const (
|
const (
|
||||||
StatusUnprocessableEntity = 422
|
StatusUnprocessableEntity = 422
|
||||||
StatusTooManyRequests = 429
|
StatusTooManyRequests = 429
|
||||||
// HTTP recommendations are for servers to define 5xx error codes
|
// StatusServerTimeout is an indication that a transient server error has
|
||||||
// for scenarios not covered by behavior. In this case, ServerTimeout
|
// occurred and the client *should* retry, with an optional Retry-After
|
||||||
// is an indication that a transient server error has occurred and the
|
// header to specify the back off window.
|
||||||
// client *should* retry, with an optional Retry-After header to specify
|
|
||||||
// the back off window.
|
|
||||||
StatusServerTimeout = 504
|
StatusServerTimeout = 504
|
||||||
)
|
)
|
||||||
|
|
||||||
// StatusError is an error intended for consumption by a REST API server; it can also be
|
// StatusError is an error intended for consumption by a REST API server; it can also be
|
||||||
// reconstructed by clients from a REST response. Public to allow easy type switches.
|
// reconstructed by clients from a REST response. Public to allow easy type switches.
|
||||||
type StatusError struct {
|
type StatusError struct {
|
||||||
ErrStatus unversioned.Status
|
ErrStatus metav1.Status
|
||||||
}
|
}
|
||||||
|
|
||||||
// APIStatus is exposed by errors that can be converted to an api.Status object
|
// APIStatus is exposed by errors that can be converted to an api.Status object
|
||||||
// for finer grained details.
|
// for finer grained details.
|
||||||
type APIStatus interface {
|
type APIStatus interface {
|
||||||
Status() unversioned.Status
|
Status() metav1.Status
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ error = &StatusError{}
|
var _ error = &StatusError{}
|
||||||
|
@ -59,8 +58,8 @@ func (e *StatusError) Error() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Status allows access to e's status without having to know the detailed workings
|
// Status allows access to e's status without having to know the detailed workings
|
||||||
// of StatusError. Used by pkg/apiserver.
|
// of StatusError.
|
||||||
func (e *StatusError) Status() unversioned.Status {
|
func (e *StatusError) Status() metav1.Status {
|
||||||
return e.ErrStatus
|
return e.ErrStatus
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,23 +81,23 @@ func (u *UnexpectedObjectError) Error() string {
|
||||||
return fmt.Sprintf("unexpected object: %v", u.Object)
|
return fmt.Sprintf("unexpected object: %v", u.Object)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FromObject generates an StatusError from an unversioned.Status, if that is the type of obj; otherwise,
|
// FromObject generates an StatusError from an metav1.Status, if that is the type of obj; otherwise,
|
||||||
// returns an UnexpecteObjectError.
|
// returns an UnexpecteObjectError.
|
||||||
func FromObject(obj runtime.Object) error {
|
func FromObject(obj runtime.Object) error {
|
||||||
switch t := obj.(type) {
|
switch t := obj.(type) {
|
||||||
case *unversioned.Status:
|
case *metav1.Status:
|
||||||
return &StatusError{*t}
|
return &StatusError{*t}
|
||||||
}
|
}
|
||||||
return &UnexpectedObjectError{obj}
|
return &UnexpectedObjectError{obj}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewNotFound returns a new error which indicates that the resource of the kind and the name was not found.
|
// NewNotFound returns a new error which indicates that the resource of the kind and the name was not found.
|
||||||
func NewNotFound(qualifiedResource unversioned.GroupResource, name string) *StatusError {
|
func NewNotFound(qualifiedResource schema.GroupResource, name string) *StatusError {
|
||||||
return &StatusError{unversioned.Status{
|
return &StatusError{metav1.Status{
|
||||||
Status: unversioned.StatusFailure,
|
Status: metav1.StatusFailure,
|
||||||
Code: http.StatusNotFound,
|
Code: http.StatusNotFound,
|
||||||
Reason: unversioned.StatusReasonNotFound,
|
Reason: metav1.StatusReasonNotFound,
|
||||||
Details: &unversioned.StatusDetails{
|
Details: &metav1.StatusDetails{
|
||||||
Group: qualifiedResource.Group,
|
Group: qualifiedResource.Group,
|
||||||
Kind: qualifiedResource.Resource,
|
Kind: qualifiedResource.Resource,
|
||||||
Name: name,
|
Name: name,
|
||||||
|
@ -108,12 +107,12 @@ func NewNotFound(qualifiedResource unversioned.GroupResource, name string) *Stat
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewAlreadyExists returns an error indicating the item requested exists by that identifier.
|
// NewAlreadyExists returns an error indicating the item requested exists by that identifier.
|
||||||
func NewAlreadyExists(qualifiedResource unversioned.GroupResource, name string) *StatusError {
|
func NewAlreadyExists(qualifiedResource schema.GroupResource, name string) *StatusError {
|
||||||
return &StatusError{unversioned.Status{
|
return &StatusError{metav1.Status{
|
||||||
Status: unversioned.StatusFailure,
|
Status: metav1.StatusFailure,
|
||||||
Code: http.StatusConflict,
|
Code: http.StatusConflict,
|
||||||
Reason: unversioned.StatusReasonAlreadyExists,
|
Reason: metav1.StatusReasonAlreadyExists,
|
||||||
Details: &unversioned.StatusDetails{
|
Details: &metav1.StatusDetails{
|
||||||
Group: qualifiedResource.Group,
|
Group: qualifiedResource.Group,
|
||||||
Kind: qualifiedResource.Resource,
|
Kind: qualifiedResource.Resource,
|
||||||
Name: name,
|
Name: name,
|
||||||
|
@ -129,21 +128,21 @@ func NewUnauthorized(reason string) *StatusError {
|
||||||
if len(message) == 0 {
|
if len(message) == 0 {
|
||||||
message = "not authorized"
|
message = "not authorized"
|
||||||
}
|
}
|
||||||
return &StatusError{unversioned.Status{
|
return &StatusError{metav1.Status{
|
||||||
Status: unversioned.StatusFailure,
|
Status: metav1.StatusFailure,
|
||||||
Code: http.StatusUnauthorized,
|
Code: http.StatusUnauthorized,
|
||||||
Reason: unversioned.StatusReasonUnauthorized,
|
Reason: metav1.StatusReasonUnauthorized,
|
||||||
Message: message,
|
Message: message,
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewForbidden returns an error indicating the requested action was forbidden
|
// NewForbidden returns an error indicating the requested action was forbidden
|
||||||
func NewForbidden(qualifiedResource unversioned.GroupResource, name string, err error) *StatusError {
|
func NewForbidden(qualifiedResource schema.GroupResource, name string, err error) *StatusError {
|
||||||
return &StatusError{unversioned.Status{
|
return &StatusError{metav1.Status{
|
||||||
Status: unversioned.StatusFailure,
|
Status: metav1.StatusFailure,
|
||||||
Code: http.StatusForbidden,
|
Code: http.StatusForbidden,
|
||||||
Reason: unversioned.StatusReasonForbidden,
|
Reason: metav1.StatusReasonForbidden,
|
||||||
Details: &unversioned.StatusDetails{
|
Details: &metav1.StatusDetails{
|
||||||
Group: qualifiedResource.Group,
|
Group: qualifiedResource.Group,
|
||||||
Kind: qualifiedResource.Resource,
|
Kind: qualifiedResource.Resource,
|
||||||
Name: name,
|
Name: name,
|
||||||
|
@ -153,12 +152,12 @@ func NewForbidden(qualifiedResource unversioned.GroupResource, name string, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewConflict returns an error indicating the item can't be updated as provided.
|
// NewConflict returns an error indicating the item can't be updated as provided.
|
||||||
func NewConflict(qualifiedResource unversioned.GroupResource, name string, err error) *StatusError {
|
func NewConflict(qualifiedResource schema.GroupResource, name string, err error) *StatusError {
|
||||||
return &StatusError{unversioned.Status{
|
return &StatusError{metav1.Status{
|
||||||
Status: unversioned.StatusFailure,
|
Status: metav1.StatusFailure,
|
||||||
Code: http.StatusConflict,
|
Code: http.StatusConflict,
|
||||||
Reason: unversioned.StatusReasonConflict,
|
Reason: metav1.StatusReasonConflict,
|
||||||
Details: &unversioned.StatusDetails{
|
Details: &metav1.StatusDetails{
|
||||||
Group: qualifiedResource.Group,
|
Group: qualifiedResource.Group,
|
||||||
Kind: qualifiedResource.Resource,
|
Kind: qualifiedResource.Resource,
|
||||||
Name: name,
|
Name: name,
|
||||||
|
@ -169,30 +168,30 @@ func NewConflict(qualifiedResource unversioned.GroupResource, name string, err e
|
||||||
|
|
||||||
// NewGone returns an error indicating the item no longer available at the server and no forwarding address is known.
|
// NewGone returns an error indicating the item no longer available at the server and no forwarding address is known.
|
||||||
func NewGone(message string) *StatusError {
|
func NewGone(message string) *StatusError {
|
||||||
return &StatusError{unversioned.Status{
|
return &StatusError{metav1.Status{
|
||||||
Status: unversioned.StatusFailure,
|
Status: metav1.StatusFailure,
|
||||||
Code: http.StatusGone,
|
Code: http.StatusGone,
|
||||||
Reason: unversioned.StatusReasonGone,
|
Reason: metav1.StatusReasonGone,
|
||||||
Message: message,
|
Message: message,
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewInvalid returns an error indicating the item is invalid and cannot be processed.
|
// NewInvalid returns an error indicating the item is invalid and cannot be processed.
|
||||||
func NewInvalid(qualifiedKind unversioned.GroupKind, name string, errs field.ErrorList) *StatusError {
|
func NewInvalid(qualifiedKind schema.GroupKind, name string, errs field.ErrorList) *StatusError {
|
||||||
causes := make([]unversioned.StatusCause, 0, len(errs))
|
causes := make([]metav1.StatusCause, 0, len(errs))
|
||||||
for i := range errs {
|
for i := range errs {
|
||||||
err := errs[i]
|
err := errs[i]
|
||||||
causes = append(causes, unversioned.StatusCause{
|
causes = append(causes, metav1.StatusCause{
|
||||||
Type: unversioned.CauseType(err.Type),
|
Type: metav1.CauseType(err.Type),
|
||||||
Message: err.ErrorBody(),
|
Message: err.ErrorBody(),
|
||||||
Field: err.Field,
|
Field: err.Field,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return &StatusError{unversioned.Status{
|
return &StatusError{metav1.Status{
|
||||||
Status: unversioned.StatusFailure,
|
Status: metav1.StatusFailure,
|
||||||
Code: StatusUnprocessableEntity, // RFC 4918: StatusUnprocessableEntity
|
Code: StatusUnprocessableEntity, // RFC 4918: StatusUnprocessableEntity
|
||||||
Reason: unversioned.StatusReasonInvalid,
|
Reason: metav1.StatusReasonInvalid,
|
||||||
Details: &unversioned.StatusDetails{
|
Details: &metav1.StatusDetails{
|
||||||
Group: qualifiedKind.Group,
|
Group: qualifiedKind.Group,
|
||||||
Kind: qualifiedKind.Kind,
|
Kind: qualifiedKind.Kind,
|
||||||
Name: name,
|
Name: name,
|
||||||
|
@ -204,31 +203,31 @@ func NewInvalid(qualifiedKind unversioned.GroupKind, name string, errs field.Err
|
||||||
|
|
||||||
// NewBadRequest creates an error that indicates that the request is invalid and can not be processed.
|
// NewBadRequest creates an error that indicates that the request is invalid and can not be processed.
|
||||||
func NewBadRequest(reason string) *StatusError {
|
func NewBadRequest(reason string) *StatusError {
|
||||||
return &StatusError{unversioned.Status{
|
return &StatusError{metav1.Status{
|
||||||
Status: unversioned.StatusFailure,
|
Status: metav1.StatusFailure,
|
||||||
Code: http.StatusBadRequest,
|
Code: http.StatusBadRequest,
|
||||||
Reason: unversioned.StatusReasonBadRequest,
|
Reason: metav1.StatusReasonBadRequest,
|
||||||
Message: reason,
|
Message: reason,
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewServiceUnavailable creates an error that indicates that the requested service is unavailable.
|
// NewServiceUnavailable creates an error that indicates that the requested service is unavailable.
|
||||||
func NewServiceUnavailable(reason string) *StatusError {
|
func NewServiceUnavailable(reason string) *StatusError {
|
||||||
return &StatusError{unversioned.Status{
|
return &StatusError{metav1.Status{
|
||||||
Status: unversioned.StatusFailure,
|
Status: metav1.StatusFailure,
|
||||||
Code: http.StatusServiceUnavailable,
|
Code: http.StatusServiceUnavailable,
|
||||||
Reason: unversioned.StatusReasonServiceUnavailable,
|
Reason: metav1.StatusReasonServiceUnavailable,
|
||||||
Message: reason,
|
Message: reason,
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewMethodNotSupported returns an error indicating the requested action is not supported on this kind.
|
// NewMethodNotSupported returns an error indicating the requested action is not supported on this kind.
|
||||||
func NewMethodNotSupported(qualifiedResource unversioned.GroupResource, action string) *StatusError {
|
func NewMethodNotSupported(qualifiedResource schema.GroupResource, action string) *StatusError {
|
||||||
return &StatusError{unversioned.Status{
|
return &StatusError{metav1.Status{
|
||||||
Status: unversioned.StatusFailure,
|
Status: metav1.StatusFailure,
|
||||||
Code: http.StatusMethodNotAllowed,
|
Code: http.StatusMethodNotAllowed,
|
||||||
Reason: unversioned.StatusReasonMethodNotAllowed,
|
Reason: metav1.StatusReasonMethodNotAllowed,
|
||||||
Details: &unversioned.StatusDetails{
|
Details: &metav1.StatusDetails{
|
||||||
Group: qualifiedResource.Group,
|
Group: qualifiedResource.Group,
|
||||||
Kind: qualifiedResource.Resource,
|
Kind: qualifiedResource.Resource,
|
||||||
},
|
},
|
||||||
|
@ -238,12 +237,12 @@ func NewMethodNotSupported(qualifiedResource unversioned.GroupResource, action s
|
||||||
|
|
||||||
// NewServerTimeout returns an error indicating the requested action could not be completed due to a
|
// NewServerTimeout returns an error indicating the requested action could not be completed due to a
|
||||||
// transient error, and the client should try again.
|
// transient error, and the client should try again.
|
||||||
func NewServerTimeout(qualifiedResource unversioned.GroupResource, operation string, retryAfterSeconds int) *StatusError {
|
func NewServerTimeout(qualifiedResource schema.GroupResource, operation string, retryAfterSeconds int) *StatusError {
|
||||||
return &StatusError{unversioned.Status{
|
return &StatusError{metav1.Status{
|
||||||
Status: unversioned.StatusFailure,
|
Status: metav1.StatusFailure,
|
||||||
Code: http.StatusInternalServerError,
|
Code: http.StatusInternalServerError,
|
||||||
Reason: unversioned.StatusReasonServerTimeout,
|
Reason: metav1.StatusReasonServerTimeout,
|
||||||
Details: &unversioned.StatusDetails{
|
Details: &metav1.StatusDetails{
|
||||||
Group: qualifiedResource.Group,
|
Group: qualifiedResource.Group,
|
||||||
Kind: qualifiedResource.Resource,
|
Kind: qualifiedResource.Resource,
|
||||||
Name: operation,
|
Name: operation,
|
||||||
|
@ -255,18 +254,18 @@ func NewServerTimeout(qualifiedResource unversioned.GroupResource, operation str
|
||||||
|
|
||||||
// NewServerTimeoutForKind should not exist. Server timeouts happen when accessing resources, the Kind is just what we
|
// NewServerTimeoutForKind should not exist. Server timeouts happen when accessing resources, the Kind is just what we
|
||||||
// happened to be looking at when the request failed. This delegates to keep code sane, but we should work towards removing this.
|
// happened to be looking at when the request failed. This delegates to keep code sane, but we should work towards removing this.
|
||||||
func NewServerTimeoutForKind(qualifiedKind unversioned.GroupKind, operation string, retryAfterSeconds int) *StatusError {
|
func NewServerTimeoutForKind(qualifiedKind schema.GroupKind, operation string, retryAfterSeconds int) *StatusError {
|
||||||
return NewServerTimeout(unversioned.GroupResource{Group: qualifiedKind.Group, Resource: qualifiedKind.Kind}, operation, retryAfterSeconds)
|
return NewServerTimeout(schema.GroupResource{Group: qualifiedKind.Group, Resource: qualifiedKind.Kind}, operation, retryAfterSeconds)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewInternalError returns an error indicating the item is invalid and cannot be processed.
|
// NewInternalError returns an error indicating the item is invalid and cannot be processed.
|
||||||
func NewInternalError(err error) *StatusError {
|
func NewInternalError(err error) *StatusError {
|
||||||
return &StatusError{unversioned.Status{
|
return &StatusError{metav1.Status{
|
||||||
Status: unversioned.StatusFailure,
|
Status: metav1.StatusFailure,
|
||||||
Code: http.StatusInternalServerError,
|
Code: http.StatusInternalServerError,
|
||||||
Reason: unversioned.StatusReasonInternalError,
|
Reason: metav1.StatusReasonInternalError,
|
||||||
Details: &unversioned.StatusDetails{
|
Details: &metav1.StatusDetails{
|
||||||
Causes: []unversioned.StatusCause{{Message: err.Error()}},
|
Causes: []metav1.StatusCause{{Message: err.Error()}},
|
||||||
},
|
},
|
||||||
Message: fmt.Sprintf("Internal error occurred: %v", err),
|
Message: fmt.Sprintf("Internal error occurred: %v", err),
|
||||||
}}
|
}}
|
||||||
|
@ -275,56 +274,57 @@ func NewInternalError(err error) *StatusError {
|
||||||
// NewTimeoutError returns an error indicating that a timeout occurred before the request
|
// NewTimeoutError returns an error indicating that a timeout occurred before the request
|
||||||
// could be completed. Clients may retry, but the operation may still complete.
|
// could be completed. Clients may retry, but the operation may still complete.
|
||||||
func NewTimeoutError(message string, retryAfterSeconds int) *StatusError {
|
func NewTimeoutError(message string, retryAfterSeconds int) *StatusError {
|
||||||
return &StatusError{unversioned.Status{
|
return &StatusError{metav1.Status{
|
||||||
Status: unversioned.StatusFailure,
|
Status: metav1.StatusFailure,
|
||||||
Code: StatusServerTimeout,
|
Code: StatusServerTimeout,
|
||||||
Reason: unversioned.StatusReasonTimeout,
|
Reason: metav1.StatusReasonTimeout,
|
||||||
Message: fmt.Sprintf("Timeout: %s", message),
|
Message: fmt.Sprintf("Timeout: %s", message),
|
||||||
Details: &unversioned.StatusDetails{
|
Details: &metav1.StatusDetails{
|
||||||
RetryAfterSeconds: int32(retryAfterSeconds),
|
RetryAfterSeconds: int32(retryAfterSeconds),
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewGenericServerResponse returns a new error for server responses that are not in a recognizable form.
|
// NewGenericServerResponse returns a new error for server responses that are not in a recognizable form.
|
||||||
func NewGenericServerResponse(code int, verb string, qualifiedResource unversioned.GroupResource, name, serverMessage string, retryAfterSeconds int, isUnexpectedResponse bool) *StatusError {
|
func NewGenericServerResponse(code int, verb string, qualifiedResource schema.GroupResource, name, serverMessage string, retryAfterSeconds int, isUnexpectedResponse bool) *StatusError {
|
||||||
reason := unversioned.StatusReasonUnknown
|
reason := metav1.StatusReasonUnknown
|
||||||
message := fmt.Sprintf("the server responded with the status code %d but did not return more information", code)
|
message := fmt.Sprintf("the server responded with the status code %d but did not return more information", code)
|
||||||
switch code {
|
switch code {
|
||||||
case http.StatusConflict:
|
case http.StatusConflict:
|
||||||
if verb == "POST" {
|
if verb == "POST" {
|
||||||
reason = unversioned.StatusReasonAlreadyExists
|
reason = metav1.StatusReasonAlreadyExists
|
||||||
} else {
|
} else {
|
||||||
reason = unversioned.StatusReasonConflict
|
reason = metav1.StatusReasonConflict
|
||||||
}
|
}
|
||||||
message = "the server reported a conflict"
|
message = "the server reported a conflict"
|
||||||
case http.StatusNotFound:
|
case http.StatusNotFound:
|
||||||
reason = unversioned.StatusReasonNotFound
|
reason = metav1.StatusReasonNotFound
|
||||||
message = "the server could not find the requested resource"
|
message = "the server could not find the requested resource"
|
||||||
case http.StatusBadRequest:
|
case http.StatusBadRequest:
|
||||||
reason = unversioned.StatusReasonBadRequest
|
reason = metav1.StatusReasonBadRequest
|
||||||
message = "the server rejected our request for an unknown reason"
|
message = "the server rejected our request for an unknown reason"
|
||||||
case http.StatusUnauthorized:
|
case http.StatusUnauthorized:
|
||||||
reason = unversioned.StatusReasonUnauthorized
|
reason = metav1.StatusReasonUnauthorized
|
||||||
message = "the server has asked for the client to provide credentials"
|
message = "the server has asked for the client to provide credentials"
|
||||||
case http.StatusForbidden:
|
case http.StatusForbidden:
|
||||||
reason = unversioned.StatusReasonForbidden
|
reason = metav1.StatusReasonForbidden
|
||||||
message = "the server does not allow access to the requested resource"
|
// the server message has details about who is trying to perform what action. Keep its message.
|
||||||
|
message = serverMessage
|
||||||
case http.StatusMethodNotAllowed:
|
case http.StatusMethodNotAllowed:
|
||||||
reason = unversioned.StatusReasonMethodNotAllowed
|
reason = metav1.StatusReasonMethodNotAllowed
|
||||||
message = "the server does not allow this method on the requested resource"
|
message = "the server does not allow this method on the requested resource"
|
||||||
case StatusUnprocessableEntity:
|
case StatusUnprocessableEntity:
|
||||||
reason = unversioned.StatusReasonInvalid
|
reason = metav1.StatusReasonInvalid
|
||||||
message = "the server rejected our request due to an error in our request"
|
message = "the server rejected our request due to an error in our request"
|
||||||
case StatusServerTimeout:
|
case StatusServerTimeout:
|
||||||
reason = unversioned.StatusReasonServerTimeout
|
reason = metav1.StatusReasonServerTimeout
|
||||||
message = "the server cannot complete the requested operation at this time, try again later"
|
message = "the server cannot complete the requested operation at this time, try again later"
|
||||||
case StatusTooManyRequests:
|
case StatusTooManyRequests:
|
||||||
reason = unversioned.StatusReasonTimeout
|
reason = metav1.StatusReasonTimeout
|
||||||
message = "the server has received too many requests and has asked us to try again later"
|
message = "the server has received too many requests and has asked us to try again later"
|
||||||
default:
|
default:
|
||||||
if code >= 500 {
|
if code >= 500 {
|
||||||
reason = unversioned.StatusReasonInternalError
|
reason = metav1.StatusReasonInternalError
|
||||||
message = fmt.Sprintf("an error on the server (%q) has prevented the request from succeeding", serverMessage)
|
message = fmt.Sprintf("an error on the server (%q) has prevented the request from succeeding", serverMessage)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -334,22 +334,22 @@ func NewGenericServerResponse(code int, verb string, qualifiedResource unversion
|
||||||
case !qualifiedResource.Empty():
|
case !qualifiedResource.Empty():
|
||||||
message = fmt.Sprintf("%s (%s %s)", message, strings.ToLower(verb), qualifiedResource.String())
|
message = fmt.Sprintf("%s (%s %s)", message, strings.ToLower(verb), qualifiedResource.String())
|
||||||
}
|
}
|
||||||
var causes []unversioned.StatusCause
|
var causes []metav1.StatusCause
|
||||||
if isUnexpectedResponse {
|
if isUnexpectedResponse {
|
||||||
causes = []unversioned.StatusCause{
|
causes = []metav1.StatusCause{
|
||||||
{
|
{
|
||||||
Type: unversioned.CauseTypeUnexpectedServerResponse,
|
Type: metav1.CauseTypeUnexpectedServerResponse,
|
||||||
Message: serverMessage,
|
Message: serverMessage,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
causes = nil
|
causes = nil
|
||||||
}
|
}
|
||||||
return &StatusError{unversioned.Status{
|
return &StatusError{metav1.Status{
|
||||||
Status: unversioned.StatusFailure,
|
Status: metav1.StatusFailure,
|
||||||
Code: int32(code),
|
Code: int32(code),
|
||||||
Reason: reason,
|
Reason: reason,
|
||||||
Details: &unversioned.StatusDetails{
|
Details: &metav1.StatusDetails{
|
||||||
Group: qualifiedResource.Group,
|
Group: qualifiedResource.Group,
|
||||||
Kind: qualifiedResource.Resource,
|
Kind: qualifiedResource.Resource,
|
||||||
Name: name,
|
Name: name,
|
||||||
|
@ -363,56 +363,73 @@ func NewGenericServerResponse(code int, verb string, qualifiedResource unversion
|
||||||
|
|
||||||
// IsNotFound returns true if the specified error was created by NewNotFound.
|
// IsNotFound returns true if the specified error was created by NewNotFound.
|
||||||
func IsNotFound(err error) bool {
|
func IsNotFound(err error) bool {
|
||||||
return reasonForError(err) == unversioned.StatusReasonNotFound
|
return reasonForError(err) == metav1.StatusReasonNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsAlreadyExists determines if the err is an error which indicates that a specified resource already exists.
|
// IsAlreadyExists determines if the err is an error which indicates that a specified resource already exists.
|
||||||
func IsAlreadyExists(err error) bool {
|
func IsAlreadyExists(err error) bool {
|
||||||
return reasonForError(err) == unversioned.StatusReasonAlreadyExists
|
return reasonForError(err) == metav1.StatusReasonAlreadyExists
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsConflict determines if the err is an error which indicates the provided update conflicts.
|
// IsConflict determines if the err is an error which indicates the provided update conflicts.
|
||||||
func IsConflict(err error) bool {
|
func IsConflict(err error) bool {
|
||||||
return reasonForError(err) == unversioned.StatusReasonConflict
|
return reasonForError(err) == metav1.StatusReasonConflict
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsInvalid determines if the err is an error which indicates the provided resource is not valid.
|
// IsInvalid determines if the err is an error which indicates the provided resource is not valid.
|
||||||
func IsInvalid(err error) bool {
|
func IsInvalid(err error) bool {
|
||||||
return reasonForError(err) == unversioned.StatusReasonInvalid
|
return reasonForError(err) == metav1.StatusReasonInvalid
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsMethodNotSupported determines if the err is an error which indicates the provided action could not
|
// IsMethodNotSupported determines if the err is an error which indicates the provided action could not
|
||||||
// be performed because it is not supported by the server.
|
// be performed because it is not supported by the server.
|
||||||
func IsMethodNotSupported(err error) bool {
|
func IsMethodNotSupported(err error) bool {
|
||||||
return reasonForError(err) == unversioned.StatusReasonMethodNotAllowed
|
return reasonForError(err) == metav1.StatusReasonMethodNotAllowed
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsBadRequest determines if err is an error which indicates that the request is invalid.
|
// IsBadRequest determines if err is an error which indicates that the request is invalid.
|
||||||
func IsBadRequest(err error) bool {
|
func IsBadRequest(err error) bool {
|
||||||
return reasonForError(err) == unversioned.StatusReasonBadRequest
|
return reasonForError(err) == metav1.StatusReasonBadRequest
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsUnauthorized determines if err is an error which indicates that the request is unauthorized and
|
// IsUnauthorized determines if err is an error which indicates that the request is unauthorized and
|
||||||
// requires authentication by the user.
|
// requires authentication by the user.
|
||||||
func IsUnauthorized(err error) bool {
|
func IsUnauthorized(err error) bool {
|
||||||
return reasonForError(err) == unversioned.StatusReasonUnauthorized
|
return reasonForError(err) == metav1.StatusReasonUnauthorized
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsForbidden determines if err is an error which indicates that the request is forbidden and cannot
|
// IsForbidden determines if err is an error which indicates that the request is forbidden and cannot
|
||||||
// be completed as requested.
|
// be completed as requested.
|
||||||
func IsForbidden(err error) bool {
|
func IsForbidden(err error) bool {
|
||||||
return reasonForError(err) == unversioned.StatusReasonForbidden
|
return reasonForError(err) == metav1.StatusReasonForbidden
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsTimeout determines if err is an error which indicates that request times out due to long
|
||||||
|
// processing.
|
||||||
|
func IsTimeout(err error) bool {
|
||||||
|
return reasonForError(err) == metav1.StatusReasonTimeout
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsServerTimeout determines if err is an error which indicates that the request needs to be retried
|
// IsServerTimeout determines if err is an error which indicates that the request needs to be retried
|
||||||
// by the client.
|
// by the client.
|
||||||
func IsServerTimeout(err error) bool {
|
func IsServerTimeout(err error) bool {
|
||||||
return reasonForError(err) == unversioned.StatusReasonServerTimeout
|
return reasonForError(err) == metav1.StatusReasonServerTimeout
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsInternalError determines if err is an error which indicates an internal server error.
|
// IsInternalError determines if err is an error which indicates an internal server error.
|
||||||
func IsInternalError(err error) bool {
|
func IsInternalError(err error) bool {
|
||||||
return reasonForError(err) == unversioned.StatusReasonInternalError
|
return reasonForError(err) == metav1.StatusReasonInternalError
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsTooManyRequests determines if err is an error which indicates that there are too many requests
|
||||||
|
// that the server cannot handle.
|
||||||
|
// TODO: update IsTooManyRequests() when the TooManyRequests(429) error returned from the API server has a non-empty Reason field
|
||||||
|
func IsTooManyRequests(err error) bool {
|
||||||
|
switch t := err.(type) {
|
||||||
|
case APIStatus:
|
||||||
|
return t.Status().Code == StatusTooManyRequests
|
||||||
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsUnexpectedServerError returns true if the server response was not in the expected API format,
|
// IsUnexpectedServerError returns true if the server response was not in the expected API format,
|
||||||
|
@ -422,7 +439,7 @@ func IsUnexpectedServerError(err error) bool {
|
||||||
case APIStatus:
|
case APIStatus:
|
||||||
if d := t.Status().Details; d != nil {
|
if d := t.Status().Details; d != nil {
|
||||||
for _, cause := range d.Causes {
|
for _, cause := range d.Causes {
|
||||||
if cause.Type == unversioned.CauseTypeUnexpectedServerResponse {
|
if cause.Type == metav1.CauseTypeUnexpectedServerResponse {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -444,7 +461,7 @@ func SuggestsClientDelay(err error) (int, bool) {
|
||||||
case APIStatus:
|
case APIStatus:
|
||||||
if t.Status().Details != nil {
|
if t.Status().Details != nil {
|
||||||
switch t.Status().Reason {
|
switch t.Status().Reason {
|
||||||
case unversioned.StatusReasonServerTimeout, unversioned.StatusReasonTimeout:
|
case metav1.StatusReasonServerTimeout, metav1.StatusReasonTimeout:
|
||||||
return int(t.Status().Details.RetryAfterSeconds), true
|
return int(t.Status().Details.RetryAfterSeconds), true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -452,10 +469,10 @@ func SuggestsClientDelay(err error) (int, bool) {
|
||||||
return 0, false
|
return 0, false
|
||||||
}
|
}
|
||||||
|
|
||||||
func reasonForError(err error) unversioned.StatusReason {
|
func reasonForError(err error) metav1.StatusReason {
|
||||||
switch t := err.(type) {
|
switch t := err.(type) {
|
||||||
case APIStatus:
|
case APIStatus:
|
||||||
return t.Status().Reason
|
return t.Status().Reason
|
||||||
}
|
}
|
||||||
return unversioned.StatusReasonUnknown
|
return metav1.StatusReasonUnknown
|
||||||
}
|
}
|
26
vendor/k8s.io/apimachinery/pkg/api/meta/OWNERS
generated
vendored
Executable file
26
vendor/k8s.io/apimachinery/pkg/api/meta/OWNERS
generated
vendored
Executable file
|
@ -0,0 +1,26 @@
|
||||||
|
reviewers:
|
||||||
|
- thockin
|
||||||
|
- smarterclayton
|
||||||
|
- wojtek-t
|
||||||
|
- deads2k
|
||||||
|
- brendandburns
|
||||||
|
- derekwaynecarr
|
||||||
|
- caesarxuchao
|
||||||
|
- mikedanese
|
||||||
|
- liggitt
|
||||||
|
- nikhiljindal
|
||||||
|
- gmarek
|
||||||
|
- kargakis
|
||||||
|
- janetkuo
|
||||||
|
- ncdc
|
||||||
|
- eparis
|
||||||
|
- dims
|
||||||
|
- krousey
|
||||||
|
- markturansky
|
||||||
|
- fabioy
|
||||||
|
- resouer
|
||||||
|
- david-mcmahon
|
||||||
|
- mfojtik
|
||||||
|
- jianhuiz
|
||||||
|
- feihujiang
|
||||||
|
- ghodss
|
|
@ -14,28 +14,21 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package api
|
package meta
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"k8s.io/client-go/1.5/pkg/api/meta"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/client-go/1.5/pkg/api/unversioned"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
"k8s.io/client-go/1.5/pkg/runtime"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
"k8s.io/client-go/1.5/pkg/util/sets"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Instantiates a DefaultRESTMapper based on types registered in api.Scheme
|
// NewDefaultRESTMapperFromScheme instantiates a DefaultRESTMapper based on types registered in the given scheme.
|
||||||
func NewDefaultRESTMapper(defaultGroupVersions []unversioned.GroupVersion, interfacesFunc meta.VersionInterfacesFunc,
|
func NewDefaultRESTMapperFromScheme(defaultGroupVersions []schema.GroupVersion, interfacesFunc VersionInterfacesFunc,
|
||||||
importPathPrefix string, ignoredKinds, rootScoped sets.String) *meta.DefaultRESTMapper {
|
importPathPrefix string, ignoredKinds, rootScoped sets.String, scheme *runtime.Scheme) *DefaultRESTMapper {
|
||||||
return NewDefaultRESTMapperFromScheme(defaultGroupVersions, interfacesFunc, importPathPrefix, ignoredKinds, rootScoped, Scheme)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Instantiates a DefaultRESTMapper based on types registered in the given scheme.
|
mapper := NewDefaultRESTMapper(defaultGroupVersions, interfacesFunc)
|
||||||
func NewDefaultRESTMapperFromScheme(defaultGroupVersions []unversioned.GroupVersion, interfacesFunc meta.VersionInterfacesFunc,
|
|
||||||
importPathPrefix string, ignoredKinds, rootScoped sets.String, scheme *runtime.Scheme) *meta.DefaultRESTMapper {
|
|
||||||
|
|
||||||
mapper := meta.NewDefaultRESTMapper(defaultGroupVersions, interfacesFunc)
|
|
||||||
// enumerate all supported versions, get the kinds, and register with the mapper how to address
|
// enumerate all supported versions, get the kinds, and register with the mapper how to address
|
||||||
// our resources.
|
// our resources.
|
||||||
for _, gv := range defaultGroupVersions {
|
for _, gv := range defaultGroupVersions {
|
||||||
|
@ -47,9 +40,9 @@ func NewDefaultRESTMapperFromScheme(defaultGroupVersions []unversioned.GroupVers
|
||||||
if !strings.Contains(oType.PkgPath(), importPathPrefix) || ignoredKinds.Has(kind) {
|
if !strings.Contains(oType.PkgPath(), importPathPrefix) || ignoredKinds.Has(kind) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
scope := meta.RESTScopeNamespace
|
scope := RESTScopeNamespace
|
||||||
if rootScoped.Has(kind) {
|
if rootScoped.Has(kind) {
|
||||||
scope = meta.RESTScopeRoot
|
scope = RESTScopeRoot
|
||||||
}
|
}
|
||||||
mapper.Add(gvk, scope)
|
mapper.Add(gvk, scope)
|
||||||
}
|
}
|
|
@ -16,4 +16,4 @@ limitations under the License.
|
||||||
|
|
||||||
// Package meta provides functions for retrieving API metadata from objects
|
// Package meta provides functions for retrieving API metadata from objects
|
||||||
// belonging to the Kubernetes API
|
// belonging to the Kubernetes API
|
||||||
package meta
|
package meta // import "k8s.io/apimachinery/pkg/api/meta"
|
|
@ -19,15 +19,15 @@ package meta
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"k8s.io/client-go/1.5/pkg/api/unversioned"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
)
|
)
|
||||||
|
|
||||||
// AmbiguousResourceError is returned if the RESTMapper finds multiple matches for a resource
|
// AmbiguousResourceError is returned if the RESTMapper finds multiple matches for a resource
|
||||||
type AmbiguousResourceError struct {
|
type AmbiguousResourceError struct {
|
||||||
PartialResource unversioned.GroupVersionResource
|
PartialResource schema.GroupVersionResource
|
||||||
|
|
||||||
MatchingResources []unversioned.GroupVersionResource
|
MatchingResources []schema.GroupVersionResource
|
||||||
MatchingKinds []unversioned.GroupVersionKind
|
MatchingKinds []schema.GroupVersionKind
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *AmbiguousResourceError) Error() string {
|
func (e *AmbiguousResourceError) Error() string {
|
||||||
|
@ -44,10 +44,10 @@ func (e *AmbiguousResourceError) Error() string {
|
||||||
|
|
||||||
// AmbiguousKindError is returned if the RESTMapper finds multiple matches for a kind
|
// AmbiguousKindError is returned if the RESTMapper finds multiple matches for a kind
|
||||||
type AmbiguousKindError struct {
|
type AmbiguousKindError struct {
|
||||||
PartialKind unversioned.GroupVersionKind
|
PartialKind schema.GroupVersionKind
|
||||||
|
|
||||||
MatchingResources []unversioned.GroupVersionResource
|
MatchingResources []schema.GroupVersionResource
|
||||||
MatchingKinds []unversioned.GroupVersionKind
|
MatchingKinds []schema.GroupVersionKind
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *AmbiguousKindError) Error() string {
|
func (e *AmbiguousKindError) Error() string {
|
||||||
|
@ -76,7 +76,7 @@ func IsAmbiguousError(err error) bool {
|
||||||
|
|
||||||
// NoResourceMatchError is returned if the RESTMapper can't find any match for a resource
|
// NoResourceMatchError is returned if the RESTMapper can't find any match for a resource
|
||||||
type NoResourceMatchError struct {
|
type NoResourceMatchError struct {
|
||||||
PartialResource unversioned.GroupVersionResource
|
PartialResource schema.GroupVersionResource
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *NoResourceMatchError) Error() string {
|
func (e *NoResourceMatchError) Error() string {
|
||||||
|
@ -85,7 +85,7 @@ func (e *NoResourceMatchError) Error() string {
|
||||||
|
|
||||||
// NoKindMatchError is returned if the RESTMapper can't find any match for a kind
|
// NoKindMatchError is returned if the RESTMapper can't find any match for a kind
|
||||||
type NoKindMatchError struct {
|
type NoKindMatchError struct {
|
||||||
PartialKind unversioned.GroupVersionKind
|
PartialKind schema.GroupVersionKind
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *NoKindMatchError) Error() string {
|
func (e *NoKindMatchError) Error() string {
|
|
@ -19,8 +19,8 @@ package meta
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"k8s.io/client-go/1.5/pkg/api/unversioned"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
utilerrors "k8s.io/client-go/1.5/pkg/util/errors"
|
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// FirstHitRESTMapper is a wrapper for multiple RESTMappers which returns the
|
// FirstHitRESTMapper is a wrapper for multiple RESTMappers which returns the
|
||||||
|
@ -33,7 +33,7 @@ func (m FirstHitRESTMapper) String() string {
|
||||||
return fmt.Sprintf("FirstHitRESTMapper{\n\t%v\n}", m.MultiRESTMapper)
|
return fmt.Sprintf("FirstHitRESTMapper{\n\t%v\n}", m.MultiRESTMapper)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m FirstHitRESTMapper) ResourceFor(resource unversioned.GroupVersionResource) (unversioned.GroupVersionResource, error) {
|
func (m FirstHitRESTMapper) ResourceFor(resource schema.GroupVersionResource) (schema.GroupVersionResource, error) {
|
||||||
errors := []error{}
|
errors := []error{}
|
||||||
for _, t := range m.MultiRESTMapper {
|
for _, t := range m.MultiRESTMapper {
|
||||||
ret, err := t.ResourceFor(resource)
|
ret, err := t.ResourceFor(resource)
|
||||||
|
@ -43,10 +43,10 @@ func (m FirstHitRESTMapper) ResourceFor(resource unversioned.GroupVersionResourc
|
||||||
errors = append(errors, err)
|
errors = append(errors, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return unversioned.GroupVersionResource{}, collapseAggregateErrors(errors)
|
return schema.GroupVersionResource{}, collapseAggregateErrors(errors)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m FirstHitRESTMapper) KindFor(resource unversioned.GroupVersionResource) (unversioned.GroupVersionKind, error) {
|
func (m FirstHitRESTMapper) KindFor(resource schema.GroupVersionResource) (schema.GroupVersionKind, error) {
|
||||||
errors := []error{}
|
errors := []error{}
|
||||||
for _, t := range m.MultiRESTMapper {
|
for _, t := range m.MultiRESTMapper {
|
||||||
ret, err := t.KindFor(resource)
|
ret, err := t.KindFor(resource)
|
||||||
|
@ -56,13 +56,13 @@ func (m FirstHitRESTMapper) KindFor(resource unversioned.GroupVersionResource) (
|
||||||
errors = append(errors, err)
|
errors = append(errors, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return unversioned.GroupVersionKind{}, collapseAggregateErrors(errors)
|
return schema.GroupVersionKind{}, collapseAggregateErrors(errors)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RESTMapping provides the REST mapping for the resource based on the
|
// RESTMapping provides the REST mapping for the resource based on the
|
||||||
// kind and version. This implementation supports multiple REST schemas and
|
// kind and version. This implementation supports multiple REST schemas and
|
||||||
// return the first match.
|
// return the first match.
|
||||||
func (m FirstHitRESTMapper) RESTMapping(gk unversioned.GroupKind, versions ...string) (*RESTMapping, error) {
|
func (m FirstHitRESTMapper) RESTMapping(gk schema.GroupKind, versions ...string) (*RESTMapping, error) {
|
||||||
errors := []error{}
|
errors := []error{}
|
||||||
for _, t := range m.MultiRESTMapper {
|
for _, t := range m.MultiRESTMapper {
|
||||||
ret, err := t.RESTMapping(gk, versions...)
|
ret, err := t.RESTMapping(gk, versions...)
|
|
@ -20,12 +20,18 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
"k8s.io/client-go/1.5/pkg/conversion"
|
"k8s.io/apimachinery/pkg/conversion"
|
||||||
"k8s.io/client-go/1.5/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
// IsListType returns true if the provided Object has a slice called Items
|
// IsListType returns true if the provided Object has a slice called Items
|
||||||
func IsListType(obj runtime.Object) bool {
|
func IsListType(obj runtime.Object) bool {
|
||||||
|
// if we're a runtime.Unstructured, check whether this is a list.
|
||||||
|
// TODO: refactor GetItemsPtr to use an interface that returns []runtime.Object
|
||||||
|
if unstructured, ok := obj.(runtime.Unstructured); ok {
|
||||||
|
return unstructured.IsList()
|
||||||
|
}
|
||||||
|
|
||||||
_, err := GetItemsPtr(obj)
|
_, err := GetItemsPtr(obj)
|
||||||
return err == nil
|
return err == nil
|
||||||
}
|
}
|
||||||
|
@ -39,6 +45,7 @@ func GetItemsPtr(list runtime.Object) (interface{}, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
items := v.FieldByName("Items")
|
items := v.FieldByName("Items")
|
||||||
if !items.IsValid() {
|
if !items.IsValid() {
|
||||||
return nil, fmt.Errorf("no Items field in %#v", list)
|
return nil, fmt.Errorf("no Items field in %#v", list)
|
||||||
|
@ -57,6 +64,57 @@ func GetItemsPtr(list runtime.Object) (interface{}, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EachListItem invokes fn on each runtime.Object in the list. Any error immediately terminates
|
||||||
|
// the loop.
|
||||||
|
func EachListItem(obj runtime.Object, fn func(runtime.Object) error) error {
|
||||||
|
// TODO: Change to an interface call?
|
||||||
|
itemsPtr, err := GetItemsPtr(obj)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
items, err := conversion.EnforcePtr(itemsPtr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
len := items.Len()
|
||||||
|
if len == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
takeAddr := false
|
||||||
|
if elemType := items.Type().Elem(); elemType.Kind() != reflect.Ptr && elemType.Kind() != reflect.Interface {
|
||||||
|
if !items.Index(0).CanAddr() {
|
||||||
|
return fmt.Errorf("unable to take address of items in %T for EachListItem", obj)
|
||||||
|
}
|
||||||
|
takeAddr = true
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < len; i++ {
|
||||||
|
raw := items.Index(i)
|
||||||
|
if takeAddr {
|
||||||
|
raw = raw.Addr()
|
||||||
|
}
|
||||||
|
switch item := raw.Interface().(type) {
|
||||||
|
case *runtime.RawExtension:
|
||||||
|
if err := fn(item.Object); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
case runtime.Object:
|
||||||
|
if err := fn(item); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
obj, ok := item.(runtime.Object)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("%v: item[%v]: Expected object, got %#v(%s)", obj, i, raw.Interface(), raw.Kind())
|
||||||
|
}
|
||||||
|
if err := fn(obj); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// ExtractList returns obj's Items element as an array of runtime.Objects.
|
// ExtractList returns obj's Items element as an array of runtime.Objects.
|
||||||
// Returns an error if obj is not a List type (does not have an Items member).
|
// Returns an error if obj is not a List type (does not have an Items member).
|
||||||
func ExtractList(obj runtime.Object) ([]runtime.Object, error) {
|
func ExtractList(obj runtime.Object) ([]runtime.Object, error) {
|
||||||
|
@ -117,6 +175,13 @@ func SetList(list runtime.Object, objects []runtime.Object) error {
|
||||||
slice := reflect.MakeSlice(items.Type(), len(objects), len(objects))
|
slice := reflect.MakeSlice(items.Type(), len(objects), len(objects))
|
||||||
for i := range objects {
|
for i := range objects {
|
||||||
dest := slice.Index(i)
|
dest := slice.Index(i)
|
||||||
|
|
||||||
|
// check to see if you're directly assignable
|
||||||
|
if reflect.TypeOf(objects[i]).AssignableTo(dest.Type()) {
|
||||||
|
dest.Set(reflect.ValueOf(objects[i]))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
src, err := conversion.EnforcePtr(objects[i])
|
src, err := conversion.EnforcePtr(objects[i])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
|
@ -17,10 +17,10 @@ limitations under the License.
|
||||||
package meta
|
package meta
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"k8s.io/client-go/1.5/pkg/api/meta/metatypes"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/client-go/1.5/pkg/api/unversioned"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/client-go/1.5/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
"k8s.io/client-go/1.5/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// VersionInterfaces contains the interfaces one should use for dealing with types of a particular version.
|
// VersionInterfaces contains the interfaces one should use for dealing with types of a particular version.
|
||||||
|
@ -29,45 +29,6 @@ type VersionInterfaces struct {
|
||||||
MetadataAccessor
|
MetadataAccessor
|
||||||
}
|
}
|
||||||
|
|
||||||
type ObjectMetaAccessor interface {
|
|
||||||
GetObjectMeta() Object
|
|
||||||
}
|
|
||||||
|
|
||||||
// Object lets you work with object metadata from any of the versioned or
|
|
||||||
// internal API objects. Attempting to set or retrieve a field on an object that does
|
|
||||||
// not support that field (Name, UID, Namespace on lists) will be a no-op and return
|
|
||||||
// a default value.
|
|
||||||
type Object interface {
|
|
||||||
GetNamespace() string
|
|
||||||
SetNamespace(namespace string)
|
|
||||||
GetName() string
|
|
||||||
SetName(name string)
|
|
||||||
GetGenerateName() string
|
|
||||||
SetGenerateName(name string)
|
|
||||||
GetUID() types.UID
|
|
||||||
SetUID(uid types.UID)
|
|
||||||
GetResourceVersion() string
|
|
||||||
SetResourceVersion(version string)
|
|
||||||
GetSelfLink() string
|
|
||||||
SetSelfLink(selfLink string)
|
|
||||||
GetCreationTimestamp() unversioned.Time
|
|
||||||
SetCreationTimestamp(timestamp unversioned.Time)
|
|
||||||
GetDeletionTimestamp() *unversioned.Time
|
|
||||||
SetDeletionTimestamp(timestamp *unversioned.Time)
|
|
||||||
GetLabels() map[string]string
|
|
||||||
SetLabels(labels map[string]string)
|
|
||||||
GetAnnotations() map[string]string
|
|
||||||
SetAnnotations(annotations map[string]string)
|
|
||||||
GetFinalizers() []string
|
|
||||||
SetFinalizers(finalizers []string)
|
|
||||||
GetOwnerReferences() []metatypes.OwnerReference
|
|
||||||
SetOwnerReferences([]metatypes.OwnerReference)
|
|
||||||
GetClusterName() string
|
|
||||||
SetClusterName(clusterName string)
|
|
||||||
}
|
|
||||||
|
|
||||||
var _ Object = &runtime.Unstructured{}
|
|
||||||
|
|
||||||
type ListMetaAccessor interface {
|
type ListMetaAccessor interface {
|
||||||
GetListMeta() List
|
GetListMeta() List
|
||||||
}
|
}
|
||||||
|
@ -75,10 +36,10 @@ type ListMetaAccessor interface {
|
||||||
// List lets you work with list metadata from any of the versioned or
|
// List lets you work with list metadata from any of the versioned or
|
||||||
// internal API objects. Attempting to set or retrieve a field on an object that does
|
// internal API objects. Attempting to set or retrieve a field on an object that does
|
||||||
// not support that field will be a no-op and return a default value.
|
// not support that field will be a no-op and return a default value.
|
||||||
type List unversioned.List
|
type List metav1.List
|
||||||
|
|
||||||
// Type exposes the type and APIVersion of versioned or internal API objects.
|
// Type exposes the type and APIVersion of versioned or internal API objects.
|
||||||
type Type unversioned.Type
|
type Type metav1.Type
|
||||||
|
|
||||||
// MetadataAccessor lets you work with object and list metadata from any of the versioned or
|
// MetadataAccessor lets you work with object and list metadata from any of the versioned or
|
||||||
// internal API objects. Attempting to set or retrieve a field on an object that does
|
// internal API objects. Attempting to set or retrieve a field on an object that does
|
||||||
|
@ -143,7 +104,7 @@ type RESTMapping struct {
|
||||||
// Resource is a string representing the name of this resource as a REST client would see it
|
// Resource is a string representing the name of this resource as a REST client would see it
|
||||||
Resource string
|
Resource string
|
||||||
|
|
||||||
GroupVersionKind unversioned.GroupVersionKind
|
GroupVersionKind schema.GroupVersionKind
|
||||||
|
|
||||||
// Scope contains the information needed to deal with REST Resources that are in a resource hierarchy
|
// Scope contains the information needed to deal with REST Resources that are in a resource hierarchy
|
||||||
Scope RESTScope
|
Scope RESTScope
|
||||||
|
@ -163,21 +124,23 @@ type RESTMapping struct {
|
||||||
// TODO: split into sub-interfaces
|
// TODO: split into sub-interfaces
|
||||||
type RESTMapper interface {
|
type RESTMapper interface {
|
||||||
// KindFor takes a partial resource and returns the single match. Returns an error if there are multiple matches
|
// KindFor takes a partial resource and returns the single match. Returns an error if there are multiple matches
|
||||||
KindFor(resource unversioned.GroupVersionResource) (unversioned.GroupVersionKind, error)
|
KindFor(resource schema.GroupVersionResource) (schema.GroupVersionKind, error)
|
||||||
|
|
||||||
// KindsFor takes a partial resource and returns the list of potential kinds in priority order
|
// KindsFor takes a partial resource and returns the list of potential kinds in priority order
|
||||||
KindsFor(resource unversioned.GroupVersionResource) ([]unversioned.GroupVersionKind, error)
|
KindsFor(resource schema.GroupVersionResource) ([]schema.GroupVersionKind, error)
|
||||||
|
|
||||||
// ResourceFor takes a partial resource and returns the single match. Returns an error if there are multiple matches
|
// ResourceFor takes a partial resource and returns the single match. Returns an error if there are multiple matches
|
||||||
ResourceFor(input unversioned.GroupVersionResource) (unversioned.GroupVersionResource, error)
|
ResourceFor(input schema.GroupVersionResource) (schema.GroupVersionResource, error)
|
||||||
|
|
||||||
// ResourcesFor takes a partial resource and returns the list of potential resource in priority order
|
// ResourcesFor takes a partial resource and returns the list of potential resource in priority order
|
||||||
ResourcesFor(input unversioned.GroupVersionResource) ([]unversioned.GroupVersionResource, error)
|
ResourcesFor(input schema.GroupVersionResource) ([]schema.GroupVersionResource, error)
|
||||||
|
|
||||||
// RESTMapping identifies a preferred resource mapping for the provided group kind.
|
// RESTMapping identifies a preferred resource mapping for the provided group kind.
|
||||||
RESTMapping(gk unversioned.GroupKind, versions ...string) (*RESTMapping, error)
|
RESTMapping(gk schema.GroupKind, versions ...string) (*RESTMapping, error)
|
||||||
// RESTMappings returns all resource mappings for the provided group kind.
|
// RESTMappings returns all resource mappings for the provided group kind if no
|
||||||
RESTMappings(gk unversioned.GroupKind) ([]*RESTMapping, error)
|
// version search is provided. Otherwise identifies a preferred resource mapping for
|
||||||
|
// the provided version(s).
|
||||||
|
RESTMappings(gk schema.GroupKind, versions ...string) ([]*RESTMapping, error)
|
||||||
|
|
||||||
AliasesForResource(resource string) ([]string, bool)
|
AliasesForResource(resource string) ([]string, bool)
|
||||||
ResourceSingularizer(resource string) (singular string, err error)
|
ResourceSingularizer(resource string) (singular string, err error)
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue