modify approach to post entire entity to k8s backend
This commit is contained in:
committed by
moustafab
parent
99fffed216
commit
4639d20720
+2
-2
@@ -15,13 +15,13 @@
|
||||
*/
|
||||
|
||||
import { KubernetesAuthTranslator } from './types';
|
||||
import { AuthRequestBody, ClusterDetails } from '../types/types';
|
||||
import { KubernetesRequestBody, ClusterDetails } from '../types/types';
|
||||
|
||||
export class GoogleKubernetesAuthTranslator
|
||||
implements KubernetesAuthTranslator {
|
||||
async decorateClusterDetailsWithAuth(
|
||||
clusterDetails: ClusterDetails,
|
||||
requestBody: AuthRequestBody,
|
||||
requestBody: KubernetesRequestBody,
|
||||
): Promise<ClusterDetails> {
|
||||
const clusterDetailsWithAuthToken: ClusterDetails = Object.assign(
|
||||
{},
|
||||
|
||||
+2
-2
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
import { KubernetesAuthTranslator } from './types';
|
||||
import { AuthRequestBody, ClusterDetails } from '../types/types';
|
||||
import { KubernetesRequestBody, ClusterDetails } from '../types/types';
|
||||
|
||||
export class ServiceAccountKubernetesAuthTranslator
|
||||
implements KubernetesAuthTranslator {
|
||||
@@ -23,7 +23,7 @@ export class ServiceAccountKubernetesAuthTranslator
|
||||
clusterDetails: ClusterDetails,
|
||||
// To ignore TS6133 linting error where it detects 'requestBody' is declared but its value is never read.
|
||||
// @ts-ignore-start
|
||||
requestBody: AuthRequestBody, // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
requestBody: KubernetesRequestBody, // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
// @ts-ignore-end
|
||||
): Promise<ClusterDetails> {
|
||||
return clusterDetails;
|
||||
|
||||
@@ -14,11 +14,11 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { AuthRequestBody, ClusterDetails } from '../types/types';
|
||||
import { KubernetesRequestBody, ClusterDetails } from '../types/types';
|
||||
|
||||
export interface KubernetesAuthTranslator {
|
||||
decorateClusterDetailsWithAuth(
|
||||
clusterDetails: ClusterDetails,
|
||||
requestBody: AuthRequestBody,
|
||||
requestBody: KubernetesRequestBody,
|
||||
): Promise<ClusterDetails>;
|
||||
}
|
||||
|
||||
@@ -91,7 +91,6 @@ describe('handleGetKubernetesObjectsForService', () => {
|
||||
},
|
||||
getVoidLogger(),
|
||||
{},
|
||||
'',
|
||||
);
|
||||
|
||||
expect(getClustersByServiceId.mock.calls.length).toBe(1);
|
||||
|
||||
@@ -16,25 +16,25 @@
|
||||
|
||||
import { Logger } from 'winston';
|
||||
import {
|
||||
AuthRequestBody,
|
||||
KubernetesRequestBody,
|
||||
ClusterDetails,
|
||||
KubernetesServiceLocator,
|
||||
KubernetesFetcher,
|
||||
KubernetesObjectTypes,
|
||||
ObjectsByServiceIdResponse,
|
||||
ObjectsByEntityResponse,
|
||||
} from '../types/types';
|
||||
import { KubernetesAuthTranslator } from '../kubernetes-auth-translator/types';
|
||||
import { KubernetesAuthTranslatorGenerator } from '../kubernetes-auth-translator/KubernetesAuthTranslatorGenerator';
|
||||
import { ComponentEntityV1alpha1 } from '@backstage/catalog-model';
|
||||
|
||||
export type GetKubernetesObjectsForServiceHandler = (
|
||||
serviceId: string,
|
||||
fetcher: KubernetesFetcher,
|
||||
serviceLocator: KubernetesServiceLocator,
|
||||
logger: Logger,
|
||||
requestBody: AuthRequestBody,
|
||||
labelSelector: string,
|
||||
requestBody: KubernetesRequestBody,
|
||||
objectsToFetch?: Set<KubernetesObjectTypes>,
|
||||
) => Promise<ObjectsByServiceIdResponse>;
|
||||
) => Promise<ObjectsByEntityResponse>;
|
||||
|
||||
const DEFAULT_OBJECTS = new Set<KubernetesObjectTypes>([
|
||||
'pods',
|
||||
@@ -46,6 +46,26 @@ const DEFAULT_OBJECTS = new Set<KubernetesObjectTypes>([
|
||||
'ingresses',
|
||||
]);
|
||||
|
||||
function parseLabelSelector(entity: ComponentEntityV1alpha1): string {
|
||||
if (
|
||||
entity &&
|
||||
entity.spec &&
|
||||
entity.spec.kubernetes &&
|
||||
entity.spec.kubernetes.selector
|
||||
) {
|
||||
// TODO: figure out how to convert the selector to the full query param from the yaml
|
||||
// (as shown here https://github.com/kubernetes/apimachinery/blob/master/pkg/labels/selector.go)
|
||||
const { matchLabels } = entity.spec.kubernetes.selector;
|
||||
if (!matchLabels) {
|
||||
return '';
|
||||
}
|
||||
return Object.keys(matchLabels)
|
||||
.map(key => `${key}=${matchLabels[key.toString()]}`)
|
||||
.join(',');
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
// Fans out the request to all clusters that the service lives in, aggregates their responses together
|
||||
export const handleGetKubernetesObjectsForService: GetKubernetesObjectsForServiceHandler = async (
|
||||
serviceId,
|
||||
@@ -53,7 +73,6 @@ export const handleGetKubernetesObjectsForService: GetKubernetesObjectsForServic
|
||||
serviceLocator,
|
||||
logger,
|
||||
requestBody,
|
||||
labelSelector: string,
|
||||
objectsToFetch = DEFAULT_OBJECTS,
|
||||
) => {
|
||||
const clusterDetails: ClusterDetails[] = await serviceLocator.getClustersByServiceId(
|
||||
@@ -80,6 +99,8 @@ export const handleGetKubernetesObjectsForService: GetKubernetesObjectsForServic
|
||||
.join(', ')}]`,
|
||||
);
|
||||
|
||||
const labelSelector = parseLabelSelector(requestBody.entity);
|
||||
|
||||
return Promise.all(
|
||||
clusterDetailsDecoratedForAuth.map(cd => {
|
||||
return fetcher
|
||||
|
||||
@@ -21,14 +21,14 @@ import { makeRouter } from './router';
|
||||
import {
|
||||
KubernetesServiceLocator,
|
||||
KubernetesFetcher,
|
||||
ObjectsByServiceIdResponse,
|
||||
ObjectsByEntityResponse,
|
||||
} from '..';
|
||||
|
||||
describe('router', () => {
|
||||
let app: express.Express;
|
||||
let kubernetesFetcher: jest.Mocked<KubernetesFetcher>;
|
||||
let kubernetesServiceLocator: jest.Mocked<KubernetesServiceLocator>;
|
||||
let handleGetByServiceId: jest.Mock<Promise<ObjectsByServiceIdResponse>>;
|
||||
let handleGetByServiceId: jest.Mock<Promise<ObjectsByEntityResponse>>;
|
||||
|
||||
beforeAll(async () => {
|
||||
kubernetesFetcher = {
|
||||
|
||||
@@ -26,7 +26,7 @@ import {
|
||||
handleGetKubernetesObjectsForService,
|
||||
} from './getKubernetesObjectsForServiceHandler';
|
||||
import {
|
||||
AuthRequestBody,
|
||||
KubernetesRequestBody,
|
||||
KubernetesServiceLocator,
|
||||
KubernetesFetcher,
|
||||
ServiceLocatorMethod,
|
||||
@@ -64,23 +64,21 @@ export const makeRouter = (
|
||||
logger: Logger,
|
||||
fetcher: KubernetesFetcher,
|
||||
serviceLocator: KubernetesServiceLocator,
|
||||
handleGetByServiceId: GetKubernetesObjectsForServiceHandler,
|
||||
handleGetByEntity: GetKubernetesObjectsForServiceHandler,
|
||||
): express.Router => {
|
||||
const router = Router();
|
||||
router.use(express.json());
|
||||
|
||||
router.post('/services/:serviceId', async (req, res) => {
|
||||
const serviceId = req.params.serviceId;
|
||||
const labelSelector = req.query.labelSelector;
|
||||
const requestBody: AuthRequestBody = req.body;
|
||||
const requestBody: KubernetesRequestBody = req.body;
|
||||
try {
|
||||
const response = await handleGetByServiceId(
|
||||
const response = await handleGetByEntity(
|
||||
serviceId,
|
||||
fetcher,
|
||||
serviceLocator,
|
||||
logger,
|
||||
requestBody,
|
||||
labelSelector ? labelSelector.toString() : '',
|
||||
);
|
||||
res.send(response);
|
||||
} catch (e) {
|
||||
|
||||
@@ -23,6 +23,7 @@ import {
|
||||
V1ReplicaSet,
|
||||
V1Service,
|
||||
} from '@kubernetes/client-node';
|
||||
import { ComponentEntityV1alpha1 } from '@backstage/catalog-model';
|
||||
|
||||
export interface ClusterDetails {
|
||||
name: string;
|
||||
@@ -31,10 +32,11 @@ export interface ClusterDetails {
|
||||
serviceAccountToken?: string | undefined;
|
||||
}
|
||||
|
||||
export interface AuthRequestBody {
|
||||
export interface KubernetesRequestBody {
|
||||
auth?: {
|
||||
google?: string;
|
||||
};
|
||||
entity: ComponentEntityV1alpha1;
|
||||
}
|
||||
|
||||
export interface ClusterObjects {
|
||||
@@ -43,7 +45,7 @@ export interface ClusterObjects {
|
||||
errors: KubernetesFetchError[];
|
||||
}
|
||||
|
||||
export interface ObjectsByServiceIdResponse {
|
||||
export interface ObjectsByEntityResponse {
|
||||
items: ClusterObjects[];
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user