Skip to content

Commit d4a1e15

Browse files
committed
Add list method to generic KubernetesObjectApi
1 parent 32c1163 commit d4a1e15

File tree

2 files changed

+190
-3
lines changed

2 files changed

+190
-3
lines changed

src/object.ts

Lines changed: 88 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ type KubernetesObjectResponseBody =
2020
| V1APIResourceList;
2121

2222
/** Kubernetes API verbs. */
23-
type KubernetesApiAction = 'create' | 'delete' | 'patch' | 'read' | 'replace';
23+
type KubernetesApiAction = 'create' | 'delete' | 'patch' | 'read' | 'list' | 'replace';
2424

2525
/**
2626
* Valid Content-Type header values for patch operations. See
@@ -315,6 +315,91 @@ export class KubernetesObjectApi extends ApisApi {
315315
return this.requestPromise(localVarRequestOptions);
316316
}
317317

318+
/**
319+
* List any Kubernetes resources.
320+
* @param apiVersion api group and version of the form <apiGroup>/<version>
321+
* @param kind Kubernetes resource kind
322+
* @param namespace list resources in this namespace
323+
* @param pretty If \&#39;true\&#39;, then the output is pretty printed.
324+
* @param exact Should the export be exact. Exact export maintains cluster-specific fields like
325+
* \&#39;Namespace\&#39;. Deprecated. Planned for removal in 1.18.
326+
* @param exportt Should this value be exported. Export strips fields that a user can not
327+
* specify. Deprecated. Planned for removal in 1.18.
328+
* @param fieldSelector A selector to restrict the list of returned objects by their fields. Defaults to everything.
329+
* @param labelSelector A selector to restrict the list of returned objects by their labels. Defaults to everything.
330+
* @param limit Number of returned resources.
331+
* @param options Optional headers to use in the request.
332+
* @return Promise containing the request response and [[KubernetesListObject<KubernetesObject>]].
333+
*/
334+
public async list(
335+
apiVersion: string,
336+
kind: string,
337+
namespace?: string,
338+
pretty?: string,
339+
exact?: boolean,
340+
exportt?: boolean,
341+
fieldSelector?: string,
342+
labelSelector?: string,
343+
limit?: number,
344+
options: { headers: { [name: string]: string } } = { headers: {} },
345+
): Promise<{ body: KubernetesListObject<KubernetesObject>; response: http.IncomingMessage }> {
346+
// verify required parameters 'apiVersion', 'kind' is not null or undefined
347+
if (apiVersion === null || apiVersion === undefined) {
348+
throw new Error('Required parameter apiVersion was null or undefined when calling list.');
349+
}
350+
if (kind === null || kind === undefined) {
351+
throw new Error('Required parameter kind was null or undefined when calling list.');
352+
}
353+
354+
const localVarPath = await this.specUriPath(
355+
{
356+
apiVersion,
357+
kind,
358+
metadata: {
359+
namespace,
360+
},
361+
},
362+
'list',
363+
);
364+
const localVarQueryParameters: any = {};
365+
const localVarHeaderParams = this.generateHeaders(options.headers);
366+
367+
if (pretty !== undefined) {
368+
localVarQueryParameters.pretty = ObjectSerializer.serialize(pretty, 'string');
369+
}
370+
371+
if (exact !== undefined) {
372+
localVarQueryParameters.exact = ObjectSerializer.serialize(exact, 'boolean');
373+
}
374+
375+
if (exportt !== undefined) {
376+
localVarQueryParameters.export = ObjectSerializer.serialize(exportt, 'boolean');
377+
}
378+
379+
if (fieldSelector !== undefined) {
380+
localVarQueryParameters.fieldSelector = ObjectSerializer.serialize(fieldSelector, 'string');
381+
}
382+
383+
if (labelSelector !== undefined) {
384+
localVarQueryParameters.labelSelector = ObjectSerializer.serialize(labelSelector, 'string');
385+
}
386+
387+
if (limit !== undefined) {
388+
localVarQueryParameters.limit = ObjectSerializer.serialize(limit, 'number');
389+
}
390+
391+
const localVarRequestOptions: request.Options = {
392+
method: 'GET',
393+
qs: localVarQueryParameters,
394+
headers: localVarHeaderParams,
395+
uri: localVarPath,
396+
useQuerystring: this._useQuerystring,
397+
json: true,
398+
};
399+
400+
return this.requestPromise(localVarRequestOptions);
401+
}
402+
318403
/**
319404
* Replace any Kubernetes resource.
320405
* @param spec Kubernetes resource spec
@@ -403,15 +488,15 @@ export class KubernetesObjectApi extends ApisApi {
403488
if (!resource) {
404489
throw new Error(`Unrecognized API version and kind: ${spec.apiVersion} ${spec.kind}`);
405490
}
406-
if (resource.namespaced && !spec.metadata.namespace) {
491+
if (resource.namespaced && !spec.metadata.namespace && action !== 'list') {
407492
spec.metadata.namespace = this.defaultNamespace;
408493
}
409494
const parts = [this.apiVersionPath(spec.apiVersion)];
410495
if (resource.namespaced && spec.metadata.namespace) {
411496
parts.push('namespaces', encodeURIComponent(String(spec.metadata.namespace)));
412497
}
413498
parts.push(resource.name);
414-
if (action !== 'create') {
499+
if (action !== 'create' && action !== 'list') {
415500
if (!spec.metadata.name) {
416501
throw new Error('Required spec property name is not set');
417502
}

src/object_test.ts

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1747,6 +1747,82 @@ describe('KubernetesObject', () => {
17471747
await client.delete(s, undefined, undefined, 7, undefined, 'Foreground');
17481748
scope.done();
17491749
});
1750+
1751+
it('should list resources in a namespace', async () => {
1752+
const scope = nock('https://d.i.y')
1753+
.get(
1754+
'/api/v1/namespaces/default/secrets?fieldSelector=metadata.name%3Dtest-secret1&labelSelector=app%3Dmy-app&limit=5',
1755+
)
1756+
.reply(200, {
1757+
apiVersion: 'v1',
1758+
kind: 'SecretList',
1759+
items: [
1760+
{
1761+
apiVersion: 'v1',
1762+
kind: 'Secret',
1763+
metadata: {
1764+
name: 'test-secret-1',
1765+
uid: 'a4fd7a65-2af5-4ef1-a0bc-cb34a308b821',
1766+
},
1767+
},
1768+
],
1769+
metadata: {
1770+
resourceVersion: '216532459',
1771+
},
1772+
});
1773+
const lr = await client.list(
1774+
'v1',
1775+
'Secret',
1776+
'default',
1777+
undefined,
1778+
undefined,
1779+
undefined,
1780+
'metadata.name=test-secret1',
1781+
'app=my-app',
1782+
5,
1783+
);
1784+
const items = lr.body.items;
1785+
expect(items).to.have.length(1);
1786+
scope.done();
1787+
});
1788+
1789+
it('should list resources in all namespaces', async () => {
1790+
const scope = nock('https://d.i.y')
1791+
.get(
1792+
'/api/v1/secrets?fieldSelector=metadata.name%3Dtest-secret1&labelSelector=app%3Dmy-app&limit=5',
1793+
)
1794+
.reply(200, {
1795+
apiVersion: 'v1',
1796+
kind: 'SecretList',
1797+
items: [
1798+
{
1799+
apiVersion: 'v1',
1800+
kind: 'Secret',
1801+
metadata: {
1802+
name: 'test-secret-1',
1803+
uid: 'a4fd7a65-2af5-4ef1-a0bc-cb34a308b821',
1804+
},
1805+
},
1806+
],
1807+
metadata: {
1808+
resourceVersion: '216532459',
1809+
},
1810+
});
1811+
const lr = await client.list(
1812+
'v1',
1813+
'Secret',
1814+
undefined,
1815+
undefined,
1816+
undefined,
1817+
undefined,
1818+
'metadata.name=test-secret1',
1819+
'app=my-app',
1820+
5,
1821+
);
1822+
const items = lr.body.items;
1823+
expect(items).to.have.length(1);
1824+
scope.done();
1825+
});
17501826
});
17511827

17521828
describe('errors', () => {
@@ -1921,5 +1997,31 @@ describe('KubernetesObject', () => {
19211997
expect(thrown).to.be.true;
19221998
scope.done();
19231999
});
2000+
2001+
it('should throw error if no apiVersion', async () => {
2002+
let thrown = false;
2003+
try {
2004+
await (client.list as any)(undefined, undefined);
2005+
expect.fail('should have thrown an error');
2006+
} catch (e) {
2007+
thrown = true;
2008+
expect(e.message).to.contain(
2009+
'Required parameter apiVersion was null or undefined when calling ',
2010+
);
2011+
}
2012+
expect(thrown).to.be.true;
2013+
});
2014+
2015+
it('should throw error if no kind', async () => {
2016+
let thrown = false;
2017+
try {
2018+
await (client.list as any)('', undefined);
2019+
expect.fail('should have thrown an error');
2020+
} catch (e) {
2021+
thrown = true;
2022+
expect(e.message).to.contain('Required parameter kind was null or undefined when calling ');
2023+
}
2024+
expect(thrown).to.be.true;
2025+
});
19242026
});
19252027
});

0 commit comments

Comments
 (0)