use clusterselector w/ federated configmap deploys

fix test error formatting

updates from comments

update gofmt

simplify tests

add to new sync controller

add tests

remove configmap changes due to rebase

updates from review

refactor tests to be based on operations

improvements from review

updates from rebase

rebase to #45374

updates from review

refactor SendToCluster for tests

fix import order

rebase to upstream
pull/6/head
Wilson, Dan 2017-01-19 11:02:13 -08:00 committed by emaildanwilson
parent 0c25199117
commit 32787c5258
13 changed files with 1073 additions and 67 deletions

View File

@ -28,6 +28,7 @@ limitations under the License.
Cluster
ClusterCondition
ClusterList
ClusterSelectorRequirement
ClusterSpec
ClusterStatus
ServerAddressByClientCIDR
@ -68,24 +69,31 @@ func (m *ClusterList) Reset() { *m = ClusterList{} }
func (*ClusterList) ProtoMessage() {}
func (*ClusterList) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{2} }
func (m *ClusterSelectorRequirement) Reset() { *m = ClusterSelectorRequirement{} }
func (*ClusterSelectorRequirement) ProtoMessage() {}
func (*ClusterSelectorRequirement) Descriptor() ([]byte, []int) {
return fileDescriptorGenerated, []int{3}
}
func (m *ClusterSpec) Reset() { *m = ClusterSpec{} }
func (*ClusterSpec) ProtoMessage() {}
func (*ClusterSpec) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{3} }
func (*ClusterSpec) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{4} }
func (m *ClusterStatus) Reset() { *m = ClusterStatus{} }
func (*ClusterStatus) ProtoMessage() {}
func (*ClusterStatus) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{4} }
func (*ClusterStatus) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{5} }
func (m *ServerAddressByClientCIDR) Reset() { *m = ServerAddressByClientCIDR{} }
func (*ServerAddressByClientCIDR) ProtoMessage() {}
func (*ServerAddressByClientCIDR) Descriptor() ([]byte, []int) {
return fileDescriptorGenerated, []int{5}
return fileDescriptorGenerated, []int{6}
}
func init() {
proto.RegisterType((*Cluster)(nil), "k8s.io.kubernetes.federation.apis.federation.v1beta1.Cluster")
proto.RegisterType((*ClusterCondition)(nil), "k8s.io.kubernetes.federation.apis.federation.v1beta1.ClusterCondition")
proto.RegisterType((*ClusterList)(nil), "k8s.io.kubernetes.federation.apis.federation.v1beta1.ClusterList")
proto.RegisterType((*ClusterSelectorRequirement)(nil), "k8s.io.kubernetes.federation.apis.federation.v1beta1.ClusterSelectorRequirement")
proto.RegisterType((*ClusterSpec)(nil), "k8s.io.kubernetes.federation.apis.federation.v1beta1.ClusterSpec")
proto.RegisterType((*ClusterStatus)(nil), "k8s.io.kubernetes.federation.apis.federation.v1beta1.ClusterStatus")
proto.RegisterType((*ServerAddressByClientCIDR)(nil), "k8s.io.kubernetes.federation.apis.federation.v1beta1.ServerAddressByClientCIDR")
@ -220,6 +228,47 @@ func (m *ClusterList) MarshalTo(dAtA []byte) (int, error) {
return i, nil
}
func (m *ClusterSelectorRequirement) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalTo(dAtA)
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *ClusterSelectorRequirement) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
dAtA[i] = 0xa
i++
i = encodeVarintGenerated(dAtA, i, uint64(len(m.Key)))
i += copy(dAtA[i:], m.Key)
dAtA[i] = 0x12
i++
i = encodeVarintGenerated(dAtA, i, uint64(len(m.Operator)))
i += copy(dAtA[i:], m.Operator)
if len(m.Values) > 0 {
for _, s := range m.Values {
dAtA[i] = 0x1a
i++
l = len(s)
for l >= 1<<7 {
dAtA[i] = uint8(uint64(l)&0x7f | 0x80)
l >>= 7
i++
}
dAtA[i] = uint8(l)
i++
i += copy(dAtA[i:], s)
}
}
return i, nil
}
func (m *ClusterSpec) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
@ -406,6 +455,22 @@ func (m *ClusterList) Size() (n int) {
return n
}
func (m *ClusterSelectorRequirement) Size() (n int) {
var l int
_ = l
l = len(m.Key)
n += 1 + l + sovGenerated(uint64(l))
l = len(m.Operator)
n += 1 + l + sovGenerated(uint64(l))
if len(m.Values) > 0 {
for _, s := range m.Values {
l = len(s)
n += 1 + l + sovGenerated(uint64(l))
}
}
return n
}
func (m *ClusterSpec) Size() (n int) {
var l int
_ = l
@ -503,6 +568,18 @@ func (this *ClusterList) String() string {
}, "")
return s
}
func (this *ClusterSelectorRequirement) String() string {
if this == nil {
return "nil"
}
s := strings.Join([]string{`&ClusterSelectorRequirement{`,
`Key:` + fmt.Sprintf("%v", this.Key) + `,`,
`Operator:` + fmt.Sprintf("%v", this.Operator) + `,`,
`Values:` + fmt.Sprintf("%v", this.Values) + `,`,
`}`,
}, "")
return s
}
func (this *ClusterSpec) String() string {
if this == nil {
return "nil"
@ -1022,6 +1099,143 @@ func (m *ClusterList) Unmarshal(dAtA []byte) error {
}
return nil
}
func (m *ClusterSelectorRequirement) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: ClusterSelectorRequirement: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: ClusterSelectorRequirement: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthGenerated
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Key = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Operator", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthGenerated
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Operator = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Values", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthGenerated
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Values = append(m.Values, string(dAtA[iNdEx:postIndex]))
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipGenerated(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthGenerated
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *ClusterSpec) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
@ -1493,56 +1707,60 @@ func init() {
}
var fileDescriptorGenerated = []byte{
// 809 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x54, 0xcd, 0x6e, 0xeb, 0x44,
0x14, 0x8e, 0xf3, 0xdb, 0x4c, 0x09, 0x54, 0x23, 0x90, 0x42, 0x16, 0x4e, 0x15, 0x21, 0xd4, 0x22,
0xb0, 0x69, 0x40, 0xa8, 0x12, 0x02, 0xa9, 0x4e, 0x85, 0x54, 0xa9, 0x55, 0xd1, 0xb4, 0x62, 0x51,
0x21, 0xc1, 0xc4, 0x39, 0x71, 0x4d, 0xe2, 0x1f, 0x79, 0x26, 0x11, 0xe9, 0x8a, 0x07, 0x60, 0xc1,
0x43, 0xf0, 0x06, 0xac, 0xd9, 0x77, 0x77, 0xbb, 0xb8, 0x8b, 0xae, 0xa2, 0xdb, 0xdc, 0xb7, 0xe8,
0xea, 0x6a, 0xc6, 0x13, 0xc7, 0xbe, 0x49, 0x7a, 0x7b, 0xdb, 0x9d, 0xe7, 0xf8, 0x9c, 0xef, 0xfb,
0xe6, 0x7c, 0x73, 0x0e, 0x3a, 0x1c, 0xec, 0x33, 0xc3, 0x0d, 0xcc, 0xc1, 0xa8, 0x0b, 0x91, 0x0f,
0x1c, 0x98, 0xd9, 0x87, 0x1e, 0x44, 0x94, 0xbb, 0x81, 0x6f, 0xd2, 0xd0, 0xcd, 0x9c, 0xc7, 0x7b,
0x5d, 0xe0, 0x74, 0xcf, 0x74, 0xc0, 0x17, 0x21, 0xe8, 0x19, 0x61, 0x14, 0xf0, 0x00, 0x7f, 0x1b,
0xa3, 0x18, 0x0b, 0x14, 0x63, 0x51, 0x65, 0x08, 0x94, 0xf4, 0x59, 0xa1, 0x34, 0xbe, 0x72, 0x5c,
0x7e, 0x39, 0xea, 0x1a, 0x76, 0xe0, 0x99, 0x4e, 0xe0, 0x04, 0xa6, 0x04, 0xeb, 0x8e, 0xfa, 0xf2,
0x24, 0x0f, 0xf2, 0x2b, 0x26, 0x69, 0x28, 0x12, 0x21, 0xca, 0xa3, 0xf6, 0xa5, 0xeb, 0x43, 0x34,
0x31, 0xc3, 0x81, 0x13, 0xab, 0xf4, 0x80, 0x53, 0x73, 0xbc, 0x24, 0xad, 0x61, 0xae, 0xab, 0x8a,
0x46, 0x3e, 0x77, 0x3d, 0x58, 0x2a, 0xf8, 0xee, 0x5d, 0x05, 0xcc, 0xbe, 0x04, 0x8f, 0x2e, 0xd5,
0x7d, 0xb3, 0xae, 0x6e, 0xc4, 0xdd, 0xa1, 0xe9, 0xfa, 0x9c, 0xf1, 0x68, 0xa9, 0x28, 0x75, 0x27,
0x06, 0xd1, 0x18, 0xa2, 0xc5, 0x85, 0xe0, 0x4f, 0xea, 0x85, 0x43, 0x58, 0x75, 0xa7, 0x2f, 0x97,
0x4d, 0x53, 0x65, 0x2b, 0xb2, 0x5b, 0xff, 0xe7, 0x51, 0xa5, 0x33, 0x1c, 0x31, 0x0e, 0x11, 0xfe,
0x1d, 0x6d, 0x88, 0x46, 0xf5, 0x28, 0xa7, 0x75, 0x6d, 0x5b, 0xdb, 0xd9, 0x6c, 0x7f, 0x6d, 0x28,
0xef, 0xd2, 0xba, 0x8d, 0x70, 0xe0, 0xc4, 0xb6, 0x89, 0x6c, 0x63, 0xbc, 0x67, 0x9c, 0x76, 0xff,
0x00, 0x9b, 0x9f, 0x00, 0xa7, 0x16, 0xbe, 0x9e, 0x36, 0x73, 0xb3, 0x69, 0x13, 0x2d, 0x62, 0x24,
0x41, 0xc5, 0x36, 0x2a, 0xb2, 0x10, 0xec, 0x7a, 0x5e, 0xa2, 0x1f, 0x18, 0x4f, 0x79, 0x19, 0x86,
0x92, 0x7b, 0x16, 0x82, 0x6d, 0x7d, 0xa0, 0xe8, 0x8a, 0xe2, 0x44, 0x24, 0x38, 0x1e, 0xa0, 0x32,
0xe3, 0x94, 0x8f, 0x58, 0xbd, 0x20, 0x69, 0x3a, 0xcf, 0xa3, 0x91, 0x50, 0xd6, 0x87, 0x8a, 0xa8,
0x1c, 0x9f, 0x89, 0xa2, 0x68, 0xdd, 0x16, 0xd0, 0x96, 0xca, 0xec, 0x04, 0x7e, 0xcf, 0x15, 0x10,
0x78, 0x1f, 0x15, 0xf9, 0x24, 0x04, 0xd9, 0xc4, 0xaa, 0xf5, 0xd9, 0x5c, 0xe3, 0xf9, 0x24, 0x84,
0xfb, 0x69, 0xf3, 0xe3, 0xb7, 0xf3, 0x45, 0x9c, 0xc8, 0x0a, 0xfc, 0x4b, 0xa2, 0x3d, 0x2f, 0x6b,
0x7f, 0xcc, 0xd2, 0xde, 0x4f, 0x9b, 0x0f, 0xda, 0x6b, 0x24, 0x98, 0x59, 0x99, 0xd8, 0x41, 0xb5,
0x21, 0x65, 0xfc, 0xe7, 0x28, 0xe8, 0xc2, 0xb9, 0xeb, 0x81, 0x6a, 0xcd, 0x17, 0x8f, 0xf3, 0x57,
0x54, 0x58, 0x9f, 0x28, 0x29, 0xb5, 0xe3, 0x34, 0x10, 0xc9, 0xe2, 0xe2, 0x31, 0xc2, 0x22, 0x70,
0x1e, 0x51, 0x9f, 0xc5, 0x97, 0x13, 0x6c, 0xc5, 0xf7, 0x66, 0x6b, 0x28, 0x36, 0x7c, 0xbc, 0x84,
0x46, 0x56, 0x30, 0xe0, 0xcf, 0x51, 0x39, 0x02, 0xca, 0x02, 0xbf, 0x5e, 0x92, 0x8d, 0x4b, 0xfc,
0x22, 0x32, 0x4a, 0xd4, 0x5f, 0xbc, 0x8b, 0x2a, 0x1e, 0x30, 0x46, 0x1d, 0xa8, 0x97, 0x65, 0xe2,
0x47, 0x2a, 0xb1, 0x72, 0x12, 0x87, 0xc9, 0xfc, 0x7f, 0xeb, 0x85, 0x86, 0x36, 0x95, 0x55, 0xc7,
0x2e, 0xe3, 0xf8, 0xd7, 0xa5, 0xf1, 0x30, 0x1e, 0x77, 0x21, 0x51, 0x2d, 0x87, 0x63, 0x4b, 0x71,
0x6d, 0xcc, 0x23, 0xa9, 0xd1, 0xe8, 0xa2, 0x92, 0xcb, 0xc1, 0x13, 0xc6, 0x17, 0x76, 0x36, 0xdb,
0x3f, 0x3c, 0xeb, 0xd1, 0x5a, 0x35, 0xc5, 0x54, 0x3a, 0x12, 0x98, 0x24, 0x86, 0x6e, 0xfd, 0x9b,
0x4f, 0x6e, 0x24, 0xe6, 0x05, 0xff, 0xa7, 0xa1, 0x46, 0xbc, 0x59, 0x0e, 0x7a, 0xbd, 0x08, 0x18,
0xb3, 0x26, 0x9d, 0xa1, 0x0b, 0x3e, 0xef, 0x1c, 0x1d, 0x12, 0x56, 0xd7, 0xa4, 0x92, 0xd3, 0xa7,
0x29, 0x39, 0x5b, 0x87, 0x6b, 0xb5, 0x94, 0xb6, 0xc6, 0xda, 0x14, 0x46, 0x1e, 0x90, 0x85, 0x7f,
0x43, 0x55, 0x06, 0x76, 0x04, 0x9c, 0x40, 0x5f, 0x6d, 0x92, 0xf6, 0x0a, 0x8d, 0xca, 0x06, 0x69,
0x40, 0x60, 0xd3, 0x61, 0xbc, 0x90, 0x08, 0xf4, 0x21, 0x02, 0xdf, 0x06, 0xab, 0x36, 0x9b, 0x36,
0xab, 0x67, 0x73, 0x20, 0xb2, 0xc0, 0x6c, 0xbd, 0xd4, 0x50, 0x2d, 0x33, 0xfd, 0xf8, 0x0a, 0x21,
0x7b, 0x3e, 0x59, 0xf3, 0xbe, 0xfc, 0xf4, 0x2c, 0x87, 0x92, 0x41, 0x5d, 0x6c, 0xcc, 0x24, 0xc4,
0x48, 0x8a, 0x0d, 0x37, 0x51, 0xe9, 0x2a, 0xf0, 0x81, 0xd5, 0x4b, 0xdb, 0x85, 0x9d, 0xaa, 0x55,
0x15, 0xae, 0x5e, 0x88, 0x00, 0x89, 0xe3, 0xf1, 0xd3, 0x77, 0xdc, 0xc0, 0x57, 0x2f, 0x3a, 0xf5,
0xf4, 0x45, 0x94, 0xa8, 0xbf, 0xad, 0xbf, 0x35, 0xf4, 0xe9, 0xda, 0x96, 0xe3, 0x36, 0x42, 0x76,
0x72, 0x52, 0x9b, 0x6b, 0x21, 0x2d, 0xf9, 0x43, 0x52, 0x59, 0xf8, 0x7b, 0x54, 0xcb, 0xf8, 0xa4,
0x96, 0x56, 0xb2, 0x29, 0x32, 0x6c, 0x24, 0x9b, 0x6b, 0xed, 0x5e, 0xdf, 0xe9, 0xb9, 0x9b, 0x3b,
0x3d, 0x77, 0x7b, 0xa7, 0xe7, 0xfe, 0x9a, 0xe9, 0xda, 0xf5, 0x4c, 0xd7, 0x6e, 0x66, 0xba, 0xf6,
0x6a, 0xa6, 0x6b, 0xff, 0xbc, 0xd6, 0x73, 0x17, 0x15, 0xd5, 0xb3, 0x37, 0x01, 0x00, 0x00, 0xff,
0xff, 0x1d, 0x7e, 0xd9, 0xbe, 0x88, 0x08, 0x00, 0x00,
// 879 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x54, 0xcf, 0x6e, 0xe3, 0x44,
0x18, 0x8f, 0x9b, 0x26, 0x6d, 0xa6, 0x04, 0x56, 0x23, 0x90, 0x42, 0x24, 0x1c, 0x64, 0x21, 0xd4,
0x45, 0x8b, 0x4d, 0x0b, 0x42, 0x2b, 0x21, 0x90, 0xd6, 0x59, 0x21, 0xad, 0xe8, 0xaa, 0x68, 0x5a,
0xed, 0x61, 0x85, 0x04, 0x13, 0xe7, 0xab, 0x6b, 0x62, 0x7b, 0xcc, 0xcc, 0x38, 0x22, 0x7b, 0xe2,
0x01, 0x40, 0xe2, 0x21, 0x78, 0x03, 0xce, 0xdc, 0x7b, 0x63, 0x0f, 0x1c, 0xf6, 0x14, 0xd1, 0xf0,
0x16, 0x7b, 0x42, 0x33, 0x9e, 0x38, 0x36, 0x69, 0x96, 0xdd, 0xf6, 0xe6, 0xf9, 0xf9, 0xfb, 0x7e,
0xbf, 0xef, 0x3f, 0xba, 0x3f, 0xb9, 0x2b, 0xdc, 0x88, 0x79, 0x93, 0x7c, 0x04, 0x3c, 0x05, 0x09,
0xc2, 0x3b, 0x83, 0x31, 0x70, 0x2a, 0x23, 0x96, 0x7a, 0x34, 0x8b, 0x6a, 0xef, 0xe9, 0xc1, 0x08,
0x24, 0x3d, 0xf0, 0x42, 0x48, 0x15, 0x04, 0x63, 0x37, 0xe3, 0x4c, 0x32, 0xfc, 0x49, 0xc1, 0xe2,
0xae, 0x58, 0xdc, 0x95, 0x97, 0xab, 0x58, 0xaa, 0x6f, 0xc3, 0xd2, 0xff, 0x30, 0x8c, 0xe4, 0x79,
0x3e, 0x72, 0x03, 0x96, 0x78, 0x21, 0x0b, 0x99, 0xa7, 0xc9, 0x46, 0xf9, 0x99, 0x7e, 0xe9, 0x87,
0xfe, 0x2a, 0x44, 0xfa, 0x46, 0x44, 0x05, 0x95, 0xd0, 0xe0, 0x3c, 0x4a, 0x81, 0xcf, 0xbc, 0x6c,
0x12, 0x16, 0x51, 0x26, 0x20, 0xa9, 0x37, 0x5d, 0x0b, 0xad, 0xef, 0x6d, 0xf2, 0xe2, 0x79, 0x2a,
0xa3, 0x04, 0xd6, 0x1c, 0x3e, 0xfd, 0x3f, 0x07, 0x11, 0x9c, 0x43, 0x42, 0xd7, 0xfc, 0x3e, 0xde,
0xe4, 0x97, 0xcb, 0x28, 0xf6, 0xa2, 0x54, 0x0a, 0xc9, 0xd7, 0x9c, 0x2a, 0x39, 0x09, 0xe0, 0x53,
0xe0, 0xab, 0x84, 0xe0, 0x47, 0x9a, 0x64, 0x31, 0x5c, 0x95, 0xd3, 0x9d, 0xf5, 0xa6, 0x19, 0xb7,
0x2b, 0xac, 0x9d, 0x3f, 0xb6, 0xd0, 0xce, 0x30, 0xce, 0x85, 0x04, 0x8e, 0xbf, 0x43, 0xbb, 0xaa,
0x50, 0x63, 0x2a, 0x69, 0xcf, 0x7a, 0xd7, 0xda, 0xdf, 0x3b, 0xfc, 0xc8, 0x35, 0xbd, 0xab, 0xc6,
0xed, 0x66, 0x93, 0xb0, 0x68, 0x9b, 0xb2, 0x76, 0xa7, 0x07, 0xee, 0xf1, 0xe8, 0x7b, 0x08, 0xe4,
0x43, 0x90, 0xd4, 0xc7, 0x17, 0xf3, 0x41, 0x63, 0x31, 0x1f, 0xa0, 0x15, 0x46, 0x4a, 0x56, 0x1c,
0xa0, 0x6d, 0x91, 0x41, 0xd0, 0xdb, 0xd2, 0xec, 0xf7, 0xdc, 0xeb, 0x4c, 0x86, 0x6b, 0xc2, 0x3d,
0xc9, 0x20, 0xf0, 0x5f, 0x33, 0x72, 0xdb, 0xea, 0x45, 0x34, 0x39, 0x9e, 0xa0, 0xb6, 0x90, 0x54,
0xe6, 0xa2, 0xd7, 0xd4, 0x32, 0xc3, 0x9b, 0xc9, 0x68, 0x2a, 0xff, 0x75, 0x23, 0xd4, 0x2e, 0xde,
0xc4, 0x48, 0x38, 0xcf, 0x9a, 0xe8, 0x96, 0xb1, 0x1c, 0xb2, 0x74, 0x1c, 0x29, 0x0a, 0x7c, 0x17,
0x6d, 0xcb, 0x59, 0x06, 0xba, 0x88, 0x1d, 0xff, 0xbd, 0x65, 0x8c, 0xa7, 0xb3, 0x0c, 0x9e, 0xcf,
0x07, 0x6f, 0xfe, 0xd7, 0x5e, 0xe1, 0x44, 0x7b, 0xe0, 0x47, 0x65, 0xec, 0x5b, 0xda, 0xf7, 0x8b,
0xba, 0xec, 0xf3, 0xf9, 0xe0, 0x85, 0xed, 0x75, 0x4b, 0xce, 0x7a, 0x98, 0x38, 0x44, 0xdd, 0x98,
0x0a, 0xf9, 0x35, 0x67, 0x23, 0x38, 0x8d, 0x12, 0x30, 0xa5, 0xf9, 0xe0, 0xe5, 0xfa, 0xab, 0x3c,
0xfc, 0xb7, 0x4c, 0x28, 0xdd, 0xa3, 0x2a, 0x11, 0xa9, 0xf3, 0xe2, 0x29, 0xc2, 0x0a, 0x38, 0xe5,
0x34, 0x15, 0x45, 0x72, 0x4a, 0x6d, 0xfb, 0x95, 0xd5, 0xfa, 0x46, 0x0d, 0x1f, 0xad, 0xb1, 0x91,
0x2b, 0x14, 0xf0, 0xfb, 0xa8, 0xcd, 0x81, 0x0a, 0x96, 0xf6, 0x5a, 0xba, 0x70, 0x65, 0xbf, 0x88,
0x46, 0x89, 0xf9, 0x8b, 0x6f, 0xa3, 0x9d, 0x04, 0x84, 0xa0, 0x21, 0xf4, 0xda, 0xda, 0xf0, 0x0d,
0x63, 0xb8, 0xf3, 0xb0, 0x80, 0xc9, 0xf2, 0xbf, 0xf3, 0xa7, 0x85, 0xf6, 0x4c, 0xab, 0x8e, 0x22,
0x21, 0xf1, 0x37, 0x6b, 0xeb, 0xe1, 0xbe, 0x5c, 0x42, 0xca, 0x5b, 0x2f, 0xc7, 0x2d, 0xa3, 0xb5,
0xbb, 0x44, 0x2a, 0xab, 0x31, 0x42, 0xad, 0x48, 0x42, 0xa2, 0x1a, 0xdf, 0xdc, 0xdf, 0x3b, 0xfc,
0xfc, 0x46, 0x43, 0xeb, 0x77, 0x8d, 0x52, 0xeb, 0x81, 0xe2, 0x24, 0x05, 0xb5, 0xf3, 0x8b, 0x85,
0xfa, 0xcb, 0xb1, 0x86, 0x18, 0x02, 0xc9, 0x38, 0x81, 0x1f, 0xf2, 0x88, 0x43, 0x02, 0xa9, 0xc4,
0xef, 0xa0, 0xe6, 0x04, 0x66, 0x66, 0x6a, 0xf7, 0x0c, 0x43, 0xf3, 0x2b, 0x98, 0x11, 0x85, 0xe3,
0x3b, 0x68, 0x97, 0x65, 0x4a, 0x90, 0x71, 0x33, 0x9d, 0x65, 0x3e, 0xc7, 0x06, 0x27, 0xa5, 0x05,
0x76, 0x50, 0x7b, 0x4a, 0xe3, 0x1c, 0xd4, 0x16, 0x36, 0xf7, 0x3b, 0x3e, 0x52, 0xcd, 0x78, 0xa4,
0x11, 0x62, 0xfe, 0x38, 0xbf, 0x6d, 0x95, 0x15, 0x56, 0xfb, 0x8b, 0x7f, 0xb7, 0x50, 0xbf, 0xb8,
0x74, 0xf7, 0xc6, 0x63, 0x0e, 0x42, 0xf8, 0xb3, 0x61, 0x1c, 0x41, 0x2a, 0x87, 0x0f, 0xee, 0x13,
0xd1, 0xb3, 0x74, 0x65, 0x8e, 0xaf, 0x57, 0x99, 0x93, 0x4d, 0xbc, 0xbe, 0x63, 0xb2, 0xe8, 0x6f,
0x34, 0x11, 0xe4, 0x05, 0x61, 0xe1, 0x6f, 0x51, 0x47, 0x40, 0xc0, 0x41, 0x12, 0x38, 0x33, 0x97,
0xed, 0xf0, 0x8a, 0x18, 0xcd, 0x58, 0xe8, 0x81, 0x60, 0x01, 0x8d, 0x8b, 0x03, 0x49, 0xe0, 0x0c,
0x38, 0xa4, 0x01, 0xf8, 0xdd, 0xc5, 0x7c, 0xd0, 0x39, 0x59, 0x12, 0x91, 0x15, 0xa7, 0xf3, 0x97,
0x85, 0xba, 0xb5, 0x6b, 0x84, 0x9f, 0x20, 0x14, 0x2c, 0x37, 0x7d, 0x59, 0x97, 0x2f, 0x6f, 0x34,
0x31, 0xe5, 0xe1, 0x58, 0x5d, 0xf0, 0x12, 0x12, 0xa4, 0xa2, 0x86, 0x07, 0xa8, 0xf5, 0x84, 0xa5,
0x20, 0x7a, 0x2d, 0xdd, 0xd7, 0x8e, 0x9a, 0xb2, 0xc7, 0x0a, 0x20, 0x05, 0x5e, 0xac, 0x62, 0x18,
0xb1, 0xd4, 0x6c, 0x58, 0x65, 0x15, 0x15, 0x4a, 0xcc, 0x5f, 0xe7, 0x67, 0x0b, 0xbd, 0xbd, 0xb1,
0xe4, 0xf8, 0x10, 0xa1, 0xa0, 0x7c, 0x99, 0x99, 0x5c, 0x85, 0x56, 0xfe, 0x21, 0x15, 0x2b, 0xfc,
0x19, 0xea, 0xd6, 0xfa, 0x64, 0xc6, 0xb4, 0xbc, 0x5c, 0x35, 0x35, 0x52, 0xb7, 0xf5, 0x6f, 0x5f,
0x5c, 0xda, 0x8d, 0xa7, 0x97, 0x76, 0xe3, 0xd9, 0xa5, 0xdd, 0xf8, 0x69, 0x61, 0x5b, 0x17, 0x0b,
0xdb, 0x7a, 0xba, 0xb0, 0xad, 0xbf, 0x17, 0xb6, 0xf5, 0xeb, 0x3f, 0x76, 0xe3, 0xf1, 0x8e, 0xa9,
0xd9, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xfc, 0x8a, 0x4c, 0xa8, 0x18, 0x09, 0x00, 0x00,
}

View File

@ -83,6 +83,27 @@ message ClusterList {
repeated Cluster items = 2;
}
// ClusterSelectorRequirement contains values, a key, and an operator that relates the key and values.
// The zero value of ClusterSelectorRequirement is invalid.
// ClusterSelectorRequirement implements both set based match and exact match
message ClusterSelectorRequirement {
// +patchMergeKey=key
// +patchStrategy=merge
optional string key = 1;
// The Operator defines how the Key is matched to the Values. One of "in", "notin",
// "exists", "!", "=", "!=", "gt" or "lt".
optional string operator = 2;
// An array of string values. If the operator is "in" or "notin",
// the values array must be non-empty. If the operator is "exists" or "!",
// the values array must be empty. If the operator is "gt" or "lt", the values
// array must have a single element, which will be interpreted as an integer.
// This array is replaced during a strategic merge patch.
// +optional
repeated string values = 3;
}
// ClusterSpec describes the attributes of a kubernetes cluster.
message ClusterSpec {
// A map of client CIDR to server address.

View File

@ -2111,6 +2111,331 @@ func (x *ClusterList) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
}
func (x ClusterSelector) CodecEncodeSelf(e *codec1978.Encoder) {
var h codecSelfer1234
z, r := codec1978.GenHelperEncoder(e)
_, _, _ = h, z, r
if x == nil {
r.EncodeNil()
} else {
yym1 := z.EncBinary()
_ = yym1
if false {
} else if z.HasExtensions() && z.EncExt(x) {
} else {
h.encClusterSelector((ClusterSelector)(x), e)
}
}
}
func (x *ClusterSelector) CodecDecodeSelf(d *codec1978.Decoder) {
var h codecSelfer1234
z, r := codec1978.GenHelperDecoder(d)
_, _, _ = h, z, r
yym1 := z.DecBinary()
_ = yym1
if false {
} else if z.HasExtensions() && z.DecExt(x) {
} else {
h.decClusterSelector((*ClusterSelector)(x), d)
}
}
func (x *ClusterSelectorRequirement) CodecEncodeSelf(e *codec1978.Encoder) {
var h codecSelfer1234
z, r := codec1978.GenHelperEncoder(e)
_, _, _ = h, z, r
if x == nil {
r.EncodeNil()
} else {
yym1 := z.EncBinary()
_ = yym1
if false {
} else if z.HasExtensions() && z.EncExt(x) {
} else {
yysep2 := !z.EncBinary()
yy2arr2 := z.EncBasicHandle().StructToArray
var yyq2 [3]bool
_, _, _ = yysep2, yyq2, yy2arr2
const yyr2 bool = false
yyq2[2] = len(x.Values) != 0
var yynn2 int
if yyr2 || yy2arr2 {
r.EncodeArrayStart(3)
} else {
yynn2 = 2
for _, b := range yyq2 {
if b {
yynn2++
}
}
r.EncodeMapStart(yynn2)
yynn2 = 0
}
if yyr2 || yy2arr2 {
z.EncSendContainerState(codecSelfer_containerArrayElem1234)
yym4 := z.EncBinary()
_ = yym4
if false {
} else {
r.EncodeString(codecSelferC_UTF81234, string(x.Key))
}
} else {
z.EncSendContainerState(codecSelfer_containerMapKey1234)
r.EncodeString(codecSelferC_UTF81234, string("key"))
z.EncSendContainerState(codecSelfer_containerMapValue1234)
yym5 := z.EncBinary()
_ = yym5
if false {
} else {
r.EncodeString(codecSelferC_UTF81234, string(x.Key))
}
}
if yyr2 || yy2arr2 {
z.EncSendContainerState(codecSelfer_containerArrayElem1234)
yym7 := z.EncBinary()
_ = yym7
if false {
} else {
r.EncodeString(codecSelferC_UTF81234, string(x.Operator))
}
} else {
z.EncSendContainerState(codecSelfer_containerMapKey1234)
r.EncodeString(codecSelferC_UTF81234, string("operator"))
z.EncSendContainerState(codecSelfer_containerMapValue1234)
yym8 := z.EncBinary()
_ = yym8
if false {
} else {
r.EncodeString(codecSelferC_UTF81234, string(x.Operator))
}
}
if yyr2 || yy2arr2 {
z.EncSendContainerState(codecSelfer_containerArrayElem1234)
if yyq2[2] {
if x.Values == nil {
r.EncodeNil()
} else {
yym10 := z.EncBinary()
_ = yym10
if false {
} else {
z.F.EncSliceStringV(x.Values, false, e)
}
}
} else {
r.EncodeNil()
}
} else {
if yyq2[2] {
z.EncSendContainerState(codecSelfer_containerMapKey1234)
r.EncodeString(codecSelferC_UTF81234, string("values"))
z.EncSendContainerState(codecSelfer_containerMapValue1234)
if x.Values == nil {
r.EncodeNil()
} else {
yym11 := z.EncBinary()
_ = yym11
if false {
} else {
z.F.EncSliceStringV(x.Values, false, e)
}
}
}
}
if yyr2 || yy2arr2 {
z.EncSendContainerState(codecSelfer_containerArrayEnd1234)
} else {
z.EncSendContainerState(codecSelfer_containerMapEnd1234)
}
}
}
}
func (x *ClusterSelectorRequirement) CodecDecodeSelf(d *codec1978.Decoder) {
var h codecSelfer1234
z, r := codec1978.GenHelperDecoder(d)
_, _, _ = h, z, r
yym1 := z.DecBinary()
_ = yym1
if false {
} else if z.HasExtensions() && z.DecExt(x) {
} else {
yyct2 := r.ContainerType()
if yyct2 == codecSelferValueTypeMap1234 {
yyl2 := r.ReadMapStart()
if yyl2 == 0 {
z.DecSendContainerState(codecSelfer_containerMapEnd1234)
} else {
x.codecDecodeSelfFromMap(yyl2, d)
}
} else if yyct2 == codecSelferValueTypeArray1234 {
yyl2 := r.ReadArrayStart()
if yyl2 == 0 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
} else {
x.codecDecodeSelfFromArray(yyl2, d)
}
} else {
panic(codecSelferOnlyMapOrArrayEncodeToStructErr1234)
}
}
}
func (x *ClusterSelectorRequirement) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
var h codecSelfer1234
z, r := codec1978.GenHelperDecoder(d)
_, _, _ = h, z, r
var yys3Slc = z.DecScratchBuffer() // default slice to decode into
_ = yys3Slc
var yyhl3 bool = l >= 0
for yyj3 := 0; ; yyj3++ {
if yyhl3 {
if yyj3 >= l {
break
}
} else {
if r.CheckBreak() {
break
}
}
z.DecSendContainerState(codecSelfer_containerMapKey1234)
yys3Slc = r.DecodeBytes(yys3Slc, true, true)
yys3 := string(yys3Slc)
z.DecSendContainerState(codecSelfer_containerMapValue1234)
switch yys3 {
case "key":
if r.TryDecodeAsNil() {
x.Key = ""
} else {
yyv4 := &x.Key
yym5 := z.DecBinary()
_ = yym5
if false {
} else {
*((*string)(yyv4)) = r.DecodeString()
}
}
case "operator":
if r.TryDecodeAsNil() {
x.Operator = ""
} else {
yyv6 := &x.Operator
yym7 := z.DecBinary()
_ = yym7
if false {
} else {
*((*string)(yyv6)) = r.DecodeString()
}
}
case "values":
if r.TryDecodeAsNil() {
x.Values = nil
} else {
yyv8 := &x.Values
yym9 := z.DecBinary()
_ = yym9
if false {
} else {
z.F.DecSliceStringX(yyv8, false, d)
}
}
default:
z.DecStructFieldNotFound(-1, yys3)
} // end switch yys3
} // end for yyj3
z.DecSendContainerState(codecSelfer_containerMapEnd1234)
}
func (x *ClusterSelectorRequirement) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
var h codecSelfer1234
z, r := codec1978.GenHelperDecoder(d)
_, _, _ = h, z, r
var yyj10 int
var yyb10 bool
var yyhl10 bool = l >= 0
yyj10++
if yyhl10 {
yyb10 = yyj10 > l
} else {
yyb10 = r.CheckBreak()
}
if yyb10 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
if r.TryDecodeAsNil() {
x.Key = ""
} else {
yyv11 := &x.Key
yym12 := z.DecBinary()
_ = yym12
if false {
} else {
*((*string)(yyv11)) = r.DecodeString()
}
}
yyj10++
if yyhl10 {
yyb10 = yyj10 > l
} else {
yyb10 = r.CheckBreak()
}
if yyb10 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
if r.TryDecodeAsNil() {
x.Operator = ""
} else {
yyv13 := &x.Operator
yym14 := z.DecBinary()
_ = yym14
if false {
} else {
*((*string)(yyv13)) = r.DecodeString()
}
}
yyj10++
if yyhl10 {
yyb10 = yyj10 > l
} else {
yyb10 = r.CheckBreak()
}
if yyb10 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
if r.TryDecodeAsNil() {
x.Values = nil
} else {
yyv15 := &x.Values
yym16 := z.DecBinary()
_ = yym16
if false {
} else {
z.F.DecSliceStringX(yyv15, false, d)
}
}
for {
yyj10++
if yyhl10 {
yyb10 = yyj10 > l
} else {
yyb10 = r.CheckBreak()
}
if yyb10 {
break
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
z.DecStructFieldNotFound(yyj10-1, "")
}
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
}
func (x codecSelfer1234) encSliceServerAddressByClientCIDR(v []ServerAddressByClientCIDR, e *codec1978.Encoder) {
var h codecSelfer1234
z, r := codec1978.GenHelperEncoder(e)
@ -2467,3 +2792,122 @@ func (x codecSelfer1234) decSliceCluster(v *[]Cluster, d *codec1978.Decoder) {
*v = yyv1
}
}
func (x codecSelfer1234) encClusterSelector(v ClusterSelector, e *codec1978.Encoder) {
var h codecSelfer1234
z, r := codec1978.GenHelperEncoder(e)
_, _, _ = h, z, r
r.EncodeArrayStart(len(v))
for _, yyv1 := range v {
z.EncSendContainerState(codecSelfer_containerArrayElem1234)
yy2 := &yyv1
yy2.CodecEncodeSelf(e)
}
z.EncSendContainerState(codecSelfer_containerArrayEnd1234)
}
func (x codecSelfer1234) decClusterSelector(v *ClusterSelector, d *codec1978.Decoder) {
var h codecSelfer1234
z, r := codec1978.GenHelperDecoder(d)
_, _, _ = h, z, r
yyv1 := *v
yyh1, yyl1 := z.DecSliceHelperStart()
var yyc1 bool
_ = yyc1
if yyl1 == 0 {
if yyv1 == nil {
yyv1 = []ClusterSelectorRequirement{}
yyc1 = true
} else if len(yyv1) != 0 {
yyv1 = yyv1[:0]
yyc1 = true
}
} else if yyl1 > 0 {
var yyrr1, yyrl1 int
var yyrt1 bool
_, _ = yyrl1, yyrt1
yyrr1 = yyl1 // len(yyv1)
if yyl1 > cap(yyv1) {
yyrg1 := len(yyv1) > 0
yyv21 := yyv1
yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 56)
if yyrt1 {
if yyrl1 <= cap(yyv1) {
yyv1 = yyv1[:yyrl1]
} else {
yyv1 = make([]ClusterSelectorRequirement, yyrl1)
}
} else {
yyv1 = make([]ClusterSelectorRequirement, yyrl1)
}
yyc1 = true
yyrr1 = len(yyv1)
if yyrg1 {
copy(yyv1, yyv21)
}
} else if yyl1 != len(yyv1) {
yyv1 = yyv1[:yyl1]
yyc1 = true
}
yyj1 := 0
for ; yyj1 < yyrr1; yyj1++ {
yyh1.ElemContainerState(yyj1)
if r.TryDecodeAsNil() {
yyv1[yyj1] = ClusterSelectorRequirement{}
} else {
yyv2 := &yyv1[yyj1]
yyv2.CodecDecodeSelf(d)
}
}
if yyrt1 {
for ; yyj1 < yyl1; yyj1++ {
yyv1 = append(yyv1, ClusterSelectorRequirement{})
yyh1.ElemContainerState(yyj1)
if r.TryDecodeAsNil() {
yyv1[yyj1] = ClusterSelectorRequirement{}
} else {
yyv3 := &yyv1[yyj1]
yyv3.CodecDecodeSelf(d)
}
}
}
} else {
yyj1 := 0
for ; !r.CheckBreak(); yyj1++ {
if yyj1 >= len(yyv1) {
yyv1 = append(yyv1, ClusterSelectorRequirement{}) // var yyz1 ClusterSelectorRequirement
yyc1 = true
}
yyh1.ElemContainerState(yyj1)
if yyj1 < len(yyv1) {
if r.TryDecodeAsNil() {
yyv1[yyj1] = ClusterSelectorRequirement{}
} else {
yyv4 := &yyv1[yyj1]
yyv4.CodecDecodeSelf(d)
}
} else {
z.DecSwallow()
}
}
if yyj1 < len(yyv1) {
yyv1 = yyv1[:yyj1]
yyc1 = true
} else if yyj1 == 0 && yyv1 == nil {
yyv1 = []ClusterSelectorRequirement{}
yyc1 = true
}
}
yyh1.End()
if yyc1 {
*v = yyv1
}
}

View File

@ -123,7 +123,32 @@ type ClusterList struct {
Items []Cluster `json:"items" protobuf:"bytes,2,rep,name=items"`
}
// Expressed as value of annotation for selecting the clusters on which a resource is created.
type ClusterSelector []ClusterSelectorRequirement
// ClusterSelectorRequirement contains values, a key, and an operator that relates the key and values.
// The zero value of ClusterSelectorRequirement is invalid.
// ClusterSelectorRequirement implements both set based match and exact match
type ClusterSelectorRequirement struct {
// +patchMergeKey=key
// +patchStrategy=merge
Key string `json:"key" patchStrategy:"merge" patchMergeKey:"key" protobuf:"bytes,1,opt,name=key"`
// The Operator defines how the Key is matched to the Values. One of "in", "notin",
// "exists", "!", "=", "!=", "gt" or "lt".
Operator string `json:"operator" protobuf:"bytes,2,opt,name=operator"`
// An array of string values. If the operator is "in" or "notin",
// the values array must be non-empty. If the operator is "exists" or "!",
// the values array must be empty. If the operator is "gt" or "lt", the values
// array must have a single element, which will be interpreted as an integer.
// This array is replaced during a strategic merge patch.
// +optional
Values []string `json:"values,omitempty" protobuf:"bytes,3,rep,name=values"`
}
const (
// FederationNamespaceSystem is the system namespace where we place federation control plane components.
FederationNamespaceSystem string = "federation-system"
// FederationClusterSelectorAnnotation is used to determine placement of objects on federated clusters
FederationClusterSelectorAnnotation string = "federation.alpha.kubernetes.io/cluster-selector"
)

View File

@ -62,6 +62,16 @@ func (ClusterList) SwaggerDoc() map[string]string {
return map_ClusterList
}
var map_ClusterSelectorRequirement = map[string]string{
"": "ClusterSelectorRequirement contains values, a key, and an operator that relates the key and values. The zero value of ClusterSelectorRequirement is invalid. ClusterSelectorRequirement implements both set based match and exact match",
"operator": "The Operator defines how the Key is matched to the Values. One of \"in\", \"notin\", \"exists\", \"!\", \"=\", \"!=\", \"gt\" or \"lt\".",
"values": "An array of string values. If the operator is \"in\" or \"notin\", the values array must be non-empty. If the operator is \"exists\" or \"!\", the values array must be empty. If the operator is \"gt\" or \"lt\", the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch.",
}
func (ClusterSelectorRequirement) SwaggerDoc() map[string]string {
return map_ClusterSelectorRequirement
}
var map_ClusterSpec = map[string]string{
"": "ClusterSpec describes the attributes of a kubernetes cluster.",
"serverAddressByClientCIDRs": "A map of client CIDR to server address. This is to help clients reach servers in the most network-efficient way possible. Clients can use the appropriate server address as per the CIDR that they match. In case of multiple matches, clients should use the longest matching CIDR.",

View File

@ -39,6 +39,7 @@ func RegisterDeepCopies(scheme *runtime.Scheme) error {
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1beta1_Cluster, InType: reflect.TypeOf(&Cluster{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1beta1_ClusterCondition, InType: reflect.TypeOf(&ClusterCondition{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1beta1_ClusterList, InType: reflect.TypeOf(&ClusterList{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1beta1_ClusterSelectorRequirement, InType: reflect.TypeOf(&ClusterSelectorRequirement{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1beta1_ClusterSpec, InType: reflect.TypeOf(&ClusterSpec{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1beta1_ClusterStatus, InType: reflect.TypeOf(&ClusterStatus{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1beta1_ServerAddressByClientCIDR, InType: reflect.TypeOf(&ServerAddressByClientCIDR{})},
@ -97,6 +98,21 @@ func DeepCopy_v1beta1_ClusterList(in interface{}, out interface{}, c *conversion
}
}
// DeepCopy_v1beta1_ClusterSelectorRequirement is an autogenerated deepcopy function.
func DeepCopy_v1beta1_ClusterSelectorRequirement(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*ClusterSelectorRequirement)
out := out.(*ClusterSelectorRequirement)
*out = *in
if in.Values != nil {
in, out := &in.Values, &out.Values
*out = make([]string, len(*in))
copy(*out, *in)
}
return nil
}
}
// DeepCopy_v1beta1_ClusterSpec is an autogenerated deepcopy function.
func DeepCopy_v1beta1_ClusterSpec(in interface{}, out interface{}, c *conversion.Cloner) error {
{

View File

@ -17,6 +17,7 @@ go_library(
"//federation/client/clientset_generated/federation_clientset:go_default_library",
"//federation/pkg/federatedtypes:go_default_library",
"//federation/pkg/federation-controller/util:go_default_library",
"//federation/pkg/federation-controller/util/clusterselector:go_default_library",
"//federation/pkg/federation-controller/util/deletionhelper:go_default_library",
"//federation/pkg/federation-controller/util/eventsink:go_default_library",
"//pkg/api:go_default_library",

View File

@ -37,6 +37,7 @@ import (
federationclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset"
"k8s.io/kubernetes/federation/pkg/federatedtypes"
"k8s.io/kubernetes/federation/pkg/federation-controller/util"
"k8s.io/kubernetes/federation/pkg/federation-controller/util/clusterselector"
"k8s.io/kubernetes/federation/pkg/federation-controller/util/deletionhelper"
"k8s.io/kubernetes/federation/pkg/federation-controller/util/eventsink"
"k8s.io/kubernetes/pkg/api"
@ -356,10 +357,15 @@ func (s *FederationSyncController) reconcile(namespacedName types.NamespacedName
}
operationsAccessor := func(adapter federatedtypes.FederatedTypeAdapter, clusters []*federationapi.Cluster, obj pkgruntime.Object) ([]util.FederatedOperation, error) {
return clusterOperations(adapter, clusters, obj, func(clusterName string) (interface{}, bool, error) {
operations, err := clusterOperations(adapter, clusters, obj, key, func(clusterName string) (interface{}, bool, error) {
return s.informer.GetTargetStore().GetByKey(clusterName, key)
})
}, clusterselector.SendToCluster)
if err != nil {
s.eventRecorder.Eventf(obj, api.EventTypeWarning, "FedClusterOperationsError", "Error obtaining sync operations for %s: %s error: %s", kind, key, err.Error())
}
return operations, err
}
return syncToClusters(
s.informer.GetReadyClusters,
operationsAccessor,
@ -451,11 +457,16 @@ func syncToClusters(clustersAccessor clustersAccessorFunc, operationsAccessor op
}
type clusterObjectAccessorFunc func(clusterName string) (interface{}, bool, error)
type clusterSelectorFunc func(map[string]string, map[string]string) (bool, error)
// clusterOperations returns the list of operations needed to synchronize the state of the given object to the provided clusters
func clusterOperations(adapter federatedtypes.FederatedTypeAdapter, clusters []*federationapi.Cluster, obj pkgruntime.Object, accessor clusterObjectAccessorFunc) ([]util.FederatedOperation, error) {
key := federatedtypes.ObjectKey(adapter, obj)
func clusterOperations(adapter federatedtypes.FederatedTypeAdapter, clusters []*federationapi.Cluster, obj pkgruntime.Object, key string, accessor clusterObjectAccessorFunc, selector clusterSelectorFunc) ([]util.FederatedOperation, error) {
// The data should not be modified.
desiredObj := adapter.Copy(obj)
objMeta := adapter.ObjectMeta(desiredObj)
kind := adapter.Kind()
operations := make([]util.FederatedOperation, 0)
for _, cluster := range clusters {
clusterObj, found, err := accessor(cluster.Name)
if err != nil {
@ -463,18 +474,28 @@ func clusterOperations(adapter federatedtypes.FederatedTypeAdapter, clusters []*
runtime.HandleError(wrappedErr)
return nil, wrappedErr
}
// The data should not be modified.
desiredObj := adapter.Copy(obj)
send, err := selector(cluster.Labels, objMeta.Annotations)
if err != nil {
glog.Errorf("Error processing ClusterSelector cluster: %s for %s map: %s error: %s", cluster.Name, kind, key, err.Error())
return nil, err
} else if !send {
glog.V(5).Infof("Skipping cluster: %s for %s: %s reason: cluster selectors do not match: %-v %-v", cluster.Name, kind, key, cluster.ObjectMeta.Labels, objMeta.Annotations[federationapi.FederationClusterSelectorAnnotation])
}
var operationType util.FederatedOperationType = ""
if found {
switch {
case found && send:
clusterObj := clusterObj.(pkgruntime.Object)
if !adapter.Equivalent(desiredObj, clusterObj) {
operationType = util.OperationTypeUpdate
}
} else {
case found && !send:
operationType = util.OperationTypeDelete
case !found && send:
operationType = util.OperationTypeAdd
}
if len(operationType) > 0 {
operations = append(operations, util.FederatedOperation{
Type: operationType,

View File

@ -103,32 +103,53 @@ func TestClusterOperations(t *testing.T) {
testCases := map[string]struct {
clusterObject pkgruntime.Object
expectedErr bool
expectedSendErr bool
sendToCluster bool
operationType util.FederatedOperationType
}{
"Accessor error returned": {
expectedErr: true,
},
"sendToCluster error returned": {
expectedSendErr: true,
},
"Missing cluster object should result in add operation": {
operationType: util.OperationTypeAdd,
sendToCluster: true,
},
"Differing cluster object should result in update operation": {
clusterObject: differingObj,
operationType: util.OperationTypeUpdate,
sendToCluster: true,
},
"Matching object and not matching ClusterSelector should result in delete operation": {
clusterObject: obj,
operationType: util.OperationTypeDelete,
sendToCluster: false,
},
"Matching cluster object should not result in an operation": {
clusterObject: obj,
sendToCluster: true,
},
}
for testName, testCase := range testCases {
t.Run(testName, func(t *testing.T) {
clusters := []*federationapi.Cluster{fedtest.NewCluster("cluster1", apiv1.ConditionTrue)}
operations, err := clusterOperations(adapter, clusters, obj, func(string) (interface{}, bool, error) {
key := federatedtypes.ObjectKey(adapter, obj)
operations, err := clusterOperations(adapter, clusters, obj, key, func(string) (interface{}, bool, error) {
if testCase.expectedErr {
return nil, false, awfulError
}
return testCase.clusterObject, (testCase.clusterObject != nil), nil
}, func(map[string]string, map[string]string) (bool, error) {
if testCase.expectedSendErr {
return false, awfulError
}
return testCase.sendToCluster, nil
})
if testCase.expectedErr {
if testCase.expectedErr || testCase.expectedSendErr {
require.Error(t, err, "An error was expected")
} else {
require.NoError(t, err, "An error was not expected")

View File

@ -88,6 +88,7 @@ filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//federation/pkg/federation-controller/util/clusterselector:all-srcs",
"//federation/pkg/federation-controller/util/deletionhelper:all-srcs",
"//federation/pkg/federation-controller/util/eventsink:all-srcs",
"//federation/pkg/federation-controller/util/finalizers:all-srcs",

View File

@ -0,0 +1,44 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)
go_test(
name = "go_default_test",
srcs = ["clusterselector_test.go"],
library = ":go_default_library",
tags = ["automanaged"],
deps = [
"//federation/apis/federation/v1beta1:go_default_library",
"//vendor/github.com/stretchr/testify/require:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = ["clusterselector.go"],
tags = ["automanaged"],
deps = [
"//federation/apis/federation/v1beta1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/selection:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)

View File

@ -0,0 +1,86 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package clusterselector
import (
"encoding/json"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/selection"
federation_v1beta1 "k8s.io/kubernetes/federation/apis/federation/v1beta1"
)
// Parses the cluster selector annotation to find out if the object with that annotation should be forwarded to a cluster with the given clusterLabels.
func SendToCluster(clusterLabels map[string]string, annotations map[string]string) (bool, error) {
// Check if a ClusterSelector annotation exists and send to all clusters when it does not exist
val, ok := annotations[federation_v1beta1.FederationClusterSelectorAnnotation]
if !ok {
return true, nil
}
selector, err := getSelector(val)
if err != nil {
return false, err
}
return selector.Matches(labels.Set(clusterLabels)), nil
}
func getSelector(annotation string) (labels.Selector, error) {
selector := labels.NewSelector()
requirements := make([]federation_v1beta1.ClusterSelectorRequirement, 0)
err := json.Unmarshal([]byte(annotation), &requirements)
if err != nil {
return nil, err
}
for _, requirement := range requirements {
r, err := labels.NewRequirement(requirement.Key, ConvertOperator(requirement.Operator), requirement.Values)
if err != nil {
// Stop processing and assume failure since we have no way of knowing the end users intent for this or any other clusters.
return nil, err
}
selector = selector.Add(*r)
}
return selector, nil
}
// ConvertOperator converts a string operator into selection.Operator type
func ConvertOperator(source string) selection.Operator {
var op selection.Operator
switch source {
case "!", "DoesNotExist":
op = selection.DoesNotExist
case "=":
op = selection.Equals
case "==":
op = selection.DoubleEquals
case "in", "In":
op = selection.In
case "!=":
op = selection.NotEquals
case "notin", "NotIn":
op = selection.NotIn
case "exists", "Exists":
op = selection.Exists
case "gt", "Gt", ">":
op = selection.GreaterThan
case "lt", "Lt", "<":
op = selection.LessThan
}
return op
}

View File

@ -0,0 +1,98 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package clusterselector
import (
"testing"
"github.com/stretchr/testify/require"
federationapi "k8s.io/kubernetes/federation/apis/federation/v1beta1"
)
func TestSendToCluster(t *testing.T) {
clusterLabels := map[string]string{
"location": "europe",
"environment": "prod",
"version": "15",
}
testCases := map[string]struct {
objectAnnotations map[string]string
expectedResult bool
expectedErr bool
}{
"match with single annotation": {
objectAnnotations: map[string]string{
federationapi.FederationClusterSelectorAnnotation: `[{"key": "location", "operator": "in", "values": ["europe"]}]`,
},
expectedResult: true,
},
"match on multiple annotations": {
objectAnnotations: map[string]string{
federationapi.FederationClusterSelectorAnnotation: `[{"key": "location", "operator": "in", "values": ["europe"]}, {"key": "environment", "operator": "==", "values": ["prod"]}]`,
},
expectedResult: true,
},
"mismatch on one annotation": {
objectAnnotations: map[string]string{
federationapi.FederationClusterSelectorAnnotation: `[{"key": "location", "operator": "in", "values": ["europe"]}, {"key": "environment", "operator": "==", "values": ["test"]}]`,
},
expectedResult: false,
},
"match on not equal annotation": {
objectAnnotations: map[string]string{
federationapi.FederationClusterSelectorAnnotation: `[{"key": "location", "operator": "!=", "values": ["usa"]}, {"key": "environment", "operator": "in", "values": ["prod"]}]`,
},
expectedResult: true,
},
"match on greater than annotation": {
objectAnnotations: map[string]string{
federationapi.FederationClusterSelectorAnnotation: `[{"key": "version", "operator": ">", "values": ["14"]}]`,
},
expectedResult: true,
},
"mismatch on greater than annotation": {
objectAnnotations: map[string]string{
federationapi.FederationClusterSelectorAnnotation: `[{"key": "version", "operator": ">", "values": ["15"]}]`,
},
expectedResult: false,
},
"unable to parse annotation": {
objectAnnotations: map[string]string{
federationapi.FederationClusterSelectorAnnotation: `[{"not able to parse",}]`,
},
expectedResult: false,
expectedErr: true,
},
}
for testName, testCase := range testCases {
t.Run(testName, func(t *testing.T) {
result, err := SendToCluster(clusterLabels, testCase.objectAnnotations)
if testCase.expectedErr {
require.Error(t, err, "An error was expected")
} else {
require.NoError(t, err, "An error was not expected")
}
require.Equal(t, testCase.expectedResult, result, "Unexpected response from SendToCluster")
})
}
}