Skip to content

Commit

Permalink
Support port-forwarding for appropriate resources (#237)
Browse files Browse the repository at this point in the history
Contributes to #234.
  • Loading branch information
jinnovation authored Sep 22, 2024
1 parent ea4bd0a commit 9d07637
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 3 deletions.
6 changes: 3 additions & 3 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ With Kele, you can:

- Manage [contexts], e.g. [switching, renaming, changing the default
namespace](./how-tos/usage.md#contexts);
- [Fetch and display the manifest of a single
resource](./how-tos/usage.md#working-with-resources);
- [Follow logs for a single resource](./how-tos/usage.md#following-logs)
- [Display details](./how-tos/usage.md#working-with-resources), [follow
logs](./how-tos/usage.md#following-logs), and manage port-forwards for
resources;
- [List collections of resources](./how-tos/usage.md#working-with-resources);
- Start and stop [proxy servers](./how-tos/usage.md#managing-proxy-servers);
- Use the menu bar to perform basic cluster/config management;
Expand Down
2 changes: 2 additions & 0 deletions docs/references/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ versioning][semver].
similar to `kubectl get deployments`
- `kele-resource` now has a keybinding to follow logs for resources that support
it
- `kele-resource` now has a suffix for port-forwarding to resources that support
it

## 0.6.0

Expand Down
65 changes: 65 additions & 0 deletions kele.el
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ pods."
(defvar kele--loggable-kinds '("pods" "deployments" "jobs" "services")
"Resource kinds that can be passed to kubectl log.")

(defvar kele--port-forwardable-kinds '("pods" "deployments" "services")
"Resource kinds that can be passed to kubectl port-forward.")

;; TODO (#80): Display in the `kele-get-mode' header what fields were filtered out
(defcustom kele-filtered-fields '((metadata managedFields)
(metadata annotations kubectl.kubernetes.io/last-applied-configuration))
Expand Down Expand Up @@ -567,6 +570,16 @@ GROUP and VERSION are not always set. KIND is always set."
(concat (oref gvk group) "/" vk)
vk)))

(cl-defmethod kele--singular ((gvk kele--gvk) &optional context)
"Return the name of GVK in singular form.
If CONTEXT is provided, look up in that context. Otherwise, use
the current context."
(kele--get-singular-for-plural
kele--global-discovery-cache
(oref gvk kind)
:context (or context (kele-current-context-name))))

(cl-defstruct (kele--proxy-record
(:constructor kele--proxy-record-create)
(:copier nil))
Expand Down Expand Up @@ -1992,6 +2005,57 @@ to query for."
(list (kele--get-context-arg) ns gvk name)))
(kele--render-object (kele--get-resource gvk name :namespace namespace :context context)))

(transient-define-suffix kele-port-forward (context namespace gvk name port)
"Create a port-forward for resource GVK named NAME at PORT.
NAMESPACE and CONTEXT are used to identify the resource type to query for."
:key "F"
:description
"Port-forward to..."
:if
(lambda ()
(let-alist (oref transient--prefix scope)
(-contains? kele--port-forwardable-kinds .kind)))
(interactive
(let* ((gvk (kele--get-gvk-arg))
(context (kele--get-context-arg))
(ns (kele--get-namespace-arg
:kind (oref gvk kind)
:group-version (kele--gv-string gvk)
:use-default nil))
(cands (kele--fetch-resource-names gvk :namespace ns :context context))
(name (completing-read
(format "%s to port-forward to: " (kele--singular gvk))
(-cut kele--resources-complete <> <> <> :cands cands)))

;; TODO: Completion on the resource's exposed ports
;; TODO: Error if the port is already in use
(port (number-to-string (read-number "Port: "))))
(list context ns gvk name port)))
(let ((proc-name (format "kele: port-forward (%s/%s, %s, %s, %s)" (oref gvk kind) name context namespace port)))
(make-process
:name proc-name
:command (list kele-kubectl-executable
"--context"
context
"--namespace"
namespace
"port-forward"
(format "%s/%s" (oref gvk kind) name)
port)
:buffer (generate-new-buffer (format " *%s*" proc-name))
:sentinel
(lambda (proc _status)
(let ((exit-code (process-exit-status proc)))
(cl-case exit-code
(0 (message "Successfully terminated port-forward for %s" name))
(9 (message "Port-forward for %s (port %s) terminated" name port))
(t (message "Port-forward process for %s failed with exit code %s" name exit-code)))
(kele--kill-process-quietly proc)))
:noquery t))
(message "[kele] Started port-forward for %s/%s (port %s)" (oref gvk kind) name port))


(transient-define-suffix kele-deployment-restart (context namespace deployment-name)
"Restart DEPLOYMENT-NAME.
Expand Down Expand Up @@ -2043,6 +2107,7 @@ CONTEXT and NAMESPACE are used to identify where the deployment lives."
(propertize it 'face 'warning))
(propertize "-specific actions" 'face 'transient-heading))))
(kele-resource-follow-logs)
(kele-port-forward)
(kele-deployment-restart)]]

(interactive (let* ((context (kele-current-context-name))
Expand Down

0 comments on commit 9d07637

Please sign in to comment.