diff --git a/front/assets/js/partials/operation/manage/imagerecommendation.js b/front/assets/js/partials/operation/manage/imagerecommendation.js index fc785bfb..0f49f056 100644 --- a/front/assets/js/partials/operation/manage/imagerecommendation.js +++ b/front/assets/js/partials/operation/manage/imagerecommendation.js @@ -87,74 +87,61 @@ function initRecommendImageTable() { width: 60, }, { - title: "connectionName", - field: "connectionName", - headerSort: false, - visible: false - }, - { - title: "PROVIDER", - field: "providerName", + title: "BASIC", + field: "isBasicImage", vertAlign: "middle", hozAlign: "center", - headerHozAlign: "center", - headerSort: true, maxWidth: 100, - }, - { - title: "REGION", - field: "regionList", - vertAlign: "middle", - hozAlign: "center", + headerSort: true, formatter: function(cell) { - var regions = cell.getValue(); - if (Array.isArray(regions)) { - return regions.join(", "); + var value = cell.getValue(); + if (value === true) { + return ''; + } else { + return '-'; } - return regions; } }, - { - title: "IMAGE NAME", - field: "name", - vertAlign: "middle", - hozAlign: "left", - maxWidth: 200, - }, - { - title: "CSP IMAGE", - field: "cspImageName", - vertAlign: "middle", - hozAlign: "center", - maxWidth: 150, - }, { title: "OS TYPE", field: "osType", vertAlign: "middle", hozAlign: "center", - maxWidth: 120, + minWidth: 120, + headerSort: true, }, { - title: "OS ARCH", - field: "osArchitecture", + title: "IMAGE NAME", + field: "name", vertAlign: "middle", - hozAlign: "center", - maxWidth: 100, + hozAlign: "left", + minWidth: 180, + headerSort: true, }, { - title: "PLATFORM", - field: "osPlatform", + title: "OS DISTRIBUTION", + field: "osDistribution", vertAlign: "middle", - hozAlign: "center", - maxWidth: 120, + hozAlign: "left", + minWidth: 300, + tooltip: true, + headerSort: true, }, { - title: "STATUS", - field: "imageStatus", + title: "GPU", + field: "isGPUImage", vertAlign: "middle", hozAlign: "center", - maxWidth: 100, + maxWidth: 80, + headerSort: true, + formatter: function(cell) { + var value = cell.getValue(); + if (value === true) { + return ''; + } else { + return '-'; + } + } } ]; @@ -196,32 +183,41 @@ export async function getRecommendImageInfo() { var isGPUImage = $("#gpu_image_value").val() // 전역 변수에서 정보 가져오기 + var specId = window.selectedSpecInfo.id; // spec의 전체 ID (예: "aws+ap-northeast-2+t2.small") var provider = window.selectedSpecInfo.provider; var region = window.selectedSpecInfo.regionName; var connectionName = window.selectedSpecInfo.connectionName; - var osArchitecture = window.selectedSpecInfo.osArchitecture; + // 현재 workspace/project 정보 가져오기 try { var selectedWorkspaceProject = await webconsolejs["partials/layout/navbar"].workspaceProjectInit(); var nsId = selectedWorkspaceProject.nsId; - // API 호출을 위한 파라미터 구성 + // API 호출을 위한 파라미터 구성 (간단화된 방식) var searchParams = { - includeDeprecatedImage: false, - isGPUImage: isGPUImage === "true", - isKubernetesImage: false, - isRegisteredByAsset: false, - osArchitecture: osArchitecture, - osType: osType, - providerName: provider.toLowerCase() || "", - regionName: region || "" + matchedSpecId: specId, // spec ID를 사용하여 provider, region, architecture 자동 매칭 + osType: osType }; + + // GPU 이미지가 필요한 경우에만 추가 + if (isGPUImage === "true") { + searchParams.isGPUImage = true; + } // 이미지 검색 API 호출 var response = await webconsolejs["common/api/services/mci_api"].searchImage(nsId, searchParams); if (response.status && response.status.code === 200) { var imageList = response.responseData.imageList || []; + + // 이미지가 없는 경우 안내 메시지 + if (imageList.length === 0) { + console.warn("No images found for the selected spec and OS type"); + alert("No images found for the selected specification and OS type. Please try different criteria."); + safeSetTableData([]); + return; + } + // API 응답을 테이블 형식에 맞게 변환 var processedImageList = imageList.map(function(image) { return { @@ -235,14 +231,16 @@ export async function getRecommendImageInfo() { fetchedTime: image.fetchedTime || new Date().toLocaleString(), creationDate: image.creationDate || new Date().toISOString(), osType: image.osType || osType, - osArchitecture: image.osArchitecture || osArchitecture, + osArchitecture: image.osArchitecture, osPlatform: image.osPlatform || "Linux/UNIX", osDistribution: image.osDistribution || "", - osDiskType: image.osDiskType || "ebs", - osDiskSizeGB: image.osDiskSizeGB || -1, - imageStatus: image.imageStatus || "Available", - description: image.description || image.name - }; + osDiskType: image.osDiskType || "ebs", + osDiskSizeGB: image.osDiskSizeGB || -1, + imageStatus: image.imageStatus || "Available", + description: image.description || image.name, + isBasicImage: image.isBasicImage || false, + isGPUImage: image.isGPUImage || false + }; }); recommendImageListObj = processedImageList; diff --git a/front/assets/js/partials/operation/manage/pmk_imagerecommendation.js b/front/assets/js/partials/operation/manage/pmk_imagerecommendation.js index b5b0458c..b585c627 100644 --- a/front/assets/js/partials/operation/manage/pmk_imagerecommendation.js +++ b/front/assets/js/partials/operation/manage/pmk_imagerecommendation.js @@ -84,74 +84,77 @@ function initRecommendImageTablePmk() { width: 60, }, { - title: "connectionName", - field: "connectionName", - headerSort: false, - visible: false - }, - { - title: "PROVIDER", - field: "providerName", + title: "BASIC", + field: "isBasicImage", vertAlign: "middle", hozAlign: "center", - headerHozAlign: "center", - headerSort: true, maxWidth: 100, - }, - { - title: "REGION", - field: "regionList", - vertAlign: "middle", - hozAlign: "center", + headerSort: true, formatter: function(cell) { - var regions = cell.getValue(); - if (Array.isArray(regions)) { - return regions.join(", "); + var value = cell.getValue(); + if (value === true) { + return ''; + } else { + return '-'; } - return regions; } }, { - title: "IMAGE NAME", - field: "name", - vertAlign: "middle", - hozAlign: "left", - maxWidth: 200, - }, - { - title: "CSP IMAGE", - field: "cspImageName", + title: "OS TYPE", + field: "osType", vertAlign: "middle", hozAlign: "center", - maxWidth: 150, + minWidth: 120, + headerSort: true, }, { - title: "OS TYPE", - field: "osType", + title: "IMAGE NAME", + field: "name", vertAlign: "middle", - hozAlign: "center", - maxWidth: 120, + hozAlign: "left", + minWidth: 180, + headerSort: true, }, { - title: "OS ARCH", - field: "osArchitecture", + title: "OS DISTRIBUTION", + field: "osDistribution", vertAlign: "middle", - hozAlign: "center", - maxWidth: 100, + hozAlign: "left", + minWidth: 300, + tooltip: true, + headerSort: true, }, { - title: "PLATFORM", - field: "osPlatform", + title: "GPU", + field: "isGPUImage", vertAlign: "middle", hozAlign: "center", - maxWidth: 120, + maxWidth: 80, + headerSort: true, + formatter: function(cell) { + var value = cell.getValue(); + if (value === true) { + return ''; + } else { + return '-'; + } + } }, { - title: "STATUS", - field: "imageStatus", + title: "K8S", + field: "isKubernetesImage", vertAlign: "middle", hozAlign: "center", - maxWidth: 100, + maxWidth: 80, + headerSort: true, + formatter: function(cell) { + var value = cell.getValue(); + if (value === true) { + return ''; + } else { + return '-'; + } + } } ]; @@ -191,30 +194,27 @@ export async function getRecommendImageInfoPmk() { var isGPUImage = $("#gpu_image_value-pmk").val() // 전역 변수에서 정보 가져오기 + var specId = window.selectedPmkSpecInfo.id; // spec의 전체 ID (예: "aws+ap-northeast-2+t2.small") var provider = window.selectedPmkSpecInfo.provider; var region = window.selectedPmkSpecInfo.regionName; var connectionName = window.selectedPmkSpecInfo.connectionName; - var osArchitecture = window.selectedPmkSpecInfo.osArchitecture; - - // 현재 workspace/project 정보 가져오기 try { var selectedWorkspaceProject = await webconsolejs["partials/layout/navbar"].workspaceProjectInit(); var nsId = selectedWorkspaceProject.nsId; - - // API 호출을 위한 파라미터 구성 + // API 호출을 위한 파라미터 구성 (간단화된 방식) var searchParams = { - includeDeprecatedImage: false, - isGPUImage: isGPUImage === "true", - isKubernetesImage: true, - isRegisteredByAsset: false, - osArchitecture: osArchitecture, + matchedSpecId: specId, // spec ID를 사용하여 provider, region, architecture 자동 매칭 osType: osType, - providerName: provider.toLowerCase() || "", - regionName: region || "" + isKubernetesImage: true // PMK는 Kubernetes 이미지 필수 }; + + // GPU 이미지가 필요한 경우에만 추가 + if (isGPUImage === "true") { + searchParams.isGPUImage = true; + } @@ -237,14 +237,17 @@ export async function getRecommendImageInfoPmk() { fetchedTime: image.fetchedTime || new Date().toLocaleString(), creationDate: image.creationDate || new Date().toISOString(), osType: image.osType || osType, - osArchitecture: image.osArchitecture || osArchitecture, + osArchitecture: image.osArchitecture, osPlatform: image.osPlatform || "Linux/UNIX", osDistribution: image.osDistribution || "", - osDiskType: image.osDiskType || "ebs", - osDiskSizeGB: image.osDiskSizeGB || -1, - imageStatus: image.imageStatus || "Available", - description: image.description || image.name - }; + osDiskType: image.osDiskType || "ebs", + osDiskSizeGB: image.osDiskSizeGB || -1, + imageStatus: image.imageStatus || "Available", + description: image.description || image.name, + isBasicImage: image.isBasicImage || false, + isGPUImage: image.isGPUImage || false, + isKubernetesImage: image.isKubernetesImage || false + }; }); recommendImageListObjPmk = processedImageList; diff --git a/front/assets/js/partials/operation/manage/pmk_serverrecommendation.js b/front/assets/js/partials/operation/manage/pmk_serverrecommendation.js index 4a4f69d8..a0fe4f57 100644 --- a/front/assets/js/partials/operation/manage/pmk_serverrecommendation.js +++ b/front/assets/js/partials/operation/manage/pmk_serverrecommendation.js @@ -132,7 +132,12 @@ export async function getRecommendVmInfoPmk() { const selectedWorkspaceProject = await webconsolejs["partials/layout/navbar"].workspaceProjectInit(); const selectedNsId = selectedWorkspaceProject.nsId; - // 기본 필터링 조건 설정 + // PMK 최소 요구사항 (Kubernetes 권장 사양) + // Min vCPU: 4, Min Memory: 16GB, Disk: 100GB + const PMK_MIN_VCPU = 4; + const PMK_MIN_MEMORY = 16; + + // 기본 필터링 조건 설정 (최소 요구사항 적용) const memoryMinVal = $("#assist_min_memory-pmk").val() || ""; const memoryMaxVal = $("#assist_max_memory-pmk").val() || ""; const cpuMinVal = $("#assist_min_cpu-pmk").val() || ""; @@ -142,19 +147,18 @@ export async function getRecommendVmInfoPmk() { const lon = $("#longitude-pmk").val() || ""; const lat = $("#latitude-pmk").val() || ""; - - // 필터 정책 배열 생성 const policyArr = []; - // CPU 필터 + // CPU 필터 (최소 4 vCPU 보장) if (cpuMinVal !== "" || cpuMaxVal !== "") { if (cpuMaxVal !== "" && cpuMaxVal < cpuMinVal) { alert("Maximum value is less than the minimum value."); return; } - const cpuMin = cpuMinVal === "" ? "0" : cpuMinVal; + // 사용자 입력값과 PMK 최소값 중 큰 값 사용 + const cpuMin = Math.max(cpuMinVal === "" ? PMK_MIN_VCPU : parseInt(cpuMinVal), PMK_MIN_VCPU).toString(); const cpuMax = cpuMaxVal === "" ? "0" : cpuMaxVal; policyArr.push({ @@ -164,17 +168,26 @@ export async function getRecommendVmInfoPmk() { ], metric: "vCPU" }); - + } else { + // 사용자 입력이 없으면 PMK 최소 요구사항 적용 + policyArr.push({ + condition: [ + { operand: "0", operator: "<=" }, + { operand: PMK_MIN_VCPU.toString(), operator: ">=" } + ], + metric: "vCPU" + }); } - // Memory 필터 + // Memory 필터 (최소 16GB 보장) if (memoryMinVal !== "" || memoryMaxVal !== "") { if (memoryMaxVal !== "" && memoryMaxVal < memoryMinVal) { alert("Maximum value is less than the minimum value."); return; } - const memoryMin = memoryMinVal === "" ? "0" : memoryMinVal; + // 사용자 입력값과 PMK 최소값 중 큰 값 사용 + const memoryMin = Math.max(memoryMinVal === "" ? PMK_MIN_MEMORY : parseInt(memoryMinVal), PMK_MIN_MEMORY).toString(); const memoryMax = memoryMaxVal === "" ? "0" : memoryMaxVal; policyArr.push({ @@ -184,7 +197,15 @@ export async function getRecommendVmInfoPmk() { ], metric: "memoryGiB" }); - + } else { + // 사용자 입력이 없으면 PMK 최소 요구사항 적용 + policyArr.push({ + condition: [ + { operand: "0", operator: "<=" }, + { operand: PMK_MIN_MEMORY.toString(), operator: ">=" } + ], + metric: "memoryGiB" + }); } // Cost 필터