func makeVMControlFunc_js() string {
	strFunc := `
                function vmControl(vmName, action) {
                        var connConfig = parent.frames["top_frame"].document.getElementById("connConfig").innerHTML;
												document.getElementById("vmcontrol-" + vmName).innerHTML = '<span style="color:red">Waiting...</span>';
												setTimeout(function(){
													var xhr = new XMLHttpRequest();
													xhr.open("PUT", "$$SPIDER_SERVER$$/spider/controlvm/" + vmName + "?action=" + action, false);
													xhr.setRequestHeader('Content-Type', 'application/json');
													sendJson = '{ "ConnectionName": "' + connConfig + '"}'
													xhr.send(sendJson);
													location.reload();
												}, 10);
                }
        `
	strFunc = strings.ReplaceAll(strFunc, "$$SPIDER_SERVER$$", "http://"+cr.ServiceIPorName+cr.ServicePort)  
	return strFunc
}
make the string of javascript function
package adminweb
import (
	"fmt"
	cr "github.com/cloud-barista/cb-spider/api-runtime/common-runtime"
	cres "github.com/cloud-barista/cb-spider/cloud-control-manager/cloud-driver/interfaces/resources"
	"strconv"
	"encoding/json"
	"net/http"
	"strings"
	"github.com/labstack/echo/v4"
)
func makeVPCTRList_html(bgcolor string, height string, fontSize string, infoList []*cres.VPCInfo) string {
	if bgcolor == "" {
		bgcolor = "#FFFFFF"
	}
	if height == "" {
		height = "30"
	}
	if fontSize == "" {
		fontSize = "2"
	}
	strTR := fmt.Sprintf(`
                <tr bgcolor="%s" align="center" height="%s">
                    <td>
                            <font size=%s>$$NUM$$</font>
                    </td>
                    <td>
                            <font size=%s>$$VPCNAME$$</font>
                    </td>
                    <td>
                            <font size=%s>$$VPCCIDR$$</font>
                    </td>
                    <td>
                            <font size=%s>$$SUBNETINFO$$</font>
                    </td>
                    <td>
                            <font size=%s>$$ADDITIONALINFO$$</font>
                    </td>
                    <td>
                        <input type="checkbox" name="check_box" value=$$VPCNAME$$>
                    </td>
                </tr>
                `, bgcolor, height, fontSize, fontSize, fontSize, fontSize, fontSize)
	strRemoveSubnet := fmt.Sprintf(`
                <a href="javascript:$$REMOVESUBNET$$;">
                        <font size=%s><b>&nbsp;X</b></font>
                </a>
                `, fontSize)
	strAddSubnet := fmt.Sprintf(`
                <textarea style="font-size:12px;text-align:center;" name="subnet_text_box_$$ADDVPC$$" id="subnet_text_box_$$ADDVPC$$" cols=40>{ "Name": "subnet-xx", "IPv4_CIDR": "192.168.xx.xx/24"}</textarea>
                <a href="javascript:$$ADDSUBNET$$;">
                        <font size=%s><b>+</b></font>
                </a>
								`, fontSize)
	strData := ""
	for i, one := range infoList {
		str := strings.ReplaceAll(strTR, "$$NUM$$", strconv.Itoa(i+1))
		str = strings.ReplaceAll(str, "$$VPCNAME$$", one.IId.NameId)
		str = strings.ReplaceAll(str, "$$VPCCIDR$$", one.IPv4_CIDR)
		var vpcName = one.IId.NameId
		strSubnetList := ""
		for _, one := range one.SubnetInfoList {
			strSubnetList += one.IId.NameId + ", "
			strSubnetList += "CIDR:" + one.IPv4_CIDR + ", {"
			for _, kv := range one.KeyValueList {
				strSubnetList += kv.Key + ":" + kv.Value + ", "
			}
			strSubnetList += "}"
			var subnetName = one.IId.NameId
			strSubnetList += strings.ReplaceAll(strRemoveSubnet, "$$REMOVESUBNET$$", "deleteSubnet('"+vpcName+"', '"+subnetName+"')")
			strSubnetList += "<br>"
		}
		vpcAddSubnet := strings.ReplaceAll(strAddSubnet, "$$ADDVPC$$", vpcName)
		strSubnetList += strings.ReplaceAll(vpcAddSubnet, "$$ADDSUBNET$$", "postSubnet('"+vpcName+"')")
		str = strings.ReplaceAll(str, "$$SUBNETINFO$$", strSubnetList)
		strKeyList := ""
		for _, kv := range one.KeyValueList {
			strKeyList += kv.Key + ":" + kv.Value + ", "
		}
		str = strings.ReplaceAll(str, "$$ADDITIONALINFO$$", strKeyList)
		strData += str
	}
	return strData
}
func makePostVPCFunc_js() string {
	strFunc := `
                function postVPC() {
                        var connConfig = parent.frames["top_frame"].document.getElementById("connConfig").innerHTML;
                        var textboxes = document.getElementsByName('text_box');
            sendJson = '{ "ConnectionName" : "' + connConfig + '", "ReqInfo" : { "Name" : "$$VPCNAME$$", "IPv4_CIDR" : "$$VPCCIDR$$", "SubnetInfoList" : $$SUBNETINFOLIST$$ }}'
                        for (var i = 0; i < textboxes.length; i++) {  
                                switch (textboxes[i].id) {
                                        case "1":
                                                sendJson = sendJson.replace("$$VPCNAME$$", textboxes[i].value);
                                                break;
                                        case "2":
                                                sendJson = sendJson.replace("$$VPCCIDR$$", textboxes[i].value);
                                                break;
                                        case "3":
                                                sendJson = sendJson.replace("$$SUBNETINFOLIST$$", textboxes[i].value);
                                                break;
                                        default:
                                                break;
                                }
                        }
                        var xhr = new XMLHttpRequest();
                        xhr.open("POST", "$$SPIDER_SERVER$$/spider/vpc", false);
                        xhr.setRequestHeader('Content-Type', 'application/json');
                        xhr.send(sendJson);
			location.reload();
                }
        `
	strFunc = strings.ReplaceAll(strFunc, "$$SPIDER_SERVER$$", "http://"+cr.ServiceIPorName+cr.ServicePort)  
	return strFunc
}
func makePostSubnetFunc_js() string {
	strFunc := `
                function postSubnet(vpcName) {
                        var connConfig = parent.frames["top_frame"].document.getElementById("connConfig").innerHTML;
                        var textbox = document.getElementById('subnet_text_box_' + vpcName);
                        sendJson = '{ "ConnectionName" : "' + connConfig + '", "ReqInfo" :  $$SUBNETINFO$$ }'
                        sendJson = sendJson.replace("$$SUBNETINFO$$", textbox.value);
                        var xhr = new XMLHttpRequest();
                        xhr.open("POST", "$$SPIDER_SERVER$$/spider/vpc/" + vpcName + "/subnet", false);
                        xhr.setRequestHeader('Content-Type', 'application/json');
                        xhr.send(sendJson);
                        location.reload();
                }
        `
	strFunc = strings.ReplaceAll(strFunc, "$$SPIDER_SERVER$$", "http://"+cr.ServiceIPorName+cr.ServicePort)  
	return strFunc
}
func makeDeleteVPCFunc_js() string {
	strFunc := `
                function deleteVPC() {
                        var connConfig = parent.frames["top_frame"].document.getElementById("connConfig").innerHTML;
                        var checkboxes = document.getElementsByName('check_box');
                        for (var i = 0; i < checkboxes.length; i++) {  
                                if (checkboxes[i].checked) {
                                        var xhr = new XMLHttpRequest();
                                        xhr.open("DELETE", "$$SPIDER_SERVER$$/spider/vpc/" + checkboxes[i].value, false);
                                        xhr.setRequestHeader('Content-Type', 'application/json');
					sendJson = '{ "ConnectionName": "' + connConfig + '"}'
                                        xhr.send(sendJson);
                                }
                        }
			location.reload();
                }
        `
	strFunc = strings.ReplaceAll(strFunc, "$$SPIDER_SERVER$$", "http://"+cr.ServiceIPorName+cr.ServicePort)  
	return strFunc
}
func makeDeleteSubnetFunc_js() string {
	strFunc := `
                function deleteSubnet(vpcName, subnetName) {
                        var connConfig = parent.frames["top_frame"].document.getElementById("connConfig").innerHTML;
                        var xhr = new XMLHttpRequest();
                        xhr.open("DELETE", "$$SPIDER_SERVER$$/spider/vpc/" + vpcName + "/subnet/" + subnetName, false);
                        xhr.setRequestHeader('Content-Type', 'application/json');
                        sendJson = '{ "ConnectionName": "' + connConfig + '"}'
                        xhr.send(sendJson);
                        location.reload();
                }
        `
	strFunc = strings.ReplaceAll(strFunc, "$$SPIDER_SERVER$$", "http://"+cr.ServiceIPorName+cr.ServicePort)  
	return strFunc
}
func VPC(c echo.Context) error {
	cblog.Info("call VPC()")
	connConfig := c.Param("ConnectConfig")
	if connConfig == "region not set" {
		htmlStr := `
			<html>
			<head>
			    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
			    <script type="text/javascript">
				alert(connConfig)
			    </script>
			</head>
			<body>
				<br>
				<br>
				<label style="font-size:24px;color:#606262;">&nbsp;&nbsp;&nbsp;Please select a Connection Configuration! (MENU: 2.CONNECTION)</label>	
			</body>
		`
		return c.HTML(http.StatusOK, htmlStr)
	}
	htmlStr := `
                <html>
                <head>
                    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
                    <script type="text/javascript">
                `
	htmlStr += makeCheckBoxToggleFunc_js()
	htmlStr += makePostVPCFunc_js()
	htmlStr += makeDeleteVPCFunc_js()
	htmlStr += makePostSubnetFunc_js()
	htmlStr += makeDeleteSubnetFunc_js()
	htmlStr += `
                    </script>
                </head>
                <body>
                    <table border="0" bordercolordark="#F8F8FF" cellpadding="0" cellspacing="1" bgcolor="#FFFFFF"  style="font-size:small;">
                `
	htmlStr += makeActionTR_html("6", "", "deleteVPC()", "2")
	nameWidthList := []NameWidth{
		{"VPC Name", "200"},
		{"VPC CIDR", "200"},
		{"Subnet Info", "300"},
		{"Additional Info", "300"},
	}
	htmlStr += makeTitleTRList_html("#DDDDDD", "2", nameWidthList, true)
	resBody, err := getResourceList_with_Connection_JsonByte(connConfig, "vpc")
	if err != nil {
		cblog.Error(err)
		return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
	}
	var info struct {
		ResultList []*cres.VPCInfo `json:"vpc"`
	}
	json.Unmarshal(resBody, &info)
	htmlStr += makeVPCTRList_html("", "", "", info.ResultList)
	htmlStr += `
                        <tr bgcolor="#FFFFFF" align="center" height="30">
                            <td>
                                    <font size=2>#</font>
                            </td>
                            <td>
                                <input style="font-size:12px;text-align:center;" type="text" name="text_box" id="1" value="vpc-01">
                            </td>
                            <td>
                                <input style="font-size:12px;text-align:center;" type="text" name="text_box" id="2" value="192.168.0.0/16">
                            </td>
                            <td>
                                <textarea style="font-size:12px;text-align:center;" name="text_box" id="3" cols=50>[ { "Name": "subnet-01", "IPv4_CIDR": "192.168.1.0/24"} ]</textarea>
                            </td>
                            <td>
                                <input style="font-size:12px;text-align:center;" type="text" name="text_box" id="4" disabled value="N/A">
                            </td>                            
                            <td>
                                <a href="javascript:postVPC()">
                                    <font size=3><b>+</b></font>
                                </a>
                            </td>
                        </tr>
                `
	htmlStr += `
                    </table>
		    <hr>
                </body>
                </html>
        `
	return c.HTML(http.StatusOK, htmlStr)
}
func makeSecurityGroupTRList_html(bgcolor string, height string, fontSize string, infoList []*cres.SecurityInfo) string {
	if bgcolor == "" {
		bgcolor = "#FFFFFF"
	}
	if height == "" {
		height = "30"
	}
	if fontSize == "" {
		fontSize = "2"
	}
	strTR := fmt.Sprintf(`
                <tr bgcolor="%s" align="center" height="%s">
                    <td>
                            <font size=%s>$$NUM$$</font>
                    </td>
                    <td>
                            <font size=%s>$$VPCNAME$$</font>
                    </td>
                    <td>
                            <font size=%s>$$SGNAME$$</font>
                    </td>                    
                    <td>
                            <font size=%s>$$SECURITYRULES$$</font>
                    </td>
                    <td>
                            <font size=%s>$$ADDITIONALINFO$$</font>
                    </td>
                    <td>
                        <input type="checkbox" name="check_box" value=$$SGNAME$$>
                    </td>
                </tr>
                `, bgcolor, height, fontSize, fontSize, fontSize, fontSize, fontSize)
	strData := ""
	for i, one := range infoList {
		str := strings.ReplaceAll(strTR, "$$NUM$$", strconv.Itoa(i+1))
		str = strings.ReplaceAll(str, "$$VPCNAME$$", one.VpcIID.NameId)
		str = strings.ReplaceAll(str, "$$SGNAME$$", one.IId.NameId)
		strSRList := ""
		for _, one := range *one.SecurityRules {
			strSRList += "FromPort:" + one.FromPort + ", "
			strSRList += "ToPort:" + one.ToPort + ", "
			strSRList += "IPProtocol:" + one.IPProtocol + ", "
			strSRList += "Direction:" + one.Direction + ", "
			strSRList += "CIDR:" + one.CIDR + ", "
			strSRList += "}<br>"
		}
		str = strings.ReplaceAll(str, "$$SECURITYRULES$$", strSRList)
		strKeyList := ""
		for _, kv := range one.KeyValueList {
			strKeyList += kv.Key + ":" + kv.Value + ", "
		}
		str = strings.ReplaceAll(str, "$$ADDITIONALINFO$$", strKeyList)
		strData += str
	}
	return strData
}
func makePostSecurityGroupFunc_js() string {
	strFunc := `
                function postSecurityGroup() {
                        var connConfig = parent.frames["top_frame"].document.getElementById("connConfig").innerHTML;
                        var textboxes = document.getElementsByName('text_box');
                        sendJson = '{ "ConnectionName" : "' + connConfig + '", "ReqInfo" : { "Name" : "$$SGNAME$$", "VPCName" : "$$VPCNAME$$", "SecurityRules" : $$SECURITYRULES$$ }}'
                        for (var i = 0; i < textboxes.length; i++) {  
                                switch (textboxes[i].id) {
                                        case "1":
                                                sendJson = sendJson.replace("$$VPCNAME$$", textboxes[i].value);
                                                break;
                                        case "2":
                                                sendJson = sendJson.replace("$$SGNAME$$", textboxes[i].value);
                                                break;
                                        case "3":
                                                sendJson = sendJson.replace("$$SECURITYRULES$$", textboxes[i].value);
                                                break;
                                        default:
                                                break;
                                }
                        }
                        var xhr = new XMLHttpRequest();
                        xhr.open("POST", "$$SPIDER_SERVER$$/spider/securitygroup", false);
                        xhr.setRequestHeader('Content-Type', 'application/json');
                        xhr.send(sendJson);
            location.reload();
                }
        `
	strFunc = strings.ReplaceAll(strFunc, "$$SPIDER_SERVER$$", "http://"+cr.ServiceIPorName+cr.ServicePort)  
	return strFunc
}
func makeDeleteSecurityGroupFunc_js() string {
	strFunc := `
                function deleteSecurityGroup() {
                        var connConfig = parent.frames["top_frame"].document.getElementById("connConfig").innerHTML;
                        var checkboxes = document.getElementsByName('check_box');
                        for (var i = 0; i < checkboxes.length; i++) {  
                                if (checkboxes[i].checked) {
                                        var xhr = new XMLHttpRequest();
                                        xhr.open("DELETE", "$$SPIDER_SERVER$$/spider/securitygroup/" + checkboxes[i].value, false);
                                        xhr.setRequestHeader('Content-Type', 'application/json');
                    sendJson = '{ "ConnectionName": "' + connConfig + '"}'
                                        xhr.send(sendJson);
                                }
                        }
            location.reload();
                }
        `
	strFunc = strings.ReplaceAll(strFunc, "$$SPIDER_SERVER$$", "http://"+cr.ServiceIPorName+cr.ServicePort)  
	return strFunc
}
func SecurityGroup(c echo.Context) error {
	cblog.Info("call SecurityGroup()")
	connConfig := c.Param("ConnectConfig")
	if connConfig == "region not set" {
		htmlStr := `
            <html>
            <head>
                <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
                <script type="text/javascript">
                alert(connConfig)
                </script>
            </head>
            <body>
                <br>
                <br>
                <label style="font-size:24px;color:#606262;">&nbsp;&nbsp;&nbsp;Please select a Connection Configuration! (MENU: 2.CONNECTION)</label>   
            </body>
        `
		return c.HTML(http.StatusOK, htmlStr)
	}
	htmlStr := `
                <html>
                <head>
                    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
                    <script type="text/javascript">
                `
	htmlStr += makeCheckBoxToggleFunc_js()
	htmlStr += makePostSecurityGroupFunc_js()
	htmlStr += makeDeleteSecurityGroupFunc_js()
	htmlStr += `
                    </script>
                </head>
                <body>
                    <table border="0" bordercolordark="#F8F8FF" cellpadding="0" cellspacing="1" bgcolor="#FFFFFF"  style="font-size:small;">
                `
	htmlStr += makeActionTR_html("6", "", "deleteSecurityGroup()", "2")
	nameWidthList := []NameWidth{
		{"VPC Name", "200"},
		{"SecurityGroup Name", "200"},
		{"Security Rules", "300"},
		{"Additional Info", "300"},
	}
	htmlStr += makeTitleTRList_html("#DDDDDD", "2", nameWidthList, true)
	resBody, err := getResourceList_with_Connection_JsonByte(connConfig, "securitygroup")
	if err != nil {
		cblog.Error(err)
		return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
	}
	var info struct {
		ResultList []*cres.SecurityInfo `json:"securitygroup"`
	}
	json.Unmarshal(resBody, &info)
	htmlStr += makeSecurityGroupTRList_html("", "", "", info.ResultList)
	nameList := vpcList(connConfig)
	htmlStr += `
                        <tr bgcolor="#FFFFFF" align="center" height="30">
                            <td>
                                    <font size=2>#</font>
                            </td>
                            <td>
		`
	htmlStr += makeSelect_html("onchangeVPC", nameList, "1")
	htmlStr += `
                            </td>
                            <td>
                                <input style="font-size:12px;text-align:center;" type="text" name="text_box" id="2" value="sg-01">
                            </td>
                            <td>
                                <textarea style="font-size:12px;text-align:center;" name="text_box" id="3" cols=50 rows=3>[ {"FromPort": "1", "ToPort" : "65535", "IPProtocol" : "tcp", "Direction" : "inbound", "CIDR" : "0.0.0.0/0" } ]</textarea>
                            </td>
                            <td>
                                <input style="font-size:12px;text-align:center;" type="text" name="text_box" id="4" disabled value="N/A">                            
                            </td>
                            <td>
                                <a href="javascript:postSecurityGroup()">
                                    <font size=3><b>+</b></font>
                                </a>
                            </td>
                        </tr>
                `
	htmlStr += `
                    </table>
            <hr>
                </body>
                </html>
        `
	return c.HTML(http.StatusOK, htmlStr)
}
func makeKeyPairTRList_html(bgcolor string, height string, fontSize string, infoList []*cres.KeyPairInfo) string {
	if bgcolor == "" {
		bgcolor = "#FFFFFF"
	}
	if height == "" {
		height = "30"
	}
	if fontSize == "" {
		fontSize = "2"
	}
	strTR := fmt.Sprintf(`
                <tr bgcolor="%s" align="center" height="%s">
                    <td>
                            <font size=%s>$$NUM$$</font>
                    </td>
                    <td>
                            <font size=%s>$$KEYPAIRNAME$$</font>
                    </td>
                    <td align="left">
                            <font size=%s>$$KEYINFO$$</font>
                    </td>
                    <td>
                            <font size=%s>$$KEYUSER$$</font>
                    </td>
                    <td>
                            <font size=%s>$$ADDITIONALINFO$$</font>
                    </td>
                    <td>
                        <input type="checkbox" name="check_box" value=$$KEYPAIRNAME$$>
                    </td>
                </tr>
                `, bgcolor, height, fontSize, fontSize, fontSize, fontSize, fontSize)
	strData := ""
	for i, one := range infoList {
		str := strings.ReplaceAll(strTR, "$$NUM$$", strconv.Itoa(i+1))
		str = strings.ReplaceAll(str, "$$KEYPAIRNAME$$", one.IId.NameId)
		runes := []rune(one.Fingerprint)
		fingerPrint := string(runes[0:12]) + "XXXXXXXXXXX"
		runes = []rune(one.PrivateKey)
		privateKey := string(runes[0:12]) + "XXXXXXXXXXX"
		runes = []rune(one.PublicKey)
		publicKey := string(runes[0:12]) + "XXXXXXXXXXX"
		keyInfo := "&nbsp;* Fingerprint: " + fingerPrint + "<br>"
		keyInfo += "&nbsp;* PrivateKey: " + privateKey + "<br>"
		keyInfo += "&nbsp;* PublicKey: " + publicKey
		str = strings.ReplaceAll(str, "$$KEYINFO$$", keyInfo)
		str = strings.ReplaceAll(str, "$$KEYUSER$$", one.VMUserID)
		strKeyList := ""
		for _, kv := range one.KeyValueList {
			strKeyList += kv.Key + ":" + kv.Value + ", "
		}
		str = strings.ReplaceAll(str, "$$ADDITIONALINFO$$", strKeyList)
		strData += str
	}
	return strData
}
func makePostKeyPairFunc_js() string {
	strFunc := `
                function postKeyPair() {
                        var connConfig = parent.frames["top_frame"].document.getElementById("connConfig").innerHTML;
                        var textboxes = document.getElementsByName('text_box');
            sendJson = '{ "ConnectionName" : "' + connConfig + '", "ReqInfo" : { "Name" : "$$KEYPAIRNAME$$"}}'
                        for (var i = 0; i < textboxes.length; i++) {  
                                switch (textboxes[i].id) {
                                        case "1":
                                                sendJson = sendJson.replace("$$KEYPAIRNAME$$", textboxes[i].value);
                                                break;
                                        default:
                                                break;
                                }
                        }
                        var xhr = new XMLHttpRequest();
                        xhr.open("POST", "$$SPIDER_SERVER$$/spider/keypair", false);
                        xhr.setRequestHeader('Content-Type', 'application/json');
                        xhr.send(sendJson);
            location.reload();
                }
        `
	strFunc = strings.ReplaceAll(strFunc, "$$SPIDER_SERVER$$", "http://"+cr.ServiceIPorName+cr.ServicePort)  
	return strFunc
}
func makeDeleteKeyPairFunc_js() string {
	strFunc := `
                function deleteKeyPair() {
                        var connConfig = parent.frames["top_frame"].document.getElementById("connConfig").innerHTML;
                        var checkboxes = document.getElementsByName('check_box');
                        for (var i = 0; i < checkboxes.length; i++) {  
                                if (checkboxes[i].checked) {
                                        var xhr = new XMLHttpRequest();
                                        xhr.open("DELETE", "$$SPIDER_SERVER$$/spider/keypair/" + checkboxes[i].value, false);
                                        xhr.setRequestHeader('Content-Type', 'application/json');
                    sendJson = '{ "ConnectionName": "' + connConfig + '"}'
                                        xhr.send(sendJson);
                                }
                        }
            location.reload();
                }
        `
	strFunc = strings.ReplaceAll(strFunc, "$$SPIDER_SERVER$$", "http://"+cr.ServiceIPorName+cr.ServicePort)  
	return strFunc
}
func KeyPair(c echo.Context) error {
	cblog.Info("call KeyPair()")
	connConfig := c.Param("ConnectConfig")
	if connConfig == "region not set" {
		htmlStr := `
            <html>
            <head>
                <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
                <script type="text/javascript">
                alert(connConfig)
                </script>
            </head>
            <body>
                <br>
                <br>
                <label style="font-size:24px;color:#606262;">&nbsp;&nbsp;&nbsp;Please select a Connection Configuration! (MENU: 2.CONNECTION)</label>   
            </body>
        `
		return c.HTML(http.StatusOK, htmlStr)
	}
	htmlStr := `
                <html>
                <head>
                    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
                    <script type="text/javascript">
                `
	htmlStr += makeCheckBoxToggleFunc_js()
	htmlStr += makePostKeyPairFunc_js()
	htmlStr += makeDeleteKeyPairFunc_js()
	htmlStr += `
                    </script>
                </head>
                <body>
                    <table border="0" bordercolordark="#F8F8FF" cellpadding="0" cellspacing="1" bgcolor="#FFFFFF"  style="font-size:small;">
                `
	htmlStr += makeActionTR_html("6", "", "deleteKeyPair()", "2")
	nameWidthList := []NameWidth{
		{"KeyPair Name", "200"},
		{"KeyPair Info", "300"},
		{"Key User", "200"},
		{"Additional Info", "300"},
	}
	htmlStr += makeTitleTRList_html("#DDDDDD", "2", nameWidthList, true)
	resBody, err := getResourceList_with_Connection_JsonByte(connConfig, "keypair")
	if err != nil {
		cblog.Error(err)
		return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
	}
	var info struct {
		ResultList []*cres.KeyPairInfo `json:"keypair"`
	}
	json.Unmarshal(resBody, &info)
	htmlStr += makeKeyPairTRList_html("", "", "", info.ResultList)
	htmlStr += `
                        <tr bgcolor="#FFFFFF" align="center" height="30">
                            <td>
                                    <font size=2>#</font>
                            </td>
                            <td>
                                <input style="font-size:12px;text-align:center;" type="text" name="text_box" id="1" value="keypair-01">
                            </td>
                            <td>
                                <input style="font-size:12px;text-align:center;" type="text" name="text_box" id="2" disabled value="N/A">
                            </td>
                            <td>
                                <input style="font-size:12px;text-align:center;" type="text" name="text_box" id="3" disabled value="N/A">
                            </td>
                            <td>
                                <input style="font-size:12px;text-align:center;" type="text" name="text_box" id="4" disabled value="N/A">
                            </td>
                            <td>
                                <a href="javascript:postKeyPair()">
                                    <font size=3><b>+</b></font>
                                </a>
                            </td>
                        </tr>
                `
	htmlStr += `
                    </table>
            <hr>
                </body>
                </html>
        `
	return c.HTML(http.StatusOK, htmlStr)
}
func makeVMTRList_html(connConfig string, bgcolor string, height string, fontSize string, infoList []*cres.VMInfo) string {
	if bgcolor == "" {
		bgcolor = "#FFFFFF"
	}
	if height == "" {
		height = "30"
	}
	if fontSize == "" {
		fontSize = "2"
	}
	strTR := fmt.Sprintf(`
                <tr bgcolor="%s" align="center" height="%s">
                    <td>
                            <font size=%s>$$NUM$$</font>
                    </td>
                    <td>
														<font size=%s>$$VMNAME$$</font>
														<br>
														<font size=%s>$$VMCONTROL$$</font>
                    </td>
                    <td>
                            <font size=%s>$$VMSTATUS$$</font>
                            <br>
                            <font size=%s>$$LASTSTARTTIME$$</font>
                    </td>                    
                    <td>
                            <font size=%s>$$IMAGE$$</font>
                            <br>
                            <font size=%s>$$SPEC$$</font>
                    </td>
                    <td>
                            <font size=%s>$$VPC$$</font>
                            <br>
                            <font size=%s>$$SUBNET$$</font>
                            <br>
                            <font size=%s>$$SECURITYGROUP$$</font>
                    </td>
                    <td>
                            <font size=%s>$$NETWORKINTERFACE$$</font>
                            <br>
                            <font size=%s>$$PUBLICIP$$</font>
                            <br>
                            <font size=%s>$$PRIVATEIP$$</font>
                    </td>
                    <td>
                            <font size=%s>$$PUBLICDNS$$</font>
                            <br>
                            <font size=%s>$$PRIVATEDNS$$</font>
                    </td>
                    <td>
                            <font size=%s>$$BOOTDISK$$</font>
                            <br>
                            <font size=%s>$$BLOCKDISK$$</font>
                    </td>
                    <td>
                            <font size=%s>$$SSHACCESSPOINT$$</font>
                            <br>
                            <font size=%s>$$ACCESSKEY$$</font>
                            <br>
                            <font size=%s>$$ACCESSUSER$$</font>
                    </td>
                    <td>
                            <font size=%s>$$ADDITIONALINFO$$</font>
                    </td>
                    <td>
                        <input type="checkbox" name="check_box" value=$$VMNAME$$>
                    </td>
                </tr>
                `, bgcolor, height, fontSize, fontSize, fontSize, fontSize, fontSize, fontSize, fontSize, fontSize, fontSize, fontSize,
		fontSize, fontSize, fontSize, fontSize, fontSize, fontSize, fontSize, fontSize, fontSize)
	strData := ""
	for i, one := range infoList {
		str := strings.ReplaceAll(strTR, "$$NUM$$", strconv.Itoa(i+1))
		str = strings.ReplaceAll(str, "$$VMNAME$$", one.IId.NameId)
		status := vmStatus(connConfig, one.IId.NameId)
		str = strings.ReplaceAll(str, "$$VMSTATUS$$", status)
		if cres.VMStatus(status) == cres.Running {
			str = strings.ReplaceAll(str, "$$VMCONTROL$$", `<span id="vmcontrol-`+one.IId.NameId+`">[<a href="javascript:vmControl('`+one.IId.NameId+`','suspend')">Suspend</a> / <a href="javascript:vmControl('`+one.IId.NameId+`','reboot')">Reboot</a>]</span>`)
		} else if cres.VMStatus(status) == cres.Suspended {
			str = strings.ReplaceAll(str, "$$VMCONTROL$$", `<span id="vmcontrol-`+one.IId.NameId+`">[<a href="javascript:vmControl('`+one.IId.NameId+`','resume')">Resume</a>]</span>`)
		} else {
			str = strings.ReplaceAll(str, "$$VMCONTROL$$", `[<span style="color:brown">vm control disabed</span>] <br> you can control when Running / Suspended. <br> try refresh page...`)
		}
		str = strings.ReplaceAll(str, "$$LASTSTARTTIME$$", one.StartTime.Format("2006.01.02 15:04:05 Mon"))
		str = strings.ReplaceAll(str, "$$IMAGE$$", one.ImageIId.NameId)
		str = strings.ReplaceAll(str, "$$SPEC$$", one.VMSpecName)
		str = strings.ReplaceAll(str, "$$VPC$$", one.VpcIID.NameId)
		str = strings.ReplaceAll(str, "$$SUBNET$$", one.SubnetIID.NameId)
		strSRList := ""
		for _, one := range one.SecurityGroupIIds {
			resBody, err := getResource_with_Connection_JsonByte(connConfig, "securitygroup", one.NameId)
			if err != nil {
				cblog.Error(err)
				break
			}
			var secInfo cres.SecurityInfo
			json.Unmarshal(resBody, &secInfo)
			strSRList += "["
			for _, secRuleInfo := range *secInfo.SecurityRules {
				strSRList += "{FromPort:" + secRuleInfo.FromPort + ", "
				strSRList += "ToPort:" + secRuleInfo.ToPort + ", "
				strSRList += "IPProtocol:" + secRuleInfo.IPProtocol + ", "
				strSRList += "Direction:" + secRuleInfo.Direction + ", "
				strSRList += "CIDR:" + secRuleInfo.CIDR
				strSRList += "},<br>"
			}
			strSRList += "]"
		}
		str = strings.ReplaceAll(str, "$$SECURITYGROUP$$", strSRList)
		str = strings.ReplaceAll(str, "$$NETWORKINTERFACE$$", one.NetworkInterface)
		str = strings.ReplaceAll(str, "$$PUBLICIP$$", one.PublicIP)
		str = strings.ReplaceAll(str, "$$PRIVATEIP$$", one.PrivateIP)
		str = strings.ReplaceAll(str, "$$PUBLICDNS$$", one.PublicDNS)
		str = strings.ReplaceAll(str, "$$PRIVATEDNS$$", one.PrivateDNS)
		str = strings.ReplaceAll(str, "$$BOOTDISK$$", one.VMBootDisk)
		str = strings.ReplaceAll(str, "$$BLOCKDISK$$", one.VMBlockDisk)
		str = strings.ReplaceAll(str, "$$SSHACCESSPOINT$$", one.SSHAccessPoint)
		str = strings.ReplaceAll(str, "$$ACCESSKEY$$", one.KeyPairIId.NameId)
		str = strings.ReplaceAll(str, "$$ACCESSUSER$$", one.VMUserId)
		strKeyList := ""
		for _, kv := range one.KeyValueList {
			strKeyList += kv.Key + ":" + kv.Value + ", "
		}
		str = strings.ReplaceAll(str, "$$ADDITIONALINFO$$", strKeyList)
		strData += str
	}
	return strData
}