diff --git a/src/object.ts b/src/object.ts index 9a0888dd3a..350b8a733c 100644 --- a/src/object.ts +++ b/src/object.ts @@ -20,7 +20,7 @@ type KubernetesObjectResponseBody = | V1APIResourceList; /** Kubernetes API verbs. */ -type KubernetesApiAction = 'create' | 'delete' | 'patch' | 'read' | 'replace'; +type KubernetesApiAction = 'create' | 'delete' | 'patch' | 'read' | 'list' | 'replace'; /** * Valid Content-Type header values for patch operations. See @@ -315,6 +315,96 @@ export class KubernetesObjectApi extends ApisApi { return this.requestPromise(localVarRequestOptions); } + /** + * List any Kubernetes resources. + * @param apiVersion api group and version of the form / + * @param kind Kubernetes resource kind + * @param namespace list resources in this namespace + * @param pretty If \'true\', then the output is pretty printed. + * @param exact Should the export be exact. Exact export maintains cluster-specific fields like + * \'Namespace\'. Deprecated. Planned for removal in 1.18. + * @param exportt Should this value be exported. Export strips fields that a user can not + * specify. Deprecated. Planned for removal in 1.18. + * @param fieldSelector A selector to restrict the list of returned objects by their fields. Defaults to everything. + * @param labelSelector A selector to restrict the list of returned objects by their labels. Defaults to everything. + * @param limit Number of returned resources. + * @param options Optional headers to use in the request. + * @return Promise containing the request response and [[KubernetesListObject]]. + */ + public async list( + apiVersion: string, + kind: string, + namespace?: string, + pretty?: string, + exact?: boolean, + exportt?: boolean, + fieldSelector?: string, + labelSelector?: string, + limit?: number, + continueToken?: string, + options: { headers: { [name: string]: string } } = { headers: {} }, + ): Promise<{ body: KubernetesListObject; response: http.IncomingMessage }> { + // verify required parameters 'apiVersion', 'kind' is not null or undefined + if (apiVersion === null || apiVersion === undefined) { + throw new Error('Required parameter apiVersion was null or undefined when calling list.'); + } + if (kind === null || kind === undefined) { + throw new Error('Required parameter kind was null or undefined when calling list.'); + } + + const localVarPath = await this.specUriPath( + { + apiVersion, + kind, + metadata: { + namespace, + }, + }, + 'list', + ); + const localVarQueryParameters: any = {}; + const localVarHeaderParams = this.generateHeaders(options.headers); + + if (pretty !== undefined) { + localVarQueryParameters.pretty = ObjectSerializer.serialize(pretty, 'string'); + } + + if (exact !== undefined) { + localVarQueryParameters.exact = ObjectSerializer.serialize(exact, 'boolean'); + } + + if (exportt !== undefined) { + localVarQueryParameters.export = ObjectSerializer.serialize(exportt, 'boolean'); + } + + if (fieldSelector !== undefined) { + localVarQueryParameters.fieldSelector = ObjectSerializer.serialize(fieldSelector, 'string'); + } + + if (labelSelector !== undefined) { + localVarQueryParameters.labelSelector = ObjectSerializer.serialize(labelSelector, 'string'); + } + + if (limit !== undefined) { + localVarQueryParameters.limit = ObjectSerializer.serialize(limit, 'number'); + } + + if (continueToken !== undefined) { + localVarQueryParameters.continue = ObjectSerializer.serialize(continueToken, 'string'); + } + + const localVarRequestOptions: request.Options = { + method: 'GET', + qs: localVarQueryParameters, + headers: localVarHeaderParams, + uri: localVarPath, + useQuerystring: this._useQuerystring, + json: true, + }; + + return this.requestPromise(localVarRequestOptions); + } + /** * Replace any Kubernetes resource. * @param spec Kubernetes resource spec @@ -403,7 +493,7 @@ export class KubernetesObjectApi extends ApisApi { if (!resource) { throw new Error(`Unrecognized API version and kind: ${spec.apiVersion} ${spec.kind}`); } - if (resource.namespaced && !spec.metadata.namespace) { + if (resource.namespaced && !spec.metadata.namespace && action !== 'list') { spec.metadata.namespace = this.defaultNamespace; } const parts = [this.apiVersionPath(spec.apiVersion)]; @@ -411,7 +501,7 @@ export class KubernetesObjectApi extends ApisApi { parts.push('namespaces', encodeURIComponent(String(spec.metadata.namespace))); } parts.push(resource.name); - if (action !== 'create') { + if (action !== 'create' && action !== 'list') { if (!spec.metadata.name) { throw new Error('Required spec property name is not set'); } diff --git a/src/object_test.ts b/src/object_test.ts index c5c33d75a3..77a258855d 100644 --- a/src/object_test.ts +++ b/src/object_test.ts @@ -1747,6 +1747,85 @@ describe('KubernetesObject', () => { await client.delete(s, undefined, undefined, 7, undefined, 'Foreground'); scope.done(); }); + + it('should list resources in a namespace', async () => { + const scope = nock('https://d.i.y') + .get( + '/api/v1/namespaces/default/secrets?fieldSelector=metadata.name%3Dtest-secret1&labelSelector=app%3Dmy-app&limit=5&continue=abc', + ) + .reply(200, { + apiVersion: 'v1', + kind: 'SecretList', + items: [ + { + apiVersion: 'v1', + kind: 'Secret', + metadata: { + name: 'test-secret-1', + uid: 'a4fd7a65-2af5-4ef1-a0bc-cb34a308b821', + }, + }, + ], + metadata: { + resourceVersion: '216532459', + continue: 'abc', + }, + }); + const lr = await client.list( + 'v1', + 'Secret', + 'default', + undefined, + undefined, + undefined, + 'metadata.name=test-secret1', + 'app=my-app', + 5, + 'abc', + ); + const items = lr.body.items; + expect(items).to.have.length(1); + scope.done(); + }); + + it('should list resources in all namespaces', async () => { + const scope = nock('https://d.i.y') + .get( + '/api/v1/secrets?fieldSelector=metadata.name%3Dtest-secret1&labelSelector=app%3Dmy-app&limit=5', + ) + .reply(200, { + apiVersion: 'v1', + kind: 'SecretList', + items: [ + { + apiVersion: 'v1', + kind: 'Secret', + metadata: { + name: 'test-secret-1', + uid: 'a4fd7a65-2af5-4ef1-a0bc-cb34a308b821', + }, + }, + ], + metadata: { + resourceVersion: '216532459', + continue: 'abc', + }, + }); + const lr = await client.list( + 'v1', + 'Secret', + undefined, + undefined, + undefined, + undefined, + 'metadata.name=test-secret1', + 'app=my-app', + 5, + ); + const items = lr.body.items; + expect(items).to.have.length(1); + scope.done(); + }); }); describe('errors', () => { @@ -1921,5 +2000,31 @@ describe('KubernetesObject', () => { expect(thrown).to.be.true; scope.done(); }); + + it('should throw error if no apiVersion', async () => { + let thrown = false; + try { + await (client.list as any)(undefined, undefined); + expect.fail('should have thrown an error'); + } catch (e) { + thrown = true; + expect(e.message).to.contain( + 'Required parameter apiVersion was null or undefined when calling ', + ); + } + expect(thrown).to.be.true; + }); + + it('should throw error if no kind', async () => { + let thrown = false; + try { + await (client.list as any)('', undefined); + expect.fail('should have thrown an error'); + } catch (e) { + thrown = true; + expect(e.message).to.contain('Required parameter kind was null or undefined when calling '); + } + expect(thrown).to.be.true; + }); }); });