Skip to content

Commit

Permalink
add support for Operator Backed SBR through topology inContext
Browse files Browse the repository at this point in the history
remove comment
  • Loading branch information
sahil143 committed Nov 3, 2020
1 parent dc11145 commit 7787d84
Show file tree
Hide file tree
Showing 14 changed files with 391 additions and 364 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Extension } from './base';
namespace ExtensionProperties {
export interface DevCatalogModel {
model: K8sKind;
normalize: (data: K8sResourceKind[]) => K8sResourceKind[];
normalize: (data: K8sResourceKind[], params?: URLSearchParams) => K8sResourceKind[];
}
}

Expand Down
7 changes: 0 additions & 7 deletions frontend/packages/console-shared/src/hooks/useQueryParams.ts

This file was deleted.

14 changes: 14 additions & 0 deletions frontend/packages/console-shared/src/hooks/useQueryParams.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import * as React from 'react';
import { useLocation } from 'react-router-dom';

export const useQueryParams = () => {
const { search } = useLocation();
return React.useMemo(() => new URLSearchParams(search), [search]);
};

export const withQueryParams = <Props extends {} = {}>(
Component: React.ComponentType<Props>,
): React.FC<Props> => (props: Props) => {
const queryParams = useQueryParams();
return <Component {...props} queryParams={queryParams} />;
};
3 changes: 3 additions & 0 deletions frontend/packages/dev-console/src/actions/add-resources.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import HelmChartsIcon from '../components/helm/HelmChartsIcon';

export const allImportResourceAccess = 'allImportResourceAccess';
export const allCatalogImageResourceAccess = 'allCatalogImageResourceAccess';
export const serviceBindingAvailable = 'serviceBindingAvailable';

export const fromGit = createKebabAction(
'From Git',
Expand Down Expand Up @@ -54,6 +55,7 @@ export const fromOperatorBacked = createKebabAction(
'Operator Backed',
<BoltIcon />,
ImportOptions.OPERATORBACKED,
serviceBindingAvailable,
);

export const fromHelmCharts = createKebabAction(
Expand All @@ -77,4 +79,5 @@ export const addResourceMenuWithoutCatalog: KebabAction[] = [
fromGit,
containerImage,
fromDockerfile,
fromOperatorBacked,
];
2 changes: 2 additions & 0 deletions frontend/packages/dev-console/src/const.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,6 @@ export const UNASSIGNED_LABEL = 'no application group';
export enum CONNECTOR_INCONTEXT_ACTIONS {
/** connects to action for resources */
connectsTo = 'connectsTo',
/** connector action for service binding */
serviceBinding = 'serviceBinding',
}
9 changes: 8 additions & 1 deletion frontend/packages/dev-console/src/plugin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ import {
import { pipelinesTopologyPlugin } from './components/topology/pipelines/pipelinesTopologyPlugin';
import { usePerspectiveDetection } from './utils/usePerspectiveDetection';
import { getGuidedTour } from './components/guided-tour';
import { doConnectsToBinding } from './utils/connector-utils';
import { doConnectsToBinding, doContextualBinding } from './utils/connector-utils';

const {
ClusterTaskModel,
Expand Down Expand Up @@ -1166,6 +1166,13 @@ const plugin: Plugin<ConsumedExtensions> = [
callback: doConnectsToBinding,
},
},
{
type: 'PostFormSubmissionAction',
properties: {
type: CONNECTOR_INCONTEXT_ACTIONS.serviceBinding,
callback: doContextualBinding,
},
},
...helmTopologyPlugin,
...operatorsTopologyPlugin,
...pipelinesTopologyPlugin,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,14 @@ export const getAddPageUrl = (
case ImportOptions.OPERATORBACKED:
pageUrl = `/catalog/ns/${ns}`;
params.append('kind', JSON.stringify(['ClusterServiceVersion']));
contextSource &&
params.append(
QUERY_PROPERTIES.CONTEXT_ACTION,
JSON.stringify({
type: CONNECTOR_INCONTEXT_ACTIONS.serviceBinding,
payload: contextSource,
}),
);
break;
case ImportOptions.HELMCHARTS:
pageUrl = `/catalog/ns/${ns}`;
Expand Down
52 changes: 15 additions & 37 deletions frontend/packages/dev-console/src/utils/connector-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import {
import { DeploymentConfigModel, DeploymentModel } from '@console/internal/models';
import { ConnectsToData } from '../components/topology/topology-types';
import { createServiceBinding } from '../components/topology/operators/actions/serviceBindings';
import { ClusterServiceVersionModel } from '@console/operator-lifecycle-manager';

const getModel = (groupVersionKind: string): K8sKind => {
const m = allModels().get(groupVersionKind);
Expand Down Expand Up @@ -207,8 +206,9 @@ export const createResourceConnection = (
};

const getSourceAndTargetForBinding = async (
resources: K8sResourceKind[],
resources: K8sResourceKind[] | K8sResourceKind,
contextualSource: string,
serviceBindingAvailable?: boolean,
): Promise<{ source: K8sResourceKind; target: K8sResourceKind }> => {
if (!contextualSource) {
return Promise.reject(new Error('Cannot do a contextual binding without a source'));
Expand All @@ -217,9 +217,14 @@ const getSourceAndTargetForBinding = async (
referenceForModel(DeploymentConfigModel),
referenceForModel(DeploymentModel),
];
const target: K8sResourceKind = resources.find((resource) =>
linkingModelRefs.includes(referenceFor(resource)),
);
let target;
if (serviceBindingAvailable) {
target = resources;
} else {
target = (resources as K8sResourceKind[]).find((resource) =>
linkingModelRefs.includes(referenceFor(resource)),
);
}
const {
metadata: { namespace },
} = target;
Expand All @@ -246,39 +251,12 @@ export const doConnectsToBinding = async (

return resources;
};
export const getOperatorBackedServiceKindMap = (installedOperators) =>
installedOperators
? installedOperators.reduce((kindMap, csv) => {
(csv?.spec?.customresourcedefinitions?.owned || []).forEach((crd) => {
if (!(crd.kind in kindMap)) {
kindMap[crd.kind] = csv;
}
});
return kindMap;
}, {})
: {};

export const doContextualBinding = async (
resources: K8sResourceKind[],
target: K8sResourceKind,
contextualSource: string,
serviceBindingAvailable: boolean = true,
): Promise<K8sResourceKind[]> => {
if (!serviceBindingAvailable) {
return resources;
}
const { source, target } = await getSourceAndTargetForBinding(resources, contextualSource);
const {
metadata: { namespace },
} = target;
const operatorBackedServiceKindMap = getOperatorBackedServiceKindMap(
await k8sList(ClusterServiceVersionModel, { ns: namespace }),
);
const ownerResourceKind = target?.metadata?.ownerReferences?.[0]?.kind;
const isOperatorBacked = ownerResourceKind in operatorBackedServiceKindMap;

if (isOperatorBacked) {
await createServiceBinding(source, target);
}

return resources;
): Promise<K8sResourceKind> => {
const { source } = await getSourceAndTargetForBinding(target, contextualSource, true);
await createServiceBinding(source, target);
return target;
};
19 changes: 18 additions & 1 deletion frontend/packages/dev-console/src/utils/useAddToProjectAccess.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import * as React from 'react';
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
// @ts-ignore: FIXME missing exports due to out-of-sync @types/react-redux version
import { useSelector } from 'react-redux';
import { AccessReviewResourceAttributes, K8sKind } from '@console/internal/module/k8s';
import { useAccessReview } from '@console/internal/components/utils';
import {
Expand All @@ -10,7 +13,13 @@ import {
SecretModel,
ServiceModel,
} from '@console/internal/models';
import { allCatalogImageResourceAccess, allImportResourceAccess } from '../actions/add-resources';
import { RootState } from '@console/internal/redux';
import {
allCatalogImageResourceAccess,
allImportResourceAccess,
serviceBindingAvailable,
} from '../actions/add-resources';
import { ALLOW_SERVICE_BINDING } from '../const';

const resourceAttributes = (model: K8sKind, namespace: string): AccessReviewResourceAttributes => {
return {
Expand All @@ -36,6 +45,10 @@ export const useAddToProjectAccess = (activeNamespace: string): string[] => {
const routeAccess = useAccessReview(resourceAttributes(RouteModel, activeNamespace));
const serviceAccess = useAccessReview(resourceAttributes(ServiceModel, activeNamespace));

const serviceBindingEnabled = useSelector((state: RootState) =>
state.FLAGS.get(ALLOW_SERVICE_BINDING),
);

React.useEffect(() => {
const createResourceAccess: string[] = [];
if (
Expand All @@ -51,6 +64,9 @@ export const useAddToProjectAccess = (activeNamespace: string): string[] => {
createResourceAccess.push(allCatalogImageResourceAccess);
}
}
if (serviceBindingEnabled) {
createResourceAccess.push(serviceBindingAvailable);
}
setAddAccess(createResourceAccess);
}, [
buildConfigsAccess,
Expand All @@ -60,6 +76,7 @@ export const useAddToProjectAccess = (activeNamespace: string): string[] => {
routeAccess,
secretAccess,
serviceAccess,
serviceBindingEnabled,
]);

return addAccess;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import {
} from '../descriptors/spec/affinity';
import { OperandFormProps } from './operand-form';
import { ProvidedAPI } from '../../types';
import { usePostFormSubmitAction } from '@console/shared';

/*
* Matches a path that contains an array index. Use Sting.match against an OperandField 'path'
Expand Down Expand Up @@ -518,6 +519,7 @@ export const DEPRECATED_CreateOperandForm: React.FC<OperandFormProps> = ({
match,
next,
}) => {
const postFormCallback = usePostFormSubmitAction<K8sResourceKind>();
const immutableFormData = Immutable.fromJS(formData);
const handleFormDataUpdate = (path: string, value: any): void => {
const { regexMatch, index, pathBeforeIndex, pathAfterIndex } = parseArrayPath(path);
Expand Down Expand Up @@ -716,7 +718,10 @@ export const DEPRECATED_CreateOperandForm: React.FC<OperandFormProps> = ({
? immutableFormData.setIn(['metadata', 'namespace'], match.params.ns).toJS()
: immutableFormData.toJS(),
)
.then(() => history.push(next))
.then((res) => {
postFormCallback(res);
return history.push(next);
})
.catch((err: Error) => setError(err.message || 'Unknown error.'));
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
} from '@console/internal/components/utils';
import * as _ from 'lodash';
import * as React from 'react';
import { usePostFormSubmitAction } from '@console/shared';
import { ClusterServiceVersionModel } from '../../models';
import { ClusterServiceVersionKind, CRDDescription, APIServiceDefinition } from '../../types';
import { ClusterServiceVersionLogo } from '../index';
Expand All @@ -27,7 +28,7 @@ export const OperandForm: React.FC<OperandFormProps> = ({
}) => {
const [errors, setErrors] = React.useState<string[]>([]);
// const [formData, setFormData] = React.useState(initialData);

const postFormCallback = usePostFormSubmitAction<K8sResourceKind>();
const processFormData = ({ metadata, ...rest }) => {
const data = {
metadata: {
Expand All @@ -41,7 +42,10 @@ export const OperandForm: React.FC<OperandFormProps> = ({

const handleSubmit = ({ formData: submitFormData }) => {
k8sCreate(model, processFormData(submitFormData))
.then(() => next && history.push(next))
.then((res) => {
postFormCallback(res);
return next && history.push(next);
})
.catch((e) => setErrors([e.message]));
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const isInternal = (crd: { name: string }): boolean => {
};
export const normalizeClusterServiceVersions = (
clusterServiceVersions: ClusterServiceVersionKind[],
params?: URLSearchParams,
): K8sResourceKind[] => {
const imgFor = (desc) =>
_.get(desc.csv, 'spec.icon')
Expand Down Expand Up @@ -65,9 +66,9 @@ export const normalizeClusterServiceVersions = (
tileProvider: desc.csv.spec.provider.name,
tags: desc.csv.spec.keywords,
createLabel: 'Create',
href: `/ns/${desc.csv.metadata.namespace}/clusterserviceversions/${
href: `/k8s/ns/${desc.csv.metadata.namespace}/clusterserviceversions/${
desc.csv.metadata.name
}/${referenceForProvidedAPI(desc)}/~new`,
}/${referenceForProvidedAPI(desc)}/~new?${params.toString()}`,
supportUrl: desc.csv.metadata.annotations?.['marketplace.openshift.io/support-workflow'],
longDescription: `This resource is provided by ${desc.csv.spec.displayName}, a Kubernetes Operator enabled by the Operator Lifecycle Manager.`,
documentationUrl: _.get(
Expand Down
13 changes: 0 additions & 13 deletions frontend/packages/operator-lifecycle-manager/src/plugin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -184,19 +184,6 @@ const plugin: Plugin<ConsumedExtensions> = [
).CreateSubscriptionYAML,
},
},
{
type: 'Page/Route',
properties: {
exact: true,
path: `/k8s/ns/:ns/${models.ClusterServiceVersionModel.plural}/:appName/:plural/~new`,
loader: async () =>
(
await import(
'./components/operand/create-operand' /* webpackChunkName: "create-operand" */
)
).CreateOperandPage,
},
},
{
type: 'Page/Route',
properties: {
Expand Down

0 comments on commit 7787d84

Please sign in to comment.