Files
ITAM-test/scratch/update_dummy_servers.js

443 lines
18 KiB
JavaScript

import pkg from 'xlsx';
import * as fs from 'fs';
import * as path from 'path';
const { readFile, utils } = pkg;
const randomId = () => Math.random().toString(36).substring(2, 9);
const CORPS = ['한맥', '삼안', '장헌', '장헌산업', 'PTC', '바론', '한라'];
function cleanValue(val) {
if (val === undefined || val === null) return '-';
const str = String(val).trim();
return str === '' ? '-' : str;
}
try {
// 1. 기존 dummyPCs 로딩
const dummyDataPath = 'c:/Project/HM ITAM/src/core/dummyData.ts';
const content = fs.readFileSync(dummyDataPath, 'utf-8');
const matchPCs = content.match(/export const dummyPCs: any\[\] = (\[[\s\S]*?\]);/);
if (!matchPCs) {
console.error('Failed to parse dummyPCs from dummyData.ts');
process.exit(1);
}
const dummyPCs = JSON.parse(matchPCs[1]);
console.log(`Loaded ${dummyPCs.length} existing PCs from dummyData.ts`);
// 2. SampleData_SVR.xlsx 파싱
const workbook = readFile('c:/Project/HM ITAM/SampleData_SVR.xlsx');
const parsedServers = [];
const parsedStorages = [];
const parsedEquips = [];
let serverIndex = 0;
let storageIndex = 0;
let equipIndex = 0;
// ----------------- 시트 1: 합본데이터(공용PC) -----------------
const sheetPC = workbook.Sheets['합본데이터(공용PC)'];
const rawPC = utils.sheet_to_json(sheetPC, { header: 1 });
const rowsPC = rawPC.slice(1).filter(row => row.some(val => val !== undefined && val !== null && String(val).trim() !== ''));
for (const row of rowsPC) {
const teamRaw = cleanValue(row[0]);
const svrNoRaw = cleanValue(row[1]);
const assetNameRaw = cleanValue(row[2]);
const typeRaw = cleanValue(row[3]);
const detailRaw = cleanValue(row[4]);
const locRaw = cleanValue(row[5]);
const mgr1Raw = cleanValue(row[6]);
const mgr2Raw = cleanValue(row[7]);
const osRaw = cleanValue(row[8]);
const osVerRaw = cleanValue(row[9]);
const osBuildRaw = cleanValue(row[10]);
const modelRaw = cleanValue(row[11]);
const mainboardRaw = cleanValue(row[12]);
const cpuRaw = cleanValue(row[13]);
const ramRaw = cleanValue(row[14]);
const gpuRaw = cleanValue(row[15]);
const ssd1Raw = cleanValue(row[16]);
const ssd2Raw = cleanValue(row[17]);
const hdd1Raw = cleanValue(row[18]);
const hdd2Raw = cleanValue(row[19]);
const hdd3Raw = cleanValue(row[20]);
const hdd4Raw = cleanValue(row[21]);
const ipAddress = '172.16.10.' + (50 + (serverIndex % 150));
const randomCorp = CORPS[serverIndex % CORPS.length];
// 서비스 분류 판단
let service_type = '내부서비스';
const detailUpper = detailRaw.toUpperCase();
const assetUpper = assetNameRaw.toUpperCase();
const teamUpper = teamRaw.toUpperCase();
if (teamUpper.includes('회의실') || assetUpper.includes('회의실') || assetUpper.includes('사이니지')) {
service_type = '회의용/공용';
} else if (
detailUpper.includes('SAAS') || detailUpper.includes('웹서비스') ||
detailUpper.includes('운영') || detailUpper.includes('WAS') ||
detailUpper.includes('MYSTATION') || detailUpper.includes('CLOUD') ||
detailUpper.includes('홈페이지') || detailUpper.includes('WEB') ||
detailUpper.includes('외주') || assetUpper.includes('CLOUD') ||
assetUpper.includes('웹서비스') || assetUpper.includes('운영')
) {
service_type = '외부서비스';
}
// 방치 의심 판단
const is_inactive = (
detailUpper.includes('원격 및 로컬접근 불가') ||
detailUpper.includes('철수예정') ||
detailUpper.includes('미사용') ||
detailUpper.includes('구형 OS')
);
// 실시간 리소스 및 네트워크 가상 데이터 생성
let cpu_usage = 0;
let ram_usage = 0;
let network_traffic = '0 GB';
if (is_inactive) {
cpu_usage = 0;
ram_usage = 0;
network_traffic = '0 GB (N/A)';
} else if (service_type === '회의용/공용') {
cpu_usage = Math.floor(Math.random() * 10) + 2; // 2%~12%
ram_usage = Math.floor(Math.random() * 15) + 5; // 5%~20%
network_traffic = (Math.random() * 1.5 + 0.1).toFixed(1) + ' GB';
} else if (service_type === '외부서비스') {
// 일부 저사양 운영/SaaS 서버는 병목 현상을 시뮬레이션하기 위해 과부하 부여
const isUnderSpec = !gpuRaw.toUpperCase().includes('RTX 30') && !gpuRaw.toUpperCase().includes('RTX 40') && (cpuRaw.toUpperCase().includes('I5') || ramRaw.toUpperCase().includes('16GB') || cpuRaw === '-');
if (isUnderSpec) {
cpu_usage = Math.floor(Math.random() * 15) + 81; // 81%~95% (과부하)
ram_usage = Math.floor(Math.random() * 10) + 86; // 86%~95%
} else {
cpu_usage = Math.floor(Math.random() * 30) + 40; // 40%~70%
ram_usage = Math.floor(Math.random() * 20) + 60; // 60%~80%
}
network_traffic = (Math.random() * 1500 + 300).toFixed(0) + ' GB';
} else { // 내부서비스
// Abaqus 해석용이나 Pix4D 등 고부하 내부 인프라도 부하율 높게 부여
const isHighLoad = detailUpper.includes('ABAQUS') || detailUpper.includes('PIX4D') || detailUpper.includes('영상 렌더링') || detailUpper.includes('TERRA');
if (isHighLoad) {
cpu_usage = Math.floor(Math.random() * 20) + 70; // 70%~90%
ram_usage = Math.floor(Math.random() * 20) + 75; // 75%~95%
} else {
cpu_usage = Math.floor(Math.random() * 35) + 15; // 15%~50%
ram_usage = Math.floor(Math.random() * 30) + 20; // 20%~50%
}
network_traffic = (Math.random() * 300 + 10).toFixed(0) + ' GB';
}
const assetItem = {
id: randomId(),
asset_type: typeRaw !== '-' ? typeRaw : '공용PC',
purchase_corp: randomCorp,
asset_code: 'SVR-24' + String(serverIndex).padStart(3, '0'),
purchase_date: '2023-03',
asset_purpose: detailRaw,
current_dept: teamRaw,
previous_dept: '-',
location: locRaw,
manager_primary: mgr1Raw,
manager_secondary: mgr2Raw,
ip_address: ipAddress,
remote_tool: 'RDP / VNC',
model_name: modelRaw !== '-' ? modelRaw : (mainboardRaw !== '-' ? mainboardRaw : '사내 표준 공용PC'),
os: osRaw !== '-' ? `${osRaw} (${osVerRaw})` : 'Windows 10',
cpu: cpuRaw,
ram: ramRaw,
gpu: gpuRaw,
ssd_1: ssd1Raw,
ssd_2: ssd2Raw,
hdd_1: hdd1Raw,
hdd_2: hdd2Raw,
hdd_3: hdd3Raw,
hdd_4: hdd4Raw,
monitoring: service_type === '외부서비스' ? '대상' : '비대상',
purchase_amount: gpuRaw.toUpperCase().includes('RTX 4080') || gpuRaw.toUpperCase().includes('RTX 3090') ? '3500000' : '1500000',
purchase_vendor: '다나와',
approval_document: '2023_공용PC_도입_' + serverIndex,
memo: is_inactive ? '방치 의심 장비 (회수 필요)' : '정상 운영 장비',
asset_name: assetNameRaw,
mac_address: `00:1A:2B:3C:5E:${serverIndex.toString(16).toUpperCase().padStart(2, '0')}`,
hw_status: is_inactive ? '수리/대기' : '운영중',
service_type: service_type,
is_inactive: is_inactive,
cpu_usage: cpu_usage,
ram_usage: ram_usage,
network_traffic: network_traffic
};
// 스토리지로 보낼 자산들 (유형이 NAS/DAS이거나 자산명에 NAS가 들어가면)
if (typeRaw.toUpperCase().includes('NAS') || typeRaw.toUpperCase().includes('DAS') || assetUpper.includes('NAS') || assetUpper.includes('DAS')) {
assetItem.asset_code = 'STO-24' + String(storageIndex).padStart(3, '0');
assetItem.volume = hdd1Raw !== '-' ? hdd1Raw : '10TB';
parsedStorages.push(assetItem);
storageIndex++;
} else {
parsedServers.push(assetItem);
serverIndex++;
}
}
// ----------------- 시트 2: 합본데이터(NAS) -----------------
const sheetNAS = workbook.Sheets['합본데이터(NAS)'];
const rawNAS = utils.sheet_to_json(sheetNAS, { header: 1 });
const rowsNAS = rawNAS.slice(1).filter(row => row.some(val => val !== undefined && val !== null && String(val).trim() !== ''));
for (const row of rowsNAS) {
const teamRaw = cleanValue(row[0]);
const svrNoRaw = cleanValue(row[1]);
const assetNameRaw = cleanValue(row[2]);
const typeRaw = cleanValue(row[3]);
const detailRaw = cleanValue(row[4]);
const locRaw = cleanValue(row[5]);
const mgr1Raw = cleanValue(row[6]);
const mgr2Raw = cleanValue(row[7]);
const toolRaw = cleanValue(row[8]);
const ipRaw = cleanValue(row[9]);
const ip2Raw = cleanValue(row[10]);
const idRaw = cleanValue(row[11]);
const pwRaw = cleanValue(row[12]);
const osRaw = cleanValue(row[15]);
const osVerRaw = cleanValue(row[16]);
const osBuildRaw = cleanValue(row[17]);
const modelRaw = cleanValue(row[18]);
const cpuRaw = cleanValue(row[19]);
const ramRaw = cleanValue(row[20]);
const gpuRaw = cleanValue(row[21]);
const ssd1Raw = cleanValue(row[22]);
const ssd2Raw = cleanValue(row[23]);
const hdd1Raw = cleanValue(row[24]);
const hdd2Raw = cleanValue(row[25]);
const hdd3Raw = cleanValue(row[26]);
const hdd4Raw = cleanValue(row[27]);
const randomCorp = CORPS[storageIndex % CORPS.length];
// NAS는 기본적으로 내부 백업/공유용 인프라
const service_type = '내부서비스';
const is_inactive = false;
// NAS 실시간 리소스 가상 데이터
const cpu_usage = Math.floor(Math.random() * 25) + 15; // 15%~40%
const ram_usage = Math.floor(Math.random() * 35) + 30; // 30%~65%
const network_traffic = (Math.random() * 600 + 50).toFixed(0) + ' GB';
const assetItem = {
id: randomId(),
asset_type: typeRaw !== '-' ? typeRaw : '공용 NAS',
purchase_corp: randomCorp,
asset_code: 'STO-24' + String(storageIndex).padStart(3, '0'),
purchase_date: '2022-08',
asset_purpose: detailRaw,
current_dept: teamRaw !== '-' ? teamRaw : '디자인팀',
previous_dept: '-',
location: locRaw,
manager_primary: mgr1Raw,
manager_secondary: mgr2Raw,
ip_address: ipRaw !== '-' ? ipRaw : '172.16.42.' + (100 + storageIndex),
remote_tool: toolRaw !== '-' ? toolRaw : 'Web GUI',
model_name: modelRaw !== '-' ? modelRaw : 'Synology 공용 NAS',
os: osRaw !== '-' ? `${osRaw} ${osVerRaw}` : 'DSM 7.x',
cpu: cpuRaw,
ram: ramRaw,
gpu: gpuRaw,
ssd_1: ssd1Raw,
ssd_2: ssd2Raw,
hdd_1: hdd1Raw,
hdd_2: hdd2Raw,
hdd_3: hdd3Raw,
hdd_4: hdd4Raw,
monitoring: '비대상',
purchase_amount: '4500000',
purchase_vendor: '시놀로지 총판',
approval_document: '2022_스토리지_도입_' + storageIndex,
memo: '스토리지 서버 공유 자산',
asset_name: assetNameRaw,
mac_address: `00:1A:2B:3C:5F:${storageIndex.toString(16).toUpperCase().padStart(2, '0')}`,
hw_status: '운영중',
service_type: service_type,
is_inactive: is_inactive,
volume: hdd1Raw !== '-' ? hdd1Raw : '24TB',
cpu_usage: cpu_usage,
ram_usage: ram_usage,
network_traffic: network_traffic
};
parsedStorages.push(assetItem);
storageIndex++;
}
console.log(`Parsed Servers: ${parsedServers.length} units`);
console.log(`Parsed Storages: ${parsedStorages.length} units`);
// 3. 파일 다시 쓰기
const newDummyDataFileContent = `import { HardwareAsset, SoftwareAsset, SWUser, HardwareLog } from './excelHandler';
// 유틸리티: 랜덤 문자열
const randomId = () => Math.random().toString(36).substring(2, 9);
// 유틸리티: 랜덤 년월 (YYYY-MM) (최근 10년)
const randomPurchaseYM = () => {
const currentYear = new Date().getFullYear();
const year = currentYear - Math.floor(Math.random() * 10);
const month = String(Math.floor(Math.random() * 12) + 1).padStart(2, '0');
return \`\${year}-\${month}\`;
};
// 유틸리티: 랜덤 YYYY-MM-DD
const randomDateStr = (maxYearsAgo = 10) => {
const currentYear = new Date().getFullYear();
const year = currentYear - Math.floor(Math.random() * maxYearsAgo);
const month = String(Math.floor(Math.random() * 12) + 1).padStart(2, '0');
const day = String(Math.floor(Math.random() * 28) + 1).padStart(2, '0');
return \`\${year}-\${month}-\${day}\`;
};
const CORPS = ['한맥', '삼안', '장헌', '장헌산업', 'PTC', '바론', '한라'];
const getRandomCorp = () => CORPS[Math.floor(Math.random() * CORPS.length)];
// ────────────────────────────────────────────────────────
// 1. SampleData_PC.xlsx 에서 파싱된 PC 데이터 주입
// ────────────────────────────────────────────────────────
export const dummyPCs: any[] = ${JSON.stringify(dummyPCs, null, 2)};
// ────────────────────────────────────────────────────────
// 2. 기타 자산 더미 데이터 (서버, 스토리지, 소프트웨어 등 - 엑셀 파싱 연동)
// ────────────────────────────────────────────────────────
export const dummyServers: any[] = ${JSON.stringify(parsedServers, null, 2)};
export const dummyStorages: any[] = ${JSON.stringify(parsedStorages, null, 2)};
export const dummyEquips: any[] = Array.from({ length: 12 }).map((_, i) => ({
id: randomId(),
asset_type: '전산비품',
purchase_corp: getRandomCorp(),
asset_code: \`EQ-24\${String(i).padStart(3, '0')}\`,
asset_name: \`네트워크 스위치 \${i+1}\`,
location: '전산실 랙 1',
manager_primary: '네트워크담당자',
ip_address: \`192.168.10.\${200 + i}\`,
mac_address: \`00:1A:2B:3C:51:\${String(i).padStart(2, '0')}\`,
os: 'Cisco IOS',
purchase_date: randomPurchaseYM(),
purchase_amount: '150000',
purchase_vendor: '다나와',
approval_document: \`2024_비품구매_\${i}\`,
memo: '사내망 확장용',
asset_purpose: '네트워크 분배'
}));
export const dummyMobiles: any[] = Array.from({ length: 15 }).map((_, i) => ({
id: randomId(),
asset_type: '모바일기기',
purchase_corp: getRandomCorp(),
asset_code: \`MOB-24\${String(i).padStart(3, '0')}\`,
asset_name: \`테스트용 단말기 \${i+1}\`,
location: '개발2팀',
manager_primary: '테스터',
os: i % 2 === 0 ? 'Android 14' : 'iOS 17',
purchase_date: randomPurchaseYM(),
purchase_amount: '900000',
purchase_vendor: '삼성전자/애플',
approval_document: \`2024_모바일구매_\${i}\`,
memo: '앱 호환성 테스트 전용',
asset_purpose: 'QA 테스트',
ip_address: \`192.168.1.\${10 + i}\`,
mac_address: \`00:1A:2B:3C:50:\${String(i).padStart(2, '0')}\`
}));
export const dummySubSw: any[] = Array.from({ length: 10 }).map((_, i) => ({
id: randomId(),
sw_type: '구독SW',
sw_field: '업무용/협업',
purchase_corp: getRandomCorp(),
current_dept: '전사',
product_name: \`Microsoft 365 E\${3 + (i%2)}\`,
purchase_date: randomDateStr(3),
start_date: randomDateStr(1),
expired_date: randomDateStr(0),
purchase_amount: '150000',
asset_count: 50 + i * 5,
email_account: \`admin\${i}@hmcorp.com\`,
purchase_vendor: '소프트웨어인라이프',
memo: '연간 계약 갱신 필요'
}));
export const dummyPermSw: any[] = Array.from({ length: 5 }).map((_, i) => ({
id: randomId(),
sw_type: '영구SW',
sw_field: '디자인/설계',
purchase_corp: getRandomCorp(),
current_dept: '디자인팀',
product_name: \`AutoCAD 202\${i%4}\`,
purchase_date: randomDateStr(5),
start_date: randomDateStr(5),
expired_date: '2099-12-31',
purchase_amount: '3000000',
asset_count: 2,
email_account: \`design\${i}@hmcorp.com\`,
purchase_vendor: '오토데스크 파트너',
memo: 'USB 동글키 보관중'
}));
export const dummyCloud: any[] = Array.from({ length: 5 }).map((_, i) => ({
id: randomId(),
sw_type: '클라우드',
asset_mfr: i % 2 === 0 ? 'AWS' : 'GCP',
purchase_corp: getRandomCorp(),
current_dept: '개발팀',
product_name: \`컴퓨팅 인스턴스 Type \${i}\`,
email_account: \`awsadmin\${i}@hmcorp.com\`,
purchase_method: '법인카드(신한 1234)',
purchase_amount: \`\${500000 + i * 100000}\`,
asset_count: 1,
purchase_vendor: 'AWS/GCP',
memo: '환율 변동에 따라 매월 상이함'
}));
export const dummyDomain: any[] = Array.from({ length: 5 }).map((_, i) => ({
id: randomId(),
asset_type: '도메인',
purchase_corp: getRandomCorp(),
product_name: \`사내 운영 서비스 \${i+1}\`,
domain_address: \`service\${i+1}.hmcorp.com\`,
start_date: randomDateStr(4),
expired_date: randomDateStr(0),
purchase_amount: '22000',
manager_primary: '인프라팀장',
manager_secondary: '인프라담당자',
memo: '가비아 자동갱신 설정 완료'
}));
export const dummySwUsers: any[] = Array.from({ length: 15 }).map((_, i) => ({
id: randomId(),
sw_id: dummySubSw[0]?.id || randomId(),
purchase_corp: getRandomCorp(),
current_dept: '경영지원팀',
user_current: \`홍길동\${i}\`,
memo: \`SW신청서_2400\${i}\`
}));
export const dummyLogs: any[] = Array.from({ length: 10 }).map((_, i) => ({
id: randomId(),
assetId: dummyPCs[0]?.id || randomId(),
date: randomDateStr(1),
details: i % 2 === 0 ? '메모리 추가 증설 (16GB -> 32GB)' : '디스플레이 파손 수리',
user: 'IT지원팀',
cost: i % 2 === 0 ? 80000 : 150000,
}));
`;
fs.writeFileSync(dummyDataPath, newDummyDataFileContent, 'utf-8');
console.log('✅ dummyData.ts file updated successfully with SVR dataset.');
} catch (e) {
console.error('❌ Failed to update dummy data:', e);
}