github.com/galamsiva2020/kubernetes-heapster-monitoring@v0.0.0-20210823134957-3c1baa7c1e70/metrics/storage/podmetrics/reststorage.go (about)

     1  // Copyright 2016 Google Inc. All Rights Reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package app
    16  
    17  import (
    18  	"fmt"
    19  	"time"
    20  
    21  	"github.com/golang/glog"
    22  
    23  	"k8s.io/api/core/v1"
    24  	"k8s.io/apimachinery/pkg/api/errors"
    25  	metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion"
    26  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    27  	"k8s.io/apimachinery/pkg/labels"
    28  	"k8s.io/apimachinery/pkg/runtime"
    29  	"k8s.io/apimachinery/pkg/runtime/schema"
    30  	genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
    31  	"k8s.io/apiserver/pkg/registry/rest"
    32  	v1listers "k8s.io/client-go/listers/core/v1"
    33  	"k8s.io/heapster/metrics/core"
    34  	metricsink "k8s.io/heapster/metrics/sinks/metric"
    35  	"k8s.io/heapster/metrics/storage/util"
    36  	"k8s.io/metrics/pkg/apis/metrics"
    37  	_ "k8s.io/metrics/pkg/apis/metrics/install"
    38  )
    39  
    40  type MetricStorage struct {
    41  	groupResource schema.GroupResource
    42  	metricSink    *metricsink.MetricSink
    43  	podLister     v1listers.PodLister
    44  }
    45  
    46  var _ rest.KindProvider = &MetricStorage{}
    47  var _ rest.Storage = &MetricStorage{}
    48  var _ rest.Getter = &MetricStorage{}
    49  var _ rest.Lister = &MetricStorage{}
    50  
    51  func NewStorage(groupResource schema.GroupResource, metricSink *metricsink.MetricSink, podLister v1listers.PodLister) *MetricStorage {
    52  	return &MetricStorage{
    53  		groupResource: groupResource,
    54  		metricSink:    metricSink,
    55  		podLister:     podLister,
    56  	}
    57  }
    58  
    59  // Storage interface
    60  func (m *MetricStorage) New() runtime.Object {
    61  	return &metrics.PodMetrics{}
    62  }
    63  
    64  // KindProvider interface
    65  func (m *MetricStorage) Kind() string {
    66  	return "PodMetrics"
    67  }
    68  
    69  // Lister interface
    70  func (m *MetricStorage) NewList() runtime.Object {
    71  	return &metrics.PodMetricsList{}
    72  }
    73  
    74  // Lister interface
    75  func (m *MetricStorage) List(ctx genericapirequest.Context, options *metainternalversion.ListOptions) (runtime.Object, error) {
    76  	labelSelector := labels.Everything()
    77  	if options != nil && options.LabelSelector != nil {
    78  		labelSelector = options.LabelSelector
    79  	}
    80  	namespace := genericapirequest.NamespaceValue(ctx)
    81  	pods, err := m.podLister.Pods(namespace).List(labelSelector)
    82  	if err != nil {
    83  		errMsg := fmt.Errorf("Error while listing pods for selector %v: %v", labelSelector, err)
    84  		glog.Error(errMsg)
    85  		return &metrics.PodMetricsList{}, errMsg
    86  	}
    87  
    88  	res := metrics.PodMetricsList{}
    89  	for _, pod := range pods {
    90  		if podMetrics := m.getPodMetrics(pod); podMetrics != nil {
    91  			res.Items = append(res.Items, *podMetrics)
    92  		} else {
    93  			glog.Infof("No metrics for pod %s/%s", pod.Namespace, pod.Name)
    94  		}
    95  	}
    96  	return &res, nil
    97  }
    98  
    99  // Getter interface
   100  func (m *MetricStorage) Get(ctx genericapirequest.Context, name string, opts *metav1.GetOptions) (runtime.Object, error) {
   101  	namespace := genericapirequest.NamespaceValue(ctx)
   102  
   103  	pod, err := m.podLister.Pods(namespace).Get(name)
   104  	if err != nil {
   105  		errMsg := fmt.Errorf("Error while getting pod %v: %v", name, err)
   106  		glog.Error(errMsg)
   107  		return &metrics.PodMetrics{}, errMsg
   108  	}
   109  	if pod == nil {
   110  		return &metrics.PodMetrics{}, errors.NewNotFound(v1.Resource("Pod"), fmt.Sprintf("%v/%v", namespace, name))
   111  	}
   112  
   113  	podMetrics := m.getPodMetrics(pod)
   114  	if podMetrics == nil {
   115  		return &metrics.PodMetrics{}, errors.NewNotFound(m.groupResource, fmt.Sprintf("%v/%v", namespace, name))
   116  	}
   117  	return podMetrics, nil
   118  }
   119  
   120  func (m *MetricStorage) getPodMetrics(pod *v1.Pod) *metrics.PodMetrics {
   121  	batch := m.metricSink.GetLatestDataBatch()
   122  	if batch == nil {
   123  		return nil
   124  	}
   125  
   126  	res := &metrics.PodMetrics{
   127  		ObjectMeta: metav1.ObjectMeta{
   128  			Name:              pod.Name,
   129  			Namespace:         pod.Namespace,
   130  			CreationTimestamp: metav1.NewTime(time.Now()),
   131  		},
   132  		Timestamp:  metav1.NewTime(batch.Timestamp),
   133  		Window:     metav1.Duration{Duration: time.Minute},
   134  		Containers: make([]metrics.ContainerMetrics, 0),
   135  	}
   136  
   137  	for _, c := range pod.Spec.Containers {
   138  		ms, found := batch.MetricSets[core.PodContainerKey(pod.Namespace, pod.Name, c.Name)]
   139  		if !found {
   140  			glog.Infof("No metrics for container %s in pod %s/%s", c.Name, pod.Namespace, pod.Name)
   141  			return nil
   142  		}
   143  		usage, err := util.ParseResourceList(ms)
   144  		if err != nil {
   145  			return nil
   146  		}
   147  		res.Containers = append(res.Containers, metrics.ContainerMetrics{Name: c.Name, Usage: usage})
   148  	}
   149  
   150  	return res
   151  }