derailed 2020-11-05 17:15:50 -07:00
parent 98082eefab
commit b6c61600a4
8 changed files with 42 additions and 30 deletions

View File

@ -53,7 +53,7 @@ func init() {
if err := flags.Set("stderrthreshold", "fatal"); err != nil { if err := flags.Set("stderrthreshold", "fatal"); err != nil {
panic(err) panic(err)
} }
if err := flags.Set("v", "-1"); err != nil { if err := flags.Set("v", "0"); err != nil {
panic(err) panic(err)
} }
if err := flags.Set("log_file", config.K9sLogs); err != nil { if err := flags.Set("log_file", config.K9sLogs); err != nil {

View File

@ -27,6 +27,7 @@ const (
cacheSize = 100 cacheSize = 100
cacheExpiry = 5 * time.Minute cacheExpiry = 5 * time.Minute
cacheMXAPIKey = "metricsAPI" cacheMXAPIKey = "metricsAPI"
serverVersion = "serverVersion"
) )
var supportedMetricsAPIVersions = []string{"v1beta1"} var supportedMetricsAPIVersions = []string{"v1beta1"}
@ -58,14 +59,18 @@ func InitConnection(config *Config) (*APIClient, error) {
a := APIClient{ a := APIClient{
config: config, config: config,
cache: cache.NewLRUExpireCache(cacheSize), cache: cache.NewLRUExpireCache(cacheSize),
connOK: true,
} }
a.connOK = true err := a.supportsMetricsResources()
if err := a.supportsMetricsResources(); err != nil { if err != nil {
a.connOK = false log.Error().Err(err).Msgf("Checking metrics-server")
return nil, err
} }
if errors.Is(err, noMetricServerErr) || errors.Is(err, metricsUnsupportedErr) {
return &a, nil
}
a.connOK = false
return &a, nil return &a, err
} }
// ConnectionOK returns connection status. // ConnectionOK returns connection status.
@ -178,8 +183,6 @@ func (a *APIClient) CurrentNamespaceName() (string, error) {
return a.config.CurrentNamespaceName() return a.config.CurrentNamespaceName()
} }
const serverVersion = "serverVersion"
// ServerVersion returns the current server version info. // ServerVersion returns the current server version info.
func (a *APIClient) ServerVersion() (*version.Info, error) { func (a *APIClient) ServerVersion() (*version.Info, error) {
if v, ok := a.cache.Get(serverVersion); ok { if v, ok := a.cache.Get(serverVersion); ok {
@ -273,10 +276,8 @@ func (a *APIClient) Config() *Config {
// HasMetrics checks if the cluster supports metrics. // HasMetrics checks if the cluster supports metrics.
func (a *APIClient) HasMetrics() bool { func (a *APIClient) HasMetrics() bool {
if err := a.supportsMetricsResources(); err != nil { err := a.supportsMetricsResources()
return false return err == nil
}
return true
} }
// Dial returns a handle to api server or die. // Dial returns a handle to api server or die.
@ -416,7 +417,7 @@ func (a *APIClient) supportsMetricsResources() error {
if supported { if supported {
return nil return nil
} }
return errors.New("No metrics-server detected") return noMetricServerErr
} }
defer func() { defer func() {
@ -430,7 +431,7 @@ func (a *APIClient) supportsMetricsResources() error {
} }
apiGroups, err := dial.ServerGroups() apiGroups, err := dial.ServerGroups()
if err != nil { if err != nil {
log.Warn().Err(err).Msgf("Unable to retrieve server groups") log.Warn().Err(err).Msgf("Unable to fetch APIGroups")
return err return err
} }
for _, grp := range apiGroups.Groups { for _, grp := range apiGroups.Groups {
@ -443,7 +444,7 @@ func (a *APIClient) supportsMetricsResources() error {
} }
} }
return errors.New("No metrics-server detected") return metricsUnsupportedErr
} }
func checkMetricsVersion(grp metav1.APIGroup) bool { func checkMetricsVersion(grp metav1.APIGroup) bool {

14
internal/client/errors.go Normal file
View File

@ -0,0 +1,14 @@
package client
import metricsapi "k8s.io/metrics/pkg/apis/metrics"
type Error string
func (e Error) Error() string {
return string(e)
}
const (
noMetricServerErr = Error("No metrics-server detected")
metricsUnsupportedErr = Error("No metrics api group " + metricsapi.GroupName + " found on cluster")
)

View File

@ -87,9 +87,7 @@ func (p *Pod) List(ctx context.Context, ns string) ([]runtime.Object, error) {
var pmx *mv1beta1.PodMetricsList var pmx *mv1beta1.PodMetricsList
if withMx, ok := ctx.Value(internal.KeyWithMetrics).(bool); withMx || !ok { if withMx, ok := ctx.Value(internal.KeyWithMetrics).(bool); withMx || !ok {
if pmx, err = client.DialMetrics(p.Client()).FetchPodsMetrics(ctx, ns); err != nil { pmx, _ = client.DialMetrics(p.Client()).FetchPodsMetrics(ctx, ns)
log.Debug().Err(err).Msgf("No pods metrics")
}
} }
res := make([]runtime.Object, 0, len(oo)) res := make([]runtime.Object, 0, len(oo))

View File

@ -71,11 +71,6 @@ func (t *Table) Init(ctx context.Context) {
t.SetSelectionChangedFunc(t.selectionChanged) t.SetSelectionChangedFunc(t.selectionChanged)
t.SetBackgroundColor(tcell.ColorDefault) t.SetBackgroundColor(tcell.ColorDefault)
t.Select(1, 0) t.Select(1, 0)
t.hasMetrics = false
if mx, ok := ctx.Value(internal.KeyHasMetrics).(bool); ok {
t.hasMetrics = mx
}
if cfg, ok := ctx.Value(internal.KeyViewConfig).(*config.CustomView); ok && cfg != nil { if cfg, ok := ctx.Value(internal.KeyViewConfig).(*config.CustomView); ok && cfg != nil {
cfg.AddListener(t.GVR().String(), t) cfg.AddListener(t.GVR().String(), t)
} }
@ -187,11 +182,12 @@ func (t *Table) SetSortCol(name string, asc bool) {
} }
// Update table content. // Update table content.
func (t *Table) Update(data render.TableData) { func (t *Table) Update(data render.TableData, hasMetrics bool) {
t.header = data.Header t.header = data.Header
if t.decorateFn != nil { if t.decorateFn != nil {
data = t.decorateFn(data) data = t.decorateFn(data)
} }
t.hasMetrics = hasMetrics
t.doUpdate(t.filtered(data)) t.doUpdate(t.filtered(data))
t.UpdateTitle() t.UpdateTitle()
} }
@ -334,7 +330,7 @@ func (t *Table) Refresh() {
return return
} }
// BOZO!! Really want to tell model reload now. Refactor! // BOZO!! Really want to tell model reload now. Refactor!
t.Update(data) t.Update(data, t.hasMetrics)
} }
// GetSelectedRow returns the entire selected row. // GetSelectedRow returns the entire selected row.

View File

@ -27,7 +27,7 @@ func TestTableUpdate(t *testing.T) {
v.Init(makeContext()) v.Init(makeContext())
data := makeTableData() data := makeTableData()
v.Update(data) v.Update(data, false)
assert.Equal(t, len(data.RowEvents)+1, v.GetRowCount()) assert.Equal(t, len(data.RowEvents)+1, v.GetRowCount())
assert.Equal(t, len(data.Header), v.GetColumnCount()) assert.Equal(t, len(data.Header), v.GetColumnCount())
@ -38,7 +38,7 @@ func TestTableSelection(t *testing.T) {
v.Init(makeContext()) v.Init(makeContext())
m := &mockModel{} m := &mockModel{}
v.SetModel(m) v.SetModel(m)
v.Update(m.Peek()) v.Update(m.Peek(), false)
v.SelectRow(1, true) v.SelectRow(1, true)
r, ok := v.GetSelectedRow("r1") r, ok := v.GetSelectedRow("r1")

View File

@ -164,7 +164,7 @@ func (b *Browser) BufferActive(state bool, k model.BufferKind) {
log.Error().Err(err).Msgf("Refresh failed for %s", b.GVR()) log.Error().Err(err).Msgf("Refresh failed for %s", b.GVR())
} }
b.app.QueueUpdateDraw(func() { b.app.QueueUpdateDraw(func() {
b.Update(b.GetModel().Peek()) b.Update(b.GetModel().Peek(), b.App().Conn().HasMetrics())
if b.GetRowCount() > 1 { if b.GetRowCount() > 1 {
b.App().filterHistory.Push(b.CmdBuff().GetText()) b.App().filterHistory.Push(b.CmdBuff().GetText())
} }
@ -213,7 +213,7 @@ func (b *Browser) TableDataChanged(data render.TableData) {
b.app.QueueUpdateDraw(func() { b.app.QueueUpdateDraw(func() {
b.refreshActions() b.refreshActions()
b.Update(data) b.Update(data, b.app.Conn().HasMetrics())
}) })
} }
@ -336,6 +336,9 @@ func (b *Browser) editCmd(evt *tcell.EventKey) *tcell.EventKey {
if client.IsClusterScoped(ns) { if client.IsClusterScoped(ns) {
ns = client.AllNamespaces ns = client.AllNamespaces
} }
if b.GVR().String() == "v1/namespaces" {
ns = n
}
if ok, err := b.app.Conn().CanI(ns, b.GVR().String(), []string{"patch"}); !ok || err != nil { if ok, err := b.app.Conn().CanI(ns, b.GVR().String(), []string{"patch"}); !ok || err != nil {
b.App().Flash().Err(fmt.Errorf("Current user can't edit resource %s", b.GVR())) b.App().Flash().Err(fmt.Errorf("Current user can't edit resource %s", b.GVR()))
return nil return nil

View File

@ -57,7 +57,7 @@ func TestTableNew(t *testing.T) {
} }
data.Namespace = "" data.Namespace = ""
v.Update(*data) v.Update(*data, false)
assert.Equal(t, 3, v.GetRowCount()) assert.Equal(t, 3, v.GetRowCount())
} }