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 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
|
||||
- apiGroups: [""]
|
||||
resources: ["nodes", "namespaces"]
|
||||
verbs: ["get", "list"]
|
||||
verbs: ["get", "list", "watch"]
|
||||
# Grants RO access to RBAC resources
|
||||
- apiGroups: ["rbac.authorization.k8s.io"]
|
||||
resources: ["clusterroles", "roles", "clusterrolebindings", "rolebindings"]
|
||||
verbs: ["get", "list"]
|
||||
verbs: ["get", "list", "watch"]
|
||||
# Grants RO access to CRD resources
|
||||
- apiGroups: ["apiextensions.k8s.io"]
|
||||
resources: ["customresourcedefinitions"]
|
||||
verbs: ["get", "list"]
|
||||
verbs: ["get", "list", "watch"]
|
||||
# Grants RO access to netric server
|
||||
- apiGroups: ["metrics.k8s.io"]
|
||||
resources: ["nodes", "pods"]
|
||||
|
|
@ -228,7 +227,7 @@ rules:
|
|||
# Grants RO access to most namespaced resources
|
||||
- apiGroups: ["", "apps", "autoscaling", "batch", "extensions"]
|
||||
resources: ["*"]
|
||||
verbs: ["get", "list"]
|
||||
verbs: ["get", "list", "watch"]
|
||||
|
||||
---
|
||||
# Sample K9s user RoleBinding
|
||||
|
|
|
|||
|
|
@ -23,14 +23,14 @@ func infoCmd() *cobra.Command {
|
|||
func printInfo() {
|
||||
const secFmt = "%-15s "
|
||||
|
||||
printLogo()
|
||||
printLogo(printer.ColorCyan)
|
||||
printTuple(secFmt, "Configuration", config.K9sConfigFile)
|
||||
printTuple(secFmt, "Logs", config.K9sLogs)
|
||||
}
|
||||
|
||||
func printLogo() {
|
||||
func printLogo(color int) {
|
||||
for _, l := range views.LogoSmall {
|
||||
fmt.Println(printer.Colorize(l, printer.ColorCyan))
|
||||
fmt.Println(printer.Colorize(l, color))
|
||||
}
|
||||
fmt.Println()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ func run(cmd *cobra.Command, args []string) {
|
|||
if err := recover(); err != nil {
|
||||
log.Error().Msgf("Boom! %v", err)
|
||||
log.Error().Msg(string(debug.Stack()))
|
||||
printLogo(printer.ColorRed)
|
||||
fmt.Printf(printer.Colorize("Boom!! ", printer.ColorRed))
|
||||
fmt.Println(printer.Colorize(fmt.Sprintf("%v.", err), printer.ColorDarkGray))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ func versionCmd() *cobra.Command {
|
|||
func printVersion() {
|
||||
const secFmt = "%-10s "
|
||||
|
||||
printLogo()
|
||||
printLogo(printer.ColorCyan)
|
||||
printTuple(secFmt, "Version", version)
|
||||
printTuple(secFmt, "Commit", commit)
|
||||
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/cli-runtime v0.0.0-20190325194458-f2b4781c3ae1
|
||||
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/kubernetes v1.13.5
|
||||
k8s.io/metrics v0.0.0-20190325194013-29123f6a4aa6
|
||||
|
|
|
|||
|
|
@ -19,13 +19,15 @@ func init() {
|
|||
func TestConfigValidate(t *testing.T) {
|
||||
mc := NewMockConnection()
|
||||
m.When(mc.ValidNamespaces()).ThenReturn(namespaces(), nil)
|
||||
|
||||
mk := NewMockKubeSettings()
|
||||
m.When(mk.ClusterNames()).ThenReturn([]string{"c1", "c2"}, nil)
|
||||
m.When(mk.NamespaceNames(namespaces())).ThenReturn([]string{"default"})
|
||||
|
||||
cfg := config.NewConfig(mk)
|
||||
cfg.SetConnection(mc)
|
||||
assert.Nil(t, cfg.Load("test_assets/k9s.yml"))
|
||||
cfg.Validate()
|
||||
// mc.VerifyWasCalledOnce().ValidNamespaces()
|
||||
}
|
||||
|
||||
func TestConfigLoad(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -10,10 +10,13 @@ import (
|
|||
|
||||
func TestK9sValidate(t *testing.T) {
|
||||
mc := NewMockConnection()
|
||||
m.When(mc.ValidNamespaces()).ThenReturn(namespaces(), nil)
|
||||
|
||||
mk := NewMockKubeSettings()
|
||||
m.When(mk.CurrentContextName()).ThenReturn("ctx1", nil)
|
||||
m.When(mk.CurrentClusterName()).ThenReturn("c1", nil)
|
||||
m.When(mk.ClusterNames()).ThenReturn([]string{"c1", "c2"}, nil)
|
||||
m.When(mk.NamespaceNames(namespaces())).ThenReturn([]string{"default"})
|
||||
|
||||
c := config.NewK9s()
|
||||
c.Validate(mc, mk)
|
||||
|
|
@ -30,10 +33,13 @@ func TestK9sValidate(t *testing.T) {
|
|||
|
||||
func TestK9sValidateBlank(t *testing.T) {
|
||||
mc := NewMockConnection()
|
||||
m.When(mc.ValidNamespaces()).ThenReturn(namespaces(), nil)
|
||||
|
||||
mk := NewMockKubeSettings()
|
||||
m.When(mk.CurrentContextName()).ThenReturn("ctx1", nil)
|
||||
m.When(mk.CurrentClusterName()).ThenReturn("c1", nil)
|
||||
m.When(mk.ClusterNames()).ThenReturn([]string{"c1", "c2"}, nil)
|
||||
m.When(mk.NamespaceNames(namespaces())).ThenReturn([]string{"default"})
|
||||
|
||||
var c config.K9s
|
||||
c.Validate(mc, mk)
|
||||
|
|
|
|||
|
|
@ -39,6 +39,25 @@ func (mock *MockConnection) Config() *k8s.Config {
|
|||
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 {
|
||||
if mock == nil {
|
||||
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 (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 {
|
||||
params := []pegomock.Param{}
|
||||
methodInvocations := pegomock.GetGenericMockFrom(verifier.mock).Verify(verifier.inOrderContext, verifier.invocationCountMatcher, "DialOrDie", params, verifier.timeout)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
|
|
@ -31,11 +33,10 @@ func (n *Namespace) Validate(c Connection, ks KubeSettings) {
|
|||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
nn := ks.NamespaceNames(nns)
|
||||
if !n.isAllNamespace() && !InList(nn, n.Active) {
|
||||
log.Debug().Msg("[Config] Validation error active namespace resetting to `default")
|
||||
n.Active = defaultNS
|
||||
log.Error().Msgf("[Config] Validation error active namespace `%s does not exists", n.Active)
|
||||
panic(fmt.Errorf("Invalid namespace. The provided namespace `%s does not exists", n.Active))
|
||||
}
|
||||
|
||||
for _, ns := range n.Favorites {
|
||||
|
|
|
|||
|
|
@ -24,6 +24,12 @@ func TestNSValidate(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()
|
||||
m.When(mc.ValidNamespaces()).ThenReturn(namespaces(), nil)
|
||||
mk := NewMockKubeSettings()
|
||||
|
|
@ -81,6 +87,8 @@ func TestNSValidateRmFavs(t *testing.T) {
|
|||
allNS := []string{"default", "kube-system"}
|
||||
|
||||
mc := NewMockConnection()
|
||||
m.When(mc.ValidNamespaces()).ThenReturn(namespaces(), nil)
|
||||
|
||||
mk := NewMockKubeSettings()
|
||||
m.When(mk.NamespaceNames(namespaces())).ThenReturn(allNS)
|
||||
|
||||
|
|
@ -88,5 +96,5 @@ func TestNSValidateRmFavs(t *testing.T) {
|
|||
ns.Favorites = []string{"default", "fred", "blee"}
|
||||
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)
|
||||
ServerVersion() (*version.Info, error)
|
||||
FetchNodes() (*v1.NodeList, error)
|
||||
CurrentNamespaceName() (string, error)
|
||||
}
|
||||
|
||||
// APIClient represents a Kubernetes api client.
|
||||
|
|
@ -83,6 +84,11 @@ func InitConnectionOrDie(config *Config, logger zerolog.Logger) *APIClient {
|
|||
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.
|
||||
func (a *APIClient) ServerVersion() (*version.Info, error) {
|
||||
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)
|
||||
pmx, err := m.Get(wa.PodMXIndex, fqn, opts)
|
||||
if err != nil {
|
||||
log.Warn().Err(err).Msg("PodMetrics")
|
||||
log.Warn().Err(err).Msgf("PodMetrics %s", fqn)
|
||||
}
|
||||
if mx, ok := pmx.(*mv1beta1.PodMetrics); ok {
|
||||
res.SetPodMetrics(mx)
|
||||
|
|
@ -275,7 +275,7 @@ func (l *list) fetchFromStore(m *wa.Meta, ns string) (Columnars, error) {
|
|||
res = l.resource.New(r)
|
||||
pmx, err := m.Get(wa.PodMXIndex, fqn, opts)
|
||||
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 {
|
||||
res.SetPodMetrics(mx)
|
||||
|
|
|
|||
|
|
@ -69,6 +69,25 @@ func (mock *MockClusterMeta) ContextName() string {
|
|||
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 {
|
||||
if mock == nil {
|
||||
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 (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 {
|
||||
params := []pegomock.Param{}
|
||||
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
|
||||
}
|
||||
|
||||
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 {
|
||||
if mock == nil {
|
||||
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 (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 {
|
||||
params := []pegomock.Param{}
|
||||
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())
|
||||
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{})
|
||||
if err != nil {
|
||||
log.Warn().Err(err).Msg("List nodes")
|
||||
log.Warn().Err(err).Msg("ListNodes")
|
||||
return
|
||||
}
|
||||
nmx, err := v.app.informer.List(watch.NodeMXIndex, "", metav1.ListOptions{})
|
||||
if err != nil {
|
||||
log.Warn().Err(err).Msg("List node metrics")
|
||||
log.Warn().Err(err).Msg("ListNodeMetrics")
|
||||
return
|
||||
}
|
||||
|
||||
var cmx k8s.ClusterMetrics
|
||||
cluster.Metrics(nos, nmx, &cmx)
|
||||
c := v.GetCell(row, 1)
|
||||
c = v.GetCell(row, 1)
|
||||
cpu := resource.AsPerc(cmx.PercCPU)
|
||||
c.SetText(cpu + deltas(strip(c.Text), cpu))
|
||||
row++
|
||||
|
|
|
|||
|
|
@ -69,6 +69,25 @@ func (mock *MockClusterMeta) ContextName() string {
|
|||
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 {
|
||||
if mock == nil {
|
||||
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 (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 {
|
||||
params := []pegomock.Param{}
|
||||
methodInvocations := pegomock.GetGenericMockFrom(verifier.mock).Verify(verifier.inOrderContext, verifier.invocationCountMatcher, "DialOrDie", params, verifier.timeout)
|
||||
|
|
|
|||
|
|
@ -459,6 +459,7 @@ func namespaced(n string) (string, string) {
|
|||
|
||||
func (v *resourceView) refreshActions() {
|
||||
if v.list.Access(resource.NamespaceAccess) {
|
||||
if ns, err := v.app.conn().CurrentNamespaceName(); err != nil || ns == "" {
|
||||
v.namespaces = make(map[int]string, config.MaxFavoritesNS)
|
||||
v.actions[tcell.Key(numKeys[0])] = newKeyAction(resource.AllNamespace, v.switchNamespaceCmd, true)
|
||||
v.namespaces[0] = resource.AllNamespace
|
||||
|
|
@ -472,6 +473,7 @@ func (v *resourceView) refreshActions() {
|
|||
index++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
v.actions[tcell.KeyEnter] = newKeyAction("Enter", v.enterCmd, false)
|
||||
v.actions[tcell.KeyCtrlR] = newKeyAction("Refresh", v.refreshCmd, false)
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ func (m *Meta) List(res, ns string, opts metav1.ListOptions) (k8s.Collection, er
|
|||
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.
|
||||
|
|
@ -90,7 +90,7 @@ func (m Meta) Get(res, fqn string, opts metav1.GetOptions) (interface{}, error)
|
|||
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.
|
||||
|
|
|
|||
|
|
@ -39,6 +39,25 @@ func (mock *MockConnection) Config() *k8s.Config {
|
|||
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 {
|
||||
if mock == nil {
|
||||
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 (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 {
|
||||
params := []pegomock.Param{}
|
||||
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 (
|
||||
"os"
|
||||
"syscall"
|
||||
|
||||
"github.com/derailed/k9s/cmd"
|
||||
"github.com/derailed/k9s/internal/config"
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/rs/zerolog/log"
|
||||
_ "k8s.io/client-go/plugin/pkg/client/auth"
|
||||
"k8s.io/klog"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
|
@ -16,6 +18,9 @@ func init() {
|
|||
mod := os.O_CREATE | os.O_APPEND | os.O_WRONLY
|
||||
if file, err := os.OpenFile(config.K9sLogs, mod, config.DefaultFileMod); err == nil {
|
||||
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 {
|
||||
panic(err)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue