Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support port-forwarding for appropriate resources #237

Merged
merged 9 commits into from
Sep 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading