mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Merge branch '4.20'
This commit is contained in:
commit
0b3959221b
@ -87,6 +87,8 @@ public interface AccountService {
|
|||||||
|
|
||||||
boolean isDomainAdmin(Long accountId);
|
boolean isDomainAdmin(Long accountId);
|
||||||
|
|
||||||
|
boolean isResourceDomainAdmin(Long accountId);
|
||||||
|
|
||||||
boolean isNormalUser(long accountId);
|
boolean isNormalUser(long accountId);
|
||||||
|
|
||||||
User getActiveUserByRegistrationToken(String registrationToken);
|
User getActiveUserByRegistrationToken(String registrationToken);
|
||||||
|
|||||||
@ -190,7 +190,7 @@ public class ListClustersCmd extends BaseListCmd {
|
|||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
Pair<List<ClusterResponse>, Integer> clusterResponses = getClusterResponses();
|
Pair<List<ClusterResponse>, Integer> clusterResponses = getClusterResponses();
|
||||||
ListResponse<ClusterResponse> response = new ListResponse<ClusterResponse>();
|
ListResponse<ClusterResponse> response = new ListResponse<>();
|
||||||
response.setResponses(clusterResponses.first(), clusterResponses.second());
|
response.setResponses(clusterResponses.first(), clusterResponses.second());
|
||||||
response.setResponseName(getCommandName());
|
response.setResponseName(getCommandName());
|
||||||
this.setResponseObject(response);
|
this.setResponseObject(response);
|
||||||
|
|||||||
@ -103,8 +103,8 @@ public class ListPodsByCmd extends BaseListCmd {
|
|||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
Pair<List<? extends Pod>, Integer> result = _mgr.searchForPods(this);
|
Pair<List<? extends Pod>, Integer> result = _mgr.searchForPods(this);
|
||||||
ListResponse<PodResponse> response = new ListResponse<PodResponse>();
|
ListResponse<PodResponse> response = new ListResponse<>();
|
||||||
List<PodResponse> podResponses = new ArrayList<PodResponse>();
|
List<PodResponse> podResponses = new ArrayList<>();
|
||||||
for (Pod pod : result.first()) {
|
for (Pod pod : result.first()) {
|
||||||
PodResponse podResponse = _responseGenerator.createPodResponse(pod, showCapacities);
|
PodResponse podResponse = _responseGenerator.createPodResponse(pod, showCapacities);
|
||||||
podResponse.setObjectName("pod");
|
podResponse.setObjectName("pod");
|
||||||
|
|||||||
@ -74,6 +74,7 @@ public class ListCapabilitiesCmd extends BaseCmd {
|
|||||||
response.setSharedFsVmMinRamSize((Integer)capabilities.get(ApiConstants.SHAREDFSVM_MIN_RAM_SIZE));
|
response.setSharedFsVmMinRamSize((Integer)capabilities.get(ApiConstants.SHAREDFSVM_MIN_RAM_SIZE));
|
||||||
response.setInstanceLeaseEnabled((Boolean) capabilities.get(ApiConstants.INSTANCE_LEASE_ENABLED));
|
response.setInstanceLeaseEnabled((Boolean) capabilities.get(ApiConstants.INSTANCE_LEASE_ENABLED));
|
||||||
response.setExtensionsPath((String)capabilities.get(ApiConstants.EXTENSIONS_PATH));
|
response.setExtensionsPath((String)capabilities.get(ApiConstants.EXTENSIONS_PATH));
|
||||||
|
response.setDynamicScalingEnabled((Boolean) capabilities.get(ApiConstants.DYNAMIC_SCALING_ENABLED));
|
||||||
response.setObjectName("capability");
|
response.setObjectName("capability");
|
||||||
response.setResponseName(getCommandName());
|
response.setResponseName(getCommandName());
|
||||||
this.setResponseObject(response);
|
this.setResponseObject(response);
|
||||||
|
|||||||
@ -20,6 +20,7 @@ import java.util.Collection;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.cloud.cpu.CPU;
|
||||||
import org.apache.cloudstack.acl.SecurityChecker;
|
import org.apache.cloudstack.acl.SecurityChecker;
|
||||||
import org.apache.cloudstack.api.APICommand;
|
import org.apache.cloudstack.api.APICommand;
|
||||||
import org.apache.cloudstack.api.ApiCommandResourceType;
|
import org.apache.cloudstack.api.ApiCommandResourceType;
|
||||||
@ -148,6 +149,11 @@ public class CreateTemplateCmd extends BaseAsyncCreateCmd implements UserCmd {
|
|||||||
since = "4.19.0")
|
since = "4.19.0")
|
||||||
private String accountName;
|
private String accountName;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.ARCH, type = CommandType.STRING,
|
||||||
|
description = "the CPU arch of the template. Valid options are: x86_64, aarch64. Defaults to x86_64",
|
||||||
|
since = "4.20.2")
|
||||||
|
private String arch;
|
||||||
|
|
||||||
// ///////////////////////////////////////////////////
|
// ///////////////////////////////////////////////////
|
||||||
// ///////////////// Accessors ///////////////////////
|
// ///////////////// Accessors ///////////////////////
|
||||||
// ///////////////////////////////////////////////////
|
// ///////////////////////////////////////////////////
|
||||||
@ -234,6 +240,10 @@ public class CreateTemplateCmd extends BaseAsyncCreateCmd implements UserCmd {
|
|||||||
return accountName;
|
return accountName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CPU.CPUArch getArch() {
|
||||||
|
return CPU.CPUArch.fromType(arch);
|
||||||
|
}
|
||||||
|
|
||||||
// ///////////////////////////////////////////////////
|
// ///////////////////////////////////////////////////
|
||||||
// ///////////// API Implementation///////////////////
|
// ///////////// API Implementation///////////////////
|
||||||
// ///////////////////////////////////////////////////
|
// ///////////////////////////////////////////////////
|
||||||
|
|||||||
@ -33,7 +33,7 @@ import com.cloud.exception.ResourceUnavailableException;
|
|||||||
import com.cloud.user.UserData;
|
import com.cloud.user.UserData;
|
||||||
|
|
||||||
@APICommand(name = "registerUserData",
|
@APICommand(name = "registerUserData",
|
||||||
description = "Register a new userdata.",
|
description = "Register a new User Data.",
|
||||||
since = "4.18",
|
since = "4.18",
|
||||||
responseObject = SuccessResponse.class,
|
responseObject = SuccessResponse.class,
|
||||||
requestHasSensitiveInfo = false,
|
requestHasSensitiveInfo = false,
|
||||||
@ -46,9 +46,55 @@ public class RegisterUserDataCmd extends BaseRegisterUserDataCmd {
|
|||||||
//////////////// API parameters /////////////////////
|
//////////////// API parameters /////////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
|
|
||||||
@Parameter(name = ApiConstants.USER_DATA, type = CommandType.STRING, required = true, description = "User data content", length = 1048576)
|
@Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "Name of the User Data")
|
||||||
protected String userData;
|
private String name;
|
||||||
|
|
||||||
|
//Owner information
|
||||||
|
@Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "an optional account for the User Data. Must be used with domainId.")
|
||||||
|
private String accountName;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.DOMAIN_ID,
|
||||||
|
type = CommandType.UUID,
|
||||||
|
entityType = DomainResponse.class,
|
||||||
|
description = "an optional domainId for the User Data. If the account parameter is used, domainId must also be used.")
|
||||||
|
private Long domainId;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, entityType = ProjectResponse.class, description = "an optional project for the User Data")
|
||||||
|
private Long projectId;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.USER_DATA,
|
||||||
|
type = CommandType.STRING,
|
||||||
|
required = true,
|
||||||
|
description = "Base64 encoded User Data content. " +
|
||||||
|
"Using HTTP GET (via querystring), you can send up to 4KB of data after base64 encoding. " +
|
||||||
|
"Using HTTP POST (via POST body), you can send up to 32KB of data after base64 encoding, " +
|
||||||
|
"which can be increased upto 1MB using the vm.userdata.max.length setting",
|
||||||
|
length = 1048576)
|
||||||
|
private String userData;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.PARAMS, type = CommandType.STRING, description = "comma separated list of variables declared in the User Data content")
|
||||||
|
private String params;
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
/////////////////// Accessors ///////////////////////
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAccountName() {
|
||||||
|
return accountName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getDomainId() {
|
||||||
|
return domainId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getProjectId() {
|
||||||
|
return projectId;
|
||||||
|
}
|
||||||
|
|
||||||
public String getUserData() {
|
public String getUserData() {
|
||||||
return userData;
|
return userData;
|
||||||
|
|||||||
@ -34,8 +34,6 @@ import org.apache.cloudstack.api.response.ZoneResponse;
|
|||||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
||||||
public class ListZonesCmd extends BaseListCmd implements UserCmd {
|
public class ListZonesCmd extends BaseListCmd implements UserCmd {
|
||||||
|
|
||||||
private static final String s_name = "listzonesresponse";
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
//////////////// API parameters /////////////////////
|
//////////////// API parameters /////////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
@ -130,11 +128,6 @@ public class ListZonesCmd extends BaseListCmd implements UserCmd {
|
|||||||
/////////////// API Implementation///////////////////
|
/////////////// API Implementation///////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getCommandName() {
|
|
||||||
return s_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
ListResponse<ZoneResponse> response = _queryService.listDataCenters(this);
|
ListResponse<ZoneResponse> response = _queryService.listDataCenters(this);
|
||||||
|
|||||||
@ -145,6 +145,10 @@ public class CapabilitiesResponse extends BaseResponse {
|
|||||||
@Param(description = "The path of the extensions directory", since = "4.21.0", authorized = {RoleType.Admin})
|
@Param(description = "The path of the extensions directory", since = "4.21.0", authorized = {RoleType.Admin})
|
||||||
private String extensionsPath;
|
private String extensionsPath;
|
||||||
|
|
||||||
|
@SerializedName(ApiConstants.DYNAMIC_SCALING_ENABLED)
|
||||||
|
@Param(description = "true if dynamically scaling for instances is enabled", since = "4.21.0")
|
||||||
|
private Boolean dynamicScalingEnabled;
|
||||||
|
|
||||||
public void setSecurityGroupsEnabled(boolean securityGroupsEnabled) {
|
public void setSecurityGroupsEnabled(boolean securityGroupsEnabled) {
|
||||||
this.securityGroupsEnabled = securityGroupsEnabled;
|
this.securityGroupsEnabled = securityGroupsEnabled;
|
||||||
}
|
}
|
||||||
@ -264,4 +268,8 @@ public class CapabilitiesResponse extends BaseResponse {
|
|||||||
public void setExtensionsPath(String extensionsPath) {
|
public void setExtensionsPath(String extensionsPath) {
|
||||||
this.extensionsPath = extensionsPath;
|
this.extensionsPath = extensionsPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setDynamicScalingEnabled(Boolean dynamicScalingEnabled) {
|
||||||
|
this.dynamicScalingEnabled = dynamicScalingEnabled;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,41 +27,41 @@ import org.apache.cloudstack.api.EntityReference;
|
|||||||
public class UserDataResponse extends BaseResponseWithAnnotations implements ControlledEntityResponse {
|
public class UserDataResponse extends BaseResponseWithAnnotations implements ControlledEntityResponse {
|
||||||
|
|
||||||
@SerializedName(ApiConstants.ID)
|
@SerializedName(ApiConstants.ID)
|
||||||
@Param(description = "ID of the ssh keypair")
|
@Param(description = "ID of the User Data")
|
||||||
private String id;
|
private String id;
|
||||||
|
|
||||||
@SerializedName(ApiConstants.NAME)
|
@SerializedName(ApiConstants.NAME)
|
||||||
@Param(description = "Name of the userdata")
|
@Param(description = "Name of the User Data")
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
@SerializedName(ApiConstants.ACCOUNT_ID) @Param(description="the owner id of the userdata")
|
@SerializedName(ApiConstants.ACCOUNT_ID) @Param(description="the owner id of the User Data")
|
||||||
private String accountId;
|
private String accountId;
|
||||||
|
|
||||||
@SerializedName(ApiConstants.ACCOUNT) @Param(description="the owner of the userdata")
|
@SerializedName(ApiConstants.ACCOUNT) @Param(description="the owner of the User Data")
|
||||||
private String accountName;
|
private String accountName;
|
||||||
|
|
||||||
@SerializedName(ApiConstants.PROJECT_ID)
|
@SerializedName(ApiConstants.PROJECT_ID)
|
||||||
@Param(description = "the project id of the userdata", since = "4.19.1")
|
@Param(description = "the project id of the User Data", since = "4.19.1")
|
||||||
private String projectId;
|
private String projectId;
|
||||||
|
|
||||||
@SerializedName(ApiConstants.PROJECT)
|
@SerializedName(ApiConstants.PROJECT)
|
||||||
@Param(description = "the project name of the userdata", since = "4.19.1")
|
@Param(description = "the project name of the User Data", since = "4.19.1")
|
||||||
private String projectName;
|
private String projectName;
|
||||||
|
|
||||||
@SerializedName(ApiConstants.DOMAIN_ID) @Param(description="the domain id of the userdata owner")
|
@SerializedName(ApiConstants.DOMAIN_ID) @Param(description="the domain id of the User Data owner")
|
||||||
private String domainId;
|
private String domainId;
|
||||||
|
|
||||||
@SerializedName(ApiConstants.DOMAIN) @Param(description="the domain name of the userdata owner")
|
@SerializedName(ApiConstants.DOMAIN) @Param(description="the domain name of the User Data owner")
|
||||||
private String domain;
|
private String domain;
|
||||||
|
|
||||||
@SerializedName(ApiConstants.DOMAIN_PATH)
|
@SerializedName(ApiConstants.DOMAIN_PATH)
|
||||||
@Param(description = "path of the domain to which the userdata owner belongs", since = "4.19.2.0")
|
@Param(description = "path of the domain to which the User Data owner belongs", since = "4.19.2.0")
|
||||||
private String domainPath;
|
private String domainPath;
|
||||||
|
|
||||||
@SerializedName(ApiConstants.USER_DATA) @Param(description="base64 encoded userdata content")
|
@SerializedName(ApiConstants.USER_DATA) @Param(description="base64 encoded User Data content")
|
||||||
private String userData;
|
private String userData;
|
||||||
|
|
||||||
@SerializedName(ApiConstants.PARAMS) @Param(description="list of parameters which contains the list of keys or string parameters that are needed to be passed for any variables declared in userdata")
|
@SerializedName(ApiConstants.PARAMS) @Param(description="list of parameters which contains the list of keys or string parameters that are needed to be passed for any variables declared in the User Data")
|
||||||
private String params;
|
private String params;
|
||||||
|
|
||||||
public UserDataResponse() {
|
public UserDataResponse() {
|
||||||
|
|||||||
@ -114,11 +114,11 @@ public interface QueryService {
|
|||||||
ConfigKey<Boolean> AllowUserViewDestroyedVM = new ConfigKey<>("Advanced", Boolean.class, "allow.user.view.destroyed.vm", "false",
|
ConfigKey<Boolean> AllowUserViewDestroyedVM = new ConfigKey<>("Advanced", Boolean.class, "allow.user.view.destroyed.vm", "false",
|
||||||
"Determines whether users can view their destroyed or expunging vm ", true, ConfigKey.Scope.Account);
|
"Determines whether users can view their destroyed or expunging vm ", true, ConfigKey.Scope.Account);
|
||||||
|
|
||||||
static final ConfigKey<String> UserVMDeniedDetails = new ConfigKey<>(String.class,
|
ConfigKey<String> UserVMDeniedDetails = new ConfigKey<>(String.class,
|
||||||
"user.vm.denied.details", "Advanced", "rootdisksize, cpuOvercommitRatio, memoryOvercommitRatio, Message.ReservedCapacityFreed.Flag",
|
"user.vm.denied.details", "Advanced", "rootdisksize, cpuOvercommitRatio, memoryOvercommitRatio, Message.ReservedCapacityFreed.Flag",
|
||||||
"Determines whether users can view certain VM settings. When set to empty, default value used is: rootdisksize, cpuOvercommitRatio, memoryOvercommitRatio, Message.ReservedCapacityFreed.Flag.", true, ConfigKey.Scope.Global, null, null, null, null, null, ConfigKey.Kind.CSV, null);
|
"Determines whether users can view certain VM settings. When set to empty, default value used is: rootdisksize, cpuOvercommitRatio, memoryOvercommitRatio, Message.ReservedCapacityFreed.Flag.", true, ConfigKey.Scope.Global, null, null, null, null, null, ConfigKey.Kind.CSV, null);
|
||||||
|
|
||||||
static final ConfigKey<String> UserVMReadOnlyDetails = new ConfigKey<>(String.class,
|
ConfigKey<String> UserVMReadOnlyDetails = new ConfigKey<>(String.class,
|
||||||
"user.vm.readonly.details", "Advanced", "dataDiskController, rootDiskController",
|
"user.vm.readonly.details", "Advanced", "dataDiskController, rootDiskController",
|
||||||
"List of read-only VM settings/details as comma separated string", true, ConfigKey.Scope.Global, null, null, null, null, null, ConfigKey.Kind.CSV, null);
|
"List of read-only VM settings/details as comma separated string", true, ConfigKey.Scope.Global, null, null, null, null, null, ConfigKey.Kind.CSV, null);
|
||||||
|
|
||||||
@ -127,16 +127,20 @@ public interface QueryService {
|
|||||||
"network offering, zones), we use the flag to determine if the entities should be sorted ascending (when flag is true) " +
|
"network offering, zones), we use the flag to determine if the entities should be sorted ascending (when flag is true) " +
|
||||||
"or descending (when flag is false). Within the scope of the config all users see the same result.", true, ConfigKey.Scope.Global);
|
"or descending (when flag is false). Within the scope of the config all users see the same result.", true, ConfigKey.Scope.Global);
|
||||||
|
|
||||||
public static final ConfigKey<Boolean> AllowUserViewAllDomainAccounts = new ConfigKey<>("Advanced", Boolean.class,
|
ConfigKey<Boolean> AllowUserViewAllDomainAccounts = new ConfigKey<>("Advanced", Boolean.class,
|
||||||
"allow.user.view.all.domain.accounts", "false",
|
"allow.user.view.all.domain.accounts", "false",
|
||||||
"Determines whether users can view all user accounts within the same domain", true, ConfigKey.Scope.Domain);
|
"Determines whether users can view all user accounts within the same domain", true, ConfigKey.Scope.Domain);
|
||||||
|
|
||||||
static final ConfigKey<Boolean> SharePublicTemplatesWithOtherDomains = new ConfigKey<>("Advanced", Boolean.class, "share.public.templates.with.other.domains", "true",
|
ConfigKey<Boolean> AllowUserViewAllDataCenters = new ConfigKey<>("Advanced", Boolean.class, "allow.user.view.all.zones", "true",
|
||||||
|
"Determines whether for instance a Resource Admin can view zones that are not dedicated to them.", true, ConfigKey.Scope.Domain);
|
||||||
|
|
||||||
|
ConfigKey<Boolean> SharePublicTemplatesWithOtherDomains = new ConfigKey<>("Advanced", Boolean.class, "share.public.templates.with.other.domains", "true",
|
||||||
"If false, templates of this domain will not show up in the list templates of other domains.", true, ConfigKey.Scope.Domain);
|
"If false, templates of this domain will not show up in the list templates of other domains.", true, ConfigKey.Scope.Domain);
|
||||||
|
|
||||||
ConfigKey<Boolean> ReturnVmStatsOnVmList = new ConfigKey<>("Advanced", Boolean.class, "list.vm.default.details.stats", "true",
|
ConfigKey<Boolean> ReturnVmStatsOnVmList = new ConfigKey<>("Advanced", Boolean.class, "list.vm.default.details.stats", "true",
|
||||||
"Determines whether VM stats should be returned when details are not explicitly specified in listVirtualMachines API request. When false, details default to [group, nics, secgrp, tmpl, servoff, diskoff, backoff, iso, volume, min, affgrp]. When true, all details are returned including 'stats'.", true, ConfigKey.Scope.Global);
|
"Determines whether VM stats should be returned when details are not explicitly specified in listVirtualMachines API request. When false, details default to [group, nics, secgrp, tmpl, servoff, diskoff, backoff, iso, volume, min, affgrp]. When true, all details are returned including 'stats'.", true, ConfigKey.Scope.Global);
|
||||||
|
|
||||||
|
|
||||||
ListResponse<UserResponse> searchForUsers(ResponseObject.ResponseView responseView, ListUsersCmd cmd) throws PermissionDeniedException;
|
ListResponse<UserResponse> searchForUsers(ResponseObject.ResponseView responseView, ListUsersCmd cmd) throws PermissionDeniedException;
|
||||||
|
|
||||||
ListResponse<UserResponse> searchForUsers(Long domainId, boolean recursive) throws PermissionDeniedException;
|
ListResponse<UserResponse> searchForUsers(Long domainId, boolean recursive) throws PermissionDeniedException;
|
||||||
|
|||||||
@ -17,22 +17,33 @@
|
|||||||
|
|
||||||
package com.cloud.agent.api;
|
package com.cloud.agent.api;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.storage.volume.VolumeOnStorageTO;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class CheckVolumeAnswer extends Answer {
|
public class CheckVolumeAnswer extends Answer {
|
||||||
|
|
||||||
private long size;
|
private long size;
|
||||||
|
private Map<VolumeOnStorageTO.Detail, String> volumeDetails;
|
||||||
|
|
||||||
CheckVolumeAnswer() {
|
CheckVolumeAnswer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public CheckVolumeAnswer(CheckVolumeCommand cmd, String details, long size) {
|
public CheckVolumeAnswer(CheckVolumeCommand cmd, final boolean success, String details, long size,
|
||||||
super(cmd, true, details);
|
Map<VolumeOnStorageTO.Detail, String> volumeDetails) {
|
||||||
|
super(cmd, success, details);
|
||||||
this.size = size;
|
this.size = size;
|
||||||
|
this.volumeDetails = volumeDetails;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getSize() {
|
public long getSize() {
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Map<VolumeOnStorageTO.Detail, String> getVolumeDetails() {
|
||||||
|
return volumeDetails;
|
||||||
|
}
|
||||||
|
|
||||||
public String getString() {
|
public String getString() {
|
||||||
return "CheckVolumeAnswer [size=" + size + "]";
|
return "CheckVolumeAnswer [size=" + size + "]";
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,21 +17,28 @@
|
|||||||
|
|
||||||
package com.cloud.agent.api;
|
package com.cloud.agent.api;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.storage.volume.VolumeOnStorageTO;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class CopyRemoteVolumeAnswer extends Answer {
|
public class CopyRemoteVolumeAnswer extends Answer {
|
||||||
|
|
||||||
private String remoteIp;
|
private String remoteIp;
|
||||||
private String filename;
|
private String filename;
|
||||||
|
|
||||||
private long size;
|
private long size;
|
||||||
|
private Map<VolumeOnStorageTO.Detail, String> volumeDetails;
|
||||||
|
|
||||||
CopyRemoteVolumeAnswer() {
|
CopyRemoteVolumeAnswer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public CopyRemoteVolumeAnswer(CopyRemoteVolumeCommand cmd, String details, String filename, long size) {
|
public CopyRemoteVolumeAnswer(CopyRemoteVolumeCommand cmd, final boolean success, String details, String filename, long size,
|
||||||
super(cmd, true, details);
|
Map<VolumeOnStorageTO.Detail, String> volumeDetails) {
|
||||||
|
super(cmd, success, details);
|
||||||
this.remoteIp = cmd.getRemoteIp();
|
this.remoteIp = cmd.getRemoteIp();
|
||||||
this.filename = filename;
|
this.filename = filename;
|
||||||
this.size = size;
|
this.size = size;
|
||||||
|
this.volumeDetails = volumeDetails;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getRemoteIp() {
|
public String getRemoteIp() {
|
||||||
@ -54,6 +61,10 @@ public class CopyRemoteVolumeAnswer extends Answer {
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Map<VolumeOnStorageTO.Detail, String> getVolumeDetails() {
|
||||||
|
return volumeDetails;
|
||||||
|
}
|
||||||
|
|
||||||
public String getString() {
|
public String getString() {
|
||||||
return "CopyRemoteVolumeAnswer [remoteIp=" + remoteIp + "]";
|
return "CopyRemoteVolumeAnswer [remoteIp=" + remoteIp + "]";
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,6 +24,7 @@ import com.cloud.utils.PasswordGenerator;
|
|||||||
import com.cloud.utils.exception.CloudRuntimeException;
|
import com.cloud.utils.exception.CloudRuntimeException;
|
||||||
import org.apache.cloudstack.ca.CAManager;
|
import org.apache.cloudstack.ca.CAManager;
|
||||||
import org.apache.cloudstack.framework.ca.Certificate;
|
import org.apache.cloudstack.framework.ca.Certificate;
|
||||||
|
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||||
import org.apache.cloudstack.utils.security.CertUtils;
|
import org.apache.cloudstack.utils.security.CertUtils;
|
||||||
import org.apache.cloudstack.utils.security.KeyStoreUtils;
|
import org.apache.cloudstack.utils.security.KeyStoreUtils;
|
||||||
|
|
||||||
@ -37,6 +38,9 @@ import java.util.Base64;
|
|||||||
*/
|
*/
|
||||||
public interface VirtualMachineGuru {
|
public interface VirtualMachineGuru {
|
||||||
|
|
||||||
|
static final ConfigKey<String> NTPServerConfig = new ConfigKey<String>(String.class, "ntp.server.list", "Advanced", null,
|
||||||
|
"Comma separated list of NTP servers to configure in System VMs", true, ConfigKey.Scope.Global, null, null, null, null, null, ConfigKey.Kind.CSV, null);
|
||||||
|
|
||||||
boolean finalizeVirtualMachineProfile(VirtualMachineProfile profile, DeployDestination dest, ReservationContext context);
|
boolean finalizeVirtualMachineProfile(VirtualMachineProfile profile, DeployDestination dest, ReservationContext context);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -37,4 +37,6 @@ public interface AutoScaleVmGroupVmMapDao extends GenericDao<AutoScaleVmGroupVmM
|
|||||||
public boolean removeByGroup(long vmGroupId);
|
public boolean removeByGroup(long vmGroupId);
|
||||||
|
|
||||||
int expungeByVmList(List<Long> vmIds, Long batchSize);
|
int expungeByVmList(List<Long> vmIds, Long batchSize);
|
||||||
|
|
||||||
|
int getErroredInstanceCount(long vmGroupId);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -127,4 +127,13 @@ public class AutoScaleVmGroupVmMapDaoImpl extends GenericDaoBase<AutoScaleVmGrou
|
|||||||
sc.setParameters("vmIds", vmIds.toArray());
|
sc.setParameters("vmIds", vmIds.toArray());
|
||||||
return batchExpunge(sc, batchSize);
|
return batchExpunge(sc, batchSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getErroredInstanceCount(long vmGroupId) {
|
||||||
|
SearchCriteria<Integer> sc = CountBy.create();
|
||||||
|
sc.setParameters("vmGroupId", vmGroupId);
|
||||||
|
sc.setJoinParameters("vmSearch", "states", State.Error);
|
||||||
|
final List<Integer> results = customSearch(sc, null);
|
||||||
|
return results.get(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -58,6 +58,7 @@ import javax.inject.Inject;
|
|||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
@ -169,6 +170,7 @@ public class NASBackupProvider extends AdapterBase implements BackupProvider, Co
|
|||||||
|
|
||||||
if (VirtualMachine.State.Stopped.equals(vm.getState())) {
|
if (VirtualMachine.State.Stopped.equals(vm.getState())) {
|
||||||
List<VolumeVO> vmVolumes = volumeDao.findByInstance(vm.getId());
|
List<VolumeVO> vmVolumes = volumeDao.findByInstance(vm.getId());
|
||||||
|
vmVolumes.sort(Comparator.comparing(Volume::getDeviceId));
|
||||||
List<String> volumePaths = getVolumePaths(vmVolumes);
|
List<String> volumePaths = getVolumePaths(vmVolumes);
|
||||||
command.setVolumePaths(volumePaths);
|
command.setVolumePaths(volumePaths);
|
||||||
}
|
}
|
||||||
@ -223,7 +225,10 @@ public class NASBackupProvider extends AdapterBase implements BackupProvider, Co
|
|||||||
@Override
|
@Override
|
||||||
public boolean restoreVMFromBackup(VirtualMachine vm, Backup backup) {
|
public boolean restoreVMFromBackup(VirtualMachine vm, Backup backup) {
|
||||||
List<Backup.VolumeInfo> backedVolumes = backup.getBackedUpVolumes();
|
List<Backup.VolumeInfo> backedVolumes = backup.getBackedUpVolumes();
|
||||||
List<VolumeVO> volumes = backedVolumes.stream().map(volume -> volumeDao.findByUuid(volume.getUuid())).collect(Collectors.toList());
|
List<VolumeVO> volumes = backedVolumes.stream()
|
||||||
|
.map(volume -> volumeDao.findByUuid(volume.getUuid()))
|
||||||
|
.sorted((v1, v2) -> Long.compare(v1.getDeviceId(), v2.getDeviceId()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
LOG.debug("Restoring vm {} from backup {} on the NAS Backup Provider", vm, backup);
|
LOG.debug("Restoring vm {} from backup {} on the NAS Backup Provider", vm, backup);
|
||||||
BackupRepository backupRepository = getBackupRepository(vm, backup);
|
BackupRepository backupRepository = getBackupRepository(vm, backup);
|
||||||
@ -257,9 +262,13 @@ public class NASBackupProvider extends AdapterBase implements BackupProvider, Co
|
|||||||
if (Objects.isNull(storagePool)) {
|
if (Objects.isNull(storagePool)) {
|
||||||
throw new CloudRuntimeException("Unable to find storage pool associated to the volume");
|
throw new CloudRuntimeException("Unable to find storage pool associated to the volume");
|
||||||
}
|
}
|
||||||
String volumePathPrefix = String.format("/mnt/%s", storagePool.getUuid());
|
String volumePathPrefix;
|
||||||
if (ScopeType.HOST.equals(storagePool.getScope())) {
|
if (ScopeType.HOST.equals(storagePool.getScope())) {
|
||||||
volumePathPrefix = storagePool.getPath();
|
volumePathPrefix = storagePool.getPath();
|
||||||
|
} else if (Storage.StoragePoolType.SharedMountPoint.equals(storagePool.getPoolType())) {
|
||||||
|
volumePathPrefix = storagePool.getPath();
|
||||||
|
} else {
|
||||||
|
volumePathPrefix = String.format("/mnt/%s", storagePool.getUuid());
|
||||||
}
|
}
|
||||||
volumePaths.add(String.format("%s/%s", volumePathPrefix, volume.getPath()));
|
volumePaths.add(String.format("%s/%s", volumePathPrefix, volume.getPath()));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3731,7 +3731,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
|||||||
if (!meetRequirements) {
|
if (!meetRequirements) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return isUbuntuHost() || isIoUringSupportedByQemu();
|
return isUbuntuOrDebianHost() || isIoUringSupportedByQemu();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -3744,13 +3744,14 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
|||||||
return diskBus != DiskDef.DiskBus.IDE || getHypervisorQemuVersion() >= HYPERVISOR_QEMU_VERSION_IDE_DISCARD_FIXED;
|
return diskBus != DiskDef.DiskBus.IDE || getHypervisorQemuVersion() >= HYPERVISOR_QEMU_VERSION_IDE_DISCARD_FIXED;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isUbuntuHost() {
|
public boolean isUbuntuOrDebianHost() {
|
||||||
Map<String, String> versionString = getVersionStrings();
|
Map<String, String> versionString = getVersionStrings();
|
||||||
String hostKey = "Host.OS";
|
String hostKey = "Host.OS";
|
||||||
if (MapUtils.isEmpty(versionString) || !versionString.containsKey(hostKey) || versionString.get(hostKey) == null) {
|
if (MapUtils.isEmpty(versionString) || !versionString.containsKey(hostKey) || versionString.get(hostKey) == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return versionString.get(hostKey).equalsIgnoreCase("ubuntu");
|
return versionString.get(hostKey).equalsIgnoreCase("ubuntu")
|
||||||
|
|| versionString.get(hostKey).toLowerCase().startsWith("debian");
|
||||||
}
|
}
|
||||||
|
|
||||||
private KVMPhysicalDisk getPhysicalDiskFromNfsStore(String dataStoreUrl, DataTO data) {
|
private KVMPhysicalDisk getPhysicalDiskFromNfsStore(String dataStoreUrl, DataTO data) {
|
||||||
@ -5838,14 +5839,14 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
|||||||
|
|
||||||
public boolean hostSupportsInstanceConversion() {
|
public boolean hostSupportsInstanceConversion() {
|
||||||
int exitValue = Script.runSimpleBashScriptForExitValue(INSTANCE_CONVERSION_SUPPORTED_CHECK_CMD);
|
int exitValue = Script.runSimpleBashScriptForExitValue(INSTANCE_CONVERSION_SUPPORTED_CHECK_CMD);
|
||||||
if (isUbuntuHost() && exitValue == 0) {
|
if (isUbuntuOrDebianHost() && exitValue == 0) {
|
||||||
exitValue = Script.runSimpleBashScriptForExitValue(UBUNTU_NBDKIT_PKG_CHECK_CMD);
|
exitValue = Script.runSimpleBashScriptForExitValue(UBUNTU_NBDKIT_PKG_CHECK_CMD);
|
||||||
}
|
}
|
||||||
return exitValue == 0;
|
return exitValue == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hostSupportsWindowsGuestConversion() {
|
public boolean hostSupportsWindowsGuestConversion() {
|
||||||
if (isUbuntuHost()) {
|
if (isUbuntuOrDebianHost()) {
|
||||||
int exitValue = Script.runSimpleBashScriptForExitValue(UBUNTU_WINDOWS_GUEST_CONVERSION_SUPPORTED_CHECK_CMD);
|
int exitValue = Script.runSimpleBashScriptForExitValue(UBUNTU_WINDOWS_GUEST_CONVERSION_SUPPORTED_CHECK_CMD);
|
||||||
return exitValue == 0;
|
return exitValue == 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -32,7 +32,7 @@ public class LibvirtCheckConvertInstanceCommandWrapper extends CommandWrapper<Ch
|
|||||||
public Answer execute(CheckConvertInstanceCommand cmd, LibvirtComputingResource serverResource) {
|
public Answer execute(CheckConvertInstanceCommand cmd, LibvirtComputingResource serverResource) {
|
||||||
if (!serverResource.hostSupportsInstanceConversion()) {
|
if (!serverResource.hostSupportsInstanceConversion()) {
|
||||||
String msg = String.format("Cannot convert the instance from VMware as the virt-v2v binary is not found on host %s. " +
|
String msg = String.format("Cannot convert the instance from VMware as the virt-v2v binary is not found on host %s. " +
|
||||||
"Please install virt-v2v%s on the host before attempting the instance conversion.", serverResource.getPrivateIp(), serverResource.isUbuntuHost()? ", nbdkit" : "");
|
"Please install virt-v2v%s on the host before attempting the instance conversion.", serverResource.getPrivateIp(), serverResource.isUbuntuOrDebianHost()? ", nbdkit" : "");
|
||||||
logger.info(msg);
|
logger.info(msg);
|
||||||
return new CheckConvertInstanceAnswer(cmd, false, msg);
|
return new CheckConvertInstanceAnswer(cmd, false, msg);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,16 +31,24 @@ import com.cloud.resource.CommandWrapper;
|
|||||||
import com.cloud.resource.ResourceWrapper;
|
import com.cloud.resource.ResourceWrapper;
|
||||||
import com.cloud.storage.Storage;
|
import com.cloud.storage.Storage;
|
||||||
import com.cloud.utils.exception.CloudRuntimeException;
|
import com.cloud.utils.exception.CloudRuntimeException;
|
||||||
|
import org.apache.cloudstack.storage.volume.VolumeOnStorageTO;
|
||||||
import org.apache.cloudstack.utils.qemu.QemuImg;
|
import org.apache.cloudstack.utils.qemu.QemuImg;
|
||||||
import org.apache.cloudstack.utils.qemu.QemuImgException;
|
import org.apache.cloudstack.utils.qemu.QemuImgException;
|
||||||
import org.apache.cloudstack.utils.qemu.QemuImgFile;
|
import org.apache.cloudstack.utils.qemu.QemuImgFile;
|
||||||
|
import org.apache.commons.collections.MapUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.libvirt.LibvirtException;
|
import org.libvirt.LibvirtException;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@ResourceWrapper(handles = CheckVolumeCommand.class)
|
@ResourceWrapper(handles = CheckVolumeCommand.class)
|
||||||
public final class LibvirtCheckVolumeCommandWrapper extends CommandWrapper<CheckVolumeCommand, Answer, LibvirtComputingResource> {
|
public final class LibvirtCheckVolumeCommandWrapper extends CommandWrapper<CheckVolumeCommand, Answer, LibvirtComputingResource> {
|
||||||
|
|
||||||
|
private static final List<Storage.StoragePoolType> STORAGE_POOL_TYPES_SUPPORTED = Arrays.asList(Storage.StoragePoolType.Filesystem, Storage.StoragePoolType.NetworkFilesystem);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Answer execute(final CheckVolumeCommand command, final LibvirtComputingResource libvirtComputingResource) {
|
public Answer execute(final CheckVolumeCommand command, final LibvirtComputingResource libvirtComputingResource) {
|
||||||
String result = null;
|
String result = null;
|
||||||
@ -50,34 +58,76 @@ public final class LibvirtCheckVolumeCommandWrapper extends CommandWrapper<Check
|
|||||||
KVMStoragePool pool = poolMgr.getStoragePool(storageFilerTO.getType(), storageFilerTO.getUuid());
|
KVMStoragePool pool = poolMgr.getStoragePool(storageFilerTO.getType(), storageFilerTO.getUuid());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (storageFilerTO.getType() == Storage.StoragePoolType.Filesystem ||
|
if (STORAGE_POOL_TYPES_SUPPORTED.contains(storageFilerTO.getType())) {
|
||||||
storageFilerTO.getType() == Storage.StoragePoolType.NetworkFilesystem) {
|
|
||||||
final KVMPhysicalDisk vol = pool.getPhysicalDisk(srcFile);
|
final KVMPhysicalDisk vol = pool.getPhysicalDisk(srcFile);
|
||||||
final String path = vol.getPath();
|
final String path = vol.getPath();
|
||||||
long size = getVirtualSizeFromFile(path);
|
try {
|
||||||
return new CheckVolumeAnswer(command, "", size);
|
KVMPhysicalDisk.checkQcow2File(path);
|
||||||
|
} catch (final CloudRuntimeException e) {
|
||||||
|
return new CheckVolumeAnswer(command, false, "", 0, getVolumeDetails(pool, vol));
|
||||||
|
}
|
||||||
|
|
||||||
|
long size = KVMPhysicalDisk.getVirtualSizeFromFile(path);
|
||||||
|
return new CheckVolumeAnswer(command, true, "", size, getVolumeDetails(pool, vol));
|
||||||
} else {
|
} else {
|
||||||
return new Answer(command, false, "Unsupported Storage Pool");
|
return new Answer(command, false, "Unsupported Storage Pool");
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
logger.error("Error while locating disk: "+ e.getMessage());
|
logger.error("Error while checking the disk: {}", e.getMessage());
|
||||||
return new Answer(command, false, result);
|
return new Answer(command, false, result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private long getVirtualSizeFromFile(String path) {
|
private Map<VolumeOnStorageTO.Detail, String> getVolumeDetails(KVMStoragePool pool, KVMPhysicalDisk disk) {
|
||||||
|
Map<String, String> info = getDiskFileInfo(pool, disk, true);
|
||||||
|
if (MapUtils.isEmpty(info)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<VolumeOnStorageTO.Detail, String> volumeDetails = new HashMap<>();
|
||||||
|
|
||||||
|
String backingFilePath = info.get(QemuImg.BACKING_FILE);
|
||||||
|
if (StringUtils.isNotBlank(backingFilePath)) {
|
||||||
|
volumeDetails.put(VolumeOnStorageTO.Detail.BACKING_FILE, backingFilePath);
|
||||||
|
}
|
||||||
|
String backingFileFormat = info.get(QemuImg.BACKING_FILE_FORMAT);
|
||||||
|
if (StringUtils.isNotBlank(backingFileFormat)) {
|
||||||
|
volumeDetails.put(VolumeOnStorageTO.Detail.BACKING_FILE_FORMAT, backingFileFormat);
|
||||||
|
}
|
||||||
|
String clusterSize = info.get(QemuImg.CLUSTER_SIZE);
|
||||||
|
if (StringUtils.isNotBlank(clusterSize)) {
|
||||||
|
volumeDetails.put(VolumeOnStorageTO.Detail.CLUSTER_SIZE, clusterSize);
|
||||||
|
}
|
||||||
|
String fileFormat = info.get(QemuImg.FILE_FORMAT);
|
||||||
|
if (StringUtils.isNotBlank(fileFormat)) {
|
||||||
|
volumeDetails.put(VolumeOnStorageTO.Detail.FILE_FORMAT, fileFormat);
|
||||||
|
}
|
||||||
|
String encrypted = info.get(QemuImg.ENCRYPTED);
|
||||||
|
if (StringUtils.isNotBlank(encrypted) && encrypted.equalsIgnoreCase("yes")) {
|
||||||
|
volumeDetails.put(VolumeOnStorageTO.Detail.IS_ENCRYPTED, String.valueOf(Boolean.TRUE));
|
||||||
|
}
|
||||||
|
Boolean isLocked = isDiskFileLocked(pool, disk);
|
||||||
|
volumeDetails.put(VolumeOnStorageTO.Detail.IS_LOCKED, String.valueOf(isLocked));
|
||||||
|
|
||||||
|
return volumeDetails;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, String> getDiskFileInfo(KVMStoragePool pool, KVMPhysicalDisk disk, boolean secure) {
|
||||||
|
if (!STORAGE_POOL_TYPES_SUPPORTED.contains(pool.getType())) {
|
||||||
|
return new HashMap<>(); // unknown
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
QemuImg qemu = new QemuImg(0);
|
QemuImg qemu = new QemuImg(0);
|
||||||
QemuImgFile qemuFile = new QemuImgFile(path);
|
QemuImgFile qemuFile = new QemuImgFile(disk.getPath(), disk.getFormat());
|
||||||
Map<String, String> info = qemu.info(qemuFile);
|
return qemu.info(qemuFile, secure);
|
||||||
if (info.containsKey(QemuImg.VIRTUAL_SIZE)) {
|
|
||||||
return Long.parseLong(info.get(QemuImg.VIRTUAL_SIZE));
|
|
||||||
} else {
|
|
||||||
throw new CloudRuntimeException("Unable to determine virtual size of volume at path " + path);
|
|
||||||
}
|
|
||||||
} catch (QemuImgException | LibvirtException ex) {
|
} catch (QemuImgException | LibvirtException ex) {
|
||||||
throw new CloudRuntimeException("Error when inspecting volume at path " + path, ex);
|
logger.error("Failed to get info of disk file: " + ex.getMessage());
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isDiskFileLocked(KVMStoragePool pool, KVMPhysicalDisk disk) {
|
||||||
|
Map<String, String> info = getDiskFileInfo(pool, disk, false);
|
||||||
|
return info == null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -60,7 +60,7 @@ public class LibvirtConvertInstanceCommandWrapper extends CommandWrapper<Convert
|
|||||||
|
|
||||||
if (cmd.getCheckConversionSupport() && !serverResource.hostSupportsInstanceConversion()) {
|
if (cmd.getCheckConversionSupport() && !serverResource.hostSupportsInstanceConversion()) {
|
||||||
String msg = String.format("Cannot convert the instance %s from VMware as the virt-v2v binary is not found. " +
|
String msg = String.format("Cannot convert the instance %s from VMware as the virt-v2v binary is not found. " +
|
||||||
"Please install virt-v2v%s on the host before attempting the instance conversion.", sourceInstanceName, serverResource.isUbuntuHost()? ", nbdkit" : "");
|
"Please install virt-v2v%s on the host before attempting the instance conversion.", sourceInstanceName, serverResource.isUbuntuOrDebianHost()? ", nbdkit" : "");
|
||||||
logger.info(msg);
|
logger.info(msg);
|
||||||
return new Answer(cmd, false, msg);
|
return new Answer(cmd, false, msg);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,15 +31,22 @@ import com.cloud.resource.CommandWrapper;
|
|||||||
import com.cloud.resource.ResourceWrapper;
|
import com.cloud.resource.ResourceWrapper;
|
||||||
import com.cloud.storage.Storage;
|
import com.cloud.storage.Storage;
|
||||||
import com.cloud.utils.exception.CloudRuntimeException;
|
import com.cloud.utils.exception.CloudRuntimeException;
|
||||||
|
import org.apache.cloudstack.storage.volume.VolumeOnStorageTO;
|
||||||
import org.apache.cloudstack.utils.qemu.QemuImg;
|
import org.apache.cloudstack.utils.qemu.QemuImg;
|
||||||
import org.apache.cloudstack.utils.qemu.QemuImgException;
|
import org.apache.cloudstack.utils.qemu.QemuImgException;
|
||||||
import org.apache.cloudstack.utils.qemu.QemuImgFile;
|
import org.apache.cloudstack.utils.qemu.QemuImgFile;
|
||||||
|
import org.apache.commons.collections.MapUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.libvirt.LibvirtException;
|
import org.libvirt.LibvirtException;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@ResourceWrapper(handles = CopyRemoteVolumeCommand.class)
|
@ResourceWrapper(handles = CopyRemoteVolumeCommand.class)
|
||||||
public final class LibvirtCopyRemoteVolumeCommandWrapper extends CommandWrapper<CopyRemoteVolumeCommand, Answer, LibvirtComputingResource> {
|
public final class LibvirtCopyRemoteVolumeCommandWrapper extends CommandWrapper<CopyRemoteVolumeCommand, Answer, LibvirtComputingResource> {
|
||||||
|
private static final List<Storage.StoragePoolType> STORAGE_POOL_TYPES_SUPPORTED = Arrays.asList(Storage.StoragePoolType.Filesystem, Storage.StoragePoolType.NetworkFilesystem);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Answer execute(final CopyRemoteVolumeCommand command, final LibvirtComputingResource libvirtComputingResource) {
|
public Answer execute(final CopyRemoteVolumeCommand command, final LibvirtComputingResource libvirtComputingResource) {
|
||||||
@ -55,14 +62,19 @@ public final class LibvirtCopyRemoteVolumeCommandWrapper extends CommandWrapper<
|
|||||||
int timeoutInSecs = command.getWait();
|
int timeoutInSecs = command.getWait();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (storageFilerTO.getType() == Storage.StoragePoolType.Filesystem ||
|
if (STORAGE_POOL_TYPES_SUPPORTED.contains(storageFilerTO.getType())) {
|
||||||
storageFilerTO.getType() == Storage.StoragePoolType.NetworkFilesystem) {
|
|
||||||
String filename = libvirtComputingResource.copyVolume(srcIp, username, password, dstPath, srcFile, tmpPath, timeoutInSecs);
|
String filename = libvirtComputingResource.copyVolume(srcIp, username, password, dstPath, srcFile, tmpPath, timeoutInSecs);
|
||||||
logger.debug("Volume " + srcFile + " copy successful, copied to file: " + filename);
|
logger.debug("Volume " + srcFile + " copy successful, copied to file: " + filename);
|
||||||
final KVMPhysicalDisk vol = pool.getPhysicalDisk(filename);
|
final KVMPhysicalDisk vol = pool.getPhysicalDisk(filename);
|
||||||
final String path = vol.getPath();
|
final String path = vol.getPath();
|
||||||
long size = getVirtualSizeFromFile(path);
|
try {
|
||||||
return new CopyRemoteVolumeAnswer(command, "", filename, size);
|
KVMPhysicalDisk.checkQcow2File(path);
|
||||||
|
} catch (final CloudRuntimeException e) {
|
||||||
|
return new CopyRemoteVolumeAnswer(command, false, "", filename, 0, getVolumeDetails(pool, vol));
|
||||||
|
}
|
||||||
|
|
||||||
|
long size = KVMPhysicalDisk.getVirtualSizeFromFile(path);
|
||||||
|
return new CopyRemoteVolumeAnswer(command, true, "", filename, size, getVolumeDetails(pool, vol));
|
||||||
} else {
|
} else {
|
||||||
String msg = "Unsupported storage pool type: " + storageFilerTO.getType().toString() + ", only local and NFS pools are supported";
|
String msg = "Unsupported storage pool type: " + storageFilerTO.getType().toString() + ", only local and NFS pools are supported";
|
||||||
return new Answer(command, false, msg);
|
return new Answer(command, false, msg);
|
||||||
@ -74,18 +86,56 @@ public final class LibvirtCopyRemoteVolumeCommandWrapper extends CommandWrapper<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private long getVirtualSizeFromFile(String path) {
|
private Map<VolumeOnStorageTO.Detail, String> getVolumeDetails(KVMStoragePool pool, KVMPhysicalDisk disk) {
|
||||||
|
Map<String, String> info = getDiskFileInfo(pool, disk, true);
|
||||||
|
if (MapUtils.isEmpty(info)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<VolumeOnStorageTO.Detail, String> volumeDetails = new HashMap<>();
|
||||||
|
|
||||||
|
String backingFilePath = info.get(QemuImg.BACKING_FILE);
|
||||||
|
if (StringUtils.isNotBlank(backingFilePath)) {
|
||||||
|
volumeDetails.put(VolumeOnStorageTO.Detail.BACKING_FILE, backingFilePath);
|
||||||
|
}
|
||||||
|
String backingFileFormat = info.get(QemuImg.BACKING_FILE_FORMAT);
|
||||||
|
if (StringUtils.isNotBlank(backingFileFormat)) {
|
||||||
|
volumeDetails.put(VolumeOnStorageTO.Detail.BACKING_FILE_FORMAT, backingFileFormat);
|
||||||
|
}
|
||||||
|
String clusterSize = info.get(QemuImg.CLUSTER_SIZE);
|
||||||
|
if (StringUtils.isNotBlank(clusterSize)) {
|
||||||
|
volumeDetails.put(VolumeOnStorageTO.Detail.CLUSTER_SIZE, clusterSize);
|
||||||
|
}
|
||||||
|
String fileFormat = info.get(QemuImg.FILE_FORMAT);
|
||||||
|
if (StringUtils.isNotBlank(fileFormat)) {
|
||||||
|
volumeDetails.put(VolumeOnStorageTO.Detail.FILE_FORMAT, fileFormat);
|
||||||
|
}
|
||||||
|
String encrypted = info.get(QemuImg.ENCRYPTED);
|
||||||
|
if (StringUtils.isNotBlank(encrypted) && encrypted.equalsIgnoreCase("yes")) {
|
||||||
|
volumeDetails.put(VolumeOnStorageTO.Detail.IS_ENCRYPTED, String.valueOf(Boolean.TRUE));
|
||||||
|
}
|
||||||
|
Boolean isLocked = isDiskFileLocked(pool, disk);
|
||||||
|
volumeDetails.put(VolumeOnStorageTO.Detail.IS_LOCKED, String.valueOf(isLocked));
|
||||||
|
|
||||||
|
return volumeDetails;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, String> getDiskFileInfo(KVMStoragePool pool, KVMPhysicalDisk disk, boolean secure) {
|
||||||
|
if (!STORAGE_POOL_TYPES_SUPPORTED.contains(pool.getType())) {
|
||||||
|
return new HashMap<>(); // unknown
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
QemuImg qemu = new QemuImg(0);
|
QemuImg qemu = new QemuImg(0);
|
||||||
QemuImgFile qemuFile = new QemuImgFile(path);
|
QemuImgFile qemuFile = new QemuImgFile(disk.getPath(), disk.getFormat());
|
||||||
Map<String, String> info = qemu.info(qemuFile);
|
return qemu.info(qemuFile, secure);
|
||||||
if (info.containsKey(QemuImg.VIRTUAL_SIZE)) {
|
|
||||||
return Long.parseLong(info.get(QemuImg.VIRTUAL_SIZE));
|
|
||||||
} else {
|
|
||||||
throw new CloudRuntimeException("Unable to determine virtual size of volume at path " + path);
|
|
||||||
}
|
|
||||||
} catch (QemuImgException | LibvirtException ex) {
|
} catch (QemuImgException | LibvirtException ex) {
|
||||||
throw new CloudRuntimeException("Error when inspecting volume at path " + path, ex);
|
logger.error("Failed to get info of disk file: " + ex.getMessage());
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isDiskFileLocked(KVMStoragePool pool, KVMPhysicalDisk disk) {
|
||||||
|
Map<String, String> info = getDiskFileInfo(pool, disk, false);
|
||||||
|
return info == null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,6 +36,7 @@ import org.apache.cloudstack.utils.qemu.QemuImg;
|
|||||||
import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
|
import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
|
||||||
import org.apache.cloudstack.utils.qemu.QemuImgException;
|
import org.apache.cloudstack.utils.qemu.QemuImgException;
|
||||||
import org.apache.cloudstack.utils.qemu.QemuImgFile;
|
import org.apache.cloudstack.utils.qemu.QemuImgFile;
|
||||||
|
import org.apache.commons.collections.MapUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.libvirt.LibvirtException;
|
import org.libvirt.LibvirtException;
|
||||||
|
|
||||||
@ -91,6 +92,22 @@ public final class LibvirtGetVolumesOnStorageCommandWrapper extends CommandWrapp
|
|||||||
if (disk.getQemuEncryptFormat() != null) {
|
if (disk.getQemuEncryptFormat() != null) {
|
||||||
volumeOnStorageTO.setQemuEncryptFormat(disk.getQemuEncryptFormat().toString());
|
volumeOnStorageTO.setQemuEncryptFormat(disk.getQemuEncryptFormat().toString());
|
||||||
}
|
}
|
||||||
|
String fileFormat = info.get(QemuImg.FILE_FORMAT);
|
||||||
|
if (StringUtils.isNotBlank(fileFormat) && !fileFormat.equalsIgnoreCase(disk.getFormat().toString())) {
|
||||||
|
return new GetVolumesOnStorageAnswer(command, false, String.format("The file format is %s, but expected to be %s", fileFormat, disk.getFormat()));
|
||||||
|
}
|
||||||
|
addDetailsToVolumeOnStorageTO(volumeOnStorageTO, info, storagePool, disk);
|
||||||
|
|
||||||
|
volumes.add(volumeOnStorageTO);
|
||||||
|
}
|
||||||
|
return new GetVolumesOnStorageAnswer(command, volumes);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addDetailsToVolumeOnStorageTO(VolumeOnStorageTO volumeOnStorageTO, final Map<String, String> info, final KVMStoragePool storagePool, final KVMPhysicalDisk disk) {
|
||||||
|
if (MapUtils.isEmpty(info)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
String backingFilePath = info.get(QemuImg.BACKING_FILE);
|
String backingFilePath = info.get(QemuImg.BACKING_FILE);
|
||||||
if (StringUtils.isNotBlank(backingFilePath)) {
|
if (StringUtils.isNotBlank(backingFilePath)) {
|
||||||
volumeOnStorageTO.addDetail(VolumeOnStorageTO.Detail.BACKING_FILE, backingFilePath);
|
volumeOnStorageTO.addDetail(VolumeOnStorageTO.Detail.BACKING_FILE, backingFilePath);
|
||||||
@ -105,9 +122,6 @@ public final class LibvirtGetVolumesOnStorageCommandWrapper extends CommandWrapp
|
|||||||
}
|
}
|
||||||
String fileFormat = info.get(QemuImg.FILE_FORMAT);
|
String fileFormat = info.get(QemuImg.FILE_FORMAT);
|
||||||
if (StringUtils.isNotBlank(fileFormat)) {
|
if (StringUtils.isNotBlank(fileFormat)) {
|
||||||
if (!fileFormat.equalsIgnoreCase(disk.getFormat().toString())) {
|
|
||||||
return new GetVolumesOnStorageAnswer(command, false, String.format("The file format is %s, but expected to be %s", fileFormat, disk.getFormat()));
|
|
||||||
}
|
|
||||||
volumeOnStorageTO.addDetail(VolumeOnStorageTO.Detail.FILE_FORMAT, fileFormat);
|
volumeOnStorageTO.addDetail(VolumeOnStorageTO.Detail.FILE_FORMAT, fileFormat);
|
||||||
}
|
}
|
||||||
String encrypted = info.get(QemuImg.ENCRYPTED);
|
String encrypted = info.get(QemuImg.ENCRYPTED);
|
||||||
@ -116,10 +130,6 @@ public final class LibvirtGetVolumesOnStorageCommandWrapper extends CommandWrapp
|
|||||||
}
|
}
|
||||||
Boolean isLocked = isDiskFileLocked(storagePool, disk);
|
Boolean isLocked = isDiskFileLocked(storagePool, disk);
|
||||||
volumeOnStorageTO.addDetail(VolumeOnStorageTO.Detail.IS_LOCKED, String.valueOf(isLocked));
|
volumeOnStorageTO.addDetail(VolumeOnStorageTO.Detail.IS_LOCKED, String.valueOf(isLocked));
|
||||||
|
|
||||||
volumes.add(volumeOnStorageTO);
|
|
||||||
}
|
|
||||||
return new GetVolumesOnStorageAnswer(command, volumes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private GetVolumesOnStorageAnswer addAllVolumes(final GetVolumesOnStorageCommand command, final KVMStoragePool storagePool, String keyword) {
|
private GetVolumesOnStorageAnswer addAllVolumes(final GetVolumesOnStorageCommand command, final KVMStoragePool storagePool, String keyword) {
|
||||||
@ -134,11 +144,21 @@ public final class LibvirtGetVolumesOnStorageCommandWrapper extends CommandWrapp
|
|||||||
if (!isDiskFormatSupported(disk)) {
|
if (!isDiskFormatSupported(disk)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
Map<String, String> info = getDiskFileInfo(storagePool, disk, true);
|
||||||
|
if (info == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
VolumeOnStorageTO volumeOnStorageTO = new VolumeOnStorageTO(Hypervisor.HypervisorType.KVM, disk.getName(), disk.getName(), disk.getPath(),
|
VolumeOnStorageTO volumeOnStorageTO = new VolumeOnStorageTO(Hypervisor.HypervisorType.KVM, disk.getName(), disk.getName(), disk.getPath(),
|
||||||
disk.getFormat().toString(), disk.getSize(), disk.getVirtualSize());
|
disk.getFormat().toString(), disk.getSize(), disk.getVirtualSize());
|
||||||
if (disk.getQemuEncryptFormat() != null) {
|
if (disk.getQemuEncryptFormat() != null) {
|
||||||
volumeOnStorageTO.setQemuEncryptFormat(disk.getQemuEncryptFormat().toString());
|
volumeOnStorageTO.setQemuEncryptFormat(disk.getQemuEncryptFormat().toString());
|
||||||
}
|
}
|
||||||
|
String fileFormat = info.get(QemuImg.FILE_FORMAT);
|
||||||
|
if (StringUtils.isNotBlank(fileFormat) && !fileFormat.equalsIgnoreCase(disk.getFormat().toString())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
addDetailsToVolumeOnStorageTO(volumeOnStorageTO, info, storagePool, disk);
|
||||||
|
|
||||||
volumes.add(volumeOnStorageTO);
|
volumes.add(volumeOnStorageTO);
|
||||||
}
|
}
|
||||||
return new GetVolumesOnStorageAnswer(command, volumes);
|
return new GetVolumesOnStorageAnswer(command, volumes);
|
||||||
|
|||||||
@ -43,7 +43,7 @@ public final class LibvirtReadyCommandWrapper extends CommandWrapper<ReadyComman
|
|||||||
public Answer execute(final ReadyCommand command, final LibvirtComputingResource libvirtComputingResource) {
|
public Answer execute(final ReadyCommand command, final LibvirtComputingResource libvirtComputingResource) {
|
||||||
Map<String, String> hostDetails = new HashMap<String, String>();
|
Map<String, String> hostDetails = new HashMap<String, String>();
|
||||||
|
|
||||||
if (hostSupportsUefi(libvirtComputingResource.isUbuntuHost()) && libvirtComputingResource.isUefiPropertiesFileLoaded()) {
|
if (hostSupportsUefi(libvirtComputingResource.isUbuntuOrDebianHost()) && libvirtComputingResource.isUefiPropertiesFileLoaded()) {
|
||||||
hostDetails.put(Host.HOST_UEFI_ENABLE, Boolean.TRUE.toString());
|
hostDetails.put(Host.HOST_UEFI_ENABLE, Boolean.TRUE.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,10 +58,10 @@ public final class LibvirtReadyCommandWrapper extends CommandWrapper<ReadyComman
|
|||||||
return new ReadyAnswer(command, hostDetails);
|
return new ReadyAnswer(command, hostDetails);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hostSupportsUefi(boolean isUbuntuHost) {
|
private boolean hostSupportsUefi(boolean isUbuntuOrDebianHost) {
|
||||||
int timeout = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.AGENT_SCRIPT_TIMEOUT) * 1000; // Get property value & convert to milliseconds
|
int timeout = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.AGENT_SCRIPT_TIMEOUT) * 1000; // Get property value & convert to milliseconds
|
||||||
int result;
|
int result;
|
||||||
if (isUbuntuHost) {
|
if (isUbuntuOrDebianHost) {
|
||||||
logger.debug("Running command : [dpkg -l ovmf] with timeout : " + timeout + " ms");
|
logger.debug("Running command : [dpkg -l ovmf] with timeout : " + timeout + " ms");
|
||||||
result = Script.executeCommandForExitValue(timeout, Script.getExecutableAbsolutePath("dpkg"), "-l", "ovmf");
|
result = Script.executeCommandForExitValue(timeout, Script.getExecutableAbsolutePath("dpkg"), "-l", "ovmf");
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -25,7 +25,6 @@ import java.io.IOException;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import com.cloud.hypervisor.kvm.storage.ScaleIOStorageAdaptor;
|
import com.cloud.hypervisor.kvm.storage.ScaleIOStorageAdaptor;
|
||||||
import org.apache.cloudstack.utils.cryptsetup.KeyFile;
|
import org.apache.cloudstack.utils.cryptsetup.KeyFile;
|
||||||
@ -33,7 +32,6 @@ import org.apache.cloudstack.utils.qemu.QemuImageOptions;
|
|||||||
import org.apache.cloudstack.utils.qemu.QemuImg;
|
import org.apache.cloudstack.utils.qemu.QemuImg;
|
||||||
import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
|
import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
|
||||||
import org.apache.cloudstack.utils.qemu.QemuImgException;
|
import org.apache.cloudstack.utils.qemu.QemuImgException;
|
||||||
import org.apache.cloudstack.utils.qemu.QemuImgFile;
|
|
||||||
import org.apache.cloudstack.utils.qemu.QemuObject;
|
import org.apache.cloudstack.utils.qemu.QemuObject;
|
||||||
import org.libvirt.Connect;
|
import org.libvirt.Connect;
|
||||||
import org.libvirt.Domain;
|
import org.libvirt.Domain;
|
||||||
@ -100,7 +98,7 @@ public final class LibvirtResizeVolumeCommandWrapper extends CommandWrapper<Resi
|
|||||||
newSize = ScaleIOStorageAdaptor.getUsableBytesFromRawBytes(newSize);
|
newSize = ScaleIOStorageAdaptor.getUsableBytesFromRawBytes(newSize);
|
||||||
} else if (spool.getType().equals(StoragePoolType.PowerFlex)) {
|
} else if (spool.getType().equals(StoragePoolType.PowerFlex)) {
|
||||||
// PowerFlex RAW/LUKS is already resized, we just notify the domain based on new size (considering LUKS overhead)
|
// PowerFlex RAW/LUKS is already resized, we just notify the domain based on new size (considering LUKS overhead)
|
||||||
newSize = getVirtualSizeFromFile(path);
|
newSize = KVMPhysicalDisk.getVirtualSizeFromFile(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pool.getType() != StoragePoolType.RBD && pool.getType() != StoragePoolType.Linstor && pool.getType() != StoragePoolType.PowerFlex) {
|
if (pool.getType() != StoragePoolType.RBD && pool.getType() != StoragePoolType.Linstor && pool.getType() != StoragePoolType.PowerFlex) {
|
||||||
@ -214,21 +212,6 @@ public final class LibvirtResizeVolumeCommandWrapper extends CommandWrapper<Resi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private long getVirtualSizeFromFile(String path) {
|
|
||||||
try {
|
|
||||||
QemuImg qemu = new QemuImg(0);
|
|
||||||
QemuImgFile qemuFile = new QemuImgFile(path);
|
|
||||||
Map<String, String> info = qemu.info(qemuFile);
|
|
||||||
if (info.containsKey(QemuImg.VIRTUAL_SIZE)) {
|
|
||||||
return Long.parseLong(info.get(QemuImg.VIRTUAL_SIZE));
|
|
||||||
} else {
|
|
||||||
throw new CloudRuntimeException("Unable to determine virtual size of volume at path " + path);
|
|
||||||
}
|
|
||||||
} catch (QemuImgException | LibvirtException ex) {
|
|
||||||
throw new CloudRuntimeException("Error when inspecting volume at path " + path, ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Answer handleMultipathSCSIResize(ResizeVolumeCommand command, KVMStoragePool pool) {
|
private Answer handleMultipathSCSIResize(ResizeVolumeCommand command, KVMStoragePool pool) {
|
||||||
((MultipathSCSIPool)pool).resize(command.getPath(), command.getInstanceName(), command.getNewSize());
|
((MultipathSCSIPool)pool).resize(command.getPath(), command.getInstanceName(), command.getNewSize());
|
||||||
return new ResizeVolumeAnswer(command, true, "");
|
return new ResizeVolumeAnswer(command, true, "");
|
||||||
|
|||||||
@ -62,6 +62,7 @@ public class LibvirtRestoreBackupCommandWrapper extends CommandWrapper<RestoreBa
|
|||||||
String restoreVolumeUuid = command.getRestoreVolumeUUID();
|
String restoreVolumeUuid = command.getRestoreVolumeUUID();
|
||||||
|
|
||||||
String newVolumeId = null;
|
String newVolumeId = null;
|
||||||
|
try {
|
||||||
if (Objects.isNull(vmExists)) {
|
if (Objects.isNull(vmExists)) {
|
||||||
String volumePath = volumePaths.get(0);
|
String volumePath = volumePaths.get(0);
|
||||||
int lastIndex = volumePath.lastIndexOf("/");
|
int lastIndex = volumePath.lastIndexOf("/");
|
||||||
@ -73,6 +74,14 @@ public class LibvirtRestoreBackupCommandWrapper extends CommandWrapper<RestoreBa
|
|||||||
} else {
|
} else {
|
||||||
restoreVolumesOfDestroyedVMs(volumePaths, vmName, backupPath, backupRepoType, backupRepoAddress, mountOptions);
|
restoreVolumesOfDestroyedVMs(volumePaths, vmName, backupPath, backupRepoType, backupRepoAddress, mountOptions);
|
||||||
}
|
}
|
||||||
|
} catch (CloudRuntimeException e) {
|
||||||
|
String errorMessage = "Failed to restore backup for VM: " + vmName + ".";
|
||||||
|
if (e.getMessage() != null && !e.getMessage().isEmpty()) {
|
||||||
|
errorMessage += " Details: " + e.getMessage();
|
||||||
|
}
|
||||||
|
logger.error(errorMessage);
|
||||||
|
return new BackupAnswer(command, false, errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
return new BackupAnswer(command, true, newVolumeId);
|
return new BackupAnswer(command, true, newVolumeId);
|
||||||
}
|
}
|
||||||
@ -86,10 +95,8 @@ public class LibvirtRestoreBackupCommandWrapper extends CommandWrapper<RestoreBa
|
|||||||
String volumePath = volumePaths.get(idx);
|
String volumePath = volumePaths.get(idx);
|
||||||
Pair<String, String> bkpPathAndVolUuid = getBackupPath(mountDirectory, volumePath, backupPath, diskType, null);
|
Pair<String, String> bkpPathAndVolUuid = getBackupPath(mountDirectory, volumePath, backupPath, diskType, null);
|
||||||
diskType = "datadisk";
|
diskType = "datadisk";
|
||||||
try {
|
if (!replaceVolumeWithBackup(volumePath, bkpPathAndVolUuid.first())) {
|
||||||
replaceVolumeWithBackup(volumePath, bkpPathAndVolUuid.first());
|
throw new CloudRuntimeException(String.format("Unable to restore backup for volume [%s].", bkpPathAndVolUuid.second()));
|
||||||
} catch (IOException e) {
|
|
||||||
throw new CloudRuntimeException(String.format("Unable to revert backup for volume [%s] due to [%s].", bkpPathAndVolUuid.second(), e.getMessage()), e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
@ -108,10 +115,8 @@ public class LibvirtRestoreBackupCommandWrapper extends CommandWrapper<RestoreBa
|
|||||||
String volumePath = volumePaths.get(i);
|
String volumePath = volumePaths.get(i);
|
||||||
Pair<String, String> bkpPathAndVolUuid = getBackupPath(mountDirectory, volumePath, backupPath, diskType, null);
|
Pair<String, String> bkpPathAndVolUuid = getBackupPath(mountDirectory, volumePath, backupPath, diskType, null);
|
||||||
diskType = "datadisk";
|
diskType = "datadisk";
|
||||||
try {
|
if (!replaceVolumeWithBackup(volumePath, bkpPathAndVolUuid.first())) {
|
||||||
replaceVolumeWithBackup(volumePath, bkpPathAndVolUuid.first());
|
throw new CloudRuntimeException(String.format("Unable to restore backup for volume [%s].", bkpPathAndVolUuid.second()));
|
||||||
} catch (IOException e) {
|
|
||||||
throw new CloudRuntimeException(String.format("Unable to revert backup for volume [%s] due to [%s].", bkpPathAndVolUuid.second(), e.getMessage()), e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
@ -126,16 +131,14 @@ public class LibvirtRestoreBackupCommandWrapper extends CommandWrapper<RestoreBa
|
|||||||
Pair<String, String> bkpPathAndVolUuid;
|
Pair<String, String> bkpPathAndVolUuid;
|
||||||
try {
|
try {
|
||||||
bkpPathAndVolUuid = getBackupPath(mountDirectory, volumePath, backupPath, diskType, volumeUUID);
|
bkpPathAndVolUuid = getBackupPath(mountDirectory, volumePath, backupPath, diskType, volumeUUID);
|
||||||
try {
|
if (!replaceVolumeWithBackup(volumePath, bkpPathAndVolUuid.first())) {
|
||||||
replaceVolumeWithBackup(volumePath, bkpPathAndVolUuid.first());
|
throw new CloudRuntimeException(String.format("Unable to restore backup for volume [%s].", bkpPathAndVolUuid.second()));
|
||||||
|
}
|
||||||
if (VirtualMachine.State.Running.equals(vmNameAndState.second())) {
|
if (VirtualMachine.State.Running.equals(vmNameAndState.second())) {
|
||||||
if (!attachVolumeToVm(vmNameAndState.first(), volumePath)) {
|
if (!attachVolumeToVm(vmNameAndState.first(), volumePath)) {
|
||||||
throw new CloudRuntimeException(String.format("Failed to attach volume to VM: %s", vmNameAndState.first()));
|
throw new CloudRuntimeException(String.format("Failed to attach volume to VM: %s", vmNameAndState.first()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
|
||||||
throw new CloudRuntimeException(String.format("Unable to revert backup for volume [%s] due to [%s].", bkpPathAndVolUuid.second(), e.getMessage()), e);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new CloudRuntimeException("Failed to restore volume", e);
|
throw new CloudRuntimeException("Failed to restore volume", e);
|
||||||
} finally {
|
} finally {
|
||||||
@ -194,8 +197,9 @@ public class LibvirtRestoreBackupCommandWrapper extends CommandWrapper<RestoreBa
|
|||||||
return new Pair<>(bkpPath, volUuid);
|
return new Pair<>(bkpPath, volUuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void replaceVolumeWithBackup(String volumePath, String backupPath) throws IOException {
|
private boolean replaceVolumeWithBackup(String volumePath, String backupPath) {
|
||||||
Script.runSimpleBashScript(String.format(RSYNC_COMMAND, backupPath, volumePath));
|
int exitValue = Script.runSimpleBashScriptForExitValue(String.format(RSYNC_COMMAND, backupPath, volumePath));
|
||||||
|
return exitValue == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean attachVolumeToVm(String vmName, String volumePath) {
|
private boolean attachVolumeToVm(String vmName, String volumePath) {
|
||||||
|
|||||||
@ -16,10 +16,17 @@
|
|||||||
// under the License.
|
// under the License.
|
||||||
package com.cloud.hypervisor.kvm.storage;
|
package com.cloud.hypervisor.kvm.storage;
|
||||||
|
|
||||||
|
import com.cloud.utils.exception.CloudRuntimeException;
|
||||||
|
import org.apache.cloudstack.storage.formatinspector.Qcow2Inspector;
|
||||||
|
import org.apache.cloudstack.utils.imagestore.ImageStoreUtil;
|
||||||
|
import org.apache.cloudstack.utils.qemu.QemuImg;
|
||||||
import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
|
import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
|
||||||
|
import org.apache.cloudstack.utils.qemu.QemuImgException;
|
||||||
|
import org.apache.cloudstack.utils.qemu.QemuImgFile;
|
||||||
import org.apache.cloudstack.utils.qemu.QemuObject;
|
import org.apache.cloudstack.utils.qemu.QemuObject;
|
||||||
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
|
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.libvirt.LibvirtException;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -83,6 +90,31 @@ public class KVMPhysicalDisk {
|
|||||||
return hostIp;
|
return hostIp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static long getVirtualSizeFromFile(String path) {
|
||||||
|
try {
|
||||||
|
QemuImg qemu = new QemuImg(0);
|
||||||
|
QemuImgFile qemuFile = new QemuImgFile(path);
|
||||||
|
Map<String, String> info = qemu.info(qemuFile);
|
||||||
|
if (info.containsKey(QemuImg.VIRTUAL_SIZE)) {
|
||||||
|
return Long.parseLong(info.get(QemuImg.VIRTUAL_SIZE));
|
||||||
|
} else {
|
||||||
|
throw new CloudRuntimeException("Unable to determine virtual size of volume at path " + path);
|
||||||
|
}
|
||||||
|
} catch (QemuImgException | LibvirtException ex) {
|
||||||
|
throw new CloudRuntimeException("Error when inspecting volume at path " + path, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void checkQcow2File(String path) {
|
||||||
|
if (ImageStoreUtil.isCorrectExtension(path, "qcow2")) {
|
||||||
|
try {
|
||||||
|
Qcow2Inspector.validateQcow2File(path);
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
throw new CloudRuntimeException("The volume file at path " + path + " is not a valid QCOW2. Error: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private PhysicalDiskFormat format;
|
private PhysicalDiskFormat format;
|
||||||
private long size;
|
private long size;
|
||||||
private long virtualSize;
|
private long virtualSize;
|
||||||
|
|||||||
@ -236,6 +236,12 @@ public class MockAccountManager extends ManagerBase implements AccountManager {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isResourceDomainAdmin(Long accountId) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isNormalUser(long accountId) {
|
public boolean isNormalUser(long accountId) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|||||||
@ -136,13 +136,18 @@ public class StorageVmSharedFSLifeCycle implements SharedFSLifeCycle {
|
|||||||
return fsVmConfig;
|
return fsVmConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getStorageVmName(String fileShareName) {
|
private String getStorageVmPrefix(String fileShareName) {
|
||||||
String prefix = String.format("%s-%s", SharedFSVmNamePrefix, fileShareName);
|
String prefix = String.format("%s-%s", SharedFSVmNamePrefix, fileShareName);
|
||||||
String suffix = Long.toHexString(System.currentTimeMillis());
|
|
||||||
|
|
||||||
if (!NetUtils.verifyDomainNameLabel(prefix, true)) {
|
if (!NetUtils.verifyDomainNameLabel(prefix, true)) {
|
||||||
prefix = prefix.replaceAll("[^a-zA-Z0-9-]", "");
|
prefix = prefix.replaceAll("[^a-zA-Z0-9-]", "");
|
||||||
}
|
}
|
||||||
|
return prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getStorageVmName(String fileShareName) {
|
||||||
|
String prefix = getStorageVmPrefix(fileShareName);
|
||||||
|
String suffix = Long.toHexString(System.currentTimeMillis());
|
||||||
|
|
||||||
int nameLength = prefix.length() + suffix.length() + SharedFSVmNamePrefix.length();
|
int nameLength = prefix.length() + suffix.length() + SharedFSVmNamePrefix.length();
|
||||||
if (nameLength > 63) {
|
if (nameLength > 63) {
|
||||||
int prefixLength = prefix.length() - (nameLength - 63);
|
int prefixLength = prefix.length() - (nameLength - 63);
|
||||||
@ -232,8 +237,18 @@ public class StorageVmSharedFSLifeCycle implements SharedFSLifeCycle {
|
|||||||
Account owner = accountMgr.getActiveAccountById(sharedFS.getAccountId());
|
Account owner = accountMgr.getActiveAccountById(sharedFS.getAccountId());
|
||||||
UserVm vm = deploySharedFSVM(sharedFS.getDataCenterId(), owner, List.of(networkId), sharedFS.getName(), sharedFS.getServiceOfferingId(), diskOfferingId, sharedFS.getFsType(), size, minIops, maxIops);
|
UserVm vm = deploySharedFSVM(sharedFS.getDataCenterId(), owner, List.of(networkId), sharedFS.getName(), sharedFS.getServiceOfferingId(), diskOfferingId, sharedFS.getFsType(), size, minIops, maxIops);
|
||||||
|
|
||||||
List<VolumeVO> volumes = volumeDao.findByInstanceAndType(vm.getId(), Volume.Type.DATADISK);
|
List<VolumeVO> volumes = volumeDao.findByInstance(vm.getId());
|
||||||
return new Pair<>(volumes.get(0).getId(), vm.getId());
|
VolumeVO dataVol = null;
|
||||||
|
for (VolumeVO vol : volumes) {
|
||||||
|
String volumeName = vol.getName();
|
||||||
|
String updatedVolumeName = SharedFSVmNamePrefix + "-" + volumeName;
|
||||||
|
vol.setName(updatedVolumeName);
|
||||||
|
volumeDao.update(vol.getId(), vol);
|
||||||
|
if (vol.getVolumeType() == Volume.Type.DATADISK) {
|
||||||
|
dataVol = vol;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new Pair<>(dataVol.getId(), vm.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -259,9 +259,14 @@ public class StorageVmSharedFSLifeCycleTest {
|
|||||||
anyMap(), isNull(), isNull(), isNull(), isNull(),
|
anyMap(), isNull(), isNull(), isNull(), isNull(),
|
||||||
anyBoolean(), anyString(), isNull(), isNull(), isNull())).thenReturn(vm);
|
anyBoolean(), anyString(), isNull(), isNull(), isNull())).thenReturn(vm);
|
||||||
|
|
||||||
VolumeVO volume = mock(VolumeVO.class);
|
VolumeVO rootVol = mock(VolumeVO.class);
|
||||||
when(volume.getId()).thenReturn(s_volumeId);
|
when(rootVol.getVolumeType()).thenReturn(Volume.Type.ROOT);
|
||||||
when(volumeDao.findByInstanceAndType(s_vmId, Volume.Type.DATADISK)).thenReturn(List.of(volume));
|
when(rootVol.getName()).thenReturn("ROOT-1");
|
||||||
|
VolumeVO dataVol = mock(VolumeVO.class);
|
||||||
|
when(dataVol.getId()).thenReturn(s_volumeId);
|
||||||
|
when(dataVol.getName()).thenReturn("DATA-1");
|
||||||
|
when(dataVol.getVolumeType()).thenReturn(Volume.Type.DATADISK);
|
||||||
|
when(volumeDao.findByInstance(s_vmId)).thenReturn(List.of(rootVol, dataVol));
|
||||||
|
|
||||||
Pair<Long, Long> result = lifeCycle.deploySharedFS(sharedFS, s_networkId, s_diskOfferingId, s_size, s_minIops, s_maxIops);
|
Pair<Long, Long> result = lifeCycle.deploySharedFS(sharedFS, s_networkId, s_diskOfferingId, s_size, s_minIops, s_maxIops);
|
||||||
Assert.assertEquals(Optional.ofNullable(result.first()), Optional.ofNullable(s_volumeId));
|
Assert.assertEquals(Optional.ofNullable(result.first()), Optional.ofNullable(s_volumeId));
|
||||||
|
|||||||
@ -5,6 +5,12 @@ All notable changes to Linstor CloudStack plugin will be documented in this file
|
|||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## [2025-07-01]
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Regression in 4.19.3 and 4.21.0 with templates from snapshots
|
||||||
|
|
||||||
## [2025-05-07]
|
## [2025-05-07]
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
@ -622,7 +622,7 @@ public class LinstorStorageAdaptor implements StorageAdaptor {
|
|||||||
try {
|
try {
|
||||||
templateProps.load(new FileInputStream(propFile.toFile()));
|
templateProps.load(new FileInputStream(propFile.toFile()));
|
||||||
String desc = templateProps.getProperty("description");
|
String desc = templateProps.getProperty("description");
|
||||||
if (desc.startsWith("SystemVM Template")) {
|
if (desc != null && desc.startsWith("SystemVM Template")) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
|||||||
@ -74,12 +74,14 @@ import com.cloud.storage.StorageManager;
|
|||||||
import com.cloud.storage.StoragePool;
|
import com.cloud.storage.StoragePool;
|
||||||
import com.cloud.storage.VMTemplateStoragePoolVO;
|
import com.cloud.storage.VMTemplateStoragePoolVO;
|
||||||
import com.cloud.storage.VMTemplateStorageResourceAssoc;
|
import com.cloud.storage.VMTemplateStorageResourceAssoc;
|
||||||
|
import com.cloud.storage.VMTemplateVO;
|
||||||
import com.cloud.storage.Volume;
|
import com.cloud.storage.Volume;
|
||||||
import com.cloud.storage.VolumeDetailVO;
|
import com.cloud.storage.VolumeDetailVO;
|
||||||
import com.cloud.storage.VolumeVO;
|
import com.cloud.storage.VolumeVO;
|
||||||
import com.cloud.storage.dao.SnapshotDao;
|
import com.cloud.storage.dao.SnapshotDao;
|
||||||
import com.cloud.storage.dao.SnapshotDetailsDao;
|
import com.cloud.storage.dao.SnapshotDetailsDao;
|
||||||
import com.cloud.storage.dao.SnapshotDetailsVO;
|
import com.cloud.storage.dao.SnapshotDetailsVO;
|
||||||
|
import com.cloud.storage.dao.VMTemplateDao;
|
||||||
import com.cloud.storage.dao.VMTemplatePoolDao;
|
import com.cloud.storage.dao.VMTemplatePoolDao;
|
||||||
import com.cloud.storage.dao.VolumeDao;
|
import com.cloud.storage.dao.VolumeDao;
|
||||||
import com.cloud.storage.dao.VolumeDetailsDao;
|
import com.cloud.storage.dao.VolumeDetailsDao;
|
||||||
@ -133,6 +135,7 @@ public class LinstorPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver
|
|||||||
ConfigurationDao _configDao;
|
ConfigurationDao _configDao;
|
||||||
@Inject
|
@Inject
|
||||||
private HostDao _hostDao;
|
private HostDao _hostDao;
|
||||||
|
@Inject private VMTemplateDao _vmTemplateDao;
|
||||||
|
|
||||||
private long volumeStatsLastUpdate = 0L;
|
private long volumeStatsLastUpdate = 0L;
|
||||||
private final Map<String, Pair<Long, Long>> volumeStats = new HashMap<>();
|
private final Map<String, Pair<Long, Long>> volumeStats = new HashMap<>();
|
||||||
@ -670,8 +673,15 @@ public class LinstorPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver
|
|||||||
storagePoolVO.getId(), csCloneId, null);
|
storagePoolVO.getId(), csCloneId, null);
|
||||||
|
|
||||||
if (tmplPoolRef != null) {
|
if (tmplPoolRef != null) {
|
||||||
final String templateRscName = LinstorUtil.RSC_PREFIX + tmplPoolRef.getLocalDownloadPath();
|
final String templateRscName;
|
||||||
|
if (tmplPoolRef.getLocalDownloadPath() == null) {
|
||||||
|
VMTemplateVO vmTemplateVO = _vmTemplateDao.findById(tmplPoolRef.getTemplateId());
|
||||||
|
templateRscName = LinstorUtil.RSC_PREFIX + vmTemplateVO.getUuid();
|
||||||
|
} else {
|
||||||
|
templateRscName = LinstorUtil.RSC_PREFIX + tmplPoolRef.getLocalDownloadPath();
|
||||||
|
}
|
||||||
final String rscName = LinstorUtil.RSC_PREFIX + volumeInfo.getUuid();
|
final String rscName = LinstorUtil.RSC_PREFIX + volumeInfo.getUuid();
|
||||||
|
|
||||||
final DevelopersApi linstorApi = LinstorUtil.getLinstorAPI(storagePoolVO.getHostAddress());
|
final DevelopersApi linstorApi = LinstorUtil.getLinstorAPI(storagePoolVO.getHostAddress());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -1279,13 +1279,13 @@ public class ScaleIOPrimaryDataStoreDriver implements PrimaryDataStoreDriver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
org.apache.cloudstack.storage.datastore.api.Volume scaleIOVolume = client.getVolume(scaleIOVolumeId);
|
org.apache.cloudstack.storage.datastore.api.Volume scaleIOVolume = client.getVolume(scaleIOVolumeId);
|
||||||
long newSizeInGB = newSizeInBytes / (1024 * 1024 * 1024);
|
double newSizeInGB = newSizeInBytes / (1024.0 * 1024 * 1024);
|
||||||
long newSizeIn8gbBoundary = (long) (Math.ceil(newSizeInGB / 8.0) * 8.0);
|
long newSizeIn8GBBoundary = (long) (Math.ceil(newSizeInGB / 8.0) * 8.0);
|
||||||
|
|
||||||
if (scaleIOVolume.getSizeInKb() == newSizeIn8gbBoundary << 20) {
|
if (scaleIOVolume.getSizeInKb() == newSizeIn8GBBoundary << 20) {
|
||||||
logger.debug("No resize necessary at API");
|
logger.debug("No resize necessary at API");
|
||||||
} else {
|
} else {
|
||||||
scaleIOVolume = client.resizeVolume(scaleIOVolumeId, (int) newSizeIn8gbBoundary);
|
scaleIOVolume = client.resizeVolume(scaleIOVolumeId, (int) newSizeIn8GBBoundary);
|
||||||
if (scaleIOVolume == null) {
|
if (scaleIOVolume == null) {
|
||||||
throw new CloudRuntimeException("Failed to resize volume: " + volumeInfo.getName());
|
throw new CloudRuntimeException("Failed to resize volume: " + volumeInfo.getName());
|
||||||
}
|
}
|
||||||
@ -1411,12 +1411,12 @@ public class ScaleIOPrimaryDataStoreDriver implements PrimaryDataStoreDriver {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getVolumeSizeRequiredOnPool(long volumeSize, Long templateSize, boolean isEncryptionRequired) {
|
public long getVolumeSizeRequiredOnPool(long volumeSize, Long templateSize, boolean isEncryptionRequired) {
|
||||||
long newSizeInGB = volumeSize / (1024 * 1024 * 1024);
|
double newSizeInGB = volumeSize / (1024.0 * 1024 * 1024);
|
||||||
if (templateSize != null && isEncryptionRequired && needsExpansionForEncryptionHeader(templateSize, volumeSize)) {
|
if (templateSize != null && isEncryptionRequired && needsExpansionForEncryptionHeader(templateSize, volumeSize)) {
|
||||||
newSizeInGB = (volumeSize + (1<<30)) / (1024 * 1024 * 1024);
|
newSizeInGB = (volumeSize + (1<<30)) / (1024.0 * 1024 * 1024);
|
||||||
}
|
}
|
||||||
long newSizeIn8gbBoundary = (long) (Math.ceil(newSizeInGB / 8.0) * 8.0);
|
long newSizeIn8GBBoundary = (long) (Math.ceil(newSizeInGB / 8.0) * 8.0);
|
||||||
return newSizeIn8gbBoundary * (1024 * 1024 * 1024);
|
return newSizeIn8GBBoundary * (1024 * 1024 * 1024);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -555,6 +555,18 @@ public class ScaleIOPrimaryDataStoreDriverTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetVolumeSizeRequiredOnPool() {
|
public void testGetVolumeSizeRequiredOnPool() {
|
||||||
|
Assert.assertEquals(8L * (1024 * 1024 * 1024),
|
||||||
|
scaleIOPrimaryDataStoreDriver.getVolumeSizeRequiredOnPool(
|
||||||
|
52428800,
|
||||||
|
null,
|
||||||
|
false));
|
||||||
|
|
||||||
|
Assert.assertEquals(8L * (1024 * 1024 * 1024),
|
||||||
|
scaleIOPrimaryDataStoreDriver.getVolumeSizeRequiredOnPool(
|
||||||
|
52428800,
|
||||||
|
52428800L,
|
||||||
|
true));
|
||||||
|
|
||||||
Assert.assertEquals(16L * (1024 * 1024 * 1024),
|
Assert.assertEquals(16L * (1024 * 1024 * 1024),
|
||||||
scaleIOPrimaryDataStoreDriver.getVolumeSizeRequiredOnPool(
|
scaleIOPrimaryDataStoreDriver.getVolumeSizeRequiredOnPool(
|
||||||
10L * (1024 * 1024 * 1024),
|
10L * (1024 * 1024 * 1024),
|
||||||
|
|||||||
@ -150,6 +150,9 @@ public class StorPoolStorageAdaptor implements StorageAdaptor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static String getVolumeNameFromPath(final String volumeUuid, boolean tildeNeeded) {
|
public static String getVolumeNameFromPath(final String volumeUuid, boolean tildeNeeded) {
|
||||||
|
if (volumeUuid == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
if (volumeUuid.startsWith("/dev/storpool/")) {
|
if (volumeUuid.startsWith("/dev/storpool/")) {
|
||||||
return volumeUuid.split("/")[3];
|
return volumeUuid.split("/")[3];
|
||||||
} else if (volumeUuid.startsWith("/dev/storpool-byid/")) {
|
} else if (volumeUuid.startsWith("/dev/storpool-byid/")) {
|
||||||
|
|||||||
@ -140,10 +140,11 @@ public class LdapListUsersCmd extends BaseListCmd {
|
|||||||
try {
|
try {
|
||||||
final List<LdapUser> users = _ldapManager.getUsers(domainId);
|
final List<LdapUser> users = _ldapManager.getUsers(domainId);
|
||||||
ldapResponses = createLdapUserResponse(users);
|
ldapResponses = createLdapUserResponse(users);
|
||||||
// now filter and annotate
|
// now filter and annotate
|
||||||
ldapResponses = applyUserFilter(ldapResponses);
|
ldapResponses = applyUserFilter(ldapResponses);
|
||||||
} catch (final NoLdapUserMatchingQueryException ex) {
|
} catch (final NoLdapUserMatchingQueryException ex) {
|
||||||
// ok, we'll make do with the empty list ldapResponses = new ArrayList<LdapUserResponse>();
|
logger.debug(ex.getMessage());
|
||||||
|
// ok, we'll make do with the empty list
|
||||||
} finally {
|
} finally {
|
||||||
response.setResponses(ldapResponses);
|
response.setResponses(ldapResponses);
|
||||||
response.setResponseName(getCommandName());
|
response.setResponseName(getCommandName());
|
||||||
|
|||||||
@ -45,6 +45,8 @@ public class LdapAuthenticator extends AdapterBase implements UserAuthenticator
|
|||||||
@Inject
|
@Inject
|
||||||
private AccountManager _accountManager;
|
private AccountManager _accountManager;
|
||||||
|
|
||||||
|
private static final String LDAP_READ_TIMED_OUT_MESSAGE = "LDAP response read timed out";
|
||||||
|
|
||||||
public LdapAuthenticator() {
|
public LdapAuthenticator() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
@ -74,8 +76,8 @@ public class LdapAuthenticator extends AdapterBase implements UserAuthenticator
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
List<LdapTrustMapVO> ldapTrustMapVOs = getLdapTrustMapVOS(domainId);
|
List<LdapTrustMapVO> ldapTrustMapVOs = getLdapTrustMapVOS(domainId);
|
||||||
if(ldapTrustMapVOs != null && ldapTrustMapVOs.size() > 0) {
|
if (ldapTrustMapVOs != null && ldapTrustMapVOs.size() > 0) {
|
||||||
if(ldapTrustMapVOs.size() == 1 && ldapTrustMapVOs.get(0).getAccountId() == 0) {
|
if (ldapTrustMapVOs.size() == 1 && ldapTrustMapVOs.get(0).getAccountId() == 0) {
|
||||||
if (logger.isTraceEnabled()) {
|
if (logger.isTraceEnabled()) {
|
||||||
logger.trace("We have a single mapping of a domain to an ldap group or ou");
|
logger.trace("We have a single mapping of a domain to an ldap group or ou");
|
||||||
}
|
}
|
||||||
@ -125,11 +127,11 @@ public class LdapAuthenticator extends AdapterBase implements UserAuthenticator
|
|||||||
mappedGroups.retainAll(memberships);
|
mappedGroups.retainAll(memberships);
|
||||||
tracelist("actual groups for " + username, mappedGroups);
|
tracelist("actual groups for " + username, mappedGroups);
|
||||||
// check membership, there must be only one match in this domain
|
// check membership, there must be only one match in this domain
|
||||||
if(ldapUser.isDisabled()) {
|
if (ldapUser.isDisabled()) {
|
||||||
logAndDisable(userAccount, "attempt to log on using disabled ldap user " + userAccount.getUsername(), false);
|
logAndDisable(userAccount, "attempt to log on using disabled ldap user " + userAccount.getUsername(), false);
|
||||||
} else if(mappedGroups.size() > 1) {
|
} else if (mappedGroups.size() > 1) {
|
||||||
logAndDisable(userAccount, "user '" + username + "' is mapped to more then one account in domain and will be disabled.", false);
|
logAndDisable(userAccount, "user '" + username + "' is mapped to more then one account in domain and will be disabled.", false);
|
||||||
} else if(mappedGroups.size() < 1) {
|
} else if (mappedGroups.size() < 1) {
|
||||||
logAndDisable(userAccount, "user '" + username + "' is not mapped to an account in domain and will be removed.", true);
|
logAndDisable(userAccount, "user '" + username + "' is not mapped to an account in domain and will be removed.", true);
|
||||||
} else {
|
} else {
|
||||||
// a valid ldap configured user exists
|
// a valid ldap configured user exists
|
||||||
@ -137,12 +139,12 @@ public class LdapAuthenticator extends AdapterBase implements UserAuthenticator
|
|||||||
// we could now assert that ldapTrustMapVOs.contains(mapping);
|
// we could now assert that ldapTrustMapVOs.contains(mapping);
|
||||||
// createUser in Account can only be done by account name not by account id;
|
// createUser in Account can only be done by account name not by account id;
|
||||||
Account account = _accountManager.getAccount(mapping.getAccountId());
|
Account account = _accountManager.getAccount(mapping.getAccountId());
|
||||||
if(null == account) {
|
if (null == account) {
|
||||||
throw new CloudRuntimeException(String.format("account for user (%s) not found by id %d", username, mapping.getAccountId()));
|
throw new CloudRuntimeException(String.format("account for user (%s) not found by id %d", username, mapping.getAccountId()));
|
||||||
}
|
}
|
||||||
String accountName = account.getAccountName();
|
String accountName = account.getAccountName();
|
||||||
rc.first(_ldapManager.canAuthenticate(ldapUser.getPrincipal(), password, domainId));
|
rc.first(_ldapManager.canAuthenticate(ldapUser.getPrincipal(), password, domainId));
|
||||||
if (! rc.first()) {
|
if (!rc.first()) {
|
||||||
rc.second(ActionOnFailedAuthentication.INCREMENT_INCORRECT_LOGIN_ATTEMPT_COUNT);
|
rc.second(ActionOnFailedAuthentication.INCREMENT_INCORRECT_LOGIN_ATTEMPT_COUNT);
|
||||||
}
|
}
|
||||||
// for security reasons we keep processing on faulty login attempt to not give a way information on userid existence
|
// for security reasons we keep processing on faulty login attempt to not give a way information on userid existence
|
||||||
@ -162,7 +164,7 @@ public class LdapAuthenticator extends AdapterBase implements UserAuthenticator
|
|||||||
userAccount = _accountManager.getUserAccountById(user.getId());
|
userAccount = _accountManager.getUserAccountById(user.getId());
|
||||||
} else {
|
} else {
|
||||||
// not a new user, check if mapped group has changed
|
// not a new user, check if mapped group has changed
|
||||||
if(userAccount.getAccountId() != mapping.getAccountId()) {
|
if (userAccount.getAccountId() != mapping.getAccountId()) {
|
||||||
final Account mappedAccount = _accountManager.getAccount(mapping.getAccountId());
|
final Account mappedAccount = _accountManager.getAccount(mapping.getAccountId());
|
||||||
if (mappedAccount == null || mappedAccount.getRemoved() != null) {
|
if (mappedAccount == null || mappedAccount.getRemoved() != null) {
|
||||||
throw new CloudRuntimeException("Mapped account for users does not exist. Please contact your administrator.");
|
throw new CloudRuntimeException("Mapped account for users does not exist. Please contact your administrator.");
|
||||||
@ -174,12 +176,21 @@ public class LdapAuthenticator extends AdapterBase implements UserAuthenticator
|
|||||||
}
|
}
|
||||||
} catch (NoLdapUserMatchingQueryException e) {
|
} catch (NoLdapUserMatchingQueryException e) {
|
||||||
logger.debug(e.getMessage());
|
logger.debug(e.getMessage());
|
||||||
disableUserInCloudStack(userAccount);
|
processLdapUserErrorMessage(userAccount, e.getMessage(), rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void processLdapUserErrorMessage(UserAccount user, String errorMessage, Pair<Boolean, ActionOnFailedAuthentication> rc) {
|
||||||
|
if (StringUtils.isNotEmpty(errorMessage) && errorMessage.contains(LDAP_READ_TIMED_OUT_MESSAGE) && !rc.first()) {
|
||||||
|
rc.second(ActionOnFailedAuthentication.INCREMENT_INCORRECT_LOGIN_ATTEMPT_COUNT);
|
||||||
|
} else {
|
||||||
|
// no user in ldap ==>> disable user in cloudstack
|
||||||
|
disableUserInCloudStack(user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void tracelist(String msg, List<String> listToTrace) {
|
private void tracelist(String msg, List<String> listToTrace) {
|
||||||
if (logger.isTraceEnabled()) {
|
if (logger.isTraceEnabled()) {
|
||||||
StringBuilder logMsg = new StringBuilder();
|
StringBuilder logMsg = new StringBuilder();
|
||||||
@ -197,7 +208,7 @@ public class LdapAuthenticator extends AdapterBase implements UserAuthenticator
|
|||||||
if (logger.isInfoEnabled()) {
|
if (logger.isInfoEnabled()) {
|
||||||
logger.info(msg);
|
logger.info(msg);
|
||||||
}
|
}
|
||||||
if(remove) {
|
if (remove) {
|
||||||
removeUserInCloudStack(userAccount);
|
removeUserInCloudStack(userAccount);
|
||||||
} else {
|
} else {
|
||||||
disableUserInCloudStack(userAccount);
|
disableUserInCloudStack(userAccount);
|
||||||
@ -229,23 +240,22 @@ public class LdapAuthenticator extends AdapterBase implements UserAuthenticator
|
|||||||
processLdapUser(password, domainId, user, rc, ldapUser, accountType);
|
processLdapUser(password, domainId, user, rc, ldapUser, accountType);
|
||||||
} catch (NoLdapUserMatchingQueryException e) {
|
} catch (NoLdapUserMatchingQueryException e) {
|
||||||
logger.debug(e.getMessage());
|
logger.debug(e.getMessage());
|
||||||
// no user in ldap ==>> disable user in cloudstack
|
processLdapUserErrorMessage(user, e.getMessage(), rc);
|
||||||
disableUserInCloudStack(user);
|
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processLdapUser(String password, Long domainId, UserAccount user, Pair<Boolean, ActionOnFailedAuthentication> rc, LdapUser ldapUser, Account.Type accountType) {
|
private void processLdapUser(String password, Long domainId, UserAccount user, Pair<Boolean, ActionOnFailedAuthentication> rc, LdapUser ldapUser, Account.Type accountType) {
|
||||||
if(!ldapUser.isDisabled()) {
|
if (!ldapUser.isDisabled()) {
|
||||||
rc.first(_ldapManager.canAuthenticate(ldapUser.getPrincipal(), password, domainId));
|
rc.first(_ldapManager.canAuthenticate(ldapUser.getPrincipal(), password, domainId));
|
||||||
if(rc.first()) {
|
if (rc.first()) {
|
||||||
if(user == null) {
|
if (user == null) {
|
||||||
// import user to cloudstack
|
// import user to cloudstack
|
||||||
createCloudStackUserAccount(ldapUser, domainId, accountType);
|
createCloudStackUserAccount(ldapUser, domainId, accountType);
|
||||||
} else {
|
} else {
|
||||||
enableUserInCloudStack(user);
|
enableUserInCloudStack(user);
|
||||||
}
|
}
|
||||||
} else if(user != null) {
|
} else if (user != null) {
|
||||||
rc.second(ActionOnFailedAuthentication.INCREMENT_INCORRECT_LOGIN_ATTEMPT_COUNT);
|
rc.second(ActionOnFailedAuthentication.INCREMENT_INCORRECT_LOGIN_ATTEMPT_COUNT);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -264,30 +274,34 @@ public class LdapAuthenticator extends AdapterBase implements UserAuthenticator
|
|||||||
*/
|
*/
|
||||||
Pair<Boolean, ActionOnFailedAuthentication> authenticate(String username, String password, Long domainId, UserAccount user) {
|
Pair<Boolean, ActionOnFailedAuthentication> authenticate(String username, String password, Long domainId, UserAccount user) {
|
||||||
boolean result = false;
|
boolean result = false;
|
||||||
|
boolean timedOut = false;
|
||||||
|
|
||||||
if(user != null ) {
|
if (user != null ) {
|
||||||
try {
|
try {
|
||||||
LdapUser ldapUser = _ldapManager.getUser(username, domainId);
|
LdapUser ldapUser = _ldapManager.getUser(username, domainId);
|
||||||
if(!ldapUser.isDisabled()) {
|
if (!ldapUser.isDisabled()) {
|
||||||
result = _ldapManager.canAuthenticate(ldapUser.getPrincipal(), password, domainId);
|
result = _ldapManager.canAuthenticate(ldapUser.getPrincipal(), password, domainId);
|
||||||
} else {
|
} else {
|
||||||
logger.debug("user with principal "+ ldapUser.getPrincipal() + " is disabled in ldap");
|
logger.debug("user with principal "+ ldapUser.getPrincipal() + " is disabled in ldap");
|
||||||
}
|
}
|
||||||
} catch (NoLdapUserMatchingQueryException e) {
|
} catch (NoLdapUserMatchingQueryException e) {
|
||||||
logger.debug(e.getMessage());
|
logger.debug(e.getMessage());
|
||||||
|
if (e.getMessage().contains(LDAP_READ_TIMED_OUT_MESSAGE)) {
|
||||||
|
timedOut = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return processResultAndAction(user, result);
|
}
|
||||||
|
return processResultAndAction(user, result, timedOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Pair<Boolean, ActionOnFailedAuthentication> processResultAndAction(UserAccount user, boolean result) {
|
private Pair<Boolean, ActionOnFailedAuthentication> processResultAndAction(UserAccount user, boolean result, boolean timedOut) {
|
||||||
return (!result && user != null) ?
|
return (!result && (user != null || timedOut)) ?
|
||||||
new Pair<Boolean, ActionOnFailedAuthentication>(result, ActionOnFailedAuthentication.INCREMENT_INCORRECT_LOGIN_ATTEMPT_COUNT):
|
new Pair<Boolean, ActionOnFailedAuthentication>(result, ActionOnFailedAuthentication.INCREMENT_INCORRECT_LOGIN_ATTEMPT_COUNT):
|
||||||
new Pair<Boolean, ActionOnFailedAuthentication>(result, null);
|
new Pair<Boolean, ActionOnFailedAuthentication>(result, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void enableUserInCloudStack(UserAccount user) {
|
private void enableUserInCloudStack(UserAccount user) {
|
||||||
if(user != null && (user.getState().equalsIgnoreCase(Account.State.DISABLED.toString()))) {
|
if (user != null && (user.getState().equalsIgnoreCase(Account.State.DISABLED.toString()))) {
|
||||||
_accountManager.enableUser(user.getId());
|
_accountManager.enableUser(user.getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -166,7 +166,7 @@ public class LdapManagerImpl extends ComponentLifecycleBase implements LdapManag
|
|||||||
|
|
||||||
private LdapConfigurationResponse addConfigurationInternal(final String hostname, int port, final Long domainId) throws InvalidParameterValueException {
|
private LdapConfigurationResponse addConfigurationInternal(final String hostname, int port, final Long domainId) throws InvalidParameterValueException {
|
||||||
// TODO evaluate what the right default should be
|
// TODO evaluate what the right default should be
|
||||||
if(port <= 0) {
|
if (port <= 0) {
|
||||||
port = 389;
|
port = 389;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,7 +210,7 @@ public class LdapManagerImpl extends ComponentLifecycleBase implements LdapManag
|
|||||||
// TODO return the right account for this user
|
// TODO return the right account for this user
|
||||||
final LdapContext context = _ldapContextFactory.createUserContext(principal, password, domainId);
|
final LdapContext context = _ldapContextFactory.createUserContext(principal, password, domainId);
|
||||||
closeContext(context);
|
closeContext(context);
|
||||||
if(logger.isTraceEnabled()) {
|
if (logger.isTraceEnabled()) {
|
||||||
logger.trace(String.format("User(%s) authenticated for domain(%s)", principal, domainId));
|
logger.trace(String.format("User(%s) authenticated for domain(%s)", principal, domainId));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -234,7 +234,7 @@ public class LdapManagerImpl extends ComponentLifecycleBase implements LdapManag
|
|||||||
@Override
|
@Override
|
||||||
public LdapConfigurationResponse createLdapConfigurationResponse(final LdapConfigurationVO configuration) {
|
public LdapConfigurationResponse createLdapConfigurationResponse(final LdapConfigurationVO configuration) {
|
||||||
String domainUuid = null;
|
String domainUuid = null;
|
||||||
if(configuration.getDomainId() != null) {
|
if (configuration.getDomainId() != null) {
|
||||||
DomainVO domain = domainDao.findById(configuration.getDomainId());
|
DomainVO domain = domainDao.findById(configuration.getDomainId());
|
||||||
if (domain != null) {
|
if (domain != null) {
|
||||||
domainUuid = domain.getUuid();
|
domainUuid = domain.getUuid();
|
||||||
@ -303,8 +303,8 @@ public class LdapManagerImpl extends ComponentLifecycleBase implements LdapManag
|
|||||||
return _ldapUserManagerFactory.getInstance(_ldapConfiguration.getLdapProvider(null)).getUser(escapedUsername, context, domainId);
|
return _ldapUserManagerFactory.getInstance(_ldapConfiguration.getLdapProvider(null)).getUser(escapedUsername, context, domainId);
|
||||||
|
|
||||||
} catch (NamingException | IOException e) {
|
} catch (NamingException | IOException e) {
|
||||||
logger.debug("ldap Exception: ",e);
|
logger.debug("LDAP Exception: ", e);
|
||||||
throw new NoLdapUserMatchingQueryException("No Ldap User found for username: "+username);
|
throw new NoLdapUserMatchingQueryException("Unable to find LDAP User for username: " + username + ", due to " + e.getMessage());
|
||||||
} finally {
|
} finally {
|
||||||
closeContext(context);
|
closeContext(context);
|
||||||
}
|
}
|
||||||
@ -324,8 +324,8 @@ public class LdapManagerImpl extends ComponentLifecycleBase implements LdapManag
|
|||||||
LdapUserManager userManagerFactory = _ldapUserManagerFactory.getInstance(ldapProvider);
|
LdapUserManager userManagerFactory = _ldapUserManagerFactory.getInstance(ldapProvider);
|
||||||
return userManagerFactory.getUser(escapedUsername, type, name, context, domainId);
|
return userManagerFactory.getUser(escapedUsername, type, name, context, domainId);
|
||||||
} catch (NamingException | IOException e) {
|
} catch (NamingException | IOException e) {
|
||||||
logger.debug("ldap Exception: ",e);
|
logger.debug("LDAP Exception: ", e);
|
||||||
throw new NoLdapUserMatchingQueryException("No Ldap User found for username: "+username + " in group: " + name + " of type: " + type);
|
throw new NoLdapUserMatchingQueryException("Unable to find LDAP User for username: " + username + " in group: " + name + " of type: " + type + ", due to " + e.getMessage());
|
||||||
} finally {
|
} finally {
|
||||||
closeContext(context);
|
closeContext(context);
|
||||||
}
|
}
|
||||||
@ -338,7 +338,7 @@ public class LdapManagerImpl extends ComponentLifecycleBase implements LdapManag
|
|||||||
context = _ldapContextFactory.createBindContext(domainId);
|
context = _ldapContextFactory.createBindContext(domainId);
|
||||||
return _ldapUserManagerFactory.getInstance(_ldapConfiguration.getLdapProvider(domainId)).getUsers(context, domainId);
|
return _ldapUserManagerFactory.getInstance(_ldapConfiguration.getLdapProvider(domainId)).getUsers(context, domainId);
|
||||||
} catch (NamingException | IOException e) {
|
} catch (NamingException | IOException e) {
|
||||||
logger.debug("ldap Exception: ",e);
|
logger.debug("LDAP Exception: ", e);
|
||||||
throw new NoLdapUserMatchingQueryException("*");
|
throw new NoLdapUserMatchingQueryException("*");
|
||||||
} finally {
|
} finally {
|
||||||
closeContext(context);
|
closeContext(context);
|
||||||
@ -352,7 +352,7 @@ public class LdapManagerImpl extends ComponentLifecycleBase implements LdapManag
|
|||||||
context = _ldapContextFactory.createBindContext(domainId);
|
context = _ldapContextFactory.createBindContext(domainId);
|
||||||
return _ldapUserManagerFactory.getInstance(_ldapConfiguration.getLdapProvider(domainId)).getUsersInGroup(groupName, context, domainId);
|
return _ldapUserManagerFactory.getInstance(_ldapConfiguration.getLdapProvider(domainId)).getUsersInGroup(groupName, context, domainId);
|
||||||
} catch (NamingException | IOException e) {
|
} catch (NamingException | IOException e) {
|
||||||
logger.debug("ldap NamingException: ",e);
|
logger.debug("LDAP Exception: ", e);
|
||||||
throw new NoLdapUserMatchingQueryException("groupName=" + groupName);
|
throw new NoLdapUserMatchingQueryException("groupName=" + groupName);
|
||||||
} finally {
|
} finally {
|
||||||
closeContext(context);
|
closeContext(context);
|
||||||
@ -390,7 +390,7 @@ public class LdapManagerImpl extends ComponentLifecycleBase implements LdapManag
|
|||||||
final String escapedUsername = LdapUtils.escapeLDAPSearchFilter(username);
|
final String escapedUsername = LdapUtils.escapeLDAPSearchFilter(username);
|
||||||
return _ldapUserManagerFactory.getInstance(_ldapConfiguration.getLdapProvider(null)).getUsers("*" + escapedUsername + "*", context, null);
|
return _ldapUserManagerFactory.getInstance(_ldapConfiguration.getLdapProvider(null)).getUsers("*" + escapedUsername + "*", context, null);
|
||||||
} catch (NamingException | IOException e) {
|
} catch (NamingException | IOException e) {
|
||||||
logger.debug("ldap Exception: ",e);
|
logger.debug("LDAP Exception: ",e);
|
||||||
throw new NoLdapUserMatchingQueryException(username);
|
throw new NoLdapUserMatchingQueryException(username);
|
||||||
} finally {
|
} finally {
|
||||||
closeContext(context);
|
closeContext(context);
|
||||||
@ -481,7 +481,7 @@ public class LdapManagerImpl extends ComponentLifecycleBase implements LdapManag
|
|||||||
private void clearOldAccountMapping(LinkAccountToLdapCmd cmd) {
|
private void clearOldAccountMapping(LinkAccountToLdapCmd cmd) {
|
||||||
// first find if exists log warning and update
|
// first find if exists log warning and update
|
||||||
LdapTrustMapVO oldVo = _ldapTrustMapDao.findGroupInDomain(cmd.getDomainId(), cmd.getLdapDomain());
|
LdapTrustMapVO oldVo = _ldapTrustMapDao.findGroupInDomain(cmd.getDomainId(), cmd.getLdapDomain());
|
||||||
if(oldVo != null) {
|
if (oldVo != null) {
|
||||||
// deal with edge cases, i.e. check if the old account is indeed deleted etc.
|
// deal with edge cases, i.e. check if the old account is indeed deleted etc.
|
||||||
if (oldVo.getAccountId() != 0l) {
|
if (oldVo.getAccountId() != 0l) {
|
||||||
AccountVO oldAcount = accountDao.findByIdIncludingRemoved(oldVo.getAccountId());
|
AccountVO oldAcount = accountDao.findByIdIncludingRemoved(oldVo.getAccountId());
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -482,6 +482,7 @@ public class TemplateJoinDaoImpl extends GenericDaoBaseWithTagInformation<Templa
|
|||||||
isoResponse.setExtractable(iso.isExtractable() && !(iso.getTemplateType() == TemplateType.PERHOST));
|
isoResponse.setExtractable(iso.isExtractable() && !(iso.getTemplateType() == TemplateType.PERHOST));
|
||||||
isoResponse.setCreated(iso.getCreatedOnStore());
|
isoResponse.setCreated(iso.getCreatedOnStore());
|
||||||
isoResponse.setDynamicallyScalable(iso.isDynamicallyScalable());
|
isoResponse.setDynamicallyScalable(iso.isDynamicallyScalable());
|
||||||
|
isoResponse.setFormat(iso.getFormat());
|
||||||
if (iso.getTemplateType() == TemplateType.PERHOST) {
|
if (iso.getTemplateType() == TemplateType.PERHOST) {
|
||||||
// for TemplateManager.XS_TOOLS_ISO and TemplateManager.VMWARE_TOOLS_ISO, we didn't download, but is ready to use.
|
// for TemplateManager.XS_TOOLS_ISO and TemplateManager.VMWARE_TOOLS_ISO, we didn't download, but is ready to use.
|
||||||
isoResponse.setReady(true);
|
isoResponse.setReady(true);
|
||||||
@ -581,10 +582,14 @@ public class TemplateJoinDaoImpl extends GenericDaoBaseWithTagInformation<Templa
|
|||||||
isoResponse.setZoneName(iso.getDataCenterName());
|
isoResponse.setZoneName(iso.getDataCenterName());
|
||||||
}
|
}
|
||||||
|
|
||||||
Long isoSize = iso.getSize();
|
long isoSize = iso.getSize();
|
||||||
if (isoSize > 0) {
|
if (isoSize > 0) {
|
||||||
isoResponse.setSize(isoSize);
|
isoResponse.setSize(isoSize);
|
||||||
}
|
}
|
||||||
|
long isoPhysicalSize = iso.getPhysicalSize();
|
||||||
|
if (isoPhysicalSize > 0) {
|
||||||
|
isoResponse.setPhysicalSize(isoPhysicalSize);
|
||||||
|
}
|
||||||
|
|
||||||
if (iso.getUserDataId() != null) {
|
if (iso.getUserDataId() != null) {
|
||||||
isoResponse.setUserDataId(iso.getUserDataUUid());
|
isoResponse.setUserDataId(iso.getUserDataUUid());
|
||||||
|
|||||||
@ -50,12 +50,7 @@ import java.util.stream.Collectors;
|
|||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.naming.ConfigurationException;
|
import javax.naming.ConfigurationException;
|
||||||
|
|
||||||
import com.cloud.network.dao.NetrisProviderDao;
|
|
||||||
import com.cloud.network.element.NetrisProviderVO;
|
|
||||||
import com.cloud.network.netris.NetrisService;
|
|
||||||
import org.apache.cloudstack.acl.RoleType;
|
import org.apache.cloudstack.acl.RoleType;
|
||||||
import com.cloud.gpu.VgpuProfileVO;
|
|
||||||
import com.cloud.gpu.dao.VgpuProfileDao;
|
|
||||||
import org.apache.cloudstack.acl.SecurityChecker;
|
import org.apache.cloudstack.acl.SecurityChecker;
|
||||||
import org.apache.cloudstack.affinity.AffinityGroup;
|
import org.apache.cloudstack.affinity.AffinityGroup;
|
||||||
import org.apache.cloudstack.affinity.AffinityGroupService;
|
import org.apache.cloudstack.affinity.AffinityGroupService;
|
||||||
@ -207,6 +202,8 @@ import com.cloud.exception.PermissionDeniedException;
|
|||||||
import com.cloud.exception.ResourceAllocationException;
|
import com.cloud.exception.ResourceAllocationException;
|
||||||
import com.cloud.exception.ResourceUnavailableException;
|
import com.cloud.exception.ResourceUnavailableException;
|
||||||
import com.cloud.gpu.GPU;
|
import com.cloud.gpu.GPU;
|
||||||
|
import com.cloud.gpu.VgpuProfileVO;
|
||||||
|
import com.cloud.gpu.dao.VgpuProfileDao;
|
||||||
import com.cloud.host.HostTagVO;
|
import com.cloud.host.HostTagVO;
|
||||||
import com.cloud.host.HostVO;
|
import com.cloud.host.HostVO;
|
||||||
import com.cloud.host.dao.HostDao;
|
import com.cloud.host.dao.HostDao;
|
||||||
@ -230,10 +227,12 @@ import com.cloud.network.Networks.BroadcastDomainType;
|
|||||||
import com.cloud.network.Networks.TrafficType;
|
import com.cloud.network.Networks.TrafficType;
|
||||||
import com.cloud.network.PhysicalNetwork;
|
import com.cloud.network.PhysicalNetwork;
|
||||||
import com.cloud.network.UserIpv6AddressVO;
|
import com.cloud.network.UserIpv6AddressVO;
|
||||||
|
import com.cloud.network.as.AutoScaleManager;
|
||||||
import com.cloud.network.dao.FirewallRulesDao;
|
import com.cloud.network.dao.FirewallRulesDao;
|
||||||
import com.cloud.network.dao.IPAddressDao;
|
import com.cloud.network.dao.IPAddressDao;
|
||||||
import com.cloud.network.dao.IPAddressVO;
|
import com.cloud.network.dao.IPAddressVO;
|
||||||
import com.cloud.network.dao.Ipv6GuestPrefixSubnetNetworkMapDao;
|
import com.cloud.network.dao.Ipv6GuestPrefixSubnetNetworkMapDao;
|
||||||
|
import com.cloud.network.dao.NetrisProviderDao;
|
||||||
import com.cloud.network.dao.NetworkDao;
|
import com.cloud.network.dao.NetworkDao;
|
||||||
import com.cloud.network.dao.NetworkVO;
|
import com.cloud.network.dao.NetworkVO;
|
||||||
import com.cloud.network.dao.NsxProviderDao;
|
import com.cloud.network.dao.NsxProviderDao;
|
||||||
@ -242,7 +241,9 @@ import com.cloud.network.dao.PhysicalNetworkTrafficTypeDao;
|
|||||||
import com.cloud.network.dao.PhysicalNetworkTrafficTypeVO;
|
import com.cloud.network.dao.PhysicalNetworkTrafficTypeVO;
|
||||||
import com.cloud.network.dao.PhysicalNetworkVO;
|
import com.cloud.network.dao.PhysicalNetworkVO;
|
||||||
import com.cloud.network.dao.UserIpv6AddressDao;
|
import com.cloud.network.dao.UserIpv6AddressDao;
|
||||||
|
import com.cloud.network.element.NetrisProviderVO;
|
||||||
import com.cloud.network.element.NsxProviderVO;
|
import com.cloud.network.element.NsxProviderVO;
|
||||||
|
import com.cloud.network.netris.NetrisService;
|
||||||
import com.cloud.network.rules.LoadBalancerContainer.Scheme;
|
import com.cloud.network.rules.LoadBalancerContainer.Scheme;
|
||||||
import com.cloud.network.vpc.VpcManager;
|
import com.cloud.network.vpc.VpcManager;
|
||||||
import com.cloud.offering.DiskOffering;
|
import com.cloud.offering.DiskOffering;
|
||||||
@ -600,6 +601,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
|||||||
configValuesForValidation.add(VMLeaseManager.InstanceLeaseSchedulerInterval.key());
|
configValuesForValidation.add(VMLeaseManager.InstanceLeaseSchedulerInterval.key());
|
||||||
configValuesForValidation.add(VMLeaseManager.InstanceLeaseExpiryEventSchedulerInterval.key());
|
configValuesForValidation.add(VMLeaseManager.InstanceLeaseExpiryEventSchedulerInterval.key());
|
||||||
configValuesForValidation.add(VMLeaseManager.InstanceLeaseExpiryEventDaysBefore.key());
|
configValuesForValidation.add(VMLeaseManager.InstanceLeaseExpiryEventDaysBefore.key());
|
||||||
|
configValuesForValidation.add(AutoScaleManager.AutoScaleErroredInstanceThreshold.key());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void weightBasedParametersForValidation() {
|
protected void weightBasedParametersForValidation() {
|
||||||
|
|||||||
@ -1276,6 +1276,10 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
|
|||||||
buf.append(" vmpassword=").append(configurationDao.getValue("system.vm.password"));
|
buf.append(" vmpassword=").append(configurationDao.getValue("system.vm.password"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (StringUtils.isNotEmpty(NTPServerConfig.value())) {
|
||||||
|
buf.append(" ntpserverlist=").append(NTPServerConfig.value().replaceAll("\\s+",""));
|
||||||
|
}
|
||||||
|
|
||||||
for (NicProfile nic : profile.getNics()) {
|
for (NicProfile nic : profile.getNics()) {
|
||||||
int deviceId = nic.getDeviceId();
|
int deviceId = nic.getDeviceId();
|
||||||
if (nic.getIPv4Address() == null) {
|
if (nic.getIPv4Address() == null) {
|
||||||
@ -1506,7 +1510,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
|
|||||||
public Long[] getScannablePools() {
|
public Long[] getScannablePools() {
|
||||||
List<Long> zoneIds = dataCenterDao.listEnabledNonEdgeZoneIds();
|
List<Long> zoneIds = dataCenterDao.listEnabledNonEdgeZoneIds();
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug(String.format("Enabled non-edge zones available for scan: %s", org.apache.commons.lang3.StringUtils.join(zoneIds, ",")));
|
logger.debug(String.format("Enabled non-edge zones available for scan: %s", StringUtils.join(zoneIds, ",")));
|
||||||
}
|
}
|
||||||
return zoneIds.toArray(Long[]::new);
|
return zoneIds.toArray(Long[]::new);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -39,6 +39,12 @@ public interface AutoScaleManager extends AutoScaleService {
|
|||||||
"The Number of worker threads to scan the autoscale vm groups.",
|
"The Number of worker threads to scan the autoscale vm groups.",
|
||||||
false);
|
false);
|
||||||
|
|
||||||
|
ConfigKey<Integer> AutoScaleErroredInstanceThreshold = new ConfigKey<>(ConfigKey.CATEGORY_ADVANCED, Integer.class,
|
||||||
|
"autoscale.errored.instance.threshold",
|
||||||
|
"10",
|
||||||
|
"The number of Error Instances allowed in autoscale vm groups for scale up.",
|
||||||
|
true);
|
||||||
|
|
||||||
void checkAutoScaleUser(Long autoscaleUserId, long accountId);
|
void checkAutoScaleUser(Long autoscaleUserId, long accountId);
|
||||||
|
|
||||||
boolean deleteAutoScaleVmGroupsByAccount(Account account);
|
boolean deleteAutoScaleVmGroupsByAccount(Account account);
|
||||||
|
|||||||
@ -1722,6 +1722,11 @@ public class AutoScaleManagerImpl extends ManagerBase implements AutoScaleManage
|
|||||||
logger.warn("number of VM will greater than the maximum in this group if scaling up, so do nothing more");
|
logger.warn("number of VM will greater than the maximum in this group if scaling up, so do nothing more");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
int erroredInstanceCount = autoScaleVmGroupVmMapDao.getErroredInstanceCount(asGroup.getId());
|
||||||
|
if (erroredInstanceCount > AutoScaleManager.AutoScaleErroredInstanceThreshold.value()) {
|
||||||
|
logger.warn("Number of Errored Instances are greater than the threshold in this group for scaling up, so do nothing more");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2202,7 +2207,8 @@ public class AutoScaleManagerImpl extends ManagerBase implements AutoScaleManage
|
|||||||
return new ConfigKey<?>[] {
|
return new ConfigKey<?>[] {
|
||||||
AutoScaleStatsInterval,
|
AutoScaleStatsInterval,
|
||||||
AutoScaleStatsCleanupDelay,
|
AutoScaleStatsCleanupDelay,
|
||||||
AutoScaleStatsWorker
|
AutoScaleStatsWorker,
|
||||||
|
AutoScaleErroredInstanceThreshold
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1365,7 +1365,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
|||||||
for (int i = 0; i < retry; i++) {
|
for (int i = 0; i < retry; i++) {
|
||||||
lsuccess = true;
|
lsuccess = true;
|
||||||
try {
|
try {
|
||||||
Thread.currentThread().wait(5 * 1000);
|
Thread.sleep(5 * 1000);
|
||||||
} catch (final InterruptedException e) {
|
} catch (final InterruptedException e) {
|
||||||
logger.debug("thread unexpectedly interrupted during wait, while updating cluster");
|
logger.debug("thread unexpectedly interrupted during wait, while updating cluster");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -146,6 +146,7 @@ import com.cloud.vm.dao.VMInstanceDao;
|
|||||||
@Component
|
@Component
|
||||||
public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLimitService, Configurable {
|
public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLimitService, Configurable {
|
||||||
|
|
||||||
|
public static final String CHECKING_IF = "Checking if {}";
|
||||||
@Inject
|
@Inject
|
||||||
private AccountManager _accountMgr;
|
private AccountManager _accountMgr;
|
||||||
@Inject
|
@Inject
|
||||||
@ -171,8 +172,6 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
|
|||||||
@Inject
|
@Inject
|
||||||
private ResourceLimitDao _resourceLimitDao;
|
private ResourceLimitDao _resourceLimitDao;
|
||||||
@Inject
|
@Inject
|
||||||
private ResourceLimitService resourceLimitService;
|
|
||||||
@Inject
|
|
||||||
private ReservationDao reservationDao;
|
private ReservationDao reservationDao;
|
||||||
@Inject
|
@Inject
|
||||||
protected SnapshotDao _snapshotDao;
|
protected SnapshotDao _snapshotDao;
|
||||||
@ -356,7 +355,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final long numToIncrement = (delta.length == 0) ? 1 : delta[0].longValue();
|
final long numToIncrement = (delta.length == 0) ? 1 : delta[0];
|
||||||
removeResourceReservationIfNeededAndIncrementResourceCount(accountId, type, tag, numToIncrement);
|
removeResourceReservationIfNeededAndIncrementResourceCount(accountId, type, tag, numToIncrement);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -372,7 +371,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
|
|||||||
logger.trace("Not decrementing resource count for system accounts, returning");
|
logger.trace("Not decrementing resource count for system accounts, returning");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
long numToDecrement = (delta.length == 0) ? 1 : delta[0].longValue();
|
long numToDecrement = (delta.length == 0) ? 1 : delta[0];
|
||||||
|
|
||||||
if (!updateResourceCountForAccount(accountId, type, tag, false, numToDecrement)) {
|
if (!updateResourceCountForAccount(accountId, type, tag, false, numToDecrement)) {
|
||||||
_alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_UPDATE_RESOURCE_COUNT, 0L, 0L, "Failed to decrement resource count of type " + type + " for account id=" + accountId,
|
_alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_UPDATE_RESOURCE_COUNT, 0L, 0L, "Failed to decrement resource count of type " + type + " for account id=" + accountId,
|
||||||
@ -399,11 +398,11 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
|
|||||||
|
|
||||||
// Check if limit is configured for account
|
// Check if limit is configured for account
|
||||||
if (limit != null) {
|
if (limit != null) {
|
||||||
max = limit.getMax().longValue();
|
max = limit.getMax();
|
||||||
} else {
|
} else {
|
||||||
String resourceTypeName = type.name();
|
String resourceTypeName = type.name();
|
||||||
// If the account has an no limit set, then return global default account limits
|
// If the account has an no limit set, then return global default account limits
|
||||||
Long value = null;
|
Long value;
|
||||||
if (account.getType() == Account.Type.PROJECT) {
|
if (account.getType() == Account.Type.PROJECT) {
|
||||||
value = projectResourceLimitMap.get(resourceTypeName);
|
value = projectResourceLimitMap.get(resourceTypeName);
|
||||||
} else {
|
} else {
|
||||||
@ -444,10 +443,10 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
|
|||||||
|
|
||||||
// Check if limit is configured for account
|
// Check if limit is configured for account
|
||||||
if (limit != null) {
|
if (limit != null) {
|
||||||
max = limit.longValue();
|
max = limit;
|
||||||
} else {
|
} else {
|
||||||
// If the account has an no limit set, then return global default account limits
|
// If the account has an no limit set, then return global default account limits
|
||||||
Long value = null;
|
Long value;
|
||||||
if (account.getType() == Account.Type.PROJECT) {
|
if (account.getType() == Account.Type.PROJECT) {
|
||||||
value = projectResourceLimitMap.get(type.getName());
|
value = projectResourceLimitMap.get(type.getName());
|
||||||
} else {
|
} else {
|
||||||
@ -479,7 +478,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
|
|||||||
ResourceLimitVO limit = _resourceLimitDao.findByOwnerIdAndTypeAndTag(domain.getId(), ResourceOwnerType.Domain, type, tag);
|
ResourceLimitVO limit = _resourceLimitDao.findByOwnerIdAndTypeAndTag(domain.getId(), ResourceOwnerType.Domain, type, tag);
|
||||||
|
|
||||||
if (limit != null) {
|
if (limit != null) {
|
||||||
max = limit.getMax().longValue();
|
max = limit.getMax();
|
||||||
} else {
|
} else {
|
||||||
// check domain hierarchy
|
// check domain hierarchy
|
||||||
Long domainId = domain.getParent();
|
Long domainId = domain.getParent();
|
||||||
@ -493,12 +492,12 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (limit != null) {
|
if (limit != null) {
|
||||||
max = limit.getMax().longValue();
|
max = limit.getMax();
|
||||||
} else {
|
} else {
|
||||||
if (StringUtils.isNotEmpty(tag)) {
|
if (StringUtils.isNotEmpty(tag)) {
|
||||||
return findCorrectResourceLimitForDomain(domain, type, null);
|
return findCorrectResourceLimitForDomain(domain, type, null);
|
||||||
}
|
}
|
||||||
Long value = null;
|
Long value;
|
||||||
value = domainResourceLimitMap.get(type.name());
|
value = domainResourceLimitMap.get(type.name());
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
if (value < 0) { // return unlimit if value is set to negative
|
if (value < 0) { // return unlimit if value is set to negative
|
||||||
@ -517,7 +516,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
|
|||||||
|
|
||||||
protected void checkDomainResourceLimit(final Account account, final Project project, final ResourceType type, String tag, long numResources) throws ResourceAllocationException {
|
protected void checkDomainResourceLimit(final Account account, final Project project, final ResourceType type, String tag, long numResources) throws ResourceAllocationException {
|
||||||
// check all domains in the account's domain hierarchy
|
// check all domains in the account's domain hierarchy
|
||||||
Long domainId = null;
|
Long domainId;
|
||||||
if (project != null) {
|
if (project != null) {
|
||||||
domainId = project.getDomainId();
|
domainId = project.getDomainId();
|
||||||
} else {
|
} else {
|
||||||
@ -556,9 +555,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
|
|||||||
convCurrentDomainResourceCount, convCurrentResourceReservation, convNumResources
|
convCurrentDomainResourceCount, convCurrentResourceReservation, convNumResources
|
||||||
);
|
);
|
||||||
|
|
||||||
if (logger.isDebugEnabled()) {
|
logger.debug(CHECKING_IF, messageSuffix);
|
||||||
logger.debug("Checking if" + messageSuffix);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (domainResourceLimit != Resource.RESOURCE_UNLIMITED && requestedDomainResourceCount > domainResourceLimit) {
|
if (domainResourceLimit != Resource.RESOURCE_UNLIMITED && requestedDomainResourceCount > domainResourceLimit) {
|
||||||
String message = "Maximum" + messageSuffix;
|
String message = "Maximum" + messageSuffix;
|
||||||
@ -597,9 +594,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
|
|||||||
convertedAccountResourceLimit, convertedCurrentResourceCount, convertedCurrentResourceReservation, convertedNumResources
|
convertedAccountResourceLimit, convertedCurrentResourceCount, convertedCurrentResourceReservation, convertedNumResources
|
||||||
);
|
);
|
||||||
|
|
||||||
if (logger.isDebugEnabled()) {
|
logger.debug(CHECKING_IF, messageSuffix);
|
||||||
logger.debug("Checking if" + messageSuffix);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (accountResourceLimit != Resource.RESOURCE_UNLIMITED && requestedResourceCount > accountResourceLimit) {
|
if (accountResourceLimit != Resource.RESOURCE_UNLIMITED && requestedResourceCount > accountResourceLimit) {
|
||||||
String message = "Maximum" + messageSuffix;
|
String message = "Maximum" + messageSuffix;
|
||||||
@ -618,14 +613,14 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long findDefaultResourceLimitForDomain(ResourceType resourceType) {
|
public long findDefaultResourceLimitForDomain(ResourceType resourceType) {
|
||||||
Long resourceLimit = null;
|
Long resourceLimit;
|
||||||
resourceLimit = domainResourceLimitMap.get(resourceType.getName());
|
resourceLimit = domainResourceLimitMap.get(resourceType.getName());
|
||||||
if (resourceLimit != null && ResourceType.isStorageType(resourceType)) {
|
if (resourceLimit != null && ResourceType.isStorageType(resourceType)) {
|
||||||
if (! Long.valueOf(Resource.RESOURCE_UNLIMITED).equals(resourceLimit)) {
|
if (! Long.valueOf(Resource.RESOURCE_UNLIMITED).equals(resourceLimit)) {
|
||||||
resourceLimit = resourceLimit * ResourceType.bytesToGiB;
|
resourceLimit = resourceLimit * ResourceType.bytesToGiB;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
resourceLimit = Long.valueOf(Resource.RESOURCE_UNLIMITED);
|
resourceLimit = (long) Resource.RESOURCE_UNLIMITED;
|
||||||
}
|
}
|
||||||
return resourceLimit;
|
return resourceLimit;
|
||||||
}
|
}
|
||||||
@ -703,8 +698,8 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
|
|||||||
@Override
|
@Override
|
||||||
public List<ResourceLimitVO> searchForLimits(Long id, Long accountId, Long domainId, ResourceType resourceType, String tag, Long startIndex, Long pageSizeVal) {
|
public List<ResourceLimitVO> searchForLimits(Long id, Long accountId, Long domainId, ResourceType resourceType, String tag, Long startIndex, Long pageSizeVal) {
|
||||||
Account caller = CallContext.current().getCallingAccount();
|
Account caller = CallContext.current().getCallingAccount();
|
||||||
List<ResourceLimitVO> limits = new ArrayList<ResourceLimitVO>();
|
List<ResourceLimitVO> limits = new ArrayList<>();
|
||||||
boolean isAccount = true;
|
boolean isAccount;
|
||||||
|
|
||||||
if (!_accountMgr.isAdmin(caller.getId())) {
|
if (!_accountMgr.isAdmin(caller.getId())) {
|
||||||
accountId = caller.getId();
|
accountId = caller.getId();
|
||||||
@ -796,7 +791,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
|
|||||||
if (foundLimits.isEmpty()) {
|
if (foundLimits.isEmpty()) {
|
||||||
ResourceOwnerType ownerType = ResourceOwnerType.Domain;
|
ResourceOwnerType ownerType = ResourceOwnerType.Domain;
|
||||||
Long ownerId = domainId;
|
Long ownerId = domainId;
|
||||||
long max = 0;
|
long max;
|
||||||
if (isAccount) {
|
if (isAccount) {
|
||||||
ownerType = ResourceOwnerType.Account;
|
ownerType = ResourceOwnerType.Account;
|
||||||
ownerId = accountId;
|
ownerId = accountId;
|
||||||
@ -814,8 +809,8 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
|
|||||||
// see if any limits are missing from the table, and if yes - get it from the config table and add
|
// see if any limits are missing from the table, and if yes - get it from the config table and add
|
||||||
ResourceType[] resourceTypes = ResourceCount.ResourceType.values();
|
ResourceType[] resourceTypes = ResourceCount.ResourceType.values();
|
||||||
if (foundLimits.size() != resourceTypes.length) {
|
if (foundLimits.size() != resourceTypes.length) {
|
||||||
List<String> accountLimitStr = new ArrayList<String>();
|
List<String> accountLimitStr = new ArrayList<>();
|
||||||
List<String> domainLimitStr = new ArrayList<String>();
|
List<String> domainLimitStr = new ArrayList<>();
|
||||||
for (ResourceLimitVO foundLimit : foundLimits) {
|
for (ResourceLimitVO foundLimit : foundLimits) {
|
||||||
if (foundLimit.getAccountId() != null) {
|
if (foundLimit.getAccountId() != null) {
|
||||||
accountLimitStr.add(foundLimit.getType().toString());
|
accountLimitStr.add(foundLimit.getType().toString());
|
||||||
@ -909,8 +904,8 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
|
|||||||
Account caller = CallContext.current().getCallingAccount();
|
Account caller = CallContext.current().getCallingAccount();
|
||||||
|
|
||||||
if (max == null) {
|
if (max == null) {
|
||||||
max = new Long(Resource.RESOURCE_UNLIMITED);
|
max = (long)Resource.RESOURCE_UNLIMITED;
|
||||||
} else if (max.longValue() < Resource.RESOURCE_UNLIMITED) {
|
} else if (max < Resource.RESOURCE_UNLIMITED) {
|
||||||
throw new InvalidParameterValueException("Please specify either '-1' for an infinite limit, or a limit that is at least '0'.");
|
throw new InvalidParameterValueException("Please specify either '-1' for an infinite limit, or a limit that is at least '0'.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -918,7 +913,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
|
|||||||
ResourceType resourceType = null;
|
ResourceType resourceType = null;
|
||||||
if (typeId != null) {
|
if (typeId != null) {
|
||||||
for (ResourceType type : Resource.ResourceType.values()) {
|
for (ResourceType type : Resource.ResourceType.values()) {
|
||||||
if (type.getOrdinal() == typeId.intValue()) {
|
if (type.getOrdinal() == typeId) {
|
||||||
resourceType = type;
|
resourceType = type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -957,7 +952,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
|
|||||||
throw new InvalidParameterValueException("Only " + Resource.RESOURCE_UNLIMITED + " limit is supported for Root Admin accounts");
|
throw new InvalidParameterValueException("Only " + Resource.RESOURCE_UNLIMITED + " limit is supported for Root Admin accounts");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((caller.getAccountId() == accountId.longValue()) && (_accountMgr.isDomainAdmin(caller.getId()) || caller.getType() == Account.Type.RESOURCE_DOMAIN_ADMIN)) {
|
if ((caller.getAccountId() == accountId) && (_accountMgr.isDomainAdmin(caller.getId()) || caller.getType() == Account.Type.RESOURCE_DOMAIN_ADMIN)) {
|
||||||
// If the admin is trying to update their own account, disallow.
|
// If the admin is trying to update their own account, disallow.
|
||||||
throw new PermissionDeniedException(String.format("Unable to update resource limit for their own account %s, permission denied", account));
|
throw new PermissionDeniedException(String.format("Unable to update resource limit for their own account %s, permission denied", account));
|
||||||
}
|
}
|
||||||
@ -993,12 +988,12 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
|
|||||||
|
|
||||||
_accountMgr.checkAccess(caller, domain);
|
_accountMgr.checkAccess(caller, domain);
|
||||||
|
|
||||||
if (Domain.ROOT_DOMAIN == domainId.longValue()) {
|
if (Domain.ROOT_DOMAIN == domainId) {
|
||||||
// no one can add limits on ROOT domain, disallow...
|
// no one can add limits on ROOT domain, disallow...
|
||||||
throw new PermissionDeniedException("Cannot update resource limit for ROOT domain " + domainId + ", permission denied");
|
throw new PermissionDeniedException("Cannot update resource limit for ROOT domain " + domainId + ", permission denied");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((caller.getDomainId() == domainId.longValue()) && caller.getType() == Account.Type.DOMAIN_ADMIN || caller.getType() == Account.Type.RESOURCE_DOMAIN_ADMIN) {
|
if ((caller.getDomainId() == domainId) && caller.getType() == Account.Type.DOMAIN_ADMIN || caller.getType() == Account.Type.RESOURCE_DOMAIN_ADMIN) {
|
||||||
// if the admin is trying to update their own domain, disallow...
|
// if the admin is trying to update their own domain, disallow...
|
||||||
throw new PermissionDeniedException("Unable to update resource limit for domain " + domainId + ", permission denied");
|
throw new PermissionDeniedException("Unable to update resource limit for domain " + domainId + ", permission denied");
|
||||||
}
|
}
|
||||||
@ -1013,7 +1008,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
|
|||||||
if (parentDomainId != null) {
|
if (parentDomainId != null) {
|
||||||
DomainVO parentDomain = _domainDao.findById(parentDomainId);
|
DomainVO parentDomain = _domainDao.findById(parentDomainId);
|
||||||
long parentMaximum = findCorrectResourceLimitForDomain(parentDomain, resourceType, tag);
|
long parentMaximum = findCorrectResourceLimitForDomain(parentDomain, resourceType, tag);
|
||||||
if ((parentMaximum >= 0) && (max.longValue() > parentMaximum)) {
|
if ((parentMaximum >= 0) && (max > parentMaximum)) {
|
||||||
throw new InvalidParameterValueException(String.format("Domain %s has maximum allowed resource limit %d for %s, please specify a value less than or equal to %d", parentDomain, parentMaximum, resourceType, parentMaximum));
|
throw new InvalidParameterValueException(String.format("Domain %s has maximum allowed resource limit %d for %s, please specify a value less than or equal to %d", parentDomain, parentMaximum, resourceType, parentMaximum));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1031,7 +1026,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
|
|||||||
|
|
||||||
ActionEventUtils.onActionEvent(caller.getId(), caller.getAccountId(),
|
ActionEventUtils.onActionEvent(caller.getId(), caller.getAccountId(),
|
||||||
caller.getDomainId(), EventTypes.EVENT_RESOURCE_LIMIT_UPDATE,
|
caller.getDomainId(), EventTypes.EVENT_RESOURCE_LIMIT_UPDATE,
|
||||||
"Resource limit updated. Resource Type: " + resourceType.toString() + ", New Value: " + max,
|
"Resource limit updated. Resource Type: " + resourceType + ", New Value: " + max,
|
||||||
ownerResourceId, ownerResourceType.toString());
|
ownerResourceId, ownerResourceType.toString());
|
||||||
|
|
||||||
if (limit != null) {
|
if (limit != null) {
|
||||||
@ -1110,15 +1105,15 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
|
|||||||
@Override
|
@Override
|
||||||
public List<? extends ResourceCount> recalculateResourceCount(Long accountId, Long domainId, Integer typeId, String tag) throws CloudRuntimeException {
|
public List<? extends ResourceCount> recalculateResourceCount(Long accountId, Long domainId, Integer typeId, String tag) throws CloudRuntimeException {
|
||||||
Account callerAccount = CallContext.current().getCallingAccount();
|
Account callerAccount = CallContext.current().getCallingAccount();
|
||||||
long count = 0;
|
long count;
|
||||||
List<ResourceCountVO> counts = new ArrayList<ResourceCountVO>();
|
List<ResourceCountVO> counts = new ArrayList<>();
|
||||||
List<ResourceType> resourceTypes = new ArrayList<ResourceType>();
|
List<ResourceType> resourceTypes = new ArrayList<>();
|
||||||
|
|
||||||
ResourceType resourceType = null;
|
ResourceType resourceType = null;
|
||||||
|
|
||||||
if (typeId != null) {
|
if (typeId != null) {
|
||||||
for (ResourceType type : Resource.ResourceType.values()) {
|
for (ResourceType type : Resource.ResourceType.values()) {
|
||||||
if (type.getOrdinal() == typeId.intValue()) {
|
if (type.getOrdinal() == typeId) {
|
||||||
resourceType = type;
|
resourceType = type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1137,12 +1132,13 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
|
|||||||
throw new InvalidParameterValueException("Please specify a valid domain ID.");
|
throw new InvalidParameterValueException("Please specify a valid domain ID.");
|
||||||
}
|
}
|
||||||
_accountMgr.checkAccess(callerAccount, domain);
|
_accountMgr.checkAccess(callerAccount, domain);
|
||||||
|
if (accountId != null) {
|
||||||
Account account = _entityMgr.findById(Account.class, accountId);
|
Account account = _entityMgr.findById(Account.class, accountId);
|
||||||
if (account == null) {
|
if (account == null) {
|
||||||
throw new InvalidParameterValueException("Unable to find account " + accountId);
|
throw new InvalidParameterValueException("Unable to find account " + accountId);
|
||||||
}
|
}
|
||||||
_accountMgr.verifyCallerPrivilegeForUserOrAccountOperations(account);
|
_accountMgr.verifyCallerPrivilegeForUserOrAccountOperations(account);
|
||||||
|
}
|
||||||
if (resourceType != null) {
|
if (resourceType != null) {
|
||||||
resourceTypes.add(resourceType);
|
resourceTypes.add(resourceType);
|
||||||
} else {
|
} else {
|
||||||
@ -1191,7 +1187,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
|
|||||||
convertedDelta = toHumanReadableSize(delta);
|
convertedDelta = toHumanReadableSize(delta);
|
||||||
}
|
}
|
||||||
String typeStr = StringUtils.isNotEmpty(tag) ? String.format("%s (tag: %s)", type, tag) : type.getName();
|
String typeStr = StringUtils.isNotEmpty(tag) ? String.format("%s (tag: %s)", type, tag) : type.getName();
|
||||||
logger.debug("Updating resource Type = " + typeStr + " count for Account = " + accountId + " Operation = " + (increment ? "increasing" : "decreasing") + " Amount = " + convertedDelta);
|
logger.debug("Updating resource Type = {} count for Account with id = {} Operation = {} Amount = {}", typeStr, accountId, (increment ? "increasing" : "decreasing"), convertedDelta);
|
||||||
}
|
}
|
||||||
Set<Long> rowIdsToUpdate = _resourceCountDao.listAllRowsToUpdate(accountId, ResourceOwnerType.Account, type, tag);
|
Set<Long> rowIdsToUpdate = _resourceCountDao.listAllRowsToUpdate(accountId, ResourceOwnerType.Account, type, tag);
|
||||||
return _resourceCountDao.updateCountByDeltaForIds(new ArrayList<>(rowIdsToUpdate), increment, delta);
|
return _resourceCountDao.updateCountByDeltaForIds(new ArrayList<>(rowIdsToUpdate), increment, delta);
|
||||||
@ -1246,6 +1242,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
|
|||||||
newResourceCount += _projectDao.countProjectsForDomain(domainId);
|
newResourceCount += _projectDao.countProjectsForDomain(domainId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO make sure that the resource counts are not null
|
||||||
for (ResourceCountVO resourceCount : resourceCounts) {
|
for (ResourceCountVO resourceCount : resourceCounts) {
|
||||||
if (resourceCount.getResourceOwnerType() == ResourceOwnerType.Domain && resourceCount.getDomainId() == domainId) {
|
if (resourceCount.getResourceOwnerType() == ResourceOwnerType.Domain && resourceCount.getDomainId() == domainId) {
|
||||||
oldResourceCount = resourceCount.getCount();
|
oldResourceCount = resourceCount.getCount();
|
||||||
@ -1255,11 +1252,12 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO domainRC may be null if there are no resource counts for the domain found in the loop above
|
||||||
if (oldResourceCount != newResourceCount) {
|
if (oldResourceCount != newResourceCount) {
|
||||||
domainRC.setCount(newResourceCount);
|
domainRC.setCount(newResourceCount);
|
||||||
_resourceCountDao.update(domainRC.getId(), domainRC);
|
_resourceCountDao.update(domainRC.getId(), domainRC);
|
||||||
logger.warn("Discrepency in the resource count has been detected " + "(original count = " + oldResourceCount + " correct count = " + newResourceCount + ") for Type = " + type
|
logger.warn("Discrepency in the resource count has been detected (original count = {} correct count = {}) for Type = {} for Domain ID = {} is fixed during resource count recalculation.",
|
||||||
+ " for Domain ID = " + domainId + " is fixed during resource count recalculation.");
|
oldResourceCount, newResourceCount, type, domainId);
|
||||||
}
|
}
|
||||||
return newResourceCount;
|
return newResourceCount;
|
||||||
});
|
});
|
||||||
@ -1335,8 +1333,8 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
|
|||||||
// No need to log message for storage type resources because both are recalculating the
|
// No need to log message for storage type resources because both are recalculating the
|
||||||
// resource count which will not lead to any discrepancy.
|
// resource count which will not lead to any discrepancy.
|
||||||
if (newCount != null && !newCount.equals(oldCount) && !ResourceType.isStorageType(type)) {
|
if (newCount != null && !newCount.equals(oldCount) && !ResourceType.isStorageType(type)) {
|
||||||
logger.warn("Discrepancy in the resource count " + "(original count=" + oldCount + " correct count = " + newCount + ") for type " + type +
|
logger.warn("Discrepancy in the resource count (original count={} correct count = {}) for type {} for account ID {} is fixed during resource count recalculation.",
|
||||||
" for account ID " + accountId + " is fixed during resource count recalculation.");
|
oldCount, newCount, type, accountId);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (newCount == null) ? 0 : newCount;
|
return (newCount == null) ? 0 : newCount;
|
||||||
@ -1508,20 +1506,16 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
|
|||||||
}
|
}
|
||||||
|
|
||||||
private long calculatePublicIpForAccount(long accountId) {
|
private long calculatePublicIpForAccount(long accountId) {
|
||||||
Long dedicatedCount = 0L;
|
long dedicatedCount = 0L;
|
||||||
Long allocatedCount = 0L;
|
long allocatedCount;
|
||||||
|
|
||||||
List<VlanVO> dedicatedVlans = _vlanDao.listDedicatedVlans(accountId);
|
List<VlanVO> dedicatedVlans = _vlanDao.listDedicatedVlans(accountId);
|
||||||
for (VlanVO dedicatedVlan : dedicatedVlans) {
|
for (VlanVO dedicatedVlan : dedicatedVlans) {
|
||||||
List<IPAddressVO> ips = _ipAddressDao.listByVlanId(dedicatedVlan.getId());
|
List<IPAddressVO> ips = _ipAddressDao.listByVlanId(dedicatedVlan.getId());
|
||||||
dedicatedCount += new Long(ips.size());
|
dedicatedCount += ips.size();
|
||||||
}
|
}
|
||||||
allocatedCount = _ipAddressDao.countAllocatedIPsForAccount(accountId);
|
allocatedCount = _ipAddressDao.countAllocatedIPsForAccount(accountId);
|
||||||
if (dedicatedCount > allocatedCount) {
|
return Math.max(dedicatedCount, allocatedCount);
|
||||||
return dedicatedCount;
|
|
||||||
} else {
|
|
||||||
return allocatedCount;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected long calculatePrimaryStorageForAccount(long accountId, String tag) {
|
protected long calculatePrimaryStorageForAccount(long accountId, String tag) {
|
||||||
@ -1609,10 +1603,10 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
|
|||||||
|
|
||||||
protected TaggedResourceLimitAndCountResponse getTaggedResourceLimitAndCountResponse(Account account,
|
protected TaggedResourceLimitAndCountResponse getTaggedResourceLimitAndCountResponse(Account account,
|
||||||
Domain domain, ResourceOwnerType ownerType, ResourceType type, String tag) {
|
Domain domain, ResourceOwnerType ownerType, ResourceType type, String tag) {
|
||||||
Long limit = ResourceOwnerType.Account.equals(ownerType) ?
|
long limit = ResourceOwnerType.Account.equals(ownerType) ?
|
||||||
findCorrectResourceLimitForAccount(account, type, tag) :
|
findCorrectResourceLimitForAccount(account, type, tag) :
|
||||||
findCorrectResourceLimitForDomain(domain, type, tag);
|
findCorrectResourceLimitForDomain(domain, type, tag);
|
||||||
Long count = 0L;
|
long count = 0L;
|
||||||
ResourceCountVO countVO = _resourceCountDao.findByOwnerAndTypeAndTag(
|
ResourceCountVO countVO = _resourceCountDao.findByOwnerAndTypeAndTag(
|
||||||
ResourceOwnerType.Account.equals(ownerType) ? account.getId() : domain.getId(), ownerType, type, tag);
|
ResourceOwnerType.Account.equals(ownerType) ? account.getId() : domain.getId(), ownerType, type, tag);
|
||||||
if (countVO != null) {
|
if (countVO != null) {
|
||||||
@ -1861,7 +1855,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
|
|||||||
if (currentOfferingTags.isEmpty() && newOfferingTags.isEmpty()) {
|
if (currentOfferingTags.isEmpty() && newOfferingTags.isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Set<String> sameTags = currentOfferingTags.stream().filter(newOfferingTags::contains).collect(Collectors.toSet());;
|
Set<String> sameTags = currentOfferingTags.stream().filter(newOfferingTags::contains).collect(Collectors.toSet());
|
||||||
Set<String> newTags = newOfferingTags.stream().filter(tag -> !currentOfferingTags.contains(tag)).collect(Collectors.toSet());
|
Set<String> newTags = newOfferingTags.stream().filter(tag -> !currentOfferingTags.contains(tag)).collect(Collectors.toSet());
|
||||||
Set<String> removedTags = currentOfferingTags.stream().filter(tag -> !newOfferingTags.contains(tag)).collect(Collectors.toSet());
|
Set<String> removedTags = currentOfferingTags.stream().filter(tag -> !newOfferingTags.contains(tag)).collect(Collectors.toSet());
|
||||||
return new Ternary<>(sameTags, newTags, removedTags);
|
return new Ternary<>(sameTags, newTags, removedTags);
|
||||||
@ -1936,7 +1930,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
|
|||||||
if (currentOfferingTags.isEmpty() && newOfferingTags.isEmpty()) {
|
if (currentOfferingTags.isEmpty() && newOfferingTags.isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Set<String> sameTags = currentOfferingTags.stream().filter(newOfferingTags::contains).collect(Collectors.toSet());;
|
Set<String> sameTags = currentOfferingTags.stream().filter(newOfferingTags::contains).collect(Collectors.toSet());
|
||||||
Set<String> newTags = newOfferingTags.stream().filter(tag -> !currentOfferingTags.contains(tag)).collect(Collectors.toSet());
|
Set<String> newTags = newOfferingTags.stream().filter(tag -> !currentOfferingTags.contains(tag)).collect(Collectors.toSet());
|
||||||
Set<String> removedTags = currentOfferingTags.stream().filter(tag -> !newOfferingTags.contains(tag)).collect(Collectors.toSet());
|
Set<String> removedTags = currentOfferingTags.stream().filter(tag -> !newOfferingTags.contains(tag)).collect(Collectors.toSet());
|
||||||
return new Ternary<>(sameTags, newTags, removedTags);
|
return new Ternary<>(sameTags, newTags, removedTags);
|
||||||
|
|||||||
@ -774,14 +774,12 @@ import com.cloud.network.dao.NetworkDao;
|
|||||||
import com.cloud.network.dao.NetworkDomainDao;
|
import com.cloud.network.dao.NetworkDomainDao;
|
||||||
import com.cloud.network.dao.NetworkDomainVO;
|
import com.cloud.network.dao.NetworkDomainVO;
|
||||||
import com.cloud.network.dao.NetworkVO;
|
import com.cloud.network.dao.NetworkVO;
|
||||||
import com.cloud.network.dao.PublicIpQuarantineDao;
|
|
||||||
import com.cloud.network.vpc.dao.VpcDao;
|
import com.cloud.network.vpc.dao.VpcDao;
|
||||||
import com.cloud.org.Cluster;
|
import com.cloud.org.Cluster;
|
||||||
import com.cloud.org.Grouping.AllocationState;
|
import com.cloud.org.Grouping.AllocationState;
|
||||||
import com.cloud.projects.Project;
|
import com.cloud.projects.Project;
|
||||||
import com.cloud.projects.Project.ListProjectResourcesCriteria;
|
import com.cloud.projects.Project.ListProjectResourcesCriteria;
|
||||||
import com.cloud.projects.ProjectManager;
|
import com.cloud.projects.ProjectManager;
|
||||||
import com.cloud.resource.ResourceManager;
|
|
||||||
import com.cloud.server.ResourceTag.ResourceObjectType;
|
import com.cloud.server.ResourceTag.ResourceObjectType;
|
||||||
import com.cloud.service.ServiceOfferingVO;
|
import com.cloud.service.ServiceOfferingVO;
|
||||||
import com.cloud.service.dao.ServiceOfferingDao;
|
import com.cloud.service.dao.ServiceOfferingDao;
|
||||||
@ -883,8 +881,8 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||||||
static final ConfigKey<Integer> sshKeyLength = new ConfigKey<>("Advanced", Integer.class, "ssh.key.length", "2048", "Specifies custom SSH key length (bit)", true, ConfigKey.Scope.Global);
|
static final ConfigKey<Integer> sshKeyLength = new ConfigKey<>("Advanced", Integer.class, "ssh.key.length", "2048", "Specifies custom SSH key length (bit)", true, ConfigKey.Scope.Global);
|
||||||
static final ConfigKey<Boolean> humanReadableSizes = new ConfigKey<>("Advanced", Boolean.class, "display.human.readable.sizes", "true", "Enables outputting human readable byte sizes to logs and usage records.", false, ConfigKey.Scope.Global);
|
static final ConfigKey<Boolean> humanReadableSizes = new ConfigKey<>("Advanced", Boolean.class, "display.human.readable.sizes", "true", "Enables outputting human readable byte sizes to logs and usage records.", false, ConfigKey.Scope.Global);
|
||||||
public static final ConfigKey<String> customCsIdentifier = new ConfigKey<>("Advanced", String.class, "custom.cs.identifier", UUID.randomUUID().toString().split("-")[0].substring(4), "Custom identifier for the cloudstack installation", true, ConfigKey.Scope.Global);
|
public static final ConfigKey<String> customCsIdentifier = new ConfigKey<>("Advanced", String.class, "custom.cs.identifier", UUID.randomUUID().toString().split("-")[0].substring(4), "Custom identifier for the cloudstack installation", true, ConfigKey.Scope.Global);
|
||||||
public static final ConfigKey<Boolean> exposeCloudStackVersionInApiXmlResponse = new ConfigKey<Boolean>("Advanced", Boolean.class, "expose.cloudstack.version.api.xml.response", "true", "Indicates whether ACS version should appear in the root element of an API XML response.", true, ConfigKey.Scope.Global);
|
public static final ConfigKey<Boolean> exposeCloudStackVersionInApiXmlResponse = new ConfigKey<>("Advanced", Boolean.class, "expose.cloudstack.version.api.xml.response", "true", "Indicates whether ACS version should appear in the root element of an API XML response.", true, ConfigKey.Scope.Global);
|
||||||
public static final ConfigKey<Boolean> exposeCloudStackVersionInApiListCapabilities = new ConfigKey<Boolean>("Advanced", Boolean.class, "expose.cloudstack.version.api.list.capabilities", "true", "Indicates whether ACS version should show in the listCapabilities API.", true, ConfigKey.Scope.Global);
|
public static final ConfigKey<Boolean> exposeCloudStackVersionInApiListCapabilities = new ConfigKey<>("Advanced", Boolean.class, "expose.cloudstack.version.api.list.capabilities", "true", "Indicates whether ACS version should show in the listCapabilities API.", true, ConfigKey.Scope.Global);
|
||||||
|
|
||||||
private static final VirtualMachine.Type []systemVmTypes = { VirtualMachine.Type.SecondaryStorageVm, VirtualMachine.Type.ConsoleProxy};
|
private static final VirtualMachine.Type []systemVmTypes = { VirtualMachine.Type.SecondaryStorageVm, VirtualMachine.Type.ConsoleProxy};
|
||||||
private static final List<HypervisorType> LIVE_MIGRATION_SUPPORTING_HYPERVISORS = List.of(HypervisorType.Hyperv, HypervisorType.KVM,
|
private static final List<HypervisorType> LIVE_MIGRATION_SUPPORTING_HYPERVISORS = List.of(HypervisorType.Hyperv, HypervisorType.KVM,
|
||||||
@ -991,8 +989,6 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||||||
@Inject
|
@Inject
|
||||||
private ProjectManager _projectMgr;
|
private ProjectManager _projectMgr;
|
||||||
@Inject
|
@Inject
|
||||||
private ResourceManager _resourceMgr;
|
|
||||||
@Inject
|
|
||||||
private HighAvailabilityManager _haMgr;
|
private HighAvailabilityManager _haMgr;
|
||||||
@Inject
|
@Inject
|
||||||
private HostTagsDao _hostTagsDao;
|
private HostTagsDao _hostTagsDao;
|
||||||
@ -1050,10 +1046,6 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||||||
StoragePoolTagsDao storagePoolTagsDao;
|
StoragePoolTagsDao storagePoolTagsDao;
|
||||||
@Inject
|
@Inject
|
||||||
protected ManagementServerJoinDao managementServerJoinDao;
|
protected ManagementServerJoinDao managementServerJoinDao;
|
||||||
|
|
||||||
@Inject
|
|
||||||
private PublicIpQuarantineDao publicIpQuarantineDao;
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
ClusterManager _clusterMgr;
|
ClusterManager _clusterMgr;
|
||||||
|
|
||||||
@ -1080,7 +1072,6 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||||||
private List<UserAuthenticator> _userAuthenticators;
|
private List<UserAuthenticator> _userAuthenticators;
|
||||||
private List<UserTwoFactorAuthenticator> _userTwoFactorAuthenticators;
|
private List<UserTwoFactorAuthenticator> _userTwoFactorAuthenticators;
|
||||||
private List<UserAuthenticator> _userPasswordEncoders;
|
private List<UserAuthenticator> _userPasswordEncoders;
|
||||||
protected boolean _executeInSequence;
|
|
||||||
|
|
||||||
protected List<DeploymentPlanner> _planners;
|
protected List<DeploymentPlanner> _planners;
|
||||||
|
|
||||||
@ -4751,6 +4742,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||||||
capabilities.put(ApiConstants.INSTANCES_DISKS_STATS_RETENTION_ENABLED, StatsCollector.vmDiskStatsRetentionEnabled.value());
|
capabilities.put(ApiConstants.INSTANCES_DISKS_STATS_RETENTION_ENABLED, StatsCollector.vmDiskStatsRetentionEnabled.value());
|
||||||
capabilities.put(ApiConstants.INSTANCES_DISKS_STATS_RETENTION_TIME, StatsCollector.vmDiskStatsMaxRetentionTime.value());
|
capabilities.put(ApiConstants.INSTANCES_DISKS_STATS_RETENTION_TIME, StatsCollector.vmDiskStatsMaxRetentionTime.value());
|
||||||
capabilities.put(ApiConstants.INSTANCE_LEASE_ENABLED, VMLeaseManager.InstanceLeaseEnabled.value());
|
capabilities.put(ApiConstants.INSTANCE_LEASE_ENABLED, VMLeaseManager.InstanceLeaseEnabled.value());
|
||||||
|
capabilities.put(ApiConstants.DYNAMIC_SCALING_ENABLED, UserVmManager.EnableDynamicallyScaleVm.value());
|
||||||
if (apiLimitEnabled) {
|
if (apiLimitEnabled) {
|
||||||
capabilities.put("apiLimitInterval", apiLimitInterval);
|
capabilities.put("apiLimitInterval", apiLimitInterval);
|
||||||
capabilities.put("apiLimitMax", apiLimitMax);
|
capabilities.put("apiLimitMax", apiLimitMax);
|
||||||
|
|||||||
@ -2644,7 +2644,9 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
|
|
||||||
excludeLocalStorageIfNeeded(volumeToAttach);
|
excludeLocalStorageIfNeeded(volumeToAttach);
|
||||||
|
|
||||||
checkForDevicesInCopies(vmId, vm);
|
checkForVMSnapshots(vmId, vm);
|
||||||
|
|
||||||
|
checkForBackups(vm, true);
|
||||||
|
|
||||||
checkRightsToAttach(caller, volumeToAttach, vm);
|
checkRightsToAttach(caller, volumeToAttach, vm);
|
||||||
|
|
||||||
@ -2743,18 +2745,12 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkForDevicesInCopies(Long vmId, UserVmVO vm) {
|
private void checkForVMSnapshots(Long vmId, UserVmVO vm) {
|
||||||
// if target VM has associated VM snapshots
|
// if target VM has associated VM snapshots
|
||||||
List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
|
List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
|
||||||
if (vmSnapshots.size() > 0) {
|
if (vmSnapshots.size() > 0) {
|
||||||
throw new InvalidParameterValueException(String.format("Unable to attach volume to VM %s/%s, please specify a VM that does not have VM snapshots", vm.getName(), vm.getUuid()));
|
throw new InvalidParameterValueException(String.format("Unable to attach volume to VM %s/%s, please specify a VM that does not have VM snapshots", vm.getName(), vm.getUuid()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// if target VM has backups
|
|
||||||
List<Backup> backups = backupDao.listByVmId(vm.getDataCenterId(), vm.getId());
|
|
||||||
if (vm.getBackupOfferingId() != null && !backups.isEmpty()) {
|
|
||||||
throw new InvalidParameterValueException(String.format("Unable to attach volume to VM %s/%s, please specify a VM that does not have any backups", vm.getName(), vm.getUuid()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2854,7 +2850,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
return volumeToAttach;
|
return volumeToAttach;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void validateIfVmHasBackups(UserVmVO vm, boolean attach) {
|
protected void checkForBackups(UserVmVO vm, boolean attach) {
|
||||||
if ((vm.getBackupOfferingId() == null || CollectionUtils.isEmpty(vm.getBackupVolumeList())) || BooleanUtils.isTrue(BackupManager.BackupEnableAttachDetachVolumes.value())) {
|
if ((vm.getBackupOfferingId() == null || CollectionUtils.isEmpty(vm.getBackupVolumeList())) || BooleanUtils.isTrue(BackupManager.BackupEnableAttachDetachVolumes.value())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -3074,7 +3070,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
throw new InvalidParameterValueException("Unable to detach volume, please specify a VM that does not have VM snapshots");
|
throw new InvalidParameterValueException("Unable to detach volume, please specify a VM that does not have VM snapshots");
|
||||||
}
|
}
|
||||||
|
|
||||||
validateIfVmHasBackups(vm, false);
|
checkForBackups(vm, false);
|
||||||
|
|
||||||
AsyncJobExecutionContext asyncExecutionContext = AsyncJobExecutionContext.getCurrentExecutionContext();
|
AsyncJobExecutionContext asyncExecutionContext = AsyncJobExecutionContext.getCurrentExecutionContext();
|
||||||
if (asyncExecutionContext != null) {
|
if (asyncExecutionContext != null) {
|
||||||
|
|||||||
@ -1854,6 +1854,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
throw new InvalidParameterValueException("Failed to create private template record, please specify only one of volume ID (" + volumeId +
|
throw new InvalidParameterValueException("Failed to create private template record, please specify only one of volume ID (" + volumeId +
|
||||||
") and snapshot ID (" + snapshotId + ")");
|
") and snapshot ID (" + snapshotId + ")");
|
||||||
}
|
}
|
||||||
|
CPU.CPUArch arch = cmd.getArch();
|
||||||
|
|
||||||
HypervisorType hyperType;
|
HypervisorType hyperType;
|
||||||
VolumeVO volume = null;
|
VolumeVO volume = null;
|
||||||
@ -1946,7 +1947,6 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
String description = cmd.getDisplayText();
|
String description = cmd.getDisplayText();
|
||||||
boolean isExtractable = false;
|
boolean isExtractable = false;
|
||||||
Long sourceTemplateId = null;
|
Long sourceTemplateId = null;
|
||||||
CPU.CPUArch arch = CPU.CPUArch.amd64;
|
|
||||||
if (volume != null) {
|
if (volume != null) {
|
||||||
VMTemplateVO template = ApiDBUtils.findTemplateById(volume.getTemplateId());
|
VMTemplateVO template = ApiDBUtils.findTemplateById(volume.getTemplateId());
|
||||||
isExtractable = template != null && template.isExtractable() && template.getTemplateType() != Storage.TemplateType.SYSTEM;
|
isExtractable = template != null && template.isExtractable() && template.getTemplateType() != Storage.TemplateType.SYSTEM;
|
||||||
|
|||||||
@ -650,6 +650,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean isResourceDomainAdmin(Long accountId) {
|
public boolean isResourceDomainAdmin(Long accountId) {
|
||||||
if (accountId != null) {
|
if (accountId != null) {
|
||||||
AccountVO acct = _accountDao.findById(accountId);
|
AccountVO acct = _accountDao.findById(accountId);
|
||||||
|
|||||||
@ -19,6 +19,7 @@ package org.apache.cloudstack.backup;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -292,6 +293,7 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
|
|||||||
|
|
||||||
public static String createVolumeInfoFromVolumes(List<VolumeVO> vmVolumes) {
|
public static String createVolumeInfoFromVolumes(List<VolumeVO> vmVolumes) {
|
||||||
List<Backup.VolumeInfo> list = new ArrayList<>();
|
List<Backup.VolumeInfo> list = new ArrayList<>();
|
||||||
|
vmVolumes.sort(Comparator.comparing(VolumeVO::getDeviceId));
|
||||||
for (VolumeVO vol : vmVolumes) {
|
for (VolumeVO vol : vmVolumes) {
|
||||||
list.add(new Backup.VolumeInfo(vol.getUuid(), vol.getPath(), vol.getVolumeType(), vol.getSize()));
|
list.add(new Backup.VolumeInfo(vol.getUuid(), vol.getPath(), vol.getVolumeType(), vol.getSize()));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -170,6 +170,7 @@ import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
|
|||||||
import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
|
import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
|
||||||
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
||||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||||
|
import org.apache.cloudstack.storage.volume.VolumeOnStorageTO;
|
||||||
import org.apache.cloudstack.utils.volume.VirtualMachineDiskInfo;
|
import org.apache.cloudstack.utils.volume.VirtualMachineDiskInfo;
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
import org.apache.commons.collections.MapUtils;
|
import org.apache.commons.collections.MapUtils;
|
||||||
@ -814,7 +815,8 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
|
|||||||
throw new CloudRuntimeException("Error while copying volume of remote instance: " + answer.getDetails());
|
throw new CloudRuntimeException("Error while copying volume of remote instance: " + answer.getDetails());
|
||||||
}
|
}
|
||||||
CopyRemoteVolumeAnswer copyRemoteVolumeAnswer = (CopyRemoteVolumeAnswer) answer;
|
CopyRemoteVolumeAnswer copyRemoteVolumeAnswer = (CopyRemoteVolumeAnswer) answer;
|
||||||
if(!copyRemoteVolumeAnswer.getResult()) {
|
checkVolume(copyRemoteVolumeAnswer.getVolumeDetails());
|
||||||
|
if (!copyRemoteVolumeAnswer.getResult()) {
|
||||||
throw new CloudRuntimeException("Unable to copy volume of remote instance");
|
throw new CloudRuntimeException("Unable to copy volume of remote instance");
|
||||||
}
|
}
|
||||||
diskProfile.setSize(copyRemoteVolumeAnswer.getSize());
|
diskProfile.setSize(copyRemoteVolumeAnswer.getSize());
|
||||||
@ -1188,6 +1190,8 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
|
|||||||
allDetails.put(VmDetailConstants.KVM_VNC_PASSWORD, unmanagedInstance.getVncPassword());
|
allDetails.put(VmDetailConstants.KVM_VNC_PASSWORD, unmanagedInstance.getVncPassword());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addImportingVMBootTypeAndModeDetails(unmanagedInstance.getBootType(), unmanagedInstance.getBootMode(), allDetails);
|
||||||
|
|
||||||
VirtualMachine.PowerState powerState = VirtualMachine.PowerState.PowerOff;
|
VirtualMachine.PowerState powerState = VirtualMachine.PowerState.PowerOff;
|
||||||
if (unmanagedInstance.getPowerState().equals(UnmanagedInstanceTO.PowerState.PowerOn)) {
|
if (unmanagedInstance.getPowerState().equals(UnmanagedInstanceTO.PowerState.PowerOn)) {
|
||||||
powerState = VirtualMachine.PowerState.PowerOn;
|
powerState = VirtualMachine.PowerState.PowerOn;
|
||||||
@ -1259,6 +1263,12 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
|
|||||||
return userVm;
|
return userVm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addImportingVMBootTypeAndModeDetails(String bootType, String bootMode, Map<String, String> allDetails) {
|
||||||
|
if (StringUtils.isNotBlank(bootType) && bootType.equalsIgnoreCase("uefi") && StringUtils.isNotBlank(bootMode)) {
|
||||||
|
allDetails.put("UEFI", bootMode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private HashMap<String, UnmanagedInstanceTO> getUnmanagedInstancesForHost(HostVO host, String instanceName, List<String> managedVms) {
|
private HashMap<String, UnmanagedInstanceTO> getUnmanagedInstancesForHost(HostVO host, String instanceName, List<String> managedVms) {
|
||||||
HashMap<String, UnmanagedInstanceTO> unmanagedInstances = new HashMap<>();
|
HashMap<String, UnmanagedInstanceTO> unmanagedInstances = new HashMap<>();
|
||||||
if (host.isInMaintenanceStates()) {
|
if (host.isInMaintenanceStates()) {
|
||||||
@ -2692,7 +2702,13 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
|
|||||||
throw new CloudRuntimeException("Disk not found or is invalid");
|
throw new CloudRuntimeException("Disk not found or is invalid");
|
||||||
}
|
}
|
||||||
CheckVolumeAnswer checkVolumeAnswer = (CheckVolumeAnswer) answer;
|
CheckVolumeAnswer checkVolumeAnswer = (CheckVolumeAnswer) answer;
|
||||||
if(!checkVolumeAnswer.getResult()) {
|
try {
|
||||||
|
checkVolume(checkVolumeAnswer.getVolumeDetails());
|
||||||
|
} catch (CloudRuntimeException e) {
|
||||||
|
cleanupFailedImportVM(userVm);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
if (!checkVolumeAnswer.getResult()) {
|
||||||
cleanupFailedImportVM(userVm);
|
cleanupFailedImportVM(userVm);
|
||||||
throw new CloudRuntimeException("Disk not found or is invalid");
|
throw new CloudRuntimeException("Disk not found or is invalid");
|
||||||
}
|
}
|
||||||
@ -2718,6 +2734,31 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
|
|||||||
return userVm;
|
return userVm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void checkVolume(Map<VolumeOnStorageTO.Detail, String> volumeDetails) {
|
||||||
|
if (MapUtils.isEmpty(volumeDetails)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (volumeDetails.containsKey(VolumeOnStorageTO.Detail.IS_LOCKED)) {
|
||||||
|
String isLocked = volumeDetails.get(VolumeOnStorageTO.Detail.IS_LOCKED);
|
||||||
|
if (Boolean.parseBoolean(isLocked)) {
|
||||||
|
logFailureAndThrowException("Locked volume cannot be imported or unmanaged.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (volumeDetails.containsKey(VolumeOnStorageTO.Detail.IS_ENCRYPTED)) {
|
||||||
|
String isEncrypted = volumeDetails.get(VolumeOnStorageTO.Detail.IS_ENCRYPTED);
|
||||||
|
if (Boolean.parseBoolean(isEncrypted)) {
|
||||||
|
logFailureAndThrowException("Encrypted volume cannot be imported or unmanaged.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (volumeDetails.containsKey(VolumeOnStorageTO.Detail.BACKING_FILE)) {
|
||||||
|
String backingFile = volumeDetails.get(VolumeOnStorageTO.Detail.BACKING_FILE);
|
||||||
|
if (StringUtils.isNotBlank(backingFile)) {
|
||||||
|
logFailureAndThrowException("Volume with backing file cannot be imported or unmanaged.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private NetworkVO getDefaultNetwork(DataCenter zone, Account owner, boolean selectAny) throws InsufficientCapacityException, ResourceAllocationException {
|
private NetworkVO getDefaultNetwork(DataCenter zone, Account owner, boolean selectAny) throws InsufficientCapacityException, ResourceAllocationException {
|
||||||
NetworkVO defaultNetwork = null;
|
NetworkVO defaultNetwork = null;
|
||||||
|
|
||||||
|
|||||||
@ -672,7 +672,6 @@ public class VolumeApiServiceImplTest {
|
|||||||
when(vm.getState()).thenReturn(State.Running);
|
when(vm.getState()).thenReturn(State.Running);
|
||||||
when(vm.getDataCenterId()).thenReturn(34L);
|
when(vm.getDataCenterId()).thenReturn(34L);
|
||||||
when(vm.getBackupOfferingId()).thenReturn(null);
|
when(vm.getBackupOfferingId()).thenReturn(null);
|
||||||
when(backupDaoMock.listByVmId(anyLong(), anyLong())).thenReturn(Collections.emptyList());
|
|
||||||
when(volumeDaoMock.findByInstanceAndType(anyLong(), any(Volume.Type.class))).thenReturn(new ArrayList<>(10));
|
when(volumeDaoMock.findByInstanceAndType(anyLong(), any(Volume.Type.class))).thenReturn(new ArrayList<>(10));
|
||||||
when(volumeDataFactoryMock.getVolume(9L)).thenReturn(volumeToAttach);
|
when(volumeDataFactoryMock.getVolume(9L)).thenReturn(volumeToAttach);
|
||||||
when(volumeToAttach.getState()).thenReturn(Volume.State.Uploaded);
|
when(volumeToAttach.getState()).thenReturn(Volume.State.Uploaded);
|
||||||
@ -1311,7 +1310,7 @@ public class VolumeApiServiceImplTest {
|
|||||||
try {
|
try {
|
||||||
UserVmVO vm = Mockito.mock(UserVmVO.class);
|
UserVmVO vm = Mockito.mock(UserVmVO.class);
|
||||||
when(vm.getBackupOfferingId()).thenReturn(1l);
|
when(vm.getBackupOfferingId()).thenReturn(1l);
|
||||||
volumeApiServiceImpl.validateIfVmHasBackups(vm, false);
|
volumeApiServiceImpl.checkForBackups(vm, false);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Assert.assertEquals("Unable to detach volume, cannot detach volume from a VM that has backups. First remove the VM from the backup offering or set the global configuration 'backup.enable.attach.detach.of.volumes' to true.", e.getMessage());
|
Assert.assertEquals("Unable to detach volume, cannot detach volume from a VM that has backups. First remove the VM from the backup offering or set the global configuration 'backup.enable.attach.detach.of.volumes' to true.", e.getMessage());
|
||||||
}
|
}
|
||||||
@ -1322,7 +1321,7 @@ public class VolumeApiServiceImplTest {
|
|||||||
try {
|
try {
|
||||||
UserVmVO vm = Mockito.mock(UserVmVO.class);
|
UserVmVO vm = Mockito.mock(UserVmVO.class);
|
||||||
when(vm.getBackupOfferingId()).thenReturn(1l);
|
when(vm.getBackupOfferingId()).thenReturn(1l);
|
||||||
volumeApiServiceImpl.validateIfVmHasBackups(vm, true);
|
volumeApiServiceImpl.checkForBackups(vm, true);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Assert.assertEquals("Unable to attach volume, please specify a VM that does not have any backups or set the global configuration 'backup.enable.attach.detach.of.volumes' to true.", e.getMessage());
|
Assert.assertEquals("Unable to attach volume, please specify a VM that does not have any backups or set the global configuration 'backup.enable.attach.detach.of.volumes' to true.", e.getMessage());
|
||||||
}
|
}
|
||||||
@ -1332,7 +1331,7 @@ public class VolumeApiServiceImplTest {
|
|||||||
public void validateIfVmHaveBackupsTestSuccessWhenVMDontHaveBackupOffering() {
|
public void validateIfVmHaveBackupsTestSuccessWhenVMDontHaveBackupOffering() {
|
||||||
UserVmVO vm = Mockito.mock(UserVmVO.class);
|
UserVmVO vm = Mockito.mock(UserVmVO.class);
|
||||||
when(vm.getBackupOfferingId()).thenReturn(null);
|
when(vm.getBackupOfferingId()).thenReturn(null);
|
||||||
volumeApiServiceImpl.validateIfVmHasBackups(vm, true);
|
volumeApiServiceImpl.checkForBackups(vm, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@ -422,6 +422,11 @@ public class MockAccountManagerImpl extends ManagerBase implements Manager, Acco
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isResourceDomainAdmin(Long accountId) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isNormalUser(long accountId) {
|
public boolean isNormalUser(long accountId) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|||||||
@ -76,6 +76,7 @@ public class ConsoleProxy {
|
|||||||
static int httpCmdListenPort = 8001;
|
static int httpCmdListenPort = 8001;
|
||||||
static int reconnectMaxRetry = 5;
|
static int reconnectMaxRetry = 5;
|
||||||
static int readTimeoutSeconds = 90;
|
static int readTimeoutSeconds = 90;
|
||||||
|
public static int defaultBufferSize = 64 * 1024;
|
||||||
static int keyboardType = KEYBOARD_RAW;
|
static int keyboardType = KEYBOARD_RAW;
|
||||||
static String factoryClzName;
|
static String factoryClzName;
|
||||||
static boolean standaloneStart = false;
|
static boolean standaloneStart = false;
|
||||||
@ -160,6 +161,12 @@ public class ConsoleProxy {
|
|||||||
readTimeoutSeconds = Integer.parseInt(s);
|
readTimeoutSeconds = Integer.parseInt(s);
|
||||||
LOGGER.info("Setting readTimeoutSeconds=" + readTimeoutSeconds);
|
LOGGER.info("Setting readTimeoutSeconds=" + readTimeoutSeconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s = conf.getProperty("consoleproxy.defaultBufferSize");
|
||||||
|
if (s != null) {
|
||||||
|
defaultBufferSize = Integer.parseInt(s);
|
||||||
|
LOGGER.info("Setting defaultBufferSize=" + defaultBufferSize);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ConsoleProxyServerFactory getHttpServerFactory() {
|
public static ConsoleProxyServerFactory getHttpServerFactory() {
|
||||||
|
|||||||
@ -52,6 +52,9 @@ public class ConsoleProxyNoVncClient implements ConsoleProxyClient {
|
|||||||
private ConsoleProxyClientParam clientParam;
|
private ConsoleProxyClientParam clientParam;
|
||||||
private String sessionUuid;
|
private String sessionUuid;
|
||||||
|
|
||||||
|
private ByteBuffer readBuffer = null;
|
||||||
|
private int flushThreshold = -1;
|
||||||
|
|
||||||
public ConsoleProxyNoVncClient(Session session) {
|
public ConsoleProxyNoVncClient(Session session) {
|
||||||
this.session = session;
|
this.session = session;
|
||||||
}
|
}
|
||||||
@ -109,8 +112,9 @@ public class ConsoleProxyNoVncClient implements ConsoleProxyClient {
|
|||||||
connectClientToVNCServer(tunnelUrl, tunnelSession, websocketUrl);
|
connectClientToVNCServer(tunnelUrl, tunnelSession, websocketUrl);
|
||||||
authenticateToVNCServer(clientSourceIp);
|
authenticateToVNCServer(clientSourceIp);
|
||||||
|
|
||||||
int readBytes;
|
// Track consecutive iterations with no data and sleep accordingly. Only used for NIO socket connections.
|
||||||
byte[] b;
|
int consecutiveZeroReads = 0;
|
||||||
|
int sleepTime = 1;
|
||||||
while (connectionAlive) {
|
while (connectionAlive) {
|
||||||
logger.trace("Connection with client [{}] [IP: {}] is alive.", clientId, clientSourceIp);
|
logger.trace("Connection with client [{}] [IP: {}] is alive.", clientId, clientSourceIp);
|
||||||
if (client.isVncOverWebSocketConnection()) {
|
if (client.isVncOverWebSocketConnection()) {
|
||||||
@ -118,32 +122,55 @@ public class ConsoleProxyNoVncClient implements ConsoleProxyClient {
|
|||||||
updateFrontEndActivityTime();
|
updateFrontEndActivityTime();
|
||||||
}
|
}
|
||||||
connectionAlive = session.isOpen();
|
connectionAlive = session.isOpen();
|
||||||
|
sleepTime = 1;
|
||||||
} else if (client.isVncOverNioSocket()) {
|
} else if (client.isVncOverNioSocket()) {
|
||||||
byte[] bytesArr;
|
ByteBuffer buffer = getOrCreateReadBuffer();
|
||||||
int nextBytes = client.getNextBytes();
|
int bytesRead = client.readAvailableDataIntoBuffer(buffer, buffer.remaining());
|
||||||
bytesArr = new byte[nextBytes];
|
|
||||||
client.readBytes(bytesArr, nextBytes);
|
if (bytesRead > 0) {
|
||||||
logger.trace("Read [{}] bytes from client [{}].", nextBytes, clientId);
|
|
||||||
if (nextBytes > 0) {
|
|
||||||
session.getRemote().sendBytes(ByteBuffer.wrap(bytesArr));
|
|
||||||
updateFrontEndActivityTime();
|
updateFrontEndActivityTime();
|
||||||
|
consecutiveZeroReads = 0; // Reset counter on successful read
|
||||||
|
|
||||||
|
sleepTime = 0; // Still no sleep to catch any remaining data quickly
|
||||||
} else {
|
} else {
|
||||||
connectionAlive = session.isOpen();
|
connectionAlive = session.isOpen();
|
||||||
|
consecutiveZeroReads++;
|
||||||
|
// Use adaptive sleep time to prevent excessive busy waiting
|
||||||
|
sleepTime = Math.min(consecutiveZeroReads, 10); // Cap at 10ms max
|
||||||
|
}
|
||||||
|
|
||||||
|
final boolean bufferHasData = buffer.position() > 0;
|
||||||
|
if (bufferHasData && (bytesRead == 0 || buffer.remaining() <= flushThreshold)) {
|
||||||
|
buffer.flip();
|
||||||
|
logger.trace("Flushing buffer with [{}] bytes for client [{}]", buffer.remaining(), clientId);
|
||||||
|
session.getRemote().sendBytes(buffer);
|
||||||
|
buffer.compact();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
b = new byte[100];
|
ByteBuffer buffer = getOrCreateReadBuffer();
|
||||||
readBytes = client.read(b);
|
buffer.clear();
|
||||||
|
int readBytes = client.read(buffer.array());
|
||||||
logger.trace("Read [{}] bytes from client [{}].", readBytes, clientId);
|
logger.trace("Read [{}] bytes from client [{}].", readBytes, clientId);
|
||||||
if (readBytes == -1 || (readBytes > 0 && !sendReadBytesToNoVNC(b, readBytes))) {
|
if (readBytes > 0) {
|
||||||
|
// Update buffer position to reflect bytes read and flip for reading
|
||||||
|
buffer.position(readBytes);
|
||||||
|
buffer.flip();
|
||||||
|
if (!sendReadBytesToNoVNC(buffer)) {
|
||||||
connectionAlive = false;
|
connectionAlive = false;
|
||||||
}
|
}
|
||||||
|
} else if (readBytes == -1) {
|
||||||
|
connectionAlive = false;
|
||||||
}
|
}
|
||||||
|
sleepTime = 1;
|
||||||
|
}
|
||||||
|
if (sleepTime > 0 && connectionAlive) {
|
||||||
try {
|
try {
|
||||||
Thread.sleep(1);
|
Thread.sleep(sleepTime);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
logger.error("Error on sleep for vnc sessions", e);
|
logger.error("Error on sleep for vnc sessions", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
logger.info("Connection with client [{}] [IP: {}] is dead.", clientId, clientSourceIp);
|
logger.info("Connection with client [{}] [IP: {}] is dead.", clientId, clientSourceIp);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.error("Error on VNC client", e);
|
logger.error("Error on VNC client", e);
|
||||||
@ -154,9 +181,10 @@ public class ConsoleProxyNoVncClient implements ConsoleProxyClient {
|
|||||||
worker.start();
|
worker.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean sendReadBytesToNoVNC(byte[] b, int readBytes) {
|
private boolean sendReadBytesToNoVNC(ByteBuffer buffer) {
|
||||||
try {
|
try {
|
||||||
session.getRemote().sendBytes(ByteBuffer.wrap(b, 0, readBytes));
|
// Buffer is already prepared for reading by flip()
|
||||||
|
session.getRemote().sendBytes(buffer);
|
||||||
updateFrontEndActivityTime();
|
updateFrontEndActivityTime();
|
||||||
} catch (WebSocketException | IOException e) {
|
} catch (WebSocketException | IOException e) {
|
||||||
logger.error("VNC server connection exception.", e);
|
logger.error("VNC server connection exception.", e);
|
||||||
@ -316,9 +344,29 @@ public class ConsoleProxyNoVncClient implements ConsoleProxyClient {
|
|||||||
this.clientParam = param;
|
this.clientParam = param;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ByteBuffer getOrCreateReadBuffer() {
|
||||||
|
if (readBuffer == null) {
|
||||||
|
readBuffer = ByteBuffer.allocate(ConsoleProxy.defaultBufferSize);
|
||||||
|
logger.debug("Allocated {} KB read buffer for client [{}]", ConsoleProxy.defaultBufferSize / 1024 , clientId);
|
||||||
|
|
||||||
|
// Only apply batching logic for NIO TLS connections to work around 16KB record limitation
|
||||||
|
// For non-TLS or non-NIO connections, use immediate flush for better responsiveness
|
||||||
|
if (client != null && client.isVncOverNioSocket() && client.isTLSConnectionEstablished()) {
|
||||||
|
flushThreshold = Math.min(ConsoleProxy.defaultBufferSize / 4, 2048);
|
||||||
|
logger.debug("NIO TLS connection detected - using batching with threshold {} for client [{}]", flushThreshold, clientId);
|
||||||
|
} else {
|
||||||
|
flushThreshold = ConsoleProxy.defaultBufferSize + 1; // Always flush immediately
|
||||||
|
logger.debug("Non-TLS or non-NIO connection - using immediate flush for client [{}]", clientId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return readBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void closeClient() {
|
public void closeClient() {
|
||||||
this.connectionAlive = false;
|
this.connectionAlive = false;
|
||||||
|
// Clear buffer reference to allow GC when client disconnects
|
||||||
|
this.readBuffer = null;
|
||||||
ConsoleProxy.removeViewer(this);
|
ConsoleProxy.removeViewer(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -502,18 +502,14 @@ public class NoVncClient {
|
|||||||
return nioSocketConnection.readServerInit();
|
return nioSocketConnection.readServerInit();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getNextBytes() {
|
public int readAvailableDataIntoBuffer(ByteBuffer buffer, int maxSize) {
|
||||||
return nioSocketConnection.readNextBytes();
|
return nioSocketConnection.readAvailableDataIntoBuffer(buffer, maxSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isTLSConnectionEstablished() {
|
public boolean isTLSConnectionEstablished() {
|
||||||
return nioSocketConnection.isTLSConnection();
|
return nioSocketConnection.isTLSConnection();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void readBytes(byte[] arr, int len) {
|
|
||||||
nioSocketConnection.readNextByteArray(arr, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void processHandshakeSecurityType(int secType, String vmPassword, String host, int port) {
|
public void processHandshakeSecurityType(int secType, String vmPassword, String host, int port) {
|
||||||
waitForNoVNCReply();
|
waitForNoVNCReply();
|
||||||
|
|
||||||
|
|||||||
@ -41,6 +41,8 @@ public class NioSocket {
|
|||||||
socketChannel = SocketChannel.open();
|
socketChannel = SocketChannel.open();
|
||||||
socketChannel.configureBlocking(false);
|
socketChannel.configureBlocking(false);
|
||||||
socketChannel.socket().setSoTimeout(5000);
|
socketChannel.socket().setSoTimeout(5000);
|
||||||
|
socketChannel.socket().setKeepAlive(true);
|
||||||
|
socketChannel.socket().setTcpNoDelay(true);
|
||||||
writeSelector = Selector.open();
|
writeSelector = Selector.open();
|
||||||
readSelector = Selector.open();
|
readSelector = Selector.open();
|
||||||
socketChannel.register(writeSelector, SelectionKey.OP_WRITE);
|
socketChannel.register(writeSelector, SelectionKey.OP_WRITE);
|
||||||
@ -77,7 +79,6 @@ public class NioSocket {
|
|||||||
socketChannel.register(selector, SelectionKey.OP_CONNECT);
|
socketChannel.register(selector, SelectionKey.OP_CONNECT);
|
||||||
|
|
||||||
waitForSocketSelectorConnected(selector);
|
waitForSocketSelectorConnected(selector);
|
||||||
socketChannel.socket().setTcpNoDelay(false);
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.error(String.format("Error creating NioSocket to %s:%s: %s", host, port, e.getMessage()), e);
|
logger.error(String.format("Error creating NioSocket to %s:%s: %s", host, port, e.getMessage()), e);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,8 +29,7 @@ public interface NioSocketHandler {
|
|||||||
void readBytes(ByteBuffer data, int length);
|
void readBytes(ByteBuffer data, int length);
|
||||||
String readString();
|
String readString();
|
||||||
byte[] readServerInit();
|
byte[] readServerInit();
|
||||||
int readNextBytes();
|
int readAvailableDataIntoBuffer(ByteBuffer buffer, int maxSize);
|
||||||
void readNextByteArray(byte[] arr, int len);
|
|
||||||
|
|
||||||
// Write operations
|
// Write operations
|
||||||
void writeUnsignedInteger(int sizeInBits, int value);
|
void writeUnsignedInteger(int sizeInBits, int value);
|
||||||
|
|||||||
@ -17,6 +17,7 @@
|
|||||||
package com.cloud.consoleproxy.vnc.network;
|
package com.cloud.consoleproxy.vnc.network;
|
||||||
|
|
||||||
|
|
||||||
|
import com.cloud.consoleproxy.ConsoleProxy;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
@ -28,13 +29,11 @@ public class NioSocketHandlerImpl implements NioSocketHandler {
|
|||||||
private NioSocketOutputStream outputStream;
|
private NioSocketOutputStream outputStream;
|
||||||
private boolean isTLS = false;
|
private boolean isTLS = false;
|
||||||
|
|
||||||
private static final int DEFAULT_BUF_SIZE = 16384;
|
|
||||||
|
|
||||||
protected Logger logger = LogManager.getLogger(getClass());
|
protected Logger logger = LogManager.getLogger(getClass());
|
||||||
|
|
||||||
public NioSocketHandlerImpl(NioSocket socket) {
|
public NioSocketHandlerImpl(NioSocket socket) {
|
||||||
this.inputStream = new NioSocketInputStream(DEFAULT_BUF_SIZE, socket);
|
this.inputStream = new NioSocketInputStream(ConsoleProxy.defaultBufferSize, socket);
|
||||||
this.outputStream = new NioSocketOutputStream(DEFAULT_BUF_SIZE, socket);
|
this.outputStream = new NioSocketOutputStream(ConsoleProxy.defaultBufferSize, socket);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -97,13 +96,8 @@ public class NioSocketHandlerImpl implements NioSocketHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int readNextBytes() {
|
public int readAvailableDataIntoBuffer(ByteBuffer buffer, int maxSize) {
|
||||||
return inputStream.getNextBytes();
|
return inputStream.readAvailableDataIntoBuffer(buffer, maxSize);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void readNextByteArray(byte[] arr, int len) {
|
|
||||||
inputStream.readNextByteArrayFromReadBuffer(arr, len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -175,28 +175,38 @@ public class NioSocketInputStream extends NioSocketStream {
|
|||||||
return ArrayUtils.addAll(ret, (byte) 0, (byte) 0, (byte) 0);
|
return ArrayUtils.addAll(ret, (byte) 0, (byte) 0, (byte) 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int getNextBytes() {
|
/**
|
||||||
int size = 200;
|
* This method checks what data is immediately available and returns a reasonable amount.
|
||||||
while (size > 0) {
|
*
|
||||||
if (checkForSizeWithoutWait(size)) {
|
* @param maxSize Maximum number of bytes to attempt to read
|
||||||
break;
|
* @return Number of bytes available to read (0 if none available)
|
||||||
}
|
*/
|
||||||
size--;
|
protected int getAvailableBytes(int maxSize) {
|
||||||
}
|
// First check if we have data already in our buffer
|
||||||
return size;
|
int bufferedData = endPosition - currentPosition;
|
||||||
|
if (bufferedData > 0) {
|
||||||
|
return Math.min(bufferedData, maxSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void readNextByteArrayFromReadBuffer(byte[] arr, int len) {
|
// Try to read more data with non-blocking call
|
||||||
copyBytesFromReadBuffer(len, arr);
|
// This determines how much data is available
|
||||||
|
return getReadBytesAvailableToFitSize(1, maxSize, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void copyBytesFromReadBuffer(int length, byte[] arr) {
|
/**
|
||||||
int ptr = 0;
|
* Read available data directly into a ByteBuffer.
|
||||||
while (length > 0) {
|
*
|
||||||
int n = getReadBytesAvailableToFitSize(1, length, true);
|
* @param buffer ByteBuffer to read data into
|
||||||
readBytes(ByteBuffer.wrap(arr, ptr, n), n);
|
* @param maxSize Maximum number of bytes to read
|
||||||
ptr += n;
|
* @return Number of bytes actually read (0 if none available)
|
||||||
length -= n;
|
*/
|
||||||
|
protected int readAvailableDataIntoBuffer(ByteBuffer buffer, int maxSize) {
|
||||||
|
// Get the amount of data available to read
|
||||||
|
int available = getAvailableBytes(maxSize);
|
||||||
|
if (available > 0) {
|
||||||
|
// Read directly into the ByteBuffer
|
||||||
|
readBytes(buffer, available);
|
||||||
}
|
}
|
||||||
|
return available;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,6 +16,8 @@
|
|||||||
// under the License.
|
// under the License.
|
||||||
package com.cloud.consoleproxy.vnc.network;
|
package com.cloud.consoleproxy.vnc.network;
|
||||||
|
|
||||||
|
import com.cloud.consoleproxy.ConsoleProxy;
|
||||||
|
|
||||||
import javax.net.ssl.SSLEngine;
|
import javax.net.ssl.SSLEngine;
|
||||||
import javax.net.ssl.SSLEngineResult;
|
import javax.net.ssl.SSLEngineResult;
|
||||||
import javax.net.ssl.SSLException;
|
import javax.net.ssl.SSLException;
|
||||||
@ -43,9 +45,9 @@ public class NioSocketSSLEngineManager {
|
|||||||
|
|
||||||
executor = Executors.newSingleThreadExecutor();
|
executor = Executors.newSingleThreadExecutor();
|
||||||
|
|
||||||
int pktBufSize = engine.getSession().getPacketBufferSize();
|
int networkBufSize = Math.max(engine.getSession().getPacketBufferSize(), ConsoleProxy.defaultBufferSize);
|
||||||
myNetData = ByteBuffer.allocate(pktBufSize);
|
myNetData = ByteBuffer.allocate(networkBufSize);
|
||||||
peerNetData = ByteBuffer.allocate(pktBufSize);
|
peerNetData = ByteBuffer.allocate(networkBufSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handshakeNeedUnwrap(ByteBuffer peerAppData) throws SSLException {
|
private void handshakeNeedUnwrap(ByteBuffer peerAppData) throws SSLException {
|
||||||
@ -155,22 +157,25 @@ public class NioSocketSSLEngineManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int write(ByteBuffer data) throws IOException {
|
public int write(ByteBuffer data) throws IOException {
|
||||||
int n = 0;
|
int totalBytesConsumed = 0;
|
||||||
|
int sessionAppBufSize = engine.getSession().getApplicationBufferSize();
|
||||||
|
boolean shouldBatch = ConsoleProxy.defaultBufferSize > sessionAppBufSize;
|
||||||
|
|
||||||
while (data.hasRemaining()) {
|
while (data.hasRemaining()) {
|
||||||
SSLEngineResult result = engine.wrap(data, myNetData);
|
SSLEngineResult result = engine.wrap(data, myNetData);
|
||||||
n += result.bytesConsumed();
|
totalBytesConsumed += result.bytesConsumed();
|
||||||
switch (result.getStatus()) {
|
switch (result.getStatus()) {
|
||||||
case OK:
|
case OK:
|
||||||
myNetData.flip();
|
// Flush immediately if: batching is disabled, small data, or last chunk
|
||||||
outputStream.writeBytes(myNetData, myNetData.remaining());
|
if (!shouldBatch || result.bytesConsumed() < sessionAppBufSize || !data.hasRemaining()) {
|
||||||
outputStream.flushWriteBuffer();
|
flush();
|
||||||
myNetData.compact();
|
}
|
||||||
|
// Otherwise accumulate for batching (large chunk with more data coming)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BUFFER_OVERFLOW:
|
case BUFFER_OVERFLOW:
|
||||||
myNetData.flip();
|
// Flush when buffer is full
|
||||||
outputStream.writeBytes(myNetData, myNetData.remaining());
|
flush();
|
||||||
myNetData.compact();
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CLOSED:
|
case CLOSED:
|
||||||
@ -181,7 +186,16 @@ public class NioSocketSSLEngineManager {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return n;
|
return totalBytesConsumed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void flush() {
|
||||||
|
if (myNetData.position() > 0) {
|
||||||
|
myNetData.flip();
|
||||||
|
outputStream.writeBytes(myNetData, myNetData.remaining());
|
||||||
|
outputStream.flushWriteBuffer();
|
||||||
|
myNetData.compact();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public SSLSession getSession() {
|
public SSLSession getSession() {
|
||||||
|
|||||||
@ -16,6 +16,7 @@
|
|||||||
// under the License.
|
// under the License.
|
||||||
package com.cloud.consoleproxy.vnc.network;
|
package com.cloud.consoleproxy.vnc.network;
|
||||||
|
|
||||||
|
import com.cloud.consoleproxy.ConsoleProxy;
|
||||||
import com.cloud.utils.exception.CloudRuntimeException;
|
import com.cloud.utils.exception.CloudRuntimeException;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -26,7 +27,7 @@ public class NioSocketTLSInputStream extends NioSocketInputStream {
|
|||||||
private final NioSocketSSLEngineManager sslEngineManager;
|
private final NioSocketSSLEngineManager sslEngineManager;
|
||||||
|
|
||||||
public NioSocketTLSInputStream(NioSocketSSLEngineManager sslEngineManager, NioSocket socket) {
|
public NioSocketTLSInputStream(NioSocketSSLEngineManager sslEngineManager, NioSocket socket) {
|
||||||
super(sslEngineManager.getSession().getApplicationBufferSize(), socket);
|
super(ConsoleProxy.defaultBufferSize, socket);
|
||||||
this.sslEngineManager = sslEngineManager;
|
this.sslEngineManager = sslEngineManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -16,6 +16,8 @@
|
|||||||
// under the License.
|
// under the License.
|
||||||
package com.cloud.consoleproxy.vnc.network;
|
package com.cloud.consoleproxy.vnc.network;
|
||||||
|
|
||||||
|
import com.cloud.consoleproxy.ConsoleProxy;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
@ -24,7 +26,7 @@ public class NioSocketTLSOutputStream extends NioSocketOutputStream {
|
|||||||
private final NioSocketSSLEngineManager sslEngineManager;
|
private final NioSocketSSLEngineManager sslEngineManager;
|
||||||
|
|
||||||
public NioSocketTLSOutputStream(NioSocketSSLEngineManager sslEngineManager, NioSocket socket) {
|
public NioSocketTLSOutputStream(NioSocketSSLEngineManager sslEngineManager, NioSocket socket) {
|
||||||
super(sslEngineManager.getSession().getApplicationBufferSize(), socket);
|
super(ConsoleProxy.defaultBufferSize, socket);
|
||||||
this.sslEngineManager = sslEngineManager;
|
this.sslEngineManager = sslEngineManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,6 +40,7 @@ public class NioSocketTLSOutputStream extends NioSocketOutputStream {
|
|||||||
}
|
}
|
||||||
|
|
||||||
currentPosition = start;
|
currentPosition = start;
|
||||||
|
sslEngineManager.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int writeThroughSSLEngineManager(byte[] data, int startPos, int length) {
|
protected int writeThroughSSLEngineManager(byte[] data, int startPos, int length) {
|
||||||
|
|||||||
@ -268,9 +268,6 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar
|
|||||||
|
|
||||||
private final GlobalLock _allocLock = GlobalLock.getInternLock(getAllocLockName());
|
private final GlobalLock _allocLock = GlobalLock.getInternLock(getAllocLockName());
|
||||||
|
|
||||||
static final ConfigKey<String> NTPServerConfig = new ConfigKey<String>(String.class, "ntp.server.list", "Advanced", null,
|
|
||||||
"Comma separated list of NTP servers to configure in Secondary storage VM", true, ConfigKey.Scope.Global, null, null, null, null, null, ConfigKey.Kind.CSV, null);
|
|
||||||
|
|
||||||
static final ConfigKey<Integer> MaxNumberOfSsvmsForMigration = new ConfigKey<Integer>("Advanced", Integer.class, "max.ssvm.count", "5",
|
static final ConfigKey<Integer> MaxNumberOfSsvmsForMigration = new ConfigKey<Integer>("Advanced", Integer.class, "max.ssvm.count", "5",
|
||||||
"Number of additional SSVMs to handle migration of data objects concurrently", true, ConfigKey.Scope.Global);
|
"Number of additional SSVMs to handle migration of data objects concurrently", true, ConfigKey.Scope.Global);
|
||||||
|
|
||||||
@ -1178,7 +1175,7 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar
|
|||||||
buf.append(" vmpassword=").append(_configDao.getValue("system.vm.password"));
|
buf.append(" vmpassword=").append(_configDao.getValue("system.vm.password"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NTPServerConfig.value() != null) {
|
if (StringUtils.isNotEmpty(NTPServerConfig.value())) {
|
||||||
buf.append(" ntpserverlist=").append(NTPServerConfig.value().replaceAll("\\s+",""));
|
buf.append(" ntpserverlist=").append(NTPServerConfig.value().replaceAll("\\s+",""));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -27,6 +27,7 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import io.netty.util.IllegalReferenceCountException;
|
||||||
import org.apache.cloudstack.storage.template.UploadEntity;
|
import org.apache.cloudstack.storage.template.UploadEntity;
|
||||||
import org.apache.cloudstack.utils.imagestore.ImageStoreUtil;
|
import org.apache.cloudstack.utils.imagestore.ImageStoreUtil;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
@ -230,9 +231,16 @@ public class HttpUploadServerHandler extends SimpleChannelInboundHandler<HttpObj
|
|||||||
private void reset() {
|
private void reset() {
|
||||||
request = null;
|
request = null;
|
||||||
// destroy the decoder to release all resources
|
// destroy the decoder to release all resources
|
||||||
|
if (decoder != null) {
|
||||||
|
try {
|
||||||
decoder.destroy();
|
decoder.destroy();
|
||||||
|
} catch (IllegalReferenceCountException e) {
|
||||||
|
logger.warn("Decoder already destroyed", e);
|
||||||
|
}
|
||||||
|
|
||||||
decoder = null;
|
decoder = null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private HttpResponseStatus readFileUploadData() throws IOException {
|
private HttpResponseStatus readFileUploadData() throws IOException {
|
||||||
while (decoder.hasNext()) {
|
while (decoder.hasNext()) {
|
||||||
|
|||||||
@ -21,3 +21,4 @@ consoleproxy.httpCmdListenPort=8001
|
|||||||
consoleproxy.jarDir=./applet/
|
consoleproxy.jarDir=./applet/
|
||||||
consoleproxy.viewerLinger=180
|
consoleproxy.viewerLinger=180
|
||||||
consoleproxy.reconnectMaxRetry=5
|
consoleproxy.reconnectMaxRetry=5
|
||||||
|
consoleproxy.defaultBufferSize=65536
|
||||||
|
|||||||
@ -683,7 +683,7 @@ getPublicIp() {
|
|||||||
|
|
||||||
setup_ntp() {
|
setup_ntp() {
|
||||||
log_it "Setting up NTP"
|
log_it "Setting up NTP"
|
||||||
NTP_CONF_FILE="/etc/ntp.conf"
|
NTP_CONF_FILE="/etc/ntpsec/ntp.conf"
|
||||||
if [ -f $NTP_CONF_FILE ]
|
if [ -f $NTP_CONF_FILE ]
|
||||||
then
|
then
|
||||||
IFS=',' read -a server_list <<< "$NTP_SERVER_LIST"
|
IFS=',' read -a server_list <<< "$NTP_SERVER_LIST"
|
||||||
@ -692,9 +692,9 @@ setup_ntp() {
|
|||||||
do
|
do
|
||||||
server=$(echo ${server_list[iterator]} | tr -d '\r')
|
server=$(echo ${server_list[iterator]} | tr -d '\r')
|
||||||
PATTERN="server $server"
|
PATTERN="server $server"
|
||||||
sed -i "0,/^#server/s//$PATTERN\n#server/" $NTP_CONF_FILE
|
sed -i "0,/^# server/s//$PATTERN\n# server/" $NTP_CONF_FILE
|
||||||
done
|
done
|
||||||
systemctl enable ntp
|
systemctl enable --now --no-block ntp
|
||||||
else
|
else
|
||||||
log_it "NTP configuration file not found"
|
log_it "NTP configuration file not found"
|
||||||
fi
|
fi
|
||||||
|
|||||||
@ -40,6 +40,10 @@ setup_console_proxy() {
|
|||||||
disable_rpfilter
|
disable_rpfilter
|
||||||
enable_fwding 0
|
enable_fwding 0
|
||||||
enable_irqbalance 0
|
enable_irqbalance 0
|
||||||
|
if [[ -n "$NTP_SERVER_LIST" ]]; then
|
||||||
|
setup_ntp
|
||||||
|
systemctl restart ntp
|
||||||
|
fi
|
||||||
rm -f /etc/logrotate.d/cloud
|
rm -f /etc/logrotate.d/cloud
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -82,6 +82,7 @@ HTTP
|
|||||||
enable_fwding 0
|
enable_fwding 0
|
||||||
enable_irqbalance 0
|
enable_irqbalance 0
|
||||||
setup_ntp
|
setup_ntp
|
||||||
|
systemctl restart ntp
|
||||||
|
|
||||||
rm -f /etc/logrotate.d/cloud
|
rm -f /etc/logrotate.d/cloud
|
||||||
}
|
}
|
||||||
|
|||||||
@ -953,9 +953,72 @@ class TestLinstorVolumes(cloudstackTestCase):
|
|||||||
|
|
||||||
snapshot.delete(self.apiClient)
|
snapshot.delete(self.apiClient)
|
||||||
|
|
||||||
|
@attr(tags=['basic'], required_hardware=False)
|
||||||
|
def test_10_create_template_from_snapshot(self):
|
||||||
|
"""
|
||||||
|
Create a template from a snapshot and start an instance from it
|
||||||
|
"""
|
||||||
|
self.virtual_machine.stop(self.apiClient)
|
||||||
|
|
||||||
|
volume = list_volumes(
|
||||||
|
self.apiClient,
|
||||||
|
virtualmachineid = self.virtual_machine.id,
|
||||||
|
type = "ROOT",
|
||||||
|
listall = True,
|
||||||
|
)
|
||||||
|
snapshot = Snapshot.create(
|
||||||
|
self.apiClient,
|
||||||
|
volume_id=volume[0].id,
|
||||||
|
account=self.account.name,
|
||||||
|
domainid=self.domain.id,
|
||||||
|
)
|
||||||
|
self.cleanup.append(snapshot)
|
||||||
|
|
||||||
|
self.assertIsNotNone(snapshot, "Could not create snapshot")
|
||||||
|
|
||||||
|
services = {
|
||||||
|
"displaytext": "IntegrationTestTemplate",
|
||||||
|
"name": "int-test-template",
|
||||||
|
"ostypeid": self.template.ostypeid,
|
||||||
|
"ispublic": "true"
|
||||||
|
}
|
||||||
|
|
||||||
|
custom_template = Template.create_from_snapshot(
|
||||||
|
self.apiClient,
|
||||||
|
snapshot,
|
||||||
|
services,
|
||||||
|
)
|
||||||
|
self.cleanup.append(custom_template)
|
||||||
|
|
||||||
|
# create VM from custom template
|
||||||
|
test_virtual_machine = VirtualMachine.create(
|
||||||
|
self.apiClient,
|
||||||
|
self.testdata[TestData.virtualMachine2],
|
||||||
|
accountid=self.account.name,
|
||||||
|
zoneid=self.zone.id,
|
||||||
|
serviceofferingid=self.compute_offering.id,
|
||||||
|
templateid=custom_template.id,
|
||||||
|
domainid=self.domain.id,
|
||||||
|
startvm=False,
|
||||||
|
mode='basic',
|
||||||
|
)
|
||||||
|
self.cleanup.append(test_virtual_machine)
|
||||||
|
|
||||||
|
TestLinstorVolumes._start_vm(test_virtual_machine)
|
||||||
|
|
||||||
|
test_virtual_machine.stop(self.apiClient)
|
||||||
|
|
||||||
|
test_virtual_machine.delete(self.apiClient, True)
|
||||||
|
self.cleanup.remove(test_virtual_machine)
|
||||||
|
|
||||||
|
custom_template.delete(self.apiClient)
|
||||||
|
self.cleanup.remove(custom_template)
|
||||||
|
snapshot.delete(self.apiClient)
|
||||||
|
self.cleanup.remove(snapshot)
|
||||||
|
|
||||||
|
|
||||||
@attr(tags=['advanced', 'migration'], required_hardware=False)
|
@attr(tags=['advanced', 'migration'], required_hardware=False)
|
||||||
def test_10_migrate_volume_to_same_instance_pool(self):
|
def test_11_migrate_volume_to_same_instance_pool(self):
|
||||||
"""Migrate volume to the same instance pool"""
|
"""Migrate volume to the same instance pool"""
|
||||||
|
|
||||||
if not self.testdata[TestData.migrationTests]:
|
if not self.testdata[TestData.migrationTests]:
|
||||||
@ -1088,7 +1151,7 @@ class TestLinstorVolumes(cloudstackTestCase):
|
|||||||
test_virtual_machine.delete(self.apiClient, True)
|
test_virtual_machine.delete(self.apiClient, True)
|
||||||
|
|
||||||
@attr(tags=['advanced', 'migration'], required_hardware=False)
|
@attr(tags=['advanced', 'migration'], required_hardware=False)
|
||||||
def test_11_migrate_volume_to_distinct_instance_pool(self):
|
def test_12_migrate_volume_to_distinct_instance_pool(self):
|
||||||
"""Migrate volume to distinct instance pool"""
|
"""Migrate volume to distinct instance pool"""
|
||||||
|
|
||||||
if not self.testdata[TestData.migrationTests]:
|
if not self.testdata[TestData.migrationTests]:
|
||||||
@ -1221,7 +1284,7 @@ class TestLinstorVolumes(cloudstackTestCase):
|
|||||||
test_virtual_machine.delete(self.apiClient, True)
|
test_virtual_machine.delete(self.apiClient, True)
|
||||||
|
|
||||||
@attr(tags=["basic"], required_hardware=False)
|
@attr(tags=["basic"], required_hardware=False)
|
||||||
def test_12_create_vm_snapshots(self):
|
def test_13_create_vm_snapshots(self):
|
||||||
"""Test to create VM snapshots
|
"""Test to create VM snapshots
|
||||||
"""
|
"""
|
||||||
vm = TestLinstorVolumes._start_vm(self.virtual_machine)
|
vm = TestLinstorVolumes._start_vm(self.virtual_machine)
|
||||||
@ -1251,7 +1314,7 @@ class TestLinstorVolumes(cloudstackTestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
@attr(tags=["basic"], required_hardware=False)
|
@attr(tags=["basic"], required_hardware=False)
|
||||||
def test_13_revert_vm_snapshots(self):
|
def test_14_revert_vm_snapshots(self):
|
||||||
"""Test to revert VM snapshots
|
"""Test to revert VM snapshots
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -1313,7 +1376,7 @@ class TestLinstorVolumes(cloudstackTestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
@attr(tags=["basic"], required_hardware=False)
|
@attr(tags=["basic"], required_hardware=False)
|
||||||
def test_14_delete_vm_snapshots(self):
|
def test_15_delete_vm_snapshots(self):
|
||||||
"""Test to delete vm snapshots
|
"""Test to delete vm snapshots
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|||||||
@ -14,12 +14,12 @@
|
|||||||
"label.account.specific": "Account-Specific",
|
"label.account.specific": "Account-Specific",
|
||||||
"label.accounts": "Accounts",
|
"label.accounts": "Accounts",
|
||||||
"label.accounttype": "Account Type",
|
"label.accounttype": "Account Type",
|
||||||
"label.acl.export": "Export ACLs",
|
"label.acl.export": "Export ACL rules",
|
||||||
"label.acl.id": "ACL ID",
|
"label.acl.id": "ACL ID",
|
||||||
"label.acl.list.rules": "ACL List Rules",
|
"label.acl.rules": "ACL Rules",
|
||||||
"label.acl.reason.description": "Enter the reason behind an ACL rule.",
|
"label.acl.reason.description": "Enter the reason behind an ACL rule.",
|
||||||
"label.aclid": "ACL",
|
"label.aclid": "ACL",
|
||||||
"label.aclname": "ACL Name",
|
"label.acl.rule.name": "ACL Name",
|
||||||
"label.acquire.new.ip": "Acquire New IP",
|
"label.acquire.new.ip": "Acquire New IP",
|
||||||
"label.acquire.new.secondary.ip": "Acquire new secondary IP",
|
"label.acquire.new.secondary.ip": "Acquire new secondary IP",
|
||||||
"label.action": "Action",
|
"label.action": "Action",
|
||||||
@ -119,8 +119,8 @@
|
|||||||
"label.activeviewersessions": "Active Sessions",
|
"label.activeviewersessions": "Active Sessions",
|
||||||
"label.add": "Add",
|
"label.add": "Add",
|
||||||
"label.add.account": "Add Account",
|
"label.add.account": "Add Account",
|
||||||
"label.add.acl": "\u0625\u0636\u0627\u0641\u0629 ACL",
|
"label.add.acl.rule": "\u0625\u0636\u0627\u0641\u0629 ACL",
|
||||||
"label.add.acl.list": "Add ACL List",
|
"label.add.acl": "Add ACL",
|
||||||
"label.add.affinity.group": "Add new affinity group",
|
"label.add.affinity.group": "Add new affinity group",
|
||||||
"label.add.baremetal.dhcp.device": "Add Baremetal DHCP Device",
|
"label.add.baremetal.dhcp.device": "Add Baremetal DHCP Device",
|
||||||
"label.add.bigswitchbcf.device": "Add BigSwitch BCF Controller",
|
"label.add.bigswitchbcf.device": "Add BigSwitch BCF Controller",
|
||||||
@ -142,12 +142,12 @@
|
|||||||
"label.add.ip.range": "Add IP Range",
|
"label.add.ip.range": "Add IP Range",
|
||||||
"label.add.isolated.network": "Add Isolated Network",
|
"label.add.isolated.network": "Add Isolated Network",
|
||||||
"label.add.ldap.account": "Add LDAP account",
|
"label.add.ldap.account": "Add LDAP account",
|
||||||
"label.add.list.name": "ACL List Name",
|
"label.add.acl.name": "ACL Name",
|
||||||
"label.add.more": "Add More",
|
"label.add.more": "Add More",
|
||||||
"label.add.netscaler.device": "Add Netscaler device",
|
"label.add.netscaler.device": "Add Netscaler device",
|
||||||
"label.add.network": "Add Network",
|
"label.add.network": "Add Network",
|
||||||
"label.add.network.acl": "\u0625\u0636\u0627\u0641\u0629 \u0634\u0628\u0643\u0629 ACL",
|
"label.add.network.acl": "\u0625\u0636\u0627\u0641\u0629 \u0634\u0628\u0643\u0629 ACL",
|
||||||
"label.add.network.acl.list": "Add Network ACL List",
|
"label.add.network.acl": "Add Network ACL",
|
||||||
"label.add.network.offering": "Add network offering",
|
"label.add.network.offering": "Add network offering",
|
||||||
"label.add.new.gateway": "\u0623\u0636\u0641 \u0628\u0648\u0627\u0628\u0629 \u062c\u062f\u064a\u062f\u0629",
|
"label.add.new.gateway": "\u0623\u0636\u0641 \u0628\u0648\u0627\u0628\u0629 \u062c\u062f\u064a\u062f\u0629",
|
||||||
"label.add.new.tier": "\u0625\u0636\u0627\u0641\u0629 \u0637\u0628\u0642\u0629 \u062c\u062f\u064a\u062f\u0629",
|
"label.add.new.tier": "\u0625\u0636\u0627\u0641\u0629 \u0637\u0628\u0642\u0629 \u062c\u062f\u064a\u062f\u0629",
|
||||||
@ -334,7 +334,7 @@
|
|||||||
"label.default.use": "Default Use",
|
"label.default.use": "Default Use",
|
||||||
"label.default.view": "\u0637\u0631\u064a\u0642\u0629 \u0627\u0644\u0639\u0631\u0636 \u0627\u0644\u0627\u0641\u062a\u0631\u0627\u0636\u064a\u0629",
|
"label.default.view": "\u0637\u0631\u064a\u0642\u0629 \u0627\u0644\u0639\u0631\u0636 \u0627\u0644\u0627\u0641\u062a\u0631\u0627\u0636\u064a\u0629",
|
||||||
"label.delete": "Delete",
|
"label.delete": "Delete",
|
||||||
"label.delete.acl.list": "Delete ACL List",
|
"label.delete.acl": "Delete ACL",
|
||||||
"label.delete.affinity.group": "Delete Affinity Group",
|
"label.delete.affinity.group": "Delete Affinity Group",
|
||||||
"label.delete.alerts": "Delete alerts",
|
"label.delete.alerts": "Delete alerts",
|
||||||
"label.delete.bigswitchbcf": "Remove BigSwitch BCF Controller",
|
"label.delete.bigswitchbcf": "Remove BigSwitch BCF Controller",
|
||||||
@ -419,7 +419,7 @@
|
|||||||
"label.dpd": "\u0643\u0634\u0641 \u0627\u0644\u0642\u0631\u064a\u0646 \u0627\u0644\u0645\u0641\u0642\u0648\u062f",
|
"label.dpd": "\u0643\u0634\u0641 \u0627\u0644\u0642\u0631\u064a\u0646 \u0627\u0644\u0645\u0641\u0642\u0648\u062f",
|
||||||
"label.driver": "Driver",
|
"label.driver": "Driver",
|
||||||
"label.edit": "Edit",
|
"label.edit": "Edit",
|
||||||
"label.edit.acl.list": "Edit ACL List",
|
"label.edit.acl": "Edit ACL",
|
||||||
"label.edit.acl.rule": "Edit ACL rule",
|
"label.edit.acl.rule": "Edit ACL rule",
|
||||||
"label.edit.project.details": "\u0627\u0636\u0627\u0641\u0629 \u062a\u0641\u0627\u0635\u064a\u0644 \u0627\u0644\u0645\u0634\u0631\u0648\u0639",
|
"label.edit.project.details": "\u0627\u0636\u0627\u0641\u0629 \u062a\u0641\u0627\u0635\u064a\u0644 \u0627\u0644\u0645\u0634\u0631\u0648\u0639",
|
||||||
"label.edit.role": "Edit Role",
|
"label.edit.role": "Edit Role",
|
||||||
@ -924,7 +924,6 @@
|
|||||||
"label.remove.vpc.offering": "Remove VPC offering",
|
"label.remove.vpc.offering": "Remove VPC offering",
|
||||||
"label.removing": "Removing",
|
"label.removing": "Removing",
|
||||||
"label.replace.acl": "Replace ACL",
|
"label.replace.acl": "Replace ACL",
|
||||||
"label.replace.acl.list": "Replace ACL List",
|
|
||||||
"label.required": "Required",
|
"label.required": "Required",
|
||||||
"label.requireshvm": "HVM",
|
"label.requireshvm": "HVM",
|
||||||
"label.requiresupgrade": "Requires Upgrade",
|
"label.requiresupgrade": "Requires Upgrade",
|
||||||
@ -1150,8 +1149,7 @@
|
|||||||
"label.usehttps": "\u0627\u0633\u062a\u062e\u062f\u0645 HTTPS",
|
"label.usehttps": "\u0627\u0633\u062a\u062e\u062f\u0645 HTTPS",
|
||||||
"label.usenewdiskoffering": "Replace disk offering?",
|
"label.usenewdiskoffering": "Replace disk offering?",
|
||||||
"label.user": "User",
|
"label.user": "User",
|
||||||
"label.userdata": "Userdata",
|
"label.user.data": "User Data",
|
||||||
"label.userdatal2": "User Data",
|
|
||||||
"label.username": "Username",
|
"label.username": "Username",
|
||||||
"label.users": "Users",
|
"label.users": "Users",
|
||||||
"label.utilization": "Utilisation",
|
"label.utilization": "Utilisation",
|
||||||
@ -1329,7 +1327,7 @@
|
|||||||
"message.confirm.archive.selected.alerts": "Please confirm you would like to archive the selected alerts",
|
"message.confirm.archive.selected.alerts": "Please confirm you would like to archive the selected alerts",
|
||||||
"message.confirm.archive.selected.events": "Please confirm you would like to archive the selected events",
|
"message.confirm.archive.selected.events": "Please confirm you would like to archive the selected events",
|
||||||
"message.confirm.attach.disk": "Are you sure you want to attach disk?",
|
"message.confirm.attach.disk": "Are you sure you want to attach disk?",
|
||||||
"message.confirm.delete.acl.list": "Are you sure you want to delete this ACL list?",
|
"message.confirm.delete.acl": "Are you sure you want to delete this ACL?",
|
||||||
"message.confirm.delete.bigswitchbcf": "Please confirm that you would like to delete this BigSwitch BCF Controller",
|
"message.confirm.delete.bigswitchbcf": "Please confirm that you would like to delete this BigSwitch BCF Controller",
|
||||||
"message.confirm.delete.brocadevcs": "Please confirm that you would like to delete Brocade Vcs Switch",
|
"message.confirm.delete.brocadevcs": "Please confirm that you would like to delete Brocade Vcs Switch",
|
||||||
"message.confirm.delete.ciscoasa1000v": "Please confirm you want to delete CiscoASA1000v",
|
"message.confirm.delete.ciscoasa1000v": "Please confirm you want to delete CiscoASA1000v",
|
||||||
|
|||||||
@ -14,12 +14,12 @@
|
|||||||
"label.account.specific": "Account-Specific",
|
"label.account.specific": "Account-Specific",
|
||||||
"label.accounts": "Accounts",
|
"label.accounts": "Accounts",
|
||||||
"label.accounttype": "Account Type",
|
"label.accounttype": "Account Type",
|
||||||
"label.acl.export": "Export ACLs",
|
"label.acl.export": "Export ACL rules",
|
||||||
"label.acl.id": "ACL ID",
|
"label.acl.id": "ACL ID",
|
||||||
"label.acl.list.rules": "ACL List Rules",
|
"label.acl.rules": "ACL Rules",
|
||||||
"label.acl.reason.description": "Enter the reason behind an ACL rule.",
|
"label.acl.reason.description": "Enter the reason behind an ACL rule.",
|
||||||
"label.aclid": "ACL",
|
"label.aclid": "ACL",
|
||||||
"label.aclname": "ACL Name",
|
"label.acl.rule.name": "ACL Name",
|
||||||
"label.acquire.new.ip": "Acquire New IP",
|
"label.acquire.new.ip": "Acquire New IP",
|
||||||
"label.acquire.new.secondary.ip": "Acquire new secondary IP",
|
"label.acquire.new.secondary.ip": "Acquire new secondary IP",
|
||||||
"label.action": "Action",
|
"label.action": "Action",
|
||||||
@ -119,8 +119,8 @@
|
|||||||
"label.activeviewersessions": "Active Sessions",
|
"label.activeviewersessions": "Active Sessions",
|
||||||
"label.add": "Add",
|
"label.add": "Add",
|
||||||
"label.add.account": "Add Account",
|
"label.add.account": "Add Account",
|
||||||
|
"label.add.acl.rule": "Add ACL rule",
|
||||||
"label.add.acl": "Add ACL",
|
"label.add.acl": "Add ACL",
|
||||||
"label.add.acl.list": "Add ACL List",
|
|
||||||
"label.add.affinity.group": "Add new affinity group",
|
"label.add.affinity.group": "Add new affinity group",
|
||||||
"label.add.baremetal.dhcp.device": "Add Baremetal DHCP Device",
|
"label.add.baremetal.dhcp.device": "Add Baremetal DHCP Device",
|
||||||
"label.add.bigswitchbcf.device": "Add BigSwitch BCF Controller",
|
"label.add.bigswitchbcf.device": "Add BigSwitch BCF Controller",
|
||||||
@ -142,12 +142,12 @@
|
|||||||
"label.add.ip.range": "Add IP Range",
|
"label.add.ip.range": "Add IP Range",
|
||||||
"label.add.isolated.network": "Add Isolated Network",
|
"label.add.isolated.network": "Add Isolated Network",
|
||||||
"label.add.ldap.account": "Add LDAP account",
|
"label.add.ldap.account": "Add LDAP account",
|
||||||
"label.add.list.name": "ACL List Name",
|
"label.add.acl.name": "ACL Name",
|
||||||
"label.add.more": "Add More",
|
"label.add.more": "Add More",
|
||||||
"label.add.netscaler.device": "Add Netscaler device",
|
"label.add.netscaler.device": "Add Netscaler device",
|
||||||
"label.add.network": "Add Network",
|
"label.add.network": "Add Network",
|
||||||
"label.add.network.acl": "Add network ACL",
|
"label.add.network.acl": "Add network ACL",
|
||||||
"label.add.network.acl.list": "Add Network ACL List",
|
"label.add.network.acl": "Add Network ACL",
|
||||||
"label.add.network.offering": "Add network offering",
|
"label.add.network.offering": "Add network offering",
|
||||||
"label.add.new.gateway": "Add new gateway",
|
"label.add.new.gateway": "Add new gateway",
|
||||||
"label.add.new.tier": "Add new tier",
|
"label.add.new.tier": "Add new tier",
|
||||||
@ -334,7 +334,7 @@
|
|||||||
"label.default.use": "Default Use",
|
"label.default.use": "Default Use",
|
||||||
"label.default.view": "Default View",
|
"label.default.view": "Default View",
|
||||||
"label.delete": "Delete",
|
"label.delete": "Delete",
|
||||||
"label.delete.acl.list": "Delete ACL List",
|
"label.delete.acl": "Delete ACL",
|
||||||
"label.delete.affinity.group": "Delete Affinity Group",
|
"label.delete.affinity.group": "Delete Affinity Group",
|
||||||
"label.delete.alerts": "Delete alerts",
|
"label.delete.alerts": "Delete alerts",
|
||||||
"label.delete.bigswitchbcf": "Remove BigSwitch BCF Controller",
|
"label.delete.bigswitchbcf": "Remove BigSwitch BCF Controller",
|
||||||
@ -419,7 +419,7 @@
|
|||||||
"label.dpd": "Dead Peer Detection",
|
"label.dpd": "Dead Peer Detection",
|
||||||
"label.driver": "Driver",
|
"label.driver": "Driver",
|
||||||
"label.edit": "Edit",
|
"label.edit": "Edit",
|
||||||
"label.edit.acl.list": "Edit ACL List",
|
"label.edit.acl": "Edit ACL",
|
||||||
"label.edit.acl.rule": "Edit ACL rule",
|
"label.edit.acl.rule": "Edit ACL rule",
|
||||||
"label.edit.project.details": "Editar detalls del projecte",
|
"label.edit.project.details": "Editar detalls del projecte",
|
||||||
"label.edit.role": "Edit Role",
|
"label.edit.role": "Edit Role",
|
||||||
@ -924,7 +924,6 @@
|
|||||||
"label.remove.vpc.offering": "Remove VPC offering",
|
"label.remove.vpc.offering": "Remove VPC offering",
|
||||||
"label.removing": "Esborrant",
|
"label.removing": "Esborrant",
|
||||||
"label.replace.acl": "Replace ACL",
|
"label.replace.acl": "Replace ACL",
|
||||||
"label.replace.acl.list": "Replace ACL List",
|
|
||||||
"label.required": "Required",
|
"label.required": "Required",
|
||||||
"label.requireshvm": "HVM",
|
"label.requireshvm": "HVM",
|
||||||
"label.requiresupgrade": "Requires Upgrade",
|
"label.requiresupgrade": "Requires Upgrade",
|
||||||
@ -1150,8 +1149,7 @@
|
|||||||
"label.usehttps": "Use HTTPS",
|
"label.usehttps": "Use HTTPS",
|
||||||
"label.usenewdiskoffering": "Replace disk offering?",
|
"label.usenewdiskoffering": "Replace disk offering?",
|
||||||
"label.user": "User",
|
"label.user": "User",
|
||||||
"label.userdata": "Userdata",
|
"label.user.data": "User Data",
|
||||||
"label.userdatal2": "User Data",
|
|
||||||
"label.username": "Username",
|
"label.username": "Username",
|
||||||
"label.users": "Users",
|
"label.users": "Users",
|
||||||
"label.utilization": "Utilisation",
|
"label.utilization": "Utilisation",
|
||||||
@ -1329,7 +1327,7 @@
|
|||||||
"message.confirm.archive.selected.alerts": "Please confirm you would like to archive the selected alerts",
|
"message.confirm.archive.selected.alerts": "Please confirm you would like to archive the selected alerts",
|
||||||
"message.confirm.archive.selected.events": "Please confirm you would like to archive the selected events",
|
"message.confirm.archive.selected.events": "Please confirm you would like to archive the selected events",
|
||||||
"message.confirm.attach.disk": "Are you sure you want to attach disk?",
|
"message.confirm.attach.disk": "Are you sure you want to attach disk?",
|
||||||
"message.confirm.delete.acl.list": "Are you sure you want to delete this ACL list?",
|
"message.confirm.delete.acl": "Are you sure you want to delete this ACL?",
|
||||||
"message.confirm.delete.bigswitchbcf": "Please confirm that you would like to delete this BigSwitch BCF Controller",
|
"message.confirm.delete.bigswitchbcf": "Please confirm that you would like to delete this BigSwitch BCF Controller",
|
||||||
"message.confirm.delete.brocadevcs": "Please confirm that you would like to delete Brocade Vcs Switch",
|
"message.confirm.delete.brocadevcs": "Please confirm that you would like to delete Brocade Vcs Switch",
|
||||||
"message.confirm.delete.ciscoasa1000v": "Please confirm you want to delete CiscoASA1000v",
|
"message.confirm.delete.ciscoasa1000v": "Please confirm you want to delete CiscoASA1000v",
|
||||||
|
|||||||
@ -26,12 +26,12 @@
|
|||||||
"label.account.specific": "Besonderheiten des Benutzerkontos",
|
"label.account.specific": "Besonderheiten des Benutzerkontos",
|
||||||
"label.accounts": "Benutzerkonten",
|
"label.accounts": "Benutzerkonten",
|
||||||
"label.accounttype": "Benutzerkontotyp",
|
"label.accounttype": "Benutzerkontotyp",
|
||||||
"label.acl.export": "Export ACLs",
|
"label.acl.export": "Export ACL rules",
|
||||||
"label.acl.id": "ACL-Kennung",
|
"label.acl.id": "ACL-Kennung",
|
||||||
"label.acl.list.rules": "ACL-Listenregeln",
|
"label.acl.rules": "ACL-Listenregeln",
|
||||||
"label.acl.reason.description": "Enter the reason behind an ACL rule.",
|
"label.acl.reason.description": "Enter the reason behind an ACL rule.",
|
||||||
"label.aclid": "ACL",
|
"label.aclid": "ACL",
|
||||||
"label.aclname": "ACL-Name",
|
"label.acl.rule.name": "ACL-Name",
|
||||||
"label.acquire.new.ip": "Neue IP erwerben",
|
"label.acquire.new.ip": "Neue IP erwerben",
|
||||||
"label.acquire.new.secondary.ip": "Neue sekundäre IP anfordern",
|
"label.acquire.new.secondary.ip": "Neue sekundäre IP anfordern",
|
||||||
"label.acquiring.ip": "IP anfordern",
|
"label.acquiring.ip": "IP anfordern",
|
||||||
@ -144,8 +144,8 @@
|
|||||||
"label.activeviewersessions": "Aktive Sitzungen",
|
"label.activeviewersessions": "Aktive Sitzungen",
|
||||||
"label.add": "Hinzufügen",
|
"label.add": "Hinzufügen",
|
||||||
"label.add.account": "Konto hinzufügen",
|
"label.add.account": "Konto hinzufügen",
|
||||||
"label.add.acl": "ACL hinzufügen",
|
"label.add.acl.rule": "ACL hinzufügen",
|
||||||
"label.add.acl.list": "ACL-Liste hinzufügen",
|
"label.add.acl": "ACL-Liste hinzufügen",
|
||||||
"label.add.affinity.group": "Neue Affinitätsgruppe hinzufügen",
|
"label.add.affinity.group": "Neue Affinitätsgruppe hinzufügen",
|
||||||
"label.add.baremetal.dhcp.device": "Baremetal DHCP-Gerät hinzufügen",
|
"label.add.baremetal.dhcp.device": "Baremetal DHCP-Gerät hinzufügen",
|
||||||
"label.add.bigswitchbcf.device": "Füge BigSwitch BCF Controller hinzu",
|
"label.add.bigswitchbcf.device": "Füge BigSwitch BCF Controller hinzu",
|
||||||
@ -169,12 +169,12 @@
|
|||||||
"label.add.isolated.network": "Isoliertes Netzwerk hinzufügen",
|
"label.add.isolated.network": "Isoliertes Netzwerk hinzufügen",
|
||||||
"label.add.kubernetes.cluster": "Kubernetes Cluster hinzufügen",
|
"label.add.kubernetes.cluster": "Kubernetes Cluster hinzufügen",
|
||||||
"label.add.ldap.account": "LDAP-Konto hinzufügen",
|
"label.add.ldap.account": "LDAP-Konto hinzufügen",
|
||||||
"label.add.list.name": "ACL-Listename",
|
"label.add.acl.name": "ACL-Listename",
|
||||||
"label.add.more": "Mehr hinzufügen",
|
"label.add.more": "Mehr hinzufügen",
|
||||||
"label.add.netscaler.device": "Netscaler-Gerät hinzufügen",
|
"label.add.netscaler.device": "Netscaler-Gerät hinzufügen",
|
||||||
"label.add.network": "Netzwerk hinzufügen",
|
"label.add.network": "Netzwerk hinzufügen",
|
||||||
"label.add.network.acl": "Netzwerk-ACL hinzufügen",
|
"label.add.network.acl": "Netzwerk-ACL hinzufügen",
|
||||||
"label.add.network.acl.list": "Netzwerk-ACL-Liste hinzufügen",
|
"label.add.network.acl": "Netzwerk-ACL-Liste hinzufügen",
|
||||||
"label.add.network.offering": "Netzwerkangebot hinzufügen",
|
"label.add.network.offering": "Netzwerkangebot hinzufügen",
|
||||||
"label.add.new.gateway": "Neues Gateway hinzufügen",
|
"label.add.new.gateway": "Neues Gateway hinzufügen",
|
||||||
"label.add.new.tier": "Neue Ebene hinzufügen",
|
"label.add.new.tier": "Neue Ebene hinzufügen",
|
||||||
@ -417,7 +417,7 @@
|
|||||||
"label.default.view": "Standardansicht",
|
"label.default.view": "Standardansicht",
|
||||||
"label.defaultnetwork": "Standard-Netzwerk",
|
"label.defaultnetwork": "Standard-Netzwerk",
|
||||||
"label.delete": "Löschen",
|
"label.delete": "Löschen",
|
||||||
"label.delete.acl.list": "ACL-Liste ersetzen",
|
"label.delete.acl": "ACL-Liste ersetzen",
|
||||||
"label.delete.affinity.group": "Affinitätsgruppe entfernen",
|
"label.delete.affinity.group": "Affinitätsgruppe entfernen",
|
||||||
"label.delete.alerts": "Alarme löschen",
|
"label.delete.alerts": "Alarme löschen",
|
||||||
"label.delete.backup": "Backup löschen",
|
"label.delete.backup": "Backup löschen",
|
||||||
@ -525,7 +525,7 @@
|
|||||||
"label.driver": "Treiber",
|
"label.driver": "Treiber",
|
||||||
"label.dynamicscalingenabled": "Dynamische Skalierung aktiviert",
|
"label.dynamicscalingenabled": "Dynamische Skalierung aktiviert",
|
||||||
"label.edit": "Bearbeiten",
|
"label.edit": "Bearbeiten",
|
||||||
"label.edit.acl.list": "Edit ACL List",
|
"label.edit.acl": "Edit ACL",
|
||||||
"label.edit.acl.rule": "ACL-Regel bearbeiten",
|
"label.edit.acl.rule": "ACL-Regel bearbeiten",
|
||||||
"label.edit.project.details": "Projektdetails bearbeiten",
|
"label.edit.project.details": "Projektdetails bearbeiten",
|
||||||
"label.edit.role": "Rolle bearbeiten",
|
"label.edit.role": "Rolle bearbeiten",
|
||||||
@ -948,7 +948,7 @@
|
|||||||
"label.netscaler.vpx": "NetScaler VPX LoadBalancer",
|
"label.netscaler.vpx": "NetScaler VPX LoadBalancer",
|
||||||
"label.network": "Netzwerk",
|
"label.network": "Netzwerk",
|
||||||
"label.network.acl": "Netzwerk-ACL",
|
"label.network.acl": "Netzwerk-ACL",
|
||||||
"label.network.acl.lists": "Netzwerk ACL Listen",
|
"label.network.acls": "Netzwerk ACL Listen",
|
||||||
"label.network.addvm": "Netzwerk zur VM hinzufügen",
|
"label.network.addvm": "Netzwerk zur VM hinzufügen",
|
||||||
"label.network.desc": "Netzwerkbeschreibung",
|
"label.network.desc": "Netzwerkbeschreibung",
|
||||||
"label.network.domain": "Netzwerk-Domain",
|
"label.network.domain": "Netzwerk-Domain",
|
||||||
@ -1198,7 +1198,6 @@
|
|||||||
"label.remove.vpc.offering": "VPC-Angebot entfernen",
|
"label.remove.vpc.offering": "VPC-Angebot entfernen",
|
||||||
"label.removing": "am Entfernen",
|
"label.removing": "am Entfernen",
|
||||||
"label.replace.acl": "ACL ersetzen",
|
"label.replace.acl": "ACL ersetzen",
|
||||||
"label.replace.acl.list": "ACL-Liste ersetzen",
|
|
||||||
"label.report.bug": "Fehler melden",
|
"label.report.bug": "Fehler melden",
|
||||||
"label.required": "Erforderlich",
|
"label.required": "Erforderlich",
|
||||||
"label.requireshvm": "HVM",
|
"label.requireshvm": "HVM",
|
||||||
@ -1492,8 +1491,7 @@
|
|||||||
"label.usenewdiskoffering": "Replace disk offering?",
|
"label.usenewdiskoffering": "Replace disk offering?",
|
||||||
"label.user": "Benutzer",
|
"label.user": "Benutzer",
|
||||||
"label.user.conflict": "Konflikt",
|
"label.user.conflict": "Konflikt",
|
||||||
"label.userdata": "Benutzerdaten",
|
"label.user.data": "Benutzerdaten",
|
||||||
"label.userdatal2": "Benutzerdaten",
|
|
||||||
"label.username": "Benutzername",
|
"label.username": "Benutzername",
|
||||||
"label.users": "Benutzer",
|
"label.users": "Benutzer",
|
||||||
"label.usersource": "Benutzertyp",
|
"label.usersource": "Benutzertyp",
|
||||||
@ -1733,7 +1731,7 @@
|
|||||||
"message.confirm.archive.selected.alerts": "Bitte bestätigen Sie, dass Sie die ausgewählten Alarme archivieren möchten",
|
"message.confirm.archive.selected.alerts": "Bitte bestätigen Sie, dass Sie die ausgewählten Alarme archivieren möchten",
|
||||||
"message.confirm.archive.selected.events": "Bitte bestätigen Sie, dass Sie die ausgewählten Vorgänge archivieren möchten",
|
"message.confirm.archive.selected.events": "Bitte bestätigen Sie, dass Sie die ausgewählten Vorgänge archivieren möchten",
|
||||||
"message.confirm.attach.disk": "Sind Sie sicher, dass Sie eine Platte hinzufügen möchten?",
|
"message.confirm.attach.disk": "Sind Sie sicher, dass Sie eine Platte hinzufügen möchten?",
|
||||||
"message.confirm.delete.acl.list": "Sind Sie sicher, dass Sie diese ACL-Liste löschen möchten?",
|
"message.confirm.delete.acl": "Sind Sie sicher, dass Sie diese ACL-Liste löschen möchten?",
|
||||||
"message.confirm.delete.bigswitchbcf": "Bitte bestätigen Sie, dass Sie diesen BigSwitch BCF Controller löschen möchten",
|
"message.confirm.delete.bigswitchbcf": "Bitte bestätigen Sie, dass Sie diesen BigSwitch BCF Controller löschen möchten",
|
||||||
"message.confirm.delete.brocadevcs": "Bitte bestätigen Sie, dass Sie Brocade Vcs Switch löschen möchten",
|
"message.confirm.delete.brocadevcs": "Bitte bestätigen Sie, dass Sie Brocade Vcs Switch löschen möchten",
|
||||||
"message.confirm.delete.ciscoasa1000v": "Bitte bestätigen Sie, dass Sie CiscoASA1000v löschen möchten",
|
"message.confirm.delete.ciscoasa1000v": "Bitte bestätigen Sie, dass Sie CiscoASA1000v löschen möchten",
|
||||||
|
|||||||
@ -33,10 +33,10 @@
|
|||||||
"label.access.kubernetes.nodes": "Πρόσβαση στους κόμβους Κυβερνητών",
|
"label.access.kubernetes.nodes": "Πρόσβαση στους κόμβους Κυβερνητών",
|
||||||
"label.acl.export": "Εξαγωγή Λίστας Πρόσβασης",
|
"label.acl.export": "Εξαγωγή Λίστας Πρόσβασης",
|
||||||
"label.acl.id": "Αναγνωριστικό Λίστας Πρόσβασης",
|
"label.acl.id": "Αναγνωριστικό Λίστας Πρόσβασης",
|
||||||
"label.acl.list.rules": "Κανόνες λίστας Πρόσωασης",
|
"label.acl.rules": "Κανόνες λίστας Πρόσωασης",
|
||||||
"label.acl.reason.description": "Εισαγάγετε αιτιολογία για τον κανόνα",
|
"label.acl.reason.description": "Εισαγάγετε αιτιολογία για τον κανόνα",
|
||||||
"label.aclid": "Λίστα πρόσβασης",
|
"label.aclid": "Λίστα πρόσβασης",
|
||||||
"label.aclname": "Όνομα Λίστας Πρόσβασης",
|
"label.acl.rule.name": "Όνομα Λίστας Πρόσβασης",
|
||||||
"label.acquire.new.ip": "Απόκτηση νέας διεύθυνση IP",
|
"label.acquire.new.ip": "Απόκτηση νέας διεύθυνση IP",
|
||||||
"label.acquire.new.secondary.ip": "Απόκτηση νέας δευτερεύουσας διεύθυνσης IP",
|
"label.acquire.new.secondary.ip": "Απόκτηση νέας δευτερεύουσας διεύθυνσης IP",
|
||||||
"label.acquiring.ip": "Απόδοση IP",
|
"label.acquiring.ip": "Απόδοση IP",
|
||||||
@ -173,7 +173,7 @@
|
|||||||
"label.action.unmanage.virtualmachine": "Μη διαχείριση εικονικής μηχανής",
|
"label.action.unmanage.virtualmachine": "Μη διαχείριση εικονικής μηχανής",
|
||||||
"label.action.update.offering.access": "Ενημέρωση πρόσβασης για προσφορές",
|
"label.action.update.offering.access": "Ενημέρωση πρόσβασης για προσφορές",
|
||||||
"label.action.update.resource.count": "Ενημέρωση πλήθους πόρων",
|
"label.action.update.resource.count": "Ενημέρωση πλήθους πόρων",
|
||||||
"label.action.userdata.reset": "Επαναφορά δεδομένων χρήστη",
|
"label.action.user.data.reset": "Επαναφορά δεδομένων χρήστη",
|
||||||
"label.action.vmsnapshot.create": "Λήψη στιγμιότυπου εικονικής μηχανής",
|
"label.action.vmsnapshot.create": "Λήψη στιγμιότυπου εικονικής μηχανής",
|
||||||
"label.action.vmsnapshot.delete": "Διαγραφή στιγμιότυπου εικονικής μηχανής",
|
"label.action.vmsnapshot.delete": "Διαγραφή στιγμιότυπου εικονικής μηχανής",
|
||||||
"label.action.vmsnapshot.revert": "Επαναφορά στο στιγμιότυπο εικονικής μηχανής",
|
"label.action.vmsnapshot.revert": "Επαναφορά στο στιγμιότυπο εικονικής μηχανής",
|
||||||
@ -183,8 +183,8 @@
|
|||||||
"label.activeviewersessions": "Ενεργές περίοδοι λειτουργίας",
|
"label.activeviewersessions": "Ενεργές περίοδοι λειτουργίας",
|
||||||
"label.add": "Προσθήκη",
|
"label.add": "Προσθήκη",
|
||||||
"label.add.account": "Προσθήκη λογαριασμού",
|
"label.add.account": "Προσθήκη λογαριασμού",
|
||||||
"label.add.acl": "Προσθήκη εγγραφής στην λίστα πρόσβασης",
|
"label.add.acl.rule": "Προσθήκη εγγραφής στην λίστα πρόσβασης",
|
||||||
"label.add.acl.list": "Προσθήκη λίστας πρόσβασης",
|
"label.add.acl": "Προσθήκη λίστας πρόσβασης",
|
||||||
"label.add.affinity.group": "Προσθήκη νέας ομάδας συνάφειας",
|
"label.add.affinity.group": "Προσθήκη νέας ομάδας συνάφειας",
|
||||||
"label.add.baremetal.dhcp.device": "Προσθήκη συσκευής DHCP baremetal",
|
"label.add.baremetal.dhcp.device": "Προσθήκη συσκευής DHCP baremetal",
|
||||||
"label.add.bigswitchbcf.device": "Προσθήκη ελεγκτή BCF BigSwitch",
|
"label.add.bigswitchbcf.device": "Προσθήκη ελεγκτή BCF BigSwitch",
|
||||||
@ -209,12 +209,12 @@
|
|||||||
"label.add.isolated.network": "Προσθήκη απομονωμένου δικτύου",
|
"label.add.isolated.network": "Προσθήκη απομονωμένου δικτύου",
|
||||||
"label.add.kubernetes.cluster": "Προσθήκη ομάδας Κυβερνητών",
|
"label.add.kubernetes.cluster": "Προσθήκη ομάδας Κυβερνητών",
|
||||||
"label.add.ldap.account": "Προσθήκη λογαριασμού LDAP",
|
"label.add.ldap.account": "Προσθήκη λογαριασμού LDAP",
|
||||||
"label.add.list.name": "Όνομα λίστας Πρόσβασης",
|
"label.add.acl.name": "Όνομα λίστας Πρόσβασης",
|
||||||
"label.add.more": "Προσθήκη περισσότερων",
|
"label.add.more": "Προσθήκη περισσότερων",
|
||||||
"label.add.netscaler.device": "Προσθήκη συσκευής Netsccaler",
|
"label.add.netscaler.device": "Προσθήκη συσκευής Netsccaler",
|
||||||
"label.add.network": "Προσθήκη δικτύου",
|
"label.add.network": "Προσθήκη δικτύου",
|
||||||
"label.add.network.acl": "Προσθήκη εγγραφής πρόσβασης δικτύου",
|
"label.add.network.acl": "Προσθήκη εγγραφής πρόσβασης δικτύου",
|
||||||
"label.add.network.acl.list": "Προσθήκη λίστας πρόσβασης δικτύου",
|
"label.add.network.acl": "Προσθήκη λίστας πρόσβασης δικτύου",
|
||||||
"label.add.network.offering": "Προσθήκη προσφοράς υπηρεσίας δικτύου",
|
"label.add.network.offering": "Προσθήκη προσφοράς υπηρεσίας δικτύου",
|
||||||
"label.add.network.permission": "Προσθήκη δικαιωμάτων δικτύου",
|
"label.add.network.permission": "Προσθήκη δικαιωμάτων δικτύου",
|
||||||
"label.add.new.gateway": "Προσθήκη νέας πύλης",
|
"label.add.new.gateway": "Προσθήκη νέας πύλης",
|
||||||
@ -516,7 +516,7 @@
|
|||||||
"label.default.view": "Προεπιλεγμένη προβολή",
|
"label.default.view": "Προεπιλεγμένη προβολή",
|
||||||
"label.defaultnetwork": "Προεπιλεγμένο δίκτυο",
|
"label.defaultnetwork": "Προεπιλεγμένο δίκτυο",
|
||||||
"label.delete": "Διαγραφή",
|
"label.delete": "Διαγραφή",
|
||||||
"label.delete.acl.list": "Διαγραφή λίστας πρόσβασης",
|
"label.delete.acl": "Διαγραφή λίστας πρόσβασης",
|
||||||
"label.delete.affinity.group": "Διαγραφή ομάδας συνάφειας",
|
"label.delete.affinity.group": "Διαγραφή ομάδας συνάφειας",
|
||||||
"label.delete.alerts": "Διαγραφή ειδοποιήσεων",
|
"label.delete.alerts": "Διαγραφή ειδοποιήσεων",
|
||||||
"label.delete.backup": "Διαγραφή αντιγράφου ασφαλείας",
|
"label.delete.backup": "Διαγραφή αντιγράφου ασφαλείας",
|
||||||
@ -649,7 +649,7 @@
|
|||||||
"label.dynamicscalingenabled": "Δυναμική αναπροσαρμογή Ενεργοποίημένη",
|
"label.dynamicscalingenabled": "Δυναμική αναπροσαρμογή Ενεργοποίημένη",
|
||||||
"label.dynamicscalingenabled.tooltip": "Η εικονική μηχανή μπορεί να αναπροσαρμόζεται δυναμικά μόνο αν το πρότυπο, η προσφερόμενη υπηρεσία και οι γενικές ρυθμίσεις έχουν την επιλογή δυναμικής αναπροσαρμογής ενεργοποιήμενη.",
|
"label.dynamicscalingenabled.tooltip": "Η εικονική μηχανή μπορεί να αναπροσαρμόζεται δυναμικά μόνο αν το πρότυπο, η προσφερόμενη υπηρεσία και οι γενικές ρυθμίσεις έχουν την επιλογή δυναμικής αναπροσαρμογής ενεργοποιήμενη.",
|
||||||
"label.edit": "Επεξεργασία",
|
"label.edit": "Επεξεργασία",
|
||||||
"label.edit.acl.list": "Επεξεργασία λίστας Πρόσβασης",
|
"label.edit.acl": "Επεξεργασία λίστας Πρόσβασης",
|
||||||
"label.edit.acl.rule": "Επεξεργασία κανόνα Λίστας Πρόσβασης",
|
"label.edit.acl.rule": "Επεξεργασία κανόνα Λίστας Πρόσβασης",
|
||||||
"label.edit.project.details": "Επεξεργασία λεπτομερειών έργου",
|
"label.edit.project.details": "Επεξεργασία λεπτομερειών έργου",
|
||||||
"label.edit.project.role": "Επεξεργασία ρόλου έργου",
|
"label.edit.project.role": "Επεξεργασία ρόλου έργου",
|
||||||
@ -1142,7 +1142,7 @@
|
|||||||
"label.netscaler.vpx": "Εξισορρόπηση φόρτου VPX του NetScaler",
|
"label.netscaler.vpx": "Εξισορρόπηση φόρτου VPX του NetScaler",
|
||||||
"label.network": "Δίκτυο",
|
"label.network": "Δίκτυο",
|
||||||
"label.network.acl": "ACL δικτύου",
|
"label.network.acl": "ACL δικτύου",
|
||||||
"label.network.acl.lists": "Λίστες Λίστα Πρόσβασης δικτύου",
|
"label.network.acls": "Λίστες Λίστα Πρόσβασης δικτύου",
|
||||||
"label.network.addvm": "Προσθήκη δικτύου για την εικονική μηχανή",
|
"label.network.addvm": "Προσθήκη δικτύου για την εικονική μηχανή",
|
||||||
"label.network.addvm": "Προσθήκη δικτύου σε εικονική μηχανή",
|
"label.network.addvm": "Προσθήκη δικτύου σε εικονική μηχανή",
|
||||||
"label.network.desc": "Δίκτυο Desc",
|
"label.network.desc": "Δίκτυο Desc",
|
||||||
@ -1436,7 +1436,6 @@
|
|||||||
"label.remove.vpc.offering": "Κατάργηση προσφοράς υπηρεσίας Εικον. Ιδιωτ. Νέφους",
|
"label.remove.vpc.offering": "Κατάργηση προσφοράς υπηρεσίας Εικον. Ιδιωτ. Νέφους",
|
||||||
"label.removing": "Αφαίρεση",
|
"label.removing": "Αφαίρεση",
|
||||||
"label.replace.acl": "Αντικατάσταση λίστας Πρόσβασης",
|
"label.replace.acl": "Αντικατάσταση λίστας Πρόσβασης",
|
||||||
"label.replace.acl.list": "Αντικατάσταση λίστας Πρόσβασης",
|
|
||||||
"label.report.bug": "Θέμα αναφοράς",
|
"label.report.bug": "Θέμα αναφοράς",
|
||||||
"label.required": "Απαιτείται",
|
"label.required": "Απαιτείται",
|
||||||
"label.requireshvm": "HVM",
|
"label.requireshvm": "HVM",
|
||||||
@ -1455,7 +1454,7 @@
|
|||||||
"label.reset.config.value": "Επαναφορά στις τιμές προεπιλογής",
|
"label.reset.config.value": "Επαναφορά στις τιμές προεπιλογής",
|
||||||
"label.reset.ssh.key.pair": "Επαναφορά ζεύγους κλειδιών SSH",
|
"label.reset.ssh.key.pair": "Επαναφορά ζεύγους κλειδιών SSH",
|
||||||
"label.reset.to.default": "Επαναφορά στην τιμή προεπιλογής",
|
"label.reset.to.default": "Επαναφορά στην τιμή προεπιλογής",
|
||||||
"label.reset.userdata.on.vm": "Επαναφορά δεδομένων χρήστη της εικονικής μηχανής",
|
"label.reset.user.data.on.vm": "Επαναφορά δεδομένων χρήστη της εικονικής μηχανής",
|
||||||
"label.reset.vpn.connection": "Επαναφορά σύνδεσης Εικον. Ιδιωτ. Δικτύου",
|
"label.reset.vpn.connection": "Επαναφορά σύνδεσης Εικον. Ιδιωτ. Δικτύου",
|
||||||
"label.resource": "Πόρος",
|
"label.resource": "Πόρος",
|
||||||
"label.resource.limit.exceeded": "Υπέρβαση ορίου πόρων",
|
"label.resource.limit.exceeded": "Υπέρβαση ορίου πόρων",
|
||||||
@ -1811,19 +1810,17 @@
|
|||||||
"label.usenewdiskoffering": "Αντικατάσταση προσφοράς υπηρεσίας δίσκου;",
|
"label.usenewdiskoffering": "Αντικατάσταση προσφοράς υπηρεσίας δίσκου;",
|
||||||
"label.user": "Χρήστη",
|
"label.user": "Χρήστη",
|
||||||
"label.user.conflict": "Σύγκρουση",
|
"label.user.conflict": "Σύγκρουση",
|
||||||
"label.user.data": "Δεδομένα χρηστών",
|
"label.user.data": "Δεδομένα χρήστη",
|
||||||
"label.userdata": "Δεδομένα χρήστη",
|
"label.user.data.do.append": "Πρόσθεση δεδομένων χρήστη",
|
||||||
"label.userdata.do.append": "Πρόσθεση δεδομένων χρήστη",
|
"label.user.data.do.override": "Παράκαμψη δεδομένων χρήστη",
|
||||||
"label.userdata.do.override": "Παράκαμψη δεδομένων χρήστη",
|
"label.user.data.registered": "Εγγεγραμένα δεδομένα χρήστη",
|
||||||
"label.userdata.registered": "Εγγεγραμένα δεδομένα χρήστη",
|
"label.user.data.text": "Κείμενο δεδομένων χρήστη",
|
||||||
"label.userdata.text": "Κείμενο δεδομένων χρήστη",
|
"label.user.data.details": "Λεπτομέρειες δεδομένων χρήστη",
|
||||||
"label.userdatadetails": "Λεπτομέρειες δεδομένων χρήστη",
|
"label.user.data.id": "Αναγνωριστικό δεδομένων χρήστη",
|
||||||
"label.userdataid": "Αναγνωριστικό δεδομένων χρήστη",
|
"label.user.data.name": "Όνομα δεδομένων χρήστη",
|
||||||
"label.userdatal2": "Δεδομένα χρήστη",
|
"label.user.data.params": "Παράμετροι δεδομένων χρήστη",
|
||||||
"label.userdataname": "Όνομα δεδομένων χρήστη",
|
"label.user.data.policy": "Συνδεμένες πολιτικές δεδομένων χρήστη",
|
||||||
"label.userdataparams": "Παράμετροι δεδομένων χρήστη",
|
"label.user.data.policy.tooltip": "Τα δεδομένα χρήστη που έχουν συνδεθεί στο πρότυπο μπορούν να παρακαμφθούν απο τα δεδομένα χρηστών που ορίστηκαν κατα την δημιουργία της vm. Διαλέξτε την πολιτική παράκαμψης ανάλογα με τις απαιτήσεις.",
|
||||||
"label.userdatapolicy": "Συνδεμένες πολιτικές δεδομένων χρήστη",
|
|
||||||
"label.userdatapolicy.tooltip": "Τα δεδομένα χρήστη που έχουν συνδεθεί στο πρότυπο μπορούν να παρακαμφθούν απο τα δεδομένα χρηστών που ορίστηκαν κατα την δημιουργία της vm. Διαλέξτε την πολιτική παράκαμψης ανάλογα με τις απαιτήσεις.",
|
|
||||||
"label.username": "Όνομα χρήστη",
|
"label.username": "Όνομα χρήστη",
|
||||||
"label.users": "Χρήστες",
|
"label.users": "Χρήστες",
|
||||||
"label.usersource": "Τύπος χρήστη",
|
"label.usersource": "Τύπος χρήστη",
|
||||||
@ -2116,7 +2113,7 @@
|
|||||||
"message.confirm.attach.disk": "Είστε βέβαιοι ότι θέλετε να επισυνάψετε το δίσκο;",
|
"message.confirm.attach.disk": "Είστε βέβαιοι ότι θέλετε να επισυνάψετε το δίσκο;",
|
||||||
"message.confirm.change.offering.for.volume": "Παρακαλώ επιβεβαιώστε ότι επιθυμείτε την αλλαγή της προσφοράς δίσκου για αυτόν τον τόμο",
|
"message.confirm.change.offering.for.volume": "Παρακαλώ επιβεβαιώστε ότι επιθυμείτε την αλλαγή της προσφοράς δίσκου για αυτόν τον τόμο",
|
||||||
"message.confirm.configure.ovs": "Είστε βέβαιοι ότι θέλετε να ρυθμίσετε τις παραμέτρους του Ovs;",
|
"message.confirm.configure.ovs": "Είστε βέβαιοι ότι θέλετε να ρυθμίσετε τις παραμέτρους του Ovs;",
|
||||||
"message.confirm.delete.acl.list": "Είστε βέβαιοι ότι θέλετε να διαγράψετε αυτήν τη λίστα Λίστα Πρόσβασης;",
|
"message.confirm.delete.acl": "Είστε βέβαιοι ότι θέλετε να διαγράψετε αυτήν τη λίστα Λίστα Πρόσβασης;",
|
||||||
"message.confirm.delete.bigswitchbcf": "Επιβεβαιώστε ότι θέλετε να διαγράψετε αυτόν τον ελεγκτή BigSwitch BCF",
|
"message.confirm.delete.bigswitchbcf": "Επιβεβαιώστε ότι θέλετε να διαγράψετε αυτόν τον ελεγκτή BigSwitch BCF",
|
||||||
"message.confirm.delete.brocadevcs": "Επιβεβαιώστε ότι θέλετε να διαγράψετε το εναλλάκτη Brocade Vcs",
|
"message.confirm.delete.brocadevcs": "Επιβεβαιώστε ότι θέλετε να διαγράψετε το εναλλάκτη Brocade Vcs",
|
||||||
"message.confirm.delete.ciscoasa1000v": "Παρακαλώ επιβεβαιώστε ότι θέλετε να διαγράψετε CiscoASA1000v",
|
"message.confirm.delete.ciscoasa1000v": "Παρακαλώ επιβεβαιώστε ότι θέλετε να διαγράψετε CiscoASA1000v",
|
||||||
@ -2350,7 +2347,7 @@
|
|||||||
"message.error.upload.template": "Η αποστολή του προτύπου απέτυχε",
|
"message.error.upload.template": "Η αποστολή του προτύπου απέτυχε",
|
||||||
"message.error.upload.template.description": "Μόνο ένα πρότυπο μπορεί να αποσταλεί κάθε φορά",
|
"message.error.upload.template.description": "Μόνο ένα πρότυπο μπορεί να αποσταλεί κάθε φορά",
|
||||||
"message.error.url": "Πληκτρολογήστε διεύθυνση URL",
|
"message.error.url": "Πληκτρολογήστε διεύθυνση URL",
|
||||||
"message.error.userdata": "Εισάγωγή δεδομένων χρηστών",
|
"message.error.user.data": "Εισάγωγή δεδομένων χρηστών",
|
||||||
"message.error.username": "Εισάγετε το όνομα χρήστη σας",
|
"message.error.username": "Εισάγετε το όνομα χρήστη σας",
|
||||||
"message.error.valid.iops.range": "Εισαγεται ένα σωστό εύρος εργασίων εισαγ./εξαγ ανα δευτ.",
|
"message.error.valid.iops.range": "Εισαγεται ένα σωστό εύρος εργασίων εισαγ./εξαγ ανα δευτ.",
|
||||||
"message.error.vcenter.datacenter": "Πληκτρολογήστε vCenter Datacenter",
|
"message.error.vcenter.datacenter": "Πληκτρολογήστε vCenter Datacenter",
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -14,12 +14,12 @@
|
|||||||
"label.account.specific": "espec\u00edficas de la cuenta",
|
"label.account.specific": "espec\u00edficas de la cuenta",
|
||||||
"label.accounts": "Cuentas",
|
"label.accounts": "Cuentas",
|
||||||
"label.accounttype": "Tipo de Cuenta",
|
"label.accounttype": "Tipo de Cuenta",
|
||||||
"label.acl.export": "Export ACLs",
|
"label.acl.export": "Export ACL rules",
|
||||||
"label.acl.id": "ID de ACL",
|
"label.acl.id": "ID de ACL",
|
||||||
"label.acl.list.rules": "Lista de Reglas ACL",
|
"label.acl.rules": "Lista de Reglas ACL",
|
||||||
"label.acl.reason.description": "Enter the reason behind an ACL rule.",
|
"label.acl.reason.description": "Enter the reason behind an ACL rule.",
|
||||||
"label.aclid": "ACL",
|
"label.aclid": "ACL",
|
||||||
"label.aclname": "Nombre de ACL",
|
"label.acl.rule.name": "Nombre de ACL",
|
||||||
"label.acquire.new.ip": "Adquirir nueva IP",
|
"label.acquire.new.ip": "Adquirir nueva IP",
|
||||||
"label.acquire.new.secondary.ip": "Adquirir nueva IP secundaria",
|
"label.acquire.new.secondary.ip": "Adquirir nueva IP secundaria",
|
||||||
"label.action": "Acci\u00f3n",
|
"label.action": "Acci\u00f3n",
|
||||||
@ -119,8 +119,8 @@
|
|||||||
"label.activeviewersessions": "Sesiones activas",
|
"label.activeviewersessions": "Sesiones activas",
|
||||||
"label.add": "Agregar",
|
"label.add": "Agregar",
|
||||||
"label.add.account": "A\u00f1adir Cuenta",
|
"label.add.account": "A\u00f1adir Cuenta",
|
||||||
"label.add.acl": "Agregar ACL",
|
"label.add.acl.rule": "Agregar ACL",
|
||||||
"label.add.acl.list": "Agregar Lista ACL",
|
"label.add.acl": "Agregar Lista ACL",
|
||||||
"label.add.affinity.group": "Agregar un nuevo grupo de afinidad",
|
"label.add.affinity.group": "Agregar un nuevo grupo de afinidad",
|
||||||
"label.add.baremetal.dhcp.device": "Agregar dispositivo DHCP Baremetal",
|
"label.add.baremetal.dhcp.device": "Agregar dispositivo DHCP Baremetal",
|
||||||
"label.add.bigswitchbcf.device": "Agregar Controlador BigSwitch BCF",
|
"label.add.bigswitchbcf.device": "Agregar Controlador BigSwitch BCF",
|
||||||
@ -142,12 +142,12 @@
|
|||||||
"label.add.ip.range": "A\u00f1adir Rango IP",
|
"label.add.ip.range": "A\u00f1adir Rango IP",
|
||||||
"label.add.isolated.network": "Agregar Red Aislada",
|
"label.add.isolated.network": "Agregar Red Aislada",
|
||||||
"label.add.ldap.account": "Agregar cuenta LDAP",
|
"label.add.ldap.account": "Agregar cuenta LDAP",
|
||||||
"label.add.list.name": "Nombre de la Lista ACL",
|
"label.add.acl.name": "Nombre de la Lista ACL",
|
||||||
"label.add.more": "A\u00f1adir m\u00e1s",
|
"label.add.more": "A\u00f1adir m\u00e1s",
|
||||||
"label.add.netscaler.device": "Agregar dispositivo Netscaler",
|
"label.add.netscaler.device": "Agregar dispositivo Netscaler",
|
||||||
"label.add.network": "Agregar Red",
|
"label.add.network": "Agregar Red",
|
||||||
"label.add.network.acl": "Agregar ACL de Red",
|
"label.add.network.acl": "Agregar ACL de Red",
|
||||||
"label.add.network.acl.list": "Agregar Lista ACL de Red",
|
"label.add.network.acl": "Agregar Lista ACL de Red",
|
||||||
"label.add.network.offering": "Agregar Oferta de Red",
|
"label.add.network.offering": "Agregar Oferta de Red",
|
||||||
"label.add.new.gateway": "Agregar nuevo gateway",
|
"label.add.new.gateway": "Agregar nuevo gateway",
|
||||||
"label.add.new.tier": "Agregar un nuevo tier",
|
"label.add.new.tier": "Agregar un nuevo tier",
|
||||||
@ -344,7 +344,7 @@
|
|||||||
"label.default.use": "Uso por defecto",
|
"label.default.use": "Uso por defecto",
|
||||||
"label.default.view": "Vista Por Defecto",
|
"label.default.view": "Vista Por Defecto",
|
||||||
"label.delete": "Eliminar",
|
"label.delete": "Eliminar",
|
||||||
"label.delete.acl.list": "Borrar Lista ACL",
|
"label.delete.acl": "Borrar Lista ACL",
|
||||||
"label.delete.affinity.group": "Borrar Grupo de Afinidad",
|
"label.delete.affinity.group": "Borrar Grupo de Afinidad",
|
||||||
"label.delete.alerts": "Eliminar alertas",
|
"label.delete.alerts": "Eliminar alertas",
|
||||||
"label.delete.bigswitchbcf": "Remover Controlador BigSwitch BCF",
|
"label.delete.bigswitchbcf": "Remover Controlador BigSwitch BCF",
|
||||||
@ -431,7 +431,7 @@
|
|||||||
"label.driver": "Controlador",
|
"label.driver": "Controlador",
|
||||||
"label.dynamicscalingenabled": "Escalado din\u00e1mico habilitado",
|
"label.dynamicscalingenabled": "Escalado din\u00e1mico habilitado",
|
||||||
"label.edit": "Editar",
|
"label.edit": "Editar",
|
||||||
"label.edit.acl.list": "Edit ACL List",
|
"label.edit.acl": "Edit ACL",
|
||||||
"label.edit.acl.rule": "Editar regla ACL",
|
"label.edit.acl.rule": "Editar regla ACL",
|
||||||
"label.edit.project.details": "Editar detalles de proyecto",
|
"label.edit.project.details": "Editar detalles de proyecto",
|
||||||
"label.edit.role": "Editar Rol",
|
"label.edit.role": "Editar Rol",
|
||||||
@ -947,7 +947,6 @@
|
|||||||
"label.remove.vpc.offering": "Quitar Oferta VPC",
|
"label.remove.vpc.offering": "Quitar Oferta VPC",
|
||||||
"label.removing": "Quitando..",
|
"label.removing": "Quitando..",
|
||||||
"label.replace.acl": "Reemplazar ACL",
|
"label.replace.acl": "Reemplazar ACL",
|
||||||
"label.replace.acl.list": "Reemplazar Lista ACL",
|
|
||||||
"label.report.bug": "Reportar un Error",
|
"label.report.bug": "Reportar un Error",
|
||||||
"label.required": "Requerido",
|
"label.required": "Requerido",
|
||||||
"label.requireshvm": "HVM",
|
"label.requireshvm": "HVM",
|
||||||
@ -1180,8 +1179,7 @@
|
|||||||
"label.usehttps": "Use HTTPS",
|
"label.usehttps": "Use HTTPS",
|
||||||
"label.usenewdiskoffering": "Replace disk offering?",
|
"label.usenewdiskoffering": "Replace disk offering?",
|
||||||
"label.user": "Usuario",
|
"label.user": "Usuario",
|
||||||
"label.userdata": "DatosUsuario",
|
"label.user.data": "DatosUsuario",
|
||||||
"label.userdatal2": "Datos de Usuario",
|
|
||||||
"label.username": "Nombre de usuario",
|
"label.username": "Nombre de usuario",
|
||||||
"label.users": "Usuarios",
|
"label.users": "Usuarios",
|
||||||
"label.utilization": "Utilisation",
|
"label.utilization": "Utilisation",
|
||||||
@ -1361,7 +1359,7 @@
|
|||||||
"message.confirm.archive.selected.alerts": "Por favor confirme que desea archivar las alertas seleccionadas",
|
"message.confirm.archive.selected.alerts": "Por favor confirme que desea archivar las alertas seleccionadas",
|
||||||
"message.confirm.archive.selected.events": "Por favor confirme que desea archivar los eventos seleccionados",
|
"message.confirm.archive.selected.events": "Por favor confirme que desea archivar los eventos seleccionados",
|
||||||
"message.confirm.attach.disk": "\u00bf Est\u00e1 seguro que desea conectar el disco?",
|
"message.confirm.attach.disk": "\u00bf Est\u00e1 seguro que desea conectar el disco?",
|
||||||
"message.confirm.delete.acl.list": "\u00bfEsta seguro que desea borrar esta lista de ACL?",
|
"message.confirm.delete.acl": "\u00bfEsta seguro que desea borrar esta lista de ACL?",
|
||||||
"message.confirm.delete.bigswitchbcf": "Por favor confirme que desa borrar este Controlador BigSwitch BCF",
|
"message.confirm.delete.bigswitchbcf": "Por favor confirme que desa borrar este Controlador BigSwitch BCF",
|
||||||
"message.confirm.delete.brocadevcs": "Por favor confirme que desa borrar este Switch Brocade Vcs",
|
"message.confirm.delete.brocadevcs": "Por favor confirme que desa borrar este Switch Brocade Vcs",
|
||||||
"message.confirm.delete.ciscoasa1000v": "Por favor confirme que desea borrar CiscoASA1000v",
|
"message.confirm.delete.ciscoasa1000v": "Por favor confirme que desea borrar CiscoASA1000v",
|
||||||
|
|||||||
@ -14,12 +14,12 @@
|
|||||||
"label.account.specific": "Sp\u00e9cifique au compte",
|
"label.account.specific": "Sp\u00e9cifique au compte",
|
||||||
"label.accounts": "Comptes",
|
"label.accounts": "Comptes",
|
||||||
"label.accounttype": "Type Compte",
|
"label.accounttype": "Type Compte",
|
||||||
"label.acl.export": "Export ACLs",
|
"label.acl.export": "Export ACL rules",
|
||||||
"label.acl.id": "ID ACL",
|
"label.acl.id": "ID ACL",
|
||||||
"label.acl.list.rules": "Liste r\u00e8gles ACL",
|
"label.acl.rules": "Liste r\u00e8gles ACL",
|
||||||
"label.acl.reason.description": "Enter the reason behind an ACL rule.",
|
"label.acl.reason.description": "Enter the reason behind an ACL rule.",
|
||||||
"label.aclid": "ACL",
|
"label.aclid": "ACL",
|
||||||
"label.aclname": "Nom ACL",
|
"label.acl.rule.name": "Nom ACL",
|
||||||
"label.acquire.new.ip": "Acqu\u00e9rir nouvelle adr. IP",
|
"label.acquire.new.ip": "Acqu\u00e9rir nouvelle adr. IP",
|
||||||
"label.acquire.new.secondary.ip": "Acqu\u00e9rir nouvelle IP secondaire",
|
"label.acquire.new.secondary.ip": "Acqu\u00e9rir nouvelle IP secondaire",
|
||||||
"label.action": "Action",
|
"label.action": "Action",
|
||||||
@ -119,8 +119,8 @@
|
|||||||
"label.activeviewersessions": "Sessions actives",
|
"label.activeviewersessions": "Sessions actives",
|
||||||
"label.add": "Ajouter",
|
"label.add": "Ajouter",
|
||||||
"label.add.account": "Ajouter un compte",
|
"label.add.account": "Ajouter un compte",
|
||||||
"label.add.acl": "Ajouter r\u00e8gle ACL",
|
"label.add.acl.rule": "Ajouter r\u00e8gle ACL",
|
||||||
"label.add.acl.list": "Ajouter Liste ACL",
|
"label.add.acl": "Ajouter Liste ACL",
|
||||||
"label.add.affinity.group": "Ajouter nouveau groupe d'affinit\u00e9",
|
"label.add.affinity.group": "Ajouter nouveau groupe d'affinit\u00e9",
|
||||||
"label.add.baremetal.dhcp.device": "Ajouter un DHCP Baremetal",
|
"label.add.baremetal.dhcp.device": "Ajouter un DHCP Baremetal",
|
||||||
"label.add.bigswitchbcf.device": "Ajouter un contr\u00f4leur BigSwitch BCF",
|
"label.add.bigswitchbcf.device": "Ajouter un contr\u00f4leur BigSwitch BCF",
|
||||||
@ -142,12 +142,12 @@
|
|||||||
"label.add.ip.range": "Ajouter une plage IP",
|
"label.add.ip.range": "Ajouter une plage IP",
|
||||||
"label.add.isolated.network": "Ajouter un r\u00e9seau isol\u00e9",
|
"label.add.isolated.network": "Ajouter un r\u00e9seau isol\u00e9",
|
||||||
"label.add.ldap.account": "Ajouter un compte LDAP",
|
"label.add.ldap.account": "Ajouter un compte LDAP",
|
||||||
"label.add.list.name": "Nom Liste ACL",
|
"label.add.acl.name": "Nom Liste ACL",
|
||||||
"label.add.more": "Ajouter plus",
|
"label.add.more": "Ajouter plus",
|
||||||
"label.add.netscaler.device": "Ajouter un Netscaler",
|
"label.add.netscaler.device": "Ajouter un Netscaler",
|
||||||
"label.add.network": "Ajouter un r\u00e9seau",
|
"label.add.network": "Ajouter un r\u00e9seau",
|
||||||
"label.add.network.acl": "Ajouter une r\u00e8gle d'acc\u00e8s r\u00e9seau ACL",
|
"label.add.network.acl": "Ajouter une r\u00e8gle d'acc\u00e8s r\u00e9seau ACL",
|
||||||
"label.add.network.acl.list": "Ajouter Liste ACL r\u00e9seau",
|
"label.add.network.acl": "Ajouter Liste ACL r\u00e9seau",
|
||||||
"label.add.network.offering": "Ajouter Offre R\u00e9seau",
|
"label.add.network.offering": "Ajouter Offre R\u00e9seau",
|
||||||
"label.add.new.gateway": "Ajouter une nouvelle passerelle",
|
"label.add.new.gateway": "Ajouter une nouvelle passerelle",
|
||||||
"label.add.new.tier": "Ajouter un nouveau tiers",
|
"label.add.new.tier": "Ajouter un nouveau tiers",
|
||||||
@ -334,7 +334,7 @@
|
|||||||
"label.default.use": "Utilisation par d\u00e9faut",
|
"label.default.use": "Utilisation par d\u00e9faut",
|
||||||
"label.default.view": "Vue par d\u00e9faut",
|
"label.default.view": "Vue par d\u00e9faut",
|
||||||
"label.delete": "Supprimer",
|
"label.delete": "Supprimer",
|
||||||
"label.delete.acl.list": "Supprimer Liste ACL",
|
"label.delete.acl": "Supprimer Liste ACL",
|
||||||
"label.delete.affinity.group": "Supprimer le groupe d'affinit\u00e9",
|
"label.delete.affinity.group": "Supprimer le groupe d'affinit\u00e9",
|
||||||
"label.delete.alerts": "Supprimer alertes",
|
"label.delete.alerts": "Supprimer alertes",
|
||||||
"label.delete.bigswitchbcf": "Supprimer contr\u00f4leur BigSwitch BCF",
|
"label.delete.bigswitchbcf": "Supprimer contr\u00f4leur BigSwitch BCF",
|
||||||
@ -419,7 +419,7 @@
|
|||||||
"label.dpd": "D\u00e9tection de pair mort",
|
"label.dpd": "D\u00e9tection de pair mort",
|
||||||
"label.driver": "Pilote",
|
"label.driver": "Pilote",
|
||||||
"label.edit": "Modifier",
|
"label.edit": "Modifier",
|
||||||
"label.edit.acl.list": "Edit ACL List",
|
"label.edit.acl": "Edit ACL",
|
||||||
"label.edit.acl.rule": "Modifier r\u00e8gle ACL",
|
"label.edit.acl.rule": "Modifier r\u00e8gle ACL",
|
||||||
"label.edit.project.details": "Modifier les d\u00e9tails du projet",
|
"label.edit.project.details": "Modifier les d\u00e9tails du projet",
|
||||||
"label.edit.role": "\u00c9diter R\u00f4le",
|
"label.edit.role": "\u00c9diter R\u00f4le",
|
||||||
@ -926,7 +926,6 @@
|
|||||||
"label.remove.vpc.offering": "Supprimer offre VPC",
|
"label.remove.vpc.offering": "Supprimer offre VPC",
|
||||||
"label.removing": "Suppression",
|
"label.removing": "Suppression",
|
||||||
"label.replace.acl": "Remplacer ACL",
|
"label.replace.acl": "Remplacer ACL",
|
||||||
"label.replace.acl.list": "Remplacer Liste ACL",
|
|
||||||
"label.required": "Requis",
|
"label.required": "Requis",
|
||||||
"label.requireshvm": "HVM",
|
"label.requireshvm": "HVM",
|
||||||
"label.requiresupgrade": "Mise \u00e0 jour n\u00e9cessaire",
|
"label.requiresupgrade": "Mise \u00e0 jour n\u00e9cessaire",
|
||||||
@ -1152,8 +1151,7 @@
|
|||||||
"label.usehttps": "Utiliser HTTPS",
|
"label.usehttps": "Utiliser HTTPS",
|
||||||
"label.usenewdiskoffering": "Replace disk offering?",
|
"label.usenewdiskoffering": "Replace disk offering?",
|
||||||
"label.user": "Utilisateur",
|
"label.user": "Utilisateur",
|
||||||
"label.userdata": "Donn\u00e9es Utilisateur",
|
"label.user.data": "Donn\u00e9es Utilisateur",
|
||||||
"label.userdatal2": "Donn\u00e9es utilisateur",
|
|
||||||
"label.username": "Identifiant",
|
"label.username": "Identifiant",
|
||||||
"label.users": "Utilisateurs",
|
"label.users": "Utilisateurs",
|
||||||
"label.utilization": "Utilisation",
|
"label.utilization": "Utilisation",
|
||||||
@ -1331,7 +1329,7 @@
|
|||||||
"message.confirm.archive.selected.alerts": "Confirmer l'archivage des alertes s\u00e9lectionn\u00e9es",
|
"message.confirm.archive.selected.alerts": "Confirmer l'archivage des alertes s\u00e9lectionn\u00e9es",
|
||||||
"message.confirm.archive.selected.events": "Confirmez l'archivage des \u00e9v\u00e9nements s\u00e9lectionn\u00e9s",
|
"message.confirm.archive.selected.events": "Confirmez l'archivage des \u00e9v\u00e9nements s\u00e9lectionn\u00e9s",
|
||||||
"message.confirm.attach.disk": "Confirmer le rattachement de ce disque ?",
|
"message.confirm.attach.disk": "Confirmer le rattachement de ce disque ?",
|
||||||
"message.confirm.delete.acl.list": "Confirmer la suppression de cette liste ACL ?",
|
"message.confirm.delete.acl": "Confirmer la suppression de cette liste ACL ?",
|
||||||
"message.confirm.delete.bigswitchbcf": "Confirmer que vous voulez supprimer ce contr\u00f4leur BigSwitch BCF",
|
"message.confirm.delete.bigswitchbcf": "Confirmer que vous voulez supprimer ce contr\u00f4leur BigSwitch BCF",
|
||||||
"message.confirm.delete.brocadevcs": "Confirmer la suppression du switch Brocade Vcs",
|
"message.confirm.delete.brocadevcs": "Confirmer la suppression du switch Brocade Vcs",
|
||||||
"message.confirm.delete.ciscoasa1000v": "Confirmez la suppression du CiscoASA1000v",
|
"message.confirm.delete.ciscoasa1000v": "Confirmez la suppression du CiscoASA1000v",
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
"label.accounts": "लेखा",
|
"label.accounts": "लेखा",
|
||||||
"label.accounttype": "खाता प्रकार",
|
"label.accounttype": "खाता प्रकार",
|
||||||
"label.aclid": "ACL",
|
"label.aclid": "ACL",
|
||||||
"label.aclname": "ACL नाम",
|
"label.acl.rule.name": "ACL नाम",
|
||||||
"label.actions": "क्रियाएँ",
|
"label.actions": "क्रियाएँ",
|
||||||
"label.add": "जोड़ें",
|
"label.add": "जोड़ें",
|
||||||
"label.adding": "जोड़ना",
|
"label.adding": "जोड़ना",
|
||||||
@ -410,7 +410,7 @@
|
|||||||
"label.usageunit": "Unit",
|
"label.usageunit": "Unit",
|
||||||
"label.usehttps": "HTTPS का उपयोग करें",
|
"label.usehttps": "HTTPS का उपयोग करें",
|
||||||
"label.user": "उपयोगकर्ता",
|
"label.user": "उपयोगकर्ता",
|
||||||
"label.userdata": "Userdata",
|
"label.user.data": "User Data",
|
||||||
"label.username": "उपयोगकर्ता नाम",
|
"label.username": "उपयोगकर्ता नाम",
|
||||||
"label.users": "उपयोगकर्ता",
|
"label.users": "उपयोगकर्ता",
|
||||||
"label.uuid": "ID",
|
"label.uuid": "ID",
|
||||||
|
|||||||
@ -14,12 +14,12 @@
|
|||||||
"label.account.specific": "Sz\u00e1mla-specifikus",
|
"label.account.specific": "Sz\u00e1mla-specifikus",
|
||||||
"label.accounts": "Sz\u00e1ml\u00e1k",
|
"label.accounts": "Sz\u00e1ml\u00e1k",
|
||||||
"label.accounttype": "Sz\u00e1mla t\u00edpus",
|
"label.accounttype": "Sz\u00e1mla t\u00edpus",
|
||||||
"label.acl.export": "Export ACLs",
|
"label.acl.export": "Export ACL rules",
|
||||||
"label.acl.id": "ACL ID",
|
"label.acl.id": "ACL ID",
|
||||||
"label.acl.list.rules": "ACL List Rules",
|
"label.acl.rules": "ACL Rules",
|
||||||
"label.acl.reason.description": "Enter the reason behind an ACL rule.",
|
"label.acl.reason.description": "Enter the reason behind an ACL rule.",
|
||||||
"label.aclid": "ACL",
|
"label.aclid": "ACL",
|
||||||
"label.aclname": "ACL n\u00e9v",
|
"label.acl.rule.name": "ACL n\u00e9v",
|
||||||
"label.acquire.new.ip": "\u00daj IP c\u00edm beszerz\u00e9se",
|
"label.acquire.new.ip": "\u00daj IP c\u00edm beszerz\u00e9se",
|
||||||
"label.acquire.new.secondary.ip": "\u00daj m\u00e1sodlagos IP c\u00edm beszerz\u00e9se",
|
"label.acquire.new.secondary.ip": "\u00daj m\u00e1sodlagos IP c\u00edm beszerz\u00e9se",
|
||||||
"label.action": "M\u0171velet",
|
"label.action": "M\u0171velet",
|
||||||
@ -119,8 +119,8 @@
|
|||||||
"label.activeviewersessions": "Akt\u00edv munkamenetek",
|
"label.activeviewersessions": "Akt\u00edv munkamenetek",
|
||||||
"label.add": "Felv\u00e9tel",
|
"label.add": "Felv\u00e9tel",
|
||||||
"label.add.account": "Sz\u00e1mla felv\u00e9tele",
|
"label.add.account": "Sz\u00e1mla felv\u00e9tele",
|
||||||
"label.add.acl": "ACL felv\u00e9tele",
|
"label.add.acl.rule": "ACL felv\u00e9tele",
|
||||||
"label.add.acl.list": "ACL lista felv\u00e9tele",
|
"label.add.acl": "ACL Lista felv\u00e9tele",
|
||||||
"label.add.affinity.group": "\u00daj affin\u00edt\u00e1si csoport felv\u00e9tele",
|
"label.add.affinity.group": "\u00daj affin\u00edt\u00e1si csoport felv\u00e9tele",
|
||||||
"label.add.baremetal.dhcp.device": "Baremetal DHCP eszk\u00f6z felv\u00e9tele",
|
"label.add.baremetal.dhcp.device": "Baremetal DHCP eszk\u00f6z felv\u00e9tele",
|
||||||
"label.add.bigswitchbcf.device": "BigSwitch BCF vez\u00e9rl\u0151 felv\u00e9tele",
|
"label.add.bigswitchbcf.device": "BigSwitch BCF vez\u00e9rl\u0151 felv\u00e9tele",
|
||||||
@ -142,12 +142,12 @@
|
|||||||
"label.add.ip.range": "IP c\u00edmtartom\u00e1ny felv\u00e9tele",
|
"label.add.ip.range": "IP c\u00edmtartom\u00e1ny felv\u00e9tele",
|
||||||
"label.add.isolated.network": "Izol\u00e1lt h\u00e1l\u00f3zat felv\u00e9tele",
|
"label.add.isolated.network": "Izol\u00e1lt h\u00e1l\u00f3zat felv\u00e9tele",
|
||||||
"label.add.ldap.account": "LDAP hozz\u00e1f\u00e9r\u00e9s felv\u00e9tele",
|
"label.add.ldap.account": "LDAP hozz\u00e1f\u00e9r\u00e9s felv\u00e9tele",
|
||||||
"label.add.list.name": "ACL lista n\u00e9v",
|
"label.add.acl.name": "ACL Lista n\u00e9v",
|
||||||
"label.add.more": "Tov\u00e1bbi felv\u00e9tele",
|
"label.add.more": "Tov\u00e1bbi felv\u00e9tele",
|
||||||
"label.add.netscaler.device": "Netscaler eszk\u00f6z felv\u00e9tele",
|
"label.add.netscaler.device": "Netscaler eszk\u00f6z felv\u00e9tele",
|
||||||
"label.add.network": "H\u00e1l\u00f3zat felv\u00e9tele",
|
"label.add.network": "H\u00e1l\u00f3zat felv\u00e9tele",
|
||||||
"label.add.network.acl": "H\u00e1l\u00f3zati ACL felv\u00e9tele",
|
"label.add.network.acl": "H\u00e1l\u00f3zati ACL felv\u00e9tele",
|
||||||
"label.add.network.acl.list": "H\u00e1l\u00f3zati ACL lista felv\u00e9tele",
|
"label.add.network.acl": "H\u00e1l\u00f3zati ACL Lista felv\u00e9tele",
|
||||||
"label.add.network.offering": "H\u00e1l\u00f3zati aj\u00e1nlat felv\u00e9tele",
|
"label.add.network.offering": "H\u00e1l\u00f3zati aj\u00e1nlat felv\u00e9tele",
|
||||||
"label.add.new.gateway": "\u00daj \u00e1tj\u00e1r\u00f3 felv\u00e9tele",
|
"label.add.new.gateway": "\u00daj \u00e1tj\u00e1r\u00f3 felv\u00e9tele",
|
||||||
"label.add.new.tier": "\u00daj r\u00e9teg felv\u00e9tele",
|
"label.add.new.tier": "\u00daj r\u00e9teg felv\u00e9tele",
|
||||||
@ -334,7 +334,7 @@
|
|||||||
"label.default.use": "Alap\u00e9rtelmezett haszn\u00e1lat",
|
"label.default.use": "Alap\u00e9rtelmezett haszn\u00e1lat",
|
||||||
"label.default.view": "Alap\u00e9rtelmezett n\u00e9zet",
|
"label.default.view": "Alap\u00e9rtelmezett n\u00e9zet",
|
||||||
"label.delete": "T\u00f6rl\u00e9s",
|
"label.delete": "T\u00f6rl\u00e9s",
|
||||||
"label.delete.acl.list": "ACL lista t\u00f6rl\u00e9se",
|
"label.delete.acl": "ACL Lista t\u00f6rl\u00e9se",
|
||||||
"label.delete.affinity.group": "Affin\u00edt\u00e1si csoport t\u00f6rl\u00e9se",
|
"label.delete.affinity.group": "Affin\u00edt\u00e1si csoport t\u00f6rl\u00e9se",
|
||||||
"label.delete.alerts": "T\u00f6rl\u00e9s riaszt\u00e1sok",
|
"label.delete.alerts": "T\u00f6rl\u00e9s riaszt\u00e1sok",
|
||||||
"label.delete.bigswitchbcf": "BigSwitch BCF vez\u00e9rl\u0151 elt\u00e1vol\u00edt\u00e1sa",
|
"label.delete.bigswitchbcf": "BigSwitch BCF vez\u00e9rl\u0151 elt\u00e1vol\u00edt\u00e1sa",
|
||||||
@ -419,7 +419,7 @@
|
|||||||
"label.driver": "Driver",
|
"label.driver": "Driver",
|
||||||
"label.dynamicscalingenabled": "dinamikus m\u00e9retez\u00e9s enged\u00e9lyezve",
|
"label.dynamicscalingenabled": "dinamikus m\u00e9retez\u00e9s enged\u00e9lyezve",
|
||||||
"label.edit": "Szerkeszt\u00e9s",
|
"label.edit": "Szerkeszt\u00e9s",
|
||||||
"label.edit.acl.list": "Edit ACL List",
|
"label.edit.acl": "Edit ACL",
|
||||||
"label.edit.acl.rule": "ACL szab\u00e1ly szerkeszt\u00e9se",
|
"label.edit.acl.rule": "ACL szab\u00e1ly szerkeszt\u00e9se",
|
||||||
"label.edit.project.details": "Projekt r\u00e9szletek szerkeszt\u00e9se",
|
"label.edit.project.details": "Projekt r\u00e9szletek szerkeszt\u00e9se",
|
||||||
"label.edit.role": "Edit Role",
|
"label.edit.role": "Edit Role",
|
||||||
@ -924,7 +924,6 @@
|
|||||||
"label.remove.vpc.offering": "VPC aj\u00e1nlat t\u00f6rl\u00e9se",
|
"label.remove.vpc.offering": "VPC aj\u00e1nlat t\u00f6rl\u00e9se",
|
||||||
"label.removing": "T\u00f6rl\u00e9s",
|
"label.removing": "T\u00f6rl\u00e9s",
|
||||||
"label.replace.acl": "ACL csere",
|
"label.replace.acl": "ACL csere",
|
||||||
"label.replace.acl.list": "ACL lista cser\u00e9je",
|
|
||||||
"label.required": "Sz\u00fcks\u00e9ges",
|
"label.required": "Sz\u00fcks\u00e9ges",
|
||||||
"label.requireshvm": "HVM",
|
"label.requireshvm": "HVM",
|
||||||
"label.requiresupgrade": "Friss\u00edt\u00e9st ig\u00e9nyel",
|
"label.requiresupgrade": "Friss\u00edt\u00e9st ig\u00e9nyel",
|
||||||
@ -1150,8 +1149,7 @@
|
|||||||
"label.usehttps": "HTTPS haszn\u00e1lata",
|
"label.usehttps": "HTTPS haszn\u00e1lata",
|
||||||
"label.usenewdiskoffering": "Replace disk offering?",
|
"label.usenewdiskoffering": "Replace disk offering?",
|
||||||
"label.user": "Felhaszn\u00e1l\u00f3",
|
"label.user": "Felhaszn\u00e1l\u00f3",
|
||||||
"label.userdata": "Felhaszn\u00e1l\u00f3 adat",
|
"label.user.data": "Felhaszn\u00e1l\u00f3 adat",
|
||||||
"label.userdatal2": "Felhaszn\u00e1l\u00f3i adat",
|
|
||||||
"label.username": "Felhaszn\u00e1l\u00f3n\u00e9v",
|
"label.username": "Felhaszn\u00e1l\u00f3n\u00e9v",
|
||||||
"label.users": "Felhaszn\u00e1l\u00f3k",
|
"label.users": "Felhaszn\u00e1l\u00f3k",
|
||||||
"label.utilization": "Utilisation",
|
"label.utilization": "Utilisation",
|
||||||
@ -1329,7 +1327,7 @@
|
|||||||
"message.confirm.archive.selected.alerts": "Er\u0151s\u00edtsd meg, hogy le akarod archiv\u00e1lni a kiv\u00e1lasztott riaszt\u00e1sokat!",
|
"message.confirm.archive.selected.alerts": "Er\u0151s\u00edtsd meg, hogy le akarod archiv\u00e1lni a kiv\u00e1lasztott riaszt\u00e1sokat!",
|
||||||
"message.confirm.archive.selected.events": "Er\u0151s\u00edtsd meg, hogy archiv\u00e1lni szeretn\u00e9d a kiv\u00e1lasztott esem\u00e9nyeket!",
|
"message.confirm.archive.selected.events": "Er\u0151s\u00edtsd meg, hogy archiv\u00e1lni szeretn\u00e9d a kiv\u00e1lasztott esem\u00e9nyeket!",
|
||||||
"message.confirm.attach.disk": "Biztosan csatolni szeretn\u00e9d a merevlemezt?",
|
"message.confirm.attach.disk": "Biztosan csatolni szeretn\u00e9d a merevlemezt?",
|
||||||
"message.confirm.delete.acl.list": "Biztosan t\u00f6r\u00f6lni akarod ezt a ACL list\u00e1t?",
|
"message.confirm.delete.acl": "Biztosan t\u00f6r\u00f6lni akarod ezt a ACL List\u00e1t?",
|
||||||
"message.confirm.delete.bigswitchbcf": "Er\u0151s\u00edtsd meg, hogy t\u00f6r\u00f6lni szeretn\u00e9d ezt a BigSwitch BCF vez\u00e9rl\u0151t!",
|
"message.confirm.delete.bigswitchbcf": "Er\u0151s\u00edtsd meg, hogy t\u00f6r\u00f6lni szeretn\u00e9d ezt a BigSwitch BCF vez\u00e9rl\u0151t!",
|
||||||
"message.confirm.delete.brocadevcs": "Er\u0151s\u00edtsd meg, hogy t\u00f6r\u00f6lni szeretn\u00e9d a Brocade Vcs Switch-et",
|
"message.confirm.delete.brocadevcs": "Er\u0151s\u00edtsd meg, hogy t\u00f6r\u00f6lni szeretn\u00e9d a Brocade Vcs Switch-et",
|
||||||
"message.confirm.delete.ciscoasa1000v": "Er\u0151s\u00edtsd meg, hogy t\u00f6r\u00f6lni akarod a CiscoASA1000v-t",
|
"message.confirm.delete.ciscoasa1000v": "Er\u0151s\u00edtsd meg, hogy t\u00f6r\u00f6lni akarod a CiscoASA1000v-t",
|
||||||
@ -1354,7 +1352,7 @@
|
|||||||
"message.confirm.remove.selected.events": "Er\u0151s\u00edtsd meg, hogy t\u00f6r\u00f6lni szeretn\u00e9d a kiv\u00e1lasztott esem\u00e9nyeket",
|
"message.confirm.remove.selected.events": "Er\u0151s\u00edtsd meg, hogy t\u00f6r\u00f6lni szeretn\u00e9d a kiv\u00e1lasztott esem\u00e9nyeket",
|
||||||
"message.confirm.remove.vmware.datacenter": "Er\u0151s\u00edtsd meg, hogy el akarod t\u00e1vol\u00edtani a VMware adatk\u00f6zpontot!",
|
"message.confirm.remove.vmware.datacenter": "Er\u0151s\u00edtsd meg, hogy el akarod t\u00e1vol\u00edtani a VMware adatk\u00f6zpontot!",
|
||||||
"message.confirm.remove.vpc.offering": "Biztos vagy abban, hogy t\u00f6r\u00f6lni akarod ezt a VPC aj\u00e1nlatot?",
|
"message.confirm.remove.vpc.offering": "Biztos vagy abban, hogy t\u00f6r\u00f6lni akarod ezt a VPC aj\u00e1nlatot?",
|
||||||
"message.confirm.replace.acl.new.one": "Le akarod cser\u00e9lni ez ACL list\u00e1t egy \u00fajjal?",
|
"message.confirm.replace.acl.new.one": "Le akarod cser\u00e9lni ez ACL List\u00e1t egy \u00fajjal?",
|
||||||
"message.confirm.scale.up.router.vm": "Biztosan fel akarod m\u00e9retezni a router VM-et?",
|
"message.confirm.scale.up.router.vm": "Biztosan fel akarod m\u00e9retezni a router VM-et?",
|
||||||
"message.confirm.scale.up.system.vm": "Biztosan fel akarod m\u00e9retezni a rendszer VM-et?",
|
"message.confirm.scale.up.system.vm": "Biztosan fel akarod m\u00e9retezni a rendszer VM-et?",
|
||||||
"message.confirm.start.lb.vm": "Er\u0151s\u00edtsd meg, hogy el akarod ind\u00edtani az LB VM-et!",
|
"message.confirm.start.lb.vm": "Er\u0151s\u00edtsd meg, hogy el akarod ind\u00edtani az LB VM-et!",
|
||||||
|
|||||||
@ -14,12 +14,12 @@
|
|||||||
"label.account.specific": "Specifico dell'Account",
|
"label.account.specific": "Specifico dell'Account",
|
||||||
"label.accounts": "Utenti",
|
"label.accounts": "Utenti",
|
||||||
"label.accounttype": "Account Type",
|
"label.accounttype": "Account Type",
|
||||||
"label.acl.export": "Export ACLs",
|
"label.acl.export": "Export ACL rules",
|
||||||
"label.acl.id": "ACL ID",
|
"label.acl.id": "ACL ID",
|
||||||
"label.acl.list.rules": "ACL List Rules",
|
"label.acl.rules": "ACL Rules",
|
||||||
"label.acl.reason.description": "Enter the reason behind an ACL rule.",
|
"label.acl.reason.description": "Enter the reason behind an ACL rule.",
|
||||||
"label.aclid": "ACL",
|
"label.aclid": "ACL",
|
||||||
"label.aclname": "ACL Name",
|
"label.acl.rule.name": "ACL Name",
|
||||||
"label.acquire.new.ip": "Acquisizione nuovo indirizzo IP",
|
"label.acquire.new.ip": "Acquisizione nuovo indirizzo IP",
|
||||||
"label.acquire.new.secondary.ip": "Acquisizione nuovo IP secondario",
|
"label.acquire.new.secondary.ip": "Acquisizione nuovo IP secondario",
|
||||||
"label.action": "Action",
|
"label.action": "Action",
|
||||||
@ -119,8 +119,8 @@
|
|||||||
"label.activeviewersessions": "Sessioni Attive",
|
"label.activeviewersessions": "Sessioni Attive",
|
||||||
"label.add": "Add",
|
"label.add": "Add",
|
||||||
"label.add.account": "Aggiungi un Account",
|
"label.add.account": "Aggiungi un Account",
|
||||||
"label.add.acl": "Aggiungere ACL",
|
"label.add.acl.rule": "Aggiungere ACL",
|
||||||
"label.add.acl.list": "Add ACL List",
|
"label.add.acl": "Add ACL",
|
||||||
"label.add.affinity.group": "Aggiungere un nuovo gruppo di affinit\u00e0",
|
"label.add.affinity.group": "Aggiungere un nuovo gruppo di affinit\u00e0",
|
||||||
"label.add.baremetal.dhcp.device": "Add Baremetal DHCP Device",
|
"label.add.baremetal.dhcp.device": "Add Baremetal DHCP Device",
|
||||||
"label.add.bigswitchbcf.device": "Aggiungere Controller BigSwitch BCF",
|
"label.add.bigswitchbcf.device": "Aggiungere Controller BigSwitch BCF",
|
||||||
@ -142,12 +142,12 @@
|
|||||||
"label.add.ip.range": "Aggiungere un IP Range",
|
"label.add.ip.range": "Aggiungere un IP Range",
|
||||||
"label.add.isolated.network": "Add Isolated Network",
|
"label.add.isolated.network": "Add Isolated Network",
|
||||||
"label.add.ldap.account": "Aggiungi un account LDAP",
|
"label.add.ldap.account": "Aggiungi un account LDAP",
|
||||||
"label.add.list.name": "ACL List Name",
|
"label.add.acl.name": "ACL Name",
|
||||||
"label.add.more": "Add More",
|
"label.add.more": "Add More",
|
||||||
"label.add.netscaler.device": "Aggiungere device Netscaler",
|
"label.add.netscaler.device": "Aggiungere device Netscaler",
|
||||||
"label.add.network": "Aggiungere una Rete",
|
"label.add.network": "Aggiungere una Rete",
|
||||||
"label.add.network.acl": "Aggiungere le ACL di rete",
|
"label.add.network.acl": "Aggiungere le ACL di rete",
|
||||||
"label.add.network.acl.list": "Add Network ACL List",
|
"label.add.network.acl": "Add Network ACL",
|
||||||
"label.add.network.offering": "Aggiungere offerta di rete",
|
"label.add.network.offering": "Aggiungere offerta di rete",
|
||||||
"label.add.new.gateway": "Aggiungere un nuovo gateway",
|
"label.add.new.gateway": "Aggiungere un nuovo gateway",
|
||||||
"label.add.new.tier": "Aggiungere un nuovo livello",
|
"label.add.new.tier": "Aggiungere un nuovo livello",
|
||||||
@ -334,7 +334,7 @@
|
|||||||
"label.default.use": "Default Use",
|
"label.default.use": "Default Use",
|
||||||
"label.default.view": "Vista di default",
|
"label.default.view": "Vista di default",
|
||||||
"label.delete": "Cancellare",
|
"label.delete": "Cancellare",
|
||||||
"label.delete.acl.list": "Delete ACL List",
|
"label.delete.acl": "Delete ACL",
|
||||||
"label.delete.affinity.group": "Cancellare Gruppo di Affinit\u00e0",
|
"label.delete.affinity.group": "Cancellare Gruppo di Affinit\u00e0",
|
||||||
"label.delete.alerts": "Cancella allarmi",
|
"label.delete.alerts": "Cancella allarmi",
|
||||||
"label.delete.bigswitchbcf": "Rimuovere Controller BigSwitch BCF",
|
"label.delete.bigswitchbcf": "Rimuovere Controller BigSwitch BCF",
|
||||||
@ -419,7 +419,7 @@
|
|||||||
"label.dpd": "Dead Peer Detection",
|
"label.dpd": "Dead Peer Detection",
|
||||||
"label.driver": "Driver",
|
"label.driver": "Driver",
|
||||||
"label.edit": "Modifica",
|
"label.edit": "Modifica",
|
||||||
"label.edit.acl.list": "Edit ACL List",
|
"label.edit.acl": "Edit ACL",
|
||||||
"label.edit.acl.rule": "Edit ACL rule",
|
"label.edit.acl.rule": "Edit ACL rule",
|
||||||
"label.edit.project.details": "Modificare i dettagli del progetto",
|
"label.edit.project.details": "Modificare i dettagli del progetto",
|
||||||
"label.edit.role": "Edit Role",
|
"label.edit.role": "Edit Role",
|
||||||
@ -924,7 +924,6 @@
|
|||||||
"label.remove.vpc.offering": "Remove VPC offering",
|
"label.remove.vpc.offering": "Remove VPC offering",
|
||||||
"label.removing": "Rimozione",
|
"label.removing": "Rimozione",
|
||||||
"label.replace.acl": "Replace ACL",
|
"label.replace.acl": "Replace ACL",
|
||||||
"label.replace.acl.list": "Replace ACL List",
|
|
||||||
"label.required": "Required",
|
"label.required": "Required",
|
||||||
"label.requireshvm": "HVM",
|
"label.requireshvm": "HVM",
|
||||||
"label.requiresupgrade": "Requires Upgrade",
|
"label.requiresupgrade": "Requires Upgrade",
|
||||||
@ -1150,8 +1149,7 @@
|
|||||||
"label.usehttps": "Utilizzare HTTPS",
|
"label.usehttps": "Utilizzare HTTPS",
|
||||||
"label.usenewdiskoffering": "Replace disk offering?",
|
"label.usenewdiskoffering": "Replace disk offering?",
|
||||||
"label.user": "User",
|
"label.user": "User",
|
||||||
"label.userdata": "Userdata",
|
"label.user.data": "User Data",
|
||||||
"label.userdatal2": "User Data",
|
|
||||||
"label.username": "Username",
|
"label.username": "Username",
|
||||||
"label.users": "Users",
|
"label.users": "Users",
|
||||||
"label.utilization": "Utilisation",
|
"label.utilization": "Utilisation",
|
||||||
@ -1329,7 +1327,7 @@
|
|||||||
"message.confirm.archive.selected.alerts": "Please confirm you would like to archive the selected alerts",
|
"message.confirm.archive.selected.alerts": "Please confirm you would like to archive the selected alerts",
|
||||||
"message.confirm.archive.selected.events": "Please confirm you would like to archive the selected events",
|
"message.confirm.archive.selected.events": "Please confirm you would like to archive the selected events",
|
||||||
"message.confirm.attach.disk": "Are you sure you want to attach disk?",
|
"message.confirm.attach.disk": "Are you sure you want to attach disk?",
|
||||||
"message.confirm.delete.acl.list": "Are you sure you want to delete this ACL list?",
|
"message.confirm.delete.acl": "Are you sure you want to delete this ACL?",
|
||||||
"message.confirm.delete.bigswitchbcf": "Please confirm that you would like to delete this BigSwitch BCF Controller",
|
"message.confirm.delete.bigswitchbcf": "Please confirm that you would like to delete this BigSwitch BCF Controller",
|
||||||
"message.confirm.delete.brocadevcs": "Please confirm that you would like to delete Brocade Vcs Switch",
|
"message.confirm.delete.brocadevcs": "Please confirm that you would like to delete Brocade Vcs Switch",
|
||||||
"message.confirm.delete.ciscoasa1000v": "Please confirm you want to delete CiscoASA1000v",
|
"message.confirm.delete.ciscoasa1000v": "Please confirm you want to delete CiscoASA1000v",
|
||||||
|
|||||||
@ -58,11 +58,11 @@
|
|||||||
"label.access.kubernetes.nodes": "Kubernetesノードに接続",
|
"label.access.kubernetes.nodes": "Kubernetesノードに接続",
|
||||||
"label.acl.export": "エクスポートACLs",
|
"label.acl.export": "エクスポートACLs",
|
||||||
"label.acl.id": "ACL ID",
|
"label.acl.id": "ACL ID",
|
||||||
"label.acl.list.rules": "ACLルールのリスト",
|
"label.acl.rules": "ACLルールのリスト",
|
||||||
"label.acl.reason.description": "ACLルールの理由を入力してください。",
|
"label.acl.reason.description": "ACLルールの理由を入力してください。",
|
||||||
"label.acl.replaced": "ACLが置き換えられました",
|
"label.acl.replaced": "ACLが置き換えられました",
|
||||||
"label.aclid": "ACL",
|
"label.aclid": "ACL",
|
||||||
"label.aclname": "ACL名",
|
"label.acl.rule.name": "ACL名",
|
||||||
"label.acltotal": "ネットワークACL合計",
|
"label.acltotal": "ネットワークACL合計",
|
||||||
"label.acquire.new.ip": "新しいIPアドレスの取得",
|
"label.acquire.new.ip": "新しいIPアドレスの取得",
|
||||||
"label.acquire.new.secondary.ip": "セカンダリIPアドレスの取得",
|
"label.acquire.new.secondary.ip": "セカンダリIPアドレスの取得",
|
||||||
@ -298,8 +298,8 @@
|
|||||||
"label.add.account": "アカウント追加",
|
"label.add.account": "アカウント追加",
|
||||||
"label.add.accounts": "アカウント追加",
|
"label.add.accounts": "アカウント追加",
|
||||||
"label.add.accounts.to": "アカウントの追加先:",
|
"label.add.accounts.to": "アカウントの追加先:",
|
||||||
"label.add.acl": "ACL追加",
|
"label.add.acl.rule": "ACL追加",
|
||||||
"label.add.acl.list": "ACL一覧追加",
|
"label.add.acl": "ACL一覧追加",
|
||||||
"label.add.affinity.group": "新しいアフィニティグループ追加",
|
"label.add.affinity.group": "新しいアフィニティグループ追加",
|
||||||
"label.add.baremetal.dhcp.device": "ベアメタルDHCPデバイス追加",
|
"label.add.baremetal.dhcp.device": "ベアメタルDHCPデバイス追加",
|
||||||
"label.add.baremetal.rack.configuration": "ベアメタルラック設定追加",
|
"label.add.baremetal.rack.configuration": "ベアメタルラック設定追加",
|
||||||
@ -333,14 +333,14 @@
|
|||||||
"label.add.l2.guest.network": "L2ゲストネットワーク追加",
|
"label.add.l2.guest.network": "L2ゲストネットワーク追加",
|
||||||
"label.add.ldap.account": "LDAPアカウント追加",
|
"label.add.ldap.account": "LDAPアカウント追加",
|
||||||
"label.add.ldap.list.users": "LDAPユーザー一覧",
|
"label.add.ldap.list.users": "LDAPユーザー一覧",
|
||||||
"label.add.list.name": "ACL一覧名",
|
"label.add.acl.name": "ACL一覧名",
|
||||||
"label.add.load.balancer": "ロードバランサー追加",
|
"label.add.load.balancer": "ロードバランサー追加",
|
||||||
"label.add.management.ip.range": "マネージメントIP範囲追加",
|
"label.add.management.ip.range": "マネージメントIP範囲追加",
|
||||||
"label.add.more": "その他の項目追加",
|
"label.add.more": "その他の項目追加",
|
||||||
"label.add.netscaler.device": "NetScalerデバイス追加",
|
"label.add.netscaler.device": "NetScalerデバイス追加",
|
||||||
"label.add.network": "ネットワーク追加",
|
"label.add.network": "ネットワーク追加",
|
||||||
"label.add.network.acl": "ネットワークACL追加",
|
"label.add.network.acl": "ネットワークACL追加",
|
||||||
"label.add.network.acl.list": "ネットワークACL一覧追加",
|
"label.add.network.acl": "ネットワークACL一覧追加",
|
||||||
"label.add.network.device": "ネットワークデバイス追加",
|
"label.add.network.device": "ネットワークデバイス追加",
|
||||||
"label.add.network.offering": "ネットワークオファリング追加",
|
"label.add.network.offering": "ネットワークオファリング追加",
|
||||||
"label.add.new.f5": "新しいF5追加",
|
"label.add.new.f5": "新しいF5追加",
|
||||||
@ -718,7 +718,7 @@
|
|||||||
"label.default.view": "デフォルトビュー",
|
"label.default.view": "デフォルトビュー",
|
||||||
"label.defaultnetwork": "デフォルトネットワーク",
|
"label.defaultnetwork": "デフォルトネットワーク",
|
||||||
"label.delete": "削除",
|
"label.delete": "削除",
|
||||||
"label.delete.acl.list": "ACL一覧削除",
|
"label.delete.acl": "ACL一覧削除",
|
||||||
"label.delete.affinity.group": "アフィニティグループ削除",
|
"label.delete.affinity.group": "アフィニティグループ削除",
|
||||||
"label.delete.alerts": "アラート削除",
|
"label.delete.alerts": "アラート削除",
|
||||||
"label.delete.backup": "バックアップ削除",
|
"label.delete.backup": "バックアップ削除",
|
||||||
@ -872,7 +872,7 @@
|
|||||||
"label.dynamicscalingenabled": "ダイナミックスケーリング有効",
|
"label.dynamicscalingenabled": "ダイナミックスケーリング有効",
|
||||||
"label.dynamicscalingenabled.tooltip": "テンプレート、サービスオファリング、およびグローバル設定で動的スケーリングが有効になっている場合にのみ、VMは動的にスケーリングできます。",
|
"label.dynamicscalingenabled.tooltip": "テンプレート、サービスオファリング、およびグローバル設定で動的スケーリングが有効になっている場合にのみ、VMは動的にスケーリングできます。",
|
||||||
"label.edit": "編集",
|
"label.edit": "編集",
|
||||||
"label.edit.acl.list": "ACL一覧編集",
|
"label.edit.acl": "ACL一覧編集",
|
||||||
"label.edit.acl.rule": "ACLルール編集",
|
"label.edit.acl.rule": "ACLルール編集",
|
||||||
"label.edit.affinity.group": "アフィニティグループ編集",
|
"label.edit.affinity.group": "アフィニティグループ編集",
|
||||||
"label.edit.lb.rule": "LBルール編集",
|
"label.edit.lb.rule": "LBルール編集",
|
||||||
@ -1498,7 +1498,7 @@
|
|||||||
"label.netscaler.vpx": "NetScaler VPXロードバランサー",
|
"label.netscaler.vpx": "NetScaler VPXロードバランサー",
|
||||||
"label.network": "ネットワーク",
|
"label.network": "ネットワーク",
|
||||||
"label.network.acl": "ネットワークACL",
|
"label.network.acl": "ネットワークACL",
|
||||||
"label.network.acl.lists": "ネットワークACL一覧",
|
"label.network.acls": "ネットワークACL一覧",
|
||||||
"label.network.acls": "ネットワークACL",
|
"label.network.acls": "ネットワークACL",
|
||||||
"label.network.addvm": "VMへのネットワーク追加",
|
"label.network.addvm": "VMへのネットワーク追加",
|
||||||
"label.network.desc": "ネットワークの説明",
|
"label.network.desc": "ネットワークの説明",
|
||||||
@ -1871,7 +1871,6 @@
|
|||||||
"label.removing": "削除しています",
|
"label.removing": "削除しています",
|
||||||
"label.removing.user": "ユーザーを削除しています",
|
"label.removing.user": "ユーザーを削除しています",
|
||||||
"label.replace.acl": "ACLの置き換え",
|
"label.replace.acl": "ACLの置き換え",
|
||||||
"label.replace.acl.list": "ACL一覧の置き換え",
|
|
||||||
"label.report.bug": "問題レポート",
|
"label.report.bug": "問題レポート",
|
||||||
"label.required": "必須です",
|
"label.required": "必須です",
|
||||||
"label.requireshvm": "HVM",
|
"label.requireshvm": "HVM",
|
||||||
@ -2321,8 +2320,7 @@
|
|||||||
"label.user.details": "ユーザーの詳細",
|
"label.user.details": "ユーザーの詳細",
|
||||||
"label.user.source": "ソース",
|
"label.user.source": "ソース",
|
||||||
"label.user.vm": "ユーザーVM",
|
"label.user.vm": "ユーザーVM",
|
||||||
"label.userdata": "ユーザーデータ",
|
"label.user.data": "ユーザーデータ",
|
||||||
"label.userdatal2": "ユーザーデータ",
|
|
||||||
"label.username": "ユーザー名",
|
"label.username": "ユーザー名",
|
||||||
"label.users": "ユーザー",
|
"label.users": "ユーザー",
|
||||||
"label.usersource": "ユーザータイプ",
|
"label.usersource": "ユーザータイプ",
|
||||||
@ -2727,7 +2725,7 @@
|
|||||||
"message.confirm.dedicate.host.domain.account": "このホストをドメイン/アカウント専用に設定してもよろしいですか?",
|
"message.confirm.dedicate.host.domain.account": "このホストをドメイン/アカウント専用に設定してもよろしいですか?",
|
||||||
"message.confirm.dedicate.pod.domain.account": "このポッドをドメイン/アカウント専用に設定してもよろしいですか?",
|
"message.confirm.dedicate.pod.domain.account": "このポッドをドメイン/アカウント専用に設定してもよろしいですか?",
|
||||||
"message.confirm.dedicate.zone": "このゾーンをドメイン/アカウント専用に設定してもよろしいですか?",
|
"message.confirm.dedicate.zone": "このゾーンをドメイン/アカウント専用に設定してもよろしいですか?",
|
||||||
"message.confirm.delete.acl.list": "このACL一覧を削除してもよろしいですか?",
|
"message.confirm.delete.acl": "このACL一覧を削除してもよろしいですか?",
|
||||||
"message.confirm.delete.alert": "このアラートを削除してもよろしいですか?",
|
"message.confirm.delete.alert": "このアラートを削除してもよろしいですか?",
|
||||||
"message.confirm.delete.baremetal.rack.configuration": "ベアメタルラック設定を削除してもよろしいですか?",
|
"message.confirm.delete.baremetal.rack.configuration": "ベアメタルラック設定を削除してもよろしいですか?",
|
||||||
"message.confirm.delete.bigswitchbcf": "このBigSwitchBCFコントローラーを削除してもよろしいですか?",
|
"message.confirm.delete.bigswitchbcf": "このBigSwitchBCFコントローラーを削除してもよろしいですか?",
|
||||||
|
|||||||
@ -32,10 +32,10 @@
|
|||||||
"label.accounttype": "\uacc4\uc815 \uc720\ud615",
|
"label.accounttype": "\uacc4\uc815 \uc720\ud615",
|
||||||
"label.acl.export": "ACL \ub0b4\ubcf4\ub0b4\uae30",
|
"label.acl.export": "ACL \ub0b4\ubcf4\ub0b4\uae30",
|
||||||
"label.acl.id": "ACL ID",
|
"label.acl.id": "ACL ID",
|
||||||
"label.acl.list.rules": "ACL \ubaa9\ub85d \uaddc\uce59",
|
"label.acl.rules": "ACL \ubaa9\ub85d \uaddc\uce59",
|
||||||
"label.acl.reason.description": "ACL \uaddc\uce59 \ub4a4\uc5d0 \uc124\uba85\uc744 \uc785\ub825\ud558\uc2ed\uc2dc\uc624.",
|
"label.acl.reason.description": "ACL \uaddc\uce59 \ub4a4\uc5d0 \uc124\uba85\uc744 \uc785\ub825\ud558\uc2ed\uc2dc\uc624.",
|
||||||
"label.aclid": "ACL",
|
"label.aclid": "ACL",
|
||||||
"label.aclname": "ACL \uc774\ub984",
|
"label.acl.rule.name": "ACL \uc774\ub984",
|
||||||
"label.acquire.new.ip": "\uc0c8 IP \uc8fc\uc18c \uac00\uc838\uc624\uae30",
|
"label.acquire.new.ip": "\uc0c8 IP \uc8fc\uc18c \uac00\uc838\uc624\uae30",
|
||||||
"label.acquire.new.secondary.ip": "\uc0c8 \ubcf4\uc870 IP \uc8fc\uc18c \uac00\uc838\uc624\uae30",
|
"label.acquire.new.secondary.ip": "\uc0c8 \ubcf4\uc870 IP \uc8fc\uc18c \uac00\uc838\uc624\uae30",
|
||||||
"label.acquiring.ip": "IP \uac00\uc838\uc624\uae30",
|
"label.acquiring.ip": "IP \uac00\uc838\uc624\uae30",
|
||||||
@ -153,8 +153,8 @@
|
|||||||
"label.activeviewersessions": "\ud65c\uc131 \uc138\uc158",
|
"label.activeviewersessions": "\ud65c\uc131 \uc138\uc158",
|
||||||
"label.add": "\ucd94\uac00",
|
"label.add": "\ucd94\uac00",
|
||||||
"label.add.account": "\uacc4\uc815 \ucd94\uac00",
|
"label.add.account": "\uacc4\uc815 \ucd94\uac00",
|
||||||
"label.add.acl": "\uad8c\ud55c \uad00\ub9ac(ACL) \ucd94\uac00",
|
"label.add.acl.rule": "\uad8c\ud55c \uad00\ub9ac(ACL) \ucd94\uac00",
|
||||||
"label.add.acl.list": "ACL \ubaa9\ub85d \ucd94\uac00",
|
"label.add.acl": "ACL \ubaa9\ub85d \ucd94\uac00",
|
||||||
"label.add.affinity.group": "\uc0c8 Affinity \uadf8\ub8f9 \ucd94\uac00",
|
"label.add.affinity.group": "\uc0c8 Affinity \uadf8\ub8f9 \ucd94\uac00",
|
||||||
"label.add.baremetal.dhcp.device": "Baremetal DHCP \uc7a5\uce58 \ucd94\uac00",
|
"label.add.baremetal.dhcp.device": "Baremetal DHCP \uc7a5\uce58 \ucd94\uac00",
|
||||||
"label.add.bigswitchbcf.device": "BigSwitch BCF \ucee8\ud2b8\ub864\ub7ec \ucd94\uac00",
|
"label.add.bigswitchbcf.device": "BigSwitch BCF \ucee8\ud2b8\ub864\ub7ec \ucd94\uac00",
|
||||||
@ -178,12 +178,12 @@
|
|||||||
"label.add.isolated.network": "isolated \ub124\ud2b8\uc6cc\ud06c \ucd94\uac00",
|
"label.add.isolated.network": "isolated \ub124\ud2b8\uc6cc\ud06c \ucd94\uac00",
|
||||||
"label.add.kubernetes.cluster": "\ucfe0\ubc84\ub124\ud14c\uc2a4 \ud074\ub7ec\uc2a4\ud130 \ucd94\uac00",
|
"label.add.kubernetes.cluster": "\ucfe0\ubc84\ub124\ud14c\uc2a4 \ud074\ub7ec\uc2a4\ud130 \ucd94\uac00",
|
||||||
"label.add.ldap.account": "LDAP \uacc4\uc815 \ucd94\uac00",
|
"label.add.ldap.account": "LDAP \uacc4\uc815 \ucd94\uac00",
|
||||||
"label.add.list.name": "ACL \ubaa9\ub85d \uc774\ub984",
|
"label.add.acl.name": "ACL \ubaa9\ub85d \uc774\ub984",
|
||||||
"label.add.more": "\ub2e4\ub978 \ud56d\ubaa9 \ucd94\uac00",
|
"label.add.more": "\ub2e4\ub978 \ud56d\ubaa9 \ucd94\uac00",
|
||||||
"label.add.netscaler.device": "Netscaler \uc7a5\uce58 \ucd94\uac00",
|
"label.add.netscaler.device": "Netscaler \uc7a5\uce58 \ucd94\uac00",
|
||||||
"label.add.network": "\ub124\ud2b8\uc6cc\ud06c \ucd94\uac00",
|
"label.add.network": "\ub124\ud2b8\uc6cc\ud06c \ucd94\uac00",
|
||||||
"label.add.network.acl": "\ub124\ud2b8\uc6cc\ud06c \uad8c\ud55c \uad00\ub9ac(ACL) \ucd94\uac00",
|
"label.add.network.acl": "\ub124\ud2b8\uc6cc\ud06c \uad8c\ud55c \uad00\ub9ac(ACL) \ucd94\uac00",
|
||||||
"label.add.network.acl.list": "\ub124\ud2b8\uc6cc\ud06c ACL \ubaa9\ub85d \ucd94\uac00",
|
"label.add.network.acl": "\ub124\ud2b8\uc6cc\ud06c ACL \ubaa9\ub85d \ucd94\uac00",
|
||||||
"label.add.network.offering": "\ub124\ud2b8\uc6cc\ud06c \uc624\ud37c\ub9c1 \ucd94\uac00",
|
"label.add.network.offering": "\ub124\ud2b8\uc6cc\ud06c \uc624\ud37c\ub9c1 \ucd94\uac00",
|
||||||
"label.add.new.gateway": "\uc0c8 \uac8c\uc774\ud2b8\uc6e8\uc774 \ucd94\uac00\ud558\uae30",
|
"label.add.new.gateway": "\uc0c8 \uac8c\uc774\ud2b8\uc6e8\uc774 \ucd94\uac00\ud558\uae30",
|
||||||
"label.add.new.tier": "\uc0c8 \uc11c\ube0c\ub137 \ucd94\uac00",
|
"label.add.new.tier": "\uc0c8 \uc11c\ube0c\ub137 \ucd94\uac00",
|
||||||
@ -436,7 +436,7 @@
|
|||||||
"label.default.view": "\uae30\ubcf8 \ubcf4\uae30",
|
"label.default.view": "\uae30\ubcf8 \ubcf4\uae30",
|
||||||
"label.defaultnetwork": "\uae30\ubcf8 \ub124\ud2b8\uc6cc\ud06c",
|
"label.defaultnetwork": "\uae30\ubcf8 \ub124\ud2b8\uc6cc\ud06c",
|
||||||
"label.delete": "\uc0ad\uc81c",
|
"label.delete": "\uc0ad\uc81c",
|
||||||
"label.delete.acl.list": "ACL \ubaa9\ub85d \uc0ad\uc81c",
|
"label.delete.acl": "ACL \ubaa9\ub85d \uc0ad\uc81c",
|
||||||
"label.delete.affinity.group": "Affinity \uadf8\ub8f9 \uc0ad\uc81c",
|
"label.delete.affinity.group": "Affinity \uadf8\ub8f9 \uc0ad\uc81c",
|
||||||
"label.delete.alerts": "\uc54c\ub9bc \uc0ad\uc81c",
|
"label.delete.alerts": "\uc54c\ub9bc \uc0ad\uc81c",
|
||||||
"label.delete.backup": "\ubc31\uc5c5 \uc0ad\uc81c",
|
"label.delete.backup": "\ubc31\uc5c5 \uc0ad\uc81c",
|
||||||
@ -549,7 +549,7 @@
|
|||||||
"label.dpd": "Dead \ud53c\uc5b4 \uac10\uc9c0",
|
"label.dpd": "Dead \ud53c\uc5b4 \uac10\uc9c0",
|
||||||
"label.driver": "\ub4dc\ub77c\uc774\ubc84",
|
"label.driver": "\ub4dc\ub77c\uc774\ubc84",
|
||||||
"label.edit": "\ud3b8\uc9d1",
|
"label.edit": "\ud3b8\uc9d1",
|
||||||
"label.edit.acl.list": "ACL \ubaa9\ub85d \ud3b8\uc9d1",
|
"label.edit.acl": "ACL \ubaa9\ub85d \ud3b8\uc9d1",
|
||||||
"label.edit.acl.rule": "ACL \uaddc\uce59 \ud3b8\uc9d1",
|
"label.edit.acl.rule": "ACL \uaddc\uce59 \ud3b8\uc9d1",
|
||||||
"label.edit.project.details": "\ud504\ub85c\uc81d\ud2b8 \uc0c1\uc138 \ud3b8\uc9d1",
|
"label.edit.project.details": "\ud504\ub85c\uc81d\ud2b8 \uc0c1\uc138 \ud3b8\uc9d1",
|
||||||
"label.edit.project.role": "\ud504\ub85c\uc81d\ud2b8 \uc5ed\ud560 \ud3b8\uc9d1",
|
"label.edit.project.role": "\ud504\ub85c\uc81d\ud2b8 \uc5ed\ud560 \ud3b8\uc9d1",
|
||||||
@ -985,7 +985,7 @@
|
|||||||
"label.netscaler.vpx": "NetScaler VPX \ub85c\ub4dc\ubc38\ub7f0\uc11c",
|
"label.netscaler.vpx": "NetScaler VPX \ub85c\ub4dc\ubc38\ub7f0\uc11c",
|
||||||
"label.network": "\ub124\ud2b8\uc6cc\ud06c",
|
"label.network": "\ub124\ud2b8\uc6cc\ud06c",
|
||||||
"label.network.acl": "\ub124\ud2b8\uc6cc\ud06c \uad8c\ud55c \uad00\ub9ac(ACL)",
|
"label.network.acl": "\ub124\ud2b8\uc6cc\ud06c \uad8c\ud55c \uad00\ub9ac(ACL)",
|
||||||
"label.network.acl.lists": "Network ACL \ubaa9\ub85d",
|
"label.network.acls": "Network ACL \ubaa9\ub85d",
|
||||||
"label.network.addvm": "VM\uc5d0 \ub124\ud2b8\uc6cc\ud06c \ucd94\uac00",
|
"label.network.addvm": "VM\uc5d0 \ub124\ud2b8\uc6cc\ud06c \ucd94\uac00",
|
||||||
"label.network.desc": "\ub124\ud2b8\uc6cc\ud06c \uc124\uba85",
|
"label.network.desc": "\ub124\ud2b8\uc6cc\ud06c \uc124\uba85",
|
||||||
"label.network.domain": "\ub124\ud2b8\uc6cc\ud06c \ub3c4\uba54\uc778",
|
"label.network.domain": "\ub124\ud2b8\uc6cc\ud06c \ub3c4\uba54\uc778",
|
||||||
@ -1251,7 +1251,6 @@
|
|||||||
"label.remove.vpc.offering": "VPC \uc624\ud37c\ub9c1 \uc0ad\uc81c",
|
"label.remove.vpc.offering": "VPC \uc624\ud37c\ub9c1 \uc0ad\uc81c",
|
||||||
"label.removing": "\uc0ad\uc81c\ud558\ub294 \uc911...",
|
"label.removing": "\uc0ad\uc81c\ud558\ub294 \uc911...",
|
||||||
"label.replace.acl": "ACL \uad50\uccb4",
|
"label.replace.acl": "ACL \uad50\uccb4",
|
||||||
"label.replace.acl.list": "ACL \ubaa9\ub85d \uad50\uccb4",
|
|
||||||
"label.report.bug": "\uc774\uc288 \ub9ac\ud3ec\ud2b8",
|
"label.report.bug": "\uc774\uc288 \ub9ac\ud3ec\ud2b8",
|
||||||
"label.required": "\ud544\uc218 \uc0ac\ud56d",
|
"label.required": "\ud544\uc218 \uc0ac\ud56d",
|
||||||
"label.requireshvm": "HVM",
|
"label.requireshvm": "HVM",
|
||||||
@ -1560,8 +1559,7 @@
|
|||||||
"label.usenewdiskoffering": "\ub514\uc2a4\ud06c \uc624\ud37c\ub9c1\uc744 \ubcc0\uacbd\ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c?",
|
"label.usenewdiskoffering": "\ub514\uc2a4\ud06c \uc624\ud37c\ub9c1\uc744 \ubcc0\uacbd\ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c?",
|
||||||
"label.user": "\uc0ac\uc6a9\uc790",
|
"label.user": "\uc0ac\uc6a9\uc790",
|
||||||
"label.user.conflict": "\ucda9\ub3cc",
|
"label.user.conflict": "\ucda9\ub3cc",
|
||||||
"label.userdata": "\uc0ac\uc6a9\uc790 \ub370\uc774\ud130",
|
"label.user.data": "\uc0ac\uc6a9\uc790 \ub370\uc774\ud130",
|
||||||
"label.userdatal2": "\uc0ac\uc6a9\uc790 \ub370\uc774\ud130",
|
|
||||||
"label.username": "\uc0ac\uc6a9\uc790 \uc774\ub984",
|
"label.username": "\uc0ac\uc6a9\uc790 \uc774\ub984",
|
||||||
"label.users": "\uc0ac\uc6a9\uc790",
|
"label.users": "\uc0ac\uc6a9\uc790",
|
||||||
"label.usersource": "\uc0ac\uc6a9\uc790 \uc720\ud615",
|
"label.usersource": "\uc0ac\uc6a9\uc790 \uc720\ud615",
|
||||||
@ -1818,7 +1816,7 @@
|
|||||||
"message.confirm.archive.selected.events": "\uc120\ud0dd\ud55c \uc774\ubca4\ud2b8\ub97c \ubcf4\uad00\ud560 \uac83\uc778\uc9c0 \ud655\uc778\ud558\uc2ed\uc2dc\uc624.",
|
"message.confirm.archive.selected.events": "\uc120\ud0dd\ud55c \uc774\ubca4\ud2b8\ub97c \ubcf4\uad00\ud560 \uac83\uc778\uc9c0 \ud655\uc778\ud558\uc2ed\uc2dc\uc624.",
|
||||||
"message.confirm.attach.disk": "\ub514\uc2a4\ud06c\ub97c \uc5f0\uacb0 \ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c?",
|
"message.confirm.attach.disk": "\ub514\uc2a4\ud06c\ub97c \uc5f0\uacb0 \ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c?",
|
||||||
"message.confirm.configure.ovs": "Ovs\ub97c \uad6c\uc131\ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c?",
|
"message.confirm.configure.ovs": "Ovs\ub97c \uad6c\uc131\ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c?",
|
||||||
"message.confirm.delete.acl.list": "\uc774 ACL \ubaa9\ub85d\uc744 \uc0ad\uc81c \ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c?",
|
"message.confirm.delete.acl": "\uc774 ACL \ubaa9\ub85d\uc744 \uc0ad\uc81c \ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c?",
|
||||||
"message.confirm.delete.bigswitchbcf": "\uc774 BigSwitch BCF \ucee8\ud2b8\ub864\ub7ec\ub97c \uc0ad\uc81c\ud560 \uac83\uc778\uc9c0 \ud655\uc778\ud558\uc2ed\uc2dc\uc624.",
|
"message.confirm.delete.bigswitchbcf": "\uc774 BigSwitch BCF \ucee8\ud2b8\ub864\ub7ec\ub97c \uc0ad\uc81c\ud560 \uac83\uc778\uc9c0 \ud655\uc778\ud558\uc2ed\uc2dc\uc624.",
|
||||||
"message.confirm.delete.brocadevcs": "Brocade Vcs \uc2a4\uc704\uce58\ub97c \uc0ad\uc81c\ud560 \uac83\uc778\uc9c0 \ud655\uc778\ud558\uc2ed\uc2dc\uc624.",
|
"message.confirm.delete.brocadevcs": "Brocade Vcs \uc2a4\uc704\uce58\ub97c \uc0ad\uc81c\ud560 \uac83\uc778\uc9c0 \ud655\uc778\ud558\uc2ed\uc2dc\uc624.",
|
||||||
"message.confirm.delete.ciscoasa1000v": "CiscoASA1000\uc744 \uc0ad\uc81c\ud560 \uac83\uc778\uc9c0 \ud655\uc778\ud558\uc2ed\uc2dc\uc624.",
|
"message.confirm.delete.ciscoasa1000v": "CiscoASA1000\uc744 \uc0ad\uc81c\ud560 \uac83\uc778\uc9c0 \ud655\uc778\ud558\uc2ed\uc2dc\uc624.",
|
||||||
|
|||||||
@ -14,12 +14,12 @@
|
|||||||
"label.account.specific": "Kontospesifikk",
|
"label.account.specific": "Kontospesifikk",
|
||||||
"label.accounts": "Kontoer",
|
"label.accounts": "Kontoer",
|
||||||
"label.accounttype": "Kontotype",
|
"label.accounttype": "Kontotype",
|
||||||
"label.acl.export": "Export ACLs",
|
"label.acl.export": "Export ACL rules",
|
||||||
"label.acl.id": "ACL ID",
|
"label.acl.id": "ACL ID",
|
||||||
"label.acl.list.rules": "ACL Liste Regler",
|
"label.acl.rules": "ACL Liste Regler",
|
||||||
"label.acl.reason.description": "Enter the reason behind an ACL rule.",
|
"label.acl.reason.description": "Enter the reason behind an ACL rule.",
|
||||||
"label.aclid": "ACL",
|
"label.aclid": "ACL",
|
||||||
"label.aclname": "ACL Navn",
|
"label.acl.rule.name": "ACL Navn",
|
||||||
"label.acquire.new.ip": "Tilegne ny IP",
|
"label.acquire.new.ip": "Tilegne ny IP",
|
||||||
"label.acquire.new.secondary.ip": "Tilegne ny sekund\u00e6r IP",
|
"label.acquire.new.secondary.ip": "Tilegne ny sekund\u00e6r IP",
|
||||||
"label.action": "Handling",
|
"label.action": "Handling",
|
||||||
@ -119,8 +119,8 @@
|
|||||||
"label.activeviewersessions": "Aktive sesjoner",
|
"label.activeviewersessions": "Aktive sesjoner",
|
||||||
"label.add": "Legg til",
|
"label.add": "Legg til",
|
||||||
"label.add.account": "Legg til konto",
|
"label.add.account": "Legg til konto",
|
||||||
"label.add.acl": "Legg til ACL",
|
"label.add.acl.rule": "Legg til ACL",
|
||||||
"label.add.acl.list": "Legg til ACL liste",
|
"label.add.acl": "Legg til ACL liste",
|
||||||
"label.add.affinity.group": "Legg til affinitetsgruppe",
|
"label.add.affinity.group": "Legg til affinitetsgruppe",
|
||||||
"label.add.baremetal.dhcp.device": "Legg Til Barmetall DHCP Enhet",
|
"label.add.baremetal.dhcp.device": "Legg Til Barmetall DHCP Enhet",
|
||||||
"label.add.bigswitchbcf.device": "Legg til BigSwitch BCF kontroller",
|
"label.add.bigswitchbcf.device": "Legg til BigSwitch BCF kontroller",
|
||||||
@ -142,12 +142,12 @@
|
|||||||
"label.add.ip.range": "Legg til IP-rekke",
|
"label.add.ip.range": "Legg til IP-rekke",
|
||||||
"label.add.isolated.network": "Legg Til Isolert Nettverk",
|
"label.add.isolated.network": "Legg Til Isolert Nettverk",
|
||||||
"label.add.ldap.account": "Legg til LDAP-konto",
|
"label.add.ldap.account": "Legg til LDAP-konto",
|
||||||
"label.add.list.name": "ACL listenavn",
|
"label.add.acl.name": "ACL listenavn",
|
||||||
"label.add.more": "Legg til mer",
|
"label.add.more": "Legg til mer",
|
||||||
"label.add.netscaler.device": "Legg til Netscaler enhet",
|
"label.add.netscaler.device": "Legg til Netscaler enhet",
|
||||||
"label.add.network": "Legg til nettverk",
|
"label.add.network": "Legg til nettverk",
|
||||||
"label.add.network.acl": "Legg til nettverk ACL",
|
"label.add.network.acl": "Legg til nettverk ACL",
|
||||||
"label.add.network.acl.list": "Legg til nettverk ACL liste",
|
"label.add.network.acl": "Legg til nettverk ACL liste",
|
||||||
"label.add.network.offering": "Legg til nettverkstilbud",
|
"label.add.network.offering": "Legg til nettverkstilbud",
|
||||||
"label.add.new.gateway": "Legg til ny gateway",
|
"label.add.new.gateway": "Legg til ny gateway",
|
||||||
"label.add.new.tier": "Legg til ny gren",
|
"label.add.new.tier": "Legg til ny gren",
|
||||||
@ -334,7 +334,7 @@
|
|||||||
"label.default.use": "Standard bruk",
|
"label.default.use": "Standard bruk",
|
||||||
"label.default.view": "Standardvisning",
|
"label.default.view": "Standardvisning",
|
||||||
"label.delete": "Slett",
|
"label.delete": "Slett",
|
||||||
"label.delete.acl.list": "Slett ACL liste",
|
"label.delete.acl": "Slett ACL liste",
|
||||||
"label.delete.affinity.group": "Slett affinitetsgruppe",
|
"label.delete.affinity.group": "Slett affinitetsgruppe",
|
||||||
"label.delete.alerts": "Slette varsler",
|
"label.delete.alerts": "Slette varsler",
|
||||||
"label.delete.bigswitchbcf": "Fjern BigSwitch BCF-kontroller",
|
"label.delete.bigswitchbcf": "Fjern BigSwitch BCF-kontroller",
|
||||||
@ -419,7 +419,7 @@
|
|||||||
"label.dpd": "D\u00f8d endepunkt-deteksjon",
|
"label.dpd": "D\u00f8d endepunkt-deteksjon",
|
||||||
"label.driver": "Driver",
|
"label.driver": "Driver",
|
||||||
"label.edit": "Editer",
|
"label.edit": "Editer",
|
||||||
"label.edit.acl.list": "Edit ACL List",
|
"label.edit.acl": "Edit ACL",
|
||||||
"label.edit.acl.rule": "Endre ACL regel",
|
"label.edit.acl.rule": "Endre ACL regel",
|
||||||
"label.edit.project.details": "Editer prosjektdetaljer",
|
"label.edit.project.details": "Editer prosjektdetaljer",
|
||||||
"label.edit.role": "Edit Role",
|
"label.edit.role": "Edit Role",
|
||||||
@ -924,7 +924,6 @@
|
|||||||
"label.remove.vpc.offering": "Fjern VPC tilbud",
|
"label.remove.vpc.offering": "Fjern VPC tilbud",
|
||||||
"label.removing": "Fjerner",
|
"label.removing": "Fjerner",
|
||||||
"label.replace.acl": "Erstatt ACL",
|
"label.replace.acl": "Erstatt ACL",
|
||||||
"label.replace.acl.list": "Erstatt ACL Liste",
|
|
||||||
"label.required": "P\u00e5krevd",
|
"label.required": "P\u00e5krevd",
|
||||||
"label.requireshvm": "HVM",
|
"label.requireshvm": "HVM",
|
||||||
"label.requiresupgrade": "Krever oppgradering",
|
"label.requiresupgrade": "Krever oppgradering",
|
||||||
@ -1150,8 +1149,7 @@
|
|||||||
"label.usehttps": "Bruk HTTPS",
|
"label.usehttps": "Bruk HTTPS",
|
||||||
"label.usenewdiskoffering": "Replace disk offering?",
|
"label.usenewdiskoffering": "Replace disk offering?",
|
||||||
"label.user": "Bruker",
|
"label.user": "Bruker",
|
||||||
"label.userdata": "Brukerdata",
|
"label.user.data": "Brukerdata",
|
||||||
"label.userdatal2": "Brukerdata",
|
|
||||||
"label.username": "Brukernavn",
|
"label.username": "Brukernavn",
|
||||||
"label.users": "Brukere",
|
"label.users": "Brukere",
|
||||||
"label.utilization": "Utilisation",
|
"label.utilization": "Utilisation",
|
||||||
@ -1329,7 +1327,7 @@
|
|||||||
"message.confirm.archive.selected.alerts": "Vennligst bekreft at du \u00f8nsker \u00e5 arkivere valgte varsler",
|
"message.confirm.archive.selected.alerts": "Vennligst bekreft at du \u00f8nsker \u00e5 arkivere valgte varsler",
|
||||||
"message.confirm.archive.selected.events": "Vennligst bekreft at du vil arkivere valgte hendelser",
|
"message.confirm.archive.selected.events": "Vennligst bekreft at du vil arkivere valgte hendelser",
|
||||||
"message.confirm.attach.disk": "Er du sikker p\u00e5 at du vil tildele disk?",
|
"message.confirm.attach.disk": "Er du sikker p\u00e5 at du vil tildele disk?",
|
||||||
"message.confirm.delete.acl.list": "Er du sikker p\u00e5 at du \u00f8nsker \u00e5 slette denne ACL listen?",
|
"message.confirm.delete.acl": "Er du sikker p\u00e5 at du \u00f8nsker \u00e5 slette denne ACL listen?",
|
||||||
"message.confirm.delete.bigswitchbcf": "Vennligst bekreft at du \u00f8nsker \u00e5 slette denne BigSwitch BCF Controlleren?",
|
"message.confirm.delete.bigswitchbcf": "Vennligst bekreft at du \u00f8nsker \u00e5 slette denne BigSwitch BCF Controlleren?",
|
||||||
"message.confirm.delete.brocadevcs": "Vennligst bekreft at du vil slette denne Brocade Vcs svitsjen",
|
"message.confirm.delete.brocadevcs": "Vennligst bekreft at du vil slette denne Brocade Vcs svitsjen",
|
||||||
"message.confirm.delete.ciscoasa1000v": "Vennligst bekreft at du vil slette CiscoASA1000v",
|
"message.confirm.delete.ciscoasa1000v": "Vennligst bekreft at du vil slette CiscoASA1000v",
|
||||||
|
|||||||
@ -14,12 +14,12 @@
|
|||||||
"label.account.specific": "Account-specifiek",
|
"label.account.specific": "Account-specifiek",
|
||||||
"label.accounts": "Accounts",
|
"label.accounts": "Accounts",
|
||||||
"label.accounttype": "Account type",
|
"label.accounttype": "Account type",
|
||||||
"label.acl.export": "Export ACLs",
|
"label.acl.export": "Export ACL rules",
|
||||||
"label.acl.id": "ACL ID",
|
"label.acl.id": "ACL ID",
|
||||||
"label.acl.list.rules": "ACL lijst regels",
|
"label.acl.rules": "ACL lijst regels",
|
||||||
"label.acl.reason.description": "Enter the reason behind an ACL rule.",
|
"label.acl.reason.description": "Enter the reason behind an ACL rule.",
|
||||||
"label.aclid": "ACL",
|
"label.aclid": "ACL",
|
||||||
"label.aclname": "ACL naam",
|
"label.acl.rule.name": "ACL naam",
|
||||||
"label.acquire.new.ip": "Bemachtig nieuw IP",
|
"label.acquire.new.ip": "Bemachtig nieuw IP",
|
||||||
"label.acquire.new.secondary.ip": "Verkrijg nieuw secundair IP",
|
"label.acquire.new.secondary.ip": "Verkrijg nieuw secundair IP",
|
||||||
"label.action": "Actie",
|
"label.action": "Actie",
|
||||||
@ -119,8 +119,8 @@
|
|||||||
"label.activeviewersessions": "Actieve Sessies",
|
"label.activeviewersessions": "Actieve Sessies",
|
||||||
"label.add": "Voeg toe",
|
"label.add": "Voeg toe",
|
||||||
"label.add.account": "Voeg Account toe",
|
"label.add.account": "Voeg Account toe",
|
||||||
"label.add.acl": "Voeg ACL toe",
|
"label.add.acl.rule": "Voeg ACL toe",
|
||||||
"label.add.acl.list": "voeg een ACL lijst toe",
|
"label.add.acl": "voeg een ACL lijst toe",
|
||||||
"label.add.affinity.group": "Nieuwe affinity groep toevoegen",
|
"label.add.affinity.group": "Nieuwe affinity groep toevoegen",
|
||||||
"label.add.baremetal.dhcp.device": "Voeg Baremetal DHCP Apparaat toe",
|
"label.add.baremetal.dhcp.device": "Voeg Baremetal DHCP Apparaat toe",
|
||||||
"label.add.bigswitchbcf.device": "Voeg eenBigSwitch BCF controller toe",
|
"label.add.bigswitchbcf.device": "Voeg eenBigSwitch BCF controller toe",
|
||||||
@ -142,12 +142,12 @@
|
|||||||
"label.add.ip.range": "Voeg IP range toe",
|
"label.add.ip.range": "Voeg IP range toe",
|
||||||
"label.add.isolated.network": "Geisoleerd Netwerk Toevoegen",
|
"label.add.isolated.network": "Geisoleerd Netwerk Toevoegen",
|
||||||
"label.add.ldap.account": "Voeg LDAP account toe",
|
"label.add.ldap.account": "Voeg LDAP account toe",
|
||||||
"label.add.list.name": "ACL lijst naam",
|
"label.add.acl.name": "ACL lijst naam",
|
||||||
"label.add.more": "Voeg meer toe",
|
"label.add.more": "Voeg meer toe",
|
||||||
"label.add.netscaler.device": "Voeg Netscaler apparaat toe",
|
"label.add.netscaler.device": "Voeg Netscaler apparaat toe",
|
||||||
"label.add.network": "Voeg Netwerk toe",
|
"label.add.network": "Voeg Netwerk toe",
|
||||||
"label.add.network.acl": "Voeg netwerk ACL toe",
|
"label.add.network.acl": "Voeg netwerk ACL toe",
|
||||||
"label.add.network.acl.list": "voeg netwerk ACL lijst toe",
|
"label.add.network.acl": "voeg netwerk ACL lijst toe",
|
||||||
"label.add.network.offering": "Voeg netwerk aanbieding toe",
|
"label.add.network.offering": "Voeg netwerk aanbieding toe",
|
||||||
"label.add.new.gateway": "Voeg nieuwe gateway toe",
|
"label.add.new.gateway": "Voeg nieuwe gateway toe",
|
||||||
"label.add.new.tier": "Voeg nieuwe Tier toe",
|
"label.add.new.tier": "Voeg nieuwe Tier toe",
|
||||||
@ -334,7 +334,7 @@
|
|||||||
"label.default.use": "Standaard Gebruik",
|
"label.default.use": "Standaard Gebruik",
|
||||||
"label.default.view": "Standaard Weergave",
|
"label.default.view": "Standaard Weergave",
|
||||||
"label.delete": "Verwijder",
|
"label.delete": "Verwijder",
|
||||||
"label.delete.acl.list": "verwijder ACL lijst",
|
"label.delete.acl": "verwijder ACL lijst",
|
||||||
"label.delete.affinity.group": "Verwijder Affinity Groep",
|
"label.delete.affinity.group": "Verwijder Affinity Groep",
|
||||||
"label.delete.alerts": "Verwijder waarschuwingen",
|
"label.delete.alerts": "Verwijder waarschuwingen",
|
||||||
"label.delete.bigswitchbcf": "Verwijder BigSwitch BCF Controller",
|
"label.delete.bigswitchbcf": "Verwijder BigSwitch BCF Controller",
|
||||||
@ -420,7 +420,7 @@
|
|||||||
"label.driver": "Driver",
|
"label.driver": "Driver",
|
||||||
"label.dynamicscalingenabled": "Dynamisch schalen ingeschakeld\n",
|
"label.dynamicscalingenabled": "Dynamisch schalen ingeschakeld\n",
|
||||||
"label.edit": "Wijzig",
|
"label.edit": "Wijzig",
|
||||||
"label.edit.acl.list": "Verander een ACL lijst",
|
"label.edit.acl": "Verander een ACL lijst",
|
||||||
"label.edit.acl.rule": "wijzig ACL regel",
|
"label.edit.acl.rule": "wijzig ACL regel",
|
||||||
"label.edit.project.details": "Wijzig project details",
|
"label.edit.project.details": "Wijzig project details",
|
||||||
"label.edit.role": "Edit Role",
|
"label.edit.role": "Edit Role",
|
||||||
@ -925,7 +925,6 @@
|
|||||||
"label.remove.vpc.offering": "VPC aanbieding verwijderen",
|
"label.remove.vpc.offering": "VPC aanbieding verwijderen",
|
||||||
"label.removing": "Verwijderen",
|
"label.removing": "Verwijderen",
|
||||||
"label.replace.acl": "vervang ACL",
|
"label.replace.acl": "vervang ACL",
|
||||||
"label.replace.acl.list": "vervang ACL lijst",
|
|
||||||
"label.required": "Vereist",
|
"label.required": "Vereist",
|
||||||
"label.requireshvm": "HVM",
|
"label.requireshvm": "HVM",
|
||||||
"label.requiresupgrade": "Upgrade Benodigd",
|
"label.requiresupgrade": "Upgrade Benodigd",
|
||||||
@ -1151,8 +1150,7 @@
|
|||||||
"label.usehttps": "Gebruik HTTPS",
|
"label.usehttps": "Gebruik HTTPS",
|
||||||
"label.usenewdiskoffering": "Replace disk offering?",
|
"label.usenewdiskoffering": "Replace disk offering?",
|
||||||
"label.user": "Gebruiker",
|
"label.user": "Gebruiker",
|
||||||
"label.userdata": "Gebruikers gegevens",
|
"label.user.data": "Gebruiker Data",
|
||||||
"label.userdatal2": "Gebruiker Data",
|
|
||||||
"label.username": "Gebruikersnaam",
|
"label.username": "Gebruikersnaam",
|
||||||
"label.users": "Gebruikers",
|
"label.users": "Gebruikers",
|
||||||
"label.utilization": "Utilisation",
|
"label.utilization": "Utilisation",
|
||||||
@ -1330,7 +1328,7 @@
|
|||||||
"message.confirm.archive.selected.alerts": "bevestig dat u de geselecteerde meldingen wilt archiveren, alstublieft",
|
"message.confirm.archive.selected.alerts": "bevestig dat u de geselecteerde meldingen wilt archiveren, alstublieft",
|
||||||
"message.confirm.archive.selected.events": "bevestig dat u de geselecteerde gebeurtenissen wilt archiveren, alstublieft",
|
"message.confirm.archive.selected.events": "bevestig dat u de geselecteerde gebeurtenissen wilt archiveren, alstublieft",
|
||||||
"message.confirm.attach.disk": "Weet U zeker dat U een disk wilt koppelen?",
|
"message.confirm.attach.disk": "Weet U zeker dat U een disk wilt koppelen?",
|
||||||
"message.confirm.delete.acl.list": "Weet U zeker dat U dit ACL wilt verwijderen?",
|
"message.confirm.delete.acl": "Weet U zeker dat U dit ACL wilt verwijderen?",
|
||||||
"message.confirm.delete.bigswitchbcf": "bevestig dat u deze BigSwitch BCF Controller wilt verwijderen, alstublieft",
|
"message.confirm.delete.bigswitchbcf": "bevestig dat u deze BigSwitch BCF Controller wilt verwijderen, alstublieft",
|
||||||
"message.confirm.delete.brocadevcs": "bevestigd dat Brocade Vcs Switch wilt verwijderen, altublieft",
|
"message.confirm.delete.brocadevcs": "bevestigd dat Brocade Vcs Switch wilt verwijderen, altublieft",
|
||||||
"message.confirm.delete.ciscoasa1000v": "bevestig dat u CiscoASA100v wilt verwijderen, alstublieft",
|
"message.confirm.delete.ciscoasa1000v": "bevestig dat u CiscoASA100v wilt verwijderen, alstublieft",
|
||||||
|
|||||||
@ -14,12 +14,12 @@
|
|||||||
"label.account.specific": "Account-Specific",
|
"label.account.specific": "Account-Specific",
|
||||||
"label.accounts": "Konta",
|
"label.accounts": "Konta",
|
||||||
"label.accounttype": "Account Type",
|
"label.accounttype": "Account Type",
|
||||||
"label.acl.export": "Export ACLs",
|
"label.acl.export": "Export ACL rules",
|
||||||
"label.acl.id": "ACL ID",
|
"label.acl.id": "ACL ID",
|
||||||
"label.acl.list.rules": "ACL List Rules",
|
"label.acl.rules": "ACL Rules",
|
||||||
"label.acl.reason.description": "Enter the reason behind an ACL rule.",
|
"label.acl.reason.description": "Enter the reason behind an ACL rule.",
|
||||||
"label.aclid": "ACL",
|
"label.aclid": "ACL",
|
||||||
"label.aclname": "ACL Name",
|
"label.acl.rule.name": "ACL Name",
|
||||||
"label.acquire.new.ip": "Acquire New IP",
|
"label.acquire.new.ip": "Acquire New IP",
|
||||||
"label.acquire.new.secondary.ip": "Acquire new secondary IP",
|
"label.acquire.new.secondary.ip": "Acquire new secondary IP",
|
||||||
"label.action": "Action",
|
"label.action": "Action",
|
||||||
@ -119,8 +119,8 @@
|
|||||||
"label.activeviewersessions": "Active Sessions",
|
"label.activeviewersessions": "Active Sessions",
|
||||||
"label.add": "Dodaj",
|
"label.add": "Dodaj",
|
||||||
"label.add.account": "Dodaj konto",
|
"label.add.account": "Dodaj konto",
|
||||||
"label.add.acl": "Dodaj ACL",
|
"label.add.acl.rule": "Dodaj ACL",
|
||||||
"label.add.acl.list": "Add ACL List",
|
"label.add.acl": "Add ACL rule List",
|
||||||
"label.add.affinity.group": "Add new affinity group",
|
"label.add.affinity.group": "Add new affinity group",
|
||||||
"label.add.baremetal.dhcp.device": "Add Baremetal DHCP Device",
|
"label.add.baremetal.dhcp.device": "Add Baremetal DHCP Device",
|
||||||
"label.add.bigswitchbcf.device": "Add BigSwitch BCF Controller",
|
"label.add.bigswitchbcf.device": "Add BigSwitch BCF Controller",
|
||||||
@ -142,12 +142,12 @@
|
|||||||
"label.add.ip.range": "Add IP Range",
|
"label.add.ip.range": "Add IP Range",
|
||||||
"label.add.isolated.network": "Add Isolated Network",
|
"label.add.isolated.network": "Add Isolated Network",
|
||||||
"label.add.ldap.account": "Add LDAP account",
|
"label.add.ldap.account": "Add LDAP account",
|
||||||
"label.add.list.name": "ACL List Name",
|
"label.add.acl.name": "ACL Name",
|
||||||
"label.add.more": "Dodaj wi\u0119cej",
|
"label.add.more": "Dodaj wi\u0119cej",
|
||||||
"label.add.netscaler.device": "Add Netscaler device",
|
"label.add.netscaler.device": "Add Netscaler device",
|
||||||
"label.add.network": "Dodaj sie\u0107",
|
"label.add.network": "Dodaj sie\u0107",
|
||||||
"label.add.network.acl": "Add network ACL",
|
"label.add.network.acl": "Add network ACL",
|
||||||
"label.add.network.acl.list": "Add Network ACL List",
|
"label.add.network.acl": "Add Network ACL",
|
||||||
"label.add.network.offering": "Add network offering",
|
"label.add.network.offering": "Add network offering",
|
||||||
"label.add.new.gateway": "Add new gateway",
|
"label.add.new.gateway": "Add new gateway",
|
||||||
"label.add.new.tier": "Add new tier",
|
"label.add.new.tier": "Add new tier",
|
||||||
@ -334,7 +334,7 @@
|
|||||||
"label.default.use": "Default Use",
|
"label.default.use": "Default Use",
|
||||||
"label.default.view": "Widok domy\u015blny",
|
"label.default.view": "Widok domy\u015blny",
|
||||||
"label.delete": "Usu\u0144",
|
"label.delete": "Usu\u0144",
|
||||||
"label.delete.acl.list": "Delete ACL List",
|
"label.delete.acl": "Delete ACL",
|
||||||
"label.delete.affinity.group": "Delete Affinity Group",
|
"label.delete.affinity.group": "Delete Affinity Group",
|
||||||
"label.delete.alerts": "Delete alerts",
|
"label.delete.alerts": "Delete alerts",
|
||||||
"label.delete.bigswitchbcf": "Remove BigSwitch BCF Controller",
|
"label.delete.bigswitchbcf": "Remove BigSwitch BCF Controller",
|
||||||
@ -419,7 +419,7 @@
|
|||||||
"label.dpd": "Dead Peer Detection",
|
"label.dpd": "Dead Peer Detection",
|
||||||
"label.driver": "Driver",
|
"label.driver": "Driver",
|
||||||
"label.edit": "Edytuj",
|
"label.edit": "Edytuj",
|
||||||
"label.edit.acl.list": "Edit ACL List",
|
"label.edit.acl": "Edit ACL",
|
||||||
"label.edit.acl.rule": "Edit ACL rule",
|
"label.edit.acl.rule": "Edit ACL rule",
|
||||||
"label.edit.project.details": "Zmie\u0144 szczeg\u00f3\u0142y projektu",
|
"label.edit.project.details": "Zmie\u0144 szczeg\u00f3\u0142y projektu",
|
||||||
"label.edit.role": "Edit Role",
|
"label.edit.role": "Edit Role",
|
||||||
@ -924,7 +924,6 @@
|
|||||||
"label.remove.vpc.offering": "Remove VPC offering",
|
"label.remove.vpc.offering": "Remove VPC offering",
|
||||||
"label.removing": "Usuwanie",
|
"label.removing": "Usuwanie",
|
||||||
"label.replace.acl": "Replace ACL",
|
"label.replace.acl": "Replace ACL",
|
||||||
"label.replace.acl.list": "Replace ACL List",
|
|
||||||
"label.required": "Wymagane",
|
"label.required": "Wymagane",
|
||||||
"label.requireshvm": "HVM",
|
"label.requireshvm": "HVM",
|
||||||
"label.requiresupgrade": "Requires Upgrade",
|
"label.requiresupgrade": "Requires Upgrade",
|
||||||
@ -1150,8 +1149,7 @@
|
|||||||
"label.usehttps": "Use HTTPS",
|
"label.usehttps": "Use HTTPS",
|
||||||
"label.usenewdiskoffering": "Replace disk offering?",
|
"label.usenewdiskoffering": "Replace disk offering?",
|
||||||
"label.user": "U\u017cytkowni",
|
"label.user": "U\u017cytkowni",
|
||||||
"label.userdata": "Userdata",
|
"label.user.data": "User Data",
|
||||||
"label.userdatal2": "User Data",
|
|
||||||
"label.username": "Nazwa u\u017cytkownika",
|
"label.username": "Nazwa u\u017cytkownika",
|
||||||
"label.users": "U\u017cytkownicy",
|
"label.users": "U\u017cytkownicy",
|
||||||
"label.utilization": "Utilisation",
|
"label.utilization": "Utilisation",
|
||||||
@ -1329,7 +1327,7 @@
|
|||||||
"message.confirm.archive.selected.alerts": "Please confirm you would like to archive the selected alerts",
|
"message.confirm.archive.selected.alerts": "Please confirm you would like to archive the selected alerts",
|
||||||
"message.confirm.archive.selected.events": "Please confirm you would like to archive the selected events",
|
"message.confirm.archive.selected.events": "Please confirm you would like to archive the selected events",
|
||||||
"message.confirm.attach.disk": "Are you sure you want to attach disk?",
|
"message.confirm.attach.disk": "Are you sure you want to attach disk?",
|
||||||
"message.confirm.delete.acl.list": "Are you sure you want to delete this ACL list?",
|
"message.confirm.delete.acl": "Are you sure you want to delete this ACL?",
|
||||||
"message.confirm.delete.bigswitchbcf": "Please confirm that you would like to delete this BigSwitch BCF Controller",
|
"message.confirm.delete.bigswitchbcf": "Please confirm that you would like to delete this BigSwitch BCF Controller",
|
||||||
"message.confirm.delete.brocadevcs": "Please confirm that you would like to delete Brocade Vcs Switch",
|
"message.confirm.delete.brocadevcs": "Please confirm that you would like to delete Brocade Vcs Switch",
|
||||||
"message.confirm.delete.ciscoasa1000v": "Please confirm you want to delete CiscoASA1000v",
|
"message.confirm.delete.ciscoasa1000v": "Please confirm you want to delete CiscoASA1000v",
|
||||||
|
|||||||
@ -33,10 +33,10 @@
|
|||||||
"label.accounttype": "Tipo de conta",
|
"label.accounttype": "Tipo de conta",
|
||||||
"label.acl.export": "Exportar ACLs",
|
"label.acl.export": "Exportar ACLs",
|
||||||
"label.acl.id": "ACL ID",
|
"label.acl.id": "ACL ID",
|
||||||
"label.acl.list.rules": "Lista de regras de ACL",
|
"label.acl.rules": "Lista de regras de ACL",
|
||||||
"label.acl.reason.description": "Motivo para se utilizar a regra.",
|
"label.acl.reason.description": "Motivo para se utilizar a regra.",
|
||||||
"label.aclid": "ACL",
|
"label.aclid": "ACL",
|
||||||
"label.aclname": "Nome da ACL",
|
"label.acl.rule.name": "Nome da ACL",
|
||||||
"label.acquire.new.ip": "Adquirir novo IP",
|
"label.acquire.new.ip": "Adquirir novo IP",
|
||||||
"label.acquire.new.secondary.ip": "Adquira um novo IP secund\u00e1rio",
|
"label.acquire.new.secondary.ip": "Adquira um novo IP secund\u00e1rio",
|
||||||
"label.acquiring.ip": "Obtendo IP",
|
"label.acquiring.ip": "Obtendo IP",
|
||||||
@ -171,8 +171,8 @@
|
|||||||
"label.activeviewersessions": "Sess\u00f5es ativas",
|
"label.activeviewersessions": "Sess\u00f5es ativas",
|
||||||
"label.add": "Adicionar",
|
"label.add": "Adicionar",
|
||||||
"label.add.account": "Adicionar conta",
|
"label.add.account": "Adicionar conta",
|
||||||
"label.add.acl": "Adicionar ACL",
|
"label.add.acl.rule": "Adicionar ACL",
|
||||||
"label.add.acl.list": "Adiciona lista ACL",
|
"label.add.acl": "Adiciona lista ACL",
|
||||||
"label.add.affinity.group": "Adicionar um grupo de afinidade",
|
"label.add.affinity.group": "Adicionar um grupo de afinidade",
|
||||||
"label.add.baremetal.dhcp.device": "Adicionar dispositivo DHCP baremetal",
|
"label.add.baremetal.dhcp.device": "Adicionar dispositivo DHCP baremetal",
|
||||||
"label.add.bigswitchbcf.device": "Adicionar controlador BigSwitch BCF",
|
"label.add.bigswitchbcf.device": "Adicionar controlador BigSwitch BCF",
|
||||||
@ -196,12 +196,12 @@
|
|||||||
"label.add.isolated.network": "Adiciona rede isolada",
|
"label.add.isolated.network": "Adiciona rede isolada",
|
||||||
"label.add.kubernetes.cluster": "Adicionar cluster Kubernetes",
|
"label.add.kubernetes.cluster": "Adicionar cluster Kubernetes",
|
||||||
"label.add.ldap.account": "Adicionar conta LDAP",
|
"label.add.ldap.account": "Adicionar conta LDAP",
|
||||||
"label.add.list.name": "Nome da lista ACL",
|
"label.add.acl.name": "Nome da lista ACL",
|
||||||
"label.add.more": "Adicionar mais",
|
"label.add.more": "Adicionar mais",
|
||||||
"label.add.netscaler.device": "Adicionar dispositivo Netscaler",
|
"label.add.netscaler.device": "Adicionar dispositivo Netscaler",
|
||||||
"label.add.network": "Adicionar rede",
|
"label.add.network": "Adicionar rede",
|
||||||
"label.add.network.acl": "Adicione ACL de rede",
|
"label.add.network.acl": "Adicione ACL de rede",
|
||||||
"label.add.network.acl.list": "Adicionar lista de ACL de rede",
|
"label.add.network.acl": "Adicionar lista de ACL de rede",
|
||||||
"label.add.network.offering": "Adicionar oferta de rede",
|
"label.add.network.offering": "Adicionar oferta de rede",
|
||||||
"label.add.new.gateway": "Adicionar novo gateway",
|
"label.add.new.gateway": "Adicionar novo gateway",
|
||||||
"label.add.new.tier": "Adicionar nova camada",
|
"label.add.new.tier": "Adicionar nova camada",
|
||||||
@ -485,7 +485,7 @@
|
|||||||
"label.default.view": "Visualiza\u00e7\u00e3o padr\u00e3o",
|
"label.default.view": "Visualiza\u00e7\u00e3o padr\u00e3o",
|
||||||
"label.defaultnetwork": "Rede padr\u00e3o",
|
"label.defaultnetwork": "Rede padr\u00e3o",
|
||||||
"label.delete": "Remover",
|
"label.delete": "Remover",
|
||||||
"label.delete.acl.list": "Apagar lista ACL",
|
"label.delete.acl": "Apagar lista ACL",
|
||||||
"label.delete.affinity.group": "Apagar grupo de afinidade",
|
"label.delete.affinity.group": "Apagar grupo de afinidade",
|
||||||
"label.delete.alerts": "Remover alertas",
|
"label.delete.alerts": "Remover alertas",
|
||||||
"label.delete.backup": "Apagar backup",
|
"label.delete.backup": "Apagar backup",
|
||||||
@ -612,7 +612,7 @@
|
|||||||
"label.dynamicscalingenabled": "Escalonamento din\u00e2mico habilitado",
|
"label.dynamicscalingenabled": "Escalonamento din\u00e2mico habilitado",
|
||||||
"label.dynamicscalingenabled.tooltip": "VM s\u00f3 pode ser dinamicamente escalonada quando o escalonamento din\u00e2mico estiver habilitado no template, oferta de computa\u00e7\u00e3o e nas configura\u00e7\u00e3oes globais",
|
"label.dynamicscalingenabled.tooltip": "VM s\u00f3 pode ser dinamicamente escalonada quando o escalonamento din\u00e2mico estiver habilitado no template, oferta de computa\u00e7\u00e3o e nas configura\u00e7\u00e3oes globais",
|
||||||
"label.edit": "Editar",
|
"label.edit": "Editar",
|
||||||
"label.edit.acl.list": "Editar lista ACL",
|
"label.edit.acl": "Editar lista ACL",
|
||||||
"label.edit.acl.rule": "Editar regra ACL",
|
"label.edit.acl.rule": "Editar regra ACL",
|
||||||
"label.edit.project.details": "Editar detalhes do projeto",
|
"label.edit.project.details": "Editar detalhes do projeto",
|
||||||
"label.edit.project.role": "Editar fun\u00e7\u00e3o do projeto",
|
"label.edit.project.role": "Editar fun\u00e7\u00e3o do projeto",
|
||||||
@ -1069,7 +1069,7 @@
|
|||||||
"label.netscaler.vpx": "NetScaler VPX LoadBalancer",
|
"label.netscaler.vpx": "NetScaler VPX LoadBalancer",
|
||||||
"label.network": "Rede",
|
"label.network": "Rede",
|
||||||
"label.network.acl": "ACL de rede",
|
"label.network.acl": "ACL de rede",
|
||||||
"label.network.acl.lists": "Lista de redes ACL",
|
"label.network.acls": "Lista de redes ACL",
|
||||||
"label.network.addvm": "Adicionar rede para VM",
|
"label.network.addvm": "Adicionar rede para VM",
|
||||||
"label.network.desc": "Descri\u00e7\u00e3o de rede",
|
"label.network.desc": "Descri\u00e7\u00e3o de rede",
|
||||||
"label.network.domain": "Dom\u00ednio de rede",
|
"label.network.domain": "Dom\u00ednio de rede",
|
||||||
@ -1356,7 +1356,6 @@
|
|||||||
"label.removed": "Removido",
|
"label.removed": "Removido",
|
||||||
"label.removing": "Removendo",
|
"label.removing": "Removendo",
|
||||||
"label.replace.acl": "Substituir ACL",
|
"label.replace.acl": "Substituir ACL",
|
||||||
"label.replace.acl.list": "Substituir lista ACL",
|
|
||||||
"label.report.bug": "Reportar um problema",
|
"label.report.bug": "Reportar um problema",
|
||||||
"label.required": "Obrigat\u00f3rio",
|
"label.required": "Obrigat\u00f3rio",
|
||||||
"label.requireshvm": "HVM",
|
"label.requireshvm": "HVM",
|
||||||
@ -1701,8 +1700,7 @@
|
|||||||
"label.usenewdiskoffering": "Substituir a oferta de disco?",
|
"label.usenewdiskoffering": "Substituir a oferta de disco?",
|
||||||
"label.user": "Usu\u00e1rio",
|
"label.user": "Usu\u00e1rio",
|
||||||
"label.user.conflict": "Conflito",
|
"label.user.conflict": "Conflito",
|
||||||
"label.userdata": "Dados de usu\u00e1rio",
|
"label.user.data": "Dados de usu\u00e1rio",
|
||||||
"label.userdatal2": "Dados de usu\u00e1rio",
|
|
||||||
"label.username": "Nome de usu\u00e1rio",
|
"label.username": "Nome de usu\u00e1rio",
|
||||||
"label.users": "Usu\u00e1rios",
|
"label.users": "Usu\u00e1rios",
|
||||||
"label.usersource": "Tipo de usu\u00e1rio",
|
"label.usersource": "Tipo de usu\u00e1rio",
|
||||||
@ -1978,7 +1976,7 @@
|
|||||||
"message.confirm.archive.selected.events": "Por favor confirme que voc\u00ea deseja arquivar os eventos selecionados",
|
"message.confirm.archive.selected.events": "Por favor confirme que voc\u00ea deseja arquivar os eventos selecionados",
|
||||||
"message.confirm.attach.disk": "Voc\u00ea tem certeza que deseja conectar este disco?",
|
"message.confirm.attach.disk": "Voc\u00ea tem certeza que deseja conectar este disco?",
|
||||||
"message.confirm.configure.ovs": "Voc\u00ea tem certeza de que quer configurar os Ovs?",
|
"message.confirm.configure.ovs": "Voc\u00ea tem certeza de que quer configurar os Ovs?",
|
||||||
"message.confirm.delete.acl.list": "Voc\u00ea tem certeza que deseja apagar esta lista ACL?",
|
"message.confirm.delete.acl": "Voc\u00ea tem certeza que deseja apagar esta lista ACL?",
|
||||||
"message.confirm.delete.bigswitchbcf": "Por favor, confirme que voc\u00ea deseja deletar este controlador BigSwitch BCF",
|
"message.confirm.delete.bigswitchbcf": "Por favor, confirme que voc\u00ea deseja deletar este controlador BigSwitch BCF",
|
||||||
"message.confirm.delete.brocadevcs": "Por favor confirme que voc\u00ea deseja remover o switch Brocade Vcs",
|
"message.confirm.delete.brocadevcs": "Por favor confirme que voc\u00ea deseja remover o switch Brocade Vcs",
|
||||||
"message.confirm.delete.ciscoasa1000v": "Favor confirmar que voc\u00ea deseja apagar este CiscoASA1000v",
|
"message.confirm.delete.ciscoasa1000v": "Favor confirmar que voc\u00ea deseja apagar este CiscoASA1000v",
|
||||||
|
|||||||
@ -14,12 +14,12 @@
|
|||||||
"label.account.specific": "\u0421\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430 \u0430\u043a\u043a\u0430\u0443\u043d\u043d\u0442\u0430",
|
"label.account.specific": "\u0421\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430 \u0430\u043a\u043a\u0430\u0443\u043d\u043d\u0442\u0430",
|
||||||
"label.accounts": "\u0423\u0447\u0451\u0442\u043d\u044b\u0435 \u0437\u0430\u043f\u0438\u0441\u0438",
|
"label.accounts": "\u0423\u0447\u0451\u0442\u043d\u044b\u0435 \u0437\u0430\u043f\u0438\u0441\u0438",
|
||||||
"label.accounttype": "Account Type",
|
"label.accounttype": "Account Type",
|
||||||
"label.acl.export": "Export ACLs",
|
"label.acl.export": "Export ACL rules",
|
||||||
"label.acl.id": "ACL ID",
|
"label.acl.id": "ACL ID",
|
||||||
"label.acl.list.rules": "ACL List Rules",
|
"label.acl.rules": "ACL Rules",
|
||||||
"label.acl.reason.description": "Enter the reason behind an ACL rule.",
|
"label.acl.reason.description": "Enter the reason behind an ACL rule.",
|
||||||
"label.aclid": "ACL",
|
"label.aclid": "ACL",
|
||||||
"label.aclname": "ACL Name",
|
"label.acl.rule.name": "ACL Name",
|
||||||
"label.acquire.new.ip": "\u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0439 IP",
|
"label.acquire.new.ip": "\u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0439 IP",
|
||||||
"label.acquire.new.secondary.ip": "\u0417\u0430\u043f\u0440\u043e\u0441\u0438\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 IP-\u0430\u0434\u0440\u0435\u0441",
|
"label.acquire.new.secondary.ip": "\u0417\u0430\u043f\u0440\u043e\u0441\u0438\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 IP-\u0430\u0434\u0440\u0435\u0441",
|
||||||
"label.action": "\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u044f",
|
"label.action": "\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u044f",
|
||||||
@ -119,8 +119,8 @@
|
|||||||
"label.activeviewersessions": "\u0410\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u0441\u0435\u0441\u0441\u0438\u0438",
|
"label.activeviewersessions": "\u0410\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u0441\u0435\u0441\u0441\u0438\u0438",
|
||||||
"label.add": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c",
|
"label.add": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c",
|
||||||
"label.add.account": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0443\u0447\u0435\u0442\u043d\u0443\u044e \u0437\u0430\u043f\u0438\u0441\u044c",
|
"label.add.account": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0443\u0447\u0435\u0442\u043d\u0443\u044e \u0437\u0430\u043f\u0438\u0441\u044c",
|
||||||
"label.add.acl": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c ACL",
|
"label.add.acl.rule": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c ACL",
|
||||||
"label.add.acl.list": "Add ACL List",
|
"label.add.acl": "Add ACL",
|
||||||
"label.add.affinity.group": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u043e\u0432\u0443\u044e affinity group",
|
"label.add.affinity.group": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u043e\u0432\u0443\u044e affinity group",
|
||||||
"label.add.baremetal.dhcp.device": "Add Baremetal DHCP Device",
|
"label.add.baremetal.dhcp.device": "Add Baremetal DHCP Device",
|
||||||
"label.add.bigswitchbcf.device": "Add BigSwitch BCF Controller",
|
"label.add.bigswitchbcf.device": "Add BigSwitch BCF Controller",
|
||||||
@ -142,12 +142,12 @@
|
|||||||
"label.add.ip.range": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d \u0430\u0434\u0440\u0435\u0441\u043e\u0432",
|
"label.add.ip.range": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d \u0430\u0434\u0440\u0435\u0441\u043e\u0432",
|
||||||
"label.add.isolated.network": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0438\u0437\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u0441\u0435\u0442\u044c",
|
"label.add.isolated.network": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0438\u0437\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u0441\u0435\u0442\u044c",
|
||||||
"label.add.ldap.account": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c LDAP \u0430\u043a\u043a\u0430\u0443\u043d\u0442",
|
"label.add.ldap.account": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c LDAP \u0430\u043a\u043a\u0430\u0443\u043d\u0442",
|
||||||
"label.add.list.name": "ACL List Name",
|
"label.add.acl.name": "ACL Name",
|
||||||
"label.add.more": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u0435\u0449\u0435",
|
"label.add.more": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u0435\u0449\u0435",
|
||||||
"label.add.netscaler.device": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c Netscaler \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e",
|
"label.add.netscaler.device": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c Netscaler \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e",
|
||||||
"label.add.network": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u0435\u0442\u044c",
|
"label.add.network": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u0435\u0442\u044c",
|
||||||
"label.add.network.acl": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u0435\u0442\u0435\u0432\u0443\u044e ACL",
|
"label.add.network.acl": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u0435\u0442\u0435\u0432\u0443\u044e ACL",
|
||||||
"label.add.network.acl.list": "Add Network ACL List",
|
"label.add.network.acl": "Add Network ACL",
|
||||||
"label.add.network.offering": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u0435\u0442\u0435\u0432\u044b\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u044b",
|
"label.add.network.offering": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u0435\u0442\u0435\u0432\u044b\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u044b",
|
||||||
"label.add.new.gateway": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u0448\u043b\u044e\u0437",
|
"label.add.new.gateway": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u0448\u043b\u044e\u0437",
|
||||||
"label.add.new.tier": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0439 Tier",
|
"label.add.new.tier": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0439 Tier",
|
||||||
@ -334,7 +334,7 @@
|
|||||||
"label.default.use": "\u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e",
|
"label.default.use": "\u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e",
|
||||||
"label.default.view": "\u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u0432\u0438\u0434",
|
"label.default.view": "\u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u0432\u0438\u0434",
|
||||||
"label.delete": "\u0423\u0434\u0430\u043b\u0438\u0442\u044c",
|
"label.delete": "\u0423\u0434\u0430\u043b\u0438\u0442\u044c",
|
||||||
"label.delete.acl.list": "Delete ACL List",
|
"label.delete.acl": "Delete ACL",
|
||||||
"label.delete.affinity.group": "\u0423\u0434\u0430\u043b\u0438\u0442\u044c affinity group",
|
"label.delete.affinity.group": "\u0423\u0434\u0430\u043b\u0438\u0442\u044c affinity group",
|
||||||
"label.delete.alerts": "\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0442\u0440\u0435\u0432\u043e\u0433\u0438",
|
"label.delete.alerts": "\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0442\u0440\u0435\u0432\u043e\u0433\u0438",
|
||||||
"label.delete.bigswitchbcf": "Remove BigSwitch BCF Controller",
|
"label.delete.bigswitchbcf": "Remove BigSwitch BCF Controller",
|
||||||
@ -418,7 +418,7 @@
|
|||||||
"label.dpd": "Dead Peer Detection",
|
"label.dpd": "Dead Peer Detection",
|
||||||
"label.driver": "Driver",
|
"label.driver": "Driver",
|
||||||
"label.edit": "\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c",
|
"label.edit": "\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c",
|
||||||
"label.edit.acl.list": "Edit ACL List",
|
"label.edit.acl": "Edit ACL",
|
||||||
"label.edit.acl.rule": "Edit ACL rule",
|
"label.edit.acl.rule": "Edit ACL rule",
|
||||||
"label.edit.project.details": "\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u0435\u0442\u0430\u043b\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430",
|
"label.edit.project.details": "\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u0435\u0442\u0430\u043b\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430",
|
||||||
"label.edit.role": "Edit Role",
|
"label.edit.role": "Edit Role",
|
||||||
@ -923,7 +923,6 @@
|
|||||||
"label.remove.vpc.offering": "\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0443\u0441\u043b\u0443\u0433\u0443 VPC",
|
"label.remove.vpc.offering": "\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0443\u0441\u043b\u0443\u0433\u0443 VPC",
|
||||||
"label.removing": "\u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435",
|
"label.removing": "\u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435",
|
||||||
"label.replace.acl": "Replace ACL",
|
"label.replace.acl": "Replace ACL",
|
||||||
"label.replace.acl.list": "Replace ACL List",
|
|
||||||
"label.required": "\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f",
|
"label.required": "\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f",
|
||||||
"label.requireshvm": "HVM",
|
"label.requireshvm": "HVM",
|
||||||
"label.requiresupgrade": "Requires Upgrade",
|
"label.requiresupgrade": "Requires Upgrade",
|
||||||
@ -1149,8 +1148,7 @@
|
|||||||
"label.usehttps": "\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 HTTPS",
|
"label.usehttps": "\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 HTTPS",
|
||||||
"label.usenewdiskoffering": "Replace disk offering?",
|
"label.usenewdiskoffering": "Replace disk offering?",
|
||||||
"label.user": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c",
|
"label.user": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c",
|
||||||
"label.userdata": "Userdata",
|
"label.user.data": "User Data",
|
||||||
"label.userdatal2": "User Data",
|
|
||||||
"label.username": "\u0418\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f",
|
"label.username": "\u0418\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f",
|
||||||
"label.users": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438",
|
"label.users": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438",
|
||||||
"label.utilization": "Utilisation",
|
"label.utilization": "Utilisation",
|
||||||
@ -1328,7 +1326,7 @@
|
|||||||
"message.confirm.archive.selected.alerts": "Please confirm you would like to archive the selected alerts",
|
"message.confirm.archive.selected.alerts": "Please confirm you would like to archive the selected alerts",
|
||||||
"message.confirm.archive.selected.events": "Please confirm you would like to archive the selected events",
|
"message.confirm.archive.selected.events": "Please confirm you would like to archive the selected events",
|
||||||
"message.confirm.attach.disk": "Are you sure you want to attach disk?",
|
"message.confirm.attach.disk": "Are you sure you want to attach disk?",
|
||||||
"message.confirm.delete.acl.list": "Are you sure you want to delete this ACL list?",
|
"message.confirm.delete.acl": "Are you sure you want to delete this ACL?",
|
||||||
"message.confirm.delete.bigswitchbcf": "Please confirm that you would like to delete this BigSwitch BCF Controller",
|
"message.confirm.delete.bigswitchbcf": "Please confirm that you would like to delete this BigSwitch BCF Controller",
|
||||||
"message.confirm.delete.brocadevcs": "Please confirm that you would like to delete Brocade Vcs Switch",
|
"message.confirm.delete.brocadevcs": "Please confirm that you would like to delete Brocade Vcs Switch",
|
||||||
"message.confirm.delete.ciscoasa1000v": "Please confirm you want to delete CiscoASA1000v",
|
"message.confirm.delete.ciscoasa1000v": "Please confirm you want to delete CiscoASA1000v",
|
||||||
|
|||||||
@ -66,12 +66,12 @@
|
|||||||
|
|
||||||
"label.acl.export": "\u5BFC\u51FA ACL \u89C4\u5219",
|
"label.acl.export": "\u5BFC\u51FA ACL \u89C4\u5219",
|
||||||
"label.acl.id": "ACL \u6807\u8BC6\u7801",
|
"label.acl.id": "ACL \u6807\u8BC6\u7801",
|
||||||
"label.acl.list.rules": "ACL\u5217\u8868\u7B56\u7565",
|
"label.acl.rules": "ACL\u5217\u8868\u7B56\u7565",
|
||||||
"label.acl.reason.description": "\u8F93\u5165\u5B9A\u4E49 ACL \u7B56\u7565\u7684\u539F\u56E0\u3002",
|
"label.acl.reason.description": "\u8F93\u5165\u5B9A\u4E49 ACL \u7B56\u7565\u7684\u539F\u56E0\u3002",
|
||||||
"label.acl.replaced": "ACL \u5DF2\u66FF\u6362",
|
"label.acl.replaced": "ACL \u5DF2\u66FF\u6362",
|
||||||
|
|
||||||
"label.aclid": "\u8BBF\u95EE\u63A7\u5236\uFF08ACL\uFF09",
|
"label.aclid": "\u8BBF\u95EE\u63A7\u5236\uFF08ACL\uFF09",
|
||||||
"label.aclname": "ACL \u540D\u79F0",
|
"label.acl.rule.name": "ACL \u540D\u79F0",
|
||||||
"label.acltotal": "\u7F51\u7EDC ACL \u603B\u6570",
|
"label.acltotal": "\u7F51\u7EDC ACL \u603B\u6570",
|
||||||
"label.acquire.new.ip": "\u83B7\u53D6\u65B0 IP \u5730\u5740",
|
"label.acquire.new.ip": "\u83B7\u53D6\u65B0 IP \u5730\u5740",
|
||||||
"label.acquire.new.secondary.ip": "\u83B7\u53D6\u65B0\u4E8C\u7EA7 IP \u5730\u5740",
|
"label.acquire.new.secondary.ip": "\u83B7\u53D6\u65B0\u4E8C\u7EA7 IP \u5730\u5740",
|
||||||
@ -336,8 +336,8 @@
|
|||||||
"label.add.account": "\u6DFB\u52A0\u5E10\u6237",
|
"label.add.account": "\u6DFB\u52A0\u5E10\u6237",
|
||||||
"label.add.accounts": "\u6DFB\u52A0\u5E10\u6237",
|
"label.add.accounts": "\u6DFB\u52A0\u5E10\u6237",
|
||||||
"label.add.accounts.to": "\u6DFB\u52A0\u5E10\u6237\u81F3",
|
"label.add.accounts.to": "\u6DFB\u52A0\u5E10\u6237\u81F3",
|
||||||
"label.add.acl": "\u6DFB\u52A0 ACL",
|
"label.add.acl.rule": "\u6DFB\u52A0 ACL",
|
||||||
"label.add.acl.list": "\u6DFB\u52A0 ACL \u5217\u8868",
|
"label.add.acl": "\u6DFB\u52A0 ACL \u5217\u8868",
|
||||||
"label.add.affinity.group": "\u6DFB\u52A0\u65B0\u5173\u8054\u6027\u7EC4",
|
"label.add.affinity.group": "\u6DFB\u52A0\u65B0\u5173\u8054\u6027\u7EC4",
|
||||||
|
|
||||||
"label.add.baremetal.dhcp.device": "\u6DFB\u52A0\u88F8\u673A DHCP \u8BBE\u5907",
|
"label.add.baremetal.dhcp.device": "\u6DFB\u52A0\u88F8\u673A DHCP \u8BBE\u5907",
|
||||||
@ -381,7 +381,7 @@
|
|||||||
"label.add.l2.guest.network": "\u6DFB\u52A0 L2 \u6765\u5BBE\u7F51\u7EDC",
|
"label.add.l2.guest.network": "\u6DFB\u52A0 L2 \u6765\u5BBE\u7F51\u7EDC",
|
||||||
"label.add.ldap.account": "\u6DFB\u52A0 LDAP \u8D26\u6237",
|
"label.add.ldap.account": "\u6DFB\u52A0 LDAP \u8D26\u6237",
|
||||||
"label.add.ldap.list.users": "\u5217\u51FA LDAP \u7528\u6237",
|
"label.add.ldap.list.users": "\u5217\u51FA LDAP \u7528\u6237",
|
||||||
"label.add.list.name": "ACL \u5217\u8868\u540D\u79F0",
|
"label.add.acl.name": "ACL \u5217\u8868\u540D\u79F0",
|
||||||
"label.add.load.balancer": "\u6DFB\u52A0\u8D1F\u8F7D\u5747\u8861\u5668",
|
"label.add.load.balancer": "\u6DFB\u52A0\u8D1F\u8F7D\u5747\u8861\u5668",
|
||||||
|
|
||||||
"label.add.management.ip.range": "\u6DFB\u52A0\u7BA1\u7406 IP \u5730\u5740\u8303\u56F4",
|
"label.add.management.ip.range": "\u6DFB\u52A0\u7BA1\u7406 IP \u5730\u5740\u8303\u56F4",
|
||||||
@ -389,7 +389,7 @@
|
|||||||
"label.add.netscaler.device": "\u6DFB\u52A0 Netscaler \u8BBE\u5907",
|
"label.add.netscaler.device": "\u6DFB\u52A0 Netscaler \u8BBE\u5907",
|
||||||
"label.add.network": "\u6DFB\u52A0\u7F51\u7EDC",
|
"label.add.network": "\u6DFB\u52A0\u7F51\u7EDC",
|
||||||
"label.add.network.acl": "\u6DFB\u52A0\u7F51\u7EDC ACL",
|
"label.add.network.acl": "\u6DFB\u52A0\u7F51\u7EDC ACL",
|
||||||
"label.add.network.acl.list": "\u6DFB\u52A0\u7F51\u7EDC ACL \u5217\u8868",
|
"label.add.network.acl": "\u6DFB\u52A0\u7F51\u7EDC ACL \u5217\u8868",
|
||||||
"label.add.network.device": "\u6DFB\u52A0\u7F51\u7EDC\u8BBE\u5907",
|
"label.add.network.device": "\u6DFB\u52A0\u7F51\u7EDC\u8BBE\u5907",
|
||||||
"label.add.network.offering": "\u6DFB\u52A0\u7F51\u7EDC\u65B9\u6848",
|
"label.add.network.offering": "\u6DFB\u52A0\u7F51\u7EDC\u65B9\u6848",
|
||||||
|
|
||||||
@ -829,7 +829,7 @@
|
|||||||
"label.defaultnetwork": "\u9ED8\u8BA4\u7F51\u7EDC",
|
"label.defaultnetwork": "\u9ED8\u8BA4\u7F51\u7EDC",
|
||||||
|
|
||||||
"label.delete": "\u5220\u9664",
|
"label.delete": "\u5220\u9664",
|
||||||
"label.delete.acl.list": "\u5220\u9664 ACL \u5217\u8868",
|
"label.delete.acl": "\u5220\u9664 ACL \u5217\u8868",
|
||||||
"label.delete.affinity.group": "\u5220\u9664\u5173\u8054\u6027\u7EC4",
|
"label.delete.affinity.group": "\u5220\u9664\u5173\u8054\u6027\u7EC4",
|
||||||
"label.delete.alerts": "\u5220\u9664\u8B66\u62A5",
|
"label.delete.alerts": "\u5220\u9664\u8B66\u62A5",
|
||||||
"label.delete.backup": "\u5220\u9664\u5907\u4EFD",
|
"label.delete.backup": "\u5220\u9664\u5907\u4EFD",
|
||||||
@ -1007,7 +1007,7 @@
|
|||||||
"label.computeonly.offering.tooltip": "\u5728\u8BA1\u7B97\u65B9\u6848\u4E2D\u6307\u5B9A\u4E0E\u6839\u78C1\u76D8\u76F8\u5173\u7684\u4FE1\u606F\u6216\u5C06\u78C1\u76D8\u65B9\u6848\u76F4\u63A5\u94FE\u63A5\u5230\u8BA1\u7B97\u65B9\u6848\u7684\u9009\u9879",
|
"label.computeonly.offering.tooltip": "\u5728\u8BA1\u7B97\u65B9\u6848\u4E2D\u6307\u5B9A\u4E0E\u6839\u78C1\u76D8\u76F8\u5173\u7684\u4FE1\u606F\u6216\u5C06\u78C1\u76D8\u65B9\u6848\u76F4\u63A5\u94FE\u63A5\u5230\u8BA1\u7B97\u65B9\u6848\u7684\u9009\u9879",
|
||||||
|
|
||||||
"label.edit": "\u7F16\u8F91",
|
"label.edit": "\u7F16\u8F91",
|
||||||
"label.edit.acl.list": "\u7F16\u8F91 ACL \u5217\u8868",
|
"label.edit.acl": "\u7F16\u8F91 ACL \u5217\u8868",
|
||||||
"label.edit.acl.rule": "\u7F16\u8F91 ACL \u89C4\u5219",
|
"label.edit.acl.rule": "\u7F16\u8F91 ACL \u89C4\u5219",
|
||||||
"label.edit.affinity.group": "\u7F16\u8F91\u5173\u8054\u6027\u7EC4",
|
"label.edit.affinity.group": "\u7F16\u8F91\u5173\u8054\u6027\u7EC4",
|
||||||
"label.edit.lb.rule": "\u7F16\u8F91\u8D1F\u8F7D\u5747\u8861\u5668\u89C4\u5219",
|
"label.edit.lb.rule": "\u7F16\u8F91\u8D1F\u8F7D\u5747\u8861\u5668\u89C4\u5219",
|
||||||
@ -1717,7 +1717,7 @@
|
|||||||
"label.netscaler.vpx": "NetScaler VPX \u8D1F\u8F7D\u5747\u8861\u5668",
|
"label.netscaler.vpx": "NetScaler VPX \u8D1F\u8F7D\u5747\u8861\u5668",
|
||||||
"label.network": "\u7F51\u7EDC",
|
"label.network": "\u7F51\u7EDC",
|
||||||
"label.network.acl": "\u7F51\u7EDC ACL",
|
"label.network.acl": "\u7F51\u7EDC ACL",
|
||||||
"label.network.acl.lists": "\u7F51\u7EDC ACL \u5217\u8868",
|
"label.network.acls": "\u7F51\u7EDC ACL \u5217\u8868",
|
||||||
"label.network.acls": "\u7F51\u7EDC ACL",
|
"label.network.acls": "\u7F51\u7EDC ACL",
|
||||||
"label.network.addvm": "\u5C06\u7F51\u7EDC\u6DFB\u52A0\u5230\u865A\u62DF\u673A",
|
"label.network.addvm": "\u5C06\u7F51\u7EDC\u6DFB\u52A0\u5230\u865A\u62DF\u673A",
|
||||||
"label.network.desc": "\u7F51\u7EDC\u63CF\u8FF0",
|
"label.network.desc": "\u7F51\u7EDC\u63CF\u8FF0",
|
||||||
@ -2136,7 +2136,6 @@
|
|||||||
"label.removing.user": "\u6B63\u5728\u5220\u9664\u7528\u6237",
|
"label.removing.user": "\u6B63\u5728\u5220\u9664\u7528\u6237",
|
||||||
|
|
||||||
"label.replace.acl": "\u66FF\u6362 ACL",
|
"label.replace.acl": "\u66FF\u6362 ACL",
|
||||||
"label.replace.acl.list": "\u66FF\u6362 ACL \u5217\u8868",
|
|
||||||
"label.report.bug": "\u62A5\u544A\u95EE\u9898",
|
"label.report.bug": "\u62A5\u544A\u95EE\u9898",
|
||||||
|
|
||||||
"label.required": "\u5FC5\u586B\u9879",
|
"label.required": "\u5FC5\u586B\u9879",
|
||||||
@ -2666,8 +2665,7 @@
|
|||||||
"label.user.details": "\u7528\u6237\u8BE6\u60C5",
|
"label.user.details": "\u7528\u6237\u8BE6\u60C5",
|
||||||
"label.user.source": "\u6765\u6E90",
|
"label.user.source": "\u6765\u6E90",
|
||||||
"label.user.vm": "\u7528\u6237\u865A\u62DF\u673A",
|
"label.user.vm": "\u7528\u6237\u865A\u62DF\u673A",
|
||||||
"label.userdata": "\u7528\u6237\u6570\u636E",
|
"label.user.data": "\u7528\u6237\u6570\u636E",
|
||||||
"label.userdatal2": "\u7528\u6237\u6570\u636E",
|
|
||||||
"label.username": "\u7528\u6237\u540D",
|
"label.username": "\u7528\u6237\u540D",
|
||||||
"label.users": "\u7528\u6237",
|
"label.users": "\u7528\u6237",
|
||||||
"label.usersource": "\u7528\u6237\u7C7B\u578B",
|
"label.usersource": "\u7528\u6237\u7C7B\u578B",
|
||||||
@ -3129,7 +3127,7 @@
|
|||||||
"message.confirm.dedicate.pod.domain.account": "\u662F\u5426\u786E\u5B9E\u8981\u5C06\u6B64\u63D0\u4F9B\u70B9\u4E13\u7528\u4E8E\u57DF/\u5E10\u6237\uFF1F",
|
"message.confirm.dedicate.pod.domain.account": "\u662F\u5426\u786E\u5B9E\u8981\u5C06\u6B64\u63D0\u4F9B\u70B9\u4E13\u7528\u4E8E\u57DF/\u5E10\u6237\uFF1F",
|
||||||
"message.confirm.dedicate.zone": "\u662F\u5426\u8981\u5C06\u6B64\u8D44\u6E90\u57DF\u4E13\u7528\u4E8E\u57DF/\u5E10\u6237\uFF1F",
|
"message.confirm.dedicate.zone": "\u662F\u5426\u8981\u5C06\u6B64\u8D44\u6E90\u57DF\u4E13\u7528\u4E8E\u57DF/\u5E10\u6237\uFF1F",
|
||||||
|
|
||||||
"message.confirm.delete.acl.list": "\u662F\u5426\u786E\u5B9E\u8981\u5220\u9664\u6B64 ACL \u5217\u8868\uFF1F",
|
"message.confirm.delete.acl": "\u662F\u5426\u786E\u5B9E\u8981\u5220\u9664\u6B64 ACL \u5217\u8868\uFF1F",
|
||||||
"message.confirm.delete.alert": "\u662F\u5426\u786E\u5B9E\u8981\u5220\u9664\u6B64\u8B66\u62A5\uFF1F",
|
"message.confirm.delete.alert": "\u662F\u5426\u786E\u5B9E\u8981\u5220\u9664\u6B64\u8B66\u62A5\uFF1F",
|
||||||
"message.confirm.delete.baremetal.rack.configuration": "\u8BF7\u786E\u8BA4\u60A8\u786E\u5B9E\u8981\u5220\u9664 Baremetal Rack \u914D\u7F6E",
|
"message.confirm.delete.baremetal.rack.configuration": "\u8BF7\u786E\u8BA4\u60A8\u786E\u5B9E\u8981\u5220\u9664 Baremetal Rack \u914D\u7F6E",
|
||||||
"message.confirm.delete.bigswitchbcf": "\u8BF7\u786E\u8BA4\u60A8\u786E\u5B9E\u8981\u5220\u9664\u6B64 BigSwitch BCF \u63A7\u5236\u5668",
|
"message.confirm.delete.bigswitchbcf": "\u8BF7\u786E\u8BA4\u60A8\u786E\u5B9E\u8981\u5220\u9664\u6B64 BigSwitch BCF \u63A7\u5236\u5668",
|
||||||
|
|||||||
@ -34,6 +34,9 @@
|
|||||||
<span v-if="resourceIcon && !['router', 'systemvm', 'volume'].includes($route.path.split('/')[1])">
|
<span v-if="resourceIcon && !['router', 'systemvm', 'volume'].includes($route.path.split('/')[1])">
|
||||||
<resource-icon :image="resourceIcon" size="4x" style="margin-right: 5px"/>
|
<resource-icon :image="resourceIcon" size="4x" style="margin-right: 5px"/>
|
||||||
</span>
|
</span>
|
||||||
|
<span v-else-if="resource.vmtype === 'sharedfsvm'">
|
||||||
|
<file-text-outlined style="font-size: 36px;" />
|
||||||
|
</span>
|
||||||
<span v-else>
|
<span v-else>
|
||||||
<os-logo v-if="resource.ostypeid || resource.ostypename || ['guestoscategory'].includes($route.path.split('/')[1])" :osId="resource.ostypeid" :osName="resource.ostypename || resource.osdisplayname || resource.name" size="3x" />
|
<os-logo v-if="resource.ostypeid || resource.ostypename || ['guestoscategory'].includes($route.path.split('/')[1])" :osId="resource.ostypeid" :osName="resource.ostypename || resource.osdisplayname || resource.name" size="3x" />
|
||||||
<render-icon v-else-if="typeof $route.meta.icon ==='string'" style="font-size: 36px" :icon="$route.meta.icon" />
|
<render-icon v-else-if="typeof $route.meta.icon ==='string'" style="font-size: 36px" :icon="$route.meta.icon" />
|
||||||
@ -750,7 +753,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="resource-detail-item" v-if="resource.userdataname">
|
<div class="resource-detail-item" v-if="resource.userdataname">
|
||||||
<div class="resource-detail-item__label">{{ $t('label.userdata') }}</div>
|
<div class="resource-detail-item__label">{{ $t('label.user.data') }}</div>
|
||||||
<div class="resource-detail-item__details">
|
<div class="resource-detail-item__details">
|
||||||
<solution-outlined />
|
<solution-outlined />
|
||||||
<router-link v-if="!isStatic && $router.resolve('/userdata/' + resource.userdataid).matched[0].redirect !== '/exception/404'" :to="{ path: '/userdata/' + resource.userdataid }">{{ resource.userdataname || resource.userdataid }}</router-link>
|
<router-link v-if="!isStatic && $router.resolve('/userdata/' + resource.userdataid).matched[0].redirect !== '/exception/404'" :to="{ path: '/userdata/' + resource.userdataid }">{{ resource.userdataname || resource.userdataid }}</router-link>
|
||||||
@ -824,6 +827,18 @@
|
|||||||
<span v-else>{{ resource.webhookname || resource.webhookid }}</span>
|
<span v-else>{{ resource.webhookname || resource.webhookid }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="resource-detail-item" v-if="resource.boottype">
|
||||||
|
<div class="resource-detail-item__label">{{ $t('label.boottype') }}</div>
|
||||||
|
<div class="resource-detail-item__details">
|
||||||
|
<span>{{ resource.boottype }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="resource-detail-item" v-if="resource.bootmode">
|
||||||
|
<div class="resource-detail-item__label">{{ $t('label.bootmode') }}</div>
|
||||||
|
<div class="resource-detail-item__details">
|
||||||
|
<span>{{ resource.bootmode }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="resource-detail-item" v-if="resource.managementserverid">
|
<div class="resource-detail-item" v-if="resource.managementserverid">
|
||||||
<div class="resource-detail-item__label">{{ $t('label.management.servers') }}</div>
|
<div class="resource-detail-item__label">{{ $t('label.management.servers') }}</div>
|
||||||
<div class="resource-detail-item__details">
|
<div class="resource-detail-item__details">
|
||||||
@ -976,6 +991,7 @@ import eventBus from '@/config/eventBus'
|
|||||||
import ResourceIcon from '@/components/view/ResourceIcon'
|
import ResourceIcon from '@/components/view/ResourceIcon'
|
||||||
import ResourceLabel from '@/components/widgets/ResourceLabel'
|
import ResourceLabel from '@/components/widgets/ResourceLabel'
|
||||||
import ImageDeployInstanceButton from '@/components/view/ImageDeployInstanceButton'
|
import ImageDeployInstanceButton from '@/components/view/ImageDeployInstanceButton'
|
||||||
|
import { FileTextOutlined } from '@ant-design/icons-vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'InfoCard',
|
name: 'InfoCard',
|
||||||
@ -988,7 +1004,8 @@ export default {
|
|||||||
UploadResourceIcon,
|
UploadResourceIcon,
|
||||||
ResourceIcon,
|
ResourceIcon,
|
||||||
ResourceLabel,
|
ResourceLabel,
|
||||||
ImageDeployInstanceButton
|
ImageDeployInstanceButton,
|
||||||
|
FileTextOutlined
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
resource: {
|
resource: {
|
||||||
@ -1323,6 +1340,9 @@ export default {
|
|||||||
if (item.name === 'template') {
|
if (item.name === 'template') {
|
||||||
query.templatefilter = 'self'
|
query.templatefilter = 'self'
|
||||||
query.filter = 'self'
|
query.filter = 'self'
|
||||||
|
} else if (item.name === 'iso') {
|
||||||
|
query.isofilter = 'self'
|
||||||
|
query.filter = 'self'
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.param === 'account') {
|
if (item.param === 'account') {
|
||||||
|
|||||||
@ -60,12 +60,10 @@
|
|||||||
size="2x"
|
size="2x"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
<os-logo
|
<span v-else-if="record.vmtype === 'sharedfsvm'">
|
||||||
v-else
|
<file-text-outlined style="font-size: 18px;" />
|
||||||
:osId="record.ostypeid"
|
</span>
|
||||||
:osName="record.osdisplayname"
|
<os-logo v-else :osId="record.ostypeid" :osName="record.osdisplayname" size="xl" />
|
||||||
size="xl"
|
|
||||||
/>
|
|
||||||
</span>
|
</span>
|
||||||
<span style="min-width: 120px">
|
<span style="min-width: 120px">
|
||||||
<QuickView
|
<QuickView
|
||||||
@ -1008,6 +1006,7 @@ import { createPathBasedOnVmType } from '@/utils/plugins'
|
|||||||
import { validateLinks } from '@/utils/links'
|
import { validateLinks } from '@/utils/links'
|
||||||
import cronstrue from 'cronstrue/i18n'
|
import cronstrue from 'cronstrue/i18n'
|
||||||
import moment from 'moment-timezone'
|
import moment from 'moment-timezone'
|
||||||
|
import { FileTextOutlined } from '@ant-design/icons-vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ListView',
|
name: 'ListView',
|
||||||
@ -1018,7 +1017,8 @@ export default {
|
|||||||
CopyLabel,
|
CopyLabel,
|
||||||
TooltipButton,
|
TooltipButton,
|
||||||
ResourceIcon,
|
ResourceIcon,
|
||||||
ResourceLabel
|
ResourceLabel,
|
||||||
|
FileTextOutlined
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
columns: {
|
columns: {
|
||||||
|
|||||||
@ -55,7 +55,7 @@ export default {
|
|||||||
param: 'account'
|
param: 'account'
|
||||||
}, {
|
}, {
|
||||||
name: 'userdata',
|
name: 'userdata',
|
||||||
title: 'label.userdata',
|
title: 'label.user.data',
|
||||||
param: 'account'
|
param: 'account'
|
||||||
}, {
|
}, {
|
||||||
name: 'template',
|
name: 'template',
|
||||||
|
|||||||
@ -400,7 +400,7 @@ export default {
|
|||||||
{
|
{
|
||||||
api: 'resetUserDataForVirtualMachine',
|
api: 'resetUserDataForVirtualMachine',
|
||||||
icon: 'solution-outlined',
|
icon: 'solution-outlined',
|
||||||
label: 'label.reset.userdata.on.vm',
|
label: 'label.reset.user.data.on.vm',
|
||||||
message: 'message.desc.reset.userdata',
|
message: 'message.desc.reset.userdata',
|
||||||
docHelp: 'adminguide/virtual_machines.html#resetting-userdata',
|
docHelp: 'adminguide/virtual_machines.html#resetting-userdata',
|
||||||
dataView: true,
|
dataView: true,
|
||||||
@ -941,7 +941,7 @@ export default {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'userdata',
|
name: 'userdata',
|
||||||
title: 'label.user.data',
|
title: 'label.user.data.library',
|
||||||
icon: 'solution-outlined',
|
icon: 'solution-outlined',
|
||||||
docHelp: 'adminguide/virtual_machines.html#user-data-and-meta-data',
|
docHelp: 'adminguide/virtual_machines.html#user-data-and-meta-data',
|
||||||
permission: ['listUserData'],
|
permission: ['listUserData'],
|
||||||
@ -980,7 +980,7 @@ export default {
|
|||||||
api: 'registerUserData',
|
api: 'registerUserData',
|
||||||
icon: 'plus-outlined',
|
icon: 'plus-outlined',
|
||||||
label: 'label.register.user.data',
|
label: 'label.register.user.data',
|
||||||
docHelp: 'adminguide/virtual_machines.html#creating-the-ssh-keypair',
|
docHelp: 'adminguide/virtual_machines.html#user-data-and-meta-data',
|
||||||
listView: true,
|
listView: true,
|
||||||
popup: true,
|
popup: true,
|
||||||
component: shallowRef(defineAsyncComponent(() => import('@/views/compute/RegisterUserData.vue')))
|
component: shallowRef(defineAsyncComponent(() => import('@/views/compute/RegisterUserData.vue')))
|
||||||
|
|||||||
@ -48,6 +48,11 @@ export default {
|
|||||||
name: 'template',
|
name: 'template',
|
||||||
title: 'label.templates',
|
title: 'label.templates',
|
||||||
param: 'domainid'
|
param: 'domainid'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'iso',
|
||||||
|
title: 'label.isos',
|
||||||
|
param: 'domainid'
|
||||||
}],
|
}],
|
||||||
tabs: [
|
tabs: [
|
||||||
{
|
{
|
||||||
|
|||||||
@ -182,7 +182,7 @@ export default {
|
|||||||
{
|
{
|
||||||
api: 'replaceNetworkACLList',
|
api: 'replaceNetworkACLList',
|
||||||
icon: 'swap-outlined',
|
icon: 'swap-outlined',
|
||||||
label: 'label.replace.acl.list',
|
label: 'label.replace.acl',
|
||||||
message: 'message.confirm.replace.acl.new.one',
|
message: 'message.confirm.replace.acl.new.one',
|
||||||
docHelp: 'adminguide/networking_and_traffic.html#configuring-network-access-control-list',
|
docHelp: 'adminguide/networking_and_traffic.html#configuring-network-access-control-list',
|
||||||
dataView: true,
|
dataView: true,
|
||||||
@ -698,7 +698,7 @@ export default {
|
|||||||
{
|
{
|
||||||
api: 'resetUserDataForVirtualMachine',
|
api: 'resetUserDataForVirtualMachine',
|
||||||
icon: 'solution-outlined',
|
icon: 'solution-outlined',
|
||||||
label: 'label.reset.userdata.on.vm',
|
label: 'label.reset.user.data.on.vm',
|
||||||
message: 'message.desc.reset.userdata',
|
message: 'message.desc.reset.userdata',
|
||||||
docHelp: 'adminguide/virtual_machines.html#resetting-userdata',
|
docHelp: 'adminguide/virtual_machines.html#resetting-userdata',
|
||||||
dataView: true,
|
dataView: true,
|
||||||
@ -965,7 +965,7 @@ export default {
|
|||||||
{
|
{
|
||||||
api: 'replaceNetworkACLList',
|
api: 'replaceNetworkACLList',
|
||||||
icon: 'swap-outlined',
|
icon: 'swap-outlined',
|
||||||
label: 'label.replace.acl.list',
|
label: 'label.replace.acl',
|
||||||
message: 'message.confirm.replace.acl.new.one',
|
message: 'message.confirm.replace.acl.new.one',
|
||||||
docHelp: 'adminguide/networking_and_traffic.html#acl-on-private-gateway',
|
docHelp: 'adminguide/networking_and_traffic.html#acl-on-private-gateway',
|
||||||
dataView: true,
|
dataView: true,
|
||||||
@ -1061,10 +1061,9 @@ export default {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'acllist',
|
name: 'acllist',
|
||||||
title: 'label.network.acl.lists',
|
title: 'label.network.acls',
|
||||||
icon: 'bars-outlined',
|
icon: 'bars-outlined',
|
||||||
docHelp: 'adminguide/networking_and_traffic.html#configuring-network-access-control-list',
|
docHelp: 'adminguide/networking_and_traffic.html#configuring-network-access-control-list',
|
||||||
hidden: true,
|
|
||||||
permission: ['listNetworkACLLists'],
|
permission: ['listNetworkACLLists'],
|
||||||
columns: ['name', 'description', 'id'],
|
columns: ['name', 'description', 'id'],
|
||||||
details: ['name', 'description', 'id'],
|
details: ['name', 'description', 'id'],
|
||||||
@ -1072,15 +1071,15 @@ export default {
|
|||||||
name: 'details',
|
name: 'details',
|
||||||
component: shallowRef(defineAsyncComponent(() => import('@/components/view/DetailsTab.vue')))
|
component: shallowRef(defineAsyncComponent(() => import('@/components/view/DetailsTab.vue')))
|
||||||
}, {
|
}, {
|
||||||
name: 'acl.list.rules',
|
name: 'acl.rules',
|
||||||
component: shallowRef(defineAsyncComponent(() => import('@/views/network/AclListRulesTab.vue'))),
|
component: shallowRef(defineAsyncComponent(() => import('@/views/network/AclRulesTab.vue'))),
|
||||||
show: () => true
|
show: () => true
|
||||||
}],
|
}],
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
api: 'createNetworkACLList',
|
api: 'createNetworkACLList',
|
||||||
icon: 'plus-outlined',
|
icon: 'plus-outlined',
|
||||||
label: 'label.add.acl.list',
|
label: 'label.add.acl',
|
||||||
docHelp: 'adminguide/networking_and_traffic.html#creating-acl-lists',
|
docHelp: 'adminguide/networking_and_traffic.html#creating-acl-lists',
|
||||||
listView: true,
|
listView: true,
|
||||||
args: ['name', 'description', 'vpcid']
|
args: ['name', 'description', 'vpcid']
|
||||||
@ -1088,15 +1087,15 @@ export default {
|
|||||||
{
|
{
|
||||||
api: 'updateNetworkACLList',
|
api: 'updateNetworkACLList',
|
||||||
icon: 'edit-outlined',
|
icon: 'edit-outlined',
|
||||||
label: 'label.edit.acl.list',
|
label: 'label.edit.acl',
|
||||||
dataView: true,
|
dataView: true,
|
||||||
args: ['name', 'description']
|
args: ['name', 'description']
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
api: 'deleteNetworkACLList',
|
api: 'deleteNetworkACLList',
|
||||||
icon: 'delete-outlined',
|
icon: 'delete-outlined',
|
||||||
label: 'label.delete.acl.list',
|
label: 'label.delete.acl',
|
||||||
message: 'message.confirm.delete.acl.list',
|
message: 'message.confirm.delete.acl',
|
||||||
dataView: true
|
dataView: true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@ -39,7 +39,7 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
columns: () => {
|
columns: () => {
|
||||||
const fields = ['name', 'state', 'sizegb', 'type', 'vmname', 'vmstate']
|
const fields = ['name', 'state', 'size', 'type', 'vmname', 'vmstate']
|
||||||
const metricsFields = ['diskkbsread', 'diskkbswrite', 'diskiopstotal']
|
const metricsFields = ['diskkbsread', 'diskkbswrite', 'diskiopstotal']
|
||||||
|
|
||||||
if (store.getters.userInfo.roletype === 'Admin') {
|
if (store.getters.userInfo.roletype === 'Admin') {
|
||||||
|
|||||||
@ -76,7 +76,7 @@
|
|||||||
<div class="form" v-if="userdataid">
|
<div class="form" v-if="userdataid">
|
||||||
<div class="form__item">
|
<div class="form__item">
|
||||||
<div class="form__label">
|
<div class="form__label">
|
||||||
<tooltip-label :title="$t('label.userdataid')"/>
|
<tooltip-label :title="$t('label.user.data.id')"/>
|
||||||
</div>
|
</div>
|
||||||
{{ userdataid }}
|
{{ userdataid }}
|
||||||
</div>
|
</div>
|
||||||
@ -84,7 +84,7 @@
|
|||||||
<div class="form" v-if="userdataname">
|
<div class="form" v-if="userdataname">
|
||||||
<div class="form__item">
|
<div class="form__item">
|
||||||
<div class="form__label">
|
<div class="form__label">
|
||||||
<tooltip-label :title="$t('label.userdataname')"/>
|
<tooltip-label :title="$t('label.user.data.name')"/>
|
||||||
</div>
|
</div>
|
||||||
{{ userdataname }}
|
{{ userdataname }}
|
||||||
</div>
|
</div>
|
||||||
@ -92,7 +92,7 @@
|
|||||||
<div class="form" v-if="userdatadetails">
|
<div class="form" v-if="userdatadetails">
|
||||||
<div class="form__item">
|
<div class="form__item">
|
||||||
<div class="form__label">
|
<div class="form__label">
|
||||||
<tooltip-label :title="$t('label.userdatadetails')"/>
|
<tooltip-label :title="$t('label.user.data.details')"/>
|
||||||
</div>
|
</div>
|
||||||
{{ userdatadetails }}
|
{{ userdatadetails }}
|
||||||
</div>
|
</div>
|
||||||
@ -100,7 +100,7 @@
|
|||||||
<div class="form" v-if="userdatapolicy">
|
<div class="form" v-if="userdatapolicy">
|
||||||
<div class="form__item">
|
<div class="form__item">
|
||||||
<div class="form__label">
|
<div class="form__label">
|
||||||
<tooltip-label :title="$t('label.userdatapolicy')"/>
|
<tooltip-label :title="$t('label.user.data.policy')"/>
|
||||||
</div>
|
</div>
|
||||||
{{ userdatapolicy }}
|
{{ userdatapolicy }}
|
||||||
</div>
|
</div>
|
||||||
@ -108,7 +108,7 @@
|
|||||||
<div class="form">
|
<div class="form">
|
||||||
<div class="form__item">
|
<div class="form__item">
|
||||||
<div class="form__label">
|
<div class="form__label">
|
||||||
<tooltip-label :title="$t('label.userdata')" :tooltip="createAutoScaleVmProfileApiParams.userdata.description"/>
|
<tooltip-label :title="$t('label.user.data')" :tooltip="createAutoScaleVmProfileApiParams.userdata.description"/>
|
||||||
</div>
|
</div>
|
||||||
<a-textarea v-model:value="userdata" rows="5" :disabled="true">
|
<a-textarea v-model:value="userdata" rows="5" :disabled="true">
|
||||||
</a-textarea>
|
</a-textarea>
|
||||||
@ -124,7 +124,7 @@
|
|||||||
<div class="form__item">
|
<div class="form__item">
|
||||||
<a-button ref="submit" :disabled="!('updateAutoScaleVmProfile' in $store.getters.apis) || resource.state !== 'DISABLED'" type="primary" @click="showUpdateUserDataForm = true">
|
<a-button ref="submit" :disabled="!('updateAutoScaleVmProfile' in $store.getters.apis) || resource.state !== 'DISABLED'" type="primary" @click="showUpdateUserDataForm = true">
|
||||||
<template #icon><solution-outlined /></template>
|
<template #icon><solution-outlined /></template>
|
||||||
{{ $t('label.reset.userdata.on.autoscale.vm.group') }}
|
{{ $t('label.reset.user.data.on.autoscale.vm.group') }}
|
||||||
</a-button>
|
</a-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -291,7 +291,7 @@
|
|||||||
|
|
||||||
<a-modal
|
<a-modal
|
||||||
:visible="showUpdateUserDataForm"
|
:visible="showUpdateUserDataForm"
|
||||||
:title="$t('label.reset.userdata.on.autoscale.vm.group')"
|
:title="$t('label.reset.user.data.on.autoscale.vm.group')"
|
||||||
:closable="true"
|
:closable="true"
|
||||||
:maskClosable="false"
|
:maskClosable="false"
|
||||||
:footer="null"
|
:footer="null"
|
||||||
|
|||||||
@ -763,7 +763,7 @@
|
|||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item>
|
<a-form-item>
|
||||||
<template #label>
|
<template #label>
|
||||||
<tooltip-label :title="$t('label.userdata')" :tooltip="createAutoScaleVmProfileApiParams.userdata.description"/>
|
<tooltip-label :title="$t('label.user.data')" :tooltip="createAutoScaleVmProfileApiParams.userdata.description"/>
|
||||||
</template>
|
</template>
|
||||||
<a-card>
|
<a-card>
|
||||||
<div v-if="this.template && this.template.userdataid">
|
<div v-if="this.template && this.template.userdataid">
|
||||||
@ -791,11 +791,11 @@
|
|||||||
</div><br/><br/>
|
</div><br/><br/>
|
||||||
<div v-if="userdataDefaultOverridePolicy === 'ALLOWOVERRIDE' || userdataDefaultOverridePolicy === 'APPEND' || !userdataDefaultOverridePolicy">
|
<div v-if="userdataDefaultOverridePolicy === 'ALLOWOVERRIDE' || userdataDefaultOverridePolicy === 'APPEND' || !userdataDefaultOverridePolicy">
|
||||||
<span v-if="userdataDefaultOverridePolicy === 'ALLOWOVERRIDE'" >
|
<span v-if="userdataDefaultOverridePolicy === 'ALLOWOVERRIDE'" >
|
||||||
{{ $t('label.userdata.do.override') }}
|
{{ $t('label.user.data.do.override') }}
|
||||||
<a-switch v-model:checked="doUserdataOverride" style="margin-left: 10px"/>
|
<a-switch v-model:checked="doUserdataOverride" style="margin-left: 10px"/>
|
||||||
</span>
|
</span>
|
||||||
<span v-if="userdataDefaultOverridePolicy === 'APPEND'">
|
<span v-if="userdataDefaultOverridePolicy === 'APPEND'">
|
||||||
{{ $t('label.userdata.do.append') }}
|
{{ $t('label.user.data.do.append') }}
|
||||||
<a-switch v-model:checked="doUserdataAppend" style="margin-left: 10px"/>
|
<a-switch v-model:checked="doUserdataAppend" style="margin-left: 10px"/>
|
||||||
</span>
|
</span>
|
||||||
<a-step
|
<a-step
|
||||||
@ -1258,11 +1258,11 @@ export default {
|
|||||||
userDataValues: {},
|
userDataValues: {},
|
||||||
templateUserDataCols: [
|
templateUserDataCols: [
|
||||||
{
|
{
|
||||||
title: this.$t('label.userdata'),
|
title: this.$t('label.user.data'),
|
||||||
dataIndex: 'userdata'
|
dataIndex: 'userdata'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: this.$t('label.userdatapolicy'),
|
title: this.$t('label.user.data.policy'),
|
||||||
dataIndex: 'userdataoverridepolicy'
|
dataIndex: 'userdataoverridepolicy'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@ -1459,11 +1459,11 @@ export default {
|
|||||||
let tabList = []
|
let tabList = []
|
||||||
tabList = [{
|
tabList = [{
|
||||||
key: 'userdataregistered',
|
key: 'userdataregistered',
|
||||||
tab: this.$t('label.userdata.registered')
|
tab: this.$t('label.user.data.registered')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'userdatatext',
|
key: 'userdatatext',
|
||||||
tab: this.$t('label.userdata.text')
|
tab: this.$t('label.user.data.text')
|
||||||
}]
|
}]
|
||||||
return tabList
|
return tabList
|
||||||
},
|
},
|
||||||
|
|||||||
@ -616,7 +616,7 @@
|
|||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
<a-form-item :label="$t('label.userdata')">
|
<a-form-item :label="$t('label.user.data')">
|
||||||
<a-card>
|
<a-card>
|
||||||
<div v-if="this.template && this.template.userdataid">
|
<div v-if="this.template && this.template.userdataid">
|
||||||
<a-typography-text>
|
<a-typography-text>
|
||||||
@ -670,11 +670,11 @@
|
|||||||
</div><br/><br/>
|
</div><br/><br/>
|
||||||
<div v-if="userdataDefaultOverridePolicy === 'ALLOWOVERRIDE' || userdataDefaultOverridePolicy === 'APPEND' || !userdataDefaultOverridePolicy">
|
<div v-if="userdataDefaultOverridePolicy === 'ALLOWOVERRIDE' || userdataDefaultOverridePolicy === 'APPEND' || !userdataDefaultOverridePolicy">
|
||||||
<span v-if="userdataDefaultOverridePolicy === 'ALLOWOVERRIDE'" >
|
<span v-if="userdataDefaultOverridePolicy === 'ALLOWOVERRIDE'" >
|
||||||
{{ $t('label.userdata.do.override') }}
|
{{ $t('label.user.data.do.override') }}
|
||||||
<a-switch v-model:checked="doUserdataOverride" style="margin-left: 10px"/>
|
<a-switch v-model:checked="doUserdataOverride" style="margin-left: 10px"/>
|
||||||
</span>
|
</span>
|
||||||
<span v-if="userdataDefaultOverridePolicy === 'APPEND'">
|
<span v-if="userdataDefaultOverridePolicy === 'APPEND'">
|
||||||
{{ $t('label.userdata.do.append') }}
|
{{ $t('label.user.data.do.append') }}
|
||||||
<a-switch v-model:checked="doUserdataAppend" style="margin-left: 10px"/>
|
<a-switch v-model:checked="doUserdataAppend" style="margin-left: 10px"/>
|
||||||
</span>
|
</span>
|
||||||
<a-step
|
<a-step
|
||||||
@ -1014,8 +1014,7 @@ export default {
|
|||||||
keyboards: [],
|
keyboards: [],
|
||||||
bootTypes: [],
|
bootTypes: [],
|
||||||
bootModes: [],
|
bootModes: [],
|
||||||
ioPolicyTypes: [],
|
ioPolicyTypes: []
|
||||||
dynamicScalingVmConfig: false
|
|
||||||
},
|
},
|
||||||
rowCount: {},
|
rowCount: {},
|
||||||
loading: {
|
loading: {
|
||||||
@ -1076,11 +1075,11 @@ export default {
|
|||||||
userDataValues: {},
|
userDataValues: {},
|
||||||
templateUserDataCols: [
|
templateUserDataCols: [
|
||||||
{
|
{
|
||||||
title: this.$t('label.userdata'),
|
title: this.$t('label.user.data'),
|
||||||
dataIndex: 'userdata'
|
dataIndex: 'userdata'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: this.$t('label.userdatapolicy'),
|
title: this.$t('label.user.data.policy'),
|
||||||
dataIndex: 'userdataoverridepolicy'
|
dataIndex: 'userdataoverridepolicy'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@ -1438,11 +1437,11 @@ export default {
|
|||||||
let tabList = []
|
let tabList = []
|
||||||
tabList = [{
|
tabList = [{
|
||||||
key: 'userdataregistered',
|
key: 'userdataregistered',
|
||||||
tab: this.$t('label.userdata.registered')
|
tab: this.$t('label.user.data.registered')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'userdatatext',
|
key: 'userdatatext',
|
||||||
tab: this.$t('label.userdata.text')
|
tab: this.$t('label.user.data.text')
|
||||||
}]
|
}]
|
||||||
|
|
||||||
return tabList
|
return tabList
|
||||||
@ -1469,7 +1468,7 @@ export default {
|
|||||||
return Boolean('listUserData' in this.$store.getters.apis)
|
return Boolean('listUserData' in this.$store.getters.apis)
|
||||||
},
|
},
|
||||||
dynamicScalingVmConfigValue () {
|
dynamicScalingVmConfigValue () {
|
||||||
return this.options.dynamicScalingVmConfig?.[0]?.value === 'true'
|
return this.$store.getters.features.dynamicscalingenabled
|
||||||
},
|
},
|
||||||
isCustomizedDiskIOPS () {
|
isCustomizedDiskIOPS () {
|
||||||
return this.diskSelected?.iscustomizediops || false
|
return this.diskSelected?.iscustomizediops || false
|
||||||
@ -2529,20 +2528,29 @@ export default {
|
|||||||
if (exclude && exclude.length > 0 && exclude.includes(name)) {
|
if (exclude && exclude.length > 0 && exclude.includes(name)) {
|
||||||
return resolve(null)
|
return resolve(null)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
this.loading[name] = true
|
this.loading[name] = true
|
||||||
param.loading = true
|
param.loading = true
|
||||||
param.opts = []
|
param.opts = []
|
||||||
const options = param.options || {}
|
const options = param.options || {}
|
||||||
if (!('listall' in options) && !['zones', 'pods', 'clusters', 'hosts', 'dynamicScalingVmConfig', 'hypervisors'].includes(name)) {
|
if (!('listall' in options) && !['zones', 'pods', 'clusters', 'hosts', 'hypervisors'].includes(name)) {
|
||||||
options.listall = true
|
options.listall = true
|
||||||
}
|
}
|
||||||
postAPI(param.list, options).then((response) => {
|
postApi(param.list, options).then((response) => {
|
||||||
param.loading = false
|
param.loading = false
|
||||||
_.map(response, (responseItem, responseKey) => {
|
_.map(response, (responseItem, responseKey) => {
|
||||||
if (Object.keys(responseItem).length === 0) {
|
if (Object.keys(responseItem).length === 0) {
|
||||||
this.rowCount[name] = 0
|
this.rowCount[name] = 0
|
||||||
this.options[name] = []
|
this.options[name] = []
|
||||||
return resolve(null)
|
return
|
||||||
|
}
|
||||||
|
if (!responseKey.includes('response')) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_.map(responseItem, (response, key) => {
|
||||||
|
if (key === 'count') {
|
||||||
|
this.rowCount[name] = response
|
||||||
|
return
|
||||||
}
|
}
|
||||||
if (!responseKey.includes('response')) {
|
if (!responseKey.includes('response')) {
|
||||||
return resolve(null)
|
return resolve(null)
|
||||||
|
|||||||
@ -550,7 +550,7 @@
|
|||||||
@change="val => { dynamicscalingenabled = val }"/>
|
@change="val => { dynamicscalingenabled = val }"/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item :label="$t('label.userdata')">
|
<a-form-item :label="$t('label.user.data')">
|
||||||
<a-card>
|
<a-card>
|
||||||
<div v-if="this.template && this.template.userdataid">
|
<div v-if="this.template && this.template.userdataid">
|
||||||
<a-typography-text>
|
<a-typography-text>
|
||||||
@ -604,11 +604,11 @@
|
|||||||
</div><br/><br/>
|
</div><br/><br/>
|
||||||
<div v-if="userdataDefaultOverridePolicy === 'ALLOWOVERRIDE' || userdataDefaultOverridePolicy === 'APPEND' || !userdataDefaultOverridePolicy">
|
<div v-if="userdataDefaultOverridePolicy === 'ALLOWOVERRIDE' || userdataDefaultOverridePolicy === 'APPEND' || !userdataDefaultOverridePolicy">
|
||||||
<span v-if="userdataDefaultOverridePolicy === 'ALLOWOVERRIDE'" >
|
<span v-if="userdataDefaultOverridePolicy === 'ALLOWOVERRIDE'" >
|
||||||
{{ $t('label.userdata.do.override') }}
|
{{ $t('label.user.data.do.override') }}
|
||||||
<a-switch v-model:checked="doUserdataOverride" style="margin-left: 10px"/>
|
<a-switch v-model:checked="doUserdataOverride" style="margin-left: 10px"/>
|
||||||
</span>
|
</span>
|
||||||
<span v-if="userdataDefaultOverridePolicy === 'APPEND'">
|
<span v-if="userdataDefaultOverridePolicy === 'APPEND'">
|
||||||
{{ $t('label.userdata.do.append') }}
|
{{ $t('label.user.data.do.append') }}
|
||||||
<a-switch v-model:checked="doUserdataAppend" style="margin-left: 10px"/>
|
<a-switch v-model:checked="doUserdataAppend" style="margin-left: 10px"/>
|
||||||
</span>
|
</span>
|
||||||
<a-step
|
<a-step
|
||||||
@ -953,8 +953,7 @@ export default {
|
|||||||
keyboards: [],
|
keyboards: [],
|
||||||
bootTypes: [],
|
bootTypes: [],
|
||||||
bootModes: [],
|
bootModes: [],
|
||||||
ioPolicyTypes: [],
|
ioPolicyTypes: []
|
||||||
dynamicScalingVmConfig: false
|
|
||||||
},
|
},
|
||||||
rowCount: {},
|
rowCount: {},
|
||||||
loading: {
|
loading: {
|
||||||
@ -1012,11 +1011,11 @@ export default {
|
|||||||
userDataValues: {},
|
userDataValues: {},
|
||||||
templateUserDataCols: [
|
templateUserDataCols: [
|
||||||
{
|
{
|
||||||
title: this.$t('label.userdata'),
|
title: this.$t('label.user.data'),
|
||||||
dataIndex: 'userdata'
|
dataIndex: 'userdata'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: this.$t('label.userdatapolicy'),
|
title: this.$t('label.user.data.policy'),
|
||||||
dataIndex: 'userdataoverridepolicy'
|
dataIndex: 'userdataoverridepolicy'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@ -1291,16 +1290,17 @@ export default {
|
|||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
userdataTabList () {
|
userdataTabList () {
|
||||||
return [
|
let tabList = []
|
||||||
{
|
tabList = [{
|
||||||
key: 'userdataregistered',
|
key: 'userdataregistered',
|
||||||
tab: this.$t('label.userdata.registered')
|
tab: this.$t('label.user.data.registered')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'userdatatext',
|
key: 'userdatatext',
|
||||||
tab: this.$t('label.userdata.text')
|
tab: this.$t('label.user.data.text')
|
||||||
}
|
}]
|
||||||
]
|
|
||||||
|
return tabList
|
||||||
},
|
},
|
||||||
showVnfNicsSection () {
|
showVnfNicsSection () {
|
||||||
return this.networks && this.networks.length > 0 && this.vm.templateid && this.templateVnfNics && this.templateVnfNics.length > 0
|
return this.networks && this.networks.length > 0 && this.vm.templateid && this.templateVnfNics && this.templateVnfNics.length > 0
|
||||||
@ -1331,7 +1331,7 @@ export default {
|
|||||||
return Boolean('listUserData' in this.$store.getters.apis)
|
return Boolean('listUserData' in this.$store.getters.apis)
|
||||||
},
|
},
|
||||||
dynamicScalingVmConfigValue () {
|
dynamicScalingVmConfigValue () {
|
||||||
return this.options.dynamicScalingVmConfig?.[0]?.value === 'true'
|
return this.$store.getters.features.dynamicscalingenabled
|
||||||
},
|
},
|
||||||
isCustomizedDiskIOPS () {
|
isCustomizedDiskIOPS () {
|
||||||
return this.diskSelected?.iscustomizediops || false
|
return this.diskSelected?.iscustomizediops || false
|
||||||
@ -2472,20 +2472,29 @@ export default {
|
|||||||
if (exclude && exclude.length > 0 && exclude.includes(name)) {
|
if (exclude && exclude.length > 0 && exclude.includes(name)) {
|
||||||
return resolve(null)
|
return resolve(null)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
this.loading[name] = true
|
this.loading[name] = true
|
||||||
param.loading = true
|
param.loading = true
|
||||||
param.opts = []
|
param.opts = []
|
||||||
const options = param.options || {}
|
const options = param.options || {}
|
||||||
if (!('listall' in options) && !['zones', 'pods', 'clusters', 'hosts', 'dynamicScalingVmConfig', 'hypervisors'].includes(name)) {
|
if (!('listall' in options) && !['zones', 'pods', 'clusters', 'hosts', 'hypervisors'].includes(name)) {
|
||||||
options.listall = true
|
options.listall = true
|
||||||
}
|
}
|
||||||
postAPI(param.list, options).then((response) => {
|
postApi(param.list, options).then((response) => {
|
||||||
param.loading = false
|
param.loading = false
|
||||||
_.map(response, (responseItem, responseKey) => {
|
_.map(response, (responseItem, responseKey) => {
|
||||||
if (Object.keys(responseItem).length === 0) {
|
if (Object.keys(responseItem).length === 0) {
|
||||||
this.rowCount[name] = 0
|
this.rowCount[name] = 0
|
||||||
this.options[name] = []
|
this.options[name] = []
|
||||||
return resolve(null)
|
return
|
||||||
|
}
|
||||||
|
if (!responseKey.includes('response')) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_.map(responseItem, (response, key) => {
|
||||||
|
if (key === 'count') {
|
||||||
|
this.rowCount[name] = response
|
||||||
|
return
|
||||||
}
|
}
|
||||||
if (!responseKey.includes('response')) {
|
if (!responseKey.includes('response')) {
|
||||||
return resolve(null)
|
return resolve(null)
|
||||||
|
|||||||
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