mirror of https://github.com/k3s-io/k3s
Support multiple versions in custom metrics client
This changes the custom metrics client logic over to support multiple versions of the custom metrics API by checking discovery to find the appropriate versions. Fixes #68011 Co-authored-by: Solly Ross <sross@redhat.com>pull/8/head
parent
e5f55dd9d0
commit
364afe4042
|
@ -28,6 +28,7 @@ import (
|
|||
"k8s.io/client-go/scale"
|
||||
"k8s.io/kubernetes/pkg/controller/podautoscaler"
|
||||
"k8s.io/kubernetes/pkg/controller/podautoscaler/metrics"
|
||||
|
||||
resourceclient "k8s.io/metrics/pkg/client/clientset/versioned/typed/metrics/v1beta1"
|
||||
"k8s.io/metrics/pkg/client/custom_metrics"
|
||||
"k8s.io/metrics/pkg/client/external_metrics"
|
||||
|
@ -48,9 +49,19 @@ func startHPAController(ctx ControllerContext) (http.Handler, bool, error) {
|
|||
|
||||
func startHPAControllerWithRESTClient(ctx ControllerContext) (http.Handler, bool, error) {
|
||||
clientConfig := ctx.ClientBuilder.ConfigOrDie("horizontal-pod-autoscaler")
|
||||
hpaClient := ctx.ClientBuilder.ClientOrDie("horizontal-pod-autoscaler")
|
||||
|
||||
apiVersionsGetter := custom_metrics.NewAvailableAPIsGetter(hpaClient.Discovery())
|
||||
// invalidate the discovery information roughly once per resync interval our API
|
||||
// information is *at most* two resync intervals old.
|
||||
go custom_metrics.PeriodicallyInvalidate(
|
||||
apiVersionsGetter,
|
||||
ctx.ComponentConfig.HPAController.HorizontalPodAutoscalerSyncPeriod.Duration,
|
||||
ctx.Stop)
|
||||
|
||||
metricsClient := metrics.NewRESTMetricsClient(
|
||||
resourceclient.NewForConfigOrDie(clientConfig),
|
||||
custom_metrics.NewForConfigOrDie(clientConfig),
|
||||
custom_metrics.NewForConfig(clientConfig, ctx.RESTMapper, apiVersionsGetter),
|
||||
external_metrics.NewForConfigOrDie(clientConfig),
|
||||
)
|
||||
return startHPAControllerWithMetricsClient(ctx, metricsClient)
|
||||
|
|
|
@ -90,6 +90,18 @@
|
|||
"ImportPath": "github.com/peterbourgon/diskv",
|
||||
"Rev": "5f041e8faa004a95c88a202771f4cc3e991971e6"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/pmezard/go-difflib/difflib",
|
||||
"Rev": "d8ed2627bdf02c080bf22230dbb337003b7aba2d"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/stretchr/testify/assert",
|
||||
"Rev": "c679ae2cc0cb27ec3293fea7e254e47386f05d69"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/stretchr/testify/require",
|
||||
"Rev": "c679ae2cc0cb27ec3293fea7e254e47386f05d69"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/crypto/ssh/terminal",
|
||||
"Rev": "de0752318171da717af4ce24d0a2e8626afaeb11"
|
||||
|
@ -438,6 +450,10 @@
|
|||
"ImportPath": "k8s.io/client-go/discovery",
|
||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/discovery/cached",
|
||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/discovery/fake",
|
||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
|
|
|
@ -46,6 +46,7 @@ func addKnownTypes(scheme *runtime.Scheme) error {
|
|||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&MetricValue{},
|
||||
&MetricValueList{},
|
||||
&MetricListOptions{},
|
||||
)
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -71,6 +71,22 @@ type MetricValue struct {
|
|||
// for all objects matching the given label selector
|
||||
const AllObjects = "*"
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// MetricListOptions is used to select metrics by their label selectors
|
||||
type MetricListOptions struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
|
||||
// A selector to restrict the list of returned objects by their labels.
|
||||
// Defaults to everything.
|
||||
// +optional
|
||||
LabelSelector string `json:"labelSelector,omitempty" protobuf:"bytes,1,opt,name=labelSelector"`
|
||||
|
||||
// A selector to restrict the list of returned metrics by their labels
|
||||
// +optional
|
||||
MetricLabelSelector string `json:"metricLabelSelector,omitempty" protobuf:"bytes,2,opt,name=metricLabelSelector"`
|
||||
}
|
||||
|
||||
// NOTE: ObjectReference is copied from k8s.io/kubernetes/pkg/api/types.go. We
|
||||
// cannot depend on k8s.io/kubernetes/pkg/api because that creates cyclic
|
||||
// dependency between k8s.io/metrics and k8s.io/kubernetes. We cannot depend on
|
||||
|
|
|
@ -25,6 +25,7 @@ limitations under the License.
|
|||
k8s.io/kubernetes/vendor/k8s.io/metrics/pkg/apis/custom_metrics/v1beta1/generated.proto
|
||||
|
||||
It has these top-level messages:
|
||||
MetricListOptions
|
||||
MetricValue
|
||||
MetricValueList
|
||||
*/
|
||||
|
@ -52,18 +53,49 @@ var _ = math.Inf
|
|||
// proto package needs to be updated.
|
||||
const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
|
||||
|
||||
func (m *MetricListOptions) Reset() { *m = MetricListOptions{} }
|
||||
func (*MetricListOptions) ProtoMessage() {}
|
||||
func (*MetricListOptions) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{0} }
|
||||
|
||||
func (m *MetricValue) Reset() { *m = MetricValue{} }
|
||||
func (*MetricValue) ProtoMessage() {}
|
||||
func (*MetricValue) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{0} }
|
||||
func (*MetricValue) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{1} }
|
||||
|
||||
func (m *MetricValueList) Reset() { *m = MetricValueList{} }
|
||||
func (*MetricValueList) ProtoMessage() {}
|
||||
func (*MetricValueList) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{1} }
|
||||
func (*MetricValueList) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{2} }
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*MetricListOptions)(nil), "k8s.io.metrics.pkg.apis.custom_metrics.v1beta1.MetricListOptions")
|
||||
proto.RegisterType((*MetricValue)(nil), "k8s.io.metrics.pkg.apis.custom_metrics.v1beta1.MetricValue")
|
||||
proto.RegisterType((*MetricValueList)(nil), "k8s.io.metrics.pkg.apis.custom_metrics.v1beta1.MetricValueList")
|
||||
}
|
||||
func (m *MetricListOptions) 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 *MetricListOptions) MarshalTo(dAtA []byte) (int, error) {
|
||||
var i int
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
dAtA[i] = 0xa
|
||||
i++
|
||||
i = encodeVarintGenerated(dAtA, i, uint64(len(m.LabelSelector)))
|
||||
i += copy(dAtA[i:], m.LabelSelector)
|
||||
dAtA[i] = 0x12
|
||||
i++
|
||||
i = encodeVarintGenerated(dAtA, i, uint64(len(m.MetricLabelSelector)))
|
||||
i += copy(dAtA[i:], m.MetricLabelSelector)
|
||||
return i, nil
|
||||
}
|
||||
|
||||
func (m *MetricValue) Marshal() (dAtA []byte, err error) {
|
||||
size := m.Size()
|
||||
dAtA = make([]byte, size)
|
||||
|
@ -190,6 +222,16 @@ func encodeVarintGenerated(dAtA []byte, offset int, v uint64) int {
|
|||
dAtA[offset] = uint8(v)
|
||||
return offset + 1
|
||||
}
|
||||
func (m *MetricListOptions) Size() (n int) {
|
||||
var l int
|
||||
_ = l
|
||||
l = len(m.LabelSelector)
|
||||
n += 1 + l + sovGenerated(uint64(l))
|
||||
l = len(m.MetricLabelSelector)
|
||||
n += 1 + l + sovGenerated(uint64(l))
|
||||
return n
|
||||
}
|
||||
|
||||
func (m *MetricValue) Size() (n int) {
|
||||
var l int
|
||||
_ = l
|
||||
|
@ -238,6 +280,17 @@ func sovGenerated(x uint64) (n int) {
|
|||
func sozGenerated(x uint64) (n int) {
|
||||
return sovGenerated(uint64((x << 1) ^ uint64((int64(x) >> 63))))
|
||||
}
|
||||
func (this *MetricListOptions) String() string {
|
||||
if this == nil {
|
||||
return "nil"
|
||||
}
|
||||
s := strings.Join([]string{`&MetricListOptions{`,
|
||||
`LabelSelector:` + fmt.Sprintf("%v", this.LabelSelector) + `,`,
|
||||
`MetricLabelSelector:` + fmt.Sprintf("%v", this.MetricLabelSelector) + `,`,
|
||||
`}`,
|
||||
}, "")
|
||||
return s
|
||||
}
|
||||
func (this *MetricValue) String() string {
|
||||
if this == nil {
|
||||
return "nil"
|
||||
|
@ -272,6 +325,114 @@ func valueToStringGenerated(v interface{}) string {
|
|||
pv := reflect.Indirect(rv).Interface()
|
||||
return fmt.Sprintf("*%v", pv)
|
||||
}
|
||||
func (m *MetricListOptions) 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: MetricListOptions: wiretype end group for non-group")
|
||||
}
|
||||
if fieldNum <= 0 {
|
||||
return fmt.Errorf("proto: MetricListOptions: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field LabelSelector", 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.LabelSelector = string(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
case 2:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field MetricLabelSelector", 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.MetricLabelSelector = 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 *MetricValue) Unmarshal(dAtA []byte) error {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
|
@ -715,41 +876,44 @@ func init() {
|
|||
}
|
||||
|
||||
var fileDescriptorGenerated = []byte{
|
||||
// 566 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x93, 0x4f, 0x6f, 0xd3, 0x3e,
|
||||
0x18, 0xc7, 0x9b, 0xf5, 0xd7, 0xfd, 0x3a, 0x8f, 0x69, 0x2c, 0x17, 0xa2, 0x1d, 0xd2, 0x6a, 0x5c,
|
||||
0x0a, 0xd2, 0x6c, 0x6d, 0x20, 0x84, 0xc4, 0x2d, 0xe2, 0x82, 0xb4, 0x81, 0xc8, 0x26, 0x26, 0xf1,
|
||||
0x47, 0xe0, 0x38, 0x4f, 0x53, 0xd3, 0x26, 0x8e, 0x6c, 0xa7, 0xd3, 0x6e, 0xbc, 0x04, 0x5e, 0x56,
|
||||
0x8f, 0xe3, 0xb6, 0x53, 0x45, 0x83, 0x78, 0x1f, 0x28, 0x89, 0xd3, 0x76, 0x1b, 0x7f, 0xb6, 0x5b,
|
||||
0x6c, 0x3f, 0xdf, 0x8f, 0xbf, 0xcf, 0xf7, 0x71, 0xd0, 0xc9, 0xf0, 0xa9, 0xc2, 0x5c, 0x90, 0x61,
|
||||
0x16, 0x80, 0x4c, 0x40, 0x83, 0x22, 0x63, 0x48, 0x42, 0x21, 0x89, 0x39, 0x88, 0x41, 0x4b, 0xce,
|
||||
0x14, 0x49, 0x87, 0x11, 0xa1, 0x29, 0x57, 0x84, 0x65, 0x4a, 0x8b, 0xf8, 0x63, 0xbd, 0x3f, 0xde,
|
||||
0x0b, 0x40, 0xd3, 0x3d, 0x12, 0x41, 0x02, 0x92, 0x6a, 0x08, 0x71, 0x2a, 0x85, 0x16, 0x36, 0xae,
|
||||
0xf4, 0xd8, 0xd4, 0xe1, 0x74, 0x18, 0xe1, 0x42, 0x8f, 0x2f, 0xeb, 0xb1, 0xd1, 0x6f, 0xef, 0x46,
|
||||
0x5c, 0x0f, 0xb2, 0x00, 0x33, 0x11, 0x93, 0x48, 0x44, 0x82, 0x94, 0x98, 0x20, 0xeb, 0x97, 0xab,
|
||||
0x72, 0x51, 0x7e, 0x55, 0xf8, 0xed, 0x1d, 0x63, 0x8f, 0xa6, 0x9c, 0x30, 0x21, 0x81, 0x8c, 0xaf,
|
||||
0x59, 0xd8, 0x7e, 0xbc, 0xa8, 0x89, 0x29, 0x1b, 0xf0, 0x04, 0xe4, 0x59, 0xdd, 0x07, 0x91, 0xa0,
|
||||
0x44, 0x26, 0x19, 0xdc, 0x4a, 0xa5, 0x8a, 0x38, 0xe8, 0xef, 0xee, 0x22, 0x7f, 0x52, 0xc9, 0x2c,
|
||||
0xd1, 0x3c, 0xbe, 0x7e, 0xcd, 0x93, 0x7f, 0x09, 0x14, 0x1b, 0x40, 0x4c, 0xaf, 0xea, 0x76, 0x7e,
|
||||
0x36, 0xd1, 0xfa, 0x61, 0x99, 0xdd, 0x1b, 0x3a, 0xca, 0xc0, 0xee, 0xa3, 0xcd, 0x10, 0x14, 0x93,
|
||||
0x3c, 0x80, 0xf0, 0x55, 0xf0, 0x19, 0x98, 0x76, 0xac, 0xae, 0xd5, 0x5b, 0xdf, 0xbf, 0x5f, 0x4f,
|
||||
0x80, 0xa6, 0x1c, 0x17, 0x11, 0xe1, 0xf1, 0x1e, 0xae, 0x2a, 0x7c, 0xe8, 0x83, 0x84, 0x84, 0x81,
|
||||
0x77, 0x6f, 0x32, 0xed, 0x34, 0xf2, 0x69, 0x67, 0xf3, 0xf9, 0x65, 0x86, 0x7f, 0x15, 0x6a, 0xef,
|
||||
0x23, 0x54, 0x8d, 0xec, 0x25, 0x8d, 0xc1, 0x59, 0xe9, 0x5a, 0xbd, 0x35, 0xcf, 0x36, 0x6a, 0x74,
|
||||
0x38, 0x3f, 0xf1, 0x97, 0xaa, 0xec, 0x77, 0x68, 0xad, 0x68, 0x45, 0x69, 0x1a, 0xa7, 0x4e, 0xb3,
|
||||
0x74, 0xf5, 0x70, 0xc9, 0xd5, 0xbc, 0xef, 0xc5, 0xe3, 0x28, 0xe2, 0x2d, 0x7c, 0x1e, 0xf3, 0x18,
|
||||
0xbc, 0x2d, 0x83, 0x5f, 0x3b, 0xae, 0x21, 0xfe, 0x82, 0x67, 0x3f, 0x40, 0xab, 0xa7, 0x3c, 0x09,
|
||||
0xc5, 0xa9, 0xf3, 0x5f, 0xd7, 0xea, 0x35, 0xbd, 0xad, 0x7c, 0xda, 0xd9, 0x38, 0x29, 0x77, 0x8e,
|
||||
0x80, 0x89, 0x24, 0x54, 0xbe, 0x29, 0xb0, 0x8f, 0x50, 0x6b, 0x5c, 0x84, 0xe5, 0xb4, 0x4a, 0x0f,
|
||||
0xf8, 0x6f, 0x1e, 0x70, 0xfd, 0x30, 0xf0, 0xeb, 0x8c, 0x26, 0x9a, 0xeb, 0x33, 0x6f, 0xc3, 0xf8,
|
||||
0x68, 0x95, 0x89, 0xfb, 0x15, 0xcb, 0xfe, 0x80, 0xda, 0x0a, 0x46, 0xc0, 0xb4, 0x90, 0xce, 0x6a,
|
||||
0xc9, 0x7d, 0x74, 0xb3, 0xde, 0x0e, 0x68, 0x00, 0xa3, 0x23, 0x23, 0xf5, 0xee, 0xe4, 0xd3, 0x4e,
|
||||
0xbb, 0x5e, 0xf9, 0x73, 0xe4, 0xce, 0x37, 0x0b, 0x6d, 0x2e, 0xcd, 0xf9, 0x80, 0x2b, 0x6d, 0xbf,
|
||||
0x47, 0xed, 0x02, 0x12, 0x52, 0x4d, 0xcd, 0x90, 0xf1, 0x0d, 0xaf, 0xe4, 0x4a, 0x1f, 0x82, 0xa6,
|
||||
0xde, 0x5d, 0xd3, 0x4a, 0xbb, 0xde, 0xf1, 0xe7, 0x44, 0xfb, 0x13, 0x6a, 0x71, 0x0d, 0xb1, 0x72,
|
||||
0x56, 0xba, 0xcd, 0xde, 0xfa, 0xfe, 0xb3, 0x5b, 0xfe, 0xc1, 0x78, 0xc9, 0xed, 0x22, 0xb2, 0x17,
|
||||
0x05, 0xd1, 0xaf, 0xc0, 0xde, 0xee, 0x64, 0xe6, 0x36, 0xce, 0x67, 0x6e, 0xe3, 0x62, 0xe6, 0x36,
|
||||
0xbe, 0xe4, 0xae, 0x35, 0xc9, 0x5d, 0xeb, 0x3c, 0x77, 0xad, 0x8b, 0xdc, 0xb5, 0xbe, 0xe7, 0xae,
|
||||
0xf5, 0xf5, 0x87, 0xdb, 0x78, 0xfb, 0xbf, 0x01, 0xfe, 0x0a, 0x00, 0x00, 0xff, 0xff, 0xdb, 0xed,
|
||||
0x64, 0xfc, 0x9c, 0x04, 0x00, 0x00,
|
||||
// 616 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x94, 0x4f, 0x4f, 0x14, 0x3f,
|
||||
0x1c, 0xc6, 0x77, 0xd8, 0xdf, 0xf2, 0x5b, 0x8a, 0x04, 0x19, 0x62, 0xdc, 0x60, 0x32, 0x90, 0xf5,
|
||||
0x82, 0x26, 0xb4, 0x01, 0x8d, 0x31, 0xe1, 0x36, 0xf1, 0x62, 0xc2, 0x4a, 0x1c, 0x88, 0x24, 0xfe,
|
||||
0x89, 0x76, 0x3a, 0x5f, 0x96, 0xba, 0x3b, 0xd3, 0x49, 0xdb, 0x59, 0xc2, 0xcd, 0x97, 0xe0, 0x3b,
|
||||
0xf0, 0xed, 0x70, 0xc4, 0x1b, 0x27, 0x22, 0x63, 0x7c, 0x1f, 0x66, 0x3a, 0x9d, 0xfd, 0xc3, 0xa2,
|
||||
0xc2, 0x6d, 0xa7, 0x7d, 0x9e, 0x4f, 0x9f, 0x7e, 0x9f, 0x66, 0xd1, 0x41, 0xef, 0xb9, 0xc2, 0x5c,
|
||||
0x90, 0x5e, 0x16, 0x82, 0x4c, 0x40, 0x83, 0x22, 0x03, 0x48, 0x22, 0x21, 0x89, 0xdd, 0x88, 0x41,
|
||||
0x4b, 0xce, 0x14, 0x49, 0x7b, 0x5d, 0x42, 0x53, 0xae, 0x08, 0xcb, 0x94, 0x16, 0xf1, 0xc7, 0x6a,
|
||||
0x7d, 0xb0, 0x19, 0x82, 0xa6, 0x9b, 0xa4, 0x0b, 0x09, 0x48, 0xaa, 0x21, 0xc2, 0xa9, 0x14, 0x5a,
|
||||
0xb8, 0xb8, 0xf4, 0x63, 0xab, 0xc3, 0x69, 0xaf, 0x8b, 0x0b, 0x3f, 0x9e, 0xf4, 0x63, 0xeb, 0x5f,
|
||||
0xd9, 0xe8, 0x72, 0x7d, 0x94, 0x85, 0x98, 0x89, 0x98, 0x74, 0x45, 0x57, 0x10, 0x83, 0x09, 0xb3,
|
||||
0x43, 0xf3, 0x65, 0x3e, 0xcc, 0xaf, 0x12, 0xbf, 0xd2, 0xb6, 0xf1, 0x68, 0xca, 0x09, 0x13, 0x12,
|
||||
0xc8, 0x60, 0x2a, 0xc2, 0xca, 0xd3, 0x91, 0x26, 0xa6, 0xec, 0x88, 0x27, 0x20, 0x4f, 0xaa, 0x7b,
|
||||
0x10, 0x09, 0x4a, 0x64, 0x92, 0xc1, 0xad, 0x5c, 0xaa, 0x18, 0x07, 0xbd, 0xee, 0x2c, 0xf2, 0x27,
|
||||
0x97, 0xcc, 0x12, 0xcd, 0xe3, 0xe9, 0x63, 0x9e, 0xfd, 0xcb, 0xa0, 0xd8, 0x11, 0xc4, 0xf4, 0xaa,
|
||||
0xaf, 0xfd, 0xcd, 0x41, 0x4b, 0x1d, 0x33, 0xbb, 0x1d, 0xae, 0xf4, 0x6e, 0xaa, 0xb9, 0x48, 0x94,
|
||||
0xbb, 0x8d, 0x16, 0xfa, 0x34, 0x84, 0xfe, 0x1e, 0xf4, 0x81, 0x69, 0x21, 0x5b, 0xce, 0x9a, 0xb3,
|
||||
0x3e, 0xe7, 0xdf, 0x3b, 0xbd, 0x58, 0xad, 0xe5, 0x17, 0xab, 0x0b, 0x3b, 0xe3, 0x9b, 0xc1, 0xa4,
|
||||
0xd6, 0xed, 0xa0, 0xe5, 0xb2, 0x8d, 0x09, 0x55, 0x6b, 0xc6, 0x20, 0x1e, 0x58, 0xc4, 0x72, 0x67,
|
||||
0x5a, 0x12, 0x5c, 0xe7, 0x6b, 0xff, 0xaa, 0xa3, 0xf9, 0x52, 0xfc, 0x86, 0xf6, 0x33, 0x70, 0x0f,
|
||||
0xd1, 0x62, 0x04, 0x8a, 0x49, 0x1e, 0x42, 0xb4, 0x1b, 0x7e, 0x06, 0xa6, 0x4d, 0xba, 0xf9, 0xad,
|
||||
0x87, 0xd5, 0x1b, 0xa1, 0x29, 0xc7, 0x45, 0x89, 0x78, 0xb0, 0x89, 0x4b, 0x45, 0x00, 0x87, 0x20,
|
||||
0x21, 0x61, 0xe0, 0xdf, 0xb7, 0xe7, 0x2f, 0xbe, 0x98, 0x64, 0x04, 0x57, 0xa1, 0xee, 0x16, 0x42,
|
||||
0x65, 0x9c, 0x57, 0x34, 0x06, 0x9b, 0xde, 0xb5, 0x6e, 0xd4, 0x19, 0xee, 0x04, 0x63, 0x2a, 0xf7,
|
||||
0x1d, 0x9a, 0x2b, 0x86, 0xad, 0x34, 0x8d, 0xd3, 0x56, 0xdd, 0xa4, 0x7a, 0x3c, 0x96, 0x6a, 0xd8,
|
||||
0xcc, 0xe8, 0xf9, 0x16, 0x0f, 0xa0, 0xc8, 0xb9, 0xcf, 0x63, 0xf0, 0x97, 0x2c, 0x7e, 0x6e, 0xbf,
|
||||
0x82, 0x04, 0x23, 0x9e, 0xfb, 0x08, 0xcd, 0x1e, 0xf3, 0x24, 0x12, 0xc7, 0xad, 0xff, 0xd6, 0x9c,
|
||||
0xf5, 0xba, 0xbf, 0x54, 0x34, 0x71, 0x60, 0x56, 0xf6, 0x80, 0x89, 0x24, 0x52, 0x81, 0x15, 0xb8,
|
||||
0x7b, 0xa8, 0x31, 0x28, 0x86, 0xd5, 0x6a, 0x98, 0x0c, 0xf8, 0x6f, 0x19, 0x70, 0xf5, 0x74, 0xf1,
|
||||
0xeb, 0x8c, 0x26, 0x9a, 0xeb, 0x13, 0x7f, 0xc1, 0xe6, 0x68, 0x98, 0x89, 0x07, 0x25, 0xcb, 0xfd,
|
||||
0x80, 0x9a, 0xaa, 0x2a, 0x73, 0xd6, 0x70, 0x9f, 0xdc, 0xec, 0x6e, 0x13, 0x7d, 0xfa, 0x77, 0xf2,
|
||||
0x8b, 0xd5, 0xe6, 0xb0, 0xf2, 0x21, 0xb2, 0xfd, 0xdd, 0x41, 0x8b, 0x63, 0x3d, 0x17, 0xcf, 0xd1,
|
||||
0x7d, 0x8f, 0x9a, 0x05, 0x24, 0xa2, 0x9a, 0xda, 0x92, 0xf1, 0x0d, 0x8f, 0xe4, 0x4a, 0x77, 0x40,
|
||||
0x53, 0xff, 0xae, 0xbd, 0x4a, 0xb3, 0x5a, 0x09, 0x86, 0x44, 0xf7, 0x13, 0x6a, 0x70, 0x0d, 0xb1,
|
||||
0x6a, 0xcd, 0xac, 0xd5, 0xd7, 0xe7, 0xb7, 0xb6, 0x6f, 0xf9, 0x1f, 0x83, 0xc7, 0xd2, 0x8e, 0x46,
|
||||
0xf6, 0xb2, 0x20, 0x06, 0x25, 0xd8, 0xdf, 0x38, 0xbd, 0xf4, 0x6a, 0x67, 0x97, 0x5e, 0xed, 0xfc,
|
||||
0xd2, 0xab, 0x7d, 0xc9, 0x3d, 0xe7, 0x34, 0xf7, 0x9c, 0xb3, 0xdc, 0x73, 0xce, 0x73, 0xcf, 0xf9,
|
||||
0x91, 0x7b, 0xce, 0xd7, 0x9f, 0x5e, 0xed, 0xed, 0xff, 0x16, 0xf8, 0x3b, 0x00, 0x00, 0xff, 0xff,
|
||||
0xf5, 0x23, 0xb5, 0xdc, 0x3e, 0x05, 0x00, 0x00,
|
||||
}
|
||||
|
|
|
@ -30,6 +30,18 @@ import "k8s.io/apimachinery/pkg/runtime/schema/generated.proto";
|
|||
// Package-wide variables from generator "generated".
|
||||
option go_package = "v1beta1";
|
||||
|
||||
// MetricListOptions is used to select metrics by their label selectors
|
||||
message MetricListOptions {
|
||||
// A selector to restrict the list of returned objects by their labels.
|
||||
// Defaults to everything.
|
||||
// +optional
|
||||
optional string labelSelector = 1;
|
||||
|
||||
// A selector to restrict the list of returned metrics by their labels
|
||||
// +optional
|
||||
optional string metricLabelSelector = 2;
|
||||
}
|
||||
|
||||
// a metric value for some object
|
||||
message MetricValue {
|
||||
// a reference to the described object
|
||||
|
|
|
@ -43,6 +43,7 @@ func addKnownTypes(scheme *runtime.Scheme) error {
|
|||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&MetricValue{},
|
||||
&MetricValueList{},
|
||||
&MetricListOptions{},
|
||||
)
|
||||
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
|
||||
return nil
|
||||
|
|
|
@ -65,6 +65,22 @@ type MetricValue struct {
|
|||
Selector *metav1.LabelSelector `json:"selector" protobuf:"bytes,6,opt,name=selector"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// MetricListOptions is used to select metrics by their label selectors
|
||||
type MetricListOptions struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
|
||||
// A selector to restrict the list of returned objects by their labels.
|
||||
// Defaults to everything.
|
||||
// +optional
|
||||
LabelSelector string `json:"labelSelector,omitempty" protobuf:"bytes,1,opt,name=labelSelector"`
|
||||
|
||||
// A selector to restrict the list of returned metrics by their labels
|
||||
// +optional
|
||||
MetricLabelSelector string `json:"metricLabelSelector,omitempty" protobuf:"bytes,2,opt,name=metricLabelSelector"`
|
||||
}
|
||||
|
||||
// allObjects is a wildcard used to select metrics
|
||||
// for all objects matching the given label selector
|
||||
const AllObjects = "*"
|
||||
|
|
|
@ -35,6 +35,16 @@ func init() {
|
|||
// RegisterConversions adds conversion functions to the given scheme.
|
||||
// Public to allow building arbitrary schemes.
|
||||
func RegisterConversions(s *runtime.Scheme) error {
|
||||
if err := s.AddGeneratedConversionFunc((*MetricListOptions)(nil), (*custommetrics.MetricListOptions)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1beta1_MetricListOptions_To_custom_metrics_MetricListOptions(a.(*MetricListOptions), b.(*custommetrics.MetricListOptions), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*custommetrics.MetricListOptions)(nil), (*MetricListOptions)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_custom_metrics_MetricListOptions_To_v1beta1_MetricListOptions(a.(*custommetrics.MetricListOptions), b.(*MetricListOptions), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*MetricValue)(nil), (*custommetrics.MetricValue)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1beta1_MetricValue_To_custom_metrics_MetricValue(a.(*MetricValue), b.(*custommetrics.MetricValue), scope)
|
||||
}); err != nil {
|
||||
|
@ -68,6 +78,28 @@ func RegisterConversions(s *runtime.Scheme) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func autoConvert_v1beta1_MetricListOptions_To_custom_metrics_MetricListOptions(in *MetricListOptions, out *custommetrics.MetricListOptions, s conversion.Scope) error {
|
||||
out.LabelSelector = in.LabelSelector
|
||||
out.MetricLabelSelector = in.MetricLabelSelector
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1beta1_MetricListOptions_To_custom_metrics_MetricListOptions is an autogenerated conversion function.
|
||||
func Convert_v1beta1_MetricListOptions_To_custom_metrics_MetricListOptions(in *MetricListOptions, out *custommetrics.MetricListOptions, s conversion.Scope) error {
|
||||
return autoConvert_v1beta1_MetricListOptions_To_custom_metrics_MetricListOptions(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_custom_metrics_MetricListOptions_To_v1beta1_MetricListOptions(in *custommetrics.MetricListOptions, out *MetricListOptions, s conversion.Scope) error {
|
||||
out.LabelSelector = in.LabelSelector
|
||||
out.MetricLabelSelector = in.MetricLabelSelector
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_custom_metrics_MetricListOptions_To_v1beta1_MetricListOptions is an autogenerated conversion function.
|
||||
func Convert_custom_metrics_MetricListOptions_To_v1beta1_MetricListOptions(in *custommetrics.MetricListOptions, out *MetricListOptions, s conversion.Scope) error {
|
||||
return autoConvert_custom_metrics_MetricListOptions_To_v1beta1_MetricListOptions(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1beta1_MetricValue_To_custom_metrics_MetricValue(in *MetricValue, out *custommetrics.MetricValue, s conversion.Scope) error {
|
||||
// TODO: Inefficient conversion - can we improve it?
|
||||
if err := s.Convert(&in.DescribedObject, &out.DescribedObject, 0); err != nil {
|
||||
|
|
|
@ -25,6 +25,31 @@ import (
|
|||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *MetricListOptions) DeepCopyInto(out *MetricListOptions) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MetricListOptions.
|
||||
func (in *MetricListOptions) DeepCopy() *MetricListOptions {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(MetricListOptions)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *MetricListOptions) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *MetricValue) DeepCopyInto(out *MetricValue) {
|
||||
*out = *in
|
||||
|
|
|
@ -46,6 +46,16 @@ func RegisterConversions(s *runtime.Scheme) error {
|
|||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*MetricListOptions)(nil), (*custommetrics.MetricListOptions)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1beta2_MetricListOptions_To_custom_metrics_MetricListOptions(a.(*MetricListOptions), b.(*custommetrics.MetricListOptions), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*custommetrics.MetricListOptions)(nil), (*MetricListOptions)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_custom_metrics_MetricListOptions_To_v1beta2_MetricListOptions(a.(*custommetrics.MetricListOptions), b.(*MetricListOptions), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*MetricValue)(nil), (*custommetrics.MetricValue)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1beta2_MetricValue_To_custom_metrics_MetricValue(a.(*MetricValue), b.(*custommetrics.MetricValue), scope)
|
||||
}); err != nil {
|
||||
|
@ -91,6 +101,28 @@ func Convert_custom_metrics_MetricIdentifier_To_v1beta2_MetricIdentifier(in *cus
|
|||
return autoConvert_custom_metrics_MetricIdentifier_To_v1beta2_MetricIdentifier(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1beta2_MetricListOptions_To_custom_metrics_MetricListOptions(in *MetricListOptions, out *custommetrics.MetricListOptions, s conversion.Scope) error {
|
||||
out.LabelSelector = in.LabelSelector
|
||||
out.MetricLabelSelector = in.MetricLabelSelector
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1beta2_MetricListOptions_To_custom_metrics_MetricListOptions is an autogenerated conversion function.
|
||||
func Convert_v1beta2_MetricListOptions_To_custom_metrics_MetricListOptions(in *MetricListOptions, out *custommetrics.MetricListOptions, s conversion.Scope) error {
|
||||
return autoConvert_v1beta2_MetricListOptions_To_custom_metrics_MetricListOptions(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_custom_metrics_MetricListOptions_To_v1beta2_MetricListOptions(in *custommetrics.MetricListOptions, out *MetricListOptions, s conversion.Scope) error {
|
||||
out.LabelSelector = in.LabelSelector
|
||||
out.MetricLabelSelector = in.MetricLabelSelector
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_custom_metrics_MetricListOptions_To_v1beta2_MetricListOptions is an autogenerated conversion function.
|
||||
func Convert_custom_metrics_MetricListOptions_To_v1beta2_MetricListOptions(in *custommetrics.MetricListOptions, out *MetricListOptions, s conversion.Scope) error {
|
||||
return autoConvert_custom_metrics_MetricListOptions_To_v1beta2_MetricListOptions(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1beta2_MetricValue_To_custom_metrics_MetricValue(in *MetricValue, out *custommetrics.MetricValue, s conversion.Scope) error {
|
||||
// TODO: Inefficient conversion - can we improve it?
|
||||
if err := s.Convert(&in.DescribedObject, &out.DescribedObject, 0); err != nil {
|
||||
|
|
|
@ -46,6 +46,31 @@ func (in *MetricIdentifier) DeepCopy() *MetricIdentifier {
|
|||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *MetricListOptions) DeepCopyInto(out *MetricListOptions) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MetricListOptions.
|
||||
func (in *MetricListOptions) DeepCopy() *MetricListOptions {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(MetricListOptions)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *MetricListOptions) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *MetricValue) DeepCopyInto(out *MetricValue) {
|
||||
*out = *in
|
||||
|
|
|
@ -1,21 +1,29 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"client.go",
|
||||
"converter.go",
|
||||
"discovery.go",
|
||||
"interfaces.go",
|
||||
"multi_client.go",
|
||||
"versioned_client.go",
|
||||
],
|
||||
importmap = "k8s.io/kubernetes/vendor/k8s.io/metrics/pkg/client/custom_metrics",
|
||||
importpath = "k8s.io/metrics/pkg/client/custom_metrics",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/discovery:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/rest:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/util/flowcontrol:go_default_library",
|
||||
"//staging/src/k8s.io/metrics/pkg/apis/custom_metrics:go_default_library",
|
||||
"//staging/src/k8s.io/metrics/pkg/apis/custom_metrics/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/metrics/pkg/apis/custom_metrics/v1beta2:go_default_library",
|
||||
"//staging/src/k8s.io/metrics/pkg/client/custom_metrics/scheme:go_default_library",
|
||||
],
|
||||
|
@ -38,3 +46,18 @@ filegroup(
|
|||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["util_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//staging/src/k8s.io/metrics/pkg/apis/custom_metrics:go_default_library",
|
||||
"//staging/src/k8s.io/metrics/pkg/apis/custom_metrics/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/metrics/pkg/apis/custom_metrics/v1beta2:go_default_library",
|
||||
"//vendor/github.com/stretchr/testify/require:go_default_library",
|
||||
],
|
||||
)
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
Copyright 2018 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 custom_metrics
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
"k8s.io/client-go/rest"
|
||||
|
||||
cmint "k8s.io/metrics/pkg/apis/custom_metrics"
|
||||
cmv1beta1 "k8s.io/metrics/pkg/apis/custom_metrics/v1beta1"
|
||||
cmv1beta2 "k8s.io/metrics/pkg/apis/custom_metrics/v1beta2"
|
||||
"k8s.io/metrics/pkg/client/custom_metrics/scheme"
|
||||
)
|
||||
|
||||
var (
|
||||
// MetricVersions is the set of metric versions accepted by the converter.
|
||||
MetricVersions = []schema.GroupVersion{
|
||||
cmv1beta2.SchemeGroupVersion,
|
||||
cmv1beta1.SchemeGroupVersion,
|
||||
cmint.SchemeGroupVersion,
|
||||
}
|
||||
)
|
||||
|
||||
// MetricConverter knows how to convert between external MetricValue versions.
|
||||
type MetricConverter struct {
|
||||
scheme *runtime.Scheme
|
||||
codecs serializer.CodecFactory
|
||||
internalVersioner runtime.GroupVersioner
|
||||
}
|
||||
|
||||
// NewMetricConverter creates a MetricConverter which knows how to convert objects
|
||||
// between different versions of the custom metrics api.
|
||||
func NewMetricConverter() *MetricConverter {
|
||||
return &MetricConverter{
|
||||
scheme: scheme.Scheme,
|
||||
codecs: serializer.NewCodecFactory(scheme.Scheme),
|
||||
internalVersioner: runtime.NewMultiGroupVersioner(
|
||||
scheme.SchemeGroupVersion,
|
||||
schema.GroupKind{Group: cmint.GroupName, Kind: ""},
|
||||
schema.GroupKind{Group: cmv1beta1.GroupName, Kind: ""},
|
||||
schema.GroupKind{Group: cmv1beta2.GroupName, Kind: ""},
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
// Scheme returns the scheme used by this metric converter.
|
||||
func (c *MetricConverter) Scheme() *runtime.Scheme {
|
||||
return c.scheme
|
||||
}
|
||||
|
||||
// Codecs returns the codecs used by this metric converter
|
||||
func (c *MetricConverter) Codecs() serializer.CodecFactory {
|
||||
return c.codecs
|
||||
}
|
||||
|
||||
// ConvertListOptionsToVersion converts converts a set of MetricListOptions
|
||||
// to the provided GroupVersion.
|
||||
func (c *MetricConverter) ConvertListOptionsToVersion(opts *cmint.MetricListOptions, version schema.GroupVersion) (runtime.Object, error) {
|
||||
paramObj, err := c.UnsafeConvertToVersionVia(opts, version)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return paramObj, nil
|
||||
}
|
||||
|
||||
// ConvertResultToVersion converts a Result to the provided GroupVersion
|
||||
func (c *MetricConverter) ConvertResultToVersion(res rest.Result, gv schema.GroupVersion) (runtime.Object, error) {
|
||||
if err := res.Error(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
metricBytes, err := res.Raw()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
decoder := c.codecs.UniversalDecoder(MetricVersions...)
|
||||
rawMetricObj, err := runtime.Decode(decoder, metricBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
metricObj, err := c.UnsafeConvertToVersionVia(rawMetricObj, gv)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return metricObj, nil
|
||||
}
|
||||
|
||||
// unsafeConvertToVersionVia is like Scheme.UnsafeConvertToVersion, but it does so via an internal version first.
|
||||
// We use it here to work with the v1beta2 client internally, while preserving backwards compatibility for existing custom metrics adapters
|
||||
func (c *MetricConverter) UnsafeConvertToVersionVia(obj runtime.Object, externalVersion schema.GroupVersion) (runtime.Object, error) {
|
||||
objInt, err := c.scheme.UnsafeConvertToVersion(obj, schema.GroupVersion{Group: externalVersion.Group, Version: runtime.APIVersionInternal})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to convert the given object to the internal version: %v", err)
|
||||
}
|
||||
|
||||
objExt, err := c.scheme.UnsafeConvertToVersion(objInt, externalVersion)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to convert the given object back to the external version: %v", err)
|
||||
}
|
||||
|
||||
return objExt, err
|
||||
}
|
|
@ -0,0 +1,145 @@
|
|||
/*
|
||||
Copyright 2018 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 custom_metrics
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/client-go/discovery"
|
||||
|
||||
cmint "k8s.io/metrics/pkg/apis/custom_metrics"
|
||||
)
|
||||
|
||||
var (
|
||||
// metricVersionsToGV is the map of string group-versions
|
||||
// accepted by the converter to group-version objects (so
|
||||
// we don't have to re-parse)
|
||||
metricVersionsToGV map[string]schema.GroupVersion
|
||||
)
|
||||
|
||||
func init() {
|
||||
metricVersionsToGV = make(map[string]schema.GroupVersion)
|
||||
for _, ver := range MetricVersions {
|
||||
metricVersionsToGV[ver.String()] = ver
|
||||
}
|
||||
}
|
||||
|
||||
// NewAvailableAPIsGetter creates an AvailableAPIsGetter that checks discovery
|
||||
// to find the available versions of the custom metrics api.
|
||||
func NewAvailableAPIsGetter(client discovery.DiscoveryInterface) AvailableAPIsGetter {
|
||||
return &apiVersionsFromDiscovery{
|
||||
client: client,
|
||||
}
|
||||
}
|
||||
|
||||
// apiVersionsFromDiscovery caches a preferred version of the custom metrics api.
|
||||
type apiVersionsFromDiscovery struct {
|
||||
client discovery.DiscoveryInterface
|
||||
|
||||
// just cache the group directly since the discovery interface doesn't yet allow
|
||||
// asking for a single API group's versions.
|
||||
prefVersion *schema.GroupVersion
|
||||
mu sync.RWMutex
|
||||
}
|
||||
|
||||
// fetchVersions fetches the versions, but doesn't try to invalidate on cache misses.
|
||||
func (d *apiVersionsFromDiscovery) fetchVersions() (*metav1.APIGroup, error) {
|
||||
// TODO(directxman12): amend the discovery interface to ask for a particular group (/apis/foo)
|
||||
groups, err := d.client.ServerGroups()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Determine the preferred version on the server by first finding the custom metrics group
|
||||
var apiGroup *metav1.APIGroup
|
||||
for _, group := range groups.Groups {
|
||||
if group.Name == cmint.GroupName {
|
||||
apiGroup = &group
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if apiGroup == nil {
|
||||
return nil, fmt.Errorf("no custom metrics API (%s) registered", cmint.GroupName)
|
||||
}
|
||||
|
||||
return apiGroup, nil
|
||||
}
|
||||
|
||||
// chooseVersion sets a preferred version of the custom metrics api based on available versions.
|
||||
func (d *apiVersionsFromDiscovery) chooseVersion(apiGroup *metav1.APIGroup) (schema.GroupVersion, error) {
|
||||
var preferredVersion *schema.GroupVersion
|
||||
if gv, present := metricVersionsToGV[apiGroup.PreferredVersion.GroupVersion]; present && len(apiGroup.PreferredVersion.GroupVersion) != 0 {
|
||||
preferredVersion = &gv
|
||||
} else {
|
||||
for _, version := range apiGroup.Versions {
|
||||
if gv, present := metricVersionsToGV[version.GroupVersion]; present {
|
||||
preferredVersion = &gv
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if preferredVersion == nil {
|
||||
return schema.GroupVersion{}, fmt.Errorf("no known available metric versions found")
|
||||
}
|
||||
return *preferredVersion, nil
|
||||
}
|
||||
|
||||
// PreferredVersion returns the current preferred version of the custom metrics api.
|
||||
// If none is specified, it will use the first known one.
|
||||
func (d *apiVersionsFromDiscovery) PreferredVersion() (schema.GroupVersion, error) {
|
||||
d.mu.RLock()
|
||||
if d.prefVersion != nil {
|
||||
// if we've already got one, proceed with that
|
||||
defer d.mu.RUnlock()
|
||||
return *d.prefVersion, nil
|
||||
}
|
||||
d.mu.RUnlock()
|
||||
|
||||
d.mu.Lock()
|
||||
defer d.mu.Unlock()
|
||||
|
||||
// double check, someone might have beaten us to it
|
||||
if d.prefVersion != nil {
|
||||
return *d.prefVersion, nil
|
||||
}
|
||||
|
||||
// populate our cache
|
||||
groupInfo, err := d.fetchVersions()
|
||||
if err != nil {
|
||||
return schema.GroupVersion{}, err
|
||||
}
|
||||
prefVersion, err := d.chooseVersion(groupInfo)
|
||||
if err != nil {
|
||||
return schema.GroupVersion{}, err
|
||||
}
|
||||
|
||||
d.prefVersion = &prefVersion
|
||||
return *d.prefVersion, nil
|
||||
}
|
||||
|
||||
// Invalidate refreshes the preferred version information.
|
||||
func (d *apiVersionsFromDiscovery) Invalidate() {
|
||||
d.mu.Lock()
|
||||
defer d.mu.Unlock()
|
||||
|
||||
d.prefVersion = nil
|
||||
}
|
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
Copyright 2018 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 custom_metrics
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/client-go/rest"
|
||||
|
||||
"k8s.io/metrics/pkg/apis/custom_metrics/v1beta2"
|
||||
)
|
||||
|
||||
// AvailableAPIsGetter knows how to fetch and cache the preferred custom metrics API version,
|
||||
// and invalidate that cache when asked.
|
||||
type AvailableAPIsGetter interface {
|
||||
PreferredVersion() (schema.GroupVersion, error)
|
||||
Invalidate()
|
||||
}
|
||||
|
||||
// PeriodicallyInvalidate periodically invalidates the preferred version cache until
|
||||
// told to stop.
|
||||
func PeriodicallyInvalidate(cache AvailableAPIsGetter, interval time.Duration, stopCh <-chan struct{}) {
|
||||
ticker := time.NewTicker(interval)
|
||||
defer ticker.Stop()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
cache.Invalidate()
|
||||
case <-stopCh:
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NewForConfig creates a new custom metrics client which delegates to a client which
|
||||
// uses the preferred api version.
|
||||
func NewForConfig(baseConfig *rest.Config, mapper meta.RESTMapper, availableAPIs AvailableAPIsGetter) CustomMetricsClient {
|
||||
return &multiClient{
|
||||
clients: make(map[schema.GroupVersion]CustomMetricsClient),
|
||||
availableAPIs: availableAPIs,
|
||||
|
||||
newClient: func(ver schema.GroupVersion) (CustomMetricsClient, error) {
|
||||
return NewForVersionForConfig(rest.CopyConfig(baseConfig), mapper, ver)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// multiClient is a CustomMetricsClient that can work with *any* metrics API version.
|
||||
type multiClient struct {
|
||||
newClient func(schema.GroupVersion) (CustomMetricsClient, error)
|
||||
clients map[schema.GroupVersion]CustomMetricsClient
|
||||
availableAPIs AvailableAPIsGetter
|
||||
mu sync.RWMutex
|
||||
}
|
||||
|
||||
// getPreferredClient returns a custom metrics client of the preferred api version.
|
||||
func (c *multiClient) getPreferredClient() (CustomMetricsClient, error) {
|
||||
pref, err := c.availableAPIs.PreferredVersion()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c.mu.RLock()
|
||||
client, present := c.clients[pref]
|
||||
c.mu.RUnlock()
|
||||
if present {
|
||||
return client, nil
|
||||
}
|
||||
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
client, err = c.newClient(pref)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.clients[pref] = client
|
||||
|
||||
return client, nil
|
||||
}
|
||||
|
||||
func (c *multiClient) RootScopedMetrics() MetricsInterface {
|
||||
return &multiClientInterface{clients: c}
|
||||
}
|
||||
|
||||
func (c *multiClient) NamespacedMetrics(namespace string) MetricsInterface {
|
||||
return &multiClientInterface{
|
||||
clients: c,
|
||||
namespace: &namespace,
|
||||
}
|
||||
}
|
||||
|
||||
type multiClientInterface struct {
|
||||
clients *multiClient
|
||||
namespace *string
|
||||
}
|
||||
|
||||
func (m *multiClientInterface) GetForObject(groupKind schema.GroupKind, name string, metricName string, metricSelector labels.Selector) (*v1beta2.MetricValue, error) {
|
||||
client, err := m.clients.getPreferredClient()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if m.namespace == nil {
|
||||
return client.RootScopedMetrics().GetForObject(groupKind, name, metricName, metricSelector)
|
||||
} else {
|
||||
return client.NamespacedMetrics(*m.namespace).GetForObject(groupKind, name, metricName, metricSelector)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *multiClientInterface) GetForObjects(groupKind schema.GroupKind, selector labels.Selector, metricName string, metricSelector labels.Selector) (*v1beta2.MetricValueList, error) {
|
||||
client, err := m.clients.getPreferredClient()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if m.namespace == nil {
|
||||
return client.RootScopedMetrics().GetForObjects(groupKind, selector, metricName, metricSelector)
|
||||
} else {
|
||||
return client.NamespacedMetrics(*m.namespace).GetForObjects(groupKind, selector, metricName, metricSelector)
|
||||
}
|
||||
}
|
|
@ -11,6 +11,7 @@ go_library(
|
|||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
|
||||
"//staging/src/k8s.io/metrics/pkg/apis/custom_metrics:go_default_library",
|
||||
"//staging/src/k8s.io/metrics/pkg/apis/custom_metrics/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/metrics/pkg/apis/custom_metrics/v1beta2:go_default_library",
|
||||
],
|
||||
|
|
|
@ -21,10 +21,15 @@ import (
|
|||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
serializer "k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
cmint "k8s.io/metrics/pkg/apis/custom_metrics"
|
||||
cmv1beta1 "k8s.io/metrics/pkg/apis/custom_metrics/v1beta1"
|
||||
cmv1beta2 "k8s.io/metrics/pkg/apis/custom_metrics/v1beta2"
|
||||
)
|
||||
|
||||
const GroupName = cmv1beta1.GroupName
|
||||
|
||||
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: runtime.APIVersionInternal}
|
||||
|
||||
var Scheme = runtime.NewScheme()
|
||||
var Codecs = serializer.NewCodecFactory(Scheme)
|
||||
var ParameterCodec = runtime.NewParameterCodec(Scheme)
|
||||
|
@ -49,6 +54,7 @@ func init() {
|
|||
// After this, RawExtensions in Kubernetes types will serialize kube-aggregator types
|
||||
// correctly.
|
||||
func AddToScheme(scheme *runtime.Scheme) {
|
||||
cmint.AddToScheme(scheme)
|
||||
cmv1beta1.AddToScheme(scheme)
|
||||
cmv1beta2.AddToScheme(scheme)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
Copyright 2018 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 custom_metrics
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
|
||||
cmint "k8s.io/metrics/pkg/apis/custom_metrics"
|
||||
cmv1beta1 "k8s.io/metrics/pkg/apis/custom_metrics/v1beta1"
|
||||
cmv1beta2 "k8s.io/metrics/pkg/apis/custom_metrics/v1beta2"
|
||||
)
|
||||
|
||||
func TestMetricConverter(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
group schema.GroupVersion
|
||||
expected runtime.Object
|
||||
}{
|
||||
{
|
||||
name: "Use custom metrics v1beta2",
|
||||
group: cmv1beta2.SchemeGroupVersion,
|
||||
expected: &cmv1beta2.MetricListOptions{
|
||||
TypeMeta: metav1.TypeMeta{Kind: "MetricListOptions", APIVersion: cmv1beta2.SchemeGroupVersion.String()},
|
||||
MetricLabelSelector: "foo",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Use custom metrics v1beta1",
|
||||
group: cmv1beta1.SchemeGroupVersion,
|
||||
expected: &cmv1beta1.MetricListOptions{
|
||||
TypeMeta: metav1.TypeMeta{Kind: "MetricListOptions", APIVersion: cmv1beta1.SchemeGroupVersion.String()},
|
||||
MetricLabelSelector: "foo",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
metricConverter := NewMetricConverter()
|
||||
opts := &cmint.MetricListOptions{MetricLabelSelector: "foo"}
|
||||
res, err := metricConverter.ConvertListOptionsToVersion(opts, test.group)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, test.expected, res)
|
||||
})
|
||||
}
|
||||
}
|
|
@ -25,22 +25,35 @@ import (
|
|||
serializer "k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/util/flowcontrol"
|
||||
|
||||
cmint "k8s.io/metrics/pkg/apis/custom_metrics"
|
||||
"k8s.io/metrics/pkg/apis/custom_metrics/v1beta1"
|
||||
"k8s.io/metrics/pkg/apis/custom_metrics/v1beta2"
|
||||
"k8s.io/metrics/pkg/client/custom_metrics/scheme"
|
||||
)
|
||||
|
||||
var (
|
||||
codecs = serializer.NewCodecFactory(scheme.Scheme)
|
||||
versionConverter = NewMetricConverter()
|
||||
)
|
||||
|
||||
type customMetricsClient struct {
|
||||
client rest.Interface
|
||||
mapper meta.RESTMapper
|
||||
client rest.Interface
|
||||
version schema.GroupVersion
|
||||
mapper meta.RESTMapper
|
||||
}
|
||||
|
||||
func New(client rest.Interface) CustomMetricsClient {
|
||||
// NewForVersion returns a new CustomMetricsClient for a particular api version.
|
||||
func NewForVersion(client rest.Interface, mapper meta.RESTMapper, version schema.GroupVersion) CustomMetricsClient {
|
||||
return &customMetricsClient{
|
||||
client: client,
|
||||
client: client,
|
||||
version: version,
|
||||
mapper: mapper,
|
||||
}
|
||||
}
|
||||
|
||||
func NewForConfig(c *rest.Config) (CustomMetricsClient, error) {
|
||||
// NewForVersionForConfig returns a new CustomMetricsClient for a particular api version and base configuration.
|
||||
func NewForVersionForConfig(c *rest.Config, mapper meta.RESTMapper, version schema.GroupVersion) (CustomMetricsClient, error) {
|
||||
configShallowCopy := *c
|
||||
if configShallowCopy.RateLimiter == nil && configShallowCopy.QPS > 0 {
|
||||
configShallowCopy.RateLimiter = flowcontrol.NewTokenBucketRateLimiter(configShallowCopy.QPS, configShallowCopy.Burst)
|
||||
|
@ -49,7 +62,7 @@ func NewForConfig(c *rest.Config) (CustomMetricsClient, error) {
|
|||
if configShallowCopy.UserAgent == "" {
|
||||
configShallowCopy.UserAgent = rest.DefaultKubernetesUserAgent()
|
||||
}
|
||||
configShallowCopy.GroupVersion = &v1beta2.SchemeGroupVersion
|
||||
configShallowCopy.GroupVersion = &version
|
||||
configShallowCopy.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: scheme.Codecs}
|
||||
|
||||
client, err := rest.RESTClientFor(&configShallowCopy)
|
||||
|
@ -57,24 +70,7 @@ func NewForConfig(c *rest.Config) (CustomMetricsClient, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
return New(client), nil
|
||||
}
|
||||
|
||||
func NewForConfigOrDie(c *rest.Config) CustomMetricsClient {
|
||||
client, err := NewForConfig(c)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
// NewForMapper constructs the client with a RESTMapper, which allows more
|
||||
// accurate translation from GroupVersionKind to GroupVersionResource.
|
||||
func NewForMapper(client rest.Interface, mapper meta.RESTMapper) CustomMetricsClient {
|
||||
return &customMetricsClient{
|
||||
client: client,
|
||||
mapper: mapper,
|
||||
}
|
||||
return NewForVersion(client, mapper, version), nil
|
||||
}
|
||||
|
||||
func (c *customMetricsClient) RootScopedMetrics() MetricsInterface {
|
||||
|
@ -88,16 +84,8 @@ func (c *customMetricsClient) NamespacedMetrics(namespace string) MetricsInterfa
|
|||
}
|
||||
}
|
||||
|
||||
// qualResourceForKind returns the string format of a qualified group resource for the specified GroupKind
|
||||
func (c *customMetricsClient) qualResourceForKind(groupKind schema.GroupKind) (string, error) {
|
||||
if c.mapper == nil {
|
||||
// the version doesn't matter
|
||||
gvk := groupKind.WithVersion("")
|
||||
gvr, _ := meta.UnsafeGuessKindToResource(gvk)
|
||||
gr := gvr.GroupResource()
|
||||
return gr.String(), nil
|
||||
}
|
||||
|
||||
// use the mapper if it's available
|
||||
mapping, err := c.mapper.RESTMapping(groupKind)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("unable to map kind %s to resource: %v", groupKind.String(), err)
|
||||
|
@ -112,21 +100,26 @@ type rootScopedMetrics struct {
|
|||
}
|
||||
|
||||
func (m *rootScopedMetrics) getForNamespace(namespace string, metricName string, metricSelector labels.Selector) (*v1beta2.MetricValue, error) {
|
||||
res := &v1beta2.MetricValueList{}
|
||||
err := m.client.client.Get().
|
||||
Resource("metrics").
|
||||
Namespace(namespace).
|
||||
Name(metricName).
|
||||
VersionedParams(&v1beta2.MetricListOptions{
|
||||
MetricLabelSelector: metricSelector.String(),
|
||||
}, scheme.ParameterCodec).
|
||||
Do().
|
||||
Into(res)
|
||||
|
||||
params, err := versionConverter.ConvertListOptionsToVersion(&cmint.MetricListOptions{
|
||||
MetricLabelSelector: metricSelector.String(),
|
||||
}, m.client.version)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := m.client.client.Get().
|
||||
Resource("metrics").
|
||||
Namespace(namespace).
|
||||
Name(metricName).
|
||||
VersionedParams(params, scheme.ParameterCodec).
|
||||
Do()
|
||||
|
||||
metricObj, err := versionConverter.ConvertResultToVersion(result, v1beta2.SchemeGroupVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res := metricObj.(*v1beta2.MetricValueList)
|
||||
if len(res.Items) != 1 {
|
||||
return nil, fmt.Errorf("the custom metrics API server returned %v results when we asked for exactly one", len(res.Items))
|
||||
}
|
||||
|
@ -145,21 +138,26 @@ func (m *rootScopedMetrics) GetForObject(groupKind schema.GroupKind, name string
|
|||
return nil, err
|
||||
}
|
||||
|
||||
res := &v1beta2.MetricValueList{}
|
||||
err = m.client.client.Get().
|
||||
Resource(resourceName).
|
||||
Name(name).
|
||||
SubResource(metricName).
|
||||
VersionedParams(&v1beta2.MetricListOptions{
|
||||
MetricLabelSelector: metricSelector.String(),
|
||||
}, scheme.ParameterCodec).
|
||||
Do().
|
||||
Into(res)
|
||||
|
||||
params, err := versionConverter.ConvertListOptionsToVersion(&cmint.MetricListOptions{
|
||||
MetricLabelSelector: metricSelector.String(),
|
||||
}, m.client.version)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := m.client.client.Get().
|
||||
Resource(resourceName).
|
||||
Name(name).
|
||||
SubResource(metricName).
|
||||
VersionedParams(params, scheme.ParameterCodec).
|
||||
Do()
|
||||
|
||||
metricObj, err := versionConverter.ConvertResultToVersion(result, v1beta2.SchemeGroupVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res := metricObj.(*v1beta2.MetricValueList)
|
||||
if len(res.Items) != 1 {
|
||||
return nil, fmt.Errorf("the custom metrics API server returned %v results when we asked for exactly one", len(res.Items))
|
||||
}
|
||||
|
@ -178,22 +176,27 @@ func (m *rootScopedMetrics) GetForObjects(groupKind schema.GroupKind, selector l
|
|||
return nil, err
|
||||
}
|
||||
|
||||
res := &v1beta2.MetricValueList{}
|
||||
err = m.client.client.Get().
|
||||
Resource(resourceName).
|
||||
Name(v1beta2.AllObjects).
|
||||
SubResource(metricName).
|
||||
VersionedParams(&v1beta2.MetricListOptions{
|
||||
LabelSelector: selector.String(),
|
||||
MetricLabelSelector: metricSelector.String(),
|
||||
}, scheme.ParameterCodec).
|
||||
Do().
|
||||
Into(res)
|
||||
|
||||
params, err := versionConverter.ConvertListOptionsToVersion(&cmint.MetricListOptions{
|
||||
LabelSelector: selector.String(),
|
||||
MetricLabelSelector: metricSelector.String(),
|
||||
}, m.client.version)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := m.client.client.Get().
|
||||
Resource(resourceName).
|
||||
Name(v1beta1.AllObjects).
|
||||
SubResource(metricName).
|
||||
VersionedParams(params, scheme.ParameterCodec).
|
||||
Do()
|
||||
|
||||
metricObj, err := versionConverter.ConvertResultToVersion(result, v1beta2.SchemeGroupVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res := metricObj.(*v1beta2.MetricValueList)
|
||||
return res, nil
|
||||
}
|
||||
|
||||
|
@ -208,22 +211,27 @@ func (m *namespacedMetrics) GetForObject(groupKind schema.GroupKind, name string
|
|||
return nil, err
|
||||
}
|
||||
|
||||
res := &v1beta2.MetricValueList{}
|
||||
err = m.client.client.Get().
|
||||
Resource(resourceName).
|
||||
Namespace(m.namespace).
|
||||
Name(name).
|
||||
SubResource(metricName).
|
||||
VersionedParams(&v1beta2.MetricListOptions{
|
||||
MetricLabelSelector: metricSelector.String(),
|
||||
}, scheme.ParameterCodec).
|
||||
Do().
|
||||
Into(res)
|
||||
|
||||
params, err := versionConverter.ConvertListOptionsToVersion(&cmint.MetricListOptions{
|
||||
MetricLabelSelector: metricSelector.String(),
|
||||
}, m.client.version)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := m.client.client.Get().
|
||||
Resource(resourceName).
|
||||
Namespace(m.namespace).
|
||||
Name(name).
|
||||
SubResource(metricName).
|
||||
VersionedParams(params, scheme.ParameterCodec).
|
||||
Do()
|
||||
|
||||
metricObj, err := versionConverter.ConvertResultToVersion(result, v1beta2.SchemeGroupVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res := metricObj.(*v1beta2.MetricValueList)
|
||||
if len(res.Items) != 1 {
|
||||
return nil, fmt.Errorf("the custom metrics API server returned %v results when we asked for exactly one", len(res.Items))
|
||||
}
|
||||
|
@ -237,22 +245,27 @@ func (m *namespacedMetrics) GetForObjects(groupKind schema.GroupKind, selector l
|
|||
return nil, err
|
||||
}
|
||||
|
||||
res := &v1beta2.MetricValueList{}
|
||||
err = m.client.client.Get().
|
||||
Resource(resourceName).
|
||||
Namespace(m.namespace).
|
||||
Name(v1beta2.AllObjects).
|
||||
SubResource(metricName).
|
||||
VersionedParams(&v1beta2.MetricListOptions{
|
||||
LabelSelector: selector.String(),
|
||||
MetricLabelSelector: metricSelector.String(),
|
||||
}, scheme.ParameterCodec).
|
||||
Do().
|
||||
Into(res)
|
||||
|
||||
params, err := versionConverter.ConvertListOptionsToVersion(&cmint.MetricListOptions{
|
||||
LabelSelector: selector.String(),
|
||||
MetricLabelSelector: metricSelector.String(),
|
||||
}, m.client.version)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := m.client.client.Get().
|
||||
Resource(resourceName).
|
||||
Namespace(m.namespace).
|
||||
Name(v1beta1.AllObjects).
|
||||
SubResource(metricName).
|
||||
VersionedParams(params, scheme.ParameterCodec).
|
||||
Do()
|
||||
|
||||
metricObj, err := versionConverter.ConvertResultToVersion(result, v1beta2.SchemeGroupVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res := metricObj.(*v1beta2.MetricValueList)
|
||||
return res, nil
|
||||
}
|
|
@ -29,6 +29,7 @@ go_library(
|
|||
"//staging/src/k8s.io/apimachinery/pkg/selection:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/discovery:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/discovery/cached:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
|
||||
"//staging/src/k8s.io/metrics/pkg/client/custom_metrics:go_default_library",
|
||||
"//staging/src/k8s.io/metrics/pkg/client/external_metrics:go_default_library",
|
||||
|
|
|
@ -29,11 +29,13 @@ import (
|
|||
|
||||
gcm "google.golang.org/api/monitoring/v3"
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/selection"
|
||||
"k8s.io/client-go/discovery"
|
||||
"k8s.io/kubernetes/test/e2e/framework"
|
||||
cmv1beta1 "k8s.io/metrics/pkg/apis/custom_metrics/v1beta1"
|
||||
customclient "k8s.io/metrics/pkg/client/custom_metrics"
|
||||
externalclient "k8s.io/metrics/pkg/client/external_metrics"
|
||||
)
|
||||
|
@ -57,8 +59,10 @@ var _ = instrumentation.SIGDescribe("Stackdriver Monitoring", func() {
|
|||
if err != nil {
|
||||
framework.Failf("Failed to load config: %s", err)
|
||||
}
|
||||
customMetricsClient := customclient.NewForConfigOrDie(config)
|
||||
discoveryClient := discovery.NewDiscoveryClientForConfigOrDie(config)
|
||||
apiVersionsGetter := customclient.NewAvailableAPIsGetter(discoveryClient)
|
||||
restMapper := meta.NewDefaultRESTMapper([]schema.GroupVersion{cmv1beta1.SchemeGroupVersion})
|
||||
customMetricsClient := customclient.NewForConfig(config, restMapper, apiVersionsGetter)
|
||||
testCustomMetrics(f, kubeClient, customMetricsClient, discoveryClient, AdapterForOldResourceModel)
|
||||
})
|
||||
|
||||
|
@ -68,8 +72,10 @@ var _ = instrumentation.SIGDescribe("Stackdriver Monitoring", func() {
|
|||
if err != nil {
|
||||
framework.Failf("Failed to load config: %s", err)
|
||||
}
|
||||
customMetricsClient := customclient.NewForConfigOrDie(config)
|
||||
discoveryClient := discovery.NewDiscoveryClientForConfigOrDie(config)
|
||||
apiVersionsGetter := customclient.NewAvailableAPIsGetter(discoveryClient)
|
||||
restMapper := meta.NewDefaultRESTMapper([]schema.GroupVersion{cmv1beta1.SchemeGroupVersion})
|
||||
customMetricsClient := customclient.NewForConfig(config, restMapper, apiVersionsGetter)
|
||||
testCustomMetrics(f, kubeClient, customMetricsClient, discoveryClient, AdapterForNewResourceModel)
|
||||
})
|
||||
|
||||
|
|
Loading…
Reference in New Issue