Bumping k8s dependencies to 1.13

This commit is contained in:
Cheng Xing
2018-11-16 14:08:25 -08:00
parent 305407125c
commit b4c0b68ec7
8002 changed files with 884099 additions and 276228 deletions

View File

@@ -20,6 +20,7 @@ import (
"encoding/json"
"fmt"
"net/http"
"reflect"
"strings"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -82,7 +83,20 @@ func (u *UnexpectedObjectError) Error() string {
func FromObject(obj runtime.Object) error {
switch t := obj.(type) {
case *metav1.Status:
return &StatusError{*t}
return &StatusError{ErrStatus: *t}
case runtime.Unstructured:
var status metav1.Status
obj := t.UnstructuredContent()
if !reflect.DeepEqual(obj["kind"], "Status") {
break
}
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(t.UnstructuredContent(), &status); err != nil {
return err
}
if status.APIVersion != "v1" && status.APIVersion != "meta.k8s.io/v1" {
break
}
return &StatusError{ErrStatus: status}
}
return &UnexpectedObjectError{obj}
}

View File

@@ -132,12 +132,12 @@ func AsPartialObjectMetadata(m metav1.Object) *metav1beta1.PartialObjectMetadata
CreationTimestamp: m.GetCreationTimestamp(),
DeletionTimestamp: m.GetDeletionTimestamp(),
DeletionGracePeriodSeconds: m.GetDeletionGracePeriodSeconds(),
Labels: m.GetLabels(),
Annotations: m.GetAnnotations(),
OwnerReferences: m.GetOwnerReferences(),
Finalizers: m.GetFinalizers(),
ClusterName: m.GetClusterName(),
Initializers: m.GetInitializers(),
Labels: m.GetLabels(),
Annotations: m.GetAnnotations(),
OwnerReferences: m.GetOwnerReferences(),
Finalizers: m.GetFinalizers(),
ClusterName: m.GetClusterName(),
Initializers: m.GetInitializers(),
},
}
}

View File

@@ -24,7 +24,7 @@ import (
)
// TestOnlyStaticRESTMapper returns a union RESTMapper of all known types with priorities chosen in the following order:
// 1. legacy kube group preferred version, extensions preferred version, metrics perferred version, legacy
// 1. legacy kube group preferred version, extensions preferred version, metrics preferred version, legacy
// kube any version, extensions any version, metrics any version, all other groups alphabetical preferred version,
// all other groups alphabetical.
// TODO callers of this method should be updated to build their own specific restmapper based on their scheme for their tests

View File

@@ -14,9 +14,8 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by protoc-gen-gogo.
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/api/resource/generated.proto
// DO NOT EDIT!
/*
Package resource is a generated protocol buffer package.

View File

@@ -27,9 +27,9 @@ option go_package = "resource";
// Quantity is a fixed-point representation of a number.
// It provides convenient marshaling/unmarshaling in JSON and YAML,
// in addition to String() and Int64() accessors.
//
//
// The serialization format is:
//
//
// <quantity> ::= <signedNumber><suffix>
// (Note that <suffix> may be empty, from the "" case in <decimalSI>.)
// <digit> ::= 0 | 1 | ... | 9
@@ -43,16 +43,16 @@ option go_package = "resource";
// <decimalSI> ::= m | "" | k | M | G | T | P | E
// (Note that 1024 = 1Ki but 1000 = 1k; I didn't choose the capitalization.)
// <decimalExponent> ::= "e" <signedNumber> | "E" <signedNumber>
//
//
// No matter which of the three exponent forms is used, no quantity may represent
// a number greater than 2^63-1 in magnitude, nor may it have more than 3 decimal
// places. Numbers larger or more precise will be capped or rounded up.
// (E.g.: 0.1m will rounded up to 1m.)
// This may be extended in the future if we require larger or smaller quantities.
//
//
// When a Quantity is parsed from a string, it will remember the type of suffix
// it had, and will use the same type again when it is serialized.
//
//
// Before serializing, Quantity will be put in "canonical form".
// This means that Exponent/suffix will be adjusted up or down (with a
// corresponding increase or decrease in Mantissa) such that:
@@ -60,22 +60,22 @@ option go_package = "resource";
// b. No fractional digits will be emitted
// c. The exponent (or suffix) is as large as possible.
// The sign will be omitted unless the number is negative.
//
//
// Examples:
// 1.5 will be serialized as "1500m"
// 1.5Gi will be serialized as "1536Mi"
//
//
// Note that the quantity will NEVER be internally represented by a
// floating point number. That is the whole point of this exercise.
//
//
// Non-canonical values will still parse as long as they are well formed,
// but will be re-emitted in their canonical form. (So always use canonical
// form, or don't diff.)
//
//
// This format is intended to make it difficult to use these numbers without
// writing some sort of special handling code in the hopes that that will
// cause implementors to also use a fixed point implementation.
//
//
// +protobuf=true
// +protobuf.embed=string
// +protobuf.options.marshal=false

9
vendor/k8s.io/apimachinery/pkg/apis/OWNERS generated vendored Normal file
View File

@@ -0,0 +1,9 @@
# Disable inheritance as this is an api owners file
options:
no_parent_owners: true
approvers:
- api-approvers
reviewers:
- api-reviewers
labels:
- kind/api-change

View File

@@ -19,4 +19,5 @@ limitations under the License.
// +k8s:defaulter-gen=TypeMeta
// +groupName=meta.k8s.io
package v1 // import "k8s.io/apimachinery/pkg/apis/meta/v1"

View File

@@ -14,9 +14,8 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by protoc-gen-gogo.
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto
// DO NOT EDIT!
/*
Package v1 is a generated protocol buffer package.
@@ -1768,24 +1767,6 @@ func (m *WatchEvent) MarshalTo(dAtA []byte) (int, error) {
return i, nil
}
func encodeFixed64Generated(dAtA []byte, offset int, v uint64) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
dAtA[offset+2] = uint8(v >> 16)
dAtA[offset+3] = uint8(v >> 24)
dAtA[offset+4] = uint8(v >> 32)
dAtA[offset+5] = uint8(v >> 40)
dAtA[offset+6] = uint8(v >> 48)
dAtA[offset+7] = uint8(v >> 56)
return offset + 8
}
func encodeFixed32Generated(dAtA []byte, offset int, v uint32) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
dAtA[offset+2] = uint8(v >> 16)
dAtA[offset+3] = uint8(v >> 24)
return offset + 4
}
func encodeVarintGenerated(dAtA []byte, offset int, v uint64) int {
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
@@ -5043,51 +5024,14 @@ func (m *LabelSelector) Unmarshal(dAtA []byte) error {
if postIndex > l {
return io.ErrUnexpectedEOF
}
var keykey uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
keykey |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
var stringLenmapkey uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLenmapkey |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLenmapkey := int(stringLenmapkey)
if intStringLenmapkey < 0 {
return ErrInvalidLengthGenerated
}
postStringIndexmapkey := iNdEx + intStringLenmapkey
if postStringIndexmapkey > l {
return io.ErrUnexpectedEOF
}
mapkey := string(dAtA[iNdEx:postStringIndexmapkey])
iNdEx = postStringIndexmapkey
if m.MatchLabels == nil {
m.MatchLabels = make(map[string]string)
}
if iNdEx < postIndex {
var valuekey uint64
var mapkey string
var mapvalue string
for iNdEx < postIndex {
entryPreIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
@@ -5097,41 +5041,80 @@ func (m *LabelSelector) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
valuekey |= (uint64(b) & 0x7F) << shift
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
var stringLenmapvalue uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
fieldNum := int32(wire >> 3)
if fieldNum == 1 {
var stringLenmapkey uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLenmapkey |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if iNdEx >= l {
intStringLenmapkey := int(stringLenmapkey)
if intStringLenmapkey < 0 {
return ErrInvalidLengthGenerated
}
postStringIndexmapkey := iNdEx + intStringLenmapkey
if postStringIndexmapkey > l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLenmapvalue |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
mapkey = string(dAtA[iNdEx:postStringIndexmapkey])
iNdEx = postStringIndexmapkey
} else if fieldNum == 2 {
var stringLenmapvalue uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLenmapvalue |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLenmapvalue := int(stringLenmapvalue)
if intStringLenmapvalue < 0 {
return ErrInvalidLengthGenerated
}
postStringIndexmapvalue := iNdEx + intStringLenmapvalue
if postStringIndexmapvalue > l {
return io.ErrUnexpectedEOF
}
mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue])
iNdEx = postStringIndexmapvalue
} else {
iNdEx = entryPreIndex
skippy, err := skipGenerated(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthGenerated
}
if (iNdEx + skippy) > postIndex {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
intStringLenmapvalue := int(stringLenmapvalue)
if intStringLenmapvalue < 0 {
return ErrInvalidLengthGenerated
}
postStringIndexmapvalue := iNdEx + intStringLenmapvalue
if postStringIndexmapvalue > l {
return io.ErrUnexpectedEOF
}
mapvalue := string(dAtA[iNdEx:postStringIndexmapvalue])
iNdEx = postStringIndexmapvalue
m.MatchLabels[mapkey] = mapvalue
} else {
var mapvalue string
m.MatchLabels[mapkey] = mapvalue
}
m.MatchLabels[mapkey] = mapvalue
iNdEx = postIndex
case 2:
if wireType != 2 {
@@ -6146,51 +6129,14 @@ func (m *ObjectMeta) Unmarshal(dAtA []byte) error {
if postIndex > l {
return io.ErrUnexpectedEOF
}
var keykey uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
keykey |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
var stringLenmapkey uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLenmapkey |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLenmapkey := int(stringLenmapkey)
if intStringLenmapkey < 0 {
return ErrInvalidLengthGenerated
}
postStringIndexmapkey := iNdEx + intStringLenmapkey
if postStringIndexmapkey > l {
return io.ErrUnexpectedEOF
}
mapkey := string(dAtA[iNdEx:postStringIndexmapkey])
iNdEx = postStringIndexmapkey
if m.Labels == nil {
m.Labels = make(map[string]string)
}
if iNdEx < postIndex {
var valuekey uint64
var mapkey string
var mapvalue string
for iNdEx < postIndex {
entryPreIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
@@ -6200,41 +6146,80 @@ func (m *ObjectMeta) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
valuekey |= (uint64(b) & 0x7F) << shift
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
var stringLenmapvalue uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
fieldNum := int32(wire >> 3)
if fieldNum == 1 {
var stringLenmapkey uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLenmapkey |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if iNdEx >= l {
intStringLenmapkey := int(stringLenmapkey)
if intStringLenmapkey < 0 {
return ErrInvalidLengthGenerated
}
postStringIndexmapkey := iNdEx + intStringLenmapkey
if postStringIndexmapkey > l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLenmapvalue |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
mapkey = string(dAtA[iNdEx:postStringIndexmapkey])
iNdEx = postStringIndexmapkey
} else if fieldNum == 2 {
var stringLenmapvalue uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLenmapvalue |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLenmapvalue := int(stringLenmapvalue)
if intStringLenmapvalue < 0 {
return ErrInvalidLengthGenerated
}
postStringIndexmapvalue := iNdEx + intStringLenmapvalue
if postStringIndexmapvalue > l {
return io.ErrUnexpectedEOF
}
mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue])
iNdEx = postStringIndexmapvalue
} else {
iNdEx = entryPreIndex
skippy, err := skipGenerated(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthGenerated
}
if (iNdEx + skippy) > postIndex {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
intStringLenmapvalue := int(stringLenmapvalue)
if intStringLenmapvalue < 0 {
return ErrInvalidLengthGenerated
}
postStringIndexmapvalue := iNdEx + intStringLenmapvalue
if postStringIndexmapvalue > l {
return io.ErrUnexpectedEOF
}
mapvalue := string(dAtA[iNdEx:postStringIndexmapvalue])
iNdEx = postStringIndexmapvalue
m.Labels[mapkey] = mapvalue
} else {
var mapvalue string
m.Labels[mapkey] = mapvalue
}
m.Labels[mapkey] = mapvalue
iNdEx = postIndex
case 12:
if wireType != 2 {
@@ -6262,51 +6247,14 @@ func (m *ObjectMeta) Unmarshal(dAtA []byte) error {
if postIndex > l {
return io.ErrUnexpectedEOF
}
var keykey uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
keykey |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
var stringLenmapkey uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLenmapkey |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLenmapkey := int(stringLenmapkey)
if intStringLenmapkey < 0 {
return ErrInvalidLengthGenerated
}
postStringIndexmapkey := iNdEx + intStringLenmapkey
if postStringIndexmapkey > l {
return io.ErrUnexpectedEOF
}
mapkey := string(dAtA[iNdEx:postStringIndexmapkey])
iNdEx = postStringIndexmapkey
if m.Annotations == nil {
m.Annotations = make(map[string]string)
}
if iNdEx < postIndex {
var valuekey uint64
var mapkey string
var mapvalue string
for iNdEx < postIndex {
entryPreIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
@@ -6316,41 +6264,80 @@ func (m *ObjectMeta) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
valuekey |= (uint64(b) & 0x7F) << shift
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
var stringLenmapvalue uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
fieldNum := int32(wire >> 3)
if fieldNum == 1 {
var stringLenmapkey uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLenmapkey |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if iNdEx >= l {
intStringLenmapkey := int(stringLenmapkey)
if intStringLenmapkey < 0 {
return ErrInvalidLengthGenerated
}
postStringIndexmapkey := iNdEx + intStringLenmapkey
if postStringIndexmapkey > l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLenmapvalue |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
mapkey = string(dAtA[iNdEx:postStringIndexmapkey])
iNdEx = postStringIndexmapkey
} else if fieldNum == 2 {
var stringLenmapvalue uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLenmapvalue |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLenmapvalue := int(stringLenmapvalue)
if intStringLenmapvalue < 0 {
return ErrInvalidLengthGenerated
}
postStringIndexmapvalue := iNdEx + intStringLenmapvalue
if postStringIndexmapvalue > l {
return io.ErrUnexpectedEOF
}
mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue])
iNdEx = postStringIndexmapvalue
} else {
iNdEx = entryPreIndex
skippy, err := skipGenerated(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthGenerated
}
if (iNdEx + skippy) > postIndex {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
intStringLenmapvalue := int(stringLenmapvalue)
if intStringLenmapvalue < 0 {
return ErrInvalidLengthGenerated
}
postStringIndexmapvalue := iNdEx + intStringLenmapvalue
if postStringIndexmapvalue > l {
return io.ErrUnexpectedEOF
}
mapvalue := string(dAtA[iNdEx:postStringIndexmapvalue])
iNdEx = postStringIndexmapvalue
m.Annotations[mapkey] = mapvalue
} else {
var mapvalue string
m.Annotations[mapkey] = mapvalue
}
m.Annotations[mapkey] = mapvalue
iNdEx = postIndex
case 13:
if wireType != 2 {

View File

@@ -107,7 +107,7 @@ message APIResourceList {
// APIVersions lists the versions that are available, to allow clients to
// discover the API at /api, which is the root path of the legacy v1 API.
//
//
// +protobuf.options.(gogoproto.goproto_stringer)=false
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
message APIVersions {
@@ -211,7 +211,7 @@ message GetOptions {
// GroupKind specifies a Group and a Kind, but does not force a version. This is useful for identifying
// concepts during lookup stages without having partially valid types
//
//
// +protobuf.options.(gogoproto.goproto_stringer)=false
message GroupKind {
optional string group = 1;
@@ -221,7 +221,7 @@ message GroupKind {
// GroupResource specifies a Group and a Resource, but does not force a version. This is useful for identifying
// concepts during lookup stages without having partially valid types
//
//
// +protobuf.options.(gogoproto.goproto_stringer)=false
message GroupResource {
optional string group = 1;
@@ -230,7 +230,7 @@ message GroupResource {
}
// GroupVersion contains the "group" and the "version", which uniquely identifies the API.
//
//
// +protobuf.options.(gogoproto.goproto_stringer)=false
message GroupVersion {
optional string group = 1;
@@ -251,7 +251,7 @@ message GroupVersionForDiscovery {
// GroupVersionKind unambiguously identifies a kind. It doesn't anonymously include GroupVersion
// to avoid automatic coersion. It doesn't use a GroupVersion to avoid custom marshalling
//
//
// +protobuf.options.(gogoproto.goproto_stringer)=false
message GroupVersionKind {
optional string group = 1;
@@ -263,7 +263,7 @@ message GroupVersionKind {
// GroupVersionResource unambiguously identifies a resource. It doesn't anonymously include GroupVersion
// to avoid automatic coersion. It doesn't use a GroupVersion to avoid custom marshalling
//
//
// +protobuf.options.(gogoproto.goproto_stringer)=false
message GroupVersionResource {
optional string group = 1;
@@ -411,7 +411,7 @@ message ListOptions {
// more results are available. Servers may choose not to support the limit argument and will return
// all of the available results. If limit is specified and the continue field is empty, clients may
// assume that no more results are available. This field is not supported if watch is true.
//
//
// The server guarantees that the objects returned when using continue will be identical to issuing
// a single list call without a limit - that is, no objects created, modified, or deleted after the
// first request is issued will be included in any subsequent continued requests. This is sometimes
@@ -432,14 +432,14 @@ message ListOptions {
// a list starting from the next key, but from the latest snapshot, which is inconsistent from the
// previous list results - objects that are created, modified, or deleted after the first list request
// will be included in the response, as long as their keys are after the "next key".
//
//
// This field is not supported when watch is true. Clients may start a watch from the last
// resourceVersion value returned by the server and not miss any modifications.
optional string continue = 8;
}
// MicroTime is version of Time with microsecond level precision.
//
//
// +protobuf.options.marshal=false
// +protobuf.as=Timestamp
// +protobuf.options.(gogoproto.goproto_stringer)=false
@@ -475,12 +475,12 @@ message ObjectMeta {
// The provided value has the same validation rules as the Name field,
// and may be truncated by the length of the suffix required to make the value
// unique on the server.
//
//
// If this field is specified and the generated name exists, the server will
// NOT return a 409 - instead, it will either return 201 Created or 500 with Reason
// ServerTimeout indicating a unique name could not be found in the time allotted, and the client
// should retry (optionally after the time indicated in the Retry-After header).
//
//
// Applied only if Name is not specified.
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#idempotency
// +optional
@@ -490,7 +490,7 @@ message ObjectMeta {
// equivalent to the "default" namespace, but "default" is the canonical representation.
// Not all objects are required to be scoped to a namespace - the value of this field for
// those objects will be empty.
//
//
// Must be a DNS_LABEL.
// Cannot be updated.
// More info: http://kubernetes.io/docs/user-guide/namespaces
@@ -506,7 +506,7 @@ message ObjectMeta {
// UID is the unique in time and space value for this object. It is typically generated by
// the server on successful creation of a resource and is not allowed to change on PUT
// operations.
//
//
// Populated by the system.
// Read-only.
// More info: http://kubernetes.io/docs/user-guide/identifiers#uids
@@ -518,7 +518,7 @@ message ObjectMeta {
// concurrency, change detection, and the watch operation on a resource or set of resources.
// Clients must treat these values as opaque and passed unmodified back to the server.
// They may only be valid for a particular resource or set of resources.
//
//
// Populated by the system.
// Read-only.
// Value must be treated as opaque by clients and .
@@ -534,7 +534,7 @@ message ObjectMeta {
// CreationTimestamp is a timestamp representing the server time when this object was
// created. It is not guaranteed to be set in happens-before order across separate operations.
// Clients may not set this value. It is represented in RFC3339 form and is in UTC.
//
//
// Populated by the system.
// Read-only.
// Null for lists.
@@ -556,7 +556,7 @@ message ObjectMeta {
// exist after this timestamp, until an administrator or automated process can determine the
// resource is fully terminated.
// If not set, graceful deletion of the object has not been requested.
//
//
// Populated by the system when a graceful deletion is requested.
// Read-only.
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata
@@ -598,7 +598,7 @@ message ObjectMeta {
// this object has been completely initialized. Otherwise, the object is considered uninitialized
// and is hidden (in list/watch and get calls) from clients that haven't explicitly asked to
// observe uninitialized objects.
//
//
// When an object is created, the system will populate this list with the current set of initializers.
// Only privileged users may set or modify this list. Once it is empty, it may not be modified further
// by any user.
@@ -620,8 +620,8 @@ message ObjectMeta {
}
// OwnerReference contains enough information to let you identify an owning
// object. Currently, an owning object must be in the same namespace, so there
// is no namespace field.
// object. An owning object must be in the same namespace as the dependent, or
// be cluster-scoped, so there is no namespace field.
message OwnerReference {
// API version of the referent.
optional string apiVersion = 5;
@@ -734,7 +734,7 @@ message StatusCause {
// Arrays are zero-indexed. Fields may appear more than once in an array of
// causes due to fields having multiple errors.
// Optional.
//
//
// Examples:
// "name" - the field "name" on the current resource
// "items[0].name" - the field "name" on the first array entry in "items"
@@ -785,7 +785,7 @@ message StatusDetails {
// Time is a wrapper around time.Time which supports correct
// marshaling to YAML and JSON. Wrappers are provided for many
// of the factory methods that the time package offers.
//
//
// +protobuf.options.marshal=false
// +protobuf.as=Timestamp
// +protobuf.options.(gogoproto.goproto_stringer)=false
@@ -821,7 +821,7 @@ message Timestamp {
// TypeMeta describes an individual object in an API response or request
// with strings representing the type of the object and its API schema version.
// Structures that are versioned or persisted should inline TypeMeta.
//
//
// +k8s:deepcopy-gen=false
message TypeMeta {
// Kind is a string value representing the REST resource this object represents.
@@ -852,7 +852,7 @@ message UpdateOptions {
}
// Verbs masks the value so protobuf can generate
//
//
// +protobuf.nullable=true
// +protobuf.options.(gogoproto.goproto_stringer)=false
message Verbs {
@@ -862,7 +862,7 @@ message Verbs {
}
// Event represents a single event to a watched resource.
//
//
// +protobuf=true
// +k8s:deepcopy-gen=true
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

View File

@@ -35,8 +35,8 @@ func TestMicroTimeMarshalYAML(t *testing.T) {
result string
}{
{MicroTime{}, "t: null\n"},
{DateMicro(1998, time.May, 5, 1, 5, 5, 50, time.FixedZone("test", -4*60*60)), "t: 1998-05-05T05:05:05.000000Z\n"},
{DateMicro(1998, time.May, 5, 5, 5, 5, 0, time.UTC), "t: 1998-05-05T05:05:05.000000Z\n"},
{DateMicro(1998, time.May, 5, 1, 5, 5, 50, time.FixedZone("test", -4*60*60)), "t: \"1998-05-05T05:05:05.000000Z\"\n"},
{DateMicro(1998, time.May, 5, 5, 5, 5, 0, time.UTC), "t: \"1998-05-05T05:05:05.000000Z\"\n"},
}
for _, c := range cases {

View File

@@ -35,8 +35,8 @@ func TestTimeMarshalYAML(t *testing.T) {
result string
}{
{Time{}, "t: null\n"},
{Date(1998, time.May, 5, 1, 5, 5, 50, time.FixedZone("test", -4*60*60)), "t: 1998-05-05T05:05:05Z\n"},
{Date(1998, time.May, 5, 5, 5, 5, 0, time.UTC), "t: 1998-05-05T05:05:05Z\n"},
{Date(1998, time.May, 5, 1, 5, 5, 50, time.FixedZone("test", -4*60*60)), "t: \"1998-05-05T05:05:05Z\"\n"},
{Date(1998, time.May, 5, 5, 5, 5, 0, time.UTC), "t: \"1998-05-05T05:05:05Z\"\n"},
}
for _, c := range cases {

View File

@@ -286,8 +286,8 @@ const (
)
// OwnerReference contains enough information to let you identify an owning
// object. Currently, an owning object must be in the same namespace, so there
// is no namespace field.
// object. An owning object must be in the same namespace as the dependent, or
// be cluster-scoped, so there is no namespace field.
type OwnerReference struct {
// API version of the referent.
APIVersion string `json:"apiVersion" protobuf:"bytes,5,opt,name=apiVersion"`

View File

@@ -240,7 +240,7 @@ func (ObjectMeta) SwaggerDoc() map[string]string {
}
var map_OwnerReference = map[string]string{
"": "OwnerReference contains enough information to let you identify an owning object. Currently, an owning object must be in the same namespace, so there is no namespace field.",
"": "OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.",
"apiVersion": "API version of the referent.",
"kind": "Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds",
"name": "Name of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#names",

View File

@@ -19,4 +19,5 @@ limitations under the License.
// +k8s:defaulter-gen=TypeMeta
// +groupName=meta.k8s.io
package v1beta1

View File

@@ -14,9 +14,8 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by protoc-gen-gogo.
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1/generated.proto
// DO NOT EDIT!
/*
Package v1beta1 is a generated protocol buffer package.
@@ -148,24 +147,6 @@ func (m *TableOptions) MarshalTo(dAtA []byte) (int, error) {
return i, nil
}
func encodeFixed64Generated(dAtA []byte, offset int, v uint64) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
dAtA[offset+2] = uint8(v >> 16)
dAtA[offset+3] = uint8(v >> 24)
dAtA[offset+4] = uint8(v >> 32)
dAtA[offset+5] = uint8(v >> 40)
dAtA[offset+6] = uint8(v >> 48)
dAtA[offset+7] = uint8(v >> 56)
return offset + 8
}
func encodeFixed32Generated(dAtA []byte, offset int, v uint32) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
dAtA[offset+2] = uint8(v >> 16)
dAtA[offset+3] = uint8(v >> 24)
return offset + 4
}
func encodeVarintGenerated(dAtA []byte, offset int, v uint64) int {
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)

View File

@@ -20,4 +20,5 @@ limitations under the License.
// +k8s:defaulter-gen=TypeMeta
// +groupName=testapigroup.apimachinery.k8s.io
package v1 // import "k8s.io/apimachinery/pkg/apis/testapigroup/v1"

View File

@@ -14,9 +14,8 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by protoc-gen-gogo.
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/apis/testapigroup/v1/generated.proto
// DO NOT EDIT!
/*
Package v1 is a generated protocol buffer package.
@@ -382,24 +381,6 @@ func (m *CarpStatus) MarshalTo(dAtA []byte) (int, error) {
return i, nil
}
func encodeFixed64Generated(dAtA []byte, offset int, v uint64) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
dAtA[offset+2] = uint8(v >> 16)
dAtA[offset+3] = uint8(v >> 24)
dAtA[offset+4] = uint8(v >> 32)
dAtA[offset+5] = uint8(v >> 40)
dAtA[offset+6] = uint8(v >> 48)
dAtA[offset+7] = uint8(v >> 56)
return offset + 8
}
func encodeFixed32Generated(dAtA []byte, offset int, v uint32) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
dAtA[offset+2] = uint8(v >> 16)
dAtA[offset+3] = uint8(v >> 24)
return offset + 4
}
func encodeVarintGenerated(dAtA []byte, offset int, v uint64) int {
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
@@ -1224,51 +1205,14 @@ func (m *CarpSpec) Unmarshal(dAtA []byte) error {
if postIndex > l {
return io.ErrUnexpectedEOF
}
var keykey uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
keykey |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
var stringLenmapkey uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLenmapkey |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLenmapkey := int(stringLenmapkey)
if intStringLenmapkey < 0 {
return ErrInvalidLengthGenerated
}
postStringIndexmapkey := iNdEx + intStringLenmapkey
if postStringIndexmapkey > l {
return io.ErrUnexpectedEOF
}
mapkey := string(dAtA[iNdEx:postStringIndexmapkey])
iNdEx = postStringIndexmapkey
if m.NodeSelector == nil {
m.NodeSelector = make(map[string]string)
}
if iNdEx < postIndex {
var valuekey uint64
var mapkey string
var mapvalue string
for iNdEx < postIndex {
entryPreIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
@@ -1278,41 +1222,80 @@ func (m *CarpSpec) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
valuekey |= (uint64(b) & 0x7F) << shift
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
var stringLenmapvalue uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
fieldNum := int32(wire >> 3)
if fieldNum == 1 {
var stringLenmapkey uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLenmapkey |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if iNdEx >= l {
intStringLenmapkey := int(stringLenmapkey)
if intStringLenmapkey < 0 {
return ErrInvalidLengthGenerated
}
postStringIndexmapkey := iNdEx + intStringLenmapkey
if postStringIndexmapkey > l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLenmapvalue |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
mapkey = string(dAtA[iNdEx:postStringIndexmapkey])
iNdEx = postStringIndexmapkey
} else if fieldNum == 2 {
var stringLenmapvalue uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLenmapvalue |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLenmapvalue := int(stringLenmapvalue)
if intStringLenmapvalue < 0 {
return ErrInvalidLengthGenerated
}
postStringIndexmapvalue := iNdEx + intStringLenmapvalue
if postStringIndexmapvalue > l {
return io.ErrUnexpectedEOF
}
mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue])
iNdEx = postStringIndexmapvalue
} else {
iNdEx = entryPreIndex
skippy, err := skipGenerated(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthGenerated
}
if (iNdEx + skippy) > postIndex {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
intStringLenmapvalue := int(stringLenmapvalue)
if intStringLenmapvalue < 0 {
return ErrInvalidLengthGenerated
}
postStringIndexmapvalue := iNdEx + intStringLenmapvalue
if postStringIndexmapvalue > l {
return io.ErrUnexpectedEOF
}
mapvalue := string(dAtA[iNdEx:postStringIndexmapvalue])
iNdEx = postStringIndexmapvalue
m.NodeSelector[mapkey] = mapvalue
} else {
var mapvalue string
m.NodeSelector[mapkey] = mapvalue
}
m.NodeSelector[mapkey] = mapvalue
iNdEx = postIndex
case 8:
if wireType != 2 {

View File

@@ -333,7 +333,7 @@ func TestConverter_IgnoredConversionNested(t *testing.T) {
}
}
func TestConverter_GeneratedConversionOverriden(t *testing.T) {
func TestConverter_GeneratedConversionOverridden(t *testing.T) {
type A struct{}
type B struct{}
c := NewConverter(DefaultNameFunc)
@@ -355,7 +355,7 @@ func TestConverter_GeneratedConversionOverriden(t *testing.T) {
}
}
func TestConverter_WithConversionOverriden(t *testing.T) {
func TestConverter_WithConversionOverridden(t *testing.T) {
type A struct{}
type B struct{}
c := NewConverter(DefaultNameFunc)

View File

@@ -14,9 +14,8 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by protoc-gen-gogo.
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/runtime/generated.proto
// DO NOT EDIT!
/*
Package runtime is a generated protocol buffer package.
@@ -158,24 +157,6 @@ func (m *Unknown) MarshalTo(dAtA []byte) (int, error) {
return i, nil
}
func encodeFixed64Generated(dAtA []byte, offset int, v uint64) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
dAtA[offset+2] = uint8(v >> 16)
dAtA[offset+3] = uint8(v >> 24)
dAtA[offset+4] = uint8(v >> 32)
dAtA[offset+5] = uint8(v >> 40)
dAtA[offset+6] = uint8(v >> 48)
dAtA[offset+7] = uint8(v >> 56)
return offset + 8
}
func encodeFixed32Generated(dAtA []byte, offset int, v uint32) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
dAtA[offset+2] = uint8(v >> 16)
dAtA[offset+3] = uint8(v >> 24)
return offset + 4
}
func encodeVarintGenerated(dAtA []byte, offset int, v uint64) int {
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)

View File

@@ -25,11 +25,11 @@ package k8s.io.apimachinery.pkg.runtime;
option go_package = "runtime";
// RawExtension is used to hold extensions in external versions.
//
//
// To use this, make a field which has RawExtension as its type in your external, versioned
// struct, and Object in your internal struct. You also need to register your
// various plugin types.
//
//
// // Internal package:
// type MyAPIObject struct {
// runtime.TypeMeta `json:",inline"`
@@ -38,7 +38,7 @@ option go_package = "runtime";
// type PluginA struct {
// AOption string `json:"aOption"`
// }
//
//
// // External package:
// type MyAPIObject struct {
// runtime.TypeMeta `json:",inline"`
@@ -47,7 +47,7 @@ option go_package = "runtime";
// type PluginA struct {
// AOption string `json:"aOption"`
// }
//
//
// // On the wire, the JSON will look something like this:
// {
// "kind":"MyAPIObject",
@@ -57,7 +57,7 @@ option go_package = "runtime";
// "aOption":"foo",
// },
// }
//
//
// So what happens? Decode first uses json or yaml to unmarshal the serialized data into
// your external MyAPIObject. That causes the raw JSON to be stored, but not unpacked.
// The next step is to copy (using pkg/conversion) into the internal struct. The runtime
@@ -65,13 +65,13 @@ option go_package = "runtime";
// JSON stored in RawExtension, turning it into the correct object type, and storing it
// in the Object. (TODO: In the case where the object is of an unknown type, a
// runtime.Unknown object will be created and stored.)
//
//
// +k8s:deepcopy-gen=true
// +protobuf=true
// +k8s:openapi-gen=true
message RawExtension {
// Raw is the underlying serialization of this object.
//
//
// TODO: Determine how to detect ContentType and ContentEncoding of 'Raw' data.
optional bytes raw = 1;
}
@@ -83,10 +83,10 @@ message RawExtension {
// ... // other fields
// }
// func (obj *MyAwesomeAPIObject) SetGroupVersionKind(gvk *metav1.GroupVersionKind) { metav1.UpdateTypeMeta(obj,gvk) }; GroupVersionKind() *GroupVersionKind
//
//
// TypeMeta is provided here for convenience. You may use it directly from this package or define
// your own with the same fields.
//
//
// +k8s:deepcopy-gen=false
// +protobuf=true
// +k8s:openapi-gen=true
@@ -103,7 +103,7 @@ message TypeMeta {
// TypeMeta features-- kind, version, etc.
// TODO: Make this object have easy access to field based accessors and settors for
// metadata and field mutatation.
//
//
// +k8s:deepcopy-gen=true
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +protobuf=true

View File

@@ -14,9 +14,8 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by protoc-gen-gogo.
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/runtime/schema/generated.proto
// DO NOT EDIT!
/*
Package schema is a generated protocol buffer package.

View File

@@ -66,7 +66,7 @@ func (gr GroupResource) Empty() bool {
return len(gr.Group) == 0 && len(gr.Resource) == 0
}
func (gr *GroupResource) String() string {
func (gr GroupResource) String() string {
if len(gr.Group) == 0 {
return gr.Resource
}
@@ -111,7 +111,7 @@ func (gvr GroupVersionResource) GroupVersion() GroupVersion {
return GroupVersion{Group: gvr.Group, Version: gvr.Version}
}
func (gvr *GroupVersionResource) String() string {
func (gvr GroupVersionResource) String() string {
return strings.Join([]string{gvr.Group, "/", gvr.Version, ", Resource=", gvr.Resource}, "")
}
@@ -130,7 +130,7 @@ func (gk GroupKind) WithVersion(version string) GroupVersionKind {
return GroupVersionKind{Group: gk.Group, Version: version, Kind: gk.Kind}
}
func (gk *GroupKind) String() string {
func (gk GroupKind) String() string {
if len(gk.Group) == 0 {
return gk.Kind
}
@@ -281,8 +281,8 @@ func bestMatch(kinds []GroupVersionKind, targets []GroupVersionKind) GroupVersio
// ToAPIVersionAndKind is a convenience method for satisfying runtime.Object on types that
// do not use TypeMeta.
func (gvk *GroupVersionKind) ToAPIVersionAndKind() (string, string) {
if gvk == nil {
func (gvk GroupVersionKind) ToAPIVersionAndKind() (string, string) {
if gvk.Empty() {
return "", ""
}
return gvk.GroupVersion().String(), gvk.Kind

View File

@@ -670,7 +670,7 @@ func TestConvertToVersion(t *testing.T) {
gv: schema.GroupVersions{{Version: runtime.APIVersionInternal}, {Version: "v1"}},
out: &runtimetesting.ExternalTestType1{
MyWeirdCustomEmbeddedVersionKindField: runtimetesting.MyWeirdCustomEmbeddedVersionKindField{APIVersion: "v1", ObjectKind: "TestType1"},
A: "test",
A: "test",
},
},
// unversioned type returned as-is
@@ -681,7 +681,7 @@ func TestConvertToVersion(t *testing.T) {
same: true,
out: &runtimetesting.UnversionedType{
MyWeirdCustomEmbeddedVersionKindField: runtimetesting.MyWeirdCustomEmbeddedVersionKindField{APIVersion: "v1", ObjectKind: "UnversionedType"},
A: "test",
A: "test",
},
},
// unversioned type returned when not included in the target types
@@ -692,7 +692,7 @@ func TestConvertToVersion(t *testing.T) {
same: true,
out: &runtimetesting.UnversionedType{
MyWeirdCustomEmbeddedVersionKindField: runtimetesting.MyWeirdCustomEmbeddedVersionKindField{APIVersion: "v1", ObjectKind: "UnversionedType"},
A: "test",
A: "test",
},
},
// detected as already being in the target version
@@ -703,7 +703,7 @@ func TestConvertToVersion(t *testing.T) {
same: true,
out: &runtimetesting.ExternalTestType1{
MyWeirdCustomEmbeddedVersionKindField: runtimetesting.MyWeirdCustomEmbeddedVersionKindField{APIVersion: "v1", ObjectKind: "TestType1"},
A: "test",
A: "test",
},
},
// detected as already being in the first target version
@@ -714,7 +714,7 @@ func TestConvertToVersion(t *testing.T) {
same: true,
out: &runtimetesting.ExternalTestType1{
MyWeirdCustomEmbeddedVersionKindField: runtimetesting.MyWeirdCustomEmbeddedVersionKindField{APIVersion: "v1", ObjectKind: "TestType1"},
A: "test",
A: "test",
},
},
// detected as already being in the first target version
@@ -725,7 +725,7 @@ func TestConvertToVersion(t *testing.T) {
same: true,
out: &runtimetesting.ExternalTestType1{
MyWeirdCustomEmbeddedVersionKindField: runtimetesting.MyWeirdCustomEmbeddedVersionKindField{APIVersion: "v1", ObjectKind: "TestType1"},
A: "test",
A: "test",
},
},
// the external type is registered in multiple groups, versions, and kinds, and can be targeted to all of them (1/3): different kind
@@ -736,7 +736,7 @@ func TestConvertToVersion(t *testing.T) {
same: true,
out: &runtimetesting.ExternalTestType1{
MyWeirdCustomEmbeddedVersionKindField: runtimetesting.MyWeirdCustomEmbeddedVersionKindField{APIVersion: "v1", ObjectKind: "TestType3"},
A: "test",
A: "test",
},
},
// the external type is registered in multiple groups, versions, and kinds, and can be targeted to all of them (2/3): different gv
@@ -747,7 +747,7 @@ func TestConvertToVersion(t *testing.T) {
same: true,
out: &runtimetesting.ExternalTestType1{
MyWeirdCustomEmbeddedVersionKindField: runtimetesting.MyWeirdCustomEmbeddedVersionKindField{APIVersion: "custom/v1", ObjectKind: "TestType3"},
A: "test",
A: "test",
},
},
// the external type is registered in multiple groups, versions, and kinds, and can be targeted to all of them (3/3): different gvk
@@ -758,7 +758,7 @@ func TestConvertToVersion(t *testing.T) {
same: true,
out: &runtimetesting.ExternalTestType1{
MyWeirdCustomEmbeddedVersionKindField: runtimetesting.MyWeirdCustomEmbeddedVersionKindField{APIVersion: "custom/v1", ObjectKind: "TestType5"},
A: "test",
A: "test",
},
},
// multi group versioner recognizes multiple groups and forces the output to a particular version, copies because version differs
@@ -768,7 +768,7 @@ func TestConvertToVersion(t *testing.T) {
gv: runtime.NewMultiGroupVersioner(schema.GroupVersion{Group: "other", Version: "v2"}, schema.GroupKind{Group: "custom", Kind: "TestType3"}, schema.GroupKind{Kind: "TestType1"}),
out: &runtimetesting.ExternalTestType1{
MyWeirdCustomEmbeddedVersionKindField: runtimetesting.MyWeirdCustomEmbeddedVersionKindField{APIVersion: "other/v2", ObjectKind: "TestType1"},
A: "test",
A: "test",
},
},
// multi group versioner recognizes multiple groups and forces the output to a particular version, copies because version differs
@@ -778,7 +778,7 @@ func TestConvertToVersion(t *testing.T) {
gv: runtime.NewMultiGroupVersioner(schema.GroupVersion{Group: "other", Version: "v2"}, schema.GroupKind{Kind: "TestType1"}, schema.GroupKind{Group: "custom", Kind: "TestType3"}),
out: &runtimetesting.ExternalTestType1{
MyWeirdCustomEmbeddedVersionKindField: runtimetesting.MyWeirdCustomEmbeddedVersionKindField{APIVersion: "other/v2", ObjectKind: "TestType1"},
A: "test",
A: "test",
},
},
// multi group versioner is unable to find a match when kind AND group don't match (there is no TestType1 kind in group "other", and no kind "TestType5" in the default group)
@@ -798,7 +798,7 @@ func TestConvertToVersion(t *testing.T) {
same: true,
out: &runtimetesting.ExternalTestType1{
MyWeirdCustomEmbeddedVersionKindField: runtimetesting.MyWeirdCustomEmbeddedVersionKindField{APIVersion: "v1", ObjectKind: "TestType1"},
A: "test",
A: "test",
},
},
// multi group versioner recognizes multiple groups and forces the output to a particular version, performs no copy
@@ -809,7 +809,7 @@ func TestConvertToVersion(t *testing.T) {
same: true,
out: &runtimetesting.ExternalTestType1{
MyWeirdCustomEmbeddedVersionKindField: runtimetesting.MyWeirdCustomEmbeddedVersionKindField{APIVersion: "v1", ObjectKind: "TestType1"},
A: "test",
A: "test",
},
},
// group versioner can choose a particular target kind for a given input when kind is the same across group versions
@@ -819,7 +819,7 @@ func TestConvertToVersion(t *testing.T) {
gv: testGroupVersioner{ok: true, target: schema.GroupVersionKind{Version: "v1", Kind: "TestType3"}},
out: &runtimetesting.ExternalTestType1{
MyWeirdCustomEmbeddedVersionKindField: runtimetesting.MyWeirdCustomEmbeddedVersionKindField{APIVersion: "v1", ObjectKind: "TestType3"},
A: "test",
A: "test",
},
},
// group versioner can choose a different kind
@@ -829,7 +829,7 @@ func TestConvertToVersion(t *testing.T) {
gv: testGroupVersioner{ok: true, target: schema.GroupVersionKind{Kind: "TestType5", Group: "custom", Version: "v1"}},
out: &runtimetesting.ExternalTestType1{
MyWeirdCustomEmbeddedVersionKindField: runtimetesting.MyWeirdCustomEmbeddedVersionKindField{APIVersion: "custom/v1", ObjectKind: "TestType5"},
A: "test",
A: "test",
},
},
}

View File

@@ -18,6 +18,7 @@ package versioning
import (
"io"
"reflect"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
@@ -90,7 +91,16 @@ func (c *codec) Decode(data []byte, defaultGVK *schema.GroupVersionKind, into ru
into = versioned.Last()
}
obj, gvk, err := c.decoder.Decode(data, defaultGVK, into)
// If the into object is unstructured and expresses an opinion about its group/version,
// create a new instance of the type so we always exercise the conversion path (skips short-circuiting on `into == obj`)
decodeInto := into
if into != nil {
if _, ok := into.(runtime.Unstructured); ok && !into.GetObjectKind().GroupVersionKind().GroupVersion().Empty() {
decodeInto = reflect.New(reflect.TypeOf(into).Elem()).Interface().(runtime.Object)
}
}
obj, gvk, err := c.decoder.Decode(data, defaultGVK, decodeInto)
if err != nil {
return nil, gvk, err
}

View File

@@ -136,12 +136,12 @@ func Handshake(req *http.Request, w http.ResponseWriter, serverProtocols []strin
negotiatedProtocol := negotiateProtocol(clientProtocols, serverProtocols)
if len(negotiatedProtocol) == 0 {
w.WriteHeader(http.StatusForbidden)
for i := range serverProtocols {
w.Header().Add(HeaderAcceptedProtocolVersions, serverProtocols[i])
}
fmt.Fprintf(w, "unable to upgrade: unable to negotiate protocol: client supports %v, server accepts %v", clientProtocols, serverProtocols)
return "", fmt.Errorf("unable to upgrade: unable to negotiate protocol: client supports %v, server supports %v", clientProtocols, serverProtocols)
err := fmt.Errorf("unable to upgrade: unable to negotiate protocol: client supports %v, server accepts %v", clientProtocols, serverProtocols)
http.Error(w, err.Error(), http.StatusForbidden)
return "", err
}
w.Header().Add(HeaderProtocolVersion, negotiatedProtocol)

View File

@@ -67,6 +67,9 @@ type SpdyRoundTripper struct {
// followRedirects indicates if the round tripper should examine responses for redirects and
// follow them.
followRedirects bool
// requireSameHostRedirects restricts redirect following to only follow redirects to the same host
// as the original request.
requireSameHostRedirects bool
}
var _ utilnet.TLSClientConfigHolder = &SpdyRoundTripper{}
@@ -75,14 +78,18 @@ var _ utilnet.Dialer = &SpdyRoundTripper{}
// NewRoundTripper creates a new SpdyRoundTripper that will use
// the specified tlsConfig.
func NewRoundTripper(tlsConfig *tls.Config, followRedirects bool) httpstream.UpgradeRoundTripper {
return NewSpdyRoundTripper(tlsConfig, followRedirects)
func NewRoundTripper(tlsConfig *tls.Config, followRedirects, requireSameHostRedirects bool) httpstream.UpgradeRoundTripper {
return NewSpdyRoundTripper(tlsConfig, followRedirects, requireSameHostRedirects)
}
// NewSpdyRoundTripper creates a new SpdyRoundTripper that will use
// the specified tlsConfig. This function is mostly meant for unit tests.
func NewSpdyRoundTripper(tlsConfig *tls.Config, followRedirects bool) *SpdyRoundTripper {
return &SpdyRoundTripper{tlsConfig: tlsConfig, followRedirects: followRedirects}
func NewSpdyRoundTripper(tlsConfig *tls.Config, followRedirects, requireSameHostRedirects bool) *SpdyRoundTripper {
return &SpdyRoundTripper{
tlsConfig: tlsConfig,
followRedirects: followRedirects,
requireSameHostRedirects: requireSameHostRedirects,
}
}
// TLSClientConfig implements pkg/util/net.TLSClientConfigHolder for proper TLS checking during
@@ -257,7 +264,7 @@ func (s *SpdyRoundTripper) RoundTrip(req *http.Request) (*http.Response, error)
)
if s.followRedirects {
conn, rawResponse, err = utilnet.ConnectWithRedirects(req.Method, req.URL, header, req.Body, s)
conn, rawResponse, err = utilnet.ConnectWithRedirects(req.Method, req.URL, header, req.Body, s, s.requireSameHostRedirects)
} else {
clone := utilnet.CloneRequest(req)
clone.Header = header

View File

@@ -282,7 +282,7 @@ func TestRoundTripAndNewConnection(t *testing.T) {
t.Fatalf("%s: Error creating request: %s", k, err)
}
spdyTransport := NewSpdyRoundTripper(testCase.clientTLS, redirect)
spdyTransport := NewSpdyRoundTripper(testCase.clientTLS, redirect, redirect)
var proxierCalled bool
var proxyCalledWithHost string
@@ -391,8 +391,8 @@ func TestRoundTripRedirects(t *testing.T) {
}{
{0, true},
{1, true},
{10, true},
{11, false},
{9, true},
{10, false},
}
for _, test := range tests {
t.Run(fmt.Sprintf("with %d redirects", test.redirects), func(t *testing.T) {
@@ -425,7 +425,7 @@ func TestRoundTripRedirects(t *testing.T) {
t.Fatalf("Error creating request: %s", err)
}
spdyTransport := NewSpdyRoundTripper(nil, true)
spdyTransport := NewSpdyRoundTripper(nil, true, true)
client := &http.Client{Transport: spdyTransport}
resp, err := client.Do(req)

View File

@@ -74,15 +74,15 @@ func (u responseUpgrader) UpgradeResponse(w http.ResponseWriter, req *http.Reque
connectionHeader := strings.ToLower(req.Header.Get(httpstream.HeaderConnection))
upgradeHeader := strings.ToLower(req.Header.Get(httpstream.HeaderUpgrade))
if !strings.Contains(connectionHeader, strings.ToLower(httpstream.HeaderUpgrade)) || !strings.Contains(upgradeHeader, strings.ToLower(HeaderSpdy31)) {
w.WriteHeader(http.StatusBadRequest)
fmt.Fprintf(w, "unable to upgrade: missing upgrade headers in request: %#v", req.Header)
errorMsg := fmt.Sprintf("unable to upgrade: missing upgrade headers in request: %#v", req.Header)
http.Error(w, errorMsg, http.StatusBadRequest)
return nil
}
hijacker, ok := w.(http.Hijacker)
if !ok {
w.WriteHeader(http.StatusInternalServerError)
fmt.Fprintf(w, "unable to upgrade: unable to hijack response")
errorMsg := fmt.Sprintf("unable to upgrade: unable to hijack response")
http.Error(w, errorMsg, http.StatusInternalServerError)
return nil
}

View File

@@ -14,9 +14,8 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by protoc-gen-gogo.
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/util/intstr/generated.proto
// DO NOT EDIT!
/*
Package intstr is a generated protocol buffer package.
@@ -81,24 +80,6 @@ func (m *IntOrString) MarshalTo(dAtA []byte) (int, error) {
return i, nil
}
func encodeFixed64Generated(dAtA []byte, offset int, v uint64) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
dAtA[offset+2] = uint8(v >> 16)
dAtA[offset+3] = uint8(v >> 24)
dAtA[offset+4] = uint8(v >> 32)
dAtA[offset+5] = uint8(v >> 40)
dAtA[offset+6] = uint8(v >> 48)
dAtA[offset+7] = uint8(v >> 56)
return offset + 8
}
func encodeFixed32Generated(dAtA []byte, offset int, v uint32) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
dAtA[offset+2] = uint8(v >> 16)
dAtA[offset+3] = uint8(v >> 24)
return offset + 4
}
func encodeVarintGenerated(dAtA []byte, offset int, v uint64) int {
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)

View File

@@ -29,7 +29,7 @@ option go_package = "intstr";
// inner type. This allows you to have, for example, a JSON field that can
// accept a name or number.
// TODO: Rename to Int32OrString
//
//
// +protobuf=true
// +protobuf.options.(gogoproto.goproto_stringer)=false
// +k8s:openapi-gen=true

View File

@@ -31,12 +31,12 @@ func TestGetNameFromCallsite(t *testing.T) {
{
name: "ignore-package",
ignoredPackages: []string{"k8s.io/apimachinery/pkg/util/naming"},
expected: "testing/testing.go:777",
expected: "testing/testing.go:827",
},
{
name: "ignore-file",
ignoredPackages: []string{"k8s.io/apimachinery/pkg/util/naming/from_stack_test.go"},
expected: "testing/testing.go:777",
expected: "testing/testing.go:827",
},
{
name: "ignore-multiple",

View File

@@ -321,9 +321,10 @@ type Dialer interface {
// ConnectWithRedirects uses dialer to send req, following up to 10 redirects (relative to
// originalLocation). It returns the opened net.Conn and the raw response bytes.
func ConnectWithRedirects(originalMethod string, originalLocation *url.URL, header http.Header, originalBody io.Reader, dialer Dialer) (net.Conn, []byte, error) {
// If requireSameHostRedirects is true, only redirects to the same host are permitted.
func ConnectWithRedirects(originalMethod string, originalLocation *url.URL, header http.Header, originalBody io.Reader, dialer Dialer, requireSameHostRedirects bool) (net.Conn, []byte, error) {
const (
maxRedirects = 10
maxRedirects = 9 // Fail on the 10th redirect
maxResponseSize = 16384 // play it safe to allow the potential for lots of / large headers
)
@@ -387,10 +388,6 @@ redirectLoop:
resp.Body.Close() // not used
// Reset the connection.
intermediateConn.Close()
intermediateConn = nil
// Prepare to follow the redirect.
redirectStr := resp.Header.Get("Location")
if redirectStr == "" {
@@ -404,6 +401,15 @@ redirectLoop:
if err != nil {
return nil, nil, fmt.Errorf("malformed Location header: %v", err)
}
// Only follow redirects to the same host. Otherwise, propagate the redirect response back.
if requireSameHostRedirects && location.Hostname() != originalLocation.Hostname() {
break redirectLoop
}
// Reset the connection.
intermediateConn.Close()
intermediateConn = nil
}
connToReturn := intermediateConn

View File

@@ -19,14 +19,23 @@ limitations under the License.
package net
import (
"bufio"
"bytes"
"crypto/tls"
"fmt"
"io/ioutil"
"net"
"net/http"
"net/http/httptest"
"net/url"
"os"
"reflect"
"strings"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"k8s.io/apimachinery/pkg/util/wait"
)
func TestGetClientIP(t *testing.T) {
@@ -280,3 +289,153 @@ func TestJoinPreservingTrailingSlash(t *testing.T) {
})
}
}
func TestConnectWithRedirects(t *testing.T) {
tests := []struct {
desc string
redirects []string
method string // initial request method, empty == GET
expectError bool
expectedRedirects int
newPort bool // special case different port test
}{{
desc: "relative redirects allowed",
redirects: []string{"/ok"},
expectedRedirects: 1,
}, {
desc: "redirects to the same host are allowed",
redirects: []string{"http://HOST/ok"}, // HOST replaced with server address in test
expectedRedirects: 1,
}, {
desc: "POST redirects to GET",
method: http.MethodPost,
redirects: []string{"/ok"},
expectedRedirects: 1,
}, {
desc: "PUT redirects to GET",
method: http.MethodPut,
redirects: []string{"/ok"},
expectedRedirects: 1,
}, {
desc: "DELETE redirects to GET",
method: http.MethodDelete,
redirects: []string{"/ok"},
expectedRedirects: 1,
}, {
desc: "9 redirects are allowed",
redirects: []string{"/1", "/2", "/3", "/4", "/5", "/6", "/7", "/8", "/9"},
expectedRedirects: 9,
}, {
desc: "10 redirects are forbidden",
redirects: []string{"/1", "/2", "/3", "/4", "/5", "/6", "/7", "/8", "/9", "/10"},
expectError: true,
}, {
desc: "redirect to different host are prevented",
redirects: []string{"http://example.com/foo"},
expectedRedirects: 0,
}, {
desc: "multiple redirect to different host forbidden",
redirects: []string{"/1", "/2", "/3", "http://example.com/foo"},
expectedRedirects: 3,
}, {
desc: "redirect to different port is allowed",
redirects: []string{"http://HOST/foo"},
expectedRedirects: 1,
newPort: true,
}}
const resultString = "Test output"
for _, test := range tests {
t.Run(test.desc, func(t *testing.T) {
redirectCount := 0
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
// Verify redirect request.
if redirectCount > 0 {
expectedURL, err := url.Parse(test.redirects[redirectCount-1])
require.NoError(t, err, "test URL error")
assert.Equal(t, req.URL.Path, expectedURL.Path, "unknown redirect path")
assert.Equal(t, http.MethodGet, req.Method, "redirects must always be GET")
}
if redirectCount < len(test.redirects) {
http.Redirect(w, req, test.redirects[redirectCount], http.StatusFound)
redirectCount++
} else if redirectCount == len(test.redirects) {
w.Write([]byte(resultString))
} else {
t.Errorf("unexpected number of redirects %d to %s", redirectCount, req.URL.String())
}
}))
defer s.Close()
u, err := url.Parse(s.URL)
require.NoError(t, err, "Error parsing server URL")
host := u.Host
// Special case new-port test with a secondary server.
if test.newPort {
s2 := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
w.Write([]byte(resultString))
}))
defer s2.Close()
u2, err := url.Parse(s2.URL)
require.NoError(t, err, "Error parsing secondary server URL")
// Sanity check: secondary server uses same hostname, different port.
require.Equal(t, u.Hostname(), u2.Hostname(), "sanity check: same hostname")
require.NotEqual(t, u.Port(), u2.Port(), "sanity check: different port")
// Redirect to the secondary server.
host = u2.Host
}
// Update redirect URLs with actual host.
for i := range test.redirects {
test.redirects[i] = strings.Replace(test.redirects[i], "HOST", host, 1)
}
method := test.method
if method == "" {
method = http.MethodGet
}
netdialer := &net.Dialer{
Timeout: wait.ForeverTestTimeout,
KeepAlive: wait.ForeverTestTimeout,
}
dialer := DialerFunc(func(req *http.Request) (net.Conn, error) {
conn, err := netdialer.Dial("tcp", req.URL.Host)
if err != nil {
return conn, err
}
if err = req.Write(conn); err != nil {
require.NoError(t, conn.Close())
return nil, fmt.Errorf("error sending request: %v", err)
}
return conn, err
})
conn, rawResponse, err := ConnectWithRedirects(method, u, http.Header{} /*body*/, nil, dialer, true)
if test.expectError {
require.Error(t, err, "expected request error")
return
}
require.NoError(t, err, "unexpected request error")
assert.NoError(t, conn.Close(), "error closing connection")
resp, err := http.ReadResponse(bufio.NewReader(bytes.NewReader(rawResponse)), nil)
require.NoError(t, err, "unexpected request error")
result, err := ioutil.ReadAll(resp.Body)
require.NoError(t, resp.Body.Close())
if test.expectedRedirects < len(test.redirects) {
// Expect the last redirect to be returned.
assert.Equal(t, http.StatusFound, resp.StatusCode, "Final response is not a redirect")
assert.Equal(t, test.redirects[len(test.redirects)-1], resp.Header.Get("Location"))
assert.NotEqual(t, resultString, string(result), "wrong content")
} else {
assert.Equal(t, resultString, string(result), "stream content does not match")
}
})
}
}

View File

@@ -68,6 +68,8 @@ type UpgradeAwareHandler struct {
// InterceptRedirects determines whether the proxy should sniff backend responses for redirects,
// following them as necessary.
InterceptRedirects bool
// RequireSameHostRedirects only allows redirects to the same host. It is only used if InterceptRedirects=true.
RequireSameHostRedirects bool
// UseRequestLocation will use the incoming request URL when talking to the backend server.
UseRequestLocation bool
// FlushInterval controls how often the standard HTTP proxy will flush content from the upstream.
@@ -256,7 +258,7 @@ func (h *UpgradeAwareHandler) tryUpgrade(w http.ResponseWriter, req *http.Reques
utilnet.AppendForwardedForHeader(clone)
if h.InterceptRedirects {
glog.V(6).Infof("Connecting to backend proxy (intercepting redirects) %s\n Headers: %v", &location, clone.Header)
backendConn, rawResponse, err = utilnet.ConnectWithRedirects(req.Method, &location, clone.Header, req.Body, utilnet.DialerFunc(h.DialForUpgrade))
backendConn, rawResponse, err = utilnet.ConnectWithRedirects(req.Method, &location, clone.Header, req.Body, utilnet.DialerFunc(h.DialForUpgrade), h.RequireSameHostRedirects)
} else {
glog.V(6).Infof("Connecting to backend proxy (direct dial) %s\n Headers: %v", &location, clone.Header)
clone.URL = &location

View File

@@ -27,7 +27,14 @@ var rng = struct {
sync.Mutex
rand *rand.Rand
}{
rand: rand.New(rand.NewSource(time.Now().UTC().UnixNano())),
rand: rand.New(rand.NewSource(time.Now().UnixNano())),
}
// Int returns a non-negative pseudo-random int.
func Int() int {
rng.Lock()
defer rng.Unlock()
return rng.rand.Int()
}
// Intn generates an integer in range [0,max).

View File

@@ -74,7 +74,7 @@ func getSchema(f Fake, model string) (openapi.Schema, error) {
return m.LookupModel(model), nil
}
// GetSchemaOrDie returns returns the openapi schema.
// GetSchemaOrDie returns the openapi schema.
func GetSchemaOrDie(f Fake, model string) openapi.Schema {
s, err := getSchema(f, model)
if err != nil {

View File

@@ -297,7 +297,7 @@ func TestIsValidLabelValue(t *testing.T) {
"end-with-num-1",
"1234", // only num
strings.Repeat("a", 63), // to the limit
"", // empty value
"", // empty value
}
for i := range successCases {
if errs := IsValidLabelValue(successCases[i]); len(errs) != 0 {

18
vendor/k8s.io/apimachinery/pkg/util/version/doc.go generated vendored Normal file
View File

@@ -0,0 +1,18 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Package version provides utilities for version number comparisons
package version // import "k8s.io/apimachinery/pkg/util/version"

285
vendor/k8s.io/apimachinery/pkg/util/version/version.go generated vendored Normal file
View File

@@ -0,0 +1,285 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package version
import (
"bytes"
"fmt"
"regexp"
"strconv"
"strings"
)
// Version is an opqaue representation of a version number
type Version struct {
components []uint
semver bool
preRelease string
buildMetadata string
}
var (
// versionMatchRE splits a version string into numeric and "extra" parts
versionMatchRE = regexp.MustCompile(`^\s*v?([0-9]+(?:\.[0-9]+)*)(.*)*$`)
// extraMatchRE splits the "extra" part of versionMatchRE into semver pre-release and build metadata; it does not validate the "no leading zeroes" constraint for pre-release
extraMatchRE = regexp.MustCompile(`^(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?\s*$`)
)
func parse(str string, semver bool) (*Version, error) {
parts := versionMatchRE.FindStringSubmatch(str)
if parts == nil {
return nil, fmt.Errorf("could not parse %q as version", str)
}
numbers, extra := parts[1], parts[2]
components := strings.Split(numbers, ".")
if (semver && len(components) != 3) || (!semver && len(components) < 2) {
return nil, fmt.Errorf("illegal version string %q", str)
}
v := &Version{
components: make([]uint, len(components)),
semver: semver,
}
for i, comp := range components {
if (i == 0 || semver) && strings.HasPrefix(comp, "0") && comp != "0" {
return nil, fmt.Errorf("illegal zero-prefixed version component %q in %q", comp, str)
}
num, err := strconv.ParseUint(comp, 10, 0)
if err != nil {
return nil, fmt.Errorf("illegal non-numeric version component %q in %q: %v", comp, str, err)
}
v.components[i] = uint(num)
}
if semver && extra != "" {
extraParts := extraMatchRE.FindStringSubmatch(extra)
if extraParts == nil {
return nil, fmt.Errorf("could not parse pre-release/metadata (%s) in version %q", extra, str)
}
v.preRelease, v.buildMetadata = extraParts[1], extraParts[2]
for _, comp := range strings.Split(v.preRelease, ".") {
if _, err := strconv.ParseUint(comp, 10, 0); err == nil {
if strings.HasPrefix(comp, "0") && comp != "0" {
return nil, fmt.Errorf("illegal zero-prefixed version component %q in %q", comp, str)
}
}
}
}
return v, nil
}
// ParseGeneric parses a "generic" version string. The version string must consist of two
// or more dot-separated numeric fields (the first of which can't have leading zeroes),
// followed by arbitrary uninterpreted data (which need not be separated from the final
// numeric field by punctuation). For convenience, leading and trailing whitespace is
// ignored, and the version can be preceded by the letter "v". See also ParseSemantic.
func ParseGeneric(str string) (*Version, error) {
return parse(str, false)
}
// MustParseGeneric is like ParseGeneric except that it panics on error
func MustParseGeneric(str string) *Version {
v, err := ParseGeneric(str)
if err != nil {
panic(err)
}
return v
}
// ParseSemantic parses a version string that exactly obeys the syntax and semantics of
// the "Semantic Versioning" specification (http://semver.org/) (although it ignores
// leading and trailing whitespace, and allows the version to be preceded by "v"). For
// version strings that are not guaranteed to obey the Semantic Versioning syntax, use
// ParseGeneric.
func ParseSemantic(str string) (*Version, error) {
return parse(str, true)
}
// MustParseSemantic is like ParseSemantic except that it panics on error
func MustParseSemantic(str string) *Version {
v, err := ParseSemantic(str)
if err != nil {
panic(err)
}
return v
}
// Major returns the major release number
func (v *Version) Major() uint {
return v.components[0]
}
// Minor returns the minor release number
func (v *Version) Minor() uint {
return v.components[1]
}
// Patch returns the patch release number if v is a Semantic Version, or 0
func (v *Version) Patch() uint {
if len(v.components) < 3 {
return 0
}
return v.components[2]
}
// BuildMetadata returns the build metadata, if v is a Semantic Version, or ""
func (v *Version) BuildMetadata() string {
return v.buildMetadata
}
// PreRelease returns the prerelease metadata, if v is a Semantic Version, or ""
func (v *Version) PreRelease() string {
return v.preRelease
}
// Components returns the version number components
func (v *Version) Components() []uint {
return v.components
}
// String converts a Version back to a string; note that for versions parsed with
// ParseGeneric, this will not include the trailing uninterpreted portion of the version
// number.
func (v *Version) String() string {
var buffer bytes.Buffer
for i, comp := range v.components {
if i > 0 {
buffer.WriteString(".")
}
buffer.WriteString(fmt.Sprintf("%d", comp))
}
if v.preRelease != "" {
buffer.WriteString("-")
buffer.WriteString(v.preRelease)
}
if v.buildMetadata != "" {
buffer.WriteString("+")
buffer.WriteString(v.buildMetadata)
}
return buffer.String()
}
// compareInternal returns -1 if v is less than other, 1 if it is greater than other, or 0
// if they are equal
func (v *Version) compareInternal(other *Version) int {
vLen := len(v.components)
oLen := len(other.components)
for i := 0; i < vLen && i < oLen; i++ {
switch {
case other.components[i] < v.components[i]:
return 1
case other.components[i] > v.components[i]:
return -1
}
}
// If components are common but one has more items and they are not zeros, it is bigger
switch {
case oLen < vLen && !onlyZeros(v.components[oLen:]):
return 1
case oLen > vLen && !onlyZeros(other.components[vLen:]):
return -1
}
if !v.semver || !other.semver {
return 0
}
switch {
case v.preRelease == "" && other.preRelease != "":
return 1
case v.preRelease != "" && other.preRelease == "":
return -1
case v.preRelease == other.preRelease: // includes case where both are ""
return 0
}
vPR := strings.Split(v.preRelease, ".")
oPR := strings.Split(other.preRelease, ".")
for i := 0; i < len(vPR) && i < len(oPR); i++ {
vNum, err := strconv.ParseUint(vPR[i], 10, 0)
if err == nil {
oNum, err := strconv.ParseUint(oPR[i], 10, 0)
if err == nil {
switch {
case oNum < vNum:
return 1
case oNum > vNum:
return -1
default:
continue
}
}
}
if oPR[i] < vPR[i] {
return 1
} else if oPR[i] > vPR[i] {
return -1
}
}
switch {
case len(oPR) < len(vPR):
return 1
case len(oPR) > len(vPR):
return -1
}
return 0
}
// returns false if array contain any non-zero element
func onlyZeros(array []uint) bool {
for _, num := range array {
if num != 0 {
return false
}
}
return true
}
// AtLeast tests if a version is at least equal to a given minimum version. If both
// Versions are Semantic Versions, this will use the Semantic Version comparison
// algorithm. Otherwise, it will compare only the numeric components, with non-present
// components being considered "0" (ie, "1.4" is equal to "1.4.0").
func (v *Version) AtLeast(min *Version) bool {
return v.compareInternal(min) != -1
}
// LessThan tests if a version is less than a given version. (It is exactly the opposite
// of AtLeast, for situations where asking "is v too old?" makes more sense than asking
// "is v new enough?".)
func (v *Version) LessThan(other *Version) bool {
return v.compareInternal(other) == -1
}
// Compare compares v against a version string (which will be parsed as either Semantic
// or non-Semantic depending on v). On success it returns -1 if v is less than other, 1 if
// it is greater than other, or 0 if they are equal.
func (v *Version) Compare(other string) (int, error) {
ov, err := parse(other, v.semver)
if err != nil {
return 0, err
}
return v.compareInternal(ov), nil
}

View File

@@ -0,0 +1,348 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package version
import (
"fmt"
"reflect"
"testing"
)
type testItem struct {
version string
unparsed string
equalsPrev bool
}
func testOne(v *Version, item, prev testItem) error {
str := v.String()
if item.unparsed == "" {
if str != item.version {
return fmt.Errorf("bad round-trip: %q -> %q", item.version, str)
}
} else {
if str != item.unparsed {
return fmt.Errorf("bad unparse: %q -> %q, expected %q", item.version, str, item.unparsed)
}
}
if prev.version != "" {
cmp, err := v.Compare(prev.version)
if err != nil {
return fmt.Errorf("unexpected parse error: %v", err)
}
rv, err := parse(prev.version, v.semver)
if err != nil {
return fmt.Errorf("unexpected parse error: %v", err)
}
rcmp, err := rv.Compare(item.version)
if err != nil {
return fmt.Errorf("unexpected parse error: %v", err)
}
switch {
case cmp == -1:
return fmt.Errorf("unexpected ordering %q < %q", item.version, prev.version)
case cmp == 0 && !item.equalsPrev:
return fmt.Errorf("unexpected comparison %q == %q", item.version, prev.version)
case cmp == 1 && item.equalsPrev:
return fmt.Errorf("unexpected comparison %q != %q", item.version, prev.version)
case cmp != -rcmp:
return fmt.Errorf("unexpected reverse comparison %q <=> %q %v %v %v %v", item.version, prev.version, cmp, rcmp, v.Components(), rv.Components())
}
}
return nil
}
func TestSemanticVersions(t *testing.T) {
tests := []testItem{
// This is every version string that appears in the 2.0 semver spec,
// sorted in strictly increasing order except as noted.
{version: "0.1.0"},
{version: "1.0.0-0.3.7"},
{version: "1.0.0-alpha"},
{version: "1.0.0-alpha+001", equalsPrev: true},
{version: "1.0.0-alpha.1"},
{version: "1.0.0-alpha.beta"},
{version: "1.0.0-beta"},
{version: "1.0.0-beta+exp.sha.5114f85", equalsPrev: true},
{version: "1.0.0-beta.2"},
{version: "1.0.0-beta.11"},
{version: "1.0.0-rc.1"},
{version: "1.0.0-x.7.z.92"},
{version: "1.0.0"},
{version: "1.0.0+20130313144700", equalsPrev: true},
{version: "1.8.0-alpha.3"},
{version: "1.8.0-alpha.3.673+73326ef01d2d7c"},
{version: "1.9.0"},
{version: "1.10.0"},
{version: "1.11.0"},
{version: "2.0.0"},
{version: "2.1.0"},
{version: "2.1.1"},
{version: "42.0.0"},
// We also allow whitespace and "v" prefix
{version: " 42.0.0", unparsed: "42.0.0", equalsPrev: true},
{version: "\t42.0.0 ", unparsed: "42.0.0", equalsPrev: true},
{version: "43.0.0-1", unparsed: "43.0.0-1"},
{version: "43.0.0-1 ", unparsed: "43.0.0-1", equalsPrev: true},
{version: "v43.0.0-1", unparsed: "43.0.0-1", equalsPrev: true},
{version: " v43.0.0", unparsed: "43.0.0"},
{version: " 43.0.0 ", unparsed: "43.0.0", equalsPrev: true},
}
var prev testItem
for _, item := range tests {
v, err := ParseSemantic(item.version)
if err != nil {
t.Errorf("unexpected parse error: %v", err)
continue
}
err = testOne(v, item, prev)
if err != nil {
t.Errorf("%v", err)
}
prev = item
}
}
func TestBadSemanticVersions(t *testing.T) {
tests := []string{
// "MUST take the form X.Y.Z"
"1",
"1.2",
"1.2.3.4",
".2.3",
"1..3",
"1.2.",
"",
"..",
// "where X, Y, and Z are non-negative integers"
"-1.2.3",
"1.-2.3",
"1.2.-3",
"1a.2.3",
"1.2a.3",
"1.2.3a",
"a1.2.3",
"a.b.c",
"1 .2.3",
"1. 2.3",
// "and MUST NOT contain leading zeroes."
"01.2.3",
"1.02.3",
"1.2.03",
// "[pre-release] identifiers MUST comprise only ASCII alphanumerics and hyphen"
"1.2.3-/",
// "[pre-release] identifiers MUST NOT be empty"
"1.2.3-",
"1.2.3-.",
"1.2.3-foo.",
"1.2.3-.foo",
// "Numeric [pre-release] identifiers MUST NOT include leading zeroes"
"1.2.3-01",
// "[build metadata] identifiers MUST comprise only ASCII alphanumerics and hyphen"
"1.2.3+/",
// "[build metadata] identifiers MUST NOT be empty"
"1.2.3+",
"1.2.3+.",
"1.2.3+foo.",
"1.2.3+.foo",
// whitespace/"v"-prefix checks
"v 1.2.3",
"vv1.2.3",
}
for i := range tests {
_, err := ParseSemantic(tests[i])
if err == nil {
t.Errorf("unexpected success parsing invalid semver %q", tests[i])
}
}
}
func TestGenericVersions(t *testing.T) {
tests := []testItem{
// This is all of the strings from TestSemanticVersions, plus some strings
// from TestBadSemanticVersions that should parse as generic versions,
// plus some additional strings.
{version: "0.1.0", unparsed: "0.1.0"},
{version: "1.0.0-0.3.7", unparsed: "1.0.0"},
{version: "1.0.0-alpha", unparsed: "1.0.0", equalsPrev: true},
{version: "1.0.0-alpha+001", unparsed: "1.0.0", equalsPrev: true},
{version: "1.0.0-alpha.1", unparsed: "1.0.0", equalsPrev: true},
{version: "1.0.0-alpha.beta", unparsed: "1.0.0", equalsPrev: true},
{version: "1.0.0.beta", unparsed: "1.0.0", equalsPrev: true},
{version: "1.0.0-beta+exp.sha.5114f85", unparsed: "1.0.0", equalsPrev: true},
{version: "1.0.0.beta.2", unparsed: "1.0.0", equalsPrev: true},
{version: "1.0.0.beta.11", unparsed: "1.0.0", equalsPrev: true},
{version: "1.0.0.rc.1", unparsed: "1.0.0", equalsPrev: true},
{version: "1.0.0-x.7.z.92", unparsed: "1.0.0", equalsPrev: true},
{version: "1.0.0", unparsed: "1.0.0", equalsPrev: true},
{version: "1.0.0+20130313144700", unparsed: "1.0.0", equalsPrev: true},
{version: "1.2", unparsed: "1.2"},
{version: "1.2a.3", unparsed: "1.2", equalsPrev: true},
{version: "1.2.3", unparsed: "1.2.3"},
{version: "1.2.3.0", unparsed: "1.2.3.0", equalsPrev: true},
{version: "1.2.3a", unparsed: "1.2.3", equalsPrev: true},
{version: "1.2.3-foo.", unparsed: "1.2.3", equalsPrev: true},
{version: "1.2.3-.foo", unparsed: "1.2.3", equalsPrev: true},
{version: "1.2.3-01", unparsed: "1.2.3", equalsPrev: true},
{version: "1.2.3+", unparsed: "1.2.3", equalsPrev: true},
{version: "1.2.3+foo.", unparsed: "1.2.3", equalsPrev: true},
{version: "1.2.3+.foo", unparsed: "1.2.3", equalsPrev: true},
{version: "1.02.3", unparsed: "1.2.3", equalsPrev: true},
{version: "1.2.03", unparsed: "1.2.3", equalsPrev: true},
{version: "1.2.003", unparsed: "1.2.3", equalsPrev: true},
{version: "1.2.3.4", unparsed: "1.2.3.4"},
{version: "1.2.3.4b3", unparsed: "1.2.3.4", equalsPrev: true},
{version: "1.2.3.4.5", unparsed: "1.2.3.4.5"},
{version: "1.9.0", unparsed: "1.9.0"},
{version: "1.9.0.0.0.0.0.0", unparsed: "1.9.0.0.0.0.0.0", equalsPrev: true},
{version: "1.10.0", unparsed: "1.10.0"},
{version: "1.11.0", unparsed: "1.11.0"},
{version: "1.11.0.0.5", unparsed: "1.11.0.0.5"},
{version: "2.0.0", unparsed: "2.0.0"},
{version: "2.1.0", unparsed: "2.1.0"},
{version: "2.1.1", unparsed: "2.1.1"},
{version: "42.0.0", unparsed: "42.0.0"},
{version: " 42.0.0", unparsed: "42.0.0", equalsPrev: true},
{version: "\t42.0.0 ", unparsed: "42.0.0", equalsPrev: true},
{version: "42.0.0-1", unparsed: "42.0.0", equalsPrev: true},
{version: "42.0.0-1 ", unparsed: "42.0.0", equalsPrev: true},
{version: "v42.0.0-1", unparsed: "42.0.0", equalsPrev: true},
{version: " v43.0.0", unparsed: "43.0.0"},
{version: " 43.0.0 ", unparsed: "43.0.0", equalsPrev: true},
}
var prev testItem
for _, item := range tests {
v, err := ParseGeneric(item.version)
if err != nil {
t.Errorf("unexpected parse error: %v", err)
continue
}
err = testOne(v, item, prev)
if err != nil {
t.Errorf("%v", err)
}
prev = item
}
}
func TestBadGenericVersions(t *testing.T) {
tests := []string{
"1",
"01.2.3",
"-1.2.3",
"1.-2.3",
".2.3",
"1..3",
"1a.2.3",
"a1.2.3",
"1 .2.3",
"1. 2.3",
"1.bob",
"bob",
"v 1.2.3",
"vv1.2.3",
"",
".",
}
for i := range tests {
_, err := ParseGeneric(tests[i])
if err == nil {
t.Errorf("unexpected success parsing invalid version %q", tests[i])
}
}
}
func TestComponents(t *testing.T) {
var tests = []struct {
version string
semver bool
expectedComponents []uint
expectedMajor uint
expectedMinor uint
expectedPatch uint
expectedPreRelease string
expectedBuildMetadata string
}{
{
version: "1.0.2",
semver: true,
expectedComponents: []uint{1, 0, 2},
expectedMajor: 1,
expectedMinor: 0,
expectedPatch: 2,
},
{
version: "1.0.2-alpha+001",
semver: true,
expectedComponents: []uint{1, 0, 2},
expectedMajor: 1,
expectedMinor: 0,
expectedPatch: 2,
expectedPreRelease: "alpha",
expectedBuildMetadata: "001",
},
{
version: "1.2",
semver: false,
expectedComponents: []uint{1, 2},
expectedMajor: 1,
expectedMinor: 2,
},
{
version: "1.0.2-beta+exp.sha.5114f85",
semver: true,
expectedComponents: []uint{1, 0, 2},
expectedMajor: 1,
expectedMinor: 0,
expectedPatch: 2,
expectedPreRelease: "beta",
expectedBuildMetadata: "exp.sha.5114f85",
},
}
for _, test := range tests {
version, _ := parse(test.version, test.semver)
if !reflect.DeepEqual(test.expectedComponents, version.Components()) {
t.Error("parse returned un'expected components")
}
if test.expectedMajor != version.Major() {
t.Errorf("parse returned version.Major %d, expected %d", test.expectedMajor, version.Major())
}
if test.expectedMinor != version.Minor() {
t.Errorf("parse returned version.Minor %d, expected %d", test.expectedMinor, version.Minor())
}
if test.expectedPatch != version.Patch() {
t.Errorf("parse returned version.Patch %d, expected %d", test.expectedPatch, version.Patch())
}
if test.expectedPreRelease != version.PreRelease() {
t.Errorf("parse returned version.PreRelease %s, expected %s", test.expectedPreRelease, version.PreRelease())
}
if test.expectedBuildMetadata != version.BuildMetadata() {
t.Errorf("parse returned version.BuildMetadata %s, expected %s", test.expectedBuildMetadata, version.BuildMetadata())
}
}
}

View File

@@ -197,8 +197,8 @@ stuff: 1
t.Fatal("expected error with yaml: violate, got no error")
}
fmt.Printf("err: %s\n", err.Error())
if !strings.Contains(err.Error(), "yaml: line 2:") {
t.Fatalf("expected %q to have 'yaml: line 2:' found a tab character", err.Error())
if !strings.Contains(err.Error(), "yaml: line 3:") {
t.Fatalf("expected %q to have 'yaml: line 3:' found a tab character", err.Error())
}
}

View File

@@ -14,6 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
// Package version supplies the type for version information collected at build time.
// +k8s:openapi-gen=true
// Package version supplies the type for version information collected at build time.
package version // import "k8s.io/apimachinery/pkg/version"