[Feature] Add Docker kubectl support and cluster connectivity + Apply Prettier formatting to frontend files

This commit is contained in:
Sadallah
2026-06-11 11:55:22 +02:00
parent 7e105eb79a
commit 700d249986
6 changed files with 33 additions and 17 deletions
+7
View File
@@ -23,6 +23,13 @@ RUN apk update && apk add --no-cache \
musl-dev \
&& rm -rf /var/cache/apk/*
# Install kubectl (statically compiled Go binary — works on Alpine/musl)
RUN ARCH=$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/') && \
KUBECTL_VERSION=$(curl -fsSL https://dl.k8s.io/release/stable.txt) && \
curl -fsSL -o /usr/local/bin/kubectl \
"https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/linux/${ARCH}/kubectl" && \
chmod +x /usr/local/bin/kubectl
# Copy Helm from first stage
COPY --from=helm /usr/bin/helm /usr/local/bin/helm
+7
View File
@@ -43,8 +43,13 @@ services:
volumes:
# Persist logs outside container
- ./backend/logs:/app/logs
# Mount host kubeconfig so kubectl can reach the cluster started on the host
- ${HOME}/.kube:/root/.kube:ro
# Mount minikube certs at the same absolute path as on the host (kubeconfig references them by absolute path)
- ${HOME}/.minikube:${HOME}/.minikube:ro
networks:
- kubediagrams-network
- minikube
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "--fail", "--silent", "http://localhost:5000/api/health"]
@@ -59,3 +64,5 @@ services:
networks:
kubediagrams-network:
driver: bridge
minikube:
external: true
@@ -121,9 +121,7 @@ const HistoryPanel = ({ history, onRestore, onRemove, onClear, isOpen, onToggle
<div className="flex flex-col items-center justify-center h-full text-slate-500">
<FileText className="w-16 h-16 mb-4 opacity-50" />
<p className="text-center">No diagrams in history</p>
<p className="text-xs text-center mt-2">
Generated diagrams will appear here
</p>
<p className="text-xs text-center mt-2">Generated diagrams will appear here</p>
</div>
) : (
history.map((item) => (
@@ -80,7 +80,10 @@ function ClusterInput({
<label className="block text-sm font-medium text-white">Namespace</label>
<button
type="button"
onClick={() => { fetchNamespaces(); fetchContext(); }}
onClick={() => {
fetchNamespaces();
fetchContext();
}}
disabled={loadingNamespaces}
className="text-xs text-blue-400 hover:text-blue-300 flex items-center gap-1"
>
@@ -175,9 +178,12 @@ function ClusterInput({
: `${availableResourceTypes.length} types known by the cluster`}
{namespace && !allNamespaces && !resourceTypeSearch && (
<span>
{' '} resources tagged{' '}
<span className="text-purple-400 font-medium">cluster</span> are not bound to a
namespace but can still be included (e.g. nodes for pod placement).
{' '}
resources tagged <span className="text-purple-400 font-medium">
cluster
</span>{' '}
are not bound to a namespace but can still be included (e.g. nodes for pod
placement).
</span>
)}
</p>
@@ -262,7 +268,9 @@ function ClusterInput({
</>
)}
</div>
<p className={`text-xs mt-1 ${resourceTypes.length === 0 ? 'text-yellow-400' : 'text-gray-400'}`}>
<p
className={`text-xs mt-1 ${resourceTypes.length === 0 ? 'text-yellow-400' : 'text-gray-400'}`}
>
{resourceTypes.length > 0
? `${resourceTypes.length} type${resourceTypes.length > 1 ? 's' : ''} selected`
: 'No types selected — please select at least one resource type.'}
@@ -307,12 +315,10 @@ function ClusterInput({
<>
<strong>No cluster detected.</strong> Start your cluster, then click{' '}
<strong>Refresh</strong>:
<br /> minikube:{' '}
<code className="bg-gray-800 px-1 rounded">minikube start</code>
<br /> minikube: <code className="bg-gray-800 px-1 rounded">minikube start</code>
<br /> kind:{' '}
<code className="bg-gray-800 px-1 rounded">kind create cluster</code>
<br /> k3d:{' '}
<code className="bg-gray-800 px-1 rounded">k3d cluster create</code>
<br /> k3d: <code className="bg-gray-800 px-1 rounded">k3d cluster create</code>
<br />
Make sure <code className="bg-gray-800 px-1 rounded">kubectl</code> is installed
and your kubeconfig points to the right context.
@@ -406,4 +412,4 @@ ClusterInput.propTypes = {
handleNamespaceChange: PropTypes.func.isRequired,
};
export default ClusterInput;
export default ClusterInput;
+2 -3
View File
@@ -136,8 +136,7 @@ export function useClusterData({
const commons = availableResourceTypes.filter((rt) => rt.isCommon);
// With a specific namespace, default to namespaced commons only — cluster-scoped
// resources (nodes, storageclasses…) can still be added manually.
const selected =
namespace && !allNamespaces ? commons.filter((rt) => rt.namespaced) : commons;
const selected = namespace && !allNamespaces ? commons.filter((rt) => rt.namespaced) : commons;
setResourceTypes(selected.map((rt) => rt.name));
};
@@ -226,4 +225,4 @@ export function useClusterData({
handleAllNamespacesToggle,
handleNamespaceChange,
};
}
}
@@ -306,7 +306,6 @@ export async function getClusterResourceTypes() {
}
}
/**
* Submit user feedback
* @param {Object} params - Feedback parameters