mirror of https://github.com/k3s-io/k3s
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 upstreampull/6/head
parent
0c25199117
commit
32787c5258
|
@ -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,
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
)
|
||||
|
|
|
@ -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.",
|
||||
|
|
|
@ -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 {
|
||||
{
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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"],
|
||||
)
|
|
@ -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
|
||||
}
|
|
@ -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")
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue