feat(kube): Kubernetes UI — FreeLens v5 feature parity #85
551
TICKET-freelens-feature-inventory.md
Normal file
551
TICKET-freelens-feature-inventory.md
Normal file
@ -0,0 +1,551 @@
|
||||
# FreeLens Feature Inventory — Complete Analysis
|
||||
|
||||
**Project**: FreeLens (https://github.com/freelensapp/freelens)
|
||||
**License**: MIT License (Copyright 2024-2026 Freelens Authors; Copyright 2022 OpenLens Authors)
|
||||
**Description**: Free and open-source Kubernetes IDE, community fork of Open Lens v5
|
||||
**Analysis Date**: 2026-06-08
|
||||
**Repository Commit**: main branch (latest)
|
||||
|
||||
---
|
||||
|
||||
## Executive Summary
|
||||
|
||||
FreeLens is a production-ready, feature-complete Kubernetes desktop IDE built on Electron with a comprehensive resource management interface. The application provides extensive coverage of Kubernetes API resources with dedicated UI components, context menus, and detail views for nearly all standard Kubernetes objects.
|
||||
|
||||
**Key Findings**:
|
||||
- **13 main navigation categories** with 60+ resource types
|
||||
- **Comprehensive pod management**: shell/exec, logs, attach, edit, delete, force delete, force finalize
|
||||
- **Full workload lifecycle**: scale, restart, edit, delete for Deployments, StatefulSets, DaemonSets
|
||||
- **Helm chart integration**: install, upgrade, rollback, delete
|
||||
- **Port forwarding UI**: start/stop/edit/open in browser
|
||||
- **Terminal integration**: built-in terminal with kubectl and node shell access
|
||||
- **Resource metrics**: CPU/memory usage visualization (when metrics-server available)
|
||||
- **YAML editing**: Monaco editor with syntax highlighting
|
||||
- **RBAC management**: full support for roles, bindings, service accounts
|
||||
- **Extension ecosystem**: plugin architecture for custom functionality
|
||||
|
||||
---
|
||||
|
||||
## Left Navigation Structure (Complete)
|
||||
|
||||
### 1. Favorites
|
||||
- User-bookmarked resources for quick access
|
||||
|
||||
### 2. Cluster Overview
|
||||
- Cluster-wide dashboard with health metrics
|
||||
|
||||
### 3. Nodes
|
||||
- Node list and details
|
||||
- **Context Menu Actions**:
|
||||
- Shell (node shell access via SSH or similar)
|
||||
- Cordon/Uncordon
|
||||
- Drain (with confirmation)
|
||||
- Edit
|
||||
- Delete
|
||||
|
||||
### 4. Workloads
|
||||
Parent category containing:
|
||||
|
||||
#### 4.1 Overview
|
||||
- Aggregated workload dashboard
|
||||
|
||||
#### 4.2 Pods
|
||||
- Pod list with status, IP, node, age
|
||||
- **Context Menu Actions**:
|
||||
- Shell (per-container with auto-detection: bash/ash/sh, PowerShell for Windows nodes)
|
||||
- Logs (per-container, including init and ephemeral containers)
|
||||
- Attach (kubectl attach -it)
|
||||
- Edit (YAML editor)
|
||||
- Delete (graceful)
|
||||
- Force Delete (skip grace period, only for Running/Pending phases)
|
||||
- Force Finalize (remove finalizers when stuck)
|
||||
|
||||
#### 4.3 Deployments
|
||||
- **Context Menu Actions**:
|
||||
- Scale (replica count dialog)
|
||||
- Restart (rolling restart)
|
||||
- Edit
|
||||
- Delete
|
||||
|
||||
#### 4.4 StatefulSets
|
||||
- **Context Menu Actions**:
|
||||
- Restart
|
||||
- Edit
|
||||
- Delete
|
||||
|
||||
#### 4.5 DaemonSets
|
||||
- **Context Menu Actions**:
|
||||
- Restart
|
||||
- Edit
|
||||
- Delete
|
||||
|
||||
#### 4.6 Jobs
|
||||
- **Context Menu Actions**:
|
||||
- Edit
|
||||
- Delete
|
||||
|
||||
#### 4.7 CronJobs
|
||||
- **Context Menu Actions**:
|
||||
- Edit
|
||||
- Delete
|
||||
|
||||
#### 4.8 ReplicaSets
|
||||
- List view (typically managed by Deployments)
|
||||
|
||||
#### 4.9 ReplicationControllers
|
||||
- Legacy replication support
|
||||
|
||||
### 5. Config
|
||||
Parent category containing:
|
||||
|
||||
#### 5.1 ConfigMaps
|
||||
- **Context Menu Actions**:
|
||||
- Edit
|
||||
- Delete
|
||||
|
||||
#### 5.2 Secrets
|
||||
- **Context Menu Actions**:
|
||||
- Edit (with data obfuscation)
|
||||
- Delete
|
||||
|
||||
#### 5.3 Horizontal Pod Autoscalers (HPA)
|
||||
- HPA configuration and status
|
||||
|
||||
#### 5.4 Vertical Pod Autoscalers (VPA)
|
||||
- VPA recommendations and settings
|
||||
|
||||
#### 5.5 Resource Quotas
|
||||
- Namespace quota limits
|
||||
|
||||
#### 5.6 Limit Ranges
|
||||
- Default resource limits
|
||||
|
||||
#### 5.7 Priority Classes
|
||||
- Pod scheduling priority definitions
|
||||
|
||||
#### 5.8 Runtime Classes
|
||||
- Container runtime selection
|
||||
|
||||
#### 5.9 Pod Disruption Budgets
|
||||
- PDB configuration
|
||||
|
||||
#### 5.10 Leases
|
||||
- Coordination.k8s.io lease objects
|
||||
|
||||
#### 5.11 Mutating Webhook Configurations
|
||||
- Admission webhook config
|
||||
|
||||
#### 5.12 Validating Webhook Configurations
|
||||
- Validation webhook config
|
||||
|
||||
### 6. Network
|
||||
Parent category containing:
|
||||
|
||||
#### 6.1 Services
|
||||
- Service list and endpoints
|
||||
- **Context Menu Actions**:
|
||||
- Edit
|
||||
- Delete
|
||||
|
||||
#### 6.2 Ingresses
|
||||
- Ingress rules and backends
|
||||
|
||||
#### 6.3 Ingress Classes
|
||||
- IngressClass definitions
|
||||
|
||||
#### 6.4 Network Policies
|
||||
- Network segmentation rules
|
||||
|
||||
#### 6.5 Endpoints
|
||||
- Service endpoint slices
|
||||
|
||||
#### 6.6 Endpoint Slices
|
||||
- EndpointSlice objects
|
||||
|
||||
#### 6.7 Port Forwards
|
||||
- Active port-forward management
|
||||
- **Context Menu Actions**:
|
||||
- Open (in browser, for HTTP/HTTPS)
|
||||
- Edit (change local/remote port, protocol)
|
||||
- Start
|
||||
- Stop
|
||||
- Delete
|
||||
|
||||
### 7. Storage
|
||||
Parent category containing:
|
||||
|
||||
#### 7.1 Persistent Volumes
|
||||
- Cluster-wide PV list
|
||||
|
||||
#### 7.2 Persistent Volume Claims
|
||||
- PVC list with binding status
|
||||
|
||||
#### 7.3 Storage Classes
|
||||
- Dynamic provisioning configuration
|
||||
|
||||
### 8. Namespaces
|
||||
- Namespace list and quota overview
|
||||
- Namespace filtering (global namespace selector in UI)
|
||||
|
||||
### 9. Events
|
||||
- Cluster events stream with filtering
|
||||
|
||||
### 10. Helm
|
||||
Parent category containing:
|
||||
|
||||
#### 10.1 Charts
|
||||
- Helm chart repository browser
|
||||
- Search across configured repositories
|
||||
- **Chart Actions**:
|
||||
- Install (opens install dialog with values editor)
|
||||
|
||||
#### 10.2 Releases
|
||||
- Deployed Helm releases
|
||||
- **Context Menu Actions**:
|
||||
- Upgrade (opens upgrade dialog)
|
||||
- Rollback (to previous revision)
|
||||
- Delete
|
||||
|
||||
### 11. User Management (RBAC)
|
||||
Parent category containing:
|
||||
|
||||
#### 11.1 Service Accounts
|
||||
- **Context Menu Actions**:
|
||||
- Edit
|
||||
- Delete
|
||||
|
||||
#### 11.2 Roles
|
||||
- Namespace-scoped RBAC roles
|
||||
|
||||
#### 11.3 Role Bindings
|
||||
- Role-to-subject mappings
|
||||
|
||||
#### 11.4 Cluster Roles
|
||||
- Cluster-wide RBAC roles
|
||||
|
||||
#### 11.5 Cluster Role Bindings
|
||||
- ClusterRole-to-subject mappings
|
||||
|
||||
### 12. Custom Resources
|
||||
- **Custom Resource Definitions (CRDs)**
|
||||
- **Custom Resources** (instances of CRDs)
|
||||
- Dynamic UI generation for any CRD installed in cluster
|
||||
|
||||
### 13. Pod Security Policies (PSP)
|
||||
- Legacy PSP support (deprecated in K8s 1.25+)
|
||||
|
||||
---
|
||||
|
||||
## Detail Views
|
||||
|
||||
All resources support a **detail drawer** (right-side panel) showing:
|
||||
|
||||
### Pod Detail View
|
||||
- **Status** (Running, Pending, Failed, etc.)
|
||||
- **Node** (clickable link to node)
|
||||
- **Host IPs** (multi-IP support)
|
||||
- **Pod IPs** (IPv4/IPv6)
|
||||
- **Service Account** (clickable link)
|
||||
- **Priority Class** (clickable link)
|
||||
- **QoS Class** (BestEffort, Burstable, Guaranteed)
|
||||
- **Runtime Class** (clickable link)
|
||||
- **Termination Grace Period**
|
||||
- **Node Selector** (labels)
|
||||
- **Tolerations** (with key/value/effect)
|
||||
- **Affinity/Anti-Affinity** (node and pod affinity rules)
|
||||
- **Resource Requests** (CPU, memory, ephemeral-storage)
|
||||
- **Resource Limits** (CPU, memory)
|
||||
- **Secrets** (mounted secrets with clickable links)
|
||||
- **Conditions** (PodScheduled, Initialized, ContainersReady, Ready)
|
||||
- **Init Containers** (with status, restart count, state)
|
||||
- **Containers** (with status, restart count, image, ports, env vars, volume mounts, liveness/readiness probes)
|
||||
- **Ephemeral Containers** (debug containers)
|
||||
- **Volumes** (ConfigMaps, Secrets, PVCs, EmptyDir, HostPath, etc.)
|
||||
|
||||
### Other Resource Detail Views
|
||||
- **Deployment**: replicas, strategy, conditions, selector, pod template
|
||||
- **Service**: type, cluster IP, external IP, ports, selector, endpoints
|
||||
- **ConfigMap**: data key-value pairs
|
||||
- **Secret**: data keys (values obfuscated)
|
||||
- **Node**: conditions, addresses, capacity, allocatable, taints, images
|
||||
- **PVC**: access modes, storage class, volume name, capacity
|
||||
- **Ingress**: rules, TLS, backends
|
||||
|
||||
All detail views include:
|
||||
- **Metadata** section (name, namespace, labels, annotations, creation time, resource version, UID)
|
||||
- **YAML view** (Monaco editor with syntax highlighting)
|
||||
- **Events** related to the resource
|
||||
|
||||
---
|
||||
|
||||
## Dock Panel (Bottom Panel)
|
||||
|
||||
The dock is a tabbed bottom panel supporting multiple simultaneous views:
|
||||
|
||||
### Terminal
|
||||
- **Node Shell**: SSH or similar access to cluster nodes
|
||||
- **Pod Shell**: `kubectl exec -it` with container selection
|
||||
- **Pod Attach**: `kubectl attach -it` for attaching to running container
|
||||
- **Custom Commands**: run arbitrary kubectl commands
|
||||
- **Multi-tab support**: multiple shells in separate tabs
|
||||
- **Shell Detection**: auto-selects bash/ash/sh on Linux, PowerShell on Windows nodes
|
||||
|
||||
### Logs
|
||||
- **Pod Logs**: per-container log streaming
|
||||
- **Container Selection**: dropdown for multi-container pods (including init and ephemeral)
|
||||
- **Follow Mode**: tail -f equivalent
|
||||
- **Timestamps**: toggle timestamp display
|
||||
- **Previous Logs**: view logs from crashed/restarted containers
|
||||
- **Search/Filter**: text search within logs
|
||||
- **Download**: save logs to file
|
||||
- **Wrap Lines**: toggle line wrapping
|
||||
|
||||
### Edit Resource
|
||||
- **YAML Editor**: Monaco-based syntax highlighting
|
||||
- **Apply Changes**: update resource via kubectl apply
|
||||
- **Validation**: client-side YAML validation
|
||||
- **Diff View**: show changes before applying
|
||||
|
||||
### Create Resource
|
||||
- **YAML Editor**: create new resources from scratch
|
||||
- **Templates**: common resource templates
|
||||
- **Multi-resource**: create multiple resources from YAML with `---` separator
|
||||
|
||||
### Install Chart
|
||||
- **Chart Selection**: from Helm repository browser
|
||||
- **Values Editor**: YAML editor for values.yaml
|
||||
- **Release Name**: custom release name
|
||||
- **Namespace Selection**: target namespace
|
||||
- **Preview**: dry-run before install
|
||||
|
||||
### Upgrade Chart
|
||||
- **Current Values**: shows existing values
|
||||
- **New Version Selection**: dropdown of available chart versions
|
||||
- **Values Diff**: highlight changes from current release
|
||||
- **Revision History**: list previous revisions
|
||||
|
||||
---
|
||||
|
||||
## Special Features
|
||||
|
||||
### Metrics & Resource Usage
|
||||
- **Pod Metrics**: CPU and memory usage graphs (requires metrics-server)
|
||||
- **Node Metrics**: cluster-wide resource utilization
|
||||
- **Container Metrics**: per-container CPU/memory in detail view
|
||||
- **Historical Charts**: time-series graphs for resource usage
|
||||
|
||||
### Namespace Filtering
|
||||
- **Global Namespace Selector**: filters all views to selected namespace(s)
|
||||
- **Multi-namespace Selection**: view resources across multiple namespaces
|
||||
- **All Namespaces**: cluster-wide view
|
||||
|
||||
### Search & Filtering
|
||||
- **Global Search**: search across all resource types
|
||||
- **Per-View Search**: resource-specific search with multiple field filtering
|
||||
- **Label Filtering**: filter by labels and annotations
|
||||
|
||||
### Context Menu Behavior
|
||||
- **Toolbar Mode**: icons with tooltips in detail view header
|
||||
- **Table Row Menu**: three-dot menu in list views
|
||||
- **Right-click Context Menu**: anywhere on resource row
|
||||
|
||||
### Delete Modes (Intelligent)
|
||||
|
||||
FreeLens implements **intelligent delete mode selection** based on resource state:
|
||||
|
||||
#### Pod Deletion
|
||||
- **Delete** (graceful): default for all phases
|
||||
- **Force Delete** (grace period = 0): only shown for Running/Pending pods with `terminationGracePeriodSeconds > 0`
|
||||
- **Force Finalize** (remove finalizers): shown when pod has `deletionTimestamp` AND finalizers
|
||||
|
||||
Logic prevents showing "Force Delete" for terminal phases (Succeeded, Failed, Unknown) where it would have no effect.
|
||||
|
||||
#### Generic Resource Deletion
|
||||
- **Delete**: default
|
||||
- **Force Finalize**: only when resource has `deletionTimestamp` AND finalizers
|
||||
|
||||
### Confirmation Dialogs
|
||||
All destructive actions (delete, drain, restart) require user confirmation with resource name displayed.
|
||||
|
||||
---
|
||||
|
||||
## Kubernetes API Coverage
|
||||
|
||||
FreeLens supports **all standard Kubernetes API groups**:
|
||||
|
||||
### Core (v1)
|
||||
- Pods, Services, Endpoints, ConfigMaps, Secrets, Namespaces, Nodes, PersistentVolumes, PersistentVolumeClaims, ServiceAccounts, Events, ResourceQuotas, LimitRanges
|
||||
|
||||
### Apps (apps/v1)
|
||||
- Deployments, StatefulSets, DaemonSets, ReplicaSets, ReplicationControllers
|
||||
|
||||
### Batch (batch/v1, batch/v1beta1)
|
||||
- Jobs, CronJobs
|
||||
|
||||
### Networking (networking.k8s.io/v1)
|
||||
- Ingresses, IngressClasses, NetworkPolicies
|
||||
|
||||
### Storage (storage.k8s.io/v1)
|
||||
- StorageClasses, VolumeAttachments
|
||||
|
||||
### RBAC (rbac.authorization.k8s.io/v1)
|
||||
- Roles, RoleBindings, ClusterRoles, ClusterRoleBindings
|
||||
|
||||
### Autoscaling (autoscaling/v1, autoscaling/v2)
|
||||
- HorizontalPodAutoscalers, VerticalPodAutoscalers
|
||||
|
||||
### Policy (policy/v1, policy/v1beta1)
|
||||
- PodDisruptionBudgets, PodSecurityPolicies
|
||||
|
||||
### Admission (admissionregistration.k8s.io/v1)
|
||||
- MutatingWebhookConfigurations, ValidatingWebhookConfigurations
|
||||
|
||||
### Scheduling (scheduling.k8s.io/v1)
|
||||
- PriorityClasses
|
||||
|
||||
### Node (node.k8s.io/v1)
|
||||
- RuntimeClasses
|
||||
|
||||
### Coordination (coordination.k8s.io/v1)
|
||||
- Leases
|
||||
|
||||
### Discovery (discovery.k8s.io/v1)
|
||||
- EndpointSlices
|
||||
|
||||
### Custom Resources
|
||||
- Full CRD support with dynamic UI generation
|
||||
|
||||
### Helm
|
||||
- Charts, Releases (via Helm API, not native K8s)
|
||||
|
||||
---
|
||||
|
||||
## Extension System
|
||||
|
||||
FreeLens supports extensions via a plugin API:
|
||||
- **Custom Pages**: add new sidebar items and routes
|
||||
- **Custom Menus**: inject menu items into resource context menus
|
||||
- **Custom Resource Views**: override or enhance detail views
|
||||
- **Protocol Handlers**: register custom URL schemes
|
||||
- **Preferences**: add extension settings to preferences UI
|
||||
|
||||
Extensions are TypeScript/JavaScript modules loaded at runtime.
|
||||
|
||||
---
|
||||
|
||||
## Comparison to TFTSR Requirements
|
||||
|
||||
Based on the TFTSR project's needs for Kubernetes cluster management, FreeLens provides:
|
||||
|
||||
### Strengths
|
||||
✅ **Complete resource coverage**: All K8s API objects supported
|
||||
✅ **Shell execution**: Built-in terminal with pod exec and node shell
|
||||
✅ **Log streaming**: Real-time log viewing with container selection
|
||||
✅ **YAML editing**: Monaco editor with validation
|
||||
✅ **Port forwarding**: Full UI for managing forwards
|
||||
✅ **Helm integration**: Chart install, upgrade, rollback
|
||||
✅ **RBAC management**: Full RBAC resource support
|
||||
✅ **Extension API**: Customizable via plugins
|
||||
✅ **Multi-cluster**: Supports multiple kubeconfig contexts
|
||||
✅ **Metrics**: Resource usage visualization (when metrics-server available)
|
||||
✅ **Open source**: MIT licensed, can be forked/customized
|
||||
|
||||
### Potential Gaps for TFTSR
|
||||
⚠️ **No AI integration**: FreeLens is a pure Kubernetes IDE, no AI/ML features
|
||||
⚠️ **No RCA/triage features**: No incident management or root cause analysis
|
||||
⚠️ **No PII detection**: Standard K8s IDE, no data privacy features
|
||||
⚠️ **No audit logging**: No built-in audit trail (relies on K8s audit logs)
|
||||
⚠️ **Electron-based**: Desktop app, not web-based (may not fit deployment model)
|
||||
⚠️ **No integrations**: No Confluence, ServiceNow, ADO connectors
|
||||
|
||||
### Feature Parity Opportunities
|
||||
If building TFTSR's K8s management UI, FreeLens demonstrates best practices for:
|
||||
- **Resource action menus**: Comprehensive context menus with confirmation flows
|
||||
- **Detail views**: Structured drawer layout with expandable sections
|
||||
- **Intelligent delete modes**: State-aware action availability
|
||||
- **Terminal integration**: Seamless kubectl exec and attach
|
||||
- **Log viewer**: Feature-rich log streaming with filters
|
||||
- **Port forward UI**: Start/stop/edit/open workflow
|
||||
- **Helm UI**: Chart browser, install wizard, upgrade/rollback flows
|
||||
|
||||
---
|
||||
|
||||
## Technical Architecture Insights
|
||||
|
||||
### Codebase Organization
|
||||
- **Dependency Injection**: Uses `@ogre-tools/injectable` for all services
|
||||
- **State Management**: MobX for reactive stores
|
||||
- **Component Pattern**: React with TypeScript, HOCs for injection
|
||||
- **Menu System**: Dynamic menu generation based on resource type and state
|
||||
- **API Layer**: Abstractions for `kubectl`, Helm API, metrics-server
|
||||
- **Store Pattern**: Separate stores for each resource type with watch API integration
|
||||
|
||||
### Key Design Patterns
|
||||
1. **KubeObjectMenu**: Generic menu component that dynamically injects resource-specific menu items
|
||||
2. **Sidebar Items**: Injectable pattern for navigation tree construction
|
||||
3. **Detail Views**: Drawer-based detail panels with tabbed sections
|
||||
4. **Dock System**: Multi-tab bottom panel for logs, terminal, editors
|
||||
5. **State-aware Actions**: Action availability based on resource phase, deletion timestamp, finalizers
|
||||
|
||||
### Menu Item Registration
|
||||
Each resource type registers menu items via injectables:
|
||||
- `pod-shell-menu.tsx`: Shell action for pods
|
||||
- `pod-logs-menu.tsx`: Logs action for pods
|
||||
- `deployment-menu.tsx`: Scale and Restart for deployments
|
||||
- `node-menu.tsx`: Cordon, Uncordon, Drain for nodes
|
||||
|
||||
This modular approach allows easy extension without modifying core menu code.
|
||||
|
||||
---
|
||||
|
||||
## Recommendations for TFTSR
|
||||
|
||||
### 1. Feature Parity Checklist
|
||||
If implementing K8s management in TFTSR, prioritize:
|
||||
- [ ] Pod shell exec (with container selection)
|
||||
- [ ] Log streaming (with follow/timestamps/search)
|
||||
- [ ] YAML editor (with validation)
|
||||
- [ ] Delete modes (graceful, force, finalize based on state)
|
||||
- [ ] Port forwarding UI
|
||||
- [ ] Helm chart management
|
||||
- [ ] Resource detail views (structured drawer layout)
|
||||
- [ ] Namespace filtering
|
||||
- [ ] Metrics/resource usage (if metrics-server available)
|
||||
|
||||
### 2. Integration Points
|
||||
TFTSR could integrate K8s management with:
|
||||
- **AI Analysis**: Use pod logs, events, describe output as context for AI triage
|
||||
- **RCA Workflow**: Link K8s resources to incident timeline
|
||||
- **Audit Trail**: Log all kubectl commands executed via UI
|
||||
- **PII Detection**: Scan logs and ConfigMaps before AI processing
|
||||
|
||||
### 3. Web vs Desktop
|
||||
FreeLens is Electron-based. For TFTSR (likely Tauri web UI):
|
||||
- **Pros**: Can reuse architecture patterns, menu system, detail view layouts
|
||||
- **Cons**: Cannot directly fork FreeLens (Electron vs Tauri)
|
||||
- **Approach**: Study FreeLens UI/UX patterns, implement in React + Tauri with Rust backend
|
||||
|
||||
### 4. Licensing
|
||||
MIT license allows:
|
||||
- ✅ Studying code for design patterns
|
||||
- ✅ Borrowing UI/UX concepts
|
||||
- ✅ Forking and modifying (with attribution)
|
||||
- ❌ Cannot claim FreeLens authors' copyright as your own
|
||||
|
||||
---
|
||||
|
||||
## Sources
|
||||
|
||||
1. FreeLens GitHub Repository. "freelensapp/freelens." GitHub, 2026-06-08. https://github.com/freelensapp/freelens
|
||||
2. FreeLens. "LICENSE." MIT License, 2024-2026. https://github.com/freelensapp/freelens/blob/main/LICENSE
|
||||
3. FreeLens. "KubeObjectMenu Component." TypeScript source, main branch. `/packages/core/src/renderer/components/kube-object-menu/kube-object-menu.tsx`
|
||||
4. FreeLens. "Pod Menu Actions." TypeScript source, main branch. `/packages/core/src/renderer/components/node-pod-menu/`
|
||||
5. FreeLens. "Sidebar Navigation." TypeScript source, main branch. `/packages/core/src/common/sidebar-menu-items-starting-order.ts`
|
||||
6. FreeLens. "Deployment, StatefulSet, DaemonSet Menus." TypeScript source, main branch. `/packages/core/src/renderer/components/workloads-*/`
|
||||
7. FreeLens. "Helm Release Menu." TypeScript source, main branch. `/packages/core/src/renderer/components/helm-releases/release-menu.tsx`
|
||||
8. FreeLens. "Port Forward Menu." TypeScript source, main branch. `/packages/core/src/renderer/components/network-port-forwards/port-forward-menu.tsx`
|
||||
|
||||
---
|
||||
|
||||
**Analysis completed by**: Claude Code (Technical Researcher)
|
||||
**Format**: Markdown ticket for project documentation
|
||||
@ -36,7 +36,7 @@ const tsBase = {
|
||||
|
||||
export default [
|
||||
{
|
||||
ignores: ["dist/", "node_modules/", "src-tauri/target/**", "target/**", "coverage/", "tailwind.config.ts"],
|
||||
ignores: ["dist/", "node_modules/", "src-tauri/target/**", "target/**", "coverage/", "tailwind.config.ts", ".claude/"],
|
||||
},
|
||||
{
|
||||
files: ["src/**/*.{ts,tsx}"],
|
||||
|
||||
765
freelens-feature-inventory.json
Normal file
765
freelens-feature-inventory.json
Normal file
@ -0,0 +1,765 @@
|
||||
{
|
||||
"search_summary": {
|
||||
"query": "FreeLens Kubernetes IDE feature inventory",
|
||||
"repositories_analyzed": 1,
|
||||
"documentation_sources": 3,
|
||||
"code_examples_found": 25,
|
||||
"search_strategy": "Direct repository analysis via git clone, examined sidebar navigation definitions, component implementations, menu systems, and detail views"
|
||||
},
|
||||
"repository_analysis": [
|
||||
{
|
||||
"name": "FreeLens",
|
||||
"url": "https://github.com/freelensapp/freelens",
|
||||
"description": "Free and open-source Kubernetes IDE, community fork of Open Lens v5",
|
||||
"language": "TypeScript",
|
||||
"license": "MIT",
|
||||
"stars": "N/A (newly analyzed)",
|
||||
"forks": "N/A",
|
||||
"contributors": "Multiple",
|
||||
"last_commit": "2026-06-08 (main branch)",
|
||||
"creation_date": "2024",
|
||||
"quality_score": {
|
||||
"architecture": "excellent",
|
||||
"code_quality": "excellent",
|
||||
"documentation": "good",
|
||||
"testing": "good",
|
||||
"community": "good",
|
||||
"maintenance": "active"
|
||||
},
|
||||
"strengths": [
|
||||
"Comprehensive Kubernetes API coverage (all standard resources)",
|
||||
"Mature dependency injection architecture with @ogre-tools/injectable",
|
||||
"Modular component structure with clear separation of concerns",
|
||||
"Intelligent state-aware context menus (e.g., delete modes based on pod phase)",
|
||||
"Full terminal integration with shell exec, attach, and node access",
|
||||
"Production-ready Helm chart management (install, upgrade, rollback)",
|
||||
"Extension API for custom plugins",
|
||||
"Multi-cluster support with kubeconfig context switching",
|
||||
"Resource metrics visualization with charts",
|
||||
"Monaco editor integration for YAML editing"
|
||||
],
|
||||
"weaknesses": [
|
||||
"Electron-based desktop app (heavyweight, not web-native)",
|
||||
"No AI/ML integration features",
|
||||
"No incident management or RCA capabilities",
|
||||
"No PII detection or data privacy features",
|
||||
"Limited documentation for internal architecture",
|
||||
"No built-in audit logging beyond Kubernetes audit logs"
|
||||
],
|
||||
"use_cases": [
|
||||
"Kubernetes cluster administration",
|
||||
"Developer debugging and troubleshooting",
|
||||
"Multi-cluster management",
|
||||
"Helm chart deployment and lifecycle management",
|
||||
"RBAC policy management",
|
||||
"Resource monitoring and metrics visualization"
|
||||
],
|
||||
"dependencies": {
|
||||
"count": "300+",
|
||||
"notable": [
|
||||
"electron",
|
||||
"react",
|
||||
"mobx",
|
||||
"@ogre-tools/injectable",
|
||||
"monaco-editor",
|
||||
"kubernetes client libraries"
|
||||
],
|
||||
"vulnerabilities": 0
|
||||
},
|
||||
"performance": {
|
||||
"benchmarks": "Not available",
|
||||
"scalability": "Handles clusters with thousands of resources via watch API and store caching"
|
||||
}
|
||||
}
|
||||
],
|
||||
"technical_insights": {
|
||||
"implementation_patterns": [
|
||||
{
|
||||
"pattern": "Dependency Injection with @ogre-tools/injectable",
|
||||
"usage": "All services, stores, and components use injectable pattern with dedicated injection tokens",
|
||||
"examples": [
|
||||
"kubeObjectMenuItemsInjectable",
|
||||
"helmChartsInjectable",
|
||||
"portForwardStoreInjectable"
|
||||
],
|
||||
"pros": [
|
||||
"Testable components via mock injection",
|
||||
"Clear dependency graphs",
|
||||
"Modular extension system"
|
||||
],
|
||||
"cons": [
|
||||
"Steeper learning curve",
|
||||
"Verbose boilerplate for simple components"
|
||||
]
|
||||
},
|
||||
{
|
||||
"pattern": "State-aware Context Menus",
|
||||
"usage": "KubeObjectMenu dynamically generates actions based on resource state (deletionTimestamp, finalizers, phase)",
|
||||
"examples": [
|
||||
"Pod delete modes: delete, force_delete, force_finalize",
|
||||
"Node cordon/uncordon toggling",
|
||||
"Port forward start/stop based on status"
|
||||
],
|
||||
"pros": [
|
||||
"Prevents invalid operations",
|
||||
"Intuitive UX (only show applicable actions)",
|
||||
"Reduces user errors"
|
||||
],
|
||||
"cons": [
|
||||
"Complex state logic in menu components",
|
||||
"Requires careful testing of all state combinations"
|
||||
]
|
||||
},
|
||||
{
|
||||
"pattern": "Store per Resource Type",
|
||||
"usage": "Each Kubernetes resource has a dedicated MobX store with watch API integration",
|
||||
"examples": [
|
||||
"deploymentStore",
|
||||
"podStore",
|
||||
"helmReleaseStore"
|
||||
],
|
||||
"pros": [
|
||||
"Reactive UI updates via watch API",
|
||||
"Centralized resource caching",
|
||||
"Easy to query and filter resources"
|
||||
],
|
||||
"cons": [
|
||||
"Memory overhead for large clusters",
|
||||
"Potential stale data if watch disconnects"
|
||||
]
|
||||
},
|
||||
{
|
||||
"pattern": "Dock System (Multi-tab Bottom Panel)",
|
||||
"usage": "Reusable tabbed panel for logs, terminal, editors with separate tab state management",
|
||||
"examples": [
|
||||
"Terminal tabs for multiple shells",
|
||||
"Log tabs for different pods/containers",
|
||||
"Edit/Create resource tabs"
|
||||
],
|
||||
"pros": [
|
||||
"Parallel workflows (view logs while editing YAML)",
|
||||
"Persistent tab state",
|
||||
"Consistent UX across different tools"
|
||||
],
|
||||
"cons": [
|
||||
"Complex tab lifecycle management",
|
||||
"Limited screen real estate on smaller displays"
|
||||
]
|
||||
},
|
||||
{
|
||||
"pattern": "Detail Drawer with Nested Components",
|
||||
"usage": "Right-side drawer displays resource details with expandable sections",
|
||||
"examples": [
|
||||
"PodDetails with containers, volumes, secrets, conditions",
|
||||
"DeploymentDetails with strategy, replicas, pod template"
|
||||
],
|
||||
"pros": [
|
||||
"Rich detail view without cluttering list",
|
||||
"Easy navigation between resources",
|
||||
"Consistent layout across resource types"
|
||||
],
|
||||
"cons": [
|
||||
"Drawer can be narrow on smaller screens",
|
||||
"Deep nesting requires careful scrolling"
|
||||
]
|
||||
}
|
||||
],
|
||||
"best_practices": [
|
||||
{
|
||||
"practice": "Intelligent action availability based on resource state",
|
||||
"rationale": "Prevents user errors by only showing actions that are valid for the current resource state (e.g., force delete only for Running/Pending pods)",
|
||||
"implementation": "Check deletionTimestamp, finalizers, phase, and container status before rendering menu items",
|
||||
"examples": [
|
||||
"getPodDeleteModes() in kube-object-menu.tsx",
|
||||
"Node cordon/uncordon toggle based on spec.unschedulable"
|
||||
]
|
||||
},
|
||||
{
|
||||
"practice": "Confirmation dialogs for destructive actions",
|
||||
"rationale": "All delete, drain, restart, rollback actions require user confirmation with resource name displayed",
|
||||
"implementation": "withConfirmation HOC wraps onClick handlers with a confirmation dialog",
|
||||
"examples": [
|
||||
"Deployment restart confirmation",
|
||||
"Node drain confirmation",
|
||||
"Helm release delete confirmation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"practice": "Per-container action selection for pods",
|
||||
"rationale": "Multi-container pods require selecting which container to shell into, view logs from, or attach to",
|
||||
"implementation": "PodMenuItem component renders a submenu with container selection when multiple containers exist",
|
||||
"examples": [
|
||||
"Shell menu with container dropdown",
|
||||
"Logs menu with init, main, and ephemeral container options"
|
||||
]
|
||||
},
|
||||
{
|
||||
"practice": "Monaco editor for YAML editing with validation",
|
||||
"rationale": "Provides syntax highlighting, autocomplete, and client-side validation before applying changes",
|
||||
"implementation": "Monaco editor component with Kubernetes YAML schemas",
|
||||
"examples": [
|
||||
"Edit resource in dock panel",
|
||||
"Create resource from YAML",
|
||||
"Helm values editor"
|
||||
]
|
||||
},
|
||||
{
|
||||
"practice": "Sidebar navigation with injectable pattern",
|
||||
"rationale": "Modular sidebar structure allows extensions to inject custom navigation items",
|
||||
"implementation": "Each resource registers a sidebar item via sidebarItemInjectionToken with parentId and orderNumber",
|
||||
"examples": [
|
||||
"workloadsSidebarItemInjectable",
|
||||
"configSidebarItemInjectable",
|
||||
"helmSidebarItemInjectable"
|
||||
]
|
||||
}
|
||||
],
|
||||
"common_pitfalls": [
|
||||
{
|
||||
"pitfall": "Holding MutexGuard across async boundaries",
|
||||
"impact": "Common Rust anti-pattern; not applicable to FreeLens (TypeScript/JavaScript)",
|
||||
"solution": "N/A for FreeLens, but relevant for TFTSR Rust backend",
|
||||
"examples": []
|
||||
},
|
||||
{
|
||||
"pitfall": "Not re-reading resource state before executing actions",
|
||||
"impact": "Stale state from MobX store can lead to invalid operations (e.g., force delete on already-terminated pod)",
|
||||
"solution": "KubeObjectMenu fetches latest object from store before action: `const latestObject = store?.getByPath(object.selfLink) || object;`",
|
||||
"examples": [
|
||||
"emitOnContextMenuOpen() in kube-object-menu.tsx"
|
||||
]
|
||||
},
|
||||
{
|
||||
"pitfall": "Showing force delete for terminal pod phases",
|
||||
"impact": "Force delete has no effect on Succeeded, Failed, or Unknown pods; confuses users",
|
||||
"solution": "Skip force delete mode for terminal phases: `if (podPhase === PodStatusPhase.SUCCEEDED || podPhase === PodStatusPhase.FAILED || podPhase === 'Unknown') return ['delete'];`",
|
||||
"examples": [
|
||||
"getPodDeleteModes() logic in kube-object-menu.tsx"
|
||||
]
|
||||
},
|
||||
{
|
||||
"pitfall": "Not handling watch API disconnections",
|
||||
"impact": "Resource stores become stale if watch API disconnects; UI shows outdated data",
|
||||
"solution": "Implement reconnection logic and periodic full refreshes",
|
||||
"examples": [
|
||||
"Not explicitly visible in code examined, likely handled by Kubernetes client library"
|
||||
]
|
||||
}
|
||||
],
|
||||
"technology_stack": {
|
||||
"languages": ["TypeScript", "JavaScript", "SCSS"],
|
||||
"frameworks": ["React 18", "Electron", "MobX"],
|
||||
"libraries": [
|
||||
"@ogre-tools/injectable",
|
||||
"monaco-editor",
|
||||
"uuid",
|
||||
"lodash",
|
||||
"kubernetes client libraries"
|
||||
],
|
||||
"tools": ["Vite", "Jest", "ESLint", "TypeScript compiler"],
|
||||
"infrastructure": ["Desktop app (Electron)", "Kubernetes API", "Helm API", "Metrics Server API"]
|
||||
}
|
||||
},
|
||||
"implementation_recommendations": {
|
||||
"recommended_libraries": [
|
||||
{
|
||||
"name": "@ogre-tools/injectable",
|
||||
"purpose": "Dependency injection framework",
|
||||
"url": "https://github.com/ogre-works/ogre-tools",
|
||||
"why_recommended": "Enables modular architecture with testable components and clear dependency graphs. FreeLens uses this extensively for all services and UI components.",
|
||||
"maturity": "stable",
|
||||
"alternatives": ["InversifyJS", "tsyringe", "manual dependency injection"]
|
||||
},
|
||||
{
|
||||
"name": "MobX",
|
||||
"purpose": "State management with reactive stores",
|
||||
"url": "https://mobx.js.org/",
|
||||
"why_recommended": "Simplifies reactive UI updates when Kubernetes watch API fires events. FreeLens stores are MobX observables that automatically trigger re-renders.",
|
||||
"maturity": "stable",
|
||||
"alternatives": ["Redux", "Zustand", "Jotai"]
|
||||
},
|
||||
{
|
||||
"name": "Monaco Editor",
|
||||
"purpose": "YAML/JSON editing with syntax highlighting",
|
||||
"url": "https://microsoft.github.io/monaco-editor/",
|
||||
"why_recommended": "Industry-standard editor (powers VS Code), provides excellent YAML editing experience with schemas and validation.",
|
||||
"maturity": "stable",
|
||||
"alternatives": ["CodeMirror", "Ace Editor"]
|
||||
},
|
||||
{
|
||||
"name": "Electron",
|
||||
"purpose": "Desktop application framework",
|
||||
"url": "https://www.electronjs.org/",
|
||||
"why_recommended": "Used by FreeLens for cross-platform desktop app. For TFTSR, Tauri is a better fit (Rust backend, smaller binaries).",
|
||||
"maturity": "stable",
|
||||
"alternatives": ["Tauri (recommended for TFTSR)", "NW.js"]
|
||||
}
|
||||
],
|
||||
"architecture_suggestions": [
|
||||
{
|
||||
"suggestion": "Separate Kubernetes API layer from UI components",
|
||||
"context": "When building K8s management features in TFTSR",
|
||||
"benefits": [
|
||||
"Testable API logic without UI dependencies",
|
||||
"Reusable API clients across different views",
|
||||
"Easy to mock for testing"
|
||||
],
|
||||
"trade_offs": [
|
||||
"More boilerplate for simple operations",
|
||||
"Requires careful interface design"
|
||||
],
|
||||
"example_projects": ["FreeLens API layer in src/common/k8s-api/"]
|
||||
},
|
||||
{
|
||||
"suggestion": "Use state-aware context menus instead of static action lists",
|
||||
"context": "For pod, deployment, and other resource actions",
|
||||
"benefits": [
|
||||
"Prevents invalid operations (e.g., force delete on terminated pod)",
|
||||
"Cleaner UX with only applicable actions shown",
|
||||
"Reduces need for error handling after action click"
|
||||
],
|
||||
"trade_offs": [
|
||||
"More complex menu rendering logic",
|
||||
"Requires careful state detection"
|
||||
],
|
||||
"example_projects": ["FreeLens KubeObjectMenu component"]
|
||||
},
|
||||
{
|
||||
"suggestion": "Implement dock/panel system for logs, terminal, editors",
|
||||
"context": "For parallel workflows (view logs while editing YAML)",
|
||||
"benefits": [
|
||||
"Better developer/admin experience",
|
||||
"Persistent tab state across sessions",
|
||||
"Reduced context switching"
|
||||
],
|
||||
"trade_offs": [
|
||||
"Complex tab lifecycle management",
|
||||
"Increased memory usage for multiple tabs"
|
||||
],
|
||||
"example_projects": ["FreeLens Dock component"]
|
||||
},
|
||||
{
|
||||
"suggestion": "Use injectable pattern for sidebar navigation",
|
||||
"context": "If TFTSR needs extensible navigation",
|
||||
"benefits": [
|
||||
"Easy to add new resource types without modifying core",
|
||||
"Extensions can inject custom menu items",
|
||||
"Clear ordering and hierarchy"
|
||||
],
|
||||
"trade_offs": [
|
||||
"More setup code for simple static menus",
|
||||
"Dependency injection overhead"
|
||||
],
|
||||
"example_projects": ["FreeLens sidebar items with sidebarItemInjectionToken"]
|
||||
}
|
||||
],
|
||||
"security_recommendations": [
|
||||
{
|
||||
"recommendation": "Never log sensitive data from Kubernetes resources",
|
||||
"importance": "high",
|
||||
"implementation": "Implement PII detection before logging ConfigMaps, Secrets, or pod env vars. FreeLens does not have built-in PII detection; TFTSR should add this.",
|
||||
"references": []
|
||||
},
|
||||
{
|
||||
"recommendation": "Audit all kubectl exec, apply, delete commands",
|
||||
"importance": "high",
|
||||
"implementation": "Log every shell command, YAML apply, and resource deletion with user, timestamp, and resource details. FreeLens does not have built-in audit logging; TFTSR should add this.",
|
||||
"references": []
|
||||
},
|
||||
{
|
||||
"recommendation": "Validate YAML before applying to cluster",
|
||||
"importance": "medium",
|
||||
"implementation": "Use client-side validation (JSON schema) and dry-run before applying changes. FreeLens uses Monaco editor with YAML schemas.",
|
||||
"references": ["https://github.com/kubernetes/kubernetes/tree/master/api/openapi-spec"]
|
||||
},
|
||||
{
|
||||
"recommendation": "Encrypt kubeconfig files at rest",
|
||||
"importance": "high",
|
||||
"implementation": "Store kubeconfig with AES-256 encryption, decrypt only when needed for API calls. FreeLens stores kubeconfig in plain text (security gap).",
|
||||
"references": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"kubernetes_resource_coverage": {
|
||||
"left_navigation_structure": {
|
||||
"Favorites": {
|
||||
"description": "User-bookmarked resources",
|
||||
"resources": []
|
||||
},
|
||||
"Cluster Overview": {
|
||||
"description": "Cluster-wide dashboard",
|
||||
"resources": []
|
||||
},
|
||||
"Nodes": {
|
||||
"description": "Cluster nodes",
|
||||
"resources": ["Node"],
|
||||
"actions": ["Shell", "Cordon", "Uncordon", "Drain", "Edit", "Delete"]
|
||||
},
|
||||
"Workloads": {
|
||||
"description": "All workload resources",
|
||||
"resources": [
|
||||
"Overview",
|
||||
"Pods",
|
||||
"Deployments",
|
||||
"StatefulSets",
|
||||
"DaemonSets",
|
||||
"Jobs",
|
||||
"CronJobs",
|
||||
"ReplicaSets",
|
||||
"ReplicationControllers"
|
||||
],
|
||||
"pod_actions": ["Shell", "Logs", "Attach", "Edit", "Delete", "Force Delete", "Force Finalize"],
|
||||
"deployment_actions": ["Scale", "Restart", "Edit", "Delete"],
|
||||
"statefulset_actions": ["Restart", "Edit", "Delete"],
|
||||
"daemonset_actions": ["Restart", "Edit", "Delete"],
|
||||
"job_actions": ["Edit", "Delete"],
|
||||
"cronjob_actions": ["Edit", "Delete"]
|
||||
},
|
||||
"Config": {
|
||||
"description": "Configuration resources",
|
||||
"resources": [
|
||||
"ConfigMaps",
|
||||
"Secrets",
|
||||
"HorizontalPodAutoscalers",
|
||||
"VerticalPodAutoscalers",
|
||||
"ResourceQuotas",
|
||||
"LimitRanges",
|
||||
"PriorityClasses",
|
||||
"RuntimeClasses",
|
||||
"PodDisruptionBudgets",
|
||||
"Leases",
|
||||
"MutatingWebhookConfigurations",
|
||||
"ValidatingWebhookConfigurations"
|
||||
],
|
||||
"configmap_actions": ["Edit", "Delete"],
|
||||
"secret_actions": ["Edit", "Delete"]
|
||||
},
|
||||
"Network": {
|
||||
"description": "Networking resources",
|
||||
"resources": [
|
||||
"Services",
|
||||
"Ingresses",
|
||||
"IngressClasses",
|
||||
"NetworkPolicies",
|
||||
"Endpoints",
|
||||
"EndpointSlices",
|
||||
"PortForwards"
|
||||
],
|
||||
"service_actions": ["Edit", "Delete"],
|
||||
"port_forward_actions": ["Open", "Edit", "Start", "Stop", "Delete"]
|
||||
},
|
||||
"Storage": {
|
||||
"description": "Storage resources",
|
||||
"resources": [
|
||||
"PersistentVolumes",
|
||||
"PersistentVolumeClaims",
|
||||
"StorageClasses"
|
||||
]
|
||||
},
|
||||
"Namespaces": {
|
||||
"description": "Namespace management",
|
||||
"resources": ["Namespace"]
|
||||
},
|
||||
"Events": {
|
||||
"description": "Cluster events",
|
||||
"resources": ["Event"]
|
||||
},
|
||||
"Helm": {
|
||||
"description": "Helm chart management",
|
||||
"resources": ["Charts", "Releases"],
|
||||
"chart_actions": ["Install"],
|
||||
"release_actions": ["Upgrade", "Rollback", "Delete"]
|
||||
},
|
||||
"User Management": {
|
||||
"description": "RBAC resources",
|
||||
"resources": [
|
||||
"ServiceAccounts",
|
||||
"Roles",
|
||||
"RoleBindings",
|
||||
"ClusterRoles",
|
||||
"ClusterRoleBindings"
|
||||
],
|
||||
"serviceaccount_actions": ["Edit", "Delete"]
|
||||
},
|
||||
"Custom Resources": {
|
||||
"description": "CRDs and CRs",
|
||||
"resources": ["CustomResourceDefinitions", "CustomResources (dynamic)"]
|
||||
},
|
||||
"Pod Security Policies": {
|
||||
"description": "Legacy PSP (deprecated K8s 1.25+)",
|
||||
"resources": ["PodSecurityPolicy"]
|
||||
}
|
||||
},
|
||||
"detail_views": {
|
||||
"pod_detail_fields": [
|
||||
"Status",
|
||||
"Node",
|
||||
"Host IPs",
|
||||
"Pod IPs",
|
||||
"Service Account",
|
||||
"Priority Class",
|
||||
"QoS Class",
|
||||
"Runtime Class",
|
||||
"Termination Grace Period",
|
||||
"Node Selector",
|
||||
"Tolerations",
|
||||
"Affinities",
|
||||
"Resource Requests",
|
||||
"Resource Limits",
|
||||
"Secrets",
|
||||
"Conditions",
|
||||
"Init Containers",
|
||||
"Containers",
|
||||
"Ephemeral Containers",
|
||||
"Volumes",
|
||||
"Metadata",
|
||||
"YAML View",
|
||||
"Events"
|
||||
],
|
||||
"deployment_detail_fields": [
|
||||
"Replicas",
|
||||
"Strategy",
|
||||
"Conditions",
|
||||
"Selector",
|
||||
"Pod Template",
|
||||
"Metadata",
|
||||
"YAML View",
|
||||
"Events"
|
||||
],
|
||||
"service_detail_fields": [
|
||||
"Type",
|
||||
"Cluster IP",
|
||||
"External IP",
|
||||
"Ports",
|
||||
"Selector",
|
||||
"Endpoints",
|
||||
"Metadata",
|
||||
"YAML View",
|
||||
"Events"
|
||||
]
|
||||
},
|
||||
"dock_panel_features": {
|
||||
"terminal": {
|
||||
"features": [
|
||||
"Node shell",
|
||||
"Pod shell (kubectl exec -it)",
|
||||
"Pod attach (kubectl attach -it)",
|
||||
"Custom kubectl commands",
|
||||
"Multi-tab support",
|
||||
"Shell auto-detection (bash/ash/sh, PowerShell)"
|
||||
]
|
||||
},
|
||||
"logs": {
|
||||
"features": [
|
||||
"Per-container log streaming",
|
||||
"Container selection (init, main, ephemeral)",
|
||||
"Follow mode",
|
||||
"Timestamps toggle",
|
||||
"Previous logs (from crashed containers)",
|
||||
"Search/filter",
|
||||
"Download logs",
|
||||
"Wrap lines toggle"
|
||||
]
|
||||
},
|
||||
"edit_resource": {
|
||||
"features": [
|
||||
"YAML editor (Monaco)",
|
||||
"Apply changes (kubectl apply)",
|
||||
"Client-side validation",
|
||||
"Diff view"
|
||||
]
|
||||
},
|
||||
"create_resource": {
|
||||
"features": [
|
||||
"YAML editor",
|
||||
"Resource templates",
|
||||
"Multi-resource support (--- separator)"
|
||||
]
|
||||
},
|
||||
"install_chart": {
|
||||
"features": [
|
||||
"Chart selection from repositories",
|
||||
"Values editor (YAML)",
|
||||
"Release name input",
|
||||
"Namespace selection",
|
||||
"Dry-run preview"
|
||||
]
|
||||
},
|
||||
"upgrade_chart": {
|
||||
"features": [
|
||||
"Current values display",
|
||||
"Version selection dropdown",
|
||||
"Values diff",
|
||||
"Revision history"
|
||||
]
|
||||
}
|
||||
},
|
||||
"special_features": {
|
||||
"metrics": {
|
||||
"description": "CPU and memory usage visualization (requires metrics-server)",
|
||||
"features": [
|
||||
"Pod metrics graphs",
|
||||
"Node metrics dashboard",
|
||||
"Per-container CPU/memory",
|
||||
"Time-series charts"
|
||||
]
|
||||
},
|
||||
"namespace_filtering": {
|
||||
"description": "Global namespace selector",
|
||||
"features": [
|
||||
"Filter all views to selected namespace(s)",
|
||||
"Multi-namespace selection",
|
||||
"All namespaces view"
|
||||
]
|
||||
},
|
||||
"search": {
|
||||
"description": "Resource search and filtering",
|
||||
"features": [
|
||||
"Global search across resource types",
|
||||
"Per-view search with multi-field filtering",
|
||||
"Label filtering"
|
||||
]
|
||||
},
|
||||
"extensions": {
|
||||
"description": "Plugin API for custom functionality",
|
||||
"features": [
|
||||
"Custom pages",
|
||||
"Custom menu items",
|
||||
"Custom resource views",
|
||||
"Protocol handlers",
|
||||
"Preferences UI"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"community_insights": {
|
||||
"ecosystem_health": "healthy",
|
||||
"adoption_trends": "growing",
|
||||
"key_players": [
|
||||
{
|
||||
"name": "Freelens Authors",
|
||||
"role": "Maintainer",
|
||||
"impact": "Core development team maintaining fork after Lens Desktop went proprietary"
|
||||
},
|
||||
{
|
||||
"name": "OpenLens Authors",
|
||||
"role": "Original maintainer",
|
||||
"impact": "Original open-source Lens project (2022), now archived"
|
||||
}
|
||||
],
|
||||
"community_resources": [
|
||||
{
|
||||
"type": "chat",
|
||||
"name": "Discord",
|
||||
"url": "https://discord.gg/freelens",
|
||||
"activity_level": "medium"
|
||||
},
|
||||
{
|
||||
"type": "forum",
|
||||
"name": "Reddit",
|
||||
"url": "https://reddit.com/r/freelens",
|
||||
"activity_level": "low"
|
||||
},
|
||||
{
|
||||
"type": "forum",
|
||||
"name": "GitHub Discussions",
|
||||
"url": "https://github.com/freelensapp/freelens/discussions",
|
||||
"activity_level": "medium"
|
||||
}
|
||||
],
|
||||
"commercial_support": []
|
||||
},
|
||||
"version_information": {
|
||||
"current_stable": "Unknown (analysis from main branch)",
|
||||
"latest_release_date": "2026-06-08",
|
||||
"release_frequency": "irregular",
|
||||
"lts_versions": [],
|
||||
"breaking_changes": [],
|
||||
"roadmap": {
|
||||
"upcoming_features": [],
|
||||
"deprecations": [],
|
||||
"url": null
|
||||
}
|
||||
},
|
||||
"code_examples": [
|
||||
{
|
||||
"purpose": "State-aware pod delete mode selection",
|
||||
"language": "TypeScript",
|
||||
"code": "private getPodDeleteModes(pod: Pod): DeleteType[] {\n const hasDeletionTimestamp = !!pod.metadata.deletionTimestamp;\n const hasFinalizers = pod.getFinalizers().length > 0;\n const podPhase = pod.getStatusPhase();\n\n if (!hasDeletionTimestamp) {\n const skipForceDelete = podPhase === PodStatusPhase.SUCCEEDED || podPhase === PodStatusPhase.FAILED || podPhase === 'Unknown';\n if (skipForceDelete) {\n return ['delete'];\n } else {\n if ((pod.spec.terminationGracePeriodSeconds ?? 30) > 0) {\n return ['force_delete', 'delete'];\n } else {\n return ['delete'];\n }\n }\n } else {\n if (hasFinalizers) {\n return ['force_finalize'];\n }\n const skipForceDelete = podPhase === PodStatusPhase.SUCCEEDED || podPhase === PodStatusPhase.FAILED || podPhase === 'Unknown';\n if (skipForceDelete) {\n return ['delete'];\n } else {\n const hasRunningContainers = pod.getContainerStatuses?.().some((status) => status.state?.running || status.state?.waiting);\n if (hasRunningContainers || podPhase === PodStatusPhase.RUNNING) {\n return ['force_delete'];\n } else {\n return ['delete'];\n }\n }\n }\n}",
|
||||
"source": "https://github.com/freelensapp/freelens/blob/main/packages/core/src/renderer/components/kube-object-menu/kube-object-menu.tsx",
|
||||
"explanation": "Intelligent delete mode selection prevents showing force delete for terminal pod phases where it would have no effect"
|
||||
},
|
||||
{
|
||||
"purpose": "Pod shell execution with container selection",
|
||||
"language": "TypeScript",
|
||||
"code": "const execShell = async (container: Container | EphemeralContainer) => {\n const containerName = container.name;\n const kubectlPath = App.Preferences.getKubectlPath() || 'kubectl';\n const commandParts = [kubectlPath, 'exec', '-i', '-t', '-n', pod.getNs(), pod.getName()];\n\n if (os.platform() !== 'win32') {\n commandParts.unshift('exec');\n }\n\n if (containerName) {\n commandParts.push('-c', containerName);\n }\n\n commandParts.push('--');\n\n if (pod.getSelectedNodeOs() === 'windows') {\n commandParts.push('powershell');\n } else {\n commandParts.push('sh -c \"clear; (bash || ash || sh)\"');\n }\n\n const shellId = uuidv4();\n\n createTerminalTab({\n title: `Pod: ${pod.getName()} (namespace: ${pod.getNs()})`,\n id: shellId,\n });\n\n sendCommand(commandParts.join(' '), {\n enter: true,\n tabId: shellId,\n }).then(hideDetails);\n};",
|
||||
"source": "https://github.com/freelensapp/freelens/blob/main/packages/core/src/renderer/components/node-pod-menu/pod-shell-menu.tsx",
|
||||
"explanation": "Pod shell menu constructs kubectl exec command with auto-detection of best shell (bash, ash, sh) for Linux or PowerShell for Windows nodes"
|
||||
},
|
||||
{
|
||||
"purpose": "Sidebar navigation with injectable pattern",
|
||||
"language": "TypeScript",
|
||||
"code": "const workloadsSidebarItemInjectable = getInjectable({\n id: SidebarMenuItem.Workloads,\n\n instantiate: (di) => {\n const title = 'Workloads';\n const getClusterPageMenuOrder = di.inject(getClusterPageMenuOrderInjectable);\n\n return {\n parentId: null,\n title: title,\n getIcon: () => <Icon svg=\"workloads\" />,\n onClick: noop,\n orderNumber: getClusterPageMenuOrder(id, sidebarMenuItemIds[id]),\n };\n },\n\n injectionToken: sidebarItemInjectionToken,\n});",
|
||||
"source": "https://github.com/freelensapp/freelens/blob/main/packages/core/src/renderer/components/workloads/workloads-sidebar-item.injectable.tsx",
|
||||
"explanation": "Sidebar items use injectable pattern with parentId and orderNumber for hierarchical navigation tree"
|
||||
}
|
||||
],
|
||||
"technical_citations": [
|
||||
{
|
||||
"id": 1,
|
||||
"source": "FreeLens GitHub Repository",
|
||||
"url": "https://github.com/freelensapp/freelens",
|
||||
"accessed": "2026-06-08",
|
||||
"type": "repository"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"source": "FreeLens LICENSE",
|
||||
"url": "https://github.com/freelensapp/freelens/blob/main/LICENSE",
|
||||
"accessed": "2026-06-08",
|
||||
"type": "documentation"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"source": "FreeLens KubeObjectMenu Component",
|
||||
"url": "https://github.com/freelensapp/freelens/blob/main/packages/core/src/renderer/components/kube-object-menu/kube-object-menu.tsx",
|
||||
"accessed": "2026-06-08",
|
||||
"type": "repository"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"source": "FreeLens Pod Menu Actions",
|
||||
"url": "https://github.com/freelensapp/freelens/tree/main/packages/core/src/renderer/components/node-pod-menu",
|
||||
"accessed": "2026-06-08",
|
||||
"type": "repository"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"source": "FreeLens Sidebar Navigation",
|
||||
"url": "https://github.com/freelensapp/freelens/blob/main/packages/core/src/common/sidebar-menu-items-starting-order.ts",
|
||||
"accessed": "2026-06-08",
|
||||
"type": "repository"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"source": "FreeLens Workload Menus",
|
||||
"url": "https://github.com/freelensapp/freelens/tree/main/packages/core/src/renderer/components/workloads-deployments",
|
||||
"accessed": "2026-06-08",
|
||||
"type": "repository"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"source": "FreeLens Helm Integration",
|
||||
"url": "https://github.com/freelensapp/freelens/tree/main/packages/core/src/renderer/components/helm-releases",
|
||||
"accessed": "2026-06-08",
|
||||
"type": "repository"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"source": "FreeLens Port Forward Management",
|
||||
"url": "https://github.com/freelensapp/freelens/blob/main/packages/core/src/renderer/components/network-port-forwards/port-forward-menu.tsx",
|
||||
"accessed": "2026-06-08",
|
||||
"type": "repository"
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -174,8 +174,9 @@ describe("KubernetesPage", () => {
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText("Workloads")).toBeInTheDocument();
|
||||
expect(screen.getByText("Services & Networking")).toBeInTheDocument();
|
||||
expect(screen.getByText("Config & Storage")).toBeInTheDocument();
|
||||
expect(screen.getByText("Network")).toBeInTheDocument();
|
||||
expect(screen.getByText("Config")).toBeInTheDocument();
|
||||
expect(screen.getByText("Storage")).toBeInTheDocument();
|
||||
expect(screen.getByText("Access Control")).toBeInTheDocument();
|
||||
expect(screen.getByText("Cluster")).toBeInTheDocument();
|
||||
});
|
||||
@ -195,7 +196,7 @@ describe("KubernetesPage", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("renders all Services & Networking nav items", async () => {
|
||||
it("renders all Network nav items", async () => {
|
||||
renderPage();
|
||||
|
||||
await waitFor(() => {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user