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
3 changes: 2 additions & 1 deletion CONTRIBUTIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ Pull requests are the best way to propose changes to the codebase. We actively w

## Any contributions you make will be under the MIT Software License

In short, when you submit code changes, your submissions are understood to be under the same [MIT License](http://choosealicense.com/licenses/mit/) that covers the project. Feel free to contact the maintainers if that's a concern.
In short, when you submit code changes, your submissions are understood to be under the same [MIT License](http://choosealicense.com/licenses/mit/) that covers
the project. Feel free to contact the maintainers if that's a concern.

## Development

Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Codefresh Support Package

This project is designed to gather data from Hybrid Runtimes for Codefresh SaaS platform, and Hybrid Runtimes and OnPrem isntallation on the OnPrem Platform. It collects information about various Kubernetes resources such as Pods, Nodes, Configmaps, Services, and Events. For Classic and OnPrem we gather some informtion from the platform itself.
This project is designed to gather data from Hybrid Runtimes for Codefresh SaaS platform, and Hybrid Runtimes and OnPrem isntallation on the OnPrem Platform. It
collects information about various Kubernetes resources such as Pods, Nodes, Configmaps, Services, and Events. For Classic and OnPrem we gather some informtion
from the platform itself.

## Prereqs

Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.2.0
2.3.0
46 changes: 36 additions & 10 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,31 +38,48 @@ function selectRuntimeType() {
async function saveItems(resources, dir) {
try {
await Deno.mkdir(`${dirPath}/${dir}/`, { recursive: true });

const writePromises = resources.map(async (item) => {
const filePath = `${dirPath}/${dir}/${item.metadata.name}.yaml`;
const filePath = `${dirPath}/${dir}/${item.metadata.name}_get.yaml`;
const fileContent = toYaml(item, { skipInvalid: true });
await Deno.writeTextFile(filePath, fileContent);
});

await Promise.all(writePromises);
} catch (error) {
console.error(`Error saving items to ${dir}:`, error);
}
}

async function describeItems(dir, namespace, name) {
try {
const describe = new Deno.Command('kubectl', { args: ['describe', dir.toLowerCase(), '-n', namespace, name] });
const output = await describe.output();
await Deno.writeTextFile(`${dirPath}/${dir}/${name}_describe.yaml`, new TextDecoder().decode(output.stdout));
} catch (error) {
console.error(`Failed to describe ${name}:`, error);
}
}

async function saveEvents(namespace) {
try {
const events = new Deno.Command('kubectl', { args: ['get', 'events', '-n', namespace, '--sort-by=.metadata.creationTimestamp'] });
const output = await events.output();
await Deno.writeTextFile(`${dirPath}/Events.txt`, new TextDecoder().decode(output.stdout));
} catch (error) {
console.error(`Error saving events:`, error);
}
}

async function saveHelmReleases(type, namespace) {
try {
const helmList = new Deno.Command('helm', { args: ['list', '-n', namespace, '-o', 'json'] });
const output = await helmList.output();
const helmReleases = JSON.parse(new TextDecoder().decode(output.stdout));
await Deno.writeTextFile(`${dirPath}/${type}-helmReleases.yaml`, toYaml(helmReleases, { skipInvalid: true }));
await Deno.writeTextFile(`${dirPath}/${type}_helmReleases.yaml`, toYaml(helmReleases, { skipInvalid: true }));
} catch (error) {
console.error(`Error saving Helm releases for ${type}:`, error);
}
}


function dataFetchers(type, namespace) {
switch (type) {
case 'classic':
Expand All @@ -75,7 +92,6 @@ function dataFetchers(type, namespace) {
'Configmaps': () => coreApi.namespace(namespace).getConfigMapList({ labelSelector: 'app.kubernetes.io/name=cf-runtime' }),
'Services': () => coreApi.namespace(namespace).getServiceList(),
'Pods': () => coreApi.namespace(namespace).getPodList(),
'Events': () => coreApi.namespace(namespace).getEventList(),
'Storageclass': () => storageApi.getStorageClassList(),
};
case 'gitops':
Expand All @@ -85,7 +101,6 @@ function dataFetchers(type, namespace) {
'Configmaps': () => coreApi.namespace(namespace).getConfigMapList(),
'Services': () => coreApi.namespace(namespace).getServiceList(),
'Pods': () => coreApi.namespace(namespace).getPodList(),
'Events': () => coreApi.namespace(namespace).getEventList(),
};
case 'onprem':
return {
Expand All @@ -96,7 +111,6 @@ function dataFetchers(type, namespace) {
'Volumeclaims': () => coreApi.namespace(namespace).getPersistentVolumeClaimList({ labelSelector: 'io.codefresh.accountName' }),
'Services': () => coreApi.namespace(namespace).getServiceList(),
'Pods': () => coreApi.namespace(namespace).getPodList(),
'Events': () => coreApi.namespace(namespace).getEventList(),
'Storageclass': () => storageApi.getStorageClassList(),
};
default:
Expand All @@ -108,6 +122,7 @@ function dataFetchers(type, namespace) {
async function fetchAndSaveData(type, namespace) {
for (const [dir, fetcher] of Object.entries(dataFetchers(type, namespace))) {
const resources = await fetcher();

await saveItems(resources.items, dir);

if (dir === 'Pods') {
Expand All @@ -116,14 +131,25 @@ async function fetchAndSaveData(type, namespace) {
try {
log = await coreApi.namespace(namespace).getPodLog(item.metadata.name, { container: item.spec.containers[0].name });
} catch (error) {
console.error(`Failed to get logs for ${item.metadata.name}:`, error);
console.error(`Failed to get items for ${item.metadata.name}:`, error);
log = error;
}
await Deno.writeTextFile(`${dirPath}/${dir}/${item.metadata.name}.log`, log);
await Deno.writeTextFile(`${dirPath}/${dir}/${item.metadata.name}_log.log`, log);
await describeItems(dir, namespace, item.metadata.name);
}));
}

if (dir === 'Nodes') {
await Promise.all(resources.items.map(async (item) => {
await describeItems(dir, namespace, item.metadata.name);
}));
}
}
await saveHelmReleases(type, namespace);
await saveEvents(namespace);
const listPods = new Deno.Command('kubectl', { args: ['get', 'pods', '-n', namespace] });
const output = await listPods.output();
await Deno.writeTextFile(`${dirPath}/ListPods.txt`, new TextDecoder().decode(output.stdout));
}

async function gatherClassic() {
Expand Down