Skip to content

Commit

Permalink
Merge pull request kubernetes#80561 from seans3/move-metricsutil-staging
Browse files Browse the repository at this point in the history
Move pkg/kubectl/metricsutil to staging

Kubernetes-commit: c1eff52
  • Loading branch information
k8s-publishing-bot committed Jul 30, 2019
2 parents 8f21c5b + 6f46e8d commit 98d4a9f
Show file tree
Hide file tree
Showing 5 changed files with 572 additions and 4 deletions.
58 changes: 57 additions & 1 deletion Godeps/Godeps.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 5 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ require (
k8s.io/api v0.0.0-20190726022912-69e1bce1dad5
k8s.io/apimachinery v0.0.0-20190727130956-f97a4e5b4abc
k8s.io/cli-runtime v0.0.0-20190726024606-74a61cd71909
k8s.io/client-go v0.0.0-20190726023111-a9c895e7f2ac
k8s.io/client-go v0.0.0-20190730143201-693ed41095c3
k8s.io/klog v0.3.1
k8s.io/kube-openapi v0.0.0-20190709113604-33be087ad058
k8s.io/metrics v0.0.0-20190726024513-9140f5fe6ab8
k8s.io/utils v0.0.0-20190607212802-c55fbcfc754a
sigs.k8s.io/yaml v1.1.0
)
Expand All @@ -45,5 +46,7 @@ replace (
k8s.io/api => k8s.io/api v0.0.0-20190726022912-69e1bce1dad5
k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20190727130956-f97a4e5b4abc
k8s.io/cli-runtime => k8s.io/cli-runtime v0.0.0-20190726024606-74a61cd71909
k8s.io/client-go => k8s.io/client-go v0.0.0-20190725230141-579ad46bdcb9
k8s.io/client-go => k8s.io/client-go v0.0.0-20190730143201-693ed41095c3
k8s.io/code-generator => k8s.io/code-generator v0.0.0-20190726022633-14ba7d03f06f
k8s.io/metrics => k8s.io/metrics v0.0.0-20190726024513-9140f5fe6ab8
)
18 changes: 17 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7O
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
github.com/Azure/go-autorest v11.1.2+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd h1:sjQovDkwrZp8u+gxLtPgKGjk5hCxuy2hrRejBTA9xFU=
github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E=
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
Expand Down Expand Up @@ -129,6 +130,7 @@ github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M=
github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
Expand All @@ -154,6 +156,10 @@ github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljT
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
golang.org/x/crypto v0.0.0-20181025213731-e84da0312774 h1:a4tQYYYuK9QdeO/+kEvNYyuR21S+7ve5EANok6hABhI=
golang.org/x/crypto v0.0.0-20181025213731-e84da0312774/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190312203227-4b39c73a6495/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/net v0.0.0-20190206173232-65e2d4e15006 h1:bfLnR+k0tq5Lqt6dflRLcZiz6UaXCMt3vhYJ1l4FQ80=
golang.org/x/net v0.0.0-20190206173232-65e2d4e15006/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a h1:tImsplftrFpALCYumobsd0K86vlAs/eXGFms2txfJfA=
Expand All @@ -167,6 +173,9 @@ golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5f
golang.org/x/time v0.0.0-20161028155119-f51c12702a4d h1:TnM+PKb3ylGmZvyPXmo9m/wktg7Jn/a/fNmr33HSj8g=
golang.org/x/time v0.0.0-20161028155119-f51c12702a4d/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20190313210603-aa82965741a9/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0=
gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
Expand All @@ -188,16 +197,23 @@ gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81
k8s.io/api v0.0.0-20190726022912-69e1bce1dad5/go.mod h1:V6cpJ9D7WqSy0wqcE096gcbj+W//rshgQgmj1Shdwi8=
k8s.io/apimachinery v0.0.0-20190727130956-f97a4e5b4abc/go.mod h1:eXR4ljjmbwK6Ng0PKsXRySPXnTUy/qBUa6kPDeckhQ0=
k8s.io/cli-runtime v0.0.0-20190726024606-74a61cd71909/go.mod h1:bk/fSEmINmKG2jHCCbqbXmwEJgE6kHVMkOC1U9dclzo=
k8s.io/client-go v0.0.0-20190725230141-579ad46bdcb9/go.mod h1:ncT9fCvHnM5BUiZs0RCf9vAEqRrRoJtR2sZ2evompEU=
k8s.io/client-go v0.0.0-20190730143201-693ed41095c3/go.mod h1:WHnpzOmgNDpM2XNcGwWUVwx5ERofFlRgmtg0ljqAwds=
k8s.io/code-generator v0.0.0-20190726022633-14ba7d03f06f/go.mod h1:kr7tMYxZEaP3mrijPwXnhxOvPyqdJw6TZH87KfFboQ0=
k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
k8s.io/klog v0.3.1 h1:RVgyDHY/kFKtLqh67NvEWIgkMneNoIrdkN0CxDSQc68=
k8s.io/klog v0.3.1/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
k8s.io/kube-openapi v0.0.0-20190709113604-33be087ad058 h1:di3XCwddOR9cWBNpfgXaskhh6cgJuwcK54rvtwUaC10=
k8s.io/kube-openapi v0.0.0-20190709113604-33be087ad058/go.mod h1:nfDlWeOsu3pUf4yWGL+ERqohP4YsZcBJXWMK+gkzOA4=
k8s.io/metrics v0.0.0-20190726024513-9140f5fe6ab8/go.mod h1:qKj9Rmzs1afkjgcziJ2/HzORbC8bXn457iAFxXUDykA=
k8s.io/utils v0.0.0-20190607212802-c55fbcfc754a h1:2jUDc9gJja832Ftp+QbDV0tVhQHMISFn01els+2ZAcw=
k8s.io/utils v0.0.0-20190607212802-c55fbcfc754a/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw=
modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk=
modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k=
modernc.org/strutil v1.0.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs=
modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I=
sigs.k8s.io/kustomize v2.0.3+incompatible h1:JUufWFNlI44MdtnjUqVnvh29rR37PQFzPbLXqhyOyX0=
sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU=
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
Expand Down
170 changes: 170 additions & 0 deletions pkg/metricsutil/metrics_client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
/*
Copyright 2016 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 metricsutil

import (
"encoding/json"
"errors"
"fmt"

"k8s.io/apimachinery/pkg/api/validation"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime/schema"
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
metricsapi "k8s.io/metrics/pkg/apis/metrics"
metricsv1alpha1api "k8s.io/metrics/pkg/apis/metrics/v1alpha1"
)

const (
DefaultHeapsterNamespace = "kube-system"
DefaultHeapsterScheme = "http"
DefaultHeapsterService = "heapster"
DefaultHeapsterPort = "" // use the first exposed port on the service
)

var (
prefix = "/apis"
groupVersion = fmt.Sprintf("%s/%s", metricsGv.Group, metricsGv.Version)
metricsRoot = fmt.Sprintf("%s/%s", prefix, groupVersion)

// TODO: get this from metrics api once it's finished
metricsGv = schema.GroupVersion{Group: "metrics", Version: "v1alpha1"}
)

type HeapsterMetricsClient struct {
SVCClient corev1client.ServicesGetter
HeapsterNamespace string
HeapsterScheme string
HeapsterService string
HeapsterPort string
}

func NewHeapsterMetricsClient(svcClient corev1client.ServicesGetter, namespace, scheme, service, port string) *HeapsterMetricsClient {
return &HeapsterMetricsClient{
SVCClient: svcClient,
HeapsterNamespace: namespace,
HeapsterScheme: scheme,
HeapsterService: service,
HeapsterPort: port,
}
}

func podMetricsURL(namespace string, name string) (string, error) {
if namespace == metav1.NamespaceAll {
return fmt.Sprintf("%s/pods", metricsRoot), nil
}
errs := validation.ValidateNamespaceName(namespace, false)
if len(errs) > 0 {
message := fmt.Sprintf("invalid namespace: %s - %v", namespace, errs)
return "", errors.New(message)
}
if len(name) > 0 {
errs = validation.NameIsDNSSubdomain(name, false)
if len(errs) > 0 {
message := fmt.Sprintf("invalid pod name: %s - %v", name, errs)
return "", errors.New(message)
}
}
return fmt.Sprintf("%s/namespaces/%s/pods/%s", metricsRoot, namespace, name), nil
}

func nodeMetricsURL(name string) (string, error) {
if len(name) > 0 {
errs := validation.NameIsDNSSubdomain(name, false)
if len(errs) > 0 {
message := fmt.Sprintf("invalid node name: %s - %v", name, errs)
return "", errors.New(message)
}
}
return fmt.Sprintf("%s/nodes/%s", metricsRoot, name), nil
}

func (cli *HeapsterMetricsClient) GetNodeMetrics(nodeName string, selector string) (*metricsapi.NodeMetricsList, error) {
params := map[string]string{"labelSelector": selector}
path, err := nodeMetricsURL(nodeName)
if err != nil {
return nil, err
}
resultRaw, err := GetHeapsterMetrics(cli, path, params)
if err != nil {
return nil, err
}
versionedMetrics := metricsv1alpha1api.NodeMetricsList{}
if len(nodeName) == 0 {
err = json.Unmarshal(resultRaw, &versionedMetrics)
if err != nil {
return nil, fmt.Errorf("failed to unmarshall heapster response: %v", err)
}
} else {
var singleMetric metricsv1alpha1api.NodeMetrics
err = json.Unmarshal(resultRaw, &singleMetric)
if err != nil {
return nil, fmt.Errorf("failed to unmarshall heapster response: %v", err)
}
versionedMetrics.Items = []metricsv1alpha1api.NodeMetrics{singleMetric}
}
metrics := &metricsapi.NodeMetricsList{}
err = metricsv1alpha1api.Convert_v1alpha1_NodeMetricsList_To_metrics_NodeMetricsList(&versionedMetrics, metrics, nil)
if err != nil {
return nil, err
}
return metrics, nil
}

func (cli *HeapsterMetricsClient) GetPodMetrics(namespace string, podName string, allNamespaces bool, selector labels.Selector) (*metricsapi.PodMetricsList, error) {
if allNamespaces {
namespace = metav1.NamespaceAll
}
path, err := podMetricsURL(namespace, podName)
if err != nil {
return nil, err
}

params := map[string]string{"labelSelector": selector.String()}
versionedMetrics := metricsv1alpha1api.PodMetricsList{}

resultRaw, err := GetHeapsterMetrics(cli, path, params)
if err != nil {
return nil, err
}
if len(podName) == 0 {
err = json.Unmarshal(resultRaw, &versionedMetrics)
if err != nil {
return nil, fmt.Errorf("failed to unmarshall heapster response: %v", err)
}
} else {
var singleMetric metricsv1alpha1api.PodMetrics
err = json.Unmarshal(resultRaw, &singleMetric)
if err != nil {
return nil, fmt.Errorf("failed to unmarshall heapster response: %v", err)
}
versionedMetrics.Items = []metricsv1alpha1api.PodMetrics{singleMetric}
}
metrics := &metricsapi.PodMetricsList{}
err = metricsv1alpha1api.Convert_v1alpha1_PodMetricsList_To_metrics_PodMetricsList(&versionedMetrics, metrics, nil)
if err != nil {
return nil, err
}
return metrics, nil
}

func GetHeapsterMetrics(cli *HeapsterMetricsClient, path string, params map[string]string) ([]byte, error) {
return cli.SVCClient.Services(cli.HeapsterNamespace).
ProxyGet(cli.HeapsterScheme, cli.HeapsterService, cli.HeapsterPort, path, params).
DoRaw()
}
Loading

0 comments on commit 98d4a9f

Please sign in to comment.