cleaning up
parent
407d90edb5
commit
b536767a1f
|
|
@ -29,8 +29,8 @@ type Authorizer interface {
|
|||
CanI(ns, gvr string, verbs []string) (bool, error)
|
||||
}
|
||||
|
||||
// BOZO!! Refactor!
|
||||
// Connection represents a Kubenetes apiserver connection.
|
||||
// BOZO!! Refactor!
|
||||
type Connection interface {
|
||||
Authorizer
|
||||
|
||||
|
|
@ -203,6 +203,7 @@ func (a *APIClient) RestConfigOrDie() *restclient.Config {
|
|||
return cfg
|
||||
}
|
||||
|
||||
// CachedDiscovery returns a cached discovery client.
|
||||
func (a *APIClient) CachedDiscovery() (*disk.CachedDiscoveryClient, error) {
|
||||
a.mx.Lock()
|
||||
defer a.mx.Unlock()
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ func (g GVR) ToV() string {
|
|||
return tokens[len(tokens)-2]
|
||||
}
|
||||
|
||||
// ToRAndG returns the resource and group.
|
||||
func (g GVR) ToRAndG() (string, string) {
|
||||
tokens := strings.Split(string(g), "/")
|
||||
switch len(tokens) {
|
||||
|
|
@ -89,17 +90,20 @@ func (g GVR) ToG() string {
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// GVRs represents a collection of gvr.
|
||||
type GVRs []GVR
|
||||
|
||||
// Len returns the list size.
|
||||
func (g GVRs) Len() int {
|
||||
return len(g)
|
||||
}
|
||||
|
||||
// Swap swaps list values.
|
||||
func (g GVRs) Swap(i, j int) {
|
||||
g[i], g[j] = g[j], g[i]
|
||||
}
|
||||
|
||||
// Less returns true if i < j.
|
||||
func (g GVRs) Less(i, j int) bool {
|
||||
g1, g2 := g[i].ToG(), g[j].ToG()
|
||||
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ func (m *MetricsServer) FetchPodsMetrics(ns string) (*mv1beta1.PodMetricsList, e
|
|||
return client.MetricsV1beta1().PodMetricses(ns).List(metav1.ListOptions{})
|
||||
}
|
||||
|
||||
// FetchPodsMetrics return all metrics for pods in a given namespace.
|
||||
// FetchPodMetrics return all metrics for pods in a given namespace.
|
||||
func (m *MetricsServer) FetchPodMetrics(ns, sel string) (*mv1beta1.PodMetrics, error) {
|
||||
client, err := m.MXDial()
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ func TestBenchEmpty(t *testing.T) {
|
|||
}
|
||||
|
||||
for k := range uu {
|
||||
u := uu[k]
|
||||
u := uu[k]
|
||||
t.Run(k, func(t *testing.T) {
|
||||
assert.Equal(t, u.e, u.b.empty())
|
||||
})
|
||||
|
|
@ -48,7 +48,7 @@ func TestBenchLoad(t *testing.T) {
|
|||
}
|
||||
|
||||
for k := range uu {
|
||||
u := uu[k]
|
||||
u := uu[k]
|
||||
t.Run(k, func(t *testing.T) {
|
||||
b, err := NewBench(u.file)
|
||||
|
||||
|
|
@ -98,7 +98,7 @@ func TestBenchServiceLoad(t *testing.T) {
|
|||
}
|
||||
|
||||
for k := range uu {
|
||||
u := uu[k]
|
||||
u := uu[k]
|
||||
t.Run(k, func(t *testing.T) {
|
||||
b, err := NewBench("test_assets/b_good.yml")
|
||||
|
||||
|
|
@ -169,7 +169,7 @@ func TestBenchContainerLoad(t *testing.T) {
|
|||
}
|
||||
|
||||
for k := range uu {
|
||||
u := uu[k]
|
||||
u := uu[k]
|
||||
t.Run(k, func(t *testing.T) {
|
||||
b, err := NewBench("test_assets/b_containers.yml")
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,9 @@ var (
|
|||
K9sStylesFile = filepath.Join(K9sHome, "skin.yml")
|
||||
)
|
||||
|
||||
// StyleListener represents a skin's listener.
|
||||
type StyleListener interface {
|
||||
// StylesChanged notifies listener the skin changed.
|
||||
StylesChanged(*Styles)
|
||||
}
|
||||
|
||||
|
|
@ -278,10 +280,12 @@ func (s *Styles) BgColor() tcell.Color {
|
|||
return AsColor(s.Body().BgColor)
|
||||
}
|
||||
|
||||
// AddListener registers a new listener.
|
||||
func (s *Styles) AddListener(l StyleListener) {
|
||||
s.listeners = append(s.listeners, l)
|
||||
}
|
||||
|
||||
// RemoveListener unregister a listener.
|
||||
func (s *Styles) RemoveListener(l StyleListener) {
|
||||
victim := -1
|
||||
for i, lis := range s.listeners {
|
||||
|
|
@ -322,7 +326,7 @@ func (s *Styles) Title() Title {
|
|||
return s.Frame().Title
|
||||
}
|
||||
|
||||
// Table returns table styles.
|
||||
// GetTable returns table styles.
|
||||
func (s *Styles) GetTable() Table {
|
||||
return s.K9s.Table
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ func NewAlias(f Factory) *Alias {
|
|||
}
|
||||
}
|
||||
|
||||
// ClearAliases remove all aliases.
|
||||
// Clear remove all aliases.
|
||||
func (a *Alias) Clear() {
|
||||
for k := range a.Alias {
|
||||
delete(a.Alias, k)
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import (
|
|||
restclient "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
// Container represents a pod's container dao.
|
||||
type Container struct {
|
||||
Generic
|
||||
}
|
||||
|
|
@ -21,7 +22,7 @@ type Container struct {
|
|||
var _ Accessor = &Container{}
|
||||
var _ Loggable = &Container{}
|
||||
|
||||
// Logs tails a given container logs
|
||||
// TailLogs tails a given container logs
|
||||
func (c *Container) TailLogs(ctx context.Context, logChan chan<- string, opts LogOptions) error {
|
||||
fac, ok := ctx.Value(internal.KeyFactory).(*watch.Factory)
|
||||
if !ok {
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import (
|
|||
"k8s.io/client-go/tools/clientcmd"
|
||||
)
|
||||
|
||||
// Context represents a kubenetes context.
|
||||
type Context struct {
|
||||
Generic
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import (
|
|||
|
||||
const maxJobNameSize = 42
|
||||
|
||||
// CronJob represents a cronjob K8s resource.
|
||||
type CronJob struct {
|
||||
Generic
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import (
|
|||
"k8s.io/kubectl/pkg/polymorphichelpers"
|
||||
)
|
||||
|
||||
// Deployment represents a deployment K8s resource.
|
||||
type Deployment struct {
|
||||
Generic
|
||||
}
|
||||
|
|
@ -59,7 +60,7 @@ func (d *Deployment) Restart(path string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
// Logs tail logs for all pods represented by this Deployment.
|
||||
// TailLogs tail logs for all pods represented by this Deployment.
|
||||
func (d *Deployment) TailLogs(ctx context.Context, c chan<- string, opts LogOptions) error {
|
||||
o, err := d.Get(string(d.gvr), opts.Path, labels.Everything())
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -6,12 +6,14 @@ import (
|
|||
"k8s.io/client-go/dynamic"
|
||||
)
|
||||
|
||||
// Generic represents a generic resource.
|
||||
type Generic struct {
|
||||
Factory
|
||||
|
||||
gvr client.GVR
|
||||
}
|
||||
|
||||
// Init initializes the resource.
|
||||
func (r *Generic) Init(f Factory, gvr client.GVR) {
|
||||
r.Factory, r.gvr = f, gvr
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import (
|
|||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// Job represents a K8s job resource.
|
||||
type Job struct {
|
||||
Generic
|
||||
}
|
||||
|
|
@ -18,7 +19,7 @@ type Job struct {
|
|||
var _ Accessor = &Job{}
|
||||
var _ Loggable = &Job{}
|
||||
|
||||
// Logs tail logs for all pods represented by this Job.
|
||||
// TailLogs tail logs for all pods represented by this Job.
|
||||
func (j *Job) TailLogs(ctx context.Context, c chan<- string, opts LogOptions) error {
|
||||
o, err := j.Get(string(j.gvr), opts.Path, labels.Everything())
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package dao
|
||||
|
||||
// PortForward represents a port forward dao.
|
||||
type PortForward struct {
|
||||
Generic
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import (
|
|||
"k8s.io/kubectl/pkg/polymorphichelpers"
|
||||
)
|
||||
|
||||
// StatefulSet represents a K8s sts.
|
||||
type StatefulSet struct {
|
||||
Generic
|
||||
}
|
||||
|
|
@ -59,22 +60,22 @@ func (s *StatefulSet) Restart(path string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
// Logs tail logs for all pods represented by this StatefulSet.
|
||||
// TailLogs tail logs for all pods represented by this StatefulSet.
|
||||
func (s *StatefulSet) TailLogs(ctx context.Context, c chan<- string, opts LogOptions) error {
|
||||
o, err := s.Get(string(s.gvr), opts.Path, labels.Everything())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var dp appsv1.StatefulSet
|
||||
err = runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, &dp)
|
||||
var sts appsv1.StatefulSet
|
||||
err = runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, &sts)
|
||||
if err != nil {
|
||||
return errors.New("expecting StatefulSet resource")
|
||||
}
|
||||
|
||||
if dp.Spec.Selector == nil || len(dp.Spec.Selector.MatchLabels) == 0 {
|
||||
if sts.Spec.Selector == nil || len(sts.Spec.Selector.MatchLabels) == 0 {
|
||||
return fmt.Errorf("No valid selector found on StatefulSet %s", opts.Path)
|
||||
}
|
||||
|
||||
return podLogs(ctx, c, dp.Spec.Selector.MatchLabels, opts)
|
||||
return podLogs(ctx, c, sts.Spec.Selector.MatchLabels, opts)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,158 +7,158 @@ import (
|
|||
// BOZO!! Break up deps and merge into single registrar
|
||||
var Registry = map[string]ResourceMeta{
|
||||
// Custom...
|
||||
"containers": ResourceMeta{
|
||||
"containers": {
|
||||
Model: &Container{},
|
||||
Renderer: &render.Container{},
|
||||
},
|
||||
"contexts": ResourceMeta{
|
||||
"contexts": {
|
||||
Model: &Context{},
|
||||
Renderer: &render.Context{},
|
||||
},
|
||||
"screendumps": ResourceMeta{
|
||||
"screendumps": {
|
||||
Model: &ScreenDump{},
|
||||
Renderer: &render.ScreenDump{},
|
||||
},
|
||||
"rbac": ResourceMeta{
|
||||
"rbac": {
|
||||
Model: &Rbac{},
|
||||
Renderer: &render.Rbac{},
|
||||
},
|
||||
"policy": ResourceMeta{
|
||||
"policy": {
|
||||
Model: &Policy{},
|
||||
Renderer: &render.Policy{},
|
||||
},
|
||||
"users": ResourceMeta{
|
||||
"users": {
|
||||
Model: &Subject{},
|
||||
Renderer: &render.Subject{},
|
||||
},
|
||||
"groups": ResourceMeta{
|
||||
"groups": {
|
||||
Model: &Subject{},
|
||||
Renderer: &render.Subject{},
|
||||
},
|
||||
"portforwards": ResourceMeta{
|
||||
"portforwards": {
|
||||
Model: &PortForward{},
|
||||
Renderer: &render.PortForward{},
|
||||
},
|
||||
"benchmarks": ResourceMeta{
|
||||
"benchmarks": {
|
||||
Model: &Benchmark{},
|
||||
Renderer: &render.Benchmark{},
|
||||
},
|
||||
"aliases": ResourceMeta{
|
||||
"aliases": {
|
||||
Model: &Alias{},
|
||||
Renderer: &render.Alias{},
|
||||
},
|
||||
|
||||
// Core...
|
||||
"v1/configmaps": ResourceMeta{
|
||||
"v1/configmaps": {
|
||||
Renderer: &render.ConfigMap{},
|
||||
},
|
||||
"v1/endpoints": ResourceMeta{
|
||||
"v1/endpoints": {
|
||||
Renderer: &render.Endpoints{},
|
||||
},
|
||||
"v1/events": ResourceMeta{
|
||||
"v1/events": {
|
||||
Renderer: &render.Event{},
|
||||
},
|
||||
"v1/pods": ResourceMeta{
|
||||
"v1/pods": {
|
||||
Model: &Pod{},
|
||||
Renderer: &render.Pod{},
|
||||
},
|
||||
"v1/namespaces": ResourceMeta{
|
||||
"v1/namespaces": {
|
||||
Renderer: &render.Namespace{},
|
||||
},
|
||||
"v1/nodes": ResourceMeta{
|
||||
"v1/nodes": {
|
||||
Model: &Node{},
|
||||
Renderer: &render.Node{},
|
||||
},
|
||||
"v1/secrets": ResourceMeta{
|
||||
"v1/secrets": {
|
||||
Renderer: &render.Secret{},
|
||||
},
|
||||
"v1/services": ResourceMeta{
|
||||
"v1/services": {
|
||||
Renderer: &render.Service{},
|
||||
},
|
||||
"v1/serviceaccounts": ResourceMeta{
|
||||
"v1/serviceaccounts": {
|
||||
Renderer: &render.ServiceAccount{},
|
||||
},
|
||||
|
||||
// Apps...
|
||||
"apps/v1/deployments": ResourceMeta{
|
||||
"apps/v1/deployments": {
|
||||
Renderer: &render.Deployment{},
|
||||
},
|
||||
"apps/v1/replicasets": ResourceMeta{
|
||||
"apps/v1/replicasets": {
|
||||
Renderer: &render.ReplicaSet{},
|
||||
},
|
||||
"apps/v1/statefulsets": ResourceMeta{
|
||||
"apps/v1/statefulsets": {
|
||||
Renderer: &render.StatefulSet{},
|
||||
},
|
||||
"apps/v1/daemonsets": ResourceMeta{
|
||||
"apps/v1/daemonsets": {
|
||||
Renderer: &render.DaemonSet{},
|
||||
},
|
||||
|
||||
// Extensions...
|
||||
"extensions/v1beta1/daemonsets": ResourceMeta{
|
||||
"extensions/v1beta1/daemonsets": {
|
||||
Renderer: &render.DaemonSet{},
|
||||
},
|
||||
"extensions/v1beta1/ingresses": ResourceMeta{
|
||||
"extensions/v1beta1/ingresses": {
|
||||
Renderer: &render.Ingress{},
|
||||
},
|
||||
"extensions/v1beta1/networkpolicies": ResourceMeta{
|
||||
"extensions/v1beta1/networkpolicies": {
|
||||
Renderer: &render.NetworkPolicy{},
|
||||
},
|
||||
|
||||
// Batch...
|
||||
"batch/v1beta1/cronjobs": ResourceMeta{
|
||||
"batch/v1beta1/cronjobs": {
|
||||
Renderer: &render.CronJob{},
|
||||
},
|
||||
"batch/v1/jobs": ResourceMeta{
|
||||
"batch/v1/jobs": {
|
||||
Model: &Job{},
|
||||
Renderer: &render.Job{},
|
||||
},
|
||||
|
||||
// Autoscaling...
|
||||
"autoscaling/v1/horizontalpodautoscalers": ResourceMeta{
|
||||
"autoscaling/v1/horizontalpodautoscalers": {
|
||||
Model: &HorizontalPodAutoscaler{},
|
||||
Renderer: &render.HorizontalPodAutoscaler{},
|
||||
},
|
||||
"autoscaling/v2beta1/horizontalpodautoscalers": ResourceMeta{
|
||||
"autoscaling/v2beta1/horizontalpodautoscalers": {
|
||||
Model: &HorizontalPodAutoscaler{},
|
||||
Renderer: &render.HorizontalPodAutoscaler{},
|
||||
},
|
||||
"autoscaling/v2beta2/horizontalpodautoscalers": ResourceMeta{
|
||||
"autoscaling/v2beta2/horizontalpodautoscalers": {
|
||||
Model: &HorizontalPodAutoscaler{},
|
||||
Renderer: &render.HorizontalPodAutoscaler{},
|
||||
},
|
||||
|
||||
// CRDs...
|
||||
"apiextensions.k8s.io/v1/customresourcedefinitions": ResourceMeta{
|
||||
"apiextensions.k8s.io/v1/customresourcedefinitions": {
|
||||
Model: &CustomResourceDefinition{},
|
||||
Renderer: &render.CustomResourceDefinition{},
|
||||
},
|
||||
"apiextensions.k8s.io/v1beta1/customresourcedefinitions": ResourceMeta{
|
||||
"apiextensions.k8s.io/v1beta1/customresourcedefinitions": {
|
||||
Model: &CustomResourceDefinition{},
|
||||
Renderer: &render.CustomResourceDefinition{},
|
||||
},
|
||||
|
||||
// Storage...
|
||||
"storage.k8s.io/v1/storageclasses": ResourceMeta{
|
||||
"storage.k8s.io/v1/storageclasses": {
|
||||
Renderer: &render.StorageClass{},
|
||||
},
|
||||
|
||||
// Policy...
|
||||
"policy/v1beta1/poddisruptionbudgets": ResourceMeta{
|
||||
"policy/v1beta1/poddisruptionbudgets": {
|
||||
Renderer: &render.PodDisruptionBudget{},
|
||||
},
|
||||
|
||||
// RBAC...
|
||||
"rbac.authorization.k8s.io/v1/clusterroles": ResourceMeta{
|
||||
"rbac.authorization.k8s.io/v1/clusterroles": {
|
||||
Model: &Rbac{},
|
||||
Renderer: &render.ClusterRole{},
|
||||
},
|
||||
"rbac.authorization.k8s.io/v1/clusterrolebindings": ResourceMeta{
|
||||
"rbac.authorization.k8s.io/v1/clusterrolebindings": {
|
||||
Renderer: &render.ClusterRoleBinding{},
|
||||
},
|
||||
"rbac.authorization.k8s.io/v1/roles": ResourceMeta{
|
||||
"rbac.authorization.k8s.io/v1/roles": {
|
||||
Renderer: &render.Role{},
|
||||
},
|
||||
"rbac.authorization.k8s.io/v1/rolebindings": ResourceMeta{
|
||||
"rbac.authorization.k8s.io/v1/rolebindings": {
|
||||
Renderer: &render.RoleBinding{},
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ type StackEvent struct {
|
|||
// Kind represents the event condition.
|
||||
Action StackAction
|
||||
|
||||
// Item represents the targetted item.
|
||||
// Item represents the targeted item.
|
||||
Component Component
|
||||
}
|
||||
|
||||
|
|
@ -47,7 +47,7 @@ func NewStack() *Stack {
|
|||
return &Stack{}
|
||||
}
|
||||
|
||||
// Flatten retuns a string representation of the component stack.
|
||||
// Flatten returns a string representation of the component stack.
|
||||
func (s *Stack) Flatten() []string {
|
||||
ss := make([]string, len(s.components))
|
||||
for i, c := range s.components {
|
||||
|
|
|
|||
|
|
@ -16,11 +16,16 @@ const (
|
|||
noDataCount = 2
|
||||
)
|
||||
|
||||
// TableListener represents a table model listener.
|
||||
type TableListener interface {
|
||||
// TableDataChanged notifies the model data changed.
|
||||
TableDataChanged(render.TableData)
|
||||
|
||||
// TableLoadFailed notifies the load failed.
|
||||
TableLoadFailed(error)
|
||||
}
|
||||
|
||||
// Table represents a table model.
|
||||
type Table struct {
|
||||
gvr string
|
||||
namespace string
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ type Lister interface {
|
|||
Hydrate(oo []runtime.Object, rr render.Rows, r Renderer) error
|
||||
}
|
||||
|
||||
// Factory represents a K8s resource factory.
|
||||
type Factory interface {
|
||||
// Client retrieves an api client.
|
||||
Client() client.Connection
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ type NamedContext struct {
|
|||
Config ContextNamer
|
||||
}
|
||||
|
||||
// ContextNamer represents a named context.
|
||||
type ContextNamer interface {
|
||||
CurrentContextName() (string, error)
|
||||
}
|
||||
|
|
@ -80,7 +81,7 @@ func NewNamedContext(c ContextNamer, n string, ctx *api.Context) *NamedContext {
|
|||
return &NamedContext{Name: n, Context: ctx, Config: c}
|
||||
}
|
||||
|
||||
// MustCurrentContextName return the active context name.
|
||||
// IsCurrentContext return the active context name.
|
||||
func (c *NamedContext) IsCurrentContext(n string) bool {
|
||||
cl, err := c.Config.CurrentContextName()
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ func cleanseResource(r string) string {
|
|||
return n
|
||||
}
|
||||
|
||||
// PolicyRes represents a rback policy rule.
|
||||
type PolicyRes struct {
|
||||
Namespace, Binding string
|
||||
Resource, Group string
|
||||
|
|
@ -76,6 +77,7 @@ type PolicyRes struct {
|
|||
Verbs []string
|
||||
}
|
||||
|
||||
// NewPolicyRes returns a new policy.
|
||||
func NewPolicyRes(ns, binding, res, grp string, vv []string) PolicyRes {
|
||||
return PolicyRes{
|
||||
Namespace: ns,
|
||||
|
|
@ -96,8 +98,10 @@ func (p PolicyRes) DeepCopyObject() runtime.Object {
|
|||
return p
|
||||
}
|
||||
|
||||
// Policies represents a collection of RBAC policies.
|
||||
type Policies []PolicyRes
|
||||
|
||||
// Upsert adds a new policy.
|
||||
func (pp Policies) Upsert(p PolicyRes) Policies {
|
||||
idx, ok := pp.findPol(p.Resource)
|
||||
if !ok {
|
||||
|
|
|
|||
|
|
@ -116,6 +116,7 @@ func hasVerb(verbs []string, verb string) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
// RuleRes represents an rbac rule.
|
||||
type RuleRes struct {
|
||||
Resource, Group string
|
||||
ResourceName string
|
||||
|
|
@ -123,6 +124,7 @@ type RuleRes struct {
|
|||
Verbs []string
|
||||
}
|
||||
|
||||
// NewRuleRes returns a new rule.
|
||||
func NewRuleRes(res, grp string, vv []string) RuleRes {
|
||||
return RuleRes{
|
||||
Resource: res,
|
||||
|
|
@ -141,8 +143,10 @@ func (r RuleRes) DeepCopyObject() runtime.Object {
|
|||
return r
|
||||
}
|
||||
|
||||
// Rules represents a collection of rules.
|
||||
type Rules []RuleRes
|
||||
|
||||
// Upsert adds a new rule.
|
||||
func (rr Rules) Upsert(r RuleRes) Rules {
|
||||
idx, ok := rr.find(r.Resource)
|
||||
if !ok {
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ func (r RowEvent) Clone() RowEvent {
|
|||
}
|
||||
}
|
||||
|
||||
// Changed returns true if the row changed.
|
||||
func (r RowEvent) Changed(re RowEvent) bool {
|
||||
if r.Kind != re.Kind {
|
||||
log.Debug().Msgf("KIND Changed")
|
||||
|
|
@ -229,8 +230,10 @@ func findIndex(ss []string, s string) int {
|
|||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// StringSet represents a collection of unique strings.
|
||||
type StringSet []string
|
||||
|
||||
// Add adds a new item in the set.
|
||||
func (ss StringSet) Add(item string) StringSet {
|
||||
if ss.In(item) {
|
||||
return ss
|
||||
|
|
@ -238,6 +241,7 @@ func (ss StringSet) Add(item string) StringSet {
|
|||
return append(ss, item)
|
||||
}
|
||||
|
||||
// In checks if a string is in the set.
|
||||
func (ss StringSet) In(item string) bool {
|
||||
return ss.indexOf(item) >= 0
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ func (t *TableData) Update(rows Rows) {
|
|||
}
|
||||
}
|
||||
|
||||
// EnsureDeletes delete items in cache that are no longer valid.
|
||||
// Delete delete items in cache that are no longer valid.
|
||||
func (t *TableData) Delete(newKeys []string) {
|
||||
for _, re := range t.RowEvents {
|
||||
var found bool
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ func (a *App) Init() {
|
|||
a.SetRoot(a.Main, true)
|
||||
}
|
||||
|
||||
// ReloadStyles reloads skin file.
|
||||
func (a *App) ReloadStyles(cluster string) {
|
||||
a.RefreshStyles(cluster)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ type Configurator struct {
|
|||
Bench *config.Bench
|
||||
}
|
||||
|
||||
// HasSkins returns true if a skin file was located.
|
||||
func (c *Configurator) HasSkins() bool {
|
||||
return c.skinFile != ""
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ func NewFlash(app *App, m string) *Flash {
|
|||
return &f
|
||||
}
|
||||
|
||||
// StylesChanged notifies listener the skin changed.
|
||||
func (f *Flash) StylesChanged(s *config.Styles) {
|
||||
f.SetBackgroundColor(s.BgColor())
|
||||
f.SetTextColor(s.FgColor())
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ func NewStatusIndicator(app *App, styles *config.Styles) *StatusIndicator {
|
|||
return &s
|
||||
}
|
||||
|
||||
// StyleChanged notifies the skins changed.
|
||||
func (s *StatusIndicator) StylesChanged(styles *config.Styles) {
|
||||
s.styles = styles
|
||||
s.SetBackgroundColor(styles.BgColor())
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ type Tabular interface {
|
|||
AddListener(model.TableListener)
|
||||
}
|
||||
|
||||
// Selectable represents a table with selections.
|
||||
// SelectTable represents a table with selections.
|
||||
type SelectTable struct {
|
||||
*tview.Table
|
||||
|
||||
|
|
@ -120,7 +120,7 @@ func (s *SelectTable) SetSelectedFn(f func(string) string) {
|
|||
s.selectedFn = f
|
||||
}
|
||||
|
||||
// GetSelectedRow fetch the currently selected row index.
|
||||
// GetSelectedRowIndex fetch the currently selected row index.
|
||||
func (s *SelectTable) GetSelectedRowIndex() int {
|
||||
return s.selectedRow
|
||||
}
|
||||
|
|
@ -184,6 +184,7 @@ func (s *SelectTable) ToggleMark() {
|
|||
)
|
||||
}
|
||||
|
||||
// IsMarked returns true if this item was marked.
|
||||
func (s *Table) IsMarked(item string) bool {
|
||||
return s.marks[item]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ var LogoSmall = []string{
|
|||
` \/ \/ `,
|
||||
}
|
||||
|
||||
// Logo K9s big logo for splash page.
|
||||
// LogoBig K9s big logo for splash page.
|
||||
var LogoBig = []string{
|
||||
` ____ __.________ _________ .____ .___ `,
|
||||
`| |/ _/ __ \_____\_ ___ \| | | |`,
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ func (a *App) ActiveView() model.Component {
|
|||
return a.Content.GetPrimitive("main").(model.Component)
|
||||
}
|
||||
|
||||
// PrevCmd pops the command stack.
|
||||
func (a *App) PrevCmd(evt *tcell.EventKey) *tcell.EventKey {
|
||||
if !a.Content.IsLast() {
|
||||
a.Content.Pop()
|
||||
|
|
@ -64,6 +65,7 @@ func (a *App) PrevCmd(evt *tcell.EventKey) *tcell.EventKey {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Init initializes the application.
|
||||
func (a *App) Init(version string, rate int) error {
|
||||
ctx := context.WithValue(context.Background(), internal.KeyApp, a)
|
||||
if err := a.Content.Init(ctx); err != nil {
|
||||
|
|
@ -112,6 +114,7 @@ func (a *App) Init(version string, rate int) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// StylesChanges notifies the skin changed.
|
||||
func (a *App) StylesChanged(s *config.Styles) {
|
||||
a.Main.SetBackgroundColor(s.BgColor())
|
||||
if f, ok := a.Main.GetPrimitive("main").(*tview.Flex); ok {
|
||||
|
|
@ -136,10 +139,10 @@ func (a *App) bindKeys() {
|
|||
})
|
||||
}
|
||||
|
||||
// Changed indicates the buffer was changed.
|
||||
// BufferChanged indicates the buffer was changed.
|
||||
func (a *App) BufferChanged(s string) {}
|
||||
|
||||
// Active indicates the buff activity changed.
|
||||
// BufferActive indicates the buff activity changed.
|
||||
func (a *App) BufferActive(state bool, _ ui.BufferKind) {
|
||||
flex, ok := a.Main.GetPrimitive("main").(*tview.Flex)
|
||||
if !ok {
|
||||
|
|
@ -185,12 +188,14 @@ func (a *App) buildHeader() tview.Primitive {
|
|||
return header
|
||||
}
|
||||
|
||||
// Halt stop the application event loop.
|
||||
func (a *App) Halt() {
|
||||
if a.cancelFn != nil {
|
||||
a.cancelFn()
|
||||
}
|
||||
}
|
||||
|
||||
// Resume restarts the app event loop.
|
||||
func (a *App) Resume() {
|
||||
var ctx context.Context
|
||||
ctx, a.cancelFn = context.WithCancel(context.Background())
|
||||
|
|
@ -338,6 +343,7 @@ func (a *App) Run() {
|
|||
}
|
||||
}
|
||||
|
||||
// Status reports a new app status for display.
|
||||
func (a *App) Status(l ui.FlashLevel, msg string) {
|
||||
a.Flash().Info(msg)
|
||||
a.setIndicator(l, msg)
|
||||
|
|
@ -345,7 +351,7 @@ func (a *App) Status(l ui.FlashLevel, msg string) {
|
|||
a.Draw()
|
||||
}
|
||||
|
||||
// StatusReset reset log back to normal.
|
||||
// ClearStatus reset log back to normal.
|
||||
func (a *App) ClearStatus() {
|
||||
a.Logo().Reset()
|
||||
a.Flash().Clear()
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import (
|
|||
// ContextFunc enhances a given context.
|
||||
type ContextFunc func(context.Context) context.Context
|
||||
|
||||
// BindKeysFunc adds new menu actions.
|
||||
type BindKeysFunc func(ui.KeyActions)
|
||||
|
||||
// Browser represents a generic resource browser.
|
||||
|
|
@ -181,7 +182,7 @@ func (b *Browser) GVR() string { return string(b.gvr) }
|
|||
// GetTable returns the underlying table.
|
||||
func (b *Browser) GetTable() *Table { return b.Table }
|
||||
|
||||
// TableLoadChanged notifies view something went south.
|
||||
// TableLoadFailed notifies view something went south.
|
||||
func (b *Browser) TableLoadFailed(err error) {
|
||||
b.app.QueueUpdateDraw(func() {
|
||||
b.app.Flash().Err(err)
|
||||
|
|
@ -497,10 +498,12 @@ func (b *Browser) refreshActions() {
|
|||
b.app.Menu().HydrateMenu(b.Hints())
|
||||
}
|
||||
|
||||
// Aliases returns all available aliases.
|
||||
func (b *Browser) Aliases() []string {
|
||||
return append(b.meta.ShortNames, b.meta.SingularName, b.meta.Name)
|
||||
}
|
||||
|
||||
// EnvFn returns an plugin env function if available.
|
||||
func (b *Browser) EnvFn() EnvFunc {
|
||||
return b.envFn
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ func (c *ClusterInfo) init(version string) {
|
|||
c.refresh()
|
||||
}
|
||||
|
||||
// StylesChanges notifies skin changed.
|
||||
// StylesChanged notifies skin changed.
|
||||
func (c *ClusterInfo) StylesChanged(s *config.Styles) {
|
||||
c.styles = s
|
||||
c.SetBackgroundColor(s.BgColor())
|
||||
|
|
|
|||
|
|
@ -13,18 +13,21 @@ import (
|
|||
|
||||
var customViewers MetaViewers
|
||||
|
||||
// Command represents a user command.
|
||||
type Command struct {
|
||||
app *App
|
||||
|
||||
alias *dao.Alias
|
||||
}
|
||||
|
||||
// NewCommand returns a new command.
|
||||
func NewCommand(app *App) *Command {
|
||||
return &Command{
|
||||
app: app,
|
||||
}
|
||||
}
|
||||
|
||||
// Init initializes the command.
|
||||
func (c *Command) Init() error {
|
||||
c.alias = dao.NewAlias(c.app.factory)
|
||||
if _, err := c.alias.Ensure(); err != nil {
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ type Container struct {
|
|||
ResourceViewer
|
||||
}
|
||||
|
||||
// New Container returns a new container view.
|
||||
// NewContainer returns a new container view.
|
||||
func NewContainer(gvr client.GVR) ResourceViewer {
|
||||
c := Container{}
|
||||
c.ResourceViewer = NewLogsExtender(NewBrowser(gvr), c.selectedContainer)
|
||||
|
|
|
|||
|
|
@ -12,10 +12,12 @@ import (
|
|||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// DaemonSet represents a daemon set custom viewer.
|
||||
type DaemonSet struct {
|
||||
ResourceViewer
|
||||
}
|
||||
|
||||
// NewDaemonSet returns a new viewer.
|
||||
func NewDaemonSet(gvr client.GVR) ResourceViewer {
|
||||
d := DaemonSet{
|
||||
ResourceViewer: NewRestartExtender(
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ func TestK9sEnv(t *testing.T) {
|
|||
}
|
||||
|
||||
for k := range uu {
|
||||
u := uu[k]
|
||||
u := uu[k]
|
||||
t.Run(k, func(t *testing.T) {
|
||||
a, err := e.envFor(u.q)
|
||||
assert.Equal(t, u.err, err)
|
||||
|
|
|
|||
|
|
@ -21,8 +21,10 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
logTitle = "logs"
|
||||
logBuffSize = 100
|
||||
logTitle = "logs"
|
||||
logBuffSize = 100
|
||||
|
||||
// FlushTimeout represents a duration between log flushes.
|
||||
FlushTimeout = 200 * time.Millisecond
|
||||
|
||||
logCoFmt = " Logs([fg:bg:]%s:[hilite:bg:b]%s[-:bg:-]) "
|
||||
|
|
@ -88,6 +90,7 @@ func (l *Log) Init(ctx context.Context) (err error) {
|
|||
return nil
|
||||
}
|
||||
|
||||
// StylesChanged reports skin changes.
|
||||
func (l *Log) StylesChanged(s *config.Styles) {
|
||||
l.SetBackgroundColor(config.AsColor(s.Views().Log.BgColor))
|
||||
l.logs.SetTextColor(config.AsColor(s.Views().Log.FgColor))
|
||||
|
|
@ -120,6 +123,7 @@ func (l *Log) Stop() {
|
|||
l.app.Styles.RemoveListener(l)
|
||||
}
|
||||
|
||||
// Name returns the component name.
|
||||
func (l *Log) Name() string { return logTitle }
|
||||
|
||||
func (l *Log) bindKeys() {
|
||||
|
|
@ -235,6 +239,7 @@ func (l *Log) keyboard(evt *tcell.EventKey) *tcell.EventKey {
|
|||
return evt
|
||||
}
|
||||
|
||||
// Logs returns the log viewer.
|
||||
func (l *Log) Logs() *Details {
|
||||
return l.logs
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,28 +32,34 @@ func NewLogIndicator(styles *config.Styles) *LogIndicator {
|
|||
return &l
|
||||
}
|
||||
|
||||
// AutoScroll reports the current scrolling status.
|
||||
func (l *LogIndicator) AutoScroll() bool {
|
||||
return atomic.LoadInt32(&l.scrollStatus) == 1
|
||||
}
|
||||
|
||||
// TextWrap reports the current wrap mode.
|
||||
func (l *LogIndicator) TextWrap() bool {
|
||||
return l.textWrap
|
||||
}
|
||||
|
||||
// FullScreen reports the current screen mode.
|
||||
func (l *LogIndicator) FullScreen() bool {
|
||||
return l.fullScreen
|
||||
}
|
||||
|
||||
// ToggleFullScreen toggles the screen mode.
|
||||
func (l *LogIndicator) ToggleFullScreen() {
|
||||
l.fullScreen = !l.fullScreen
|
||||
l.Refresh()
|
||||
}
|
||||
|
||||
// ToggleTextWrap toggles the wrap mode.
|
||||
func (l *LogIndicator) ToggleTextWrap() {
|
||||
l.textWrap = !l.textWrap
|
||||
l.Refresh()
|
||||
}
|
||||
|
||||
// ToggleAutoScroll toggles the scroll mode.
|
||||
func (l *LogIndicator) ToggleAutoScroll() {
|
||||
var val int32 = 1
|
||||
if l.AutoScroll() {
|
||||
|
|
@ -63,6 +69,7 @@ func (l *LogIndicator) ToggleAutoScroll() {
|
|||
l.Refresh()
|
||||
}
|
||||
|
||||
// Refresh updates the view.
|
||||
func (l *LogIndicator) Refresh() {
|
||||
l.Clear()
|
||||
l.update("Autoscroll: " + l.onOff(l.AutoScroll()))
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ func NewPicker() *Picker {
|
|||
}
|
||||
}
|
||||
|
||||
// Init initializes the view.
|
||||
func (v *Picker) Init(ctx context.Context) error {
|
||||
app, err := extractApp(ctx)
|
||||
if err != nil {
|
||||
|
|
@ -47,12 +48,17 @@ func (v *Picker) Init(ctx context.Context) error {
|
|||
|
||||
return nil
|
||||
}
|
||||
func (v *Picker) Start() {}
|
||||
func (v *Picker) Stop() {}
|
||||
|
||||
// Start starts the view.
|
||||
func (v *Picker) Start() {}
|
||||
|
||||
// Stop stops the view.
|
||||
func (v *Picker) Stop() {}
|
||||
|
||||
// Name returns the component name.
|
||||
func (v *Picker) Name() string { return "picker" }
|
||||
|
||||
// Protocol...
|
||||
|
||||
// Hints returns the view hints.
|
||||
func (v *Picker) Hints() model.MenuHints {
|
||||
return v.actions.Hints()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ type Secret struct {
|
|||
ResourceViewer
|
||||
}
|
||||
|
||||
// NewSecrets returns a new viewer.
|
||||
// NewSecret returns a new viewer.
|
||||
func NewSecret(gvr client.GVR) ResourceViewer {
|
||||
s := Secret{
|
||||
ResourceViewer: NewBrowser(gvr),
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import (
|
|||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
// Table represents a table viewer.
|
||||
type Table struct {
|
||||
*ui.Table
|
||||
|
||||
|
|
@ -17,6 +18,7 @@ type Table struct {
|
|||
enterFn EnterFunc
|
||||
}
|
||||
|
||||
// NewTable returns a new viewer.
|
||||
func NewTable(gvr string) *Table {
|
||||
return &Table{
|
||||
Table: ui.NewTable(gvr),
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ type (
|
|||
// EnvFunc represent the current view exposed environment.
|
||||
EnvFunc func() K9sEnv
|
||||
|
||||
// BoostActionFunc extends viewer keyboard actions.
|
||||
// BoostActionsFunc extends viewer keyboard actions.
|
||||
BoostActionsFunc func(ui.KeyActions)
|
||||
|
||||
// EnterFunc represents an enter key action.
|
||||
|
|
@ -71,16 +71,19 @@ type ResourceViewer interface {
|
|||
SetBindKeysFn(BindKeysFunc)
|
||||
}
|
||||
|
||||
// LogViewer represents a log viewer.
|
||||
type LogViewer interface {
|
||||
ResourceViewer
|
||||
|
||||
ShowLogs(prev bool)
|
||||
}
|
||||
|
||||
// RestartableViewer represents a viewer with restartable resources.
|
||||
type RestartableViewer interface {
|
||||
LogViewer
|
||||
}
|
||||
|
||||
// ScalableViewer represents a viewer with scalable resources.
|
||||
type ScalableViewer interface {
|
||||
LogViewer
|
||||
}
|
||||
|
|
@ -93,6 +96,7 @@ type SubjectViewer interface {
|
|||
SetSubject(s string)
|
||||
}
|
||||
|
||||
// ViewerFunc returns a viewer matching a given gvr.
|
||||
type ViewerFunc func(client.GVR) ResourceViewer
|
||||
|
||||
// MetaViewer represents a registered meta viewer.
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ func NewForwarders() Forwarders {
|
|||
return make(map[string]Forwarder)
|
||||
}
|
||||
|
||||
// KillAll stops and delete all port-forwards.
|
||||
// DeleteAll stops and delete all port-forwards.
|
||||
func (ff Forwarders) DeleteAll() {
|
||||
for k, f := range ff {
|
||||
log.Debug().Msgf("Deleting forwarder %s", f.Path())
|
||||
|
|
@ -68,6 +68,7 @@ func (ff Forwarders) Kill(path string) int {
|
|||
return stats
|
||||
}
|
||||
|
||||
// Dump for debug!
|
||||
func (ff Forwarders) Dump() {
|
||||
log.Debug().Msgf("----------- PORT-FORWARDS --------------")
|
||||
for k, f := range ff {
|
||||
|
|
|
|||
Loading…
Reference in New Issue