Skip to content
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
16 changes: 14 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Uma interface gráfica (GUI) moderna e intuitiva para visualização e consulta
Este é um projeto **Open Source**. Contribuições são muito bem-vindas! Veja o arquivo [CONTRIBUTING.md](CONTRIBUTING.md) para saber como ajudar.

![Visão Geral do Smash Kube](assets/screenshots/main-view.png)
*(Sugestão: Adicione aqui uma captura de tela da tela principal)*


## 🎯 Funcionalidades Principais

Expand Down Expand Up @@ -59,7 +59,7 @@ Utilize a barra lateral para alternar entre as diferentes categorias de recursos
### 3. Describe e Logs
Clique nos ícones de ação para ver detalhes técnicos ou logs em tempo real.

![Describe e Logs](assets/screenshots/describe-logs.png)
![Describe e Logs](assets/screenshots/describe-pod.png)

## 🛠️ Tecnologias Utilizadas

Expand Down Expand Up @@ -89,8 +89,20 @@ npm install

# Iniciar em modo de desenvolvimento (Webpack + Electron)
npm start

# Iniciar em MODO DEMO (Dados fictícios para prints e testes)
npm run start:demo
```

## 🖼️ Modo de Demonstração (DEMO)

O Smash Kube possui um modo especial para demonstrações, treinamentos ou capturas de tela sem a necessidade de uma conexão real com a AWS ou Kubernetes.

Ao executar `npm run start:demo`:
1. Uma conexão chamada **"demonstracao"** aparecerá automaticamente na barra lateral.
2. Ao selecionar essa conexão, a aplicação carregará dados fictícios (Pods, Deployments, Nodes, Logs, etc.) instantaneamente.
3. Nenhuma chamada real será feita à API da AWS ou do Kubernetes, tornando-o seguro para uso em qualquer ambiente.

## 📦 Build e Distribuição

Para gerar o executável (dmg, exe ou appimage) para o seu sistema:
Expand Down
Binary file added assets/screenshots/add-cluster.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/screenshots/describe-pod.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/screenshots/main-view.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/screenshots/navigation.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
19 changes: 18 additions & 1 deletion main/handlers/ipcHandlers.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,24 @@ const store = new Store();

function registerIpcHandlers() {
ipcMain.handle('get-clusters', () => {
return store.get('clusters', []);
const clusters = store.get('clusters', []);

// --- MODO DEMO: Injetar cluster de demonstração ---
if (process.env.DEMO_MODE === 'true') {
const demoCluster = {
id: 'demo-id-123',
name: 'demonstracao',
region: 'us-east-1',
profile: 'demo-profile',
authMethod: 'sso'
};
// Garantir que o cluster demo apareça na lista se não estiver lá
if (!clusters.find(c => c.name === 'demonstracao')) {
return [demoCluster, ...clusters];
}
}

return clusters;
});

ipcMain.handle('save-clusters', (event, clusters) => {
Expand Down
5 changes: 5 additions & 0 deletions main/services/awsService.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ class AwsService {
* @param {Object} cluster - Cluster configuration object.
*/
async updateKubeconfig(cluster) {
if (process.env.DEMO_MODE === 'true' && cluster.name === 'demonstracao') {
console.log('[DEMO] Skipping real updateKubeconfig for demo cluster');
return "Using DEMO MODE for cluster: demonstracao";
}

const { name, region, profile, accessKeyId, secretAccessKey, sessionToken, ssoUrl } = cluster;
const finalRegion = region || 'us-east-1';

Expand Down
57 changes: 57 additions & 0 deletions main/services/k8sService.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,14 @@ class K8sService {
}

async executeMethod(method, args) {
// --- MODO DEMO (FAKE DATA) PARA PRINTS ---
const isDemo = process.env.DEMO_MODE === 'true';
if (isDemo) {
console.log(`[DEMO] Mocking method: ${method}`);
return this.getFakeData(method, args);
}
// -----------------------------------------

const k8sApi = this.getApiClient(k8s.CoreV1Api);
const appsApi = this.getApiClient(k8s.AppsV1Api);
const networkingApi = this.getApiClient(k8s.NetworkingV1Api);
Expand Down Expand Up @@ -187,6 +195,55 @@ class K8sService {
output += `Status:\n${JSON.stringify(resourceData.status, null, 2)}\n`;
return output;
}

getFakeData(method, args) {
const ns = args?.namespace && args.namespace !== 'all' ? args.namespace : 'default';
const uid = () => Math.random().toString(36).substring(2, 15);
const date = new Date().toISOString();

switch (method) {
case 'listNamespaces':
return { items: [
{ metadata: { name: 'default' } },
{ metadata: { name: 'kube-system' } },
{ metadata: { name: 'production' } },
{ metadata: { name: 'staging' } },
{ metadata: { name: 'monitoring' } }
]};
case 'listPods':
return { items: [
{ metadata: { name: 'api-gateway-7f8d9b-x2k4', namespace: ns, uid: uid(), creationTimestamp: date }, status: { phase: 'Running', containerStatuses: [{ restartCount: 0, state: { running: {} } }] } },
{ metadata: { name: 'auth-service-5d4c3b-m9n1', namespace: ns, uid: uid(), creationTimestamp: date }, status: { phase: 'Running', containerStatuses: [{ restartCount: 2, state: { running: {} } }] } },
{ metadata: { name: 'payment-worker-88a2f-p0q8', namespace: ns, uid: uid(), creationTimestamp: date }, status: { phase: 'Pending', containerStatuses: [{ restartCount: 0, state: { waiting: { reason: 'ContainerCreating' } } }] } },
{ metadata: { name: 'redis-master-0', namespace: ns, uid: uid(), creationTimestamp: date }, status: { phase: 'Running', containerStatuses: [{ restartCount: 0, state: { running: {} } }] } }
]};
case 'listDeployments':
return { items: [
{ metadata: { name: 'api-gateway', namespace: ns, uid: uid(), creationTimestamp: date }, spec: { replicas: 3 }, status: { availableReplicas: 3, readyReplicas: 3, updatedReplicas: 3, conditions: [{ type: 'Available', status: 'True' }] } },
{ metadata: { name: 'auth-service', namespace: ns, uid: uid(), creationTimestamp: date }, spec: { replicas: 2 }, status: { availableReplicas: 2, readyReplicas: 2, updatedReplicas: 2, conditions: [{ type: 'Available', status: 'True' }] } }
]};
case 'listServices':
return { items: [
{ metadata: { name: 'api-gateway', namespace: ns, uid: uid(), creationTimestamp: date }, spec: { type: 'LoadBalancer', clusterIP: '10.100.0.1' }, status: { loadBalancer: { ingress: [{ hostname: 'a1b2c3d4.us-east-1.elb.amazonaws.com' }] } } },
{ metadata: { name: 'redis', namespace: ns, uid: uid(), creationTimestamp: date }, spec: { type: 'ClusterIP', clusterIP: '10.100.55.21' } }
]};
case 'listNodes':
return { items: [
{ metadata: { name: 'ip-192-168-10-1.ec2.internal', uid: uid(), creationTimestamp: date }, status: { capacity: { cpu: '4', memory: '16Gi' }, conditions: [{ type: 'Ready', status: 'True' }] } },
{ metadata: { name: 'ip-192-168-10-2.ec2.internal', uid: uid(), creationTimestamp: date }, status: { capacity: { cpu: '4', memory: '16Gi' }, conditions: [{ type: 'Ready', status: 'True' }] } }
]};
case 'getPodLogs':
return `[2024-03-14 10:00:01] INFO: Starting API Gateway...
[2024-03-14 10:00:05] INFO: Connected to Redis at 10.100.55.21:6379
[2024-03-14 10:00:10] DEBUG: Initializing authentication middleware
[2024-03-14 10:05:22] WARN: Latency spike detected on /v1/auth endpoint
[2024-03-14 10:10:00] INFO: Health check passed. Status: OK`;
case 'describeResource':
return `Name: \t\t${args.name}\nNamespace: \t${args.namespace}\nLabels: \tapp=${args.name}, env=production\nAPI Version: \tv1\nKind: \t\t${args.kind}\nCreation: \t${date}\n------------------------------------------------------------\n\nSpec:\n{\n "replicas": 3,\n "selector": {\n "matchLabels": {\n "app": "${args.name}"\n }\n }\n}\n\nStatus:\n{\n "availableReplicas": 3,\n "readyReplicas": 3\n}`;
default:
return { items: [] };
}
}
}

module.exports = new K8sService();
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"main": "main/index.js",
"scripts": {
"start": "concurrently \"npm run watch\" \"electron .\"",
"start:demo": "DEMO_MODE=true concurrently \"npm run watch\" \"electron .\"",
"watch": "webpack --watch --config webpack.config.js",
"build": "webpack --config webpack.config.js && electron-builder",
"compile": "webpack --config webpack.config.js",
Expand Down
Loading