mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Better fix for formatting urls
Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
parent
26ea3f4a80
commit
3ef643190c
@ -80,7 +80,7 @@ describe("createKubeApiForRemoteCluster", () => {
|
|||||||
|
|
||||||
it("should request pods from default namespace", () => {
|
it("should request pods from default namespace", () => {
|
||||||
expect(fetchMock.mock.lastCall).toMatchObject([
|
expect(fetchMock.mock.lastCall).toMatchObject([
|
||||||
"https://127.0.0.1:6443/api/v1/namespaces/default/pods",
|
"https://127.0.0.1:6443/api/v1/pods",
|
||||||
{
|
{
|
||||||
headers: {
|
headers: {
|
||||||
"content-type": "application/json",
|
"content-type": "application/json",
|
||||||
@ -93,7 +93,7 @@ describe("createKubeApiForRemoteCluster", () => {
|
|||||||
describe("when request resolves with data", () => {
|
describe("when request resolves with data", () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await fetchMock.resolveSpecific(
|
await fetchMock.resolveSpecific(
|
||||||
["https://127.0.0.1:6443/api/v1/namespaces/default/pods"],
|
["https://127.0.0.1:6443/api/v1/pods"],
|
||||||
new Response(JSON.stringify({
|
new Response(JSON.stringify({
|
||||||
kind: "PodList",
|
kind: "PodList",
|
||||||
apiVersion: "v1",
|
apiVersion: "v1",
|
||||||
@ -1495,4 +1495,138 @@ describe("KubeApi", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("listing pods", () => {
|
||||||
|
let api: PodApi;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
api = new PodApi({
|
||||||
|
request,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when listing pods with no descriptor", () => {
|
||||||
|
let listRequest: Promise<Pod[] | null>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
listRequest = api.list();
|
||||||
|
|
||||||
|
await flushPromises();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should request that the pods from all namespaces", () => {
|
||||||
|
expect(fetchMock.mock.lastCall).toMatchObject([
|
||||||
|
"http://127.0.0.1:9999/api-kube/api/v1/pods",
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
"content-type": "application/json",
|
||||||
|
},
|
||||||
|
method: "get",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when the request resolves with empty data", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await fetchMock.resolveSpecific(
|
||||||
|
["http://127.0.0.1:9999/api-kube/api/v1/pods"],
|
||||||
|
new Response(JSON.stringify({
|
||||||
|
kind: "PodList",
|
||||||
|
apiVersion: "v1",
|
||||||
|
metadata: {},
|
||||||
|
items: [],
|
||||||
|
})),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("the call should resolve to an empty list", async () => {
|
||||||
|
expect(await listRequest).toEqual([]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when listing pods with descriptor with namespace=''", () => {
|
||||||
|
let listRequest: Promise<Pod[] | null>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
listRequest = api.list({
|
||||||
|
namespace: "",
|
||||||
|
});
|
||||||
|
|
||||||
|
await flushPromises();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should request that the pods from all namespaces", () => {
|
||||||
|
expect(fetchMock.mock.lastCall).toMatchObject([
|
||||||
|
"http://127.0.0.1:9999/api-kube/api/v1/pods",
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
"content-type": "application/json",
|
||||||
|
},
|
||||||
|
method: "get",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when the request resolves with empty data", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await fetchMock.resolveSpecific(
|
||||||
|
["http://127.0.0.1:9999/api-kube/api/v1/pods"],
|
||||||
|
new Response(JSON.stringify({
|
||||||
|
kind: "PodList",
|
||||||
|
apiVersion: "v1",
|
||||||
|
metadata: {},
|
||||||
|
items: [],
|
||||||
|
})),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("the call should resolve to an empty list", async () => {
|
||||||
|
expect(await listRequest).toEqual([]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when listing pods with descriptor with namespace='default'", () => {
|
||||||
|
let listRequest: Promise<Pod[] | null>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
listRequest = api.list({
|
||||||
|
namespace: "default",
|
||||||
|
});
|
||||||
|
|
||||||
|
await flushPromises();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should request that the pods from just the default namespace", () => {
|
||||||
|
expect(fetchMock.mock.lastCall).toMatchObject([
|
||||||
|
"http://127.0.0.1:9999/api-kube/api/v1/namespaces/default/pods",
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
"content-type": "application/json",
|
||||||
|
},
|
||||||
|
method: "get",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when the request resolves with empty data", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await fetchMock.resolveSpecific(
|
||||||
|
["http://127.0.0.1:9999/api-kube/api/v1/namespaces/default/pods"],
|
||||||
|
new Response(JSON.stringify({
|
||||||
|
kind: "PodList",
|
||||||
|
apiVersion: "v1",
|
||||||
|
metadata: {},
|
||||||
|
items: [],
|
||||||
|
})),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("the call should resolve to an empty list", async () => {
|
||||||
|
expect(await listRequest).toEqual([]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -393,13 +393,33 @@ export class KubeApi<
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getUrl({ name, namespace }: Partial<ResourceDescriptor> = {}, query?: Partial<KubeApiQueryParams>) {
|
/**
|
||||||
|
* This method differs from {@link formatUrlForNotListing} because this treats `""` as "all namespaces"
|
||||||
|
* @param namespace The namespace to list in or `""` for all namespaces
|
||||||
|
*/
|
||||||
|
formatUrlForListing(namespace: string) {
|
||||||
|
return createKubeApiURL({
|
||||||
|
apiPrefix: this.apiPrefix,
|
||||||
|
apiVersion: this.apiVersionWithGroup,
|
||||||
|
resource: this.apiResource,
|
||||||
|
namespace: this.isNamespaced
|
||||||
|
? namespace ?? "default"
|
||||||
|
: undefined,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format a URL pathname and query for acting upon a specific resource.
|
||||||
|
*/
|
||||||
|
formatUrlForNotListing(resource?: Partial<ResourceDescriptor>, query?: Partial<KubeApiQueryParams>): string;
|
||||||
|
|
||||||
|
formatUrlForNotListing({ name, namespace }: Partial<ResourceDescriptor> = {}, query?: Partial<KubeApiQueryParams>) {
|
||||||
const resourcePath = createKubeApiURL({
|
const resourcePath = createKubeApiURL({
|
||||||
apiPrefix: this.apiPrefix,
|
apiPrefix: this.apiPrefix,
|
||||||
apiVersion: this.apiVersionWithGroup,
|
apiVersion: this.apiVersionWithGroup,
|
||||||
resource: this.apiResource,
|
resource: this.apiResource,
|
||||||
namespace: this.isNamespaced
|
namespace: this.isNamespaced
|
||||||
? namespace ?? "default" // allow `""` to mean all namespaces
|
? namespace || "default"
|
||||||
: undefined,
|
: undefined,
|
||||||
name,
|
name,
|
||||||
});
|
});
|
||||||
@ -407,6 +427,13 @@ export class KubeApi<
|
|||||||
return resourcePath + (query ? `?${stringify(this.normalizeQuery(query))}` : "");
|
return resourcePath + (query ? `?${stringify(this.normalizeQuery(query))}` : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated use {@link formatUrlForNotListing} instead
|
||||||
|
*/
|
||||||
|
getUrl(resource?: Partial<ResourceDescriptor>, query?: Partial<KubeApiQueryParams>) {
|
||||||
|
return this.formatUrlForNotListing(resource, query);
|
||||||
|
}
|
||||||
|
|
||||||
protected normalizeQuery(query: Partial<KubeApiQueryParams> = {}) {
|
protected normalizeQuery(query: Partial<KubeApiQueryParams> = {}) {
|
||||||
if (query.labelSelector) {
|
if (query.labelSelector) {
|
||||||
query.labelSelector = [query.labelSelector].flat().join(",");
|
query.labelSelector = [query.labelSelector].flat().join(",");
|
||||||
@ -484,7 +511,7 @@ export class KubeApi<
|
|||||||
async list({ namespace = "", reqInit }: KubeApiListOptions = {}, query?: KubeApiQueryParams): Promise<Object[] | null> {
|
async list({ namespace = "", reqInit }: KubeApiListOptions = {}, query?: KubeApiQueryParams): Promise<Object[] | null> {
|
||||||
await this.checkPreferredVersion();
|
await this.checkPreferredVersion();
|
||||||
|
|
||||||
const url = this.getUrl({ namespace });
|
const url = this.formatUrlForListing(namespace);
|
||||||
const res = await this.request.get(url, { query }, reqInit);
|
const res = await this.request.get(url, { query }, reqInit);
|
||||||
const parsed = this.parseResponse(res, namespace);
|
const parsed = this.parseResponse(res, namespace);
|
||||||
|
|
||||||
@ -502,7 +529,7 @@ export class KubeApi<
|
|||||||
async get(desc: ResourceDescriptor, query?: KubeApiQueryParams): Promise<Object | null> {
|
async get(desc: ResourceDescriptor, query?: KubeApiQueryParams): Promise<Object | null> {
|
||||||
await this.checkPreferredVersion();
|
await this.checkPreferredVersion();
|
||||||
|
|
||||||
const url = this.getUrl(desc);
|
const url = this.formatUrlForNotListing(desc);
|
||||||
const res = await this.request.get(url, { query });
|
const res = await this.request.get(url, { query });
|
||||||
const parsed = this.parseResponse(res);
|
const parsed = this.parseResponse(res);
|
||||||
|
|
||||||
@ -516,7 +543,7 @@ export class KubeApi<
|
|||||||
async create({ name, namespace }: Partial<ResourceDescriptor>, partialData?: PartialDeep<Object>): Promise<Object | null> {
|
async create({ name, namespace }: Partial<ResourceDescriptor>, partialData?: PartialDeep<Object>): Promise<Object | null> {
|
||||||
await this.checkPreferredVersion();
|
await this.checkPreferredVersion();
|
||||||
|
|
||||||
const apiUrl = this.getUrl({ namespace });
|
const apiUrl = this.formatUrlForNotListing({ namespace });
|
||||||
const data = merge(partialData, {
|
const data = merge(partialData, {
|
||||||
kind: this.kind,
|
kind: this.kind,
|
||||||
apiVersion: this.apiVersionWithGroup,
|
apiVersion: this.apiVersionWithGroup,
|
||||||
@ -537,7 +564,7 @@ export class KubeApi<
|
|||||||
|
|
||||||
async update({ name, namespace }: ResourceDescriptor, data: PartialDeep<Object>): Promise<Object | null> {
|
async update({ name, namespace }: ResourceDescriptor, data: PartialDeep<Object>): Promise<Object | null> {
|
||||||
await this.checkPreferredVersion();
|
await this.checkPreferredVersion();
|
||||||
const apiUrl = this.getUrl({ namespace, name });
|
const apiUrl = this.formatUrlForNotListing({ namespace, name });
|
||||||
|
|
||||||
const res = await this.request.put(apiUrl, {
|
const res = await this.request.put(apiUrl, {
|
||||||
data: merge(data, {
|
data: merge(data, {
|
||||||
@ -562,7 +589,7 @@ export class KubeApi<
|
|||||||
async patch(desc: ResourceDescriptor, data: PartialDeep<Object> | Patch, strategy: KubeApiPatchType): Promise<Object | null>;
|
async patch(desc: ResourceDescriptor, data: PartialDeep<Object> | Patch, strategy: KubeApiPatchType): Promise<Object | null>;
|
||||||
async patch(desc: ResourceDescriptor, data: PartialDeep<Object> | Patch, strategy: KubeApiPatchType = "strategic"): Promise<Object | null> {
|
async patch(desc: ResourceDescriptor, data: PartialDeep<Object> | Patch, strategy: KubeApiPatchType = "strategic"): Promise<Object | null> {
|
||||||
await this.checkPreferredVersion();
|
await this.checkPreferredVersion();
|
||||||
const apiUrl = this.getUrl(desc);
|
const apiUrl = this.formatUrlForNotListing(desc);
|
||||||
|
|
||||||
const res = await this.request.patch(apiUrl, { data }, {
|
const res = await this.request.patch(apiUrl, { data }, {
|
||||||
headers: {
|
headers: {
|
||||||
@ -580,7 +607,7 @@ export class KubeApi<
|
|||||||
|
|
||||||
async delete({ propagationPolicy = "Background", ...desc }: DeleteResourceDescriptor) {
|
async delete({ propagationPolicy = "Background", ...desc }: DeleteResourceDescriptor) {
|
||||||
await this.checkPreferredVersion();
|
await this.checkPreferredVersion();
|
||||||
const apiUrl = this.getUrl(desc);
|
const apiUrl = this.formatUrlForNotListing(desc);
|
||||||
|
|
||||||
return this.request.del(apiUrl, {
|
return this.request.del(apiUrl, {
|
||||||
query: {
|
query: {
|
||||||
@ -590,7 +617,7 @@ export class KubeApi<
|
|||||||
}
|
}
|
||||||
|
|
||||||
getWatchUrl(namespace?: string, query: KubeApiQueryParams = {}) {
|
getWatchUrl(namespace?: string, query: KubeApiQueryParams = {}) {
|
||||||
return this.getUrl({ namespace }, {
|
return this.formatUrlForNotListing({ namespace }, {
|
||||||
watch: 1,
|
watch: 1,
|
||||||
resourceVersion: this.getResourceVersion(namespace),
|
resourceVersion: this.getResourceVersion(namespace),
|
||||||
...query,
|
...query,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user