Skip to content

Commit cde27fa

Browse files
authored
Support Package Refresh 2024-09 (#12)
* Updated Version * moved to jsr, updated items gathers, rename items * updated error, add exclude, fromatting
1 parent e671ebe commit cde27fa

File tree

6 files changed

+108
-47
lines changed

6 files changed

+108
-47
lines changed

.devcontainer/devcontainer.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// For format details, see https://aka.ms/devcontainer.json.
22
{
33
"name": "Codefresh Support Package",
4-
"image": "denoland/deno:1.42.1",
4+
"image": "denoland/deno:1.46.3",
55
"onCreateCommand": "apt-get update && apt-get install git zip -y",
66
"customizations": {
77
"vscode": {
@@ -16,4 +16,4 @@
1616
]
1717
}
1818
}
19-
}
19+
}

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2.4.0
1+
3.0.0

ci/codefresh.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ steps:
2020
title: Compiling
2121
stage: Build
2222
arguments:
23-
image: denoland/deno:alpine-1.42.1
23+
image: denoland/deno:alpine-1.46.3
2424
commands:
2525
- cf_export VERSION=$(cat VERSION)
2626
- deno task compile
@@ -43,4 +43,4 @@ steps:
4343
- ${{CF_VOLUME_PATH}}/${{CF_REPO_NAME}}/bin/cf-support_windows_x86_64.zip
4444
- ${{CF_VOLUME_PATH}}/${{CF_REPO_NAME}}/bin/cf-support_darwin_x86_64.tar.gz
4545
- ${{CF_VOLUME_PATH}}/${{CF_REPO_NAME}}/bin/cf-support_darwin_arm64.tar.gz
46-
- ${{CF_VOLUME_PATH}}/${{CF_REPO_NAME}}/bin/cf-support_linux_x86_64.tar.gz
46+
- ${{CF_VOLUME_PATH}}/${{CF_REPO_NAME}}/bin/cf-support_linux_x86_64.tar.gz

deno.json

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,21 @@
33
"indentWidth": 2,
44
"lineWidth": 160,
55
"singleQuote": true,
6-
"semiColons": true
6+
"semiColons": true,
7+
"exclude": [".devcontainer/**"]
78
},
89
"tasks": {
910
"pre-compile": "rm -rf ./bin && mkdir ./bin",
1011
"compile:linux": "deno compile --config=./deno.json --allow-env --allow-read --allow-write --allow-net --unsafely-ignore-certificate-errors --allow-run --output=./bin/cf-support_linux_x86_64 --target=x86_64-unknown-linux-gnu ./src/main.js",
1112
"compile:windows": "deno compile --config=./deno.json --allow-env --allow-read --allow-write --allow-net --unsafely-ignore-certificate-errors --allow-run --output=./bin/cf-support_windows_x86_64 --target=x86_64-pc-windows-msvc ./src/main.js",
12-
"compile:apple_x86_64": "deno compile --config=./deno.json --allow-env --allow-read --allow-write --allow-net --unsafely-ignore-certificate-errors --allow-run --output=./bin/cf-support_darwin_x86_64 --target=x86_64-apple-darwin ./src/main.js",
13+
"compile:apple": "deno compile --config=./deno.json --allow-env --allow-read --allow-write --allow-net --unsafely-ignore-certificate-errors --allow-run --output=./bin/cf-support_darwin_x86_64 --target=x86_64-apple-darwin ./src/main.js",
1314
"compile:apple_arm64": "deno compile --config=./deno.json --allow-env --allow-read --allow-write --allow-net --unsafely-ignore-certificate-errors --allow-run --output=./bin/cf-support_darwin_arm64 --target=aarch64-apple-darwin ./src/main.js",
14-
"compile": "deno task pre-compile && deno task compile:linux && deno task compile:windows && deno task compile:apple_x86_64 && deno task compile:apple_arm64"
15+
"compile": "deno task pre-compile && deno task compile:linux && deno task compile:windows && deno task compile:apple && deno task compile:apple_arm64"
16+
},
17+
"imports": {
18+
"@cloudydeno/kubernetes-apis": "jsr:@cloudydeno/kubernetes-apis@^0.5.1",
19+
"@cloudydeno/kubernetes-client": "jsr:@cloudydeno/kubernetes-client@^0.7.3",
20+
"@fakoua/zip-ts": "jsr:@fakoua/zip-ts@^1.3.1",
21+
"@std/yaml": "jsr:@std/yaml@^1.0.5"
1522
}
1623
}

src/codefresh.js

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
'use strict';
2-
import { parse } from 'https://deno.land/[email protected]/yaml/mod.ts';
2+
import { parse } from '@std/yaml';
33

44
class Codefresh {
55
async init() {
@@ -72,6 +72,34 @@ class Codefresh {
7272
return error;
7373
}
7474
}
75+
76+
async getOnPremUserTotal() {
77+
try {
78+
const response = await fetch(`${this.baseURL}/admin/users?limit=1&page=1`, {
79+
method: 'GET',
80+
headers: this.headers,
81+
});
82+
const users = await response.json();
83+
return users.total;
84+
} catch (error) {
85+
console.error(error);
86+
return error;
87+
}
88+
}
89+
90+
async getOnPremSystemFF() {
91+
try {
92+
const response = await fetch(`${this.baseURL}/admin/features`, {
93+
method: 'GET',
94+
headers: this.headers,
95+
});
96+
const onPremSystemFF = await response.json();
97+
return onPremSystemFF;
98+
} catch (error) {
99+
console.error(error);
100+
return error;
101+
}
102+
}
75103
}
76104

77105
export { Codefresh };

src/main.js

Lines changed: 64 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
'use strict';
22

33
import { Codefresh } from './codefresh.js';
4-
import { autoDetectClient } from 'https://deno.land/x/[email protected]/mod.ts';
5-
import { AppsV1Api } from 'https://deno.land/x/[email protected]/builtin/apps@v1/mod.ts';
6-
import { BatchV1Api } from 'https://deno.land/x/[email protected]/builtin/batch@v1/mod.ts';
7-
import { CoreV1Api } from 'https://deno.land/x/[email protected]/builtin/core@v1/mod.ts';
8-
import { StorageV1Api } from 'https://deno.land/x/[email protected]/builtin/storage.k8s.io@v1/mod.ts';
9-
import { ArgoprojIoV1alpha1Api } from 'https://deno.land/x/[email protected]/argo-cd/argoproj.io@v1alpha1/mod.ts';
10-
import { compress } from 'https://deno.land/x/[email protected]/mod.ts';
11-
import { stringify as toYaml } from 'https://deno.land/[email protected]/yaml/mod.ts';
4+
import { autoDetectClient } from '@cloudydeno/kubernetes-client';
5+
import { AppsV1Api } from '@cloudydeno/kubernetes-apis/apps/v1';
6+
import { BatchV1Api } from '@cloudydeno/kubernetes-apis/batch/v1';
7+
import { CoreV1Api } from '@cloudydeno/kubernetes-apis/core/v1';
8+
import { StorageV1Api } from '@cloudydeno/kubernetes-apis/storage.k8s.io/v1';
9+
import { ArgoprojIoV1alpha1Api } from '@cloudydeno/kubernetes-apis/argoproj.io/v1alpha1';
10+
11+
import { compress } from '@fakoua/zip-ts';
12+
import { stringify as toYaml } from '@std/yaml';
1213

1314
console.log('Initializing \n');
1415
const kubeConfig = await autoDetectClient();
@@ -21,7 +22,7 @@ const timestamp = new Date().getTime();
2122
const dirPath = `./codefresh-support-${timestamp}`;
2223

2324
function selectRuntimeType() {
24-
const reTypes = ['classic', 'gitops', 'onprem'];
25+
const reTypes = ['Pipelines Runtime', 'GitOps Runtime', 'On-Prem'];
2526
reTypes.forEach((reType, index) => {
2627
console.log(`${index + 1}. ${reType}`);
2728
});
@@ -82,10 +83,12 @@ async function saveHelmReleases(type, namespace) {
8283

8384
function dataFetchers(type, namespace) {
8485
switch (type) {
85-
case 'classic':
86+
case 'Pipelines Runtime':
8687
return {
8788
'Cron': () => batchApi.namespace(namespace).getCronJobList(),
8889
'Jobs': () => batchApi.namespace(namespace).getJobList(),
90+
'Deployments': () => appsApi.namespace(namespace).getDeploymentList(),
91+
'Daemonsets': () => appsApi.namespace(namespace).getDaemonSetList(),
8992
'Nodes': () => coreApi.getNodeList(),
9093
'Volumes': () => coreApi.getPersistentVolumeList({ labelSelector: 'io.codefresh.accountName' }),
9194
'Volumeclaims': () => coreApi.namespace(namespace).getPersistentVolumeClaimList({ labelSelector: 'io.codefresh.accountName' }),
@@ -94,22 +97,30 @@ function dataFetchers(type, namespace) {
9497
'Pods': () => coreApi.namespace(namespace).getPodList(),
9598
'Storageclass': () => storageApi.getStorageClassList(),
9699
};
97-
case 'gitops':
100+
case 'GitOps Runtime':
98101
return {
99-
'Apps': () => argoProj.namespace(namespace).getApplicationList(),
100-
'AppSets': () => argoProj.namespace(namespace).getApplicationSetList(),
102+
'Argo-Apps': () => argoProj.namespace(namespace).getApplicationList(),
103+
'Argo-AppSets': () => argoProj.namespace(namespace).getApplicationSetList(),
104+
'Cron': () => batchApi.namespace(namespace).getCronJobList(),
105+
'Jobs': () => batchApi.namespace(namespace).getJobList(),
106+
'Deployments': () => appsApi.namespace(namespace).getDeploymentList(),
107+
'Daemonsets': () => appsApi.namespace(namespace).getDaemonSetList(),
108+
'Statefulsets': () => appsApi.namespace(namespace).getStatefulSetList(),
101109
'Nodes': () => coreApi.getNodeList(),
102110
'Configmaps': () => coreApi.namespace(namespace).getConfigMapList(),
103111
'Services': () => coreApi.namespace(namespace).getServiceList(),
104112
'Pods': () => coreApi.namespace(namespace).getPodList(),
105113
};
106-
case 'onprem':
114+
case 'On-Prem':
107115
return {
116+
'Cron': () => batchApi.namespace(namespace).getCronJobList(),
117+
'Jobs': () => batchApi.namespace(namespace).getJobList(),
108118
'Deployments': () => appsApi.namespace(namespace).getDeploymentList(),
109119
'Daemonsets': () => appsApi.namespace(namespace).getDaemonSetList(),
110120
'Nodes': () => coreApi.getNodeList(),
111121
'Volumes': () => coreApi.getPersistentVolumeList({ labelSelector: 'io.codefresh.accountName' }),
112122
'Volumeclaims': () => coreApi.namespace(namespace).getPersistentVolumeClaimList({ labelSelector: 'io.codefresh.accountName' }),
123+
'Configmaps': () => coreApi.namespace(namespace).getConfigMapList(),
113124
'Services': () => coreApi.namespace(namespace).getServiceList(),
114125
'Pods': () => coreApi.namespace(namespace).getPodList(),
115126
'Storageclass': () => storageApi.getStorageClassList(),
@@ -128,18 +139,25 @@ async function fetchAndSaveData(type, namespace) {
128139

129140
if (dir === 'Pods') {
130141
await Promise.all(resources.items.map(async (item) => {
131-
let log;
132-
try {
133-
log = await coreApi.namespace(namespace).getPodLog(item.metadata.name, {
134-
container: item.spec.containers[0].name,
135-
timestamps: true,
136-
});
137-
} catch (error) {
138-
console.error(`Failed to get items for ${item.metadata.name}:`, error);
139-
log = error;
140-
}
141-
await Deno.writeTextFile(`${dirPath}/${dir}/${item.metadata.name}_log.log`, log);
142-
await describeItems(dir, namespace, item.metadata.name);
142+
const podName = item.metadata.name;
143+
const containers = item.spec.containers;
144+
145+
await Promise.all(containers.map(async (container) => {
146+
let log;
147+
try {
148+
log = await coreApi.namespace(namespace).getPodLog(podName, {
149+
container: container.name,
150+
timestamps: true,
151+
});
152+
} catch (error) {
153+
console.error(`Failed to get logs for container ${container.name} in pod ${podName}:`, error);
154+
log = error.toString();
155+
}
156+
const logFileName = `${dirPath}/${dir}/${podName}_${container.name}_log.log`;
157+
await Deno.writeTextFile(logFileName, log);
158+
}));
159+
160+
await describeItems(dir, namespace, podName);
143161
}));
144162
}
145163

@@ -156,7 +174,7 @@ async function fetchAndSaveData(type, namespace) {
156174
await Deno.writeTextFile(`${dirPath}/ListPods.txt`, new TextDecoder().decode(output.stdout));
157175
}
158176

159-
async function gatherClassic() {
177+
async function gatherPipelines() {
160178
try {
161179
const cf = new Codefresh();
162180
await cf.init();
@@ -166,22 +184,22 @@ async function gatherClassic() {
166184
console.log(`${index + 1}. ${re}`);
167185
});
168186

169-
let selection = Number(prompt('\nWhich Classic Runtime Are We Working With? (Number): '));
187+
let selection = Number(prompt('\nWhich Pipelines Runtime Are We Working With? (Number): '));
170188
while (isNaN(selection) || selection < 1 || selection > reNames.length) {
171189
console.log('Invalid selection. Please enter a number corresponding to one of the listed runtimes.');
172-
selection = Number(prompt('\nWhich Classic Runtime Are We Working With? (Number): '));
190+
selection = Number(prompt('\nWhich Pipelines Runtime Are We Working With? (Number): '));
173191
}
174192

175193
const reSpec = cf.runtimes[selection - 1];
176194
const namespace = reSpec.runtimeScheduler.cluster.namespace;
177195

178196
console.log(`\nGathering Data For ${reSpec.metadata.name}.`);
179197

180-
await fetchAndSaveData('classic', namespace);
198+
await fetchAndSaveData('Pipelines Runtime', namespace);
181199

182200
await Deno.writeTextFile(`${dirPath}/runtimeSpec.yaml`, toYaml(reSpec, { skipInvalid: true }));
183201
} catch (error) {
184-
console.error(`Error gathering classic runtime data:`, error);
202+
console.error(`Error gathering Pipelines Runtime data:`, error);
185203
}
186204
}
187205

@@ -203,7 +221,7 @@ async function gatherGitOps() {
203221

204222
console.log(`\nGathering Data In ${namespace} For The GitOps Runtime.`);
205223

206-
await fetchAndSaveData('gitops', namespace);
224+
await fetchAndSaveData('GitOps Runtime', namespace);
207225
} catch (error) {
208226
console.error(`Error gathering GitOps runtime data:`, error);
209227
}
@@ -213,8 +231,14 @@ async function gatherOnPrem() {
213231
try {
214232
const cf = new Codefresh();
215233
await cf.init();
234+
if (cf.apiURL === 'https://g.codefresh.io') {
235+
console.error(`The API URL ( ${cf.apiURL} ) is not an On Prem instance. Please use Pipelines Runtime or GitOps Runtime.`);
236+
Deno.exit(1);
237+
}
216238
const accounts = await cf.getOnPremAccounts();
217239
const runtimes = await cf.getOnPremRuntimes();
240+
const userTotal = await cf.getOnPremUserTotal();
241+
const systemFF = await cf.getOnPremSystemFF();
218242

219243
const namespaceList = await coreApi.getNamespaceList();
220244
console.log('');
@@ -232,10 +256,12 @@ async function gatherOnPrem() {
232256

233257
console.log(`\nGathering Data For On Prem.`);
234258

235-
await fetchAndSaveData('onprem', namespace);
259+
await fetchAndSaveData('On-Prem', namespace);
236260

237261
await Deno.writeTextFile(`${dirPath}/onPremAccounts.yaml`, toYaml(accounts, { skipInvalid: true }));
238262
await Deno.writeTextFile(`${dirPath}/onPremRuntimes.yaml`, toYaml(runtimes, { skipInvalid: true }));
263+
await Deno.writeTextFile(`${dirPath}/onPremUserTotal.txt`, userTotal.toString());
264+
await Deno.writeTextFile(`${dirPath}/onPremSystemFF.yaml`, toYaml(systemFF, { skipInvalid: true }));
239265
} catch (error) {
240266
console.error(`Error gathering On Prem data:`, error);
241267
}
@@ -246,13 +272,13 @@ async function main() {
246272
const runtimeType = selectRuntimeType();
247273

248274
switch (runtimeType) {
249-
case 'classic':
250-
await gatherClassic();
275+
case 'Pipelines Runtime':
276+
await gatherPipelines();
251277
break;
252-
case 'gitops':
278+
case 'GitOps Runtime':
253279
await gatherGitOps();
254280
break;
255-
case 'onprem':
281+
case 'On-Prem':
256282
await gatherOnPrem();
257283
break;
258284
}
@@ -266,7 +292,7 @@ async function main() {
266292
console.log(`\nPlease attach ./codefresh-support-package-${timestamp}.zip to your support ticket.`);
267293
console.log('Before attaching, verify the contents and remove any sensitive information.');
268294
} catch (error) {
269-
console.error(`Error in main function:`, error);
295+
console.error(`Error:`, error);
270296
}
271297
}
272298

0 commit comments

Comments
 (0)