Skip to content

Commit

Permalink
sync code from shell-operator
Browse files Browse the repository at this point in the history
  • Loading branch information
Eugene Shevchenko committed May 28, 2021
1 parent b80f168 commit 8e963c1
Show file tree
Hide file tree
Showing 8 changed files with 99 additions and 422 deletions.
30 changes: 16 additions & 14 deletions client/client.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package client

// TODO do not copy, use import "github.com/flant/kubedog/pkg/kube"

import (
"fmt"
"io/ioutil"
Expand Down Expand Up @@ -63,7 +61,7 @@ func New() Client {
return &client{}
}

func NewFake() Client {
func NewFake(_ map[schema.GroupVersionResource]string) Client {
scheme := runtime.NewScheme()
objs := []runtime.Object{}

Expand Down Expand Up @@ -209,11 +207,12 @@ func (c *client) Init() error {
}

if c.metricStorage != nil {
metrics.Register(metrics.RegisterOpts{
RateLimiterLatency: NewRateLimiterLatencyMetric(c.metricStorage),
RequestLatency: NewRequestLatencyMetric(c.metricStorage, c.metricLabels),
RequestResult: NewRequestResultMetric(c.metricStorage, c.metricLabels),
})
metrics.Register(
metrics.RegisterOpts{
RequestLatency: NewRateLimiterLatencyMetric(c.metricStorage),
RequestResult: NewRequestResultMetric(c.metricStorage, c.metricLabels),
},
)
}

cacheDiscoveryDir, err := ioutil.TempDir("", "kube-cache-discovery-*")
Expand Down Expand Up @@ -273,6 +272,7 @@ func hasInClusterConfig() bool {
return token && ns
}

// fileExists returns true if path exists
func fileExists(path string) (bool, error) {
_, err := os.Stat(path)
if err != nil {
Expand All @@ -299,13 +299,13 @@ func getOutOfClusterConfig(contextName, configPath string) (config *rest.Config,

// rc, err := clientConfig.RawConfig()
// if err != nil {
// return nil, fmt.Errorf("cannot get raw kubernetes config: %s", err)
// return nil, fmt.Errorf("cannot get raw kubernetes config: %s", err)
// }
//
// if contextName != "" {
// Context = contextName
// Context = contextName
// } else {
// Context = rc.CurrentContext
// Context = rc.CurrentContext
// }

return
Expand Down Expand Up @@ -337,6 +337,8 @@ func (c *client) APIResourceList(apiVersion string) (lists []*metav1.APIResource
// Can return errors if api controllers are not available.
switch c.discovery().(type) {
case *fakediscovery.FakeDiscovery:
// FakeDiscovery does not implement ServerPreferredResources method
// lets return all possible resources, its better then nil
_, res, err := c.discovery().ServerGroupsAndResources()
return res, err

Expand All @@ -362,9 +364,9 @@ func (c *client) APIResourceList(apiVersion string) (lists []*metav1.APIResource
// TODO create debug command to output this from cli
// Debug mode will list all available CRDs for apiVersion
// for _, r := range list.APIResources {
// log.Debugf("GVR: %30s %30s %30s", list.GroupVersion, r.Kind,
// fmt.Sprintf("%+v", append([]string{r.Name}, r.ShortNames...)),
// )
// log.Debugf("GVR: %30s %30s %30s", list.GroupVersion, r.Kind,
// fmt.Sprintf("%+v", append([]string{r.Name}, r.ShortNames...)),
// )
// }

return
Expand Down
63 changes: 11 additions & 52 deletions client/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,50 +15,35 @@ import (
// 2. Register backends in client-go.
//
// Backends are used to send metrics from client-go to a Prometheus client.
// Backends are implemented interfaces from https:// github.com/kubernetes/client-go/blob/master/tools/metrics/metrics.go
// Backends are implemented interfaces from https://github.com/kubernetes/client-go/blob/master/tools/metrics/metrics.go

// Deprecated: MetricStorage contains methods from flant/shell-operator metric storage.
// The metrics support is to be deleted from this library. It is left for the time being.
type MetricStorage interface {
RegisterCounter(metric string, labels map[string]string) *prometheus.CounterVec
CounterAdd(metric string, value float64, labels map[string]string)
RegisterHistogram(metric string, labels map[string]string) *prometheus.HistogramVec
RegisterHistogramWithBuckets(metric string, labels map[string]string, buckets []float64) *prometheus.HistogramVec
HistogramObserve(metric string, value float64, labels map[string]string)
RegisterHistogram(metric string, labels map[string]string, buckets []float64) *prometheus.HistogramVec
HistogramObserve(metric string, value float64, labels map[string]string, buckets []float64)
}

// Deprecated: to be removed since it is not a part of the client to support
func RegisterMetrics(metricStorage MetricStorage, metricLabels map[string]string) {
// Deprecated: RegisterKubernetesClientMetrics defines metrics in Prometheus client.
func RegisterKubernetesClientMetrics(metricStorage MetricStorage, metricLabels map[string]string) {
labels := map[string]string{}
for k := range metricLabels {
labels[k] = ""
}
labels["verb"] = ""
labels["url"] = ""

metricStorage.RegisterHistogramWithBuckets("{PREFIX}kubernetes_client_request_latency_seconds",
metricStorage.RegisterHistogram("{PREFIX}kubernetes_client_request_latency_seconds",
labels,
[]float64{
0.0,
0.001, 0.002, 0.005, // 1,2,5 milliseconds
0.01, 0.02, 0.05, // 10,20,50 milliseconds
0.1, 0.2, 0.5, // 100,200,500 milliseconds
1, 2, 5, // 1,2,5 seconds
10, // 10 seconds
})

metricStorage.RegisterHistogramWithBuckets("{PREFIX}kubernetes_client_rate_limiter_latency_seconds",
map[string]string{
"verb": "",
"url": "",
},
[]float64{
0.0,
0.001, 0.002, 0.005, // 1,2,5 milliseconds
0.01, 0.02, 0.05, // 10,20,50 milliseconds
0.1, 0.2, 0.5, // 100,200,500 milliseconds
1, 2, 5, // 1,2,5 seconds
10, // 10 seconds
10, 20, 50, // 10,20,50 seconds
})

labels = map[string]string{}
Expand All @@ -72,33 +57,6 @@ func RegisterMetrics(metricStorage MetricStorage, metricLabels map[string]string
metricStorage.RegisterCounter("{PREFIX}kubernetes_client_request_result_total", labels)
}

// Deprecated: to be removed since it is not a part of the client to support
func NewRequestLatencyMetric(metricStorage MetricStorage, labels map[string]string) metrics.LatencyMetric {
return ClientRequestLatencyMetric{metricStorage, labels}
}

// Deprecated: to be removed since it is not a part of the client to support
type ClientRequestLatencyMetric struct {
metricStorage MetricStorage
labels map[string]string
}

// Deprecated: to be removed since it is not a part of the client to support
func (c ClientRequestLatencyMetric) Observe(verb string, u url.URL, latency time.Duration) {
labels := map[string]string{}
for k, v := range c.labels {
labels[k] = v
}
labels["verb"] = verb
labels["url"] = u.String()

c.metricStorage.HistogramObserve(
"{PREFIX}kubernetes_client_request_latency_seconds",
latency.Seconds(),
labels,
)
}

// Deprecated: to be removed since it is not a part of the client to support
func NewRateLimiterLatencyMetric(metricStorage MetricStorage) metrics.LatencyMetric {
return ClientRateLimiterLatencyMetric{metricStorage}
Expand All @@ -117,21 +75,22 @@ func (c ClientRateLimiterLatencyMetric) Observe(verb string, u url.URL, latency
map[string]string{
"verb": verb,
"url": u.String(),
})
},
nil,
)
}

// Deprecated: to be removed since it is not a part of the client to support
func NewRequestResultMetric(metricStorage MetricStorage, labels map[string]string) metrics.ResultMetric {
return ClientRequestResultMetric{metricStorage, labels}
}

// Deprecated: to be removed since it is not a part of the client to support
type ClientRequestResultMetric struct {
metricStorage MetricStorage
labels map[string]string
}

// Deprecated: to be removed since it is not a part of the client to support
// Deprecated: ClientRequestResultMetric
func (c ClientRequestResultMetric) Increment(code, method, host string) {
labels := map[string]string{}
for k, v := range c.labels {
Expand Down
44 changes: 29 additions & 15 deletions fake/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,35 +13,45 @@ import (
fakediscovery "k8s.io/client-go/discovery/fake"
"k8s.io/client-go/kubernetes/scheme"

"github.com/flant/kube-client/client"
klient "github.com/flant/kube-client/client"
"github.com/flant/kube-client/manifest"
)

type Cluster struct {
Client client.Client
Client klient.Client

Discovery *fakediscovery.FakeDiscovery
}

func NewCluster(ver ClusterVersion) *Cluster {
func NewFakeCluster(ver ClusterVersion) *Cluster {
if ver == "" {
ver = ClusterVersionV119
}

// Client
cres := ClusterResources(ver)

// FIXME: below code will be used in go-client 0.20.x pass it to NewFakeKubernetesClient
// gvrToListKind := make(map[schema.GroupVersionResource]string)
// for _, gr := range cres {
// for _, res := range gr.APIResources {
// gvr := schema.GroupVersionResource{
// Group: res.Group,
// Version: res.Version,
// Resource: res.Name,
// }
// gvrToListKind[gvr] = res.Kind + "List"
// }
// }

fc := &Cluster{}
fc.Client = client.NewFake()

// Discovery
fc.Client = klient.NewFake(nil)

var ok bool
fc.Discovery, ok = fc.Client.Discovery().(*fakediscovery.FakeDiscovery)
if !ok {
panic("couldn't convert Discovery() to *FakeDiscovery")
}
fc.Discovery.FakedServerVersion = &version.Info{GitCommit: ver.String(), Major: ver.Major(), Minor: ver.Minor()}
fc.Discovery.Resources = ClusterResources(ver)
fc.Discovery.Resources = cres

return fc
}
Expand Down Expand Up @@ -165,12 +175,13 @@ func findGvr(resources []*metav1.APIResourceList, apiVersion, kindOrName string)
return nil
}

// Pluralize simplest way to make plural form (like resource) from object Kind
// Pluralize is the simplest way to make a plural form (like resource) from k8s object Kind
// ex: User -> users
// Prometheus -> prometheuses
// NetworkPolicy -> netwrokpolicies
// CustomPrometheusRules -> customprometheusrules
// Endpoints -> endpoints
func Pluralize(kind string) string {

if kind == "" {
return kind
}
Expand All @@ -179,11 +190,14 @@ func Pluralize(kind string) string {

// maybe we dont need more complex pluralizer here
// but if we do, can take smth like https://github.com/gertd/go-pluralize
if strings.HasSuffix(kind, "s") {
switch {
case strings.HasSuffix(kind, "es"):
return kind
case strings.HasSuffix(kind, "ts"):
return kind
case strings.HasSuffix(kind, "s"):
return kind + "es"
}

if strings.HasSuffix(kind, "cy") {
case strings.HasSuffix(kind, "cy"):
return strings.TrimSuffix(kind, "y") + "ies"
}

Expand Down
39 changes: 39 additions & 0 deletions fake/cluster_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package fake

import (
"context"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
)

func TestRegisterCRD(t *testing.T) {
f := NewFakeCluster("")

f.RegisterCRD("deckhouse.io", "v1alpha1", "KeepalivedInstance", false)
gvk := schema.GroupVersionResource{
Group: "deckhouse.io",
Version: "v1alpha1",
Resource: Pluralize("KeepalivedInstance"),
}
_, err := f.Client.Dynamic().Resource(gvk).Namespace("").List(context.TODO(), v1.ListOptions{})
require.NoError(t, err)
}

func TestPluralize(t *testing.T) {
tests := map[string]string{
"Endpoints": "endpoints",
"Prometheus": "prometheuses",
"NetworkPolicy": "networkpolicies",
"CustomPrometheusRules": "customprometheusrules",
"Alertmanager": "alertmanagers",
"Node": "nodes",
}

for before, after := range tests {
assert.Equal(t, after, Pluralize(before))
}
}
Loading

0 comments on commit 8e963c1

Please sign in to comment.