Skip to content

Commit

Permalink
fixup! feat(nutanix): manage node resiliated
Browse files Browse the repository at this point in the history
Signed-off-by: Thibault Barske <[email protected]>
  • Loading branch information
tibs245 committed Feb 17, 2025
1 parent 56ea990 commit 6b7344c
Show file tree
Hide file tree
Showing 20 changed files with 342 additions and 24 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ playwright-helpers/config.ts
test-results
e2e-dist
coverage
.vscode
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const mock = jest.fn();
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const mock = jest.fn();
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
export const CLUSTER_RESPONSE_MOCK = {
serviceName: 'cluster-2116.nutanix.ovh.net',
allowedRedundancyFactor: [2],
availableVersions: ['6.10', '7.0'],
targetSpec: {
name: 'cluster-2116.nutanix.ovh.net',
version: '6.10',
prismCentral: { type: 'alone', vip: '172.16.1.100', ips: [] },
prismElementVip: '172.16.1.99',
prismSecretId: '00000000-0000-0000-0000-000000000000',
controlPanelURL: 'https://cluster-2116.nutanix.ovh.net:9440/',
erasureCoding: false,
redundancyFactor: 2,
nodes: [
{
server: 'ns31715911.ip-57-129-136.eu',
cvmIp: '172.16.1.1',
ahvIp: '172.16.0.1',
status: 'DEPLOYED',
possibleActions: [
{
action: 'INSTALL',
isPossible: false,
reason: '{{ node_already_installed }}',
},
{ action: 'REINSTALL', isPossible: true, reason: '' },
{
action: 'UNINSTALL',
isPossible: false,
reason: '{{ node_is_powered_on }}',
},
{
action: 'TERMINATE',
isPossible: false,
reason: '{{ node_not_uninstalled }}',
},
{
action: 'POWER_ON',
isPossible: false,
reason: '{{ node_is_powered_on }}',
},
{ action: 'POWER_OFF', isPossible: true, reason: '' },
],
},
{
server: 'ns31715909.ip-57-129-136.eu',
cvmIp: '172.16.1.2',
ahvIp: '172.16.0.2',
status: 'DEPLOYED',
possibleActions: [
{
action: 'INSTALL',
isPossible: false,
reason: '{{ node_already_installed }}',
},
{ action: 'REINSTALL', isPossible: true, reason: '' },
{
action: 'UNINSTALL',
isPossible: false,
reason: '{{ node_is_powered_on }}',
},
{
action: 'TERMINATE',
isPossible: false,
reason: '{{ node_not_uninstalled }}',
},
{
action: 'POWER_ON',
isPossible: false,
reason: '{{ node_is_powered_on }}',
},
{ action: 'POWER_OFF', isPossible: true, reason: '' },
],
},
{
server: 'ns31715910.ip-57-129-130.eu',
cvmIp: '172.16.1.3',
ahvIp: '172.16.0.3',
status: 'DEPLOYED',
possibleActions: [
{
action: 'INSTALL',
isPossible: false,
reason: '{{ node_already_installed }}',
},
{ action: 'REINSTALL', isPossible: true, reason: '' },
{
action: 'UNINSTALL',
isPossible: false,
reason: '{{ node_is_powered_on }}',
},
{
action: 'TERMINATE',
isPossible: false,
reason: '{{ node_not_uninstalled }}',
},
{
action: 'POWER_ON',
isPossible: false,
reason: '{{ node_is_powered_on }}',
},
{ action: 'POWER_OFF', isPossible: true, reason: '' },
],
},
],
vrack: 'pn-1206211',
gatewayCidr: '172.16.0.254/22',
ipfo: '51.77.126.52/30',
iplb: 'loadbalancer-080153d447748b49c172506ec59eed4a',
rackAwareness: false,
infraVlanNumber: 1,
},
status: 'Active',
iam: {
displayName: 'cluster-2116.nutanix.ovh.net',
id: '58711c09-296a-48da-9171-259628802423',
urn: 'urn:v1:eu:resource:nutanix:cluster-2116.nutanix.ovh.net',
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import '../../../../../../../modules/nutanix/src/dashboard/nodes/list/module.js';
import { CLUSTER_RESPONSE_MOCK } from './cluster.mock';
import Cluster from '../../../../../../../modules/nutanix/src/cluster.class';
import Node from '../../../../../../../modules/nutanix/src/node.class';
import { NODE_RESPONSE_MOCK } from './node.mock';

describe('ovhManagerNutanixAllNodes component tests suite', () => {
let $compile;
let $rootScope;

const mockCoreConfig = {
getUser: jest.fn().mockReturnValue({ ovhSubsidiary: 'FR' }),
};

angular.module('ovhManagerCore', []);
beforeEach(() => {
angular.mock.module(
'oui',
'pascalprecht.translate',
'ovhManagerNutanixAllNodes',
($provide) => {
$provide.value('coreConfig', mockCoreConfig);
},
);
});

beforeEach(() => {
angular.mock.inject([
'$compile',
'$rootScope',
'$componentController',
(_$compile_, _$rootScope_) => {
$compile = _$compile_;
$rootScope = _$rootScope_;
},
]);
});

function addComponentBindings(binding, { isNodeTerminated }) {
const cluster = new Cluster(CLUSTER_RESPONSE_MOCK);
const node = new Node({
...NODE_RESPONSE_MOCK,
...CLUSTER_RESPONSE_MOCK.targetSpec.nodes[0],
...(isNodeTerminated && { serviceStatus: 'suspended' }),
});

Object.assign(binding, {
serviceName: 'serviceName',
cluster,
nodes: [node],
powerOnNode: jest.fn(),
goToAddNode: jest.fn(),
powerOffNode: jest.fn(),
installNode: jest.fn(),
reinstallNode: jest.fn(),
uninstallNode: jest.fn(),
terminateNode: jest.fn(),
handleSuccess: jest.fn(),
handleError: jest.fn(),
});
}

it('should render the list of nodes', () => {
const $scope = $rootScope.$new();
addComponentBindings($scope, { isNodeTerminated: false });

const component = `
<nutanix-all-nodes
service-name="serviceName"
cluster="cluster"
nodes="nodes"
power-on-node="powerOnNode"
go-to-add-node="goToAddNode"
power-off-node="powerOffNode"
install-node="installNode"
reinstall-node="reinstallNode"
uninstall-node="uninstallNode"
terminate-node="terminateNode"
handle-success="handleSuccess"
handle-error="handleError"
></nutanix-all-nodes>
`;
const element = $compile(component)($scope);
$scope.$digest();
const html = element.html();

expect(html).toContain('<oui-datagrid ');
expect(html).toContain('node-action-menu ');
expect(html).not.toContain('node-action-menu-terminated ');
});

it('should render the list of nodes with terminated action', () => {
const $scope = $rootScope.$new();
addComponentBindings($scope, { isNodeTerminated: true });

const component = `
<nutanix-all-nodes
service-name="serviceName"
cluster="cluster"
nodes="nodes"
power-on-node="powerOnNode"
go-to-add-node="goToAddNode"
power-off-node="powerOffNode"
install-node="installNode"
reinstall-node="reinstallNode"
uninstall-node="uninstallNode"
terminate-node="terminateNode"
handle-success="handleSuccess"
handle-error="handleError"
></nutanix-all-nodes>
`;
const element = $compile(component)($scope);
$scope.$digest();
const html = element.html();

expect(html).toContain('<oui-datagrid ');
expect(html).not.toContain('node-action-menu ');
expect(html).toContain('node-action-menu-terminated ');
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
export const NODE_RESPONSE_MOCK = {
expiration: '2025-03-01T00:00:00.000Z',
netbootLabel: 'hd - Boot to disk',
order: [
'failoverIP',
'kvm',
'ip',
'backupStorage',
'ipMigration',
'supportLevel',
],
canOrder: true,
canOrderBandwith: false,
canOrderVrackBandwith: false,
canOrderUsbDisk: false,
canOrderQuota: false,
canResiliateBandwidth: true,
canResiliateVrackBandwidth: true,
engagement: null,
availableProfessionalUse: false,
hasProfessionalUse: false,
commercialRange: 'Scale-i2',
isExpired: false,
isCachecade: false,
raidController: false,
typeDisk: 'NVME',
nbPhysicalDisk: 2,
diskSize: 1030792,
nbDisk: 2,
totalSize: 2061584,
otherDisk: [{ typeDisk: 'NVME', nbDisk: 4, sizeDisk: 2061584 }],
ipv6: '2001:41d0:809:e900::/56',
description: 'Scale-i2',
state: 'OK',
diskGroups: [
{
defaultHardwareRaidSize: null,
raidController: null,
description: '2 X Disk NVME 960 GB, JBOD',
diskType: 'NVME',
diskSize: { value: 960, unit: 'GB' },
defaultHardwareRaidType: null,
numberOfDisks: 2,
diskGroupId: 1,
},
{
diskType: 'NVME',
defaultHardwareRaidType: null,
numberOfDisks: 4,
diskSize: { value: 1920, unit: 'GB' },
diskGroupId: 2,
defaultHardwareRaidSize: null,
description: '4 X Disk NVME 1920 GB, JBOD',
raidController: null,
},
],
ip: '57.129.130.233',
os: 'Nutanix AOS 6.10 (single node)',
reverse: 'ns31715910.ip-57-129-130.eu',
datacenter: 'ERI_1',
rack: 'ERI0111D04B',
bootId: 1,
serverId: 1758538,
monitored: false,
rootDevice: null,
name: 'ns31715910.ip-57-129-130.eu',
displayName: 'ERI - cluster-2116.nutanix.ovh.net - node1',
serviceId: 130073469,
canTakeRendezVous: false,
shouldReengage: null,
noIntervention: false,
region: 'eu-west-eri',
availabilityZone: 'eu-west-eri-a',
iam: {
displayName: 'ERI - cluster-2116.nutanix.ovh.net - node1',
id: '8eeafeeb-c117-466c-910e-6bda27e75327',
urn: 'urn:v1:eu:resource:dedicatedServer:ns31715910.ip-57-129-130.eu',
},
newUpgradeSystem: true,
powerState: 'poweron',
serviceStatus: 'active',
};
2 changes: 2 additions & 0 deletions packages/manager/apps/dedicated/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ module.exports = {
},
moduleNameMapper: {
'\\.(css|scss|png|less)$': 'identity-obj-proxy',
'^@ovh-ux/manager-components$':
'<rootDir>/../../modules/manager-components/src/index.js',
'^@ovh-ux/manager-(.*)$': '<rootDir>/../../modules/$1/src/index.js',
'^@ovh-ux/ng-(.*)$': '<rootDir>/../../../components/ng-$1/src/index.js',
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,11 @@ import '@ovh-ux/ui-kit';

import component from './component';

const moduleName = 'ovhManagerNutanixNodeActionMenuResiliated';
const moduleName = 'ovhManagerNutanixNodeActionMenuTerminated';

angular
.module(moduleName, [
'oui',
'ovhManagerCore',
'pascalprecht.translate',
'ui.router',
])
.component('nodeActionMenuResiliated', component)
.module(moduleName, ['oui', 'pascalprecht.translate', 'ui.router'])
.component('nodeActionMenuTerminated', component)
.run(/* @ngTranslationsInject:json ./translations */);

export default moduleName;
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ export default class NutanixGeneralInfoCtrl {

$onInit() {
this.loadServicesDetails();
this.loadNodesStatus();
this.setPrivateBandwidthServiceId();
this.clusterRedeploying = this.cluster.status === CLUSTER_STATUS.DEPLOYING;
this.showRedeployWarningModal = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@ import {

export default class NutanixAllNodesCtrl {
/* @ngInject */
constructor(NutanixService, ovhManagerRegionService, $translate) {
this.ovhManagerRegionService = ovhManagerRegionService;
constructor($translate) {
this.$translate = $translate;
this.NutanixService = NutanixService;
this.nodesMapped = [];
this.SERVICE_STATES = SERVICE_STATES;
}
Expand Down
Loading

0 comments on commit 6b7344c

Please sign in to comment.