Merge pull request #68015 from damemi/hpa-metrics-specificity

Support backwards compatibility for v1beta1 custom metrics client
pull/8/head
k8s-ci-robot 2018-09-10 16:12:23 -07:00 committed by GitHub
commit 99f319567a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 1025 additions and 156 deletions

View File

@ -79039,11 +79039,6 @@
},
"io.k8s.api.autoscaling.v2beta2.MetricValueStatus": {
"description": "MetricValueStatus holds the current value for a metric",
"required": [
"value",
"averageValue",
"averageUtilization"
],
"properties": {
"averageUtilization": {
"description": "currentAverageUtilization is the current value of the average of the resource metric across all relevant pods, represented as a percentage of the requested value of the resource for the pods.",

View File

@ -1840,11 +1840,6 @@
"v2beta2.MetricValueStatus": {
"id": "v2beta2.MetricValueStatus",
"description": "MetricValueStatus holds the current value for a metric",
"required": [
"value",
"averageValue",
"averageUtilization"
],
"properties": {
"value": {
"type": "string",

View File

@ -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)

View File

@ -1002,21 +1002,21 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">value</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">value is the current value of the metric (as a quantity).</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">averageValue</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">averageValue is the current value of the average of the metric across all relevant pods (as a quantity)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">averageUtilization</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">currentAverageUtilization is the current value of the average of the resource metric across all relevant pods, represented as a percentage of the requested value of the resource for the pods.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">integer (int32)</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>

View File

@ -259,31 +259,37 @@ message MetricTarget {
optional string type = 1;
// value is the target value of the metric (as a quantity).
// +optional
optional k8s.io.apimachinery.pkg.api.resource.Quantity value = 2;
// averageValue is the target value of the average of the
// metric across all relevant pods (as a quantity)
// +optional
optional k8s.io.apimachinery.pkg.api.resource.Quantity averageValue = 3;
// averageUtilization is the target value of the average of the
// resource metric across all relevant pods, represented as a percentage of
// the requested value of the resource for the pods.
// Currently only valid for Resource metric source type
// +optional
optional int32 averageUtilization = 4;
}
// MetricValueStatus holds the current value for a metric
message MetricValueStatus {
// value is the current value of the metric (as a quantity).
// +optional
optional k8s.io.apimachinery.pkg.api.resource.Quantity value = 1;
// averageValue is the current value of the average of the
// metric across all relevant pods (as a quantity)
// +optional
optional k8s.io.apimachinery.pkg.api.resource.Quantity averageValue = 2;
// currentAverageUtilization is the current value of the average of the
// resource metric across all relevant pods, represented as a percentage of
// the requested value of the resource for the pods.
// +optional
optional int32 averageUtilization = 3;
}

View File

@ -200,16 +200,18 @@ type MetricTarget struct {
// type represents whether the metric type is Utilization, Value, or AverageValue
Type MetricTargetType `json:"type" protobuf:"bytes,1,name=type"`
// value is the target value of the metric (as a quantity).
Value *resource.Quantity `json:"value,omitempty" protobuf:"bytes,2,name=value"`
// +optional
Value *resource.Quantity `json:"value,omitempty" protobuf:"bytes,2,opt,name=value"`
// averageValue is the target value of the average of the
// metric across all relevant pods (as a quantity)
AverageValue *resource.Quantity `json:"averageValue,omitempty" protobuf:"bytes,3,name=averageValue"`
// +optional
AverageValue *resource.Quantity `json:"averageValue,omitempty" protobuf:"bytes,3,opt,name=averageValue"`
// averageUtilization is the target value of the average of the
// resource metric across all relevant pods, represented as a percentage of
// the requested value of the resource for the pods.
// Currently only valid for Resource metric source type
AverageUtilization *int32 `json:"averageUtilization,omitempty" protobuf:"bytes,4,name=averageUtilization"`
// +optional
AverageUtilization *int32 `json:"averageUtilization,omitempty" protobuf:"bytes,4,opt,name=averageUtilization"`
}
// MetricTargetType specifies the type of metric being targeted, and should be either
@ -364,14 +366,17 @@ type ExternalMetricStatus struct {
// MetricValueStatus holds the current value for a metric
type MetricValueStatus struct {
// value is the current value of the metric (as a quantity).
Value *resource.Quantity `json:"value" protobuf:"bytes,1,name=value"`
// +optional
Value *resource.Quantity `json:"value,omitempty" protobuf:"bytes,1,opt,name=value"`
// averageValue is the current value of the average of the
// metric across all relevant pods (as a quantity)
AverageValue *resource.Quantity `json:"averageValue" protobuf:"bytes,2,name=averageValue"`
// +optional
AverageValue *resource.Quantity `json:"averageValue,omitempty" protobuf:"bytes,2,opt,name=averageValue"`
// currentAverageUtilization is the current value of the average of the
// resource metric across all relevant pods, represented as a percentage of
// the requested value of the resource for the pods.
AverageUtilization *int32 `json:"averageUtilization" protobuf:"bytes,3,name=averageUtilization"`
// +optional
AverageUtilization *int32 `json:"averageUtilization,omitempty" protobuf:"bytes,3,opt,name=averageUtilization"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

View File

@ -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"

View File

@ -46,6 +46,7 @@ func addKnownTypes(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(SchemeGroupVersion,
&MetricValue{},
&MetricValueList{},
&MetricListOptions{},
)
return nil
}

View File

@ -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

View File

@ -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,
}

View File

@ -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

View File

@ -43,6 +43,7 @@ func addKnownTypes(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(SchemeGroupVersion,
&MetricValue{},
&MetricValueList{},
&MetricListOptions{},
)
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
return nil

View File

@ -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 = "*"

View File

@ -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 {

View File

@ -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

View File

@ -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 {

View File

@ -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

View File

@ -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",
],
)

View File

@ -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
}

View File

@ -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
}

View File

@ -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)
}
}

View File

@ -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",
],

View File

@ -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)
}

View File

@ -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)
})
}
}

View File

@ -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
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,
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{
params, err := versionConverter.ConvertListOptionsToVersion(&cmint.MetricListOptions{
MetricLabelSelector: metricSelector.String(),
}, scheme.ParameterCodec).
Do().
Into(res)
}, 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{
params, err := versionConverter.ConvertListOptionsToVersion(&cmint.MetricListOptions{
MetricLabelSelector: metricSelector.String(),
}, scheme.ParameterCodec).
Do().
Into(res)
}, 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{
params, err := versionConverter.ConvertListOptionsToVersion(&cmint.MetricListOptions{
LabelSelector: selector.String(),
MetricLabelSelector: metricSelector.String(),
}, scheme.ParameterCodec).
Do().
Into(res)
}, 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{
params, err := versionConverter.ConvertListOptionsToVersion(&cmint.MetricListOptions{
MetricLabelSelector: metricSelector.String(),
}, scheme.ParameterCodec).
Do().
Into(res)
}, 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{
params, err := versionConverter.ConvertListOptionsToVersion(&cmint.MetricListOptions{
LabelSelector: selector.String(),
MetricLabelSelector: metricSelector.String(),
}, scheme.ParameterCodec).
Do().
Into(res)
}, 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
}

View File

@ -22,6 +22,7 @@ go_library(
"//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/api/extensions/v1beta1:go_default_library",
"//staging/src/k8s.io/api/rbac/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/resource: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",
@ -30,6 +31,7 @@ go_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/kubernetes:go_default_library",
"//staging/src/k8s.io/metrics/pkg/apis/custom_metrics/v1beta1: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",
"//test/e2e/common:go_default_library",

View File

@ -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)
})