Skip to content

Commit

Permalink
chore: test examples and update docs
Browse files Browse the repository at this point in the history
  • Loading branch information
mstruebing committed Jun 18, 2023
1 parent c431ef3 commit a112a84
Show file tree
Hide file tree
Showing 18 changed files with 107 additions and 57 deletions.
22 changes: 11 additions & 11 deletions FETCH_MIGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,27 +67,27 @@ Code will be on the `master` branch.
- [ ] in-cluster-create-job-from-cronjob // done but unable to test with media type problems
- [x] in-cluster
- [x] ingress
- [ ] namespace // done but unable to test with media type problems
- [ ] patch-example
- [x] namespace
- [ ] patch-example // throws an error `TypeError: Cannot read properties of undefined (reading 'makeRequestContext')`
- [x] raw-example (note: uses request lib directly, will require full fetch migration not just client param swap)
- [ ] scale-deployment // done but unable to test with media type problems
- [x] scale-deployment
- [x] top_pods
- [x] top
- [ ] yaml-example // done but unable to test with media type problems
- [ ] yaml-example // create works but deletion throws an error `TypeError: Cannot read properties of undefined (reading 'makeRequestContext')`

- [ ] Fix TypeScript examples and validate their param signatures (due to new api)

- [ ] apply-example
- [ ] attach-example
- [ ] cp-example
- [ ] exec-example
- [ ] informer-with-label-selector // done but unable to test with media type problems
- [ ] apply-example // KubernetesObjectApi is missing
- [x] attach-example
- [x] cp-example
- [x] exec-example
- [x] informer-with-label-selector
- [x] informer
- [ ] port-forward
- [x] port-forward
- [x] example
- [x] watch-example

- [ ] Update docs
- [ ] Update README examples
- [ ] Document breaking changes for users
- [ ] Release initial version (1.0.0)
[ ] Release initial version (1.0.0)
4 changes: 3 additions & 1 deletion examples/cache-example.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ kc.loadFromDefault();

const k8sApi = kc.makeApiClient(k8s.CoreV1Api);

const namespace = 'default';

const path = '/api/v1/pods';
const watch = new k8s.Watch(kc);

Expand All @@ -14,7 +16,7 @@ const listFn = () => k8sApi.listPodForAllNamespaces();
const cache = new k8s.ListWatch(path, watch, listFn);

const looper = () => {
const list = cache.list('default');
const list = cache.list(namespace);
if (list) {
let names = [];
for (let i = 0; i < list.length; i++) {
Expand Down
4 changes: 3 additions & 1 deletion examples/example.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ kc.loadFromDefault();

const k8sApi = kc.makeApiClient(k8s.CoreV1Api);

const namespace = 'default';

k8sApi
.listNamespacedPod({ namespace: 'default' })
.listNamespacedPod({ namespace })
.then((res) => {
console.log(res);
})
Expand Down
8 changes: 6 additions & 2 deletions examples/follow-logs.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const stream = require('stream');
// in a real program use require('@kubernetes/client-node')
const k8s = require('../dist/index');
const stream = require('stream');

const kc = new k8s.KubeConfig();
kc.loadFromDefault();
Expand All @@ -9,12 +9,16 @@ const log = new k8s.Log(kc);

const logStream = new stream.PassThrough();

const namespace = 'default';
const pod = 'pod1';
const container = 'container1';

logStream.on('data', (chunk) => {
// use write rather than console.log to prevent double line feed
process.stdout.write(chunk);
});

log.log('default', 'pod1', 'container1', logStream, {
log.log(namespace, pod, container, logStream, {
follow: true,
tailLines: 50,
pretty: false,
Expand Down
6 changes: 4 additions & 2 deletions examples/in-cluster-create-job-from-cronjob.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// in a real program use require('@kubernetes/client-node')
const k8s = require('../dist/index');

const namespace = 'default';

const kc = new k8s.KubeConfig();
kc.loadFromCluster();

Expand All @@ -20,11 +22,11 @@ metadata.annotations = {
job.metadata = metadata;

batchV1beta1Api
.readNamespacedCronJob({ name: cronJobName, namespace: 'default' })
.readNamespacedCronJob({ name: cronJobName, namespace })
.then((cronJobRes) => {
job.spec = cronJobRes?.spec?.jobTemplate.spec;
batchV1Api
.createNamespacedJob({ namespace: 'default', body: job })
.createNamespacedJob({ namespace, body: job })
.then((res) => {
console.log(res);
})
Expand Down
4 changes: 3 additions & 1 deletion examples/in-cluster.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ kc.loadFromCluster();

const k8sApi = kc.makeApiClient(k8s.CoreV1Api);

const namespace = 'default';

k8sApi
.listNamespacedPod({ namespace: 'default' })
.listNamespacedPod({ namespace })
.then((res) => {
console.log(res);
})
Expand Down
4 changes: 3 additions & 1 deletion examples/ingress.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ const kc = new k8s.KubeConfig();
kc.loadFromDefault();

const k8sApi = kc.makeApiClient(k8s.NetworkingV1Api);

const namespace = 'default';
const clientIdentifier = 'my-subdomain';

k8sApi
.createNamespacedIngress({
namespace: 'default',
namespace,
body: {
apiVersion: 'networking.k8s.io/v1',
kind: 'Ingress',
Expand Down
9 changes: 4 additions & 5 deletions examples/patch-example.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ kc.loadFromDefault();

const k8sApi = kc.makeApiClient(k8s.CoreV1Api);

k8sApi.listNamespacedPod({ namespace: 'default' }).then((res) => {
const namespace = 'default';

k8sApi.listNamespacedPod({ namespace }).then((res) => {
const patch = [
{
op: 'replace',
Expand All @@ -19,10 +21,7 @@ k8sApi.listNamespacedPod({ namespace: 'default' }).then((res) => {
// TODO this method of passing the content type will change when we figure out a way to properly do this
const options = { headers: { 'Content-type': k8s.PatchUtils.PATCH_FORMAT_JSON_PATCH } };
k8sApi
.patchNamespacedPod(
{ name: res?.items?.[0].metadata?.name ?? '', namespace: 'default', body: patch },
options,
)
.patchNamespacedPod({ name: res?.items?.[0].metadata?.name ?? '', namespace, body: patch }, options)
.then(() => {
console.log('Patched.');
})
Expand Down
12 changes: 6 additions & 6 deletions examples/scale-deployment.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ const targetNamespaceName = 'default';
const targetDeploymentName = 'docker-test-deployment';
const numberOfTargetReplicas = 3;

async function scale(deploymentNamespace, deploymentName, replicas) {
async function scale(namespace, name, replicas) {
// find the particular deployment
const deployment = await k8sApi.readNamespacedDeployment({
name: deploymentName,
namespace: deploymentNamespace,
name,
namespace,
});

if (!deployment || !deployment.spec) {
throw new Error(`Deployment ${deploymentName} not found in namespace ${deploymentNamespace}`);
throw new Error(`Deployment ${name} not found in namespace ${namespace}`);
}
// edit
const newDeployment = {
Expand All @@ -31,8 +31,8 @@ async function scale(deploymentNamespace, deploymentName, replicas) {

// replace
await k8sApi.replaceNamespacedDeployment({
name: deploymentName,
namespace: deploymentNamespace,
name,
namespace,
body: newDeployment,
});
}
Expand Down
6 changes: 4 additions & 2 deletions examples/top_pods.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ kc.loadFromDefault();
const k8sApi = kc.makeApiClient(k8s.CoreV1Api);
const metricsClient = new k8s.Metrics(kc);

k8s.topPods(k8sApi, metricsClient, 'kube-system').then((pods) => {
const namespace = 'kube-system';

k8s.topPods(k8sApi, metricsClient, namespace).then((pods) => {
const podsColumns = pods.map((pod) => {
return {
POD: pod.Pod.metadata?.name,
Expand All @@ -19,7 +21,7 @@ k8s.topPods(k8sApi, metricsClient, 'kube-system').then((pods) => {
console.table(podsColumns);
});

k8s.topPods(k8sApi, metricsClient, 'kube-system').then((pods) => {
k8s.topPods(k8sApi, metricsClient, namespace).then((pods) => {
const podsAndContainersColumns = pods.flatMap((pod) => {
return pod.Containers.map((containerUsage) => {
return {
Expand Down
5 changes: 3 additions & 2 deletions examples/typescript/apply/apply-example.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as k8s from '@kubernetes/client-node';
// in a real program use require('@kubernetes/client-node')
import * as k8s from '../../../dist';
import * as fs from 'fs';
import * as yaml from 'js-yaml';
import { promisify } from 'util';
Expand All @@ -16,7 +17,7 @@ export async function apply(specPath: string): Promise<k8s.KubernetesObject[]> {
const client = k8s.KubernetesObjectApi.makeApiClient(kc);
const fsReadFileP = promisify(fs.readFile);
const specString = await fsReadFileP(specPath, 'utf8');
const specs: k8s.KubernetesObject[] = yaml.loadAll(specString);
const specs = yaml.loadAll(specString) as k8s.KubernetesObject[];
const validSpecs = specs.filter((s) => s && s.kind && s.metadata);
const created: k8s.KubernetesObject[] = [];
for (const spec of validSpecs) {
Expand Down
11 changes: 8 additions & 3 deletions examples/typescript/attach/attach-example.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import k8s = require('@kubernetes/client-node');
// in a real program use require('@kubernetes/client-node')
import * as k8s from '../../../dist';

const kc = new k8s.KubeConfig();
kc.loadFromDefault();

const attach = new k8s.Attach(kc);
attach.attach('default', 'nginx-4217019353-9gl4s', 'nginx',
process.stdout, process.stderr, null /* stdin */, false /* tty */);

const namespace = 'default';
const pod = 'nginx-4217019353-9gl4s';
const container = 'nginx';

attach.attach(namespace, pod, container, process.stdout, process.stderr, null /* stdin */, false /* tty */);
12 changes: 10 additions & 2 deletions examples/typescript/cp/cp-example.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
import * as k8s from '@kubernetes/client-node';
// in a real program use require('@kubernetes/client-node')
import * as k8s from '../../../dist';

const kc = new k8s.KubeConfig();
kc.loadFromDefault();

const cp = new k8s.Cp(kc);
cp.cpFromPod('default', 'nginx-4217019353-9gl4s', 'nginx', './test.txt', '/tmp');

const namespace = 'default';
const pod = 'nginx-4217019353-9gl4s';
const container = 'nginx';
const srcPath = '/test.txt';
const targetPath = '/tmp';

cp.cpFromPod(namespace, pod, container, srcPath, targetPath);
21 changes: 17 additions & 4 deletions examples/typescript/exec/exec-example.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as k8s from '@kubernetes/client-node';
// in a real program use require('@kubernetes/client-node')
import * as k8s from '../../../dist';
import * as stream from 'stream';

const command = process.argv[2];
Expand All @@ -7,12 +8,24 @@ const kc = new k8s.KubeConfig();
kc.loadFromDefault();

const exec = new k8s.Exec(kc);
exec.exec('default', 'nginx-4217019353-9gl4s', 'nginx', command,
process.stdout as stream.Writable, process.stderr as stream.Writable, process.stdin as stream.Readable,

const namespace = 'default';
const pod = 'nginx-4217019353-9gl4s';
const container = 'nginx';

exec.exec(
namespace,
pod,
container,
command,
process.stdout as stream.Writable,
process.stderr as stream.Writable,
process.stdin as stream.Readable,
true /* tty */,
(status: k8s.V1Status) => {
// tslint:disable-next-line:no-console
console.log('Exited with status:');
// tslint:disable-next-line:no-console
console.log(JSON.stringify(status, null, 2));
});
},
);
13 changes: 7 additions & 6 deletions examples/typescript/informer/informer-with-label-selector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ kc.loadFromDefault();

const k8sApi = kc.makeApiClient(k8s.CoreV1Api);

const namespace = 'default';
const APP_LABEL_SELECTOR = 'app=foo';

const listFn = () =>
k8sApi.listNamespacedPod({
namespace: 'default',
namespace,
labelSelector: APP_LABEL_SELECTOR,
});

Expand All @@ -32,20 +33,20 @@ const createPod = async (name: string, app: string) => {
containers: [appPodContainer],
},
} as k8s.V1Pod;
await k8sApi.createNamespacedPod({ namespace: 'default', body: appPod }).catch((e) => console.error(e));
await k8sApi.createNamespacedPod({ namespace, body: appPod }).catch((e) => console.error(e));
console.log('create', name);
};

const deletePod = async (podName: string, podNamespace: string) => {
await k8sApi.deleteNamespacedPod({ name: podName, namespace: podNamespace });
console.log('delete', name);
console.log('delete', podName);
};

const delay = (ms: number) => {
return new Promise((resolve) => setTimeout(resolve, ms));
};

const informer = k8s.makeInformer(kc, '/api/v1/namespaces/default/pods', listFn, APP_LABEL_SELECTOR);
const informer = k8s.makeInformer(kc, `/api/v1/namespaces/${namespace}/pods`, listFn, APP_LABEL_SELECTOR);

informer.on('add', (obj: k8s.V1Pod) => {
console.log(`Added: ${obj.metadata!.name}`);
Expand All @@ -70,7 +71,7 @@ informer.start().then(() => {
await delay(5000);
await createPod('server-bar', 'bar');
await delay(5000);
await deletePod('server-foo', 'default');
await deletePod('server-bar', 'default');
await deletePod('server-foo', namespace);
await deletePod('server-bar', namespace);
}, 5000);
});
6 changes: 4 additions & 2 deletions examples/typescript/informer/informer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ kc.loadFromDefault();

const k8sApi = kc.makeApiClient(k8s.CoreV1Api);

const listFn = () => k8sApi.listNamespacedPod({ namespace: 'default' });
const namespace = 'default';

const informer = k8s.makeInformer(kc, '/api/v1/namespaces/default/pods', listFn);
const listFn = () => k8sApi.listNamespacedPod({ namespace });

const informer = k8s.makeInformer(kc, `/api/v1/namespaces/${namespace}/pods`, listFn);

informer.on('add', (obj: k8s.V1Pod) => {
console.log(`Added: ${obj.metadata!.name}`);
Expand Down
13 changes: 8 additions & 5 deletions examples/typescript/port-forward/port-forward.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
import * as k8s from '@kubernetes/client-node';
// in a real program use require('@kubernetes/client-node')
import * as k8s from '../../../dist';
import * as net from 'net';

const command = process.argv[2];

const kc = new k8s.KubeConfig();
kc.loadFromDefault();

const forward = new k8s.PortForward(kc);

const namespace = 'default';
const pod = 'demo';
const port = 8080;

// This simple server just forwards traffic from itself to a service running in kubernetes
// -> localhost:8080 -> port-forward-tunnel -> kubernetes-pod
// This is basically equivalent to 'kubectl port-forward ...' but in TypeScript.
const server = net.createServer((socket) => {
forward.portForward('default', 'demo', [8080], socket, null, socket);
forward.portForward(namespace, pod, [port], socket, null, socket);
});

server.listen(8080, '127.0.0.1');
server.listen(port, '127.0.0.1');
Loading

0 comments on commit a112a84

Please sign in to comment.