]> git.eshelyaron.com Git - kubed.git/commitdiff
New commands for managing Kubernetes API proxies
authorEshel Yaron <me@eshelyaron.com>
Sun, 22 Sep 2024 20:27:10 +0000 (22:27 +0200)
committerEshel Yaron <me@eshelyaron.com>
Mon, 23 Sep 2024 06:51:22 +0000 (08:51 +0200)
* 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.

NEWS.org
kubed-transient.el
kubed.el

index e3b938db6ff760def034449893061086a6018138..a49c09736dbc64a3ddadaf4c6a158aa8da08f6a5 100644 (file)
--- 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.
index 8d8fe170cf91751465f768ed0ccf171b06622c4a..3d2838c5ef45ea801e152eea93b8316f0bce8078 100644 (file)
@@ -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."
index d5b140e0e2b59e183039435c7f51a1cf1c669e1d..f4ac16a0805f8dbfd04755098579895dcfeae552 100644 (file)
--- 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."
   "<cronjob>"          '("Cron Jobs..."          . kubed-cronjob-menu-map)
   "<ingressclass>"     '("Ingress Classes..."    . kubed-ingressclass-menu-map)
   "<ingress>"          '("Ingresses..."          . kubed-ingress-menu-map)
+  "<proxy>"            '("Proxy Kubernetes API"  . kubed-proxy)
   "<patch>"            '("Patch Resource"        . kubed-patch)
   "<diff>"             '("Diff Config with Live" . kubed-diff)
   "<kubectl-command>"  '("Invoke kubectl"        . kubed-kubectl-command)