mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Merge remote-tracking branch 'origin/4.16'
Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com>
This commit is contained in:
commit
c84198d76d
2
debian/control
vendored
2
debian/control
vendored
@ -22,7 +22,7 @@ Description: CloudStack server library
|
||||
|
||||
Package: cloudstack-agent
|
||||
Architecture: all
|
||||
Depends: ${python:Depends}, ${python3:Depends}, openjdk-11-jre-headless | java11-runtime-headless | java11-runtime | openjdk-11-jre-headless | zulu-11, cloudstack-common (= ${source:Version}), lsb-base (>= 9), openssh-client, qemu-kvm (>= 2.5), libvirt-bin (>= 1.3) | libvirt-daemon-system (>= 3.0), iproute2, ebtables, vlan, ipset, python3-libvirt, ethtool, iptables, lsb-release, aria2, ufw, apparmor
|
||||
Depends: ${python:Depends}, ${python3:Depends}, openjdk-11-jre-headless | java11-runtime-headless | java11-runtime | openjdk-11-jre-headless | zulu-11, cloudstack-common (= ${source:Version}), lsb-base (>= 9), openssh-client, qemu-kvm (>= 2.5) | qemu-system-x86 (>= 5.2), libvirt-bin (>= 1.3) | libvirt-daemon-system (>= 3.0), iproute2, ebtables, vlan, ipset, python3-libvirt, ethtool, iptables, lsb-release, aria2, ufw, apparmor
|
||||
Recommends: init-system-helpers
|
||||
Conflicts: cloud-agent, cloud-agent-libs, cloud-agent-deps, cloud-agent-scripts
|
||||
Description: CloudStack agent
|
||||
|
||||
@ -3714,10 +3714,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
||||
return null;
|
||||
}
|
||||
|
||||
if (_guestCpuArch != null && _guestCpuArch.equals("aarch64")) {
|
||||
return DiskDef.DiskBus.SCSI;
|
||||
}
|
||||
|
||||
String rootDiskController = details.get(VmDetailConstants.ROOT_DISK_CONTROLLER);
|
||||
if (StringUtils.isNotBlank(rootDiskController)) {
|
||||
s_logger.debug("Passed custom disk controller for ROOT disk " + rootDiskController);
|
||||
@ -3751,10 +3747,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
||||
}
|
||||
|
||||
private DiskDef.DiskBus getGuestDiskModel(final String platformEmulator, boolean isUefiEnabled) {
|
||||
if (_guestCpuArch != null && _guestCpuArch.equals("aarch64")) {
|
||||
return DiskDef.DiskBus.SCSI;
|
||||
}
|
||||
|
||||
if (platformEmulator == null) {
|
||||
return DiskDef.DiskBus.IDE;
|
||||
} else if (platformEmulator.startsWith("Other PV Virtio-SCSI")) {
|
||||
@ -3765,6 +3757,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
||||
return DiskDef.DiskBus.VIRTIO;
|
||||
} else if (isUefiEnabled && StringUtils.startsWithAny(platformEmulator, "Windows", "Other")) {
|
||||
return DiskDef.DiskBus.SATA;
|
||||
} else if (_guestCpuArch != null && _guestCpuArch.equals("aarch64")) {
|
||||
return DiskDef.DiskBus.SCSI;
|
||||
} else {
|
||||
return DiskDef.DiskBus.IDE;
|
||||
}
|
||||
|
||||
@ -420,7 +420,7 @@ public class LibvirtComputingResourceTest {
|
||||
public void testCreateDevicesWithSCSIDisk() {
|
||||
VirtualMachineTO to = createDefaultVM(false);
|
||||
to.setDetails(new HashMap<>());
|
||||
libvirtComputingResourceSpy._guestCpuArch = "aarch64";
|
||||
to.setPlatformEmulator("Other PV Virtio-SCSI");
|
||||
|
||||
GuestDef guest = new GuestDef();
|
||||
guest.setGuestType(GuestType.KVM);
|
||||
|
||||
@ -629,7 +629,7 @@ public class ScaleIOPrimaryDataStoreDriver implements PrimaryDataStoreDriver {
|
||||
|
||||
private Answer copyTemplateToVolume(DataObject srcData, DataObject destData, Host destHost) {
|
||||
// Copy PowerFlex/ScaleIO template to volume
|
||||
LOGGER.debug("Initiating copy from PowerFlex template volume on host " + destHost != null ? destHost.getId() : "");
|
||||
LOGGER.debug(String.format("Initiating copy from PowerFlex template volume on host %s", destHost != null ? destHost.getId() : "<not specified>"));
|
||||
int primaryStorageDownloadWait = StorageManager.PRIMARY_STORAGE_DOWNLOAD_WAIT.value();
|
||||
CopyCommand cmd = new CopyCommand(srcData.getTO(), destData.getTO(), primaryStorageDownloadWait, VirtualMachineManager.ExecuteInSequence.value());
|
||||
|
||||
@ -648,7 +648,7 @@ public class ScaleIOPrimaryDataStoreDriver implements PrimaryDataStoreDriver {
|
||||
|
||||
private Answer copyVolume(DataObject srcData, DataObject destData, Host destHost) {
|
||||
// Copy PowerFlex/ScaleIO volume
|
||||
LOGGER.debug("Initiating copy from PowerFlex volume on host " + destHost != null ? destHost.getId() : "");
|
||||
LOGGER.debug(String.format("Initiating copy from PowerFlex template volume on host %s", destHost != null ? destHost.getId() : "<not specified>"));
|
||||
String value = configDao.getValue(Config.CopyVolumeWait.key());
|
||||
int copyVolumeWait = NumbersUtil.parseInt(value, Integer.parseInt(Config.CopyVolumeWait.getDefaultValue()));
|
||||
|
||||
|
||||
@ -3152,6 +3152,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
||||
SearchCriteria<ServiceOfferingJoinVO> cpuSearchCriteria = _srvOfferingJoinDao.createSearchCriteria();
|
||||
cpuSearchCriteria.addOr("minCpu", Op.NULL);
|
||||
cpuSearchCriteria.addOr("constraints", Op.SC, cpuConstraintSearchCriteria);
|
||||
cpuSearchCriteria.addOr("minCpu", Op.GTEQ, cpuNumber);
|
||||
|
||||
sc.addAnd("cpuConstraints", SearchCriteria.Op.SC, cpuSearchCriteria);
|
||||
}
|
||||
@ -3164,6 +3165,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
||||
SearchCriteria<ServiceOfferingJoinVO> memSearchCriteria = _srvOfferingJoinDao.createSearchCriteria();
|
||||
memSearchCriteria.addOr("minMemory", Op.NULL);
|
||||
memSearchCriteria.addOr("memconstraints", Op.SC, memoryConstraintSearchCriteria);
|
||||
memSearchCriteria.addOr("minMemory", Op.GTEQ, memory);
|
||||
|
||||
sc.addAnd("memoryConstraints", SearchCriteria.Op.SC, memSearchCriteria);
|
||||
}
|
||||
@ -3171,7 +3173,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
||||
if (cpuSpeed != null) {
|
||||
SearchCriteria<ServiceOfferingJoinVO> cpuSpeedSearchCriteria = _srvOfferingJoinDao.createSearchCriteria();
|
||||
cpuSpeedSearchCriteria.addOr("speed", Op.NULL);
|
||||
cpuSpeedSearchCriteria.addOr("speed", Op.EQ, cpuSpeed);
|
||||
cpuSpeedSearchCriteria.addOr("speed", Op.GTEQ, cpuSpeed);
|
||||
sc.addAnd("cpuspeedconstraints", SearchCriteria.Op.SC, cpuSpeedSearchCriteria);
|
||||
}
|
||||
|
||||
|
||||
@ -259,9 +259,17 @@ public abstract class LibvirtServerDiscoverer extends DiscovererBase implements
|
||||
sshConnection = new Connection(agentIp, 22);
|
||||
|
||||
sshConnection.connect(null, 60000, 60000);
|
||||
|
||||
final String privateKey = _configDao.getValue("ssh.privatekey");
|
||||
if (!SSHCmdHelper.acquireAuthorizedConnectionWithPublicKey(sshConnection, username, privateKey)) {
|
||||
s_logger.error("Failed to authenticate with ssh key");
|
||||
if (org.apache.commons.lang3.StringUtils.isEmpty(password)) {
|
||||
throw new DiscoveredWithErrorException("Authentication error with ssh private key");
|
||||
}
|
||||
if (!sshConnection.authenticateWithPassword(username, password)) {
|
||||
s_logger.debug("Failed to authenticate");
|
||||
throw new DiscoveredWithErrorException("Authentication error");
|
||||
s_logger.error("Failed to authenticate with password");
|
||||
throw new DiscoveredWithErrorException("Authentication error with host password");
|
||||
}
|
||||
}
|
||||
|
||||
if (!SSHCmdHelper.sshExecuteCmd(sshConnection, "ls /dev/kvm")) {
|
||||
|
||||
@ -165,7 +165,8 @@ import com.cloud.storage.dao.StoragePoolHostDao;
|
||||
import com.cloud.storage.dao.VMTemplateDao;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountManager;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.Ternary;
|
||||
import com.cloud.utils.StringUtils;
|
||||
import com.cloud.utils.UriUtils;
|
||||
import com.cloud.utils.component.Manager;
|
||||
import com.cloud.utils.component.ManagerBase;
|
||||
@ -695,10 +696,17 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
throw new InvalidParameterValueException("Can't specify cluster without specifying the pod");
|
||||
}
|
||||
List<String> skipList = Arrays.asList(HypervisorType.VMware.name().toLowerCase(Locale.ROOT), Type.SecondaryStorage.name().toLowerCase(Locale.ROOT));
|
||||
if (!skipList.contains(hypervisorType.toLowerCase(Locale.ROOT)) &&
|
||||
(StringUtils.isAnyEmpty(username, password))) {
|
||||
if (!skipList.contains(hypervisorType.toLowerCase(Locale.ROOT))) {
|
||||
if (HypervisorType.KVM.toString().equalsIgnoreCase(hypervisorType)) {
|
||||
if (org.apache.commons.lang3.StringUtils.isBlank(username)) {
|
||||
throw new InvalidParameterValueException("Username need to be provided.");
|
||||
}
|
||||
} else {
|
||||
if (org.apache.commons.lang3.StringUtils.isBlank(username) || org.apache.commons.lang3.StringUtils.isBlank(password)) {
|
||||
throw new InvalidParameterValueException("Username and Password need to be provided.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (clusterId != null) {
|
||||
if (_clusterDao.findById(clusterId) == null) {
|
||||
@ -2731,8 +2739,8 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
}
|
||||
final boolean sshToAgent = Boolean.parseBoolean(_configDao.getValue(KvmSshToAgentEnabled.key()));
|
||||
if (sshToAgent) {
|
||||
Pair<String, String> credentials = getHostCredentials(host);
|
||||
connectAndRestartAgentOnHost(host, credentials.first(), credentials.second());
|
||||
Ternary<String, String, String> credentials = getHostCredentials(host);
|
||||
connectAndRestartAgentOnHost(host, credentials.first(), credentials.second(), credentials.third());
|
||||
} else {
|
||||
throw new CloudRuntimeException("SSH access is disabled, cannot cancel maintenance mode as " +
|
||||
"host agent is not connected");
|
||||
@ -2743,22 +2751,23 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
* Get host credentials
|
||||
* @throws CloudRuntimeException if username or password are not found
|
||||
*/
|
||||
protected Pair<String, String> getHostCredentials(HostVO host) {
|
||||
protected Ternary<String, String, String> getHostCredentials(HostVO host) {
|
||||
_hostDao.loadDetails(host);
|
||||
final String password = host.getDetail("password");
|
||||
final String username = host.getDetail("username");
|
||||
if (password == null || username == null) {
|
||||
throw new CloudRuntimeException("SSH to agent is enabled, but username/password credentials are not found");
|
||||
final String privateKey = _configDao.getValue("ssh.privatekey");
|
||||
if ((password == null && privateKey == null) || username == null) {
|
||||
throw new CloudRuntimeException("SSH to agent is enabled, but username and password or private key are not found");
|
||||
}
|
||||
return new Pair<>(username, password);
|
||||
return new Ternary<>(username, password, privateKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* True if agent is restarted via SSH. Assumes kvm.ssh.to.agent = true and host status is not Up
|
||||
*/
|
||||
protected void connectAndRestartAgentOnHost(HostVO host, String username, String password) {
|
||||
protected void connectAndRestartAgentOnHost(HostVO host, String username, String password, String privateKey) {
|
||||
final com.trilead.ssh2.Connection connection = SSHCmdHelper.acquireAuthorizedConnection(
|
||||
host.getPrivateIpAddress(), 22, username, password);
|
||||
host.getPrivateIpAddress(), 22, username, password, privateKey);
|
||||
if (connection == null) {
|
||||
throw new CloudRuntimeException(String.format("SSH to agent is enabled, but failed to connect to %s via IP address [%s].", host, host.getPrivateIpAddress()));
|
||||
}
|
||||
|
||||
@ -2136,6 +2136,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
||||
if (hostIds.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
Collections.shuffle(hostIds);
|
||||
|
||||
for (Long hostId : hostIds) {
|
||||
Host host = _hostDao.findById(hostId);
|
||||
|
||||
@ -67,7 +67,7 @@ import com.cloud.host.Status;
|
||||
import com.cloud.host.dao.HostDao;
|
||||
import com.cloud.hypervisor.Hypervisor;
|
||||
import com.cloud.storage.StorageManager;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.Ternary;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.utils.fsm.NoTransitionException;
|
||||
import com.cloud.utils.ssh.SSHCmdHelper;
|
||||
@ -125,6 +125,7 @@ public class ResourceManagerImplTest {
|
||||
private static long hostId = 1L;
|
||||
private static final String hostUsername = "user";
|
||||
private static final String hostPassword = "password";
|
||||
private static final String hostPrivateKey = "privatekey";
|
||||
private static final String hostPrivateIp = "192.168.1.10";
|
||||
|
||||
private static long vm1Id = 1L;
|
||||
@ -148,6 +149,7 @@ public class ResourceManagerImplTest {
|
||||
when(hostDao.findById(hostId)).thenReturn(host);
|
||||
when(host.getDetail("username")).thenReturn(hostUsername);
|
||||
when(host.getDetail("password")).thenReturn(hostPassword);
|
||||
when(configurationDao.getValue("ssh.privatekey")).thenReturn(hostPrivateKey);
|
||||
when(host.getStatus()).thenReturn(Status.Up);
|
||||
when(host.getPrivateIpAddress()).thenReturn(hostPrivateIp);
|
||||
when(vm1.getId()).thenReturn(vm1Id);
|
||||
@ -171,7 +173,7 @@ public class ResourceManagerImplTest {
|
||||
|
||||
PowerMockito.mockStatic(SSHCmdHelper.class);
|
||||
BDDMockito.given(SSHCmdHelper.acquireAuthorizedConnection(eq(hostPrivateIp), eq(22),
|
||||
eq(hostUsername), eq(hostPassword))).willReturn(sshConnection);
|
||||
eq(hostUsername), eq(hostPassword), eq(hostPrivateKey))).willReturn(sshConnection);
|
||||
BDDMockito.given(SSHCmdHelper.sshExecuteCmdOneShot(eq(sshConnection),
|
||||
eq("service cloudstack-agent restart"))).
|
||||
willReturn(new SSHCmdHelper.SSHCmdResult(0,"",""));
|
||||
@ -292,34 +294,36 @@ public class ResourceManagerImplTest {
|
||||
@Test(expected = CloudRuntimeException.class)
|
||||
public void testGetHostCredentialsMissingParameter() {
|
||||
when(host.getDetail("password")).thenReturn(null);
|
||||
when(configurationDao.getValue("ssh.privatekey")).thenReturn(null);
|
||||
resourceManager.getHostCredentials(host);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetHostCredentials() {
|
||||
Pair<String, String> credentials = resourceManager.getHostCredentials(host);
|
||||
Ternary<String, String, String> credentials = resourceManager.getHostCredentials(host);
|
||||
Assert.assertNotNull(credentials);
|
||||
Assert.assertEquals(hostUsername, credentials.first());
|
||||
Assert.assertEquals(hostPassword, credentials.second());
|
||||
Assert.assertEquals(hostPrivateKey, credentials.third());
|
||||
}
|
||||
|
||||
@Test(expected = CloudRuntimeException.class)
|
||||
public void testConnectAndRestartAgentOnHostCannotConnect() {
|
||||
BDDMockito.given(SSHCmdHelper.acquireAuthorizedConnection(eq(hostPrivateIp), eq(22),
|
||||
eq(hostUsername), eq(hostPassword))).willReturn(null);
|
||||
resourceManager.connectAndRestartAgentOnHost(host, hostUsername, hostPassword);
|
||||
eq(hostUsername), eq(hostPassword), eq(hostPrivateKey))).willReturn(null);
|
||||
resourceManager.connectAndRestartAgentOnHost(host, hostUsername, hostPassword, hostPrivateKey);
|
||||
}
|
||||
|
||||
@Test(expected = CloudRuntimeException.class)
|
||||
public void testConnectAndRestartAgentOnHostCannotRestart() throws Exception {
|
||||
BDDMockito.given(SSHCmdHelper.sshExecuteCmdOneShot(eq(sshConnection),
|
||||
eq("service cloudstack-agent restart"))).willThrow(new SshException("exception"));
|
||||
resourceManager.connectAndRestartAgentOnHost(host, hostUsername, hostPassword);
|
||||
resourceManager.connectAndRestartAgentOnHost(host, hostUsername, hostPassword, hostPrivateKey);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConnectAndRestartAgentOnHost() {
|
||||
resourceManager.connectAndRestartAgentOnHost(host, hostUsername, hostPassword);
|
||||
resourceManager.connectAndRestartAgentOnHost(host, hostUsername, hostPassword, hostPrivateKey);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -327,7 +331,7 @@ public class ResourceManagerImplTest {
|
||||
when(host.getStatus()).thenReturn(Status.Disconnected);
|
||||
resourceManager.handleAgentIfNotConnected(host, false);
|
||||
verify(resourceManager).getHostCredentials(eq(host));
|
||||
verify(resourceManager).connectAndRestartAgentOnHost(eq(host), eq(hostUsername), eq(hostPassword));
|
||||
verify(resourceManager).connectAndRestartAgentOnHost(eq(host), eq(hostUsername), eq(hostPassword), eq(hostPrivateKey));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -335,7 +339,7 @@ public class ResourceManagerImplTest {
|
||||
when(host.getStatus()).thenReturn(Status.Up);
|
||||
resourceManager.handleAgentIfNotConnected(host, false);
|
||||
verify(resourceManager, never()).getHostCredentials(eq(host));
|
||||
verify(resourceManager, never()).connectAndRestartAgentOnHost(eq(host), eq(hostUsername), eq(hostPassword));
|
||||
verify(resourceManager, never()).connectAndRestartAgentOnHost(eq(host), eq(hostUsername), eq(hostPassword), eq(hostPrivateKey));
|
||||
}
|
||||
|
||||
@Test(expected = CloudRuntimeException.class)
|
||||
@ -351,14 +355,14 @@ public class ResourceManagerImplTest {
|
||||
when(configurationDao.getValue(ResourceManager.KvmSshToAgentEnabled.key())).thenReturn("false");
|
||||
resourceManager.handleAgentIfNotConnected(host, false);
|
||||
verify(resourceManager, never()).getHostCredentials(eq(host));
|
||||
verify(resourceManager, never()).connectAndRestartAgentOnHost(eq(host), eq(hostUsername), eq(hostPassword));
|
||||
verify(resourceManager, never()).connectAndRestartAgentOnHost(eq(host), eq(hostUsername), eq(hostPassword), eq(hostPrivateKey));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandleAgentVMsMigrating() {
|
||||
resourceManager.handleAgentIfNotConnected(host, true);
|
||||
verify(resourceManager, never()).getHostCredentials(eq(host));
|
||||
verify(resourceManager, never()).connectAndRestartAgentOnHost(eq(host), eq(hostUsername), eq(hostPassword));
|
||||
verify(resourceManager, never()).connectAndRestartAgentOnHost(eq(host), eq(hostUsername), eq(hostPassword), eq(hostPrivateKey));
|
||||
}
|
||||
|
||||
private void setupNoPendingMigrationRetries() {
|
||||
|
||||
@ -635,7 +635,7 @@ class ConfigDriveUtils:
|
||||
"""
|
||||
ssh.execute("umount -d %s" % mount_path)
|
||||
# Give the VM time to unlock the iso device
|
||||
time.sleep(2)
|
||||
time.sleep(0.5)
|
||||
# Verify umount
|
||||
result = ssh.execute("ls %s" % mount_path)
|
||||
self.assertTrue(len(result) == 0,
|
||||
@ -1089,10 +1089,8 @@ class ConfigDriveUtils:
|
||||
|
||||
vm.details = vm_new_ssh.details
|
||||
|
||||
# reset SSH key also resets the password.
|
||||
self._decrypt_password(vm)
|
||||
|
||||
vm.password_test = ConfigDriveUtils.PasswordTest(vm=vm)
|
||||
# reset SSH key also removes the password (see https://github.com/apache/cloudstack/pull/4819)
|
||||
vm.password_test = ConfigDriveUtils.PasswordTest(expect_pw=False)
|
||||
vm.key_pair = self.keypair
|
||||
|
||||
if public_ip:
|
||||
@ -1119,7 +1117,7 @@ class ConfigDriveUtils:
|
||||
cipher = PKCS1_v1_5.new(key)
|
||||
new_password = cipher.decrypt(b64decode(password_), None)
|
||||
if new_password:
|
||||
vm.password = new_password
|
||||
vm.password = new_password.decode()
|
||||
else:
|
||||
self.fail("Failed to decrypt new password")
|
||||
except ImportError:
|
||||
@ -1511,7 +1509,6 @@ class TestConfigDrive(cloudstackTestCase, ConfigDriveUtils):
|
||||
tries = 1 if negative_test else 3
|
||||
private_key_file_location = keypair.private_key_file if keypair else None
|
||||
|
||||
@retry(tries=tries)
|
||||
def retry_ssh():
|
||||
ssh_client = vm.get_ssh_client(
|
||||
ipaddress=public_ip.ipaddress.ipaddress,
|
||||
@ -1732,8 +1729,7 @@ class TestConfigDrive(cloudstackTestCase, ConfigDriveUtils):
|
||||
self.api_client.restartVPC(cmd)
|
||||
self.debug("Restarted VPC with ID - %s" % vpc.id)
|
||||
|
||||
# was tags=["advanced", "isonw"]
|
||||
@attr(tags=["TODO"], required_hardware="true")
|
||||
@attr(tags=["advanced", "isonw"], required_hardware="true")
|
||||
def test_configdrive_isolated_network(self):
|
||||
"""Test Configdrive as provider for isolated Networks
|
||||
to provide userdata and password reset functionality
|
||||
@ -2500,6 +2496,7 @@ class TestConfigDrive(cloudstackTestCase, ConfigDriveUtils):
|
||||
# =====================================================================
|
||||
self.debug("+++ Scenario: "
|
||||
"validate updated userdata after migrate")
|
||||
time.sleep(30)
|
||||
host = self.migrate_VM(vm)
|
||||
vm.hostname = host.name
|
||||
self.then_config_drive_is_as_expected(vm, public_ip_1, metadata=True)
|
||||
|
||||
1
ui/public/config.json
vendored
1
ui/public/config.json
vendored
@ -10,6 +10,7 @@
|
||||
"docBase": "http://docs.cloudstack.apache.org/en/latest",
|
||||
"appTitle": "CloudStack",
|
||||
"footer": "Licensed under the <a href='http://www.apache.org/licenses/' target='_blank'>Apache License</a>, Version 2.0.",
|
||||
"loginFooter": "",
|
||||
"logo": "assets/logo.svg",
|
||||
"banner": "assets/banner.svg",
|
||||
"error": {
|
||||
|
||||
@ -468,6 +468,8 @@
|
||||
"label.associatednetworkid": "Associated Network ID",
|
||||
"label.associatednetworkname": "Network Name",
|
||||
"label.asyncbackup": "Async Backup",
|
||||
"label.authentication.method": "Authentication Method",
|
||||
"label.authentication.sshkey": "System SSH Key",
|
||||
"label.author.email": "Author e-mail",
|
||||
"label.author.name": "Author name",
|
||||
"label.auto.assign": "Automatically assign",
|
||||
@ -577,6 +579,7 @@
|
||||
"label.cks.cluster.size": "Cluster size (Worker nodes)",
|
||||
"label.cleanup": "Clean up",
|
||||
"label.clear": "Clear",
|
||||
"label.clear.notification": "Clear notification",
|
||||
"label.clear.list": "Clear list",
|
||||
"label.close": "Close",
|
||||
"label.cloud.console": "Cloud Management Console",
|
||||
@ -2595,6 +2598,7 @@
|
||||
"message.add.firewall.rule.processing": "Adding new Firewall rule...",
|
||||
"message.add.guest.network": "Please confirm that you would like to add a guest network",
|
||||
"message.add.host": "Please specify the following parameters to add a new host",
|
||||
"message.add.host.sshkey": "WARNING: In order to add a host with SSH key, you must ensure your hypervisor host has been configured correctly.",
|
||||
"message.add.ip.range": "Add an IP range to public network in zone",
|
||||
"message.add.ip.range.direct.network": "Add an IP range to direct network <b><span id=\"directnetwork_name\"></span></b> in zone <b><span id=\"zone_name\"></span></b>",
|
||||
"message.add.ip.range.to.pod": "<p>Add an IP range to pod: <b><span id=\"pod_name_label\"></span></b></p>",
|
||||
|
||||
@ -20,7 +20,6 @@
|
||||
<a-row :gutter="6">
|
||||
<a-col :md="24" :lg="layout === 'horizontal' ? 12 : 24">
|
||||
<a-checkbox
|
||||
v-decorator="[checkBoxDecorator, {}]"
|
||||
:checked="checked"
|
||||
@change="handleCheckChange">
|
||||
{{ checkBoxLabel }}
|
||||
@ -31,8 +30,7 @@
|
||||
v-if="reversed != checked"
|
||||
:label="selectLabel">
|
||||
<a-select
|
||||
v-decorator="[selectDecorator, { initialValue: selectedOption ? selectedOption : getSelectInitialValue()}]"
|
||||
:defaultValue="selectDecorator ? undefined : selectedOption ? selectedOption : getSelectInitialValue()"
|
||||
v-model="selectedOption"
|
||||
showSearch
|
||||
optionFilterProp="children"
|
||||
:filterOption="(input, option) => {
|
||||
@ -69,10 +67,6 @@ export default {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
checkBoxDecorator: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
defaultCheckBoxValue: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
@ -85,10 +79,6 @@ export default {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
selectDecorator: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
reversed: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
@ -97,12 +87,21 @@ export default {
|
||||
data () {
|
||||
return {
|
||||
checked: false,
|
||||
selectedOption: null
|
||||
selectedOption: null,
|
||||
selectOptionsTimer: null
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.checked = this.defaultCheckBoxValue
|
||||
},
|
||||
watch: {
|
||||
selectOptions () {
|
||||
clearTimeout(this.selectOptionsTimer)
|
||||
this.selectOptionsTimer = setTimeout(() => {
|
||||
this.handleSelectOptionsUpdated()
|
||||
}, 50)
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
selectSource () {
|
||||
return this.selectOptions.map(item => {
|
||||
@ -118,18 +117,23 @@ export default {
|
||||
arrayHasItems (array) {
|
||||
return array !== null && array !== undefined && Array.isArray(array) && array.length > 0
|
||||
},
|
||||
getSelectInitialValue () {
|
||||
const initialValue = this.selectSource?.filter(x => x.enabled !== false)?.[0]?.id || ''
|
||||
this.handleSelectChange(initialValue)
|
||||
return initialValue
|
||||
},
|
||||
handleCheckChange (e) {
|
||||
this.checked = e.target.checked
|
||||
if (this.checked && !this.selectedOption) {
|
||||
this.selectedOption = this.selectSource?.filter(x => x.enabled !== false)?.[0]?.id || null
|
||||
}
|
||||
this.$emit('handle-checkselectpair-change', this.resourceKey, this.checked, this.selectedOption)
|
||||
},
|
||||
handleSelectChange (val) {
|
||||
this.selectedOption = val
|
||||
this.$emit('handle-checkselectpair-change', this.resourceKey, this.checked, this.selectedOption)
|
||||
},
|
||||
handleSelectOptionsUpdated () {
|
||||
if (!this.checked) return
|
||||
var enabledOptions = this.selectSource?.filter(x => x.enabled !== false) || []
|
||||
if (this.selectedOption && !enabledOptions.includes(this.selectedOption)) {
|
||||
this.handleSelectChange(enabledOptions[0]?.id || null)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,7 +84,8 @@ export default {
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
image: ''
|
||||
image: '',
|
||||
countNotify: 0
|
||||
}
|
||||
},
|
||||
created () {
|
||||
@ -92,6 +93,12 @@ export default {
|
||||
eventBus.$on('refresh-header', () => {
|
||||
this.getIcon()
|
||||
})
|
||||
this.$store.watch(
|
||||
(state, getters) => getters.countNotify,
|
||||
(newValue, oldValue) => {
|
||||
this.countNotify = newValue
|
||||
}
|
||||
)
|
||||
},
|
||||
watch: {
|
||||
image () {
|
||||
@ -137,6 +144,10 @@ export default {
|
||||
description: err.message
|
||||
})
|
||||
})
|
||||
},
|
||||
clearAllNotify () {
|
||||
this.$store.commit('SET_COUNT_NOTIFY', 0)
|
||||
this.$notification.destroy()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -91,6 +91,13 @@
|
||||
/>
|
||||
</a-affix>
|
||||
|
||||
<a-button
|
||||
v-if="showClear"
|
||||
type="default"
|
||||
size="small"
|
||||
class="button-clear-notification"
|
||||
@click="onClearNotification">{{ $t('label.clear.notification') }}</a-button>
|
||||
|
||||
<!-- layout content -->
|
||||
<a-layout-content class="layout-content" :class="{'is-header-fixed': fixedHeader}">
|
||||
<slot></slot>
|
||||
@ -128,7 +135,8 @@ export default {
|
||||
return {
|
||||
collapsed: false,
|
||||
menus: [],
|
||||
showSetting: false
|
||||
showSetting: false,
|
||||
showClear: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@ -161,6 +169,12 @@ export default {
|
||||
} else {
|
||||
document.body.classList.remove('dark-mode')
|
||||
}
|
||||
},
|
||||
'$store.getters.countNotify' (countNotify) {
|
||||
this.showClear = false
|
||||
if (countNotify && countNotify > 0) {
|
||||
this.showClear = true
|
||||
}
|
||||
}
|
||||
},
|
||||
provide: function () {
|
||||
@ -212,6 +226,10 @@ export default {
|
||||
},
|
||||
toggleSetting (showSetting) {
|
||||
this.showSetting = showSetting
|
||||
},
|
||||
onClearNotification () {
|
||||
this.$notification.destroy()
|
||||
this.$store.commit('SET_COUNT_NOTIFY', 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -219,7 +219,8 @@ export default {
|
||||
apiName = 'updateTemplate'
|
||||
}
|
||||
if (!(apiName in this.$store.getters.apis)) {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('error.execute.api.failed') + ' ' + apiName,
|
||||
description: this.$t('message.user.not.permitted.api')
|
||||
})
|
||||
|
||||
@ -651,7 +651,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="account-center-tags" v-if="!isStatic && resourceType && 'listTags' in $store.getters.apis">
|
||||
<div class="account-center-tags" v-if="!isStatic && resourceType && tagsSupportingResourceTypes.includes(this.resourceType) && 'listTags' in $store.getters.apis">
|
||||
<a-divider/>
|
||||
<a-spin :spinning="loadingTags">
|
||||
<div class="title">{{ $t('label.tags') }}</div>
|
||||
@ -772,11 +772,13 @@ export default {
|
||||
this.showKeys = false
|
||||
this.setData()
|
||||
|
||||
if (this.tagsSupportingResourceTypes.includes(this.resourceType)) {
|
||||
if ('tags' in this.resource) {
|
||||
this.tags = this.resource.tags
|
||||
} else if (this.resourceType) {
|
||||
this.getTags()
|
||||
}
|
||||
}
|
||||
if ('apikey' in this.resource) {
|
||||
this.getUserKeys()
|
||||
}
|
||||
@ -794,6 +796,12 @@ export default {
|
||||
await this.getIcons()
|
||||
},
|
||||
computed: {
|
||||
tagsSupportingResourceTypes () {
|
||||
return ['UserVm', 'Template', 'ISO', 'Volume', 'Snapshot', 'Backup', 'Network',
|
||||
'LoadBalancer', 'PortForwardingRule', 'FirewallRule', 'SecurityGroup', 'SecurityGroupRule',
|
||||
'PublicIpAddress', 'Project', 'Account', 'Vpc', 'NetworkACL', 'StaticRoute', 'VMSnapshot',
|
||||
'RemoteAccessVpn', 'User', 'SnapshotPolicy', 'VpcOffering']
|
||||
},
|
||||
name () {
|
||||
return this.resource.displayname || this.resource.displaytext || this.resource.name || this.resource.username ||
|
||||
this.resource.ipaddress || this.resource.virtualmachinename || this.resource.templatetype
|
||||
|
||||
@ -514,7 +514,8 @@ export default {
|
||||
json.updateconfigurationresponse.configuration &&
|
||||
!json.updateconfigurationresponse.configuration.isdynamic &&
|
||||
['Admin'].includes(this.$store.getters.userInfo.roletype)) {
|
||||
this.$notification.warning({
|
||||
this.$showNotification({
|
||||
type: 'warning',
|
||||
message: this.$t('label.status'),
|
||||
description: this.$t('message.restart.mgmt.server')
|
||||
})
|
||||
|
||||
@ -107,7 +107,8 @@ export default {
|
||||
this.dataResource = await this.listResourceLimits(params)
|
||||
this.formLoading = false
|
||||
} catch (e) {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('message.request.failed'),
|
||||
description: e
|
||||
})
|
||||
|
||||
@ -164,7 +164,8 @@ export default {
|
||||
}).catch(error => {
|
||||
console.error(error)
|
||||
this.$message.error(this.$t('message.error.save.setting'))
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('label.error'),
|
||||
description: this.$t('message.error.try.save.setting')
|
||||
})
|
||||
|
||||
@ -234,13 +234,15 @@ export default {
|
||||
}).then(json => {
|
||||
console.log(this.resource)
|
||||
if (json?.uploadresourceiconresponse?.success) {
|
||||
this.$notification.success({
|
||||
this.$showNotification({
|
||||
type: 'success',
|
||||
message: this.$t('label.upload.icon'),
|
||||
description: `${this.$t('message.success.upload.icon')} ${resourceType}: ` + (this.resource.name || this.resource.username || resourceid)
|
||||
})
|
||||
}
|
||||
}).catch((error) => {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('label.upload.icon'),
|
||||
description: error?.response?.data?.uploadresourceiconresponse?.errortext || '',
|
||||
duration: 0
|
||||
@ -264,13 +266,15 @@ export default {
|
||||
resourceids: resourceid
|
||||
}).then(json => {
|
||||
if (json?.deleteresourceiconresponse?.success) {
|
||||
this.$notification.success({
|
||||
this.$showNotification({
|
||||
type: 'success',
|
||||
message: this.$t('label.delete.icon'),
|
||||
description: `${this.$t('message.success.delete.icon')} ${resourceType}: ` + (this.resource.name || this.resource.username || resourceid)
|
||||
})
|
||||
}
|
||||
}).catch((error) => {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('label.delete.icon'),
|
||||
description: error?.response?.data?.deleteresourceiconresponse?.errortext || '',
|
||||
duration: 0
|
||||
|
||||
@ -152,7 +152,8 @@ export default {
|
||||
const vm = result.jobresult.virtualmachine || {}
|
||||
if (result.jobstatus === 1 && vm.password) {
|
||||
const name = vm.displayname || vm.name || vm.id
|
||||
obj.$notification.success({
|
||||
obj.$showNotification({
|
||||
type: 'success',
|
||||
message: `${obj.$t('label.reinstall.vm')}: ` + name,
|
||||
description: `${obj.$t('label.password.reset.confirm')}: ` + vm.password,
|
||||
duration: 0
|
||||
@ -361,7 +362,8 @@ export default {
|
||||
const vm = result.jobresult.virtualmachine || {}
|
||||
if (result.jobstatus === 1 && vm.password) {
|
||||
const name = vm.displayname || vm.name || vm.id
|
||||
obj.$notification.success({
|
||||
obj.$showNotification({
|
||||
type: 'success',
|
||||
message: `${obj.$t('label.reset.ssh.key.pair.on.vm')}: ` + name,
|
||||
description: `${obj.$t('label.password.reset.confirm')}: ` + vm.password,
|
||||
duration: 0
|
||||
|
||||
@ -17,6 +17,12 @@
|
||||
|
||||
<template>
|
||||
<div id="userLayout" :class="['user-layout', device]">
|
||||
<a-button
|
||||
v-if="showClear"
|
||||
type="default"
|
||||
size="small"
|
||||
class="button-clear-notification"
|
||||
@click="onClearNotification">{{ $t('label.clear.notification') }}</a-button>
|
||||
<div class="user-layout-container">
|
||||
<div class="user-layout-header">
|
||||
<img
|
||||
@ -31,6 +37,9 @@
|
||||
</div>
|
||||
<route-view></route-view>
|
||||
</div>
|
||||
<div class="user-layout-footer" v-if="$config.loginFooter">
|
||||
<label v-html="$config.loginFooter"></label>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -45,7 +54,9 @@ export default {
|
||||
components: { RouteView },
|
||||
mixins: [mixinDevice],
|
||||
data () {
|
||||
return {}
|
||||
return {
|
||||
showClear: false
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'$store.getters.darkMode' (darkMode) {
|
||||
@ -54,6 +65,12 @@ export default {
|
||||
} else {
|
||||
document.body.classList.remove('dark-mode')
|
||||
}
|
||||
},
|
||||
'$store.getters.countNotify' (countNotify) {
|
||||
this.showClear = false
|
||||
if (countNotify && countNotify > 0) {
|
||||
this.showClear = true
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
@ -66,6 +83,12 @@ export default {
|
||||
beforeDestroy () {
|
||||
document.body.classList.remove('userLayout')
|
||||
document.body.classList.remove('dark-mode')
|
||||
},
|
||||
methods: {
|
||||
onClearNotification () {
|
||||
this.$notification.destroy()
|
||||
this.$store.commit('SET_COUNT_NOTIFY', 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -97,5 +120,25 @@ export default {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
&-footer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: absolute;
|
||||
bottom: 20px;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
|
||||
@media (max-height: 600px) {
|
||||
position: relative;
|
||||
margin-top: 50px;
|
||||
}
|
||||
|
||||
label {
|
||||
width: 368px;
|
||||
font-weight: 500;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -78,10 +78,19 @@ router.beforeEach((to, from, next) => {
|
||||
})
|
||||
})
|
||||
.catch(() => {
|
||||
let countNotify = store.getters.countNotify
|
||||
countNotify++
|
||||
store.commit('SET_COUNT_NOTIFY', countNotify)
|
||||
notification.error({
|
||||
top: '65px',
|
||||
message: 'Error',
|
||||
description: i18n.t('message.error.discovering.feature'),
|
||||
duration: 0
|
||||
duration: 0,
|
||||
onClose: () => {
|
||||
let countNotify = store.getters.countNotify
|
||||
countNotify > 0 ? countNotify-- : countNotify = 0
|
||||
store.commit('SET_COUNT_NOTIFY', countNotify)
|
||||
}
|
||||
})
|
||||
store.dispatch('Logout').then(() => {
|
||||
next({ path: '/user/login', query: { redirect: to.fullPath } })
|
||||
|
||||
@ -40,7 +40,8 @@ const getters = {
|
||||
domainStore: state => state.user.domainStore,
|
||||
darkMode: state => state.user.darkMode,
|
||||
themeSetting: state => state.user.themeSetting,
|
||||
defaultListViewPageSize: state => state.user.defaultListViewPageSize
|
||||
defaultListViewPageSize: state => state.user.defaultListViewPageSize,
|
||||
countNotify: state => state.user.countNotify
|
||||
}
|
||||
|
||||
export default getters
|
||||
|
||||
@ -55,7 +55,8 @@ const user = {
|
||||
domainStore: {},
|
||||
darkMode: false,
|
||||
themeSetting: {},
|
||||
defaultListViewPageSize: 20
|
||||
defaultListViewPageSize: 20,
|
||||
countNotify: 0
|
||||
},
|
||||
|
||||
mutations: {
|
||||
@ -121,6 +122,9 @@ const user = {
|
||||
},
|
||||
SET_DEFAULT_LISTVIEW_PAGE_SIZE: (state, defaultListViewPageSize) => {
|
||||
state.defaultListViewPageSize = defaultListViewPageSize
|
||||
},
|
||||
SET_COUNT_NOTIFY (state, number) {
|
||||
state.countNotify = number
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@ -901,4 +901,8 @@
|
||||
.ant-empty-normal {
|
||||
color: @dark-text-color-3;
|
||||
}
|
||||
|
||||
.button-clear-notification {
|
||||
background-color: @dark-secondary-bgColor;
|
||||
}
|
||||
}
|
||||
@ -344,3 +344,10 @@ a {
|
||||
border-color: @primary-color;
|
||||
}
|
||||
}
|
||||
|
||||
.button-clear-notification {
|
||||
position: fixed;
|
||||
right: 287px;
|
||||
top: 35px;
|
||||
z-index: 1001;
|
||||
}
|
||||
|
||||
@ -132,11 +132,20 @@ export const pollJobPlugin = {
|
||||
desc = `(${name}) ${desc}`
|
||||
}
|
||||
if (!bulkAction) {
|
||||
let countNotify = store.getters.countNotify
|
||||
countNotify++
|
||||
store.commit('SET_COUNT_NOTIFY', countNotify)
|
||||
notification.error({
|
||||
top: '65px',
|
||||
message: errMessage,
|
||||
description: desc,
|
||||
key: jobId,
|
||||
duration: 0
|
||||
duration: 0,
|
||||
onClose: () => {
|
||||
let countNotify = store.getters.countNotify
|
||||
countNotify > 0 ? countNotify-- : countNotify = 0
|
||||
store.commit('SET_COUNT_NOTIFY', countNotify)
|
||||
}
|
||||
})
|
||||
}
|
||||
store.dispatch('AddHeaderNotice', {
|
||||
@ -168,10 +177,19 @@ export const pollJobPlugin = {
|
||||
}
|
||||
}).catch(e => {
|
||||
console.error(`${catchMessage} - ${e}`)
|
||||
let countNotify = store.getters.countNotify
|
||||
countNotify++
|
||||
store.commit('SET_COUNT_NOTIFY', countNotify)
|
||||
notification.error({
|
||||
top: '65px',
|
||||
message: i18n.t('label.error'),
|
||||
description: catchMessage,
|
||||
duration: 0
|
||||
duration: 0,
|
||||
onClose: () => {
|
||||
let countNotify = store.getters.countNotify
|
||||
countNotify > 0 ? countNotify-- : countNotify = 0
|
||||
store.commit('SET_COUNT_NOTIFY', countNotify)
|
||||
}
|
||||
})
|
||||
catchMethod && catchMethod()
|
||||
})
|
||||
@ -203,12 +221,50 @@ export const notifierPlugin = {
|
||||
}
|
||||
}
|
||||
}
|
||||
let countNotify = store.getters.countNotify
|
||||
countNotify++
|
||||
store.commit('SET_COUNT_NOTIFY', countNotify)
|
||||
notification.error({
|
||||
top: '65px',
|
||||
message: msg,
|
||||
description: desc,
|
||||
duration: 0
|
||||
duration: 0,
|
||||
onClose: () => {
|
||||
let countNotify = store.getters.countNotify
|
||||
countNotify > 0 ? countNotify-- : countNotify = 0
|
||||
store.commit('SET_COUNT_NOTIFY', countNotify)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Vue.prototype.$showNotification = function (config) {
|
||||
let countNotify = store.getters.countNotify
|
||||
countNotify++
|
||||
store.commit('SET_COUNT_NOTIFY', countNotify)
|
||||
const defaultConfig = {
|
||||
top: '65px',
|
||||
onClose: () => {
|
||||
let countNotify = store.getters.countNotify
|
||||
countNotify > 0 ? countNotify-- : countNotify = 0
|
||||
store.commit('SET_COUNT_NOTIFY', countNotify)
|
||||
}
|
||||
}
|
||||
config = Object.assign({}, defaultConfig, config)
|
||||
switch (config.type) {
|
||||
case 'info':
|
||||
notification.info(config)
|
||||
break
|
||||
case 'error':
|
||||
notification.error(config)
|
||||
break
|
||||
case 'success':
|
||||
notification.success(config)
|
||||
break
|
||||
case 'warning':
|
||||
notification.warning(config)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -30,11 +30,23 @@ const service = axios.create({
|
||||
|
||||
const err = (error) => {
|
||||
const response = error.response
|
||||
let countNotify = store.getters.countNotify
|
||||
if (response) {
|
||||
console.log(response)
|
||||
if (response.status === 403) {
|
||||
const data = response.data
|
||||
notification.error({ message: i18n.t('label.forbidden'), description: data.message })
|
||||
countNotify++
|
||||
store.commit('SET_COUNT_NOTIFY', countNotify)
|
||||
notification.error({
|
||||
top: '65px',
|
||||
message: i18n.t('label.forbidden'),
|
||||
description: data.message,
|
||||
onClose: () => {
|
||||
let countNotify = store.getters.countNotify
|
||||
countNotify > 0 ? countNotify-- : countNotify = 0
|
||||
store.commit('SET_COUNT_NOTIFY', countNotify)
|
||||
}
|
||||
})
|
||||
}
|
||||
if (response.status === 401) {
|
||||
if (response.config && response.config.params && ['listIdps', 'cloudianIsEnabled'].includes(response.config.params.command)) {
|
||||
@ -43,20 +55,36 @@ const err = (error) => {
|
||||
for (const key in response.data) {
|
||||
if (key.includes('response')) {
|
||||
if (response.data[key].errortext.includes('not available for user')) {
|
||||
countNotify++
|
||||
store.commit('SET_COUNT_NOTIFY', countNotify)
|
||||
notification.error({
|
||||
top: '65px',
|
||||
message: 'Error',
|
||||
description: response.data[key].errortext + ' ' + i18n.t('error.unable.to.proceed'),
|
||||
duration: 0
|
||||
duration: 0,
|
||||
onClose: () => {
|
||||
let countNotify = store.getters.countNotify
|
||||
countNotify > 0 ? countNotify-- : countNotify = 0
|
||||
store.commit('SET_COUNT_NOTIFY', countNotify)
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
countNotify++
|
||||
store.commit('SET_COUNT_NOTIFY', countNotify)
|
||||
notification.error({
|
||||
top: '65px',
|
||||
message: i18n.t('label.unauthorized'),
|
||||
description: i18n.t('message.authorization.failed'),
|
||||
key: 'http-401',
|
||||
duration: 0
|
||||
duration: 0,
|
||||
onClose: () => {
|
||||
let countNotify = store.getters.countNotify
|
||||
countNotify > 0 ? countNotify-- : countNotify = 0
|
||||
store.commit('SET_COUNT_NOTIFY', countNotify)
|
||||
}
|
||||
})
|
||||
store.dispatch('Logout').then(() => {
|
||||
if (router.history.current.path !== '/user/login') {
|
||||
@ -65,15 +93,34 @@ const err = (error) => {
|
||||
})
|
||||
}
|
||||
if (response.status === 404) {
|
||||
notification.error({ message: i18n.t('label.not.found'), description: i18n.t('message.resource.not.found') })
|
||||
countNotify++
|
||||
store.commit('SET_COUNT_NOTIFY', countNotify)
|
||||
notification.error({
|
||||
top: '65px',
|
||||
message: i18n.t('label.not.found'),
|
||||
description: i18n.t('message.resource.not.found'),
|
||||
onClose: () => {
|
||||
let countNotify = store.getters.countNotify
|
||||
countNotify > 0 ? countNotify-- : countNotify = 0
|
||||
store.commit('SET_COUNT_NOTIFY', countNotify)
|
||||
}
|
||||
})
|
||||
router.push({ path: '/exception/404' })
|
||||
}
|
||||
}
|
||||
if (error.isAxiosError && !error.response) {
|
||||
countNotify++
|
||||
store.commit('SET_COUNT_NOTIFY', countNotify)
|
||||
notification.warn({
|
||||
top: '65px',
|
||||
message: error.message || i18n.t('message.network.error'),
|
||||
description: i18n.t('message.network.error.description'),
|
||||
key: 'network-error'
|
||||
key: 'network-error',
|
||||
onClose: () => {
|
||||
let countNotify = store.getters.countNotify
|
||||
countNotify > 0 ? countNotify-- : countNotify = 0
|
||||
store.commit('SET_COUNT_NOTIFY', countNotify)
|
||||
}
|
||||
})
|
||||
}
|
||||
return Promise.reject(error)
|
||||
|
||||
@ -1128,7 +1128,8 @@ export default {
|
||||
if (action.response) {
|
||||
const description = action.response(result.jobresult)
|
||||
if (description) {
|
||||
this.$notification.info({
|
||||
this.$showNotification({
|
||||
type: 'info',
|
||||
message: this.$t(action.label),
|
||||
description: (<span domPropsInnerHTML={description}></span>),
|
||||
duration: 0
|
||||
|
||||
@ -294,7 +294,8 @@ export default {
|
||||
[variableKey]: variableValue,
|
||||
networkids: this.selectedNetwork
|
||||
}).then(response => {
|
||||
this.$notification.success({
|
||||
this.$showNotification({
|
||||
type: 'success',
|
||||
message: this.$t('label.loadbalancerinstance')
|
||||
})
|
||||
this.$parent.$parent.close()
|
||||
|
||||
@ -149,7 +149,8 @@ export default {
|
||||
id: this.resource.id,
|
||||
affinitygroupids: this.selectedRowKeys.join(',')
|
||||
}).then(response => {
|
||||
this.$notification.success({
|
||||
this.$showNotification({
|
||||
type: 'success',
|
||||
message: this.$t('message.success.change.affinity.group')
|
||||
})
|
||||
this.$parent.$parent.close()
|
||||
|
||||
@ -198,7 +198,8 @@ export default {
|
||||
this.hiddenElement.click()
|
||||
},
|
||||
notifyCopied () {
|
||||
this.$notification.info({
|
||||
this.$showNotification({
|
||||
type: 'info',
|
||||
message: this.$t('message.success.copy.clipboard')
|
||||
})
|
||||
},
|
||||
|
||||
@ -141,7 +141,8 @@ export default {
|
||||
const volumeId = result.jobresult.snapshot.volumeid
|
||||
const snapshotId = result.jobresult.snapshot.id
|
||||
const message = `${this.$t('label.create.snapshot.for.volume')} ${volumeId} ${this.$t('label.with.snapshotid')} ${snapshotId}`
|
||||
this.$notification.success({
|
||||
this.$showNotification({
|
||||
type: 'success',
|
||||
message: message,
|
||||
duration: 0
|
||||
})
|
||||
|
||||
@ -1133,7 +1133,9 @@ export default {
|
||||
this.vm.hostname = host.name
|
||||
}
|
||||
|
||||
if (this.diskSize) {
|
||||
if (this.serviceOffering.rootdisksize) {
|
||||
this.vm.disksizetotalgb = this.serviceOffering.rootdisksize
|
||||
} else if (this.diskSize) {
|
||||
this.vm.disksizetotalgb = this.diskSize
|
||||
}
|
||||
|
||||
@ -1489,14 +1491,16 @@ export default {
|
||||
this.form.validateFieldsAndScroll(options, async (err, values) => {
|
||||
if (err) {
|
||||
if (err.licensesaccepted) {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('message.license.agreements.not.accepted'),
|
||||
description: this.$t('message.step.license.agreements.continue')
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('message.request.failed'),
|
||||
description: this.$t('error.form.message')
|
||||
})
|
||||
@ -1504,27 +1508,31 @@ export default {
|
||||
}
|
||||
|
||||
if (!values.templateid && !values.isoid) {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('message.request.failed'),
|
||||
description: this.$t('message.template.iso')
|
||||
})
|
||||
return
|
||||
} else if (values.isoid && (!values.diskofferingid || values.diskofferingid === '0')) {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('message.request.failed'),
|
||||
description: this.$t('message.step.3.continue')
|
||||
})
|
||||
return
|
||||
}
|
||||
if (!values.computeofferingid) {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('message.request.failed'),
|
||||
description: this.$t('message.step.2.continue')
|
||||
})
|
||||
return
|
||||
}
|
||||
if (this.error) {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('message.request.failed'),
|
||||
description: this.$t('error.form.message')
|
||||
})
|
||||
@ -1637,7 +1645,8 @@ export default {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('message.request.failed'),
|
||||
description: this.$t('message.step.4.continue')
|
||||
})
|
||||
@ -1699,7 +1708,8 @@ export default {
|
||||
const vm = result.jobresult.virtualmachine
|
||||
const name = vm.displayname || vm.name || vm.id
|
||||
if (vm.password) {
|
||||
this.$notification.success({
|
||||
this.$showNotification({
|
||||
type: 'success',
|
||||
message: password + ` ${this.$t('label.for')} ` + name,
|
||||
description: vm.password,
|
||||
duration: 0
|
||||
|
||||
@ -321,7 +321,8 @@ export default {
|
||||
config.configdata !== '') {
|
||||
this.clusterConfig = config.configdata
|
||||
} else {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('message.request.failed'),
|
||||
description: this.$t('message.error.retrieve.kubeconfig')
|
||||
})
|
||||
|
||||
@ -306,7 +306,8 @@ export default {
|
||||
})
|
||||
this.closeModal()
|
||||
}).catch(error => {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('message.request.failed'),
|
||||
description: (error.response && error.response.headers && error.response.headers['x-description']) || error.message,
|
||||
duration: 0
|
||||
|
||||
@ -166,7 +166,8 @@ export default {
|
||||
this.$pollJob({
|
||||
jobId,
|
||||
successMethod: result => {
|
||||
this.$notification.success({
|
||||
this.$showNotification({
|
||||
type: 'success',
|
||||
message: this.$t('message.success.change.offering')
|
||||
})
|
||||
},
|
||||
|
||||
@ -143,7 +143,8 @@ export default {
|
||||
api('listPods', params).then(json => {
|
||||
this.pods = json.listpodsresponse.pod || []
|
||||
if (this.pods.length === 0) {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: 'No pods found',
|
||||
duration: 0
|
||||
})
|
||||
@ -162,7 +163,8 @@ export default {
|
||||
api('listClusters', params).then(json => {
|
||||
this.clusters = json.listclustersresponse.cluster || []
|
||||
if (this.clusters.length === 0) {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: 'No clusters found',
|
||||
duration: 0
|
||||
})
|
||||
@ -184,7 +186,8 @@ export default {
|
||||
api('listHosts', params).then(json => {
|
||||
this.hosts = json.listhostsresponse.host || []
|
||||
if (this.hosts.length === 0) {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: 'No hosts found',
|
||||
duration: 0
|
||||
})
|
||||
|
||||
@ -157,7 +157,8 @@ export default {
|
||||
this.actionLoading = true
|
||||
api('deleteBackupSchedule', params).then(json => {
|
||||
if (json.deletebackupscheduleresponse.success) {
|
||||
this.$notification.success({
|
||||
this.$showNotification({
|
||||
type: 'success',
|
||||
message: this.$t('label.scheduled.backups'),
|
||||
description: this.$t('message.success.delete.backup.schedule')
|
||||
})
|
||||
|
||||
@ -284,7 +284,8 @@ export default {
|
||||
}
|
||||
this.actionLoading = true
|
||||
api('createBackupSchedule', params).then(json => {
|
||||
this.$notification.success({
|
||||
this.$showNotification({
|
||||
type: 'success',
|
||||
message: this.$t('label.scheduled.backups'),
|
||||
description: this.$t('message.success.config.backup.schedule')
|
||||
})
|
||||
|
||||
@ -157,11 +157,11 @@ export default {
|
||||
(item.iscustomized === true && maxCpuNumber < this.minimumCpunumber))) {
|
||||
disabled = true
|
||||
}
|
||||
if (disabled === false && this.minimumCpuspeed > 0 && maxCpuSpeed && maxCpuSpeed !== this.minimumCpuspeed) {
|
||||
if (disabled === false && this.minimumCpuspeed > 0 && maxCpuSpeed && maxCpuSpeed < this.minimumCpuspeed) {
|
||||
disabled = true
|
||||
}
|
||||
if (disabled === false && maxMemory && this.minimumMemory > 0 &&
|
||||
((item.iscustomized === false && maxMemory !== this.minimumMemory) ||
|
||||
((item.iscustomized === false && maxMemory < this.minimumMemory) ||
|
||||
(item.iscustomized === true && maxMemory < this.minimumMemory))) {
|
||||
disabled = true
|
||||
}
|
||||
|
||||
@ -266,7 +266,8 @@ export default {
|
||||
this.domainsList = response.listdomainsresponse.domain || []
|
||||
this.selectedDomain = this.domainsList[0].id || ''
|
||||
}).catch(error => {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: `${this.$t('label.error')} ${error.response.status}`,
|
||||
description: error.response.data.errorresponse.errortext
|
||||
})
|
||||
@ -341,7 +342,8 @@ export default {
|
||||
|
||||
api('createAccount', {}, 'POST', params).then(response => {
|
||||
this.$emit('refresh-data')
|
||||
this.$notification.success({
|
||||
this.$showNotification({
|
||||
type: 'success',
|
||||
message: this.$t('label.create.account'),
|
||||
description: `${this.$t('message.success.create.account')} ${params.username}`
|
||||
})
|
||||
@ -353,12 +355,14 @@ export default {
|
||||
entityid: values.samlentity,
|
||||
userid: users[i].id
|
||||
}).then(response => {
|
||||
this.$notification.success({
|
||||
this.$showNotification({
|
||||
type: 'success',
|
||||
message: this.$t('label.samlenable'),
|
||||
description: this.$t('message.success.enable.saml.auth')
|
||||
})
|
||||
}).catch(error => {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('message.request.failed'),
|
||||
description: (error.response && error.response.headers && error.response.headers['x-description']) || error.message,
|
||||
duration: 0
|
||||
@ -368,7 +372,8 @@ export default {
|
||||
}
|
||||
this.closeAction()
|
||||
}).catch(error => {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('message.request.failed'),
|
||||
description: (error.response && error.response.headers && error.response.headers['x-description']) || error.message,
|
||||
duration: 0
|
||||
|
||||
@ -410,13 +410,15 @@ export default {
|
||||
this.authorizeUsersForSamlSSO(users, entityId)
|
||||
}
|
||||
} else if (apiName === 'importLdapUsers' && response.ldapuserresponse && values.samlEnable) {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('message.request.failed'),
|
||||
description: this.$t('message.error.enable.saml')
|
||||
})
|
||||
} else {
|
||||
if (apiName === 'ldapCreateAccount') {
|
||||
this.$notification.success({
|
||||
this.$showNotification({
|
||||
type: 'success',
|
||||
message: this.$t('label.add.ldap.account'),
|
||||
description: response.createaccountresponse.account.name
|
||||
})
|
||||
|
||||
@ -238,7 +238,8 @@ export default {
|
||||
this.domainsList = response.listdomainsresponse.domain || []
|
||||
this.selectedDomain = this.domainsList[0].id || ''
|
||||
}).catch(error => {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: `${this.$t('label.error')} ${error.response.status}`,
|
||||
description: error.response.data.errorresponse.errortext
|
||||
})
|
||||
@ -252,7 +253,8 @@ export default {
|
||||
api('listAccounts', { listAll: true, showicon: true }).then(response => {
|
||||
this.accountList = response.listaccountsresponse.account || []
|
||||
}).catch(error => {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: `${this.$t('label.error')} ${error.response.status}`,
|
||||
description: error.response.data.errorresponse.errortext
|
||||
})
|
||||
@ -319,7 +321,8 @@ export default {
|
||||
|
||||
api('createUser', {}, 'POST', params).then(response => {
|
||||
this.$emit('refresh-data')
|
||||
this.$notification.success({
|
||||
this.$showNotification({
|
||||
type: 'success',
|
||||
message: this.$t('label.create.user'),
|
||||
description: `${this.$t('message.success.create.user')} ${params.username}`
|
||||
})
|
||||
@ -330,12 +333,14 @@ export default {
|
||||
entityid: values.samlentity,
|
||||
userid: user.id
|
||||
}).then(response => {
|
||||
this.$notification.success({
|
||||
this.$showNotification({
|
||||
type: 'success',
|
||||
message: this.$t('label.samlenable'),
|
||||
description: this.$t('message.success.enable.saml.auth')
|
||||
})
|
||||
}).catch(error => {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('message.request.failed'),
|
||||
description: (error.response && error.response.headers && error.response.headers['x-description']) || error.message,
|
||||
duration: 0
|
||||
@ -344,7 +349,8 @@ export default {
|
||||
}
|
||||
this.closeAction()
|
||||
}).catch(error => {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('message.request.failed'),
|
||||
description: (error.response && error.response.headers && error.response.headers['x-description']) || error.message,
|
||||
duration: 0
|
||||
|
||||
@ -128,7 +128,8 @@ export default {
|
||||
params.currentpassword = values.currentpassword
|
||||
}
|
||||
api('updateUser', {}, 'POST', params).then(json => {
|
||||
this.$notification.success({
|
||||
this.$showNotification({
|
||||
type: 'success',
|
||||
message: this.$t('label.action.change.password'),
|
||||
description: `${this.$t('message.success.change.password')} ${this.resource.username}`
|
||||
})
|
||||
|
||||
@ -108,14 +108,16 @@ export default {
|
||||
userid: this.resource.id,
|
||||
entityid: values.samlEntity
|
||||
}).then(response => {
|
||||
this.$notification.success({
|
||||
this.$showNotification({
|
||||
type: 'success',
|
||||
message: values.samlEnable ? this.$t('label.saml.enable') : this.$t('label.saml.disable'),
|
||||
description: values.samlEnable ? `${this.$t('message.success.enable.saml.auth')} ${this.$t('label.for')} ${this.resource.username}`
|
||||
: `${this.$t('message.success.disable.saml.auth')} ${this.$t('label.for')} ${this.resource.username}`
|
||||
})
|
||||
this.handleClose()
|
||||
}).catch(error => {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('message.request.failed'),
|
||||
description: (error.response && error.response.headers && error.response.headers['x-description']) || error.message,
|
||||
duration: 0
|
||||
|
||||
@ -174,7 +174,8 @@ export default {
|
||||
const role = json.createroleresponse.role
|
||||
if (role) {
|
||||
this.$emit('refresh-data')
|
||||
this.$notification.success({
|
||||
this.$showNotification({
|
||||
type: 'success',
|
||||
message: 'Create Role',
|
||||
description: 'Sucessfully created role ' + params.name
|
||||
})
|
||||
|
||||
@ -253,7 +253,8 @@ export default {
|
||||
if (this.action.response) {
|
||||
const description = this.action.response(result.jobresult)
|
||||
if (description) {
|
||||
this.$notification.info({
|
||||
this.$showNotification({
|
||||
type: 'info',
|
||||
message: this.$t(this.action.label),
|
||||
description: (<span domPropsInnerHTML={description}></span>),
|
||||
duration: 0
|
||||
@ -289,7 +290,8 @@ export default {
|
||||
}
|
||||
this.parentCloseAction()
|
||||
}).catch(error => {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('message.request.failed'),
|
||||
description: (error.response && error.response.headers && error.response.headers['x-description']) || error.message
|
||||
})
|
||||
|
||||
@ -187,7 +187,8 @@ export default {
|
||||
return
|
||||
}
|
||||
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('message.request.failed'),
|
||||
description: error.response.headers['x-description'],
|
||||
duration: 0
|
||||
|
||||
@ -178,13 +178,15 @@ export default {
|
||||
|
||||
api('updateUser', params).then(response => {
|
||||
this.$emit('refresh-data')
|
||||
this.$notification.success({
|
||||
this.$showNotification({
|
||||
type: 'success',
|
||||
message: this.$t('label.edit.user'),
|
||||
description: `${this.$t('message.success.update.user')} ${params.username}`
|
||||
})
|
||||
this.closeAction()
|
||||
}).catch(error => {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('message.request.failed'),
|
||||
description: (error.response && error.response.headers && error.response.headers['x-description']) || error.message,
|
||||
duration: 0
|
||||
|
||||
@ -128,7 +128,8 @@ export default {
|
||||
},
|
||||
handleChange (info) {
|
||||
if (info.file.status === 'error') {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('label.error.file.upload'),
|
||||
description: this.$t('label.error.file.upload')
|
||||
})
|
||||
@ -185,7 +186,8 @@ export default {
|
||||
const role = json.importroleresponse.role
|
||||
if (role) {
|
||||
this.$emit('refresh-data')
|
||||
this.$notification.success({
|
||||
this.$showNotification({
|
||||
type: 'success',
|
||||
message: 'Import Role',
|
||||
description: 'Sucessfully imported role ' + params.name
|
||||
})
|
||||
|
||||
@ -455,7 +455,8 @@ export default {
|
||||
catchMessage: this.$t('error.fetching.async.job.result')
|
||||
})
|
||||
}).catch(error => {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('message.request.failed'),
|
||||
description: (error.response && error.response.headers && error.response.headers['x-description']) || error.message
|
||||
})
|
||||
|
||||
@ -265,7 +265,8 @@ export default {
|
||||
handleUpload () {
|
||||
const { fileList } = this
|
||||
if (this.fileList.length > 1) {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('message.upload.iso.failed'),
|
||||
description: this.$t('message.error.upload.iso.description'),
|
||||
duration: 0
|
||||
@ -290,14 +291,16 @@ export default {
|
||||
},
|
||||
timeout: 86400000
|
||||
}).then((json) => {
|
||||
this.$notification.success({
|
||||
this.$showNotification({
|
||||
type: 'success',
|
||||
message: this.$t('message.success.upload'),
|
||||
description: this.$t('message.success.upload.description')
|
||||
})
|
||||
this.closeAction()
|
||||
this.$emit('refresh-data')
|
||||
}).catch(e => {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('message.upload.failed'),
|
||||
description: `${this.$t('message.upload.iso.failed.description')} - ${e}`,
|
||||
duration: 0
|
||||
@ -342,7 +345,8 @@ export default {
|
||||
if (this.currentForm === 'Create') {
|
||||
this.loading = true
|
||||
api('registerIso', params).then(json => {
|
||||
this.$notification.success({
|
||||
this.$showNotification({
|
||||
type: 'success',
|
||||
message: this.$t('label.action.register.iso'),
|
||||
description: `${this.$t('message.success.register.iso')} ${params.name}`
|
||||
})
|
||||
@ -363,7 +367,8 @@ export default {
|
||||
this.uploadParams = (json.postuploadisoresponse && json.postuploadisoresponse.getuploadparams) ? json.postuploadisoresponse.getuploadparams : ''
|
||||
const response = this.handleUpload()
|
||||
if (response === 'upload successful') {
|
||||
this.$notification.success({
|
||||
this.$showNotification({
|
||||
type: 'success',
|
||||
message: this.$t('message.success.upload'),
|
||||
description: this.$t('message.success.upload.iso.description')
|
||||
})
|
||||
|
||||
@ -511,14 +511,16 @@ export default {
|
||||
},
|
||||
timeout: 86400000
|
||||
}).then((json) => {
|
||||
this.$notification.success({
|
||||
this.$showNotification({
|
||||
type: 'success',
|
||||
message: this.$t('message.success.upload'),
|
||||
description: this.$t('message.success.upload.template.description')
|
||||
})
|
||||
this.$emit('refresh-data')
|
||||
this.closeAction()
|
||||
}).catch(e => {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('message.upload.failed'),
|
||||
description: `${this.$t('message.upload.template.failed.description')} - ${e}`,
|
||||
duration: 0
|
||||
@ -887,7 +889,8 @@ export default {
|
||||
if (this.currentForm === 'Create') {
|
||||
this.loading = true
|
||||
api('registerTemplate', params).then(json => {
|
||||
this.$notification.success({
|
||||
this.$showNotification({
|
||||
type: 'success',
|
||||
message: this.$t('label.register.template'),
|
||||
description: `${this.$t('message.success.register.template')} ${params.name}`
|
||||
})
|
||||
@ -901,7 +904,8 @@ export default {
|
||||
} else {
|
||||
this.loading = true
|
||||
if (this.fileList.length > 1) {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('message.error.upload.template'),
|
||||
description: this.$t('message.error.upload.template.description'),
|
||||
duration: 0
|
||||
|
||||
@ -554,7 +554,8 @@ export default {
|
||||
catchMessage: this.$t('error.fetching.async.job.result')
|
||||
})
|
||||
}).catch(error => {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('message.request.failed'),
|
||||
description: (error.response && error.response.headers && error.response.headers['x-description']) || error.message
|
||||
})
|
||||
|
||||
@ -289,7 +289,8 @@ export default {
|
||||
featured: this.resource.featured,
|
||||
op: this.selectedOperation.toLowerCase()
|
||||
}).then(response => {
|
||||
this.$notification.success({
|
||||
this.$showNotification({
|
||||
type: 'success',
|
||||
message: `${this.$t('label.success.updated')} ${resourceType} ${this.$t('label.permissions')}`
|
||||
})
|
||||
this.closeModal()
|
||||
|
||||
@ -709,7 +709,8 @@ export default {
|
||||
}
|
||||
this.loading = true
|
||||
api('createStoragePool', {}, 'POST', params).then(json => {
|
||||
this.$notification.success({
|
||||
this.$showNotification({
|
||||
type: 'success',
|
||||
message: this.$t('label.add.primary.storage'),
|
||||
description: this.$t('label.add.primary.storage')
|
||||
})
|
||||
|
||||
@ -293,7 +293,8 @@ export default {
|
||||
|
||||
this.loading = true
|
||||
api('addImageStore', data).then(json => {
|
||||
this.$notification.success({
|
||||
this.$showNotification({
|
||||
type: 'success',
|
||||
message: this.$t('label.add.secondary.storage'),
|
||||
description: this.$t('label.add.secondary.storage')
|
||||
})
|
||||
|
||||
@ -257,7 +257,8 @@ export default {
|
||||
}
|
||||
this.addCluster()
|
||||
}).catch(error => {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: `${this.$t('label.error')} ${error.response.status}`,
|
||||
description: error.response.data.listvmwaredcsresponse.errortext,
|
||||
duration: 0
|
||||
@ -308,7 +309,8 @@ export default {
|
||||
this.parentToggleLoading()
|
||||
this.$parent.$parent.close()
|
||||
}).catch(error => {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: `${this.$t('label.error')} ${error.response.status}`,
|
||||
description: error.response.data.addclusterresponse.errortext,
|
||||
duration: 0
|
||||
@ -343,7 +345,8 @@ export default {
|
||||
}
|
||||
})
|
||||
}).catch(error => {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: `${this.$t('label.error')} ${error.response.status}`,
|
||||
description: error.response.data.errorresponse.errortext,
|
||||
duration: 0
|
||||
|
||||
@ -94,7 +94,30 @@
|
||||
<a-input :placeholder="placeholder.username" v-model="username"></a-input>
|
||||
</div>
|
||||
|
||||
<div class="form__item required-field" v-if="selectedClusterHyperVisorType !== 'VMware'">
|
||||
<div class="form__item" v-if="selectedClusterHyperVisorType !== 'VMware'">
|
||||
<div class="form__label"><span class="required">* </span>{{ $t('label.authentication.method') }}</div>
|
||||
<a-radio-group
|
||||
v-decorator="['authmethod', {
|
||||
initialValue: authMethod
|
||||
}]"
|
||||
buttonStyle="solid"
|
||||
:defaultValue="authMethod"
|
||||
@change="selected => { handleAuthMethodChange(selected.target.value) }">
|
||||
<a-radio-button value="password">
|
||||
{{ $t('label.password') }}
|
||||
</a-radio-button>
|
||||
<a-radio-button value="sshkey" v-if="selectedClusterHyperVisorType === 'KVM'">
|
||||
{{ $t('label.authentication.sshkey') }}
|
||||
</a-radio-button>
|
||||
</a-radio-group>
|
||||
<span v-if="authMethod === 'sshkey'">
|
||||
<a-alert type="warning">
|
||||
<span style="display:block;width:300px;word-wrap:break-word;" slot="message" v-html="$t('message.add.host.sshkey')" />
|
||||
</a-alert>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="form__item required-field" v-if="selectedClusterHyperVisorType !== 'VMware' && authMethod === 'password'">
|
||||
<div class="form__label"><span class="required">* </span>{{ $t('label.password') }}</div>
|
||||
<span class="required required-label">{{ $t('label.required') }}</span>
|
||||
<a-input :placeholder="placeholder.password" type="password" v-model="password"></a-input>
|
||||
@ -190,6 +213,7 @@ export default {
|
||||
agentusername: null,
|
||||
agentpassword: null,
|
||||
agentport: null,
|
||||
authMethod: 'password',
|
||||
selectedCluster: null,
|
||||
selectedClusterHyperVisorType: null,
|
||||
showDedicated: false,
|
||||
@ -280,6 +304,9 @@ export default {
|
||||
this.dedicatedAccount = null
|
||||
this.showDedicated = !this.showDedicated
|
||||
},
|
||||
handleAuthMethodChange (val) {
|
||||
this.authMethod = val
|
||||
},
|
||||
handleSubmitForm () {
|
||||
if (this.loading) return
|
||||
const requiredFields = document.querySelectorAll('.required-field')
|
||||
@ -306,6 +333,10 @@ export default {
|
||||
this.url = this.hostname
|
||||
}
|
||||
|
||||
if (this.authMethod !== 'password') {
|
||||
this.password = ''
|
||||
}
|
||||
|
||||
const args = {
|
||||
zoneid: this.zoneId,
|
||||
podid: this.podId,
|
||||
@ -331,7 +362,8 @@ export default {
|
||||
this.parentFetchData()
|
||||
this.$parent.$parent.close()
|
||||
}).catch(error => {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: `${this.$t('label.error')} ${error.response.status}`,
|
||||
description: error.response.data.addhostresponse.errortext,
|
||||
duration: 0
|
||||
@ -366,7 +398,8 @@ export default {
|
||||
}
|
||||
})
|
||||
}).catch(error => {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: `${this.$t('label.error')} ${error.response.status}`,
|
||||
description: error.response.data.errorresponse.errortext,
|
||||
duration: 0
|
||||
|
||||
@ -241,12 +241,14 @@ export default {
|
||||
const result = json.queryasyncjobresultresponse
|
||||
if (result.jobstatus === 1 && this.maxCerts === count) {
|
||||
this.$message.success(`${this.$t('label.certificate.upload')}: ${result.jobresult.customcertificate.message}`)
|
||||
this.$notification.success({
|
||||
this.$showNotification({
|
||||
type: 'success',
|
||||
message: this.$t('label.certificate.upload'),
|
||||
description: result.jobresult.customcertificate.message || this.$t('message.success.certificate.upload')
|
||||
})
|
||||
} else if (result.jobstatus === 2) {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('label.certificate.upload.failed'),
|
||||
description: result.jobresult.errortext || this.$t('label.certificate.upload.failed.description'),
|
||||
duration: 0
|
||||
|
||||
@ -154,12 +154,14 @@ export default {
|
||||
const success = result.imagestore.success || false
|
||||
const message = result.imagestore.message || ''
|
||||
if (success) {
|
||||
this.$notification.success({
|
||||
this.$showNotification({
|
||||
type: 'success',
|
||||
message: title,
|
||||
description: message
|
||||
})
|
||||
} else {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: title,
|
||||
description: message,
|
||||
duration: 0
|
||||
|
||||
@ -207,7 +207,8 @@ export default {
|
||||
this.parentFetchData()
|
||||
this.$parent.$parent.close()
|
||||
}).catch(error => {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: `${this.$t('label.error')} ${error.response.status}`,
|
||||
description: error.response.data.createpodresponse.errortext,
|
||||
duration: 0
|
||||
@ -242,7 +243,8 @@ export default {
|
||||
}
|
||||
})
|
||||
}).catch(error => {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: `${this.$t('label.error')} ${error.response.status}`,
|
||||
description: error.response.data.errorresponse.errortext,
|
||||
duration: 0
|
||||
|
||||
@ -254,7 +254,8 @@ export default {
|
||||
this.items = response.listdedicatedguestvlanrangesresponse.dedicatedguestvlanrange || []
|
||||
this.totalCount = response.listdedicatedguestvlanrangesresponse.count || 0
|
||||
}).catch(error => {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: `${this.$t('label.error')} ${error.response.status}`,
|
||||
description: error.response.data.errorresponse.errortext,
|
||||
duration: 0
|
||||
|
||||
@ -133,7 +133,8 @@ export default {
|
||||
this.traffictype = this.trafficTypes[0].traffictype || undefined
|
||||
})
|
||||
.catch(error => {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: `${this.$t('label.error')} ${error.response.status}`,
|
||||
description: error.response.data.errorresponse.errortext
|
||||
})
|
||||
|
||||
@ -504,7 +504,8 @@ export default {
|
||||
handleDeleteIpRange (id) {
|
||||
this.componentLoading = true
|
||||
api('deleteVlanIpRange', { id }).then(() => {
|
||||
this.$notification.success({
|
||||
this.$showNotification({
|
||||
type: 'success',
|
||||
message: 'Removed IP Range'
|
||||
})
|
||||
}).catch(error => {
|
||||
@ -540,11 +541,13 @@ export default {
|
||||
params.networkid = this.network.id
|
||||
}
|
||||
api('createVlanIpRange', params).then(() => {
|
||||
this.$notification.success({
|
||||
this.$showNotification({
|
||||
type: 'success',
|
||||
message: this.$t('message.success.add.iprange')
|
||||
})
|
||||
}).catch(error => {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: `${this.$t('label.error')} ${error.response.status}`,
|
||||
description: error.response.data.createvlaniprangeresponse
|
||||
? error.response.data.createvlaniprangeresponse.errortext : error.response.data.errorresponse.errortext,
|
||||
@ -572,11 +575,13 @@ export default {
|
||||
forsystemvms: values.forsystemvms
|
||||
}
|
||||
api('updateVlanIpRange', params).then(() => {
|
||||
this.$notification.success({
|
||||
this.$showNotification({
|
||||
type: 'success',
|
||||
message: this.$t('message.success.update.iprange')
|
||||
})
|
||||
}).catch(error => {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: `${this.$t('label.error')} ${error.response.status}`,
|
||||
description: error.response.data.updatevlaniprangeresponse
|
||||
? error.response.data.updatevlaniprangeresponse.errortext : error.response.data.errorresponse.errortext,
|
||||
|
||||
@ -1219,7 +1219,8 @@ export default {
|
||||
this.onCloseAction()
|
||||
} catch (error) {
|
||||
this.actionLoading = false
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('message.request.failed'),
|
||||
description: error
|
||||
})
|
||||
@ -1355,7 +1356,8 @@ export default {
|
||||
this.onCloseAction()
|
||||
} catch (message) {
|
||||
this.actionLoading = false
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('message.request.failed'),
|
||||
description: message
|
||||
})
|
||||
|
||||
@ -253,7 +253,8 @@ export default {
|
||||
this.loading = false
|
||||
} catch (error) {
|
||||
this.loading = false
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('message.request.failed'),
|
||||
description: (error.response && error.response.headers && error.response.headers['x-description']) || error.message
|
||||
})
|
||||
|
||||
@ -288,7 +288,8 @@ export default {
|
||||
this.loading = false
|
||||
} catch (error) {
|
||||
this.loading = false
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('message.request.failed'),
|
||||
description: (error.response && error.response.headers && error.response.headers['x-description']) || error.message
|
||||
})
|
||||
|
||||
@ -160,7 +160,8 @@ export default {
|
||||
this.loading = false
|
||||
} catch (error) {
|
||||
this.loading = false
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('message.request.failed'),
|
||||
description: (error.response && error.response.headers && error.response.headers['x-description']) || error.message
|
||||
})
|
||||
|
||||
@ -377,7 +377,8 @@ export default {
|
||||
this.loading = false
|
||||
} catch (error) {
|
||||
this.loading = false
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('message.request.failed'),
|
||||
description: (error.response && error.response.headers && error.response.headers['x-description']) || error.message
|
||||
})
|
||||
|
||||
@ -322,7 +322,8 @@ export default {
|
||||
this.loading = false
|
||||
} catch (error) {
|
||||
this.loading = false
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('message.request.failed'),
|
||||
description: (error.response && error.response.headers && error.response.headers['x-description']) || error.message
|
||||
})
|
||||
|
||||
@ -188,7 +188,8 @@ export default {
|
||||
this.listData[args.title].loading = false
|
||||
} catch (error) {
|
||||
this.listData[args.title].loading = false
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('message.request.failed'),
|
||||
description: (error.response && error.response.headers && error.response.headers['x-description']) || error.message
|
||||
})
|
||||
|
||||
@ -300,7 +300,8 @@ export default {
|
||||
this.actionLoading = false
|
||||
} catch (error) {
|
||||
this.actionLoading = false
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('message.request.failed'),
|
||||
description: (error.response && error.response.headers && error.response.headers['x-description']) || error.message
|
||||
})
|
||||
@ -336,7 +337,8 @@ export default {
|
||||
this.actionLoading = false
|
||||
} catch (error) {
|
||||
this.actionLoading = false
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('message.request.failed'),
|
||||
description: (error.response && error.response.headers && error.response.headers['x-description']) || error.message
|
||||
})
|
||||
|
||||
@ -1547,7 +1547,8 @@ export default {
|
||||
this.$emit('refresh-data')
|
||||
} catch (e) {
|
||||
this.loading = false
|
||||
await this.$notification.error({
|
||||
await this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('message.request.failed'),
|
||||
description: e
|
||||
})
|
||||
|
||||
@ -475,6 +475,7 @@ export default {
|
||||
|
||||
Object.keys(fields).forEach(key => {
|
||||
this.form.getFieldDecorator([key], { initialValue: fields[key] })
|
||||
this.form.setFieldsValue({ [key]: fields[key] })
|
||||
})
|
||||
},
|
||||
deleteTraffic (key, traffic, $event) {
|
||||
|
||||
@ -571,7 +571,8 @@ export default {
|
||||
data.aclid = this.resource.id
|
||||
|
||||
api('createNetworkACL', {}, 'POST', data).then(() => {
|
||||
this.$notification.success({
|
||||
this.$showNotification({
|
||||
type: 'success',
|
||||
message: this.$t('label.success'),
|
||||
description: this.$t('message.success.add.rule')
|
||||
})
|
||||
|
||||
@ -442,7 +442,8 @@ export default {
|
||||
}
|
||||
}
|
||||
api('createNetwork', params).then(json => {
|
||||
this.$notification.success({
|
||||
this.$showNotification({
|
||||
type: 'success',
|
||||
message: 'Network',
|
||||
description: this.$t('message.success.create.isolated.network')
|
||||
})
|
||||
|
||||
@ -393,7 +393,8 @@ export default {
|
||||
}
|
||||
}
|
||||
api('createNetwork', params).then(json => {
|
||||
this.$notification.success({
|
||||
this.$showNotification({
|
||||
type: 'success',
|
||||
message: 'Network',
|
||||
description: this.$t('message.success.create.l2.network')
|
||||
})
|
||||
|
||||
@ -703,7 +703,8 @@ export default {
|
||||
!this.isValidTextValueForKey(values, 'ip6gateway') && !this.isValidTextValueForKey(values, 'ip6cidr') &&
|
||||
!this.isValidTextValueForKey(values, 'startipv6') && !this.isValidTextValueForKey(values, 'endipv6'))
|
||||
) {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('message.request.failed'),
|
||||
description: this.$t('message.error.add.guest.network')
|
||||
})
|
||||
@ -788,7 +789,8 @@ export default {
|
||||
params.hideipaddressusage = true
|
||||
}
|
||||
api('createNetwork', params).then(json => {
|
||||
this.$notification.success({
|
||||
this.$showNotification({
|
||||
type: 'success',
|
||||
message: this.$t('label.network'),
|
||||
description: this.$t('message.success.add.guest.network')
|
||||
})
|
||||
|
||||
@ -248,13 +248,15 @@ export default {
|
||||
|
||||
api('createVlanIpRange', params)
|
||||
.then(() => {
|
||||
this.$notification.success({
|
||||
this.$showNotification({
|
||||
type: 'success',
|
||||
message: this.$t('message.success.add.iprange')
|
||||
})
|
||||
this.closeAction()
|
||||
this.$emit('refresh-data')
|
||||
}).catch(error => {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: `${this.$t('label.error')} ${error.response.status}`,
|
||||
description: error.response.data.createvlaniprangeresponse
|
||||
? error.response.data.createvlaniprangeresponse.errortext : error.response.data.errorresponse.errortext,
|
||||
|
||||
@ -223,7 +223,8 @@ export default {
|
||||
})
|
||||
this.closeModal()
|
||||
}).catch(error => {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: `${this.$t('label.error')} ${error.response.status}`,
|
||||
description: error.response.data.errorresponse.errortext,
|
||||
duration: 0
|
||||
|
||||
@ -359,7 +359,8 @@ export default {
|
||||
})
|
||||
this.onCloseModal()
|
||||
}).catch(error => {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: `${this.$t('label.error')} ${error.response.status}`,
|
||||
description: error.response.data.errorresponse.errortext,
|
||||
duration: 0
|
||||
@ -426,7 +427,8 @@ export default {
|
||||
})
|
||||
}).catch(error => {
|
||||
this.fetchLoading = false
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: `${this.$t('label.error')} ${error.response.status}`,
|
||||
description: error.response.data.errorresponse.errortext,
|
||||
duration: 0
|
||||
|
||||
@ -207,7 +207,7 @@
|
||||
|
||||
<a-modal
|
||||
:title="$t('label.configure.sticky.policy')"
|
||||
v-model="stickinessModalVisible"
|
||||
:visible="stickinessModalVisible"
|
||||
:footer="null"
|
||||
:afterClose="closeModal"
|
||||
:maskClosable="false"
|
||||
@ -288,7 +288,7 @@
|
||||
|
||||
<div :span="24" class="action-button">
|
||||
<a-button @click="stickinessModalVisible = false">{{ $t('label.cancel') }}</a-button>
|
||||
<a-button type="primary" @submit="handleSubmitStickinessForm">{{ $t('label.ok') }}</a-button>
|
||||
<a-button type="primary" ref="submit" @click="handleSubmitStickinessForm">{{ $t('label.ok') }}</a-button>
|
||||
</div>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
@ -890,6 +890,8 @@ export default {
|
||||
})
|
||||
}).catch(error => {
|
||||
this.$notifyError(error)
|
||||
}).finally(() => {
|
||||
this.closeModal()
|
||||
})
|
||||
},
|
||||
handleDeleteStickinessPolicy () {
|
||||
@ -962,6 +964,7 @@ export default {
|
||||
})
|
||||
},
|
||||
handleStickinessMethodSelectChange (e) {
|
||||
this.stickinessPolicyForm.resetFields()
|
||||
this.stickinessPolicyMethod = e
|
||||
},
|
||||
handleDeleteInstanceFromRule (instance, rule, ip) {
|
||||
|
||||
@ -331,7 +331,7 @@ export default {
|
||||
inject: ['parentFetchData', 'parentToggleLoading'],
|
||||
data () {
|
||||
return {
|
||||
checked: true,
|
||||
checked: false,
|
||||
selectedRowKeys: [],
|
||||
showGroupActionModal: false,
|
||||
selectedItems: [],
|
||||
@ -639,6 +639,7 @@ export default {
|
||||
this.addVmModalNicLoading = false
|
||||
this.showConfirmationAction = false
|
||||
this.nics = []
|
||||
this.checked = false
|
||||
this.resetTagInputs()
|
||||
},
|
||||
openTagsModal (id) {
|
||||
|
||||
@ -664,7 +664,8 @@ export default {
|
||||
}
|
||||
|
||||
api('createNetwork', params).then(() => {
|
||||
this.$notification.success({
|
||||
this.$showNotification({
|
||||
type: 'success',
|
||||
message: this.$t('message.success.add.vpc.network')
|
||||
})
|
||||
}).catch(error => {
|
||||
|
||||
@ -132,7 +132,8 @@ export default {
|
||||
jobId: response.createremoteaccessvpnresponse.jobid,
|
||||
successMethod: result => {
|
||||
const res = result.jobresult.remoteaccessvpn
|
||||
this.$notification.success({
|
||||
this.$showNotification({
|
||||
type: 'success',
|
||||
message: this.$t('label.status'),
|
||||
description:
|
||||
`${this.$t('message.enabled.vpn')} ${res.publicip}. ${this.$t('message.enabled.vpn.ip.sec')} ${res.presharedkey}`,
|
||||
|
||||
@ -89,25 +89,11 @@
|
||||
</a-row>
|
||||
<a-form-item v-if="guestType === 'isolated'">
|
||||
<tooltip-label slot="label" :title="$t('label.vpc')" :tooltip="apiParams.forvpc.description"/>
|
||||
<a-switch v-decorator="['forvpc', {initialValue: forVpc}]" :defaultChecked="forVpc" @change="val => { handleForVpcChange(val) }" />
|
||||
<a-switch v-decorator="['forvpc']" :checked="forVpc" @change="val => { handleForVpcChange(val) }" />
|
||||
</a-form-item>
|
||||
<a-form-item :label="$t('label.userdatal2')" v-if="guestType === 'l2'">
|
||||
<a-switch v-decorator="['userdatal2', {initialValue: false}]" />
|
||||
</a-form-item>
|
||||
<a-form-item :label="$t('label.lbtype')" v-if="forVpc && lbServiceChecked">
|
||||
<a-radio-group
|
||||
v-decorator="[' ', {
|
||||
initialValue: 'publicLb'
|
||||
}]"
|
||||
buttonStyle="solid">
|
||||
<a-radio-button value="publicLb">
|
||||
{{ $t('label.public.lb') }}
|
||||
</a-radio-button>
|
||||
<a-radio-button value="internalLb">
|
||||
{{ $t('label.internal.lb') }}
|
||||
</a-radio-button>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
<a-row :gutter="12">
|
||||
<a-col :md="12" :lg="12">
|
||||
<a-form-item>
|
||||
@ -202,15 +188,28 @@
|
||||
v-decorator="['service.'+item.name, {}]"
|
||||
:resourceKey="item.name"
|
||||
:checkBoxLabel="item.description"
|
||||
:checkBoxDecorator="'service.' + item.name"
|
||||
:selectOptions="item.provider"
|
||||
:selectDecorator="item.name + '.provider'"
|
||||
:selectOptions="!supportedServiceLoading ? item.provider: []"
|
||||
@handle-checkselectpair-change="handleSupportedServiceChange"/>
|
||||
</a-list-item>
|
||||
</a-list>
|
||||
</div>
|
||||
</a-form-item>
|
||||
<a-form-item v-if="isVirtualRouterForAtLeastOneService">
|
||||
<a-form-item :label="$t('label.lbtype')" v-if="forVpc && lbServiceChecked">
|
||||
<a-radio-group
|
||||
v-decorator="['lbType', {
|
||||
initialValue: lbType
|
||||
}]"
|
||||
buttonStyle="solid"
|
||||
@change="e => { handleLbTypeChange(e.target.value) }" >
|
||||
<a-radio-button value="publicLb">
|
||||
{{ $t('label.public.lb') }}
|
||||
</a-radio-button>
|
||||
<a-radio-button value="internalLb">
|
||||
{{ $t('label.internal.lb') }}
|
||||
</a-radio-button>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
<a-form-item v-if="isVirtualRouterForAtLeastOneService || isVpcVirtualRouterForAtLeastOneService">
|
||||
<tooltip-label slot="label" :title="$t('label.serviceofferingid')" :tooltip="apiParams.serviceofferingid.description"/>
|
||||
<a-select
|
||||
v-decorator="['serviceofferingid', {
|
||||
@ -453,6 +452,7 @@ export default {
|
||||
selectedDomains: [],
|
||||
selectedZones: [],
|
||||
forVpc: false,
|
||||
lbType: 'publicLb',
|
||||
macLearningValue: '',
|
||||
supportedServices: [],
|
||||
supportedServiceLoading: false,
|
||||
@ -463,6 +463,8 @@ export default {
|
||||
sourceNatServiceChecked: false,
|
||||
lbServiceChecked: false,
|
||||
lbServiceProvider: '',
|
||||
registeredServicePackages: [],
|
||||
registeredServicePackageLoading: false,
|
||||
isElasticIp: false,
|
||||
staticNatServiceChecked: false,
|
||||
staticNatServiceProvider: '',
|
||||
@ -531,6 +533,27 @@ export default {
|
||||
},
|
||||
handleGuestTypeChange (val) {
|
||||
this.guestType = val
|
||||
if (val === 'l2') {
|
||||
this.forVpc = false
|
||||
this.lbType = 'publicLb'
|
||||
this.isVirtualRouterForAtLeastOneService = false
|
||||
this.isVpcVirtualRouterForAtLeastOneService = false
|
||||
this.serviceOfferings = []
|
||||
this.serviceOfferingLoading = false
|
||||
this.sourceNatServiceChecked = false
|
||||
this.lbServiceChecked = false
|
||||
this.lbServiceProvider = ''
|
||||
this.registeredServicePackages = []
|
||||
this.registeredServicePackageLoading = false
|
||||
this.isElasticIp = false
|
||||
this.staticNatServiceChecked = false
|
||||
this.staticNatServiceProvider = ''
|
||||
this.connectivityServiceChecked = false
|
||||
this.firewallServiceChecked = false
|
||||
this.firewallServiceProvider = ''
|
||||
this.selectedServiceProviderMap = {}
|
||||
this.updateSupportedServices()
|
||||
}
|
||||
},
|
||||
fetchSupportedServiceData () {
|
||||
const params = {}
|
||||
@ -594,18 +617,21 @@ export default {
|
||||
this.supportedServices[i].provider = providers
|
||||
this.supportedServices[i].description = serviceDisplayName
|
||||
}
|
||||
}).finally(() => {
|
||||
this.supportedServiceLoading = false
|
||||
this.updateSupportedServices()
|
||||
})
|
||||
},
|
||||
fetchServiceOfferingData () {
|
||||
const params = {}
|
||||
params.issystem = true
|
||||
params.systemvmtype = 'domainrouter'
|
||||
this.supportedServiceLoading = true
|
||||
this.serviceOfferingLoading = true
|
||||
api('listServiceOfferings', params).then(json => {
|
||||
const listServiceOfferings = json.listserviceofferingsresponse.serviceoffering
|
||||
this.serviceOfferings = this.serviceOfferings.concat(listServiceOfferings)
|
||||
}).finally(() => {
|
||||
this.supportedServiceLoading = false
|
||||
this.serviceOfferingLoading = false
|
||||
})
|
||||
},
|
||||
fetchRegisteredServicePackageData () {
|
||||
@ -627,32 +653,41 @@ export default {
|
||||
this.registeredServicePackageLoading = false
|
||||
})
|
||||
},
|
||||
handleForVpcChange (forVpc) {
|
||||
updateSupportedServices () {
|
||||
this.supportedServiceLoading = true
|
||||
var supportedServices = this.supportedServices
|
||||
var self = this
|
||||
this.forVpc = forVpc
|
||||
this.supportedServices.forEach(function (svc, index) {
|
||||
if (svc !== 'Connectivity') {
|
||||
supportedServices.forEach(function (svc, index) {
|
||||
if (svc.name !== 'Connectivity') {
|
||||
var providers = svc.provider
|
||||
providers.forEach(function (provider, providerIndex) {
|
||||
if (self.forVpc) { // *** vpc ***
|
||||
if (provider.name === 'InternalLbVm' || provider.name === 'VpcVirtualRouter' || provider.name === 'Netscaler' || provider.name === 'BigSwitchBcf' || provider.name === 'ConfigDrive') {
|
||||
provider.enabled = true
|
||||
} else {
|
||||
provider.enabled = false
|
||||
var enabledProviders = ['VpcVirtualRouter', 'Netscaler', 'BigSwitchBcf', 'ConfigDrive']
|
||||
if (self.lbType === 'internalLb') {
|
||||
enabledProviders.push('InternalLbVm')
|
||||
}
|
||||
provider.enabled = enabledProviders.includes(provider.name)
|
||||
} else { // *** non-vpc ***
|
||||
if (provider.name === 'InternalLbVm' || provider.name === 'VpcVirtualRouter') {
|
||||
provider.enabled = false
|
||||
} else {
|
||||
provider.enabled = true
|
||||
}
|
||||
provider.enabled = !['InternalLbVm', 'VpcVirtualRouter'].includes(provider.name)
|
||||
}
|
||||
providers[providerIndex] = provider
|
||||
})
|
||||
svc.provider = providers
|
||||
self.supportedServices[index] = svc
|
||||
supportedServices[index] = svc
|
||||
}
|
||||
})
|
||||
setTimeout(() => {
|
||||
self.supportedServices = supportedServices
|
||||
self.supportedServiceLoading = false
|
||||
}, 50)
|
||||
},
|
||||
handleForVpcChange (forVpc) {
|
||||
this.forVpc = forVpc
|
||||
this.updateSupportedServices()
|
||||
},
|
||||
handleLbTypeChange (lbType) {
|
||||
this.lbType = lbType
|
||||
this.updateSupportedServices()
|
||||
},
|
||||
handleSupportedServiceChange (service, checked, provider) {
|
||||
if (service === 'SourceNat') {
|
||||
@ -696,13 +731,14 @@ export default {
|
||||
providers.forEach(function (prvdr, idx) {
|
||||
if (prvdr === 'VirtualRouter') {
|
||||
self.isVirtualRouterForAtLeastOneService = true
|
||||
if (self.serviceOfferings.length === 0) {
|
||||
self.fetchServiceOfferingData()
|
||||
}
|
||||
}
|
||||
if (prvdr === 'VpcVirtualRouter') {
|
||||
self.isVpcVirtualRouterForAtLeastOneService = true
|
||||
}
|
||||
if ((self.isVirtualRouterForAtLeastOneService || self.isVpcVirtualRouterForAtLeastOneService) &&
|
||||
self.serviceOfferings.length === 0) {
|
||||
self.fetchServiceOfferingData()
|
||||
}
|
||||
})
|
||||
},
|
||||
handleSubmit (e) {
|
||||
@ -724,7 +760,7 @@ export default {
|
||||
var selectedServices = null
|
||||
var keys = Object.keys(values)
|
||||
const detailsKey = ['promiscuousmode', 'macaddresschanges', 'forgedtransmits', 'maclearning']
|
||||
const ignoredKeys = [...detailsKey, 'state', 'status', 'allocationstate', 'forvpc', 'specifyvlan', 'ispublic', 'domainid', 'zoneid', 'egressdefaultpolicy', 'isolation', 'supportspublicaccess']
|
||||
const ignoredKeys = [...detailsKey, 'state', 'status', 'allocationstate', 'forvpc', 'lbType', 'specifyvlan', 'ispublic', 'domainid', 'zoneid', 'egressdefaultpolicy', 'isolation', 'supportspublicaccess']
|
||||
keys.forEach(function (key, keyIndex) {
|
||||
if (self.isSupportedServiceObject(values[key])) {
|
||||
if (selectedServices == null) {
|
||||
|
||||
@ -48,9 +48,7 @@
|
||||
v-decorator="['service.'+item.name, {}]"
|
||||
:resourceKey="item.name"
|
||||
:checkBoxLabel="item.description"
|
||||
:checkBoxDecorator="'service.' + item.name"
|
||||
:selectOptions="item.provider"
|
||||
:selectDecorator="item.name + '.provider'"
|
||||
@handle-checkselectpair-change="handleSupportedServiceChange"/>
|
||||
</a-list-item>
|
||||
</a-list>
|
||||
|
||||
@ -297,7 +297,8 @@ export default {
|
||||
this.loading = true
|
||||
api('update' + this.offeringType, params).then(json => {
|
||||
this.$emit('refresh-data')
|
||||
this.$notification.success({
|
||||
this.$showNotification({
|
||||
type: 'success',
|
||||
message: this.$t('label.action.update.offering.access'),
|
||||
description: this.$t('label.action.update.offering.access')
|
||||
})
|
||||
|
||||
@ -125,7 +125,8 @@ export default {
|
||||
this.$message.success(`${this.$t('message.setting.updated')} ${this.resource.description}`)
|
||||
this.onClose()
|
||||
}).catch(error => {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('message.request.failed'),
|
||||
description: (error.response && error.response.headers && error.response.headers['x-description']) || error.message
|
||||
})
|
||||
|
||||
@ -229,7 +229,8 @@ export default {
|
||||
params[key] = input
|
||||
}
|
||||
api('updateProjectRole', params).then(response => {
|
||||
this.$notification.success({
|
||||
this.$showNotification({
|
||||
type: 'success',
|
||||
message: this.$t('label.update.project.role'),
|
||||
description: this.$t('label.update.project.role')
|
||||
})
|
||||
@ -268,7 +269,8 @@ export default {
|
||||
params[key] = input
|
||||
}
|
||||
api('createProjectRole', params).then(response => {
|
||||
this.$notification.success({
|
||||
this.$showNotification({
|
||||
type: 'success',
|
||||
message: this.$t('label.create.project.role'),
|
||||
description: this.$t('label.create.project.role')
|
||||
})
|
||||
@ -287,7 +289,8 @@ export default {
|
||||
projectid: this.resource.id,
|
||||
id: role.id
|
||||
}).then(response => {
|
||||
this.$notification.success({
|
||||
this.$showNotification({
|
||||
type: 'success',
|
||||
message: this.$t('label.delete.project.role'),
|
||||
description: this.$t('label.delete.project.role')
|
||||
})
|
||||
|
||||
@ -385,7 +385,8 @@ export default {
|
||||
this.actionLoading = true
|
||||
api('createSnapshotPolicy', params).then(json => {
|
||||
this.$emit('refresh')
|
||||
this.$notification.success({
|
||||
this.$showNotification({
|
||||
type: 'success',
|
||||
message: this.$t('label.action.recurring.snapshot'),
|
||||
description: this.$t('message.success.recurring.snapshot')
|
||||
})
|
||||
|
||||
@ -125,7 +125,8 @@ export default {
|
||||
})
|
||||
this.closeModal()
|
||||
}).catch(error => {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: `${this.$t('label.error')} ${error.response.status}`,
|
||||
description: error.response.data.errorresponse.errortext,
|
||||
duration: 0
|
||||
|
||||
@ -162,7 +162,8 @@ export default {
|
||||
this.actionLoading = true
|
||||
api('deleteSnapshotPolicies', params).then(json => {
|
||||
if (json.deletesnapshotpoliciesresponse.success) {
|
||||
this.$notification.success({
|
||||
this.$showNotification({
|
||||
type: 'success',
|
||||
message: this.$t('label.delete.snapshot.policy'),
|
||||
description: this.$t('message.success.delete.snapshot.policy')
|
||||
})
|
||||
|
||||
@ -191,7 +191,8 @@ export default {
|
||||
this.uploadParams = (json.postuploadvolumeresponse && json.postuploadvolumeresponse.getuploadparams) ? json.postuploadvolumeresponse.getuploadparams : ''
|
||||
const { fileList } = this
|
||||
if (this.fileList.length > 1) {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('message.upload.volume.failed'),
|
||||
description: this.$t('message.upload.file.limit'),
|
||||
duration: 0
|
||||
@ -216,13 +217,15 @@ export default {
|
||||
},
|
||||
timeout: 86400000
|
||||
}).then((json) => {
|
||||
this.$notification.success({
|
||||
this.$showNotification({
|
||||
type: 'success',
|
||||
message: this.$t('message.success.upload'),
|
||||
description: this.$t('message.success.upload.volume.description')
|
||||
})
|
||||
this.closeAction()
|
||||
}).catch(e => {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('message.upload.failed'),
|
||||
description: `${this.$t('message.upload.iso.failed.description')} - ${e}`,
|
||||
duration: 0
|
||||
|
||||
@ -631,7 +631,8 @@ export default {
|
||||
displayname: values.displayname
|
||||
}
|
||||
if (!this.computeOffering || !this.computeOffering.id) {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('message.request.failed'),
|
||||
description: this.$t('message.step.2.continue')
|
||||
})
|
||||
@ -642,7 +643,8 @@ export default {
|
||||
var details = [this.cpuNumberKey, this.cpuSpeedKey, this.memoryKey]
|
||||
for (var detail of details) {
|
||||
if (!(values[detail] || this.computeOffering[detail])) {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('message.request.failed'),
|
||||
description: this.$t('message.please.enter.valid.value') + ': ' + this.$t('label.' + detail.toLowerCase())
|
||||
})
|
||||
@ -657,7 +659,8 @@ export default {
|
||||
var iopsDetails = [this.minIopsKey, this.maxIopsKey]
|
||||
for (var iopsDetail of iopsDetails) {
|
||||
if (!values[iopsDetail] || values[iopsDetail] < 0) {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('message.request.failed'),
|
||||
description: this.$t('message.please.enter.valid.value') + ': ' + this.$t('label.' + iopsDetail.toLowerCase())
|
||||
})
|
||||
@ -666,7 +669,8 @@ export default {
|
||||
params['details[0].' + iopsDetail] = values[iopsDetail]
|
||||
}
|
||||
if (values[this.minIopsKey] > values[this.maxIopsKey]) {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('message.request.failed'),
|
||||
description: this.$t('error.form.message')
|
||||
})
|
||||
@ -684,7 +688,8 @@ export default {
|
||||
var diskOfferingIndex = 0
|
||||
for (var diskId in this.dataDisksOfferingsMapping) {
|
||||
if (!this.dataDisksOfferingsMapping[diskId]) {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('message.request.failed'),
|
||||
description: this.$t('message.select.disk.offering') + ': ' + diskId
|
||||
})
|
||||
@ -698,7 +703,8 @@ export default {
|
||||
var nicIpIndex = 0
|
||||
for (var nicId in this.nicsNetworksMapping) {
|
||||
if (!this.nicsNetworksMapping[nicId].network) {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('message.request.failed'),
|
||||
description: this.$t('message.select.nic.network') + ': ' + nicId
|
||||
})
|
||||
@ -709,7 +715,8 @@ export default {
|
||||
nicNetworkIndex++
|
||||
if ('ipAddress' in this.nicsNetworksMapping[nicId]) {
|
||||
if (!this.nicsNetworksMapping[nicId].ipAddress) {
|
||||
this.$notification.error({
|
||||
this.$showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('message.request.failed'),
|
||||
description: this.$t('message.enter.valid.nic.ip') + ': ' + nicId
|
||||
})
|
||||
|
||||
@ -52,21 +52,14 @@ mocks = {
|
||||
$notifyError: jest.fn((error) => {
|
||||
return error
|
||||
}),
|
||||
$notification: {
|
||||
info: jest.fn((option) => {
|
||||
$showNotification: jest.fn((option) => {
|
||||
return {
|
||||
type: option.type,
|
||||
message: option.message,
|
||||
description: 'test-description',
|
||||
duration: option.duration
|
||||
}
|
||||
}),
|
||||
success: jest.fn((option) => {
|
||||
return {
|
||||
message: option.message,
|
||||
description: option.description
|
||||
}
|
||||
})
|
||||
},
|
||||
$message: {
|
||||
success: jest.fn((obj) => {
|
||||
return obj
|
||||
@ -1577,7 +1570,7 @@ describe('Views > AutogenView.vue', () => {
|
||||
})
|
||||
|
||||
describe('pollActionCompletion()', () => {
|
||||
it('check $notification when pollActionCompletion() is called with action is empty', (done) => {
|
||||
it('check $showNotification when pollActionCompletion() is called with action is empty', (done) => {
|
||||
const mockData = {
|
||||
queryasyncjobresultresponse: {
|
||||
jobstatus: 1,
|
||||
@ -1595,7 +1588,7 @@ describe('Views > AutogenView.vue', () => {
|
||||
wrapper.vm.pollActionCompletion(jobId, action)
|
||||
|
||||
setTimeout(() => {
|
||||
expect(mocks.$notification.info).not.toHaveBeenCalled()
|
||||
expect(mocks.$showNotification).not.toHaveBeenCalled()
|
||||
expect(mockAxios).toHaveBeenCalled()
|
||||
expect(mockAxios).toHaveBeenCalledWith({
|
||||
url: '/',
|
||||
@ -1612,7 +1605,7 @@ describe('Views > AutogenView.vue', () => {
|
||||
})
|
||||
})
|
||||
|
||||
it('check $notification when pollActionCompletion() is called with action is not empty', (done) => {
|
||||
it('check $showNotification when pollActionCompletion() is called with action is not empty', (done) => {
|
||||
const mockData = {
|
||||
queryasyncjobresultresponse: {
|
||||
jobstatus: 1,
|
||||
@ -1633,8 +1626,9 @@ describe('Views > AutogenView.vue', () => {
|
||||
wrapper.vm.pollActionCompletion(jobId, action)
|
||||
|
||||
setTimeout(() => {
|
||||
expect(mocks.$notification.info).toHaveBeenCalled()
|
||||
expect(mocks.$notification.info).toHaveLastReturnedWith({
|
||||
expect(mocks.$showNotification).toHaveBeenCalled()
|
||||
expect(mocks.$showNotification).toHaveLastReturnedWith({
|
||||
type: 'info',
|
||||
message: 'test-name-en',
|
||||
description: 'test-description',
|
||||
duration: 0
|
||||
@ -2787,7 +2781,7 @@ describe('Views > AutogenView.vue', () => {
|
||||
})
|
||||
})
|
||||
|
||||
it('check $notification when api is called and response have not jobId result', async (done) => {
|
||||
it('check $message when api is called and response have not jobId result', async (done) => {
|
||||
wrapper = factory({
|
||||
data: {
|
||||
showAction: true,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user