fixed ns + klog stderr
parent
5db91d79a6
commit
a52cf37ff1
|
|
@ -154,7 +154,6 @@ This initial drop is brittle. K9s will most likely blow up...
|
||||||
|
|
||||||
1. You're running older versions of Kubernetes. K9s works best Kubernetes 1.12+.
|
1. You're running older versions of Kubernetes. K9s works best Kubernetes 1.12+.
|
||||||
1. You don't have enough RBAC fu to manage your cluster (see RBAC section below).
|
1. You don't have enough RBAC fu to manage your cluster (see RBAC section below).
|
||||||
1. Your cluster does not run a metric server.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -182,15 +181,15 @@ rules:
|
||||||
# Grants RO access to cluster resources node and namespace
|
# Grants RO access to cluster resources node and namespace
|
||||||
- apiGroups: [""]
|
- apiGroups: [""]
|
||||||
resources: ["nodes", "namespaces"]
|
resources: ["nodes", "namespaces"]
|
||||||
verbs: ["get", "list"]
|
verbs: ["get", "list", "watch"]
|
||||||
# Grants RO access to RBAC resources
|
# Grants RO access to RBAC resources
|
||||||
- apiGroups: ["rbac.authorization.k8s.io"]
|
- apiGroups: ["rbac.authorization.k8s.io"]
|
||||||
resources: ["clusterroles", "roles", "clusterrolebindings", "rolebindings"]
|
resources: ["clusterroles", "roles", "clusterrolebindings", "rolebindings"]
|
||||||
verbs: ["get", "list"]
|
verbs: ["get", "list", "watch"]
|
||||||
# Grants RO access to CRD resources
|
# Grants RO access to CRD resources
|
||||||
- apiGroups: ["apiextensions.k8s.io"]
|
- apiGroups: ["apiextensions.k8s.io"]
|
||||||
resources: ["customresourcedefinitions"]
|
resources: ["customresourcedefinitions"]
|
||||||
verbs: ["get", "list"]
|
verbs: ["get", "list", "watch"]
|
||||||
# Grants RO access to netric server
|
# Grants RO access to netric server
|
||||||
- apiGroups: ["metrics.k8s.io"]
|
- apiGroups: ["metrics.k8s.io"]
|
||||||
resources: ["nodes", "pods"]
|
resources: ["nodes", "pods"]
|
||||||
|
|
@ -228,7 +227,7 @@ rules:
|
||||||
# Grants RO access to most namespaced resources
|
# Grants RO access to most namespaced resources
|
||||||
- apiGroups: ["", "apps", "autoscaling", "batch", "extensions"]
|
- apiGroups: ["", "apps", "autoscaling", "batch", "extensions"]
|
||||||
resources: ["*"]
|
resources: ["*"]
|
||||||
verbs: ["get", "list"]
|
verbs: ["get", "list", "watch"]
|
||||||
|
|
||||||
---
|
---
|
||||||
# Sample K9s user RoleBinding
|
# Sample K9s user RoleBinding
|
||||||
|
|
|
||||||
|
|
@ -23,14 +23,14 @@ func infoCmd() *cobra.Command {
|
||||||
func printInfo() {
|
func printInfo() {
|
||||||
const secFmt = "%-15s "
|
const secFmt = "%-15s "
|
||||||
|
|
||||||
printLogo()
|
printLogo(printer.ColorCyan)
|
||||||
printTuple(secFmt, "Configuration", config.K9sConfigFile)
|
printTuple(secFmt, "Configuration", config.K9sConfigFile)
|
||||||
printTuple(secFmt, "Logs", config.K9sLogs)
|
printTuple(secFmt, "Logs", config.K9sLogs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func printLogo() {
|
func printLogo(color int) {
|
||||||
for _, l := range views.LogoSmall {
|
for _, l := range views.LogoSmall {
|
||||||
fmt.Println(printer.Colorize(l, printer.ColorCyan))
|
fmt.Println(printer.Colorize(l, color))
|
||||||
}
|
}
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,7 @@ func run(cmd *cobra.Command, args []string) {
|
||||||
if err := recover(); err != nil {
|
if err := recover(); err != nil {
|
||||||
log.Error().Msgf("Boom! %v", err)
|
log.Error().Msgf("Boom! %v", err)
|
||||||
log.Error().Msg(string(debug.Stack()))
|
log.Error().Msg(string(debug.Stack()))
|
||||||
|
printLogo(printer.ColorRed)
|
||||||
fmt.Printf(printer.Colorize("Boom!! ", printer.ColorRed))
|
fmt.Printf(printer.Colorize("Boom!! ", printer.ColorRed))
|
||||||
fmt.Println(printer.Colorize(fmt.Sprintf("%v.", err), printer.ColorDarkGray))
|
fmt.Println(printer.Colorize(fmt.Sprintf("%v.", err), printer.ColorDarkGray))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ func versionCmd() *cobra.Command {
|
||||||
func printVersion() {
|
func printVersion() {
|
||||||
const secFmt = "%-10s "
|
const secFmt = "%-10s "
|
||||||
|
|
||||||
printLogo()
|
printLogo(printer.ColorCyan)
|
||||||
printTuple(secFmt, "Version", version)
|
printTuple(secFmt, "Version", version)
|
||||||
printTuple(secFmt, "Commit", commit)
|
printTuple(secFmt, "Commit", commit)
|
||||||
printTuple(secFmt, "Date", date)
|
printTuple(secFmt, "Date", date)
|
||||||
|
|
|
||||||
1
go.mod
1
go.mod
|
|
@ -53,6 +53,7 @@ require (
|
||||||
k8s.io/apiserver v0.0.0-20190426133039-accf7b6d6716 // indirect
|
k8s.io/apiserver v0.0.0-20190426133039-accf7b6d6716 // indirect
|
||||||
k8s.io/cli-runtime v0.0.0-20190325194458-f2b4781c3ae1
|
k8s.io/cli-runtime v0.0.0-20190325194458-f2b4781c3ae1
|
||||||
k8s.io/client-go v10.0.0+incompatible
|
k8s.io/client-go v10.0.0+incompatible
|
||||||
|
k8s.io/klog v0.3.0
|
||||||
k8s.io/kube-openapi v0.0.0-20190426233423-c5d3b0f4bee0 // indirect
|
k8s.io/kube-openapi v0.0.0-20190426233423-c5d3b0f4bee0 // indirect
|
||||||
k8s.io/kubernetes v1.13.5
|
k8s.io/kubernetes v1.13.5
|
||||||
k8s.io/metrics v0.0.0-20190325194013-29123f6a4aa6
|
k8s.io/metrics v0.0.0-20190325194013-29123f6a4aa6
|
||||||
|
|
|
||||||
|
|
@ -19,13 +19,15 @@ func init() {
|
||||||
func TestConfigValidate(t *testing.T) {
|
func TestConfigValidate(t *testing.T) {
|
||||||
mc := NewMockConnection()
|
mc := NewMockConnection()
|
||||||
m.When(mc.ValidNamespaces()).ThenReturn(namespaces(), nil)
|
m.When(mc.ValidNamespaces()).ThenReturn(namespaces(), nil)
|
||||||
|
|
||||||
mk := NewMockKubeSettings()
|
mk := NewMockKubeSettings()
|
||||||
m.When(mk.ClusterNames()).ThenReturn([]string{"c1", "c2"}, nil)
|
m.When(mk.NamespaceNames(namespaces())).ThenReturn([]string{"default"})
|
||||||
|
|
||||||
cfg := config.NewConfig(mk)
|
cfg := config.NewConfig(mk)
|
||||||
cfg.SetConnection(mc)
|
cfg.SetConnection(mc)
|
||||||
assert.Nil(t, cfg.Load("test_assets/k9s.yml"))
|
assert.Nil(t, cfg.Load("test_assets/k9s.yml"))
|
||||||
cfg.Validate()
|
cfg.Validate()
|
||||||
|
// mc.VerifyWasCalledOnce().ValidNamespaces()
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestConfigLoad(t *testing.T) {
|
func TestConfigLoad(t *testing.T) {
|
||||||
|
|
|
||||||
|
|
@ -10,10 +10,13 @@ import (
|
||||||
|
|
||||||
func TestK9sValidate(t *testing.T) {
|
func TestK9sValidate(t *testing.T) {
|
||||||
mc := NewMockConnection()
|
mc := NewMockConnection()
|
||||||
|
m.When(mc.ValidNamespaces()).ThenReturn(namespaces(), nil)
|
||||||
|
|
||||||
mk := NewMockKubeSettings()
|
mk := NewMockKubeSettings()
|
||||||
m.When(mk.CurrentContextName()).ThenReturn("ctx1", nil)
|
m.When(mk.CurrentContextName()).ThenReturn("ctx1", nil)
|
||||||
m.When(mk.CurrentClusterName()).ThenReturn("c1", nil)
|
m.When(mk.CurrentClusterName()).ThenReturn("c1", nil)
|
||||||
m.When(mk.ClusterNames()).ThenReturn([]string{"c1", "c2"}, nil)
|
m.When(mk.ClusterNames()).ThenReturn([]string{"c1", "c2"}, nil)
|
||||||
|
m.When(mk.NamespaceNames(namespaces())).ThenReturn([]string{"default"})
|
||||||
|
|
||||||
c := config.NewK9s()
|
c := config.NewK9s()
|
||||||
c.Validate(mc, mk)
|
c.Validate(mc, mk)
|
||||||
|
|
@ -30,10 +33,13 @@ func TestK9sValidate(t *testing.T) {
|
||||||
|
|
||||||
func TestK9sValidateBlank(t *testing.T) {
|
func TestK9sValidateBlank(t *testing.T) {
|
||||||
mc := NewMockConnection()
|
mc := NewMockConnection()
|
||||||
|
m.When(mc.ValidNamespaces()).ThenReturn(namespaces(), nil)
|
||||||
|
|
||||||
mk := NewMockKubeSettings()
|
mk := NewMockKubeSettings()
|
||||||
m.When(mk.CurrentContextName()).ThenReturn("ctx1", nil)
|
m.When(mk.CurrentContextName()).ThenReturn("ctx1", nil)
|
||||||
m.When(mk.CurrentClusterName()).ThenReturn("c1", nil)
|
m.When(mk.CurrentClusterName()).ThenReturn("c1", nil)
|
||||||
m.When(mk.ClusterNames()).ThenReturn([]string{"c1", "c2"}, nil)
|
m.When(mk.ClusterNames()).ThenReturn([]string{"c1", "c2"}, nil)
|
||||||
|
m.When(mk.NamespaceNames(namespaces())).ThenReturn([]string{"default"})
|
||||||
|
|
||||||
var c config.K9s
|
var c config.K9s
|
||||||
c.Validate(mc, mk)
|
c.Validate(mc, mk)
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,25 @@ func (mock *MockConnection) Config() *k8s.Config {
|
||||||
return ret0
|
return ret0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (mock *MockConnection) CurrentNamespaceName() (string, error) {
|
||||||
|
if mock == nil {
|
||||||
|
panic("mock must not be nil. Use myMock := NewMockConnection().")
|
||||||
|
}
|
||||||
|
params := []pegomock.Param{}
|
||||||
|
result := pegomock.GetGenericMockFrom(mock).Invoke("CurrentNamespaceName", params, []reflect.Type{reflect.TypeOf((*string)(nil)).Elem(), reflect.TypeOf((*error)(nil)).Elem()})
|
||||||
|
var ret0 string
|
||||||
|
var ret1 error
|
||||||
|
if len(result) != 0 {
|
||||||
|
if result[0] != nil {
|
||||||
|
ret0 = result[0].(string)
|
||||||
|
}
|
||||||
|
if result[1] != nil {
|
||||||
|
ret1 = result[1].(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret0, ret1
|
||||||
|
}
|
||||||
|
|
||||||
func (mock *MockConnection) DialOrDie() kubernetes.Interface {
|
func (mock *MockConnection) DialOrDie() kubernetes.Interface {
|
||||||
if mock == nil {
|
if mock == nil {
|
||||||
panic("mock must not be nil. Use myMock := NewMockConnection().")
|
panic("mock must not be nil. Use myMock := NewMockConnection().")
|
||||||
|
|
@ -320,6 +339,23 @@ func (c *Connection_Config_OngoingVerification) GetCapturedArguments() {
|
||||||
func (c *Connection_Config_OngoingVerification) GetAllCapturedArguments() {
|
func (c *Connection_Config_OngoingVerification) GetAllCapturedArguments() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (verifier *VerifierConnection) CurrentNamespaceName() *Connection_CurrentNamespaceName_OngoingVerification {
|
||||||
|
params := []pegomock.Param{}
|
||||||
|
methodInvocations := pegomock.GetGenericMockFrom(verifier.mock).Verify(verifier.inOrderContext, verifier.invocationCountMatcher, "CurrentNamespaceName", params, verifier.timeout)
|
||||||
|
return &Connection_CurrentNamespaceName_OngoingVerification{mock: verifier.mock, methodInvocations: methodInvocations}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Connection_CurrentNamespaceName_OngoingVerification struct {
|
||||||
|
mock *MockConnection
|
||||||
|
methodInvocations []pegomock.MethodInvocation
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Connection_CurrentNamespaceName_OngoingVerification) GetCapturedArguments() {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Connection_CurrentNamespaceName_OngoingVerification) GetAllCapturedArguments() {
|
||||||
|
}
|
||||||
|
|
||||||
func (verifier *VerifierConnection) DialOrDie() *Connection_DialOrDie_OngoingVerification {
|
func (verifier *VerifierConnection) DialOrDie() *Connection_DialOrDie_OngoingVerification {
|
||||||
params := []pegomock.Param{}
|
params := []pegomock.Param{}
|
||||||
methodInvocations := pegomock.GetGenericMockFrom(verifier.mock).Verify(verifier.inOrderContext, verifier.invocationCountMatcher, "DialOrDie", params, verifier.timeout)
|
methodInvocations := pegomock.GetGenericMockFrom(verifier.mock).Verify(verifier.inOrderContext, verifier.invocationCountMatcher, "DialOrDie", params, verifier.timeout)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -31,11 +33,10 @@ func (n *Namespace) Validate(c Connection, ks KubeSettings) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
nn := ks.NamespaceNames(nns)
|
nn := ks.NamespaceNames(nns)
|
||||||
if !n.isAllNamespace() && !InList(nn, n.Active) {
|
if !n.isAllNamespace() && !InList(nn, n.Active) {
|
||||||
log.Debug().Msg("[Config] Validation error active namespace resetting to `default")
|
log.Error().Msgf("[Config] Validation error active namespace `%s does not exists", n.Active)
|
||||||
n.Active = defaultNS
|
panic(fmt.Errorf("Invalid namespace. The provided namespace `%s does not exists", n.Active))
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, ns := range n.Favorites {
|
for _, ns := range n.Favorites {
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,12 @@ func TestNSValidate(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNSValidateMissing(t *testing.T) {
|
func TestNSValidateMissing(t *testing.T) {
|
||||||
|
defer func() {
|
||||||
|
if err := recover(); err == nil {
|
||||||
|
t.Fatalf("Expected panic on non existing namespace")
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
mc := NewMockConnection()
|
mc := NewMockConnection()
|
||||||
m.When(mc.ValidNamespaces()).ThenReturn(namespaces(), nil)
|
m.When(mc.ValidNamespaces()).ThenReturn(namespaces(), nil)
|
||||||
mk := NewMockKubeSettings()
|
mk := NewMockKubeSettings()
|
||||||
|
|
@ -81,6 +87,8 @@ func TestNSValidateRmFavs(t *testing.T) {
|
||||||
allNS := []string{"default", "kube-system"}
|
allNS := []string{"default", "kube-system"}
|
||||||
|
|
||||||
mc := NewMockConnection()
|
mc := NewMockConnection()
|
||||||
|
m.When(mc.ValidNamespaces()).ThenReturn(namespaces(), nil)
|
||||||
|
|
||||||
mk := NewMockKubeSettings()
|
mk := NewMockKubeSettings()
|
||||||
m.When(mk.NamespaceNames(namespaces())).ThenReturn(allNS)
|
m.When(mk.NamespaceNames(namespaces())).ThenReturn(allNS)
|
||||||
|
|
||||||
|
|
@ -88,5 +96,5 @@ func TestNSValidateRmFavs(t *testing.T) {
|
||||||
ns.Favorites = []string{"default", "fred", "blee"}
|
ns.Favorites = []string{"default", "fred", "blee"}
|
||||||
ns.Validate(mc, mk)
|
ns.Validate(mc, mk)
|
||||||
|
|
||||||
assert.Equal(t, []string{"fred"}, ns.Favorites)
|
assert.Equal(t, []string{"default"}, ns.Favorites)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,7 @@ type (
|
||||||
SupportsRes(grp string, versions []string) (string, bool)
|
SupportsRes(grp string, versions []string) (string, bool)
|
||||||
ServerVersion() (*version.Info, error)
|
ServerVersion() (*version.Info, error)
|
||||||
FetchNodes() (*v1.NodeList, error)
|
FetchNodes() (*v1.NodeList, error)
|
||||||
|
CurrentNamespaceName() (string, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// APIClient represents a Kubernetes api client.
|
// APIClient represents a Kubernetes api client.
|
||||||
|
|
@ -83,6 +84,11 @@ func InitConnectionOrDie(config *Config, logger zerolog.Logger) *APIClient {
|
||||||
return &conn
|
return &conn
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CurrentNamespaceName return namespace name set via either cli arg or cluster config.
|
||||||
|
func (a *APIClient) CurrentNamespaceName() (string, error) {
|
||||||
|
return a.config.CurrentNamespaceName()
|
||||||
|
}
|
||||||
|
|
||||||
// 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) {
|
||||||
return a.DialOrDie().Discovery().ServerVersion()
|
return a.DialOrDie().Discovery().ServerVersion()
|
||||||
|
|
|
||||||
|
|
@ -265,7 +265,7 @@ func (l *list) fetchFromStore(m *wa.Meta, ns string) (Columnars, error) {
|
||||||
res = l.resource.New(r)
|
res = l.resource.New(r)
|
||||||
pmx, err := m.Get(wa.PodMXIndex, fqn, opts)
|
pmx, err := m.Get(wa.PodMXIndex, fqn, opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn().Err(err).Msg("PodMetrics")
|
log.Warn().Err(err).Msgf("PodMetrics %s", fqn)
|
||||||
}
|
}
|
||||||
if mx, ok := pmx.(*mv1beta1.PodMetrics); ok {
|
if mx, ok := pmx.(*mv1beta1.PodMetrics); ok {
|
||||||
res.SetPodMetrics(mx)
|
res.SetPodMetrics(mx)
|
||||||
|
|
@ -275,7 +275,7 @@ func (l *list) fetchFromStore(m *wa.Meta, ns string) (Columnars, error) {
|
||||||
res = l.resource.New(r)
|
res = l.resource.New(r)
|
||||||
pmx, err := m.Get(wa.PodMXIndex, fqn, opts)
|
pmx, err := m.Get(wa.PodMXIndex, fqn, opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn().Err(err).Msg("PodMetrics")
|
log.Warn().Err(err).Msgf("PodMetrics<container> %s", fqn)
|
||||||
}
|
}
|
||||||
if mx, ok := pmx.(*mv1beta1.PodMetrics); ok {
|
if mx, ok := pmx.(*mv1beta1.PodMetrics); ok {
|
||||||
res.SetPodMetrics(mx)
|
res.SetPodMetrics(mx)
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,25 @@ func (mock *MockClusterMeta) ContextName() string {
|
||||||
return ret0
|
return ret0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (mock *MockClusterMeta) CurrentNamespaceName() (string, error) {
|
||||||
|
if mock == nil {
|
||||||
|
panic("mock must not be nil. Use myMock := NewMockClusterMeta().")
|
||||||
|
}
|
||||||
|
params := []pegomock.Param{}
|
||||||
|
result := pegomock.GetGenericMockFrom(mock).Invoke("CurrentNamespaceName", params, []reflect.Type{reflect.TypeOf((*string)(nil)).Elem(), reflect.TypeOf((*error)(nil)).Elem()})
|
||||||
|
var ret0 string
|
||||||
|
var ret1 error
|
||||||
|
if len(result) != 0 {
|
||||||
|
if result[0] != nil {
|
||||||
|
ret0 = result[0].(string)
|
||||||
|
}
|
||||||
|
if result[1] != nil {
|
||||||
|
ret1 = result[1].(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret0, ret1
|
||||||
|
}
|
||||||
|
|
||||||
func (mock *MockClusterMeta) DialOrDie() kubernetes.Interface {
|
func (mock *MockClusterMeta) DialOrDie() kubernetes.Interface {
|
||||||
if mock == nil {
|
if mock == nil {
|
||||||
panic("mock must not be nil. Use myMock := NewMockClusterMeta().")
|
panic("mock must not be nil. Use myMock := NewMockClusterMeta().")
|
||||||
|
|
@ -437,6 +456,23 @@ func (c *ClusterMeta_ContextName_OngoingVerification) GetCapturedArguments() {
|
||||||
func (c *ClusterMeta_ContextName_OngoingVerification) GetAllCapturedArguments() {
|
func (c *ClusterMeta_ContextName_OngoingVerification) GetAllCapturedArguments() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (verifier *VerifierClusterMeta) CurrentNamespaceName() *ClusterMeta_CurrentNamespaceName_OngoingVerification {
|
||||||
|
params := []pegomock.Param{}
|
||||||
|
methodInvocations := pegomock.GetGenericMockFrom(verifier.mock).Verify(verifier.inOrderContext, verifier.invocationCountMatcher, "CurrentNamespaceName", params, verifier.timeout)
|
||||||
|
return &ClusterMeta_CurrentNamespaceName_OngoingVerification{mock: verifier.mock, methodInvocations: methodInvocations}
|
||||||
|
}
|
||||||
|
|
||||||
|
type ClusterMeta_CurrentNamespaceName_OngoingVerification struct {
|
||||||
|
mock *MockClusterMeta
|
||||||
|
methodInvocations []pegomock.MethodInvocation
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ClusterMeta_CurrentNamespaceName_OngoingVerification) GetCapturedArguments() {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ClusterMeta_CurrentNamespaceName_OngoingVerification) GetAllCapturedArguments() {
|
||||||
|
}
|
||||||
|
|
||||||
func (verifier *VerifierClusterMeta) DialOrDie() *ClusterMeta_DialOrDie_OngoingVerification {
|
func (verifier *VerifierClusterMeta) DialOrDie() *ClusterMeta_DialOrDie_OngoingVerification {
|
||||||
params := []pegomock.Param{}
|
params := []pegomock.Param{}
|
||||||
methodInvocations := pegomock.GetGenericMockFrom(verifier.mock).Verify(verifier.inOrderContext, verifier.invocationCountMatcher, "DialOrDie", params, verifier.timeout)
|
methodInvocations := pegomock.GetGenericMockFrom(verifier.mock).Verify(verifier.inOrderContext, verifier.invocationCountMatcher, "DialOrDie", params, verifier.timeout)
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,25 @@ func (mock *MockConnection) Config() *k8s.Config {
|
||||||
return ret0
|
return ret0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (mock *MockConnection) CurrentNamespaceName() (string, error) {
|
||||||
|
if mock == nil {
|
||||||
|
panic("mock must not be nil. Use myMock := NewMockConnection().")
|
||||||
|
}
|
||||||
|
params := []pegomock.Param{}
|
||||||
|
result := pegomock.GetGenericMockFrom(mock).Invoke("CurrentNamespaceName", params, []reflect.Type{reflect.TypeOf((*string)(nil)).Elem(), reflect.TypeOf((*error)(nil)).Elem()})
|
||||||
|
var ret0 string
|
||||||
|
var ret1 error
|
||||||
|
if len(result) != 0 {
|
||||||
|
if result[0] != nil {
|
||||||
|
ret0 = result[0].(string)
|
||||||
|
}
|
||||||
|
if result[1] != nil {
|
||||||
|
ret1 = result[1].(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret0, ret1
|
||||||
|
}
|
||||||
|
|
||||||
func (mock *MockConnection) DialOrDie() kubernetes.Interface {
|
func (mock *MockConnection) DialOrDie() kubernetes.Interface {
|
||||||
if mock == nil {
|
if mock == nil {
|
||||||
panic("mock must not be nil. Use myMock := NewMockConnection().")
|
panic("mock must not be nil. Use myMock := NewMockConnection().")
|
||||||
|
|
@ -320,6 +339,23 @@ func (c *Connection_Config_OngoingVerification) GetCapturedArguments() {
|
||||||
func (c *Connection_Config_OngoingVerification) GetAllCapturedArguments() {
|
func (c *Connection_Config_OngoingVerification) GetAllCapturedArguments() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (verifier *VerifierConnection) CurrentNamespaceName() *Connection_CurrentNamespaceName_OngoingVerification {
|
||||||
|
params := []pegomock.Param{}
|
||||||
|
methodInvocations := pegomock.GetGenericMockFrom(verifier.mock).Verify(verifier.inOrderContext, verifier.invocationCountMatcher, "CurrentNamespaceName", params, verifier.timeout)
|
||||||
|
return &Connection_CurrentNamespaceName_OngoingVerification{mock: verifier.mock, methodInvocations: methodInvocations}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Connection_CurrentNamespaceName_OngoingVerification struct {
|
||||||
|
mock *MockConnection
|
||||||
|
methodInvocations []pegomock.MethodInvocation
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Connection_CurrentNamespaceName_OngoingVerification) GetCapturedArguments() {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Connection_CurrentNamespaceName_OngoingVerification) GetAllCapturedArguments() {
|
||||||
|
}
|
||||||
|
|
||||||
func (verifier *VerifierConnection) DialOrDie() *Connection_DialOrDie_OngoingVerification {
|
func (verifier *VerifierConnection) DialOrDie() *Connection_DialOrDie_OngoingVerification {
|
||||||
params := []pegomock.Param{}
|
params := []pegomock.Param{}
|
||||||
methodInvocations := pegomock.GetGenericMockFrom(verifier.mock).Verify(verifier.inOrderContext, verifier.invocationCountMatcher, "DialOrDie", params, verifier.timeout)
|
methodInvocations := pegomock.GetGenericMockFrom(verifier.mock).Verify(verifier.inOrderContext, verifier.invocationCountMatcher, "DialOrDie", params, verifier.timeout)
|
||||||
|
|
|
||||||
|
|
@ -104,19 +104,25 @@ func (v *clusterInfoView) refresh() {
|
||||||
v.GetCell(row, 1).SetText(cluster.Version())
|
v.GetCell(row, 1).SetText(cluster.Version())
|
||||||
row++
|
row++
|
||||||
|
|
||||||
|
c := v.GetCell(row, 1)
|
||||||
|
c.SetText(resource.NAValue)
|
||||||
|
c = v.GetCell(row+1, 1)
|
||||||
|
c.SetText(resource.NAValue)
|
||||||
|
|
||||||
nos, err := v.app.informer.List(watch.NodeIndex, "", metav1.ListOptions{})
|
nos, err := v.app.informer.List(watch.NodeIndex, "", metav1.ListOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn().Err(err).Msg("List nodes")
|
log.Warn().Err(err).Msg("ListNodes")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
nmx, err := v.app.informer.List(watch.NodeMXIndex, "", metav1.ListOptions{})
|
nmx, err := v.app.informer.List(watch.NodeMXIndex, "", metav1.ListOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn().Err(err).Msg("List node metrics")
|
log.Warn().Err(err).Msg("ListNodeMetrics")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var cmx k8s.ClusterMetrics
|
var cmx k8s.ClusterMetrics
|
||||||
cluster.Metrics(nos, nmx, &cmx)
|
cluster.Metrics(nos, nmx, &cmx)
|
||||||
c := v.GetCell(row, 1)
|
c = v.GetCell(row, 1)
|
||||||
cpu := resource.AsPerc(cmx.PercCPU)
|
cpu := resource.AsPerc(cmx.PercCPU)
|
||||||
c.SetText(cpu + deltas(strip(c.Text), cpu))
|
c.SetText(cpu + deltas(strip(c.Text), cpu))
|
||||||
row++
|
row++
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,25 @@ func (mock *MockClusterMeta) ContextName() string {
|
||||||
return ret0
|
return ret0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (mock *MockClusterMeta) CurrentNamespaceName() (string, error) {
|
||||||
|
if mock == nil {
|
||||||
|
panic("mock must not be nil. Use myMock := NewMockClusterMeta().")
|
||||||
|
}
|
||||||
|
params := []pegomock.Param{}
|
||||||
|
result := pegomock.GetGenericMockFrom(mock).Invoke("CurrentNamespaceName", params, []reflect.Type{reflect.TypeOf((*string)(nil)).Elem(), reflect.TypeOf((*error)(nil)).Elem()})
|
||||||
|
var ret0 string
|
||||||
|
var ret1 error
|
||||||
|
if len(result) != 0 {
|
||||||
|
if result[0] != nil {
|
||||||
|
ret0 = result[0].(string)
|
||||||
|
}
|
||||||
|
if result[1] != nil {
|
||||||
|
ret1 = result[1].(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret0, ret1
|
||||||
|
}
|
||||||
|
|
||||||
func (mock *MockClusterMeta) DialOrDie() kubernetes.Interface {
|
func (mock *MockClusterMeta) DialOrDie() kubernetes.Interface {
|
||||||
if mock == nil {
|
if mock == nil {
|
||||||
panic("mock must not be nil. Use myMock := NewMockClusterMeta().")
|
panic("mock must not be nil. Use myMock := NewMockClusterMeta().")
|
||||||
|
|
@ -437,6 +456,23 @@ func (c *ClusterMeta_ContextName_OngoingVerification) GetCapturedArguments() {
|
||||||
func (c *ClusterMeta_ContextName_OngoingVerification) GetAllCapturedArguments() {
|
func (c *ClusterMeta_ContextName_OngoingVerification) GetAllCapturedArguments() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (verifier *VerifierClusterMeta) CurrentNamespaceName() *ClusterMeta_CurrentNamespaceName_OngoingVerification {
|
||||||
|
params := []pegomock.Param{}
|
||||||
|
methodInvocations := pegomock.GetGenericMockFrom(verifier.mock).Verify(verifier.inOrderContext, verifier.invocationCountMatcher, "CurrentNamespaceName", params, verifier.timeout)
|
||||||
|
return &ClusterMeta_CurrentNamespaceName_OngoingVerification{mock: verifier.mock, methodInvocations: methodInvocations}
|
||||||
|
}
|
||||||
|
|
||||||
|
type ClusterMeta_CurrentNamespaceName_OngoingVerification struct {
|
||||||
|
mock *MockClusterMeta
|
||||||
|
methodInvocations []pegomock.MethodInvocation
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ClusterMeta_CurrentNamespaceName_OngoingVerification) GetCapturedArguments() {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ClusterMeta_CurrentNamespaceName_OngoingVerification) GetAllCapturedArguments() {
|
||||||
|
}
|
||||||
|
|
||||||
func (verifier *VerifierClusterMeta) DialOrDie() *ClusterMeta_DialOrDie_OngoingVerification {
|
func (verifier *VerifierClusterMeta) DialOrDie() *ClusterMeta_DialOrDie_OngoingVerification {
|
||||||
params := []pegomock.Param{}
|
params := []pegomock.Param{}
|
||||||
methodInvocations := pegomock.GetGenericMockFrom(verifier.mock).Verify(verifier.inOrderContext, verifier.invocationCountMatcher, "DialOrDie", params, verifier.timeout)
|
methodInvocations := pegomock.GetGenericMockFrom(verifier.mock).Verify(verifier.inOrderContext, verifier.invocationCountMatcher, "DialOrDie", params, verifier.timeout)
|
||||||
|
|
|
||||||
|
|
@ -459,17 +459,19 @@ func namespaced(n string) (string, string) {
|
||||||
|
|
||||||
func (v *resourceView) refreshActions() {
|
func (v *resourceView) refreshActions() {
|
||||||
if v.list.Access(resource.NamespaceAccess) {
|
if v.list.Access(resource.NamespaceAccess) {
|
||||||
v.namespaces = make(map[int]string, config.MaxFavoritesNS)
|
if ns, err := v.app.conn().CurrentNamespaceName(); err != nil || ns == "" {
|
||||||
v.actions[tcell.Key(numKeys[0])] = newKeyAction(resource.AllNamespace, v.switchNamespaceCmd, true)
|
v.namespaces = make(map[int]string, config.MaxFavoritesNS)
|
||||||
v.namespaces[0] = resource.AllNamespace
|
v.actions[tcell.Key(numKeys[0])] = newKeyAction(resource.AllNamespace, v.switchNamespaceCmd, true)
|
||||||
index := 1
|
v.namespaces[0] = resource.AllNamespace
|
||||||
for _, n := range v.app.config.FavNamespaces() {
|
index := 1
|
||||||
if n == resource.AllNamespace {
|
for _, n := range v.app.config.FavNamespaces() {
|
||||||
continue
|
if n == resource.AllNamespace {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
v.actions[tcell.Key(numKeys[index])] = newKeyAction(n, v.switchNamespaceCmd, true)
|
||||||
|
v.namespaces[index] = n
|
||||||
|
index++
|
||||||
}
|
}
|
||||||
v.actions[tcell.Key(numKeys[index])] = newKeyAction(n, v.switchNamespaceCmd, true)
|
|
||||||
v.namespaces[index] = n
|
|
||||||
index++
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ func (m *Meta) List(res, ns string, opts metav1.ListOptions) (k8s.Collection, er
|
||||||
return i.List(ns, opts), nil
|
return i.List(ns, opts), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, fmt.Errorf("No informer found for resource %s", res)
|
return nil, fmt.Errorf("No informer found for resource %s:%q", res, ns)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get a resource by name.
|
// Get a resource by name.
|
||||||
|
|
@ -90,7 +90,7 @@ func (m Meta) Get(res, fqn string, opts metav1.GetOptions) (interface{}, error)
|
||||||
return informer.Get(fqn, opts)
|
return informer.Get(fqn, opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, fmt.Errorf("No informer found for resource %s", res)
|
return nil, fmt.Errorf("No informer found for resource %s:%q", res, fqn)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run starts watching cluster resources.
|
// Run starts watching cluster resources.
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,25 @@ func (mock *MockConnection) Config() *k8s.Config {
|
||||||
return ret0
|
return ret0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (mock *MockConnection) CurrentNamespaceName() (string, error) {
|
||||||
|
if mock == nil {
|
||||||
|
panic("mock must not be nil. Use myMock := NewMockConnection().")
|
||||||
|
}
|
||||||
|
params := []pegomock.Param{}
|
||||||
|
result := pegomock.GetGenericMockFrom(mock).Invoke("CurrentNamespaceName", params, []reflect.Type{reflect.TypeOf((*string)(nil)).Elem(), reflect.TypeOf((*error)(nil)).Elem()})
|
||||||
|
var ret0 string
|
||||||
|
var ret1 error
|
||||||
|
if len(result) != 0 {
|
||||||
|
if result[0] != nil {
|
||||||
|
ret0 = result[0].(string)
|
||||||
|
}
|
||||||
|
if result[1] != nil {
|
||||||
|
ret1 = result[1].(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret0, ret1
|
||||||
|
}
|
||||||
|
|
||||||
func (mock *MockConnection) DialOrDie() kubernetes.Interface {
|
func (mock *MockConnection) DialOrDie() kubernetes.Interface {
|
||||||
if mock == nil {
|
if mock == nil {
|
||||||
panic("mock must not be nil. Use myMock := NewMockConnection().")
|
panic("mock must not be nil. Use myMock := NewMockConnection().")
|
||||||
|
|
@ -320,6 +339,23 @@ func (c *Connection_Config_OngoingVerification) GetCapturedArguments() {
|
||||||
func (c *Connection_Config_OngoingVerification) GetAllCapturedArguments() {
|
func (c *Connection_Config_OngoingVerification) GetAllCapturedArguments() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (verifier *VerifierConnection) CurrentNamespaceName() *Connection_CurrentNamespaceName_OngoingVerification {
|
||||||
|
params := []pegomock.Param{}
|
||||||
|
methodInvocations := pegomock.GetGenericMockFrom(verifier.mock).Verify(verifier.inOrderContext, verifier.invocationCountMatcher, "CurrentNamespaceName", params, verifier.timeout)
|
||||||
|
return &Connection_CurrentNamespaceName_OngoingVerification{mock: verifier.mock, methodInvocations: methodInvocations}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Connection_CurrentNamespaceName_OngoingVerification struct {
|
||||||
|
mock *MockConnection
|
||||||
|
methodInvocations []pegomock.MethodInvocation
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Connection_CurrentNamespaceName_OngoingVerification) GetCapturedArguments() {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Connection_CurrentNamespaceName_OngoingVerification) GetAllCapturedArguments() {
|
||||||
|
}
|
||||||
|
|
||||||
func (verifier *VerifierConnection) DialOrDie() *Connection_DialOrDie_OngoingVerification {
|
func (verifier *VerifierConnection) DialOrDie() *Connection_DialOrDie_OngoingVerification {
|
||||||
params := []pegomock.Param{}
|
params := []pegomock.Param{}
|
||||||
methodInvocations := pegomock.GetGenericMockFrom(verifier.mock).Verify(verifier.inOrderContext, verifier.invocationCountMatcher, "DialOrDie", params, verifier.timeout)
|
methodInvocations := pegomock.GetGenericMockFrom(verifier.mock).Verify(verifier.inOrderContext, verifier.invocationCountMatcher, "DialOrDie", params, verifier.timeout)
|
||||||
|
|
|
||||||
5
main.go
5
main.go
|
|
@ -2,12 +2,14 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
"github.com/derailed/k9s/cmd"
|
"github.com/derailed/k9s/cmd"
|
||||||
"github.com/derailed/k9s/internal/config"
|
"github.com/derailed/k9s/internal/config"
|
||||||
"github.com/rs/zerolog"
|
"github.com/rs/zerolog"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
_ "k8s.io/client-go/plugin/pkg/client/auth"
|
_ "k8s.io/client-go/plugin/pkg/client/auth"
|
||||||
|
"k8s.io/klog"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
|
@ -16,6 +18,9 @@ func init() {
|
||||||
mod := os.O_CREATE | os.O_APPEND | os.O_WRONLY
|
mod := os.O_CREATE | os.O_APPEND | os.O_WRONLY
|
||||||
if file, err := os.OpenFile(config.K9sLogs, mod, config.DefaultFileMod); err == nil {
|
if file, err := os.OpenFile(config.K9sLogs, mod, config.DefaultFileMod); err == nil {
|
||||||
log.Logger = log.Output(zerolog.ConsoleWriter{Out: file})
|
log.Logger = log.Output(zerolog.ConsoleWriter{Out: file})
|
||||||
|
// Klogs (of course) want to print stuff to the screen ;(
|
||||||
|
klog.SetOutput(file)
|
||||||
|
syscall.Dup2(int(file.Fd()), 2)
|
||||||
} else {
|
} else {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue