Skip to content

Commit

Permalink
Checking for service catalog and service brokers installation and dep…
Browse files Browse the repository at this point in the history
…loyed service instances (#86)

* checks for service catalog, service brokers and service instances

* review changes

* moving checkCatalogInstalled into an action
  • Loading branch information
sozercan authored and prydonius committed Feb 19, 2018
1 parent eb719c8 commit 9be3ea2
Show file tree
Hide file tree
Showing 8 changed files with 132 additions and 76 deletions.
8 changes: 8 additions & 0 deletions src/actions/catalog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,11 @@ export function getCatalog() {
dispatch(getPlans());
};
}

export function checkCatalogInstalled() {
return async (dispatch: Dispatch<IStoreState>) => {
const isInstalled = await ServiceCatalog.isCatalogInstalled();
isInstalled ? dispatch(installed()) : dispatch(notInstalled());
return isInstalled;
};
}
39 changes: 23 additions & 16 deletions src/components/Config/ServiceBrokerList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,29 @@ export const ServiceBrokerList = (props: IServiceBrokerListProps) => {
return (
<div className="service-broker-list">
<h3>Brokers</h3>
<CardContainer>
{brokers.map(broker => {
const card = (
<div>
<Card
key={broker.metadata.uid}
header={broker.metadata.name}
body={broker.spec.url}
notes={`Last updated ${broker.status.lastCatalogRetrievalTime}`}
button={<SyncButton sync={sync} broker={broker} />}
/>
</div>
);
return card;
})}
</CardContainer>
{brokers.length > 0 ? (
<CardContainer>
{brokers.map(broker => {
const card = (
<div>
<Card
key={broker.metadata.uid}
header={broker.metadata.name}
body={broker.spec.url}
notes={`Last updated ${broker.status.lastCatalogRetrievalTime}`}
button={<SyncButton sync={sync} broker={broker} />}
/>
</div>
);
return card;
})}
</CardContainer>
) : (
<div>
No service brokers are installed in your cluster. Please ask an administrator to install
it.
</div>
)}
</div>
);
};
2 changes: 1 addition & 1 deletion src/components/Config/ServiceCatalog/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { IServiceCatalogState } from "../../../reducers/catalog";
import { ServiceBrokerList } from "../ServiceBrokerList";

export interface IServiceCatalogDispatch {
checkCatalogInstalled: () => Promise<boolean>;
checkCatalogInstalled: () => Promise<any>;
getCatalog: () => Promise<any>;
sync: () => Promise<any>;
}
Expand Down
55 changes: 55 additions & 0 deletions src/components/InstanceListView/InstanceCardList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import * as React from "react";

import { IClusterServiceClass } from "../../shared/ClusterServiceClass";
import { IServiceInstance } from "../../shared/ServiceInstance";
import { Card, CardContainer } from "../Card";

export interface InstanceCardListProps {
classes: IClusterServiceClass[];
instances: IServiceInstance[];
}

export const InstanceCardList = (props: InstanceCardListProps) => {
const { instances, classes } = props;
return (
<div className="InstanceCardList">
<section>
<CardContainer>
{instances.length > 0 &&
instances.map(instance => {
const conditions = [...instance.status.conditions];
const status = conditions.shift(); // first in list is most recent
const message = status ? status.message : "";
const svcClass = classes.find(
potential => potential.metadata.name === instance.spec.clusterServiceClassRef.name,
);
const broker = svcClass && svcClass.spec.clusterServiceBrokerName;
const icon =
svcClass &&
svcClass.spec.externalMetadata &&
svcClass.spec.externalMetadata.imageUrl;

const card = (
<Card
key={instance.metadata.uid}
header={
<span>
{instance.metadata.namespace}/{instance.metadata.name}
</span>
}
icon={icon}
body={message}
buttonText="Details"
linkTo={`/services/brokers/${broker}/instances/${instance.metadata.namespace}/${
instance.metadata.name
}/`}
notes={<span>{instance.spec.clusterServicePlanExternalName}</span>}
/>
);
return card;
})}
</CardContainer>
</section>
</div>
);
};
89 changes: 37 additions & 52 deletions src/components/InstanceListView/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,79 +4,64 @@ import { Link } from "react-router-dom";
import { IClusterServiceClass } from "../../shared/ClusterServiceClass";
import { IServiceBroker, IServicePlan } from "../../shared/ServiceCatalog";
import { IServiceInstance } from "../../shared/ServiceInstance";
import { Card, CardContainer } from "../Card";
import { InstanceCardList } from "./InstanceCardList";

export interface InstanceListViewProps {
brokers: IServiceBroker[];
classes: IClusterServiceClass[];
getCatalog: () => Promise<any>;
checkCatalogInstalled: () => Promise<any>;
instances: IServiceInstance[];
plans: IServicePlan[];
isInstalled: boolean;
}

export class InstanceListView extends React.PureComponent<InstanceListViewProps> {
public async componentDidMount() {
this.props.checkCatalogInstalled();
this.props.getCatalog();
}

public render() {
const { brokers, instances, classes } = this.props;
const { isInstalled, brokers, instances, classes } = this.props;

return (
<div className="InstanceList">
{brokers && (
<h3>Service Instances</h3>

{isInstalled ? (
<div>
<div className="row">
<div className="col-8">
<h3>Service Instances</h3>
<p>Service instances from your brokers:</p>
{brokers.length > 0 ? (
<div>
<div className="row">
<div className="col-8">
<p>Service instances from your brokers:</p>
</div>
<div className="col-4 text-r">
<Link to={`/services/classes`}>
<button className="button button-accent">Provision New Service</button>
</Link>
</div>
</div>
{instances.length > 0 ? (
<InstanceCardList instances={instances} classes={classes} />
) : (
<div>No service instances are found.</div>
)}
</div>
<div className="col-2 margin-normal">
<Link to={`/services/classes`}>
<button className="button button-primary">Provision New Service</button>
</Link>
) : (
<div>
No service brokers are installed in your cluster. Please ask an administrator to
install it.
</div>
</div>
<table>
<tbody>
<CardContainer>
{instances.length > 0 &&
instances.map(instance => {
const conditions = [...instance.status.conditions];
const status = conditions.shift(); // first in list is most recent
const message = status ? status.message : "";
const svcClass = classes.find(
potential =>
potential.metadata.name === instance.spec.clusterServiceClassRef.name,
);
const broker = svcClass && svcClass.spec.clusterServiceBrokerName;
const icon =
svcClass &&
svcClass.spec.externalMetadata &&
svcClass.spec.externalMetadata.imageUrl;

const card = (
<Card
key={instance.metadata.uid}
header={
<span>
{instance.metadata.namespace}/{instance.metadata.name}
</span>
}
icon={icon}
body={message}
buttonText="Details"
linkTo={`/services/brokers/${broker}/instances/${
instance.metadata.namespace
}/${instance.metadata.name}/`}
notes={<span>{instance.spec.clusterServicePlanExternalName}</span>}
/>
);
return card;
})}
</CardContainer>
</tbody>
</table>
)}
</div>
) : (
<div>
<div>No Service Catalog is installed.</div>
<Link className="button button-primary" to={`/charts/svc-cat/catalog`}>
Install Catalog
</Link>
</div>
)}
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/components/ProvisionButton/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ class ProvisionButton extends React.Component<IProvisionButtonProps, IProvisionB
selectedPlan.spec.externalName,
parametersObject,
);
push(`/services`);
push(`/services/instances`);
}
} catch (err) {
this.setState({ isProvisioning: false, error: err.toString() });
Expand Down
5 changes: 5 additions & 0 deletions src/containers/InstanceListViewContainer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,21 @@ function mapStateToProps({ catalog }: IStoreState, { match: { params } }: IRoute
const plans = catalog.plans;
const classes = catalog.classes;
const instances = catalog.instances;
const isInstalled = catalog.isInstalled;
return {
brokers,
classes,
instances,
isInstalled,
plans,
};
}

function mapDispatchToProps(dispatch: Dispatch<IStoreState>) {
return {
checkCatalogInstalled: async () => {
dispatch(actions.catalog.checkCatalogInstalled());
},
getCatalog: async () => {
dispatch(actions.catalog.getCatalog());
},
Expand Down
8 changes: 2 additions & 6 deletions src/containers/ServiceCatalogContainer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Dispatch } from "redux";

import actions from "../actions";
import { ServiceCatalogView } from "../components/Config/ServiceCatalog";
import { IServiceBroker, ServiceCatalog } from "../shared/ServiceCatalog";
import { IServiceBroker } from "../shared/ServiceCatalog";
import { IStoreState } from "../shared/types";

function mapStateToProps({ catalog }: IStoreState) {
Expand All @@ -15,11 +15,7 @@ function mapStateToProps({ catalog }: IStoreState) {
function mapDispatchToProps(dispatch: Dispatch<IStoreState>) {
return {
checkCatalogInstalled: async () => {
const isInstalled = await ServiceCatalog.isCatalogInstalled();
isInstalled
? dispatch(actions.catalog.installed())
: dispatch(actions.catalog.notInstalled());
return isInstalled;
dispatch(actions.catalog.checkCatalogInstalled());
},
getCatalog: () => dispatch(actions.catalog.getCatalog()),
sync: (broker: IServiceBroker) => dispatch(actions.catalog.sync(broker)),
Expand Down

0 comments on commit 9be3ea2

Please sign in to comment.