Skip to content

Commit

Permalink
Simplify API utils for constructing URLs
Browse files Browse the repository at this point in the history
There's no longer a need for multiple utils to build Kube API URLs.
This is an artifact of an earlier approach which is no longer used.

Combine the various URL builders into a single util and replace usage
as appropriate.

`getTektonAPI` will be removed in a future change.

This simplification will be core to the planned updates for React
Router 6, providing a single common approach to handling all Kube
resources in the app.
  • Loading branch information
AlanGreene authored and tekton-robot committed May 17, 2024
1 parent 6af26ae commit a792138
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 142 deletions.
13 changes: 6 additions & 7 deletions src/api/extensions.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2019-2021 The Tekton Authors
Copyright 2019-2024 The Tekton Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
Expand All @@ -12,15 +12,14 @@ limitations under the License.
*/

import { get } from './comms';
import { dashboardAPIGroup, getResourcesAPI, useCollection } from './utils';
import { dashboardAPIGroup, getKubeAPI, useCollection } from './utils';

function getExtensionsAPI({ isWebSocket, namespace }) {
return getResourcesAPI({
return getKubeAPI({
group: dashboardAPIGroup,
isWebSocket,
version: 'v1alpha1',
type: 'extensions',
namespace
kind: 'extensions',
params: { isWebSocket, namespace },
version: 'v1alpha1'
});
}

Expand Down
97 changes: 67 additions & 30 deletions src/api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import {
apiRoot,
getKubeAPI,
getQueryParams,
getResourcesAPI,
getTektonAPI,
getTektonPipelinesAPIVersion,
isLogTimestampsEnabled,
Expand All @@ -49,26 +48,37 @@ export * from './triggerBindings';
export * from './triggers';
export * from './triggerTemplates';

function getCustomResourcesAPI({
filters,
export function getCustomResources({
filters = [],
involvedObjectKind,
involvedObjectName,
name,
...rest
}) {
return getResourcesAPI(
rest,
getQueryParams({ filters, involvedObjectKind, involvedObjectName, name })
);
}

export function getCustomResources({ filters = [], ...rest }) {
const uri = getCustomResourcesAPI({ filters, ...rest });
const { isWebSocket, group, namespace, type, version } = rest;
const uri = getKubeAPI({
group,
kind: type,
params: { isWebSocket, name, namespace },
queryParams: getQueryParams({
filters,
involvedObjectKind,
involvedObjectName,
name
}),
version
});
return get(uri);
}

export function useCustomResources(params, queryConfig) {
const webSocketURL = getCustomResourcesAPI({ ...params, isWebSocket: true });
const webSocketURL = getKubeAPI({
group: params.group,
kind: params.type,
params: { isWebSocket: true, namespace: params.namespace },
queryParams: getQueryParams({ filters: params.filters }),
version: params.version
});
return useCollection({
api: getCustomResources,
kind: params.type,
Expand All @@ -78,13 +88,27 @@ export function useCustomResources(params, queryConfig) {
});
}

export function getCustomResource(params) {
const uri = getResourcesAPI(params);
export function getCustomResource({ group, name, namespace, type, version }) {
const uri = getKubeAPI({
group,
kind: type,
params: { name, namespace },
version
});
return get(uri);
}

export function useCustomResource(params) {
const webSocketURL = getCustomResourcesAPI({ ...params, isWebSocket: true });
const webSocketURL = getKubeAPI({
group: params.group,
kind: params.type,
params: {
isWebSocket: true,
name: params.name,
namespace: params.namespace
},
version: params.version
});
return useResource({
api: getCustomResource,
kind: params.type,
Expand Down Expand Up @@ -133,7 +157,12 @@ export async function getInstallProperties() {
}

function getNamespacesAPI({ isWebSocket } = {}) {
return getKubeAPI('namespaces', { isWebSocket });
return getKubeAPI({
group: 'core',
version: 'v1',
kind: 'namespaces',
params: { isWebSocket }
});
}

export function getNamespaces() {
Expand All @@ -152,16 +181,19 @@ export function useNamespaces(queryConfig) {
}

export function usePod(params, queryConfig) {
const gvt = { group: 'core', type: 'pods', version: 'v1' };
const webSocketURL = getCustomResourcesAPI({
...gvt,
...params,
isWebSocket: true
const group = 'core';
const type = 'pods';
const version = 'v1';
const webSocketURL = getKubeAPI({
group,
kind: type,
params: { ...params, isWebSocket: true },
version
});
return useResource({
api: getCustomResource,
kind: 'customResource',
params: { ...gvt, ...params },
params: { group, type, version, ...params },
queryConfig,
webSocketURL
});
Expand All @@ -179,9 +211,12 @@ export function useEvents(
type: 'events',
version: 'v1'
};
const webSocketURL = getCustomResourcesAPI({
...params,
isWebSocket: true
const webSocketURL = getKubeAPI({
group: params.group,
kind: params.type,
params: { isWebSocket: true, namespace },
queryParams: getQueryParams({ involvedObjectKind, involvedObjectName }),
version: params.version
});
return useCollection({
api: getCustomResources,
Expand Down Expand Up @@ -221,11 +256,13 @@ export function getPodLogURL({ container, name, namespace, follow }) {
...(follow && { follow }),
...(timestamps && { timestamps })
};
const uri = `${getKubeAPI(
'pods',
{ name, namespace, subResource: 'log' },
queryParams
)}`;
const uri = `${getKubeAPI({
group: 'core',
kind: 'pods',
params: { name, namespace, subResource: 'log' },
queryParams,
version: 'v1'
})}`;
return uri;
}

Expand Down
20 changes: 15 additions & 5 deletions src/api/serviceAccounts.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2019-2021 The Tekton Authors
Copyright 2019-2024 The Tekton Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
Expand All @@ -15,14 +15,24 @@ import { get } from './comms';
import { getKubeAPI, useCollection } from './utils';

export function getServiceAccounts({ namespace } = {}) {
const uri = getKubeAPI('serviceaccounts', { namespace });
const uri = getKubeAPI({
group: 'core',
kind: 'serviceaccounts',
params: { namespace },
version: 'v1'
});
return get(uri);
}

export function useServiceAccounts(params, queryConfig) {
const webSocketURL = getKubeAPI('serviceaccounts', {
...params,
isWebSocket: true
const webSocketURL = getKubeAPI({
group: 'core',
kind: 'serviceaccounts',
params: {
...params,
isWebSocket: true
},
version: 'v1'
});
return useCollection({
api: getServiceAccounts,
Expand Down
59 changes: 21 additions & 38 deletions src/api/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,41 +22,19 @@ export const tektonAPIGroup = 'tekton.dev';
export const triggersAPIGroup = 'triggers.tekton.dev';
export const dashboardAPIGroup = 'dashboard.tekton.dev';

export function getKubeAPI(
type,
{ isWebSocket, name = '', namespace, subResource } = {},
queryParams
) {
export function getKubeAPI({
group,
kind,
params: { isWebSocket, name = '', namespace, subResource } = {},
queryParams,
version
}) {
const queryParamsToUse = {
...queryParams,
...(isWebSocket
? { [subResource === 'log' ? 'follow' : 'watch']: true }
: null)
};

return [
isWebSocket ? apiRoot.replace('http', 'ws') : apiRoot,
'/api/v1/',
namespace && namespace !== ALL_NAMESPACES
? `namespaces/${encodeURIComponent(namespace)}/`
: '',
type,
'/',
encodeURIComponent(name),
subResource ? `/${subResource}` : '',
Object.keys(queryParamsToUse).length > 0
? `?${new URLSearchParams(queryParamsToUse).toString()}`
: ''
].join('');
}

export function getResourcesAPI(
{ isWebSocket, group, name = '', namespace, type, version },
queryParams
) {
const queryParamsToUse = {
...queryParams,
...(isWebSocket ? { watch: true } : null)
: null),
...(isWebSocket && name ? { fieldSelector: `metadata.name=${name}` } : null)
};

return [
Expand All @@ -65,9 +43,10 @@ export function getResourcesAPI(
namespace && namespace !== ALL_NAMESPACES
? `namespaces/${encodeURIComponent(namespace)}/`
: '',
type,
kind,
'/',
encodeURIComponent(name),
isWebSocket ? '' : encodeURIComponent(name),
subResource ? `/${subResource}` : '',
Object.keys(queryParamsToUse).length > 0
? `?${new URLSearchParams(queryParamsToUse).toString()}`
: ''
Expand Down Expand Up @@ -109,8 +88,9 @@ export function getTektonPipelinesAPIVersion() {
return isPipelinesV1ResourcesEnabled() ? 'v1' : 'v1beta1';
}

// TODO: remove this and replace usage with getKubeAPI directly
export function getTektonAPI(
type,
kind,
{
group = tektonAPIGroup,
isWebSocket,
Expand All @@ -120,10 +100,13 @@ export function getTektonAPI(
} = {},
queryParams
) {
return getResourcesAPI(
{ group, isWebSocket, name, namespace, type, version },
queryParams
);
return getKubeAPI({
group,
kind,
params: { isWebSocket, name, namespace },
queryParams,
version
});
}

export const NamespaceContext = createContext();
Expand Down
63 changes: 1 addition & 62 deletions src/api/utils.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2019-2023 The Tekton Authors
Copyright 2019-2024 The Tekton Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
Expand Down Expand Up @@ -58,67 +58,6 @@ describe('getTektonAPI', () => {
});
});

describe('getResourcesAPI', () => {
it('returns a URI containing the given type', () => {
const uri = utils.getResourcesAPI({
group: 'test.dev',
version: 'testversion',
type: 'testtype'
});
expect(uri).toContain('test.dev');
expect(uri).toContain('testversion');
expect(uri).toContain('testtype');
});

it('returns a URI containing the given type and name without namespace', () => {
const uri = utils.getResourcesAPI({
group: 'test.dev',
version: 'testversion',
type: 'testtype',
name: 'testname'
});
expect(uri).toContain('test.dev');
expect(uri).toContain('testversion');
expect(uri).toContain('testtype');
expect(uri).toContain('testname');
expect(uri).not.toContain('namespaces');
});

it('returns a URI containing the given type, name and namespace', () => {
const uri = utils.getResourcesAPI({
group: 'test.dev',
version: 'testversion',
type: 'testtype',
namespace: 'testnamespace',
name: 'testname'
});
expect(uri).toContain('test.dev');
expect(uri).toContain('testversion');
expect(uri).toContain('testtype');
expect(uri).toContain('testname');
expect(uri).toContain('namespaces');
expect(uri).toContain('testnamespace');
});

it('handles the core group correctly', () => {
const uri = utils.getResourcesAPI({
group: 'core',
version: 'testversion',
type: 'testtype',
namespace: 'testnamespace',
name: 'testname'
});
expect(uri).not.toContain('core');
expect(uri).toContain('api');
expect(uri).not.toContain('apis');
expect(uri).toContain('testversion');
expect(uri).toContain('testtype');
expect(uri).toContain('testname');
expect(uri).toContain('namespaces');
expect(uri).toContain('testnamespace');
});
});

describe('getQueryParams', () => {
it('should handle label filters', () => {
const filters = ['fakeLabel=fakeValue'];
Expand Down

0 comments on commit a792138

Please sign in to comment.