diff --git a/src/brokers/broker-details/BrokerDetails.container.tsx b/src/brokers/broker-details/BrokerDetails.container.tsx
index 281f5e8e..2710d1de 100644
--- a/src/brokers/broker-details/BrokerDetails.container.tsx
+++ b/src/brokers/broker-details/BrokerDetails.container.tsx
@@ -144,7 +144,7 @@ const BrokerDetailsPage: FC = () => {
diff --git a/src/brokers/broker-details/components/Overview/Overview.container.tsx b/src/brokers/broker-details/components/Overview/Overview.container.tsx
index 805dba92..926104bc 100644
--- a/src/brokers/broker-details/components/Overview/Overview.container.tsx
+++ b/src/brokers/broker-details/components/Overview/Overview.container.tsx
@@ -1,26 +1,206 @@
import { FC } from 'react';
-import { Page } from '@patternfly/react-core';
+import {
+ Bullseye,
+ CodeBlock,
+ DescriptionList,
+ DescriptionListDescription,
+ DescriptionListGroup,
+ DescriptionListTerm,
+ List,
+ ListItem,
+ Page,
+ PageSection,
+ Title,
+} from '@patternfly/react-core';
import { Metrics } from '../../../../metrics';
import { Loading } from '../../../../shared-components';
+import {
+ Acceptor,
+ IssuerResource,
+ K8sResourceCommon,
+ SecretResource,
+} from '../../../../utils';
+import {
+ getIssuerForAcceptor,
+ getIssuerIngressHostForAcceptor,
+} from '../../../../brokers/utils';
+import { useK8sWatchResource } from '@openshift-console/dynamic-plugin-sdk';
+
+const useGetIssuerCa = (
+ cr: K8sResourceCommon,
+ acceptor: Acceptor,
+): [string, boolean, string] => {
+ const acceptorIssuer = getIssuerForAcceptor(cr, acceptor);
+ const [issuer, loadedIssuers, loadErrorIssuers] =
+ useK8sWatchResource({
+ groupVersionKind: {
+ group: 'cert-manager.io',
+ version: 'v1',
+ kind: 'Issuer',
+ },
+ namespace: cr.metadata.namespace,
+ name: acceptorIssuer,
+ });
+ if (!loadedIssuers || loadErrorIssuers) {
+ return ['', loadedIssuers, loadErrorIssuers];
+ }
+ const secret = issuer.spec?.ca?.secretName ? issuer.spec.ca.secretName : '';
+ return [secret, loadedIssuers, loadErrorIssuers];
+};
+
+const useGetTlsSecret = (cr: K8sResourceCommon, acceptor: Acceptor) => {
+ const [secretName, hasSecretName] = useGetIssuerCa(cr, acceptor);
+ const [secret] = useK8sWatchResource({
+ groupVersionKind: {
+ version: 'v1',
+ kind: 'Secret',
+ },
+ name: secretName,
+ namespace: cr.metadata.namespace,
+ });
+
+ if (hasSecretName && !secretName) {
+ return undefined;
+ }
+ if (!(secret && secret.data && secret.data['tls.crt'])) {
+ return undefined;
+ }
+ return secret;
+};
+
+type SecretDownloaLinkProps = {
+ secret: SecretResource;
+};
+
+const SecretDownloadLink: FC = ({ secret }) => {
+ return (
+
+ {secret.metadata.name + '.pem'}
+
+ );
+};
+
+type IssuerSecretsDownloaderProps = {
+ cr: K8sResourceCommon;
+};
+
+type HelperConnectAcceptorProps = {
+ cr: K8sResourceCommon;
+ acceptor: Acceptor;
+};
+
+const HelpConnectAcceptor: FC = ({
+ cr,
+ acceptor,
+}) => {
+ const secret = useGetTlsSecret(cr, acceptor);
+ const ingressHost = getIssuerIngressHostForAcceptor(cr, acceptor);
+ if (!secret) {
+ return ;
+ }
+ return (
+
+
+ Test the connection to {acceptor.name}
+
+
+
+
+ Download the secret:
+
+
+ Run the command with the secret (here in /tmp)
+
+ $ ./artemis check queue --name TEST --produce 10 --browse 10
+ --consume 10 --url 'tcp://{ingressHost}
+ :443?sslEnabled=true&trustStorePath=/tmp/{secret.metadata.name}
+ .pem&trustStoreType=PEM&useTopologyForLoadBalancing=false'
+ --verbose
+
+
+
+
+
+ );
+};
+
+const ConnectivityHelper: FC = ({ cr }) => {
+ const oneAcceptorHasGeneratedSecrets = cr.spec?.acceptors
+ ? cr.spec.acceptors
+ .map((acceptor) =>
+ acceptor.sslSecret ? acceptor.sslSecret.endsWith('-ptls') : false,
+ )
+ .reduce((acc, hasGeneratedSecrets) => acc || hasGeneratedSecrets)
+ : false;
+ if (!oneAcceptorHasGeneratedSecrets) {
+ return <>bou>;
+ }
+ return (
+ <>
+
+ Connect using Artemis
+
+
+
+ Get Artemis
+
+ Download the{' '}
+
+ latest release
+ {' '}
+ of ActiveMQ Artemis, decompress the tarball and locate the artemis
+ executable.
+
+
+ {cr.spec.acceptors.map((acceptor) => (
+
+ ))}
+
+
+ >
+ );
+};
export type OverviewContainerProps = {
namespace: string;
name: string;
- size: number;
+ cr: K8sResourceCommon;
loading: boolean;
};
export const OverviewContainer: FC = ({
namespace,
name,
- size,
+ cr,
loading,
}) => {
if (loading) return ;
return (
-
+
+
);
};
diff --git a/src/brokers/utils/add-broker.ts b/src/brokers/utils/add-broker.ts
index 060fbe2b..3060bb2b 100644
--- a/src/brokers/utils/add-broker.ts
+++ b/src/brokers/utils/add-broker.ts
@@ -1870,3 +1870,25 @@ export const getIssuerForAcceptor = (cr: ArtemisCR, acceptor: Acceptor) => {
}
return '';
};
+
+export const getIssuerIngressHostForAcceptor = (
+ cr: ArtemisCR,
+ acceptor: Acceptor,
+) => {
+ if (!acceptor) {
+ return '';
+ }
+ // in case there are no resource templates in the CR
+ if (!cr.spec.resourceTemplates) {
+ cr.spec.resourceTemplates = [];
+ }
+ // find if there is already an annotation for this acceptor
+ const selector = certManagerSelector(cr, acceptor.name);
+ const rt = cr.spec.resourceTemplates.find(
+ (rt) => rt.selector?.name === selector,
+ );
+ if (rt) {
+ return rt.patch.spec.tls[0].hosts[0];
+ }
+ return '';
+};
diff --git a/src/metrics/components/MetricsLayout/MetricsLayout.tsx b/src/metrics/components/MetricsLayout/MetricsLayout.tsx
index d6f48111..bcf2704a 100644
--- a/src/metrics/components/MetricsLayout/MetricsLayout.tsx
+++ b/src/metrics/components/MetricsLayout/MetricsLayout.tsx
@@ -1,5 +1,5 @@
import { FC, ReactElement } from 'react';
-import { Grid, GridItem, PageSection } from '@patternfly/react-core';
+import { Grid, GridItem, PageSection, Title } from '@patternfly/react-core';
import { MetricsType } from '../../utils';
export type MetricsLayoutProps = {
@@ -24,6 +24,7 @@ export const MetricsLayout: FC = ({
'pf-u-px-lg-on-xl pf-u-pt-sm-on-xl pf-u-pb-lg-on-xl pf-u-px-md pf-u-pb-md'
}
>
+ Metrics
{metricsActions}
{(() => {
diff --git a/src/utils/types.ts b/src/utils/types.ts
index 38f20b81..630bdec8 100644
--- a/src/utils/types.ts
+++ b/src/utils/types.ts
@@ -100,3 +100,21 @@ export enum BrokerConditionTypes {
IngressReady = 'IngressReady',
TriggerChannelReady = 'TriggerChannelReady',
}
+
+export type IssuerResource = K8sResource & {
+ kind: 'Issuer';
+ spec?: {
+ ca?: {
+ secretName: string;
+ };
+ };
+};
+
+export type SecretResource = K8sResource & {
+ kind: 'Secret';
+ data?: {
+ 'ca.crt'?: string;
+ 'tls.crt'?: string;
+ 'tls.key'?: string;
+ };
+};