mirror of
https://github.com/philippemerle/KubeDiagrams.git
synced 2026-08-16 14:16:14 +00:00
[Feature] Add Docker kubectl support and cluster connectivity + Apply Prettier formatting to frontend files
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user