mirror of
https://github.com/kubernetes-sigs/prometheus-adapter.git
synced 2026-04-07 02:07:58 +00:00
Switch to ginkgo/gomega for tests
This switches over to ginkgo/gomega for tests, which makes writing certain tests easier/more fluent in the future.
This commit is contained in:
parent
c5801455ec
commit
cc08a1fb41
260 changed files with 184637 additions and 6412 deletions
72
vendor/github.com/kubernetes-incubator/metrics-server/pkg/apiserver/generic/storage.go
generated
vendored
Normal file
72
vendor/github.com/kubernetes-incubator/metrics-server/pkg/apiserver/generic/storage.go
generated
vendored
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
// 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 generic
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
genericapiserver "k8s.io/apiserver/pkg/server"
|
||||
coreinf "k8s.io/client-go/informers/core/v1"
|
||||
"k8s.io/metrics/pkg/apis/metrics"
|
||||
"k8s.io/metrics/pkg/apis/metrics/install"
|
||||
"k8s.io/metrics/pkg/apis/metrics/v1beta1"
|
||||
|
||||
"github.com/kubernetes-incubator/metrics-server/pkg/provider"
|
||||
nodemetricsstorage "github.com/kubernetes-incubator/metrics-server/pkg/storage/nodemetrics"
|
||||
podmetricsstorage "github.com/kubernetes-incubator/metrics-server/pkg/storage/podmetrics"
|
||||
)
|
||||
|
||||
var (
|
||||
// Scheme contains the types needed by the resource metrics API.
|
||||
Scheme = runtime.NewScheme()
|
||||
// Codecs is a codec factory for serving the resource metrics API.
|
||||
Codecs = serializer.NewCodecFactory(Scheme)
|
||||
)
|
||||
|
||||
func init() {
|
||||
install.Install(Scheme)
|
||||
metav1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: "v1"})
|
||||
}
|
||||
|
||||
// ProviderConfig holds the providers for node and pod metrics
|
||||
// for serving the resource metrics API.
|
||||
type ProviderConfig struct {
|
||||
Node provider.NodeMetricsProvider
|
||||
Pod provider.PodMetricsProvider
|
||||
}
|
||||
|
||||
// BuildStorage constructs APIGroupInfo the metrics.k8s.io API group using the given providers.
|
||||
func BuildStorage(providers *ProviderConfig, informers coreinf.Interface) genericapiserver.APIGroupInfo {
|
||||
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(metrics.GroupName, Scheme, metav1.ParameterCodec, Codecs)
|
||||
|
||||
nodemetricsStorage := nodemetricsstorage.NewStorage(metrics.Resource("nodemetrics"), providers.Node, informers.Nodes().Lister())
|
||||
podmetricsStorage := podmetricsstorage.NewStorage(metrics.Resource("podmetrics"), providers.Pod, informers.Pods().Lister())
|
||||
metricsServerResources := map[string]rest.Storage{
|
||||
"nodes": nodemetricsStorage,
|
||||
"pods": podmetricsStorage,
|
||||
}
|
||||
apiGroupInfo.VersionedResourcesStorageMap[v1beta1.SchemeGroupVersion.Version] = metricsServerResources
|
||||
|
||||
return apiGroupInfo
|
||||
}
|
||||
|
||||
// InstallStorage builds the storage for the metrics.k8s.io API, and then installs it into the given API server.
|
||||
func InstallStorage(providers *ProviderConfig, informers coreinf.Interface, server *genericapiserver.GenericAPIServer) error {
|
||||
info := BuildStorage(providers, informers)
|
||||
return server.InstallAPIGroup(&info)
|
||||
}
|
||||
63
vendor/github.com/kubernetes-incubator/metrics-server/pkg/provider/interfaces.go
generated
vendored
Normal file
63
vendor/github.com/kubernetes-incubator/metrics-server/pkg/provider/interfaces.go
generated
vendored
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
// 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 provider
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
apitypes "k8s.io/apimachinery/pkg/types"
|
||||
metrics "k8s.io/metrics/pkg/apis/metrics"
|
||||
)
|
||||
|
||||
// MetricsProvider is both a PodMetricsProvider and a NodeMetricsProvider
|
||||
type MetricsProvider interface {
|
||||
PodMetricsProvider
|
||||
NodeMetricsProvider
|
||||
}
|
||||
|
||||
// TimeSpan represents the timing information for a metric, which was
|
||||
// potentially calculated over some window of time (e.g. for CPU usage rate).
|
||||
type TimeInfo struct {
|
||||
// NB: we consider the earliest timestamp amongst multiple containers
|
||||
// for the purposes of determining if a metric is tained by a time
|
||||
// period, like pod startup (used by things like the HPA).
|
||||
|
||||
// Timestamp is the time at which the metrics were initially collected.
|
||||
// In the case of a rate metric, it should be the timestamp of the last
|
||||
// data point used in the calculation. If it represents multiple metric
|
||||
// points, it should be the earliest such timestamp from all of the points.
|
||||
Timestamp time.Time
|
||||
|
||||
// Window represents the window used to calculate rate metrics associated
|
||||
// with this timestamp.
|
||||
Window time.Duration
|
||||
}
|
||||
|
||||
// PodMetricsProvider knows how to fetch metrics for the containers in a pod.
|
||||
type PodMetricsProvider interface {
|
||||
// GetContainerMetrics gets the latest metrics for all containers in each listed pod,
|
||||
// returning both the metrics and the associated collection timestamp.
|
||||
// If a pod is missing, the container metrics should be nil for that pod.
|
||||
GetContainerMetrics(pods ...apitypes.NamespacedName) ([]TimeInfo, [][]metrics.ContainerMetrics, error)
|
||||
}
|
||||
|
||||
// NodeMetricsProvider knows how to fetch metrics for a node.
|
||||
type NodeMetricsProvider interface {
|
||||
// GetNodeMetrics gets the latest metrics for the given nodes,
|
||||
// returning both the metrics and the associated collection timestamp.
|
||||
// If a node is missing, the resourcelist should be nil for that node.
|
||||
GetNodeMetrics(nodes ...string) ([]TimeInfo, []corev1.ResourceList, error)
|
||||
}
|
||||
149
vendor/github.com/kubernetes-incubator/metrics-server/pkg/storage/nodemetrics/reststorage.go
generated
vendored
Normal file
149
vendor/github.com/kubernetes-incubator/metrics-server/pkg/storage/nodemetrics/reststorage.go
generated
vendored
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
// 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 nodemetrics
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/golang/glog"
|
||||
|
||||
"github.com/kubernetes-incubator/metrics-server/pkg/provider"
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
v1listers "k8s.io/client-go/listers/core/v1"
|
||||
"k8s.io/metrics/pkg/apis/metrics"
|
||||
_ "k8s.io/metrics/pkg/apis/metrics/install"
|
||||
)
|
||||
|
||||
type MetricStorage struct {
|
||||
groupResource schema.GroupResource
|
||||
prov provider.NodeMetricsProvider
|
||||
nodeLister v1listers.NodeLister
|
||||
}
|
||||
|
||||
var _ rest.KindProvider = &MetricStorage{}
|
||||
var _ rest.Storage = &MetricStorage{}
|
||||
var _ rest.Getter = &MetricStorage{}
|
||||
var _ rest.Lister = &MetricStorage{}
|
||||
var _ rest.Scoper = &MetricStorage{}
|
||||
|
||||
func NewStorage(groupResource schema.GroupResource, prov provider.NodeMetricsProvider, nodeLister v1listers.NodeLister) *MetricStorage {
|
||||
return &MetricStorage{
|
||||
groupResource: groupResource,
|
||||
prov: prov,
|
||||
nodeLister: nodeLister,
|
||||
}
|
||||
}
|
||||
|
||||
// Storage interface
|
||||
func (m *MetricStorage) New() runtime.Object {
|
||||
return &metrics.NodeMetrics{}
|
||||
}
|
||||
|
||||
// KindProvider interface
|
||||
func (m *MetricStorage) Kind() string {
|
||||
return "NodeMetrics"
|
||||
}
|
||||
|
||||
// Lister interface
|
||||
func (m *MetricStorage) NewList() runtime.Object {
|
||||
return &metrics.NodeMetricsList{}
|
||||
}
|
||||
|
||||
// Lister interface
|
||||
func (m *MetricStorage) List(ctx context.Context, options *metainternalversion.ListOptions) (runtime.Object, error) {
|
||||
labelSelector := labels.Everything()
|
||||
if options != nil && options.LabelSelector != nil {
|
||||
labelSelector = options.LabelSelector
|
||||
}
|
||||
nodes, err := m.nodeLister.ListWithPredicate(func(node *v1.Node) bool {
|
||||
if labelSelector.Empty() {
|
||||
return true
|
||||
}
|
||||
return labelSelector.Matches(labels.Set(node.Labels))
|
||||
})
|
||||
if err != nil {
|
||||
errMsg := fmt.Errorf("Error while listing nodes for selector %v: %v", labelSelector, err)
|
||||
glog.Error(errMsg)
|
||||
return &metrics.NodeMetricsList{}, errMsg
|
||||
}
|
||||
|
||||
names := make([]string, len(nodes))
|
||||
for i, node := range nodes {
|
||||
names[i] = node.Name
|
||||
}
|
||||
|
||||
metricsItems, err := m.getNodeMetrics(names...)
|
||||
if err != nil {
|
||||
errMsg := fmt.Errorf("Error while fetching node metrics for selector %v: %v", labelSelector, err)
|
||||
glog.Error(errMsg)
|
||||
return &metrics.NodeMetricsList{}, errMsg
|
||||
}
|
||||
|
||||
return &metrics.NodeMetricsList{Items: metricsItems}, nil
|
||||
}
|
||||
|
||||
func (m *MetricStorage) Get(ctx context.Context, name string, opts *metav1.GetOptions) (runtime.Object, error) {
|
||||
nodeMetrics, err := m.getNodeMetrics(name)
|
||||
if err == nil && len(nodeMetrics) == 0 {
|
||||
err = fmt.Errorf("no metrics known for node %q", name)
|
||||
}
|
||||
if err != nil {
|
||||
glog.Errorf("unable to fetch node metrics for node %q: %v", name, err)
|
||||
return nil, errors.NewNotFound(m.groupResource, name)
|
||||
}
|
||||
|
||||
return &nodeMetrics[0], nil
|
||||
}
|
||||
|
||||
func (m *MetricStorage) getNodeMetrics(names ...string) ([]metrics.NodeMetrics, error) {
|
||||
timestamps, usages, err := m.prov.GetNodeMetrics(names...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res := make([]metrics.NodeMetrics, 0, len(names))
|
||||
|
||||
for i, name := range names {
|
||||
if usages[i] == nil {
|
||||
glog.Errorf("unable to fetch node metrics for node %q: no metrics known for node", name)
|
||||
|
||||
continue
|
||||
}
|
||||
res = append(res, metrics.NodeMetrics{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
CreationTimestamp: metav1.NewTime(time.Now()),
|
||||
},
|
||||
Timestamp: metav1.NewTime(timestamps[i].Timestamp),
|
||||
Window: metav1.Duration{Duration: timestamps[i].Window},
|
||||
Usage: usages[i],
|
||||
})
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (m *MetricStorage) NamespaceScoped() bool {
|
||||
return false
|
||||
}
|
||||
164
vendor/github.com/kubernetes-incubator/metrics-server/pkg/storage/podmetrics/reststorage.go
generated
vendored
Normal file
164
vendor/github.com/kubernetes-incubator/metrics-server/pkg/storage/podmetrics/reststorage.go
generated
vendored
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
// 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 podmetrics
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/golang/glog"
|
||||
|
||||
"github.com/kubernetes-incubator/metrics-server/pkg/provider"
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
apitypes "k8s.io/apimachinery/pkg/types"
|
||||
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
|
||||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
v1listers "k8s.io/client-go/listers/core/v1"
|
||||
"k8s.io/metrics/pkg/apis/metrics"
|
||||
_ "k8s.io/metrics/pkg/apis/metrics/install"
|
||||
)
|
||||
|
||||
type MetricStorage struct {
|
||||
groupResource schema.GroupResource
|
||||
prov provider.PodMetricsProvider
|
||||
podLister v1listers.PodLister
|
||||
}
|
||||
|
||||
var _ rest.KindProvider = &MetricStorage{}
|
||||
var _ rest.Storage = &MetricStorage{}
|
||||
var _ rest.Getter = &MetricStorage{}
|
||||
var _ rest.Lister = &MetricStorage{}
|
||||
|
||||
func NewStorage(groupResource schema.GroupResource, prov provider.PodMetricsProvider, podLister v1listers.PodLister) *MetricStorage {
|
||||
return &MetricStorage{
|
||||
groupResource: groupResource,
|
||||
prov: prov,
|
||||
podLister: podLister,
|
||||
}
|
||||
}
|
||||
|
||||
// Storage interface
|
||||
func (m *MetricStorage) New() runtime.Object {
|
||||
return &metrics.PodMetrics{}
|
||||
}
|
||||
|
||||
// KindProvider interface
|
||||
func (m *MetricStorage) Kind() string {
|
||||
return "PodMetrics"
|
||||
}
|
||||
|
||||
// Lister interface
|
||||
func (m *MetricStorage) NewList() runtime.Object {
|
||||
return &metrics.PodMetricsList{}
|
||||
}
|
||||
|
||||
// Lister interface
|
||||
func (m *MetricStorage) List(ctx context.Context, options *metainternalversion.ListOptions) (runtime.Object, error) {
|
||||
labelSelector := labels.Everything()
|
||||
if options != nil && options.LabelSelector != nil {
|
||||
labelSelector = options.LabelSelector
|
||||
}
|
||||
namespace := genericapirequest.NamespaceValue(ctx)
|
||||
pods, err := m.podLister.Pods(namespace).List(labelSelector)
|
||||
if err != nil {
|
||||
errMsg := fmt.Errorf("Error while listing pods for selector %v in namespace %q: %v", labelSelector, namespace, err)
|
||||
glog.Error(errMsg)
|
||||
return &metrics.PodMetricsList{}, errMsg
|
||||
}
|
||||
|
||||
metricsItems, err := m.getPodMetrics(pods...)
|
||||
if err != nil {
|
||||
errMsg := fmt.Errorf("Error while fetching pod metrics for selector %v in namespace %q: %v", labelSelector, namespace, err)
|
||||
glog.Error(errMsg)
|
||||
return &metrics.PodMetricsList{}, errMsg
|
||||
}
|
||||
|
||||
return &metrics.PodMetricsList{Items: metricsItems}, nil
|
||||
}
|
||||
|
||||
// Getter interface
|
||||
func (m *MetricStorage) Get(ctx context.Context, name string, opts *metav1.GetOptions) (runtime.Object, error) {
|
||||
namespace := genericapirequest.NamespaceValue(ctx)
|
||||
|
||||
pod, err := m.podLister.Pods(namespace).Get(name)
|
||||
if err != nil {
|
||||
errMsg := fmt.Errorf("Error while getting pod %v: %v", name, err)
|
||||
glog.Error(errMsg)
|
||||
if errors.IsNotFound(err) {
|
||||
// return not-found errors directly
|
||||
return &metrics.PodMetrics{}, err
|
||||
}
|
||||
return &metrics.PodMetrics{}, errMsg
|
||||
}
|
||||
if pod == nil {
|
||||
return &metrics.PodMetrics{}, errors.NewNotFound(v1.Resource("pods"), fmt.Sprintf("%v/%v", namespace, name))
|
||||
}
|
||||
|
||||
podMetrics, err := m.getPodMetrics(pod)
|
||||
if err == nil && len(podMetrics) == 0 {
|
||||
err = fmt.Errorf("no metrics known for pod \"%s/%s\"", pod.Namespace, pod.Name)
|
||||
}
|
||||
if err != nil {
|
||||
glog.Errorf("unable to fetch pod metrics for pod %s/%s: %v", pod.Namespace, pod.Name, err)
|
||||
return nil, errors.NewNotFound(m.groupResource, fmt.Sprintf("%v/%v", namespace, name))
|
||||
}
|
||||
return &podMetrics[0], nil
|
||||
}
|
||||
|
||||
func (m *MetricStorage) getPodMetrics(pods ...*v1.Pod) ([]metrics.PodMetrics, error) {
|
||||
namespacedNames := make([]apitypes.NamespacedName, len(pods))
|
||||
for i, pod := range pods {
|
||||
namespacedNames[i] = apitypes.NamespacedName{
|
||||
Name: pod.Name,
|
||||
Namespace: pod.Namespace,
|
||||
}
|
||||
}
|
||||
timestamps, containerMetrics, err := m.prov.GetContainerMetrics(namespacedNames...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res := make([]metrics.PodMetrics, 0, len(pods))
|
||||
|
||||
for i, pod := range pods {
|
||||
if containerMetrics[i] == nil {
|
||||
glog.Errorf("unable to fetch pod metrics for pod %s/%s: no metrics known for pod", pod.Namespace, pod.Name)
|
||||
continue
|
||||
}
|
||||
|
||||
res = append(res, metrics.PodMetrics{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: pod.Name,
|
||||
Namespace: pod.Namespace,
|
||||
CreationTimestamp: metav1.NewTime(time.Now()),
|
||||
},
|
||||
Timestamp: metav1.NewTime(timestamps[i].Timestamp),
|
||||
Window: metav1.Duration{Duration: timestamps[i].Window},
|
||||
Containers: containerMetrics[i],
|
||||
})
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (m *MetricStorage) NamespaceScoped() bool {
|
||||
return true
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue