diff --git a/federation/apis/federation/v1beta1/generated.pb.go b/federation/apis/federation/v1beta1/generated.pb.go index 841972aa87e..052eadcebfb 100644 --- a/federation/apis/federation/v1beta1/generated.pb.go +++ b/federation/apis/federation/v1beta1/generated.pb.go @@ -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, } diff --git a/federation/apis/federation/v1beta1/generated.proto b/federation/apis/federation/v1beta1/generated.proto index f62ce9c3a66..fc9badaf4c1 100644 --- a/federation/apis/federation/v1beta1/generated.proto +++ b/federation/apis/federation/v1beta1/generated.proto @@ -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. diff --git a/federation/apis/federation/v1beta1/types.generated.go b/federation/apis/federation/v1beta1/types.generated.go index a4b1540babf..52b18ada29c 100644 --- a/federation/apis/federation/v1beta1/types.generated.go +++ b/federation/apis/federation/v1beta1/types.generated.go @@ -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 + } +} diff --git a/federation/apis/federation/v1beta1/types.go b/federation/apis/federation/v1beta1/types.go index 1b5ebbd01ab..3f2578413a9 100644 --- a/federation/apis/federation/v1beta1/types.go +++ b/federation/apis/federation/v1beta1/types.go @@ -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" ) diff --git a/federation/apis/federation/v1beta1/types_swagger_doc_generated.go b/federation/apis/federation/v1beta1/types_swagger_doc_generated.go index 7cc9e6800db..58a15d38527 100644 --- a/federation/apis/federation/v1beta1/types_swagger_doc_generated.go +++ b/federation/apis/federation/v1beta1/types_swagger_doc_generated.go @@ -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.", diff --git a/federation/apis/federation/v1beta1/zz_generated.deepcopy.go b/federation/apis/federation/v1beta1/zz_generated.deepcopy.go index 4c20e932983..00e8b5caf63 100644 --- a/federation/apis/federation/v1beta1/zz_generated.deepcopy.go +++ b/federation/apis/federation/v1beta1/zz_generated.deepcopy.go @@ -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 { { diff --git a/federation/pkg/federation-controller/sync/BUILD b/federation/pkg/federation-controller/sync/BUILD index a597ede5e78..df5861468d8 100644 --- a/federation/pkg/federation-controller/sync/BUILD +++ b/federation/pkg/federation-controller/sync/BUILD @@ -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", diff --git a/federation/pkg/federation-controller/sync/controller.go b/federation/pkg/federation-controller/sync/controller.go index 0d607e6915b..7b5e3bef848 100644 --- a/federation/pkg/federation-controller/sync/controller.go +++ b/federation/pkg/federation-controller/sync/controller.go @@ -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, diff --git a/federation/pkg/federation-controller/sync/controller_test.go b/federation/pkg/federation-controller/sync/controller_test.go index 9f077ad7878..10023a4eb38 100644 --- a/federation/pkg/federation-controller/sync/controller_test.go +++ b/federation/pkg/federation-controller/sync/controller_test.go @@ -101,34 +101,55 @@ func TestClusterOperations(t *testing.T) { federatedtypes.SetAnnotation(adapter, differingObj, "foo", "bar") testCases := map[string]struct { - clusterObject pkgruntime.Object - expectedErr bool + 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") diff --git a/federation/pkg/federation-controller/util/BUILD b/federation/pkg/federation-controller/util/BUILD index 4abcec5d6a0..ea101af8fef 100644 --- a/federation/pkg/federation-controller/util/BUILD +++ b/federation/pkg/federation-controller/util/BUILD @@ -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", diff --git a/federation/pkg/federation-controller/util/clusterselector/BUILD b/federation/pkg/federation-controller/util/clusterselector/BUILD new file mode 100644 index 00000000000..05d9d8cda90 --- /dev/null +++ b/federation/pkg/federation-controller/util/clusterselector/BUILD @@ -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"], +) diff --git a/federation/pkg/federation-controller/util/clusterselector/clusterselector.go b/federation/pkg/federation-controller/util/clusterselector/clusterselector.go new file mode 100644 index 00000000000..e4a56f25a90 --- /dev/null +++ b/federation/pkg/federation-controller/util/clusterselector/clusterselector.go @@ -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 +} diff --git a/federation/pkg/federation-controller/util/clusterselector/clusterselector_test.go b/federation/pkg/federation-controller/util/clusterselector/clusterselector_test.go new file mode 100644 index 00000000000..247ef299cc1 --- /dev/null +++ b/federation/pkg/federation-controller/util/clusterselector/clusterselector_test.go @@ -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") + }) + } +}