From: Eshel Yaron Date: Sun, 22 Sep 2024 20:27:10 +0000 (+0200) Subject: New commands for managing Kubernetes API proxies X-Git-Tag: v0.4.1~2 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=2e45b42397a454b09bc3168b2fd003d73ef7f336;p=kubed.git New commands for managing Kubernetes API proxies * kubed.el (kubed--proxy-alist): New variable. (kubed-stop-proxy, kubed-proxy): New commands, use it. (kubed-prefix-map, kubed-menu-map): Bind 'kubed-proxy'. * kubed-transient.el (kubed-transient-proxy): New transient. (kubed-transient): Bind it. * NEWS.org: Announce new commands. --- diff --git a/NEWS.org b/NEWS.org index e3b938d..a49c097 100644 --- a/NEWS.org +++ b/NEWS.org @@ -10,7 +10,7 @@ for Kubernetes. For further details, see the Kubed manual: [[https://eshelyaron.com/sweep.html][https://eshelyaron.com/kubed.html]]. -* Version 0.4.1 on in development +* Version 0.4.1 in development ** New command and transient menu for scaling deployments @@ -18,6 +18,14 @@ You can now scale Kubernetes deployment with Kubed, directly with ~kubed-scale-deployment~, from the deployments table buffer, or via the new transient menu ~kubed-transient-scale-deployment~. +** New commands and transient menu for managing Kubernetes API proxies + +You can now use Kubed to create proxy servers that give access to the +Kubernetes API server. The commands ~kubed-proxy~ and +~kubed-stop-proxy~ start and stop proxy servers, respectively. The +new transient menu ~kubed-transient-proxy~ lets specify options when +starting a proxy, such as the local port to use. + * Version 0.4.0 on 2024-08-23 ** ~kubed-list-update~ is now bound to ~g~ in resource table buffers. diff --git a/kubed-transient.el b/kubed-transient.el index 8d8fe17..3d2838c 100644 --- a/kubed-transient.el +++ b/kubed-transient.el @@ -70,6 +70,7 @@ Return an RFC3339 string representation of the selected date." ("P" "Patch" kubed-transient-patch) ("R" "Rollout" kubed-transient-rollout)] [("$" "Scale" kubed-transient-scale-deployment) + (":" "Proxy" kubed-transient-proxy) ("E" "Explain" kubed-explain) ("!" "Command line" kubed-kubectl-command)]]) @@ -176,6 +177,31 @@ defaults to \"RESOURCEs\"." (transient-setup 'kubed-transient-scale-deployment nil nil :scope '("scale" "deployment"))) +;;;###autoload (autoload 'kubed-transient-proxy "kubed-transient" nil t) +(transient-define-prefix kubed-transient-proxy () + "Create a proxy between localhost and the Kubernetes API server." + ["Kubernetes Proxy\n" + ["Action" + (":" "Start proxy" kubed-proxy) + ("|" "Stop proxy" kubed-stop-proxy) + ("!" "Command line" kubed-kubectl-command)] + ["Options" + ("-C" "Context" "--context=" + :prompt "Context" :reader kubed-transient-read-context) + ("-a" "Address" "--address=" + :prompt "Local proxy address: ") + ("-p" "Port" "--port=" + :prompt "Local proxy port: " :reader transient-read-number-N0) + ("-w" "WWW directory" "--www=" + :prompt "Local WWW directory: " :reader transient-read-existing-directory) + ("-P" "WWW prefix" "--www-prefix=" + :prompt "WWW prefix: ") + ("-A" "API prefix" "--api-prefix=" + :prompt "API prefix: ")]] + (interactive) + (transient-setup 'kubed-transient-proxy nil nil + :scope '("proxy"))) + ;;;###autoload (autoload 'kubed-transient-rollout "kubed-transient" nil t) (transient-define-prefix kubed-transient-rollout () "Manage Kubernetes deployments." diff --git a/kubed.el b/kubed.el index d5b140e..f4ac16a 100644 --- a/kubed.el +++ b/kubed.el @@ -3158,6 +3158,90 @@ for CONTEXT." (user-error "Patching `%s' failed" name)) (message "Applying patch to `%s'... Done." name)) +(defvar kubed--proxy-alist nil + "Alist associating `kubectl' context names and their proxy processes.") + +;;;###autoload +(defun kubed-proxy + (&optional addr port api-prefix www-dir www-prefix context) + "Start a web server on localhost proxying the Kubernetes API server. + +ADDR and PORT are the local address and port to bind the proxy server +to. They default to 127.0.0.1 and 8001, respectively. API-PREFIX is a +prefix under which to proxy the Kubernetes API. WWW-DIR is a local +directory to serve under WWW-PREFIX, which defaults to \"/static/\". +Lastly, CONTEXT is the the `kubectl' context to use, defaulting to the +local context." + (interactive + (let ((addr nil) (port nil) + (api-prefix nil) (www-dir nil) (www-prefix nil) + (context nil)) + (dolist (arg (kubed-transient-args 'kubed-transient-proxy)) + (cond + ((string-match "--address=\\(.+\\)" arg) + (setq addr (match-string 1 arg))) + ((string-match "--port=\\(.+\\)" arg) + (setq port (string-to-number (match-string 1 arg)))) + ((string-match "--api-prefix=\\(.+\\)" arg) + (setq api-prefix (match-string 1 arg))) + ((string-match "--www-dir=\\(.+\\)" arg) + (setq www-dir (match-string 1 arg))) + ((string-match "--www-prefix=\\(.+\\)" arg) + (setq www-prefix (match-string 1 arg))) + ((string-match "--context=\\(.+\\)" arg) + (setq context (match-string 1 arg))))) + (unless context + (setq context + (let ((cxt (kubed-local-context))) + (if (equal current-prefix-arg '(16)) + (kubed-read-context "Context" cxt) + cxt)))) + (list addr port api-prefix www-dir www-prefix context))) + (let ((context (or context (kubed-local-context)))) + (when-let ((proc (alist-get context kubed--proxy-alist + nil nil #'string=)) + ((process-live-p proc))) + (if (y-or-n-p (concat "Proxy already running for context `" context + "'. Stop it and start new proxy?")) + (kill-process proc) + (user-error "Proxy already running for context `%s'" context)) + (message "Stopped proxy for context `%s'." context)) + (setf (alist-get context kubed--proxy-alist nil nil #'string=) + (apply #'start-process (format "*kubed-proxy[%s]*" context) nil + kubed-kubectl-program "proxy" + "--context" context + (append + (when addr (list "--address" addr)) + (when port (list "--port" (number-to-string port))) + (when api-prefix (list "--api-prefix" api-prefix)) + (when www-dir (list "--www-dir" www-dir)) + (when www-prefix (list "--www-prefix" www-prefix))))) + (message "Started proxy for context `%s'." context))) + +;;;###autoload +(defun kubed-stop-proxy (&optional context) + "Stop local proxy for context CONTEXT, defaulting to the local context." + (interactive + (let ((context nil)) + (dolist (arg (kubed-transient-args 'kubed-transient-proxy)) + (cond + ((string-match "--context=\\(.+\\)" arg) + (setq context (match-string 1 arg))))) + (unless context + (setq context + (let ((cxt (kubed-local-context))) + (if (equal current-prefix-arg '(16)) + (kubed-read-context "Context" cxt) + cxt)))) + (list context))) + (let ((context (or context (kubed-local-context)))) + (if-let ((proc (alist-get context kubed--proxy-alist + nil nil #'string=)) + ((process-live-p proc))) + (kill-process proc) + (user-error "No proxy running for context `%s'" context)) + (message "Stopped proxy for context `%s'." context))) + (with-eval-after-load 'help-mode ;; Wait for `help-mode' to define `help-xref'. It's always loaded by ;; the time we actually need it in `kubed-explain'. @@ -3347,6 +3431,7 @@ Interactively, prompt for COMMAND with completion for `kubectl' arguments." "=" #'kubed-diff "E" #'kubed-explain "P" #'kubed-patch + ":" #'kubed-proxy "RET" #'kubed-display-resource "!" #'kubed-kubectl-command) @@ -3365,6 +3450,7 @@ Interactively, prompt for COMMAND with completion for `kubectl' arguments." "" '("Cron Jobs..." . kubed-cronjob-menu-map) "" '("Ingress Classes..." . kubed-ingressclass-menu-map) "" '("Ingresses..." . kubed-ingress-menu-map) + "" '("Proxy Kubernetes API" . kubed-proxy) "" '("Patch Resource" . kubed-patch) "" '("Diff Config with Live" . kubed-diff) "" '("Invoke kubectl" . kubed-kubectl-command)