From 37569b8772eee3ae29c3a3a1eabb34f459f0b595 Mon Sep 17 00:00:00 2001 From: Fernand Galiana Date: Tue, 18 Oct 2022 09:01:20 -0600 Subject: [PATCH] K9s/rel v0.26.7 (#1816) * update batch resource api and remove unused ingress render * docs update: add rel notes + update release version --- .github/workflows/test.yml | 2 +- Dockerfile | 2 +- Makefile | 2 +- README.md | 8 +-- change_logs/release_v0.26.7.md | 44 +++++++++++++++ go.mod | 7 +-- go.sum | 14 ++--- internal/client/client.go | 22 ++++---- internal/dao/cluster.go | 12 ++--- internal/dao/cronjob.go | 2 +- internal/dao/helm.go | 4 +- internal/render/ing.go | 98 ---------------------------------- internal/render/ing_test.go | 17 ------ internal/view/cronjob.go | 19 ++++--- 14 files changed, 96 insertions(+), 157 deletions(-) create mode 100644 change_logs/release_v0.26.7.md delete mode 100644 internal/render/ing.go delete mode 100644 internal/render/ing_test.go diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 12d64dbb..1998301b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-20.04 steps: - name: Install Go - uses: actions/setup-go@v2 + uses: actions/setup-go@v3.1.0 with: go-version: 1.19 diff --git a/Dockerfile b/Dockerfile index 307e2a4f..b19c6214 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,7 +13,7 @@ RUN apk --no-cache add --update make libx11-dev git gcc libc-dev curl && make bu # Build the final Docker image FROM alpine:3.16.2 -ARG KUBECTL_VERSION="v1.24.3" +ARG KUBECTL_VERSION="v1.25.2" COPY --from=build /k9s/execs/k9s /bin/k9s RUN apk add --update ca-certificates \ diff --git a/Makefile b/Makefile index fa2db228..c8818e26 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ PACKAGE := github.com/derailed/$(NAME) GIT_REV ?= $(shell git rev-parse --short HEAD) SOURCE_DATE_EPOCH ?= $(shell date +%s) DATE ?= $(shell date -u -d @${SOURCE_DATE_EPOCH} +"%Y-%m-%dT%H:%M:%SZ") -VERSION ?= v0.26.6 +VERSION ?= v0.26.7 IMG_NAME := derailed/k9s IMAGE := ${IMG_NAME}:${VERSION} diff --git a/README.md b/README.md index 8ae42efa..e47ca370 100644 --- a/README.md +++ b/README.md @@ -87,7 +87,7 @@ K9s is available on Linux, macOS and Windows platforms. ```shell # NOTE: The dev version will be in effect! - go install github.com/derailed/k9s + go install github.com/derailed/k9s@latest ``` * Via [Webi](https://webinstall.dev) for Linux and macOS @@ -359,7 +359,7 @@ K9s uses aliases to navigate most K8s resources. - default view: active: dp - # The path to screen dump. Default: '%temp_dir%/k9s-screens-%username%' (k9s info) + # The path to screen dump. Default: '%temp_dir%/k9s-screens-%username%' (k9s info) screenDumpDir: /tmp ``` @@ -449,9 +449,9 @@ Entering the command mode and typing a resource name or alias, could be cumberso As of v0.25.0, you can leverage the `FastForwards` feature to tell K9s how to default port-forwards. In situations where you are dealing with multiple containers or containers exposing multiple ports, it can be cumbersome to specify the desired port-forward from the dialog as in most cases, you already know which container/port tuple you desire. For these use cases, you can now annotate your manifests with the following annotations: -- `k9scli.io/auto-port-forwards` +- `k9scli.io/auto-port-forwards` activates one or more port-forwards directly bypassing the port-forward dialog all together. -- `k9scli.io/port-forwards` +- `k9scli.io/port-forwards` pre-selects one or more port-forwards when launching the port-forward dialog. The annotation value takes on the shape `container-name::[local-port:]container-port` diff --git a/change_logs/release_v0.26.7.md b/change_logs/release_v0.26.7.md new file mode 100644 index 00000000..37bd3f5a --- /dev/null +++ b/change_logs/release_v0.26.7.md @@ -0,0 +1,44 @@ + + +# Release v0.26.7 + +## Notes + +Thank you to all that contributed with flushing out issues and enhancements for K9s! I'll try to mark some of these issues as fixed. But if you don't mind grab the latest rev and see if we're happier with some of the fixes! If you've filed an issue please help me verify and close. Your support, kindness and awesome suggestions to make K9s better are, as ever, very much noted and appreciated! Also big thanks to all that have allocated their own time to help others on both slack and on this repo!! + +As you may know, K9s is not pimped out by corps with deep pockets, thus if you feel K9s is helping your Kubernetes journey, please consider joining our [sponsorship program](https://github.com/sponsors/derailed) and/or make some noise on social! [@kitesurfer](https://twitter.com/kitesurfer) + +On Slack? Please join us [K9slackers](https://join.slack.com/t/k9sers/shared_invite/enQtOTA5MDEyNzI5MTU0LWQ1ZGI3MzliYzZhZWEyNzYxYzA3NjE0YTk1YmFmNzViZjIyNzhkZGI0MmJjYzhlNjdlMGJhYzE2ZGU1NjkyNTM) + +--- + +## Maintenance Release + +--- + +## A Word From Our Sponsors... + +To all the good folks below that opted to `pay it forward` and join our sponsorship program, I salute you!! + +* [Microsoft](https://github.com/microsoft) +* [Audun V. Nes](https://github.com/avnes) +* [Marco Aurelio Caldas Miranda](https://github.com/macmiranda) +* [Jon Waltom](https://github.com/jon-walton) +* [Eckl, Máté](https://github.com/ecklm) +* [Iguanasoft](https://github.com/iguanasoft) + +--- + +## Resolved Issues + +* [Issue #1805](https://github.com/derailed/k9s/issues/1805) CronJobs: allow sorting by LAST_SCHEDULE + +## Contributed PRs (Thank you!!) + +* [PR #1804](https://github.com/derailed/k9s/pull/1804) Allow multiple port forwards +* [PR #1797](https://github.com/derailed/k9s/pull/1797) README - use go install +* [PR #1793](https://github.com/derailed/k9s/pull/1793) Update CronJob version to v1 + +--- + + © 2022 Imhotep Software LLC. All materials licensed under [Apache v2.0](http://www.apache.org/licenses/LICENSE-2.0) diff --git a/go.mod b/go.mod index 84a7fa0b..33a7dd6a 100644 --- a/go.mod +++ b/go.mod @@ -26,9 +26,9 @@ require ( github.com/stretchr/testify v1.8.0 golang.org/x/text v0.4.0 gopkg.in/yaml.v2 v2.4.0 - helm.sh/helm/v3 v3.10.0 + helm.sh/helm/v3 v3.10.1 k8s.io/api v0.25.3 - k8s.io/apiextensions-apiserver v0.25.1 + k8s.io/apiextensions-apiserver v0.25.3 k8s.io/apimachinery v0.25.3 k8s.io/cli-runtime v0.25.3 k8s.io/client-go v0.25.3 @@ -145,6 +145,7 @@ require ( github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xeipuuv/gojsonschema v1.2.0 // indirect github.com/xlab/treeprint v1.1.0 // indirect + go.etcd.io/etcd/api/v3 v3.5.4 // indirect go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect @@ -159,7 +160,7 @@ require ( google.golang.org/protobuf v1.28.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/apiserver v0.25.1 // indirect + k8s.io/apiserver v0.25.3 // indirect k8s.io/component-base v0.25.3 // indirect k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1 // indirect k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed // indirect diff --git a/go.sum b/go.sum index f3c6587c..3a7c5c6f 100644 --- a/go.sum +++ b/go.sum @@ -665,6 +665,8 @@ github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f h1 github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs= github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= +go.etcd.io/etcd/api/v3 v3.5.4 h1:OHVyt3TopwtUQ2GKdd5wu3PmmipR4FTwCqoEjSyRdIc= +go.etcd.io/etcd/api/v3 v3.5.4/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A= go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= @@ -1140,8 +1142,8 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= -helm.sh/helm/v3 v3.10.0 h1:y/MYONZ/bsld9kHwqgBX2uPggnUr5hahpjwt9/jrHlI= -helm.sh/helm/v3 v3.10.0/go.mod h1:paPw0hO5KVfrCMbi1M8+P8xdfBri3IiJiVKATZsFR94= +helm.sh/helm/v3 v3.10.1 h1:uTnNlYx8QcTSNA4ZJ50Llwife4CSohUY4ehumyVf2QE= +helm.sh/helm/v3 v3.10.1/go.mod h1:CXOcs02AYvrlPMWARNYNRgf2rNP7gLJQsi/Ubd4EDrI= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -1151,12 +1153,12 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= k8s.io/api v0.25.3 h1:Q1v5UFfYe87vi5H7NU0p4RXC26PPMT8KOpr1TLQbCMQ= k8s.io/api v0.25.3/go.mod h1:o42gKscFrEVjHdQnyRenACrMtbuJsVdP+WVjqejfzmI= -k8s.io/apiextensions-apiserver v0.25.1 h1:HEIKlxj6oHaDwHgotEIX/Ld5K/RGuOFwN/TWMiQ5s5s= -k8s.io/apiextensions-apiserver v0.25.1/go.mod h1:67sgnMs2yIO2iV4DpCdS91vlP+pdnVIsG/mz60qRn44= +k8s.io/apiextensions-apiserver v0.25.3 h1:bfI4KS31w2f9WM1KLGwnwuVlW3RSRPuIsfNF/3HzR0k= +k8s.io/apiextensions-apiserver v0.25.3/go.mod h1:ZJqwpCkxIx9itilmZek7JgfUAM0dnTsA48I4krPqRmo= k8s.io/apimachinery v0.25.3 h1:7o9ium4uyUOM76t6aunP0nZuex7gDf8VGwkR5RcJnQc= k8s.io/apimachinery v0.25.3/go.mod h1:jaF9C/iPNM1FuLl7Zuy5b9v+n35HGSh6AQ4HYRkCqwo= -k8s.io/apiserver v0.25.1 h1:A3gnoQL6lhqRiwWN6f2DGBGdCb+7brCSTrW3klR9Xwc= -k8s.io/apiserver v0.25.1/go.mod h1:IB1EhM28U3cCrV+VNC06p1/YSZMCNYiH+P5sI5yLaZY= +k8s.io/apiserver v0.25.3 h1:m7+xGuG5+KYAnEsqaFtDyWMkmMMEOFYlu+NlWv5qSBI= +k8s.io/apiserver v0.25.3/go.mod h1:9bT47iM2fzRuhICJpM/RcQR9sqDDfZ7Yw60h0p3JW08= k8s.io/cli-runtime v0.25.3 h1:Zs7P7l7db/5J+KDePOVtDlArAa9pZXaDinGWGZl0aM8= k8s.io/cli-runtime v0.25.3/go.mod h1:InHHsjkyW5hQsILJGpGjeruiDZT/R0OkROQgD6GzxO4= k8s.io/client-go v0.25.3 h1:oB4Dyl8d6UbfDHD8Bv8evKylzs3BXzzufLiO27xuPs0= diff --git a/internal/client/client.go b/internal/client/client.go index cb0b80be..39c36265 100644 --- a/internal/client/client.go +++ b/internal/client/client.go @@ -20,7 +20,7 @@ import ( "k8s.io/client-go/kubernetes" restclient "k8s.io/client-go/rest" metricsapi "k8s.io/metrics/pkg/apis/metrics" - versioned "k8s.io/metrics/pkg/client/clientset/versioned" + "k8s.io/metrics/pkg/client/clientset/versioned" ) const ( @@ -188,8 +188,8 @@ func (a *APIClient) CurrentNamespaceName() (string, error) { // ServerVersion returns the current server version info. func (a *APIClient) ServerVersion() (*version.Info, error) { if v, ok := a.cache.Get(serverVersion); ok { - if version, ok := v.(*version.Info); ok { - return version, nil + if vi, ok := v.(*version.Info); ok { + return vi, nil } } dial, err := a.CachedDiscovery() @@ -242,7 +242,7 @@ func (a *APIClient) CheckConnectivity() bool { } }() - // Need to reload to pickup any kubeconfig changes. + // Need reload to pick up any kubeconfig changes. cfg, err := NewConfig(a.config.flags).RESTConfig() if err != nil { log.Error().Err(err).Msgf("restConfig load failed") @@ -281,10 +281,10 @@ func (a *APIClient) HasMetrics() bool { return err == nil } -// LogDial returns a handle to api server for logs. +// DialLogs returns a handle to api server for logs. func (a *APIClient) DialLogs() (kubernetes.Interface, error) { if !a.connOK { - return nil, errors.New("No connection to dial") + return nil, errors.New("no connection to dial") } if a.logClient != nil { return a.logClient, nil @@ -305,7 +305,7 @@ func (a *APIClient) DialLogs() (kubernetes.Interface, error) { // Dial returns a handle to api server or die. func (a *APIClient) Dial() (kubernetes.Interface, error) { if !a.connOK { - return nil, errors.New("No connection to dial") + return nil, errors.New("no connection to dial") } if a.client != nil { return a.client, nil @@ -333,7 +333,7 @@ func (a *APIClient) CachedDiscovery() (*disk.CachedDiscoveryClient, error) { defer a.mx.Unlock() if !a.connOK { - return nil, errors.New("No connection to cached dial") + return nil, errors.New("no connection to cached dial") } if a.cachedClient != nil { @@ -406,7 +406,7 @@ func (a *APIClient) SwitchContext(name string) error { a.mx.Unlock() if !a.CheckConnectivity() { - return fmt.Errorf("Unable to connect to context %q", name) + return fmt.Errorf("unable to connect to context %q", name) } return nil @@ -465,9 +465,9 @@ func (a *APIClient) supportsMetricsResources() error { } func checkMetricsVersion(grp metav1.APIGroup) bool { - for _, version := range grp.Versions { + for _, v := range grp.Versions { for _, supportedVersion := range supportedMetricsAPIVersions { - if version.Version == supportedVersion { + if v.Version == supportedVersion { return true } } diff --git a/internal/dao/cluster.go b/internal/dao/cluster.go index b4272360..38d8cb5c 100644 --- a/internal/dao/cluster.go +++ b/internal/dao/cluster.go @@ -40,12 +40,12 @@ var ( func scanners() map[string]RefScanner { return map[string]RefScanner{ - "apps/v1/deployments": &Deployment{}, - "apps/v1/statefulsets": &StatefulSet{}, - "apps/v1/daemonsets": &DaemonSet{}, - "batch/v1/jobs": &Job{}, - "batch/v1beta1/cronjobs": &CronJob{}, - "v1/pods": &Pod{}, + "apps/v1/deployments": &Deployment{}, + "apps/v1/statefulsets": &StatefulSet{}, + "apps/v1/daemonsets": &DaemonSet{}, + "batch/v1/jobs": &Job{}, + "batch/v1/cronjobs": &CronJob{}, + "v1/pods": &Pod{}, } } diff --git a/internal/dao/cronjob.go b/internal/dao/cronjob.go index 59355865..ace45c80 100644 --- a/internal/dao/cronjob.go +++ b/internal/dao/cronjob.go @@ -62,7 +62,7 @@ func (c *CronJob) Run(path string) error { Labels: cj.Spec.JobTemplate.Labels, OwnerReferences: []metav1.OwnerReference{ { - APIVersion: c.gvr.G() + "/" + c.gvr.V(), + APIVersion: c.gvr.GV().String(), Kind: "CronJob", BlockOwnerDeletion: &true, Name: cj.Name, diff --git a/internal/dao/helm.go b/internal/dao/helm.go index afc4f21f..322d2aa0 100644 --- a/internal/dao/helm.go +++ b/internal/dao/helm.go @@ -117,7 +117,9 @@ func (h *Helm) Delete(_ context.Context, path string, _ *metav1.DeletionPropagat if err != nil { return err } - res, err := action.NewUninstall(cfg).Run(n) + u := action.NewUninstall(cfg) + u.KeepHistory = true + res, err := u.Run(n) if err != nil { return err } diff --git a/internal/render/ing.go b/internal/render/ing.go deleted file mode 100644 index ea76de54..00000000 --- a/internal/render/ing.go +++ /dev/null @@ -1,98 +0,0 @@ -package render - -import ( - "fmt" - "strings" - - "github.com/derailed/k9s/internal/client" - v1 "k8s.io/api/core/v1" - netv1 "k8s.io/api/networking/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime" -) - -// Ingress renders a K8s Ingress to screen. -type Ingress struct{} - -// ColorerFunc colors a resource row. -func (Ingress) ColorerFunc() ColorerFunc { - return DefaultColorer -} - -// Header returns a header row. -func (Ingress) Header(ns string) Header { - return Header{ - HeaderColumn{Name: "NAMESPACE"}, - HeaderColumn{Name: "NAME"}, - HeaderColumn{Name: "CLASS"}, - HeaderColumn{Name: "HOSTS"}, - HeaderColumn{Name: "ADDRESS"}, - HeaderColumn{Name: "PORTS"}, - HeaderColumn{Name: "LABELS", Wide: true}, - HeaderColumn{Name: "AGE", Time: true}, - } -} - -// Render renders a K8s resource to screen. -func (i Ingress) Render(o interface{}, ns string, r *Row) error { - raw, ok := o.(*unstructured.Unstructured) - if !ok { - return fmt.Errorf("Expected Ingress, but got %T", o) - } - var ing netv1.Ingress - err := runtime.DefaultUnstructuredConverter.FromUnstructured(raw.Object, &ing) - if err != nil { - return err - } - - r.ID = client.MetaFQN(ing.ObjectMeta) - r.Fields = Fields{ - ing.Namespace, - ing.Name, - strpToStr(ing.Spec.IngressClassName), - toHosts(ing.Spec.Rules), - toAddress(ing.Status.LoadBalancer), - toTLSPorts(ing.Spec.TLS), - mapToStr(ing.Labels), - toAge(ing.GetCreationTimestamp()), - } - - return nil -} - -// ---------------------------------------------------------------------------- -// Helpers... - -func toAddress(lbs v1.LoadBalancerStatus) string { - ings := lbs.Ingress - res := make([]string, 0, len(ings)) - for _, lb := range ings { - if len(lb.IP) > 0 { - res = append(res, lb.IP) - } else if len(lb.Hostname) != 0 { - res = append(res, lb.Hostname) - } - } - - return strings.Join(res, ",") -} - -func toTLSPorts(tls []netv1.IngressTLS) string { - if len(tls) != 0 { - return "80, 443" - } - - return "80" -} - -func toHosts(rr []netv1.IngressRule) string { - hh := make([]string, 0, len(rr)) - for _, r := range rr { - if r.Host == "" { - r.Host = "*" - } - hh = append(hh, r.Host) - } - - return strings.Join(hh, ",") -} diff --git a/internal/render/ing_test.go b/internal/render/ing_test.go deleted file mode 100644 index 0aa871fa..00000000 --- a/internal/render/ing_test.go +++ /dev/null @@ -1,17 +0,0 @@ -package render_test - -import ( - "testing" - - "github.com/derailed/k9s/internal/render" - "github.com/stretchr/testify/assert" -) - -func TestIngressRender(t *testing.T) { - c := render.Ingress{} - r := render.NewRow(6) - c.Render(load(t, "ing"), "", &r) - - assert.Equal(t, "default/test-ingress", r.ID) - assert.Equal(t, render.Fields{"default", "test-ingress", "", "*", "", "80", "role=ingress"}, r.Fields[:7]) -} diff --git a/internal/view/cronjob.go b/internal/view/cronjob.go index 3ef3aaa2..08e2206a 100644 --- a/internal/view/cronjob.go +++ b/internal/view/cronjob.go @@ -19,7 +19,11 @@ import ( "k8s.io/apimachinery/pkg/runtime" ) -const suspendDialogKey = "suspend" +const ( + suspendDialogKey = "suspend" + lastScheduledCol = "LAST_SCHEDULE" + defaultSuspendStatus = "true" +) // CronJob represents a cronjob viewer. type CronJob struct { @@ -66,8 +70,9 @@ func jobCtx(path, uid string) ContextFunc { func (c *CronJob) bindKeys(aa ui.KeyActions) { aa.Add(ui.KeyActions{ - ui.KeyT: ui.NewKeyAction("Trigger", c.triggerCmd, true), - ui.KeyS: ui.NewKeyAction("Suspend/Resume", c.toggleSuspendCmd, true), + ui.KeyT: ui.NewKeyAction("Trigger", c.triggerCmd, true), + ui.KeyS: ui.NewKeyAction("Suspend/Resume", c.toggleSuspendCmd, true), + ui.KeyShiftL: ui.NewKeyAction("Sort LastScheduled", c.GetTable().SortColCmd(lastScheduledCol, true), false), }) } @@ -119,7 +124,7 @@ func (c *CronJob) showSuspendDialog(sel string) { c.App().Flash().Errf("Unable to assert current status") return } - suspended := strings.TrimSpace(cell.Text) == "True" + suspended := strings.TrimSpace(cell.Text) == defaultSuspendStatus title := "Suspend" if suspended { title = "Resume" @@ -136,9 +141,9 @@ func (c *CronJob) showSuspendDialog(sel string) { func (c *CronJob) makeSuspendForm(sel string, suspend bool) *tview.Form { f := c.makeStyledForm() - action := "suspend" + action := "suspended" if !suspend { - action = "resume" + action = "resumed" } f.AddButton("Cancel", func() { @@ -153,7 +158,7 @@ func (c *CronJob) makeSuspendForm(sel string, suspend bool) *tview.Form { log.Error().Err(err).Msgf("CronJob %s %s failed", sel, action) c.App().Flash().Err(err) } else { - c.App().Flash().Infof("CronJob %s %s successfully", sel, action) + c.App().Flash().Infof("CronJob %s %s successfully!", sel, action) } })