mirror of
https://github.com/zalando-incubator/kube-metrics-adapter.git
synced 2025-05-11 16:10:40 +00:00
Compare commits
3 Commits
v0.1.0
...
feature/k8
Author | SHA1 | Date | |
---|---|---|---|
417f650caa | |||
37003d6513 | |||
b685c7db1c |
22
go.mod
22
go.mod
@ -2,10 +2,12 @@ module github.com/zalando-incubator/kube-metrics-adapter
|
||||
|
||||
require (
|
||||
bitbucket.org/ww/goautoneg v0.0.0-20120707110453-75cd24fc2f2c // indirect
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 // indirect
|
||||
github.com/BurntSushi/toml v0.3.0 // indirect
|
||||
github.com/NYTimes/gziphandler v1.0.1 // indirect
|
||||
github.com/PuerkitoBio/purell v1.1.0 // indirect
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
|
||||
github.com/Sirupsen/logrus v1.0.6 // indirect
|
||||
github.com/aws/aws-sdk-go v1.16.6
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 // indirect
|
||||
github.com/boltdb/bolt v1.3.1 // indirect
|
||||
@ -14,8 +16,8 @@ require (
|
||||
github.com/coreos/go-semver v0.2.0 // indirect
|
||||
github.com/coreos/go-systemd v0.0.0-20180705093442-88bfeed483d3 // indirect
|
||||
github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
|
||||
github.com/docker/docker v1.13.1 // indirect
|
||||
github.com/elazarl/go-bindata-assetfs v1.0.0 // indirect
|
||||
github.com/emicklei/go-restful v2.8.0+incompatible // indirect
|
||||
github.com/emicklei/go-restful-swagger12 v0.0.0-20170926063155-7524189396c6 // indirect
|
||||
@ -42,7 +44,7 @@ require (
|
||||
github.com/inconshreveable/mousetrap v1.0.0 // indirect
|
||||
github.com/jonboulle/clockwork v0.1.0 // indirect
|
||||
github.com/json-iterator/go v1.1.5 // indirect
|
||||
github.com/kubernetes-incubator/custom-metrics-apiserver v0.0.0-20180824182428-26e5299457d3
|
||||
github.com/kubernetes-incubator/custom-metrics-apiserver v0.0.0-20190103205038-2655ce32a120
|
||||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
@ -52,12 +54,11 @@ require (
|
||||
github.com/onsi/gomega v1.4.1 // indirect
|
||||
github.com/pborman/uuid v0.0.0-20180122190007-c65b2f87fee3 // indirect
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/prometheus/client_golang v0.9.0-pre1.0.20180824101016-4eb539fa85a2
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 // indirect
|
||||
github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e
|
||||
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273 // indirect
|
||||
github.com/sirupsen/logrus v1.0.6
|
||||
github.com/sirupsen/logrus v1.3.0
|
||||
github.com/soheilhy/cmux v0.1.4 // indirect
|
||||
github.com/spf13/cobra v0.0.3
|
||||
github.com/spf13/pflag v1.0.2 // indirect
|
||||
@ -70,7 +71,6 @@ require (
|
||||
golang.org/x/net v0.0.0-20180824152047-4bcd98cce591 // indirect
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f // indirect
|
||||
golang.org/x/sys v0.0.0-20180824143301-4910a1d54f87 // indirect
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2 // indirect
|
||||
google.golang.org/appengine v1.2.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 // indirect
|
||||
@ -82,10 +82,12 @@ require (
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0-20170531160350-a96e63847dc3 // indirect
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
|
||||
gopkg.in/yaml.v2 v2.2.1 // indirect
|
||||
k8s.io/api v0.0.0-20180628040859-072894a440bd
|
||||
k8s.io/apimachinery v0.0.0-20180621070125-103fd098999d
|
||||
k8s.io/apiserver v0.0.0-20180628044425-01459b68eb5f
|
||||
k8s.io/client-go v8.0.0+incompatible
|
||||
k8s.io/api v0.0.0-20181128191700-6db15a15d2d3
|
||||
k8s.io/apimachinery v0.0.0-20190104073114-849b284f3b75
|
||||
k8s.io/apiserver v0.0.0-20181207191401-9601a7bf41ef
|
||||
k8s.io/client-go v2.0.0-alpha.0.0.20181126152608-d082d5923d3c+incompatible
|
||||
k8s.io/klog v0.1.0 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20180731170545-e3762e86a74c // indirect
|
||||
k8s.io/metrics v0.0.0-20180718014405-6efa0bfaa5c1
|
||||
k8s.io/metrics v0.0.0-20181217194040-83acca0c921f
|
||||
sigs.k8s.io/yaml v1.1.0 // indirect
|
||||
)
|
||||
|
46
go.sum
46
go.sum
@ -1,5 +1,7 @@
|
||||
bitbucket.org/ww/goautoneg v0.0.0-20120707110453-75cd24fc2f2c h1:t+Ra932MCC0eeyD/vigXqMbZTzgZjd4JOfBJWC6VSMI=
|
||||
bitbucket.org/ww/goautoneg v0.0.0-20120707110453-75cd24fc2f2c/go.mod h1:1vhO7Mn/FZMgOgDVGLy5X1mE6rq1HbkBdkF/yj8zkcg=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
||||
github.com/BurntSushi/toml v0.3.0 h1:e1/Ivsx3Z0FVTV0NSOv/aVgbUWyQuzj7DDnFblkRvsY=
|
||||
github.com/BurntSushi/toml v0.3.0/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/NYTimes/gziphandler v1.0.1 h1:iLrQrdwjDd52kHDA5op2UBJFjmOb9g+7scBan4RN8F0=
|
||||
@ -8,6 +10,8 @@ github.com/PuerkitoBio/purell v1.1.0 h1:rmGxhojJlM0tuKtfdvliR84CFHljx9ag64t2xmVk
|
||||
github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/Sirupsen/logrus v1.0.6 h1:HCAGQRk48dRVPA5Y+Yh0qdCSTzPOyU1tBJ7Q9YzotII=
|
||||
github.com/Sirupsen/logrus v1.0.6/go.mod h1:rmk17hk6i8ZSAJkSDa7nOxamrG+SP4P0mm+DAvExv4U=
|
||||
github.com/aws/aws-sdk-go v1.16.6 h1:pig/KdfESvIv4gUu1B8nVAJAURxbPCTt6e5u79Nqxqc=
|
||||
github.com/aws/aws-sdk-go v1.16.6/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0=
|
||||
@ -28,6 +32,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/docker/docker v1.13.1 h1:IkZjBSIc8hBjLpqeAbeE5mca5mNgeatLHBy3GO78BWo=
|
||||
github.com/docker/docker v1.13.1/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/elazarl/go-bindata-assetfs v1.0.0 h1:G/bYguwHIzWq9ZoyUQqrjTmJbbYn3j3CKKpKinvZLFk=
|
||||
github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4=
|
||||
github.com/emicklei/go-restful v2.8.0+incompatible h1:wN8GCRDPGHguIynsnBartv5GUgGUg1LAU7+xnSn1j7Q=
|
||||
@ -84,8 +90,10 @@ github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/json-iterator/go v1.1.5 h1:gL2yXlmiIo4+t+y32d4WGwOjKGYcGOuyrg46vadswDE=
|
||||
github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/kubernetes-incubator/custom-metrics-apiserver v0.0.0-20180824182428-26e5299457d3 h1:X22IRs6vbuj0xu3ZuMYMI2Qe0IDmxv0RJvWEwLw2nSg=
|
||||
github.com/kubernetes-incubator/custom-metrics-apiserver v0.0.0-20180824182428-26e5299457d3/go.mod h1:KWRxWvzVCNvDtG9ejU5UdpgvxdCZFMUZu0xroKWG8Bo=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kubernetes-incubator/custom-metrics-apiserver v0.0.0-20190103205038-2655ce32a120 h1:sGvfPs6pXe/mLD0dbEUd7t2jc4JFDGuNwSL+h01TjQg=
|
||||
github.com/kubernetes-incubator/custom-metrics-apiserver v0.0.0-20190103205038-2655ce32a120/go.mod h1:KWRxWvzVCNvDtG9ejU5UdpgvxdCZFMUZu0xroKWG8Bo=
|
||||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 h1:2gxZ0XQIU/5z3Z3bUBu+FXuk2pFbkN6tcwi/pjyaDic=
|
||||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||
@ -114,14 +122,15 @@ github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e h1:n/3MEhJQjQxrO
|
||||
github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273 h1:agujYaXJSxSo18YNX3jzl+4G6Bstwt+kqv47GS12uL0=
|
||||
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/sirupsen/logrus v1.0.6 h1:hcP1GmhGigz/O7h1WVUM5KklBp1JoNS9FggWKdj/j3s=
|
||||
github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
|
||||
github.com/sirupsen/logrus v1.3.0 h1:hI/7Q+DtNZ2kINb6qt/lS+IyXnHQe9e90POfeewL/ME=
|
||||
github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E=
|
||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
github.com/spf13/cobra v0.0.3 h1:ZlrZ4XsMRm04Fr5pSFxBgfND2EBVa1nLpiy1stUsX/8=
|
||||
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/pflag v1.0.2 h1:Fy0orTDgHdbnzHcsOgfCN4LtHf0ec3wwtiwJqwvf3Gc=
|
||||
github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20171017195756-830351dc03c6 h1:lYIiVDtZnyTWlNwiAxLj0bbpTcx1BWCFhXjfsvmPdNc=
|
||||
@ -132,6 +141,7 @@ github.com/xiang90/probing v0.0.0-20160813154853-07dd2e8dfe18 h1:MPPkRncZLN9Kh4M
|
||||
github.com/xiang90/probing v0.0.0-20160813154853-07dd2e8dfe18/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/zalando-incubator/cluster-lifecycle-manager v0.0.0-20180921141935-824b77fb1f84 h1:LirBPRU6n8qjPFWCTIlTDh+1FW2M4z2RFS7lCzNkKgA=
|
||||
github.com/zalando-incubator/cluster-lifecycle-manager v0.0.0-20180921141935-824b77fb1f84/go.mod h1:6GNNHCquvS1cn0APtLvgYNYEMYK+JRwp6ZTGxi+pc+w=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181015023909-0c41d7ab0a0e h1:IzypfodbhbnViNUO/MEh0FzCUooG97cIGfdggUrUSyU=
|
||||
golang.org/x/crypto v0.0.0-20181015023909-0c41d7ab0a0e/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@ -141,8 +151,8 @@ golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180824143301-4910a1d54f87 h1:GqwDwfvIpC33dK9bA1fD+JiDUNsuAiQiEkpHqUKze4o=
|
||||
golang.org/x/sys v0.0.0-20180824143301-4910a1d54f87/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33 h1:I6FyU15t786LL7oL/hn43zqTuEGr4PN7F4XJ1p4E3Y8=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2 h1:+DCIGbF/swA92ohVg0//6X2IVY3KZs6p9mix0ziNYJM=
|
||||
@ -169,15 +179,19 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkep
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
k8s.io/api v0.0.0-20180628040859-072894a440bd h1:HzgYeLDS1jLxw8DGr68KJh9cdQ5iZJizG0HZWstIhfQ=
|
||||
k8s.io/api v0.0.0-20180628040859-072894a440bd/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA=
|
||||
k8s.io/apimachinery v0.0.0-20180621070125-103fd098999d h1:MZjlsu9igBoVPZkXpIGoxI6EonqNsXXZU7hhvfQLkd4=
|
||||
k8s.io/apimachinery v0.0.0-20180621070125-103fd098999d/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0=
|
||||
k8s.io/apiserver v0.0.0-20180628044425-01459b68eb5f h1:eCb6E7epnzes186KGtXgA3PE2mLim3ceVSbCXQ8v5e8=
|
||||
k8s.io/apiserver v0.0.0-20180628044425-01459b68eb5f/go.mod h1:6bqaTSOSJavUIXUtfaR9Os9JtTCm8ZqH2SUl2S60C4w=
|
||||
k8s.io/client-go v8.0.0+incompatible h1:tTI4hRmb1DRMl4fG6Vclfdi6nTM82oIrTT7HfitmxC4=
|
||||
k8s.io/client-go v8.0.0+incompatible/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s=
|
||||
k8s.io/api v0.0.0-20181128191700-6db15a15d2d3 h1:yU+uHaWFaeWjRoVDuKI2qxcOP9PPFJ+665yJuHI5Ils=
|
||||
k8s.io/api v0.0.0-20181128191700-6db15a15d2d3/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA=
|
||||
k8s.io/apimachinery v0.0.0-20190104073114-849b284f3b75 h1:dLhsGWh58R0WYgTCX6ZdaqSz2FltMZsk+ByHsUgMWRU=
|
||||
k8s.io/apimachinery v0.0.0-20190104073114-849b284f3b75/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0=
|
||||
k8s.io/apiserver v0.0.0-20181207191401-9601a7bf41ef h1:MREYcVS7G5mUkXTCeqMuE7xEnCaoQFyV89eLqaJsHVo=
|
||||
k8s.io/apiserver v0.0.0-20181207191401-9601a7bf41ef/go.mod h1:6bqaTSOSJavUIXUtfaR9Os9JtTCm8ZqH2SUl2S60C4w=
|
||||
k8s.io/client-go v2.0.0-alpha.0.0.20181126152608-d082d5923d3c+incompatible h1:QOMBR2qlbwRbUJbJDXFjS8YEiXQc3AJBcEac7z3769I=
|
||||
k8s.io/client-go v2.0.0-alpha.0.0.20181126152608-d082d5923d3c+incompatible/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s=
|
||||
k8s.io/klog v0.1.0 h1:I5HMfc/DtuVaGR1KPwUrTc476K8NCqNBldC7H4dYEzk=
|
||||
k8s.io/klog v0.1.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
|
||||
k8s.io/kube-openapi v0.0.0-20180731170545-e3762e86a74c h1:3KSCztE7gPitlZmWbNwue/2U0YruD65DqX3INopDAQM=
|
||||
k8s.io/kube-openapi v0.0.0-20180731170545-e3762e86a74c/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc=
|
||||
k8s.io/metrics v0.0.0-20180718014405-6efa0bfaa5c1 h1:7l3a6VjAMN3vKX7iN6pJLIn+wVzdIdHm+YWJfV4sg2s=
|
||||
k8s.io/metrics v0.0.0-20180718014405-6efa0bfaa5c1/go.mod h1:a25VAbm3QT3xiVl1jtoF1ueAKQM149UdZ+L93ePfV3M=
|
||||
k8s.io/metrics v0.0.0-20181217194040-83acca0c921f h1:nMKVdNP4pn7wB8A1rZkOCaUZFWWxjZ0gmx8TJDmTABM=
|
||||
k8s.io/metrics v0.0.0-20181217194040-83acca0c921f/go.mod h1:a25VAbm3QT3xiVl1jtoF1ueAKQM149UdZ+L93ePfV3M=
|
||||
sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
|
||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||
|
@ -9,7 +9,7 @@ import (
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
"github.com/aws/aws-sdk-go/service/sqs"
|
||||
"github.com/aws/aws-sdk-go/service/sqs/sqsiface"
|
||||
autoscalingv2beta1 "k8s.io/api/autoscaling/v2beta1"
|
||||
autoscalingv2beta2 "k8s.io/api/autoscaling/v2beta2"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/metrics/pkg/apis/external_metrics"
|
||||
@ -32,7 +32,7 @@ func NewAWSCollectorPlugin(sessions map[string]*session.Session) *AWSCollectorPl
|
||||
}
|
||||
|
||||
// NewCollector initializes a new skipper collector from the specified HPA.
|
||||
func (c *AWSCollectorPlugin) NewCollector(hpa *autoscalingv2beta1.HorizontalPodAutoscaler, config *MetricConfig, interval time.Duration) (Collector, error) {
|
||||
func (c *AWSCollectorPlugin) NewCollector(hpa *autoscalingv2beta2.HorizontalPodAutoscaler, config *MetricConfig, interval time.Duration) (Collector, error) {
|
||||
switch config.Name {
|
||||
case AWSSQSQueueLengthMetric:
|
||||
return NewAWSSQSCollector(c.sessions, config, interval)
|
||||
@ -49,7 +49,7 @@ type AWSSQSCollector struct {
|
||||
queueName string
|
||||
labels map[string]string
|
||||
metricName string
|
||||
metricType autoscalingv2beta1.MetricSourceType
|
||||
metricType autoscalingv2beta2.MetricSourceType
|
||||
}
|
||||
|
||||
func NewAWSSQSCollector(sessions map[string]*session.Session, config *MetricConfig, interval time.Duration) (*AWSSQSCollector, error) {
|
||||
|
@ -5,7 +5,8 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
autoscalingv2beta1 "k8s.io/api/autoscaling/v2beta1"
|
||||
autoscalingv2beta2 "k8s.io/api/autoscaling/v2beta2"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/metrics/pkg/apis/custom_metrics"
|
||||
"k8s.io/metrics/pkg/apis/external_metrics"
|
||||
)
|
||||
@ -17,7 +18,7 @@ const (
|
||||
)
|
||||
|
||||
type ObjectReference struct {
|
||||
autoscalingv2beta1.CrossVersionObjectReference
|
||||
autoscalingv2beta2.CrossVersionObjectReference
|
||||
Namespace string
|
||||
}
|
||||
|
||||
@ -49,7 +50,7 @@ func NewCollectorFactory() *CollectorFactory {
|
||||
}
|
||||
|
||||
type CollectorPlugin interface {
|
||||
NewCollector(hpa *autoscalingv2beta1.HorizontalPodAutoscaler, config *MetricConfig, interval time.Duration) (Collector, error)
|
||||
NewCollector(hpa *autoscalingv2beta2.HorizontalPodAutoscaler, config *MetricConfig, interval time.Duration) (Collector, error)
|
||||
}
|
||||
|
||||
func (c *CollectorFactory) RegisterPodsCollector(metricCollector string, plugin CollectorPlugin) error {
|
||||
@ -106,9 +107,9 @@ func (c *CollectorFactory) RegisterExternalCollector(metrics []string, plugin Co
|
||||
}
|
||||
}
|
||||
|
||||
func (c *CollectorFactory) NewCollector(hpa *autoscalingv2beta1.HorizontalPodAutoscaler, config *MetricConfig, interval time.Duration) (Collector, error) {
|
||||
func (c *CollectorFactory) NewCollector(hpa *autoscalingv2beta2.HorizontalPodAutoscaler, config *MetricConfig, interval time.Duration) (Collector, error) {
|
||||
switch config.Type {
|
||||
case autoscalingv2beta1.PodsMetricSourceType:
|
||||
case autoscalingv2beta2.PodsMetricSourceType:
|
||||
// first try to find a plugin by format
|
||||
if plugin, ok := c.podsPlugins.Named[config.CollectorName]; ok {
|
||||
return plugin.NewCollector(hpa, config, interval)
|
||||
@ -118,7 +119,7 @@ func (c *CollectorFactory) NewCollector(hpa *autoscalingv2beta1.HorizontalPodAut
|
||||
if c.podsPlugins.Any != nil {
|
||||
return c.podsPlugins.Any.NewCollector(hpa, config, interval)
|
||||
}
|
||||
case autoscalingv2beta1.ObjectMetricSourceType:
|
||||
case autoscalingv2beta2.ObjectMetricSourceType:
|
||||
// first try to find a plugin by kind
|
||||
if kinds, ok := c.objectPlugins.Named[config.ObjectReference.Kind]; ok {
|
||||
if plugin, ok := kinds.Named[config.CollectorName]; ok {
|
||||
@ -139,7 +140,7 @@ func (c *CollectorFactory) NewCollector(hpa *autoscalingv2beta1.HorizontalPodAut
|
||||
if c.objectPlugins.Any.Any != nil {
|
||||
return c.objectPlugins.Any.Any.NewCollector(hpa, config, interval)
|
||||
}
|
||||
case autoscalingv2beta1.ExternalMetricSourceType:
|
||||
case autoscalingv2beta2.ExternalMetricSourceType:
|
||||
if plugin, ok := c.externalPlugins[config.Name]; ok {
|
||||
return plugin.NewCollector(hpa, config, interval)
|
||||
}
|
||||
@ -148,13 +149,13 @@ func (c *CollectorFactory) NewCollector(hpa *autoscalingv2beta1.HorizontalPodAut
|
||||
return nil, fmt.Errorf("no plugin found for %s", config.MetricTypeName)
|
||||
}
|
||||
|
||||
func getObjectReference(hpa *autoscalingv2beta1.HorizontalPodAutoscaler, metricName string) (custom_metrics.ObjectReference, error) {
|
||||
func getObjectReference(hpa *autoscalingv2beta2.HorizontalPodAutoscaler, metricName string) (custom_metrics.ObjectReference, error) {
|
||||
for _, metric := range hpa.Spec.Metrics {
|
||||
if metric.Type == autoscalingv2beta1.ObjectMetricSourceType && metric.Object.MetricName == metricName {
|
||||
if metric.Type == autoscalingv2beta2.ObjectMetricSourceType && metric.Object.Metric.Name == metricName {
|
||||
return custom_metrics.ObjectReference{
|
||||
APIVersion: metric.Object.Target.APIVersion,
|
||||
Kind: metric.Object.Target.Kind,
|
||||
Name: metric.Object.Target.Name,
|
||||
APIVersion: metric.Object.DescribedObject.APIVersion,
|
||||
Kind: metric.Object.DescribedObject.Kind,
|
||||
Name: metric.Object.DescribedObject.Name,
|
||||
Namespace: hpa.Namespace,
|
||||
}, nil
|
||||
}
|
||||
@ -164,12 +165,13 @@ func getObjectReference(hpa *autoscalingv2beta1.HorizontalPodAutoscaler, metricN
|
||||
}
|
||||
|
||||
type MetricTypeName struct {
|
||||
Type autoscalingv2beta1.MetricSourceType
|
||||
Name string
|
||||
Type autoscalingv2beta2.MetricSourceType
|
||||
Name string
|
||||
MetricLabels *metav1.LabelSelector
|
||||
}
|
||||
|
||||
type CollectedMetric struct {
|
||||
Type autoscalingv2beta1.MetricSourceType
|
||||
Type autoscalingv2beta2.MetricSourceType
|
||||
Custom custom_metrics.MetricValue
|
||||
External external_metrics.ExternalMetricValue
|
||||
Labels map[string]string
|
||||
@ -215,9 +217,9 @@ func parseCustomMetricsAnnotations(annotations map[string]string) (map[MetricTyp
|
||||
|
||||
switch configs[1] {
|
||||
case "pods":
|
||||
metricTypeName.Type = autoscalingv2beta1.PodsMetricSourceType
|
||||
metricTypeName.Type = autoscalingv2beta2.PodsMetricSourceType
|
||||
case "object":
|
||||
metricTypeName.Type = autoscalingv2beta1.ObjectMetricSourceType
|
||||
metricTypeName.Type = autoscalingv2beta2.ObjectMetricSourceType
|
||||
}
|
||||
|
||||
metricCollector := configs[3]
|
||||
@ -258,7 +260,7 @@ func parseCustomMetricsAnnotations(annotations map[string]string) (map[MetricTyp
|
||||
}
|
||||
|
||||
// ParseHPAMetrics parses the HPA object into a list of metric configurations.
|
||||
func ParseHPAMetrics(hpa *autoscalingv2beta1.HorizontalPodAutoscaler) ([]*MetricConfig, error) {
|
||||
func ParseHPAMetrics(hpa *autoscalingv2beta2.HorizontalPodAutoscaler) ([]*MetricConfig, error) {
|
||||
metricConfigs := make([]*MetricConfig, 0, len(hpa.Spec.Metrics))
|
||||
|
||||
// TODO: validate that the specified metric names are defined
|
||||
@ -275,19 +277,20 @@ func ParseHPAMetrics(hpa *autoscalingv2beta1.HorizontalPodAutoscaler) ([]*Metric
|
||||
|
||||
var ref custom_metrics.ObjectReference
|
||||
switch metric.Type {
|
||||
case autoscalingv2beta1.PodsMetricSourceType:
|
||||
typeName.Name = metric.Pods.MetricName
|
||||
case autoscalingv2beta1.ObjectMetricSourceType:
|
||||
typeName.Name = metric.Object.MetricName
|
||||
case autoscalingv2beta2.PodsMetricSourceType:
|
||||
typeName.Name = metric.Pods.Metric.Name
|
||||
case autoscalingv2beta2.ObjectMetricSourceType:
|
||||
typeName.Name = metric.Object.Metric.Name
|
||||
typeName.MetricLabels = metric.Object.Metric.Selector
|
||||
ref = custom_metrics.ObjectReference{
|
||||
APIVersion: metric.Object.Target.APIVersion,
|
||||
Kind: metric.Object.Target.Kind,
|
||||
Name: metric.Object.Target.Name,
|
||||
APIVersion: metric.Object.DescribedObject.APIVersion,
|
||||
Kind: metric.Object.DescribedObject.Kind,
|
||||
Name: metric.Object.DescribedObject.Name,
|
||||
Namespace: hpa.Namespace,
|
||||
}
|
||||
case autoscalingv2beta1.ExternalMetricSourceType:
|
||||
typeName.Name = metric.External.MetricName
|
||||
case autoscalingv2beta1.ResourceMetricSourceType:
|
||||
case autoscalingv2beta2.ExternalMetricSourceType:
|
||||
typeName.Name = metric.External.Metric.Name
|
||||
case autoscalingv2beta2.ResourceMetricSourceType:
|
||||
continue // kube-metrics-adapter does not collect resource metrics
|
||||
}
|
||||
|
||||
@ -303,8 +306,8 @@ func ParseHPAMetrics(hpa *autoscalingv2beta1.HorizontalPodAutoscaler) ([]*Metric
|
||||
Config: map[string]string{},
|
||||
}
|
||||
|
||||
if metric.Type == autoscalingv2beta1.ExternalMetricSourceType {
|
||||
config.Labels = metric.External.MetricSelector.MatchLabels
|
||||
if metric.Type == autoscalingv2beta2.ExternalMetricSourceType {
|
||||
config.Labels = metric.External.Metric.Selector.MatchLabels
|
||||
}
|
||||
metricConfigs = append(metricConfigs, config)
|
||||
}
|
||||
|
@ -1,25 +1,30 @@
|
||||
package collector
|
||||
|
||||
import "time"
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
"time"
|
||||
)
|
||||
|
||||
// MaxCollector is a simple aggregator collector that returns the maximum value
|
||||
// of metrics from all collectors.
|
||||
type MaxCollector struct {
|
||||
type WeightedMaxCollector struct {
|
||||
collectors []Collector
|
||||
interval time.Duration
|
||||
weight float64
|
||||
}
|
||||
|
||||
// NewMaxCollector initializes a new MacCollector.
|
||||
func NewMaxCollector(interval time.Duration, collectors ...Collector) *MaxCollector {
|
||||
return &MaxCollector{
|
||||
func NewWeightedMaxCollector(interval time.Duration, weight float64, collectors ...Collector) *WeightedMaxCollector {
|
||||
return &WeightedMaxCollector{
|
||||
collectors: collectors,
|
||||
interval: interval,
|
||||
weight: weight,
|
||||
}
|
||||
}
|
||||
|
||||
// GetMetrics gets metrics from all collectors and return the higest value.
|
||||
func (c *MaxCollector) GetMetrics() ([]CollectedMetric, error) {
|
||||
var max CollectedMetric
|
||||
func (c *WeightedMaxCollector) GetMetrics() ([]CollectedMetric, error) {
|
||||
var max *CollectedMetric
|
||||
for _, collector := range c.collectors {
|
||||
values, err := collector.GetMetrics()
|
||||
if err != nil {
|
||||
@ -27,16 +32,22 @@ func (c *MaxCollector) GetMetrics() ([]CollectedMetric, error) {
|
||||
}
|
||||
|
||||
for _, value := range values {
|
||||
if value.Custom.Value.MilliValue() > max.Custom.Value.MilliValue() {
|
||||
max = value
|
||||
if max != nil {
|
||||
if value.Custom.Value.MilliValue() > max.Custom.Value.MilliValue() {
|
||||
max = &value
|
||||
}
|
||||
} else {
|
||||
max = &value
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return []CollectedMetric{max}, nil
|
||||
max.Custom.Value = *resource.NewMilliQuantity(int64(float64(max.Custom.Value.MilliValue())*c.weight), resource.DecimalSI)
|
||||
|
||||
return []CollectedMetric{*max}, nil
|
||||
}
|
||||
|
||||
// Interval returns the interval at which the collector should run.
|
||||
func (c *MaxCollector) Interval() time.Duration {
|
||||
func (c *WeightedMaxCollector) Interval() time.Duration {
|
||||
return c.interval
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import (
|
||||
"time"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
autoscalingv2beta1 "k8s.io/api/autoscaling/v2beta1"
|
||||
autoscalingv2beta2 "k8s.io/api/autoscaling/v2beta2"
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@ -24,7 +24,7 @@ func NewPodCollectorPlugin(client kubernetes.Interface) *PodCollectorPlugin {
|
||||
}
|
||||
}
|
||||
|
||||
func (p *PodCollectorPlugin) NewCollector(hpa *autoscalingv2beta1.HorizontalPodAutoscaler, config *MetricConfig, interval time.Duration) (Collector, error) {
|
||||
func (p *PodCollectorPlugin) NewCollector(hpa *autoscalingv2beta2.HorizontalPodAutoscaler, config *MetricConfig, interval time.Duration) (Collector, error) {
|
||||
return NewPodCollector(p.client, hpa, config, interval)
|
||||
}
|
||||
|
||||
@ -34,7 +34,7 @@ type PodCollector struct {
|
||||
podLabelSelector string
|
||||
namespace string
|
||||
metricName string
|
||||
metricType autoscalingv2beta1.MetricSourceType
|
||||
metricType autoscalingv2beta2.MetricSourceType
|
||||
interval time.Duration
|
||||
logger *log.Entry
|
||||
}
|
||||
@ -43,7 +43,7 @@ type PodMetricsGetter interface {
|
||||
GetMetric(pod *v1.Pod) (float64, error)
|
||||
}
|
||||
|
||||
func NewPodCollector(client kubernetes.Interface, hpa *autoscalingv2beta1.HorizontalPodAutoscaler, config *MetricConfig, interval time.Duration) (*PodCollector, error) {
|
||||
func NewPodCollector(client kubernetes.Interface, hpa *autoscalingv2beta2.HorizontalPodAutoscaler, config *MetricConfig, interval time.Duration) (*PodCollector, error) {
|
||||
// get pod selector based on HPA scale target ref
|
||||
selector, err := getPodLabelSelector(client, hpa)
|
||||
if err != nil {
|
||||
@ -106,9 +106,11 @@ func (c *PodCollector) GetMetrics() ([]CollectedMetric, error) {
|
||||
Name: pod.Name,
|
||||
Namespace: pod.Namespace,
|
||||
},
|
||||
MetricName: c.metricName,
|
||||
Timestamp: metav1.Time{Time: time.Now().UTC()},
|
||||
Value: *resource.NewMilliQuantity(int64(value*1000), resource.DecimalSI),
|
||||
Metric: custom_metrics.MetricIdentifier{
|
||||
Name: c.metricName,
|
||||
},
|
||||
Timestamp: metav1.Time{Time: time.Now().UTC()},
|
||||
Value: *resource.NewMilliQuantity(int64(value*1000), resource.DecimalSI),
|
||||
},
|
||||
Labels: pod.Labels,
|
||||
}
|
||||
@ -123,7 +125,7 @@ func (c *PodCollector) Interval() time.Duration {
|
||||
return c.interval
|
||||
}
|
||||
|
||||
func getPodLabelSelector(client kubernetes.Interface, hpa *autoscalingv2beta1.HorizontalPodAutoscaler) (string, error) {
|
||||
func getPodLabelSelector(client kubernetes.Interface, hpa *autoscalingv2beta2.HorizontalPodAutoscaler) (string, error) {
|
||||
switch hpa.Spec.ScaleTargetRef.Kind {
|
||||
case "Deployment":
|
||||
deployment, err := client.AppsV1().Deployments(hpa.Namespace).Get(hpa.Spec.ScaleTargetRef.Name, metav1.GetOptions{})
|
||||
|
@ -9,7 +9,7 @@ import (
|
||||
"github.com/prometheus/client_golang/api"
|
||||
promv1 "github.com/prometheus/client_golang/api/prometheus/v1"
|
||||
"github.com/prometheus/common/model"
|
||||
autoscalingv2beta1 "k8s.io/api/autoscaling/v2beta1"
|
||||
autoscalingv2beta2 "k8s.io/api/autoscaling/v2beta2"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
@ -38,7 +38,7 @@ func NewPrometheusCollectorPlugin(client kubernetes.Interface, prometheusServer
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (p *PrometheusCollectorPlugin) NewCollector(hpa *autoscalingv2beta1.HorizontalPodAutoscaler, config *MetricConfig, interval time.Duration) (Collector, error) {
|
||||
func (p *PrometheusCollectorPlugin) NewCollector(hpa *autoscalingv2beta2.HorizontalPodAutoscaler, config *MetricConfig, interval time.Duration) (Collector, error) {
|
||||
return NewPrometheusCollector(p.client, p.promAPI, hpa, config, interval)
|
||||
}
|
||||
|
||||
@ -47,14 +47,14 @@ type PrometheusCollector struct {
|
||||
promAPI promv1.API
|
||||
query string
|
||||
metricName string
|
||||
metricType autoscalingv2beta1.MetricSourceType
|
||||
metricType autoscalingv2beta2.MetricSourceType
|
||||
objectReference custom_metrics.ObjectReference
|
||||
interval time.Duration
|
||||
perReplica bool
|
||||
hpa *autoscalingv2beta1.HorizontalPodAutoscaler
|
||||
hpa *autoscalingv2beta2.HorizontalPodAutoscaler
|
||||
}
|
||||
|
||||
func NewPrometheusCollector(client kubernetes.Interface, promAPI promv1.API, hpa *autoscalingv2beta1.HorizontalPodAutoscaler, config *MetricConfig, interval time.Duration) (*PrometheusCollector, error) {
|
||||
func NewPrometheusCollector(client kubernetes.Interface, promAPI promv1.API, hpa *autoscalingv2beta2.HorizontalPodAutoscaler, config *MetricConfig, interval time.Duration) (*PrometheusCollector, error) {
|
||||
c := &PrometheusCollector{
|
||||
client: client,
|
||||
objectReference: config.ObjectReference,
|
||||
@ -117,9 +117,12 @@ func (c *PrometheusCollector) GetMetrics() ([]CollectedMetric, error) {
|
||||
Type: c.metricType,
|
||||
Custom: custom_metrics.MetricValue{
|
||||
DescribedObject: c.objectReference,
|
||||
MetricName: c.metricName,
|
||||
Timestamp: metav1.Time{Time: time.Now().UTC()},
|
||||
Value: *resource.NewMilliQuantity(int64(sampleValue*1000), resource.DecimalSI),
|
||||
Metric: custom_metrics.MetricIdentifier{
|
||||
Name: c.metricName,
|
||||
Selector: nil,
|
||||
},
|
||||
Timestamp: metav1.Time{Time: time.Now().UTC()},
|
||||
Value: *resource.NewMilliQuantity(int64(sampleValue*1000), resource.DecimalSI),
|
||||
},
|
||||
}
|
||||
|
||||
@ -129,3 +132,23 @@ func (c *PrometheusCollector) GetMetrics() ([]CollectedMetric, error) {
|
||||
func (c *PrometheusCollector) Interval() time.Duration {
|
||||
return c.interval
|
||||
}
|
||||
|
||||
func targetRefReplicas(client kubernetes.Interface, hpa *autoscalingv2beta2.HorizontalPodAutoscaler) (int32, error) {
|
||||
var replicas int32
|
||||
switch hpa.Spec.ScaleTargetRef.Kind {
|
||||
case "Deployment":
|
||||
deployment, err := client.AppsV1().Deployments(hpa.Namespace).Get(hpa.Spec.ScaleTargetRef.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
replicas = deployment.Status.Replicas
|
||||
case "StatefulSet":
|
||||
sts, err := client.AppsV1().StatefulSets(hpa.Namespace).Get(hpa.Spec.ScaleTargetRef.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
replicas = sts.Status.Replicas
|
||||
}
|
||||
|
||||
return replicas, nil
|
||||
}
|
||||
|
@ -1,20 +1,24 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
autoscalingv2beta1 "k8s.io/api/autoscaling/v2beta1"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
autoscalingv2beta2 "k8s.io/api/autoscaling/v2beta2"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/metrics/pkg/apis/custom_metrics"
|
||||
)
|
||||
|
||||
const (
|
||||
rpsQuery = `scalar(sum(rate(skipper_serve_host_duration_seconds_count{host="%s"}[1m])))`
|
||||
rpsMetricName = "requests-per-second"
|
||||
rpsQuery = `scalar(sum(rate(skipper_serve_host_duration_seconds_count{host="%s"}[1m])))`
|
||||
rpsMetricName = "requests-per-second"
|
||||
stackTrafficWeights = "zalando.org/stack-traffic-weights"
|
||||
backendWeights = "zalando.org/backend-weights"
|
||||
hostLabel = "backend"
|
||||
)
|
||||
|
||||
// SkipperCollectorPlugin is a collector plugin for initializing metrics
|
||||
@ -33,7 +37,7 @@ func NewSkipperCollectorPlugin(client kubernetes.Interface, prometheusPlugin *Pr
|
||||
}
|
||||
|
||||
// NewCollector initializes a new skipper collector from the specified HPA.
|
||||
func (c *SkipperCollectorPlugin) NewCollector(hpa *autoscalingv2beta1.HorizontalPodAutoscaler, config *MetricConfig, interval time.Duration) (Collector, error) {
|
||||
func (c *SkipperCollectorPlugin) NewCollector(hpa *autoscalingv2beta2.HorizontalPodAutoscaler, config *MetricConfig, interval time.Duration) (Collector, error) {
|
||||
switch config.Name {
|
||||
case rpsMetricName:
|
||||
return NewSkipperCollector(c.client, c.plugin, hpa, config, interval)
|
||||
@ -48,14 +52,16 @@ type SkipperCollector struct {
|
||||
client kubernetes.Interface
|
||||
metricName string
|
||||
objectReference custom_metrics.ObjectReference
|
||||
hpa *autoscalingv2beta1.HorizontalPodAutoscaler
|
||||
hpa *autoscalingv2beta2.HorizontalPodAutoscaler
|
||||
interval time.Duration
|
||||
plugin CollectorPlugin
|
||||
config MetricConfig
|
||||
}
|
||||
|
||||
// NewSkipperCollector initializes a new SkipperCollector.
|
||||
func NewSkipperCollector(client kubernetes.Interface, plugin CollectorPlugin, hpa *autoscalingv2beta1.HorizontalPodAutoscaler, config *MetricConfig, interval time.Duration) (*SkipperCollector, error) {
|
||||
func NewSkipperCollector(
|
||||
client kubernetes.Interface, plugin CollectorPlugin, hpa *autoscalingv2beta2.HorizontalPodAutoscaler,
|
||||
config *MetricConfig, interval time.Duration) (*SkipperCollector, error) {
|
||||
return &SkipperCollector{
|
||||
client: client,
|
||||
objectReference: config.ObjectReference,
|
||||
@ -67,13 +73,41 @@ func NewSkipperCollector(client kubernetes.Interface, plugin CollectorPlugin, hp
|
||||
}, nil
|
||||
}
|
||||
|
||||
func getAnnotationWeight(annotations map[string]string, backendName, annotation string) float64 {
|
||||
if weightAnnotation, ok := annotations[annotation]; ok {
|
||||
var stackWeights map[string]int
|
||||
err := json.Unmarshal([]byte(weightAnnotation), &stackWeights)
|
||||
if err == nil {
|
||||
if _, ok := stackWeights[backendName]; ok {
|
||||
return float64(stackWeights[backendName]) / 100
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0.0
|
||||
}
|
||||
|
||||
func getMaxWeights(annotations map[string]string, backendName string) float64 {
|
||||
stacksetWeight := getAnnotationWeight(annotations, backendName, stackTrafficWeights)
|
||||
backendWeight := getAnnotationWeight(annotations, backendName, backendWeights)
|
||||
if stacksetWeight == 0.0 && backendWeight == 0.0 {
|
||||
return 1.0
|
||||
}
|
||||
return math.Max(stacksetWeight, backendWeight)
|
||||
}
|
||||
|
||||
// getCollector returns a collector for getting the metrics.
|
||||
func (c *SkipperCollector) getCollector() (Collector, error) {
|
||||
ingress, err := c.client.ExtensionsV1beta1().Ingresses(c.objectReference.Namespace).Get(c.objectReference.Name, metav1.GetOptions{})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
backendWeight := 1.0
|
||||
if c.config.MetricLabels != nil {
|
||||
backendWeight = getMaxWeights(ingress.Annotations, c.config.MetricLabels.MatchLabels[hostLabel])
|
||||
}
|
||||
|
||||
config := c.config
|
||||
|
||||
var collector Collector
|
||||
@ -92,10 +126,8 @@ func (c *SkipperCollector) getCollector() (Collector, error) {
|
||||
|
||||
collectors = append(collectors, collector)
|
||||
}
|
||||
if len(collectors) > 1 {
|
||||
collector = NewMaxCollector(c.interval, collectors...)
|
||||
} else if len(collectors) == 1 {
|
||||
collector = collectors[0]
|
||||
if len(collectors) >= 1 {
|
||||
collector = NewWeightedMaxCollector(c.interval, backendWeight, collectors...)
|
||||
} else {
|
||||
return nil, fmt.Errorf("no hosts defined on ingress %s/%s, unable to create collector", c.objectReference.Namespace, c.objectReference.Name)
|
||||
}
|
||||
@ -118,24 +150,7 @@ func (c *SkipperCollector) GetMetrics() ([]CollectedMetric, error) {
|
||||
if len(values) != 1 {
|
||||
return nil, fmt.Errorf("expected to only get one metric value, got %d", len(values))
|
||||
}
|
||||
|
||||
// get current replicas for the targeted scale object. This is used to
|
||||
// calculate an average metric instead of total.
|
||||
// targetAverageValue will be available in Kubernetes v1.12
|
||||
// https://github.com/kubernetes/kubernetes/pull/64097
|
||||
replicas, err := targetRefReplicas(c.client, c.hpa)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if replicas < 1 {
|
||||
return nil, fmt.Errorf("unable to get average value for %d replicas", replicas)
|
||||
}
|
||||
|
||||
value := values[0]
|
||||
avgValue := float64(value.Custom.Value.MilliValue()) / float64(replicas)
|
||||
value.Custom.Value = *resource.NewMilliQuantity(int64(avgValue), resource.DecimalSI)
|
||||
|
||||
return []CollectedMetric{value}, nil
|
||||
}
|
||||
|
||||
@ -143,23 +158,3 @@ func (c *SkipperCollector) GetMetrics() ([]CollectedMetric, error) {
|
||||
func (c *SkipperCollector) Interval() time.Duration {
|
||||
return c.interval
|
||||
}
|
||||
|
||||
func targetRefReplicas(client kubernetes.Interface, hpa *autoscalingv2beta1.HorizontalPodAutoscaler) (int32, error) {
|
||||
var replicas int32
|
||||
switch hpa.Spec.ScaleTargetRef.Kind {
|
||||
case "Deployment":
|
||||
deployment, err := client.AppsV1().Deployments(hpa.Namespace).Get(hpa.Spec.ScaleTargetRef.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
replicas = deployment.Status.Replicas
|
||||
case "StatefulSet":
|
||||
sts, err := client.AppsV1().StatefulSets(hpa.Namespace).Get(hpa.Spec.ScaleTargetRef.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
replicas = sts.Status.Replicas
|
||||
}
|
||||
|
||||
return replicas, nil
|
||||
}
|
||||
|
@ -1,87 +1,167 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"k8s.io/api/apps/v1"
|
||||
autoscalingv2beta1 "k8s.io/api/autoscaling/v2beta1"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/stretchr/testify/assert"
|
||||
autoscalingv2beta2 "k8s.io/api/autoscaling/v2beta2"
|
||||
"k8s.io/api/extensions/v1beta1"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
"k8s.io/metrics/pkg/apis/custom_metrics"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestTargetRefReplicasDeployments(t *testing.T) {
|
||||
client := fake.NewSimpleClientset()
|
||||
name := "some-app"
|
||||
defaultNamespace := "default"
|
||||
deployment, err := newDeployment(client, defaultNamespace, name)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Create an HPA with the deployment as ref
|
||||
hpa, err := client.AutoscalingV2beta1().HorizontalPodAutoscalers(deployment.Namespace).
|
||||
Create(newHPA(defaultNamespace, name, "Deployment"))
|
||||
require.NoError(t, err)
|
||||
|
||||
replicas, err := targetRefReplicas(client, hpa)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, deployment.Status.Replicas, replicas)
|
||||
type testCollector struct {
|
||||
metrics []int
|
||||
interval time.Duration
|
||||
}
|
||||
|
||||
func TestTargetRefReplicasStatefulSets(t *testing.T) {
|
||||
client := fake.NewSimpleClientset()
|
||||
name := "some-app"
|
||||
defaultNamespace := "default"
|
||||
statefulSet, err := newStatefulSet(client, defaultNamespace, name)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Create an HPA with the statefulSet as ref
|
||||
hpa, err := client.AutoscalingV2beta1().HorizontalPodAutoscalers(statefulSet.Namespace).
|
||||
Create(newHPA(defaultNamespace, name, "StatefulSet"))
|
||||
require.NoError(t, err)
|
||||
|
||||
replicas, err := targetRefReplicas(client, hpa)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, statefulSet.Status.Replicas, replicas)
|
||||
}
|
||||
|
||||
func newHPA(namesapce string, refName string, refKind string) *autoscalingv2beta1.HorizontalPodAutoscaler {
|
||||
return &autoscalingv2beta1.HorizontalPodAutoscaler{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: namesapce,
|
||||
func (c testCollector) GetMetrics() ([]CollectedMetric, error) {
|
||||
return []CollectedMetric{
|
||||
{
|
||||
Custom: custom_metrics.MetricValue{Value: *resource.NewQuantity(1000, resource.DecimalSI)},
|
||||
},
|
||||
Spec: autoscalingv2beta1.HorizontalPodAutoscalerSpec{
|
||||
ScaleTargetRef: autoscalingv2beta1.CrossVersionObjectReference{
|
||||
Name: refName,
|
||||
Kind: refKind,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c testCollector) Interval() time.Duration {
|
||||
return c.interval
|
||||
}
|
||||
|
||||
type testCollectorPlugin struct {
|
||||
metrics []int
|
||||
}
|
||||
|
||||
func (c testCollectorPlugin) NewCollector(hpa *autoscalingv2beta2.HorizontalPodAutoscaler, config *MetricConfig, interval time.Duration) (Collector, error) {
|
||||
return &testCollector{interval: interval, metrics: c.metrics}, nil
|
||||
}
|
||||
|
||||
func makeTestCollectorPlugin(metrics []int) *testCollectorPlugin {
|
||||
return &testCollectorPlugin{metrics: metrics}
|
||||
}
|
||||
|
||||
func makeHpa(ingressName string) *autoscalingv2beta2.HorizontalPodAutoscaler {
|
||||
return &autoscalingv2beta2.HorizontalPodAutoscaler{
|
||||
Spec: autoscalingv2beta2.HorizontalPodAutoscalerSpec{
|
||||
Metrics: []autoscalingv2beta2.MetricSpec{
|
||||
{
|
||||
Type: autoscalingv2beta2.ObjectMetricSourceType,
|
||||
Object: &autoscalingv2beta2.ObjectMetricSource{
|
||||
DescribedObject: autoscalingv2beta2.CrossVersionObjectReference{
|
||||
Kind: "Ingress",
|
||||
APIVersion: "extensions/v1",
|
||||
Name: ingressName,
|
||||
},
|
||||
Metric: autoscalingv2beta2.MetricIdentifier{
|
||||
Name: rpsMetricName,
|
||||
},
|
||||
Target: autoscalingv2beta2.MetricTarget{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Status: autoscalingv2beta1.HorizontalPodAutoscalerStatus{},
|
||||
}
|
||||
}
|
||||
|
||||
func newDeployment(client *fake.Clientset, namespace string, name string) (*v1.Deployment, error) {
|
||||
return client.AppsV1().Deployments(namespace).Create(&v1.Deployment{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: namespace,
|
||||
func makeMetricConfig(ingressName, backend string) *MetricConfig {
|
||||
selector, _ := metav1.ParseToLabelSelector(fmt.Sprintf("%s=%s", hostLabel, backend))
|
||||
return &MetricConfig{
|
||||
ObjectReference: custom_metrics.ObjectReference{Kind: "Ingress", Namespace: "default", Name: ingressName},
|
||||
MetricTypeName: MetricTypeName{
|
||||
Name: rpsMetricName,
|
||||
MetricLabels: selector,
|
||||
},
|
||||
Spec: v1.DeploymentSpec{},
|
||||
Status: v1.DeploymentStatus{
|
||||
ReadyReplicas: 1,
|
||||
Replicas: 2,
|
||||
}
|
||||
}
|
||||
|
||||
func makeIngress(client *fake.Clientset, ingressName string, bWeights, sWeights map[string]int) {
|
||||
backendWeightAnno, _ := json.Marshal(bWeights)
|
||||
stacksetWeightAnno, _ := json.Marshal(sWeights)
|
||||
client.Extensions().Ingresses("default").Create(&v1beta1.Ingress{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: ingressName,
|
||||
Annotations: map[string]string{
|
||||
stackTrafficWeights: string(stacksetWeightAnno),
|
||||
backendWeights: string(backendWeightAnno),
|
||||
},
|
||||
},
|
||||
Spec: v1beta1.IngressSpec{
|
||||
Rules: []v1beta1.IngressRule{
|
||||
{
|
||||
Host: "dummy.example.com",
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func newStatefulSet(client *fake.Clientset, namespace string, name string) (*v1.StatefulSet, error) {
|
||||
return client.AppsV1().StatefulSets(namespace).Create(&v1.StatefulSet{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: namespace,
|
||||
func TestNewSkipperCollectorSimple(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
bWeights map[string]int
|
||||
sWeights map[string]int
|
||||
metrics []int
|
||||
msg string
|
||||
ingressName string
|
||||
backend string
|
||||
expectedMetric int
|
||||
}{
|
||||
{
|
||||
msg: "backend without weights",
|
||||
sWeights: map[string]int{"another-backend": 60},
|
||||
bWeights: map[string]int{"another-backend": 60},
|
||||
ingressName: "dummy-ingress",
|
||||
backend: "dummy-backend",
|
||||
metrics: []int{1000},
|
||||
expectedMetric: 1000,
|
||||
},
|
||||
Status: v1.StatefulSetStatus{
|
||||
ReadyReplicas: 1,
|
||||
Replicas: 2,
|
||||
{
|
||||
msg: "weighted backed",
|
||||
sWeights: map[string]int{"dummy-backend": 60},
|
||||
bWeights: map[string]int{"dummy-backend": 60},
|
||||
ingressName: "dummy-ingress",
|
||||
backend: "dummy-backend",
|
||||
metrics: []int{1000},
|
||||
expectedMetric: 600,
|
||||
},
|
||||
})
|
||||
{
|
||||
msg: "missing weights annotation",
|
||||
ingressName: "dummy-ingress",
|
||||
backend: "dummy-backend",
|
||||
metrics: []int{1000},
|
||||
expectedMetric: 1000,
|
||||
},
|
||||
{
|
||||
msg: "missing stackset weights annotation",
|
||||
bWeights: map[string]int{"dummy-backend": 40},
|
||||
ingressName: "dummy-ingress",
|
||||
backend: "dummy-backend",
|
||||
metrics: []int{1000},
|
||||
expectedMetric: 400,
|
||||
},
|
||||
{
|
||||
msg: "missing backend weights annotation",
|
||||
sWeights: map[string]int{"dummy-backend": 100},
|
||||
ingressName: "dummy-ingress",
|
||||
backend: "dummy-backend",
|
||||
metrics: []int{1000},
|
||||
expectedMetric: 1000,
|
||||
},
|
||||
} {
|
||||
t.Run(tc.msg, func(tt *testing.T) {
|
||||
client := fake.NewSimpleClientset()
|
||||
makeIngress(client, tc.ingressName, tc.bWeights, tc.sWeights)
|
||||
plugin := makeTestCollectorPlugin(tc.metrics)
|
||||
hpa := makeHpa(tc.ingressName)
|
||||
config := makeMetricConfig(tc.ingressName, tc.backend)
|
||||
collector, err := NewSkipperCollector(client, plugin, hpa, config, time.Minute)
|
||||
assert.NoError(t, err, "failed to create skipper collector: %v", err)
|
||||
collectedMetrics, err := collector.GetMetrics()
|
||||
assert.NoError(t, err, "failed to get metrics from collector: %v", err)
|
||||
assert.Len(t, collectedMetrics, len(tc.metrics), "number of metrics returned is not %d", len(tc.metrics))
|
||||
assert.EqualValues(t, collectedMetrics[0].Custom.Value.Value(), tc.expectedMetric, "the collected metric is not 1000")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/zalando-incubator/kube-metrics-adapter/pkg/zmon"
|
||||
autoscalingv2beta1 "k8s.io/api/autoscaling/v2beta1"
|
||||
autoscalingv2beta2 "k8s.io/api/autoscaling/v2beta2"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/metrics/pkg/apis/external_metrics"
|
||||
@ -41,7 +41,7 @@ func NewZMONCollectorPlugin(zmon zmon.ZMON) (*ZMONCollectorPlugin, error) {
|
||||
}
|
||||
|
||||
// NewCollector initializes a new ZMON collector from the specified HPA.
|
||||
func (c *ZMONCollectorPlugin) NewCollector(hpa *autoscalingv2beta1.HorizontalPodAutoscaler, config *MetricConfig, interval time.Duration) (Collector, error) {
|
||||
func (c *ZMONCollectorPlugin) NewCollector(hpa *autoscalingv2beta2.HorizontalPodAutoscaler, config *MetricConfig, interval time.Duration) (Collector, error) {
|
||||
switch config.Name {
|
||||
case ZMONCheckMetric:
|
||||
annotations := map[string]string{}
|
||||
@ -65,7 +65,7 @@ type ZMONCollector struct {
|
||||
duration time.Duration
|
||||
aggregators []string
|
||||
metricName string
|
||||
metricType autoscalingv2beta1.MetricSourceType
|
||||
metricType autoscalingv2beta2.MetricSourceType
|
||||
}
|
||||
|
||||
// NewZMONCollector initializes a new ZMONCollector.
|
||||
|
@ -6,7 +6,7 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/zalando-incubator/kube-metrics-adapter/pkg/zmon"
|
||||
autoscalingv2beta1 "k8s.io/api/autoscaling/v2beta1"
|
||||
autoscalingv2beta2 "k8s.io/api/autoscaling/v2beta2"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/metrics/pkg/apis/external_metrics"
|
||||
@ -37,7 +37,7 @@ func TestZMONCollectorNewCollector(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
hpa := &autoscalingv2beta1.HorizontalPodAutoscaler{}
|
||||
hpa := &autoscalingv2beta2.HorizontalPodAutoscaler{}
|
||||
|
||||
collector, err := collectPlugin.NewCollector(hpa, config, 1*time.Second)
|
||||
require.NoError(t, err)
|
||||
|
@ -12,7 +12,7 @@ import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/zalando-incubator/kube-metrics-adapter/pkg/collector"
|
||||
"github.com/zalando-incubator/kube-metrics-adapter/pkg/recorder"
|
||||
autoscalingv2beta1 "k8s.io/api/autoscaling/v2beta1"
|
||||
autoscalingv2beta2 "k8s.io/api/autoscaling/v2beta2"
|
||||
apiv1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
@ -47,7 +47,7 @@ var (
|
||||
)
|
||||
|
||||
type objectCollector struct {
|
||||
ObjectReference *autoscalingv2beta1.CrossVersionObjectReference
|
||||
ObjectReference *autoscalingv2beta2.CrossVersionObjectReference
|
||||
}
|
||||
|
||||
// HPAProvider is a base provider for initializing metric collectors based on
|
||||
@ -58,7 +58,7 @@ type HPAProvider struct {
|
||||
collectorScheduler *CollectorScheduler
|
||||
collectorInterval time.Duration
|
||||
metricSink chan metricCollection
|
||||
hpaCache map[resourceReference]autoscalingv2beta1.HorizontalPodAutoscaler
|
||||
hpaCache map[resourceReference]autoscalingv2beta2.HorizontalPodAutoscaler
|
||||
metricStore *MetricStore
|
||||
collectorFactory *collector.CollectorFactory
|
||||
recorder kube_record.EventRecorder
|
||||
@ -120,12 +120,12 @@ func (p *HPAProvider) Run(ctx context.Context) {
|
||||
func (p *HPAProvider) updateHPAs() error {
|
||||
p.logger.Info("Looking for HPAs")
|
||||
|
||||
hpas, err := p.client.AutoscalingV2beta1().HorizontalPodAutoscalers(metav1.NamespaceAll).List(metav1.ListOptions{})
|
||||
hpas, err := p.client.AutoscalingV2beta2().HorizontalPodAutoscalers(metav1.NamespaceAll).List(metav1.ListOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
newHPACache := make(map[resourceReference]autoscalingv2beta1.HorizontalPodAutoscaler, len(hpas.Items))
|
||||
newHPACache := make(map[resourceReference]autoscalingv2beta2.HorizontalPodAutoscaler, len(hpas.Items))
|
||||
|
||||
newHPAs := 0
|
||||
|
||||
@ -187,7 +187,7 @@ func (p *HPAProvider) updateHPAs() error {
|
||||
}
|
||||
|
||||
// equalHPA returns true if two HPAs are identical (apart from their status).
|
||||
func equalHPA(a, b autoscalingv2beta1.HorizontalPodAutoscaler) bool {
|
||||
func equalHPA(a, b autoscalingv2beta2.HorizontalPodAutoscaler) bool {
|
||||
// reset resource version to not compare it since this will change
|
||||
// whenever the status of the object is updated. We only want to
|
||||
// compare the metadata and the spec.
|
||||
@ -225,15 +225,15 @@ func (p *HPAProvider) collectMetrics(ctx context.Context) {
|
||||
p.logger.Infof("Collected %d new metric(s)", len(collection.Values))
|
||||
for _, value := range collection.Values {
|
||||
switch value.Type {
|
||||
case autoscalingv2beta1.ObjectMetricSourceType, autoscalingv2beta1.PodsMetricSourceType:
|
||||
case autoscalingv2beta2.ObjectMetricSourceType, autoscalingv2beta2.PodsMetricSourceType:
|
||||
p.logger.Infof("Collected new custom metric '%s' (%s) for %s %s/%s",
|
||||
value.Custom.MetricName,
|
||||
value.Custom.Metric.Name,
|
||||
value.Custom.Value.String(),
|
||||
value.Custom.DescribedObject.Kind,
|
||||
value.Custom.DescribedObject.Namespace,
|
||||
value.Custom.DescribedObject.Name,
|
||||
)
|
||||
case autoscalingv2beta1.ExternalMetricSourceType:
|
||||
case autoscalingv2beta2.ExternalMetricSourceType:
|
||||
p.logger.Infof("Collected new external metric '%s' (%s) [%s]",
|
||||
value.External.MetricName,
|
||||
value.External.Value.String(),
|
||||
|
@ -2,6 +2,7 @@ package provider
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/sirupsen/logrus"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
@ -9,7 +10,7 @@ import (
|
||||
|
||||
"github.com/kubernetes-incubator/custom-metrics-apiserver/pkg/provider"
|
||||
"github.com/zalando-incubator/kube-metrics-adapter/pkg/collector"
|
||||
autoscalingv2beta1 "k8s.io/api/autoscaling/v2beta1"
|
||||
autoscalingv2beta2 "k8s.io/api/autoscaling/v2beta2"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
@ -50,10 +51,12 @@ func NewMetricStore(ttlCalculator func() time.Time) *MetricStore {
|
||||
// Insert inserts a collected metric into the metric customMetricsStore.
|
||||
func (s *MetricStore) Insert(value collector.CollectedMetric) {
|
||||
switch value.Type {
|
||||
case autoscalingv2beta1.ObjectMetricSourceType, autoscalingv2beta1.PodsMetricSourceType:
|
||||
case autoscalingv2beta2.ObjectMetricSourceType, autoscalingv2beta2.PodsMetricSourceType:
|
||||
s.insertCustomMetric(value.Custom, value.Labels)
|
||||
case autoscalingv2beta1.ExternalMetricSourceType:
|
||||
case autoscalingv2beta2.ExternalMetricSourceType:
|
||||
s.insertExternalMetric(value.External)
|
||||
default:
|
||||
logrus.Errorf("value type unknown: %v", value.Type)
|
||||
}
|
||||
}
|
||||
|
||||
@ -82,10 +85,10 @@ func (s *MetricStore) insertCustomMetric(value custom_metrics.MetricValue, label
|
||||
TTL: s.metricsTTLCalculator(), // TODO: make TTL configurable
|
||||
}
|
||||
|
||||
metrics, ok := s.customMetricsStore[value.MetricName]
|
||||
metrics, ok := s.customMetricsStore[value.Metric.Name]
|
||||
if !ok {
|
||||
s.customMetricsStore[value.MetricName] = map[schema.GroupResource]map[string]map[string]customMetricsStoredMetric{
|
||||
groupResource: map[string]map[string]customMetricsStoredMetric{
|
||||
s.customMetricsStore[value.Metric.Name] = map[schema.GroupResource]map[string]map[string]customMetricsStoredMetric{
|
||||
groupResource: {
|
||||
value.DescribedObject.Namespace: map[string]customMetricsStoredMetric{
|
||||
value.DescribedObject.Name: metric,
|
||||
},
|
||||
@ -97,7 +100,7 @@ func (s *MetricStore) insertCustomMetric(value custom_metrics.MetricValue, label
|
||||
group, ok := metrics[groupResource]
|
||||
if !ok {
|
||||
metrics[groupResource] = map[string]map[string]customMetricsStoredMetric{
|
||||
value.DescribedObject.Namespace: map[string]customMetricsStoredMetric{
|
||||
value.DescribedObject.Namespace: {
|
||||
value.DescribedObject.Name: metric,
|
||||
},
|
||||
}
|
||||
@ -113,6 +116,7 @@ func (s *MetricStore) insertCustomMetric(value custom_metrics.MetricValue, label
|
||||
}
|
||||
|
||||
namespace[value.DescribedObject.Name] = metric
|
||||
|
||||
}
|
||||
|
||||
// insertExternalMetric inserts an external metric into the store.
|
||||
|
@ -4,7 +4,7 @@ import (
|
||||
"github.com/kubernetes-incubator/custom-metrics-apiserver/pkg/provider"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/zalando-incubator/kube-metrics-adapter/pkg/collector"
|
||||
"k8s.io/api/autoscaling/v2beta1"
|
||||
"k8s.io/api/autoscaling/v2beta2"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
@ -33,10 +33,10 @@ func TestInternalMetricStorage(t *testing.T) {
|
||||
{
|
||||
test: "insert/list/get a namespaced resource metric",
|
||||
insert: collector.CollectedMetric{
|
||||
Type: v2beta1.MetricSourceType("Object"),
|
||||
Type: v2beta2.MetricSourceType("Object"),
|
||||
Custom: custom_metrics.MetricValue{
|
||||
MetricName: "metric-per-unit",
|
||||
Value: *resource.NewQuantity(0, ""),
|
||||
Metric: custom_metrics.MetricIdentifier{Name: "metric-per-unit"},
|
||||
Value: *resource.NewQuantity(0, ""),
|
||||
DescribedObject: custom_metrics.ObjectReference{
|
||||
Name: "metricObject",
|
||||
Namespace: "default",
|
||||
@ -80,10 +80,10 @@ func TestInternalMetricStorage(t *testing.T) {
|
||||
{
|
||||
test: "insert/list/get a Pod metric",
|
||||
insert: collector.CollectedMetric{
|
||||
Type: v2beta1.MetricSourceType("Object"),
|
||||
Type: v2beta2.MetricSourceType("Object"),
|
||||
Custom: custom_metrics.MetricValue{
|
||||
MetricName: "metric-per-unit",
|
||||
Value: *resource.NewQuantity(0, ""),
|
||||
Metric: custom_metrics.MetricIdentifier{Name: "metric-per-unit"},
|
||||
Value: *resource.NewQuantity(0, ""),
|
||||
DescribedObject: custom_metrics.ObjectReference{
|
||||
Name: "metricObject",
|
||||
Namespace: "default",
|
||||
@ -136,10 +136,10 @@ func TestInternalMetricStorage(t *testing.T) {
|
||||
{
|
||||
test: "insert/list/get a non-namespaced resource metric",
|
||||
insert: collector.CollectedMetric{
|
||||
Type: v2beta1.MetricSourceType("Object"),
|
||||
Type: v2beta2.MetricSourceType("Object"),
|
||||
Custom: custom_metrics.MetricValue{
|
||||
MetricName: "metric-per-unit",
|
||||
Value: *resource.NewQuantity(0, ""),
|
||||
Metric: custom_metrics.MetricIdentifier{Name: "metric-per-unit"},
|
||||
Value: *resource.NewQuantity(0, ""),
|
||||
DescribedObject: custom_metrics.ObjectReference{
|
||||
Name: "metricObject",
|
||||
Kind: "Node",
|
||||
@ -182,10 +182,10 @@ func TestInternalMetricStorage(t *testing.T) {
|
||||
{
|
||||
test: "insert/list/get an Ingress metric",
|
||||
insert: collector.CollectedMetric{
|
||||
Type: v2beta1.MetricSourceType("Object"),
|
||||
Type: v2beta2.MetricSourceType("Object"),
|
||||
Custom: custom_metrics.MetricValue{
|
||||
MetricName: "metric-per-unit",
|
||||
Value: *resource.NewQuantity(0, ""),
|
||||
Metric: custom_metrics.MetricIdentifier{Name: "metric-per-unit"},
|
||||
Value: *resource.NewQuantity(0, ""),
|
||||
DescribedObject: custom_metrics.ObjectReference{
|
||||
Name: "metricObject",
|
||||
Kind: "Ingress",
|
||||
@ -286,10 +286,10 @@ func TestMultipleMetricValues(t *testing.T) {
|
||||
test: "insert/list/get multiple Ingress metrics",
|
||||
insert: []collector.CollectedMetric{
|
||||
{
|
||||
Type: v2beta1.MetricSourceType("Object"),
|
||||
Type: v2beta2.MetricSourceType("Object"),
|
||||
Custom: custom_metrics.MetricValue{
|
||||
MetricName: "metric-per-unit",
|
||||
Value: *resource.NewQuantity(0, ""),
|
||||
Metric: custom_metrics.MetricIdentifier{Name: "metric-per-unit"},
|
||||
Value: *resource.NewQuantity(0, ""),
|
||||
DescribedObject: custom_metrics.ObjectReference{
|
||||
Name: "metricObject",
|
||||
Kind: "Ingress",
|
||||
@ -298,10 +298,10 @@ func TestMultipleMetricValues(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
Type: v2beta1.MetricSourceType("Object"),
|
||||
Type: v2beta2.MetricSourceType("Object"),
|
||||
Custom: custom_metrics.MetricValue{
|
||||
MetricName: "metric-per-unit",
|
||||
Value: *resource.NewQuantity(1, ""),
|
||||
Metric: custom_metrics.MetricIdentifier{Name: "metric-per-unit"},
|
||||
Value: *resource.NewQuantity(1, ""),
|
||||
DescribedObject: custom_metrics.ObjectReference{
|
||||
Name: "metricObject",
|
||||
Kind: "Ingress",
|
||||
@ -355,10 +355,10 @@ func TestMultipleMetricValues(t *testing.T) {
|
||||
test: "insert/list/get multiple namespaced resource metrics",
|
||||
insert: []collector.CollectedMetric{
|
||||
{
|
||||
Type: v2beta1.MetricSourceType("Object"),
|
||||
Type: v2beta2.MetricSourceType("Object"),
|
||||
Custom: custom_metrics.MetricValue{
|
||||
MetricName: "metric-per-unit",
|
||||
Value: *resource.NewQuantity(0, ""),
|
||||
Metric: custom_metrics.MetricIdentifier{Name: "metric-per-unit"},
|
||||
Value: *resource.NewQuantity(0, ""),
|
||||
DescribedObject: custom_metrics.ObjectReference{
|
||||
Name: "metricObject",
|
||||
Namespace: "default",
|
||||
@ -368,10 +368,10 @@ func TestMultipleMetricValues(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
Type: v2beta1.MetricSourceType("Object"),
|
||||
Type: v2beta2.MetricSourceType("Object"),
|
||||
Custom: custom_metrics.MetricValue{
|
||||
MetricName: "metric-per-unit",
|
||||
Value: *resource.NewQuantity(1, ""),
|
||||
Metric: custom_metrics.MetricIdentifier{Name: "metric-per-unit"},
|
||||
Value: *resource.NewQuantity(1, ""),
|
||||
DescribedObject: custom_metrics.ObjectReference{
|
||||
Name: "metricObject",
|
||||
Namespace: "default",
|
||||
@ -489,10 +489,10 @@ func TestCustomMetricsStorageErrors(t *testing.T) {
|
||||
{
|
||||
test: "test that not all Kinds are mapped to a group/resource",
|
||||
insert: collector.CollectedMetric{
|
||||
Type: v2beta1.MetricSourceType("Object"),
|
||||
Type: v2beta2.MetricSourceType("Object"),
|
||||
Custom: custom_metrics.MetricValue{
|
||||
MetricName: "metric-per-unit",
|
||||
Value: *resource.NewQuantity(0, ""),
|
||||
Metric: custom_metrics.MetricIdentifier{Name: "metric-per-unit"},
|
||||
Value: *resource.NewQuantity(0, ""),
|
||||
DescribedObject: custom_metrics.ObjectReference{
|
||||
Name: "metricObject",
|
||||
Namespace: "default",
|
||||
@ -581,10 +581,10 @@ func TestCustomMetricsStorageErrors(t *testing.T) {
|
||||
test: "insert/list/get multiple metrics in different groups",
|
||||
insert: []collector.CollectedMetric{
|
||||
{
|
||||
Type: v2beta1.MetricSourceType("Object"),
|
||||
Type: v2beta2.MetricSourceType("Object"),
|
||||
Custom: custom_metrics.MetricValue{
|
||||
MetricName: "metric-per-unit",
|
||||
Value: *resource.NewQuantity(0, ""),
|
||||
Metric: custom_metrics.MetricIdentifier{Name: "metric-per-unit"},
|
||||
Value: *resource.NewQuantity(0, ""),
|
||||
DescribedObject: custom_metrics.ObjectReference{
|
||||
Name: "metricObject",
|
||||
Namespace: "default",
|
||||
@ -594,10 +594,10 @@ func TestCustomMetricsStorageErrors(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
Type: v2beta1.MetricSourceType("Object"),
|
||||
Type: v2beta2.MetricSourceType("Object"),
|
||||
Custom: custom_metrics.MetricValue{
|
||||
MetricName: "metric-per-unit",
|
||||
Value: *resource.NewQuantity(1, ""),
|
||||
Metric: custom_metrics.MetricIdentifier{Name: "metric-per-unit"},
|
||||
Value: *resource.NewQuantity(1, ""),
|
||||
DescribedObject: custom_metrics.ObjectReference{
|
||||
Name: "metricObject",
|
||||
Namespace: "default",
|
||||
@ -607,10 +607,10 @@ func TestCustomMetricsStorageErrors(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
Type: v2beta1.MetricSourceType("Object"),
|
||||
Type: v2beta2.MetricSourceType("Object"),
|
||||
Custom: custom_metrics.MetricValue{
|
||||
MetricName: "metric-per-unit",
|
||||
Value: *resource.NewQuantity(1, ""),
|
||||
Metric: custom_metrics.MetricIdentifier{Name: "metric-per-unit"},
|
||||
Value: *resource.NewQuantity(1, ""),
|
||||
DescribedObject: custom_metrics.ObjectReference{
|
||||
Name: "metricObject",
|
||||
Namespace: "new-namespace",
|
||||
@ -684,7 +684,7 @@ func TestExternalMetricStorage(t *testing.T) {
|
||||
{
|
||||
test: "insert/list/get an external metric",
|
||||
insert: collector.CollectedMetric{
|
||||
Type: v2beta1.MetricSourceType("External"),
|
||||
Type: v2beta2.MetricSourceType("External"),
|
||||
External: external_metrics.ExternalMetricValue{
|
||||
MetricName: "metric-per-unit",
|
||||
Value: *resource.NewQuantity(0, ""),
|
||||
@ -744,7 +744,7 @@ func TestMultipleExternalMetricStorage(t *testing.T) {
|
||||
test: "the latest value overrides the last one",
|
||||
insert: []collector.CollectedMetric{
|
||||
{
|
||||
Type: v2beta1.MetricSourceType("External"),
|
||||
Type: v2beta2.MetricSourceType("External"),
|
||||
External: external_metrics.ExternalMetricValue{
|
||||
MetricName: "metric-per-unit",
|
||||
Value: *resource.NewQuantity(0, ""),
|
||||
@ -752,7 +752,7 @@ func TestMultipleExternalMetricStorage(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
Type: v2beta1.MetricSourceType("External"),
|
||||
Type: v2beta2.MetricSourceType("External"),
|
||||
External: external_metrics.ExternalMetricValue{
|
||||
MetricName: "metric-per-unit",
|
||||
Value: *resource.NewQuantity(1, ""),
|
||||
@ -808,10 +808,12 @@ func TestMetricsExpiration(t *testing.T) {
|
||||
})
|
||||
|
||||
customMetric := collector.CollectedMetric{
|
||||
Type: v2beta1.MetricSourceType("Object"),
|
||||
Type: v2beta2.MetricSourceType("Object"),
|
||||
Custom: custom_metrics.MetricValue{
|
||||
MetricName: "metric-per-unit",
|
||||
Value: *resource.NewQuantity(0, ""),
|
||||
Metric: custom_metrics.MetricIdentifier{
|
||||
Name: "metric-per-unit",
|
||||
},
|
||||
Value: *resource.NewQuantity(0, ""),
|
||||
DescribedObject: custom_metrics.ObjectReference{
|
||||
Name: "metricObject",
|
||||
Kind: "Node",
|
||||
@ -821,7 +823,7 @@ func TestMetricsExpiration(t *testing.T) {
|
||||
}
|
||||
|
||||
externalMetric := collector.CollectedMetric{
|
||||
Type: v2beta1.MetricSourceType("External"),
|
||||
Type: v2beta2.MetricSourceType("External"),
|
||||
External: external_metrics.ExternalMetricValue{
|
||||
MetricName: "metric-per-unit",
|
||||
Value: *resource.NewQuantity(0, ""),
|
||||
@ -847,10 +849,12 @@ func TestMetricsNonExpiration(t *testing.T) {
|
||||
})
|
||||
|
||||
customMetric := collector.CollectedMetric{
|
||||
Type: v2beta1.MetricSourceType("Object"),
|
||||
Type: v2beta2.MetricSourceType("Object"),
|
||||
Custom: custom_metrics.MetricValue{
|
||||
MetricName: "metric-per-unit",
|
||||
Value: *resource.NewQuantity(0, ""),
|
||||
Metric: custom_metrics.MetricIdentifier{
|
||||
Name: "metric-per-unit",
|
||||
},
|
||||
Value: *resource.NewQuantity(0, ""),
|
||||
DescribedObject: custom_metrics.ObjectReference{
|
||||
Name: "metricObject",
|
||||
Kind: "Node",
|
||||
@ -860,7 +864,7 @@ func TestMetricsNonExpiration(t *testing.T) {
|
||||
}
|
||||
|
||||
externalMetric := collector.CollectedMetric{
|
||||
Type: v2beta1.MetricSourceType("External"),
|
||||
Type: v2beta2.MetricSourceType("External"),
|
||||
External: external_metrics.ExternalMetricValue{
|
||||
MetricName: "metric-per-unit",
|
||||
Value: *resource.NewQuantity(0, ""),
|
||||
|
Reference in New Issue
Block a user