Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deregistration #1430

Merged
merged 61 commits into from
Jun 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
8b7db2a
Host deregistration events (#1245)
CDimonaco Mar 8, 2023
8ac4924
Fix deregistration commands namespace
CDimonaco Mar 9, 2023
eeacc9d
Deregistration side effects (#1252)
rtorrero Mar 14, 2023
c255d6e
Host Deregistration process manager and aggregate handling (#1249)
CDimonaco Mar 14, 2023
ee696f4
Cluster and cluster host deregistration events/commands (#1274)
rtorrero Mar 23, 2023
3d6cab4
Fix Hosts query without the soft deleted hosts exclusion (#1282)
CDimonaco Mar 24, 2023
921d510
Cluster registration also for nodes not DC (#1275)
CDimonaco Mar 27, 2023
a6f6c98
Cluster deregistration process manager & aggregate changes (#1278)
rtorrero Mar 31, 2023
d5d8823
Cluster deregistered side effects (#1280)
CDimonaco Apr 5, 2023
608e839
Correct typos (#1315)
jamie-suse Apr 11, 2023
c5f7e25
Database registration changes (#1326)
CDimonaco Apr 18, 2023
84d4332
Add SAP System deregistration commands & events (#1314)
jamie-suse Apr 18, 2023
b2d4cf8
Fix Deregistration process manager state validation
CDimonaco Apr 26, 2023
d379e3a
Add application instance deregistration logic (#1357)
rtorrero Apr 26, 2023
585ce81
Application instances registration changes (#1358)
CDimonaco May 2, 2023
3c6718f
Add SAP System de/registration logic to Process Manager (#1356)
jamie-suse May 2, 2023
17138fa
Add database instance deregistration logic (#1372)
jamie-suse May 4, 2023
78c6e55
Add SAP System deregistration side effects (#1387)
jamie-suse May 9, 2023
cf5dad9
Detect ascs/ers cluster type (#1392)
arbulu89 May 10, 2023
bf7a9ae
Ascs ers type frontend (#1398)
arbulu89 May 10, 2023
2812cc5
Discover ASCS/ERS cluster SIDs (#1400)
arbulu89 May 11, 2023
fb2af98
Handle `:database_not_registered` errors (#1405)
jamie-suse May 12, 2023
202b58a
Add polymorphic embed usage to deftype macro (#1411)
arbulu89 May 16, 2023
8ce53a5
Properly handle multiple errors returned (#1413)
rtorrero May 16, 2023
0c83b2b
Display ASCS/ERS clusters SID in clusters view (#1403)
arbulu89 May 16, 2023
7a36b42
Revert HeartbeatSucceeded to old name (#1429)
arbulu89 May 18, 2023
87e78e8
Add deregistration websocket events (#1424)
rtorrero May 23, 2023
ef0911c
Discover ASCS/ERS clusters health and initial details (#1422)
arbulu89 May 23, 2023
d763180
Set default value to additional_sids in cluster events (#1441)
arbulu89 May 23, 2023
d2b93e2
Cluster delta deregistration (#1386)
fabriziosestito May 29, 2023
858bca3
Add additional ascs/ers cluster details discovery (#1442)
arbulu89 May 29, 2023
e9ffacb
Deregistration process manager retry the rollup errors from aggregate…
CDimonaco May 30, 2023
083a123
Fix HostRemovedFromCluster concurrency issues (#1474)
fabriziosestito May 30, 2023
b4f3e5e
Basic deregistration leftovers (#1461)
CDimonaco May 31, 2023
ccb1aab
Deregistration tombstoning rollup (#1425)
CDimonaco Jun 1, 2023
3ce2c36
Change redirect plug to use a list of available versions (#1487)
arbulu89 Jun 5, 2023
913690a
Enable openapi schema versioning (#1488)
arbulu89 Jun 6, 2023
51fd837
Add endpoint to deregister a host (#1450)
jamie-suse Jun 7, 2023
971eb74
Add V2 scope to /api/clusters endpoint (#1492)
arbulu89 Jun 7, 2023
7497a94
Aggregate clauses reorder (#1495)
CDimonaco Jun 7, 2023
cf9fcd7
Sap system delta deregistration (#1491)
fabriziosestito Jun 8, 2023
c8c7533
Identify sap systems ensa version (#1496)
arbulu89 Jun 8, 2023
f6b1a03
DatabaseDeregistered side effects (#1504)
rtorrero Jun 8, 2023
00facf1
Make `HostReadModel.last_heartbeat_timestamp` a virtual field (#1505)
jamie-suse Jun 9, 2023
22de7de
Project removal of db/app instances to the read models (#1507)
rtorrero Jun 12, 2023
c7ac1c4
Reject commands when aggregate deregistered (#1513)
CDimonaco Jun 13, 2023
3267484
Ensa version domain (#1512)
arbulu89 Jun 13, 2023
59d5916
Create AscsErsClusterRole enum (#1520)
arbulu89 Jun 14, 2023
76102d2
Host restoration (#1517)
CDimonaco Jun 14, 2023
be4cf53
Broadcast sap system updated (#1516)
arbulu89 Jun 14, 2023
f0f39dd
Cluster restoration (#1523)
CDimonaco Jun 15, 2023
eeeef68
Move sagas functions to separate files according to adr 0009 (#1531)
rtorrero Jun 16, 2023
4f0183d
Update health summary endpoint (#1530)
arbulu89 Jun 19, 2023
b311326
Frontend instance removal on broadcast (#1522)
rtorrero Jun 19, 2023
5594adb
Fix sap system domain apply ordering issues (#1550)
arbulu89 Jun 21, 2023
60eb897
Move application instances (#1554)
fabriziosestito Jun 21, 2023
e98f4b5
Add Deregistration modal (#1537)
jamie-suse Jun 22, 2023
fa827eb
Allow rollup on deregistered aggregates (#1551)
CDimonaco Jun 22, 2023
10983a5
Complete tests on command acceptance/rejection (#1563)
arbulu89 Jun 22, 2023
7370429
Sap system restoration (#1545)
CDimonaco Jun 29, 2023
6de3737
Merge remote-tracking branch 'origin/main' into deregistration
rtorrero Jun 29, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ jobs:
- name: Build docs
uses: lee-dohm/generate-elixir-docs@v1
- name: Generate openapi.json
run: mix openapi.spec.json --start-app=false --spec TrentoWeb.OpenApi.ApiSpec
run: mix openapi.spec.json --start-app=false --spec TrentoWeb.OpenApi.V1.ApiSpec
- name: Generate Swagger UI
uses: Legion2/swagger-ui-action@v1
with:
Expand Down
6 changes: 5 additions & 1 deletion assets/js/components/Button/Button.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,14 @@ const getButtonClasses = (type) => {
switch (type) {
case 'primary-white':
return 'bg-white hover:opacity-75 focus:outline-none text-jungle-green-500 w-full transition ease-in duration-200 text-center font-semibold rounded shadow';
case 'primary-white-fit':
return 'bg-white hover:opacity-75 focus:outline-none text-jungle-green-500 w-fit transition ease-in duration-200 text-center font-semibold rounded shadow';
case 'transparent':
return 'bg-transparent hover:opacity-75 focus:outline-none w-full transition ease-in duration-200 font-semibold';
case 'secondary':
return 'bg-persimmon hover:opacity-75 focus:outline-none text-gray-800 w-full transition ease-in duration-200 text-center font-semibold rounded shadow';
return 'bg-persimmon hover:opacity-75 focus:outline-none text-gray-800 w-full transition ease-in duration-200 text-center font-semibold rounded shadow';
case 'default-fit':
return 'bg-jungle-green-500 hover:opacity-75 focus:outline-none text-white w-fit transition ease-in duration-200 text-center font-semibold rounded shadow';
default:
return 'bg-jungle-green-500 hover:opacity-75 focus:outline-none text-white w-full transition ease-in duration-200 text-center font-semibold rounded shadow';
}
Expand Down
8 changes: 6 additions & 2 deletions assets/js/components/ClustersList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ const getClusterTypeLabel = (type) => {
return 'HANA Scale Up';
case 'hana_scale_out':
return 'HANA Scale Out';
case 'ascs_ers':
return 'ASCS/ERS';
default:
return 'Unknown';
}
Expand Down Expand Up @@ -67,7 +69,9 @@ function ClustersList() {
title: 'SID',
key: 'sid',
filterFromParams: true,
filter: true,
filter: (filter, key) => (element) =>
element[key].some((sid) => filter.includes(sid)),
render: (_, { sid }) => sid.join(', '),
},
{
title: 'Hosts',
Expand Down Expand Up @@ -122,7 +126,7 @@ function ClustersList() {
health: cluster.health,
name: cluster.name,
id: cluster.id,
sid: cluster.sid,
sid: (cluster.sid ? [cluster.sid] : []).concat(cluster.additional_sids),
type: cluster.type,
hosts_number: cluster.hosts_number,
resources_number: cluster.resources_number,
Expand Down
31 changes: 27 additions & 4 deletions assets/js/components/ClustersList.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,28 +58,33 @@ describe('ClustersList component', () => {
},
{
filter: 'SID',
options: ['PRD', 'QAS'],
options: ['PRD', 'QAS', 'HA1', 'HA2'],
state: {
...cleanInitialState,
clustersList: {
clusters: [].concat(
clusterFactory.buildList(4),
clusterFactory.buildList(2, { sid: 'PRD' }),
clusterFactory.buildList(2, { sid: 'QAS' })
clusterFactory.buildList(2, { sid: 'QAS' }),
clusterFactory.buildList(2, {
sid: null,
additional_sids: ['HA1', 'HA2'],
})
),
},
},
expectedRows: 2,
},
{
filter: 'Type',
options: ['hana_scale_up'],
options: ['hana_scale_up', 'ascs_ers'],
state: {
...cleanInitialState,
clustersList: {
clusters: [].concat(
clusterFactory.buildList(2, { type: 'unknown' }),
clusterFactory.buildList(2, { type: 'hana_scale_up' })
clusterFactory.buildList(2, { type: 'hana_scale_up' }),
clusterFactory.buildList(2, { type: 'ascs_ers' })
),
},
},
Expand Down Expand Up @@ -123,6 +128,24 @@ describe('ClustersList component', () => {
}
);

it('should show SIDs delimited by comma in multi-sid clusters', () => {
const state = {
...cleanInitialState,
clustersList: {
clusters: clusterFactory.buildList(1, {
sid: null,
additional_sids: ['HA1', 'HA2'],
}),
},
};

const [StatefulClustersList] = withState(<ClustersList />, state);

renderWithRouter(StatefulClustersList);

expect(screen.getByText('HA1, HA2')).toBeVisible();
});

it('should put the filters values in the query string when filters are selected', () => {
const tag = 'Tag1';
const clusters = clusterFactory.buildList(1, {
Expand Down
48 changes: 48 additions & 0 deletions assets/js/components/DeregistrationModal/DeregistrationModal.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React from 'react';

import { EOS_CLEANING_SERVICES } from 'eos-icons-react';

import Modal from '@components/Modal';
import Button from '@components/Button';

function DeregistrationModal({
hostname,
isOpen = false,
onCleanUp,
onCancel,
}) {
return (
<Modal
title={`Clean up data discovered by agent on host ${hostname}`}
open={isOpen}
onClose={onCancel}
>
<div className="text-gray-500">
This action will cause Trento to stop tracking all the components
discovered by the agent in this host, including the host itself and any
other component depending on it.
</div>
<div className="flex justify-start gap-2 mt-4">
<Button
type="default-fit"
className="inline-block mx-0.5 border-green-500 border w-fit"
size="small"
onClick={onCleanUp}
>
<EOS_CLEANING_SERVICES size="base" className="fill-white inline" />
<span className="text-white text-sm font-bold pl-1.5">Clean up</span>
</Button>
<Button
type="primary-white-fit"
className="inline-block mx-0.5 border-green-500 border"
size="small"
onClick={onCancel}
>
Cancel
</Button>
</div>
</Modal>
);
}

export default DeregistrationModal;
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import React, { useState } from 'react';

import Button from '@components/Button';
import DeregistrationModal from '.';

export default {
title: 'DeregistrationModal',
component: DeregistrationModal,
argTypes: {
hostname: {
type: 'string',
description: 'The host name to confirm deregistration of',
control: { type: 'text' },
},
isOpen: {
type: 'boolean',
description: 'Sets the visibility of the modal',
control: false,
},
onCleanUp: {
description: 'Callback function to run when "Clean up" button is clicked',
action: 'Deregistration',
control: false,
},
onClose: {
description: 'Callback function to run when "Cancel" button is clicked',
action: 'Cancel',
control: false,
},
},
};

function ButtonToOpenModal({ hostname }) {
const [open, setOpen] = useState(false);
const [deregistered, setDeregistered] = useState(false);

return (
<>
<Button
type="default-fit"
className={`inline-block mx-0.5 border-green-500 border w-fit ${
deregistered ? 'bg-rose-500' : 'bg-jungle-green-500'
}`}
size="small"
onClick={() => setOpen(true)}
>
{deregistered
? `Host ${hostname} deregistered`
: 'Click me to open modal'}
</Button>

<DeregistrationModal
hostname={hostname}
isOpen={open}
onCleanUp={() => {
setDeregistered(true);
setOpen(false);
}}
onCancel={() => setOpen(false)}
/>
</>
);
}

export const Default = {
args: {
hostname: 'example host',
},
render: (args) => <ButtonToOpenModal {...args} />,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import { faker } from '@faker-js/faker';

import DeregistrationModal from '.';

describe('Deregistration Modal component', () => {
it('should render deregistration modal correctly', async () => {
const hostname = faker.name.firstName();

render(
<DeregistrationModal
hostname={hostname}
isOpen
onCleanUp={() => {}}
onCancel={() => {}}
/>
);

expect(await screen.findByText(hostname, { exact: false })).toBeTruthy();
expect(
await screen.findByRole('button', { name: /Clean up/i })
).toBeTruthy();
expect(await screen.findByRole('button', { name: /Cancel/i })).toBeTruthy();
});
});
3 changes: 3 additions & 0 deletions assets/js/components/DeregistrationModal/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import DeregistrationModal from './DeregistrationModal';

export default DeregistrationModal;
16 changes: 8 additions & 8 deletions assets/js/lib/network/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,36 +68,36 @@ function handleResponseStatus(response) {
return response;
}

export const post = function post(url, data) {
export const post = function post(url, data, config = null) {
return networkClient
.post(url, data)
.post(url, data, config)
.then(handleResponseStatus)
.catch((error) => {
handleError(error);
});
};

export const del = function del(url) {
export const del = function del(url, config = null) {
return networkClient
.delete(url)
.delete(url, config)
.then(handleResponseStatus)
.catch((error) => {
handleError(error);
});
};

export const put = function put(url, data) {
export const put = function put(url, data, config = null) {
return networkClient
.put(url, data)
.put(url, data, config)
.then(handleResponseStatus)
.catch((error) => {
handleError(error);
});
};

export const get = function get(url) {
export const get = function get(url, config = null) {
return networkClient
.get(url)
.get(url, config)
.then(handleResponseStatus)
.catch((error) => {
handleError(error);
Expand Down
16 changes: 16 additions & 0 deletions assets/js/lib/network/network.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,22 @@ describe('networkClient', () => {
clearCredentialsFromStore();
});

it('should use default baseURL', async () => {
axiosMock.onGet('/api/v1/test').reply(200, { ok: 'ok' });

const response = await networkClient.get('/test');

expect(response.data).toEqual({ ok: 'ok' });
});

it('should apply the specific config in each request', async () => {
axiosMock.onGet('/base/test').reply(200, { ok: 'ok' });

const response = await networkClient.get('/test', { baseURL: '/base' });

expect(response.data).toEqual({ ok: 'ok' });
});

it('should attach the access token from the store when a request is made', async () => {
storeAccessToken('test-access');

Expand Down
6 changes: 6 additions & 0 deletions assets/js/state/channels.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const processChannelEvents = (reduxStore, socket) => {
'host_details_updated',
'heartbeat_succeded',
'heartbeat_failed',
'host_deregistered',
]);
registerEvents(reduxStore, socket, 'monitoring:clusters', [
'cluster_registered',
Expand All @@ -30,17 +31,22 @@ const processChannelEvents = (reduxStore, socket) => {
'checks_results_updated',
'cluster_health_changed',
'cluster_cib_last_written_updated',
'cluster_deregistered',
]);
registerEvents(reduxStore, socket, 'monitoring:sap_systems', [
'sap_system_registered',
'sap_system_health_changed',
'application_instance_registered',
'application_instance_deregistered',
'application_instance_health_changed',
'sap_system_deregistered',
'sap_system_updated',
]);
registerEvents(reduxStore, socket, 'monitoring:databases', [
'database_registered',
'database_health_changed',
'database_instance_registered',
'database_instance_deregistered',
'database_instance_health_changed',
'database_instance_system_replication_changed',
]);
Expand Down
6 changes: 6 additions & 0 deletions assets/js/state/clusters.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,14 @@ export const clustersListSlice = createSlice({
return cluster;
});
},
removeCluster: (state, { payload: { id } }) => {
state.clusters = state.clusters.filter((cluster) => cluster.id !== id);
},
},
});

export const CLUSTER_DEREGISTERED = 'CLUSTER_DEREGISTERED';

export const {
setClusters,
appendCluster,
Expand All @@ -110,6 +115,7 @@ export const {
updateCibLastWritten,
startClustersLoading,
stopClustersLoading,
removeCluster,
} = clustersListSlice.actions;

export default clustersListSlice.reducer;
Loading