diff --git a/go.mod b/go.mod index 08f65ee7..eaa9bcf7 100644 --- a/go.mod +++ b/go.mod @@ -27,10 +27,8 @@ replace ( ) require ( - github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect - github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4 // indirect github.com/atotto/clipboard v0.1.2 - github.com/derailed/tview v0.2.1 + github.com/derailed/tview v0.2.4 github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c // indirect github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f // indirect github.com/elazarl/goproxy/ext v0.0.0-20190421051319-9d40249d3c2f // indirect @@ -44,7 +42,7 @@ require ( github.com/imdario/mergo v0.3.7 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/mattn/go-runewidth v0.0.4 - github.com/petergtz/pegomock v2.5.0+incompatible + github.com/petergtz/pegomock v2.6.0+incompatible github.com/rakyll/hey v0.1.2 github.com/rs/zerolog v1.14.3 github.com/sahilm/fuzzy v0.1.0 @@ -52,7 +50,6 @@ require ( github.com/stretchr/testify v1.3.0 golang.org/x/text v0.3.2 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect - gopkg.in/alecthomas/kingpin.v2 v2.2.6 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.2.2 gotest.tools v2.2.0+incompatible diff --git a/go.sum b/go.sum index 51e30b22..9229e3b1 100644 --- a/go.sum +++ b/go.sum @@ -39,8 +39,6 @@ github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdko github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/Rican7/retry v0.1.0/go.mod h1:FgOROf8P5bebcC1DS0PdOQiqGUridaZvikzUmkFW6gg= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= @@ -89,8 +87,12 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd/go.mod h1:dv4zxwHi5C/8AeI+4gX4dCWOIvNi7I6JCSX0HvlKPgE= -github.com/derailed/tview v0.2.1 h1:3UjeNni+Q94WmmVnc8tLSTZab5NuRVrwolghCiXCtSs= -github.com/derailed/tview v0.2.1/go.mod h1:aDhJBLLf7pXbkaNmVroSvsjiP8ry6sfBVWNHTz6klZw= +github.com/derailed/tview v0.2.2 h1:APBixkqfHz3fL+XJ/bjxZivvd8HUtrXVcTUb/qu6wR0= +github.com/derailed/tview v0.2.2/go.mod h1:rFq1AIpLyyo8ilN1vG//2YnXmHg6szt4zIdg1ftJx9E= +github.com/derailed/tview v0.2.3 h1:bvoF230amMmzrwDYTHnToSLjemeCp6shmBJ+lnJRiAA= +github.com/derailed/tview v0.2.3/go.mod h1:rFq1AIpLyyo8ilN1vG//2YnXmHg6szt4zIdg1ftJx9E= +github.com/derailed/tview v0.2.4 h1:txiIdBLeSH1JV+9uP7hfuZAQBt1qJ+iDasmDCtVsvk0= +github.com/derailed/tview v0.2.4/go.mod h1:rFq1AIpLyyo8ilN1vG//2YnXmHg6szt4zIdg1ftJx9E= github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= @@ -112,7 +114,6 @@ github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb github.com/emicklei/go-restful v2.9.5+incompatible h1:spTtZBk5DYEvbxMVutUuTyh1Ao2r4iyvLdACqsl/Ljk= github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/euank/go-kmsg-parser v2.0.0+incompatible/go.mod h1:MhmAMZ8V4CYH4ybgdRwPr2TU5ThnS43puaKEMpja1uw= -github.com/evanphx/json-patch v4.1.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.2.0+incompatible h1:fUDGZCv/7iAN7u0puUVhvKCcsR6vRfwrJatElLBEf0I= github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4= @@ -124,6 +125,7 @@ github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko= github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg= +github.com/gdamore/tcell v1.1.1/go.mod h1:K1udHkiR3cOtlpKG5tZPD5XxrF7v2y7lDq7Whcj+xkQ= github.com/gdamore/tcell v1.1.2 h1:Afe8cU6SECC06UmvaJ55Jr3Eh0tz/ywLjqWYqjGZp3s= github.com/gdamore/tcell v1.1.2/go.mod h1:h3kq4HO9l2On+V9ed8w8ewqQEmGCSSHOgQ+2h8uzurE= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -175,7 +177,6 @@ github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+ github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA= github.com/go-ozzo/ozzo-validation v3.5.0+incompatible/go.mod h1:gsEKFIVnabGBt6mXmxK0MoFy+cZoTJY6mu5Ll3LVLBU= github.com/godbus/dbus v4.1.0+incompatible/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= -github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d h1:3PaI8p3seN09VjbTYC/QWlUZdZ1qS1zGjy7LH2Wt07I= github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -211,7 +212,6 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+ github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.2.0 h1:l6N3VoaVzTncYYW+9yOz2LJJammFZGBO13sqgEhpy9g= github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= -github.com/gophercloud/gophercloud v0.0.0-20190427020117-60507118a582/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= github.com/gophercloud/gophercloud v0.1.0 h1:P/nh25+rzXouhytV2pUHBb65fnds26Ghl8/391+sT5o= github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= @@ -251,7 +251,6 @@ github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/u github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/karrick/godirwalk v1.7.5/go.mod h1:2c9FRhkDxdIbgkOnCEvnSWs71Bhugbl46shStcFDJ34= -github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= @@ -273,6 +272,7 @@ github.com/lucas-clemente/aes12 v0.0.0-20171027163421-cd47fb39b79f/go.mod h1:JpH github.com/lucas-clemente/quic-clients v0.1.0/go.mod h1:y5xVIEoObKqULIKivu+gD/LU90pL73bTdtQjPBvtCBk= github.com/lucas-clemente/quic-go v0.10.2/go.mod h1:hvaRS9IHjFLMq76puFJeWNfmn+H70QZ/CXoxqw9bzao= github.com/lucas-clemente/quic-go-certificates v0.0.0-20160823095156-d2f86524cced/go.mod h1:NCcRLrOTZbzhZvixZLlERbJtDtYsmMw8Jc4vS8Z0g58= +github.com/lucasb-eyer/go-colorful v0.0.0-20181028223441-12d3b2882a08/go.mod h1:NXg0ArsFk0Y01623LgUqoqcouGDB+PwCCQlrwrG6xJ4= github.com/lucasb-eyer/go-colorful v1.0.2 h1:mCMFu6PgSozg9tDNMMK3g18oJBX7oYGrC09mS6CXfO4= github.com/lucasb-eyer/go-colorful v1.0.2/go.mod h1:0MS4r+7BZKSJ5mw4/S5MPN+qHFF1fYclkSPilDOKW0s= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= @@ -331,8 +331,8 @@ github.com/pelletier/go-toml v1.0.1/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9 github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= -github.com/petergtz/pegomock v2.5.0+incompatible h1:NgwX1/qc+tsl7I45OkDxYZ1mIonYWbOESnpZcd20sR0= -github.com/petergtz/pegomock v2.5.0+incompatible/go.mod h1:nuBLWZpVyv/fLo56qTwt/AUau7jgouO1h7bEvZCq82o= +github.com/petergtz/pegomock v2.6.0+incompatible h1:gD9YvI42LylIA/il2Cy8lMfg+CncNFMqexYepyEWGaQ= +github.com/petergtz/pegomock v2.6.0+incompatible/go.mod h1:nuBLWZpVyv/fLo56qTwt/AUau7jgouO1h7bEvZCq82o= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -373,7 +373,6 @@ github.com/soheilhy/cmux v0.1.3/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4k github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= @@ -416,7 +415,6 @@ golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8 h1:1wopBVtVdWnn03fZelqdXTqk7U7zPQCb+T4rbU9ZEoU= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -446,7 +444,6 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190328230028-74de082e2cca/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190424112056-4829fb13d2c6/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc h1:gkKoSkUmnU6bpS/VhkuO27bzQeSA51uaEfbOW5dNb68= @@ -485,7 +482,6 @@ golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20170824195420-5d2fd3ccab98/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -517,8 +513,8 @@ google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRn google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +gopkg.in/DATA-DOG/go-sqlmock.v1 v1.3.0/go.mod h1:OdE7CF6DbADk7lN8LIKRzRJTTZXIjtWgA5THM5lhBAw= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -569,7 +565,6 @@ k8s.io/gengo v0.0.0-20190822140433-26a664648505/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8 k8s.io/heapster v1.2.0-beta.1/go.mod h1:h1uhptVXMwC8xtZBYsPXKVi8fpdlYkTs6k949KozGrM= k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= -k8s.io/klog v0.3.1/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.4.0 h1:lCJCxf/LIowc2IGS9TPjWDyXY4nOmdGdfcwwDQCOURQ= k8s.io/klog v0.4.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= k8s.io/kube-aggregator v0.0.0-20190918161219-8c8f079fddc3/go.mod h1:NJisPUqwlg1A99RhO1BTnNtwC4pKUyXJ2f3Xc4PxKQg= diff --git a/internal/k8s/api.go b/internal/k8s/api.go index 0388166e..a1b76e07 100644 --- a/internal/k8s/api.go +++ b/internal/k8s/api.go @@ -26,20 +26,6 @@ const NA = "n/a" var supportedMetricsAPIVersions = []string{"v1beta1"} type ( - // GKV tracks api resource version info. - GKV struct { - Group, Kind, Version string - } - - // APIGroup represents a K8s resource descriptor. - APIGroup struct { - GKV - - Resource string - Plural, Singular string - Aliases []string - } - // Collection of empty interfaces. Collection []interface{} @@ -72,7 +58,7 @@ type ( CurrentNamespaceName() (string, error) CheckNSAccess(ns string) error CheckListNSAccess() error - CanIAccess(ns, resURL string, verbs []string) (bool, error) + CanIAccess(ns, rvg string, verbs []string) (bool, error) } k8sClient struct { @@ -121,12 +107,12 @@ func (a *APIClient) CheckNSAccess(n string) error { return err } -func makeSAR(ns, resURL string) *authorizationv1.SelfSubjectAccessReview { - gvr, _ := schema.ParseResourceArg(strings.ToLower(resURL)) +func makeSAR(ns, rvg string) *authorizationv1.SelfSubjectAccessReview { + gvr, _ := schema.ParseResourceArg(strings.ToLower(rvg)) if gvr == nil { - panic(fmt.Errorf("Unable to get GVR from url %s", resURL)) + panic(fmt.Errorf("Unable to get GVR from url %s", rvg)) } - log.Debug().Msgf("GVR for %s -- %#v", resURL, *gvr) + log.Debug().Msgf("GVR for %s -- %#v", rvg, *gvr) return &authorizationv1.SelfSubjectAccessReview{ Spec: authorizationv1.SelfSubjectAccessReviewSpec{ ResourceAttributes: &authorizationv1.ResourceAttributes{ @@ -139,8 +125,8 @@ func makeSAR(ns, resURL string) *authorizationv1.SelfSubjectAccessReview { } // CanIAccess checks if user has access to a certain resource. -func (a *APIClient) CanIAccess(ns, resURL string, verbs []string) (bool, error) { - sar := makeSAR(ns, resURL) +func (a *APIClient) CanIAccess(ns, rvg string, verbs []string) (bool, error) { + sar := makeSAR(ns, rvg) dial := a.DialOrDie().AuthorizationV1().SelfSubjectAccessReviews() for _, v := range verbs { sar.Spec.ResourceAttributes.Verb = v @@ -210,7 +196,7 @@ func (a *APIClient) IsNamespaced(res string) bool { func (a *APIClient) SupportsResource(group string) bool { list, err := a.DialOrDie().Discovery().ServerPreferredResources() if err != nil { - log.Debug().Err(err).Msg("Unable to dial api server") + log.Error().Err(err).Msg("Unable to dial api server") return false } for _, l := range list { @@ -294,7 +280,7 @@ func (a *APIClient) MXDial() (*versioned.Clientset, error) { } var err error if a.mxsClient, err = versioned.NewForConfig(a.RestConfigOrDie()); err != nil { - a.log.Debug().Err(err) + a.log.Error().Err(err) } return a.mxsClient, err diff --git a/internal/k8s/gvr.go b/internal/k8s/gvr.go index a0a11bf4..5d7ea45f 100644 --- a/internal/k8s/gvr.go +++ b/internal/k8s/gvr.go @@ -33,6 +33,15 @@ func (g GVR) AsGR() schema.GroupVersion { } } +// AsGVR returns a schema gvr instance. +func (g GVR) AsGVR() schema.GroupVersionResource { + return schema.GroupVersionResource{ + Group: g.ToG(), + Version: g.ToV(), + Resource: g.ToR(), + } +} + // String returns a GVR as a string. func (g GVR) String() string { return string(g) @@ -41,6 +50,9 @@ func (g GVR) String() string { // ToV returns the resource version. func (g GVR) ToV() string { tokens := strings.Split(string(g), "/") + if len(tokens) < 2 { + return "" + } return tokens[len(tokens)-2] } diff --git a/internal/k8s/gvr_test.go b/internal/k8s/gvr_test.go new file mode 100644 index 00000000..3b0b93d7 --- /dev/null +++ b/internal/k8s/gvr_test.go @@ -0,0 +1,146 @@ +package k8s_test + +import ( + "testing" + + "github.com/derailed/k9s/internal/k8s" + "github.com/stretchr/testify/assert" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +func TestAsGR(t *testing.T) { + uu := map[string]struct { + gvr string + e schema.GroupVersion + }{ + "full": {"apps/v1/deployments", schema.GroupVersion{"apps", "v1"}}, + "core": {"v1/pods", schema.GroupVersion{"", "v1"}}, + "bork": {"users", schema.GroupVersion{"", ""}}, + } + + for k, u := range uu { + t.Run(k, func(t *testing.T) { + assert.Equal(t, u.e, k8s.GVR(u.gvr).AsGR()) + }) + } +} + +func TestNewGVR(t *testing.T) { + uu := map[string]struct { + g, v, r string + e string + }{ + "full": {"apps", "v1", "deployments", "apps/v1/deployments"}, + "core": {"", "v1", "pods", "v1/pods"}, + } + + for k, u := range uu { + t.Run(k, func(t *testing.T) { + assert.Equal(t, u.e, k8s.NewGVR(u.g, u.v, u.r).String()) + }) + } +} + +func TestToGVR(t *testing.T) { + uu := map[string]struct { + gv, r, e string + }{ + "full": {"apps/v1", "deployments", "apps/v1/deployments"}, + "core": {"v1", "pods", "v1/pods"}, + } + + for k, u := range uu { + t.Run(k, func(t *testing.T) { + assert.Equal(t, u.e, k8s.ToGVR(u.gv, u.r).String()) + }) + } +} + +func TestResName(t *testing.T) { + uu := map[string]struct { + gvr string + e string + }{ + "full": {"apps/v1/deployments", "deployments.v1.apps"}, + "core": {"v1/pods", "pods.v1."}, + "k9s": {"users", "users.."}, + "empty": {"", ".."}, + } + + for k, u := range uu { + t.Run(k, func(t *testing.T) { + assert.Equal(t, u.e, k8s.GVR(u.gvr).ResName()) + }) + } +} + +func TestToR(t *testing.T) { + uu := map[string]struct { + gvr string + e string + }{ + "full": {"apps/v1/deployments", "deployments"}, + "core": {"v1/pods", "pods"}, + "k9s": {"users", "users"}, + "empty": {"", ""}, + } + + for k, u := range uu { + t.Run(k, func(t *testing.T) { + assert.Equal(t, u.e, k8s.GVR(u.gvr).ToR()) + }) + } +} + +func TestToG(t *testing.T) { + uu := map[string]struct { + gvr string + e string + }{ + "full": {"apps/v1/deployments", "apps"}, + "core": {"v1/pods", ""}, + "k9s": {"users", ""}, + "empty": {"", ""}, + } + + for k, u := range uu { + t.Run(k, func(t *testing.T) { + assert.Equal(t, u.e, k8s.GVR(u.gvr).ToG()) + }) + } +} + +func TestToV(t *testing.T) { + uu := map[string]struct { + gvr string + e string + }{ + "full": {"apps/v1/deployments", "v1"}, + "core": {"v1beta1/pods", "v1beta1"}, + "k9s": {"users", ""}, + "empty": {"", ""}, + } + + for k, u := range uu { + t.Run(k, func(t *testing.T) { + assert.Equal(t, u.e, k8s.GVR(u.gvr).ToV()) + }) + } +} + +func TestToStringer(t *testing.T) { + uu := map[string]struct { + gvr string + }{ + "full": {"apps/v1/deployments"}, + "core": {"v1beta1/pods"}, + "k9s": {"users"}, + "empty": {""}, + } + + for k, u := range uu { + t.Run(k, func(t *testing.T) { + assert.Equal(t, u.gvr, k8s.GVR(u.gvr).String()) + }) + } +} diff --git a/internal/k8s/ing.go b/internal/k8s/ing.go index 19d50e61..3aef3803 100644 --- a/internal/k8s/ing.go +++ b/internal/k8s/ing.go @@ -20,7 +20,7 @@ func (i *Ingress) Get(ns, n string) (interface{}, error) { return i.DialOrDie().ExtensionsV1beta1().Ingresses(ns).Get(n, metav1.GetOptions{}) } -// List all Ingresss in a given namespace. +// List all Ingresses in a given namespace. func (i *Ingress) List(ns string) (Collection, error) { opts := metav1.ListOptions{ LabelSelector: i.labelSelector, diff --git a/internal/k8s/resource.go b/internal/k8s/resource.go index d93f2631..7dc3fa75 100644 --- a/internal/k8s/resource.go +++ b/internal/k8s/resource.go @@ -6,7 +6,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1" "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/serializer" "k8s.io/client-go/dynamic" "k8s.io/client-go/rest" @@ -31,12 +30,7 @@ func (r *Resource) GetInfo() GVR { } func (r *Resource) nsRes() dynamic.NamespaceableResourceInterface { - g := schema.GroupVersionResource{ - Group: r.gvr.ToG(), - Version: r.gvr.ToV(), - Resource: r.gvr.ToR(), - } - return r.DynDialOrDie().Resource(g) + return r.DynDialOrDie().Resource(r.gvr.AsGVR()) } // Get a Resource. diff --git a/internal/resource/base.go b/internal/resource/base.go index 132acfa7..2274dac3 100644 --- a/internal/resource/base.go +++ b/internal/resource/base.go @@ -133,7 +133,7 @@ func (b *Base) Describe(gvr, pa string) (string, error) { mapper := k8s.RestMapper{Connection: b.Connection} mapping, err := mapper.ResourceFor(k8s.GVR(gvr).ResName()) if err != nil { - log.Debug().Err(err).Msgf("Unable to find mapper for %s %s", gvr, pa) + log.Error().Err(err).Msgf("Unable to find mapper for %s %s", gvr, pa) return "", err } ns, n := Namespaced(pa) diff --git a/internal/views/app.go b/internal/views/app.go index 4be89320..97a6ff0c 100644 --- a/internal/views/app.go +++ b/internal/views/app.go @@ -203,22 +203,58 @@ func (a *appView) refreshIndicator() { a.indicator().SetPermanent(info) } -func (a *appView) startInformer(ns string) { +func (a *appView) switchNS(ns string) bool { + if ns == a.Config.ActiveNamespace() { + log.Debug().Msgf("Namespace did not change %s", ns) + return true + } + a.Config.SetActiveNamespace(ns) + + return a.startInformer(ns) +} + +func (a *appView) switchCtx(ctx string, load bool) error { + l := resource.NewContext(a.Conn()) + if err := l.Switch(ctx); err != nil { + return err + } + + a.stopForwarders() + ns, err := a.Conn().Config().CurrentNamespaceName() + if err != nil { + log.Info().Err(err).Msg("No namespace specified using all namespaces") + } + a.startInformer(ns) + a.Config.Reset() + a.Config.Save() + a.Flash().Infof("Switching context to %s", ctx) + if load { + a.gotoResource("po", true) + } + + return nil +} + +func (a *appView) startInformer(ns string) bool { if a.stopCh != nil { close(a.stopCh) + a.stopCh = nil } var err error - a.stopCh = make(chan struct{}) a.informer, err = watch.NewInformer(a.Conn(), ns) if err != nil { - log.Panic().Err(err).Msgf("%v", err) + log.Error().Err(err).Msgf("%v", err) + a.Flash().Err(err) + return false } + a.stopCh = make(chan struct{}) a.informer.Run(a.stopCh) - if a.Config.K9s.GetHeadless() { a.refreshIndicator() } + + return true } // BailOut exists the application. @@ -340,9 +376,9 @@ func (a *appView) helpCmd(evt *tcell.EventKey) *tcell.EventKey { if _, ok := a.Frame().GetPrimitive("main").(*helpView); ok { return evt } - h := newHelpView(a, a.ActiveView(), a.GetHints()) a.inject(h) + return nil } @@ -350,7 +386,6 @@ func (a *appView) aliasCmd(evt *tcell.EventKey) *tcell.EventKey { if _, ok := a.Frame().GetPrimitive("main").(*aliasView); ok { return evt } - a.inject(newAliasView(a, a.ActiveView())) return nil diff --git a/internal/views/command.go b/internal/views/command.go index 2656d7ee..5f3e3888 100644 --- a/internal/views/command.go +++ b/internal/views/command.go @@ -3,6 +3,7 @@ package views import ( "fmt" "regexp" + "strings" "time" "github.com/derailed/k9s/internal/k8s" @@ -55,18 +56,22 @@ func (c *command) defaultCmd() { var policyMatcher = regexp.MustCompile(`\Apol\s([u|g|s]):([\w-:]+)\b`) -func (c *command) isCustCmd(cmd string) bool { - switch { - case cmd == "q", cmd == "quit": +func (c *command) isK9sCmd(cmd string) bool { + cmds := strings.Split(cmd, " ") + switch cmds[0] { + case "q", "quit": c.app.BailOut() return true - case cmd == "?", cmd == "help": + case "?", "help": c.app.helpCmd(nil) return true - case cmd == "alias": + case "alias": c.app.aliasCmd(nil) return true - case policyMatcher.MatchString(cmd): + default: + if !policyMatcher.MatchString(cmd) { + return false + } tokens := policyMatcher.FindAllStringSubmatch(cmd, -1) if len(tokens) == 1 && len(tokens[0]) == 3 { c.app.inject(newPolicyView(c.app, tokens[0][1], tokens[0][2])) @@ -76,36 +81,72 @@ func (c *command) isCustCmd(cmd string) bool { return false } -// Exec the command by showing associated display. -func (c *command) run(cmd string) bool { - defer func(t time.Time) { - log.Debug().Msgf("RUN CMD Elapsed %v", time.Since(t)) - }(time.Now()) - - if c.isCustCmd(cmd) { - return true - } - - vv := make(viewers, 200) +// load scrape api for resources and populate aliases. +func (c *command) load() viewers { + vv := make(viewers, 100) resourceViews(c.app.Conn(), vv) allCRDs(c.app.Conn(), vv) + + return vv +} + +func (c *command) viewMetaFor(cmd string) (string, *viewer) { + vv := c.load() gvr, ok := aliases.Get(cmd) if !ok { log.Error().Err(fmt.Errorf("Huh? `%s` command not found", cmd)).Msg("Command Failed") c.app.Flash().Warnf("Huh? `%s` command not found", cmd) - return false + return "", nil } v, ok := vv[gvr] if !ok { log.Error().Err(fmt.Errorf("Huh? `%s` viewer not found", cmd)).Msg("Viewer Failed") c.app.Flash().Warnf("Huh? `%s` viewer not found", gvr) - return false + return "", nil } - return c.execCmd(gvr, v) + + return gvr, &v } -func (c *command) execCmd(gvr string, v viewer) bool { - log.Debug().Msgf("ExecCmd gvr %s", gvr) +// Exec the command by showing associated display. +func (c *command) run(cmd string) bool { + log.Debug().Msgf("Running command %v", cmd) + defer func(t time.Time) { + log.Debug().Msgf("RUN CMD Elapsed %v", time.Since(t)) + }(time.Now()) + + if c.isK9sCmd(cmd) { + return true + } + + cmds := strings.Split(cmd, " ") + gvr, v := c.viewMetaFor(cmds[0]) + if v == nil { + return false + } + switch cmds[0] { + case "ctx", "context", "contexts": + if len(cmds) == 2 { + c.app.switchCtx(cmds[1], true) + return true + } + view := c.viewerFor(gvr, v) + return c.exec(gvr, "", view) + default: + ns := c.app.Config.ActiveNamespace() + if len(cmds) == 2 { + ns = cmds[1] + } + if !c.app.switchNS(ns) { + return false + } + return c.exec(gvr, ns, c.viewerFor(gvr, v)) + } + + return false +} + +func (c *command) viewerFor(gvr string, v *viewer) resourceViewer { var r resource.List if v.listFn != nil { r = v.listFn(c.app.Conn(), resource.DefaultNamespace) @@ -127,10 +168,10 @@ func (c *command) execCmd(gvr string, v viewer) bool { view.setDecorateFn(v.decorateFn) } - return c.exec(gvr, view) + return view } -func (c *command) exec(gvr string, v ui.Igniter) bool { +func (c *command) exec(gvr string, ns string, v ui.Igniter) bool { if v == nil { log.Error().Err(fmt.Errorf("No igniter given for %s", gvr)) return false diff --git a/internal/views/context.go b/internal/views/context.go index 4756585e..380de31c 100644 --- a/internal/views/context.go +++ b/internal/views/context.go @@ -5,7 +5,6 @@ import ( "github.com/derailed/k9s/internal/resource" "github.com/derailed/k9s/internal/ui" - "github.com/rs/zerolog/log" ) type contextView struct { @@ -50,18 +49,19 @@ func (v *contextView) useContext(name string) error { return err } - v.app.stopForwarders() - ns, err := v.app.Conn().Config().CurrentNamespaceName() - if err != nil { - log.Info().Err(err).Msg("No namespace specified using all namespaces") - } - v.app.startInformer(ns) - v.app.Config.Reset() - v.app.Config.Save() - v.app.Flash().Infof("Switching context to %s", ctx) + v.app.switchCtx(name, false) + // v.app.stopForwarders() + // ns, err := v.app.Conn().Config().CurrentNamespaceName() + // if err != nil { + // log.Info().Err(err).Msg("No namespace specified using all namespaces") + // } + // v.app.startInformer(ns) + // v.app.Config.Reset() + // v.app.Config.Save() + // v.app.Flash().Infof("Switching context to %s", ctx) v.refresh() if tv, ok := v.GetPrimitive("ctx").(*tableView); ok { - tv.Select(0, 0) + tv.Select(1, 0) } return nil diff --git a/internal/views/context_test.go b/internal/views/context_test.go index 73f61fbf..52e06813 100644 --- a/internal/views/context_test.go +++ b/internal/views/context_test.go @@ -10,7 +10,7 @@ import ( func TestContextView(t *testing.T) { l := resource.NewContextList(nil, "fred") - v := newContextView("blee", NewApp(config.NewConfig(ks{})), l).(*contextView) + v := newContextView("blee", "", NewApp(config.NewConfig(ks{})), l).(*contextView) assert.Equal(t, 10, len(v.hints())) } diff --git a/internal/views/dp_test.go b/internal/views/dp_test.go index ac7a6f30..0aa3f58e 100644 --- a/internal/views/dp_test.go +++ b/internal/views/dp_test.go @@ -10,7 +10,7 @@ import ( func TestDeployView(t *testing.T) { l := resource.NewDeploymentList(nil, "fred") - v := newDeployView("blee", NewApp(config.NewConfig(ks{})), l).(*deployView) + v := newDeployView("blee", "", NewApp(config.NewConfig(ks{})), l).(*deployView) assert.Equal(t, 10, len(v.hints())) } diff --git a/internal/views/ds_test.go b/internal/views/ds_test.go index 908751f2..3503a903 100644 --- a/internal/views/ds_test.go +++ b/internal/views/ds_test.go @@ -10,7 +10,7 @@ import ( func TestDaemonSetView(t *testing.T) { l := resource.NewDaemonSetList(nil, "fred") - v := newDaemonSetView("blee", NewApp(config.NewConfig(ks{})), l).(*daemonSetView) + v := newDaemonSetView("blee", "", NewApp(config.NewConfig(ks{})), l).(*daemonSetView) assert.Equal(t, 10, len(v.hints())) } diff --git a/internal/views/no.go b/internal/views/no.go index a29aea8f..6a0f63f1 100644 --- a/internal/views/no.go +++ b/internal/views/no.go @@ -50,13 +50,13 @@ func showPods(app *appView, ns, labelSel, fieldSel string, a ui.ActionHandler) { list.SetLabelSelector(labelSel) list.SetFieldSelector(fieldSel) - pv := newPodView("Pods", "v1/pods", app, list) + pv := newPodView("Pod", "v1/pods", app, list) pv.setColorerFn(podColorer) // pv.setExtraActionsFn(func(aa ui.KeyActions) { pv.masterPage().SetActions(ui.KeyActions{ tcell.KeyEsc: ui.NewKeyAction("Back", a, true), }) - // Reset active namespace to all. + // Reset active namespace to ns. app.Config.SetActiveNamespace(ns) app.inject(pv) } diff --git a/internal/views/ns.go b/internal/views/ns.go index a04d6ca7..3335b9ba 100644 --- a/internal/views/ns.go +++ b/internal/views/ns.go @@ -56,6 +56,7 @@ func (v *namespaceView) useNamespace(ns string) { v.app.Flash().Infof("Namespace %s is now active!", ns) } v.app.Config.Save() + v.app.startInformer(ns) } func (*namespaceView) cleanser(s string) string { diff --git a/internal/views/pod.go b/internal/views/pod.go index cded5185..af2431ca 100644 --- a/internal/views/pod.go +++ b/internal/views/pod.go @@ -76,7 +76,7 @@ func (v *podView) listContainers(app *appView, _, res, sel string) { pod := po.(*v1.Pod) list := resource.NewContainerList(app.Conn(), pod) - title := skinTitle(fmt.Sprintf(containerFmt, "Containers", sel), app.Styles.Frame()) + title := skinTitle(fmt.Sprintf(containerFmt, "Container", sel), app.Styles.Frame()) // Stop my updater if v.cancelFn != nil { diff --git a/internal/views/policy.go b/internal/views/policy.go index d3dc978c..dfeff84b 100644 --- a/internal/views/policy.go +++ b/internal/views/policy.go @@ -90,7 +90,8 @@ func (v *policyView) getTitle() string { func (v *policyView) refresh() { data, err := v.reconcile() if err != nil { - log.Error().Err(err).Msgf("Unable to reconcile for %s:%s", v.subjectKind, v.subjectName) + log.Error().Err(err).Msgf("Refresh for %s:%s", v.subjectKind, v.subjectName) + v.app.Flash().Err(err) } v.Update(data) } @@ -129,7 +130,7 @@ func (v *policyView) reconcile() (resource.TableData, error) { evts, errs := v.clusterPolicies() if len(errs) > 0 { for _, err := range errs { - log.Debug().Err(err).Msg("Unable to find cluster policies") + log.Error().Err(err).Msg("Unable to find cluster policies") } return table, errs[0] } @@ -137,7 +138,7 @@ func (v *policyView) reconcile() (resource.TableData, error) { nevts, errs := v.namespacedPolicies() if len(errs) > 0 { for _, err := range errs { - log.Debug().Err(err).Msg("Unable to find cluster policies") + log.Error().Err(err).Msg("Unable to find cluster policies") } return table, errs[0] } diff --git a/internal/views/rbac.go b/internal/views/rbac.go index 7f314603..c2006875 100644 --- a/internal/views/rbac.go +++ b/internal/views/rbac.go @@ -136,7 +136,8 @@ func (v *rbacView) getTitle() string { func (v *rbacView) refresh() { data, err := v.reconcile(v.ActiveNS(), v.roleName, v.roleType) if err != nil { - log.Error().Err(err).Msgf("Unable to reconcile for %s:%d", v.roleName, v.roleType) + log.Error().Err(err).Msgf("Refresh for %s:%d", v.roleName, v.roleType) + v.app.Flash().Err(err) } v.Update(data) } diff --git a/internal/views/resource.go b/internal/views/resource.go index 08630bcd..10e69509 100644 --- a/internal/views/resource.go +++ b/internal/views/resource.go @@ -334,8 +334,9 @@ func (v *resourceView) refresh() { if v.list.Namespaced() { v.list.SetNamespace(v.currentNS) } + log.Debug().Msgf("Reconcile with NS %q", v.currentNS) if err := v.list.Reconcile(v.app.informer, v.path); err != nil { - v.app.Flash().Errf("Reconciliation for %s failed - %s", v.list.GetName(), err) + v.app.Flash().Err(err) } data := v.list.Data() if v.decorateFn != nil { @@ -345,6 +346,11 @@ func (v *resourceView) refresh() { } func (v *resourceView) namespaceActions(aa ui.KeyActions) { + ns, err := v.app.Conn().Config().CurrentNamespaceName() + log.Debug().Msgf("NAMESPACE %q -- %v", ns, err) + if err == nil && ns != resource.AllNamespace { + return + } if !v.list.Access(resource.NamespaceAccess) { return } diff --git a/internal/views/subject.go b/internal/views/subject.go index 7a181bca..d5f32ec2 100644 --- a/internal/views/subject.go +++ b/internal/views/subject.go @@ -115,7 +115,8 @@ func (v *subjectView) SetSubject(s string) { func (v *subjectView) refresh() { data, err := v.reconcile() if err != nil { - log.Error().Err(err).Msgf("Unable to reconcile for %s", v.subjectKind) + log.Error().Err(err).Msgf("Refresh for %s", v.subjectKind) + v.app.Flash().Err(err) } v.Update(data) } diff --git a/internal/views/svc.go b/internal/views/svc.go index e8eea32d..7b548c30 100644 --- a/internal/views/svc.go +++ b/internal/views/svc.go @@ -209,20 +209,10 @@ func benchTimedOut(app *appView) { }) } -func (v *svcView) showSvcPods(ns string, sel map[string]string, b ui.ActionHandler) { +func (v *svcView) showSvcPods(ns string, sel map[string]string, a ui.ActionHandler) { var s []string for k, v := range sel { s = append(s, fmt.Sprintf("%s=%s", k, v)) } - list := resource.NewPodList(v.app.Conn(), ns) - list.SetLabelSelector(strings.Join(s, ",")) - - pv := newPodView("Pods", "v1/pods", v.app, list) - pv.setColorerFn(podColorer) - pv.setExtraActionsFn(func(aa ui.KeyActions) { - aa[tcell.KeyEsc] = ui.NewKeyAction("Back", b, true) - }) - // set active namespace to service ns. - v.app.Config.SetActiveNamespace(ns) - v.app.inject(pv) + showPods(v.app, ns, strings.Join(s, ","), "", a) } diff --git a/internal/watch/informer.go b/internal/watch/informer.go index 3f9d0ace..24959a20 100644 --- a/internal/watch/informer.go +++ b/internal/watch/informer.go @@ -64,17 +64,12 @@ type Informer struct { // NewInformer creates a new cluster resource informer func NewInformer(client k8s.Connection, ns string) (*Informer, error) { i := Informer{client: client, informers: map[string]StoreInformer{}} - if client.CheckListNSAccess() == nil { - i.init(allNamespaces) - return &i, nil - } - if err := client.CheckNSAccess(ns); err != nil { log.Error().Err(err).Msg("Checking NS Access") return nil, err } - i.init(ns) + return &i, nil }