Skip to content

Commit

Permalink
add bindable resources to topology data factory
Browse files Browse the repository at this point in the history
  • Loading branch information
rottencandy committed Aug 19, 2021
1 parent a5fb9ec commit b5c890f
Show file tree
Hide file tree
Showing 6 changed files with 166 additions and 0 deletions.
13 changes: 13 additions & 0 deletions frontend/packages/dev-console/console-extensions.json
Expand Up @@ -482,6 +482,19 @@
"required": ["ALLOW_SERVICE_BINDING"]
}
},
{
"type": "console.topology/data/factory",
"properties": {
"id": "bindable-service-topology-data-model-factory",
"getDataModel": { "$codeRef": "topology.getBindableServicesTopologyDataModel" },
"isResourceDepicted": { "$codeRef": "topology.isServiceBindable" },
"resources": { "$codeRef": "topology.useBindableResources" },
"priority": 100
},
"flags": {
"required": ["ALLOW_SERVICE_BINDING"]
}
},
{
"type": "console.topology/details/tab-section",
"properties": {
Expand Down
@@ -0,0 +1,112 @@
import * as React from 'react';
import { Model, NodeModel } from '@patternfly/react-topology';
import { ExtensionHook, WatchK8sResources } from '@console/dynamic-plugin-sdk';
import { TopologyDataResources } from '@console/dynamic-plugin-sdk/src/api/topology-types';
import { useK8sWatchResource } from '@console/internal/components/utils/k8s-watch-hook';
import {
K8sResourceKind,
referenceForGroupVersionKind,
referenceForModel,
} from '@console/internal/module/k8s';
import { getRhoasServiceBindingEdges } from '@console/rhoas-plugin/src/topology/rhoas-data-transformer';
import { useActiveNamespace } from '@console/shared';
import { getTopologyNodeItem } from '@console/topology/src/data-transforms/transform-utils';
import { ServiceBindingModel } from '@console/topology/src/models';
import { TopologyDataObject } from '@console/topology/src/topology-types';
import { TYPE_BINDABLE_NODE } from '../const';
import { BindableServicesModel } from './models';
import { BindableServicesKind } from './types';

const getTopologyBindableServiceNodes = (resources: K8sResourceKind[]): NodeModel[] => {
const nodes = resources.map((obj) => {
const data: TopologyDataObject = {
id: obj.metadata.uid,
name: obj.metadata.name,
type: TYPE_BINDABLE_NODE,
resource: obj,
resources: { obj },
data: {
resource: obj,
},
};
return getTopologyNodeItem(obj, TYPE_BINDABLE_NODE, data);
});

return nodes;
};

export const getBindableServicesTopologyDataModel = async (
_namespace: string,
resources: TopologyDataResources,
): Promise<Model> => {
const bindableService = resources?.bindableService.data?.[0] as BindableServicesKind;
const bindableResources = bindableService?.spec?.map(({ kind }) => resources[kind]?.data || []);
const serviceBindingRequests = resources?.serviceBindingRequests?.data;

const servicesDataModel: Model = {
edges: [],
nodes: [],
};
bindableResources.forEach((resource) =>
servicesDataModel.nodes.push(...getTopologyBindableServiceNodes(resource)),
);

if (servicesDataModel.nodes.length) {
bindableResources.forEach((resource) =>
servicesDataModel.edges.push(
...getRhoasServiceBindingEdges(
resource as K8sResourceKind,
servicesDataModel.nodes,
serviceBindingRequests,
),
),
);
}

return servicesDataModel;
};

export const useBindableResources: ExtensionHook<WatchK8sResources<any>> = () => {
const [namespace] = useActiveNamespace();
const bindableWatchResource = React.useMemo(
() => ({
kind: referenceForModel(BindableServicesModel),
isList: false,
namespaced: false,
name: 'bindable-services',
}),
[],
);
const [bindableService, loaded, loadError] = useK8sWatchResource<BindableServicesKind>(
bindableWatchResource,
);
const resources = React.useMemo<[WatchK8sResources<any>, boolean, any]>(() => {
return [
{
bindableResources: bindableWatchResource,
serviceBindingRequests: {
isList: true,
kind: referenceForModel(ServiceBindingModel),
namespace,
optional: true,
},
...bindableService?.spec.reduce(
(acc, { group, version, kind }) => ({
[kind]: {
isList: true,
namespaced: true,
namespace,
kind: referenceForGroupVersionKind(group)(version)(kind),
},
...acc,
}),
{},
),
},
loaded,
loadError,
];
}, [bindableWatchResource, namespace, bindableService, loaded, loadError]);

return resources;
};
@@ -0,0 +1,9 @@
import { Model } from '@patternfly/react-topology';
import { K8sResourceKind } from '@console/internal/module/k8s';

export const isBindable = (resource: K8sResourceKind, model: Model): boolean => {
if (!model?.nodes?.length) {
return false;
}
return resource.metadata.labels?.['app.kubernetes.io/component'] === 'external-service';
};
@@ -0,0 +1,13 @@
import { K8sKind } from '@console/internal/module/k8s';

export const BindableServicesModel: K8sKind = {
apiGroup: 'binding.operators.coreos.com',
apiVersion: 'v1alpha1',
kind: 'BindableService',
plural: 'BindableServices',
label: 'BindableService',
labelPlural: 'BindableServices',
abbr: 'BS',
crd: true,
namespaced: false,
};
@@ -0,0 +1,14 @@
import { K8sResourceKind } from '@console/internal/module/k8s';

export type BindableServiceGVK = {
group: string;
version: string;
kind: string;
};

export type BindableServicesKind = {
metadata: {
name: string;
};
spec: BindableServiceGVK[];
} & K8sResourceKind;
Expand Up @@ -5,3 +5,8 @@ export {
} from './relationship-provider';
export * from './hpa-tab-section';
export * from './observe-tab-section';
export { isBindable } from './bindable-services/isBindable';
export {
getBindableServicesTopologyDataModel,
useBindableResources,
} from './bindable-services/data-transformer';

0 comments on commit b5c890f

Please sign in to comment.