Skip to content

Commit

Permalink
[#192] support multiple hosts for the PEM case
Browse files Browse the repository at this point in the history
Add support for multiple hosts to be exposed via an ingress when the
user selects several replicas. Each pod gets exposed and has its own url
to get connected to.

The connectivity helper shows the url of the currently selected pod.

fixes #192
  • Loading branch information
lavocatt committed Aug 14, 2024
1 parent 0b49579 commit 63588d4
Show file tree
Hide file tree
Showing 5 changed files with 191 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
Spinner,
Title,
} from '@patternfly/react-core';
import { FC, useState } from 'react';
import { FC, useContext, useState } from 'react';
import {
getIssuerForAcceptor,
getIssuerIngressHostForAcceptor,
Expand All @@ -32,6 +32,7 @@ import {
SecretResource,
} from '../../../../k8s/types';
import { Metrics } from './Metrics/Metrics';
import { AuthContext } from '../../../../jolokia/context';

const useGetIssuerCa = (
cr: BrokerCR,
Expand Down Expand Up @@ -106,8 +107,9 @@ const HelpConnectAcceptor: FC<HelperConnectAcceptorProps> = ({
cr,
acceptor,
}) => {
const { podOrdinal } = useContext(AuthContext);
const secret = useGetTlsSecret(cr, acceptor);
const ingressHost = getIssuerIngressHostForAcceptor(cr, acceptor);
const ingressHost = getIssuerIngressHostForAcceptor(cr, acceptor, podOrdinal);
const [copied, setCopied] = useState(false);

const clipboardCopyFunc = (text: string) => {
Expand Down
2 changes: 2 additions & 0 deletions src/jolokia/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export type JolokiaLogin = {
isError: boolean;
token: string;
source: jolokiaLoginSource;
podOrdinal: number;
};

export const AuthContext = createContext<JolokiaLogin>({
Expand All @@ -16,4 +17,5 @@ export const AuthContext = createContext<JolokiaLogin>({
isSuccess: false,
isError: false,
source: 'api',
podOrdinal: 0,
});
2 changes: 2 additions & 0 deletions src/jolokia/customHooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ export const useJolokiaLogin = (
isError: isErrorRequestApi,
token: token,
source: 'session',
podOrdinal: ordinal,
};
}
return {
Expand All @@ -241,6 +242,7 @@ export const useJolokiaLogin = (
isLoading: isLoginMutationLoading || isLoginMutationIdle,
token: token,
source: 'api',
podOrdinal: ordinal,
};
};

Expand Down
124 changes: 124 additions & 0 deletions src/reducers/7.12/reducer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -743,6 +743,130 @@ describe('test the creation broker reducer', () => {
).toBe('ing.' + 'bob' + '.' + 'bro' + '-0.' + 'space' + '.' + 'tttt.com');
});

it('test changing number of replicas while in the PEM preset gives the correct number of hosts', () => {
const initialState = newArtemisCRState('namespace');
const stateWith1Acceptor = artemisCrReducer(initialState, {
operation: ArtemisReducerOperations.addAcceptor,
});
const stateWithPEM = artemisCrReducer(stateWith1Acceptor, {
operation: ArtemisReducerOperations.activatePEMGenerationForAcceptor,
payload: {
acceptor: 'acceptors0',
issuer: 'someIssuer',
},
});
expect(stateWithPEM.cr.spec.acceptors[0].sslEnabled).toBe(true);
expect(stateWithPEM.cr.spec.acceptors[0].exposeMode).toBe(
ExposeMode.ingress,
);
expect(stateWithPEM.cr.spec.acceptors[0].ingressHost).toBe(
'ing.$(ITEM_NAME).$(CR_NAME)-$(BROKER_ORDINAL).$(CR_NAMESPACE).$(INGRESS_DOMAIN)',
);
expect(stateWithPEM.cr.spec.acceptors[0].sslSecret).toBe(
'ex-aao-acceptors0-0-svc-ing-ptls',
);
expect(stateWithPEM.cr.spec.resourceTemplates).toHaveLength(1);
expect(stateWithPEM.cr.spec.resourceTemplates[0].selector.name).toBe(
'ex-aao' + '-' + 'acceptors0' + '-0-svc-ing',
);
expect(stateWithPEM.cr.spec.resourceTemplates[0].selector.name).toBe(
'ex-aao' + '-' + 'acceptors0' + '-0-svc-ing',
);
expect(
stateWithPEM.cr.spec.resourceTemplates[0].patch.spec.tls[0].hosts[0],
).toBe(
'ing.' +
'acceptors0' +
'.' +
'ex-aao' +
'-0.' +
'namespace' +
'.' +
'apps-crc.testing',
);
const stateWith2Replicas = artemisCrReducer(stateWithPEM, {
operation: ArtemisReducerOperations.incrementReplicas,
});
expect(
stateWith2Replicas.cr.spec.resourceTemplates[0].patch.spec.tls[0]
.hosts[0],
).toBe(
'ing.' +
'acceptors0' +
'.' +
'ex-aao' +
'-0.' +
'namespace' +
'.' +
'apps-crc.testing',
);
expect(
stateWith2Replicas.cr.spec.resourceTemplates[0].patch.spec.tls[0]
.hosts[1],
).toBe(
'ing.' +
'acceptors0' +
'.' +
'ex-aao' +
'-1.' +
'namespace' +
'.' +
'apps-crc.testing',
);
expect(
stateWith2Replicas.cr.spec.resourceTemplates[0].patch.spec.tls[0].hosts,
).toHaveLength(2);

const newNumber = 10;
const stateWith10Replicas = artemisCrReducer(stateWith2Replicas, {
operation: ArtemisReducerOperations.setReplicasNumber,
payload: newNumber,
});
expect(
stateWith10Replicas.cr.spec.resourceTemplates[0].patch.spec.tls[0].hosts,
).toHaveLength(newNumber);
for (let i = 0; i < newNumber; i++) {
expect(
stateWith10Replicas.cr.spec.resourceTemplates[0].patch.spec.tls[0]
.hosts[i],
).toBe(
'ing.' +
'acceptors0' +
'.' +
'ex-aao' +
'-' +
i +
'.' +
'namespace' +
'.' +
'apps-crc.testing',
);
}
const stateWith9Replicas = artemisCrReducer(stateWith10Replicas, {
operation: ArtemisReducerOperations.decrementReplicas,
});
expect(
stateWith9Replicas.cr.spec.resourceTemplates[0].patch.spec.tls[0].hosts,
).toHaveLength(9);
for (let i = 0; i < 9; i++) {
expect(
stateWith10Replicas.cr.spec.resourceTemplates[0].patch.spec.tls[0]
.hosts[i],
).toBe(
'ing.' +
'acceptors0' +
'.' +
'ex-aao' +
'-' +
i +
'.' +
'namespace' +
'.' +
'apps-crc.testing',
);
}
});

it('test deletePEMGenerationForAcceptor', () => {
const initialState = newArtemisCRState('namespace');
const stateWith1Acceptor = artemisCrReducer(initialState, {
Expand Down
83 changes: 59 additions & 24 deletions src/reducers/7.12/reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -622,16 +622,19 @@ export const artemisCrReducer: React.Reducer<
updateNamespace(formState.cr, action.payload);
break;
case ArtemisReducerOperations.setReplicasNumber:
formState.cr.spec.deploymentPlan.size = action.payload;
updateDeploymentSize(formState.cr, action.payload);
break;
case ArtemisReducerOperations.incrementReplicas:
formState.cr.spec.deploymentPlan.size += 1;
updateDeploymentSize(
formState.cr,
formState.cr.spec.deploymentPlan.size + 1,
);
break;
case ArtemisReducerOperations.decrementReplicas:
formState.cr.spec.deploymentPlan.size -= 1;
if (formState.cr.spec.deploymentPlan.size < 1) {
formState.cr.spec.deploymentPlan.size = 1;
}
updateDeploymentSize(
formState.cr,
formState.cr.spec.deploymentPlan.size - 1,
);
break;
case ArtemisReducerOperations.setBrokerName:
updateBrokerName(formState.cr, action.payload);
Expand Down Expand Up @@ -889,7 +892,31 @@ const updateIngressDomain = (cr: BrokerCR, newName: string) => {
if (!rt) {
return;
}
rt.patch.spec.tls[0].hosts = [certManagerTlsHost(cr, acceptor.name)];
rt.patch.spec.tls[0].hosts = certManagerTlsHosts(cr, acceptor.name);
});
};

const updateDeploymentSize = (cr: BrokerCR, newSize: number) => {
cr.spec.deploymentPlan.size = newSize;
if (cr.spec.deploymentPlan.size < 1) {
cr.spec.deploymentPlan.size = 1;
}
// when the size changes, some annotations will need an update to
// stay in sync
if (!cr.spec.acceptors) {
return;
}
if (!cr.spec.resourceTemplates) {
return;
}
cr.spec.acceptors.forEach((acceptor) => {
const rt = cr.spec.resourceTemplates.find(
(rt) => rt.selector.name === certManagerSelector(cr, acceptor.name),
);
if (!rt) {
return;
}
rt.patch.spec.tls[0].hosts = certManagerTlsHosts(cr, acceptor.name);
});
};

Expand All @@ -910,7 +937,7 @@ const updateNamespace = (cr: BrokerCR, newName: string) => {
if (!rt) {
return;
}
rt.patch.spec.tls[0].hosts = [certManagerTlsHost(cr, acceptor.name)];
rt.patch.spec.tls[0].hosts = certManagerTlsHosts(cr, acceptor.name);
});
};

Expand Down Expand Up @@ -939,7 +966,7 @@ const updateBrokerName = (cr: BrokerCR, newName: string) => {
}
rt.selector.name = certManagerSelector(cr, acceptor.name);
rt.patch.spec.tls[0] = {
hosts: [certManagerTlsHost(cr, acceptor.name)],
hosts: certManagerTlsHosts(cr, acceptor.name),
secretName: acceptor.sslSecret,
};
});
Expand Down Expand Up @@ -996,16 +1023,25 @@ const setIssuerForAcceptor = (
}
};

// TODO handle multiple ordinals
const certManagerTlsHost = (cr: BrokerCR, acceptor: string) =>
'ing.' +
acceptor +
'.' +
cr.metadata.name +
'-0.' +
cr.metadata.namespace +
'.' +
cr.spec.ingressDomain;
const certManagerTlsHosts = (cr: BrokerCR, acceptor: string): string[] => {
const ret: string[] = [];
for (let i = 0; i < cr.spec.deploymentPlan.size; i++) {
ret.push(
'ing.' +
acceptor +
'.' +
cr.metadata.name +
'-' +
i +
'.' +
cr.metadata.namespace +
'.' +
cr.spec.ingressDomain,
);
}

return ret;
};

const certManagerSelector = (cr: BrokerCR, acceptor: string) =>
cr.metadata.name + '-' + acceptor + '-0-svc-ing';
Expand Down Expand Up @@ -1033,8 +1069,7 @@ const updateAcceptorNameInResourceTemplate = (
// if there's a match update the required fields
if (rt) {
rt.selector.name = certManagerSelector(cr, newName);
// TODO support multiple ordinals
rt.patch.spec.tls[0].hosts = [certManagerTlsHost(cr, newName)];
rt.patch.spec.tls[0].hosts = certManagerTlsHosts(cr, newName);
rt.patch.spec.tls[0].secretName = certManagerSecret(cr, newName);
}
};
Expand All @@ -1049,7 +1084,6 @@ const createCertManagerResourceTemplate = (
acceptor: Acceptor,
issuerName: string,
): ResourceTemplate => {
// TODO support multiple ordinals
return {
selector: {
kind: 'Ingress',
Expand All @@ -1063,7 +1097,7 @@ const createCertManagerResourceTemplate = (
spec: {
tls: [
{
hosts: [certManagerTlsHost(cr, acceptor.name)],
hosts: certManagerTlsHosts(cr, acceptor.name),
secretName: acceptor.sslSecret,
},
],
Expand Down Expand Up @@ -1885,6 +1919,7 @@ export const getIssuerForAcceptor = (cr: BrokerCR, acceptor: Acceptor) => {
export const getIssuerIngressHostForAcceptor = (
cr: BrokerCR,
acceptor: Acceptor,
podOrdinal: number,
) => {
if (!acceptor) {
return '';
Expand All @@ -1899,7 +1934,7 @@ export const getIssuerIngressHostForAcceptor = (
(rt) => rt.selector?.name === selector,
);
if (rt) {
return rt.patch.spec.tls[0].hosts[0];
return rt.patch.spec.tls[0].hosts[podOrdinal];
}
return '';
};

0 comments on commit 63588d4

Please sign in to comment.