diff --git a/BACKEND/app/services/line_connection.ts b/BACKEND/app/services/line_connection.ts
index 8b98131..bf0b1de 100644
--- a/BACKEND/app/services/line_connection.ts
+++ b/BACKEND/app/services/line_connection.ts
@@ -1225,18 +1225,18 @@ export default class LineConnection {
const timeZone = process.env.TIME_ZONE || 'Australia/Sydney'
const dataFormat = momentTZ().tz(timeZone).format('YYYY/MM/DD, HH:mm:ss')
const body = `
- Load IOS Report
+ Load License Report
────────────────────────────────
Station : ${this.config.stationName}
Line : ${this.config.lineNumber}
- License : ${nameLicense}
+ License : ${nameLicense}
Started At : ${startTime}
Finished At : ${dataFormat}
────────────────────────────────
`.trim()
await sendMessageToMail(
- `[ATC] - [${this.config.stationName} - Line: ${this.config.lineNumber}] - Load IOS Report`,
+ `[ATC] - [${this.config.stationName} - Line: ${this.config.lineNumber}] - Load License Report`,
body
)
}
@@ -1370,7 +1370,7 @@ export default class LineConnection {
* Handle load License for switch
* Assumes traditional licensing (PAK/file-based) via TFTP
*/
- async loadLicenseSwitch(licenseFileName: string, userName: string) {
+ async loadLicenseSwitch(licenseFileName: string, userName: string, portName: string) {
const station = await Station.find(this.config.stationId)
if (!station) return
@@ -1384,21 +1384,22 @@ export default class LineConnection {
const startTime = momentTZ().tz(timeZone).format('YYYY/MM/DD, HH:mm:ss')
const body = buildBody(
- 'ROUTER_IOS',
+ 'SWITCH_LICENSE',
tftpIp,
licenseFileName,
`${a}.${b}.100.${this.config.id < 254 ? this.config.id : 254 - this.config.id}`,
`${station?.gateway ? station?.gateway : '0.0.0.0'}`,
- this.listDeviceIos
+ this.listDeviceIos,
+ portName
)
const script = {
- id: 0, // Hoặc ID khác tuỳ logic DB
- isReboot: true, // License thường cần reboot
+ id: 0,
+ isReboot: false,
sendResult: false,
send_result: false,
title: 'Load License Switch',
- timeout: 1000, // Tăng timeout nếu cần vì lệnh install có thể lâu
+ timeout: 1000,
body: JSON.stringify(body),
}
@@ -1409,7 +1410,7 @@ export default class LineConnection {
/**
* Handle load License for Router
*/
- async loadLicenseRouter(licenseFileName: string, userName: string) {
+ async loadLicenseRouter(licenseFileName: string, userName: string, portName: string) {
const station = await Station.find(this.config.stationId)
if (!station) return
@@ -1417,24 +1418,22 @@ export default class LineConnection {
const tftpIp = station?.tftp_ip || '172.16.7.69'
const [a, b] = network.split('.').map(Number)
- // Tên Interface dùng để load (Cần sửa nếu router dùng 0/0/0 hoặc tên khác)
- const mgmtInterface = 'GigabitEthernet0/0'
-
const timeZone = process.env.TIME_ZONE || 'Australia/Sydney'
const startTime = momentTZ().tz(timeZone).format('YYYY/MM/DD, HH:mm:ss')
const body = buildBody(
- 'ROUTER_IOS',
+ 'ROUTER_LICENSE',
tftpIp,
licenseFileName,
`${a}.${b}.100.${this.config.id < 254 ? this.config.id : 254 - this.config.id}`,
`${station?.gateway ? station?.gateway : '0.0.0.0'}`,
- this.listDeviceIos
+ this.listDeviceIos,
+ portName
)
const script = {
id: 0,
- isReboot: true,
+ isReboot: false,
sendResult: false,
send_result: false,
title: 'Load License Router',
diff --git a/BACKEND/app/ultils/helper.ts b/BACKEND/app/ultils/helper.ts
index 9aee0c6..fc56b93 100644
--- a/BACKEND/app/ultils/helper.ts
+++ b/BACKEND/app/ultils/helper.ts
@@ -684,7 +684,8 @@ export function buildBody(
fileName: string,
address: string,
gateway: string,
- listDeviceIos: string[]
+ listDeviceIos: string[],
+ portName?: string
) {
switch (type) {
/* ================= ROUTER LOAD IOS ================= */
@@ -769,7 +770,14 @@ export function buildBody(
},
{
expect: '#',
- send: `show inventory`,
+ send: `show license`,
+ delay: '1',
+ repeat: '1',
+ note: 'Verify license status',
+ },
+ {
+ expect: '#',
+ send: ` show inventory`,
delay: '1',
repeat: '1',
note: '',
@@ -989,7 +997,7 @@ export function buildBody(
},
{
expect: '#',
- send: `show version`,
+ send: ` show version`,
delay: '1',
repeat: '1',
note: 'Verify version info',
@@ -1022,7 +1030,7 @@ export function buildBody(
},
{
expect: '#',
- send: `interface vlan 1`,
+ send: `interface ${portName ? portName : 'vlan 1'}`,
delay: '1',
repeat: '1',
note: 'Select Interface Vlan 1',
@@ -1062,6 +1070,13 @@ export function buildBody(
repeat: '1',
note: 'End config',
},
+ {
+ expect: '',
+ send: ``,
+ delay: '1',
+ repeat: '1',
+ note: '',
+ },
{
expect: '#',
send: `license install tftp://${tftpIp}/License/${fileName}`,
@@ -1069,6 +1084,13 @@ export function buildBody(
repeat: '1',
note: 'Install license',
},
+ {
+ expect: '',
+ send: ``,
+ delay: '1',
+ repeat: '1',
+ note: '',
+ },
{
expect: '#',
send: `write memory`,
@@ -1076,6 +1098,13 @@ export function buildBody(
repeat: '1',
note: 'Save config',
},
+ {
+ expect: '',
+ send: ``,
+ delay: '1',
+ repeat: '1',
+ note: '',
+ },
{
expect: '#',
send: `reload`,
@@ -1129,7 +1158,7 @@ export function buildBody(
},
{
expect: '#',
- send: `show version`,
+ send: ` show version`,
delay: '1',
repeat: '1',
note: 'Verify version info',
@@ -1162,7 +1191,7 @@ export function buildBody(
},
{
expect: '#',
- send: `interface GigabitEthernet0/0`,
+ send: `interface ${portName ? portName : 'GigabitEthernet0/0'}`,
delay: '1',
repeat: '1',
note: 'Select management interface',
@@ -1202,6 +1231,13 @@ export function buildBody(
repeat: '1',
note: 'End config',
},
+ {
+ expect: '',
+ send: ``,
+ delay: '1',
+ repeat: '1',
+ note: '',
+ },
{
expect: '#',
send: `license install tftp://${tftpIp}/License/${fileName}`,
@@ -1209,6 +1245,13 @@ export function buildBody(
repeat: '1',
note: 'Install license',
},
+ {
+ expect: '',
+ send: ``,
+ delay: '1',
+ repeat: '1',
+ note: '',
+ },
{
expect: '#',
send: `write memory`,
@@ -1216,6 +1259,13 @@ export function buildBody(
repeat: '1',
note: 'Save config',
},
+ {
+ expect: '',
+ send: ``,
+ delay: '1',
+ repeat: '1',
+ note: '',
+ },
{
expect: '#',
send: `reload`,
@@ -1224,8 +1274,8 @@ export function buildBody(
note: 'Reload router',
},
{
- expect: '', // Router thường hỏi câu này
- send: ``, // Enter confirm
+ expect: '',
+ send: ``,
delay: '1',
repeat: '1',
note: 'Confirm reload',
@@ -1269,7 +1319,7 @@ export function buildBody(
},
{
expect: '#',
- send: `show version`,
+ send: ` show version`,
delay: '1',
repeat: '1',
note: 'Verify version info',
diff --git a/BACKEND/providers/socket_io_provider.ts b/BACKEND/providers/socket_io_provider.ts
index 1da7b13..0d8f71a 100644
--- a/BACKEND/providers/socket_io_provider.ts
+++ b/BACKEND/providers/socket_io_provider.ts
@@ -705,6 +705,32 @@ export class WebSocketIo {
{}
)
})
+
+ socket.on('load_license_router', async (data) => {
+ const { stationId, lineId, licenseName, portName } = data
+ await this.handleLineOperation(
+ io,
+ stationId,
+ [lineId],
+ async (lineCon) => {
+ lineCon.loadLicenseRouter(licenseName, userName, portName)
+ },
+ {}
+ )
+ })
+
+ socket.on('load_license_switch', async (data) => {
+ const { stationId, lineId, licenseName, portName } = data
+ await this.handleLineOperation(
+ io,
+ stationId,
+ [lineId],
+ async (lineCon) => {
+ lineCon.loadLicenseSwitch(licenseName, userName, portName)
+ },
+ {}
+ )
+ })
})
socketServer.listen(SOCKET_IO_PORT, () => {
diff --git a/FRONTEND/src/components/FormAddEdit.tsx b/FRONTEND/src/components/FormAddEdit.tsx
index 757e0c3..e6ac87f 100644
--- a/FRONTEND/src/components/FormAddEdit.tsx
+++ b/FRONTEND/src/components/FormAddEdit.tsx
@@ -82,6 +82,7 @@ const StationSetting = ({
form.setFieldValue("apc_2_password", dataStation.apc_2_password);
form.setFieldValue("switch_control_ip", dataStation.switch_control_ip);
form.setFieldValue("send_wiki", dataStation?.send_wiki);
+ // form.setFieldValue("is_active", dataStation?.is_active);
form.setFieldValue(
"switch_control_port",
dataStation.switch_control_port
@@ -402,6 +403,16 @@ const StationSetting = ({
form.setFieldValue("send_wiki", event.currentTarget.checked)
}
/>
+ {/*
+ form.setFieldValue("is_active", event.currentTarget.checked)
+ }
+ /> */}
}
size={"90%"}
diff --git a/FRONTEND/src/components/Modal/ModalSelectLicense.tsx b/FRONTEND/src/components/Modal/ModalSelectLicense.tsx
index 00b7283..05d7866 100644
--- a/FRONTEND/src/components/Modal/ModalSelectLicense.tsx
+++ b/FRONTEND/src/components/Modal/ModalSelectLicense.tsx
@@ -4,6 +4,7 @@ import {
Modal,
ScrollArea,
Table,
+ Tabs,
Text,
TextInput,
} from "@mantine/core";
@@ -28,6 +29,9 @@ const ModalSelectLicense = ({
line: TLine | undefined;
}) => {
const [inputSearch, setInputSearch] = useState("");
+ const [inputPort, setInputPort] = useState("GigabitEthernet0/0");
+ const [licenseName, setLicenseName] = useState("");
+ const [modalConfirm, setModalConfirm] = useState(false);
const filterLicense = () => {
return listLicense.filter((ios) =>
@@ -103,9 +107,9 @@ const ModalSelectLicense = ({
- {filterLicense()?.map((ios, i) => (
+ {filterLicense()?.map((lic, i) => (
- {ios || ""}
+ {lic || ""}
}
onClick={() => {
- socket?.emit("load_ios_switch", {
- stationId: Number(station?.id),
- lineId: Number(line?.id),
- iosName: ios,
- });
- close();
+ // socket?.emit("load_ios_switch", {
+ // stationId: Number(station?.id),
+ // lineId: Number(line?.id),
+ // iosName: ios,
+ // });
+ // close();
+ setLicenseName(lic);
+ setModalConfirm(true);
}}
>
Run
@@ -134,6 +140,144 @@ const ModalSelectLicense = ({
+
+ {
+ setModalConfirm(false);
+ setLicenseName("");
+ setInputPort("GigabitEthernet0/0");
+ }}
+ title={
+
+ Confirm
+
+ }
+ size="lg"
+ >
+
+
+ {licenseName}
+
+
+
+
+ {
+ setInputPort("GigabitEthernet0/0");
+ }}
+ >
+ Router
+
+ {
+ setInputPort("vlan 1");
+ }}
+ >
+ Switch
+
+
+
+
+ setInputPort(event.currentTarget.value)}
+ rightSection={
+ inputPort ? (
+ setInputPort("")}
+ />
+ ) : null
+ }
+ rightSectionPointerEvents="auto"
+ size="md"
+ />
+
+
+ }
+ onClick={() => {
+ socket?.emit("load_license_router", {
+ stationId: Number(station?.id),
+ lineId: Number(line?.id),
+ licenseName: licenseName,
+ portName: inputPort,
+ });
+ setModalConfirm(false);
+ setLicenseName("");
+ setInputPort("GigabitEthernet0/0");
+ close();
+ }}
+ >
+ Run
+
+
+
+
+
+ setInputPort(event.currentTarget.value)}
+ rightSection={
+ inputPort ? (
+ setInputPort("")}
+ />
+ ) : null
+ }
+ rightSectionPointerEvents="auto"
+ size="md"
+ />
+
+
+ }
+ onClick={() => {
+ socket?.emit("load_license_switch", {
+ stationId: Number(station?.id),
+ lineId: Number(line?.id),
+ licenseName: licenseName,
+ portName: inputPort,
+ });
+ setModalConfirm(false);
+ setLicenseName("");
+ setInputPort("GigabitEthernet0/0");
+ close();
+ }}
+ >
+ Run
+
+
+
+
+
);
};