Index: /branches/rel_apv_10_7_3/usr/click/bin/backend/sys_cmd.c
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/bin/backend/sys_cmd.c	(revision 39037)
+++ /branches/rel_apv_10_7_3/usr/click/bin/backend/sys_cmd.c	(working copy)
@@ -3077,322 +3077,271 @@
 		return ptyrun_ex("ping", ping_path, "ping", "-c", "5", inet_ntoa(in), option) == 0 ? 0 : -1;
 }
 
-
 // AZURE CLOUD FUNCTION START
-void 
-cloud_az_ha_enable() 
+void
+cloud_az_ha_enable()
 {
-	cloud_az_ha_disable();
-
-	FILE *fp;
-	char path[1035];
-	char cmd[1024];
-
-	fp = popen("python3 /ca/bin/azure/SystemRun.py 0 /tmp/az_account az account show", "r");
-	if (fp == NULL) {
-		printf("Fail\n");
-		exit(1);
-	} else {
-		pclose(fp);
-	}
-
-	fp = fopen("/tmp/az_account_0", "r");
-	if (fp == NULL) {
-		printf("Fail\n");
-		return;
-	} else {
-		fclose(fp);
-	}
+    cloud_az_ha_disable();
+    FILE *fp;
+    char cmd[1024];
+    char path[1035];
+    int status;
 
-	// run in background
-	snprintf(cmd, 1024, "python3 /ca/bin/azure/AZFailoverPoller.py -mode 1 &");
-	system(cmd);
+    // Format the command string
+    snprintf(cmd, 1024, "python3 /ca/bin/azure/AZFailoverPoller.py -mode 1 &");
 
+    status = system(cmd);
 	sleep(2);
-	// ret = system("ps aux | grep -v grep | grep -q \"python3 /ca/bin/azure/AZFailoverPoller.py -mode 1\"");
-	// if (ret == -1) {
-	// 	printf("Fail\n");
-	// 	return;
-	// }
-
-	// if (WIFEXITED(ret)) {
-	// 	if (WEXITSTATUS(ret) != 0) {
-	// 		printf("Fail\n");
-	// 	} else {
-	// 		printf("Success\n");
-	// 	}
-	// } else {
-	// 	printf("Fail\n");
-	// }
-
-	fp = popen("python3 /ca/bin/azure/SystemRun.py 1 /tmp/az_ha ps aux '|' grep -v grep '|' grep -q 'python3 /ca/bin/azure/AZFailoverPoller.py -mode 1'", "r");
-	if (fp == NULL) {
-		printf("Fail\n");
-		exit(1);
-	} else {
-		pclose(fp);
-	}
-
-	fp = fopen("/tmp/az_ha_0", "r");
-	if (fp == NULL) {
-		printf("Fail\n");
-		return;
-	} else {
-		fclose(fp);
-	}
-	printf("Success\n");
-
-
-//
-	// fp = popen("python3 /ca/bin/azure/AZFailoverPoller.py -mode 1", "r");
-	// if (fp == NULL) {
-    //     printf("Failed to run command\n" );
-    //     exit(1);
-    // }
-    // while (fgets(path, sizeof(path)-1, fp) != NULL) {
-    //     printf("%s", path);
-    // }
-    // pclose(fp);
-//
+    // Check if the command executed successfully
+    if (status == -1) {
+        // system() failed to start the command
+        printf("Failed to execute \"cloud az ha enable\"\n");
+
+    } else {
+        // Check if the command returned a non-zero status (failure)
+        if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
+		    // Format the command string
+            snprintf(cmd, 1024, "python3 /ca/bin/azure/AZFailoverPoller.py -mode 3");
+            // Run the command and capture the return status
+            fp = popen(cmd, "r");
+            if (fp == NULL) {
+                printf("Failed to execute \"cloud az ha enable\"\n");
+            }
+            while (fgets(path, sizeof(path)-1, fp) != NULL) {
+                path[strcspn(path, "\n")] = 0;
+                // Check if the output is "True"
+                if (strcmp(path, "True\n") == 0 || strcmp(path, "True") == 0) {
+                    printf("Succeed");
+                } else if (strcmp(path, "False\n") == 0 || strcmp(path, "False") == 0) {
+                    printf("Failed to execute \"cloud az ha enable\"\n");
+                } else {
+                    printf("Failed to execute \"cloud az ha enable\"\n");
+                }
+            }
+        } else {
+            printf("Failed to execute \"cloud az ha enable\" with status %d.\n", 3);
+        }
+    }
 }
 
-// void
-// cloud_az_show_ha_enable()
-// {
-// 	if (system("ps aux | grep -v grep | grep -q \"python3 /ca/bin/azure/AZFailoverPoller.py -mode 1\"")) {
-// 		printf("Disable\n");
-// 	} else {
-// 		printf("Enable\n");
-// 	}
-// 	printf("123\n");
-// 	sleep(1);
-// 	printf("456\n");
-// 	return;
-// }
-// Failed to execute "cloud az show ha"
+void
+cloud_az_ha_disable()
+{
+    FILE *fp;
+    char cmd[1024];
+    char path[1035];
+    int status;
+    // system("ps aux | grep 'python3 /ca/bin/azure/AZFailoverPoller.py -mode 1' | grep -v grep | awk '{print $2}' | xargs kill -9");
+    // Format the command string
+    snprintf(cmd, 1024, "python3 /ca/bin/azure/AZFailoverPoller.py -mode 2");
+
+    status = system(cmd);
+    sleep(1);
+    // Check if the command executed successfully
+    if (status == -1) {
+        // system() failed to start the command
+        printf("Failed to execute \"cloud az ha disable\"\n");
+
+    } else {
+        // Check if the command returned a non-zero status (failure)
+        if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
+            // Format the command string
+            snprintf(cmd, 1024, "python3 /ca/bin/azure/AZFailoverPoller.py -mode 3");
+            // Run the command and capture the return status
+            fp = popen(cmd, "r");
+            if (fp == NULL) {
+                printf("Failed to execute \"cloud az ha disable\"\n" );
+            }
+            while (fgets(path, sizeof(path)-1, fp) != NULL) {
+                path[strcspn(path, "\n")] = 0;
+                // Check if the output is "True"
+                if (strcmp(path, "True\n") == 0 || strcmp(path, "True") == 0) {
+                    printf("Failed to execute \"cloud az ha disable\"");
+                } else if (strcmp(path, "False\n") == 0 || strcmp(path, "False") == 0) {
+                    printf("");
+                } else {
+                    printf("Failed to execute \"cloud az ha disable\"");
+                }
+            }
+        } else {
+            printf("Failed to execute \"cloud az ha disable\" with status %d.\n", 3);
+        }
+    }
+}
 
-void 
-cloud_az_ha_disable() 
+void cloud_az_show_ha()
 {
-	FILE *fp;
-	char path[1035];
-	char cmd[1024];
+    FILE *fp;
+    char path[1035];
+    char cmd[1024];
 
-	// snprintf(cmd, 1024, "python3 /ca/bin/azure/AZFailoverPoller.py -mode 2");
-	// system(cmd);
+    fp = popen("python3 /ca/bin/azure/AZFailoverPoller.py -mode 3", "r");
+    if (fp == NULL) {
+        printf("Failed to run command\n");
+        exit(1);
+    }
+    while (fgets(path, sizeof(path)-1, fp) != NULL) {
+        path[strcspn(path, "\n")] = 0;
 
-//
-	// fp = popen("python3 /ca/bin/azure/AZFailoverPoller.py -mode 2", "r");
-	// if (fp == NULL) {
-    //     printf("Failed to run command\n" );
-    //     exit(1);
-    // }
-    // while (fgets(path, sizeof(path)-1, fp) != NULL) {
-    //     printf("%s", path);
-    // }
-    // pclose(fp);
-//
+        // Check if the output is "True"
+        if (strcmp(path, "True\n") == 0 || strcmp(path, "True") == 0) {
+            printf("az ha on");
+        } else if (strcmp(path, "False\n") == 0 || strcmp(path, "False") == 0) {
+            printf("az ha off");
+        } else {
+            printf("Fail");
 
-	system("ps aux | grep 'python3 /ca/bin/azure/AZFailoverPoller.py -mode 1' | grep -v grep | awk '{print $2}' | xargs kill -9");
+        }
+    }
+    pclose(fp);
 }
 
-void 
-cloud_az_udr_enable() 
+void
+cloud_az_udr_enable()
 {
-	cloud_az_udr_disable();
+    cloud_az_udr_disable();
 
-	FILE *fp;
-	char path[1035];
-	char cmd[1024];
+    FILE *fp;
+    char path[1035];
+    char cmd[1024];
 
-	fp = popen("python3 /ca/bin/azure/SystemRun.py 0 /tmp/az_account az account show", "r");
-	if (fp == NULL) {
-		printf("Fail\n");
-		exit(1);
-	} else {
-		pclose(fp);
-	}
+    fp = popen("python3 /ca/bin/azure/SystemRun.py 0 /tmp/az_account az account show", "r");
+    if (fp == NULL) {
+        printf("Failed to execute \"cloud az udr enable\"\n");
+        exit(1);
+    } else {
+        pclose(fp);
+    }
 
-	fp = fopen("/tmp/az_account_0", "r");
-	if (fp == NULL) {
-		printf("Fail\n");
-		return;
-	} else {
-		fclose(fp);
-	}
+    fp = fopen("/tmp/az_account_0", "r");
+    if (fp == NULL) {
+        printf("Failed to execute \"cloud az udr enable\"\n");
+        return;
+    } else {
+        fclose(fp);
+    }
+    // run in background
+    snprintf(cmd, 1024, "python3 /ca/bin/azure/UDRPoller.py -mode 1 &");
+    system(cmd);
+    sleep(2);
 
-	// run in background
-	snprintf(cmd, 1024, "python3 /ca/bin/azure/UDRPoller.py -mode 1 &");
-	system(cmd);
+    fp = popen("python3 /ca/bin/azure/SystemRun.py 1 /tmp/az_udr ps aux '|' grep -v grep '|' grep -q 'python3 /ca/bin/azure/UDRPoller.py -mode 1'", "r");
+    if (fp == NULL) {
+        printf("Failed to execute \"cloud az udr enable\"\n");
+        exit(1);
+    } else {
+        pclose(fp);
+    }
 
-	sleep(2);
-	// ret = system("ps aux | grep -v grep | grep -q \"python3 /ca/bin/azure/UDRPoller.py -mode 1\"");
-	// if (ret == -1) {
-	// 	printf("Fail\n");
-	// 	return;
-	// }
-
-	// if (WIFEXITED(ret)) {
-	// 	if (WEXITSTATUS(ret) != 0) {
-	// 		printf("Fail\n");
-	// 	} else {
-	// 		printf("Success\n");
-	// 	}
-	// } else {
-	// 	printf("Fail\n");
-	// }
+    fp = fopen("/tmp/az_udr_0", "r");
+    if (fp == NULL) {
+        printf("Failed to execute \"cloud az udr enable\"\n");
+        return;
+    } else {
+        fclose(fp);
+    }
+    printf("Success\n");
 
-	fp = popen("python3 /ca/bin/azure/SystemRun.py 1 /tmp/az_udr ps aux '|' grep -v grep '|' grep -q 'python3 /ca/bin/azure/UDRPoller.py -mode 1'", "r");
-	if (fp == NULL) {
-		printf("Fail\n");
-		exit(1);
-	} else {
-		pclose(fp);
-	}
+}
 
-	fp = fopen("/tmp/az_udr_0", "r");
-	if (fp == NULL) {
-		printf("Fail\n");
-		return;
-	} else {
-		fclose(fp);
-	}
-	printf("Success\n");
+void
+cloud_az_udr_disable()
+{
+    FILE *fp;
+    char path[1035];
+    char cmd[1024];
+    int status;
 
-//
-	// fp = popen("python3 /ca/bin/azure/AZFailoverPoller.py -mode 1", "r");
-	// if (fp == NULL) {
-    //     printf("Failed to run command\n" );
-    //     exit(1);
-    // }
-    // while (fgets(path, sizeof(path)-1, fp) != NULL) {
-    //     printf("%s", path);
-    // }
-    // pclose(fp);
-//
+    snprintf(cmd, 1024, "python3 /ca/bin/azure/AZFailoverPoller.py -mode 2");
+    status = system(cmd);
 }
 
-// void
-// cloud_az_show_udr_enable()
-// {
-// 	if (system("ps aux | grep -v grep | grep -q \"python3 /ca/bin/azure/UDRPoller.py -mode 1\"")) {
-// 		printf("Disable\n");
-// 	} else {
-// 		printf("Enable\n");
-// 	}
-// }
-
-void 
-cloud_az_udr_disable() 
+void
+cloud_az_login()
 {
-	FILE *fp;
-	char path[1035];
-	char cmd[1024];
-
-	// snprintf(cmd, 1024, "python3 /ca/bin/azure/AZFailoverPoller.py -mode 2");
-	// system(cmd);
+    FILE *fp = NULL;
+    char path[1035];
+    char cmd[1024];
+    char buffer[1024];
+    size_t bytesRead;
 
-//
-	// fp = popen("python3 /ca/bin/azure/AZFailoverPoller.py -mode 2", "r");
-	// if (fp == NULL) {
-    //     printf("Failed to run command\n" );
-    //     exit(1);
-    // }
-    // while (fgets(path, sizeof(path)-1, fp) != NULL) {
-    //     printf("%s", path);
-    // }
-    // pclose(fp);
-//
+    // check and delete file first
 
-	system("ps aux | grep 'python3 /ca/bin/azure/UDRPoller.py -mode 1' | grep -v grep | awk '{print $2}' | xargs kill -9");
-}
+    // First File
+    fp = fopen("/tmp/login_msg.txt", "r");
+    if (fp != NULL) {
+        fclose(fp);
+        snprintf(cmd, 1024, "rm -rf /tmp/login_msg.txt");
+        system(cmd);
+        fp = NULL;
+    }
 
-void 
-cloud_az_login() 
-{
-	FILE *fp = NULL;
-	char path[1035];
-	char cmd[1024];
-	char buffer[1024];
-	size_t bytesRead;
+    //Second File
+    fp = fopen("/tmp/login_response.txt", "r");
+    if (fp != NULL) {
+        fclose(fp);
+        snprintf(cmd, 1024, "rm -rf /tmp/login_response.txt");
+        system(cmd);
+        fp = NULL;
+    }
 
-// check and delete file first
+    snprintf(cmd, 1024, "python3 /ca/bin/azure/AZAuthManager.py -mode login &");
+    system(cmd);
 
-	// First File
-	fp = fopen("/tmp/login_msg.txt", "r");
-	if (fp != NULL) {
-		fclose(fp);
-		snprintf(cmd, 1024, "rm -rf /tmp/login_msg.txt");
-		system(cmd);
-		fp = NULL;
-	}
+    printf("Your authentication code will expire in 60 seconds.\nPlease use the following information to sign in immediately.\n");
+    int count = 0;
 
-	//Second File
-	fp = fopen("/tmp/login_response.txt", "r");
-	if (fp != NULL) {
-		fclose(fp);
-		snprintf(cmd, 1024, "rm -rf /tmp/login_response.txt");
-		system(cmd);
-		fp = NULL;
-	}
+    // read the tmp file from Mary
+    while(fp == NULL && count < 60) {
+        fp = fopen("/tmp/login_msg.txt", "r");
+        sleep(1);
+        count++;
+    }
 
-	snprintf(cmd, 1024, "python3 /ca/bin/azure/AZAuthManager.py -mode login &");
-	system(cmd);
+    if (fp != NULL) {
+        fclose(fp);
+        sleep(3);
+        fp = fopen("/tmp/login_msg.txt", "r");
+    }
 
-	printf("Please login using the above information in 1 minute.\nAfter 1 minute the login credential will be clear.\n");
-	int count = 0;
+    if (fp != NULL) {
+        while (fgets(buffer, sizeof(buffer), fp) != NULL) {
+            printf("%s", buffer);
+        }
 
-	// read the tmp file from Mary
-	while(fp == NULL && count < 60) {
-		fp = fopen("/tmp/login_msg.txt", "r");
-		sleep(1);
-		count++;
-	}
+        fclose(fp);
+    }
 
-	if (fp != NULL) {
-		fclose(fp);
-		sleep(3);
-		fp = fopen("/tmp/login_msg.txt", "r");
-	}
-	
-	if (fp != NULL) {
-		while (fgets(buffer, sizeof(buffer), fp) != NULL) {
-        	printf("%s", buffer);
-		}
+    fp = NULL;
 
-		fclose(fp);
-	}
-    
-	fp = NULL;
+    // read the second file from Mary
+    while(fp == NULL && count < 60) {
+        fp = fopen("/tmp/login_response.txt", "r");
+        sleep(1);
+        count++;
+    }
 
-	// read the second file from Mary
-	while(fp == NULL && count < 60) {
-		fp = fopen("/tmp/login_response.txt", "r");
-		sleep(1);
-		count++;
-	}
+    if (fp != NULL) {
+        fclose(fp);
+        sleep(3);
+        fp = fopen("/tmp/login_response.txt", "r");
+    }
 
-	if (fp != NULL) {
-		fclose(fp);
-		sleep(3);
-		fp = fopen("/tmp/login_response.txt", "r");
-	}
+    if (fp == NULL) {
+        fp = fopen("/tmp/login_response.txt", "r");
+    }
 
-	if (fp == NULL) {
-		fp = fopen("/tmp/login_response.txt", "r");
-	}
-	
-	if (fp != NULL) {
-		while (fgets(buffer, sizeof(buffer), fp) != NULL) {
-			printf("%s", buffer);
-		}
+    if (fp != NULL) {
+        while (fgets(buffer, sizeof(buffer), fp) != NULL) {
+            printf("%s", buffer);
+        }
 
-		fclose(fp);
-	}
+        fclose(fp);
+    }
 
-	system("ps aux | grep 'az login' | grep -v grep | awk '{print $2}' | xargs kill -9");
-	system("ps aux | grep 'python3 -sm azure.cli login' | grep -v grep | awk '{print $2}' | xargs kill -9");
-	system("ps aux | grep 'python3 /ca/bin/azure/AZAuthManager.py -mode login' | grep -v grep | awk '{print $2}' | xargs kill -9");
+    system("ps aux | grep 'az login' | grep -v grep | awk '{print $2}' | xargs kill -9");
+    system("ps aux | grep 'python3 -sm azure.cli login' | grep -v grep | awk '{print $2}' | xargs kill -9");
+    system("ps aux | grep 'python3 /ca/bin/azure/AZAuthManager.py -mode login' | grep -v grep | awk '{print $2}' | xargs kill -9");
 }
 
 
@@ -3402,8 +3351,8 @@
     FILE *fp;
     char path[1035];
     char cmd[1024];
- 
-// delete output file
+
+    // delete output file
     fp = popen("/tmp/output.txt", "r");
     if (fp != NULL) {
         snprintf(cmd, 1024, "rm -rf /tmp/output.txt");
@@ -3503,64 +3452,49 @@
 		}
 		fclose(fp);
 	}
+}
 
-	// fp = popen("az account show", "r");
-	// if (fp == NULL) {
-	// 	printf("Please run 'cloud az login' to setup account. 2");
-	// 	return;
-	// } else {
-	// 	while (fgets(path, sizeof(path)-1, fp) != NULL) {
-	// 		printf("%s", path);
-	// 	}
-	// 	pclose(fp);
-	// }
-
-
+void cloud_az_failover_trigger()
+{
+    FILE *fp;
+    char path[1035];
+    char cmd[1024];
 
+    fp = popen("python3 /ca/bin/azure/AZFailoverManager.py -mode 1", "r");
+    if (fp == NULL) {
+        printf("Failed to run command\n" );
+        exit(1);
+    }
+    while (fgets(path, sizeof(path)-1, fp) != NULL) {
+        printf("%s", path);
+    }
+    pclose(fp);
+}
 
-	// int ret = system("az account show");
-	// printf("1: %d\n", ret);
-	// if (ret == -1) {
-	// 	printf("Please run 'cloud az login' to setup account. 1");
-	// 	return;
-	// }
-
-	// if (WIFEXITED(ret)) {
-	// 	printf("2: %d\n", WEXITSTATUS(ret));
-	// 	if (WEXITSTATUS(ret) != 0) {
-	// 		printf("Please run 'cloud az login' to setup account. 2");
-	// 		return;
-	// 	}
-	// } else {
-	// 	printf("Please run 'cloud az login' to setup account. 3");
-	// 	return;
-	// }
-	
-	// fp = popen("az account show", "r");
-	// if (fp == NULL) {
-	// 	printf("Please run 'cloud az login' to setup account.");
-	// 	exit(1);
-	// } else {
-	// 	while (fgets(path, sizeof(path)-1, fp) != NULL) {
-	// 		printf("%s", path);
-	// 	}
-	// 	pclose(fp);
-	// }
-//
+void cloud_az_set_log_on()
+{
+    FILE *fp;
+    char path[1035];
+    char cmd[1024];
+    snprintf(cmd, 1024, "python3 /ca/bin/azure/LoggerManager.py -mode on");
+    fp = popen(cmd, "r");
+    if (fp == NULL) {
+        printf("Failed to run command\n" );
+        exit(1);
+    }
+    while (fgets(path, sizeof(path)-1, fp) != NULL) {
+        printf("%s", path);
+    }
+    pclose(fp);
 }
 
-void 
-cloud_az_failover_trigger() 
+void cloud_az_set_log_off()
 {
 	FILE *fp;
 	char path[1035];
 	char cmd[1024];
-
-	// snprintf(cmd, 1024, "python3 /ca/bin/azure/AZFailoverManager.py -mode 1");
-	// system(cmd);
-
-//
-	fp = popen("python3 /ca/bin/azure/AZFailoverManager.py -mode 1", "r");
+	snprintf(cmd, 1024, "python3 /ca/bin/azure/LoggerManager.py -mode off");
+	fp = popen(cmd, "r");
 	if (fp == NULL) {
         printf("Failed to run command\n" );
         exit(1);
@@ -3569,22 +3503,43 @@
         printf("%s", path);
     }
     pclose(fp);
-//
 }
 
-void 
-cloud_az_failover_recover() 
+void cloud_az_show_log_config()
 {
 	FILE *fp;
 	char path[1035];
 	char cmd[1024];
+	snprintf(cmd, 1024, "python3 /ca/bin/azure/LoggerManager.py -mode status");
+	fp = popen(cmd, "r");
+	if (fp == NULL) {
+        printf("Failed to run command\n" );
+        exit(1);
+    }
+    while (fgets(path, sizeof(path)-1, fp) != NULL) {
+        path[strcspn(path, "\n")] = 0;
 
-	// snprintf(cmd, 1024, "python3 /ca/bin/azure/AZFailoverManager.py -mode 2");
-	// system(cmd);
+        // Check if the output is "True"
+        if (strcmp(path, "True\n") == 0 || strcmp(path, "True") == 0) {
+            printf("az log on");
+        } else if (strcmp(path, "False\n") == 0 || strcmp(path, "False") == 0) {
+			printf("az log off");
+        } else {
+			exit(1);
+		}
+    }
+    pclose(fp);
 
-//
-	fp = popen("python3 /ca/bin/azure/AZFailoverManager.py -mode 2", "r");
-	if (fp == NULL) {
+}
+
+void cloud_az_show_log_buffer(uint32_t number_of_line)
+{
+    FILE *fp;
+    char path[1035];
+    char cmd[1024];
+    snprintf(cmd, 1024, "python3 /ca/bin/azure/LoggerManager.py -mode show -lines %d", number_of_line);
+    fp = popen(cmd, "r");
+    if (fp == NULL) {
         printf("Failed to run command\n" );
         exit(1);
     }
@@ -3592,20 +3547,14 @@
         printf("%s", path);
     }
     pclose(fp);
-//
 }
 
-void 
-cloud_az_set_nicconfig(char *subscription_id, char *resource_group_name, char *from_nic_name, char *to_nic_name) 
+void cloud_az_show_log_loglevel()
 {
 	FILE *fp;
 	char path[1035];
 	char cmd[1024];
-
-	snprintf(cmd, 1024, "python3 /ca/bin/azure/ConfigManager.py -mode set -sub_id %s -res_grp_name %s -src_nic_name %s -dest_nic_name %s", 
-			subscription_id, resource_group_name, from_nic_name, to_nic_name);
-	// system(cmd);
-
+	snprintf(cmd, 1024, "python3 /ca/bin/azure/LoggerManager.py -level status");
 	fp = popen(cmd, "r");
 	if (fp == NULL) {
         printf("Failed to run command\n" );
@@ -3617,17 +3566,12 @@
     pclose(fp);
 }
 
-void 
-cloud_az_set_udrconfig(char *subscription_id, char *resource_group_name, char *vm_name, char *ip_running, char *ip_deallocating) 
+void cloud_az_loglevel_debug()
 {
 	FILE *fp;
 	char path[1035];
 	char cmd[1024];
-
-	snprintf(cmd, 1024, "python3 /ca/bin/azure/RouteConfigManager.py -mode set -sub_id %s -res_grp_name %s -vm_name %s -ip_running %s -ip_deallocating %s", 
-			subscription_id, resource_group_name, vm_name, ip_running, ip_deallocating);
-	// system(cmd);
-
+	snprintf(cmd, 1024, "python3 /ca/bin/azure/LoggerManager.py -level debug");
 	fp = popen(cmd, "r");
 	if (fp == NULL) {
         printf("Failed to run command\n" );
@@ -3639,18 +3583,47 @@
     pclose(fp);
 }
 
-void 
-cloud_az_clear_nicconfig() 
+void cloud_az_loglevel_info()
 {
 	FILE *fp;
 	char path[1035];
 	char cmd[1024];
+	snprintf(cmd, 1024, "python3 /ca/bin/azure/LoggerManager.py -level info");
+	fp = popen(cmd, "r");
+	if (fp == NULL) {
+        printf("Failed to run command\n" );
+        exit(1);
+    }
+    while (fgets(path, sizeof(path)-1, fp) != NULL) {
+        printf("%s", path);
+    }
+    pclose(fp);
+}
 
-	// snprintf(cmd, 1024, "python3 /ca/bin/azure/ConfigManager.py -mode clear");
-	// system(cmd);
+void cloud_az_loglevel_warning()
+{
+	FILE *fp;
+	char path[1035];
+	char cmd[1024];
+	snprintf(cmd, 1024, "python3 /ca/bin/azure/LoggerManager.py -level warning");
+	fp = popen(cmd, "r");
+	if (fp == NULL) {
+        printf("Failed to run command\n" );
+        exit(1);
+    }
+    while (fgets(path, sizeof(path)-1, fp) != NULL) {
+        printf("%s", path);
+    }
+    pclose(fp);
+}
 
-//
-	fp = popen("python3 /ca/bin/azure/ConfigManager.py -mode clear", "r");
+void cloud_az_loglevel_error()
+{
+	FILE *fp;
+	char path[1035];
+	char cmd[1024];
+	snprintf(cmd, 1024, "python3 /ca/bin/azure/LoggerManager.py -level error");
+	fp = popen(cmd, "r");
 	if (fp == NULL) {
         printf("Failed to run command\n" );
         exit(1);
@@ -3659,21 +3632,20 @@
         printf("%s", path);
     }
     pclose(fp);
-//
 }
 
-void 
-cloud_az_show_nicconfig() 
+void
+cloud_az_failover_recover()
 {
 	FILE *fp;
 	char path[1035];
 	char cmd[1024];
 
-	// snprintf(cmd, 1024, "python3 /ca/bin/azure/ConfigManager.py -mode show");
+	// snprintf(cmd, 1024, "python3 /ca/bin/azure/AZFailoverManager.py -mode 2");
 	// system(cmd);
 
 //
-	fp = popen("python3 /ca/bin/azure/ConfigManager.py -mode show", "r");
+	fp = popen("python3 /ca/bin/azure/AZFailoverManager.py -mode 2", "r");
 	if (fp == NULL) {
         printf("Failed to run command\n" );
         exit(1);
@@ -3685,18 +3657,101 @@
 //
 }
 
-void 
-cloud_az_clear_udrconfig() 
+void
+cloud_az_set_nicconfig(char *subscription_id, char *resource_group_name, char *from_nic_name, char *to_nic_name)
 {
 	FILE *fp;
 	char path[1035];
 	char cmd[1024];
 
-	// snprintf(cmd, 1024, "python3 /ca/bin/azure/ConfigManager.py -mode clear");
-	// system(cmd);
+	snprintf(cmd, 1024, "ps aux | grep -v grep | grep 'python3 /ca/bin/azure/AZFailoverPoller.py -mode 1' | wc -l");
+	fp = popen(cmd, "r");
+	if (fp != NULL) {
+		fgets(path, sizeof(path)-1, fp);
+		if (path[0] == '0') {
+			snprintf(cmd, 1024, "python3 /ca/bin/azure/ConfigManager.py -mode set -sub_id %s -res_grp_name %s -src_nic_name %s -dest_nic_name %s",
+				subscription_id, resource_group_name, from_nic_name, to_nic_name);
+			fp = popen(cmd, "r");
+			if (fp == NULL) {
+				printf("Failed to run command\n" );
+				exit(1);
+			}
+			while (fgets(path, sizeof(path)-1, fp) != NULL) {
+				printf("%s", path);
+			}
+			pclose(fp);
+		} else {
+			printf("Please execute \"cloud az ha disable\" first.");
+		}
+	}
+}
 
-//
-	fp = popen("python3 /ca/bin/azure/RouteConfigManager.py -mode clear", "r");
+void
+cloud_az_set_udrconfig(char *subscription_id, char *resource_group_name, char *vm_name, char *ip_running, char *ip_deallocating)
+{
+	FILE *fp;
+	char path[1035];
+	char cmd[1024];
+
+	snprintf(cmd, 1024, "ps aux | grep -v grep | grep 'python3 /ca/bin/azure/UDRPoller.py -mode 1' | wc -l");
+	fp = popen(cmd, "r");
+	if (fp != NULL) {
+		fgets(path, sizeof(path)-1, fp);
+		if (path[0] == '0') {
+			snprintf(cmd, 1024, "python3 /ca/bin/azure/RouteConfigManager.py -mode set -sub_id %s -res_grp_name %s -vm_name %s -ip_running %s -ip_deallocating %s",
+				subscription_id, resource_group_name, vm_name, ip_running, ip_deallocating);
+			fp = popen(cmd, "r");
+			if (fp == NULL) {
+				printf("Failed to run command\n" );
+				exit(1);
+			}
+			while (fgets(path, sizeof(path)-1, fp) != NULL) {
+				printf("%s", path);
+			}
+			pclose(fp);
+		} else {
+			printf("Please execute \"cloud az udr disable\" first.");
+		}
+	}
+}
+
+void
+cloud_az_clear_nicconfig(uint32_t idx)
+{
+	FILE *fp;
+	char path[1035];
+	char cmd[1024];
+
+	snprintf(cmd, 1024, "ps aux | grep -v grep | grep 'python3 /ca/bin/azure/AZFailoverPoller.py -mode 1' | wc -l");
+	fp = popen(cmd, "r");
+	if (fp != NULL) {
+		fgets(path, sizeof(path)-1, fp);
+		if (path[0] == '0') {
+			snprintf(cmd, 1024, "python3 /ca/bin/azure/ConfigManager.py -mode clear -index %d", idx);
+			fp = popen(cmd, "r");
+			if (fp == NULL) {
+				printf("Failed to run command\n" );
+				exit(1);
+			}
+			while (fgets(path, sizeof(path)-1, fp) != NULL) {
+				printf("%s", path);
+			}
+			pclose(fp);
+		} else {
+			printf("Please execute \"cloud az ha disable\" first.");
+		}
+	}
+}
+
+void
+cloud_az_show_nicconfig(uint32_t idx)
+{
+	FILE *fp;
+	char path[1035];
+	char cmd[1024];
+
+	snprintf(cmd, 1024, "python3 /ca/bin/azure/ConfigManager.py -mode show -index %d", idx);
+	fp = popen(cmd, "r");
 	if (fp == NULL) {
         printf("Failed to run command\n" );
         exit(1);
@@ -3705,21 +3760,45 @@
         printf("%s", path);
     }
     pclose(fp);
-//
 }
 
-void 
-cloud_az_show_udrconfig() 
+void
+cloud_az_clear_udrconfig(uint32_t idx)
 {
 	FILE *fp;
 	char path[1035];
 	char cmd[1024];
 
-	// snprintf(cmd, 1024, "python3 /ca/bin/azure/ConfigManager.py -mode show");
-	// system(cmd);
+	snprintf(cmd, 1024, "ps aux | grep -v grep | grep 'python3 /ca/bin/azure/UDRPoller.py -mode 1' | wc -l");
+	fp = popen(cmd, "r");
+	if (fp != NULL) {
+		fgets(path, sizeof(path)-1, fp);
+		if (path[0] == '0') {
+			snprintf(cmd, 1024, "python3 /ca/bin/azure/RouteConfigManager.py -mode clear -index %d", idx);
+			fp = popen(cmd, "r");
+			if (fp == NULL) {
+				printf("Failed to run command\n" );
+				exit(1);
+			}
+			while (fgets(path, sizeof(path)-1, fp) != NULL) {
+				printf("%s", path);
+			}
+			pclose(fp);
+		} else {
+			printf("Please execute \"cloud az udr disable\" first.");
+		}
+	}
+}
 
-//
-	fp = popen("python3 /ca/bin/azure/RouteConfigManager.py -mode show", "r");
+void
+cloud_az_show_udrconfig(uint32_t idx)
+{
+	FILE *fp;
+	char path[1035];
+	char cmd[1024];
+
+	snprintf(cmd, 1024, "python3 /ca/bin/azure/RouteConfigManager.py -mode show -index %d", idx);
+	fp = popen(cmd, "r");
 	if (fp == NULL) {
         printf("Failed to run command\n" );
         exit(1);
@@ -3728,7 +3807,6 @@
         printf("%s", path);
     }
     pclose(fp);
-//
 }
 
 // AZURE CLOUD FUNCTION END
Index: /branches/rel_apv_10_7_3/usr/click/lib/libparser/commands.pm
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/lib/libparser/commands.pm	(revision 39037)
+++ /branches/rel_apv_10_7_3/usr/click/lib/libparser/commands.pm	(working copy)
@@ -463,6 +463,19 @@
 		function_args => [],
 	},
 
+	# cloud az show ha
+
+	{
+		obj_type => "ITEM",
+		name => "ha",
+		menu => "root_cloud_azure_show",
+		help_string => "Show Azure ha status",
+		cmd_attribute => "CMD_ARRAYOS|CMD_SPROXY|CMD_NORMAL|CMD_KILLABLE|CMD_NON_MORE",
+		user_level => "CLI_LEVEL_CONFIG",
+		function_name => "cloud_az_show_ha",
+		function_args => [],
+	},
+
     # cloud az udr
 
 	{
@@ -539,7 +552,19 @@
 		help_string => "Display Cloud Azure Show decision",
 	},
 
-	# cloud az show status
+	# cloud az show log
+
+	{
+		obj_type => "MENU",
+		name => "log",
+		parent_menu => "root_cloud_azure_show",
+		uniq_name => "root_cloud_azure_show_log",
+		cmd_attribute => "CMD_ARRAYOS|CMD_SPROXY|CMD_NORMAL",
+		user_level => "CLI_LEVEL_CONFIG",
+		help_string => "Display Cloud Azure log and status",
+	},
+
+	# cloud az show subscription
 
 	{
 		obj_type => "ITEM",
@@ -608,35 +633,32 @@
 		obj_type => "ITEM",
 		name => "nicconfig",
 		menu => "root_cloud_azure_set",
-		cmd_attribute => "CMD_ARRAYOS|CMD_SPROXY|CMD_NORMAL|CMD_KILLABLE|CMD_NON_MORE",	
+		cmd_attribute => "CMD_ARRAYOS|CMD_SPROXY|CMD_NORMAL|CMD_KILLABLE|CMD_NON_MORE",
 		user_level => "CLI_LEVEL_CONFIG",
 		help_string => "Set the configuration of NIC",
 		function_name => "cloud_az_set_nicconfig",
 		function_args => [
-								 {
-                                        type => "STRING",
-										help_string => "Enter subscription ID: ",
-                                        optional => "NO",
-
-                                 }, 
-   								 {
-                                        type => "STRING",
-										help_string => "Enter resource group name: ",
-                                        optional => "NO",
-                                 }, 
-								 {
-                                        type => "STRING",
-										help_string => "Enter NIC name of the primary machine: ",
-                                        optional => "NO",
-
-                                 }, 
-								 {
-                                        type => "STRING",
-										help_string => "Enter NIC name of the secondary machine: ",
-                                        optional => "NO",
-
-                                 }, 
-				 		 ],
+			{
+				type => "STRING",
+				help_string => "Subscription ID",
+				optional => "NO",
+			},
+			{
+				type => "STRING",
+				help_string => "Resource Group Name",
+				optional => "NO",
+			},
+			{
+				type => "STRING",
+				help_string => "NIC name of the active APV",
+				optional => "NO",
+			},
+			{
+				type => "STRING",
+				help_string => "NIC name of the standby APV",
+				optional => "NO",
+			},
+		],
 	},
 
     # cloud az set udrconfig
@@ -645,59 +667,80 @@
 		obj_type => "ITEM",
 		name => "udrconfig",
 		menu => "root_cloud_azure_set",
-		cmd_attribute => "CMD_ARRAYOS|CMD_SPROXY|CMD_NORMAL|CMD_KILLABLE|CMD_NON_MORE",	
+		cmd_attribute => "CMD_ARRAYOS|CMD_SPROXY|CMD_NORMAL|CMD_KILLABLE|CMD_NON_MORE",
 		user_level => "CLI_LEVEL_CONFIG",
 		help_string => "Set the configuration of UDR",
 		function_name => "cloud_az_set_udrconfig",
 		function_args => [
-								 {
-                                        type => "STRING",
-										help_string => "Enter subscription ID: ",
-                                        optional => "NO",
-
-                                 }, 
-   								 {
-                                        type => "STRING",
-										help_string => "Enter resource group name: ",
-                                        optional => "NO",
-                                 }, 
-                                 {
-                                        type => "STRING",
-										help_string => "Enter vm name: ",
-                                        optional => "NO",
-                                 }, 
-								 {
-                                        type => "IPADDR",
-										help_string => "Enter ip of set on UDR while monitored vm is up: ",
-                                        optional => "NO",
-
-                                 }, 
-								 {
-                                        type => "IPADDR",
-										help_string => "Enterip of set on UDR while monitored vm is down: ",
-                                        optional => "NO",
-
-                                 }, 
-				 		 ],
+			{
+				type => "STRING",
+				help_string => "Subscription ID",
+				optional => "NO",
+			},
+			{
+				type => "STRING",
+				help_string => "Resource Group Name",
+				optional => "NO",
+			},
+			{
+				type => "STRING",
+				help_string => "Virtual Machine Name",
+				optional => "NO",
+			},
+			{
+				type => "IPADDR",
+				help_string => "The IP address in UDR when monitored virtual machine is up",
+				optional => "NO",
+			},
+			{
+				type => "IPADDR",
+				help_string => "The IP address in UDR when monitored virtual machine is down",
+				optional => "NO",
+			},
+		],
 	},
 
     # cloud az set subscription
+
 	{
 		obj_type => "ITEM",
 		name => "subscription",
 		menu => "root_cloud_azure_set",
-		cmd_attribute => "CMD_ARRAYOS|CMD_SPROXY|CMD_NORMAL|CMD_KILLABLE|CMD_NON_MORE",	
+		cmd_attribute => "CMD_ARRAYOS|CMD_SPROXY|CMD_NORMAL|CMD_KILLABLE|CMD_NON_MORE",
 		user_level => "CLI_LEVEL_CONFIG",
 		help_string => "Set the subscription of azure",
 		function_name => "cloud_az_set_subscription",
 		function_args => [
-								 {
-                                        type => "STRING",
-										help_string => "subscription ID: ",
-                                        optional => "NO",
+							{
+								type => "STRING",
+								help_string => "subscription ID: ",
+								optional => "NO",
+							},
+						],
+	},
+
+	# cloud az set log
 
-                                 }, 
-				 		 ],
+	{
+		obj_type => "MENU",
+		name => "log",
+		parent_menu => "root_cloud_azure_set",
+		uniq_name => "root_cloud_azure_set_log",
+		cmd_attribute => "CMD_ARRAYOS|CMD_SPROXY|CMD_NORMAL",
+		user_level => "CLI_LEVEL_CONFIG",
+		help_string => "Set the status of the log functionality",
+	},
+
+	# cloud az set loglevel
+
+	{
+		obj_type => "MENU",
+		name => "loglevel",
+		parent_menu => "root_cloud_azure_set",
+		uniq_name => "root_cloud_azure_set_loglevel",
+		cmd_attribute => "CMD_ARRAYOS|CMD_SPROXY|CMD_NORMAL",
+		user_level => "CLI_LEVEL_CONFIG",
+		help_string => "Set the severity of the log functionality",
 	},
 
 	# cloud az clear
@@ -718,11 +761,18 @@
 		obj_type => "ITEM",
 		name => "nicconfig",
 		menu => "root_cloud_azure_clear",
-		cmd_attribute => "CMD_ARRAYOS|CMD_SPROXY|CMD_NORMAL|CMD_KILLABLE|CMD_NON_MORE",	
+		cmd_attribute => "CMD_ARRAYOS|CMD_SPROXY|CMD_NORMAL|CMD_KILLABLE|CMD_NON_MORE",
 		user_level => "CLI_LEVEL_CONFIG",
 		help_string => "Clear the configuration of NIC",
 		function_name => "cloud_az_clear_nicconfig",
-		function_args => [],
+		function_args => [
+			{
+				type => "U32",
+				help_string => "Index of the NIC configuration to delete (default: 0, to delete all)",
+				optional => "YES",
+				default_value => "0",
+			}
+		],
 	},
 
 	# cloud az show nicconfig
@@ -731,37 +781,37 @@
 		obj_type => "ITEM",
 		name => "nicconfig",
 		menu => "root_cloud_azure_show",
-		cmd_attribute => "CMD_ARRAYOS|CMD_SPROXY|CMD_NORMAL|CMD_KILLABLE|CMD_NON_MORE",	
+		cmd_attribute => "CMD_ARRAYOS|CMD_SPROXY|CMD_NORMAL|CMD_KILLABLE|CMD_NON_MORE",
 		user_level => "CLI_LEVEL_CONFIG",
 		help_string => "Show the configuration of NIC",
 		function_name => "cloud_az_show_nicconfig",
-		function_args => [],
+		function_args => [
+			{
+				type => "U32",
+				help_string => "Index of the NIC configuration to display (default: 0, to display all)",
+				optional => "YES",
+				default_value => "0",
+			}
+		],
 	},
 
-	# # cloud az show ha_enable
-
-	# {
-	# 	obj_type => "ITEM",
-	# 	name => "ha",
-	# 	menu => "root_cloud_azure_show",
-	# 	cmd_attribute => "CMD_ARRAYOS|CMD_SPROXY|CMD_NORMAL|CMD_KILLABLE|CMD_NON_MORE",	
-	# 	user_level => "CLI_LEVEL_CONFIG",
-	# 	help_string => "Show the ha status of Azure",
-	# 	function_name => "cloud_az_show_ha_enable",
-	# 	function_args => [],
-	# },
-
-    # cloud az clear udrconfig
 
 	{
 		obj_type => "ITEM",
 		name => "udrconfig",
 		menu => "root_cloud_azure_clear",
-		cmd_attribute => "CMD_ARRAYOS|CMD_SPROXY|CMD_NORMAL|CMD_KILLABLE|CMD_NON_MORE",	
+		cmd_attribute => "CMD_ARRAYOS|CMD_SPROXY|CMD_NORMAL|CMD_KILLABLE|CMD_NON_MORE",
 		user_level => "CLI_LEVEL_CONFIG",
 		help_string => "Clear the configuration of UDR",
 		function_name => "cloud_az_clear_udrconfig",
-		function_args => [],
+		function_args => [
+			{
+				type => "U32",
+				help_string => "Index of the UDR configuration to delete (default: 0, to delete all)",
+				optional => "YES",
+				default_value => "0",
+			}
+		],
 	},
 
 	# cloud az show udrconfig
@@ -770,28 +820,171 @@
 		obj_type => "ITEM",
 		name => "udrconfig",
 		menu => "root_cloud_azure_show",
-		cmd_attribute => "CMD_ARRAYOS|CMD_SPROXY|CMD_NORMAL|CMD_KILLABLE|CMD_NON_MORE",	
+		cmd_attribute => "CMD_ARRAYOS|CMD_SPROXY|CMD_NORMAL|CMD_KILLABLE|CMD_NON_MORE",
 		user_level => "CLI_LEVEL_CONFIG",
 		help_string => "Show the configuration of UDR",
 		function_name => "cloud_az_show_udrconfig",
+		function_args => [
+			{
+				type => "U32",
+				help_string => "Index of the UDR configuration to display (default: 0, to display all)",
+				optional => "YES",
+				default_value => "0",
+			}
+		],
+	},
+
+    # cloud az log
+
+	{
+		obj_type => "MENU",
+		name => "log",
+		parent_menu => "root_cloud_azure",
+		uniq_name => "root_cloud_azure_log",
+		cmd_attribute => "CMD_ARRAYOS|CMD_SPROXY|CMD_NORMAL",
+		user_level => "CLI_LEVEL_CONFIG",
+		help_string => "Set the status of the log functionality",
+	},
+
+    # cloud az log on
+
+	{
+		obj_type => "ITEM",
+		name => "on",
+		menu => "root_cloud_azure_log",
+		help_string => "Enable both Failover and Recover function in Azure",
+		cmd_attribute => "CMD_ARRAYOS|CMD_SPROXY|CMD_NORMAL|CMD_KILLABLE|CMD_NON_MORE",
+		user_level => "CLI_LEVEL_CONFIG",
+		function_name => "cloud_az_set_log_on",
 		function_args => [],
 	},
 
-	# # cloud az show udr_enable
+	# cloud az log off
 
-	# {
-	# 	obj_type => "ITEM",
-	# 	name => "udr",
-	# 	menu => "root_cloud_azure_show",
-	# 	cmd_attribute => "CMD_ARRAYOS|CMD_SPROXY|CMD_NORMAL|CMD_KILLABLE|CMD_NON_MORE",	
-	# 	user_level => "CLI_LEVEL_CONFIG",
-	# 	help_string => "Show the UDR status of Azure",
-	# 	function_name => "cloud_az_show_udr_enable",
-	# 	function_args => [],
-	# },
+	{
+		obj_type => "ITEM",
+		name => "off",
+		menu => "root_cloud_azure_log",
+		help_string => "Disable both Failover and Recover function in Azure",
+		cmd_attribute => "CMD_ARRAYOS|CMD_SPROXY|CMD_NORMAL|CMD_KILLABLE|CMD_NON_MORE",
+		user_level => "CLI_LEVEL_CONFIG",
+		function_name => "cloud_az_set_log_off",
+		function_args => [],
+	},
+
+	# cloud az show log config
+
+	{
+		obj_type => "ITEM",
+		name => "config",
+		menu => "root_cloud_azure_show_log",
+		cmd_attribute => "CMD_ARRAYOS|CMD_SPROXY|CMD_NORMAL|CMD_KILLABLE|CMD_NON_MORE",
+		user_level => "CLI_LEVEL_CONFIG",
+		help_string => "Check Azure CLI log functionality status",
+		function_name => "cloud_az_show_log_config",
+		function_args => [],
+	},
+
+	# cloud az show log buffer
+
+	{
+		obj_type => "ITEM",
+		name => "buffer",
+		menu => "root_cloud_azure_show_log",
+		cmd_attribute => "CMD_ARRAYOS|CMD_SPROXY|CMD_NORMAL|CMD_KILLABLE|CMD_NON_MORE",
+		user_level => "CLI_LEVEL_CONFIG",
+		help_string => "Show the log of az tools",
+		function_name => "cloud_az_show_log_buffer",
+		function_args => [
+			{
+				type => "U32",
+				help_string => "Enter the number of shown line",
+				optional => "YES",
+				default_value => "0",
+			}
+		],
+	},
+
+	# cloud az show log loglevel
+
+	{
+		obj_type => "ITEM",
+		name => "loglevel",
+		menu => "root_cloud_azure_show_log",
+		cmd_attribute => "CMD_ARRAYOS|CMD_SPROXY|CMD_NORMAL|CMD_KILLABLE|CMD_NON_MORE",
+		user_level => "CLI_LEVEL_CONFIG",
+		help_string => "Show the log of az tools",
+		function_name => "cloud_az_show_log_loglevel",
+		function_args => [],
+	},
+
+	# cloud az loglevel
+
+	{
+		obj_type => "MENU",
+		name => "loglevel",
+		parent_menu => "root_cloud_azure",
+		uniq_name => "root_cloud_azure_loglevel",
+		cmd_attribute => "CMD_ARRAYOS|CMD_SPROXY|CMD_NORMAL",
+		user_level => "CLI_LEVEL_CONFIG",
+		help_string => "Display Cloud Azure Set Loglevel decision",
+	},
+
+	# cloud az loglevel debug
+
+	{
+		obj_type => "ITEM",
+		name => "debug",
+		menu => "root_cloud_azure_loglevel",
+		cmd_attribute => "CMD_ARRAYOS|CMD_SPROXY|CMD_NORMAL|CMD_KILLABLE|CMD_NON_MORE",
+		user_level => "CLI_LEVEL_CONFIG",
+		help_string => "Set the log severity to debug",
+		function_name => "cloud_az_loglevel_debug",
+		function_args => [],
+	},
+
+	# cloud az loglevel info
+
+	{
+		obj_type => "ITEM",
+		name => "info",
+		menu => "root_cloud_azure_loglevel",
+		cmd_attribute => "CMD_ARRAYOS|CMD_SPROXY|CMD_NORMAL|CMD_KILLABLE|CMD_NON_MORE",
+		user_level => "CLI_LEVEL_CONFIG",
+		help_string => "Set the log severity to info",
+		function_name => "cloud_az_loglevel_info",
+		function_args => [],
+	},
+
+	# cloud az loglevel warning
+
+	{
+		obj_type => "ITEM",
+		name => "warning",
+		menu => "root_cloud_azure_loglevel",
+		cmd_attribute => "CMD_ARRAYOS|CMD_SPROXY|CMD_NORMAL|CMD_KILLABLE|CMD_NON_MORE",
+		user_level => "CLI_LEVEL_CONFIG",
+		help_string => "Set the log severity to warning",
+		function_name => "cloud_az_loglevel_warning",
+		function_args => [],
+	},
+
+	# cloud az loglevel error
+
+	{
+		obj_type => "ITEM",
+		name => "error",
+		menu => "root_cloud_azure_loglevel",
+		cmd_attribute => "CMD_ARRAYOS|CMD_SPROXY|CMD_NORMAL|CMD_KILLABLE|CMD_NON_MORE",
+		user_level => "CLI_LEVEL_CONFIG",
+		help_string => "Set the log severity to error",
+		function_name => "cloud_az_loglevel_error",
+		function_args => [],
+	},
 
 # AZURE COMMAND END
 
+
 # AWS COMMAND START
 
 	# cloud aws
Index: /branches/rel_apv_10_7_3/usr/click/tools/aws/aws_auth/AWSAuthController.py
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/tools/aws/aws_auth/AWSAuthController.py	(revision 39037)
+++ /branches/rel_apv_10_7_3/usr/click/tools/aws/aws_auth/AWSAuthController.py	(working copy)
@@ -97,7 +97,7 @@
                 )
                 res[key] = process.stdout.replace("\n", "")
             except Exception as e:
-                print(str(e))
+                ProxyAWSLogger.error(str(e))
 
         if res["aws_access_key_id"] or res["aws_access_key_id"]:
             res["aws_access_key_id"] = cls._mask_credential(
Index: /branches/rel_apv_10_7_3/usr/click/tools/azure/AZAuthManager.py
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/tools/azure/AZAuthManager.py	(revision 39037)
+++ /branches/rel_apv_10_7_3/usr/click/tools/azure/AZAuthManager.py	(working copy)
@@ -23,9 +23,6 @@
         output_controller.end_to_file()
     elif  args.mode=='show':
         output_controller = OutputController()
-        output_controller.start_to_file()
         az_auth_controller.show_az()
-        output_controller.end_to_file()
     else:
         print(f"Error: mode arugment must be login, logout, and show. mode:[{args.mode}]")
-    
Index: /branches/rel_apv_10_7_3/usr/click/tools/azure/AZFailoverManager.py
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/tools/azure/AZFailoverManager.py	(revision 39037)
+++ /branches/rel_apv_10_7_3/usr/click/tools/azure/AZFailoverManager.py	(working copy)
@@ -1,8 +1,13 @@
 import argparse
 import json
 import os
+
 from az_nic.NICController import NICController
 from az_route_table.RouteTableFailoverManager import RouteTableFailoverManager
+from ConfigManager import IPConfigManager
+from logger.ProxyAZLogger import ProxyAZLogger
+
+
 class AZFailoverManager():
     '''This class is used while failover happen and failover recover.\n
     It does two things:
@@ -17,18 +22,25 @@
         self.to_nic_name = ip_config_setting['to_nic_name']
         # self.to_ip_config_name = ip_config_setting['to_ip_config_name']
     def failover_happen(self):
-        '''two things to do: 1. transfer ip config. 2. transfer UDR'''
+        '''transfer ip config.'''
+        ProxyAZLogger.info("start to transfer all IPs")
         nicC = NICController(self.subscription_id, self.resource_group_name)
-        # nicC.transfer_ip_config(self.from_nic_name, self.from_ip_config_name, self.to_nic_name, self.to_ip_config_name)
-        nicC.transfer_all_ip_config(from_nic_name=self.from_nic_name, to_nic_name=self.to_nic_name)
-        # Assumption is that two vAPV is within the same subnet. No need to transfer UDR
-        # fm = RouteTableFailoverManager()
-        # fm.handle_failover_happen()
+        try:
+            nicC.transfer_all_ip_config(from_nic_name=self.from_nic_name, to_nic_name=self.to_nic_name)
+            ProxyAZLogger.info("finish transfering all IPs")
+        except Exception as e:
+            ProxyAZLogger.error("Fail to transfer all ip config: "+str(e))
 
     def failover_recover(self):
+        ProxyAZLogger.info("start to transfer all IPs")
         nicC = NICController(self.subscription_id, self.resource_group_name)
-        # nicC.transfer_ip_config(self.to_nic_name, self.to_ip_config_name, self.from_nic_name, self.to_ip_config_name)
-        nicC.transfer_all_ip_config(from_nic_name=self.to_nic_name, to_nic_name= self.from_nic_name)
+        try:
+            nicC.transfer_all_ip_config(from_nic_name=self.to_nic_name, to_nic_name= self.from_nic_name)
+            ProxyAZLogger.info("finish to transfer all IPs")
+        except Exception as e:
+            ProxyAZLogger.error("Fail to transfer all ip config: "+str(e))
+
+
 if __name__=="__main__":
     parser = argparse.ArgumentParser(description='Process optional name argument.')
     parser.add_argument('-mode', type=str, help='Enter 1 or 2: mode 1 is for failover happen; mode 2 is failover recover')
@@ -37,14 +49,18 @@
     config_dir = '/ca/conf/'
     ip_config_setting_file_name = 'ip_config_setting.json'
     setting_file_location = os.path.join(config_dir, ip_config_setting_file_name)
-    with open(setting_file_location, 'r') as file:
-        ip_config_setting = json.load(file)
-    az_failover_manager = AZFailoverManager(ip_config_setting)
-    if args.mode=='1':
-        # print("mode 1")
-        az_failover_manager.failover_happen()
-    elif  args.mode=='2':
-        # print("mode 2")
-        az_failover_manager.failover_recover()
+
+    if args.mode=='1' or args.mode=='2':
+        ip_config_manager = IPConfigManager(setting_file_location)
+        ip_config_setting_json = ip_config_manager.get_ip_config()
+        for i in ip_config_setting_json:
+            data = ip_config_setting_json[i]
+            az_failover_manager = AZFailoverManager(data)
+            if args.mode=='1':
+                ProxyAZLogger.info("mode 1 is for failover happen")
+                az_failover_manager.failover_happen()
+            elif  args.mode=='2':
+                ProxyAZLogger.info("mode 2 is failover recover")
+                az_failover_manager.failover_recover()
     else:
-        print(f"Error: mode must arugment must be 1 or 2. mode:[{args.mode}]")
\ No newline at end of file
+        ProxyAZLogger.error(f"Error: mode must arugment must be 1 or 2. mode:[{args.mode}]")
\ No newline at end of file
Index: /branches/rel_apv_10_7_3/usr/click/tools/azure/AZFailoverPoller.py
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/tools/azure/AZFailoverPoller.py	(revision 39037)
+++ /branches/rel_apv_10_7_3/usr/click/tools/azure/AZFailoverPoller.py	(working copy)
@@ -6,26 +6,29 @@
 import time
 import psutil
 import os
+
 from apv_controller.APVController import APVController
 from AZFailoverManager import AZFailoverManager
+from ConfigManager import IPConfigManager
+from logger.ProxyAZLogger import ProxyAZLogger
+
 # todo put it in APV enviroment, parse heartbeat
 class AZFailoverPoller():
     def __init__(self) -> None:
         pass
-    def start(self, setting_file_location):
-        
+    def start(self, ip_config_setting_json):
         in_failover = False
-        polling_period = 2 #seconds
-        # self.print_current_time(1)
+        polling_period = 1 #seconds
         apv_contronller = APVController()
         if apv_contronller.is_primary():
-            print(f"This APV [{apv_contronller.get_apv_name()}] is primary APV in HA.")
+            ProxyAZLogger.debug(f"This APV [{apv_contronller.get_apv_name()}] is primary APV in HA. Stop pooling.")
             return
-        print(f"This APV [{apv_contronller.get_apv_name()}] is secondary APV in HA.")
-        print(f'APV [{apv_contronller.get_apv_name()}] start polling')
+        ProxyAZLogger.debug(f"This APV [{apv_contronller.get_apv_name()}] is secondary APV in HA.")
+        ProxyAZLogger.info(f'APV [{apv_contronller.get_apv_name()}] start polling')
         # pooling
         while True:
             time.sleep(polling_period)
+            ProxyAZLogger.debug("try pooling")
             # primary machine doesn't need to do pooling
             if apv_contronller.is_primary():
                 break
@@ -33,11 +36,14 @@
                 if not in_failover:
                     # failover happen
                     current_time = datetime.now().strftime("%Y-%m-%d %H %M %S")
-                    print(f"Failover happen on {current_time}")
-                    az_failover_manager = AZFailoverManager(setting_file_location)
-                    az_failover_manager.failover_happen()
+                    ProxyAZLogger.info(f"Failover happen on {current_time}")
+                    for idx in ip_config_setting_json:
+                        data = ip_config_setting_json[idx]
+                        az_failover_manager = AZFailoverManager(data)
+                        az_failover_manager.failover_happen()
+
                     #todo need to verify that all setting are set, and then set is_failover=True
-                    print("Succeessfully handle failover transition")
+                    ProxyAZLogger.info("Succeessfully handle failover transition")
 
                     # set in_failover=True for condition that the primary APV is ON again.
                     in_failover = True
@@ -45,22 +51,24 @@
             elif in_failover:
                 # failover happended before and now the primary APV is ON
                 current_time = datetime.now().strftime("%Y-%m-%d %H %M %S")
-                print(f"Failover recover on {current_time}")
-                az_failover_manager = AZFailoverManager(setting_file_location)
-                az_failover_manager.failover_recover()
+                ProxyAZLogger.info(f"Failover recover on {current_time}")
+                for idx in ip_config_setting_json:
+                    data = ip_config_setting_json[idx]
+                    az_failover_manager = AZFailoverManager(data)
+                    az_failover_manager.failover_recover()
 
                 # reset
                 in_failover = False
 
-
     def kill_poller(self, process_name):
+        '''This method will kill all the process with the same name of process_name.'''
         for proc in psutil.process_iter(['pid', 'cmdline']):
-            if process_name in proc.info['cmdline']:
-                proc.kill()
-                print('kill ', process_name)
-                return
-        print(f"Didn't stop poller. Cannnot found module name:{process_name}. Please check current module name.", )
-    
+            if proc.info['cmdline']:
+                for peice_of_cmd in proc.info['cmdline']:
+                    if process_name in peice_of_cmd and (not proc.info['pid']==os.getpid()) :
+                        proc.kill()
+                        ProxyAZLogger.info("kill process_name")
+
     def stop(self):
         '''kill poller that is another running process by its filename, a.k.a. this file name.'''
         # get this module name (filename)
@@ -75,24 +83,51 @@
                 print("pid: ", pid, " Current Time:", current_time)
                 time.sleep(interval)
         except KeyboardInterrupt:
-            print("\nProcess interrupted. Exiting...")
+            ProxyAZLogger.error("\nProcess interrupted. Exiting...")
+    def is_poller_running(self, this_mode)->bool:
+        '''This method is used to determine if the poller is running or not.
+        return True if it is running
+        return False if it isn't running
+        '''
+        module_name = os.path.basename(__file__)
+        for proc in psutil.process_iter(['pid', 'cmdline']):
+            # print(module_name, proc.info, os.getpid())
+            if proc.info['cmdline']:
+                for peice_of_cmd in proc.info['cmdline']:
+                    if module_name in peice_of_cmd and (not proc.info['pid']==os.getpid()) :
+                        return True
+        return False
+
+
 if __name__=='__main__':
-    parser = argparse.ArgumentParser(description='Process optional name argument.')
-    parser.add_argument('-mode', type=str, help='Enter 1 or 2: mode 1: start polling; mode 2: stop polling')
+    parser = argparse.ArgumentParser(description='''This API is used to start polling, stop polling, and check the status of poller for IPs transfering''')
+    parser.add_argument('-mode', type=str, choices=["1", "2", "3"], help='Enter 1 or 2: mode 1: start polling; mode 2: stop polling; mode3: check poller status')
     args = parser.parse_args()
-    az_polloer = AZFailoverPoller()
+    az_poller = AZFailoverPoller()
     config_dir = '/ca/conf/'
     ip_config_setting_file_name = 'ip_config_setting.json'
     setting_file_location = os.path.join(config_dir, ip_config_setting_file_name)
-    with open(setting_file_location, 'r') as f:
-        data = f.read()
-    ip_config_setting_json = json.loads(data)
+    ip_config_manager = IPConfigManager(setting_file_location)
+    ip_config_setting_json = ip_config_manager.get_ip_config()
 
     if args.mode=='1':
-        print("mode 1")    
-        az_polloer.start(ip_config_setting_json)
+        if not az_poller.is_poller_running(args.mode):
+            ProxyAZLogger.info("start polling mode")
+            az_poller.start(ip_config_setting_json)
+        else:
+            ProxyAZLogger.info("try to start polling mode, but poller has been running")
     elif  args.mode=='2':
-        print("mode 2")
-        az_polloer.stop()
+        if az_poller.is_poller_running(args.mode):
+            ProxyAZLogger.info("stop polling mode")
+            az_poller.stop()
+        else:
+            ProxyAZLogger.info("try to stop polling mode, but the poller isn't running")
+    elif args.mode=="3":
+        status = az_poller.is_poller_running(args.mode)
+        print(status)
+        if status:
+            ProxyAZLogger.info(f"check {os.path.basename(__file__)} status: running")
+        else:
+            ProxyAZLogger.info(f"check {os.path.basename(__file__)} status: not running")
     else:
-        print(f"Error: mode must arugment must be 1 or 2. mode:[{args.mode}]")
\ No newline at end of file
+        ProxyAZLogger.error(f"Error: mode must arugment must be 1 or 2. mode:[{args.mode}]")
\ No newline at end of file
Index: /branches/rel_apv_10_7_3/usr/click/tools/azure/ConfigManager.py
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/tools/azure/ConfigManager.py	(revision 39037)
+++ /branches/rel_apv_10_7_3/usr/click/tools/azure/ConfigManager.py	(working copy)
@@ -1,35 +1,79 @@
 import json
 import os
 import argparse
-
+from logger.ProxyAZLogger import ProxyAZLogger
 class IPConfigManager():
     '''set needed configuration for transferring routing table and network interface'''
     def __init__(self, ip_config_file_path) -> None:
         self.ip_config_file_path = ip_config_file_path
-    def show_ip_config(self):
-        try:
+
+    def save_ip_config(self, ip_config_setting_json):
+        ip_config_setting_json = dict(sorted(ip_config_setting_json.items()))
+
+        with open(self.ip_config_file_path, 'w') as json_file:
+            json.dump(ip_config_setting_json, json_file, indent=4)
+
+    def get_ip_config(self):
+        ip_config_setting_json = {}
+        if os.path.exists(self.ip_config_file_path):
             with open(self.ip_config_file_path, 'r') as f:
                 data = f.read()
-            ip_config_setting_json = json.loads(data)
 
-            print(f"Subscription ID: {ip_config_setting_json['subscription_id']}")
-            print(f"Resource group name: {ip_config_setting_json['resource_group_name']}")
-            print(f"Primary NIC name: {ip_config_setting_json['from_nic_name']}")
-            # print(f"The name of ip configuration: {ip_config_setting_json['from_ip_config_name']}")
-            print(f"Secondary NIC name: {ip_config_setting_json['to_nic_name']}")
+            try:
+                ip_config_setting_json = json.loads(data)
+            except Exception:
+                print(f"load data to json error.")
+
+        return ip_config_setting_json
+
+    def print_ip_config(self, idx, single_data):
+        ProxyAZLogger.debug("print_ip_config")
+        print(f"{idx}:")
+        print(f"    Subscription ID:     {single_data['subscription_id']}")
+        print(f"    Resource group name: {single_data['resource_group_name']}")
+        print(f"    Primary NIC name:    {single_data['from_nic_name']}")
+        # print(f"The name of ip configuration: {single_data['from_ip_config_name']}")
+        print(f"    Secondary NIC name:  {single_data['to_nic_name']}")
+
+    def show_ip_config(self, idx=0):
+        ip_config_setting_json = self.get_ip_config()
+        if not ip_config_setting_json:
+            print("No NIC configuration")
+            return
+        try:
+            if idx == 0:
+                for idx in ip_config_setting_json:
+                    data = ip_config_setting_json[idx]
+                    self.print_ip_config(idx, data)
+            else:
+                if f"{idx}" in ip_config_setting_json:
+                    data = ip_config_setting_json[f"{idx}"]
+                    self.print_ip_config(idx, data)
         except Exception:
+            ProxyAZLogger.error("Error: No ip configuration found. Set it before examine it.")
             print("Error: No ip configuration found. Set it before examine it.")
-    def clear_ip_config(self):
+
+    def clear_ip_config(self, idx=0):
         if os.path.exists(self.ip_config_file_path):
-            os.remove(self.ip_config_file_path)
-            print('clear ip configuration')
+            ProxyAZLogger.info(f"clear ip config with idx: {idx}")
+            if idx == 0:
+                os.remove(self.ip_config_file_path)
+                print('clear all ip configuration')
+            else:
+                ip_config_setting_json = self.get_ip_config()
+                if f"{idx}" in ip_config_setting_json:
+                    del ip_config_setting_json[f"{idx}"]
+                    print(f'clear {idx} ip configuration')
+
+                if len(ip_config_setting_json) == 0:
+                    os.remove(self.ip_config_file_path)
+                    print('clear all ip configuration')
+                else:
+                    self.save_ip_config(ip_config_setting_json)
+
+
 
     def set_ip_config(self, subscription_id, resource_group_name, from_nic_name, to_nic_name):
-        # subscription_id = input("Enter subscription ID: ")
-        # resource_group_name = input("Enter resource group name: ")
-        # from_nic_name = input("Enter NIC name of the primary machine: ")
-        # from_ip_config_name = input("Enter name of ip configuration need to be switch while failover happen: ")
-        # to_nic_name = input("Enter NIC name of the secondary machine: ")
         data = {
             "subscription_id": subscription_id,
             "resource_group_name": resource_group_name,
@@ -38,9 +82,16 @@
             "to_nic_name": to_nic_name,
             # "to_ip_config_name": from_ip_config_name,
         }
+
+        ip_config_setting_json = self.get_ip_config()
+        for idx in range(1, 200+1):
+            if not f"{idx}" in ip_config_setting_json:
+                ip_config_setting_json[f"{idx}"] = data
+                break
+
         # Write the dictionary of setting to a JSON file
-        with open(self.ip_config_file_path, 'w') as json_file:
-            json.dump(data, json_file, indent=4)
+        ProxyAZLogger.info(f"save ip config: {ip_config_setting_json}")
+        self.save_ip_config(ip_config_setting_json)
 
 if __name__=="__main__":
     parser = argparse.ArgumentParser(description='Process optional name argument.')
@@ -51,6 +102,7 @@
     parser.add_argument('-src_nic_name', type=str, help='NIC name of the primary machine')
     # parser.add_argument('-src_ip_cfg_name', type=str, help='name of ip configuration need to be switch while failover happen')
     parser.add_argument('-dest_nic_name', type=str, help='NIC name of the secondary machine')
+    parser.add_argument('-index', type=int, help='Show or clear the index config')
 
     args = parser.parse_args()
 
@@ -60,14 +112,19 @@
         os.makedirs(config_dir)
         print(f"Directory '{config_dir}' created successfully.")
     setting_file_location = os.path.join(config_dir, ip_config_setting_file_name)
-    
+
     ip_config_manager = IPConfigManager(setting_file_location)
     if args.mode=='set':
+        ProxyAZLogger.info("config manager set mode")
         ip_config_manager.set_ip_config(args.sub_id, args.res_grp_name, args.src_nic_name, args.dest_nic_name)
     elif  args.mode=='show':
-        ip_config_manager.show_ip_config()
+        ProxyAZLogger.info("config manager show mode")
+        ip_config_manager.show_ip_config(args.index)
     elif  args.mode=='clear':
-        ip_config_manager.clear_ip_config()
-
+        ProxyAZLogger.info("config manager clear mode")
+        ip_config_manager.clear_ip_config(args.index)
+    elif args.mode=='getipconfig':
+        ProxyAZLogger.info("config manager getconfig mode")
+        print(ip_config_manager.get_ip_config())
     else:
-        print(f"Error: mode must arugment must be set, show, and clear. mode:[{args.mode}]")
+        ProxyAZLogger.error(f"Error: mode must arugment must be set, show, and clear. mode:[{args.mode}]")
Index: /branches/rel_apv_10_7_3/usr/click/tools/azure/LoggerManager.py
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/tools/azure/LoggerManager.py	(revision 0)
+++ /branches/rel_apv_10_7_3/usr/click/tools/azure/LoggerManager.py	(working copy)
@@ -0,0 +1,83 @@
+import argparse
+from logger.ProxyAZLogger import ProxyAZLogger
+class LoggerManager():
+    def __init__():
+        pass
+    @classmethod
+    def turn_on_logger(cls)->None:
+        ProxyAZLogger.debug("Turn on log functionality.")
+        ProxyAZLogger.turn_on()
+
+    @classmethod
+    def turn_off_logger(cls)->None:
+        ProxyAZLogger.debug("Turn off log functionality.")
+        ProxyAZLogger.turn_off()
+
+    @classmethod
+    def check_Logger_state(cls)->bool:
+        return ProxyAZLogger.get_Logger_state()
+
+    @classmethod
+    def check_Logger_level_state(cls)->str:
+        return ProxyAZLogger.get_Logger_level_state()
+
+    @classmethod
+    def get_log(cls, number_of_line: int = None) -> None:
+        log_list = ProxyAZLogger.get_log_list()
+        reverse_log_list = list(reversed(log_list))
+        shown_log_list = []
+        if number_of_line==0:
+            # print all log
+            shown_log_list = reverse_log_list
+        else:
+            # print log according to the number of line
+            shown_log_list = reverse_log_list[:number_of_line]
+        for line in shown_log_list:
+            print(line.strip())
+
+    @classmethod
+    def show_log(cls, number_of_line: int = None) -> str:
+        res = ProxyAZLogger.get_log()
+
+    @classmethod
+    def set_logger_level(cls, level:str)->None:
+        ProxyAZLogger.info(f"set new log severity: {level}")
+        ProxyAZLogger.set_level(level)
+
+    @classmethod
+    def get_log_file_path(cls)->str:
+        log_file_path = ProxyAZLogger.get_log_file_path()
+        ProxyAZLogger.info("get log file path: "+log_file_path)
+        return log_file_path
+
+
+if __name__=='__main__':
+    description = '''This API is used to
+    1. manipulate the mode(on or off) of the functionality.
+    2. dump the log message.
+    3. check current logger status
+    4. set the log severity and show log severity'''
+    parser = argparse.ArgumentParser(description=description)
+    parser.add_argument('-mode', type=str, choices=["on", "off", "show", "status", "getlogpath"], help='Enter [on], [off], [getlogpath], or [show]')
+    parser.add_argument('-level', type=str, choices=["debug", "info", "warning", "error", "status"], help='choose severity amond [debug], [info], [warning], or [error]')
+    parser.add_argument('-lines', type=int, help='the number of line of shown log', default=0)
+
+    args = parser.parse_args()
+
+    # set severity
+    if args.level in ["debug", "info", "warning", "error"]:
+        LoggerManager.set_logger_level(args.level)
+    elif args.level in ["status"]:
+        print(LoggerManager.check_Logger_level_state())
+
+    # set mode
+    if args.mode=="on":
+        LoggerManager.turn_on_logger()
+    elif args.mode=="off":
+        LoggerManager.turn_off_logger()
+    elif args.mode=="show":
+        log = LoggerManager.get_log(args.lines)
+    elif args.mode=="status":
+        print(LoggerManager.check_Logger_state())
+    elif args.mode=="getlogpath":
+        print(LoggerManager.get_log_file_path())
Index: /branches/rel_apv_10_7_3/usr/click/tools/azure/RouteConfigManager.py
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/tools/azure/RouteConfigManager.py	(revision 39037)
+++ /branches/rel_apv_10_7_3/usr/click/tools/azure/RouteConfigManager.py	(working copy)
@@ -2,28 +2,75 @@
 import os
 import argparse
 import ipaddress
+from logger.ProxyAZLogger import ProxyAZLogger
 
 class RouteConfigManager():
     '''set needed configuration for transferring routing table and network interface'''
     def __init__(self, ip_config_file_path) -> None:
         self.ip_config_file_path = ip_config_file_path
-    def show_UDR_config(self):
-        try:
+
+    def save_UDR_config(self, ip_config_setting_json):
+        ip_config_setting_json = dict(sorted(ip_config_setting_json.items()))
+
+        with open(self.ip_config_file_path, 'w') as json_file:
+            json.dump(ip_config_setting_json, json_file, indent=4)
+
+    def get_UDR_config(self):
+        ip_config_setting_json = {}
+        if os.path.exists(self.ip_config_file_path):
             with open(self.ip_config_file_path, 'r') as f:
                 data = f.read()
-            ip_config_setting_json = json.loads(data)
 
-            print(f"Subscription ID: {ip_config_setting_json['subscription_id']}")
-            print(f"Resource group name: {ip_config_setting_json['resource_group_name']}")
-            print(f"Monitored_vm_name: {ip_config_setting_json['monitored_vm_name']}")
-            print(f"The required ip while monitored vm is up: {ip_config_setting_json['target_ip_when_running']}")
-            print(f"The required ip while monitored vm is down: {ip_config_setting_json['target_ip_when_deallocated']}")
+            try:
+                ip_config_setting_json = json.loads(data)
+            except Exception:
+                print(f"load data to json error.")
+
+        return ip_config_setting_json
+
+    def print_UDR_config(self, idx, single_data):
+        print(f"{idx}:")
+        print(f"    Subscription ID:     {single_data['subscription_id']}")
+        print(f"    Resource group name: {single_data['resource_group_name']}")
+        print(f"    Monitored_vm_name:   {single_data['monitored_vm_name']}")
+        print(f"    The required ip while monitored vm is up:   {single_data['target_ip_when_running']}")
+        print(f"    The required ip while monitored vm is down: {single_data['target_ip_when_deallocated']}")
+
+    def show_UDR_config(self, idx=0):
+        udr_config_setting_json = self.get_UDR_config()
+        if not udr_config_setting_json:
+            print("No UDR configuration")
+            return
+        try:
+            if idx == 0:
+                for idx in udr_config_setting_json:
+                    data = udr_config_setting_json[idx]
+                    self.print_UDR_config(idx, data)
+            else:
+                if f"{idx}" in udr_config_setting_json:
+                    data = udr_config_setting_json[f"{idx}"]
+                    self.print_UDR_config(idx, data)
         except Exception:
             print("Error: No ip configuration found. Set it before examine it.")
-    def clear_UDR_config(self):
+            ProxyAZLogger.error("Error: No ip configuration found. Set it before examine it.")
+
+    def clear_UDR_config(self, idx=0):
         if os.path.exists(self.ip_config_file_path):
-            os.remove(self.ip_config_file_path)
-            print('clear ip configuration')
+            ProxyAZLogger.info(f"clear UDR config with idx: {idx}")
+            if idx == 0:
+                os.remove(self.ip_config_file_path)
+                print('clear all ip configuration')
+            else:
+                ip_config_setting_json = self.get_UDR_config()
+                if f"{idx}" in ip_config_setting_json:
+                    del ip_config_setting_json[f"{idx}"]
+                    print(f'clear {idx} ip configuration')
+
+                if len(ip_config_setting_json) == 0:
+                    os.remove(self.ip_config_file_path)
+                    print('clear all ip configuration')
+                else:
+                    self.save_UDR_config(ip_config_setting_json)
 
     def set_UDR_config(self, subscription_id, resource_group_name, monitored_vm_name, target_ip_when_running, target_ip_when_deallocated):
         # subscription_id = input("Enter subscription ID: ")
@@ -38,9 +85,17 @@
             "target_ip_when_running": target_ip_when_running,
             "target_ip_when_deallocated": target_ip_when_deallocated,
         }
+
+        ip_config_setting_json = self.get_UDR_config()
+        ProxyAZLogger.info(ip_config_setting_json)
+
+        for idx in range(1, 200+1):
+            if not f"{idx}" in ip_config_setting_json:
+                ip_config_setting_json[f"{idx}"] = data
+                break
         # Write the dictionary of setting to a JSON file
-        with open(self.ip_config_file_path, 'w') as json_file:
-            json.dump(data, json_file, indent=4)
+        self.save_UDR_config(ip_config_setting_json)
+        ProxyAZLogger.info(f"save UDR config: {ip_config_setting_json}")
 
     def is_valid_ipv4_address(self, address):
         try:
@@ -48,7 +103,8 @@
             return isinstance(ip, ipaddress.IPv4Address)
         except ValueError:
             return False
-        
+
+
 if __name__=="__main__":
     parser = argparse.ArgumentParser(description='Process optional name argument.')
     parser.add_argument('-mode', type=str, help='Enter [set], [show], or [clear]')
@@ -58,6 +114,7 @@
     parser.add_argument('-vm_name', type=str, help='the name of vm will be monitored')
     parser.add_argument('-ip_running', type=str, help='the ip of set on UDR while monitored vm is up')
     parser.add_argument('-ip_deallocating', type=str, help='the ip of set on UDR while monitored vm is down')
+    parser.add_argument('-index', type=int, help='Show or clear the index config')
 
     args = parser.parse_args()
 
@@ -65,27 +122,34 @@
     ip_config_setting_file_name = 'route_table_config_setting.json'
     if not os.path.exists(config_dir):
         os.makedirs(config_dir)
-        print(f"Directory '{config_dir}' created successfully.")
+        ProxyAZLogger.info(f"Directory '{config_dir}' created successfully.")
     setting_file_location = os.path.join(config_dir, ip_config_setting_file_name)
     # print("setting_file_location", setting_file_location)
     route_config_manager = RouteConfigManager(setting_file_location)
     if args.mode=='set':
+        ProxyAZLogger.info("set route config")
         is_ip_valid = True
         is_ip_valid &= route_config_manager.is_valid_ipv4_address(args.ip_running)
         is_ip_valid &= route_config_manager.is_valid_ipv4_address(args.ip_deallocating)
         if is_ip_valid:
-            route_config_manager.set_UDR_config(args.sub_id, 
-                                                args.res_grp_name, 
-                                                args.vm_name, 
+            route_config_manager.set_UDR_config(args.sub_id,
+                                                args.res_grp_name,
+                                                args.vm_name,
                                                 args.ip_running,
                                                 args.ip_deallocating
                                                 )
         else:
             print("IP4 format is not correct.")
+            ProxyAZLogger.error("IP4 format is not correct.")
     elif  args.mode=='show':
-        route_config_manager.show_UDR_config()
+        ProxyAZLogger.info("show route config")
+        route_config_manager.show_UDR_config(args.index)
     elif  args.mode=='clear':
-        route_config_manager.clear_UDR_config()
+        ProxyAZLogger.info("clear route config index:"+str(args.index))
+        route_config_manager.clear_UDR_config(args.index)
+    elif  args.mode=='getrouteconfig':
+        ProxyAZLogger.info("get route config")
+        print(route_config_manager.get_UDR_config())
 
     else:
         print(f"Error: mode must arugment must be set, show, and clear. mode:[{args.mode}]")
Index: /branches/rel_apv_10_7_3/usr/click/tools/azure/UDRPoller.py
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/tools/azure/UDRPoller.py	(revision 39037)
+++ /branches/rel_apv_10_7_3/usr/click/tools/azure/UDRPoller.py	(working copy)
@@ -6,83 +6,146 @@
 from az_vm.VMController import VMController
 from az_route_table.RouteTableController import RouteTableController
 
-
+from RouteConfigManager import RouteConfigManager
+from logger.ProxyAZLogger import ProxyAZLogger
 class UDRPoller():
-    def __init__(self, rout_table_config_setting_json) -> None:
-        self.rout_table_config_setting_json = rout_table_config_setting_json
+    def __init__(self, setting_file_location:str) -> None:
+        self.setting_file_location = setting_file_location
+        self.reload_route_table_config_setting_json()
+
+    def reload_route_table_config_setting_json(self):
+        route_config_manager = RouteConfigManager(self.setting_file_location)
+        self.route_table_config_setting_json = route_config_manager.get_UDR_config()
+
     def start(self):
         polling_period = 2 #seconds
-        vm_controller = VMController(
-            self.rout_table_config_setting_json['subscription_id'],
-            self.rout_table_config_setting_json['resource_group_name']
+
+        vm_controller_list = []
+        is_target_vm_down_list = []
+        route_table_update_count_list = []
+        route_table_controller_list = []
+
+        for idx in self.route_table_config_setting_json:
+            data = self.route_table_config_setting_json[idx]
+            vm_controller = VMController(
+                data['subscription_id'],
+                data['resource_group_name']
             )
-        is_target_vm_down = False
 
-        route_table_update_count = 0
-        route_table_controller = RouteTableController(
-            subscription_id=self.rout_table_config_setting_json['subscription_id'],
-            resource_group_name=self.rout_table_config_setting_json['resource_group_name']
-        )
+            route_table_controller = RouteTableController(
+                subscription_id=data['subscription_id'],
+                resource_group_name=data['resource_group_name']
+            )
+
+            vm_controller_list.append(vm_controller)
+            is_target_vm_down_list.append(False)
+            route_table_update_count_list.append(0)
+            route_table_controller_list.append(route_table_controller)
+
         while True:
+            # self.reload_route_table_config_setting_json()
             time.sleep(polling_period)
-            print("polling...")
-            if not vm_controller.is_VM_alive_by_name(self.rout_table_config_setting_json["monitored_vm_name"]):
-                # target vm is down
-                print("detect target vm is down")
-                route_table_controller.change_all_UDR_routes_by_ip(
-                    ori_next_hop_ip=self.rout_table_config_setting_json["target_ip_when_running"],
-                    modify_next_hop_ip=self.rout_table_config_setting_json["target_ip_when_deallocated"],
-                )
-                # set vm status
-                is_target_vm_down=True
-            else:
-                # target vm is up
-                print("detect target vm is up")
-                route_table_controller.change_all_UDR_routes_by_ip(
-                    ori_next_hop_ip=self.rout_table_config_setting_json["target_ip_when_deallocated"],
-                    modify_next_hop_ip=self.rout_table_config_setting_json["target_ip_when_running"],
-                )
-                # set vm status
-                is_target_vm_down=False
-            
-            route_table_update_count += 1
-            if route_table_update_count >= 60 / polling_period:
-                route_table_controller = RouteTableController(
-                    subscription_id=self.rout_table_config_setting_json['subscription_id'],
-                    resource_group_name=self.rout_table_config_setting_json['resource_group_name']
-                )
-                route_table_update_count = 0
-                
+            i = 0
+            for idx in self.route_table_config_setting_json:
+                data = self.route_table_config_setting_json[idx]
+
+                ProxyAZLogger.info("UDR pooling")
+                if not vm_controller_list[i].is_VM_alive_by_name(data["monitored_vm_name"]):
+                    # target vm is down
+                    ProxyAZLogger.info("detect target vm is down")
+                    print("detect target vm is down")
+                    try:
+                        route_table_controller_list[i].change_all_UDR_routes_by_ip(
+                            ori_next_hop_ip=data["target_ip_when_running"],
+                            modify_next_hop_ip=data["target_ip_when_deallocated"],
+                        )
+                    except Exception as e:
+                        ProxyAZLogger.error("Fail change all UDR route: "+str(e))
+                    # set vm status
+                    is_target_vm_down_list[i]=True
+                else:
+                    # target vm is up
+                    ProxyAZLogger.info("detect target vm is up")
+                    try:
+                        route_table_controller_list[i].change_all_UDR_routes_by_ip(
+                            ori_next_hop_ip=data["target_ip_when_deallocated"],
+                            modify_next_hop_ip=data["target_ip_when_running"],
+                        )
+                    except Exception as e:
+                        ProxyAZLogger.error("Fail change all UDR route: "+str(e))
+                    # set vm status
+                    is_target_vm_down_list[i]=False
+
+                route_table_update_count_list[i] += 1
+                if route_table_update_count_list[i] >= 60 / polling_period:
+                    vm_controller_list[i] = VMController(
+                        data['subscription_id'],
+                        data['resource_group_name']
+                    )
+
+                    route_table_controller_list[i] = RouteTableController(
+                        subscription_id=data['subscription_id'],
+                        resource_group_name=data['resource_group_name']
+                    )
+
+                    route_table_update_count_list[i] = 0
+
+                i += 1
+
     def stop(self):
         '''kill poller that is another running process by its filename, a.k.a. this file name.'''
         # get this module name (filename)
         module_name = os.path.basename(__file__)
         self.kill_poller(module_name)
     def kill_poller(self, process_name):
-            for proc in psutil.process_iter(['pid', 'cmdline']):
-                if process_name in proc.info['cmdline']:
-                    proc.kill()
-                    print('kill ', process_name)
-                    return
-            print(f"Didn't stop poller. Cannnot found module name:{process_name}. Please check current module name.", )
+        '''This method will kill all the process with the same name of process_name.'''
+        for proc in psutil.process_iter(['pid', 'cmdline']):
+            if proc.info['cmdline']:
+                for peice_of_cmd in proc.info['cmdline']:
+                    if process_name in peice_of_cmd and (not proc.info['pid']==os.getpid()) :
+                        proc.kill()
+                        ProxyAZLogger.info("kill "+process_name)
+
+    def is_poller_running(self, this_mode)->bool:
+        '''This method is used to determine if the poller is running or not.
+        return True if it is running
+        return False if it isn't running
+        '''
+        module_name = os.path.basename(__file__)
+        for proc in psutil.process_iter(['pid', 'cmdline']):
+            # print(proc.info, os.getpid())
+            if proc.info['cmdline']:
+                for peice_of_cmd in proc.info['cmdline']:
+                    if module_name in peice_of_cmd and (not proc.info['pid']==os.getpid()) :
+                        return True
+        return False
 if __name__=='__main__':
-    parser = argparse.ArgumentParser(description='Process optional name argument.')
-    parser.add_argument('-mode', type=str, help='Enter 1 or 2: mode 1 is for starting pooling; mode 2 is for stopping pooling')
+    parser = argparse.ArgumentParser(description='''This API is used to start polling, stop polling, and check the status of poller for UDR transfering''')
+    parser.add_argument('-mode', type=str, choices=['1', '2', '3'], help='Enter 1 or 2: mode 1 is for starting polling; mode 2 is for stopping polling; mode 3 is for checking poller status')
     args = parser.parse_args()
 
     config_dir = '/ca/conf/'
     route_table_config_setting_file_name = 'route_table_config_setting.json'
     setting_file_location = os.path.join(config_dir, route_table_config_setting_file_name)
-    with open(setting_file_location, 'r') as f:
-        data = f.read()
-    rout_table_config_setting_json = json.loads(data)
-
-    udr_pooler = UDRPoller(rout_table_config_setting_json)
+    udr_poller = UDRPoller(setting_file_location)
     if args.mode=='1':
-        # print("mode 1")
-        udr_pooler.start()
-        pass
-    elif  args.mode=='2':
-        # print("mode 2")
-        udr_pooler.stop()
-        pass
\ No newline at end of file
+        if not udr_poller.is_poller_running(args.mode):
+            ProxyAZLogger.info("starting polling mode")
+            udr_poller.start()
+        else:
+            ProxyAZLogger.info("try to start UDR polling mode, but poller has been running")
+
+    elif args.mode=='2':
+        if udr_poller.is_poller_running(args.mode):
+            ProxyAZLogger.info("stopping polling mode")
+            udr_poller.stop()
+        else:
+            ProxyAZLogger.info("try to stop UDR polling mode, but the poller isn't running")
+
+    elif args.mode=="3":
+        status = udr_poller.is_poller_running(args.mode)
+        print(status)
+        if status:
+            ProxyAZLogger.info(f"check {os.path.basename(__file__)} status: running")
+        else:
+            ProxyAZLogger.info(f"check {os.path.basename(__file__)} status: not running")
Index: /branches/rel_apv_10_7_3/usr/click/tools/azure/apv_controller/APVController.py
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/tools/azure/apv_controller/APVController.py	(revision 39037)
+++ /branches/rel_apv_10_7_3/usr/click/tools/azure/apv_controller/APVController.py	(working copy)
@@ -1,7 +1,9 @@
-# from apv_controller.APVCommander import APVCommander
 import re
 import subprocess
 import argparse
+from collections import deque
+
+from logger.ProxyAZLogger import ProxyAZLogger
 
 class APVCommander():
     def __init__(self) -> None:
@@ -56,11 +58,14 @@
 class APVController():
     def __init__(self) -> None:
         self.name = self.get_apv_name()
+        peer_state_q_max_len = 3 #workaround
+        self.peer_state_q:deque = deque(maxlen=peer_state_q_max_len)
+
     def get_apv_version():
         commander = APVCommander()
         res = commander.launch_apv_command("show version")
         return res
-    
+
     def get_apv_name(self)->str:
         ''' get APV name in HA.
         Algo:
@@ -97,9 +102,10 @@
         pattern ='ha group priority \"(.+)\" [\d]+ (\d+)' # need to be checked
         group_priority_list = re.findall(pattern, context)
         if not group_priority_list:
-            error_msg = "Error: cannot find APV group priority in "+context
-            raise Exception(error_msg)
-        
+            error_msg = "Error: cannot find APV group priority in " + context
+            ProxyAZLogger.erro(error_msg)
+            exit(1)
+
         group_priority_list = [(item[0], int(item[1])) for item in group_priority_list] # make priority of string to integer
 
         sorted_group_priority_list = sorted(group_priority_list, key=lambda x: x[1]) #from low priority to heigh priority
@@ -107,22 +113,52 @@
         return self.name==sorted_group_priority_list[-1][0]
     def is_primary_alive(self)->bool:
         '''This function is to check if the primary APV is alive or not.
-        return True: primary APV is alive
+        return True: primary APV is alive, do nothing
         return False: Primary APV is not alive.
         This must be called in secondary APV.
         Algo:
         step1. Use APV CLI "show ha status domain to check if peer(primary APV) is UP or DOWN".
-        step2. if peer(primary APV) is "DOWN", it means primary is dead, aka not alive. 
+        step2. if peer(primary APV) is "DOWN", it means primary is dead, aka not alive.
         '''
         commander = APVCommander()
         context = commander.launch_apv_command("show ha status domain")
+        print(context)
         pattern ='Peer[\s]+unit:[\s]+(.+)\s(UP|DOWN)\s*'
         peer_up_or_down_list = re.findall(pattern, context)
+        print(peer_up_or_down_list)
+
         # print("peer_up_or_down_list", peer_up_or_down_list)
+
         if not peer_up_or_down_list:
             error_msg = "Error: cannot parse peer status in "+ context
-            raise Exception(error_msg)
-        return peer_up_or_down_list[0][1] not in ["DOWN", '-']
+            ProxyAZLogger.erro(error_msg)
+            exit(1)
+
+        import sys
+        from datetime import datetime
+        file = open('/tmp/heartbeat_workaround.txt', 'a')
+
+        # Redirect sys.stdout to the file
+        sys.stdout = file
+
+
+        timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')  # Current time formatted as YYYY-MM-DD HH:MM:SS
+        print(f"[{timestamp}] {peer_up_or_down_list[0]}")
+        sys.stdout = sys.__stdout__
+        # to solve ha flapping issue, we use container to store the recent five heartbeat results
+        # true failure happen <=> in the last five heartbeat check, all state is DOWN
+        self.peer_state_q.append(peer_up_or_down_list[0][1])
+        if self.peer_state_q.count("DOWN")==self.peer_state_q.maxlen:
+            # after checking recent five heartbeat results, the peer is truely DOWN
+            return False
+        elif self.peer_state_q.count("-")==self.peer_state_q.maxlen:
+            # user doesn't turn on ha functionality
+            return True
+        elif self.peer_state_q.count("UP")==self.peer_state_q.maxlen:
+            # after checking recent five heartbeat results, the peer is truely up
+            return True
+        return True # the machine just booted, do nothing
+
 
 
 if __name__=='__main__':
@@ -131,5 +167,5 @@
     args = parser.parse_args()
 
     apv_c = APVController()
-    print("+++++mary", apv_c.is_primary())
+    print(apv_c.is_primary_alive())
     # print(f"run command {args.c}")
\ No newline at end of file
Index: /branches/rel_apv_10_7_3/usr/click/tools/azure/az_auth/AZAuthController.py
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/tools/azure/az_auth/AZAuthController.py	(revision 39037)
+++ /branches/rel_apv_10_7_3/usr/click/tools/azure/az_auth/AZAuthController.py	(working copy)
@@ -4,6 +4,7 @@
 import os
 import time
 import re
+from logger.AZLogger import AZLogger
 
 class AZAuthController():
     def __init__(self) -> None:
@@ -25,11 +26,10 @@
         login_msg_file_name = "login_msg.txt"
         login_response_file_name = "login_response.txt"
 
-        command = ["az", "login"]
+        command = ["az", "login", "--use-device-code"]
         # print("Execute command ", " ".join(command))
         login_msg_file = self.get_login_message_file(file_name=login_msg_file_name)
         result = subprocess.Popen(command, stdout=login_msg_file, stderr=login_msg_file)
-
         while result.poll() is None:
             print('waiting user login by broswer')
             time.sleep(1)
@@ -50,9 +50,9 @@
         if not len(matches)==0:
             print("write file")
             file.write(matches[0])
-        
+
         if result.returncode==0:
-            print("Succeefully log in az account.")
+            print("Successfully signed in the Azure account.")
         else:
             print("Fail to log in az account.\n")
             print("result", result)
@@ -62,7 +62,7 @@
         # print("Execute command ", " ".join(command))
         result = subprocess.run(command, stdout=sys.stdout, stderr=sys.stderr)
         if result.returncode==0:
-            print("Succeefully log out az account.")
+            print("Successfully signed out of the Azure account.")
         else:
             print("Fail to log out az account.\n")
 
@@ -79,19 +79,17 @@
             return True
         else:
             return False
-        
+
     def show_az(self):
+        AZLogger.info("show az log in information")
         command = ["az", "account", "show"]
-        # print("Execute command ", " ".join(command))
         result = subprocess.run(command, capture_output=True, text=True)
         if result.returncode==0:
-            print("result.stdout", result.stdout)
+            print(result.stdout)
         else:
             print("Please log in az first.")
-            # print(result.stdout)
-            # print(result.stderr)
-        
+
 
 if __name__=="__main__":
     c = AZAuthController()
-    c.is_az_login()
\ No newline at end of file
+    c.show_az()
\ No newline at end of file
Index: /branches/rel_apv_10_7_3/usr/click/tools/azure/az_route_table/RouteTableController.py
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/tools/azure/az_route_table/RouteTableController.py	(revision 39037)
+++ /branches/rel_apv_10_7_3/usr/click/tools/azure/az_route_table/RouteTableController.py	(working copy)
@@ -1,12 +1,12 @@
 from azure.identity import DefaultAzureCredential
 from azure.mgmt.network import NetworkManagementClient
 from azure.mgmt.network.models import (Route, RouteNextHopType)
-
+from logger.ProxyAZLogger import ProxyAZLogger
 class RouteTableController():
-    def __init__(self, 
-                subscription_id= "2960d47a-5c8a-44eb-a95c-c71227757824",
-                resource_group_name= "test-rg-2",
-                route_table_name= "route-table-public"
+    def __init__(self,
+                subscription_id= "",
+                resource_group_name= "",
+                route_table_name= ""
                 ) -> None:
         self.subscription_id = subscription_id
         self.resource_group_name = resource_group_name
@@ -96,7 +96,7 @@
                     self.route_table_name,
                     route_rule_name
                 ).wait()
-                print(f"Route '{route_rule_name}' deleted successfully from route table '{self.route_table_name}'")
+                ProxyAZLogger.info(f"Route '{route_rule_name}' deleted successfully from route table '{self.route_table_name}'")
             else:
                 print(f"Route '{route_rule_name}' not found in route table '{self.route_table_name}'")
         except Exception as e:
@@ -128,11 +128,11 @@
 
 if __name__=="__main__":
     rc = RouteTableController(
-        subscription_id= "2960d47a-5c8a-44eb-a95c-c71227757824",
-        resource_group_name= "AZURECENTOS",
+        subscription_id= "",
+        resource_group_name= "",
     )
-    target_ip_when_running = "10.0.3.101"
-    target_ip_when_deallocated = "10.0.3.100"
+    target_ip_when_running = "10.0.100.30"
+    target_ip_when_deallocated = "10.0.100.31"
     rc.change_all_UDR_routes_by_ip(
         ori_next_hop_ip=target_ip_when_running,
         modify_next_hop_ip=target_ip_when_deallocated
Index: /branches/rel_apv_10_7_3/usr/click/tools/azure/logger/AZLogger.py
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/tools/azure/logger/AZLogger.py	(revision 0)
+++ /branches/rel_apv_10_7_3/usr/click/tools/azure/logger/AZLogger.py	(working copy)
@@ -0,0 +1,160 @@
+import logging
+from logging.handlers import RotatingFileHandler
+import json
+from abc import ABC, abstractmethod
+import os
+
+
+class AbstractAZLogger(ABC):
+    @classmethod
+    @abstractmethod
+    def set_log_path1(cls, log_path:str)->None:
+        pass
+
+    @classmethod
+    @abstractmethod
+    def set_log_path(cls, log_path:str)->None:
+        cls.log_path = log_path
+
+    @classmethod
+    @abstractmethod
+    def debug(cls, message:str)->None:
+        pass
+
+    @classmethod
+    @abstractmethod
+    def info(cls, message:str)->None:
+        pass
+
+    @classmethod
+    @abstractmethod
+    def warning(cls, message:str)->None:
+        pass
+
+    @classmethod
+    @abstractmethod
+    def error(cls, message:str)->None:
+        pass
+
+    @classmethod
+    @abstractmethod
+    def _load_config(file_path):
+        pass
+
+log_levels = {
+    "debug": logging.DEBUG,
+    "info": logging.INFO,
+    "warning": logging.WARNING,
+    "error": logging.ERROR,
+}
+
+class AZLogger(AbstractAZLogger):
+    '''
+    This class is used to log the azure event.
+    We use the python build-in logging under the hood to implement this class.
+    This class have several static method to log the message.
+    There is no interface to configure this class, that is, all the configurations are set inside the class
+    The AZlogger have four levels of severity, debug, info, warning and error which have the same name of class method.
+    '''
+    # is there a way to make the initilization clean?
+    def _load_config(file_path):
+        try:
+            with open(file_path, 'r') as config_file:
+                config = json.load(config_file)
+                return config
+        except FileNotFoundError:
+            print(f"Error: The file {file_path} was not found.")
+        except json.JSONDecodeError:
+            print(f"Error: The file {file_path} is not a valid JSON file.")
+
+    current_module_directory = os.path.dirname(os.path.abspath(__file__))
+    config_file_path = os.path.join(current_module_directory, "config.json")
+    config = _load_config(config_file_path)
+    log_path = config["log_path"]
+    # log_path = "./azure_ha.log" # for developing purpose
+    log_format = config["log_format"]
+    max_size_log_file = config["max_size_log_file"] #MB
+
+    # logger
+    logger = logging.getLogger("azlogger")
+    log_levels.get(config["level_of_severity"].lower(), logging.DEBUG)
+    logger.setLevel(log_levels.get(config["level_of_severity"].lower(), logging.DEBUG))
+
+
+    # log handler
+    file_handler = RotatingFileHandler(log_path, maxBytes=max_size_log_file*1024*1024, backupCount=1)
+    logger.addHandler(file_handler)
+
+    # log formatter
+    file_formatter = logging.Formatter(log_format, datefmt=config["datefmt"])
+    file_handler.setFormatter(file_formatter)
+
+    def __init__():
+        pass
+    @classmethod
+    def set_log_path(cls, log_path:str)->None:
+        cls.log_path = log_path
+
+    @classmethod
+    def debug(cls, message:str)->None:
+        cls.logger.debug(message)
+    @classmethod
+    def info(cls, message:str)->None:
+        cls.logger.info(message)
+    @classmethod
+    def warning(cls, message:str)->None:
+        cls.logger.warning(message)
+    @classmethod
+    def error(cls, message:str)->None:
+        cls.logger.error(message)
+
+    @classmethod
+    def reload_config(cls)->None:
+
+        try:
+            with open(cls.config_file_path, 'r') as config_file:
+                config = json.load(config_file)
+        except FileNotFoundError:
+            print(f"Error: The file {config_file} was not found.")
+        except json.JSONDecodeError:
+            print(f"Error: The file {config_file} is not a valid JSON file.")
+
+        log_path = config["log_path"]
+        # log_path = "./azure_ha.log" # for developing purpose
+        log_format = config["log_format"]
+        max_size_log_file = config["max_size_log_file"] #MB
+
+        # logger
+        logger = logging.getLogger("azlogger")
+        log_levels.get(config["level_of_severity"].lower(), logging.DEBUG)
+        logger.setLevel(log_levels.get(config["level_of_severity"].lower(), logging.DEBUG))
+
+        # log handler
+        # Remove all existing handlers
+        for handler in logger.handlers[:]:  # Create a copy of the list for safe iteration
+            logger.removeHandler(handler)
+        file_handler = RotatingFileHandler(log_path, maxBytes=max_size_log_file*1024*1024, backupCount=1)
+
+        # log formatter
+        file_formatter = logging.Formatter(log_format, datefmt=config["datefmt"])
+        file_handler.setFormatter(file_formatter)
+
+        logger.addHandler(file_handler)
+
+
+if __name__=="__main__":
+    # test code
+
+    AZLogger.debug("This is a debug message")
+    AZLogger.info("This is an info message")
+    AZLogger.warning("This is a warning message")
+    AZLogger.error("This is a error message")
+    mb = 1
+    for i in range(mb*5000):
+        AZLogger.reload_config()
+        AZLogger.debug(f"This is a debug message {i}")
+        AZLogger.info(f"This is an info message {i}")
+        AZLogger.warning(f"This is a warning message {i}")
+        AZLogger.error(f"This is a error message {i}")
+        import time
+        time.sleep(1)
\ No newline at end of file
Index: /branches/rel_apv_10_7_3/usr/click/tools/azure/logger/ProxyAZLogger.py
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/tools/azure/logger/ProxyAZLogger.py	(revision 0)
+++ /branches/rel_apv_10_7_3/usr/click/tools/azure/logger/ProxyAZLogger.py	(working copy)
@@ -0,0 +1,163 @@
+from logger.AZLogger import AbstractAZLogger
+from logger.AZLogger import AZLogger
+import os
+import json
+
+class ProxyAZLogger(AbstractAZLogger):
+    '''
+    This class is designed using the proxy pattern, a structural design pattern.
+    Becuase there is a requirement of dynamically changing the level of serverity, we use proxy to determine
+    if configuration file is chaged or not in order to keep the AZLogger class pure.
+    '''
+    config_modified_indicator_file = os.path.join(AZLogger.current_module_directory, 'config_modified.txt')
+    with open(AZLogger.config_file_path, 'r') as config_file:
+        config = json.load(config_file)
+    is_logger_on = config["is_logger_on"]
+    @classmethod
+    def get_config(cls)->dict:
+        '''THe usage of this method refers to the set_config()'''
+        try:
+            with open(AZLogger.config_file_path, 'r') as config_file:
+                config = json.load(config_file)
+                return config
+        except FileNotFoundError:
+            AZLogger.error(f"Error: The file {config_file} was not found.")
+        except json.JSONDecodeError:
+            AZLogger.error(f"Error: The file {config_file} is not a valid JSON file.")
+
+    @classmethod
+    def set_config(cls, config:dict)->None:
+        '''The suggested method to modify configuration file is to use get_config() method
+        to get the original configuration dictionary, modify the dictionary objecct, and invoke set_config() with
+        arugment of modified dictionary object
+        algo:
+        1. take input to override the original config dictionary.
+        2. write the file.
+        3. set config file modified indictor
+        '''
+        # AZLogger.info(f"setting new config: {config}")
+        ori_config = cls.get_config()
+        for key in ori_config.keys():
+            ori_config[key] = config[key]
+        with open(AZLogger.config_file_path, "w") as json_file:
+            json.dump(ori_config, json_file, indent=4)
+        with open(cls.config_modified_indicator_file, 'w') as file:
+            pass
+    @classmethod
+    def is_config_modified(cls)->bool:
+        '''This method is used to check if the configuration file is modified or not.
+        The alogrithem to do that is check if there is the modified file existed.
+        If the file existed, the configuration file is modified; otherwise, the configuration is unchaged.
+        '''
+        return os.path.exists(cls.config_modified_indicator_file)
+    @classmethod
+    def _refresh_config(cls)->None:
+        '''If the config file indictor file is existed, then reload the configuration file and delete indictor file.'''
+        if cls.is_config_modified():
+            AZLogger.reload_config()
+            with open(AZLogger.config_file_path, 'r') as config_file:
+                config = json.load(config_file)
+            cls.is_logger_on = config["is_logger_on"]
+            # delete config file changed indicator
+            os.remove(cls.config_modified_indicator_file)
+    @classmethod
+    def set_level(cls, level:str)->None:
+        config = cls.get_config()
+        config["level_of_severity"] = level
+        cls.set_config(config)
+    @classmethod
+    def turn_on(cls)->None:
+        '''This on off functionality is on off all the invoking debug, info, warning, and error method using ProxyAZLogger class.
+        That is, if the client directly use AZLogger, the message is still be logger. However, it's not recommanded'''
+        config = cls.get_config()
+        config["is_logger_on"] = True
+        cls.set_config(config)
+        cls._refresh_config()
+        # cls.is_logger_on = True
+    @classmethod
+    def turn_off(cls)->None:
+        '''This on off functionality is on off all the invoking debug, info, warning, and error method using ProxyAZLogger class.
+        That is, if the client directly use AZLogger, the message is still be logger. However, it's not recommanded'''
+        config = cls.get_config()
+        config["is_logger_on"] = False
+        cls.set_config(config)
+        cls._refresh_config()
+        # cls.is_logger_on = False
+    @classmethod
+    def get_log(cls)->str:
+        '''return a string of content of log file'''
+        config = cls.get_config()
+        with open(config["log_path"], 'r', encoding='utf-8') as file:
+            content = file.read()
+        return content
+    @classmethod
+    def get_log_list(cls) -> list:
+        '''return a list of content of log file'''
+        with open(cls.get_log_file_path(), "r") as file:
+            lines = file.readlines()
+        return lines
+    @classmethod
+    def get_Logger_state(cls)->bool:
+        '''This is used to check if logger is on or not
+        return True if logger is on
+        return False if logger is off
+        '''
+        config = cls.get_config()
+        return config["is_logger_on"]
+    @classmethod
+    def get_Logger_level_state(cls)->str:
+        '''This is used to check if logger level is debug, info, warning, and error
+        return a string of log severity
+        '''
+        config = cls.get_config()
+        return config["level_of_severity"]
+    @classmethod
+    def get_log_file_path(cls)->str:
+        config = cls.get_config()
+        return config["log_path"]
+    @classmethod
+    def debug(cls, message:str)->None:
+        cls._refresh_config()
+        if cls.is_logger_on:
+            AZLogger.debug(message)
+    @classmethod
+    def info(cls, message:str)->None:
+        cls._refresh_config()
+        if cls.is_logger_on:
+            AZLogger.info(message)
+    @classmethod
+    def warning(cls, message:str)->None:
+        cls._refresh_config()
+        if cls.is_logger_on:
+            AZLogger.warning(message)
+    @classmethod
+    def error(cls, message:str)->None:
+        cls._refresh_config()
+        if cls.is_logger_on:
+            AZLogger.error(message)
+
+
+if __name__=="__main__":
+    # test code
+    import os
+    # Get the location of the current module
+    current_module_directory = os.path.dirname(os.path.abspath(__file__))
+
+    ProxyAZLogger.debug("This is a debug message")
+    ProxyAZLogger.info("This is an info message")
+    ProxyAZLogger.warning("This is a warning message")
+    ProxyAZLogger.error("This is a error message")
+    mb = 5
+    for i in range(mb*5000):
+        ProxyAZLogger.debug(f"This is a debug message {i}")
+        ProxyAZLogger.info(f"This is an info message {i}")
+        ProxyAZLogger.warning(f"This is a warning message {i}")
+        ProxyAZLogger.error(f"This is a error message {i}")
+        import time
+        if i%3==0:
+            # test config file changing
+            cur_config = ProxyAZLogger.get_config()
+            cur_config["level_of_severity"] = "info" if cur_config["level_of_severity"]=="debug" else "debug"
+            ProxyAZLogger.set_config(cur_config)
+            print("change level")
+        time.sleep(2)
\ No newline at end of file
Index: /branches/rel_apv_10_7_3/usr/click/tools/azure/logger/__init__.py	(added)
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/tools/azure/logger/__init__.py	(revision 0)
+++ /branches/rel_apv_10_7_3/usr/click/tools/azure/logger/__init__.py	(revision 0)
Index: /branches/rel_apv_10_7_3/usr/click/tools/azure/logger/config.json
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/tools/azure/logger/config.json	(revision 0)
+++ /branches/rel_apv_10_7_3/usr/click/tools/azure/logger/config.json	(working copy)
@@ -0,0 +1,8 @@
+{
+    "log_path": "/var/crash/azure_ha.log",
+    "log_format": "[%(asctime)s] - [%(levelname)s] %(message)s",
+    "max_size_log_file": 10,
+    "level_of_severity": "info",
+    "datefmt": "%Y-%m-%dT%H:%M:%S",
+    "is_logger_on": true
+}
\ No newline at end of file
Index: /branches/rel_apv_10_7_3/usr/click/tools/azure/p/p1.py
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/tools/azure/p/p1.py	(revision 39037)
+++ /branches/rel_apv_10_7_3/usr/click/tools/azure/p/p1.py	(working copy)
@@ -1,6 +0,0 @@
-
-
-class p1():
-    def __init__(self) -> None:
-        print("p1 contructor")
-
Index: /branches/rel_apv_10_7_3/usr/click/tools/azure/p/p2.py
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/tools/azure/p/p2.py	(revision 39037)
+++ /branches/rel_apv_10_7_3/usr/click/tools/azure/p/p2.py	(working copy)
@@ -1,7 +0,0 @@
-from p.p1 import p1
-class p2():
-    def __init__(self) -> None:
-        pass
-
-if __name__=="__main__":
-    p1()
\ No newline at end of file
Index: /branches/rel_apv_10_7_3/usr/click/tools/azure/textOuput.py
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/tools/azure/textOuput.py	(revision 39037)
+++ /branches/rel_apv_10_7_3/usr/click/tools/azure/textOuput.py	(working copy)
@@ -1,8 +0,0 @@
-import os
-from utils.OutputController import OutputController
-print("first")
-output_controller = OutputController()
-output_controller.start_to_file()
-print("start to file")
-output_controller.end_to_file()
-print("end to file")
\ No newline at end of file
Index: /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/router.py
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/router.py	(revision 39037)
+++ /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/router.py	(working copy)
@@ -744,33 +744,49 @@
                                     PackageLoader('apv', 'templates')]))
     if request.GET['type'] == "azure":
         if request.GET['page'] == "basic":
-            template = env.get_template("/ha/cloud/azure/basic.html")
+            template = env.get_template("/network/cloud/azure/basic.html")
             response = HttpResponse(template.render())
             return response
         elif request.GET['page'] == "nic":
-            template = env.get_template("/ha/cloud/azure/nic.html")
+            template = env.get_template("/network/cloud/azure/nic.html")
             response = HttpResponse(template.render())
             return response
         elif request.GET['page'] == "udr":
-            template = env.get_template("/ha/cloud/azure/udr.html")
+            template = env.get_template("/network/cloud/azure/udr.html")
             response = HttpResponse(template.render())
             return response
         elif request.GET['page'] == "log":
-            template = env.get_template("/ha/cloud/azure/log.html")
+            template = env.get_template("/network/cloud/azure/log.html")
             response = HttpResponse(template.render())
             return response
 
     elif request.GET['type'] == "aws":
         if request.GET['page'] == "basic":
-            template = env.get_template("/ha/cloud/aws/basic.html")
+            template = env.get_template("/network/cloud/aws/basic.html")
             response = HttpResponse(template.render())
             return response
         elif request.GET['page'] == "eni":
-            template = env.get_template("/ha/cloud/aws/eni.html")
+            template = env.get_template("/network/cloud/aws/eni.html")
             response = HttpResponse(template.render())
             return response
         elif request.GET['page'] == "log":
-            template = env.get_template("/ha/cloud/aws/log.html")
+            template = env.get_template("/network/cloud/aws/log.html")
+            response = HttpResponse(template.render())
+            return response
+    raise Http404('Page not found')
+
+def get_prometheus_page(request):
+    if not request.GET['type'] or not request.GET['page']:
+        raise Http404('Page not found')
+    env = HiveEnvironment(loader=ChoiceLoader([
+                                      PackageLoader('apv', 'templates')]))
+    if request.GET['type'] == "matrix":
+        if request.GET['page'] == "basic":
+            template = env.get_template("/monitoring/prometheus/index/basic.html")
+            response = HttpResponse(template.render())
+            return response
+        elif request.GET['page'] == "log":
+            template = env.get_template("/monitoring/prometheus/index/log.html")
             response = HttpResponse(template.render())
             return response
     raise Http404('Page not found')
\ No newline at end of file
Index: /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/templates/ha/cloud/aws/basic.html
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/templates/ha/cloud/aws/basic.html	(revision 39037)
+++ /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/templates/ha/cloud/aws/basic.html	(working copy)
@@ -1,196 +0,0 @@
-<form class="form-horizontal main-form">
-<div class="row-fluid">
-    <div class="span12 with-min-width field-group-box">
-
-        <fieldset class="log_out_component">
-            <div class="form-group">
-                <label class="col-md-3 control-label">{% trans %}access key{% endtrans %}:</label>
-                <div class="col-md-9 aws_access_key_field">
-                    <div class="align_center_for_info" target="_blank">...</div>
-                </div>
-            </div>
-             <div class="form-group">
-                <label class="col-md-3 control-label">{% trans %}secret access key{% endtrans %}:</label>
-                <div class="col-md-9 aws_secret_access_key_field">
-                    <div class="align_center_for_info" target="_blank">...</div>
-                </div>
-            </div>
-            <div class="form-group">
-                <label class="col-md-3 control-label">{% trans %}region{% endtrans %}:</label>
-                <div class="col-md-9 region_field">
-                    <div class="align_center_for_info" target="_blank">...</div>
-                </div>
-            </div>
-            <div class="form-group">
-                <label class="col-md-3 control-label"></label>
-                <div class="col-md-9">
-                    <button type="button" class="btn btn-primary btn-log-out">{% trans %}Log Out{% endtrans %}</button>
-                </div>
-            </div>
-        </fieldset>
-        <fieldset class='log_in_component'>
-                <fieldset>
-                    <div class="group_actions">
-                        <div class="form-group">
-                            <label class="col-md-3 control-label">{% trans %}access key{% endtrans %}:</label>
-                            <div class="col-md-9">
-                                <input type="text" class="field" data-id="aws_access_key_id" value=""/>
-                                <span class="field-icon-set"><i class="fa fa-question-circle"></i></span>
-                            </div>
-                        </div>
-                        <div class="form-group">
-                            <label class="col-md-3 control-label">{% trans %}secret access key{% endtrans %}:</label>
-                            <div class="col-md-9">
-                                <input type="text" class="field" data-id="aws_secret_access_key" value=""/>
-                                <span class="field-icon-set"><i class="fa fa-question-circle"></i></span>
-                            </div>
-                        </div>
-                        <div class="form-group">
-                            <label class="col-md-3 control-label">{% trans %}region{% endtrans %}:</label>
-                            <div class="col-md-9">
-                                <input type="text" class="field" data-id="region" value=""/>
-                                <span class="field-icon-set"><i class="fa fa-question-circle"></i></span>
-                            </div>
-                        </div>
-                        <div class="form-group">
-                            <label class="col-md-3 control-label"></label>
-                            <div class="col-md-9">
-                                <button type="button" class="btn btn-primary btn-log-in">{% trans %}Log In{% endtrans %}</button>
-                            </div>
-                        </div>
-                </fieldset>
-
-            </div>
-        </fieldset>
-        <fieldset class="error_field">
-            <div class="form-group">
-                <div class="col-md-3"></div>
-                <div class="error-info">{% trans %}Internal error, please refresh the page.{% endtrans %}</div>
-            </div>
-        </fieldset>
-
-
-    </div>
-</div>
-</form>
-<style type="text/css">
-.log_out_component{
-    display: none;
-}
-.align_center_for_info {
-    line-height: 28px;
-    display: inline-block;
-}
-
-.error_field {
-    display: none;
-}
-</style>
-
-{% block box_script %}
-
-<script type="text/javascript">
-
-$(function () {
-    getStatus();
-    function getStatus () {
-        $.ajax({
-            url: "/api/v1/cloud/aws/credential/",
-            type: 'GET',
-            dataType: 'json',
-            success: function (res) {
-                if (typeof (res["aws_access_key_id"]) === "undefined"
-                || typeof (res["aws_secret_access_key"]) === "undefined") {
-                    return
-                }
-
-                if (res["aws_access_key_id"] != ""
-                && res["aws_secret_access_key"] != "") {
-                    $('.aws_access_key_field div').html(res["aws_access_key_id"]);
-                    $('.aws_secret_access_key_field div').html(res["aws_secret_access_key"]);
-                    $('.region_field div').html(res["region"]);
-                    $('.log_in_component').css('display', 'none');
-                    $('.log_out_component').css('display', 'block');
-
-                }else{
-
-                    $('.log_out_component').css('display', 'none');
-                    $('.log_in_component').css('display', 'block');
-                    var content = [
-                    '{% trans %}Enter the access key, secret access key and region code(e.g. us-east-1) of AWS for the purpose of manipulating AWS resource.{% endtrans %}<br />',
-                        ].join("");
-                    $('.field-icon-set').popover({
-                        trigger: "hover",
-                        content: content,
-                        html: true
-                    });
-
-                }
-
-            },
-            error: function (xhr, textStatus, errorThrown) {
-                console.log(textStatus + "," + errorThrown + "," + xhr.responseText);
-            }
-        });
-    }
-    $('.btn-log-in').click(function(evt) {
-        if(evt.detail && evt.detail != 1) {
-            return;
-        }
-        var each = {};
-        $('.field').each(function() {
-            if ($(this).val() == "") {
-                return;
-            }
-
-            "data-id"
-            "data-id"
-            each[$(this).data('id')] = $(this).val();
-        });
-        if (Object.keys(each).length < 1) {
-            return;
-        }
-
-        $.ajax({
-            url: "/api/v1/cloud/aws/credential/",
-            type: 'POST',
-            dataType: 'json',
-            data: JSON.stringify({
-                aws_access_key_id: each.aws_access_key_id,
-                aws_secret_access_key: each.aws_secret_access_key,
-                region: each.region,
-            }),
-            success: function (res) {
-            getStatus();
-            },
-            error: function (xhr, textStatus, errorThrown) {
-                console.log(textStatus + "," + errorThrown + "," + xhr.responseText);
-            }
-        });
-
-    });
-    $('.btn-log-out').click(function() {
-        var that = this;
-        $(that).prop('disabled', true);
-        $.ajax({
-            url: "/api/v1/cloud/aws/credential/",
-            type: 'DELETE',
-            dataType: 'json',
-            success: function (res) {
-                $(that).prop('disabled', false);
-                getStatus();
-            },
-            error: function (xhr, textStatus, errorThrown) {
-                $(that).prop('disabled', false);
-                console.log(textStatus + "," + errorThrown + "," + xhr.responseText);
-            }
-        });
-    });
-
-
-
-});
-
-</script>
-
-{% endblock box_script %}
Index: /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/templates/ha/cloud/aws/eni.html
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/templates/ha/cloud/aws/eni.html	(revision 39037)
+++ /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/templates/ha/cloud/aws/eni.html	(working copy)
@@ -1,464 +0,0 @@
-<form class="form-horizontal main-form">
-<div class="row-fluid">
-    <div class="span12 with-min-width field-group-box">
-        <fieldset>
-            <div class="group_actions"></div>
-            <div class="form-group switch switch_enable">
-                <label class="col-md-3 control-label">{% trans %}Enable{% endtrans %}:</label>
-                <div class="col-md-3">
-                    <input class="switch-small" type="checkbox" name="switch_btn"
-                    data-on-label="{% trans %}Enable{% endtrans %}"
-                    data-off-label="{% trans %}Disabled{% endtrans %}" />
-                    <span class="field-icon-set"></span>
-                </div>
-                <label class="col-md-3 control-label">{% trans %}Manual Trigger{% endtrans %}:</label>
-                <div class="col-md-3 col-manual-trigger">
-                    <button type="button" class="btn btn-primary failover-btn">{% trans %}Failover{% endtrans %}</button>
-                    <button type="button" class="btn btn-primary recover-btn">{% trans %}Recover{% endtrans %}</button>
-                </div>
-            </div>
-        </fieldset>
-        <fieldset>
-            <div class="form-group add-btn-style">
-                <div class="col-md-3">
-                    <button type="button" class="btn btn-action add-btn"><i class="fa fa-plus-circle"></i>{% trans %}ADD{% endtrans %}</button>
-                </div>
-                <div class="col-md-9" id="app"></div>
-            </div>
-        </fieldset>
-    </div>
-</div>
-<!-- row-fluid -->
-<div class="btn-static">
-    <div class="btn-switch">
-        <button type="button" class="btn btn-action btn-submit">{% trans %}Save Changes{% endtrans %}</button>
-        <button type="button" class="btn btn-default btn-cancel-action">{% trans %}Cancel{% endtrans %}</button>
-    </div>
-</div>
-<div class="modal fade" id="addModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
-    <div class="modal-dialog">
-        <div class="box modal-content">
-            <div class="box-header">
-                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
-                    <span aria-hidden="true"></span></button>
-                    <h2>{{ gettext('New %s')%"NIC" }}</h2>
-                </button>
-            </div>
-            <div class="box-body">
-                <form class="form-horizontal main-form">
-                    <div class="padded">
-                        <div class="row-fluid">
-                            <div class="span12 with-min-width field-group-box modal-fields">
-                            </div>
-                        </div>
-                    </div>
-                    <div class="form-actions col-md-offset-3">
-                        <button type="button" class="btn btn-action btn-save">{% trans %}Submit{% endtrans %}</button>
-                        <button type="button" data-dismiss="modal" class="btn btn-default btn-cancel">{% trans %}Cancel{% endtrans %}</button>
-                    </div>
-                </form>
-            </div>
-        </div>
-    </div>
-</div>
-</form>
-<style type="text/css">
-.add-btn-style {
-    text-align: right;
-}
-.add-btn-style .add-btn {
-    background-color: transparent;
-    border: 0;
-}
-.modal-fields {
-    padding-top: 20px;
-}
-.form-actions {
-    padding-bottom: 20px;
-}
-#app {
-    display: flex;
-    flex-direction: row;
-    flex-wrap: wrap;
-}
-#app .block {
-    min-width: 200px;
-    box-sizing: border-box;
-    margin-right: 20px;
-}
-#app .box.modal-content {
-    border-radius: 6px;
-}
-#app .block .modal-dialog {
-    width: 100%;
-    margin: 0;
-}
-#app .box-header {
-    display: flex;
-    align-items: center;
-    justify-content: space-between;
-    padding-right: 10px;
-    padding-left: 10px;
-}
-#app .box-header button.close:active {
-    opacity: 0.2;
-}
-#app .box-body ul {
-    padding: 0;
-    list-style: none;
-}
-#app .box-body ul li {
-    padding: 5px;
-    text-align: left;
-}
-.btn-static {
-    display: none;
-}
-</style>
-</div>
-
-{% block box_script %}
-
-<script type="text/javascript">
-
-$(function(){
-    var enableSwitch = $("input[name='switch_btn']").bootstrapSwitch();
-    var is_init = 0;
-    getEnableStatus();
-    function getEnableStatus() {
-        // get the current status of enable toggle
-        $.ajax({
-            url: '/api/v1/cloud/aws/ha/status/',
-            type: 'GET',
-            dataType: 'json',
-            success: function (res) {
-                if (typeof(res["status"]) == "undefined") {
-                    return;
-                }
-                enableSwitch.bootstrapSwitch('setState', res["status"]);
-                is_init++;
-            },
-            error: function (xhr, textStatus, errorThrown) {
-                console.log(textStatus + "," + errorThrown + "," + xhr.responseText);
-            }
-        });
-    }
-    enableSwitch.on('switch-change', function(e, data) {
-        // event listener for enable toggle
-        if (is_init < 1) {
-            return;
-        }
-        $('#frame_model_main .btn-static').fadeIn("slow");
-        // why the following code is needed?
-        if ($(".btn-static").is(":visible")) {
-            var buttonH = $(".btn-static").offset().top;
-            $(function(){
-                $(window).scroll(function(){
-                    var scrollH = $(this).scrollTop();
-                    if (scrollH >= buttonH) {
-                        $(".btn-switch").addClass("btn-fixed");
-                    }else{
-                        $(".btn-switch").removeClass("btn-fixed");
-                    }
-                });
-            });
-        }
-    });
-    $('.btn-cancel-action').click(function(evt) {
-        // cancel btn of changing enable status
-        if(evt.detail && evt.detail != 1) {
-            return;
-        }
-        refreshPage();
-    });
-    $('.btn-submit').click(function(evt) {
-        // save btn of changing enable status
-        if(evt.detail && evt.detail != 1) {
-            return;
-        }
-        var enable = enableSwitch.bootstrapSwitch('state'); // true / false
-        $.ajax({
-            url: '/api/v1/cloud/aws/ha/status/',
-            type: 'POST',
-            dataType: 'json',
-            data: JSON.stringify({
-                status: (enable ? 1 : 0)
-            }),
-            success: function (res) {
-                refreshPage();
-            },
-            error: function (xhr, textStatus, errorThrown) {
-                console.log(textStatus + "," + errorThrown + "," + xhr.responseText);
-            }
-        });
-    });
-    var modal_fields = [{
-        field: '{% trans %}source ENI id{% endtrans %}',
-        id: 'src_eni_id',
-        value: ''
-    },{
-        field: '{% trans %}destination ENI {% endtrans %}',
-        id: 'dest_eni_id',
-        value: ''
-    },];
-    // for displaying fields in each block
-    var show_fields = ['index', 'dest_eni_id', 'src_eni_id'];
-    var is_show_field_title = true;
-
-    $('.add-btn').click(function() {
-        // add eni btn
-        var content = setContent(modal_fields);
-        $('.modal-fields').html(content);
-        $('#addModal').modal();
-    });
-    $('.failover-btn').click(function(evt) {
-        // btn of manual trigger failover
-        if(evt.detail && evt.detail != 1) {
-            return;
-        }
-        var that = this;
-        $(that).css("disabled", true);
-        $.ajax({
-            url: '/api/v1/cloud/aws/failover/',
-            type: 'PUT',
-            dataType: 'json',
-            data: JSON.stringify({
-                status: 1
-            }),
-            success: function (res) {
-                if (typeof(res["msg"]) == "undefined") {
-                console.log(res["msg"], typeof(res["msg"]))
-
-                    return;
-                }
-                alert(res["msg"]);
-                $(that).css("disabled", false);
-            },
-            error: function (xhr, textStatus, errorThrown) {
-                console.log(textStatus + "," + errorThrown + "," + xhr.responseText);
-                $(that).css("disabled", false);
-            }
-        });
-    });
-    $('.recover-btn').click(function(evt) {
-        // btn of manual trigger recover
-        if(evt.detail && evt.detail != 1) {
-            return;
-        }
-        var that = this;
-        $(that).css("disabled", true);
-        $.ajax({
-            url: '/api/v1/cloud/aws/recover/',
-            type: 'PUT',
-            dataType: 'json',
-            data: JSON.stringify({
-                status: 0
-            }),
-            success: function (res) {
-                console.log(res["msg"], typeof(res["msg"]))
-                if (typeof(res["msg"]) == "undefined") {
-                    return;
-                }
-                alert(res["msg"]);
-                $(that).css("disabled", false);
-            },
-            error: function (xhr, textStatus, errorThrown) {
-                console.log(textStatus + "," + errorThrown + "," + xhr.responseText);
-                $(that).css("disabled", false);
-            }
-        });
-    });
-    var config = [];
-    $('.btn-save').click(function(evt) {
-        // submit btn of adding eni
-        // why this can get the needed  data
-        if(evt.detail && evt.detail != 1) {
-            return;
-        }
-        var each = {};
-        $('.field').each(function() {
-            if ($(this).val() == "") {
-                return;
-            }
-            each[$(this).data('id')] = $(this).val();
-        });
-        if (Object.keys(each).length < 1) {
-            return;
-        }
-        addENI(each.src_eni_id, each.dest_eni_id);
-    });
-
-    getENIConfig();
-    function getENIConfig() {
-        // get list of eni config
-        $.ajax({
-            url: '/api/v1/cloud/aws/eniconfig/',
-            type: 'GET',
-            dataType: 'json',
-            success: function(res) {
-                for (var index in res) {
-                    config.push({
-                        primary_key: index,
-                        dest_eni_id: res[index].dest_eni_id,
-                        src_eni_id: res[index].src_eni_id,
-                    })
-                }
-                updateBlockList(config, show_fields, is_show_field_title);
-
-            },
-            error: function (xhr, textStatus, errorThrown) {
-                console.log(textStatus + "," + errorThrown + "," + xhr.responseText);
-            }
-        });
-    }
-
-    /**
-     * Return html string for content of pop up window(Add)
-     * @param array setting: array for each setting
-     * @return string
-     */
-    function setContent(setting) {
-        // for modal of adding eni
-        var html = [];
-        for (var ind = 0; ind < setting.length; ++ind) {
-            var each = setting[ind];
-            html.push([
-                '<fieldset>',
-                    '<div class="group_actions"></div>',
-                        '<div class="form-group">',
-                        '<label class="col-md-3 control-label">',
-                            setting[ind].field,
-                        ':</label>',
-                        '<div class="col-md-9">',
-                            '<input type="text" class="field" data-id="' + setting[ind].id,
-                            '" value="' + setting[ind].value + '" />',
-                        '</div>',
-                    '</div>',
-                '</fieldset>'
-            ].join(""));
-        }
-        return html.join("");
-    }
-
-    /**
-     * Update layout for each blocks
-     * @param array setting: array of block information
-     * @param array fields: array of displaying fields, empty is all
-     * @param bool value_only: display value or [field: value] for each list
-     * @return void
-     */
-    function updateBlockList(setting, fields = [], value_only = true) {
-        // update and rerender the list of eni config
-        var html = [];
-        var nameMapping = getNameMapping(); // ex: sub_id: SubId
-        for (var ind = 0; ind < setting.length; ++ind) {
-            var list = [];
-            for (var field in setting[ind]) {
-                if (fields.length !== 0 && fields.indexOf(field) === -1) {
-                    // Not display
-                    continue;
-                }
-                if (field == "index") {
-                    // Not display
-                    continue;
-                }
-                var content = setting[ind][field];
-                if (!value_only) {
-                    var display_name = "";
-                    if (nameMapping.hasOwnProperty(field)) {
-                        display_name = nameMapping[field];
-                    }
-                    content = display_name + ": " + content;
-                }
-                list.push([
-                    '<li data-id="' + field + '">' + content + '</li>'
-                ].join(""));
-            }
-            html.push([
-                '<div class="block">',
-                    '<div class="modal-dialog">',
-                        '<div class="box modal-content">',
-                            '<div class="box-header">',
-                                '<span>' + setting[ind]['primary_key'] + '</span>',
-                                '<button type="button" class="close" aria-label="Close"',
-                                    'data-id="' + setting[ind]['primary_key'] + '">',
-                                    '<span aria-hidden="true">&times;</span></button>',
-                            '</div>',
-                            '<div class="box-body">',
-                                '<ul>',
-                                    list.join(""),
-                                '</ul>',
-                            '</div>',
-                        '</div>',
-                    '</div>',
-                '</div>'
-            ].join(""));
-        }
-        $('#app').html(html.join(""));
-        $('#app .block .box-header button').click(function() {
-            var index = parseInt($(this).data("id"));
-            delNIC(index);
-        });
-    }
-
-    function addENI(src_eni_id, dest_eni_id) {
-        // add eni api
-        $.ajax({
-            url: '/api/v1/cloud/aws/eniconfig/',
-            type: 'POST',
-            dataType: 'json',
-            data: JSON.stringify({
-                src_eni_id: src_eni_id,
-                dest_eni_id: dest_eni_id,
-            }),
-            success: function(res) {
-                $('#addModal').modal('hide');
-                setTimeout(function() {
-                    refreshPage();
-                }, 400);
-            },
-            error: function (xhr, textStatus, errorThrown) {
-                $('#addModal').modal('hide');
-                console.log(textStatus + "," + errorThrown + "," + xhr.responseText);
-            }
-        });
-    }
-
-    function delNIC(index) {
-        // delete eni api
-        $.ajax({
-            url: '/api/v1/cloud/aws/eniconfig/',
-            type: 'DELETE',
-            dataType: 'json',
-            data: JSON.stringify({
-                index: String(index)
-            }),
-            success: function(res) {
-                refreshPage();
-            },
-            error: function (xhr, textStatus, errorThrown) {
-                console.log(textStatus + "," + errorThrown + "," + xhr.responseText);
-            }
-        });
-    }
-
-    /**
-     * Get Display name mapping by index
-     * @return object
-     */
-    function getNameMapping() {
-        var mapping = {};
-        for (var ind = 0; ind < modal_fields.length; ++ind) {
-            mapping[modal_fields[ind].id] = modal_fields[ind].field;
-        }
-        return mapping;
-    }
-
-    function refreshPage() {
-        $('.config-nav li.active a').trigger('click');
-    }
-
-});
-
-</script>
-{% endblock box_script %}
Index: /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/templates/ha/cloud/aws/index.html
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/templates/ha/cloud/aws/index.html	(revision 39037)
+++ /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/templates/ha/cloud/aws/index.html	(working copy)
@@ -1,117 +0,0 @@
-{% extends "base.html" %}
-
-{% block content %}
-
-{% block horizontal_nav %}
-<div class="horizontal-nav">
-    <div class="crumbs">
-        <a href="/apv/ha/cloud/azure/_index"><i class="fa fa-home"></i></a>
-    </div>
-<ul class="nav nav-tabs">
-    <li class="active">
-        <a href="/apv/ha/cloud/azure/_index">Azure</a>
-    </li>
-    <li class="active">
-        <a href="/apv/ha/cloud/aws/_index">AWS</a>
-    </li>
-</ul>
-</div>
-<div></div>
-{% endblock horizontal_nav %}
-
-<div class="head-nav-box clearfix-before">
-{% block model_nav %}
-<nav class="head-nav" role="navigation">
-    <a class="model-name" href="#" style="width:90%;"><i class="fa fa-folder-open"></i>&nbsp;AWS</a>
-</nav>
-{% endblock model_nav %}
-</div>
-
-{% block sub_nav %}
-<ul class="config-nav nav nav-pills" style="display:none;">
-    <li class="active">
-        <a class="config-nav-a" val="/apv/get_cloud_page?type=aws&page=basic" href="javascript:;">{% trans %}Basic Settings{% endtrans %} <i class="fa fa-wrench"></i></a>
-        <ul class="sub-config-nav group-index">
-            <li><a val="/apv/get_cloud_page?type=azure&page=basic" href="javascript:;">General</a></li>
-        </ul>
-    </li>
-    <li>
-        <a class="config-nav-a" val="/apv/get_cloud_page?type=aws&page=eni" href="javascript:;">{% trans %}ENI{% endtrans %} <i class="fa fa-wrench"></i></a>
-        <ul class="sub-config-nav group-nic">
-            <li><a val="/apv/get_cloud_page?type=aws&page=eni" href="javascript:;">General</a></li>
-        </ul>
-    </li>
-
-    <li>
-        <a class="config-nav-a" val="/apv/get_cloud_page?type=azure&page=log" href="javascript:;">{% trans %}Log{% endtrans %} <i class="fa fa-wrench"></i></a>
-        <ul class="sub-config-nav group-log">
-            <li><a val="/apv/get_cloud_page?type=azure&page=log" href="javascript:;">General</a></li>
-        </ul>
-    </li>
-</ul>
-<ul class="sub-config-nav-real"></ul>
-<script type="text/javascript">
-require(['jquery'], function(){
-    if ($('.config-nav li').length > 1) {
-        $('.config-nav').show();
-    }
-});
-</script>
-{% endblock %}
-
-<div id="frame_model_main" class="frame" style="display: block;">
-</div>
-<style type="text/css">
-#frame_model_main {
-    position: relative;
-}
-.align_center_for_info {
-    line-height: 28px;
-}
-</style>
-
-{% endblock %}
-
-{% block page_javascript %}
-<script type="text/javascript">
-require(['jquery'], function(){
-    $(".config-nav-a").on("click", function(e) {
-        e.preventDefault();
-    });
-});
-require(['hive', 'widget-form'], function(){
-    var initiator = new Object();
-    $HIVE.enable_event(initiator);
-    $(".config-nav a.config-nav-a").click(function(){
-        $(".config-nav li").removeClass("active");
-        $(this).parents("li").addClass("active");
-        var sub_nav = $($(this).parents('li').find('ul')[0])
-        if (sub_nav && sub_nav.children().length > 1) {
-           var real_sub_nav = sub_nav.clone(true).removeClass('sub-config-nav').addClass('sub-config-nav-real');
-            $(".sub-config-nav-real").replaceWith(real_sub_nav);
-            $(".sub-config-nav-real").show();
-            $("#frame_instance_main").css("padding-top", "50px");
-            real_sub_nav.find('a').click(function(){
-                $(".sub-config-nav-real li").removeClass("active");
-                $(this).parents("li").addClass("active");
-                var url = $(this).attr('val')
-                $HIVE.ajax_load_box(url, initiator, $("#frame_model_main"));
-                return false;
-            });
-            $(".sub-config-nav-real a:first").trigger("click");
-        } else {
-            $("#frame_instance_main").css("padding-top", "0px");
-            $(".sub-config-nav-real").empty();
-            $(".sub-config-nav-real").hide();
-            var url = $(this).attr('val')
-            $HIVE.ajax_load_box(url, initiator, $("#frame_model_main"));
-        }
-        return false;
-    });
-    $(".config-nav a:first").trigger("click");
-});
-</script>
-{% endblock %}
-
-{% block box_script %}
-{% endblock %}
Index: /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/templates/ha/cloud/aws/log.html
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/templates/ha/cloud/aws/log.html	(revision 39037)
+++ /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/templates/ha/cloud/aws/log.html	(working copy)
@@ -1,259 +0,0 @@
-
-<form class="form-horizontal main-form">
-    <div class="row-fluid">
-        <div class="span12 with-min-width field-group-box">
-            <fieldset>
-                <div class="group_actions"></div>
-                <div class="form-group switch switch_enable">
-                    <label class="col-md-3 control-label">{% trans %}Enable{% endtrans %}:</label>
-                    <div class="col-md-9">
-                        <input class="switch-small" type="checkbox" name="switch_btn"
-                        data-on-label="{% trans %}On{% endtrans %}"
-                        data-off-label="{% trans %}Off{% endtrans %}" />
-                        <span class="field-icon-set"></span>
-                    </div>
-                </div>
-            </fieldset>
-            <fieldset>
-                <div class="form-group">
-                    <label class="col-md-3 control-label">{% trans %}Level{% endtrans %}</label>
-                    <div class="col-md-9">
-                        <select class="selectpicker select-level">
-                            <option value="debug">0: {% trans %}Debug{% endtrans %}</option>
-                            <option value="info">1: {% trans %}Info{% endtrans %}</option>
-                            <option value="warning">2: {% trans %}Warning{% endtrans %}</option>
-                            <option value="error">3: {% trans %}Error{% endtrans %}</option>
-                        </select>
-                        <span class="field-icon-set"><i class="fa fa-question-circle" style="display:none;"></i></span>
-                    </div>
-                </div>
-            </fieldset>
-            <fieldset>
-                <div class="form-group">
-                    <label class="col-md-3 control-label"></label>
-                    <div class="col-md-9">
-                        <button type="button" class="btn btn-primary download-btn">{% trans %}Download{% endtrans %}</button>
-                    </div>
-                </div>
-            </fieldset>
-            <fieldset>
-                <pre class="log_content"></pre>
-            </fieldset>
-        </div>
-    </div><!-- row-fluid -->
-    <div
-    class="btn-static">
-        <div class="btn-switch">
-            <button type="button" class="btn btn-action btn-submit">{% trans %}Save Changes{% endtrans %}</button>
-            <button type="button" class="btn btn-default btn-cancel-action">{% trans %}Cancel{% endtrans %}</button>
-        </div>
-    </div>
-</form>
-<style type="text/css">
-.main-form pre {
-    background: #1b2d43;
-}
-.btn-static {
-    display: none;
-}
-</style>
-
-{% block box_script %}
-
-<script type="text/javascript">
-
-$(function() {
-    var enableSwitch = $("input[name='switch_btn']").bootstrapSwitch();
-    let is_change = false
-
-    $('.btn-cancel-action').click(function(evt) {
-        // cancel current changes
-        if(evt.detail && evt.detail != 1) {
-            return;
-        }
-        refreshPage();
-    });
-    $('.btn-submit').click(function(evt) {
-        // submit the chages of state of log functionality and log severity
-        if(evt.detail && evt.detail != 1) {
-            return;
-        }
-        var enable = enableSwitch.bootstrapSwitch('state'); // true / false
-        var ajaxes = [];
-        ajaxes.push($.ajax({
-            url: '/api/v1/cloud/aws/log/status/',
-            type: 'PUT',
-            dataType: 'json',
-            data: JSON.stringify({
-                status: (enable ? 1 : 0)
-            }),
-            success: function (res) {
-            },
-            error: function (xhr, textStatus, errorThrown) {
-                console.log(textStatus + "," + errorThrown + "," + xhr.responseText);
-            }
-        }));
-        ajaxes.push($.ajax({
-            url: '/api/v1/cloud/aws/log/severity/',
-            type: 'PUT',
-            dataType: 'json',
-            data: JSON.stringify({
-                severity: $(".select-level").selectpicker('val')
-            }),
-            success: function (res) {
-                refreshPage();
-            },
-            error: function (xhr, textStatus, errorThrown) {
-                console.log(textStatus + "," + errorThrown + "," + xhr.responseText);
-            }
-        }));
-        refreshPage();
-    });
-
-    $('.download-btn').click(function(evt) {
-        // add event listener to the download button
-        if(evt.detail && evt.detail != 1) {
-            return;
-        }
-        window.open("/api/v1/cloud/aws/log/file/");
-    });
-
-    async function getEnableStatus() {
-        // get the status of the log functionality
-        console.log("getEnableStatus");
-        const res = await new Promise((resolve, reject) => {
-            $.ajax({
-                url: '/api/v1/cloud/aws/log/status/',
-                type: 'GET',
-                dataType: 'json',
-                success: function (response) {
-
-                    if (typeof(response["status"]) === "undefined") {
-                        reject("Status undefined");
-                    } else {
-                        enableSwitch.bootstrapSwitch('setState', response["status"]);
-                        $('.btn-static').css('display', 'none');
-
-                        resolve(response);  // Resolve the promise with the response data
-                    }
-                },
-                error: function (xhr, textStatus, errorThrown) {
-                    console.log(textStatus + "," + errorThrown + "," + xhr.responseText);
-                    reject(errorThrown);  // Reject the promise on AJAX error
-                }
-            });
-        });
-        console.log("finish getEnableStatus")
-
-        // Return the result if necessary (optional)
-        return res;
-    }
-
-    async function getLogLevel() {
-        // get the current log level
-        const res = await new Promise((resolve, reject) => {
-            console.log("getLogLevel")
-            $.ajax({
-            url: '/api/v1/cloud/aws/log/severity/',
-            type: 'GET',
-            dataType: 'json',
-            success: function (response) {
-                if (typeof(response["severity"]) == "undefined") {
-                    reject("Status undefined");
-                }
-                $('.select-level').selectpicker("val", response["severity"]);
-                $('.btn-static').css('display', 'none');
-
-                resolve(response);  // Resolve the promise with the response data
-            },
-            error: function (xhr, textStatus, errorThrown) {
-                console.log(textStatus + "," + errorThrown + "," + xhr.responseText);
-                reject(errorThrown);  // Reject the promise on AJAX error
-            }
-            });
-        });
-        console.log("finish getLogLevel")
-        return res;
-
-    }
-    async function getLog() {
-        // get the content of log
-        const res = await new Promise((resolve, reject) => {
-            console.log("getInit")
-            $.ajax({
-            url: '/api/v1/cloud/aws/log/buffer/',
-            type: 'GET',
-            dataType: 'json',
-            success: function(response) {
-                if (typeof(response["msg"]) == "undefined") {
-                    return;
-                }
-                $('.log_content').html(response ["msg"]);
-                resolve(response);  // Resolve the promise with the response data
-            },
-            error: function (xhr, textStatus, errorThrown) {
-                console.log(textStatus + "," + errorThrown + "," + xhr.responseText);
-                reject(errorThrown);  // Reject the promise on AJAX error
-            }
-        });
-        });
-        console.log("finish getLog")
-
-        return res;
-
-    }
-    initPage();
-    async function initPage(){
-        console.log("init")
-        // Run all three functions asynchronously
-        await Promise.all([getEnableStatus(), getLogLevel(), getLog()]);
-        // Once all functions are completed, hide the element
-        console.log("display none");
-        $('.btn-static').css('display', 'none');
-
-        enableSwitch.on('switch-change', function(e, data) {
-            // add the event listener to the enable switch
-            $('#frame_model_main .btn-static').fadeIn("slow");
-            if ($(".btn-static").is(":visible")) {
-                var buttonH = $(".btn-static").offset().top;
-                $(function(){
-                    $(window).scroll(function(){
-                        var scrollH = $(this).scrollTop();
-                        if (scrollH >= buttonH) {
-                            $(".btn-switch").addClass("btn-fixed");
-                        }else{
-                            $(".btn-switch").removeClass("btn-fixed");
-                        }
-                    });
-                });
-            }
-        });
-        $(".select-level").change(function() {
-            // add the event listener to the log level select
-            $('#frame_model_main .btn-static').fadeIn("slow");
-            if ($(".btn-static").is(":visible")) {
-                var buttonH = $(".btn-static").offset().top;
-                $(function(){
-                    $(window).scroll(function(){
-                        var scrollH = $(this).scrollTop();
-                        if (scrollH >= buttonH) {
-                            $(".btn-switch").addClass("btn-fixed");
-                        }else{
-                            $(".btn-switch").removeClass("btn-fixed");
-                        }
-                    });
-                });
-            }
-        });
-    }
-
-    function refreshPage() {
-        $('.config-nav li.active a').trigger('click');
-    }
-
-    $('.select-level').selectpicker();
-
-});
-
-</script>
-{% endblock box_script %}
Index: /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/templates/monitoring/prometheus/index/basic.html
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/templates/monitoring/prometheus/index/basic.html	(revision 0)
+++ /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/templates/monitoring/prometheus/index/basic.html	(working copy)
@@ -0,0 +1,1081 @@
+<link rel="stylesheet" type="text/css" href="../../../../media/css/dataTables.dataTables.css" />
+<form class="form-horizontal main-form">
+    <div class="row-fluid">
+        <div class="span12 with-min-width field-group-box">
+            <fieldset>
+                <div class="group_actions"></div>
+                <div class="form-group switch switch_enable">
+                    <label class="col-md-3 control-label">{% trans %}Enable{% endtrans %}</label>
+                    <div class="col-md-9">
+                        <input class="switch-small" type="checkbox" name="switch_btn"
+                            data-on-label="{% trans %}Enable{% endtrans %}"
+                            data-off-label="{% trans %}Disable{% endtrans %}" />
+                        <span class="field-icon-set"></span>
+                    </div>
+                </div>
+            </fieldset>
+            <fieldset class="controled active">
+                <div class="form-group">
+                    <label class="col-md-3 control-label">{% trans %}Port{% endtrans %}</label>
+                    <div class="col-md-9">
+                        <input type="number" name="port_number" min="0" max="65535" /> (0-65535)
+                    </div>
+                </div>
+            </fieldset>
+            <fieldset class="controled active">
+                <div class="group_actions"></div>
+                <div class="form-group switch switch_enable">
+                    <label class="col-md-3 control-label">{% trans %}Enable HTTPS{% endtrans %}</label>
+                    <div class="col-md-9">
+                        <input class="switch-small" type="checkbox" name="switch_https_btn"
+                            data-on-label="{% trans %}Enable{% endtrans %}"
+                            data-off-label="{% trans %}Disable{% endtrans %}" />
+                        <span class="field-icon-set"></span>
+                    </div>
+                </div>
+            </fieldset>
+            <fieldset class="controled active">
+                <div class="form-group">
+                    <label class="col-md-3 control-label">{% trans %}Certificate{% endtrans %}</label>
+                    <div class="col-md-9">
+                        <button type="button" class="btn btn-primary lightbox-toggle">Import</button>
+                        <button type="button" class="btn btn-danger remove-data">Remove</button>
+                    </div>
+                </div>
+            </fieldset>
+            <fieldset class="controled active">
+                <div class="form-group">
+                    <label class="col-md-3 control-label">{% trans %}TTL{% endtrans %}</label>
+                    <div class="col-md-9">
+                        <input type="number" name="ttl" min="3" max="60" /> (3-60)min
+                    </div>
+                </div>
+            </fieldset>
+        </div>
+    </div><!-- row-fluid -->
+    <div class="btn-static">
+        <div class="btn-switch">
+            <button type="button" class="btn btn-action btn-submit">{% trans %}Save Changes{% endtrans %}</button>
+            <button type="button" class="btn btn-default btn-cancel-action">{% trans %}Cancel{% endtrans %}</button>
+        </div>
+    </div>
+    <div id="basic-setting-table">
+        <div class="box-header" id="25db1b5a-6eae-43a0-972b-2df786ddaf74_header">
+            <div class="box-bg-spe">
+                <div class="box-icon-title">
+                    <i class="fa fa-list-alt" id="25db1b5a-6eae-43a0-972b-2df786ddaf74_setting"></i>
+                </div>
+            </div>
+            <div class="control-group table-btn-group" id="25db1b5a-6eae-43a0-972b-2df786ddaf74_actions">
+                <button type="button" class="btn btn-action add-btn"><i class="fa fa-plus-circle"></i>ADD</button>
+                <button type="button" class="btn btn-action delete-btn disabled"><i class="fa fa-minus-circle"></i>DELETE</button>
+                <select class="expired-filter" id="25db1b5a-6eae-43a0-972b-2df786ddaf74_expired_filter">
+                    <option value="all">All</option>
+                    <option value="expired">Expired</option>
+                    <option value="not_expired">Not Expired</option>
+                </select>
+            </div>
+            <div class="pull-right filter-control-group">
+            </div>
+        </div>
+        <table id="prometheus_token" class="display" style="width:100%">
+            <thead>
+                <tr>
+                    <th></th>
+                    <th>ID</th>
+                    <th>{% trans %}User Name{% endtrans %}</th>
+                    <th>{% trans %}Token{% endtrans %}</th>
+                    <th>{% trans %}Created Date{% endtrans %}</th>
+                    <th>{% trans %}Expired Date{% endtrans %}</th>
+                    <th>{% trans %}Last Used Date{% endtrans %}</th>
+                    <th>{% trans %}Is Expired{% endtrans %}</th>
+                </tr>
+            </thead>
+        </table>
+    </div>
+</form>
+<div class="custom-lightbox">
+    <div class="lightbox-toggle close-lightbox">
+        <i class="fa modal-close-icon">×</i>
+    </div>
+    <div class="lightbox-content">
+        <div class="box">
+            <div class="box-header my-header">
+                <div class="box-icon-title">
+                    <i class="fa fa-wrench"></i>
+                </div>
+                <h2>Import Certificate</h2>
+            </div>
+            <div class="box-content">
+                <form class="form-horizontal main-form">
+                <script type="text/javascript">
+                        var js_hook_8f332b50_80db_42ca_a4cb_e33faf2ab4a3_Import_Cert = {
+                        id: "8f332b50_80db_42ca_a4cb_e33faf2ab4a3_Import_Cert",
+                        form_fields: {},
+                        ready_total: 0,
+                        ready_count: 0,
+                    };
+                </script>
+                <div class="row-fluid">
+                    <div class="span12 with-min-width field-group-box">
+                        <a id="Import Certificate"></a>
+                        <legend>Import Certificate</legend>
+                        <fieldset>
+                            <div class="form-group unionwidget union_using" id="0x4f">
+                                <script type="text/javascript">
+                                    var inner_hook_e05277ce_9d29_4ff0_994e_2e363b8816fd =
+                                        new Object();
+                                    inner_hook_e05277ce_9d29_4ff0_994e_2e363b8816fd.id =
+                                        "e05277ce_9d29_4ff0_994e_2e363b8816fd";
+                                    inner_hook_e05277ce_9d29_4ff0_994e_2e363b8816fd.form_fields =
+                                        {};
+                                    inner_hook_e05277ce_9d29_4ff0_994e_2e363b8816fd.ready_total = 0;
+                                    inner_hook_e05277ce_9d29_4ff0_994e_2e363b8816fd.ready_count = 0;
+                                </script>
+                                <div class="col-md-9 union-content">
+                                    <div class="btn-group select-tab-group">
+                                        <label class="btn nested-radio active">
+                                            <input
+                                                style="display: none"
+                                                type="radio"
+                                                name="radio_0x4f"
+                                                value="local"
+                                                checked="checked"
+                                            />
+                                            <span class="field-name">Local File</span>
+                                        </label>
+                                        <label class="btn nested-radio">
+                                            <input
+                                                style="display: none"
+                                                type="radio"
+                                                name="radio_0x4f"
+                                                value="online"
+                                            />
+                                            <span class="field-name">TFTP/FTP/HTTP</span>
+                                        </label>
+                                        <label class="btn nested-radio">
+                                            <input
+                                                style="display: none"
+                                                type="radio"
+                                                name="radio_0x4f"
+                                                value="manual_input"
+                                            />
+                                            <span class="field-name">Manual Input</span>
+                                        </label>
+                                    </div>
+                                <div
+                                    class="form-nested groupwidget group_local"
+                                    id="0x50"
+                                    style=""
+                                >
+                                    <script type="text/javascript">
+                                        var inner_hook_ceecbb9b_54c8_4e18_a7eb_7da8c7b731f1 =
+                                            new Object();
+                                        inner_hook_ceecbb9b_54c8_4e18_a7eb_7da8c7b731f1.id =
+                                            "ceecbb9b_54c8_4e18_a7eb_7da8c7b731f1";
+                                        inner_hook_ceecbb9b_54c8_4e18_a7eb_7da8c7b731f1.form_fields =
+                                            {};
+                                        inner_hook_ceecbb9b_54c8_4e18_a7eb_7da8c7b731f1.ready_total = 0;
+                                        inner_hook_ceecbb9b_54c8_4e18_a7eb_7da8c7b731f1.ready_count = 0;
+                                    </script>
+                                    <div>
+                                        <div>
+                                            <label class="nested-name">Private Key</label>
+                                            <div class="file-upload">
+                                                <input type="file" id="private-key" name="private-key" class="form-control" accept=".pem,.key" />
+                                                <button type="button" id="upload-private-button" class="btn btn-primary">Upload</button>
+                                                <textarea id="private-key-textarea" class="file-text"></textarea>
+                                            </div>
+
+                                            <label class="nested-name">Certificate</label>
+                                            <div class="file-upload">
+                                                <input type="file" id="certificate" name="certificate" class="form-control" accept=".pem,.crt,.cer" />
+                                                <button type="button" id="upload-certificate-button" class="btn btn-primary">Upload</button>
+                                                <textarea id="certificate-textarea" class="file-text"></textarea>
+                                            </div>
+                                        </div>
+                                        <div class="action-btn">
+                                            <button
+                                                type="button"
+                                                class="btn action-btn action-btn-Import_Cert btn-danger slow-action"
+                                                id="upload-cert-button-file"
+                                            >
+                                                Import
+                                            </button>
+                                        </div>
+                                    </div>
+                                </div>
+                                <script type="text/javascript">
+                                    inner_hook_e05277ce_9d29_4ff0_994e_2e363b8816fd.ready_total++;
+                                    require(["widget-form", "domReady"], function (form) {
+                                    var widget = $.parseJSON(
+                                        window.atob(
+                                        "eyJuYW1lIjogImxvY2FsIiwgImlkIjogIjB4NTAiLCAicmVxdWlyZWQiOiB0cnVlLCAibGFiZWwiOiAiTG9jYWwgRmlsZSIsICJoZWxwX3RleHQiOiAiIiwgIl9pZCI6IDgwLCAiZmllbGRfbGlzdCI6IFsiPC5sb2NhbC5wZW06IEltcG9ydExvY2FsRmlsZUZpZWxkPiIsICI8LmxvY2FsLnBhc3NwaHJhc2U6IFBhc3N3b3JkRmllbGQ+Il19"
+                                        )
+                                    );
+                                    widget["field_list"] = [];
+                                    widget["field_list"].push("pem");
+                                    var hook = inner_hook_e05277ce_9d29_4ff0_994e_2e363b8816fd;
+                                    form.on_ready(
+                                        inner_hook_ceecbb9b_54c8_4e18_a7eb_7da8c7b731f1,
+                                        function () {
+                                            var widget_view = new form.FormGroup(
+                                                widget,
+                                                hook,
+                                                inner_hook_ceecbb9b_54c8_4e18_a7eb_7da8c7b731f1
+                                            );
+                                        }
+                                    );
+                                    });
+                                </script>
+                                <div
+                                    class="form-nested groupwidget group_online"
+                                    id="0x53"
+                                    style="display: none"
+                                >
+                                    <script type="text/javascript">
+                                        var inner_hook_02119340_6a90_47d3_904d_a6ed367f19ba =
+                                            new Object();
+                                        inner_hook_02119340_6a90_47d3_904d_a6ed367f19ba.id =
+                                            "02119340_6a90_47d3_904d_a6ed367f19ba";
+                                        inner_hook_02119340_6a90_47d3_904d_a6ed367f19ba.form_fields =
+                                            {};
+                                        inner_hook_02119340_6a90_47d3_904d_a6ed367f19ba.ready_total = 0;
+                                        inner_hook_02119340_6a90_47d3_904d_a6ed367f19ba.ready_count = 0;
+                                    </script>
+                                    <div>
+                                    <div>
+                                        <div>
+                                            <div>
+                                                <div>
+                                                    <label class="nested-name">Private Key URL</label>
+                                                    <div class="file-upload">
+                                                        <input type="text" id="private-key-url" name="private-key" class="form-control" />
+                                                    </div>
+        
+                                                    <label class="nested-name">Certificate URL</label>
+                                                    <div class="file-upload">
+                                                        <input type="text" id="certificate-url" name="certificate" class="form-control" />
+                                                    </div>
+                                                </div>
+                                                <div class="action-btn">
+                                                    <button
+                                                        type="button"
+                                                        class="btn action-btn action-btn-Import_Cert btn-danger slow-action"
+                                                        id="upload-cert-button-url"
+                                                    >
+                                                        Import
+                                                    </button>
+                                                </div>
+                                            </div>
+                                        </div>
+                                    </div>
+                                    </div>
+                                </div>
+                                <script type="text/javascript">
+                                    inner_hook_e05277ce_9d29_4ff0_994e_2e363b8816fd.ready_total++;
+                                    require(["widget-form", "domReady"], function (form) {
+                                    var widget = $.parseJSON(
+                                        window.atob(
+                                        "eyJuYW1lIjogIm9ubGluZSIsICJpZCI6ICIweDUzIiwgInJlcXVpcmVkIjogdHJ1ZSwgImxhYmVsIjogIlRGVFAvRlRQL0hUVFAiLCAiaGVscF90ZXh0IjogIiIsICJfaWQiOiA4MywgImZpZWxkX2xpc3QiOiBbIjwub25saW5lLnVybDogVVJMRmllbGQ+IiwgIjwub25saW5lLnBhc3NwaHJhc2U6IFBhc3N3b3JkRmllbGQ+Il19"
+                                        )
+                                    );
+                                    widget["field_list"] = [];
+                                    widget["field_list"].push("url");
+                                    var hook = inner_hook_e05277ce_9d29_4ff0_994e_2e363b8816fd;
+                                    form.on_ready(
+                                        inner_hook_02119340_6a90_47d3_904d_a6ed367f19ba,
+                                        function () {
+                                            var widget_view = new form.FormGroup(
+                                                widget,
+                                                hook,
+                                                inner_hook_02119340_6a90_47d3_904d_a6ed367f19ba
+                                            );
+                                        }
+                                    );
+                                    });
+                                </script>
+                                <div
+                                    class="form-nested groupwidget group_manual_input"
+                                    id="0x56"
+                                    style="display: none"
+                                >
+                                    <script type="text/javascript">
+                                    var inner_hook_607c854e_57cb_4aeb_9bce_6edbc30dae26 =
+                                        new Object();
+                                    inner_hook_607c854e_57cb_4aeb_9bce_6edbc30dae26.id =
+                                        "607c854e_57cb_4aeb_9bce_6edbc30dae26";
+                                    inner_hook_607c854e_57cb_4aeb_9bce_6edbc30dae26.form_fields =
+                                        {};
+                                    inner_hook_607c854e_57cb_4aeb_9bce_6edbc30dae26.ready_total = 0;
+                                    inner_hook_607c854e_57cb_4aeb_9bce_6edbc30dae26.ready_count = 0;
+                                    </script>
+                                    <div>
+                                    <div>
+                                        <div>
+                                            <div>
+                                                <div>
+                                                    <label class="nested-name">Private Key</label>
+                                                    <div class="file-upload">
+                                                        <textarea id="private-key-textarea-manual" class="file-text"></textarea>
+                                                    </div>
+        
+                                                    <label class="nested-name">Certificate</label>
+                                                    <div class="file-upload">
+                                                        <textarea id="certificate-textarea-manual" class="file-text"></textarea>
+                                                    </div>
+                                                </div>
+                                                <div class="action-btn">
+                                                    <button
+                                                        type="button"
+                                                        class="btn action-btn action-btn-Import_Cert btn-danger slow-action"
+                                                        id="upload-cert-button-manual"
+                                                    >
+                                                        Import
+                                                    </button>
+                                                </div>
+                                            </div>
+                                        </div>
+                                    </div>
+                                    </div>
+                                </div>
+                                <script type="text/javascript">
+                                    inner_hook_e05277ce_9d29_4ff0_994e_2e363b8816fd.ready_total++;
+                                    require(["widget-form", "domReady"], function (form) {
+                                    var widget = $.parseJSON(
+                                        window.atob(
+                                        "eyJuYW1lIjogIm1hbnVhbF9pbnB1dCIsICJpZCI6ICIweDU2IiwgInJlcXVpcmVkIjogdHJ1ZSwgImxhYmVsIjogIk1hbnVhbCBJbnB1dCIsICJoZWxwX3RleHQiOiAiIiwgIl9pZCI6IDg2LCAiZmllbGRfbGlzdCI6IFsiPC5tYW51YWxfaW5wdXQuY2VydF9jb250ZW50OiBUZXh0RmllbGQ+IiwgIjwubWFudWFsX2lucHV0LnBhc3NwaHJhc2U6IFBhc3N3b3JkRmllbGQ+Il19"
+                                        )
+                                    );
+                                    widget["field_list"] = [];
+                                    widget["field_list"].push("cert_content");
+                                    widget["field_list"].push("passphrase");
+                                    var hook = inner_hook_e05277ce_9d29_4ff0_994e_2e363b8816fd;
+                                    form.on_ready(
+                                        inner_hook_607c854e_57cb_4aeb_9bce_6edbc30dae26,
+                                        function () {
+                                            var widget_view = new form.FormGroup(
+                                                widget,
+                                                hook,
+                                                inner_hook_607c854e_57cb_4aeb_9bce_6edbc30dae26
+                                            );
+                                        }
+                                    );
+                                    });
+                                </script>
+                                </div>
+                            </div>
+                            <script type="text/javascript">
+                                js_hook_8f332b50_80db_42ca_a4cb_e33faf2ab4a3_Import_Cert.ready_total++;
+                                require(["widget-form", "domReady"], function (form) {
+                                var widget = $.parseJSON(
+                                    window.atob(
+                                    "eyJuYW1lIjogInVzaW5nIiwgImlkIjogIjB4NGYiLCAicmVxdWlyZWQiOiBmYWxzZSwgImxhYmVsIjogIlVzaW5nIiwgImhlbHBfdGV4dCI6ICIiLCAiX2lkIjogNzksICJmaWVsZF9saXN0IjogWyI8LmxvY2FsOiBHcm91cEZpZWxkPiIsICI8Lm9ubGluZTogR3JvdXBGaWVsZD4iLCAiPC5tYW51YWxfaW5wdXQ6IEdyb3VwRmllbGQ+Il19"
+                                    )
+                                );
+                                var hook =
+                                    js_hook_8f332b50_80db_42ca_a4cb_e33faf2ab4a3_Import_Cert;
+                                $(".select-tab-group")
+                                    .find("label:first-child")
+                                    .addClass("active");
+                                $(".nested-radio").click(function () {
+                                    $(this).addClass("active");
+                                    $(this).nextAll().removeClass("active");
+                                    $(this).prevAll().removeClass("active");
+                                });
+                                form.on_ready(
+                                    inner_hook_e05277ce_9d29_4ff0_994e_2e363b8816fd,
+                                    function () {
+                                        var widget_view = new form.FormUnion(
+                                            widget,
+                                            hook,
+                                            inner_hook_e05277ce_9d29_4ff0_994e_2e363b8816fd
+                                        );
+                                    }
+                                );
+                                });
+                            </script>
+                        </fieldset>
+                    </div>
+                </div>
+                <!-- row-fluid -->
+                </form>
+            </div>
+            <!-- box-content -->
+        </div>
+    </div>
+</div>
+<style type="text/css">
+    #frame_model_main {
+        position: relative;
+    }
+    .add-btn-style {
+        text-align: right;
+    }
+    .add-btn-style .add-btn {
+        background-color: transparent;
+        border: 0;
+    }
+    .modal-fields {
+        padding-top: 20px;
+    }
+    .form-actions {
+        padding-bottom: 20px;
+    }
+    #app {
+        display: flex;
+        flex-direction: row;
+        flex-wrap: wrap;
+    }
+    #app .block {
+        min-width: 200px;
+        box-sizing: border-box;
+        margin-right: 20px;
+    }
+    #app .box.modal-content {
+        border-radius: 6px;
+    }
+    #app .block .modal-dialog {
+        width: 100%;
+        margin: 0;
+    }
+    #app .box-header {
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        padding-right: 10px;
+        padding-left: 10px;
+    }
+    #app .box-header button.close:active {
+        opacity: 0.2;
+    }
+    #app .box-body ul {
+        padding: 0;
+        list-style: none;
+    }
+    #app .box-body ul li {
+        padding: 5px;
+        text-align: left;
+    }
+    .btn-static {
+        display: none;
+    }
+    .controled {
+        display: none;
+    }
+    .controled.active {
+        display: block;
+    }
+    .action-btn {
+        margin-top: 8px;
+    }
+    input[name="port_number"], input[name="ttl"] {
+        width: 150px;
+    }
+</style>
+<style type="text/css">
+    .custom-lightbox {
+        display: none;
+        position: fixed;
+        z-index: 9999;
+        left: 0;
+        top: 0;
+        width: 100%;
+        height: 100%;
+        background-color: rgba(0,0,0,0.5);
+    }
+    .lightbox-content {
+        width: 800px;
+        margin: 80px auto 0;
+    }
+    .close-lightbox {
+        font-size: 40px;
+        padding: 5px;
+        cursor: pointer;
+        color: #fff;
+        background-color: rgba(255, 255, 255, 0.5);
+        width: fit-content;
+        position: absolute;
+        right: 0;
+        top: 0;
+    }
+    .file-text {
+        width: 100%;
+        height: 100px;
+    }
+    .file-upload {
+        display: flex;
+        flex-direction: column;
+        gap: 8px;
+    }
+    #prometheus_token_wrapper.dataTables_wrapper .dataTables_filter {
+        right: 20px;
+    }
+    .table-btn-group {
+        position: relative;
+    }
+    .table-btn-group select {
+        background: #8b939c;
+        position: absolute;
+        right: 215px;
+        cursor: pointer;
+    }
+</style>
+<script type="text/javascript">
+require(['list-list'],function(){
+    $(document).ready(function() {
+        var formState = {
+            enable: false,
+            enable_https: false,
+            metrics: '',
+            port: 9100,
+            ttl: 5
+        };
+
+        var isInitializing = true;
+        var selectedTokens = [];
+        var tokenLength = 10;
+
+        function toggleControl() {
+            if (formState.enable) {
+                $('.controled').removeClass('active');
+            } else {
+                $('.controled').addClass('active');
+            }
+        }
+
+        var enableSwitch = $("input[name='switch_btn']").bootstrapSwitch();
+        var enableHttpsSwitch = $("input[name='switch_https_btn']").bootstrapSwitch();
+
+        enableSwitch.on('switch-change', async function(e, data) {
+            formState.enable = data.value;
+            toggleControl();
+            await updateEnableSetting();
+        });
+        enableHttpsSwitch.on('switch-change', function(e, data) {
+            if (isInitializing) return;
+            $('#frame_model_main .btn-static').fadeIn("slow");
+            if ($(".btn-static").is(":visible")) {
+                var buttonH = $(".btn-static").offset().top;
+                $(function(){
+                    $(window).scroll(function(){
+                        var scrollH = $(this).scrollTop();
+                        if (scrollH >= buttonH) {
+                            $(".btn-switch").addClass("btn-fixed");
+                        }else{
+                            $(".btn-switch").removeClass("btn-fixed");
+                        }
+                    });
+                });
+            }
+            formState.enable_https = data.value;
+        });
+
+        $("input[name='port_number']").on('input', function() {
+            $('#frame_model_main .btn-static').fadeIn("slow");
+            if ($(".btn-static").is(":visible")) {
+                var buttonH = $(".btn-static").offset().top;
+                $(function(){
+                    $(window).scroll(function(){
+                        var scrollH = $(this).scrollTop();
+                        if (scrollH >= buttonH) {
+                            $(".btn-switch").addClass("btn-fixed");
+                        }else{
+                            $(".btn-switch").removeClass("btn-fixed");
+                        }
+                    });
+                });
+            }
+            formState.port = $(this).val();
+        });
+
+        $("input[name='ttl']").on('input', function() {
+            $('#frame_model_main .btn-static').fadeIn("slow");
+            if ($(".btn-static").is(":visible")) {
+                var buttonH = $(".btn-static").offset().top;
+                $(function(){
+                    $(window).scroll(function(){
+                        var scrollH = $(this).scrollTop();
+                        if (scrollH >= buttonH) {
+                            $(".btn-switch").addClass("btn-fixed");
+                        }else{
+                            $(".btn-switch").removeClass("btn-fixed");
+                        }
+                    });
+                });
+            }
+            formState.ttl = $(this).val();
+        });
+
+        $('.btn-cancel-action').click(function() {
+            $('#frame_model_main .btn-static').fadeOut("slow");
+        });
+
+        $('.select-level').selectpicker();
+
+        function getBasicSetting() {
+            return $.ajax({
+                url: '/api/apv/prometheus/BasicSetting/_field_group?name=get',
+                type: 'GET',
+                cache: false,
+                dataType: 'json'
+            }).then(function(data){
+                formState.enable = data.enable;
+                formState.enable_https = data.enable_https;
+                formState.metrics = data.metrics;
+                formState.port = parseInt(data.port, 10);
+                formState.ttl = parseInt(data.ttl, 10);
+            }).then(function(){
+                enableSwitch.bootstrapSwitch('setState', formState.enable);
+                enableHttpsSwitch.bootstrapSwitch('setState', formState.enable_https);
+                $("input[name='port_number']").val(formState.port);
+                $("input[name='ttl']").val(formState.ttl);
+            }).then(function(){
+                toggleControl();
+                isInitializing = false;
+            });
+        }
+
+        async function updateEnableSetting() {
+            try {
+                const data = {
+                    post_data: JSON.stringify({
+                        'enable': formState.enable,
+                    })
+                };
+                const response = await $.ajax({
+                    url: '/api/apv/prometheus/BasicSetting/_update',
+                    type: 'POST',
+                    data: $.param(data),
+                    contentType: 'application/x-www-form-urlencoded',
+                    dataType: 'json'
+                });
+                console.log('Upload successful:', response);
+            } catch (error) {
+                console.error('API call failed:', error);
+            }
+        }
+
+        async function updateBasicSetting() {
+            try {
+                const data = {
+                    post_data: JSON.stringify({
+                        'port': parseInt(formState.port),
+                        'enable_https': formState.enable_https,
+                        'ttl': parseInt(formState.ttl)
+                    })
+                };
+                const response = await $.ajax({
+                    url: '/api/apv/prometheus/BasicSetting/_update',
+                    type: 'POST',
+                    data: $.param(data),
+                    contentType: 'application/x-www-form-urlencoded',
+                    dataType: 'json'
+                });
+                console.log('Upload successful:', response);
+            } catch (error) {
+                console.error('API call failed:', error);
+            }
+        }
+        function getPrometheusTokenLength(status) {
+            const data = {
+                draw: 1,
+                columns: [
+                    { data: 'id', name: 'id', searchable: true, orderable: false, search: { value: '', regex: false } },
+                    { data: 'username', name: 'username', searchable: true, orderable: true, search: { value: '', regex: false } },
+                    { data: 'token', name: 'token', searchable: true, orderable: true, search: { value: '', regex: false } },
+                    { data: 'created', name: 'created', searchable: true, orderable: true, search: { value: '', regex: false } },
+                    { data: 'expired', name: 'expired', searchable: true, orderable: true, search: { value: '', regex: false } },
+                    { data: 'last_used', name: 'last_used', searchable: true, orderable: true, search: { value: '', regex: false } },
+                    { data: 'is_expired', name: 'is_expired', searchable: true, orderable: true, search: { value: '', regex: false } }
+                ],
+                start: 0,
+                length: 10,
+                search: { value: '', regex: false }
+            };
+            const url = status && status != '' ? `/api/apv/prometheus/Token/_config_table?initial_filter=${encodeURIComponent(`{"is_expired":${status}}`)}` : '/api/apv/prometheus/Token/_config_table';
+            return $.ajax({
+                url: url,
+                type: 'POST',
+                data: $.param(data),
+                contentType: 'application/x-www-form-urlencoded',
+                dataType: 'json'
+            });
+        }
+        function getPrometheusToken(status, length) {
+            const data = {
+                draw: 1,
+                columns: [
+                    { data: 'id', name: 'id', searchable: true, orderable: false, search: { value: '', regex: false } },
+                    { data: 'username', name: 'username', searchable: true, orderable: true, search: { value: '', regex: false } },
+                    { data: 'token', name: 'token', searchable: true, orderable: true, search: { value: '', regex: false } },
+                    { data: 'created', name: 'created', searchable: true, orderable: true, search: { value: '', regex: false } },
+                    { data: 'expired', name: 'expired', searchable: true, orderable: true, search: { value: '', regex: false } },
+                    { data: 'last_used', name: 'last_used', searchable: true, orderable: true, search: { value: '', regex: false } },
+                    { data: 'is_expired', name: 'is_expired', searchable: true, orderable: true, search: { value: '', regex: false } }
+                ],
+                start: 0,
+                length: length,
+                search: { value: '', regex: false }
+            };
+            const url = status && status != '' ? `/api/apv/prometheus/Token/_config_table?initial_filter=${encodeURIComponent(`{"is_expired":${status}}`)}` : '/api/apv/prometheus/Token/_config_table';
+            return $.ajax({
+                url: url,
+                type: 'POST',
+                data: $.param(data),
+                contentType: 'application/x-www-form-urlencoded',
+                dataType: 'json'
+            });
+        }
+
+        $('.expired-filter').change(async function() {
+            var expire_status = $(this).val();
+            var status;
+            if(expire_status == 'all') {
+                status = '';
+            } else if(expire_status == 'expired') {
+                status = 'true';
+            } else if(expire_status == 'not_expired') {
+                status = 'false';
+            }
+            try {
+                var tokenLength = await getPrometheusTokenLength(status);
+                var tokenData = await getPrometheusToken(status, tokenLength.recordsTotal);
+                console.log('Token Data:', tokenData);
+                await $('#prometheus_token').DataTable().destroy();
+                await populateDataTable(tokenData.data);
+            } catch (error) {
+                console.error('Error fetching Prometheus tokens:', error);
+            }
+        });
+
+        async function addPrometheusToken() {
+            try {
+                const data = {
+                    action: 'Create',
+                    options: '{}'
+                };
+                const response = await $.ajax({
+                    url: '/api/apv/prometheus/Token/_perform',
+                    type: 'POST',
+                    data: $.param(data),
+                    contentType: 'application/x-www-form-urlencoded',
+                    dataType: 'json'
+                });
+                console.log('Upload successful:', response);
+            } catch (error) {
+                console.error('API call failed:', error);
+            }
+        }
+
+        async function deletePrometheusToken(pk_id) {
+            try {
+                const data = {
+                    pk: pk_id,
+                };
+                const response = await $.ajax({
+                    url: '/api/apv/prometheus/Token/_delete',
+                    type: 'POST',
+                    data: $.param(data),
+                    contentType: 'application/x-www-form-urlencoded',
+                    dataType: 'json'
+                });
+                console.log('Upload successful:', response);
+            } catch (error) {
+                console.error('API call failed:', error);
+            }
+
+        }
+
+        function populateDataTable(data) {
+            $('#prometheus_token').DataTable({
+                data: data,
+                columns: [
+                    {
+                        title: "<input type='checkbox' id='select-all' />",
+                        data: null,
+                        render: function(data, type, row) {
+                            return `<input type='checkbox' class='select-checkbox' value='${row.token}' />`;
+                        },
+                        orderable: false
+                    },
+                    { title: "ID", data: "id" },
+                    { title: "User Name", data: "username" },
+                    { title: "Token", data: "token" },
+                    { title: "Created Date", data: "created" },
+                    { title: "Expired Date", data: "expired" },
+                    { title: "Last Used Date", data: "last_used" },
+                    { title: "Is Expired", data: "is_expired" }
+                ]
+            });
+            // select all toggle
+            $('#select-all').on('click', function() {
+                var rows = $('#prometheus_token').DataTable().rows({ 'search': 'applied' }).nodes();
+                $('input[type="checkbox"]', rows).prop('checked', this.checked);
+                updateSelectedTokens();
+            });
+
+            // select simple
+            $('#prometheus_token tbody').on('change', 'input[type="checkbox"]', function() {
+                if (!this.checked) {
+                    var el = $('#select-all').get(0);
+                    if (el && el.checked && ('indeterminate' in el)) {
+                        el.indeterminate = true;
+                    }
+                }
+                updateSelectedTokens();
+            });
+        }
+
+        function updateSelectedTokens() {
+            selectedTokens = [];
+            $('#prometheus_token tbody input[type="checkbox"]:checked').each(function() {
+                selectedTokens.push($(this).val());
+            });
+            console.log('Selected Tokens:', selectedTokens);
+
+            if (selectedTokens.length > 0) {
+                $('.delete-btn').removeClass('disabled');
+            } else {
+                $('.delete-btn').addClass('disabled');
+            }
+        }
+
+        $('.delete-btn').click(async function() {
+            if (selectedTokens.length > 0) {
+                const pk = selectedTokens.map(token => `{"token": "${token}"}`).join('ÿÿÿÿÿ');
+                await deletePrometheusToken(pk);
+                refreshPage();
+            }
+        });
+
+        $('.add-btn').click(async function() {
+            await addPrometheusToken();
+            refreshPage();
+        });
+
+        async function initialize() {
+            await getBasicSetting();
+            tokenLength = await getPrometheusTokenLength();
+            const tokenData = await getPrometheusToken('', tokenLength.recordsTotal);
+            console.log('Token Data:', tokenData);
+            populateDataTable(tokenData.data);
+        }
+
+        $('.btn-submit').click(async function() {
+            await updateBasicSetting();
+            refreshPage();
+        });
+
+        function getNameMapping() {
+            var mapping = {};
+            for (var ind = 0; ind < modal_fields.length; ++ind) {
+                mapping[modal_fields[ind].id] = modal_fields[ind].field;
+            }
+            return mapping;
+        }
+
+        function refreshPage() {
+            $('.config-nav li.active a').trigger('click');
+        }
+
+        initialize();
+
+        $(document).ready(function() {
+            getBasicSetting();
+        });
+
+        function toggleLightbox() {
+            $('.custom-lightbox').fadeToggle();
+        }
+        $('.lightbox-toggle').click(function(){
+            toggleLightbox();
+        });
+        $('.custom-lightbox').click(function(e){
+            if (e.target === this) {
+                toggleLightbox();
+            }
+        });
+
+        $('#upload-private-button').click(async function() {
+            var privateKeyFile = $('#private-key')[0].files[0];
+            if (privateKeyFile) {
+                await uploadFile(privateKeyFile, '#private-key-textarea');
+            }
+        });
+        $('#upload-certificate-button').click(function() {
+            var certificateFile = $('#certificate')[0].files[0];
+            if (certificateFile) {
+                uploadFile(certificateFile, '#certificate-textarea');
+            }
+        });
+
+        async function uploadFile(file, textareaSelector) {
+            try {
+                const content = await readFileAsync(file);
+                $(textareaSelector).val(content);
+            } catch (error) {
+                console.error('Error reading file:', error);
+            }
+        }
+
+        function readFileAsync(file) {
+            return new Promise((resolve, reject) => {
+                const reader = new FileReader();
+                reader.onload = () => resolve(reader.result);
+                reader.onerror = reject;
+                reader.readAsText(file);
+            });
+        }
+
+        $('#upload-cert-button-file').click(async function() {
+            var privateKey = $('#private-key-textarea').val();
+            var certificate = $('#certificate-textarea').val();
+
+            if (privateKey && certificate) {
+                await uploadCertFile(privateKey, certificate);
+            } else {
+                alert('Please select both private key and certificate files.');
+            }
+        });
+
+        async function uploadCertFile(privateKeyContent, certificateContent) {
+            try {
+                const data = {
+                    action: 'Import_Cert',
+                    options: JSON.stringify({
+                        '__pk_list': [
+                            ""
+                        ],
+                        'using': {
+                            'manual_input': {
+                                'key_content': privateKeyContent,
+                                'crt_content': certificateContent
+                            }
+                        }
+                    })
+                };
+                const response = await $.ajax({
+                    url: '/api/apv/prometheus/BasicSetting/_perform',
+                    type: 'POST',
+                    data: $.param(data),
+                    contentType: 'application/x-www-form-urlencoded',
+                    dataType: 'json'
+                });
+                console.log('Upload successful:', response);
+                toggleLightbox();
+            } catch (error) {
+                console.error('API call failed:', error);
+            }
+        }
+
+        $('#upload-cert-button-manual').click(async function() {
+            var privateKey = $('#private-key-textarea-manual').val();
+            var certificate = $('#certificate-textarea-manual').val();
+
+            if (privateKey && certificate) {
+                await uploadCertManual(privateKey, certificate);
+            } else {
+                alert('Please select both private key and certificate files.');
+            }
+        });
+
+        async function uploadCertManual(privateKeyContent, certificateContent) {
+            try {
+
+                const data = {
+                    action: 'Import_Cert',
+                    options: JSON.stringify({
+                        '__pk_list': [
+                            ""
+                        ],
+                        'using': {
+                            'manual_input': {
+                                'key_content': privateKeyContent,
+                                'crt_content': certificateContent
+                            }
+                        }
+                    })
+                };
+                const response = await $.ajax({
+                    url: '/api/apv/prometheus/BasicSetting/_perform',
+                    type: 'POST',
+                    data: $.param(data),
+                    contentType: 'application/x-www-form-urlencoded',
+                    dataType: 'json'
+                });
+                console.log('Upload successful:', response);
+                toggleLightbox();
+            } catch (error) {
+                console.error('API call failed:', error);
+            }
+        }
+
+        $('#upload-cert-button-url').click(async function() {
+            var privateKey = $('#private-key-url').val();
+            var certificate = $('#certificate-url').val();
+
+            if (privateKey && certificate) {
+                await uploadCertUrl(privateKey, certificate);
+            } else {
+                alert('Please select both private key and certificate files.');
+            }
+        });
+
+        async function uploadCertUrl(privateKeyContent, certificateContent) {
+            try {
+
+                const data = {
+                    action: 'Import_Cert',
+                    options: JSON.stringify({
+                        '__pk_list': [
+                            ""
+                        ],
+                        'using': {
+                            'online': {
+                                'key_url': privateKeyContent,
+                                'crt_url': certificateContent
+                            }
+                        }
+                    })
+                };
+                const response = await $.ajax({
+                    url: '/api/apv/prometheus/BasicSetting/_perform',
+                    type: 'POST',
+                    data: $.param(data),
+                    contentType: 'application/x-www-form-urlencoded',
+                    dataType: 'json'
+                });
+                console.log('Upload successful:', response);
+                toggleLightbox();
+            } catch (error) {
+                console.error('API call failed:', error);
+            }
+        }
+
+        $('.remove-data').click(async function() {
+            try {
+                const data = {
+                    action: 'Clear_Cert',
+                    options: JSON.stringify({
+                        '__pk_list': [
+                            ""
+                        ]
+                    })
+                };
+                const response = await $.ajax({
+                    url: '/api/apv/prometheus/BasicSetting/_perform',
+                    type: 'POST',
+                    data: $.param(data),
+                    contentType: 'application/x-www-form-urlencoded',
+                    dataType: 'json'
+                });
+                console.log('Remove successful:', response);
+            } catch (error) {
+                console.error('API call failed:', error);
+            }
+        });
+
+    });
+})
+</script>
\ No newline at end of file
Index: /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/templates/monitoring/prometheus/index/import_certificate.html
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/templates/monitoring/prometheus/index/import_certificate.html	(revision 0)
+++ /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/templates/monitoring/prometheus/index/import_certificate.html	(working copy)
@@ -0,0 +1,232 @@
+{% block box_content %}
+<div class="box-header my-header">
+    <div class="box-icon-title">
+        <i class="fa fa-wrench"></i>
+    </div>
+    <h2>
+        Import Certificate
+    </h2>
+</div>
+<div class="box-content">
+    <form class="form-horizontal main-form">
+        <div class="row-fluid">
+            <div class="span12 with-min-width field-group-box">
+                <legend>{% trans %}Request{% endtrans %}</legend>
+                <div class="row">
+                    <div class="col-md-3">
+                        <select class="form-control" id="method">
+                            <option>--Please Select--</option>
+                            <option>GET</option>
+                            <option>POST</option>
+                            <option>PUT</option>
+                            <option>DELETE</option>
+                        </select>
+                    </div>
+                    <div class="col-md-7">
+                        <input type="text" id="url" class="form-control" aria-label="URL" placeholder="URL" style="width: 100%;">
+                        <span class="field-icon-set"><i class="error-sign fa fa-times-circle"></i></span>
+                        <span class="error-info"></span>
+                    </div>
+                    <div class="col-md-2">
+                        <button type="button" id="send" class="btn btn-primary btn-xs">Send</button>
+                    </div>
+                </div>
+                <legend>Header</legend>
+                <button type="button" class="btn btn-xs btn-primary btn-add-header">Add Header</button>
+                <div class="row header-add-div">
+                    <form class="form-horizontal main-form">
+                        <div class="row-fluid">
+                            <div class="span12 with-min-width field-group-box">
+                                    <div class="form-group textinput textinput_port" id="0x19">
+                                        <label class="col-md-3 control-label">Key</label>
+                                        <div class="col-md-9">
+                                            <input type="text" id="header_key" placeholder="">
+                                        </div>
+                                    </div>
+                                    <div class="form-group textinput textinput_options" id="0x18">
+                                        <label class="col-md-3 control-label">Value</label>
+                                        <div class="col-md-9">
+                                            <input type="text" id="header_value" placeholder="">
+                                        </div>
+                                    </div>
+                                    <div class="form-group action-actions">
+                                        <label class="col-md-3"></label>
+                                        <div class="col-md-9">
+                                            <button type="button" class="btn btn-xs btn-primary action-add-btn-header">Add</button>
+                                            <button type="button" class="btn btn-xs btn-primary action-cancle-btn-header">Cancel</button>
+                                        </div>
+                                    </div>
+                                </fieldset>
+                            </div>
+                        </div><!-- row-fluid -->
+                    </form>
+                </div>
+                <div class="row header-display-div">
+                </div>
+                <legend>Request Body</legend>
+                <div class="row">
+                    <div class="col-md-12">
+                        <textarea id="body" class="form-control" rows="5"></textarea>
+                    </div>
+                </div>
+                <br/>
+                <legend class="response-elm">Response</legend>
+                <div class="row response-elm">
+                    <ul class="nav nav-tabs" role="tablist">
+                        <li role="presentation" class="active"><a href="#header" aria-controls="header" role="tab" data-toggle="tab">Header</a></li>
+                        <li role="presentation"><a href="#content" aria-controls="content" role="tab" data-toggle="tab">Content</a></li>
+                    </ul>
+                        <div class="tab-content">
+                        <div role="tabpanel" class="tab-pane active" id="header">
+                            <pre></pre>
+                        </div>
+                        <div role="tabpanel" class="tab-pane" id="content">
+                            <pre></pre>
+                        </div>
+                        </div>
+                    <pre></pre>
+                    <pre></pre>
+                </div>
+            </div>
+        </div><!-- row-fluid -->
+    </form>
+</div><!-- box-content -->
+<div class="modal fade" tabindex="-1" role="dialog" id="header-add-dlg">
+    <div class="modal-dialog" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
+                <h4 class="modal-title">Header</h4>
+            </div>
+            <div class="modal-body">
+                <form class="form-horizontal main-form">
+                    <div class="row-fluid">
+                        <div class="span12 with-min-width field-group-box">
+                            <legend>{{ action.verbose_name }}</legend>
+                            <fieldset>
+                                <div class="form-group textinput textinput_ip_hostname" id="0x18">
+                                    <label class="col-md-3 control-label">{{ action.option_fields[0].verbose_name }}&nbsp;*</label>
+                                    <div class="col-md-9">
+                                        <input type="text" id="textinput_ip_hostname" placeholder="">
+                                        <span class="field-icon-set"><i class="error-sign fa fa-times-circle"></i></span>
+                                        <span class="error-info"></span>
+                                        <div class="big_help_text"></div>
+                                        <div class="link_help_text"></div>
+                                    </div>
+                                </div>
+                                <div class="form-group textinput textinput_port" id="0x19">
+                                    <label class="col-md-3 control-label">{{ action.option_fields[1].verbose_name }}</label>
+                                    <div class="col-md-9">
+                                        <input type="text" id="textinput_port" placeholder="">
+                                    </div>
+                                </div>
+                                <div class="form-group textinput textinput_options" id="0x18">
+                                    <label class="col-md-3 control-label">{{ action.option_fields[2].verbose_name }}</label>
+                                    <div class="col-md-9">
+                                        <input type="text" id="textinput_options" placeholder="">
+                                    </div>
+                                </div>
+                                <div class="form-group action-actions">
+                                    <label class="col-md-3"></label>
+                                    <div class="col-md-9">
+                                    <button type="button" class="btn action-btn action-btn-{{ action.name }} {{ action.btn_class }}">{{ action.action_name }}</button>
+                                    </div>
+                                </div>
+                            </fieldset>
+                        </div>
+                    </div><!-- row-fluid -->
+                </form>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-default telnet_console_close">Close</button>
+            </div>
+        </div><!-- /.modal-content -->
+    </div><!-- /.modal-dialog -->
+</div>
+<script type="text/javascript">
+    $(".error-sign").hide();
+    $(".header-add-div").hide();
+    $(".response-elm").hide();
+    var header_list = [];
+    function delete_header_str(idx) {
+        header_list.splice(idx, 1);
+        display_header_list();
+        return;
+    }
+    function display_header_list() {
+        $(".header-display-div").html("");
+        for( var i = 0; i < header_list.length; i++) {
+            var close_btn = '<button type="button btn-xs" class="close" aria-label="Close" onclick="delete_header_str(' + i + ')" style="float:none; opacity:1"><span class="label label-danger" aria-hidden="true">&times;</span></button>';
+            var html_str = '<div class="col-md-12"><span class="label label-info">'+ header_list[i] +'</span>' + close_btn +' </div>';
+            $(".header-display-div").append(html_str);
+        }
+    }
+    $(".btn-add-header").click(function(){
+        $("#header_key").val("");
+        $("#header_value").val("");
+        $(".header-add-div").show();
+    });
+    $(".action-add-btn-header").click(function(){
+        var key = $("#header_key").val();
+        var val = $("#header_value").val();
+        var header_str = key +': ' + val;
+        header_list.push(header_str);
+        display_header_list();
+        $(".header-add-div").hide();
+    });
+    $(".action-cancle-btn-header").click(function(){
+        $("#header_key").val("");
+        $("#header_value").val("");
+        $(".header-add-div").hide();
+    });
+    $("#send").click(function(){
+        var method = $("#method").val();
+        var url =  $("#url").val();
+        var body =  $("#body").val();
+        if (!url) {
+            var msg = gettext("Required field")
+            $(".error-sign").show();
+            $(".error-info").html(msg);
+            var err_msg = '<b>URL</b> -- ' + gettext("The required field must not be empty.") + '<br />';
+            $HIVE.alert('warning',gettext('Please correct these errors'),err_msg,false);
+            return false;
+        } else {
+            $(".error-sign").hide();
+            $(".error-info").html("");
+        }
+        var dlg = new $HIVE.ProgressDlg({"title":'Telnet', "full_progress":true, "total_time":0, "type":'info', "msg":''})
+        dlg.show();
+        $.post(
+            '/api/apv/admintools/troubleshooting/Tools/_perform?action=URL',
+            {'action':'URL', 'options':JSON.stringify({'method':method,'url':url,'header':header_list,'request_body':body}),'csrfmiddlewaretoken':'{{ csrf_token }}'},
+            function(data) {
+                dlg.hide();
+                if (data[0]) {
+                    var cmd = data[1]['cmd'];
+                    var resp = data[1]['response'];
+                    var resp_hd = "";
+                    var resp_cnt = "";
+                    var idx = resp.indexOf('\r\n\r\n');
+                    if (idx != -1) {
+                        resp_hd = resp.slice(0, idx);
+                        resp_cnt = resp.slice(idx+4);
+                    } else {
+                        resp_cnt = resp
+                    }
+                    $(".response-elm").show();
+                    $("#header pre").html(resp_hd);
+                    $("#content pre").html(resp_cnt);
+                } else {
+                    $HIVE.alert('error','URL' + ' ' +gettext('Error'), data[1]);
+                    return false
+                }
+                console.log(data);
+            },
+            'json'
+        );
+    });
+</script>
+{% endblock box_content %}
+
+{% block box_script %}
+{% endblock %}
\ No newline at end of file
Index: /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/templates/monitoring/prometheus/index/index.html
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/templates/monitoring/prometheus/index/index.html	(revision 0)
+++ /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/templates/monitoring/prometheus/index/index.html	(working copy)
@@ -0,0 +1,134 @@
+{% extends "base.html" %}
+
+{% block content %}
+
+{% block horizontal_nav %}
+<div class="horizontal-nav">
+    <div class="crumbs">
+        <a href="/apv/monitoring/prometheus/index/_index"><i class="fa fa-home"></i></a>
+    </div>
+    <ul class="nav nav-tabs">
+        <li class="active">
+            <a href="/apv/monitoring/prometheus/index/_index">{% trans %}Matrix{% endtrans %}</a>
+        </li>
+    </ul>
+</div>
+<div></div>
+{% endblock horizontal_nav %}
+
+<div class="head-nav-box clearfix-before">
+{% block model_nav %}
+<nav class="head-nav" role="navigation">
+    <a class="model-name" href="#" style="width:90%;"><i class="fa fa-folder-open"></i>&nbsp;{% trans %}Matrix{% endtrans %}</a>
+    <div class="model-intro">
+        <pre></pre>
+    </div>
+</nav>
+{% endblock model_nav %}
+</div>
+
+{% block sub_nav %}
+<ul class="config-nav nav nav-pills" style="display:none;">
+    <li class="active">
+        <a class="config-nav-a" val="/apv/get_prometheus_page?type=matrix&page=basic" href="javascript:;">{% trans %}Basic Settings{% endtrans %} <i class="fa fa-wrench"></i></a>
+        <ul class="sub-config-nav group-index">
+            <li><a val="/apv/get_prometheus_page?type=matrix&page=basic" href="javascript:;">General</a></li>
+        </ul>
+    </li>
+    <li class="active">
+        <a class="config-nav-a" val="/apv/get_prometheus_page?type=matrix&page=log" href="javascript:;">{% trans %}Log{% endtrans %} <i class="fa fa-wrench"></i></a>
+        <ul class="sub-config-nav group-index">
+            <li><a val="/apv/get_prometheus_page?type=matrix&page=log" href="javascript:;">General</a></li>
+        </ul>
+    </li>
+</ul>
+<ul class="sub-config-nav-real"></ul>
+<script type="text/javascript">
+require(['jquery'], function(){
+    if ($('.config-nav li').length > 1) {
+        $('.config-nav').show();
+    }
+});
+</script>
+{% endblock %}
+
+<div id="frame_model_main" class="frame" style="display: block;">
+</div>
+
+{% endblock %}
+
+{% block page_javascript %}
+<script type="text/javascript">
+require(['jquery'], function(){
+    $(".config-nav-a").on("click", function(e) {
+        e.preventDefault();
+    });
+    function getBasicSetting() {
+        return $.ajax({
+            url: '/api/apv/prometheus/BasicSetting/_field_group?name=get',
+            type: 'GET',
+            cache: false,
+            dataType: 'json'
+        }).then(function(data){
+            $('.model-intro pre').html(data.metrics);
+        })
+    }
+    getBasicSetting();
+});
+require(['hive', 'widget-form'], function(){
+    var initiator = new Object();
+    $HIVE.enable_event(initiator);
+    $(".config-nav a.config-nav-a").click(function(){
+        $(".config-nav li").removeClass("active");
+        $(this).parents("li").addClass("active");
+        var sub_nav = $($(this).parents('li').find('ul')[0])
+        if (sub_nav && sub_nav.children().length > 1) {
+            var real_sub_nav = sub_nav.clone(true).removeClass('sub-config-nav').addClass('sub-config-nav-real');
+            $(".sub-config-nav-real").replaceWith(real_sub_nav);
+            $(".sub-config-nav-real").show();
+            $("#frame_instance_main").css("padding-top", "50px");
+            real_sub_nav.find('a').click(function(){
+                $(".sub-config-nav-real li").removeClass("active");
+                $(this).parents("li").addClass("active");
+                var url = $(this).attr('val')
+                $HIVE.ajax_load_box(url, initiator, $("#frame_model_main"));
+                return false;
+            });
+            $(".sub-config-nav-real a:first").trigger("click");
+        } else {
+            $("#frame_instance_main").css("padding-top", "0px");
+            $(".sub-config-nav-real").empty();
+            $(".sub-config-nav-real").hide();
+            var url = $(this).attr('val')
+            $HIVE.ajax_load_box(url, initiator, $("#frame_model_main"));
+        }
+        return false;
+    });
+    $(".config-nav a:first").trigger("click");
+});
+</script>
+<style type="text/css">
+.model-intro {
+    font-size: 14px;
+    margin-top: 5px;
+    padding: 15px;
+    color: #b6bfd6;
+    border-left: 5px solid #b6bfd6;
+    background-color: #03072f;
+}
+.head-nav-box, .head-nav {
+    height: auto;
+}
+.head-nav .model-name {
+    border-bottom: unset;
+}
+div pre {
+    color: unset;
+    font-size: inherit;
+    margin-bottom: 0;
+}
+</style>
+{% endblock %}
+
+{% block box_script %}
+{% endblock %}
\ No newline at end of file
Index: /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/templates/monitoring/prometheus/index/log.html
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/templates/monitoring/prometheus/index/log.html	(revision 0)
+++ /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/templates/monitoring/prometheus/index/log.html	(working copy)
@@ -0,0 +1,50 @@
+<form class="form-horizontal main-form" id="log-form">
+    <div class="row-fluid">
+        <div class="span12 with-min-width field-group-box">
+            <fieldset>
+                <ul class="nav nav-pills pull-right">
+                    <li><a href="#" class="copy-btn" title="{% trans %}Copy to clipboard{% endtrans %}" data-clipboard-action="copy" data-clipboard-target="#prometheus_log_pre" id="prometheus_log_flash_copy" ><i class="fa fa-copy"></i></a></li>
+                    <li><a href="/apv/prometheus/Log/download" target="_blank" class="download-btn" title="{% trans %}Download as .txt file{% endtrans %}"><i class="fa fa-download"></i></a></li>
+                </ul>
+                <pre id="prometheus_log_pre" >[[ prometheus_log ]]</pre>
+            </fieldset>
+        </div>
+    </div>
+</form>
+<script type="text/javascript">
+require(['clipboard', 'vue'],function(ClipboardJS, Vue){
+    var clipboard = new ClipboardJS('#prometheus_log_flash_copy');
+    clipboard.on('error', function (e) {
+        console.log(e);
+    });
+
+    var app = new Vue({
+        el: '#log-form',
+        delimiters: ['[[', ']]'], // Because we still under python, so need delimiters
+        data: {
+            prometheus_log: ''
+        },
+        methods: {
+            getPrometheusLog: function() {
+                var self = this;
+                $.ajax({
+                    url: '/api/apv/prometheus/Log/_field_group?name=get',
+                    type: 'GET',
+                    cache: false,
+                    dataType: 'json'
+                }).then(function(data){
+                    self.prometheus_log = data.content;
+                });
+            }
+        },
+        mounted: function() {
+            this.getPrometheusLog();
+        }
+    });
+});
+</script>
+<style type="text/css">
+    #frame_model_main {
+        position: relative;
+    }
+</style>
\ No newline at end of file
Index: /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/templates/network/cloud/aws/basic.html
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/templates/network/cloud/aws/basic.html	(revision 0)
+++ /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/templates/network/cloud/aws/basic.html	(working copy)
@@ -0,0 +1,196 @@
+<form class="form-horizontal main-form">
+<div class="row-fluid">
+    <div class="span12 with-min-width field-group-box">
+
+        <fieldset class="log_out_component">
+            <div class="form-group">
+                <label class="col-md-3 control-label">{% trans %}access key{% endtrans %}:</label>
+                <div class="col-md-9 aws_access_key_field">
+                    <div class="align_center_for_info" target="_blank">...</div>
+                </div>
+            </div>
+            <div class="form-group">
+                <label class="col-md-3 control-label">{% trans %}secret access key{% endtrans %}:</label>
+                <div class="col-md-9 aws_secret_access_key_field">
+                    <div class="align_center_for_info" target="_blank">...</div>
+                </div>
+            </div>
+            <div class="form-group">
+                <label class="col-md-3 control-label">{% trans %}region{% endtrans %}:</label>
+                <div class="col-md-9 region_field">
+                    <div class="align_center_for_info" target="_blank">...</div>
+                </div>
+            </div>
+            <div class="form-group">
+                <label class="col-md-3 control-label"></label>
+                <div class="col-md-9">
+                    <button type="button" class="btn btn-primary btn-log-out">{% trans %}Log Out{% endtrans %}</button>
+                </div>
+            </div>
+        </fieldset>
+        <fieldset class='log_in_component'>
+                <fieldset>
+                    <div class="group_actions">
+                        <div class="form-group">
+                            <label class="col-md-3 control-label">{% trans %}access key{% endtrans %}:</label>
+                            <div class="col-md-9">
+                                <input type="text" class="field" data-id="aws_access_key_id" value=""/>
+                                <span class="field-icon-set"><i class="fa fa-question-circle"></i></span>
+                            </div>
+                        </div>
+                        <div class="form-group">
+                            <label class="col-md-3 control-label">{% trans %}secret access key{% endtrans %}:</label>
+                            <div class="col-md-9">
+                                <input type="text" class="field" data-id="aws_secret_access_key" value=""/>
+                                <span class="field-icon-set"><i class="fa fa-question-circle"></i></span>
+                            </div>
+                        </div>
+                        <div class="form-group">
+                            <label class="col-md-3 control-label">{% trans %}region{% endtrans %}:</label>
+                            <div class="col-md-9">
+                                <input type="text" class="field" data-id="region" value=""/>
+                                <span class="field-icon-set"><i class="fa fa-question-circle"></i></span>
+                            </div>
+                        </div>
+                        <div class="form-group">
+                            <label class="col-md-3 control-label"></label>
+                            <div class="col-md-9">
+                                <button type="button" class="btn btn-primary btn-log-in">{% trans %}Log In{% endtrans %}</button>
+                            </div>
+                        </div>
+                </fieldset>
+
+            </div>
+        </fieldset>
+        <fieldset class="error_field">
+            <div class="form-group">
+                <div class="col-md-3"></div>
+                <div class="error-info">{% trans %}Internal error, please refresh the page.{% endtrans %}</div>
+            </div>
+        </fieldset>
+
+
+    </div>
+</div>
+</form>
+<style type="text/css">
+.log_out_component{
+    display: none;
+}
+.align_center_for_info {
+    line-height: 28px;
+    display: inline-block;
+}
+
+.error_field {
+    display: none;
+}
+</style>
+
+{% block box_script %}
+
+<script type="text/javascript">
+
+$(function () {
+    getStatus();
+    function getStatus () {
+        $.ajax({
+            url: "/api/v1/cloud/aws/credential/",
+            type: 'GET',
+            dataType: 'json',
+            success: function (res) {
+                if (typeof (res["aws_access_key_id"]) === "undefined"
+                || typeof (res["aws_secret_access_key"]) === "undefined") {
+                    return
+                }
+
+                if (res["aws_access_key_id"] != ""
+                && res["aws_secret_access_key"] != "") {
+                    $('.aws_access_key_field div').html(res["aws_access_key_id"]);
+                    $('.aws_secret_access_key_field div').html(res["aws_secret_access_key"]);
+                    $('.region_field div').html(res["region"]);
+                    $('.log_in_component').css('display', 'none');
+                    $('.log_out_component').css('display', 'block');
+
+                }else{
+
+                    $('.log_out_component').css('display', 'none');
+                    $('.log_in_component').css('display', 'block');
+                    var content = [
+                    '{% trans %}Enter the access key, secret access key and region code(e.g. us-east-1) of AWS for the purpose of manipulating AWS resource.{% endtrans %}<br />',
+                        ].join("");
+                    $('.field-icon-set').popover({
+                        trigger: "hover",
+                        content: content,
+                        html: true
+                    });
+
+                }
+
+            },
+            error: function (xhr, textStatus, errorThrown) {
+                console.log(textStatus + "," + errorThrown + "," + xhr.responseText);
+            }
+        });
+    }
+    $('.btn-log-in').click(function(evt) {
+        if(evt.detail && evt.detail != 1) {
+            return;
+        }
+        var each = {};
+        $('.field').each(function() {
+            if ($(this).val() == "") {
+                return;
+            }
+
+            "data-id"
+            "data-id"
+            each[$(this).data('id')] = $(this).val();
+        });
+        if (Object.keys(each).length < 1) {
+            return;
+        }
+
+        $.ajax({
+            url: "/api/v1/cloud/aws/credential/",
+            type: 'POST',
+            dataType: 'json',
+            data: JSON.stringify({
+                aws_access_key_id: each.aws_access_key_id,
+                aws_secret_access_key: each.aws_secret_access_key,
+                region: each.region,
+            }),
+            success: function (res) {
+            getStatus();
+            },
+            error: function (xhr, textStatus, errorThrown) {
+                console.log(textStatus + "," + errorThrown + "," + xhr.responseText);
+            }
+        });
+
+    });
+    $('.btn-log-out').click(function() {
+        var that = this;
+        $(that).prop('disabled', true);
+        $.ajax({
+            url: "/api/v1/cloud/aws/credential/",
+            type: 'DELETE',
+            dataType: 'json',
+            success: function (res) {
+                $(that).prop('disabled', false);
+                getStatus();
+            },
+            error: function (xhr, textStatus, errorThrown) {
+                $(that).prop('disabled', false);
+                console.log(textStatus + "," + errorThrown + "," + xhr.responseText);
+            }
+        });
+    });
+
+
+
+});
+
+</script>
+
+{% endblock box_script %}
Index: /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/templates/network/cloud/aws/eni.html
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/templates/network/cloud/aws/eni.html	(revision 0)
+++ /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/templates/network/cloud/aws/eni.html	(working copy)
@@ -0,0 +1,464 @@
+<form class="form-horizontal main-form">
+<div class="row-fluid">
+    <div class="span12 with-min-width field-group-box">
+        <fieldset>
+            <div class="group_actions"></div>
+            <div class="form-group switch switch_enable">
+                <label class="col-md-3 control-label">{% trans %}Enable{% endtrans %}:</label>
+                <div class="col-md-3">
+                    <input class="switch-small" type="checkbox" name="switch_btn"
+                    data-on-label="{% trans %}Enable{% endtrans %}"
+                    data-off-label="{% trans %}Disabled{% endtrans %}" />
+                    <span class="field-icon-set"></span>
+                </div>
+                <label class="col-md-3 control-label">{% trans %}Manual Trigger{% endtrans %}:</label>
+                <div class="col-md-3 col-manual-trigger">
+                    <button type="button" class="btn btn-primary failover-btn">{% trans %}Failover{% endtrans %}</button>
+                    <button type="button" class="btn btn-primary recover-btn">{% trans %}Recover{% endtrans %}</button>
+                </div>
+            </div>
+        </fieldset>
+        <fieldset>
+            <div class="form-group add-btn-style">
+                <div class="col-md-3">
+                    <button type="button" class="btn btn-action add-btn"><i class="fa fa-plus-circle"></i>{% trans %}ADD{% endtrans %}</button>
+                </div>
+                <div class="col-md-9" id="app"></div>
+            </div>
+        </fieldset>
+    </div>
+</div>
+<!-- row-fluid -->
+<div class="btn-static">
+    <div class="btn-switch">
+        <button type="button" class="btn btn-action btn-submit">{% trans %}Save Changes{% endtrans %}</button>
+        <button type="button" class="btn btn-default btn-cancel-action">{% trans %}Cancel{% endtrans %}</button>
+    </div>
+</div>
+<div class="modal fade" id="addModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
+    <div class="modal-dialog">
+        <div class="box modal-content">
+            <div class="box-header">
+                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true"></span></button>
+                    <h2>{{ gettext('New %s')%"NIC" }}</h2>
+                </button>
+            </div>
+            <div class="box-body">
+                <form class="form-horizontal main-form">
+                    <div class="padded">
+                        <div class="row-fluid">
+                            <div class="span12 with-min-width field-group-box modal-fields">
+                            </div>
+                        </div>
+                    </div>
+                    <div class="form-actions col-md-offset-3">
+                        <button type="button" class="btn btn-action btn-save">{% trans %}Submit{% endtrans %}</button>
+                        <button type="button" data-dismiss="modal" class="btn btn-default btn-cancel">{% trans %}Cancel{% endtrans %}</button>
+                    </div>
+                </form>
+            </div>
+        </div>
+    </div>
+</div>
+</form>
+<style type="text/css">
+.add-btn-style {
+    text-align: right;
+}
+.add-btn-style .add-btn {
+    background-color: transparent;
+    border: 0;
+}
+.modal-fields {
+    padding-top: 20px;
+}
+.form-actions {
+    padding-bottom: 20px;
+}
+#app {
+    display: flex;
+    flex-direction: row;
+    flex-wrap: wrap;
+}
+#app .block {
+    min-width: 200px;
+    box-sizing: border-box;
+    margin-right: 20px;
+}
+#app .box.modal-content {
+    border-radius: 6px;
+}
+#app .block .modal-dialog {
+    width: 100%;
+    margin: 0;
+}
+#app .box-header {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    padding-right: 10px;
+    padding-left: 10px;
+}
+#app .box-header button.close:active {
+    opacity: 0.2;
+}
+#app .box-body ul {
+    padding: 0;
+    list-style: none;
+}
+#app .box-body ul li {
+    padding: 5px;
+    text-align: left;
+}
+.btn-static {
+    display: none;
+}
+</style>
+</div>
+
+{% block box_script %}
+
+<script type="text/javascript">
+
+$(function(){
+    var enableSwitch = $("input[name='switch_btn']").bootstrapSwitch();
+    var is_init = 0;
+    getEnableStatus();
+    function getEnableStatus() {
+        // get the current status of enable toggle
+        $.ajax({
+            url: '/api/v1/cloud/aws/ha/status/',
+            type: 'GET',
+            dataType: 'json',
+            success: function (res) {
+                if (typeof(res["status"]) == "undefined") {
+                    return;
+                }
+                enableSwitch.bootstrapSwitch('setState', res["status"]);
+                is_init++;
+            },
+            error: function (xhr, textStatus, errorThrown) {
+                console.log(textStatus + "," + errorThrown + "," + xhr.responseText);
+            }
+        });
+    }
+    enableSwitch.on('switch-change', function(e, data) {
+        // event listener for enable toggle
+        if (is_init < 1) {
+            return;
+        }
+        $('#frame_model_main .btn-static').fadeIn("slow");
+        // why the following code is needed?
+        if ($(".btn-static").is(":visible")) {
+            var buttonH = $(".btn-static").offset().top;
+            $(function(){
+                $(window).scroll(function(){
+                    var scrollH = $(this).scrollTop();
+                    if (scrollH >= buttonH) {
+                        $(".btn-switch").addClass("btn-fixed");
+                    }else{
+                        $(".btn-switch").removeClass("btn-fixed");
+                    }
+                });
+            });
+        }
+    });
+    $('.btn-cancel-action').click(function(evt) {
+        // cancel btn of changing enable status
+        if(evt.detail && evt.detail != 1) {
+            return;
+        }
+        refreshPage();
+    });
+    $('.btn-submit').click(function(evt) {
+        // save btn of changing enable status
+        if(evt.detail && evt.detail != 1) {
+            return;
+        }
+        var enable = enableSwitch.bootstrapSwitch('state'); // true / false
+        $.ajax({
+            url: '/api/v1/cloud/aws/ha/status/',
+            type: 'POST',
+            dataType: 'json',
+            data: JSON.stringify({
+                status: (enable ? 1 : 0)
+            }),
+            success: function (res) {
+                refreshPage();
+            },
+            error: function (xhr, textStatus, errorThrown) {
+                console.log(textStatus + "," + errorThrown + "," + xhr.responseText);
+            }
+        });
+    });
+    var modal_fields = [{
+        field: '{% trans %}source ENI id{% endtrans %}',
+        id: 'src_eni_id',
+        value: ''
+    },{
+        field: '{% trans %}destination ENI {% endtrans %}',
+        id: 'dest_eni_id',
+        value: ''
+    },];
+    // for displaying fields in each block
+    var show_fields = ['index', 'src_eni_id', 'dest_eni_id'];
+    var is_show_field_title = false;
+
+    $('.add-btn').click(function() {
+        // add eni btn
+        var content = setContent(modal_fields);
+        $('.modal-fields').html(content);
+        $('#addModal').modal();
+    });
+    $('.failover-btn').click(function(evt) {
+        // btn of manual trigger failover
+        if(evt.detail && evt.detail != 1) {
+            return;
+        }
+        var that = this;
+        $(that).css("disabled", true);
+        $.ajax({
+            url: '/api/v1/cloud/aws/failover/',
+            type: 'PUT',
+            dataType: 'json',
+            data: JSON.stringify({
+                status: 1
+            }),
+            success: function (res) {
+                if (typeof(res["msg"]) == "undefined") {
+                console.log(res["msg"], typeof(res["msg"]))
+
+                    return;
+                }
+                alert(res["msg"]);
+                $(that).css("disabled", false);
+            },
+            error: function (xhr, textStatus, errorThrown) {
+                console.log(textStatus + "," + errorThrown + "," + xhr.responseText);
+                $(that).css("disabled", false);
+            }
+        });
+    });
+    $('.recover-btn').click(function(evt) {
+        // btn of manual trigger recover
+        if(evt.detail && evt.detail != 1) {
+            return;
+        }
+        var that = this;
+        $(that).css("disabled", true);
+        $.ajax({
+            url: '/api/v1/cloud/aws/recover/',
+            type: 'PUT',
+            dataType: 'json',
+            data: JSON.stringify({
+                status: 0
+            }),
+            success: function (res) {
+                console.log(res["msg"], typeof(res["msg"]))
+                if (typeof(res["msg"]) == "undefined") {
+                    return;
+                }
+                alert(res["msg"]);
+                $(that).css("disabled", false);
+            },
+            error: function (xhr, textStatus, errorThrown) {
+                console.log(textStatus + "," + errorThrown + "," + xhr.responseText);
+                $(that).css("disabled", false);
+            }
+        });
+    });
+    var config = [];
+    $('.btn-save').click(function(evt) {
+        // submit btn of adding eni
+        // why this can get the needed  data
+        if(evt.detail && evt.detail != 1) {
+            return;
+        }
+        var each = {};
+        $('.field').each(function() {
+            if ($(this).val() == "") {
+                return;
+            }
+            each[$(this).data('id')] = $(this).val();
+        });
+        if (Object.keys(each).length < 1) {
+            return;
+        }
+        addENI(each.src_eni_id, each.dest_eni_id);
+    });
+
+    getENIConfig();
+    function getENIConfig() {
+        // get list of eni config
+        $.ajax({
+            url: '/api/v1/cloud/aws/eniconfig/',
+            type: 'GET',
+            dataType: 'json',
+            success: function(res) {
+                for (var index in res) {
+                    config.push({
+                        primary_key: index,
+                        dest_eni_id: res[index].dest_eni_id,
+                        src_eni_id: res[index].src_eni_id,
+                    })
+                }
+                updateBlockList(config, show_fields, is_show_field_title);
+
+            },
+            error: function (xhr, textStatus, errorThrown) {
+                console.log(textStatus + "," + errorThrown + "," + xhr.responseText);
+            }
+        });
+    }
+
+    /**
+     * Return html string for content of pop up window(Add)
+     * @param array setting: array for each setting
+     * @return string
+     */
+    function setContent(setting) {
+        // for modal of adding eni
+        var html = [];
+        for (var ind = 0; ind < setting.length; ++ind) {
+            var each = setting[ind];
+            html.push([
+                '<fieldset>',
+                    '<div class="group_actions"></div>',
+                        '<div class="form-group">',
+                        '<label class="col-md-3 control-label">',
+                            setting[ind].field,
+                        ':</label>',
+                        '<div class="col-md-9">',
+                            '<input type="text" class="field" data-id="' + setting[ind].id,
+                            '" value="' + setting[ind].value + '" />',
+                        '</div>',
+                    '</div>',
+                '</fieldset>'
+            ].join(""));
+        }
+        return html.join("");
+    }
+
+    /**
+     * Update layout for each blocks
+     * @param array setting: array of block information
+     * @param array fields: array of displaying fields, empty is all
+     * @param bool value_only: display value or [field: value] for each list
+     * @return void
+     */
+    function updateBlockList(setting, fields = [], value_only = true) {
+        // update and rerender the list of eni config
+        var html = [];
+        var nameMapping = getNameMapping(); // ex: sub_id: SubId
+        for (var ind = 0; ind < setting.length; ++ind) {
+            var list = [];
+            for (var field in setting[ind]) {
+                if (fields.length !== 0 && fields.indexOf(field) === -1) {
+                    // Not display
+                    continue;
+                }
+                if (field == "index") {
+                    // Not display
+                    continue;
+                }
+                var content = setting[ind][field];
+                if (!value_only) {
+                    var display_name = "";
+                    if (nameMapping.hasOwnProperty(field)) {
+                        display_name = nameMapping[field];
+                    }
+                    content = display_name + ": " + content;
+                }
+                list.push([
+                    '<li data-id="' + field + '">' + content + '</li>'
+                ].join(""));
+            }
+            html.push([
+                '<div class="block">',
+                    '<div class="modal-dialog">',
+                        '<div class="box modal-content">',
+                            '<div class="box-header">',
+                                '<span>' + setting[ind]['primary_key'] + '</span>',
+                                '<button type="button" class="close" aria-label="Close"',
+                                    'data-id="' + setting[ind]['primary_key'] + '">',
+                                    '<span aria-hidden="true">&times;</span></button>',
+                            '</div>',
+                            '<div class="box-body">',
+                                '<ul>',
+                                    list.join(""),
+                                '</ul>',
+                            '</div>',
+                        '</div>',
+                    '</div>',
+                '</div>'
+            ].join(""));
+        }
+        $('#app').html(html.join(""));
+        $('#app .block .box-header button').click(function() {
+            var index = parseInt($(this).data("id"));
+            delNIC(index);
+        });
+    }
+
+    function addENI(src_eni_id, dest_eni_id) {
+        // add eni api
+        $.ajax({
+            url: '/api/v1/cloud/aws/eniconfig/',
+            type: 'POST',
+            dataType: 'json',
+            data: JSON.stringify({
+                src_eni_id: src_eni_id,
+                dest_eni_id: dest_eni_id,
+            }),
+            success: function(res) {
+                $('#addModal').modal('hide');
+                setTimeout(function() {
+                    refreshPage();
+                }, 400);
+            },
+            error: function (xhr, textStatus, errorThrown) {
+                $('#addModal').modal('hide');
+                console.log(textStatus + "," + errorThrown + "," + xhr.responseText);
+            }
+        });
+    }
+
+    function delNIC(index) {
+        // delete eni api
+        $.ajax({
+            url: '/api/v1/cloud/aws/eniconfig/',
+            type: 'DELETE',
+            dataType: 'json',
+            data: JSON.stringify({
+                index: String(index)
+            }),
+            success: function(res) {
+                refreshPage();
+            },
+            error: function (xhr, textStatus, errorThrown) {
+                console.log(textStatus + "," + errorThrown + "," + xhr.responseText);
+            }
+        });
+    }
+
+    /**
+     * Get Display name mapping by index
+     * @return object
+     */
+    function getNameMapping() {
+        var mapping = {};
+        for (var ind = 0; ind < modal_fields.length; ++ind) {
+            mapping[modal_fields[ind].id] = modal_fields[ind].field;
+        }
+        return mapping;
+    }
+
+    function refreshPage() {
+        $('.config-nav li.active a').trigger('click');
+    }
+
+});
+
+</script>
+{% endblock box_script %}
Index: /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/templates/network/cloud/aws/index.html
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/templates/network/cloud/aws/index.html	(revision 0)
+++ /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/templates/network/cloud/aws/index.html	(working copy)
@@ -0,0 +1,117 @@
+{% extends "base.html" %}
+
+{% block content %}
+
+{% block horizontal_nav %}
+<div class="horizontal-nav">
+    <div class="crumbs">
+        <a href="/apv/network/cloud/azure/_index"><i class="fa fa-home"></i></a>
+    </div>
+<ul class="nav nav-tabs">
+    <li class="active">
+        <a href="/apv/network/cloud/azure/_index">Azure</a>
+    </li>
+    <li class="active">
+        <a href="/apv/network/cloud/aws/_index">AWS</a>
+    </li>
+</ul>
+</div>
+<div></div>
+{% endblock horizontal_nav %}
+
+<div class="head-nav-box clearfix-before">
+{% block model_nav %}
+<nav class="head-nav" role="navigation">
+    <a class="model-name" href="#" style="width:90%;"><i class="fa fa-folder-open"></i>&nbsp;AWS</a>
+</nav>
+{% endblock model_nav %}
+</div>
+
+{% block sub_nav %}
+<ul class="config-nav nav nav-pills" style="display:none;">
+    <li class="active">
+        <a class="config-nav-a" val="/apv/get_cloud_page?type=aws&page=basic" href="javascript:;">{% trans %}Basic Settings{% endtrans %} <i class="fa fa-wrench"></i></a>
+        <ul class="sub-config-nav group-index">
+            <li><a val="/apv/get_cloud_page?type=azure&page=basic" href="javascript:;">General</a></li>
+        </ul>
+    </li>
+    <li>
+        <a class="config-nav-a" val="/apv/get_cloud_page?type=aws&page=eni" href="javascript:;">{% trans %}ENI{% endtrans %} <i class="fa fa-wrench"></i></a>
+        <ul class="sub-config-nav group-nic">
+            <li><a val="/apv/get_cloud_page?type=aws&page=eni" href="javascript:;">General</a></li>
+        </ul>
+    </li>
+
+    <li>
+        <a class="config-nav-a" val="/apv/get_cloud_page?type=azure&page=log" href="javascript:;">{% trans %}Log{% endtrans %} <i class="fa fa-wrench"></i></a>
+        <ul class="sub-config-nav group-log">
+            <li><a val="/apv/get_cloud_page?type=azure&page=log" href="javascript:;">General</a></li>
+        </ul>
+    </li>
+</ul>
+<ul class="sub-config-nav-real"></ul>
+<script type="text/javascript">
+require(['jquery'], function(){
+    if ($('.config-nav li').length > 1) {
+        $('.config-nav').show();
+    }
+});
+</script>
+{% endblock %}
+
+<div id="frame_model_main" class="frame" style="display: block;">
+</div>
+<style type="text/css">
+#frame_model_main {
+    position: relative;
+}
+.align_center_for_info {
+    line-height: 28px;
+}
+</style>
+
+{% endblock %}
+
+{% block page_javascript %}
+<script type="text/javascript">
+require(['jquery'], function(){
+    $(".config-nav-a").on("click", function(e) {
+        e.preventDefault();
+    });
+});
+require(['hive', 'widget-form'], function(){
+    var initiator = new Object();
+    $HIVE.enable_event(initiator);
+    $(".config-nav a.config-nav-a").click(function(){
+        $(".config-nav li").removeClass("active");
+        $(this).parents("li").addClass("active");
+        var sub_nav = $($(this).parents('li').find('ul')[0])
+        if (sub_nav && sub_nav.children().length > 1) {
+           var real_sub_nav = sub_nav.clone(true).removeClass('sub-config-nav').addClass('sub-config-nav-real');
+            $(".sub-config-nav-real").replaceWith(real_sub_nav);
+            $(".sub-config-nav-real").show();
+            $("#frame_instance_main").css("padding-top", "50px");
+            real_sub_nav.find('a').click(function(){
+                $(".sub-config-nav-real li").removeClass("active");
+                $(this).parents("li").addClass("active");
+                var url = $(this).attr('val')
+                $HIVE.ajax_load_box(url, initiator, $("#frame_model_main"));
+                return false;
+            });
+            $(".sub-config-nav-real a:first").trigger("click");
+        } else {
+            $("#frame_instance_main").css("padding-top", "0px");
+            $(".sub-config-nav-real").empty();
+            $(".sub-config-nav-real").hide();
+            var url = $(this).attr('val')
+            $HIVE.ajax_load_box(url, initiator, $("#frame_model_main"));
+        }
+        return false;
+    });
+    $(".config-nav a:first").trigger("click");
+});
+</script>
+{% endblock %}
+
+{% block box_script %}
+{% endblock %}
Index: /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/templates/network/cloud/aws/log.html
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/templates/network/cloud/aws/log.html	(revision 0)
+++ /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/templates/network/cloud/aws/log.html	(working copy)
@@ -0,0 +1,259 @@
+
+<form class="form-horizontal main-form">
+    <div class="row-fluid">
+        <div class="span12 with-min-width field-group-box">
+            <fieldset>
+                <div class="group_actions"></div>
+                <div class="form-group switch switch_enable">
+                    <label class="col-md-3 control-label">{% trans %}Enable{% endtrans %}:</label>
+                    <div class="col-md-9">
+                        <input class="switch-small" type="checkbox" name="switch_btn"
+                        data-on-label="{% trans %}On{% endtrans %}"
+                        data-off-label="{% trans %}Off{% endtrans %}" />
+                        <span class="field-icon-set"></span>
+                    </div>
+                </div>
+            </fieldset>
+            <fieldset>
+                <div class="form-group">
+                    <label class="col-md-3 control-label">{% trans %}Level{% endtrans %}</label>
+                    <div class="col-md-9">
+                        <select class="selectpicker select-level">
+                            <option value="debug">0: {% trans %}Debug{% endtrans %}</option>
+                            <option value="info">1: {% trans %}Info{% endtrans %}</option>
+                            <option value="warning">2: {% trans %}Warning{% endtrans %}</option>
+                            <option value="error">3: {% trans %}Error{% endtrans %}</option>
+                        </select>
+                        <span class="field-icon-set"><i class="fa fa-question-circle" style="display:none;"></i></span>
+                    </div>
+                </div>
+            </fieldset>
+            <fieldset>
+                <div class="form-group">
+                    <label class="col-md-3 control-label"></label>
+                    <div class="col-md-9">
+                        <button type="button" class="btn btn-primary download-btn">{% trans %}Download{% endtrans %}</button>
+                    </div>
+                </div>
+            </fieldset>
+            <fieldset>
+                <pre class="log_content"></pre>
+            </fieldset>
+        </div>
+    </div><!-- row-fluid -->
+    <div
+    class="btn-static">
+        <div class="btn-switch">
+            <button type="button" class="btn btn-action btn-submit">{% trans %}Save Changes{% endtrans %}</button>
+            <button type="button" class="btn btn-default btn-cancel-action">{% trans %}Cancel{% endtrans %}</button>
+        </div>
+    </div>
+</form>
+<style type="text/css">
+.main-form pre {
+    background: #1b2d43;
+}
+.btn-static {
+    display: none;
+}
+</style>
+
+{% block box_script %}
+
+<script type="text/javascript">
+
+$(function() {
+    var enableSwitch = $("input[name='switch_btn']").bootstrapSwitch();
+    let is_change = false
+
+    $('.btn-cancel-action').click(function(evt) {
+        // cancel current changes
+        if(evt.detail && evt.detail != 1) {
+            return;
+        }
+        refreshPage();
+    });
+    $('.btn-submit').click(function(evt) {
+        // submit the chages of state of log functionality and log severity
+        if(evt.detail && evt.detail != 1) {
+            return;
+        }
+        var enable = enableSwitch.bootstrapSwitch('state'); // true / false
+        var ajaxes = [];
+        ajaxes.push($.ajax({
+            url: '/api/v1/cloud/aws/log/status/',
+            type: 'PUT',
+            dataType: 'json',
+            data: JSON.stringify({
+                status: (enable ? 1 : 0)
+            }),
+            success: function (res) {
+            },
+            error: function (xhr, textStatus, errorThrown) {
+                console.log(textStatus + "," + errorThrown + "," + xhr.responseText);
+            }
+        }));
+        ajaxes.push($.ajax({
+            url: '/api/v1/cloud/aws/log/severity/',
+            type: 'PUT',
+            dataType: 'json',
+            data: JSON.stringify({
+                severity: $(".select-level").selectpicker('val')
+            }),
+            success: function (res) {
+                refreshPage();
+            },
+            error: function (xhr, textStatus, errorThrown) {
+                console.log(textStatus + "," + errorThrown + "," + xhr.responseText);
+            }
+        }));
+        refreshPage();
+    });
+
+    $('.download-btn').click(function(evt) {
+        // add event listener to the download button
+        if(evt.detail && evt.detail != 1) {
+            return;
+        }
+        window.open("/api/v1/cloud/aws/log/file/");
+    });
+
+    async function getEnableStatus() {
+        // get the status of the log functionality
+        console.log("getEnableStatus");
+        const res = await new Promise((resolve, reject) => {
+            $.ajax({
+                url: '/api/v1/cloud/aws/log/status/',
+                type: 'GET',
+                dataType: 'json',
+                success: function (response) {
+
+                    if (typeof(response["status"]) === "undefined") {
+                        reject("Status undefined");
+                    } else {
+                        enableSwitch.bootstrapSwitch('setState', response["status"]);
+                        $('.btn-static').css('display', 'none');
+
+                        resolve(response);  // Resolve the promise with the response data
+                    }
+                },
+                error: function (xhr, textStatus, errorThrown) {
+                    console.log(textStatus + "," + errorThrown + "," + xhr.responseText);
+                    reject(errorThrown);  // Reject the promise on AJAX error
+                }
+            });
+        });
+        console.log("finish getEnableStatus")
+
+        // Return the result if necessary (optional)
+        return res;
+    }
+
+    async function getLogLevel() {
+        // get the current log level
+        const res = await new Promise((resolve, reject) => {
+            console.log("getLogLevel")
+            $.ajax({
+            url: '/api/v1/cloud/aws/log/severity/',
+            type: 'GET',
+            dataType: 'json',
+            success: function (response) {
+                if (typeof(response["severity"]) == "undefined") {
+                    reject("Status undefined");
+                }
+                $('.select-level').selectpicker("val", response["severity"]);
+                $('.btn-static').css('display', 'none');
+
+                resolve(response);  // Resolve the promise with the response data
+            },
+            error: function (xhr, textStatus, errorThrown) {
+                console.log(textStatus + "," + errorThrown + "," + xhr.responseText);
+                reject(errorThrown);  // Reject the promise on AJAX error
+            }
+            });
+        });
+        console.log("finish getLogLevel")
+        return res;
+
+    }
+    async function getLog() {
+        // get the content of log
+        const res = await new Promise((resolve, reject) => {
+            console.log("getInit")
+            $.ajax({
+            url: '/api/v1/cloud/aws/log/buffer/',
+            type: 'GET',
+            dataType: 'json',
+            success: function(response) {
+                if (typeof(response["msg"]) == "undefined") {
+                    return;
+                }
+                $('.log_content').html(response ["msg"]);
+                resolve(response);  // Resolve the promise with the response data
+            },
+            error: function (xhr, textStatus, errorThrown) {
+                console.log(textStatus + "," + errorThrown + "," + xhr.responseText);
+                reject(errorThrown);  // Reject the promise on AJAX error
+            }
+        });
+        });
+        console.log("finish getLog")
+
+        return res;
+
+    }
+    initPage();
+    async function initPage(){
+        console.log("init")
+        // Run all three functions asynchronously
+        await Promise.all([getEnableStatus(), getLogLevel(), getLog()]);
+        // Once all functions are completed, hide the element
+        console.log("display none");
+        $('.btn-static').css('display', 'none');
+
+        enableSwitch.on('switch-change', function(e, data) {
+            // add the event listener to the enable switch
+            $('#frame_model_main .btn-static').fadeIn("slow");
+            if ($(".btn-static").is(":visible")) {
+                var buttonH = $(".btn-static").offset().top;
+                $(function(){
+                    $(window).scroll(function(){
+                        var scrollH = $(this).scrollTop();
+                        if (scrollH >= buttonH) {
+                            $(".btn-switch").addClass("btn-fixed");
+                        }else{
+                            $(".btn-switch").removeClass("btn-fixed");
+                        }
+                    });
+                });
+            }
+        });
+        $(".select-level").change(function() {
+            // add the event listener to the log level select
+            $('#frame_model_main .btn-static').fadeIn("slow");
+            if ($(".btn-static").is(":visible")) {
+                var buttonH = $(".btn-static").offset().top;
+                $(function(){
+                    $(window).scroll(function(){
+                        var scrollH = $(this).scrollTop();
+                        if (scrollH >= buttonH) {
+                            $(".btn-switch").addClass("btn-fixed");
+                        }else{
+                            $(".btn-switch").removeClass("btn-fixed");
+                        }
+                    });
+                });
+            }
+        });
+    }
+
+    function refreshPage() {
+        $('.config-nav li.active a').trigger('click');
+    }
+
+    $('.select-level').selectpicker();
+
+});
+
+</script>
+{% endblock box_script %}
Index: /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/templates/network/cloud/azure/basic.html
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/templates/network/cloud/azure/basic.html	(revision 0)
+++ /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/templates/network/cloud/azure/basic.html	(working copy)
@@ -0,0 +1,159 @@
+<form class="form-horizontal main-form">
+<div class="row-fluid">
+    <div class="span12 with-min-width field-group-box">
+        <fieldset>
+            <div class="form-group">
+                <label class="col-md-3 control-label">{% trans %}Status{% endtrans %}:</label>
+                <div class="col-md-9 status_field">
+                    <div class="align_center_for_info">...</div>
+                </div>
+            </div>
+        </fieldset>
+        <fieldset class="not_logged_check">
+            <div class="form-group">
+                <label class="col-md-3 control-label">{% trans %}Login Url{% endtrans %}:</label>
+                <div class="col-md-9 url_field">
+                    <a href="#" class="align_center_for_info" target="_blank">...</a>
+                    <span class="field-icon-set"><i class="fa fa-question-circle"></i></span>
+                </div>
+            </div>
+        </fieldset>
+        <fieldset class="not_logged_check">
+            <div class="form-group">
+                <label class="col-md-3 control-label">{% trans %}Code{% endtrans %}:</label>
+                <div class="col-md-9 code_field">
+                    <div class="align_center_for_info" target="_blank">...</div>
+                    <span class="field-icon-set"><i class="fa fa-question-circle"></i></span>
+                </div>
+            </div>
+        </fieldset>
+        <fieldset class="error_field">
+            <div class="form-group">
+                <div class="col-md-3"></div>
+                <div class="error-info">{% trans %}Internal error, please refresh the page.{% endtrans %}</div>
+            </div>
+        </fieldset>
+        <fieldset>
+            <div class="form-group">
+                <label class="col-md-3 control-label"></label>
+                <div class="col-md-9">
+                    <button type="button" class="btn btn-primary btn-log-out">{% trans %}Log Out{% endtrans %}</button>
+                </div>
+            </div>
+        </fieldset>
+    </div>
+</div>
+</form>
+<style type="text/css">
+.align_center_for_info {
+    line-height: 28px;
+}
+.btn-log-out {
+    display: none;
+}
+.code_field div {
+    display: inline-block;
+}
+.code_field span {
+    display: none;
+}
+.error_field {
+    display: none;
+}
+</style>
+
+{% block box_script %}
+
+<script type="text/javascript">
+
+$(function () {
+
+    getStatus();
+    function getStatus () {
+        $('.status_field div').html('...');
+        $('.btn-log-out').css('display', 'none');
+        $.ajax({
+            url: "/api/v1/cloud/az/login/status/",
+            type: 'GET',
+            dataType: 'json',
+            success: function (res) {
+                var status = false;
+                if (typeof (res["status"]) != "undefined") {
+                    status = res["status"];
+                }
+                if (!status) {
+                    getInformation();
+                    $('.status_field div').html("{% trans %}Not logged in{% endtrans %}");
+                    return;
+                }
+                $('.not_logged_check').css('display', 'none');
+                $('.status_field div').html("{% trans %}Logged in{% endtrans %}");
+                $('.btn-log-out').css('display', 'block');
+            },
+            error: function (xhr, textStatus, errorThrown) {
+                getInformation();
+                console.log(textStatus + "," + errorThrown + "," + xhr.responseText);
+            }
+        });
+    }
+    function getInformation () {
+        $.ajax({
+            url: "/api/v1/cloud/az/login/",
+            type: 'GET',
+            dataType: 'json',
+            success: function (res) {
+                var url = "", code = "";
+                if (typeof (res["url"]) != "undefined") {
+                    url = res["url"];
+                }
+                if (typeof (res["code"]) != "undefined") {
+                    code = res["code"];
+                }
+                $('.url_field a').html(url).prop('href', url);
+                $('.code_field div').html(code);
+                $('.code_field span').css('display', 'inline-block');
+                var content = [
+                    '{% trans %}Your authentication code will expire in 60 seconds.{% endtrans %}<br />',
+                    '{% trans %}Please use the following information to sign in immediately.{% endtrans %}<br />',
+                    '{% trans %}WARNING: To sign in, use a web browser to open the page %s {% endtrans %}'.replace("%s", url),
+                    '{% trans %} and enter the code {% endtrans %}',
+                    code,
+                    '{% trans %} to authenticate.{% endtrans %}'
+                ].join("");
+                $('.field-icon-set').popover({
+                    trigger: "hover",
+                    content: content,
+                    html: true
+                });
+                $('.not_logged_check').css('display', 'block');
+            },
+            error: function (xhr, textStatus, errorThrown) {
+                console.log(textStatus + "," + errorThrown + "," + xhr.responseText);
+                $('.error_field').css('display', 'block');
+            }
+        });
+    }
+
+    $('.btn-log-out').click(function() {
+        var that = this;
+        $(that).prop('disabled', true);
+        $.ajax({
+            url: "/api/v1/cloud/az/logout/",
+            type: 'POST',
+            dataType: 'json',
+            success: function (res) {
+                $(that).prop('disabled', false);
+                getStatus();
+            },
+            error: function (xhr, textStatus, errorThrown) {
+                $(that).prop('disabled', false);
+                console.log(textStatus + "," + errorThrown + "," + xhr.responseText);
+            }
+        });
+    });
+
+});
+
+</script>
+
+{% endblock box_script %}
Index: /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/templates/network/cloud/azure/index.html
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/templates/network/cloud/azure/index.html	(revision 0)
+++ /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/templates/network/cloud/azure/index.html	(working copy)
@@ -0,0 +1,123 @@
+{% extends "base.html" %}
+
+{% block content %}
+
+{% block horizontal_nav %}
+<div class="horizontal-nav">
+    <div class="crumbs">
+        <a href="/apv/network/cloud/azure/_index"><i class="fa fa-home"></i></a>
+    </div>
+<ul class="nav nav-tabs">
+    <li class="active">
+        <a href="/apv/network/cloud/azure/_index">Azure</a>
+    </li>
+    <li class="active">
+        <a href="/apv/network/cloud/aws/_index">AWS</a>
+    </li>
+</ul>
+</div>
+<div></div>
+{% endblock horizontal_nav %}
+
+<div class="head-nav-box clearfix-before">
+{% block model_nav %}
+<nav class="head-nav" role="navigation">
+    <a class="model-name" href="#" style="width:90%;"><i class="fa fa-folder-open"></i>&nbsp;Azure</a>
+</nav>
+{% endblock model_nav %}
+</div>
+
+{% block sub_nav %}
+<ul class="config-nav nav nav-pills" style="display:none;">
+    <li class="active">
+        <a class="config-nav-a" val="/apv/get_cloud_page?type=azure&page=basic" href="javascript:;">{% trans %}Basic Settings{% endtrans %} <i class="fa fa-wrench"></i></a>
+        <ul class="sub-config-nav group-index">
+            <li><a val="/apv/get_cloud_page?type=azure&page=basic" href="javascript:;">General</a></li>
+        </ul>
+    </li>
+    <li>
+        <a class="config-nav-a" val="/apv/get_cloud_page?type=azure&page=nic" href="javascript:;">{% trans %}NIC{% endtrans %} <i class="fa fa-wrench"></i></a>
+        <ul class="sub-config-nav group-nic">
+            <li><a val="/apv/get_cloud_page?type=azure&page=nic" href="javascript:;">General</a></li>
+        </ul>
+    </li>
+    <li>
+        <a class="config-nav-a" val="/apv/get_cloud_page?type=azure&page=udr" href="javascript:;">{% trans %}UDR{% endtrans %} <i class="fa fa-wrench"></i></a>
+        <ul class="sub-config-nav group-udr">
+            <li><a val="/apv/get_cloud_page?type=azure&page=udr" href="javascript:;">General</a></li>
+        </ul>
+    </li>
+    <li>
+        <a class="config-nav-a" val="/apv/get_cloud_page?type=azure&page=log" href="javascript:;">{% trans %}Log{% endtrans %} <i class="fa fa-wrench"></i></a>
+        <ul class="sub-config-nav group-log">
+            <li><a val="/apv/get_cloud_page?type=azure&page=log" href="javascript:;">General</a></li>
+        </ul>
+    </li>
+</ul>
+<ul class="sub-config-nav-real"></ul>
+<script type="text/javascript">
+require(['jquery'], function(){
+    if ($('.config-nav li').length > 1) {
+        $('.config-nav').show();
+    }
+});
+</script>
+{% endblock %}
+
+<div id="frame_model_main" class="frame" style="display: block;">
+</div>
+<style type="text/css">
+#frame_model_main {
+    position: relative;
+}
+.align_center_for_info {
+    line-height: 28px;
+}
+</style>
+
+{% endblock %}
+
+{% block page_javascript %}
+<script type="text/javascript">
+require(['jquery'], function(){
+    $(".config-nav-a").on("click", function(e) {
+        e.preventDefault();
+    });
+});
+require(['hive', 'widget-form'], function(){
+    var initiator = new Object();
+    $HIVE.enable_event(initiator);
+    $(".config-nav a.config-nav-a").click(function(){
+        $(".config-nav li").removeClass("active");
+        $(this).parents("li").addClass("active");
+        var sub_nav = $($(this).parents('li').find('ul')[0])
+        if (sub_nav && sub_nav.children().length > 1) {
+           var real_sub_nav = sub_nav.clone(true).removeClass('sub-config-nav').addClass('sub-config-nav-real');
+            $(".sub-config-nav-real").replaceWith(real_sub_nav);
+            $(".sub-config-nav-real").show();
+            $("#frame_instance_main").css("padding-top", "50px");
+            real_sub_nav.find('a').click(function(){
+                $(".sub-config-nav-real li").removeClass("active");
+                $(this).parents("li").addClass("active");
+                var url = $(this).attr('val')
+                $HIVE.ajax_load_box(url, initiator, $("#frame_model_main"));
+                return false;
+            });
+            $(".sub-config-nav-real a:first").trigger("click");
+        } else {
+            $("#frame_instance_main").css("padding-top", "0px");
+            $(".sub-config-nav-real").empty();
+            $(".sub-config-nav-real").hide();
+            var url = $(this).attr('val')
+            $HIVE.ajax_load_box(url, initiator, $("#frame_model_main"));
+        }
+       
+        return false;
+    });
+    $(".config-nav a:first").trigger("click");
+});
+</script>
+{% endblock %}
+
+{% block box_script %}
+{% endblock %}
Index: /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/templates/network/cloud/azure/log.html
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/templates/network/cloud/azure/log.html	(revision 0)
+++ /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/templates/network/cloud/azure/log.html	(working copy)
@@ -0,0 +1,215 @@
+
+<form class="form-horizontal main-form">
+    <div class="row-fluid">
+        <div class="span12 with-min-width field-group-box">
+            <fieldset>
+                <div class="group_actions"></div>
+                <div class="form-group switch switch_enable">
+                    <label class="col-md-3 control-label">{% trans %}Enable{% endtrans %}:</label>
+                    <div class="col-md-9">
+                        <input class="switch-small" type="checkbox" name="switch_btn"
+                        data-on-label="{% trans %}On{% endtrans %}"
+                        data-off-label="{% trans %}Off{% endtrans %}" />
+                        <span class="field-icon-set"></span>
+                    </div>
+                </div>
+            </fieldset>
+            <fieldset>
+                <div class="form-group">
+                    <label class="col-md-3 control-label">{% trans %}Level{% endtrans %}</label>
+                    <div class="col-md-9">
+                        <select class="selectpicker select-level">
+                            <option value="debug">0: {% trans %}Debug{% endtrans %}</option>
+                            <option value="info">1: {% trans %}Info{% endtrans %}</option>
+                            <option value="warning">2: {% trans %}Warning{% endtrans %}</option>
+                            <option value="error">3: {% trans %}Error{% endtrans %}</option>
+                        </select>
+                        <span class="field-icon-set"><i class="fa fa-question-circle" style="display:none;"></i></span>
+                    </div>
+                </div>
+            </fieldset>
+            <fieldset>
+                <div class="form-group">
+                    <label class="col-md-3 control-label"></label>
+                    <div class="col-md-9">
+                        <button type="button" class="btn btn-primary download-btn">{% trans %}Download{% endtrans %}</button>
+                    </div>
+                </div>
+            </fieldset>
+            <fieldset>
+                <pre class="log_content log_background"></pre>
+            </fieldset>
+        </div>
+    </div><!-- row-fluid -->
+    <div class="btn-static">
+        <div class="btn-switch">
+            <button type="button" class="btn btn-action btn-submit">{% trans %}Save Changes{% endtrans %}</button>
+            <button type="button" class="btn btn-default btn-cancel-action">{% trans %}Cancel{% endtrans %}</button>
+        </div>
+    </div>
+</form>
+<style type="text/css">
+.btn-static {
+    display: none;
+}
+</style>
+
+{% block box_script %}
+
+<script type="text/javascript">
+
+$(function() {
+    var enableSwitch = $("input[name='switch_btn']").bootstrapSwitch();
+    var is_init = 0;
+    getEnableStatus();
+    function getEnableStatus() {
+        $.ajax({
+            url: '/api/v1/cloud/az/log/status/',
+            type: 'GET',
+            dataType: 'json',
+            success: function (res) {
+                if (typeof(res["is_on"]) == "undefined") {
+                    return;
+                }
+                enableSwitch.bootstrapSwitch('setState', res["is_on"]);
+                is_init++;
+            },
+            error: function (xhr, textStatus, errorThrown) {
+                console.log(textStatus + "," + errorThrown + "," + xhr.responseText);
+            }
+        });
+    }
+    enableSwitch.on('switch-change', function(e, data) {
+        if (is_init < 2) {
+            return;
+        }
+        $('#frame_model_main .btn-static').fadeIn("slow");
+        if ($(".btn-static").is(":visible")) {
+            var buttonH = $(".btn-static").offset().top;  
+            $(function(){ 
+                $(window).scroll(function(){ 
+                    var scrollH = $(this).scrollTop();  
+                    if (scrollH >= buttonH) {
+                        $(".btn-switch").addClass("btn-fixed");
+                    }else{  
+                        $(".btn-switch").removeClass("btn-fixed");
+                    } 
+                });
+            });
+        }
+    });
+    $('.select-level').selectpicker();
+    getLogLevel();
+    function getLogLevel() {
+        $.ajax({
+            url: '/api/v1/cloud/az/log/severity/',
+            type: 'GET',
+            dataType: 'json',
+            success: function (res) {
+                if (typeof(res["severity"]) == "undefined") {
+                    return;
+                }
+                $('.select-level').selectpicker("val", res["severity"]);
+                is_init++;
+            },
+            error: function (xhr, textStatus, errorThrown) {
+                console.log(textStatus + "," + errorThrown + "," + xhr.responseText);
+            }
+        });
+    }
+    $(".select-level").change(function() {
+        if (is_init < 2) {
+            return;
+        }
+        $('#frame_model_main .btn-static').fadeIn("slow");
+        if ($(".btn-static").is(":visible")) {
+            var buttonH = $(".btn-static").offset().top;  
+            $(function(){ 
+                $(window).scroll(function(){ 
+                    var scrollH = $(this).scrollTop();  
+                    if (scrollH >= buttonH) {
+                        $(".btn-switch").addClass("btn-fixed");
+                    }else{  
+                        $(".btn-switch").removeClass("btn-fixed");
+                    } 
+                });
+            });
+        }
+    });
+    $('.btn-cancel-action').click(function(evt) {
+        if(evt.detail && evt.detail != 1) {
+            return;
+        }
+        refreshPage();
+    });
+    $('.btn-submit').click(function(evt) {
+        if(evt.detail && evt.detail != 1) {
+            return;
+        }
+        var enable = enableSwitch.bootstrapSwitch('state'); // true / false
+        var ajaxes = [];
+        ajaxes.push($.ajax({
+            url: '/api/v1/cloud/az/log/status/',
+            type: 'PUT',
+            dataType: 'json',
+            data: JSON.stringify({
+                status: (enable ? 'on' : 'off')
+            }),
+            success: function (res) {
+            },
+            error: function (xhr, textStatus, errorThrown) {
+                console.log(textStatus + "," + errorThrown + "," + xhr.responseText);
+            }
+        }));
+        ajaxes.push($.ajax({
+            url: '/api/v1/cloud/az/log/severity/',
+            type: 'PUT',
+            dataType: 'json',
+            data: JSON.stringify({
+                severity: $(".select-level").selectpicker('val')
+            }),
+            success: function (res) {
+                refreshPage();
+            },
+            error: function (xhr, textStatus, errorThrown) {
+                console.log(textStatus + "," + errorThrown + "," + xhr.responseText);
+            }
+        }));
+        $.when.apply($, ajaxes)
+        .done(function(){
+            refreshPage();
+        });
+    });
+
+    $('.download-btn').click(function(evt) {
+        if(evt.detail && evt.detail != 1) {
+            return;
+        }
+        window.open("/api/v1/cloud/az/logfile/");
+    });
+
+    getInit();
+    function getInit() {
+        $.ajax({
+            url: '/api/v1/cloud/az/log/',
+            type: 'GET',
+            dataType: 'json',
+            success: function(res) {
+                if (typeof(res["message"]) == "undefined") {
+                    return;
+                }
+                $('.log_content').html(res["message"]);
+            },
+            error: function (xhr, textStatus, errorThrown) {
+                console.log(textStatus + "," + errorThrown + "," + xhr.responseText);
+            }
+        });
+    }
+
+    function refreshPage() {
+        $('.config-nav li.active a').trigger('click');
+    }
+});
+
+</script>
+{% endblock box_script %}
Index: /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/templates/network/cloud/azure/nic.html
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/templates/network/cloud/azure/nic.html	(revision 0)
+++ /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/templates/network/cloud/azure/nic.html	(working copy)
@@ -0,0 +1,458 @@
+<form class="form-horizontal main-form">
+<div class="row-fluid">
+    <div class="span12 with-min-width field-group-box">
+        <fieldset>
+            <div class="group_actions"></div>
+            <div class="form-group switch switch_enable">
+                <label class="col-md-3 control-label">{% trans %}Enable{% endtrans %}:</label>
+                <div class="col-md-3">
+                    <input class="switch-small" type="checkbox" name="switch_btn"
+                    data-on-label="{% trans %}Enable{% endtrans %}"
+                    data-off-label="{% trans %}Disabled{% endtrans %}" />
+                    <span class="field-icon-set"></span>
+                </div>
+                <label class="col-md-3 control-label">{% trans %}Manual Trigger{% endtrans %}:</label>
+                <div class="col-md-3 col-manual-trigger">
+                    <button type="button" class="btn btn-primary failover-btn">{% trans %}Failover{% endtrans %}</button>
+                    <button type="button" class="btn btn-primary recover-btn">{% trans %}Recover{% endtrans %}</button>
+                </div>
+            </div>
+        </fieldset>
+        <fieldset>
+            <div class="form-group add-btn-style">
+                <div class="col-md-3">
+                    <button type="button" class="btn btn-action add-btn control-label"><i class="fa fa-plus-circle"></i>{% trans %}ADD{% endtrans %}</button>
+                </div>
+                <div class="col-md-9" id="app"></div>
+            </div>
+        </fieldset>
+    </div>
+</div>
+<!-- row-fluid -->
+<div class="btn-static">
+    <div class="btn-switch">
+        <button type="button" class="btn btn-action btn-submit">{% trans %}Save Changes{% endtrans %}</button>
+        <button type="button" class="btn btn-default btn-cancel-action">{% trans %}Cancel{% endtrans %}</button>
+    </div>
+</div>
+<div class="modal fade" id="addModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
+    <div class="modal-dialog">
+        <div class="box modal-content">
+            <div class="box-header">
+                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true"></span></button>
+                    <h2>{{ gettext('New %s')%"NIC" }}</h2>
+                </button>
+            </div>
+            <div class="box-body">
+                <form class="form-horizontal main-form">
+                    <div class="padded">
+                        <div class="row-fluid">
+                            <div class="span12 with-min-width field-group-box modal-fields">
+                            </div>
+                        </div>
+                    </div>
+                    <div class="form-actions col-md-offset-3">
+                        <button type="button" class="btn btn-action btn-save">{% trans %}Submit{% endtrans %}</button>
+                        <button type="button" data-dismiss="modal" class="btn btn-default btn-cancel">{% trans %}Cancel{% endtrans %}</button>
+                    </div>
+                </form>
+            </div>
+        </div>
+    </div>
+</div>
+</form>
+<style type="text/css">
+.add-btn-style {
+    text-align: right;
+}
+.add-btn-style .add-btn {
+    background-color: transparent;
+    border: 0;
+    font-weight: 700;
+}
+.modal-fields {
+    padding-top: 20px;
+}
+.form-actions {
+    padding-bottom: 20px;
+}
+#app {
+    display: flex;
+    flex-direction: row;
+    flex-wrap: wrap;
+}
+#app .block {
+    min-width: 200px;
+    box-sizing: border-box;
+    margin-right: 20px;
+}
+#app .box.modal-content {
+    border-radius: 6px;
+}
+#app .block .modal-dialog {
+    width: 100%;
+    margin: 0;
+}
+#app .box-header {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    padding-right: 10px;
+    padding-left: 10px;
+}
+#app .box-header button.close:active {
+    opacity: 0.2;
+}
+#app .box-body ul {
+    padding: 0;
+    list-style: none;
+}
+#app .box-body ul li {
+    padding: 5px;
+    text-align: left;
+}
+.btn-static {
+    display: none;
+}
+</style>
+</div>
+
+{% block box_script %}
+
+<script type="text/javascript">
+
+$(function(){
+    var enableSwitch = $("input[name='switch_btn']").bootstrapSwitch();
+    var is_init = 0;
+    getEnableStatus();
+    function getEnableStatus() {
+        $.ajax({
+            url: '/api/v1/cloud/az/nicpoller/status/',
+            type: 'GET',
+            dataType: 'json',
+            success: function (res) {
+                if (typeof(res["is_running"]) == "undefined") {
+                    return;
+                }
+                enableSwitch.bootstrapSwitch('setState', res["is_running"]);
+                is_init++;
+            },
+            error: function (xhr, textStatus, errorThrown) {
+                console.log(textStatus + "," + errorThrown + "," + xhr.responseText);
+            }
+        });
+    }
+    enableSwitch.on('switch-change', function(e, data) {
+        if (is_init < 1) {
+            return;
+        }
+        $('#frame_model_main .btn-static').fadeIn("slow");
+        if ($(".btn-static").is(":visible")) {
+            var buttonH = $(".btn-static").offset().top;  
+            $(function(){ 
+                $(window).scroll(function(){ 
+                    var scrollH = $(this).scrollTop();  
+                    if (scrollH >= buttonH) {
+                        $(".btn-switch").addClass("btn-fixed");
+                    }else{  
+                        $(".btn-switch").removeClass("btn-fixed");
+                    } 
+                });
+            });
+        }
+    });
+    $('.btn-cancel-action').click(function(evt) {
+        if(evt.detail && evt.detail != 1) {
+            return;
+        }
+        refreshPage();
+    });
+    $('.btn-submit').click(function(evt) {
+        if(evt.detail && evt.detail != 1) {
+            return;
+        }
+        var enable = enableSwitch.bootstrapSwitch('state'); // true / false
+        $.ajax({
+            url: '/api/v1/cloud/az/nicpoller/',
+            type: 'PUT',
+            dataType: 'json',
+            data: JSON.stringify({
+                status: (enable ? 'on' : 'off')
+            }),
+            success: function (res) {
+                refreshPage();
+            },
+            error: function (xhr, textStatus, errorThrown) {
+                console.log(textStatus + "," + errorThrown + "," + xhr.responseText);
+            }
+        });
+    });
+    var modal_fields = [{
+        field: '{% trans %}Sub ID{% endtrans %}',
+        id: 'sub_id',
+        value: ''
+    }, {
+        field: '{% trans %}Resource Grop Name{% endtrans %}',
+        id: 'res_grp_name',
+        value: ''
+    }, {
+        field: '{% trans %}Source NIC Name{% endtrans %}',
+        id: 'src_nic_name',
+        value: ''
+    }, {
+        field: '{% trans %}Destination NIC Name{% endtrans %}',
+        id: 'dest_nic_name',
+        value: ''
+    }];
+    // for displaying fields in each block
+    var show_fields = ['src_nic_name', 'dest_nic_name'];
+    var is_show_field_title = true;
+
+    $('.add-btn').click(function() {
+        var content = setContent(modal_fields);
+        $('.modal-fields').html(content);
+        $('#addModal').modal();
+    });
+    $('.failover-btn').click(function(evt) {
+        if(evt.detail && evt.detail != 1) {
+            return;
+        }
+        var that = this;
+        $(that).css("disabled", true);
+        $.ajax({
+            url: '/api/v1/cloud/az/nictrigger/',
+            type: 'PUT',
+            dataType: 'json',
+            data: JSON.stringify({
+                status: 'failover'
+            }),
+            success: function (res) {
+                if (typeof(res["message"]) == "undefined") {
+                    return;
+                }
+                alert(res["message"]);
+                $(that).css("disabled", false);
+            },
+            error: function (xhr, textStatus, errorThrown) {
+                console.log(textStatus + "," + errorThrown + "," + xhr.responseText);
+                $(that).css("disabled", false);
+            }
+        });
+    });
+    $('.recover-btn').click(function(evt) {
+        if(evt.detail && evt.detail != 1) {
+            return;
+        }
+        var that = this;
+        $(that).css("disabled", true);
+        $.ajax({
+            url: '/api/v1/cloud/az/nictrigger/',
+            type: 'PUT',
+            dataType: 'json',
+            data: JSON.stringify({
+                status: 'recover'
+            }),
+            success: function (res) {
+                if (typeof(res["message"]) == "undefined") {
+                    return;
+                }
+                alert(res["message"]);
+                $(that).css("disabled", false);
+            },
+            error: function (xhr, textStatus, errorThrown) {
+                console.log(textStatus + "," + errorThrown + "," + xhr.responseText);
+                $(that).css("disabled", false);
+            }
+        });
+    });
+    var config = [];
+    $('.btn-save').click(function(evt) {
+        if(evt.detail && evt.detail != 1) {
+            return;
+        }
+        var each = {};
+        $('.field').each(function() {
+            if ($(this).val() == "") {
+                return;
+            }
+            each[$(this).data('id')] = $(this).val();
+        });
+        if (Object.keys(each).length < 1) {
+            return;
+        }
+        addNIC(each.sub_id, each.res_grp_name, each.src_nic_name, each.dest_nic_name);
+    });
+
+    getInit();
+    function getInit() {
+        $.ajax({
+            url: '/api/v1/cloud/az/nicconfig/',
+            type: 'GET',
+            dataType: 'json',
+            success: function(res) {
+                for (var index in res) {
+                    config.push({
+                        primary_key: index,
+                        sub_id: res[index].subscription_id,
+                        res_grp_name: res[index].res_grp_name,
+                        src_nic_name: res[index].from_nic_name,
+                        dest_nic_name: res[index].to_nic_name
+                    })
+                }
+                updateBlockList(config, show_fields, is_show_field_title);
+            },
+            error: function (xhr, textStatus, errorThrown) {
+                console.log(textStatus + "," + errorThrown + "," + xhr.responseText);
+            }
+        });
+    }
+
+    /**
+     * Return html string for content of pop up window(Add)
+     * @param array setting: array for each setting
+     * @return string
+     */
+    function setContent(setting) {
+        var html = [];
+        for (var ind = 0; ind < setting.length; ++ind) {
+            var each = setting[ind];
+            html.push([
+                '<fieldset>',
+                    '<div class="group_actions"></div>',
+                        '<div class="form-group">',
+                        '<label class="col-md-3 control-label">',
+                            setting[ind].field,
+                        ':</label>',
+                        '<div class="col-md-9">',
+                            '<input type="text" class="field" data-id="' + setting[ind].id,
+                            '" value="' + setting[ind].value + '" />',
+                        '</div>',
+                    '</div>',
+                '</fieldset>'
+            ].join(""));
+        }
+        return html.join("");
+    }
+
+    /**
+     * Update layout for each blocks
+     * @param array setting: array of block information
+     * @param array fields: array of displaying fields, empty is all
+     * @param bool value_only: display value or [field: value] for each list
+     * @return void
+     */
+    function updateBlockList(setting, fields = [], value_only = true) {
+        var html = [];
+        var nameMapping = getNameMapping(); // ex: sub_id: SubId
+        for (var ind = 0; ind < setting.length; ++ind) {
+            var list = [];
+            for (var field in setting[ind]) {
+                if (fields.length !== 0 && fields.indexOf(field) === -1) {
+                    // Not display
+                    continue;
+                }
+                if (field == "primary_key") {
+                    // Not display
+                    continue;
+                }
+                var content = setting[ind][field];
+                if (!value_only) {
+                    var display_name = "";
+                    if (nameMapping.hasOwnProperty(field)) {
+                        display_name = nameMapping[field];
+                    }
+                    content = display_name + ": " + content;
+                }
+                list.push([
+                    '<li data-id="' + field + '">' + content + '</li>'
+                ].join(""));
+            }
+            html.push([
+                '<div class="block">',
+                    '<div class="modal-dialog">',
+                        '<div class="box modal-content">',
+                            '<div class="box-header">',
+                                '<span>' + setting[ind]['primary_key'] + '</span>',
+                                '<button type="button" class="close" aria-label="Close"',
+                                    'data-id="' + setting[ind]['primary_key'] + '">',
+                                    '<span aria-hidden="true">&times;</span></button>',
+                            '</div>',
+                            '<div class="box-body">',
+                                '<ul>',
+                                    list.join(""),
+                                '</ul>',
+                            '</div>',
+                        '</div>',
+                    '</div>',
+                '</div>'
+            ].join(""));
+        }
+        $('#app').html(html.join(""));
+        $('#app .block .box-header button').click(function() {
+            var index = parseInt($(this).data("id"));
+            delNIC(index);
+        });
+    }
+
+    function addNIC(sub_id, res_grp_name, src_nic_name, dest_nic_name) {
+        $.ajax({
+            url: '/api/v1/cloud/az/nicconfig/',
+            type: 'POST',
+            dataType: 'json',
+            data: JSON.stringify({
+                sub_id: sub_id,
+                res_grp_name: res_grp_name,
+                src_nic_name: src_nic_name,
+                dest_nic_name: dest_nic_name
+            }),
+            success: function(res) {
+                $('#addModal').modal('hide');
+                setTimeout(function() {
+                    refreshPage();
+                }, 400);
+            },
+            error: function (xhr, textStatus, errorThrown) {
+                $('#addModal').modal('hide');
+                console.log(textStatus + "," + errorThrown + "," + xhr.responseText);
+            }
+        });
+    }
+
+    function delNIC(index) {
+        $.ajax({
+            url: '/api/v1/cloud/az/nicconfig/',
+            type: 'DELETE',
+            dataType: 'json',
+            data: JSON.stringify({
+                index: index
+            }),
+            success: function(res) {
+                refreshPage();
+            },
+            error: function (xhr, textStatus, errorThrown) {
+                console.log(textStatus + "," + errorThrown + "," + xhr.responseText);
+            }
+        });
+    }
+
+    /**
+     * Get Display name mapping by index
+     * @return object
+     */
+    function getNameMapping() {
+        var mapping = {};
+        for (var ind = 0; ind < modal_fields.length; ++ind) {
+            mapping[modal_fields[ind].id] = modal_fields[ind].field;
+        }
+        return mapping;
+    }
+
+    function refreshPage() {
+        $('.config-nav li.active a').trigger('click');
+    }
+
+});
+
+</script>
+{% endblock box_script %}
Index: /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/templates/network/cloud/azure/udr.html
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/templates/network/cloud/azure/udr.html	(revision 0)
+++ /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/templates/network/cloud/azure/udr.html	(working copy)
@@ -0,0 +1,407 @@
+<form class="form-horizontal main-form">
+<div class="row-fluid">
+    <div class="span12 with-min-width field-group-box">
+        <fieldset>
+            <div class="group_actions"></div>
+            <div class="form-group switch switch_enable">
+                <label class="col-md-3 control-label">{% trans %}Enable{% endtrans %}:</label>
+                <div class="col-md-9">
+                    <input class="switch-small" type="checkbox" name="switch_btn"
+                    data-on-label="{% trans %}Enable{% endtrans %}"
+                    data-off-label="{% trans %}Disabled{% endtrans %}" />
+                    <span class="field-icon-set"></span>
+                </div>
+            </div>
+        </fieldset>
+        <fieldset>
+            <div class="form-group add-btn-style">
+                <div class="col-md-3">
+                    <button type="button" class="btn btn-action add-btn control-label"><i class="fa fa-plus-circle"></i>{% trans %}ADD{% endtrans %}</button>
+                </div>
+                <div class="col-md-9" id="app"></div>
+            </div>
+        </fieldset>
+    </div>
+</div>
+<!-- row-fluid -->
+<div class="btn-static">
+    <div class="btn-switch">
+        <button type="button" class="btn btn-action btn-submit">{% trans %}Save Changes{% endtrans %}</button>
+        <button type="button" class="btn btn-default btn-cancel-action">{% trans %}Cancel{% endtrans %}</button>
+    </div>
+</div>
+<div class="modal fade" id="addModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
+    <div class="modal-dialog">
+        <div class="box modal-content">
+            <div class="box-header">
+                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true"></span></button>
+                    <h2>{{ gettext('New %s')%"UDR" }}</h2>
+                </button>
+            </div>
+            <div class="box-body">
+                <form class="form-horizontal main-form">
+                    <div class="padded">
+                        <div class="row-fluid">
+                            <div class="span12 with-min-width field-group-box modal-fields">
+                            </div>
+                        </div>
+                    </div>
+                    <div class="form-actions col-md-offset-3">
+                        <button type="button" class="btn btn-action btn-save">{% trans %}Submit{% endtrans %}</button>
+                        <button type="button" data-dismiss="modal" class="btn btn-default btn-cancel">{% trans %}Cancel{% endtrans %}</button>
+                    </div>
+                </form>
+            </div>
+        </div>
+    </div>
+</div>
+</form>
+<style type="text/css">
+.add-btn-style {
+    text-align: right;
+}
+.add-btn-style .add-btn {
+    background-color: transparent;
+    border: 0;
+    font-weight: 700;
+}
+.modal-fields {
+    padding-top: 20px;
+}
+.form-actions {
+    padding-bottom: 20px;
+}
+#app {
+    display: flex;
+    flex-direction: row;
+    flex-wrap: wrap;
+}
+#app .block {
+    min-width: 200px;
+    box-sizing: border-box;
+    margin-right: 20px;
+}
+#app .box.modal-content {
+    border-radius: 6px;
+}
+#app .block .modal-dialog {
+    width: 100%;
+    margin: 0;
+}
+#app .box-header {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    padding-right: 10px;
+    padding-left: 10px;
+}
+#app .box-header button.close:active {
+    opacity: 0.2;
+}
+#app .box-body ul {
+    padding: 0;
+    list-style: none;
+}
+#app .box-body ul li {
+    padding: 5px;
+    text-align: left;
+}
+.btn-static {
+    display: none;
+}
+</style>
+</div>
+
+{% block box_script %}
+
+<script type="text/javascript">
+
+$(function(){
+    var enableSwitch = $("input[name='switch_btn']").bootstrapSwitch();
+    var is_init = 0;
+    getEnableStatus();
+    function getEnableStatus() {
+        $.ajax({
+            url: '/api/v1/cloud/az/udrpoller/status/',
+            type: 'GET',
+            dataType: 'json',
+            success: function (res) {
+                if (typeof(res["is_running"]) == "undefined") {
+                    return;
+                }
+                enableSwitch.bootstrapSwitch('setState', res["is_running"]);
+                is_init++;
+            },
+            error: function (xhr, textStatus, errorThrown) {
+                console.log(textStatus + "," + errorThrown + "," + xhr.responseText);
+            }
+        });
+    }
+    enableSwitch.on('switch-change', function(e, data) {
+        if (is_init < 1) {
+            return;
+        }
+        $('#frame_model_main .btn-static').fadeIn("slow");
+        if ($(".btn-static").is(":visible")) {
+            var buttonH = $(".btn-static").offset().top;  
+            $(function(){ 
+                $(window).scroll(function(){ 
+                    var scrollH = $(this).scrollTop();  
+                    if (scrollH >= buttonH) {
+                        $(".btn-switch").addClass("btn-fixed");
+                    }else{  
+                        $(".btn-switch").removeClass("btn-fixed");
+                    } 
+                });
+            });
+        }
+    });
+    $('.btn-cancel-action').click(function(evt) {
+        if(evt.detail && evt.detail != 1) {
+            return;
+        }
+        refreshPage();
+    });
+    $('.btn-submit').click(function(evt) {
+        if(evt.detail && evt.detail != 1) {
+            return;
+        }
+        var enable = enableSwitch.bootstrapSwitch('state'); // true / false
+        $.ajax({
+            url: '/api/v1/cloud/az/udrpoller/',
+            type: 'PUT',
+            dataType: 'json',
+            data: JSON.stringify({
+                status: (enable ? 'on' : 'off')
+            }),
+            success: function (res) {
+                refreshPage();
+            },
+            error: function (xhr, textStatus, errorThrown) {
+                console.log(textStatus + "," + errorThrown + "," + xhr.responseText);
+            }
+        });
+    });
+    var modal_fields = [{
+        field: '{% trans %}Sub ID{% endtrans %}',
+        id: 'sub_id',
+        value: ''
+    }, {
+        field: '{% trans %}Resource Grop Name{% endtrans %}',
+        id: 'res_grp_name',
+        value: ''
+    }, {
+        field: '{% trans %}Monitored VM Name{% endtrans %}',
+        id: 'vm_name',
+        value: ''
+    }, {
+        field: '{% trans %}Target IP When Running{% endtrans %}',
+        id: 'ip_running',
+        value: ''
+    }, {
+        field: '{% trans %}Target IP When Deallocated{% endtrans %}',
+        id: 'ip_deallocated',
+        value: ''
+    }];
+    // for displaying fields in each block
+    var show_fields = []; // for displaying fields in each block
+    is_show_field_title = false;
+
+    $('.add-btn').click(function() {
+        var content = setContent(modal_fields);
+        $('.modal-fields').html(content);
+        $('#addModal').modal();
+    });
+    var config = [];
+    $('.btn-save').click(function(evt) {
+        if(evt.detail && evt.detail != 1) {
+            return;
+        }
+        var each = {};
+        $('.field').each(function() {
+            if ($(this).val() == "") {
+                return;
+            }
+            each[$(this).data('id')] = $(this).val();
+        });
+        if (Object.keys(each).length < 1) {
+            return;
+        }
+        addUDR(each.sub_id, each.res_grp_name, each.vm_name, each.ip_running, each.ip_deallocated);
+    });
+
+    getInit();
+    function getInit() {
+        $.ajax({
+            url: '/api/v1/cloud/az/udrconfig/',
+            type: 'GET',
+            dataType: 'json',
+            success: function(res) {
+                for (var index in res) {
+                    config.push({
+                        primary_key: index,
+                        sub_id: res[index].subscription_id,
+                        res_grp_name: res[index].resource_group_name,
+                        vm_name: res[index].monitored_vm_name,
+                        ip_running: res[index].target_ip_when_running,
+                        ip_deallocated: res[index].target_ip_when_deallocated
+                    })
+                }
+                updateBlockList(config, show_fields, is_show_field_title);
+            },
+            error: function (xhr, textStatus, errorThrown) {
+                console.log(textStatus + "," + errorThrown + "," + xhr.responseText);
+            }
+        });
+    }
+
+    /**
+     * Return html string for content of pop up window(Add)
+     * @param array setting: array for each setting
+     * @return string
+     */
+    function setContent(setting) {
+        var html = [];
+        for (var ind = 0; ind < setting.length; ++ind) {
+            var each = setting[ind];
+            html.push([
+                '<fieldset>',
+                    '<div class="group_actions"></div>',
+                        '<div class="form-group">',
+                        '<label class="col-md-3 control-label">',
+                            setting[ind].field,
+                        ':</label>',
+                        '<div class="col-md-9">',
+                            '<input type="text" class="field" data-id="' + setting[ind].id,
+                            '" value="' + setting[ind].value + '" />',
+                        '</div>',
+                    '</div>',
+                '</fieldset>'
+            ].join(""));
+        }
+        return html.join("");
+    }
+
+    /**
+     * Update layout for each blocks
+     * @param array setting: array of block information
+     * @param array fields: array of displaying fields, empty is all
+     * @param bool value_only: display value or [field: value] for each list
+     * @return void
+     */
+    function updateBlockList(setting, fields = [], value_only = true) {
+        var html = [];
+        var nameMapping = getNameMapping(); // ex: sub_id: SubId
+        for (var ind = 0; ind < setting.length; ++ind) {
+            var list = [];
+            for (var field in setting[ind]) {
+                if (fields.length !== 0 && fields.indexOf(field) === -1) {
+                    // Not display
+                    continue;
+                }
+                if (field == "primary_key") {
+                    // Not display
+                    continue;
+                }
+                var content = setting[ind][field];
+                if (!value_only) {
+                    var display_name = "";
+                    if (nameMapping.hasOwnProperty(field)) {
+                        display_name = nameMapping[field];
+                    }
+                    content = display_name + ": " + content;
+                }
+                list.push([
+                    '<li data-id="' + field + '">' + content + '</li>'
+                ].join(""));
+            }
+            html.push([
+                '<div class="block">',
+                    '<div class="modal-dialog">',
+                        '<div class="box modal-content">',
+                            '<div class="box-header">',
+                                '<span>' + setting[ind]['primary_key'] + '</span>',
+                                '<button type="button" class="close" aria-label="Close"',
+                                    'data-id="' + setting[ind]['primary_key'] + '">',
+                                    '<span aria-hidden="true">&times;</span></button>',
+                            '</div>',
+                            '<div class="box-body">',
+                                '<ul>',
+                                    list.join(""),
+                                '</ul>',
+                            '</div>',
+                        '</div>',
+                    '</div>',
+                '</div>'
+            ].join(""));
+        }
+        $('#app').html(html.join(""));
+        $('#app .block .box-header button').click(function() {
+            var index = parseInt($(this).data("id"));
+            delUDR(index);
+        });
+    }
+
+    function addUDR(sub_id, res_grp_name, vm_name, ip_running, ip_deallocated) {
+        $.ajax({
+            url: '/api/v1/cloud/az/udrconfig/',
+            type: 'POST',
+            dataType: 'json',
+            data: JSON.stringify({
+                sub_id: sub_id,
+                res_grp_name: res_grp_name,
+                vm_name: vm_name,
+                ip_running: ip_running,
+                ip_deallocating: ip_deallocated
+            }),
+            success: function(res) {
+                $('#addModal').modal('hide');
+                setTimeout(function() {
+                    refreshPage();
+                }, 400);
+            },
+            error: function (xhr, textStatus, errorThrown) {
+                $('#addModal').modal('hide');
+                console.log(textStatus + "," + errorThrown + "," + xhr.responseText);
+            }
+        });
+    }
+
+    function delUDR(index) {
+        $.ajax({
+            url: '/api/v1/cloud/az/udrconfig/',
+            type: 'DELETE',
+            dataType: 'json',
+            data: JSON.stringify({
+                index: index
+            }),
+            success: function(res) {
+                refreshPage();
+            },
+            error: function (xhr, textStatus, errorThrown) {
+                console.log(textStatus + "," + errorThrown + "," + xhr.responseText);
+            }
+        });
+    }
+
+    /**
+     * Get Display name mapping by index
+     * @return object
+     */
+    function getNameMapping() {
+        var mapping = {};
+        for (var ind = 0; ind < modal_fields.length; ++ind) {
+            mapping[modal_fields[ind].id] = modal_fields[ind].field;
+        }
+        return mapping;
+    }
+
+    function refreshPage() {
+        $('.config-nav li.active a').trigger('click');
+    }
+
+});
+
+</script>
+{% endblock box_script %}
Index: /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/tree.py
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/tree.py	(revision 39037)
+++ /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/tree.py	(working copy)
@@ -39,6 +39,9 @@
         ('report', {'cls':MenuNode, 'verbose_name':_('Statistics Report'),'sub_nodes':D([
             ('report', {'cls':ModuleNode, 'default_action':'monitor', 'package':''}),
         ])}),
+        ('prometheus', {'cls':MenuNode, 'verbose_name':_('Prometheus Metrix'),'sub_nodes':D([
+            ('index', {'cls':ModuleNode, 'default_action':'index', 'package':''}),
+        ])}),
     ])}),
 
     ('slb', {'cls':ModuleNode, 'verbose_name':_('SLB'), 'icon':'fa-sitemap', 'package':'loadbalancing.slb', 'sub_nodes':D([
@@ -264,6 +267,10 @@
             ('dnsnat46', {'cls':ModelNode, 'model':'network.ipv6.DNSNAT46Settings'}),
             ('ipv6', {'cls':ModelNode, 'model':'network.ipv6.IPv6Tune'}),
         ])}),
+        ('cloud', {'cls':MenuNode, 'verbose_name':_('Cloud'),'sub_nodes':D([
+            ('azure', {'cls':ModuleNode, 'default_action':'index', 'package':''}),
+            ('aws', {'cls':ModuleNode, 'default_action':'index', 'package':''}),
+        ])}),
         ('route', {'cls':MenuNode, 'verbose_name':_('Routing'), 'icon':'fa-code-fork', 'sub_nodes':D([
             ('basic', {'cls':MenuNode, 'verbose_name':_('Basic Routing'),'sub_nodes':D([
                 ('default', {'cls':ModelNode, 'model':'routing.static.DefaultRoutingSetting'}),
@@ -459,9 +466,6 @@
             ('synchronization', {'cls':ModelNode, 'model':'ha.synconfig.SynconfigGeneralSettings'}),
             ('IncrementalSynconfig', {'cls':ModelNode, 'model':'ha.synconfig.IncrementalSynconfig'}),
         ])}),
-        ('cloud', {'cls':MenuNode, 'verbose_name':_('Cloud'),'sub_nodes':D([
-            ('aws', {'cls':ModuleNode, 'default_action':'index', 'package':''}),
-        ])}),
     ])}),
             
     ('ajax', {'cls':MenuNode, 'hidden':True, 'sub_nodes':D([
Index: /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/urls.py
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/urls.py	(revision 39037)
+++ /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/urls.py	(working copy)
@@ -49,4 +49,5 @@
     url(r'^%s/get_sslo_status$' % PRODUCT_KEYWORD, get_sslo_status),
     url(r'^%s/prometheus/Log/download' % PRODUCT_KEYWORD, prometheus_log_download),
     url(r'^%s/get_cloud_page$' % PRODUCT_KEYWORD, get_cloud_page),
+    url(r'^%s/get_prometheus_page$' % PRODUCT_KEYWORD, get_prometheus_page),
 )
Index: /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/hive/cloud/aws/__init__.py	(added)
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/hive/cloud/aws/__init__.py	(revision 0)
+++ /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/hive/cloud/aws/__init__.py	(revision 0)
Index: /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/hive/cloud/aws/aws_basic_view.py
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/hive/cloud/aws/aws_basic_view.py	(revision 0)
+++ /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/hive/cloud/aws/aws_basic_view.py	(working copy)
@@ -0,0 +1,129 @@
+import json
+import subprocess
+from django.http import HttpResponse
+from hive.utils import aninfo, anerror
+
+
+def get_aws_credential(request):
+    '''
+    Get the AWS credential stored on vAPV.
+
+    Returns:
+        HttpResponse: A response with the AWS credential details or an error message.
+    '''
+    command = "python3 /ca/bin/aws/AWSAuthManager.py -mode show"
+    res = subprocess.Popen(
+        command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE
+    )
+    stdout, stderr = res.communicate()
+
+    if res.returncode != 0:
+        anerror("hive.debug", stderr)
+        return HttpResponse(
+            json.dumps({"message": "error while running aws tools"}),
+            content_type="application/json",
+            status=500
+        )
+    try:
+        credential = json.loads(stdout.decode().replace("'", '"'))
+        return HttpResponse(
+            json.dumps(credential),
+            content_type="application/json",
+            status=200
+        )
+    except json.JSONDecodeError as e:
+        anerror("hive.debug", "Fail to decode enconfig to json:{}".format(e))
+        return HttpResponse(
+            json.dumps({}),
+            content_type="application/json",
+            status=500
+        )
+    except UnicodeDecodeError as e:
+        anerror("hive.debug", "Fail to decode stdout:{}".format(e))
+        return HttpResponse(
+            json.dumps({}),
+            content_type="application/json",
+            status=500
+        )
+
+
+def delete_aws_credential(request):
+    '''
+    Delete the AWS credential stored on vAPV
+
+    Returns:
+        HttpResponse: A response indicating the success or failure of
+                      the authentication process.
+    '''
+    command = "python3 /ca/bin/aws/AWSAuthManager.py -mode logout"
+    res = subprocess.Popen(
+        command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE
+    )
+    stdout, stderr = res.communicate()
+
+    if res.returncode != 0:
+        anerror("hive.debug", stderr)
+        return HttpResponse(
+            json.dumps({"message": "error while running aws tools"}),
+            content_type="application/json",
+            status=500
+        )
+
+    response_data = {
+        "msg": "Succeed"
+    }
+    aninfo("hive.debug", "Succeed to delete aws credential")
+    return HttpResponse(
+        json.dumps(response_data),
+        content_type="application/json",
+        status=200
+    )
+
+
+def post_aws_credential(request):
+    '''
+    Authenticate AWS credentials to vAPV.
+
+    Returns:
+        HttpResponse: A response indicating the success or failure of
+                      the authentication process.
+    '''
+    # verify user input
+    required_keys = ["aws_access_key_id", "aws_secret_access_key", "region"]
+    data = json.loads(request.body)
+    for key in required_keys:
+        if key not in data:
+            return HttpResponse(
+                json.dumps({"message": "body should contain key: "
+                                       "{}".format(', '.join(required_keys))}),
+                content_type="application/json",
+                status=400
+            )
+
+    command = (
+        "python3 /ca/bin/aws/AWSAuthManager.py -mode login "
+        "-access_key {} -secret_access_key {} -region {}"
+    ).format(data["aws_access_key_id"], data["aws_secret_access_key"], data["region"])
+    res = subprocess.Popen(
+        command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE
+    )
+    stdout, stderr = res.communicate()
+
+    if res.returncode != 0:
+        anerror("hive.debug", stderr)
+        return HttpResponse(
+            json.dumps({"message": "error while running aws tools"}),
+            content_type="application/json",
+            status=500
+        )
+
+    response_data = {
+        "msg": "Succeed"
+    }
+    aninfo("hive.debug", "Succeed to authenticate aws credential")
+
+    return HttpResponse(
+        json.dumps(response_data),
+        content_type="application/json",
+        status=200
+    )
\ No newline at end of file
Index: /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/hive/cloud/aws/aws_eni_view.py
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/hive/cloud/aws/aws_eni_view.py	(revision 0)
+++ /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/hive/cloud/aws/aws_eni_view.py	(working copy)
@@ -0,0 +1,208 @@
+import json
+import subprocess
+import shlex
+from django.http import HttpResponse
+from hive.utils import aninfo, anerror
+
+
+def validate_input(data, required_keys):
+    """Validates if the required keys are present in the input data."""
+    missing_keys = [key for key in required_keys if key not in data]
+    if missing_keys:
+        return False, "Body should contain key: {}".format(', '.join(missing_keys))
+    return True, ""
+
+
+def create_json_response(data, status_code):
+    """Creates a JSON response with the given data and status code."""
+    return HttpResponse(
+        json.dumps(data),
+        content_type="application/json",
+        status=status_code
+    )
+
+
+def run_command(command):
+    """Executes a command and returns the result or raises an error."""
+    try:
+        res = subprocess.Popen(
+            command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE
+        )
+        stdout, stderr = res.communicate()
+
+        if res.returncode != 0:
+            anerror("hive.debug", stderr)
+            raise RuntimeError("Error while running AWS tools.")
+        return stdout.decode()
+
+    except subprocess.SubprocessError as e:
+        anerror("hive.debug", str(e))
+        raise RuntimeError("Subprocess execution failed.")
+
+
+def post_eniconfig(request):
+    """
+    Add the eni configuration of AWS to vAPV.
+
+    Returns:
+        HttpResponse: A response indicating the success or failure of
+                      the eni configuration process.
+    """
+    required_keys = ["src_eni_id", "dest_eni_id"]
+    data = json.loads(request.body)
+    is_valid, message = validate_input(data, required_keys)
+    if not is_valid:
+        return create_json_response({"message": message}, 400)
+
+    command = (
+        "python3 /ca/bin/aws/AWSConfigManager.py -ENI set "
+        "-src_eni_id {} -dest_eni_id {}".format(
+            data["src_eni_id"], data["dest_eni_id"]
+        )
+    )
+    try:
+        run_command(command)
+        aninfo("hive.debug", "Succeeded to add eni configuration")
+        return create_json_response({"msg": "Succeed"}, 200)
+    except RuntimeError:
+        return create_json_response({"message": "error while running aws tools"}, 500)
+
+
+def get_eniconfig(request):
+    """
+    Get the eni configuration of AWS from vAPV.
+
+    Returns:
+        HttpResponse: A response with the eni configuration
+                      details or an error message.
+    """
+    command = "python3 /ca/bin/aws/AWSConfigManager.py -ENI show"
+    try:
+        output = run_command(command)
+        enconfig = json.loads(output.replace("'", '"'))
+        return create_json_response(enconfig, 200)
+    except (RuntimeError, json.JSONDecodeError, UnicodeDecodeError) as e:
+        anerror("hive.debug", "Error decoding or running command: {}".format(str(e)))
+        return create_json_response({}, 500)
+
+
+def delete_eniconfig(request):
+    """
+    Delete the eni configuration of AWS from vAPV.
+
+    Returns:
+        HttpResponse: A response indicating the success or failure of
+                      the eni configuration process.
+    """
+    required_keys = ["index"]
+    data = json.loads(request.body)
+
+    # Validate input
+    is_valid, message = validate_input(data, required_keys)
+    if not is_valid:
+        return create_json_response({"message": message}, 400)
+
+    command = (
+        "python3 /ca/bin/aws/AWSConfigManager.py -ENI remove -index "
+        "{}".format(data["index"])
+    )
+    try:
+        run_command(command)
+        aninfo("hive.debug", "Succeeded to delete aws eni configuration")
+        return create_json_response({"msg": "Succeed"}, 200)
+    except RuntimeError:
+        return create_json_response({"message": "error while running aws tools"}, 500)
+
+
+def post_failover(request):
+    """
+    Manually trigger IP swifting while failover happening.
+
+    Returns:
+        HttpResponse: A response indicating the success or failure of
+                      the eni configuration process.
+    """
+    command = "python3 /ca/bin/aws/AWSENIManager.py -mode trigger"
+    try:
+        run_command(command)
+        aninfo("hive.debug", "Succeeded to trigger IP transfering.")
+        return create_json_response({"msg": "Succeed"}, 200)
+    except RuntimeError:
+        return create_json_response({"message": "error while running aws tools."}, 500)
+
+
+def post_recover(request):
+    """
+    Manually trigger IP swifting while recover happening.
+
+    Returns:
+        HttpResponse: A response indicating the success or failure of
+                      the eni configuration process.
+    """
+    command = "python3 /ca/bin/aws/AWSENIManager.py -mode recover"
+    try:
+        run_command(command)
+        aninfo("hive.debug", "Succeeded to trigger IP transfering.")
+        return create_json_response({"msg": "Succeed"}, 200)
+    except RuntimeError:
+        return create_json_response({"message": "error while running aws tools"}, 500)
+
+
+def get_ha_status(request):
+    """
+    Get the HA polling status of AWS from vAPV.
+
+    Returns:
+        HttpResponse: A response with the HA status details
+                      or an error message.
+    """
+    # the output of the command is either "True\n" or "False\n"
+    output_map = {
+        "True\n": 1,
+        "False\n": 0
+    }
+    command = "python3 /ca/bin/aws/AWSFailoverPoller.py -mode status"
+    try:
+        output = run_command(command)
+        aninfo("hive.debug", "Succeeded to get ha poller status.")
+        return create_json_response({"status": output_map[output]}, 200)
+    except RuntimeError:
+        return create_json_response({"message": "error while running aws tools."}, 500)
+
+
+def post_ha_status(request):
+    """
+    Enable or disable the HA polling of AWS from vAPV.
+
+    Returns:
+        HttpResponse: A response indicating the success or failure of
+                      the HA status process.
+    """
+    input_map = {
+        1: "enable",
+        0: "disable"
+    }
+    required_keys = ["status"]
+    data = json.loads(request.body)
+
+    # Validate input
+    is_valid, message = validate_input(data, required_keys)
+    if not is_valid:
+        return create_json_response({"message": message}, 400)
+    if data["status"] not in [0, 1]:
+        return create_json_response({"message": "status should be number 0 or 1"}, 400)
+
+    command = (
+        "python3 /ca/bin/aws/AWSFailoverPoller.py -mode "
+        "{}".format(input_map[data["status"]])
+    )
+    aninfo("hive.debug", "command")
+
+    try:
+        # Start the command in the background. That is why we use Popen instead of call.
+        args = shlex.split(command)
+        subprocess.Popen(args)
+        aninfo("hive.debug", "Succeeded to set ha poller status: {}".format(input_map[data["status"]]))
+        return create_json_response({"msg": "Succeed"}, 200)
+    except RuntimeError:
+        return create_json_response({"message": "error while running aws tools."}, 500)
Index: /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/hive/cloud/aws/aws_log_view.py
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/hive/cloud/aws/aws_log_view.py	(revision 0)
+++ /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/hive/cloud/aws/aws_log_view.py	(working copy)
@@ -0,0 +1,190 @@
+import json
+import os
+import subprocess
+from django.http import HttpResponse
+from hive.utils import aninfo, anerror
+
+
+def validate_input(data, required_keys):
+    """Validates if the required keys are present in the input data."""
+    missing_keys = [key for key in required_keys if key not in data]
+    if missing_keys:
+        return False, "Body should contain key: {}".format(', '.join(missing_keys))
+    return True, ""
+
+
+def create_json_response(data, status_code):
+    """Creates a JSON response with the given data and status code."""
+    return HttpResponse(
+        json.dumps(data),
+        content_type="application/json",
+        status=status_code
+    )
+
+
+def run_command(command):
+    """Executes a command and returns the result or raises an error."""
+    try:
+        res = subprocess.Popen(
+            command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE
+        )
+        stdout, stderr = res.communicate()
+        if res.returncode != 0:
+            anerror("hive.debug", stderr)
+            raise RuntimeError("Error while running AWS tools.")
+        return stdout.decode()
+
+    except subprocess.SubprocessError as e:
+        anerror("hive.debug", str(e))
+        raise RuntimeError("Subprocess execution failed.")
+
+
+def get_log_buffer(request):
+    """
+    Get the log file content of aws tool from vAPV.
+
+    Returns:
+        HttpResponse: A response containing the log buffer.
+    """
+    command = "python3 /ca/bin/aws/LoggerManager.py -mode show"
+    try:
+        log_buffer = run_command(command)
+        return create_json_response({"msg": log_buffer}, 200)
+    except RuntimeError as e:
+        anerror("hive.debug", str(e))
+        return create_json_response(
+            {"msg": "Error while getting log buffer"}, 500)
+
+
+def get_switcher(request):
+    """
+    Get the status of log functionality aws tool from vAPV.
+
+    Returns:
+        HttpResponse: A response containing the switcher status{}.
+    """
+    # the output of the command is either "True\n" or "False\n"
+    output_map = {
+        "True\n": 1,
+        "False\n": 0
+    }
+    command = "python3 /ca/bin/aws/LoggerManager.py -mode status"
+    try:
+        switcher = run_command(command)
+        return create_json_response({"status": output_map[switcher]}, 200)
+    except RuntimeError as e:
+        anerror("hive.debug", str(e))
+        return create_json_response(
+            {"msg": "Error while getting switcher status"}, 500)
+
+
+def post_switcher(request):
+    """
+    Turn on or off the status of log functionality aws tool on vAPV.
+
+    Returns:
+        HttpResponse: A response indicating the success or failure of
+    """
+    input_map = {
+        1: "on",
+        0: "off"
+    }
+    required_keys = ["status"]
+    data = json.loads(request.body)
+
+    # Validate input
+    is_valid, message = validate_input(data, required_keys)
+    if not is_valid:
+        return create_json_response({"msg": message}, 400)
+    if data["status"] not in [0, 1]:
+        return create_json_response({"msg": "status should be number 0 or 1"}, 400)
+
+    command = ("python3 /ca/bin/aws/LoggerManager.py -mode "
+               "{}".format(input_map[data["status"]]))
+
+    try:
+        output = run_command(command)
+        aninfo("hive.debug", "Succeeded to set log functionality: "
+               "{}".format(data["status"]))
+        return create_json_response({"msg": "Succeed"}, 200)
+    except RuntimeError:
+        return create_json_response({"msg": "error while running aws tools."}, 500)
+
+
+def get_log_severity(request):
+    """
+    Get the severity level of log functionality of aws tool from vAPV.
+
+    Returns:
+        HttpResponse: A response containing the severity level.
+    """
+    command = "python3 /ca/bin/aws/LoggerManager.py -level status"
+    try:
+        severity = run_command(command)
+        aninfo("hive.debug", "Succeeded to get log severity.")
+        return create_json_response({"severity": severity.replace("\n", "")}, 200)
+    except RuntimeError as e:
+        anerror("hive.debug", str(e))
+        return create_json_response(
+            {"msg": "Error while getting severity level"}, 500)
+
+
+def post_log_severity(request):
+    """
+    Set the severity level of log functionality of aws tool on vAPV.
+
+    Returns:
+        HttpResponse: A response indicating the success or failure of
+                      the severity level setting process.
+    """
+    required_keys = ["severity"]
+    data = json.loads(request.body)
+
+    # Validate input
+    is_valid, message = validate_input(data, required_keys)
+    if not is_valid:
+        return create_json_response({"msg": message}, 400)
+
+    if data["severity"] not in ["debug", "info", "warning", "error"]:
+        return create_json_response(
+            {"msg": "severity should be one of debug, info, warning, error"}, 400)
+
+    command = ("python3 /ca/bin/aws/LoggerManager.py -level "
+               "{}".format(data["severity"]))
+    try:
+        output = run_command(command)
+        aninfo("hive.debug", "Succeeded to set log severity: "
+               "{}".format(data["severity"]))
+        return create_json_response({"msg": "Succeed"}, 200)
+    except RuntimeError as e:
+        aninfo("hive.debug", str(e))
+        return create_json_response({"msg": "error while running aws tools."}, 501)
+
+
+def download_log_file(request):
+    """
+    Get the log file of aws tool from vAPV.
+
+    Returns:
+        HttpResponse: A response containing the log file.
+    """
+    command = "python3 /ca/bin/aws/LoggerManager.py -mode getlogpath"
+    try:
+        log_file_path = run_command(command)
+        log_file_path = log_file_path.replace("\n", "")
+
+        if not os.path.exists(log_file_path):
+            return HttpResponse(
+                json.dumps({"msg": "No log file found"}),
+                content_type="application/json",
+                status=200
+            )
+        with open(log_file_path, 'rb') as file:
+            response = HttpResponse(file.read(), content_type='text/plain')
+            response['Content-Disposition'] = 'attachment; filename="{}"'.format("aws_tool.log")
+            response['Content-Length'] = os.path.getsize(log_file_path)
+            return response
+    except RuntimeError as e:
+        anerror("hive.debug", str(e))
+        return create_json_response(
+            {"msg": "Error while getting log file"}, 500)
\ No newline at end of file
Index: /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/hive/cloud/aws/urls.py
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/hive/cloud/aws/urls.py	(revision 0)
+++ /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/hive/cloud/aws/urls.py	(working copy)
@@ -0,0 +1,119 @@
+import json
+
+from django.http import HttpResponse
+from django.conf.urls import patterns, url
+
+from hive.cloud.aws.aws_basic_view import (
+    post_aws_credential,
+    get_aws_credential,
+    delete_aws_credential
+)
+from hive.cloud.aws.aws_eni_view import (
+    get_eniconfig,
+    post_eniconfig,
+    delete_eniconfig,
+    post_failover,
+    post_recover,
+    get_ha_status,
+    post_ha_status
+)
+from hive.cloud.aws.aws_log_view import (
+    get_log_buffer,
+    get_switcher,
+    post_switcher,
+    get_log_severity as get_aws_log_severity,
+    post_log_severity,
+    download_log_file as download_aws_log_file
+)
+
+
+def get_bad_http_method():
+    return HttpResponse(
+        json.dumps({"message": "Bad http method"}),
+        content_type="application/json",
+        status=400
+    )
+
+
+# aws router start
+def aws_credential_method_router(request):
+    if request.method == "GET":
+        return get_aws_credential(request)
+    elif request.method == "POST":
+        return post_aws_credential(request)
+    elif request.method == "DELETE":
+        return delete_aws_credential(request)
+    return get_bad_http_method()
+
+
+def aws_eniconfig_method_router(request):
+    if request.method == "GET":
+        return get_eniconfig(request)
+    elif request.method == "POST":
+        return post_eniconfig(request)
+    elif request.method == "DELETE":
+        return delete_eniconfig(request)
+    return get_bad_http_method()
+
+
+def aws_failover_method_router(request):
+    if request.method == "PUT":
+        return post_failover(request)
+    return get_bad_http_method()
+
+
+def aws_recover_method_router(request):
+    if request.method == "PUT":
+        return post_recover(request)
+    return get_bad_http_method()
+
+
+def aws_ha_status_method_router(request):
+    if request.method == "POST":
+        return post_ha_status(request)
+    elif request.method == "GET":
+        return get_ha_status(request)
+    return get_bad_http_method()
+
+
+def aws_log_buffer_method_router(request):
+    if request.method == "GET":
+        return get_log_buffer(request)
+    return get_bad_http_method()
+
+
+def aws_switcher_method_router(request):
+    if request.method == "GET":
+        return get_switcher(request)
+    elif request.method == "PUT":
+        return post_switcher(request)
+    return get_bad_http_method()
+
+
+def aws_log_severity_method_router(request):
+    if request.method == "GET":
+        return get_aws_log_severity(request)
+    elif request.method == "PUT":
+        return post_log_severity(request)
+    return get_bad_http_method()
+
+
+def aws_log_file_method_router(request):
+    if request.method == "GET":
+        return download_aws_log_file(request)
+    return get_bad_http_method()
+# aws router end
+
+
+urlpatterns = patterns(
+    '',
+    url(r'^credential/$', aws_credential_method_router),
+    url(r'^eniconfig/$', aws_eniconfig_method_router),
+    url(r'^failover/$', aws_failover_method_router),
+    url(r'^recover/$', aws_recover_method_router),
+    url(r'^ha/status/$', aws_ha_status_method_router),
+    url(r'^log/buffer/$', aws_log_buffer_method_router),
+    url(r'^log/status/$', aws_switcher_method_router),
+    url(r'^log/severity/$', aws_log_severity_method_router),
+    url(r'^log/file/$', aws_log_file_method_router),
+)
\ No newline at end of file
Index: /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/hive/cloud/aws_basic_view.py
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/hive/cloud/aws_basic_view.py	(revision 39037)
+++ /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/hive/cloud/aws_basic_view.py	(working copy)
@@ -1,129 +0,0 @@
-import json
-import subprocess
-from django.http import HttpResponse
-from hive.utils import aninfo, anerror
-
-
-def get_aws_credential(request):
-    '''
-    Get the AWS credential stored on vAPV.
-
-    Returns:
-        HttpResponse: A response with the AWS credential details or an error message.
-    '''
-    command = "python3 /ca/bin/aws/AWSAuthManager.py -mode show"
-    res = subprocess.Popen(
-        command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE
-    )
-    stdout, stderr = res.communicate()
-
-    if res.returncode != 0:
-        anerror("hive.debug", stderr)
-        return HttpResponse(
-            json.dumps({"message": "error while running aws tools"}),
-            content_type="application/json",
-            status=500
-        )
-    try:
-        credential = json.loads(stdout.decode().replace("'", '"'))
-        return HttpResponse(
-            json.dumps(credential),
-            content_type="application/json",
-            status=200
-        )
-    except json.JSONDecodeError as e:
-        anerror("hive.debug", "Fail to decode enconfig to json:{}".format(e))
-        return HttpResponse(
-            json.dumps({}),
-            content_type="application/json",
-            status=500
-        )
-    except UnicodeDecodeError as e:
-        anerror("hive.debug", "Fail to decode stdout:{}".format(e))
-        return HttpResponse(
-            json.dumps({}),
-            content_type="application/json",
-            status=500
-        )
-
-
-def delete_aws_credential(request):
-    '''
-    Delete the AWS credential stored on vAPV
-
-    Returns:
-        HttpResponse: A response indicating the success or failure of
-                      the authentication process.
-    '''
-    command = "python3 /ca/bin/aws/AWSAuthManager.py -mode logout"
-    res = subprocess.Popen(
-        command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE
-    )
-    stdout, stderr = res.communicate()
-
-    if res.returncode != 0:
-        anerror("hive.debug", stderr)
-        return HttpResponse(
-            json.dumps({"message": "error while running aws tools"}),
-            content_type="application/json",
-            status=500
-        )
-
-    response_data = {
-        "msg": "Succeed"
-    }
-    aninfo("hive.debug", "Succeed to delete aws credential")
-    return HttpResponse(
-        json.dumps(response_data),
-        content_type="application/json",
-        status=200
-    )
-
-
-def post_aws_credential(request):
-    '''
-    Authenticate AWS credentials to vAPV.
-
-    Returns:
-        HttpResponse: A response indicating the success or failure of
-                      the authentication process.
-    '''
-    # verify user input
-    required_keys = ["aws_access_key_id", "aws_secret_access_key", "region"]
-    data = json.loads(request.body)
-    for key in required_keys:
-        if key not in data:
-            return HttpResponse(
-                json.dumps({"message": "body should contain key: "
-                                       "{}".format(', '.join(required_keys))}),
-                content_type="application/json",
-                status=400
-            )
-
-    command = (
-        "python3 /ca/bin/aws/AWSAuthManager.py -mode login "
-        "-access_key {} -secret_access_key {} -region {}"
-    ).format(data["aws_access_key_id"], data["aws_secret_access_key"], data["region"])
-    res = subprocess.Popen(
-        command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE
-    )
-    stdout, stderr = res.communicate()
-
-    if res.returncode != 0:
-        anerror("hive.debug", stderr)
-        return HttpResponse(
-            json.dumps({"message": "error while running aws tools"}),
-            content_type="application/json",
-            status=500
-        )
-
-    response_data = {
-        "msg": "Succeed"
-    }
-    aninfo("hive.debug", "Succeed to authenticate aws credential")
-
-    return HttpResponse(
-        json.dumps(response_data),
-        content_type="application/json",
-        status=200
-    )
\ No newline at end of file
Index: /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/hive/cloud/aws_eni_view.py
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/hive/cloud/aws_eni_view.py	(revision 39037)
+++ /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/hive/cloud/aws_eni_view.py	(working copy)
@@ -1,208 +0,0 @@
-import json
-import subprocess
-import shlex
-from django.http import HttpResponse
-from hive.utils import aninfo, anerror
-
-
-def validate_input(data, required_keys):
-    """Validates if the required keys are present in the input data."""
-    missing_keys = [key for key in required_keys if key not in data]
-    if missing_keys:
-        return False, "Body should contain key: {}".format(', '.join(missing_keys))
-    return True, ""
-
-
-def create_json_response(data, status_code):
-    """Creates a JSON response with the given data and status code."""
-    return HttpResponse(
-        json.dumps(data),
-        content_type="application/json",
-        status=status_code
-    )
-
-
-def run_command(command):
-    """Executes a command and returns the result or raises an error."""
-    try:
-        res = subprocess.Popen(
-            command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE
-        )
-        stdout, stderr = res.communicate()
-
-        if res.returncode != 0:
-            anerror("hive.debug", stderr)
-            raise RuntimeError("Error while running AWS tools.")
-        return stdout.decode()
-
-    except subprocess.SubprocessError as e:
-        anerror("hive.debug", str(e))
-        raise RuntimeError("Subprocess execution failed.")
-
-
-def post_eniconfig(request):
-    """
-    Add the eni configuration of AWS to vAPV.
-
-    Returns:
-        HttpResponse: A response indicating the success or failure of
-                      the eni configuration process.
-    """
-    required_keys = ["src_eni_id", "dest_eni_id"]
-    data = json.loads(request.body)
-    is_valid, message = validate_input(data, required_keys)
-    if not is_valid:
-        return create_json_response({"message": message}, 400)
-
-    command = (
-        "python3 /ca/bin/aws/AWSConfigManager.py -ENI set "
-        "-src_eni_id {} -dest_eni_id {}".format(
-            data["src_eni_id"], data["dest_eni_id"]
-        )
-    )
-    try:
-        run_command(command)
-        aninfo("hive.debug", "Succeeded to add eni configuration")
-        return create_json_response({"msg": "Succeed"}, 200)
-    except RuntimeError:
-        return create_json_response({"message": "error while running aws tools"}, 500)
-
-
-def get_eniconfig(request):
-    """
-    Get the eni configuration of AWS from vAPV.
-
-    Returns:
-        HttpResponse: A response with the eni configuration
-                      details or an error message.
-    """
-    command = "python3 /ca/bin/aws/AWSConfigManager.py -ENI show"
-    try:
-        output = run_command(command)
-        enconfig = json.loads(output.replace("'", '"'))
-        return create_json_response(enconfig, 200)
-    except (RuntimeError, json.JSONDecodeError, UnicodeDecodeError) as e:
-        anerror("hive.debug", "Error decoding or running command: {}".format(str(e)))
-        return create_json_response({}, 500)
-
-
-def delete_eniconfig(request):
-    """
-    Delete the eni configuration of AWS from vAPV.
-
-    Returns:
-        HttpResponse: A response indicating the success or failure of
-                      the eni configuration process.
-    """
-    required_keys = ["index"]
-    data = json.loads(request.body)
-
-    # Validate input
-    is_valid, message = validate_input(data, required_keys)
-    if not is_valid:
-        return create_json_response({"message": message}, 400)
-
-    command = (
-        "python3 /ca/bin/aws/AWSConfigManager.py -ENI remove -index "
-        "{}".format(data["index"])
-    )
-    try:
-        run_command(command)
-        aninfo("hive.debug", "Succeeded to delete aws eni configuration")
-        return create_json_response({"msg": "Succeed"}, 200)
-    except RuntimeError:
-        return create_json_response({"message": "error while running aws tools"}, 500)
-
-
-def post_failover(request):
-    """
-    Manually trigger IP swifting while failover happening.
-
-    Returns:
-        HttpResponse: A response indicating the success or failure of
-                      the eni configuration process.
-    """
-    command = "python3 /ca/bin/aws/AWSENIManager.py -mode trigger"
-    try:
-        run_command(command)
-        aninfo("hive.debug", "Succeeded to trigger IP transfering.")
-        return create_json_response({"msg": "Succeed"}, 200)
-    except RuntimeError:
-        return create_json_response({"message": "error while running aws tools."}, 500)
-
-
-def post_recover(request):
-    """
-    Manually trigger IP swifting while recover happening.
-
-    Returns:
-        HttpResponse: A response indicating the success or failure of
-                      the eni configuration process.
-    """
-    command = "python3 /ca/bin/aws/AWSENIManager.py -mode recover"
-    try:
-        run_command(command)
-        aninfo("hive.debug", "Succeeded to trigger IP transfering.")
-        return create_json_response({"msg": "Succeed"}, 200)
-    except RuntimeError:
-        return create_json_response({"message": "error while running aws tools"}, 500)
-
-
-def get_ha_status(request):
-    """
-    Get the HA polling status of AWS from vAPV.
-
-    Returns:
-        HttpResponse: A response with the HA status details
-                      or an error message.
-    """
-    # the output of the command is either "True\n" or "False\n"
-    output_map = {
-        "True\n": 1,
-        "False\n": 0
-    }
-    command = "python3 /ca/bin/aws/AWSFailoverPoller.py -mode status"
-    try:
-        output = run_command(command)
-        aninfo("hive.debug", "Succeeded to get ha poller status.")
-        return create_json_response({"status": output_map[output]}, 200)
-    except RuntimeError:
-        return create_json_response({"message": "error while running aws tools."}, 500)
-
-
-def post_ha_status(request):
-    """
-    Enable or disable the HA polling of AWS from vAPV.
-
-    Returns:
-        HttpResponse: A response indicating the success or failure of
-                      the HA status process.
-    """
-    input_map = {
-        1: "enable",
-        0: "disable"
-    }
-    required_keys = ["status"]
-    data = json.loads(request.body)
-
-    # Validate input
-    is_valid, message = validate_input(data, required_keys)
-    if not is_valid:
-        return create_json_response({"message": message}, 400)
-    if data["status"] not in [0, 1]:
-        return create_json_response({"message": "status should be number 0 or 1"}, 400)
-
-    command = (
-        "python3 /ca/bin/aws/AWSFailoverPoller.py -mode "
-        "{}".format(input_map[data["status"]])
-    )
-    aninfo("hive.debug", "command")
-
-    try:
-        # Start the command in the background. That is why we use Popen instead of call.
-        args = shlex.split(command)
-        subprocess.Popen(args)
-        aninfo("hive.debug", "Succeeded to set ha poller status: {}".format(input_map[data["status"]]))
-        return create_json_response({"msg": "Succeed"}, 200)
-    except RuntimeError:
-        return create_json_response({"message": "error while running aws tools."}, 500)
Index: /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/hive/cloud/aws_log_view.py
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/hive/cloud/aws_log_view.py	(revision 39037)
+++ /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/hive/cloud/aws_log_view.py	(working copy)
@@ -1,190 +0,0 @@
-import json
-import os
-import subprocess
-from django.http import HttpResponse
-from hive.utils import aninfo, anerror
-
-
-def validate_input(data, required_keys):
-    """Validates if the required keys are present in the input data."""
-    missing_keys = [key for key in required_keys if key not in data]
-    if missing_keys:
-        return False, "Body should contain key: {}".format(', '.join(missing_keys))
-    return True, ""
-
-
-def create_json_response(data, status_code):
-    """Creates a JSON response with the given data and status code."""
-    return HttpResponse(
-        json.dumps(data),
-        content_type="application/json",
-        status=status_code
-    )
-
-
-def run_command(command):
-    """Executes a command and returns the result or raises an error."""
-    try:
-        res = subprocess.Popen(
-            command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE
-        )
-        stdout, stderr = res.communicate()
-        if res.returncode != 0:
-            anerror("hive.debug", stderr)
-            raise RuntimeError("Error while running AWS tools.")
-        return stdout.decode()
-
-    except subprocess.SubprocessError as e:
-        anerror("hive.debug", str(e))
-        raise RuntimeError("Subprocess execution failed.")
-
-
-def get_log_buffer(request):
-    """
-    Get the log file content of aws tool from vAPV.
-
-    Returns:
-        HttpResponse: A response containing the log buffer.
-    """
-    command = "python3 /ca/bin/aws/LoggerManager.py -mode show"
-    try:
-        log_buffer = run_command(command)
-        return create_json_response({"msg": log_buffer}, 200)
-    except RuntimeError as e:
-        anerror("hive.debug", str(e))
-        return create_json_response(
-            {"msg": "Error while getting log buffer"}, 500)
-
-
-def get_switcher(request):
-    """
-    Get the status of log functionality aws tool from vAPV.
-
-    Returns:
-        HttpResponse: A response containing the switcher status{}.
-    """
-    # the output of the command is either "True\n" or "False\n"
-    output_map = {
-        "True\n": 1,
-        "False\n": 0
-    }
-    command = "python3 /ca/bin/aws/LoggerManager.py -mode status"
-    try:
-        switcher = run_command(command)
-        return create_json_response({"status": output_map[switcher]}, 200)
-    except RuntimeError as e:
-        anerror("hive.debug", str(e))
-        return create_json_response(
-            {"msg": "Error while getting switcher status"}, 500)
-
-
-def post_switcher(request):
-    """
-    Turn on or off the status of log functionality aws tool on vAPV.
-
-    Returns:
-        HttpResponse: A response indicating the success or failure of
-    """
-    input_map = {
-        1: "on",
-        0: "off"
-    }
-    required_keys = ["status"]
-    data = json.loads(request.body)
-
-    # Validate input
-    is_valid, message = validate_input(data, required_keys)
-    if not is_valid:
-        return create_json_response({"msg": message}, 400)
-    if data["status"] not in [0, 1]:
-        return create_json_response({"msg": "status should be number 0 or 1"}, 400)
-
-    command = ("python3 /ca/bin/aws/LoggerManager.py -mode "
-               "{}".format(input_map[data["status"]]))
-
-    try:
-        output = run_command(command)
-        aninfo("hive.debug", "Succeeded to set log functionality: "
-               "{}".format(data["status"]))
-        return create_json_response({"msg": "Succeed"}, 200)
-    except RuntimeError:
-        return create_json_response({"msg": "error while running aws tools."}, 500)
-
-
-def get_log_severity(request):
-    """
-    Get the severity level of log functionality of aws tool from vAPV.
-
-    Returns:
-        HttpResponse: A response containing the severity level.
-    """
-    command = "python3 /ca/bin/aws/LoggerManager.py -level status"
-    try:
-        severity = run_command(command)
-        aninfo("hive.debug", "Succeeded to get log severity.")
-        return create_json_response({"severity": severity.replace("\n", "")}, 200)
-    except RuntimeError as e:
-        anerror("hive.debug", str(e))
-        return create_json_response(
-            {"msg": "Error while getting severity level"}, 500)
-
-
-def post_log_severity(request):
-    """
-    Set the severity level of log functionality of aws tool on vAPV.
-
-    Returns:
-        HttpResponse: A response indicating the success or failure of
-                      the severity level setting process.
-    """
-    required_keys = ["severity"]
-    data = json.loads(request.body)
-
-    # Validate input
-    is_valid, message = validate_input(data, required_keys)
-    if not is_valid:
-        return create_json_response({"msg": message}, 400)
-
-    if data["severity"] not in ["debug", "info", "warning", "error"]:
-        return create_json_response(
-            {"msg": "severity should be one of debug, info, warning, error"}, 400)
-
-    command = ("python3 /ca/bin/aws/LoggerManager.py -level "
-               "{}".format(data["severity"]))
-    try:
-        output = run_command(command)
-        aninfo("hive.debug", "Succeeded to set log severity: "
-               "{}".format(data["severity"]))
-        return create_json_response({"msg": "Succeed"}, 200)
-    except RuntimeError as e:
-        aninfo("hive.debug", str(e))
-        return create_json_response({"msg": "error while running aws tools."}, 501)
-
-
-def download_log_file(request):
-    """
-    Get the log file of aws tool from vAPV.
-
-    Returns:
-        HttpResponse: A response containing the log file.
-    """
-    command = "python3 /ca/bin/aws/LoggerManager.py -mode getlogpath"
-    try:
-        log_file_path = run_command(command)
-        log_file_path = log_file_path.replace("\n", "")
-
-        if not os.path.exists(log_file_path):
-            return HttpResponse(
-                json.dumps({"msg": "No log file found"}),
-                content_type="application/json",
-                status=200
-            )
-        with open(log_file_path, 'rb') as file:
-            response = HttpResponse(file.read(), content_type='text/plain')
-            response['Content-Disposition'] = 'attachment; filename="{}"'.format("aws_tool.log")
-            response['Content-Length'] = os.path.getsize(log_file_path)
-            return response
-    except RuntimeError as e:
-        anerror("hive.debug", str(e))
-        return create_json_response(
-            {"msg": "Error while getting log file"}, 500)
\ No newline at end of file
Index: /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/hive/cloud/az/__init__.py	(added)
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/hive/cloud/az/__init__.py	(revision 0)
+++ /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/hive/cloud/az/__init__.py	(revision 0)
Index: /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/hive/cloud/az/az_basic_view.py
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/hive/cloud/az/az_basic_view.py	(revision 0)
+++ /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/hive/cloud/az/az_basic_view.py	(working copy)
@@ -0,0 +1,125 @@
+from django.http import HttpResponse
+import subprocess, os, time, json, re
+from hive.utils import aninfo, anerror
+
+def logout(request):
+    command = "python3 /ca/bin/azure/AZAuthManager.py -mode logout"
+    res = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+    stdout, stderr = res.communicate()
+    if stderr:
+        anerror("hive.debug", stderr)
+        return HttpResponse(
+        json.dumps({"message":"error while running az tools"}),
+            content_type="application/json",
+            status=500
+        )
+    aninfo("hive.debug","log out az account")
+    response = {
+        "message":"success to log out"
+    }
+    return HttpResponse(
+        json.dumps(response),
+        content_type="application/json",
+        status=200
+    )
+
+def get_login_code(request):
+    '''This is used to get the azure log in url and its code.
+    User can use this url and code to authenticate our app.
+    Eighter url and code cannot be resolve by regular express will retrun status code 500.
+    The way to run the az tool is to code the az tool API, and read the information from the related content from the file where API stores the output.
+    This method doesn't directly call Array CLI because of the limitation of architecture.'''
+
+    # launch process and read the content of file
+    file_path = "/tmp/login_msg.txt"
+    count = 0
+    fp = None
+    if os.path.exists(file_path):
+        os.remove(file_path)
+    command = "python3 /ca/bin/azure/AZAuthManager.py -mode login"
+    subprocess.Popen(command, shell=True)
+
+    # Wait for the file to become available, up to 60 seconds
+    while fp is None and count < 60:
+        if os.path.exists(file_path):
+            fp = open(file_path, "r")
+        else:
+            time.sleep(1)
+            count += 1
+    msg = ""
+    if fp is not None:
+        for line in fp:
+            msg+=line
+        fp.close()
+
+    # extract the url and code by regrex to form json response
+    url = ""
+    code = ""
+    url_pattern = r'https?:\/\/[^\s]+'
+    code_pattern = r'code\s([A-Za-z0-9]+)'
+    code_match = re.search(code_pattern, msg)
+    if code_match:
+        code = code_match.group(1)
+    else:
+        error_response = {
+            "message": "Not Found code",
+        }
+        anerror("hive.debug", error_response)
+        return HttpResponse(
+        error_response,
+        content_type="application/json",
+        status=500
+    )
+    url_match = re.search(url_pattern, msg)
+    if url_match:
+        url = url_match.group(0)
+    else:
+        error_response = {
+            "message": "Not Found url",
+        }
+        anerror("hive.debug", error_response)
+        return HttpResponse(
+        error_response,
+        content_type="application/json",
+        status=500
+    )
+
+    response_data = {
+        "url": url,
+        "code": code
+    }
+    return HttpResponse(
+        json.dumps(response_data),
+        content_type="application/json",
+        status=200
+    )
+
+def get_login_status(request):
+    '''Use to get login status.
+    return statuscode=401 if az tool return nothiing, which meaning that use haven't login.
+    return statuscode=200 if user have logged in. return all 
+    '''
+    command = "python3 /ca/bin/azure/AZAuthManager.py -mode show"
+    res = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+    stdout, stderr = res.communicate()
+    response_data = {
+        "status":True
+    }
+    try:
+        json.loads(stdout.decode())
+    except Exception as e:
+        anerror("hive.debug", "Fail to decode return to json:{}".format(e))
+        response_data["status"] = False
+        return HttpResponse(
+            json.dumps(response_data),
+            content_type="application/json",
+            status=200
+        )
+    aninfo("hive.debug", response_data)
+
+    return HttpResponse(
+        json.dumps(response_data),
+        # stdout.decode(),
+        content_type="application/json",
+        status=200
+    )
\ No newline at end of file
Index: /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/hive/cloud/az/az_log_view.py
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/hive/cloud/az/az_log_view.py	(revision 0)
+++ /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/hive/cloud/az/az_log_view.py	(working copy)
@@ -0,0 +1,177 @@
+from django.http import HttpResponse
+import subprocess, os, json
+from hive.utils import aninfo, anerror
+import logging
+
+log_file_path = '/ca/webui/htdocs/new/logfile.log'
+logging.basicConfig(
+    filename=log_file_path,            # Path to the log file
+    level=logging.DEBUG,               # Log level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
+    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',  # Log message format
+    datefmt='%Y-%m-%d %H:%M:%S'         # Date format in the logs
+)
+
+def get_all_log(request):
+    command = "python3 /ca/bin/azure/LoggerManager.py -mode show"
+    res = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+    stdout, stderr = res.communicate()
+    if stderr:
+        anerror("hive.debug", stderr)
+        return HttpResponse(
+        json.dumps({"message":"error while running az tools"}),
+            content_type="application/json",
+            status=500
+        )
+    aninfo("hive.debug", "get all log")
+    return HttpResponse(
+        json.dumps({"message":stdout}),
+            content_type="application/json",
+            status=200
+        )
+
+def download_log_file(request):
+    command = "python3 /ca/bin/azure/LoggerManager.py -mode getlogpath"
+    res = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+    stdout, stderr = res.communicate()
+    if stderr:
+        anerror("hive.debug", stderr)
+        return HttpResponse(
+        json.dumps({"message":"error while running az tools"}),
+            content_type="application/json",
+            status=500
+        )
+
+    log_file_path = stdout.replace("\n", "")
+
+    if not os.path.exists(log_file_path):
+        return HttpResponse(
+        json.dumps({"message":"No log file found"}),
+            content_type="application/json",
+            status=200
+        )
+    # Open the file in binary mode and prepare it for downloading
+    with open(log_file_path, 'rb') as file:
+        response = HttpResponse(file.read(), content_type='text/plain')  # Assuming the file is a log file (plain text)
+        response['Content-Disposition'] = 'attachment; filename="{}"'.format("az_tool.log")
+        response['Content-Length'] = os.path.getsize(log_file_path)
+        return response
+
+    if is_running is None:
+        anerror("hive.debug", stderr)
+        return HttpResponse(
+        json.dumps({"message":"error while running az tools"}),
+            content_type="application/json",
+            status=500
+        ) 
+    aninfo("hive.debug", "download log file")
+    return HttpResponse(
+        json.dumps({"is_running":is_running}),
+        content_type="application/json",
+        status=200
+    )
+
+def get_log_severity(request):
+    command = "python3 /ca/bin/azure/LoggerManager.py -level status"
+    res = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+    stdout, stderr = res.communicate()
+
+    if stderr:
+        anerror("hive.debug", stderr)
+        return HttpResponse(
+        json.dumps({"message":"error while running az tools"}),
+            content_type="application/json",
+            status=500
+        )
+    aninfo("hive.debug", "get log severity: {}".format(stdout.replace("\n", "")))
+    return HttpResponse(
+        json.dumps({"severity":stdout.replace("\n", "")}),
+        content_type="application/json",
+        status=200
+    )
+def set_log_severity(request):
+    # verify user input
+    required_keys = ["severity"]
+
+    data = json.loads(request.body)
+    for key in required_keys:
+        if key not in data:
+            return HttpResponse(
+                json.dumps({"message":"body should contain key: {}".format(', '.join(required_keys))}),
+                content_type="application/json",
+                status=400
+            ) 
+    allow_severity = ["debug", "info", "warning", "error"]
+    if not data["severity"] in allow_severity:
+        return HttpResponse(
+            json.dumps({"message":"status should be: {}".format(','.join(allow_severity))}),
+            content_type="application/json",
+            status=400
+        )
+    # call az tools
+    command = 'python3 /ca/bin/azure/LoggerManager.py -level {}'.format(data["severity"])
+    res = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+    stdout, stderr = res.communicate()
+    if stderr:
+        anerror("hive.debug", stderr)
+    return HttpResponse(
+        json.dumps({"message":"succeed"}),
+        content_type="application/json",
+        status=201
+    )
+def get_log_status(request):
+    '''This method is used to check if az tool log functionality is on or off.'''
+    command = "python3 /ca/bin/azure/LoggerManager.py -mode status"
+    res = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+    stdout, stderr = res.communicate()
+    if stderr:
+        anerror("hive.debug", stderr)
+        return HttpResponse(
+        json.dumps({"message":"error while running az tools"}),
+            content_type="application/json",
+            status=500
+        )
+    is_on = {"True": True, "False": False}.get(stdout.replace("\n", ""))
+    aninfo("hive.debug", "get log status: {}".format(is_on))
+    return HttpResponse(
+        json.dumps({"is_on":is_on}),
+        content_type="application/json",
+        status=200
+    )
+
+def switch_log_status(request):
+    '''This method is used to set az tool log functionality to on or off.'''
+    # verify user input
+    required_keys = ["status"]
+    data = json.loads(request.body)
+    for key in required_keys:
+        if key not in data:
+            return HttpResponse(
+                json.dumps({"message":"body should contain key: {}".format(', '.join(required_keys))}),
+                content_type="application/json",
+                status=400
+            )
+
+    allow_status = ["on", "off"]
+    if not data["status"] in allow_status:
+        return HttpResponse(
+            json.dumps({"message":"status should be: {}".format(', or '.join(allow_status))}),
+            content_type="application/json",
+            status=400
+        )
+    # use az tool
+    command = "python3 /ca/bin/azure/LoggerManager.py -mode {}".format(data["status"])
+    res = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+    stdout, stderr = res.communicate()
+    if stderr:
+        anerror("hive.debug", stderr)
+        return HttpResponse(
+        json.dumps({"message":"error while running az tools"}),
+            content_type="application/json",
+            status=500
+        )
+    aninfo("hive.debug", "swtich log status to {}".format(data["status"]))
+    return HttpResponse(
+        json.dumps({"message":"succeed"}),
+        content_type="application/json",
+        status=200
+    )
\ No newline at end of file
Index: /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/hive/cloud/az/az_nic_view.py
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/hive/cloud/az/az_nic_view.py	(revision 0)
+++ /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/hive/cloud/az/az_nic_view.py	(working copy)
@@ -0,0 +1,172 @@
+from django.http import HttpResponse
+import subprocess, json
+from hive.utils import aninfo, anerror
+
+def get_all_nic_config(request):
+    command = "python3 /ca/bin/azure/ConfigManager.py -mode getipconfig"
+    res = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+    stdout, stderr = res.communicate()
+    aninfo("hive.debug", stdout)
+    try:
+        return HttpResponse(
+                json.dumps(json.loads(stdout.decode().replace("'", '"'))),
+                content_type="application/json",
+                status=200
+        )
+    except Exception as e:
+        anerror("hive.debug", str(e)+". Got "+stdout)
+        return HttpResponse(
+                json.dumps({}),
+                content_type="application/json",
+                status=200
+        )
+
+def delete_nic_config_by_index(request):
+    required_keys = ["index"]
+    data = json.loads(request.body)
+    for key in required_keys:
+        if key not in data:
+            return HttpResponse(
+                json.dumps({"message":"body should contain key: {}".format(', '.join(required_keys))}),
+                content_type="application/json",
+                status=400
+            ) 
+    # call az tools
+    command = 'python3 /ca/bin/azure/ConfigManager.py -mode clear -index {}'.format(data["index"])
+    res = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+    stdout, stderr = res.communicate()
+    aninfo("hive.debug", "delete nic with index: {}".format(data["index"]))
+
+    return HttpResponse(
+        json.dumps({"message":stdout}),
+        content_type="application/json",
+        status=201
+    )
+
+def add_nic_config(request):
+    '''add nic ip configuration'''
+    # verify user input
+    required_keys = ["sub_id", "res_grp_name", "src_nic_name", "dest_nic_name"]
+    data = json.loads(request.body)
+    for key in required_keys:
+        if key not in data:
+            return HttpResponse(
+                json.dumps({"message":"body should contain key: {}".format(', '.join(required_keys))}),
+                content_type="application/json",
+                status=400
+            ) 
+    # call az tools
+    command = 'python3 /ca/bin/azure/ConfigManager.py -mode set -sub_id {} -res_grp_name {} -src_nic_name {} -dest_nic_name {}'.format(data["sub_id"], data["res_grp_name"], data["src_nic_name"], data["dest_nic_name"])
+    res = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+    stdout, stderr = res.communicate()
+    if stderr:
+        anerror("hive.debug", stderr)
+        return HttpResponse(
+        json.dumps({"message":"error while running az tools"}),
+            content_type="application/json",
+            status=500
+    )
+    aninfo("hive.debug", "add nic: {}".format(data))
+    return HttpResponse(
+        json.dumps({"message":"succeed"}),
+        content_type="application/json",
+        status=201
+    )
+
+
+def get_nic_poller_status(request):
+    command = "python3 /ca/bin/azure/AZFailoverPoller.py -mode 3"
+    res = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+    stdout, stderr = res.communicate()
+    if stderr:
+        anerror("hive.debug", stderr)
+        return HttpResponse(
+        json.dumps({"message":"error while running az tools"}),
+            content_type="application/json",
+            status=500
+        )
+    
+    is_running = {"True": True, "False": False}.get(stdout.replace("\n", ""))
+    aninfo("hive.debug", "get nic poller status: {}".format(is_running))
+    if is_running is None:
+        anerror("hive.debug", "fail to resolve ".format(stdout.replace("\n", "")))
+        return HttpResponse(
+        json.dumps({"message":"error while running az tools"}),
+            content_type="application/json",
+            status=500
+        )
+    return HttpResponse(
+        json.dumps({"is_running":is_running}),
+        content_type="application/json",
+        status=200
+    )
+def switch_nic_poller(request):
+    # verify user input
+    required_keys = ["status"]
+
+    data = json.loads(request.body)
+    for key in required_keys:
+        if key not in data:
+            return HttpResponse(
+                json.dumps({"message":"body should contain key: {}".format(', '.join(required_keys))}),
+                content_type="application/json",
+                status=400
+            )
+    # use az tool
+    status = {"on": "1", "off": "2"}.get(data["status"])
+    command = "python3 /ca/bin/azure/AZFailoverPoller.py -mode {}".format(status)
+    res = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+    stdout, stderr = res.communicate()
+
+    if stderr:
+        anerror("hive.debug", stderr)
+        return HttpResponse(
+        json.dumps({"message":"error while running az tools"}),
+            content_type="application/json",
+            status=500
+        )
+    aninfo("hive.debug", "switch nic poller to {}".format(data["status"]))
+    return HttpResponse(
+        json.dumps({"message":"succeed"}),
+        content_type="application/json",
+        status=200
+    )
+
+
+def trigger_ip_transfering(request):
+    # verify user input
+    required_keys = ["status"]
+    data = json.loads(request.body)
+    for key in required_keys:
+        if key not in data:
+            return HttpResponse(
+                json.dumps({"message":"body should contain key: {}".format(', '.join(required_keys))}),
+                content_type="application/json",
+                status=400
+            )
+
+    allow_status = ["failover", "recover"]
+    if not data["status"] in allow_status:
+        return HttpResponse(
+            json.dumps({"message":"status should be: {}".format(', or '.join(allow_status))}),
+            content_type="application/json",
+            status=400
+        )
+    # use az tool
+    status = {"failover": "1", "recover": "2"}.get(data["status"])
+    command = "python3 /ca/bin/azure/AZFailoverManager.py -mode {}".format(status)
+    res = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+    stdout, stderr = res.communicate()
+
+    if stderr:
+        return HttpResponse(
+        json.dumps({"message":"error while running az tools"}),
+            content_type="application/json",
+            status=500
+        )
+    aninfo("hive.debug", "trigger ip transfering {}".format(data["status"]))
+    return HttpResponse(
+        json.dumps({"message":"succeed"}),
+        content_type="application/json",
+        status=200
+    )
\ No newline at end of file
Index: /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/hive/cloud/az/az_udr_view.py
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/hive/cloud/az/az_udr_view.py	(revision 0)
+++ /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/hive/cloud/az/az_udr_view.py	(working copy)
@@ -0,0 +1,156 @@
+import subprocess, json, os
+
+from django.http import HttpResponse
+
+from hive.utils import aninfo, anerror
+
+def switch_udr_poller(request):
+    # verify user input
+    required_keys = ["status"]
+    data = json.loads(request.body)
+    for key in required_keys:
+        if key not in data:
+            return HttpResponse(
+                json.dumps({"message":"body should contain key: {}".format(', '.join(required_keys))}),
+                content_type="application/json",
+                status=400
+            )
+    allow_status = ["on", "off"]
+    if not data["status"] in allow_status:
+        return HttpResponse(
+            json.dumps({"message":"status should be: {}".format(', or '.join(allow_status))}),
+            content_type="application/json",
+            status=400
+        )
+
+    # use az tool
+    status = {"on": "1", "off": "2"}.get(data["status"])
+    command = "python3 /ca/bin/azure/UDRPoller.py -mode {}".format(status)
+    res = subprocess.Popen(command.split(), stdout=open(os.devnull, 'w'), stderr=open(os.devnull, 'w'))
+    stdout, stderr = res.communicate()
+    if stderr:
+        anerror("hive.debug", stderr)
+        return HttpResponse(
+        json.dumps({"message":"error while running az tools"}),
+            content_type="application/json",
+            status=500
+        )
+    aninfo("hive.debug", "swtich udr status to {}".format(data["status"]))
+    return HttpResponse(
+        json.dumps({"message":"succeed"}),
+        content_type="application/json",
+        status=200
+    )
+
+
+def get_udr_poller_status(request):
+    command = "python3 /ca/bin/azure/UDRPoller.py -mode 3"
+    res = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+    stdout, stderr = res.communicate()
+    if stderr:
+        anerror("hive.debug", stderr)
+        return HttpResponse(
+        json.dumps({"message":"error while running az tools"}),
+            content_type="application/json",
+            status=500
+        )
+    is_running = {"True": True, "False": False}.get(stdout.replace("\n", ""))
+    if is_running is None:
+        anerror("hive.debug", stderr)
+        return HttpResponse(
+        json.dumps({"message":"error while running az tools"}),
+            content_type="application/json",
+            status=500
+        )
+    aninfo("hive.debug", "get udr poller status {}".format(is_running))
+    return HttpResponse(
+        json.dumps({"is_running":is_running}),
+        content_type="application/json",
+        status=200
+    )
+
+
+def add_udr_config(request):
+    '''add udr ip configuration'''
+    # verify user input
+    required_keys = ["sub_id", "res_grp_name", "vm_name", "ip_running", "ip_deallocating"]
+   
+    data = json.loads(request.body)
+    for key in required_keys:
+        if key not in data:
+            return HttpResponse(
+                json.dumps({"message":"body should contain key: {}".format(', '.join(required_keys))}),
+                content_type="application/json",
+                status=400
+            )
+    # call az tools
+    command = 'python3 /ca/bin/azure/RouteConfigManager.py -mode set -sub_id {} -res_grp_name {} -vm_name {} -ip_running {} -ip_deallocating {}'.format(data["sub_id"], data["res_grp_name"], data["vm_name"], data["ip_running"], data["ip_deallocating"])
+    res = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+    stdout, stderr = res.communicate()
+    if stderr:
+        anerror("hive.debug", stderr)
+        return HttpResponse(
+        json.dumps({"message":"error while running az tools"}),
+            content_type="application/json",
+            status=500
+    )
+    aninfo("hive.debug", "swtich udr status to {}".format(data["status"]))
+    return HttpResponse(
+        json.dumps({"message":"succeed"}),
+        content_type="application/json",
+        status=201
+    )
+
+
+def delete_udr_config(request):
+    '''delete udr configuration'''
+    required_keys = ["index"]
+    data = json.loads(request.body)
+    for key in required_keys:
+        if key not in data:
+            return HttpResponse(
+                json.dumps({"message":"body should contain key: {}".format(', '.join(required_keys))}),
+                content_type="application/json",
+                status=400
+            )
+    # call az tools
+    command = 'python3 /ca/bin/azure/RouteConfigManager.py -mode clear -index {}'.format(data["index"])
+    res = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+    stdout, stderr = res.communicate()
+    if stderr:
+        anerror("hive.debug", stderr)
+        return HttpResponse(
+        json.dumps({"message":"error while running az tools"}),
+            content_type="application/json",
+            status=500
+    )
+    aninfo("hive.debug", "delete udr config with index: {}".format(data["index"]))
+    return HttpResponse(
+        json.dumps({"message":"succeed"}),
+        content_type="application/json",
+        status=200
+    )
+
+
+def get_udr_config(request):
+    command = "python3 /ca/bin/azure/RouteConfigManager.py -mode getrouteconfig"
+    res = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+    stdout, stderr = res.communicate()
+    try:
+        udr_config = json.dumps(json.loads(stdout.decode().replace("'", '"')))
+        aninfo("hive.debug", "get udr config")
+        return HttpResponse(
+                udr_config,
+                content_type="application/json",
+                status=200
+        )
+    except Exception as e:
+        anerror("hive.debug", stderr)
+        return HttpResponse(
+                json.dumps({}),
+                content_type="application/json",
+                status=200
+        )
+
+if __name__=="__main__":
+    pass
\ No newline at end of file
Index: /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/hive/cloud/az/urls.py
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/hive/cloud/az/urls.py	(revision 0)
+++ /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/hive/cloud/az/urls.py	(working copy)
@@ -0,0 +1,154 @@
+import json
+
+from django.http import HttpResponse
+from django.conf.urls import patterns, url
+
+from hive.cloud.az.az_basic_view import (
+    get_login_code,
+    get_login_status,
+    logout
+)
+from hive.cloud.az.az_nic_view import (
+    get_all_nic_config,
+    add_nic_config,
+    delete_nic_config_by_index,
+    get_nic_poller_status,
+    switch_nic_poller,
+    trigger_ip_transfering
+)
+from hive.cloud.az.az_udr_view import (
+    switch_udr_poller,
+    add_udr_config,
+    delete_udr_config,
+    get_udr_config,
+    get_udr_poller_status
+)
+from hive.cloud.az.az_log_view import (
+    get_all_log,
+    get_log_status,
+    download_log_file as download_az_log_file,
+    switch_log_status,
+    get_log_severity as get_az_log_severity,
+    set_log_severity
+)
+
+
+def get_bad_http_method():
+    return HttpResponse(
+        json.dumps({"message": "Bad http method"}),
+        content_type="application/json",
+        status=400
+    )
+
+
+def az_nicconfig_method_router(request):
+    if request.method=="GET":
+        return get_all_nic_config(request)
+    elif request.method=="POST":
+        return add_nic_config(request)
+    elif request.method=="DELETE":
+        return delete_nic_config_by_index(request)
+    return get_bad_http_method()
+
+
+def az_login_method_router(request):
+    if request.method=="GET":
+        return get_login_code(request)
+    return get_bad_http_method()
+
+
+def az_login_status_method_router(request):
+    if request.method=="GET":
+        return get_login_status(request)
+    return get_bad_http_method()
+
+
+def az_logout_method_router(request):
+    if request.method=="POST":
+        return logout(request)
+    return get_bad_http_method()
+
+
+def az_nicpoller_status_method_router(request):
+    if request.method=="GET":
+        return get_nic_poller_status(request)
+    return get_bad_http_method()
+
+
+def az_nicpoller_method_router(request):
+    if request.method=="PUT":
+        return switch_nic_poller(request)
+    return get_bad_http_method()
+
+
+def az_nictrigger_method_router(request):
+    if request.method=="PUT":
+        return trigger_ip_transfering(request)
+    return get_bad_http_method()
+
+
+def az_udrpoller_method_router(request):
+    if request.method=='PUT':
+        return switch_udr_poller(request)
+
+
+def az_udrpoller_status_method_router(request):
+    if request.method=='GET':
+        return get_udr_poller_status(request)
+
+
+def az_udrconfig_method_router(request):
+    if request.method=="GET":
+        return get_udr_config(request)
+    elif request.method=="POST":
+        return add_udr_config(request)
+    elif request.method=="DELETE":
+        return delete_udr_config(request)
+    return get_bad_http_method()
+
+
+def az_logfile_method_router(request):
+    if request.method=="GET":
+        return download_az_log_file(request)
+    return get_bad_http_method()
+
+
+def az_log_method_router(request):
+    if request.method=="GET":
+        return get_all_log(request)
+    return get_bad_http_method()
+
+
+def az_log_status_method_router(request):
+    if request.method=="GET":
+        return get_log_status(request)
+    if request.method=="PUT":
+        return switch_log_status(request)
+    return get_bad_http_method()
+
+
+def az_log_severity_method_router(request):
+    if request.method=="GET":
+        return get_az_log_severity(request)
+    if request.method=="PUT":
+        return set_log_severity(request)
+    return get_bad_http_method()
+
+
+urlpatterns = patterns(
+    '',
+    url(r'^login/$', az_login_method_router),
+    url(r'^login/status/$', az_login_status_method_router),
+    url(r'^logout/$', az_logout_method_router),
+    url(r'^nicconfig/$', az_nicconfig_method_router),
+    url(r'^nicpoller/status/$', az_nicpoller_status_method_router),
+    url(r'^nicpoller/$', az_nicpoller_method_router),
+    url(r'^nictrigger/$', az_nictrigger_method_router),
+    url(r'^udrpoller/$', az_udrpoller_method_router),
+    url(r'^udrpoller/status/$', az_udrpoller_status_method_router),
+    url(r'^udrconfig/$', az_udrconfig_method_router),
+    url(r'^logfile/$', az_logfile_method_router),
+    url(r'^log/$', az_log_method_router),
+    url(r'^log/status/$', az_log_status_method_router),
+    url(r'^log/severity/$', az_log_severity_method_router),
+)
\ No newline at end of file
Index: /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/hive/cloud/urls.py
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/hive/cloud/urls.py	(revision 39037)
+++ /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/hive/cloud/urls.py	(working copy)
@@ -1,122 +1,8 @@
-from django.http import HttpResponse
-import json
+from django.conf.urls import include
 from django.conf.urls import patterns, url
-from hive.cloud.aws_basic_view import (
-    post_aws_credential,
-    get_aws_credential,
-    delete_aws_credential
-)
-from hive.cloud.aws_eni_view import (
-    get_eniconfig,
-    post_eniconfig,
-    delete_eniconfig,
-    post_failover,
-    post_recover,
-    get_ha_status,
-    post_ha_status
-)
-from hive.cloud.aws_log_view import (
-    get_log_buffer,
-    get_switcher,
-    post_switcher,
-    get_log_severity,
-    post_log_severity,
-    download_log_file as aws_download_log_file
-)
-
-
-def get_bad_http_method():
-    return HttpResponse(
-        json.dumps({"message": "Bad http method"}),
-        content_type="application/json",
-        status=400
-    )
-
-
-# aws router start
-
-def aws_credential_method_router(request):
-    if request.method == "GET":
-        return get_aws_credential(request)
-    elif request.method == "POST":
-        return post_aws_credential(request)
-    elif request.method == "DELETE":
-        return delete_aws_credential(request)
-    return get_bad_http_method()
-
-
-def aws_eniconfig_method_router(request):
-    if request.method == "GET":
-        return get_eniconfig(request)
-    elif request.method == "POST":
-        return post_eniconfig(request)
-    elif request.method == "DELETE":
-        return delete_eniconfig(request)
-    return get_bad_http_method()
-
-
-def aws_failover_method_router(request):
-    if request.method == "PUT":
-        return post_failover(request)
-    return get_bad_http_method()
-
-
-def aws_recover_method_router(request):
-    if request.method == "PUT":
-        return post_recover(request)
-    return get_bad_http_method()
-
-
-def aws_ha_status_method_router(request):
-    if request.method == "POST":
-        return post_ha_status(request)
-    elif request.method == "GET":
-        return get_ha_status(request)
-    return get_bad_http_method()
-
-
-def aws_log_buffer_method_router(request):
-    if request.method == "GET":
-        return get_log_buffer(request)
-    return get_bad_http_method()
-
-
-def aws_switcher_method_router(request):
-    if request.method == "GET":
-        return get_switcher(request)
-    elif request.method == "PUT":
-        return post_switcher(request)
-    return get_bad_http_method()
-
-
-def aws_log_severity_method_router(request):
-    if request.method == "GET":
-        return get_log_severity(request)
-    elif request.method == "PUT":
-        return post_log_severity(request)
-    return get_bad_http_method()
-
-
-def aws_log_file_method_router(request):
-    if request.method == "GET":
-        return download_log_file(request)
-    return get_bad_http_method()
-
-
-# aws router end
 
 urlpatterns = patterns(
     '',
-    # aws url start
-    url(r'^aws/credential/$', aws_credential_method_router),
-    url(r'^aws/eniconfig/$', aws_eniconfig_method_router),
-    url(r'^aws/failover/$', aws_failover_method_router),
-    url(r'^aws/recover/$', aws_recover_method_router),
-    url(r'^aws/ha/status/$', aws_ha_status_method_router),
-    url(r'^aws/log/buffer/$', aws_log_buffer_method_router),
-    url(r'^aws/log/status/$', aws_switcher_method_router),
-    url(r'^aws/log/severity/$', aws_log_severity_method_router),
-    url(r'^aws/log/file/$', aws_log_file_method_router),
-    # aws url end
-    
+    url(r'^aws/', include("hive.cloud.aws.urls")),
+    url(r'^az/', include("hive.cloud.az.urls")),
 )
\ No newline at end of file
Index: /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/locale/en/LC_MESSAGES/django.po
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/locale/en/LC_MESSAGES/django.po	(revision 39037)
+++ /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/locale/en/LC_MESSAGES/django.po	(working copy)
@@ -5597,6 +5597,96 @@
 msgid "Authentication Server is required."
 msgstr ""
 
+msgid "Cloud"
+msgstr ""
+
+msgid "Log"
+msgstr ""
+
+msgid "Login Url"
+msgstr ""
+
+msgid "Logged in"
+msgstr ""
+
+msgid "Not logged in"
+msgstr ""
+
+msgid "Code"
+msgstr ""
+
+msgid "Internal error, please refresh the page."
+msgstr ""
+
+msgid "Refresh"
+msgstr ""
+
+msgid "Log Out"
+msgstr ""
+
+msgid "Your authentication code will expire in 60 seconds."
+msgstr ""
+
+msgid "Please use the following information to sign in immediately."
+msgstr ""
+
+msgid "WARNING: To sign in, use a web browser to open the page %s "
+msgstr ""
+
+msgid " and enter the code "
+msgstr ""
+
+msgid " to authenticate."
+msgstr ""
+
+msgid "Manual Trigger"
+msgstr ""
+
+msgid "Failover"
+msgstr ""
+
+msgid "Recover"
+msgstr ""
+
+msgid "Sub ID"
+msgstr ""
+
+msgid "Resource Grop Name"
+msgstr ""
+
+msgid "Source NIC Name"
+msgstr ""
+
+msgid "Destination NIC Name"
+msgstr ""
+
+msgid "Monitored VM Name"
+msgstr ""
+
+msgid "Target IP When Running"
+msgstr ""
+
+msgid "Target IP When Deallocated"
+msgstr ""
+
+msgid "Level"
+msgstr ""
+
+msgid "Debug"
+msgstr ""
+
+msgid "Info"
+msgstr ""
+
+msgid "Download"
+msgstr ""
+
+msgid "On"
+msgstr ""
+
+msgid "Off"
+msgstr ""
+
 #~ msgid "Graphs"
 #~ msgstr ""
 
@@ -5639,7 +5729,7 @@
 #~ msgid "©2021 Beijing Array Networks, Inc."
 #~ msgstr ""
 
-#~ msgid "©2021 Array Networks, Inc."
+#~ msgid "©2025 Array Networks, Inc."
 #~ msgstr ""
 
 #~ msgid "Signin"
Index: /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/locale/ja/LC_MESSAGES/django.po
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/locale/ja/LC_MESSAGES/django.po	(revision 39037)
+++ /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/locale/ja/LC_MESSAGES/django.po	(working copy)
@@ -5645,6 +5645,96 @@
 msgid "Authentication Server is required."
 msgstr "認証サーバーは必要です。"
 
+msgid "Cloud"
+msgstr "クラウドサービス"
+
+msgid "Log"
+msgstr "ログ"
+
+msgid "Login Url"
+msgstr "ログインURL"
+
+msgid "Logged in"
+msgstr "ログイン済み"
+
+msgid "Not logged in"
+msgstr "ログインしていません"
+
+msgid "Code"
+msgstr "コード"
+
+msgid "Internal error, please refresh the page."
+msgstr "内部エラーが発生しました。ページを再読み込みしてください。"
+
+msgid "Refresh"
+msgstr "更新効力"
+
+msgid "Log Out"
+msgstr "ログアウト"
+
+msgid "Your authentication code will expire in 60 seconds."
+msgstr "ログイン認証情報は60秒以内に失効します。"
+
+msgid "Please use the following information to sign in immediately."
+msgstr "直ちに以下の情報を使用してログインしてください。"
+
+msgid "WARNING: To sign in, use a web browser to open the page %s "
+msgstr "注意：ブラウザで %s を開き、"
+
+msgid " and enter the code "
+msgstr "コード「"
+
+msgid " to authenticate."
+msgstr "」を入力して認証を行ってください。"
+
+msgid "Manual Trigger"
+msgstr "手動で起動する"
+
+msgid "Failover"
+msgstr "フェイルオーバー"
+
+msgid "Recover"
+msgstr "復旧"
+
+msgid "Sub ID"
+msgstr "購読ID"
+
+msgid "Resource Grop Name"
+msgstr "リソースグループ名"
+
+msgid "Source NIC Name"
+msgstr "ソースNIC名"
+
+msgid "Destination NIC Name"
+msgstr "宛先NIC名"
+
+msgid "Monitored VM Name"
+msgstr "監視されたVMの名前"
+
+msgid "Target IP When Running"
+msgstr "実行中のターゲットIP"
+
+msgid "Target IP When Deallocated"
+msgstr "解放時のターゲットIP"
+
+msgid "Level"
+msgstr "レベル"
+
+msgid "Debug"
+msgstr "デバッグ"
+
+msgid "Info"
+msgstr "情報"
+
+msgid "Download"
+msgstr "ダウンロード"
+
+msgid "On"
+msgstr "開く"
+
+msgid "Off"
+msgstr "閉じる"
+
 #~ msgid "L2 Bridge"
 #~ msgstr "L2ブリッジ"
 
@@ -5715,7 +5805,7 @@
 #~ msgid "©2021 Beijing Array Networks, Inc."
 #~ msgstr ""
 
-#~ msgid "©2023 Array Networks, Inc."
+#~ msgid "©2025 Array Networks, Inc."
 #~ msgstr ""
 
 #~ msgid "Signin"
Index: /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/locale/zh_CN/LC_MESSAGES/django.po
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/locale/zh_CN/LC_MESSAGES/django.po	(revision 39037)
+++ /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/locale/zh_CN/LC_MESSAGES/django.po	(working copy)
@@ -5627,6 +5627,96 @@
 msgid "Authentication Server is required."
 msgstr "认证服务器不能为空。"
 
+msgid "Cloud"
+msgstr "云服务"
+
+msgid "Log"
+msgstr "日志"
+
+msgid "Login Url"
+msgstr "登录网址"
+
+msgid "Logged in"
+msgstr "已登录"
+
+msgid "Not logged in"
+msgstr "未登录"
+
+msgid "Code"
+msgstr "代码"
+
+msgid "Internal error, please refresh the page."
+msgstr "内部错误，请刷新页面。"
+
+msgid "Refresh"
+msgstr "刷新效力"
+
+msgid "Log Out"
+msgstr "登出"
+
+msgid "Your authentication code will expire in 60 seconds."
+msgstr "登录凭证将在 60 秒内过期，"
+
+msgid "Please use the following information to sign in immediately."
+msgstr "请立即使用以下信息登录。"
+
+msgid "WARNING: To sign in, use a web browser to open the page %s "
+msgstr "提醒：请使用浏览器打开 %s 进行登录操作，"
+
+msgid " and enter the code "
+msgstr "输入代码「"
+
+msgid " to authenticate."
+msgstr "」进行验证。"
+
+msgid "Manual Trigger"
+msgstr "手动触发"
+
+msgid "Failover"
+msgstr "失效转移"
+
+msgid "Recover"
+msgstr "恢复"
+
+msgid "Sub ID"
+msgstr "订阅ID"
+
+msgid "Resource Grop Name"
+msgstr "资源组名称"
+
+msgid "Source NIC Name"
+msgstr "源网卡名称"
+
+msgid "Destination NIC Name"
+msgstr "目标网卡名称"
+
+msgid "Monitored VM Name"
+msgstr "监控的虚拟机名称"
+
+msgid "Target IP When Running"
+msgstr "運行時的目標IP"
+
+msgid "Target IP When Deallocated"
+msgstr "解除分配時的目標IP"
+
+msgid "Level"
+msgstr "级别"
+
+msgid "Debug"
+msgstr "调试"
+
+msgid "Info"
+msgstr "信息"
+
+msgid "Download"
+msgstr "下载"
+
+msgid "On"
+msgstr "开启"
+
+msgid "Off"
+msgstr "关闭"
+
 #~ msgid "Graphs"
 #~ msgstr "图表"
 
@@ -5645,8 +5735,8 @@
 #~ msgid "©2021 Beijing Array Networks, Inc."
 #~ msgstr "©2021 北京华耀科技有限公司"
 
-#~ msgid "©2021 Array Networks, Inc."
-#~ msgstr "©2021 Array Networks公司"
+#~ msgid "©2025 Array Networks, Inc."
+#~ msgstr "©2025 Array Networks公司"
 
 #~ msgid "Signin"
 #~ msgstr "登录"
Index: /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/locale/zh_TW/LC_MESSAGES/django.po
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/locale/zh_TW/LC_MESSAGES/django.po	(revision 39037)
+++ /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/locale/zh_TW/LC_MESSAGES/django.po	(working copy)
@@ -1,5 +1,5 @@
 # Chinese (Simplified, China) translations for APV WebUI.
-# Copyright (C) 2020 Array Networks Inc.
+# Copyright (C) 2025 Array Networks Inc.
 # This file is distributed under the same license as the APV WebUI project.
 # Li Qian <qianli@arraynetworks.com.cn>, 2015.
 #
@@ -5635,6 +5635,96 @@
 msgid "Authentication Server is required."
 msgstr "認證服務器不能為空。"
 
+msgid "Cloud"
+msgstr "雲端服務"
+
+msgid "Log"
+msgstr "日誌"
+
+msgid "Login Url"
+msgstr "登入網址"
+
+msgid "Logged in"
+msgstr "已登入"
+
+msgid "Not logged in"
+msgstr "未登入"
+
+msgid "Code"
+msgstr "代碼"
+
+msgid "Internal error, please refresh the page."
+msgstr "內部錯誤，請重新整理網頁。"
+
+msgid "Refresh"
+msgstr "刷新時效"
+
+msgid "Log Out"
+msgstr "登出"
+
+msgid "Your authentication code will expire in 60 seconds."
+msgstr "登入憑證將在 60 秒內過期，"
+
+msgid "Please use the following information to sign in immediately."
+msgstr "請立刻用下列資訊登入。"
+
+msgid "WARNING: To sign in, use a web browser to open the page %s "
+msgstr "提醒：請用瀏覽器開啟 %s 進行登入動作，"
+
+msgid " and enter the code "
+msgstr "輸入代碼「"
+
+msgid " to authenticate."
+msgstr "」以進行驗證。"
+
+msgid "Manual Trigger"
+msgstr "手動觸發"
+
+msgid "Failover"
+msgstr "故障切換"
+
+msgid "Recover"
+msgstr "恢復"
+
+msgid "Sub ID"
+msgstr "訂閱ID"
+
+msgid "Resource Grop Name"
+msgstr "資源群組名稱"
+
+msgid "Source NIC Name"
+msgstr "源網卡名稱"
+
+msgid "Destination NIC Name"
+msgstr "目標網卡名稱"
+
+msgid "Monitored VM Name"
+msgstr "監控的虛擬機名稱"
+
+msgid "Target IP When Running"
+msgstr "執行時的目標IP"
+
+msgid "Target IP When Deallocated"
+msgstr "解除配置時的目標IP"
+
+msgid "Level"
+msgstr "級別"
+
+msgid "Debug"
+msgstr "除錯"
+
+msgid "Info"
+msgstr "一般訊息"
+
+msgid "Download"
+msgstr "下載"
+
+msgid "On"
+msgstr "開啟"
+
+msgid "Off"
+msgstr "關閉"
+
 #~ msgid "Graphs"
 #~ msgstr "圖表"
 
@@ -5677,7 +5767,7 @@
 #~ msgid "©2021 Beijing Array Networks, Inc."
 #~ msgstr ""
 
-#~ msgid "©2021 Array Networks, Inc."
+#~ msgid "©2025 Array Networks, Inc."
 #~ msgstr ""
 
 #~ msgid "Signin"
