mirror of https://github.com/apache/cloudstack.git
UI: Support to upload resource icons (#5157)
* Resource Icon support - backend * Add API support for resourceicon * update reponse params + ui support * Add exclusive list api for icons and UI changes * refactor upload view * UI changes to support resource icon wherever necessary * convert api to POST + refactor icon view * Add response name to list API + cosmetic changes in UI * Added support for the following: resource icon support for vpcs, networks, domains, and projects add icons to list view if reosurces support icons to be added support for showing project icons in the project switching drop-down menu * List resourceicon cmds to be allowed for user role too Users to inherit account icon if present (in listUsers response) Move common code to plugin.js Add icon to project list view - while switching between projects - Dashboard page Show icons against zones - Capacity Dashboard view Show user / account icon at the login button if present * cosmetic changes * optimize ui code * fix reload issue for domain view * add access check for delete operation * ui-related changes to show iso icons * iso image in uservm response * add icons to custom form's list resources * some more custom forms aligned to show icon for resources * conmitic changes + add listing of icons to listdomainchildren cmd * Add backend/server-side validation for base64 string passed for image * change preview border * preselect zone if there's only one * add default icon * show icon for network list in deploy vm view * add custom icons if any to the import-export VM view * preselect zone persistence on clearing cache * prevent root vol from inheriting template/iso icon * show tempalte icon in the info card details * fix icon not being show on hard-refresh / initial traversal * fx success message
This commit is contained in:
parent
f409e7a922
commit
3f827ef22b
|
|
@ -493,6 +493,10 @@ public class EventTypes {
|
|||
public static final String EVENT_TAGS_CREATE = "CREATE_TAGS";
|
||||
public static final String EVENT_TAGS_DELETE = "DELETE_TAGS";
|
||||
|
||||
// resource icon related events
|
||||
public static final String EVENT_RESOURCE_ICON_UPLOAD = "UPLOAD.RESOURCE.ICON";
|
||||
public static final String EVENT_RESOURCE_ICON_DELETE = "DELETE.RESOURCE.ICON";
|
||||
|
||||
// meta data related events
|
||||
public static final String EVENT_RESOURCE_DETAILS_CREATE = "CREATE_RESOURCE_DETAILS";
|
||||
public static final String EVENT_RESOURCE_DETAILS_DELETE = "DELETE_RESOURCE_DETAILS";
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package com.cloud.server;
|
||||
|
||||
import org.apache.cloudstack.api.Identity;
|
||||
import org.apache.cloudstack.api.InternalIdentity;
|
||||
|
||||
public interface ResourceIcon extends Identity, InternalIdentity {
|
||||
long getResourceId();
|
||||
|
||||
void setResourceId(long resourceId);
|
||||
|
||||
ResourceTag.ResourceObjectType getResourceType();
|
||||
|
||||
String getResourceUuid();
|
||||
|
||||
String getIcon();
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package com.cloud.server;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ResourceIconManager {
|
||||
|
||||
boolean uploadResourceIcon(List<String> resourceIds, ResourceTag.ResourceObjectType resourceType, String base64Image);
|
||||
|
||||
boolean deleteResourceIcon(List<String> resourceIds, ResourceTag.ResourceObjectType resourceType);
|
||||
|
||||
ResourceIcon getByResourceTypeAndUuid(ResourceTag.ResourceObjectType type, String resourceId);
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package com.cloud.server;
|
||||
|
||||
public interface ResourceManagerUtil {
|
||||
long getResourceId(String resourceId, ResourceTag.ResourceObjectType resourceType);
|
||||
String getUuid(String resourceId, ResourceTag.ResourceObjectType resourceType);
|
||||
ResourceTag.ResourceObjectType getResourceType(String resourceTypeStr);
|
||||
void checkResourceAccessible(Long accountId, Long domainId, String exceptionMessage);
|
||||
}
|
||||
|
|
@ -24,13 +24,13 @@ public interface ResourceTag extends ControlledEntity, Identity, InternalIdentit
|
|||
|
||||
// FIXME - extract enum to another interface as its used both by resourceTags and resourceMetaData code
|
||||
public enum ResourceObjectType {
|
||||
UserVm(true, true),
|
||||
Template(true, true),
|
||||
ISO(true, false),
|
||||
UserVm(true, true, true),
|
||||
Template(true, true, true),
|
||||
ISO(true, false, true),
|
||||
Volume(true, true),
|
||||
Snapshot(true, false),
|
||||
Backup(true, false),
|
||||
Network(true, true),
|
||||
Network(true, true, true),
|
||||
Nic(false, true),
|
||||
LoadBalancer(true, true),
|
||||
PortForwardingRule(true, true),
|
||||
|
|
@ -38,14 +38,14 @@ public interface ResourceTag extends ControlledEntity, Identity, InternalIdentit
|
|||
SecurityGroup(true, false),
|
||||
SecurityGroupRule(true, false),
|
||||
PublicIpAddress(true, true),
|
||||
Project(true, false),
|
||||
Account(true, false),
|
||||
Vpc(true, true),
|
||||
Project(true, false, true),
|
||||
Account(true, false, true),
|
||||
Vpc(true, true, true),
|
||||
NetworkACL(true, true),
|
||||
StaticRoute(true, false),
|
||||
VMSnapshot(true, false),
|
||||
RemoteAccessVpn(true, true),
|
||||
Zone(false, true),
|
||||
Zone(false, true, true),
|
||||
ServiceOffering(false, true),
|
||||
Storage(false, true),
|
||||
PrivateGateway(false, true),
|
||||
|
|
@ -53,7 +53,7 @@ public interface ResourceTag extends ControlledEntity, Identity, InternalIdentit
|
|||
VpnGateway(false, true),
|
||||
CustomerGateway(false, true),
|
||||
VpnConnection(false, true),
|
||||
User(true, true),
|
||||
User(true, true, true),
|
||||
DiskOffering(false, true),
|
||||
AutoScaleVmProfile(false, true),
|
||||
AutoScaleVmGroup(false, true),
|
||||
|
|
@ -62,7 +62,8 @@ public interface ResourceTag extends ControlledEntity, Identity, InternalIdentit
|
|||
SnapshotPolicy(true, true),
|
||||
GuestOs(false, true),
|
||||
NetworkOffering(false, true),
|
||||
VpcOffering(true, false);
|
||||
VpcOffering(true, false),
|
||||
Domain(false, false, true);
|
||||
|
||||
|
||||
ResourceObjectType(boolean resourceTagsSupport, boolean resourceMetadataSupport) {
|
||||
|
|
@ -70,8 +71,14 @@ public interface ResourceTag extends ControlledEntity, Identity, InternalIdentit
|
|||
metadataSupport = resourceMetadataSupport;
|
||||
}
|
||||
|
||||
ResourceObjectType(boolean resourceTagsSupport, boolean resourceMetadataSupport, boolean resourceIconSupport) {
|
||||
this(resourceTagsSupport, resourceMetadataSupport);
|
||||
this.resourceIconSupport = resourceIconSupport;
|
||||
}
|
||||
|
||||
private final boolean resourceTagsSupport;
|
||||
private final boolean metadataSupport;
|
||||
private boolean resourceIconSupport;
|
||||
|
||||
public boolean resourceTagsSupport() {
|
||||
return resourceTagsSupport;
|
||||
|
|
@ -80,6 +87,10 @@ public interface ResourceTag extends ControlledEntity, Identity, InternalIdentit
|
|||
public boolean resourceMetadataSupport() {
|
||||
return metadataSupport;
|
||||
}
|
||||
|
||||
public boolean resourceIconSupport() {
|
||||
return resourceIconSupport;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -43,18 +43,6 @@ public interface TaggedResourceService {
|
|||
|
||||
List<? extends ResourceTag> listByResourceTypeAndId(ResourceObjectType type, long resourceId);
|
||||
|
||||
//FIXME - the methods below should be extracted to its separate manager/service responsible just for retrieving object details
|
||||
ResourceObjectType getResourceType(String resourceTypeStr);
|
||||
|
||||
/**
|
||||
* @param resourceId
|
||||
* @param resourceType
|
||||
* @return
|
||||
*/
|
||||
String getUuid(String resourceId, ResourceObjectType resourceType);
|
||||
|
||||
public long getResourceId(String resourceId, ResourceObjectType resourceType);
|
||||
|
||||
/**
|
||||
* Retrieves tags from resource.
|
||||
* @param type
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ public class ApiConstants {
|
|||
public static final String BACKUP_ID = "backupid";
|
||||
public static final String BACKUP_OFFERING_NAME = "backupofferingname";
|
||||
public static final String BACKUP_OFFERING_ID = "backupofferingid";
|
||||
public static final String BASE64_IMAGE = "base64image";
|
||||
public static final String BITS = "bits";
|
||||
public static final String BOOTABLE = "bootable";
|
||||
public static final String BIND_DN = "binddn";
|
||||
|
|
@ -333,6 +334,7 @@ public class ApiConstants {
|
|||
public static final String SESSIONKEY = "sessionkey";
|
||||
public static final String SHOW_CAPACITIES = "showcapacities";
|
||||
public static final String SHOW_REMOVED = "showremoved";
|
||||
public static final String SHOW_RESOURCE_ICON = "showicon";
|
||||
public static final String SHOW_UNIQUE = "showunique";
|
||||
public static final String SIGNATURE = "signature";
|
||||
public static final String SIGNATURE_VERSION = "signatureversion";
|
||||
|
|
@ -747,6 +749,7 @@ public class ApiConstants {
|
|||
public static final String ACCESS_TYPE = "accesstype";
|
||||
|
||||
public static final String RESOURCE_DETAILS = "resourcedetails";
|
||||
public static final String RESOURCE_ICON = "icon";
|
||||
public static final String EXPUNGE = "expunge";
|
||||
public static final String FOR_DISPLAY = "fordisplay";
|
||||
public static final String PASSIVE = "passive";
|
||||
|
|
|
|||
|
|
@ -29,6 +29,11 @@ import java.util.regex.Pattern;
|
|||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.cloud.server.ManagementService;
|
||||
import com.cloud.server.ResourceIconManager;
|
||||
import com.cloud.server.ResourceManagerUtil;
|
||||
import com.cloud.server.ResourceMetaDataService;
|
||||
import com.cloud.server.TaggedResourceService;
|
||||
import org.apache.cloudstack.acl.ProjectRoleService;
|
||||
import org.apache.cloudstack.acl.RoleService;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
|
|
@ -67,9 +72,6 @@ import com.cloud.network.vpn.RemoteAccessVpnService;
|
|||
import com.cloud.network.vpn.Site2SiteVpnService;
|
||||
import com.cloud.projects.ProjectService;
|
||||
import com.cloud.resource.ResourceService;
|
||||
import com.cloud.server.ManagementService;
|
||||
import com.cloud.server.ResourceMetaDataService;
|
||||
import com.cloud.server.TaggedResourceService;
|
||||
import com.cloud.storage.DataStoreProviderApiService;
|
||||
import com.cloud.storage.StorageService;
|
||||
import com.cloud.storage.VolumeApiService;
|
||||
|
|
@ -164,6 +166,8 @@ public abstract class BaseCmd {
|
|||
@Inject
|
||||
public TaggedResourceService _taggedResourceService;
|
||||
@Inject
|
||||
public ResourceManagerUtil resourceManagerUtil;
|
||||
@Inject
|
||||
public ResourceMetaDataService _resourceMetaDataService;
|
||||
@Inject
|
||||
public VpcService _vpcService;
|
||||
|
|
@ -201,6 +205,8 @@ public abstract class BaseCmd {
|
|||
public UUIDManager _uuidMgr;
|
||||
@Inject
|
||||
public AnnotationService annotationService;
|
||||
@Inject
|
||||
public ResourceIconManager resourceIconManager;
|
||||
|
||||
public abstract void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
|
||||
ResourceAllocationException, NetworkRuleConflictException;
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.cloud.server.ResourceIcon;
|
||||
import org.apache.cloudstack.api.response.ResourceIconResponse;
|
||||
import org.apache.cloudstack.api.response.RouterHealthCheckResultResponse;
|
||||
import com.cloud.resource.RollingMaintenanceManager;
|
||||
import org.apache.cloudstack.api.response.RollingMaintenanceResponse;
|
||||
|
|
@ -270,7 +272,7 @@ public interface ResponseGenerator {
|
|||
|
||||
PodResponse createPodResponse(Pod pod, Boolean showCapacities);
|
||||
|
||||
ZoneResponse createZoneResponse(ResponseView view, DataCenter dataCenter, Boolean showCapacities);
|
||||
ZoneResponse createZoneResponse(ResponseView view, DataCenter dataCenter, Boolean showCapacities, Boolean showResourceIcon);
|
||||
|
||||
VolumeResponse createVolumeResponse(ResponseView view, Volume volume);
|
||||
|
||||
|
|
@ -487,4 +489,6 @@ public interface ResponseGenerator {
|
|||
|
||||
RollingMaintenanceResponse createRollingMaintenanceResponse(Boolean success, String details, List<RollingMaintenanceManager.HostUpdated> hostsUpdated, List<RollingMaintenanceManager.HostSkipped> hostsSkipped);
|
||||
|
||||
ResourceIconResponse createResourceIconResponse(ResourceIcon resourceIcon);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,9 @@ package org.apache.cloudstack.api.command.admin.domain;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.cloud.server.ResourceIcon;
|
||||
import com.cloud.server.ResourceTag;
|
||||
import org.apache.cloudstack.api.response.ResourceIconResponse;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
|
|
@ -58,6 +61,10 @@ public class ListDomainChildrenCmd extends BaseListCmd {
|
|||
description = "If set to false, list only resources belonging to the command's caller; if set to true - list resources that the caller is authorized to see. Default value is false")
|
||||
private Boolean listAll;
|
||||
|
||||
@Parameter(name = ApiConstants.SHOW_RESOURCE_ICON, type = CommandType.BOOLEAN,
|
||||
description = "flag to display the resource icon for domains")
|
||||
private Boolean showIcon;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -78,6 +85,10 @@ public class ListDomainChildrenCmd extends BaseListCmd {
|
|||
return recursive == null ? false : recursive;
|
||||
}
|
||||
|
||||
public Boolean getShowIcon() {
|
||||
return showIcon != null ? showIcon : false;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -100,6 +111,20 @@ public class ListDomainChildrenCmd extends BaseListCmd {
|
|||
|
||||
response.setResponses(domainResponses, result.second());
|
||||
response.setResponseName(getCommandName());
|
||||
if (response != null && response.getCount() > 0 && getShowIcon()) {
|
||||
updateDomainResponse(response.getResponses());
|
||||
}
|
||||
this.setResponseObject(response);
|
||||
}
|
||||
|
||||
private void updateDomainResponse(List<DomainResponse> response) {
|
||||
for (DomainResponse domainResponse : response) {
|
||||
ResourceIcon resourceIcon = resourceIconManager.getByResourceTypeAndUuid(ResourceTag.ResourceObjectType.Domain, domainResponse.getId());
|
||||
if (resourceIcon == null) {
|
||||
continue;
|
||||
}
|
||||
ResourceIconResponse iconResponse = _responseGenerator.createResourceIconResponse(resourceIcon);
|
||||
domainResponse.setResourceIconResponse(iconResponse);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,9 @@ import java.util.ArrayList;
|
|||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
|
||||
import com.cloud.server.ResourceIcon;
|
||||
import com.cloud.server.ResourceTag;
|
||||
import org.apache.cloudstack.api.response.ResourceIconResponse;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
|
|
@ -66,6 +69,10 @@ public class ListDomainsCmd extends BaseListCmd implements UserCmd {
|
|||
description = "comma separated list of domain details requested, value can be a list of [ all, resource, min]")
|
||||
private List<String> viewDetails;
|
||||
|
||||
@Parameter(name = ApiConstants.SHOW_RESOURCE_ICON, type = CommandType.BOOLEAN,
|
||||
description = "flag to display the resource icon for domains")
|
||||
private Boolean showIcon;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -105,6 +112,10 @@ public class ListDomainsCmd extends BaseListCmd implements UserCmd {
|
|||
return dv;
|
||||
}
|
||||
|
||||
public Boolean getShowIcon() {
|
||||
return showIcon != null ? showIcon : false;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -119,5 +130,19 @@ public class ListDomainsCmd extends BaseListCmd implements UserCmd {
|
|||
ListResponse<DomainResponse> response = _queryService.searchForDomains(this);
|
||||
response.setResponseName(getCommandName());
|
||||
this.setResponseObject(response);
|
||||
if (response != null && response.getCount() > 0 && getShowIcon()) {
|
||||
updateDomainResponse(response.getResponses());
|
||||
}
|
||||
}
|
||||
|
||||
private void updateDomainResponse(List<DomainResponse> response) {
|
||||
for (DomainResponse domainResponse : response) {
|
||||
ResourceIcon resourceIcon = resourceIconManager.getByResourceTypeAndUuid(ResourceTag.ResourceObjectType.Domain, domainResponse.getId());
|
||||
if (resourceIcon == null) {
|
||||
continue;
|
||||
}
|
||||
ResourceIconResponse iconResponse = _responseGenerator.createResourceIconResponse(resourceIcon);
|
||||
domainResponse.setResourceIconResponse(iconResponse);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,104 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.api.command.admin.resource.icon;
|
||||
|
||||
import com.cloud.server.ResourceIcon;
|
||||
import com.cloud.server.ResourceTag;
|
||||
import com.cloud.user.Account;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@APICommand(name = "deleteResourceIcon", description = "deletes the resource icon from the specified resource(s)",
|
||||
responseObject = SuccessResponse.class, since = "4.16.0.0", entityType = {ResourceIcon.class},
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
|
||||
authorized = {RoleType.Admin, RoleType.DomainAdmin, RoleType.ResourceAdmin, RoleType.User})
|
||||
public class DeleteResourceIconCmd extends BaseCmd {
|
||||
public static final Logger s_logger = Logger.getLogger(DeleteResourceIconCmd.class.getName());
|
||||
|
||||
private static final String s_name = "deleteresourceiconresponse";
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name = ApiConstants.RESOURCE_IDS,
|
||||
type = BaseCmd.CommandType.LIST,
|
||||
required = true,
|
||||
collectionType = BaseCmd.CommandType.STRING,
|
||||
description = "list of resources to upload the icon/image for")
|
||||
private List<String> resourceIds;
|
||||
|
||||
@Parameter(name = ApiConstants.RESOURCE_TYPE, type = BaseCmd.CommandType.STRING, required = true, description = "type of the resource")
|
||||
private String resourceType;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public List<String> getResourceIds() {
|
||||
return resourceIds;
|
||||
}
|
||||
|
||||
public ResourceTag.ResourceObjectType getResourceType() {
|
||||
return resourceManagerUtil.getResourceType(resourceType);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
try {
|
||||
boolean result = resourceIconManager.deleteResourceIcon(getResourceIds(), getResourceType());
|
||||
if (result) {
|
||||
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||
setResponseObject(response);
|
||||
} else {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete resource image");
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getLocalizedMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return s_name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
Account account = CallContext.current().getCallingAccount();// Let's give the caller here for event logging.
|
||||
if (account != null) {
|
||||
return account.getAccountId();
|
||||
}
|
||||
|
||||
return Account.ACCOUNT_ID_SYSTEM;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.api.command.admin.resource.icon;
|
||||
|
||||
import com.cloud.server.ResourceIcon;
|
||||
import com.cloud.server.ResourceTag;
|
||||
import com.cloud.user.Account;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.response.ListResponse;
|
||||
import org.apache.cloudstack.api.response.ResourceIconResponse;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@APICommand(name = "listResourceIcon", description = "Lists the resource icon for the specified resource(s)",
|
||||
responseObject = ResourceIconResponse.class, since = "4.16.0.0", entityType = {ResourceIcon.class},
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
|
||||
authorized = {RoleType.Admin, RoleType.DomainAdmin, RoleType.ResourceAdmin, RoleType.User})
|
||||
public class ListResourceIconCmd extends BaseCmd {
|
||||
public static final Logger s_logger = Logger.getLogger(ListResourceIconCmd.class.getName());
|
||||
|
||||
private static final String s_name = "listresourceiconresponse";
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
@Parameter(name = ApiConstants.RESOURCE_IDS,
|
||||
type = BaseCmd.CommandType.LIST,
|
||||
required = true,
|
||||
collectionType = BaseCmd.CommandType.STRING,
|
||||
description = "list of resources to upload the icon/image for")
|
||||
private List<String> resourceIds;
|
||||
|
||||
@Parameter(name = ApiConstants.RESOURCE_TYPE, type = BaseCmd.CommandType.STRING, required = true, description = "type of the resource")
|
||||
private String resourceType;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public List<String> getResourceIds() {
|
||||
return resourceIds;
|
||||
}
|
||||
|
||||
public ResourceTag.ResourceObjectType getResourceType() {
|
||||
return resourceManagerUtil.getResourceType(resourceType);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
ListResponse<ResourceIconResponse> response = _queryService.listResourceIcons(this);
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return s_name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return Account.ACCOUNT_ID_SYSTEM;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,144 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.api.command.admin.resource.icon;
|
||||
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.server.ResourceIcon;
|
||||
import com.cloud.server.ResourceTag;
|
||||
import com.cloud.user.Account;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.util.Base64;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@APICommand(name = "uploadResourceIcon", description = "Uploads an icon for the specified resource(s)",
|
||||
responseObject = SuccessResponse.class, since = "4.16.0.0", entityType = {ResourceIcon.class},
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
|
||||
authorized = {RoleType.Admin, RoleType.DomainAdmin, RoleType.ResourceAdmin, RoleType.User})
|
||||
public class UploadResourceIconCmd extends BaseCmd {
|
||||
public static final Logger LOGGER = Logger.getLogger(UploadResourceIconCmd.class.getName());
|
||||
|
||||
private static final String s_name = "uploadresourceiconresponse";
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name = ApiConstants.RESOURCE_IDS,
|
||||
type = BaseCmd.CommandType.LIST,
|
||||
required = true,
|
||||
collectionType = BaseCmd.CommandType.STRING,
|
||||
description = "list of resources to upload the icon/image for")
|
||||
private List<String> resourceIds;
|
||||
|
||||
@Parameter(name = ApiConstants.RESOURCE_TYPE, type = BaseCmd.CommandType.STRING, required = true, description = "type of the resource")
|
||||
private String resourceType;
|
||||
|
||||
@Parameter(name = ApiConstants.BASE64_IMAGE, type = BaseCmd.CommandType.STRING, required = true,
|
||||
description = "Base64 string representation of the resource icon/image", length = 2097152)
|
||||
private String image;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public List<String> getResourceIds() {
|
||||
return resourceIds;
|
||||
}
|
||||
|
||||
public ResourceTag.ResourceObjectType getResourceType() {
|
||||
return resourceManagerUtil.getResourceType(resourceType);
|
||||
}
|
||||
|
||||
public String getImage() {
|
||||
if (StringUtils.isEmpty(image)) {
|
||||
throw new InvalidParameterValueException("No image provided for resource icon");
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
try {
|
||||
if (!imageValidator(getImage())) {
|
||||
throw new InvalidParameterValueException("Invalid image uploaded");
|
||||
}
|
||||
boolean result = resourceIconManager.uploadResourceIcon(getResourceIds(), getResourceType(), getImage());
|
||||
if (result) {
|
||||
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||
setResponseObject(response);
|
||||
} else {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to upload resource image");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getLocalizedMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private boolean imageValidator (String base64Image) {
|
||||
BufferedImage image = null;
|
||||
byte[] imageByte;
|
||||
try {
|
||||
imageByte = Base64.getDecoder().decode(base64Image);
|
||||
ByteArrayInputStream bis = new ByteArrayInputStream(imageByte);
|
||||
image = ImageIO.read(bis);
|
||||
bis.close();
|
||||
if (image == null) {
|
||||
return false;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.warn("Data uploaded not a valid image");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return s_name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
Account account = CallContext.current().getCallingAccount();// Let's give the caller here for event logging.
|
||||
if (account != null) {
|
||||
return account.getAccountId();
|
||||
}
|
||||
|
||||
return Account.ACCOUNT_ID_SYSTEM;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -16,6 +16,9 @@
|
|||
// under the License.
|
||||
package org.apache.cloudstack.api.command.admin.user;
|
||||
|
||||
import com.cloud.server.ResourceIcon;
|
||||
import com.cloud.server.ResourceTag;
|
||||
import org.apache.cloudstack.api.response.ResourceIconResponse;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
|
|
@ -25,6 +28,8 @@ import org.apache.cloudstack.api.Parameter;
|
|||
import org.apache.cloudstack.api.response.ListResponse;
|
||||
import org.apache.cloudstack.api.response.UserResponse;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@APICommand(name = "listUsers", description = "Lists user accounts", responseObject = UserResponse.class,
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = true)
|
||||
public class ListUsersCmd extends BaseListAccountResourcesCmd {
|
||||
|
|
@ -50,6 +55,10 @@ public class ListUsersCmd extends BaseListAccountResourcesCmd {
|
|||
@Parameter(name = ApiConstants.USERNAME, type = CommandType.STRING, description = "List user by the username")
|
||||
private String username;
|
||||
|
||||
@Parameter(name = ApiConstants.SHOW_RESOURCE_ICON, type = CommandType.BOOLEAN,
|
||||
description = "flag to display the resource icon for users")
|
||||
private Boolean showIcon;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -70,6 +79,10 @@ public class ListUsersCmd extends BaseListAccountResourcesCmd {
|
|||
return username;
|
||||
}
|
||||
|
||||
public Boolean getShowIcon() {
|
||||
return showIcon != null ? showIcon : false;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -84,5 +97,22 @@ public class ListUsersCmd extends BaseListAccountResourcesCmd {
|
|||
ListResponse<UserResponse> response = _queryService.searchForUsers(this);
|
||||
response.setResponseName(getCommandName());
|
||||
this.setResponseObject(response);
|
||||
if (response != null && response.getCount() > 0 && getShowIcon()) {
|
||||
updateUserResponse(response.getResponses());
|
||||
}
|
||||
}
|
||||
|
||||
private void updateUserResponse(List<UserResponse> response) {
|
||||
for (UserResponse userResponse : response) {
|
||||
ResourceIcon resourceIcon = resourceIconManager.getByResourceTypeAndUuid(ResourceTag.ResourceObjectType.User, userResponse.getObjectId());
|
||||
if (resourceIcon == null) {
|
||||
resourceIcon = resourceIconManager.getByResourceTypeAndUuid(ResourceTag.ResourceObjectType.Account, userResponse.getAccountId());
|
||||
if (resourceIcon == null) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
ResourceIconResponse iconResponse = _responseGenerator.createResourceIconResponse(resourceIcon);
|
||||
userResponse.setResourceIconResponse(iconResponse);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -171,7 +171,7 @@ public class CreateZoneCmd extends BaseCmd {
|
|||
CallContext.current().setEventDetails("Zone Name: " + getZoneName());
|
||||
DataCenter result = _configService.createZone(this);
|
||||
if (result != null){
|
||||
ZoneResponse response = _responseGenerator.createZoneResponse(ResponseView.Full, result, false);
|
||||
ZoneResponse response = _responseGenerator.createZoneResponse(ResponseView.Full, result, false, false);
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -189,7 +189,7 @@ public class UpdateZoneCmd extends BaseCmd {
|
|||
CallContext.current().setEventDetails("Zone Id: " + getId());
|
||||
DataCenter result = _configService.editZone(this);
|
||||
if (result != null) {
|
||||
ZoneResponse response = _responseGenerator.createZoneResponse(ResponseView.Full, result, false);
|
||||
ZoneResponse response = _responseGenerator.createZoneResponse(ResponseView.Full, result, false, false);
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -20,6 +20,9 @@ import java.util.ArrayList;
|
|||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
|
||||
import com.cloud.server.ResourceIcon;
|
||||
import com.cloud.server.ResourceTag;
|
||||
import org.apache.cloudstack.api.response.ResourceIconResponse;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
|
|
@ -68,6 +71,10 @@ public class ListAccountsCmd extends BaseListDomainResourcesCmd implements UserC
|
|||
description = "comma separated list of account details requested, value can be a list of [ all, resource, min]")
|
||||
private List<String> viewDetails;
|
||||
|
||||
@Parameter(name = ApiConstants.SHOW_RESOURCE_ICON, type = CommandType.BOOLEAN,
|
||||
description = "flag to display the resource icon for accounts")
|
||||
private Boolean showIcon;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -111,6 +118,10 @@ public class ListAccountsCmd extends BaseListDomainResourcesCmd implements UserC
|
|||
return dv;
|
||||
}
|
||||
|
||||
public Boolean getShowIcon() {
|
||||
return showIcon != null ? showIcon : false;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -125,5 +136,19 @@ public class ListAccountsCmd extends BaseListDomainResourcesCmd implements UserC
|
|||
ListResponse<AccountResponse> response = _queryService.searchForAccounts(this);
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
if (response != null && response.getCount() > 0 && getShowIcon()) {
|
||||
updateAccountResponse(response.getResponses());
|
||||
}
|
||||
}
|
||||
|
||||
private void updateAccountResponse(List<AccountResponse> response) {
|
||||
for (AccountResponse accountResponse : response) {
|
||||
ResourceIcon resourceIcon = resourceIconManager.getByResourceTypeAndUuid(ResourceTag.ResourceObjectType.Account, accountResponse.getObjectId());
|
||||
if (resourceIcon == null) {
|
||||
continue;
|
||||
}
|
||||
ResourceIconResponse iconResponse = _responseGenerator.createResourceIconResponse(resourceIcon);
|
||||
accountResponse.setResourceIconResponse(iconResponse);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,9 @@
|
|||
// under the License.
|
||||
package org.apache.cloudstack.api.command.user.iso;
|
||||
|
||||
import com.cloud.server.ResourceIcon;
|
||||
import com.cloud.server.ResourceTag;
|
||||
import org.apache.cloudstack.api.response.ResourceIconResponse;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
|
|
@ -33,6 +36,8 @@ import org.apache.cloudstack.context.CallContext;
|
|||
import com.cloud.template.VirtualMachineTemplate.TemplateFilter;
|
||||
import com.cloud.user.Account;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@APICommand(name = "listIsos", description = "Lists all available ISO files.", responseObject = TemplateResponse.class, responseView = ResponseView.Restricted,
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
||||
public class ListIsosCmd extends BaseListTaggedResourcesCmd implements UserCmd {
|
||||
|
|
@ -82,6 +87,9 @@ public class ListIsosCmd extends BaseListTaggedResourcesCmd implements UserCmd {
|
|||
@Parameter(name = ApiConstants.SHOW_UNIQUE, type = CommandType.BOOLEAN, description = "If set to true, list only unique isos across zones", since = "4.13.2")
|
||||
private Boolean showUnique;
|
||||
|
||||
@Parameter(name = ApiConstants.SHOW_RESOURCE_ICON, type = CommandType.BOOLEAN, description = "flag to display the resource image for the isos")
|
||||
private Boolean showIcon;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -126,6 +134,10 @@ public class ListIsosCmd extends BaseListTaggedResourcesCmd implements UserCmd {
|
|||
return showUnique != null && showUnique;
|
||||
}
|
||||
|
||||
public Boolean getShowIcon () {
|
||||
return showIcon != null ? showIcon : false;
|
||||
}
|
||||
|
||||
public boolean listInReadyState() {
|
||||
Account account = CallContext.current().getCallingAccount();
|
||||
// It is account specific if account is admin type and domainId and accountName are not null
|
||||
|
|
@ -162,7 +174,21 @@ public class ListIsosCmd extends BaseListTaggedResourcesCmd implements UserCmd {
|
|||
@Override
|
||||
public void execute() {
|
||||
ListResponse<TemplateResponse> response = _queryService.listIsos(this);
|
||||
if (response != null && response.getCount() > 0 && getShowIcon()) {
|
||||
updateIsoResponse(response.getResponses());
|
||||
}
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
}
|
||||
|
||||
private void updateIsoResponse(List<TemplateResponse> response) {
|
||||
for (TemplateResponse templateResponse : response) {
|
||||
ResourceIcon resourceIcon = resourceIconManager.getByResourceTypeAndUuid(ResourceTag.ResourceObjectType.ISO, templateResponse.getId());
|
||||
if (resourceIcon == null) {
|
||||
continue;
|
||||
}
|
||||
ResourceIconResponse iconResponse = _responseGenerator.createResourceIconResponse(resourceIcon);
|
||||
templateResponse.setResourceIconResponse(iconResponse);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,10 @@ package org.apache.cloudstack.api.command.user.network;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.cloud.server.ResourceIcon;
|
||||
import com.cloud.server.ResourceTag;
|
||||
import org.apache.cloudstack.api.response.NetworkOfferingResponse;
|
||||
import org.apache.cloudstack.api.response.ResourceIconResponse;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
|
|
@ -93,6 +96,10 @@ public class ListNetworksCmd extends BaseListTaggedResourcesCmd implements UserC
|
|||
@Parameter(name = ApiConstants.NETWORK_OFFERING_ID, type = CommandType.UUID, entityType = NetworkOfferingResponse.class, description = "list networks by network offering ID")
|
||||
private Long networkOfferingId;
|
||||
|
||||
@Parameter(name = ApiConstants.SHOW_RESOURCE_ICON, type = CommandType.BOOLEAN,
|
||||
description = "flag to display the resource icon for networks")
|
||||
private Boolean showIcon;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -166,6 +173,11 @@ public class ListNetworksCmd extends BaseListTaggedResourcesCmd implements UserC
|
|||
}
|
||||
return super.getDisplay();
|
||||
}
|
||||
|
||||
public Boolean getShowIcon() {
|
||||
return showIcon != null ? showIcon : false;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -186,5 +198,22 @@ public class ListNetworksCmd extends BaseListTaggedResourcesCmd implements UserC
|
|||
response.setResponses(networkResponses, networks.second());
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
if (response != null && response.getCount() > 0 && getShowIcon()) {
|
||||
updateNetworkResponse(response.getResponses());
|
||||
}
|
||||
}
|
||||
|
||||
private void updateNetworkResponse(List<NetworkResponse> response) {
|
||||
for (NetworkResponse networkResponse : response) {
|
||||
ResourceIcon resourceIcon = resourceIconManager.getByResourceTypeAndUuid(ResourceTag.ResourceObjectType.Network, networkResponse.getId());
|
||||
if (resourceIcon == null) {
|
||||
resourceIcon = resourceIconManager.getByResourceTypeAndUuid(ResourceTag.ResourceObjectType.Vpc, networkResponse.getVpcId());
|
||||
if (resourceIcon == null) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
ResourceIconResponse iconResponse = _responseGenerator.createResourceIconResponse(resourceIcon);
|
||||
networkResponse.setResourceIconResponse(iconResponse);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,9 @@ import java.util.EnumSet;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.cloud.server.ResourceIcon;
|
||||
import com.cloud.server.ResourceTag;
|
||||
import org.apache.cloudstack.api.response.ResourceIconResponse;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
|
|
@ -72,6 +75,10 @@ public class ListProjectsCmd extends BaseListAccountResourcesCmd {
|
|||
description = "comma separated list of project details requested, value can be a list of [ all, resource, min]")
|
||||
private List<String> viewDetails;
|
||||
|
||||
@Parameter(name = ApiConstants.SHOW_RESOURCE_ICON, type = CommandType.BOOLEAN,
|
||||
description = "flag to display the resource icon for projects")
|
||||
private Boolean showIcon;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -124,6 +131,10 @@ public class ListProjectsCmd extends BaseListAccountResourcesCmd {
|
|||
return dv;
|
||||
}
|
||||
|
||||
public Boolean getShowIcon() {
|
||||
return showIcon != null ? showIcon : false;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -133,5 +144,19 @@ public class ListProjectsCmd extends BaseListAccountResourcesCmd {
|
|||
ListResponse<ProjectResponse> response = _queryService.listProjects(this);
|
||||
response.setResponseName(getCommandName());
|
||||
this.setResponseObject(response);
|
||||
if (response != null && response.getCount() > 0 && getShowIcon()) {
|
||||
updateProjectResponse(response.getResponses());
|
||||
}
|
||||
}
|
||||
|
||||
private void updateProjectResponse(List<ProjectResponse> response) {
|
||||
for (ProjectResponse projectResponse : response) {
|
||||
ResourceIcon resourceIcon = resourceIconManager.getByResourceTypeAndUuid(ResourceTag.ResourceObjectType.Project, projectResponse.getId());
|
||||
if (resourceIcon == null) {
|
||||
continue;
|
||||
}
|
||||
ResourceIconResponse iconResponse = _responseGenerator.createResourceIconResponse(resourceIcon);
|
||||
projectResponse.setResourceIconResponse(iconResponse);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,12 +54,12 @@ public class ListDetailOptionsCmd extends BaseCmd {
|
|||
/////////////////////////////////////////////////////
|
||||
|
||||
public ResourceTag.ResourceObjectType getResourceType() {
|
||||
return _taggedResourceService.getResourceType(resourceType);
|
||||
return resourceManagerUtil.getResourceType(resourceType);
|
||||
}
|
||||
|
||||
public String getResourceId() {
|
||||
if (!Strings.isNullOrEmpty(resourceId)) {
|
||||
return _taggedResourceService.getUuid(resourceId, getResourceType());
|
||||
return resourceManagerUtil.getUuid(resourceId, getResourceType());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ public class CreateTagsCmd extends BaseAsyncCmd {
|
|||
/////////////////////////////////////////////////////
|
||||
|
||||
public ResourceObjectType getResourceType() {
|
||||
return _taggedResourceService.getResourceType(resourceType);
|
||||
return resourceManagerUtil.getResourceType(resourceType);
|
||||
}
|
||||
|
||||
public Map<String, String> getTags() {
|
||||
|
|
@ -106,17 +106,17 @@ public class CreateTagsCmd extends BaseAsyncCmd {
|
|||
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||
setResponseObject(response);
|
||||
} else {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create tags");
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to upload resource icon");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventType() {
|
||||
return EventTypes.EVENT_TAGS_CREATE;
|
||||
return EventTypes.EVENT_RESOURCE_ICON_UPLOAD;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventDescription() {
|
||||
return "creating tags";
|
||||
return "Uploading resource icon";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ public class DeleteTagsCmd extends BaseAsyncCmd {
|
|||
/////////////////////////////////////////////////////
|
||||
|
||||
public ResourceObjectType getResourceType() {
|
||||
return _taggedResourceService.getResourceType(resourceType);
|
||||
return resourceManagerUtil.getResourceType(resourceType);
|
||||
}
|
||||
|
||||
public Map<String, String> getTags() {
|
||||
|
|
|
|||
|
|
@ -17,6 +17,9 @@
|
|||
package org.apache.cloudstack.api.command.user.template;
|
||||
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.server.ResourceIcon;
|
||||
import com.cloud.server.ResourceTag;
|
||||
import org.apache.cloudstack.api.response.ResourceIconResponse;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
|
|
@ -161,10 +164,17 @@ public class ListTemplatesCmd extends BaseListTaggedResourcesCmd implements User
|
|||
return onlyReady;
|
||||
}
|
||||
|
||||
@Parameter(name = ApiConstants.SHOW_RESOURCE_ICON, type = CommandType.BOOLEAN, description = "flag to display the resource image for the templates")
|
||||
private Boolean showIcon;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public Boolean getShowIcon () {
|
||||
return showIcon != null ? showIcon : false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return s_name;
|
||||
|
|
@ -178,10 +188,24 @@ public class ListTemplatesCmd extends BaseListTaggedResourcesCmd implements User
|
|||
@Override
|
||||
public void execute() {
|
||||
ListResponse<TemplateResponse> response = _queryService.listTemplates(this);
|
||||
if (response != null && response.getCount() > 0 && getShowIcon()) {
|
||||
updateTemplateResponse(response.getResponses());
|
||||
}
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
}
|
||||
|
||||
private void updateTemplateResponse(List<TemplateResponse> response) {
|
||||
for (TemplateResponse templateResponse : response) {
|
||||
ResourceIcon resourceIcon = resourceIconManager.getByResourceTypeAndUuid(ResourceTag.ResourceObjectType.Template, templateResponse.getId());
|
||||
if (resourceIcon == null) {
|
||||
continue;
|
||||
}
|
||||
ResourceIconResponse iconResponse = _responseGenerator.createResourceIconResponse(resourceIcon);
|
||||
templateResponse.setResourceIconResponse(iconResponse);
|
||||
}
|
||||
}
|
||||
|
||||
public List<Long> getIds() {
|
||||
return ids;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,10 @@ import java.util.ArrayList;
|
|||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
|
||||
import com.cloud.server.ResourceIcon;
|
||||
import com.cloud.server.ResourceTag;
|
||||
import org.apache.cloudstack.api.command.user.UserCmd;
|
||||
import org.apache.cloudstack.api.response.ResourceIconResponse;
|
||||
import org.apache.cloudstack.api.response.SecurityGroupResponse;
|
||||
import org.apache.cloudstack.api.response.UserResponse;
|
||||
import org.apache.log4j.Logger;
|
||||
|
|
@ -141,6 +144,10 @@ public class ListVMsCmd extends BaseListTaggedResourcesCmd implements UserCmd {
|
|||
@Parameter(name = ApiConstants.HA_ENABLE, type = CommandType.BOOLEAN, description = "list by the High Availability offering; true if filtering VMs with HA enabled; false for VMs with HA disabled", since = "4.15")
|
||||
private Boolean haEnabled;
|
||||
|
||||
@Parameter(name = ApiConstants.SHOW_RESOURCE_ICON, type = CommandType.BOOLEAN,
|
||||
description = "flag to display the resource icon for VMs", since = "4.16.0.0")
|
||||
private Boolean showIcon;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -252,6 +259,11 @@ public class ListVMsCmd extends BaseListTaggedResourcesCmd implements UserCmd {
|
|||
}
|
||||
return super.getDisplay();
|
||||
}
|
||||
|
||||
public Boolean getShowIcon() {
|
||||
return showIcon != null ? showIcon : false;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -268,7 +280,30 @@ public class ListVMsCmd extends BaseListTaggedResourcesCmd implements UserCmd {
|
|||
@Override
|
||||
public void execute() {
|
||||
ListResponse<UserVmResponse> response = _queryService.searchForUserVMs(this);
|
||||
if (response != null && response.getCount() > 0 && getShowIcon()) {
|
||||
updateVMResponse(response.getResponses());
|
||||
}
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
}
|
||||
|
||||
protected void updateVMResponse(List<UserVmResponse> response) {
|
||||
for (UserVmResponse vmResponse : response) {
|
||||
ResourceIcon resourceIcon = resourceIconManager.getByResourceTypeAndUuid(ResourceTag.ResourceObjectType.UserVm, vmResponse.getId());
|
||||
if (resourceIcon == null) {
|
||||
ResourceTag.ResourceObjectType type = ResourceTag.ResourceObjectType.Template;
|
||||
String uuid = vmResponse.getTemplateId();
|
||||
if (vmResponse.getIsoId() != null) {
|
||||
uuid = vmResponse.getIsoId();
|
||||
type = ResourceTag.ResourceObjectType.ISO;
|
||||
}
|
||||
resourceIcon = resourceIconManager.getByResourceTypeAndUuid(type, uuid);
|
||||
if (resourceIcon == null) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
ResourceIconResponse iconResponse = _responseGenerator.createResourceIconResponse(resourceIcon);
|
||||
vmResponse.setResourceIconResponse(iconResponse);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ public class AddResourceDetailCmd extends BaseAsyncCmd {
|
|||
}
|
||||
|
||||
public ResourceTag.ResourceObjectType getResourceType() {
|
||||
return _taggedResourceService.getResourceType(resourceType);
|
||||
return resourceManagerUtil.getResourceType(resourceType);
|
||||
}
|
||||
|
||||
public String getResourceId() {
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ public class ListResourceDetailsCmd extends BaseListProjectAndAccountResourcesCm
|
|||
}
|
||||
|
||||
public ResourceTag.ResourceObjectType getResourceType() {
|
||||
return _taggedResourceService.getResourceType(resourceType);
|
||||
return resourceManagerUtil.getResourceType(resourceType);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ public class RemoveResourceDetailCmd extends BaseAsyncCmd {
|
|||
/////////////////////////////////////////////////////
|
||||
|
||||
public ResourceTag.ResourceObjectType getResourceType() {
|
||||
return _taggedResourceService.getResourceType(resourceType);
|
||||
return resourceManagerUtil.getResourceType(resourceType);
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@ package org.apache.cloudstack.api.command.user.vpc;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.cloud.server.ResourceIcon;
|
||||
import com.cloud.server.ResourceTag;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
|
|
@ -27,6 +29,7 @@ import org.apache.cloudstack.api.Parameter;
|
|||
import org.apache.cloudstack.api.ResponseObject.ResponseView;
|
||||
import org.apache.cloudstack.api.command.user.UserCmd;
|
||||
import org.apache.cloudstack.api.response.ListResponse;
|
||||
import org.apache.cloudstack.api.response.ResourceIconResponse;
|
||||
import org.apache.cloudstack.api.response.VpcOfferingResponse;
|
||||
import org.apache.cloudstack.api.response.VpcResponse;
|
||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
||||
|
|
@ -76,6 +79,10 @@ public class ListVPCsCmd extends BaseListTaggedResourcesCmd implements UserCmd {
|
|||
@Parameter(name = ApiConstants.FOR_DISPLAY, type = CommandType.BOOLEAN, description = "list resources by display flag; only ROOT admin is eligible to pass this parameter", since = "4.4", authorized = {RoleType.Admin})
|
||||
private Boolean display;
|
||||
|
||||
@Parameter(name = ApiConstants.SHOW_RESOURCE_ICON, type = CommandType.BOOLEAN,
|
||||
description = "flag to display the resource icon for VPCs")
|
||||
private Boolean showIcon;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -124,6 +131,10 @@ public class ListVPCsCmd extends BaseListTaggedResourcesCmd implements UserCmd {
|
|||
return super.getDisplay();
|
||||
}
|
||||
|
||||
public Boolean getShowIcon() {
|
||||
return showIcon != null ? showIcon : false;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -144,6 +155,20 @@ public class ListVPCsCmd extends BaseListTaggedResourcesCmd implements UserCmd {
|
|||
response.setResponses(vpcResponses, vpcs.second());
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
if (response != null && response.getCount() > 0 && getShowIcon()) {
|
||||
updateVpcResponse(response.getResponses());
|
||||
}
|
||||
}
|
||||
|
||||
private void updateVpcResponse(List<VpcResponse> response) {
|
||||
for (VpcResponse vpcResponse : response) {
|
||||
ResourceIcon resourceIcon = resourceIconManager.getByResourceTypeAndUuid(ResourceTag.ResourceObjectType.Vpc, vpcResponse.getId());
|
||||
if (resourceIcon == null) {
|
||||
continue;
|
||||
}
|
||||
ResourceIconResponse iconResponse = _responseGenerator.createResourceIconResponse(resourceIcon);
|
||||
vpcResponse.setResourceIconResponse(iconResponse);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ public class AddVpnUserCmd extends BaseAsyncCreateCmd {
|
|||
if (!_ravService.applyVpnUsers(vpnUser.getAccountId(), userName)) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add vpn user");
|
||||
}
|
||||
}catch (Exception ex) {
|
||||
} catch (Exception ex) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -65,6 +65,9 @@ public class ListZonesCmd extends BaseListCmd implements UserCmd {
|
|||
@Parameter(name = ApiConstants.TAGS, type = CommandType.MAP, description = "List zones by resource tags (key/value pairs)", since = "4.3")
|
||||
private Map tags;
|
||||
|
||||
@Parameter(name = ApiConstants.SHOW_RESOURCE_ICON, type = CommandType.BOOLEAN, description = "flag to display the resource image for the zones")
|
||||
private Boolean showIcon;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -97,6 +100,10 @@ public class ListZonesCmd extends BaseListCmd implements UserCmd {
|
|||
return TaggedResources.parseKeyValueMap(tags, false);
|
||||
}
|
||||
|
||||
public Boolean getShowIcon () {
|
||||
return showIcon != null ? showIcon : false;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -108,7 +115,6 @@ public class ListZonesCmd extends BaseListCmd implements UserCmd {
|
|||
|
||||
@Override
|
||||
public void execute() {
|
||||
|
||||
ListResponse<ZoneResponse> response = _queryService.listDataCenters(this);
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ import com.cloud.user.Account;
|
|||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
@EntityReference(value = Account.class)
|
||||
public class AccountResponse extends BaseResponse implements ResourceLimitAndCountResponse {
|
||||
public class AccountResponse extends BaseResponse implements ResourceLimitAndCountResponse, SetResourceIconResponse {
|
||||
@SerializedName(ApiConstants.ID)
|
||||
@Param(description = "the id of the account")
|
||||
private String id;
|
||||
|
|
@ -263,6 +263,10 @@ public class AccountResponse extends BaseResponse implements ResourceLimitAndCou
|
|||
@Param(description = "the list of acl groups that account belongs to", since = "4.4")
|
||||
private List<String> groups;
|
||||
|
||||
@SerializedName(ApiConstants.RESOURCE_ICON)
|
||||
@Param(description = "Base64 string representation of the resource icon", since = "4.16.0.0")
|
||||
ResourceIconResponse icon;
|
||||
|
||||
@Override
|
||||
public String getObjectId() {
|
||||
return id;
|
||||
|
|
@ -537,4 +541,8 @@ public class AccountResponse extends BaseResponse implements ResourceLimitAndCou
|
|||
this.groups = groups;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setResourceIconResponse(ResourceIconResponse icon) {
|
||||
this.icon = icon;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ import com.cloud.serializer.Param;
|
|||
import java.util.Date;
|
||||
|
||||
@EntityReference(value = Domain.class)
|
||||
public class DomainResponse extends BaseResponseWithAnnotations implements ResourceLimitAndCountResponse {
|
||||
public class DomainResponse extends BaseResponseWithAnnotations implements ResourceLimitAndCountResponse, SetResourceIconResponse {
|
||||
@SerializedName(ApiConstants.ID)
|
||||
@Param(description = "the ID of the domain")
|
||||
private String id;
|
||||
|
|
@ -175,6 +175,10 @@ public class DomainResponse extends BaseResponseWithAnnotations implements Resou
|
|||
@SerializedName("secondarystorageavailable") @Param(description="the total secondary storage space (in GiB) available to be used for this domain", since="4.2.0")
|
||||
private String secondaryStorageAvailable;
|
||||
|
||||
@SerializedName(ApiConstants.RESOURCE_ICON)
|
||||
@Param(description = "Base64 string representation of the resource icon", since = "4.16.0.0")
|
||||
ResourceIconResponse icon;
|
||||
|
||||
public String getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
|
@ -429,4 +433,9 @@ public class DomainResponse extends BaseResponseWithAnnotations implements Resou
|
|||
public void setVmRunning(Integer vmRunning) {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setResourceIconResponse(ResourceIconResponse icon) {
|
||||
this.icon = icon;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ import com.google.gson.annotations.SerializedName;
|
|||
|
||||
@SuppressWarnings("unused")
|
||||
@EntityReference(value = {Network.class, ProjectAccount.class})
|
||||
public class NetworkResponse extends BaseResponseWithAnnotations implements ControlledEntityResponse {
|
||||
public class NetworkResponse extends BaseResponseWithAnnotations implements ControlledEntityResponse, SetResourceIconResponse {
|
||||
|
||||
@SerializedName(ApiConstants.ID)
|
||||
@Param(description = "the id of the network")
|
||||
|
|
@ -247,6 +247,10 @@ public class NetworkResponse extends BaseResponseWithAnnotations implements Cont
|
|||
@Param(description = "If the network has redundant routers enabled", since = "4.11.1")
|
||||
private Boolean redundantRouter;
|
||||
|
||||
@SerializedName(ApiConstants.RESOURCE_ICON)
|
||||
@Param(description = "Base64 string representation of the resource icon", since = "4.16.0.0")
|
||||
ResourceIconResponse icon;
|
||||
|
||||
@SerializedName(ApiConstants.CREATED)
|
||||
@Param(description = "the date this network was created", since = "4.16.0")
|
||||
private Date created;
|
||||
|
|
@ -271,6 +275,10 @@ public class NetworkResponse extends BaseResponseWithAnnotations implements Cont
|
|||
this.id = id;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
|
@ -428,6 +436,10 @@ public class NetworkResponse extends BaseResponseWithAnnotations implements Cont
|
|||
this.vpcId = vpcId;
|
||||
}
|
||||
|
||||
public String getVpcId() {
|
||||
return vpcId;
|
||||
}
|
||||
|
||||
public void setCanUseForDeploy(Boolean canUseForDeploy) {
|
||||
this.canUseForDeploy = canUseForDeploy;
|
||||
}
|
||||
|
|
@ -496,6 +508,11 @@ public class NetworkResponse extends BaseResponseWithAnnotations implements Cont
|
|||
this.vpcName = vpcName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setResourceIconResponse(ResourceIconResponse icon) {
|
||||
this.icon = icon;
|
||||
}
|
||||
|
||||
public Date getCreated() {
|
||||
return created;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ import com.cloud.serializer.Param;
|
|||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
@EntityReference(value = Project.class)
|
||||
public class ProjectResponse extends BaseResponse implements ResourceLimitAndCountResponse {
|
||||
public class ProjectResponse extends BaseResponse implements ResourceLimitAndCountResponse, SetResourceIconResponse {
|
||||
|
||||
@SerializedName(ApiConstants.ID)
|
||||
@Param(description = "the id of the project")
|
||||
|
|
@ -208,6 +208,10 @@ public class ProjectResponse extends BaseResponse implements ResourceLimitAndCou
|
|||
@Param(description = "the total number of virtual machines running for this project", since = "4.2.0")
|
||||
private Integer vmRunning;
|
||||
|
||||
@SerializedName(ApiConstants.RESOURCE_ICON)
|
||||
@Param(description = "Base64 string representation of the resource icon", since = "4.16.0.0")
|
||||
ResourceIconResponse icon;
|
||||
|
||||
@SerializedName(ApiConstants.CREATED)
|
||||
@Param(description = "the date this project was created", since = "4.16.0")
|
||||
private Date created;
|
||||
|
|
@ -216,6 +220,10 @@ public class ProjectResponse extends BaseResponse implements ResourceLimitAndCou
|
|||
this.id = id;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
|
@ -427,6 +435,11 @@ public class ProjectResponse extends BaseResponse implements ResourceLimitAndCou
|
|||
this.owners = owners;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setResourceIconResponse(ResourceIconResponse icon) {
|
||||
this.icon = icon;
|
||||
}
|
||||
|
||||
public Date getCreated() {
|
||||
return created;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,61 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.api.response;
|
||||
|
||||
import com.cloud.serializer.Param;
|
||||
import com.cloud.server.ResourceTag;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseResponse;
|
||||
|
||||
public class ResourceIconResponse extends BaseResponse {
|
||||
@SerializedName(ApiConstants.RESOURCE_TYPE)
|
||||
@Param(description = "resource type")
|
||||
private ResourceTag.ResourceObjectType resourceType;
|
||||
|
||||
@SerializedName(ApiConstants.RESOURCE_ID)
|
||||
@Param(description = "id of the resource")
|
||||
private String resourceId;
|
||||
|
||||
@SerializedName(ApiConstants.BASE64_IMAGE)
|
||||
@Param(description = "base64 representation of resource icon")
|
||||
private String image;
|
||||
|
||||
public ResourceTag.ResourceObjectType getResourceType() {
|
||||
return resourceType;
|
||||
}
|
||||
|
||||
public void setResourceType(ResourceTag.ResourceObjectType resourceType) {
|
||||
this.resourceType = resourceType;
|
||||
}
|
||||
|
||||
public String getResourceId() {
|
||||
return resourceId;
|
||||
}
|
||||
|
||||
public void setResourceId(String resourceId) {
|
||||
this.resourceId = resourceId;
|
||||
}
|
||||
|
||||
public String getImage() {
|
||||
return image;
|
||||
}
|
||||
|
||||
public void setImage(String image) {
|
||||
this.image = image;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.api.response;
|
||||
|
||||
public interface SetResourceIconResponse {
|
||||
void setResourceIconResponse(ResourceIconResponse icon);
|
||||
}
|
||||
|
|
@ -34,7 +34,7 @@ import com.google.gson.annotations.SerializedName;
|
|||
|
||||
@EntityReference(value = VirtualMachineTemplate.class)
|
||||
@SuppressWarnings("unused")
|
||||
public class TemplateResponse extends BaseResponseWithTagInformation implements ControlledViewEntityResponse {
|
||||
public class TemplateResponse extends BaseResponseWithTagInformation implements ControlledViewEntityResponse, SetResourceIconResponse {
|
||||
@SerializedName(ApiConstants.ID)
|
||||
@Param(description = "the template ID")
|
||||
private String id;
|
||||
|
|
@ -223,6 +223,10 @@ public class TemplateResponse extends BaseResponseWithTagInformation implements
|
|||
@Param(description = "the URL which the template/iso is registered from")
|
||||
private String url;
|
||||
|
||||
@SerializedName(ApiConstants.RESOURCE_ICON)
|
||||
@Param(description = "Base64 string representation of the resource icon", since = "4.16.0.0")
|
||||
ResourceIconResponse icon;
|
||||
|
||||
public TemplateResponse() {
|
||||
tags = new LinkedHashSet<>();
|
||||
}
|
||||
|
|
@ -458,4 +462,9 @@ public class TemplateResponse extends BaseResponseWithTagInformation implements
|
|||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setResourceIconResponse(ResourceIconResponse icon) {
|
||||
this.icon = icon;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ import com.cloud.serializer.Param;
|
|||
import com.cloud.user.User;
|
||||
|
||||
@EntityReference(value = User.class)
|
||||
public class UserResponse extends BaseResponse {
|
||||
public class UserResponse extends BaseResponse implements SetResourceIconResponse {
|
||||
@SerializedName("id")
|
||||
@Param(description = "the user ID")
|
||||
private String id;
|
||||
|
|
@ -115,6 +115,10 @@ public class UserResponse extends BaseResponse {
|
|||
@Param(description = "true if user is default, false otherwise", since = "4.2.0")
|
||||
private Boolean isDefault;
|
||||
|
||||
@SerializedName(ApiConstants.RESOURCE_ICON)
|
||||
@Param(description = "Base64 string representation of the resource icon", since = "4.16.0.0")
|
||||
ResourceIconResponse icon;
|
||||
|
||||
@Override
|
||||
public String getObjectId() {
|
||||
return this.getId();
|
||||
|
|
@ -275,4 +279,9 @@ public class UserResponse extends BaseResponse {
|
|||
this.userSource = User.Source.NATIVE.toString().toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setResourceIconResponse(ResourceIconResponse icon) {
|
||||
this.icon = icon;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ import com.google.gson.annotations.SerializedName;
|
|||
|
||||
@SuppressWarnings("unused")
|
||||
@EntityReference(value = {VirtualMachine.class, UserVm.class, VirtualRouter.class})
|
||||
public class UserVmResponse extends BaseResponseWithTagInformation implements ControlledEntityResponse {
|
||||
public class UserVmResponse extends BaseResponseWithTagInformation implements ControlledEntityResponse, SetResourceIconResponse {
|
||||
@SerializedName(ApiConstants.ID)
|
||||
@Param(description = "the ID of the virtual machine")
|
||||
private String id;
|
||||
|
|
@ -328,6 +328,10 @@ public class UserVmResponse extends BaseResponseWithTagInformation implements Co
|
|||
@Param(description = "the total number of network traffic bytes sent")
|
||||
private Long bytesSent;
|
||||
|
||||
@SerializedName(ApiConstants.RESOURCE_ICON)
|
||||
@Param(description = "Base64 string representation of the resource icon", since = "4.16.0.0")
|
||||
ResourceIconResponse resourceIconResponse;
|
||||
|
||||
public UserVmResponse() {
|
||||
securityGroupList = new LinkedHashSet<SecurityGroupResponse>();
|
||||
nics = new TreeSet<>(Comparator.comparingInt(x -> Integer.parseInt(x.getDeviceId())));
|
||||
|
|
@ -924,6 +928,15 @@ public class UserVmResponse extends BaseResponseWithTagInformation implements Co
|
|||
|
||||
public void setPoolType(String poolType) { this.poolType = poolType; }
|
||||
|
||||
@Override
|
||||
public void setResourceIconResponse(ResourceIconResponse resourceIconResponse) {
|
||||
this.resourceIconResponse = resourceIconResponse;
|
||||
}
|
||||
|
||||
public ResourceIconResponse getResourceIconResponse() {
|
||||
return resourceIconResponse;
|
||||
}
|
||||
|
||||
public void setLastUpdated(Date lastUpdated) {
|
||||
this.lastUpdated = lastUpdated;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ import com.google.gson.annotations.SerializedName;
|
|||
|
||||
@EntityReference(value = Vpc.class)
|
||||
@SuppressWarnings("unused")
|
||||
public class VpcResponse extends BaseResponseWithAnnotations implements ControlledEntityResponse {
|
||||
public class VpcResponse extends BaseResponseWithAnnotations implements ControlledEntityResponse, SetResourceIconResponse {
|
||||
@SerializedName("id")
|
||||
@Param(description = "the id of the VPC")
|
||||
private String id;
|
||||
|
|
@ -127,10 +127,18 @@ public class VpcResponse extends BaseResponseWithAnnotations implements Controll
|
|||
@Param(description = "if this VPC has redundant router", since = "4.6")
|
||||
private boolean redundantRouter;
|
||||
|
||||
@SerializedName(ApiConstants.RESOURCE_ICON)
|
||||
@Param(description = "Base64 string representation of the resource icon", since = "4.16.0.0")
|
||||
ResourceIconResponse icon;
|
||||
|
||||
public void setId(final String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setName(final String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
|
@ -231,4 +239,9 @@ public class VpcResponse extends BaseResponseWithAnnotations implements Controll
|
|||
public void setRedundantRouter(final Boolean redundantRouter) {
|
||||
this.redundantRouter = redundantRouter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setResourceIconResponse(ResourceIconResponse icon) {
|
||||
this.icon = icon;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ import com.google.gson.annotations.SerializedName;
|
|||
|
||||
@SuppressWarnings("unused")
|
||||
@EntityReference(value = DataCenter.class)
|
||||
public class ZoneResponse extends BaseResponseWithAnnotations {
|
||||
public class ZoneResponse extends BaseResponseWithAnnotations implements SetResourceIconResponse {
|
||||
@SerializedName(ApiConstants.ID)
|
||||
@Param(description = "Zone id")
|
||||
private String id;
|
||||
|
|
@ -125,6 +125,10 @@ public class ZoneResponse extends BaseResponseWithAnnotations {
|
|||
@Param(description = "Meta data associated with the zone (key/value pairs)", since = "4.3.0")
|
||||
private Map<String, String> resourceDetails;
|
||||
|
||||
@SerializedName(ApiConstants.RESOURCE_ICON)
|
||||
@Param(description = "Base64 string representation of the resource icon", since = "4.16.0.0")
|
||||
ResourceIconResponse resourceIconResponse;
|
||||
|
||||
public ZoneResponse() {
|
||||
tags = new LinkedHashSet<ResourceTagResponse>();
|
||||
}
|
||||
|
|
@ -315,4 +319,13 @@ public class ZoneResponse extends BaseResponseWithAnnotations {
|
|||
public Map<String, String> getResourceDetails() {
|
||||
return resourceDetails;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setResourceIconResponse(ResourceIconResponse resourceIconResponse) {
|
||||
this.resourceIconResponse = resourceIconResponse;
|
||||
}
|
||||
|
||||
public ResourceIconResponse getResourceIconResponse() {
|
||||
return resourceIconResponse;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import org.apache.cloudstack.api.command.admin.host.ListHostTagsCmd;
|
|||
import org.apache.cloudstack.api.command.admin.host.ListHostsCmd;
|
||||
import org.apache.cloudstack.api.command.admin.internallb.ListInternalLBVMsCmd;
|
||||
import org.apache.cloudstack.api.command.admin.management.ListMgmtsCmd;
|
||||
import org.apache.cloudstack.api.command.admin.resource.icon.ListResourceIconCmd;
|
||||
import org.apache.cloudstack.api.command.admin.router.GetRouterHealthCheckResultsCmd;
|
||||
import org.apache.cloudstack.api.command.admin.router.ListRoutersCmd;
|
||||
import org.apache.cloudstack.api.command.admin.storage.ListImageStoresCmd;
|
||||
|
|
@ -67,6 +68,7 @@ import org.apache.cloudstack.api.response.ProjectAccountResponse;
|
|||
import org.apache.cloudstack.api.response.ProjectInvitationResponse;
|
||||
import org.apache.cloudstack.api.response.ProjectResponse;
|
||||
import org.apache.cloudstack.api.response.ResourceDetailResponse;
|
||||
import org.apache.cloudstack.api.response.ResourceIconResponse;
|
||||
import org.apache.cloudstack.api.response.ResourceTagResponse;
|
||||
import org.apache.cloudstack.api.response.RouterHealthCheckResultResponse;
|
||||
import org.apache.cloudstack.api.response.SecurityGroupResponse;
|
||||
|
|
@ -159,6 +161,8 @@ public interface QueryService {
|
|||
|
||||
DetailOptionsResponse listDetailOptions(ListDetailOptionsCmd cmd);
|
||||
|
||||
ListResponse<ResourceIconResponse> listResourceIcons(ListResourceIconCmd cmd);
|
||||
|
||||
ListResponse<AffinityGroupResponse> searchForAffinityGroups(ListAffinityGroupsCmd cmd);
|
||||
|
||||
List<ResourceDetailResponse> listResourceDetails(ListResourceDetailsCmd cmd);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,167 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package com.cloud.resource.icon;
|
||||
|
||||
import com.cloud.server.ResourceIcon;
|
||||
import com.cloud.server.ResourceTag;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Enumerated;
|
||||
import javax.persistence.EnumType;
|
||||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
|
||||
@Entity
|
||||
@Table(name = "resource_icon")
|
||||
public class ResourceIconVO implements ResourceIcon {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "id")
|
||||
private long id;
|
||||
|
||||
@Column(name = "uuid")
|
||||
private String uuid;
|
||||
|
||||
@Column(name = "resource_id")
|
||||
long resourceId;
|
||||
|
||||
@Column(name = "resource_uuid")
|
||||
private String resourceUuid;
|
||||
|
||||
@Column(name = "resource_type")
|
||||
@Enumerated(value = EnumType.STRING)
|
||||
private ResourceTag.ResourceObjectType resourceType;
|
||||
|
||||
@Column(name = "icon", length = 65535)
|
||||
private String icon;
|
||||
|
||||
@Column(name = "created")
|
||||
@Temporal(value = TemporalType.TIMESTAMP)
|
||||
private Date created = null;
|
||||
|
||||
@Column(name = "updated")
|
||||
@Temporal(value = TemporalType.TIMESTAMP)
|
||||
Date updated;
|
||||
|
||||
@Column(name = "removed")
|
||||
@Temporal(value = TemporalType.TIMESTAMP)
|
||||
private Date removed;
|
||||
|
||||
protected ResourceIconVO() {
|
||||
uuid = UUID.randomUUID().toString();
|
||||
}
|
||||
|
||||
public ResourceIconVO(long resourceId, ResourceTag.ResourceObjectType resourceType, String resourceUuid, String icon) {
|
||||
super();
|
||||
this.resourceId = resourceId;
|
||||
this.resourceType = resourceType;
|
||||
uuid = UUID.randomUUID().toString();
|
||||
this.resourceUuid = resourceUuid;
|
||||
this.icon = icon;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
public void setUuid(String uuid) {
|
||||
this.uuid = uuid;
|
||||
}
|
||||
|
||||
public long getResourceId() {
|
||||
return resourceId;
|
||||
}
|
||||
|
||||
public void setResourceId(long resourceId) {
|
||||
this.resourceId = resourceId;
|
||||
}
|
||||
|
||||
public String getResourceUuid() {
|
||||
return resourceUuid;
|
||||
}
|
||||
|
||||
public void setResourceUuid(String resourceUuid) {
|
||||
this.resourceUuid = resourceUuid;
|
||||
}
|
||||
|
||||
public ResourceTag.ResourceObjectType getResourceType() {
|
||||
return resourceType;
|
||||
}
|
||||
|
||||
public void setResourceType(ResourceTag.ResourceObjectType resourceType) {
|
||||
this.resourceType = resourceType;
|
||||
}
|
||||
|
||||
public String getIcon() {
|
||||
return icon;
|
||||
}
|
||||
|
||||
public void setIcon(String icon) {
|
||||
this.icon = icon;
|
||||
}
|
||||
|
||||
public Date getCreated() {
|
||||
return created;
|
||||
}
|
||||
|
||||
public void setCreated(Date created) {
|
||||
this.created = created;
|
||||
}
|
||||
|
||||
public Date getUpdated() {
|
||||
return updated;
|
||||
}
|
||||
|
||||
public void setUpdated(Date updated) {
|
||||
this.updated = updated;
|
||||
}
|
||||
|
||||
public Date getRemoved() {
|
||||
return removed;
|
||||
}
|
||||
|
||||
public void setRemoved(Date removed) {
|
||||
this.removed = removed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ResourceIconVO{" +
|
||||
"id=" + id +
|
||||
", uuid='" + uuid + '\'' +
|
||||
", resourceId=" + resourceId +
|
||||
", resourceUuid='" + resourceUuid + '\'' +
|
||||
", resourceType=" + resourceType +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package com.cloud.resource.icon.dao;
|
||||
|
||||
import com.cloud.resource.icon.ResourceIconVO;
|
||||
import com.cloud.server.ResourceIcon;
|
||||
import com.cloud.server.ResourceTag;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
import org.apache.cloudstack.api.response.ResourceIconResponse;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ResourceIconDao extends GenericDao<ResourceIconVO, Long> {
|
||||
ResourceIconResponse newResourceIconResponse(ResourceIcon resourceIconVO);
|
||||
ResourceIconVO findByResourceUuid(String resourceUuid, ResourceTag.ResourceObjectType resourceType);
|
||||
List<ResourceIconResponse> listResourceIcons(List<String> resourceUuids, ResourceTag.ResourceObjectType resourceType);
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package com.cloud.resource.icon.dao;
|
||||
|
||||
import com.cloud.resource.icon.ResourceIconVO;
|
||||
import com.cloud.server.ResourceIcon;
|
||||
import com.cloud.server.ResourceTag;
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.response.ResourceIconResponse;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ResourceIconDaoImpl extends GenericDaoBase<ResourceIconVO, Long> implements ResourceIconDao {
|
||||
public static final Logger s_logger = Logger.getLogger(ResourceIconDaoImpl.class);
|
||||
private final SearchBuilder<ResourceIconVO> AllFieldsSearch;
|
||||
|
||||
protected ResourceIconDaoImpl() {
|
||||
AllFieldsSearch = createSearchBuilder();
|
||||
AllFieldsSearch.and("resourceId", AllFieldsSearch.entity().getResourceId(), SearchCriteria.Op.EQ);
|
||||
AllFieldsSearch.and("uuid", AllFieldsSearch.entity().getResourceUuid(), SearchCriteria.Op.IN);
|
||||
AllFieldsSearch.and("resourceType", AllFieldsSearch.entity().getResourceType(), SearchCriteria.Op.EQ);
|
||||
AllFieldsSearch.done();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceIconResponse newResourceIconResponse(ResourceIcon resourceIcon) {
|
||||
ResourceIconResponse resourceIconResponse = new ResourceIconResponse();
|
||||
resourceIconResponse.setResourceId(resourceIcon.getResourceUuid());
|
||||
resourceIconResponse.setResourceType(resourceIcon.getResourceType());
|
||||
resourceIconResponse.setImage(resourceIcon.getIcon());
|
||||
resourceIconResponse.setObjectName(ApiConstants.RESOURCE_ICON);
|
||||
return resourceIconResponse;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceIconVO findByResourceUuid(String resourceUuid, ResourceTag.ResourceObjectType resourceType) {
|
||||
SearchCriteria<ResourceIconVO> sc = AllFieldsSearch.create();
|
||||
sc.setParameters("uuid", (Object[]) new String[]{resourceUuid});
|
||||
sc.setParameters("resourceType", resourceType);
|
||||
return findOneBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ResourceIconResponse> listResourceIcons(List<String> resourceUuids, ResourceTag.ResourceObjectType resourceType) {
|
||||
SearchCriteria<ResourceIconVO> sc = AllFieldsSearch.create();
|
||||
sc.setParameters("uuid", resourceUuids.toArray());
|
||||
sc.setParameters("resourceType", resourceType);
|
||||
List<ResourceIconVO> resourceIcons = listBy(sc);
|
||||
List<ResourceIconResponse> iconResponses = new ArrayList<>();
|
||||
for (ResourceIconVO resourceIcon : resourceIcons) {
|
||||
ResourceIconResponse response = new ResourceIconResponse();
|
||||
response.setResourceId(resourceIcon.getResourceUuid());
|
||||
response.setResourceType(resourceIcon.getResourceType());
|
||||
response.setImage(resourceIcon.getIcon());
|
||||
response.setObjectName(ApiConstants.RESOURCE_ICON);
|
||||
iconResponses.add(response);
|
||||
}
|
||||
return iconResponses;
|
||||
}
|
||||
}
|
||||
|
|
@ -173,6 +173,7 @@
|
|||
<bean id="regionDaoImpl" class="org.apache.cloudstack.region.dao.RegionDaoImpl" />
|
||||
<bean id="remoteAccessVpnDaoImpl" class="com.cloud.network.dao.RemoteAccessVpnDaoImpl" />
|
||||
<bean id="resourceCountDaoImpl" class="com.cloud.configuration.dao.ResourceCountDaoImpl" />
|
||||
<bean id="resourceIconDaoImpl" class="com.cloud.resource.icon.dao.ResourceIconDaoImpl" />
|
||||
<bean id="resourceLimitDaoImpl" class="com.cloud.configuration.dao.ResourceLimitDaoImpl" />
|
||||
<bean id="resourceTagJoinDaoImpl" class="com.cloud.api.query.dao.ResourceTagJoinDaoImpl" />
|
||||
<bean id="resourceTagsDaoImpl" class="com.cloud.tags.dao.ResourceTagsDaoImpl" />
|
||||
|
|
|
|||
|
|
@ -697,6 +697,20 @@ CREATE VIEW `cloud`.`host_view` AS
|
|||
GROUP BY
|
||||
`host`.`id`;
|
||||
|
||||
CREATE TABLE `cloud`.`resource_icon` (
|
||||
`id` bigint unsigned NOT NULL auto_increment COMMENT 'id',
|
||||
`uuid` varchar(40),
|
||||
`icon` blob COMMENT 'Base64 version of the resource icon',
|
||||
`resource_id` bigint unsigned NOT NULL,
|
||||
`resource_uuid` varchar(40),
|
||||
`resource_type` varchar(255),
|
||||
`updated` datetime default NULL,
|
||||
`created` datetime default NULL,
|
||||
`removed` datetime default NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
CONSTRAINT `uc_resource_icon__uuid` UNIQUE (`uuid`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
ALTER TABLE `cloud`.`annotations` ADD COLUMN `admins_only` tinyint(1) unsigned NOT NULL DEFAULT 1;
|
||||
|
||||
-- Allow annotations for resource admins, domain admins and users
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ public class ListVMsMetricsCmd extends ListVMsCmd {
|
|||
@Override
|
||||
public void execute() {
|
||||
ListResponse<UserVmResponse> userVms = _queryService.searchForUserVMs(this);
|
||||
updateVMResponse(userVms.getResponses());
|
||||
final List<VmMetricsResponse> metricsResponses = metricsService.listVmMetrics(userVms.getResponses());
|
||||
ListResponse<VmMetricsResponse> response = new ListResponse<>();
|
||||
response.setResponses(metricsResponses, userVms.getCount());
|
||||
|
|
|
|||
|
|
@ -27,6 +27,9 @@ import java.util.Set;
|
|||
import javax.annotation.PostConstruct;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.cloud.resource.icon.ResourceIconVO;
|
||||
import com.cloud.resource.icon.dao.ResourceIconDao;
|
||||
import com.cloud.server.ResourceIcon;
|
||||
import org.apache.cloudstack.acl.Role;
|
||||
import org.apache.cloudstack.acl.RoleService;
|
||||
import org.apache.cloudstack.affinity.AffinityGroup;
|
||||
|
|
@ -55,6 +58,7 @@ import org.apache.cloudstack.api.response.NetworkOfferingResponse;
|
|||
import org.apache.cloudstack.api.response.ProjectAccountResponse;
|
||||
import org.apache.cloudstack.api.response.ProjectInvitationResponse;
|
||||
import org.apache.cloudstack.api.response.ProjectResponse;
|
||||
import org.apache.cloudstack.api.response.ResourceIconResponse;
|
||||
import org.apache.cloudstack.api.response.ResourceTagResponse;
|
||||
import org.apache.cloudstack.api.response.SecurityGroupResponse;
|
||||
import org.apache.cloudstack.api.response.ServiceOfferingResponse;
|
||||
|
|
@ -258,6 +262,7 @@ import com.cloud.server.ResourceTag;
|
|||
import com.cloud.server.ResourceTag.ResourceObjectType;
|
||||
import com.cloud.server.StatsCollector;
|
||||
import com.cloud.server.TaggedResourceService;
|
||||
import com.cloud.server.ResourceManagerUtil;
|
||||
import com.cloud.service.ServiceOfferingDetailsVO;
|
||||
import com.cloud.service.ServiceOfferingVO;
|
||||
import com.cloud.service.dao.ServiceOfferingDao;
|
||||
|
|
@ -418,6 +423,7 @@ public class ApiDBUtils {
|
|||
static AutoScaleVmGroupDao s_asVmGroupDao;
|
||||
static CounterDao s_counterDao;
|
||||
static ResourceTagJoinDao s_tagJoinDao;
|
||||
static ResourceIconDao s_resourceIconDao;
|
||||
static EventJoinDao s_eventJoinDao;
|
||||
static InstanceGroupJoinDao s_vmGroupJoinDao;
|
||||
static UserAccountJoinDao s_userAccountJoinDao;
|
||||
|
|
@ -462,6 +468,7 @@ public class ApiDBUtils {
|
|||
static BackupScheduleDao s_backupScheduleDao;
|
||||
static BackupOfferingDao s_backupOfferingDao;
|
||||
static NicDao s_nicDao;
|
||||
static ResourceManagerUtil s_resourceManagerUtil;
|
||||
|
||||
@Inject
|
||||
private ManagementServer ms;
|
||||
|
|
@ -708,6 +715,10 @@ public class ApiDBUtils {
|
|||
private BackupScheduleDao backupScheduleDao;
|
||||
@Inject
|
||||
private NicDao nicDao;
|
||||
@Inject
|
||||
private ResourceIconDao resourceIconDao;
|
||||
@Inject
|
||||
private ResourceManagerUtil resourceManagerUtil;
|
||||
|
||||
@PostConstruct
|
||||
void init() {
|
||||
|
|
@ -834,6 +845,8 @@ public class ApiDBUtils {
|
|||
s_backupDao = backupDao;
|
||||
s_backupScheduleDao = backupScheduleDao;
|
||||
s_backupOfferingDao = backupOfferingDao;
|
||||
s_resourceIconDao = resourceIconDao;
|
||||
s_resourceManagerUtil = resourceManagerUtil;
|
||||
}
|
||||
|
||||
// ///////////////////////////////////////////////////////////
|
||||
|
|
@ -1484,7 +1497,7 @@ public class ApiDBUtils {
|
|||
}
|
||||
|
||||
public static String getUuid(String resourceId, ResourceObjectType resourceType) {
|
||||
return s_taggedResourceService.getUuid(resourceId, resourceType);
|
||||
return s_resourceManagerUtil.getUuid(resourceId, resourceType);
|
||||
}
|
||||
|
||||
public static List<? extends ResourceTag> listByResourceTypeAndId(ResourceObjectType type, long resourceId) {
|
||||
|
|
@ -1800,6 +1813,10 @@ public class ApiDBUtils {
|
|||
return s_tagJoinDao.newResourceTagResponse(vsg, keyValueOnly);
|
||||
}
|
||||
|
||||
public static ResourceIconResponse newResourceIconResponse(ResourceIcon resourceIcon) {
|
||||
return s_resourceIconDao.newResourceIconResponse(resourceIcon);
|
||||
}
|
||||
|
||||
public static ResourceTagJoinVO newResourceTagView(ResourceTag sg) {
|
||||
return s_tagJoinDao.newResourceTagView(sg);
|
||||
}
|
||||
|
|
@ -2001,8 +2018,8 @@ public class ApiDBUtils {
|
|||
return s_serviceOfferingJoinDao.newServiceOfferingView(offering);
|
||||
}
|
||||
|
||||
public static ZoneResponse newDataCenterResponse(ResponseView view, DataCenterJoinVO dc, Boolean showCapacities) {
|
||||
return s_dcJoinDao.newDataCenterResponse(view, dc, showCapacities);
|
||||
public static ZoneResponse newDataCenterResponse(ResponseView view, DataCenterJoinVO dc, Boolean showCapacities, Boolean showResourceImage) {
|
||||
return s_dcJoinDao.newDataCenterResponse(view, dc, showCapacities, showResourceImage);
|
||||
}
|
||||
|
||||
public static DataCenterJoinVO newDataCenterView(DataCenter dc) {
|
||||
|
|
@ -2081,6 +2098,10 @@ public class ApiDBUtils {
|
|||
return s_tagJoinDao.listBy(resourceUUID, resourceType);
|
||||
}
|
||||
|
||||
public static ResourceIconVO getResourceIconByResourceUUID(String resourceUUID, ResourceObjectType resourceType) {
|
||||
return s_resourceIconDao.findByResourceUuid(resourceUUID, resourceType);
|
||||
}
|
||||
|
||||
public static BackupResponse newBackupResponse(Backup backup) {
|
||||
return s_backupDao.newBackupResponse(backup);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ import java.util.stream.Collectors;
|
|||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.cloud.server.ResourceIcon;
|
||||
import org.apache.cloudstack.acl.ControlledEntity;
|
||||
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
|
||||
import org.apache.cloudstack.affinity.AffinityGroup;
|
||||
|
|
@ -113,6 +114,7 @@ import org.apache.cloudstack.api.response.ProviderResponse;
|
|||
import org.apache.cloudstack.api.response.RegionResponse;
|
||||
import org.apache.cloudstack.api.response.RemoteAccessVpnResponse;
|
||||
import org.apache.cloudstack.api.response.ResourceCountResponse;
|
||||
import org.apache.cloudstack.api.response.ResourceIconResponse;
|
||||
import org.apache.cloudstack.api.response.ResourceLimitResponse;
|
||||
import org.apache.cloudstack.api.response.ResourceTagResponse;
|
||||
import org.apache.cloudstack.api.response.RollingMaintenanceHostSkippedResponse;
|
||||
|
|
@ -1151,9 +1153,9 @@ public class ApiResponseHelper implements ResponseGenerator {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ZoneResponse createZoneResponse(ResponseView view, DataCenter dataCenter, Boolean showCapacities) {
|
||||
public ZoneResponse createZoneResponse(ResponseView view, DataCenter dataCenter, Boolean showCapacities, Boolean showResourceIcon) {
|
||||
DataCenterJoinVO vOffering = ApiDBUtils.newDataCenterView(dataCenter);
|
||||
return ApiDBUtils.newDataCenterResponse(view, vOffering, showCapacities);
|
||||
return ApiDBUtils.newDataCenterResponse(view, vOffering, showCapacities, showResourceIcon);
|
||||
}
|
||||
|
||||
public static List<CapacityResponse> getDataCenterCapacityResponse(Long zoneId) {
|
||||
|
|
@ -4457,4 +4459,9 @@ public class ApiResponseHelper implements ResponseGenerator {
|
|||
response.setObjectName("rollingmaintenance");
|
||||
return response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceIconResponse createResourceIconResponse(ResourceIcon resourceIcon) {
|
||||
return ApiDBUtils.newResourceIconResponse(resourceIcon);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,10 @@ import java.util.stream.Stream;
|
|||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.cloud.resource.icon.dao.ResourceIconDao;
|
||||
import com.cloud.server.ResourceManagerUtil;
|
||||
import com.cloud.storage.dao.VMTemplateDetailsDao;
|
||||
import com.cloud.vm.VirtualMachineManager;
|
||||
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
|
||||
import org.apache.cloudstack.affinity.AffinityGroupDomainMapVO;
|
||||
import org.apache.cloudstack.affinity.AffinityGroupResponse;
|
||||
|
|
@ -48,6 +52,7 @@ import org.apache.cloudstack.api.command.admin.host.ListHostsCmd;
|
|||
import org.apache.cloudstack.api.command.admin.internallb.ListInternalLBVMsCmd;
|
||||
import org.apache.cloudstack.api.command.admin.iso.ListIsosCmdByAdmin;
|
||||
import org.apache.cloudstack.api.command.admin.management.ListMgmtsCmd;
|
||||
import org.apache.cloudstack.api.command.admin.resource.icon.ListResourceIconCmd;
|
||||
import org.apache.cloudstack.api.command.admin.router.GetRouterHealthCheckResultsCmd;
|
||||
import org.apache.cloudstack.api.command.admin.router.ListRoutersCmd;
|
||||
import org.apache.cloudstack.api.command.admin.storage.ListImageStoresCmd;
|
||||
|
|
@ -93,6 +98,7 @@ import org.apache.cloudstack.api.response.ProjectAccountResponse;
|
|||
import org.apache.cloudstack.api.response.ProjectInvitationResponse;
|
||||
import org.apache.cloudstack.api.response.ProjectResponse;
|
||||
import org.apache.cloudstack.api.response.ResourceDetailResponse;
|
||||
import org.apache.cloudstack.api.response.ResourceIconResponse;
|
||||
import org.apache.cloudstack.api.response.ResourceTagResponse;
|
||||
import org.apache.cloudstack.api.response.RouterHealthCheckResultResponse;
|
||||
import org.apache.cloudstack.api.response.SecurityGroupResponse;
|
||||
|
|
@ -217,7 +223,6 @@ import com.cloud.storage.VMTemplateVO;
|
|||
import com.cloud.storage.Volume;
|
||||
import com.cloud.storage.dao.StoragePoolTagsDao;
|
||||
import com.cloud.storage.dao.VMTemplateDao;
|
||||
import com.cloud.storage.dao.VMTemplateDetailsDao;
|
||||
import com.cloud.tags.ResourceTagVO;
|
||||
import com.cloud.tags.dao.ResourceTagDao;
|
||||
import com.cloud.template.VirtualMachineTemplate.State;
|
||||
|
|
@ -244,7 +249,6 @@ import com.cloud.vm.DomainRouterVO;
|
|||
import com.cloud.vm.UserVmVO;
|
||||
import com.cloud.vm.VMInstanceVO;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachineManager;
|
||||
import com.cloud.vm.VmDetailConstants;
|
||||
import com.cloud.vm.dao.DomainRouterDao;
|
||||
import com.cloud.vm.dao.UserVmDao;
|
||||
|
|
@ -383,6 +387,9 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||
@Inject
|
||||
private TaggedResourceService _taggedResourceMgr;
|
||||
|
||||
@Inject
|
||||
private ResourceManagerUtil resourceManagerUtil;
|
||||
|
||||
@Inject
|
||||
private AffinityGroupVMMapDao _affinityGroupVMMapDao;
|
||||
|
||||
|
|
@ -437,6 +444,9 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||
@Inject
|
||||
private VirtualMachineManager virtualMachineManager;
|
||||
|
||||
@Inject
|
||||
private ResourceIconDao resourceIconDao;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
|
|
@ -3145,7 +3155,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||
respView = ResponseView.Full;
|
||||
}
|
||||
|
||||
List<ZoneResponse> dcResponses = ViewResponseHelper.createDataCenterResponse(respView, cmd.getShowCapacities(), result.first().toArray(new DataCenterJoinVO[result.first().size()]));
|
||||
List<ZoneResponse> dcResponses = ViewResponseHelper.createDataCenterResponse(respView, cmd.getShowCapacities(), cmd.getShowIcon(), result.first().toArray(new DataCenterJoinVO[result.first().size()]));
|
||||
response.setResponses(dcResponses, result.second());
|
||||
return response;
|
||||
}
|
||||
|
|
@ -3792,6 +3802,13 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||
return new DetailOptionsResponse(options);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListResponse<ResourceIconResponse> listResourceIcons(ListResourceIconCmd cmd) {
|
||||
ListResponse<ResourceIconResponse> responses = new ListResponse<>();
|
||||
responses.setResponses(resourceIconDao.listResourceIcons(cmd.getResourceIds(), cmd.getResourceType()));
|
||||
return responses;
|
||||
}
|
||||
|
||||
private void fillVMOrTemplateDetailOptions(final Map<String, List<String>> options, final HypervisorType hypervisorType) {
|
||||
if (options == null) {
|
||||
throw new CloudRuntimeException("Invalid/null detail-options response object passed");
|
||||
|
|
@ -4066,7 +4083,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||
|
||||
//Validation - 1.3
|
||||
if (resourceIdStr != null) {
|
||||
resourceId = _taggedResourceMgr.getResourceId(resourceIdStr, resourceType);
|
||||
resourceId = resourceManagerUtil.getResourceId(resourceIdStr, resourceType);
|
||||
if (resourceId == null) {
|
||||
throw new InvalidParameterValueException("Cannot find resource with resourceId " + resourceIdStr + " and of resource type " + resourceType);
|
||||
}
|
||||
|
|
@ -4102,7 +4119,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||
|
||||
protected ResourceDetailResponse createResourceDetailsResponse(ResourceDetail requestedDetail, ResourceTag.ResourceObjectType resourceType) {
|
||||
ResourceDetailResponse resourceDetailResponse = new ResourceDetailResponse();
|
||||
resourceDetailResponse.setResourceId(_taggedResourceMgr.getUuid(String.valueOf(requestedDetail.getResourceId()), resourceType));
|
||||
resourceDetailResponse.setResourceId(resourceManagerUtil.getUuid(String.valueOf(requestedDetail.getResourceId()), resourceType));
|
||||
resourceDetailResponse.setName(requestedDetail.getName());
|
||||
resourceDetailResponse.setValue(requestedDetail.getValue());
|
||||
resourceDetailResponse.setForDisplay(requestedDetail.isDisplay());
|
||||
|
|
|
|||
|
|
@ -560,10 +560,10 @@ public class ViewResponseHelper {
|
|||
return respList;
|
||||
}
|
||||
|
||||
public static List<ZoneResponse> createDataCenterResponse(ResponseView view, Boolean showCapacities, DataCenterJoinVO... dcs) {
|
||||
public static List<ZoneResponse> createDataCenterResponse(ResponseView view, Boolean showCapacities, Boolean showResourceImage, DataCenterJoinVO... dcs) {
|
||||
List<ZoneResponse> respList = new ArrayList<ZoneResponse>();
|
||||
for (DataCenterJoinVO vt : dcs){
|
||||
respList.add(ApiDBUtils.newDataCenterResponse(view, vt, showCapacities));
|
||||
respList.add(ApiDBUtils.newDataCenterResponse(view, vt, showCapacities, showResourceImage));
|
||||
}
|
||||
return respList;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ import com.cloud.utils.db.GenericDao;
|
|||
|
||||
public interface DataCenterJoinDao extends GenericDao<DataCenterJoinVO, Long> {
|
||||
|
||||
ZoneResponse newDataCenterResponse(ResponseView view, DataCenterJoinVO dof, Boolean showCapacities);
|
||||
ZoneResponse newDataCenterResponse(ResponseView view, DataCenterJoinVO dof, Boolean showCapacities, Boolean showResourceImage);
|
||||
|
||||
DataCenterJoinVO newDataCenterView(DataCenter dof);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ import java.util.List;
|
|||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.cloud.resource.icon.ResourceIconVO;
|
||||
import org.apache.cloudstack.api.response.ResourceIconResponse;
|
||||
import org.apache.cloudstack.annotation.AnnotationService;
|
||||
import org.apache.cloudstack.annotation.dao.AnnotationDao;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
|
|
@ -61,7 +63,7 @@ public class DataCenterJoinDaoImpl extends GenericDaoBase<DataCenterJoinVO, Long
|
|||
}
|
||||
|
||||
@Override
|
||||
public ZoneResponse newDataCenterResponse(ResponseView view, DataCenterJoinVO dataCenter, Boolean showCapacities) {
|
||||
public ZoneResponse newDataCenterResponse(ResponseView view, DataCenterJoinVO dataCenter, Boolean showCapacities, Boolean showResourceImage) {
|
||||
ZoneResponse zoneResponse = new ZoneResponse();
|
||||
zoneResponse.setId(dataCenter.getUuid());
|
||||
zoneResponse.setName(dataCenter.getName());
|
||||
|
|
@ -107,6 +109,14 @@ public class DataCenterJoinDaoImpl extends GenericDaoBase<DataCenterJoinVO, Long
|
|||
zoneResponse.addTag(tagResponse);
|
||||
}
|
||||
|
||||
if (showResourceImage) {
|
||||
ResourceIconVO resourceIcon = ApiDBUtils.getResourceIconByResourceUUID(dataCenter.getUuid(), ResourceObjectType.Zone);
|
||||
if (resourceIcon != null) {
|
||||
ResourceIconResponse iconResponse = ApiDBUtils.newResourceIconResponse(resourceIcon);
|
||||
zoneResponse.setResourceIconResponse(iconResponse);
|
||||
}
|
||||
}
|
||||
|
||||
zoneResponse.setResourceDetails(ApiDBUtils.getResourceDetails(dataCenter.getId(), ResourceObjectType.Zone));
|
||||
zoneResponse.setHasAnnotation(annotationDao.hasAnnotations(dataCenter.getUuid(), AnnotationService.EntityType.ZONE.name(),
|
||||
_accountMgr.isRootAdmin(CallContext.current().getCallingAccount().getId())));
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import javax.inject.Inject;
|
|||
import javax.naming.ConfigurationException;
|
||||
|
||||
import com.cloud.offerings.dao.NetworkOfferingDetailsDao;
|
||||
import com.cloud.server.ResourceManagerUtil;
|
||||
import org.apache.cloudstack.api.ResourceDetail;
|
||||
import org.apache.cloudstack.resourcedetail.ResourceDetailsDao;
|
||||
import org.apache.cloudstack.resourcedetail.dao.AutoScaleVmGroupDetailsDao;
|
||||
|
|
@ -127,6 +128,8 @@ public class ResourceMetaDataManagerImpl extends ManagerBase implements Resource
|
|||
GuestOsDetailsDao _guestOsDetailsDao;
|
||||
@Inject
|
||||
NetworkOfferingDetailsDao _networkOfferingDetailsDao;
|
||||
@Inject
|
||||
ResourceManagerUtil resourceManagerUtil;
|
||||
|
||||
private static Map<ResourceObjectType, ResourceDetailsDao<? extends ResourceDetail>> s_daoMap = new HashMap<ResourceObjectType, ResourceDetailsDao<? extends ResourceDetail>>();
|
||||
|
||||
|
|
@ -189,7 +192,7 @@ public class ResourceMetaDataManagerImpl extends ManagerBase implements Resource
|
|||
}
|
||||
|
||||
DetailDaoHelper newDetailDaoHelper = new DetailDaoHelper(resourceType);
|
||||
newDetailDaoHelper.addDetail(_taggedResourceMgr.getResourceId(resourceId, resourceType), key, value, forDisplay);
|
||||
newDetailDaoHelper.addDetail(resourceManagerUtil.getResourceId(resourceId, resourceType), key, value, forDisplay);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -201,7 +204,7 @@ public class ResourceMetaDataManagerImpl extends ManagerBase implements Resource
|
|||
@DB
|
||||
@ActionEvent(eventType = EventTypes.EVENT_RESOURCE_DETAILS_DELETE, eventDescription = "deleting resource meta data")
|
||||
public boolean deleteResourceMetaData(String resourceId, ResourceObjectType resourceType, String key) {
|
||||
long id = _taggedResourceMgr.getResourceId(resourceId, resourceType);
|
||||
long id = resourceManagerUtil.getResourceId(resourceId, resourceType);
|
||||
|
||||
DetailDaoHelper newDetailDaoHelper = new DetailDaoHelper(resourceType);
|
||||
if (key != null) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,230 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package com.cloud.resourceicon;
|
||||
|
||||
import com.cloud.domain.PartOf;
|
||||
import com.cloud.event.ActionEvent;
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.metadata.ResourceMetaDataManagerImpl;
|
||||
import com.cloud.network.security.SecurityGroupRuleVO;
|
||||
import com.cloud.network.security.SecurityGroupVO;
|
||||
import com.cloud.network.vpc.NetworkACLItemVO;
|
||||
import com.cloud.network.vpc.NetworkACLVO;
|
||||
import com.cloud.network.vpc.VpcVO;
|
||||
import com.cloud.projects.ProjectVO;
|
||||
import com.cloud.resource.icon.dao.ResourceIconDao;
|
||||
import com.cloud.server.ResourceIcon;
|
||||
import com.cloud.server.ResourceIconManager;
|
||||
|
||||
import com.cloud.server.ResourceManagerUtil;
|
||||
import com.cloud.server.ResourceTag;
|
||||
import com.cloud.resource.icon.ResourceIconVO;
|
||||
import com.cloud.storage.SnapshotPolicyVO;
|
||||
import com.cloud.storage.VolumeVO;
|
||||
import com.cloud.tags.ResourceManagerUtilImpl;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountService;
|
||||
import com.cloud.user.AccountVO;
|
||||
import com.cloud.user.OwnedBy;
|
||||
import com.cloud.user.dao.AccountDao;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.component.ManagerBase;
|
||||
import com.cloud.utils.db.DB;
|
||||
import com.cloud.utils.db.EntityManager;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.db.Transaction;
|
||||
import com.cloud.utils.db.TransactionCallbackNoReturn;
|
||||
import com.cloud.utils.db.TransactionStatus;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.persistence.EntityExistsException;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ResourceIconManagerImpl extends ManagerBase implements ResourceIconManager {
|
||||
public static final Logger s_logger = Logger.getLogger(ResourceMetaDataManagerImpl.class);
|
||||
|
||||
@Inject
|
||||
AccountService accountService;
|
||||
@Inject
|
||||
ResourceManagerUtil resourceManagerUtil;
|
||||
@Inject
|
||||
ResourceIconDao resourceIconDao;
|
||||
@Inject
|
||||
EntityManager entityMgr;
|
||||
@Inject
|
||||
AccountDao accountDao;
|
||||
|
||||
private Pair<Long, Long> getAccountDomain(long resourceId, ResourceTag.ResourceObjectType resourceType) {
|
||||
Class<?> clazz = ResourceManagerUtilImpl.s_typeMap.get(resourceType);
|
||||
|
||||
Object entity = entityMgr.findById(clazz, resourceId);
|
||||
Long accountId = null;
|
||||
Long domainId = null;
|
||||
|
||||
// if the resource type is a security group rule, get the accountId and domainId from the security group itself
|
||||
if (resourceType == ResourceTag.ResourceObjectType.SecurityGroupRule) {
|
||||
SecurityGroupRuleVO rule = (SecurityGroupRuleVO)entity;
|
||||
Object SecurityGroup = entityMgr.findById(ResourceManagerUtilImpl.s_typeMap.get(ResourceTag.ResourceObjectType.SecurityGroup), rule.getSecurityGroupId());
|
||||
|
||||
accountId = ((SecurityGroupVO)SecurityGroup).getAccountId();
|
||||
domainId = ((SecurityGroupVO)SecurityGroup).getDomainId();
|
||||
}
|
||||
|
||||
if (resourceType == ResourceTag.ResourceObjectType.Account) {
|
||||
AccountVO account = (AccountVO)entity;
|
||||
accountId = account.getId();
|
||||
domainId = account.getDomainId();
|
||||
}
|
||||
|
||||
// if the resource type is network acl, get the accountId and domainId from VPC following: NetworkACLItem -> NetworkACL -> VPC
|
||||
if (resourceType == ResourceTag.ResourceObjectType.NetworkACL) {
|
||||
NetworkACLItemVO aclItem = (NetworkACLItemVO)entity;
|
||||
Object networkACL = entityMgr.findById(ResourceManagerUtilImpl.s_typeMap.get(ResourceTag.ResourceObjectType.NetworkACLList), aclItem.getAclId());
|
||||
Long vpcId = ((NetworkACLVO)networkACL).getVpcId();
|
||||
|
||||
if (vpcId != null && vpcId != 0) {
|
||||
Object vpc = entityMgr.findById(ResourceManagerUtilImpl.s_typeMap.get(ResourceTag.ResourceObjectType.Vpc), vpcId);
|
||||
|
||||
accountId = ((VpcVO)vpc).getAccountId();
|
||||
domainId = ((VpcVO)vpc).getDomainId();
|
||||
}
|
||||
}
|
||||
|
||||
if (resourceType == ResourceTag.ResourceObjectType.Project) {
|
||||
accountId = ((ProjectVO)entity).getProjectAccountId();
|
||||
}
|
||||
|
||||
if (resourceType == ResourceTag.ResourceObjectType.SnapshotPolicy) {
|
||||
accountId = entityMgr.findById(VolumeVO.class, ((SnapshotPolicyVO)entity).getVolumeId()).getAccountId();
|
||||
}
|
||||
|
||||
if (entity instanceof OwnedBy) {
|
||||
accountId = ((OwnedBy)entity).getAccountId();
|
||||
}
|
||||
|
||||
if (entity instanceof PartOf) {
|
||||
domainId = ((PartOf)entity).getDomainId();
|
||||
}
|
||||
|
||||
if (accountId == null) {
|
||||
accountId = Account.ACCOUNT_ID_SYSTEM;
|
||||
}
|
||||
|
||||
if ((domainId == null) || ((accountId != null) && (domainId.longValue() == -1))) {
|
||||
domainId = accountDao.getDomainIdForGivenAccountId(accountId);
|
||||
}
|
||||
return new Pair<>(accountId, domainId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@DB
|
||||
@ActionEvent(eventType = EventTypes.EVENT_RESOURCE_ICON_UPLOAD, eventDescription = "uploading resource icon")
|
||||
public boolean uploadResourceIcon(List<String> resourceIds, ResourceTag.ResourceObjectType resourceType, String base64Image) {
|
||||
final Account caller = CallContext.current().getCallingAccount();
|
||||
|
||||
Transaction.execute(new TransactionCallbackNoReturn() {
|
||||
@Override
|
||||
public void doInTransactionWithoutResult(TransactionStatus status) {
|
||||
for (String resourceId : resourceIds) {
|
||||
if (!resourceType.resourceIconSupport()) {
|
||||
throw new InvalidParameterValueException("The resource type " + resourceType + " doesn't support resource icons");
|
||||
}
|
||||
|
||||
if (base64Image == null) {
|
||||
throw new InvalidParameterValueException("No icon provided to be uploaded for resource: " + resourceId);
|
||||
}
|
||||
|
||||
long id = resourceManagerUtil.getResourceId(resourceId, resourceType);
|
||||
String resourceUuid = resourceManagerUtil.getUuid(resourceId, resourceType);
|
||||
ResourceIconVO existingResourceIcon = resourceIconDao.findByResourceUuid(resourceUuid, resourceType);
|
||||
ResourceIconVO resourceIcon = null;
|
||||
Pair<Long, Long> accountDomainPair = getAccountDomain(id, resourceType);
|
||||
Long domainId = accountDomainPair.second();
|
||||
Long accountId = accountDomainPair.first();
|
||||
resourceManagerUtil.checkResourceAccessible(accountId, domainId, String.format("Account ' %s ' doesn't have permissions to upload icon for resource ' %s ", caller, id));
|
||||
|
||||
if (existingResourceIcon == null) {
|
||||
resourceIcon = new ResourceIconVO(id, resourceType, resourceUuid, base64Image);
|
||||
} else {
|
||||
resourceIcon = existingResourceIcon;
|
||||
resourceIcon.setIcon(base64Image);
|
||||
resourceIcon.setUpdated(new Date());
|
||||
}
|
||||
try {
|
||||
resourceIconDao.persist(resourceIcon);
|
||||
} catch (EntityExistsException e) {
|
||||
throw new CloudRuntimeException(String.format("Image already uploaded for resource type: %s with id %s", resourceType.toString(), resourceId),e);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_RESOURCE_ICON_DELETE, eventDescription = "deleting resource icon")
|
||||
public boolean deleteResourceIcon(List<String> resourceIds, ResourceTag.ResourceObjectType resourceType) {
|
||||
Account caller = CallContext.current().getCallingAccount();
|
||||
List<? extends ResourceIcon> resourceIcons = searchResourceIcons(resourceIds, resourceType);
|
||||
if (resourceIcons.isEmpty()) {
|
||||
s_logger.debug("No resource Icon(s) uploaded for the specified resources");
|
||||
return false;
|
||||
}
|
||||
Transaction.execute(new TransactionCallbackNoReturn() {
|
||||
@Override
|
||||
public void doInTransactionWithoutResult(TransactionStatus status) {
|
||||
for (ResourceIcon resourceIcon : resourceIcons) {
|
||||
String resourceId = resourceIcon.getResourceUuid();
|
||||
long id = resourceManagerUtil.getResourceId(resourceId, resourceType);
|
||||
Pair<Long, Long> accountDomainPair = getAccountDomain(id, resourceType);
|
||||
Long domainId = accountDomainPair.second();
|
||||
Long accountId = accountDomainPair.first();
|
||||
resourceManagerUtil.checkResourceAccessible(accountId, domainId, String.format("Account ' %s ' doesn't have permissions to upload icon for resource ' %s ", caller, id));
|
||||
resourceIconDao.remove(resourceIcon.getId());
|
||||
s_logger.debug("Removed icon for resources (" +
|
||||
String.join(", ", resourceIds) + ")");
|
||||
}
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceIcon getByResourceTypeAndUuid(ResourceTag.ResourceObjectType type, String resourceId) {
|
||||
return resourceIconDao.findByResourceUuid(resourceId, type);
|
||||
}
|
||||
|
||||
private List<? extends ResourceIcon> searchResourceIcons(List<String> resourceIds, ResourceTag.ResourceObjectType resourceType) {
|
||||
List<String> resourceUuids = resourceIds.stream().map(resourceId -> resourceManagerUtil.getUuid(resourceId, resourceType)).collect(Collectors.toList());
|
||||
SearchBuilder<ResourceIconVO> sb = resourceIconDao.createSearchBuilder();
|
||||
sb.and("resourceUuid", sb.entity().getResourceUuid(), SearchCriteria.Op.IN);
|
||||
sb.and("resourceType", sb.entity().getResourceType(), SearchCriteria.Op.EQ);
|
||||
|
||||
SearchCriteria<ResourceIconVO> sc = sb.create();
|
||||
sc.setParameters("resourceUuid", resourceUuids.toArray());
|
||||
sc.setParameters("resourceType", resourceType);
|
||||
return resourceIconDao.search(sc, null);
|
||||
}
|
||||
}
|
||||
|
|
@ -179,6 +179,9 @@ import org.apache.cloudstack.api.command.admin.resource.ListAlertsCmd;
|
|||
import org.apache.cloudstack.api.command.admin.resource.ListCapacityCmd;
|
||||
import org.apache.cloudstack.api.command.admin.resource.StartRollingMaintenanceCmd;
|
||||
import org.apache.cloudstack.api.command.admin.resource.UploadCustomCertificateCmd;
|
||||
import org.apache.cloudstack.api.command.admin.resource.icon.DeleteResourceIconCmd;
|
||||
import org.apache.cloudstack.api.command.admin.resource.icon.ListResourceIconCmd;
|
||||
import org.apache.cloudstack.api.command.admin.resource.icon.UploadResourceIconCmd;
|
||||
import org.apache.cloudstack.api.command.admin.router.ConfigureOvsElementCmd;
|
||||
import org.apache.cloudstack.api.command.admin.router.ConfigureVirtualRouterElementCmd;
|
||||
import org.apache.cloudstack.api.command.admin.router.CreateVirtualRouterElementCmd;
|
||||
|
|
@ -3446,6 +3449,9 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||
cmdList.add(GetRouterHealthCheckResultsCmd.class);
|
||||
cmdList.add(StartRollingMaintenanceCmd.class);
|
||||
cmdList.add(MigrateSecondaryStorageDataCmd.class);
|
||||
cmdList.add(UploadResourceIconCmd.class);
|
||||
cmdList.add(DeleteResourceIconCmd.class);
|
||||
cmdList.add(ListResourceIconCmd.class);
|
||||
|
||||
// Out-of-band management APIs for admins
|
||||
cmdList.add(EnableOutOfBandManagementForHostCmd.class);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,186 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package com.cloud.tags;
|
||||
|
||||
import com.cloud.dc.DataCenterVO;
|
||||
import com.cloud.domain.DomainVO;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.exception.PermissionDeniedException;
|
||||
import com.cloud.network.LBHealthCheckPolicyVO;
|
||||
import com.cloud.network.as.AutoScaleVmGroupVO;
|
||||
import com.cloud.network.as.AutoScaleVmProfileVO;
|
||||
|
||||
import com.cloud.network.rules.FirewallRuleVO;
|
||||
import com.cloud.network.rules.PortForwardingRuleVO;
|
||||
import com.cloud.network.security.SecurityGroupRuleVO;
|
||||
import com.cloud.network.security.SecurityGroupVO;
|
||||
import com.cloud.network.dao.IPAddressVO;
|
||||
import com.cloud.network.dao.LBStickinessPolicyVO;
|
||||
import com.cloud.network.dao.LoadBalancerVO;
|
||||
import com.cloud.network.dao.NetworkVO;
|
||||
import com.cloud.network.dao.RemoteAccessVpnVO;
|
||||
import com.cloud.network.dao.Site2SiteCustomerGatewayVO;
|
||||
import com.cloud.network.dao.Site2SiteVpnConnectionVO;
|
||||
import com.cloud.network.dao.Site2SiteVpnGatewayVO;
|
||||
import com.cloud.network.vpc.NetworkACLItemVO;
|
||||
import com.cloud.network.vpc.NetworkACLVO;
|
||||
import com.cloud.network.vpc.StaticRouteVO;
|
||||
import com.cloud.network.vpc.VpcOfferingVO;
|
||||
import com.cloud.network.vpc.VpcVO;
|
||||
import com.cloud.offerings.NetworkOfferingVO;
|
||||
import com.cloud.projects.ProjectVO;
|
||||
import com.cloud.server.ResourceManagerUtil;
|
||||
import com.cloud.server.ResourceTag;
|
||||
import com.cloud.service.ServiceOfferingVO;
|
||||
import com.cloud.storage.SnapshotVO;
|
||||
import com.cloud.storage.VMTemplateVO;
|
||||
import com.cloud.storage.VolumeVO;
|
||||
import com.cloud.storage.DiskOfferingVO;
|
||||
import com.cloud.storage.SnapshotPolicyVO;
|
||||
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountManager;
|
||||
import com.cloud.user.AccountVO;
|
||||
import com.cloud.user.DomainManager;
|
||||
import com.cloud.user.UserVO;
|
||||
import com.cloud.utils.db.EntityManager;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.vm.NicVO;
|
||||
import com.cloud.vm.UserVmVO;
|
||||
import com.cloud.vm.snapshot.VMSnapshotVO;
|
||||
import org.apache.cloudstack.api.Identity;
|
||||
import org.apache.cloudstack.api.InternalIdentity;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
public class ResourceManagerUtilImpl implements ResourceManagerUtil {
|
||||
public static final Map<ResourceTag.ResourceObjectType, Class<?>> s_typeMap = new HashMap<>();
|
||||
|
||||
static {
|
||||
s_typeMap.put(ResourceTag.ResourceObjectType.UserVm, UserVmVO.class);
|
||||
s_typeMap.put(ResourceTag.ResourceObjectType.Volume, VolumeVO.class);
|
||||
s_typeMap.put(ResourceTag.ResourceObjectType.Template, VMTemplateVO.class);
|
||||
s_typeMap.put(ResourceTag.ResourceObjectType.ISO, VMTemplateVO.class);
|
||||
s_typeMap.put(ResourceTag.ResourceObjectType.Snapshot, SnapshotVO.class);
|
||||
s_typeMap.put(ResourceTag.ResourceObjectType.Network, NetworkVO.class);
|
||||
s_typeMap.put(ResourceTag.ResourceObjectType.LoadBalancer, LoadBalancerVO.class);
|
||||
s_typeMap.put(ResourceTag.ResourceObjectType.PortForwardingRule, PortForwardingRuleVO.class);
|
||||
s_typeMap.put(ResourceTag.ResourceObjectType.FirewallRule, FirewallRuleVO.class);
|
||||
s_typeMap.put(ResourceTag.ResourceObjectType.SecurityGroup, SecurityGroupVO.class);
|
||||
s_typeMap.put(ResourceTag.ResourceObjectType.SecurityGroupRule, SecurityGroupRuleVO.class);
|
||||
s_typeMap.put(ResourceTag.ResourceObjectType.PublicIpAddress, IPAddressVO.class);
|
||||
s_typeMap.put(ResourceTag.ResourceObjectType.Project, ProjectVO.class);
|
||||
s_typeMap.put(ResourceTag.ResourceObjectType.Account, AccountVO.class);
|
||||
s_typeMap.put(ResourceTag.ResourceObjectType.Vpc, VpcVO.class);
|
||||
s_typeMap.put(ResourceTag.ResourceObjectType.Nic, NicVO.class);
|
||||
s_typeMap.put(ResourceTag.ResourceObjectType.NetworkACL, NetworkACLItemVO.class);
|
||||
s_typeMap.put(ResourceTag.ResourceObjectType.StaticRoute, StaticRouteVO.class);
|
||||
s_typeMap.put(ResourceTag.ResourceObjectType.VMSnapshot, VMSnapshotVO.class);
|
||||
s_typeMap.put(ResourceTag.ResourceObjectType.RemoteAccessVpn, RemoteAccessVpnVO.class);
|
||||
s_typeMap.put(ResourceTag.ResourceObjectType.Zone, DataCenterVO.class);
|
||||
s_typeMap.put(ResourceTag.ResourceObjectType.ServiceOffering, ServiceOfferingVO.class);
|
||||
s_typeMap.put(ResourceTag.ResourceObjectType.Storage, StoragePoolVO.class);
|
||||
s_typeMap.put(ResourceTag.ResourceObjectType.PrivateGateway, RemoteAccessVpnVO.class);
|
||||
s_typeMap.put(ResourceTag.ResourceObjectType.NetworkACLList, NetworkACLVO.class);
|
||||
s_typeMap.put(ResourceTag.ResourceObjectType.VpnGateway, Site2SiteVpnGatewayVO.class);
|
||||
s_typeMap.put(ResourceTag.ResourceObjectType.CustomerGateway, Site2SiteCustomerGatewayVO.class);
|
||||
s_typeMap.put(ResourceTag.ResourceObjectType.VpnConnection, Site2SiteVpnConnectionVO.class);
|
||||
s_typeMap.put(ResourceTag.ResourceObjectType.User, UserVO.class);
|
||||
s_typeMap.put(ResourceTag.ResourceObjectType.DiskOffering, DiskOfferingVO.class);
|
||||
s_typeMap.put(ResourceTag.ResourceObjectType.AutoScaleVmProfile, AutoScaleVmProfileVO.class);
|
||||
s_typeMap.put(ResourceTag.ResourceObjectType.AutoScaleVmGroup, AutoScaleVmGroupVO.class);
|
||||
s_typeMap.put(ResourceTag.ResourceObjectType.LBStickinessPolicy, LBStickinessPolicyVO.class);
|
||||
s_typeMap.put(ResourceTag.ResourceObjectType.LBHealthCheckPolicy, LBHealthCheckPolicyVO.class);
|
||||
s_typeMap.put(ResourceTag.ResourceObjectType.SnapshotPolicy, SnapshotPolicyVO.class);
|
||||
s_typeMap.put(ResourceTag.ResourceObjectType.NetworkOffering, NetworkOfferingVO.class);
|
||||
s_typeMap.put(ResourceTag.ResourceObjectType.VpcOffering, VpcOfferingVO.class);
|
||||
s_typeMap.put(ResourceTag.ResourceObjectType.Domain, DomainVO.class);
|
||||
}
|
||||
|
||||
@Inject
|
||||
EntityManager entityMgr;
|
||||
@Inject
|
||||
AccountManager accountMgr;
|
||||
@Inject
|
||||
DomainManager domainMgr;
|
||||
|
||||
@Override
|
||||
public long getResourceId(String resourceId, ResourceTag.ResourceObjectType resourceType) {
|
||||
Class<?> clazz = s_typeMap.get(resourceType);
|
||||
Object entity = entityMgr.findByUuid(clazz, resourceId);
|
||||
if (entity != null) {
|
||||
return ((InternalIdentity)entity).getId();
|
||||
}
|
||||
if (!StringUtils.isNumeric(resourceId)) {
|
||||
throw new InvalidParameterValueException("Unable to find resource by uuid " + resourceId + " and type " + resourceType);
|
||||
}
|
||||
entity = entityMgr.findById(clazz, resourceId);
|
||||
if (entity != null) {
|
||||
return ((InternalIdentity)entity).getId();
|
||||
}
|
||||
throw new InvalidParameterValueException("Unable to find resource by id " + resourceId + " and type " + resourceType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUuid(String resourceId, ResourceTag.ResourceObjectType resourceType) {
|
||||
if (!StringUtils.isNumeric(resourceId)) {
|
||||
return resourceId;
|
||||
}
|
||||
|
||||
Class<?> clazz = s_typeMap.get(resourceType);
|
||||
|
||||
Object entity = entityMgr.findById(clazz, resourceId);
|
||||
if (entity != null && entity instanceof Identity) {
|
||||
return ((Identity)entity).getUuid();
|
||||
}
|
||||
|
||||
return resourceId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceTag.ResourceObjectType getResourceType(String resourceTypeStr) {
|
||||
|
||||
for (ResourceTag.ResourceObjectType type : ResourceTag.ResourceObjectType.values()) {
|
||||
if (type.toString().equalsIgnoreCase(resourceTypeStr)) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
throw new InvalidParameterValueException("Invalid resource type: " + resourceTypeStr);
|
||||
}
|
||||
|
||||
public void checkResourceAccessible(Long accountId, Long domainId, String exceptionMessage) {
|
||||
Account caller = CallContext.current().getCallingAccount();
|
||||
if (Objects.equals(domainId, -1))
|
||||
{
|
||||
throw new CloudRuntimeException("Invalid DomainId: -1");
|
||||
}
|
||||
if (accountId != null) {
|
||||
accountMgr.checkAccess(caller, null, false, accountMgr.getAccount(accountId));
|
||||
} else if (domainId != null && !accountMgr.isNormalUser(caller.getId())) {
|
||||
//check permissions;
|
||||
accountMgr.checkAccess(caller, domainMgr.getDomain(domainId));
|
||||
} else {
|
||||
throw new PermissionDeniedException(exceptionMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -17,60 +17,33 @@
|
|||
package com.cloud.tags;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
import javax.persistence.EntityExistsException;
|
||||
|
||||
import org.apache.cloudstack.api.Identity;
|
||||
import org.apache.cloudstack.api.InternalIdentity;
|
||||
import com.cloud.server.ResourceManagerUtil;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||
import org.apache.commons.collections.MapUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.dc.DataCenterVO;
|
||||
import com.cloud.domain.PartOf;
|
||||
import com.cloud.event.ActionEvent;
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.exception.PermissionDeniedException;
|
||||
import com.cloud.network.LBHealthCheckPolicyVO;
|
||||
import com.cloud.network.as.AutoScaleVmGroupVO;
|
||||
import com.cloud.network.as.AutoScaleVmProfileVO;
|
||||
import com.cloud.network.dao.IPAddressVO;
|
||||
import com.cloud.network.dao.LBStickinessPolicyVO;
|
||||
import com.cloud.network.dao.LoadBalancerVO;
|
||||
import com.cloud.network.dao.NetworkVO;
|
||||
import com.cloud.network.dao.RemoteAccessVpnVO;
|
||||
import com.cloud.network.dao.Site2SiteCustomerGatewayVO;
|
||||
import com.cloud.network.dao.Site2SiteVpnConnectionVO;
|
||||
import com.cloud.network.dao.Site2SiteVpnGatewayVO;
|
||||
import com.cloud.network.rules.FirewallRuleVO;
|
||||
import com.cloud.network.rules.PortForwardingRuleVO;
|
||||
import com.cloud.network.security.SecurityGroupRuleVO;
|
||||
import com.cloud.network.security.SecurityGroupVO;
|
||||
import com.cloud.network.vpc.NetworkACLItemVO;
|
||||
import com.cloud.network.vpc.NetworkACLVO;
|
||||
import com.cloud.network.vpc.StaticRouteVO;
|
||||
import com.cloud.network.vpc.VpcOfferingVO;
|
||||
import com.cloud.network.vpc.VpcVO;
|
||||
import com.cloud.offerings.NetworkOfferingVO;
|
||||
import com.cloud.projects.ProjectVO;
|
||||
import com.cloud.server.ResourceTag;
|
||||
import com.cloud.server.ResourceTag.ResourceObjectType;
|
||||
import com.cloud.server.TaggedResourceService;
|
||||
import com.cloud.service.ServiceOfferingVO;
|
||||
import com.cloud.storage.DiskOfferingVO;
|
||||
import com.cloud.storage.SnapshotPolicyVO;
|
||||
import com.cloud.storage.SnapshotVO;
|
||||
import com.cloud.storage.VMTemplateVO;
|
||||
import com.cloud.storage.VolumeVO;
|
||||
import com.cloud.tags.dao.ResourceTagDao;
|
||||
import com.cloud.user.Account;
|
||||
|
|
@ -78,7 +51,6 @@ import com.cloud.user.AccountManager;
|
|||
import com.cloud.user.AccountVO;
|
||||
import com.cloud.user.DomainManager;
|
||||
import com.cloud.user.OwnedBy;
|
||||
import com.cloud.user.UserVO;
|
||||
import com.cloud.user.dao.AccountDao;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.component.ManagerBase;
|
||||
|
|
@ -90,54 +62,10 @@ import com.cloud.utils.db.Transaction;
|
|||
import com.cloud.utils.db.TransactionCallbackNoReturn;
|
||||
import com.cloud.utils.db.TransactionStatus;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.vm.NicVO;
|
||||
import com.cloud.vm.UserVmVO;
|
||||
import com.cloud.vm.snapshot.VMSnapshotVO;
|
||||
|
||||
public class TaggedResourceManagerImpl extends ManagerBase implements TaggedResourceService {
|
||||
public static final Logger s_logger = Logger.getLogger(TaggedResourceManagerImpl.class);
|
||||
|
||||
private static final Map<ResourceObjectType, Class<?>> s_typeMap = new HashMap<>();
|
||||
static {
|
||||
s_typeMap.put(ResourceObjectType.UserVm, UserVmVO.class);
|
||||
s_typeMap.put(ResourceObjectType.Volume, VolumeVO.class);
|
||||
s_typeMap.put(ResourceObjectType.Template, VMTemplateVO.class);
|
||||
s_typeMap.put(ResourceObjectType.ISO, VMTemplateVO.class);
|
||||
s_typeMap.put(ResourceObjectType.Snapshot, SnapshotVO.class);
|
||||
s_typeMap.put(ResourceObjectType.Network, NetworkVO.class);
|
||||
s_typeMap.put(ResourceObjectType.LoadBalancer, LoadBalancerVO.class);
|
||||
s_typeMap.put(ResourceObjectType.PortForwardingRule, PortForwardingRuleVO.class);
|
||||
s_typeMap.put(ResourceObjectType.FirewallRule, FirewallRuleVO.class);
|
||||
s_typeMap.put(ResourceObjectType.SecurityGroup, SecurityGroupVO.class);
|
||||
s_typeMap.put(ResourceObjectType.SecurityGroupRule, SecurityGroupRuleVO.class);
|
||||
s_typeMap.put(ResourceObjectType.PublicIpAddress, IPAddressVO.class);
|
||||
s_typeMap.put(ResourceObjectType.Project, ProjectVO.class);
|
||||
s_typeMap.put(ResourceObjectType.Account, AccountVO.class);
|
||||
s_typeMap.put(ResourceObjectType.Vpc, VpcVO.class);
|
||||
s_typeMap.put(ResourceObjectType.Nic, NicVO.class);
|
||||
s_typeMap.put(ResourceObjectType.NetworkACL, NetworkACLItemVO.class);
|
||||
s_typeMap.put(ResourceObjectType.StaticRoute, StaticRouteVO.class);
|
||||
s_typeMap.put(ResourceObjectType.VMSnapshot, VMSnapshotVO.class);
|
||||
s_typeMap.put(ResourceObjectType.RemoteAccessVpn, RemoteAccessVpnVO.class);
|
||||
s_typeMap.put(ResourceObjectType.Zone, DataCenterVO.class);
|
||||
s_typeMap.put(ResourceObjectType.ServiceOffering, ServiceOfferingVO.class);
|
||||
s_typeMap.put(ResourceObjectType.Storage, StoragePoolVO.class);
|
||||
s_typeMap.put(ResourceObjectType.PrivateGateway, RemoteAccessVpnVO.class);
|
||||
s_typeMap.put(ResourceObjectType.NetworkACLList, NetworkACLVO.class);
|
||||
s_typeMap.put(ResourceObjectType.VpnGateway, Site2SiteVpnGatewayVO.class);
|
||||
s_typeMap.put(ResourceObjectType.CustomerGateway, Site2SiteCustomerGatewayVO.class);
|
||||
s_typeMap.put(ResourceObjectType.VpnConnection, Site2SiteVpnConnectionVO.class);
|
||||
s_typeMap.put(ResourceObjectType.User, UserVO.class);
|
||||
s_typeMap.put(ResourceObjectType.DiskOffering, DiskOfferingVO.class);
|
||||
s_typeMap.put(ResourceObjectType.AutoScaleVmProfile, AutoScaleVmProfileVO.class);
|
||||
s_typeMap.put(ResourceObjectType.AutoScaleVmGroup, AutoScaleVmGroupVO.class);
|
||||
s_typeMap.put(ResourceObjectType.LBStickinessPolicy, LBStickinessPolicyVO.class);
|
||||
s_typeMap.put(ResourceObjectType.LBHealthCheckPolicy, LBHealthCheckPolicyVO.class);
|
||||
s_typeMap.put(ResourceObjectType.SnapshotPolicy, SnapshotPolicyVO.class);
|
||||
s_typeMap.put(ResourceObjectType.NetworkOffering, NetworkOfferingVO.class);
|
||||
s_typeMap.put(ResourceObjectType.VpcOffering, VpcOfferingVO.class);
|
||||
}
|
||||
|
||||
@Inject
|
||||
EntityManager _entityMgr;
|
||||
@Inject
|
||||
|
|
@ -148,6 +76,8 @@ public class TaggedResourceManagerImpl extends ManagerBase implements TaggedReso
|
|||
DomainManager _domainMgr;
|
||||
@Inject
|
||||
AccountDao _accountDao;
|
||||
@Inject
|
||||
ResourceManagerUtil resourceManagerUtil;
|
||||
|
||||
@Override
|
||||
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
|
||||
|
|
@ -164,25 +94,8 @@ public class TaggedResourceManagerImpl extends ManagerBase implements TaggedReso
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getResourceId(String resourceId, ResourceObjectType resourceType) {
|
||||
Class<?> clazz = s_typeMap.get(resourceType);
|
||||
Object entity = _entityMgr.findByUuid(clazz, resourceId);
|
||||
if (entity != null) {
|
||||
return ((InternalIdentity)entity).getId();
|
||||
}
|
||||
if (!StringUtils.isNumeric(resourceId)) {
|
||||
throw new InvalidParameterValueException("Unable to find resource by uuid " + resourceId + " and type " + resourceType);
|
||||
}
|
||||
entity = _entityMgr.findById(clazz, resourceId);
|
||||
if (entity != null) {
|
||||
return ((InternalIdentity)entity).getId();
|
||||
}
|
||||
throw new InvalidParameterValueException("Unable to find resource by id " + resourceId + " and type " + resourceType);
|
||||
}
|
||||
|
||||
private Pair<Long, Long> getAccountDomain(long resourceId, ResourceObjectType resourceType) {
|
||||
Class<?> clazz = s_typeMap.get(resourceType);
|
||||
Class<?> clazz = ResourceManagerUtilImpl.s_typeMap.get(resourceType);
|
||||
|
||||
Object entity = _entityMgr.findById(clazz, resourceId);
|
||||
Long accountId = null;
|
||||
|
|
@ -191,7 +104,7 @@ public class TaggedResourceManagerImpl extends ManagerBase implements TaggedReso
|
|||
// if the resource type is a security group rule, get the accountId and domainId from the security group itself
|
||||
if (resourceType == ResourceObjectType.SecurityGroupRule) {
|
||||
SecurityGroupRuleVO rule = (SecurityGroupRuleVO)entity;
|
||||
Object SecurityGroup = _entityMgr.findById(s_typeMap.get(ResourceObjectType.SecurityGroup), rule.getSecurityGroupId());
|
||||
Object SecurityGroup = _entityMgr.findById(ResourceManagerUtilImpl.s_typeMap.get(ResourceObjectType.SecurityGroup), rule.getSecurityGroupId());
|
||||
|
||||
accountId = ((SecurityGroupVO)SecurityGroup).getAccountId();
|
||||
domainId = ((SecurityGroupVO)SecurityGroup).getDomainId();
|
||||
|
|
@ -206,11 +119,11 @@ public class TaggedResourceManagerImpl extends ManagerBase implements TaggedReso
|
|||
// if the resource type is network acl, get the accountId and domainId from VPC following: NetworkACLItem -> NetworkACL -> VPC
|
||||
if (resourceType == ResourceObjectType.NetworkACL) {
|
||||
NetworkACLItemVO aclItem = (NetworkACLItemVO)entity;
|
||||
Object networkACL = _entityMgr.findById(s_typeMap.get(ResourceObjectType.NetworkACLList), aclItem.getAclId());
|
||||
Object networkACL = _entityMgr.findById(ResourceManagerUtilImpl.s_typeMap.get(ResourceObjectType.NetworkACLList), aclItem.getAclId());
|
||||
Long vpcId = ((NetworkACLVO)networkACL).getVpcId();
|
||||
|
||||
if (vpcId != null && vpcId != 0) {
|
||||
Object vpc = _entityMgr.findById(s_typeMap.get(ResourceObjectType.Vpc), vpcId);
|
||||
Object vpc = _entityMgr.findById(ResourceManagerUtilImpl.s_typeMap.get(ResourceObjectType.Vpc), vpcId);
|
||||
|
||||
accountId = ((VpcVO)vpc).getAccountId();
|
||||
domainId = ((VpcVO)vpc).getDomainId();
|
||||
|
|
@ -243,49 +156,6 @@ public class TaggedResourceManagerImpl extends ManagerBase implements TaggedReso
|
|||
return new Pair<>(accountId, domainId);
|
||||
}
|
||||
|
||||
private void checkResourceAccessible(Long accountId, Long domainId, String exceptionMessage) {
|
||||
Account caller = CallContext.current().getCallingAccount();
|
||||
if (Objects.equals(domainId, -1))
|
||||
{
|
||||
throw new CloudRuntimeException("Invalid DomainId: -1");
|
||||
}
|
||||
if (accountId != null) {
|
||||
_accountMgr.checkAccess(caller, null, false, _accountMgr.getAccount(accountId));
|
||||
} else if (domainId != null && !_accountMgr.isNormalUser(caller.getId())) {
|
||||
//check permissions;
|
||||
_accountMgr.checkAccess(caller, _domainMgr.getDomain(domainId));
|
||||
} else {
|
||||
throw new PermissionDeniedException(exceptionMessage);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceObjectType getResourceType(String resourceTypeStr) {
|
||||
|
||||
for (ResourceObjectType type : ResourceTag.ResourceObjectType.values()) {
|
||||
if (type.toString().equalsIgnoreCase(resourceTypeStr)) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
throw new InvalidParameterValueException("Invalid resource type " + resourceTypeStr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUuid(String resourceId, ResourceObjectType resourceType) {
|
||||
if (!StringUtils.isNumeric(resourceId)) {
|
||||
return resourceId;
|
||||
}
|
||||
|
||||
Class<?> clazz = s_typeMap.get(resourceType);
|
||||
|
||||
Object entity = _entityMgr.findById(clazz, resourceId);
|
||||
if (entity != null && entity instanceof Identity) {
|
||||
return ((Identity)entity).getUuid();
|
||||
}
|
||||
|
||||
return resourceId;
|
||||
}
|
||||
|
||||
@Override
|
||||
@DB
|
||||
@ActionEvent(eventType = EventTypes.EVENT_TAGS_CREATE, eventDescription = "creating resource tags")
|
||||
|
|
@ -303,14 +173,14 @@ public class TaggedResourceManagerImpl extends ManagerBase implements TaggedReso
|
|||
throw new InvalidParameterValueException("The resource type " + resourceType + " doesn't support resource tags");
|
||||
}
|
||||
|
||||
long id = getResourceId(resourceId, resourceType);
|
||||
String resourceUuid = getUuid(resourceId, resourceType);
|
||||
long id = resourceManagerUtil.getResourceId(resourceId, resourceType);
|
||||
String resourceUuid = resourceManagerUtil.getUuid(resourceId, resourceType);
|
||||
|
||||
Pair<Long, Long> accountDomainPair = getAccountDomain(id, resourceType);
|
||||
Long domainId = accountDomainPair.second();
|
||||
Long accountId = accountDomainPair.first();
|
||||
|
||||
checkResourceAccessible(accountId, domainId, "Account '" + caller +
|
||||
resourceManagerUtil.checkResourceAccessible(accountId, domainId, "Account '" + caller +
|
||||
"' doesn't have permissions to create tags" + " for resource '" + id + "(" + key + ")'.");
|
||||
|
||||
String value = tags.get(key);
|
||||
|
|
@ -335,7 +205,7 @@ public class TaggedResourceManagerImpl extends ManagerBase implements TaggedReso
|
|||
}
|
||||
|
||||
private List<? extends ResourceTag> searchResourceTags(List<String> resourceIds, ResourceObjectType resourceType) {
|
||||
List<String> resourceUuids = resourceIds.stream().map(resourceId -> getUuid(resourceId, resourceType)).collect(Collectors.toList());
|
||||
List<String> resourceUuids = resourceIds.stream().map(resourceId -> resourceManagerUtil.getUuid(resourceId, resourceType)).collect(Collectors.toList());
|
||||
SearchBuilder<ResourceTagVO> sb = _resourceTagDao.createSearchBuilder();
|
||||
sb.and("resourceUuid", sb.entity().getResourceUuid(), SearchCriteria.Op.IN);
|
||||
sb.and("resourceType", sb.entity().getResourceType(), SearchCriteria.Op.EQ);
|
||||
|
|
|
|||
|
|
@ -323,4 +323,10 @@
|
|||
<property name="affinityGroupProcessors"
|
||||
value="#{affinityProcessorsRegistry.registered}" />
|
||||
</bean>
|
||||
|
||||
<bean id="resourceManagerUtilImpl"
|
||||
class="com.cloud.tags.ResourceManagerUtilImpl"/>
|
||||
|
||||
<bean id="resourceIconManager" class="com.cloud.resourceicon.ResourceIconManagerImpl" />
|
||||
|
||||
</beans>
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import java.util.Map;
|
|||
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import com.cloud.server.ResourceManagerUtil;
|
||||
import org.apache.commons.collections.map.HashedMap;
|
||||
import org.junit.Before;
|
||||
import org.mockito.Mock;
|
||||
|
|
@ -49,6 +50,8 @@ public class ResourceMetaDataManagerTest {
|
|||
NicDetailsDao _nicDetailDao;
|
||||
@Mock
|
||||
TaggedResourceService _taggedResourceMgr;
|
||||
@Mock
|
||||
ResourceManagerUtil resourceManagerUtil;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
|
|
@ -70,7 +73,7 @@ public class ResourceMetaDataManagerTest {
|
|||
public void testResourceDetails() throws ResourceAllocationException {
|
||||
|
||||
//when(_resourceMetaDataMgr.getResourceId(anyString(), eq(ResourceTag.TaggedResourceType.Volume))).thenReturn(1L);
|
||||
doReturn(1L).when(_taggedResourceMgr).getResourceId(anyString(), eq(ResourceTag.ResourceObjectType.Volume));
|
||||
doReturn(1L).when(resourceManagerUtil).getResourceId(anyString(), eq(ResourceTag.ResourceObjectType.Volume));
|
||||
// _volumeDetailDao.removeDetails(id, key);
|
||||
|
||||
doNothing().when(_volumeDetailDao).removeDetail(anyLong(), anyString());
|
||||
|
|
@ -82,7 +85,7 @@ public class ResourceMetaDataManagerTest {
|
|||
// Test adding details
|
||||
public void testAddResourceDetails() throws ResourceAllocationException {
|
||||
|
||||
doReturn(1L).when(_taggedResourceMgr).getResourceId("1", ResourceTag.ResourceObjectType.Volume);
|
||||
doReturn(1L).when(resourceManagerUtil).getResourceId("1", ResourceTag.ResourceObjectType.Volume);
|
||||
// _volumeDetailDao.removeDetails(id, key);
|
||||
|
||||
doNothing().when(_volumeDetailDao).removeDetail(anyLong(), anyString());
|
||||
|
|
|
|||
|
|
@ -136,6 +136,7 @@ known_categories = {
|
|||
'Simulator': 'simulator',
|
||||
'StaticRoute': 'VPC',
|
||||
'Tags': 'Resource tags',
|
||||
'Icon': 'Resource Icon',
|
||||
'NiciraNvpDevice': 'Nicira NVP',
|
||||
'BrocadeVcsDevice': 'Brocade VCS',
|
||||
'BigSwitchBcfDevice': 'BigSwitch BCF',
|
||||
|
|
|
|||
|
|
@ -556,6 +556,7 @@
|
|||
"label.character": "Character",
|
||||
"label.chassis": "Chassis",
|
||||
"label.checksum": "Checksum",
|
||||
"label.choose.resource.icon": "Choose Icon",
|
||||
"label.choose.saml.indentity": "Choose SAML identity provider",
|
||||
"label.cidr": "CIDR",
|
||||
"label.cidr.account": "CIDR or Account/Security Group",
|
||||
|
|
@ -718,6 +719,7 @@
|
|||
"label.delete.events": "Delete events",
|
||||
"label.delete.f5": "Delete F5",
|
||||
"label.delete.gateway": "Delete gateway",
|
||||
"label.delete.icon": "Delete icon",
|
||||
"label.delete.instance.group": "Delete Instance Group",
|
||||
"label.delete.internal.lb": "Delete Internal LB",
|
||||
"label.delete.netscaler": "Delete NetScaler",
|
||||
|
|
@ -2249,7 +2251,9 @@
|
|||
"label.upgrade.router.newer.template": "Upgrade Router to Use Newer Template",
|
||||
"label.upload": "Upload",
|
||||
"label.upload.from.local": "Upload from Local",
|
||||
"label.upload.icon": "Upload Icon",
|
||||
"label.upload.iso.from.local": "Upload ISO from Local",
|
||||
"label.upload.resource.icon": "Upload Icon",
|
||||
"label.upload.template.from.local": "Upload Template from Local",
|
||||
"label.upload.volume": "Upload volume",
|
||||
"label.upload.volume.from.local": "Upload Volume from Local",
|
||||
|
|
@ -3248,6 +3252,7 @@
|
|||
"message.success.delete": "Delete success",
|
||||
"message.success.delete.acl.rule": "Successfully removed ACL rule",
|
||||
"message.success.delete.backup.schedule": "Successfully deleted Configure VM backup schedule",
|
||||
"message.success.delete.icon": "Successfully deleted icon of",
|
||||
"message.success.delete.snapshot.policy": "Successfully deleted snapshot policy",
|
||||
"message.success.delete.static.route": "Successfully deleted static route",
|
||||
"message.success.delete.tag": "Successfully deleted tag",
|
||||
|
|
@ -3285,6 +3290,7 @@
|
|||
"message.success.upgrade.kubernetes": "Successfully upgraded Kubernetes cluster",
|
||||
"message.success.upload": "Upload Successfully",
|
||||
"message.success.upload.description": "This ISO file has been uploaded. Please check its status at Templates menu",
|
||||
"message.success.upload.icon": "Successfully uploaded icon for ",
|
||||
"message.success.upload.iso.description": "This ISO file has been uploaded. Please check its status in the Images > ISOs menu",
|
||||
"message.success.upload.template.description": "This template file has been uploaded. Please check its status at Templates menu",
|
||||
"message.success.upload.volume.description": "This Volume has been uploaded. Please check its status in the Volumes menu",
|
||||
|
|
@ -3386,6 +3392,7 @@
|
|||
"message.volume.state.uploadinprogress": "Volume upload is in progress",
|
||||
"message.volume.state.uploadop": "The volume upload operation is in progress or in short the volume is on secondary storage",
|
||||
"message.waiting.for.builtin.templates.to.load": "Waiting for builtin templates to load...",
|
||||
"message.warn.filetype": "jpg, jpeg, png, bmp and svg are the only supported image formats",
|
||||
"message.xstools61plus.update.failed": "Failed to update Original XS Version is 6.1+ field. Error:",
|
||||
"message.you.must.have.at.least.one.physical.network": "You must have at least one physical network",
|
||||
"message.your.cloudstack.is.ready": "Your CloudStack is ready!",
|
||||
|
|
|
|||
|
|
@ -39,6 +39,8 @@
|
|||
</a-tooltip>
|
||||
|
||||
<a-select-option v-for="(project, index) in projects" :key="index">
|
||||
<resource-icon v-if="project.icon && project.icon.base64image" :image="project.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
<a-icon v-else style="margin-right: 5px" type="project" />
|
||||
{{ project.displaytext || project.name }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
|
|
@ -49,9 +51,13 @@
|
|||
import store from '@/store'
|
||||
import { api } from '@/api'
|
||||
import _ from 'lodash'
|
||||
import ResourceIcon from '@/components/view/ResourceIcon'
|
||||
|
||||
export default {
|
||||
name: 'ProjectMenu',
|
||||
components: {
|
||||
ResourceIcon
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
projects: [],
|
||||
|
|
@ -70,7 +76,7 @@ export default {
|
|||
const projects = []
|
||||
const getNextPage = () => {
|
||||
this.loading = true
|
||||
api('listProjects', { listAll: true, details: 'min', page: page, pageSize: 500 }).then(json => {
|
||||
api('listProjects', { listAll: true, details: 'min', page: page, pageSize: 500, showIcon: true }).then(json => {
|
||||
if (json && json.listprojectsresponse && json.listprojectsresponse.project) {
|
||||
projects.push(...json.listprojectsresponse.project)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,10 @@
|
|||
</label>
|
||||
<a-dropdown>
|
||||
<span class="user-menu-dropdown action">
|
||||
<a-avatar class="user-menu-avatar avatar" size="small" :src="avatar()"/>
|
||||
<span v-if="image">
|
||||
<resource-icon :image="image" size="2x" style="margin-right: 5px"/>
|
||||
</span>
|
||||
<a-avatar v-else class="user-menu-avatar avatar" size="small" :src="avatar()"/>
|
||||
<span>{{ nickname() }}</span>
|
||||
</span>
|
||||
<a-menu slot="overlay" class="user-menu-wrapper">
|
||||
|
|
@ -64,16 +67,36 @@
|
|||
|
||||
<script>
|
||||
import Vue from 'vue'
|
||||
import { api } from '@/api'
|
||||
import HeaderNotice from './HeaderNotice'
|
||||
import TranslationMenu from './TranslationMenu'
|
||||
import { mapActions, mapGetters } from 'vuex'
|
||||
import ResourceIcon from '@/components/view/ResourceIcon'
|
||||
import eventBus from '@/config/eventBus'
|
||||
import { SERVER_MANAGER } from '@/store/mutation-types'
|
||||
|
||||
export default {
|
||||
name: 'UserMenu',
|
||||
components: {
|
||||
TranslationMenu,
|
||||
HeaderNotice
|
||||
HeaderNotice,
|
||||
ResourceIcon
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
image: ''
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.getIcon()
|
||||
eventBus.$on('refresh-header', () => {
|
||||
this.getIcon()
|
||||
})
|
||||
},
|
||||
watch: {
|
||||
image () {
|
||||
this.getIcon()
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
server () {
|
||||
|
|
@ -86,6 +109,25 @@ export default {
|
|||
toggleUseBrowserTimezone () {
|
||||
this.$store.dispatch('SetUseBrowserTimezone', !this.$store.getters.usebrowsertimezone)
|
||||
},
|
||||
async getIcon () {
|
||||
await this.fetchResourceIcon(this.$store.getters.userInfo.id)
|
||||
},
|
||||
fetchResourceIcon (id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
api('listUsers', {
|
||||
id: id,
|
||||
showicon: true
|
||||
}).then(json => {
|
||||
const response = json.listusersresponse.user || []
|
||||
if (response?.[0]) {
|
||||
this.image = response[0]?.icon?.base64image || ''
|
||||
resolve(this.image)
|
||||
}
|
||||
}).catch(error => {
|
||||
reject(error)
|
||||
})
|
||||
})
|
||||
},
|
||||
handleLogout () {
|
||||
return this.Logout({}).then(() => {
|
||||
this.$router.push('/user/login')
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
// $message.success(`${$t('label.copied.clipboard')} : ${name}`)
|
||||
<template>
|
||||
<a-spin :spinning="loading">
|
||||
<a-card class="spin-content" :bordered="bordered" :title="title">
|
||||
|
|
@ -23,12 +23,21 @@
|
|||
<div class="resource-details__name">
|
||||
<div
|
||||
class="avatar"
|
||||
@click="$message.success(`${$t('label.copied.clipboard')} : ${name}`)"
|
||||
@click="showUploadModal(true)"
|
||||
v-clipboard:copy="name" >
|
||||
<upload-resource-icon v-if="'uploadResourceIcon' in $store.getters.apis" :visible="showUpload" :resource="resource" @handle-close="showUpload(false)"/>
|
||||
<div class="ant-upload-preview" v-if="$showIcon()">
|
||||
<a-icon type="camera" class="upload-icon"/>
|
||||
</div>
|
||||
<slot name="avatar">
|
||||
<os-logo v-if="resource.ostypeid || resource.ostypename" :osId="resource.ostypeid" :osName="resource.ostypename" size="4x" @update-osname="(name) => resource.ostypename = name"/>
|
||||
<a-icon v-else-if="typeof $route.meta.icon ==='string'" style="font-size: 36px" :type="$route.meta.icon" />
|
||||
<a-icon v-else style="font-size: 36px" :component="$route.meta.icon" />
|
||||
<span v-if="(resource.icon && resource.icon.base64image || images.template || images.iso || resourceIcon) && !['router', 'systemvm', 'volume'].includes($route.path.split('/')[1])">
|
||||
<resource-icon :image="getImage(resource.icon && resource.icon.base64image || images.template || images.iso || resourceIcon)" size="4x" style="margin-right: 5px"/>
|
||||
</span>
|
||||
<span v-else>
|
||||
<os-logo v-if="resource.ostypeid || resource.ostypename" :osId="resource.ostypeid" :osName="resource.ostypename" size="4x" @update-osname="(name) => resource.ostypename = name"/>
|
||||
<a-icon v-else-if="typeof $route.meta.icon ==='string'" style="font-size: 36px" :type="$route.meta.icon"/>
|
||||
<a-icon v-else style="font-size: 36px" :component="$route.meta.icon" />
|
||||
</span>
|
||||
</slot>
|
||||
</div>
|
||||
<slot name="name">
|
||||
|
|
@ -121,7 +130,10 @@
|
|||
<div class="resource-detail-item" v-if="resource.ostypename && resource.ostypeid">
|
||||
<div class="resource-detail-item__label">{{ $t('label.ostypename') }}</div>
|
||||
<div class="resource-detail-item__details">
|
||||
<os-logo :osId="resource.ostypeid" :osName="resource.ostypename" size="lg" style="margin-left: -1px" />
|
||||
<span v-if="resource.icon && resource.icon.base64image || images.template || images.iso">
|
||||
<resource-icon :image="getImage(images.template || images.iso)" size="1x" style="margin-right: 5px"/>
|
||||
</span>
|
||||
<os-logo v-else :osId="resource.ostypeid" :osName="resource.ostypename" size="lg" style="margin-left: -1px" />
|
||||
<span style="margin-left: 8px">{{ resource.ostypename }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -328,7 +340,10 @@
|
|||
<div class="resource-detail-item" v-if="resource.projectid || resource.projectname">
|
||||
<div class="resource-detail-item__label">{{ $t('label.project') }}</div>
|
||||
<div class="resource-detail-item__details">
|
||||
<a-icon type="project" />
|
||||
<span v-if="images.project">
|
||||
<resource-icon :image="getImage(images.project)" size="1x" style="margin-right: 5px"/>
|
||||
</span>
|
||||
<a-icon v-else type="project" />
|
||||
<router-link v-if="!isStatic && resource.projectid" :to="{ path: '/project/' + resource.projectid }">{{ resource.project || resource.projectname || resource.projectid }}</router-link>
|
||||
<router-link v-else :to="{ path: '/project', query: { name: resource.projectname }}">{{ resource.projectname }}</router-link>
|
||||
</div>
|
||||
|
|
@ -392,7 +407,10 @@
|
|||
<div class="resource-detail-item" v-if="resource.vpcid">
|
||||
<div class="resource-detail-item__label">{{ $t('label.vpcname') }}</div>
|
||||
<div class="resource-detail-item__details">
|
||||
<a-icon type="deployment-unit" />
|
||||
<span v-if="images.vpc">
|
||||
<resource-icon :image="getImage(images.vpc)" size="1x" style="margin-right: 5px"/>
|
||||
</span>
|
||||
<a-icon v-else type="deployment-unit" />
|
||||
<router-link :to="{ path: '/vpc/' + resource.vpcid }">{{ resource.vpcname || resource.vpcid }}</router-link>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -410,7 +428,8 @@
|
|||
<div class="resource-detail-item" v-if="resource.templateid">
|
||||
<div class="resource-detail-item__label">{{ resource.isoid ? $t('label.iso') : $t('label.templatename') }}</div>
|
||||
<div class="resource-detail-item__details">
|
||||
<a-icon type="picture" />
|
||||
<resource-icon v-if="resource.icon" :image="getImage(resource.icon.base64image)" size="1x" style="margin-right: 5px"/>
|
||||
<a-icon v-else type="picture" />
|
||||
<div v-if="resource.isoid">
|
||||
<router-link :to="{ path: '/iso/' + resource.isoid }">{{ resource.isodisplaytext || resource.isoname || resource.isoid }} </router-link>
|
||||
</div>
|
||||
|
|
@ -496,7 +515,10 @@
|
|||
<div class="resource-detail-item" v-if="resource.zoneid">
|
||||
<div class="resource-detail-item__label">{{ $t('label.zone') }}</div>
|
||||
<div class="resource-detail-item__details">
|
||||
<a-icon type="global" />
|
||||
<span v-if="images.zone">
|
||||
<resource-icon :image="getImage(images.zone)" size="1x" style="margin-right: 5px"/>
|
||||
</span>
|
||||
<a-icon v-else type="global" />
|
||||
<router-link v-if="!isStatic && $router.resolve('/zone/' + resource.zoneid).route.name !== '404'" :to="{ path: '/zone/' + resource.zoneid }">{{ resource.zone || resource.zonename || resource.zoneid }}</router-link>
|
||||
<span v-else>{{ resource.zone || resource.zonename || resource.zoneid }}</span>
|
||||
</div>
|
||||
|
|
@ -519,7 +541,10 @@
|
|||
<div class="resource-detail-item" v-if="resource.account && !resource.account.startsWith('PrjAcct-')">
|
||||
<div class="resource-detail-item__label">{{ $t('label.account') }}</div>
|
||||
<div class="resource-detail-item__details">
|
||||
<a-icon type="user" />
|
||||
<span v-if="images.account">
|
||||
<resource-icon :image="getImage(images.account)" size="1x" style="margin-right: 5px"/>
|
||||
</span>
|
||||
<a-icon v-else type="user" />
|
||||
<router-link v-if="!isStatic && $store.getters.userInfo.roletype !== 'User'" :to="{ path: '/account', query: { name: resource.account, domainid: resource.domainid } }">{{ resource.account }}</router-link>
|
||||
<span v-else>{{ resource.account }}</span>
|
||||
</div>
|
||||
|
|
@ -535,7 +560,8 @@
|
|||
<div class="resource-detail-item" v-if="resource.domainid">
|
||||
<div class="resource-detail-item__label">{{ $t('label.domain') }}</div>
|
||||
<div class="resource-detail-item__details">
|
||||
<a-icon type="block" />
|
||||
<resource-icon v-if="images.domain" :image="getImage(images.domain)" size="1x" style="margin-right: 5px"/>
|
||||
<a-icon v-else type="block" />
|
||||
<router-link v-if="!isStatic && $store.getters.userInfo.roletype !== 'User'" :to="{ path: '/domain/' + resource.domainid + '?tab=details' }">{{ resource.domain || resource.domainid }}</router-link>
|
||||
<span v-else>{{ resource.domain || resource.domainid }}</span>
|
||||
</div>
|
||||
|
|
@ -663,6 +689,9 @@ import Console from '@/components/widgets/Console'
|
|||
import OsLogo from '@/components/widgets/OsLogo'
|
||||
import Status from '@/components/widgets/Status'
|
||||
import TooltipButton from '@/components/widgets/TooltipButton'
|
||||
import UploadResourceIcon from '@/components/view/UploadResourceIcon'
|
||||
import eventBus from '@/config/eventBus'
|
||||
import ResourceIcon from '@/components/view/ResourceIcon'
|
||||
|
||||
export default {
|
||||
name: 'InfoCard',
|
||||
|
|
@ -670,7 +699,9 @@ export default {
|
|||
Console,
|
||||
OsLogo,
|
||||
Status,
|
||||
TooltipButton
|
||||
TooltipButton,
|
||||
UploadResourceIcon,
|
||||
ResourceIcon
|
||||
},
|
||||
props: {
|
||||
resource: {
|
||||
|
|
@ -703,10 +734,26 @@ export default {
|
|||
inputValue: '',
|
||||
tags: [],
|
||||
showKeys: false,
|
||||
loadingTags: false
|
||||
showNotesInput: false,
|
||||
loadingTags: false,
|
||||
loadingAnnotations: false,
|
||||
showUpload: false,
|
||||
images: {
|
||||
zone: '',
|
||||
template: '',
|
||||
iso: '',
|
||||
domain: '',
|
||||
account: '',
|
||||
project: '',
|
||||
vpc: '',
|
||||
network: ''
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
$route: function () {
|
||||
this.getIcons()
|
||||
},
|
||||
resource: function (newItem, oldItem) {
|
||||
this.resource = newItem
|
||||
this.resourceType = this.$route.meta.resourceType
|
||||
|
|
@ -721,10 +768,18 @@ export default {
|
|||
if ('apikey' in this.resource) {
|
||||
this.getUserKeys()
|
||||
}
|
||||
this.getIcons()
|
||||
},
|
||||
async templateIcon () {
|
||||
this.getIcons()
|
||||
}
|
||||
},
|
||||
created () {
|
||||
async created () {
|
||||
this.setData()
|
||||
eventBus.$on('handle-close', (showModal) => {
|
||||
this.showUploadModal(showModal)
|
||||
})
|
||||
await this.getIcons()
|
||||
},
|
||||
computed: {
|
||||
name () {
|
||||
|
|
@ -736,10 +791,107 @@ export default {
|
|||
return this.resource.nic.filter(e => { return e.ip6address }).map(e => { return e.ip6address }).join(', ')
|
||||
}
|
||||
|
||||
return null
|
||||
},
|
||||
templateIcon () {
|
||||
return this.resource.templateid
|
||||
},
|
||||
resourceIcon () {
|
||||
if (this.$showIcon() && this.resource?.icon?.base64image) {
|
||||
return this.resource.icon.base64image
|
||||
}
|
||||
return null
|
||||
}
|
||||
},
|
||||
async mounted () {
|
||||
this.getIcons()
|
||||
},
|
||||
methods: {
|
||||
showUploadModal (show) {
|
||||
if (show) {
|
||||
if (this.$showIcon()) {
|
||||
this.showUpload = true
|
||||
}
|
||||
} else {
|
||||
this.showUpload = false
|
||||
}
|
||||
},
|
||||
getImage (image) {
|
||||
return (image || this.resource?.icon?.base64image)
|
||||
},
|
||||
async getIcons () {
|
||||
this.images = {
|
||||
zone: '',
|
||||
template: '',
|
||||
iso: '',
|
||||
domain: '',
|
||||
account: '',
|
||||
project: '',
|
||||
vpc: '',
|
||||
network: ''
|
||||
}
|
||||
if (this.resource.templateid) {
|
||||
await this.fetchResourceIcon(this.resource.templateid, 'template')
|
||||
}
|
||||
if (this.resource.isoid) {
|
||||
await this.fetchResourceIcon(this.resource.isoid, 'iso')
|
||||
}
|
||||
if (this.resource.zoneid) {
|
||||
await this.fetchResourceIcon(this.resource.zoneid, 'zone')
|
||||
}
|
||||
if (this.resource.domainid) {
|
||||
await this.fetchResourceIcon(this.resource.domainid, 'domain')
|
||||
}
|
||||
if (this.resource.account) {
|
||||
await this.fetchAccount()
|
||||
}
|
||||
if (this.resource.projectid) {
|
||||
await this.fetchResourceIcon(this.resource.projectid, 'project')
|
||||
}
|
||||
if (this.resource.vpcid) {
|
||||
await this.fetchResourceIcon(this.resource.vpcid, 'vpc')
|
||||
}
|
||||
if (this.resource.networkid) {
|
||||
await this.fetchResourceIcon(this.resource.networkid, 'network')
|
||||
}
|
||||
},
|
||||
fetchAccount () {
|
||||
return new Promise((resolve, reject) => {
|
||||
api('listAccounts', {
|
||||
name: this.resource.account,
|
||||
domainid: this.resource.domainid,
|
||||
showicon: true
|
||||
}).then(async json => {
|
||||
const response = json?.listaccountsresponse?.account || []
|
||||
if (response?.[0]?.icon) {
|
||||
this.images.account = response[0].icon.base64image
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
fetchResourceIcon (resourceid, type) {
|
||||
if (resourceid) {
|
||||
return new Promise((resolve, reject) => {
|
||||
api('listResourceIcon', {
|
||||
resourceids: resourceid,
|
||||
resourcetype: type
|
||||
}).then(json => {
|
||||
const response = json.listresourceiconresponse.icon || []
|
||||
if (response?.[0]) {
|
||||
this.images[type] = response[0].base64image
|
||||
resolve(this.images)
|
||||
} else {
|
||||
this.images[type] = ''
|
||||
resolve(this.images)
|
||||
}
|
||||
}).catch(error => {
|
||||
reject(error)
|
||||
})
|
||||
})
|
||||
} else {
|
||||
this.images.type = ''
|
||||
}
|
||||
},
|
||||
setData () {
|
||||
if (this.resource.nic && this.resource.nic.length > 0) {
|
||||
this.ipaddress = this.resource.nic.filter(e => { return e.ipaddress }).map(e => { return e.ipaddress }).join(', ')
|
||||
|
|
@ -950,4 +1102,16 @@ export default {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
.upload-icon {
|
||||
position: absolute;
|
||||
top: 70px;
|
||||
opacity: 0.75;
|
||||
left: 70px;
|
||||
font-size: 0.75em;
|
||||
padding: 0.25rem;
|
||||
background: rgba(247, 245, 245, 0.767);
|
||||
border-radius: 50%;
|
||||
border: 1px solid rgba(177, 177, 177, 0.788);
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -71,7 +71,15 @@
|
|||
<span v-if="$route.path.startsWith('/project')" style="margin-right: 5px">
|
||||
<tooltip-button type="dashed" size="small" icon="login" @click="changeProject(record)" />
|
||||
</span>
|
||||
<os-logo v-if="record.ostypename" :osName="record.ostypename" size="1x" style="margin-right: 5px" />
|
||||
<span v-if="$showIcon() && !['vm'].includes($route.path.split('/')[1])">
|
||||
<resource-icon v-if="$showIcon() && record.icon && record.icon.base64image" :image="record.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
<os-logo v-else-if="record.ostypename" :osName="record.ostypename" size="1x" style="margin-right: 5px" />
|
||||
<a-icon v-else-if="typeof $route.meta.icon ==='string'" style="font-size: 16px; margin-right: 5px" :type="$route.meta.icon"/>
|
||||
<a-icon v-else style="font-size: 16px; margin-right: 5px" :component="$route.meta.icon" />
|
||||
</span>
|
||||
<span v-else>
|
||||
<os-logo v-if="record.ostypename" :osName="record.ostypename" size="1x" style="margin-right: 5px" />
|
||||
</span>
|
||||
|
||||
<span v-if="record.hasannotations">
|
||||
<span v-if="record.id">
|
||||
|
|
@ -99,6 +107,14 @@
|
|||
<span v-else>{{ text }}</span>
|
||||
</template>
|
||||
<a slot="displayname" slot-scope="text, record" href="javascript:;">
|
||||
<span v-if="['vm'].includes($route.path.split('/')[1])">
|
||||
<span v-if="record.icon && record.icon.base64image">
|
||||
<resource-icon :image="record.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
</span>
|
||||
<span v-else>
|
||||
<os-logo :osId="record.ostypeid" :osName="record.ostypename" size="lg" style="margin-right: 5px" />
|
||||
</span>
|
||||
</span>
|
||||
<QuickView
|
||||
style="margin-left: 5px"
|
||||
:actions="actions"
|
||||
|
|
@ -108,6 +124,10 @@
|
|||
<router-link :to="{ path: $route.path + '/' + record.id }">{{ text }}</router-link>
|
||||
</a>
|
||||
<span slot="username" slot-scope="text, record" href="javascript:;">
|
||||
<span v-if="$showIcon() && !['vm'].includes($route.path.split('/')[1])">
|
||||
<resource-icon v-if="$showIcon() && record.icon && record.icon.base64image" :image="record.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
<a-icon v-else style="font-size: 16px; margin-right: 5px" type="user" />
|
||||
</span>
|
||||
<router-link :to="{ path: $route.path + '/' + record.id }" v-if="['/accountuser', '/vpnuser'].includes($route.path)">{{ text }}</router-link>
|
||||
<router-link :to="{ path: '/accountuser', query: { username: record.username, domainid: record.domainid } }" v-else-if="$store.getters.userInfo.roletype !== 'User'">{{ text }}</router-link>
|
||||
<span v-else>{{ text }}</span>
|
||||
|
|
@ -347,6 +367,7 @@ import Status from '@/components/widgets/Status'
|
|||
import InfoCard from '@/components/view/InfoCard'
|
||||
import QuickView from '@/components/view/QuickView'
|
||||
import TooltipButton from '@/components/widgets/TooltipButton'
|
||||
import ResourceIcon from '@/components/view/ResourceIcon'
|
||||
|
||||
export default {
|
||||
name: 'ListView',
|
||||
|
|
@ -356,7 +377,8 @@ export default {
|
|||
Status,
|
||||
InfoCard,
|
||||
QuickView,
|
||||
TooltipButton
|
||||
TooltipButton,
|
||||
ResourceIcon
|
||||
},
|
||||
props: {
|
||||
columns: {
|
||||
|
|
@ -382,6 +404,7 @@ export default {
|
|||
selectedRowKeys: [],
|
||||
editableValueKey: null,
|
||||
editableValue: '',
|
||||
resourceIcon: '',
|
||||
thresholdMapping: {
|
||||
cpuused: {
|
||||
notification: 'cputhreshold',
|
||||
|
|
|
|||
|
|
@ -0,0 +1,59 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
<template>
|
||||
<img :src="getImg()" :height="getDimensions()" :width="getDimensions()" :style="{ marginTop: (getDimensions() === '56px' || ['deployVirtualMachine'].includes(this.$route.path.split('/')[2])) ? '' : '-5px' }"/>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'ResourceIcon',
|
||||
props: {
|
||||
image: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
size: {
|
||||
type: String,
|
||||
default: '4x'
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {}
|
||||
},
|
||||
methods: {
|
||||
getImg () {
|
||||
if (this.image.startsWith('data:image/png')) {
|
||||
return this.image
|
||||
} else {
|
||||
return 'data:image/png;charset=utf-8;base64, ' + this.image
|
||||
}
|
||||
},
|
||||
getDimensions () {
|
||||
switch (this.size) {
|
||||
case '4x':
|
||||
return '56px'
|
||||
case '2x':
|
||||
return '24px'
|
||||
case '1x':
|
||||
return '16px'
|
||||
default:
|
||||
return '16px'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -67,7 +67,21 @@
|
|||
<a-select-option
|
||||
v-for="(opt, idx) in field.opts"
|
||||
:key="idx"
|
||||
:value="opt.id">{{ $t(opt.name) }}</a-select-option>
|
||||
:value="opt.id">
|
||||
<span v-if="(field.name.startsWith('zone'))">
|
||||
<span v-if="opt.icon">
|
||||
<resource-icon :image="opt.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
</span>
|
||||
<a-icon v-else type="global" style="margin-right: 5px" />
|
||||
</span>
|
||||
<span v-if="(field.name.startsWith('domain'))">
|
||||
<span v-if="opt.icon">
|
||||
<resource-icon :image="opt.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
</span>
|
||||
<a-icon v-else type="block" style="margin-right: 5px" />
|
||||
</span>
|
||||
{{ $t(opt.name) }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
<a-input
|
||||
v-else-if="field.type==='input'"
|
||||
|
|
@ -124,11 +138,13 @@
|
|||
<script>
|
||||
import { api } from '@/api'
|
||||
import TooltipButton from '@/components/widgets/TooltipButton'
|
||||
import ResourceIcon from '@/components/view/ResourceIcon'
|
||||
|
||||
export default {
|
||||
name: 'SearchView',
|
||||
components: {
|
||||
TooltipButton
|
||||
TooltipButton,
|
||||
ResourceIcon
|
||||
},
|
||||
props: {
|
||||
searchFilters: {
|
||||
|
|
@ -341,7 +357,7 @@ export default {
|
|||
},
|
||||
fetchZones () {
|
||||
return new Promise((resolve, reject) => {
|
||||
api('listZones', { listAll: true }).then(json => {
|
||||
api('listZones', { listAll: true, showicon: true }).then(json => {
|
||||
const zones = json.listzonesresponse.zone
|
||||
resolve({
|
||||
type: 'zoneid',
|
||||
|
|
@ -354,7 +370,7 @@ export default {
|
|||
},
|
||||
fetchDomains () {
|
||||
return new Promise((resolve, reject) => {
|
||||
api('listDomains', { listAll: true }).then(json => {
|
||||
api('listDomains', { listAll: true, showicon: true }).then(json => {
|
||||
const domain = json.listdomainsresponse.domain
|
||||
resolve({
|
||||
type: 'domainid',
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ import { api } from '@/api'
|
|||
import DetailsTab from '@/components/view/DetailsTab'
|
||||
import ResourceView from '@/components/view/ResourceView'
|
||||
import ResourceLayout from '@/layouts/ResourceLayout'
|
||||
import eventBus from '@/config/eventBus'
|
||||
|
||||
export default {
|
||||
name: 'TreeView',
|
||||
|
|
@ -153,6 +154,9 @@ export default {
|
|||
this.metaName = this.$route.meta.name
|
||||
this.apiList = this.$route.meta.permission[0] ? this.$route.meta.permission[0] : ''
|
||||
this.apiChildren = this.$route.meta.permission[1] ? this.$route.meta.permission[1] : ''
|
||||
eventBus.$on('refresh-domain-icon', () => {
|
||||
this.getDetailResource(this.selectedTreeKey)
|
||||
})
|
||||
},
|
||||
watch: {
|
||||
loading () {
|
||||
|
|
@ -225,7 +229,8 @@ export default {
|
|||
|
||||
const params = {
|
||||
listAll: true,
|
||||
id: treeNode.eventKey
|
||||
id: treeNode.eventKey,
|
||||
showicon: true
|
||||
}
|
||||
|
||||
return new Promise(resolve => {
|
||||
|
|
@ -341,7 +346,6 @@ export default {
|
|||
this.treeViewData = []
|
||||
this.loadingSearch = true
|
||||
this.$emit('change-tree-store', {})
|
||||
|
||||
api(this.apiList, params).then(json => {
|
||||
const listDomains = this.getResponseJsonData(json)
|
||||
this.treeVerticalData = this.treeVerticalData.concat(listDomains)
|
||||
|
|
@ -393,11 +397,11 @@ export default {
|
|||
// set id to parameter
|
||||
params.id = selectedKey
|
||||
params.listAll = true
|
||||
params.showicon = true
|
||||
params.page = 1
|
||||
params.pageSize = 1
|
||||
|
||||
this.detailLoading = true
|
||||
|
||||
api(apiName, params).then(json => {
|
||||
const jsonResponse = this.getResponseJsonData(json)
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,314 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<a-modal
|
||||
:title="$t('label.upload.resource.icon')"
|
||||
:visible="visible"
|
||||
:maskClosable="true"
|
||||
:confirmLoading="confirmLoading"
|
||||
:width="800"
|
||||
:footer="null"
|
||||
@cancel="handleClose">
|
||||
<a-row>
|
||||
<a-col :xs="24" :md="12" :style="{height: '350px'}">
|
||||
<vue-cropper
|
||||
ref="cropper"
|
||||
:img="options.img"
|
||||
:outputSize="1"
|
||||
outputType="png"
|
||||
:info="true"
|
||||
:autoCrop="options.autoCrop"
|
||||
:autoCropWidth="options.autoCropWidth"
|
||||
:autoCropHeight="options.autoCropHeight"
|
||||
:fixedBox="options.fixedBox"
|
||||
@realTime="realTime"
|
||||
>
|
||||
</vue-cropper>
|
||||
</a-col>
|
||||
<a-col :xs="24" :md="12" :style="{height: '350px'}">
|
||||
<div class="avatar-upload-preview">
|
||||
<span v-if="previews.url">
|
||||
<img :src="previews.url" :style="previews.img"/>
|
||||
</span>
|
||||
<span v-else-if="defaultImage">
|
||||
<img :src="'data:image/png;charset=utf-8;base64, ' + defaultImage" style="height: 52px;width: 52px;marginLeft: 65px;marginTop: 55px"/>
|
||||
</span>
|
||||
</div>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<br>
|
||||
<a-row>
|
||||
<a-col :xs="2" :md="2">
|
||||
<a-upload name="file" :beforeUpload="beforeUpload" :showUploadList="false">
|
||||
<a-button><a-icon type="upload" />{{ $t('label.choose.resource.icon') }} </a-button>
|
||||
</a-upload>
|
||||
</a-col>
|
||||
<a-col :xs="{span: 2, offset: 4}" :md="1">
|
||||
<a-button icon="plus" @click="changeScale(5)"/>
|
||||
</a-col>
|
||||
<a-col :xs="{span: 1, offset: 0}" :md="2">
|
||||
<a-button icon="minus" @click="changeScale(-5)"/>
|
||||
</a-col>
|
||||
<a-col :lg="{span: 1, offset: 0}" :md="2">
|
||||
<a-button icon="undo" @click="rotateLeft"/>
|
||||
</a-col>
|
||||
<a-col :lg="{span: 1, offset: 0}" :md="2">
|
||||
<a-button icon="redo" @click="rotateRight"/>
|
||||
</a-col>
|
||||
<a-col :xs="{span: 1, offset: 3}" :md="1">
|
||||
<a-button type="primary" @click="uploadIcon('blob')"> {{ $t('label.upload') }} </a-button>
|
||||
</a-col>
|
||||
<a-col :xs="{span: 2, offset: 5}" :md="2">
|
||||
<a-button v-if="resource.icon && resource.icon.resourcetype.toLowerCase() === $getResourceType().toLowerCase()" type="danger" @click="deleteIcon('blob')"> {{ $t('label.delete') }} </a-button>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-modal>
|
||||
<a-modal
|
||||
:visible="showAlert"
|
||||
:footer="null"
|
||||
style="top: 20px;"
|
||||
centered
|
||||
width="auto"
|
||||
:maskClosable="false">
|
||||
<span slot="title">
|
||||
{{ $t('label.warning') }}
|
||||
</span>
|
||||
<a-alert type="warning">
|
||||
<span slot="message" v-html="$t('message.warn.filetype')" />
|
||||
</a-alert>
|
||||
<a-divider style="margin-top: 0;"></a-divider>
|
||||
<div :span="24" class="action-button">
|
||||
<a-button key="submit" type="primary" @click="handleOk" style="textAlign: right">
|
||||
{{ $t('label.ok') }}
|
||||
</a-button>
|
||||
</div>
|
||||
</a-modal>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { api } from '@/api'
|
||||
import eventBus from '@/config/eventBus'
|
||||
|
||||
export default {
|
||||
name: 'UploadResourceIcon',
|
||||
props: {
|
||||
visible: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
resource: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
resource: function (oldVal, newVal) {
|
||||
if (oldVal === newVal) return
|
||||
this.defaultImage = this.resource?.icon?.base64image || ''
|
||||
},
|
||||
preview: function (data) {
|
||||
this.realTime(data)
|
||||
return this.previews
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
id: null,
|
||||
confirmLoading: false,
|
||||
fileList: [],
|
||||
uploading: false,
|
||||
options: {
|
||||
img: '',
|
||||
autoCrop: true,
|
||||
autoCropWidth: 200,
|
||||
autoCropHeight: 200,
|
||||
fixedBox: true
|
||||
},
|
||||
previews: {},
|
||||
defaultImage: '',
|
||||
showAlert: false,
|
||||
croppedImage: ''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleClose () {
|
||||
this.options.img = ''
|
||||
this.previews = {}
|
||||
eventBus.$emit('handle-close')
|
||||
},
|
||||
realTime (data) {
|
||||
if (data && data.url) {
|
||||
this.previews = data
|
||||
} else {
|
||||
if (this.resource?.icon?.base64image) {
|
||||
this.previews.url = 'data:image/png;charset=utf-8;base64, ' + (this.defaultImage || this.resource.icon.base64image || '')
|
||||
this.previews.img = {
|
||||
height: '52px',
|
||||
width: '52px',
|
||||
marginLeft: '65px',
|
||||
marginTop: '55px'
|
||||
}
|
||||
} else {
|
||||
this.previews = {}
|
||||
}
|
||||
}
|
||||
},
|
||||
handleOk () {
|
||||
this.showAlert = false
|
||||
this.options.img = ''
|
||||
},
|
||||
beforeUpload (file) {
|
||||
if (!/\.(svg|jpg|jpeg|png|bmp|SVG|JPG|PNG)$/.test(file.name)) {
|
||||
this.showAlert = true
|
||||
}
|
||||
const reader = new FileReader()
|
||||
reader.readAsDataURL(file)
|
||||
reader.onload = () => {
|
||||
this.options.img = reader.result
|
||||
}
|
||||
return false
|
||||
},
|
||||
changeScale (num) {
|
||||
num = num || 1
|
||||
this.$refs.cropper.changeScale(num)
|
||||
},
|
||||
rotateLeft () {
|
||||
this.$refs.cropper.rotateLeft()
|
||||
},
|
||||
rotateRight () {
|
||||
this.$refs.cropper.rotateRight()
|
||||
},
|
||||
getResourceIcon () {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.$refs.cropper.getCropData((data) => {
|
||||
resolve(data)
|
||||
return data
|
||||
})
|
||||
})
|
||||
},
|
||||
getNewImage (img) {
|
||||
return new Promise((resolve, reject) => {
|
||||
img.onload = function () {
|
||||
var canvas = document.createElement('canvas')
|
||||
var ctx = canvas.getContext('2d')
|
||||
ctx.imageSmoothingQuality = 'high'
|
||||
canvas.height = 52
|
||||
canvas.width = 52
|
||||
ctx.drawImage(img, 0, 0, canvas.width, canvas.height)
|
||||
var base64Canvas = canvas.toDataURL('image/png', 1).split(';base64,')[1]
|
||||
resolve(base64Canvas)
|
||||
return base64Canvas
|
||||
}
|
||||
})
|
||||
},
|
||||
async uploadIcon () {
|
||||
var base64Canvas = ''
|
||||
const resourceType = this.$getResourceType()
|
||||
const resourceid = this.resource.id
|
||||
if (this.options.img) {
|
||||
var newImage = new Image()
|
||||
newImage.src = await this.getResourceIcon()
|
||||
base64Canvas = await this.getNewImage(newImage)
|
||||
}
|
||||
api('uploadResourceIcon', {}, 'POST', {
|
||||
resourceids: resourceid,
|
||||
resourcetype: resourceType,
|
||||
base64image: base64Canvas
|
||||
}).then(json => {
|
||||
console.log(this.resource)
|
||||
if (json?.uploadresourceiconresponse?.success) {
|
||||
this.$notification.success({
|
||||
message: this.$t('label.upload.icon'),
|
||||
description: `${this.$t('message.success.upload.icon')} ${resourceType}: ` + (this.resource.name || this.resource.username || resourceid)
|
||||
})
|
||||
}
|
||||
}).catch((error) => {
|
||||
this.$notification.error({
|
||||
message: this.$t('label.upload.icon'),
|
||||
description: error?.response?.data?.uploadresourceiconresponse?.errortext || '',
|
||||
duration: 0
|
||||
})
|
||||
}).finally(() => {
|
||||
this.handleClose()
|
||||
eventBus.$emit('refresh-icon')
|
||||
if (['user', 'account'].includes(resourceType.toLowerCase())) {
|
||||
eventBus.$emit('refresh-header')
|
||||
}
|
||||
if (['domain'].includes(this.$route.path.split('/')[1])) {
|
||||
eventBus.$emit('refresh-domain-icon')
|
||||
}
|
||||
})
|
||||
},
|
||||
deleteIcon () {
|
||||
const resourceType = this.$getResourceType()
|
||||
const resourceid = this.resource.id
|
||||
api('deleteResourceIcon', {
|
||||
resourcetype: resourceType,
|
||||
resourceids: resourceid
|
||||
}).then(json => {
|
||||
if (json?.deleteresourceiconresponse?.success) {
|
||||
this.$notification.success({
|
||||
message: this.$t('label.delete.icon'),
|
||||
description: `${this.$t('message.success.delete.icon')} ${resourceType}: ` + (this.resource.name || this.resource.username || resourceid)
|
||||
})
|
||||
}
|
||||
}).catch((error) => {
|
||||
this.$notification.error({
|
||||
message: this.$t('label.delete.icon'),
|
||||
description: error?.response?.data?.deleteresourceiconresponse?.errortext || '',
|
||||
duration: 0
|
||||
})
|
||||
}).finally(() => {
|
||||
this.handleClose()
|
||||
eventBus.$emit('refresh-icon')
|
||||
if (['user', 'account'].includes(resourceType.toLowerCase())) {
|
||||
eventBus.$emit('refresh-header')
|
||||
}
|
||||
if (['domain'].includes(this.$route.path.split('/')[1])) {
|
||||
eventBus.$emit('refresh-domain-icon')
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.avatar-upload-preview {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translate(50%, -50%);
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
box-shadow: 0 0 4px #ccc;
|
||||
overflow: hidden;
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
.action-button {
|
||||
text-align: right;
|
||||
margin-top: 20px;
|
||||
|
||||
button {
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -68,6 +68,7 @@ import {
|
|||
AutoComplete,
|
||||
Collapse
|
||||
} from 'ant-design-vue'
|
||||
import VueCropper from 'vue-cropper'
|
||||
|
||||
Vue.use(ConfigProvider)
|
||||
Vue.use(Layout)
|
||||
|
|
@ -117,6 +118,7 @@ Vue.use(Calendar)
|
|||
Vue.use(Slider)
|
||||
Vue.use(AutoComplete)
|
||||
Vue.use(Collapse)
|
||||
Vue.use(VueCropper)
|
||||
|
||||
Vue.prototype.$confirm = Modal.confirm
|
||||
Vue.prototype.$message = message
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ import './core/lazy_use'
|
|||
import './core/ext'
|
||||
import './permission' // permission control
|
||||
import './utils/filter' // global filter
|
||||
import { pollJobPlugin, notifierPlugin, toLocaleDatePlugin, configUtilPlugin, apiMetaUtilPlugin } from './utils/plugins'
|
||||
import { pollJobPlugin, notifierPlugin, toLocaleDatePlugin, configUtilPlugin, apiMetaUtilPlugin, showIconPlugin, resourceTypePlugin } from './utils/plugins'
|
||||
import { VueAxios } from './utils/request'
|
||||
import './utils/directives'
|
||||
|
||||
|
|
@ -35,6 +35,8 @@ Vue.use(VueAxios, router)
|
|||
Vue.use(pollJobPlugin)
|
||||
Vue.use(notifierPlugin)
|
||||
Vue.use(toLocaleDatePlugin)
|
||||
Vue.use(showIconPlugin)
|
||||
Vue.use(resourceTypePlugin)
|
||||
|
||||
fetch('config.json').then(response => response.json()).then(config => {
|
||||
Vue.prototype.$config = config
|
||||
|
|
|
|||
|
|
@ -250,6 +250,39 @@ export const configUtilPlugin = {
|
|||
}
|
||||
}
|
||||
|
||||
export const showIconPlugin = {
|
||||
install (Vue) {
|
||||
Vue.prototype.$showIcon = function (resource) {
|
||||
var resourceType = this.$route.path.split('/')[1]
|
||||
if (resource) {
|
||||
resourceType = resource
|
||||
}
|
||||
if (['zone', 'template', 'iso', 'account', 'accountuser', 'vm', 'domain', 'project', 'vpc', 'guestnetwork'].includes(resourceType)) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const resourceTypePlugin = {
|
||||
install (Vue) {
|
||||
Vue.prototype.$getResourceType = function () {
|
||||
const type = this.$route.path.split('/')[1]
|
||||
if (type === 'vm') {
|
||||
return 'UserVM'
|
||||
} else if (type === 'accountuser') {
|
||||
return 'User'
|
||||
} else if (type === 'guestnetwork') {
|
||||
return 'Network'
|
||||
} else {
|
||||
return type
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const apiMetaUtilPlugin = {
|
||||
install (Vue) {
|
||||
Vue.prototype.$getApiParams = function () {
|
||||
|
|
|
|||
|
|
@ -271,6 +271,44 @@
|
|||
>
|
||||
<a-select-option key="">{{ }}</a-select-option>
|
||||
<a-select-option v-for="opt in field.opts" :key="opt.id">
|
||||
<span>
|
||||
<span v-if="(field.name.startsWith('template') || field.name.startsWith('iso'))">
|
||||
<span v-if="opt.icon">
|
||||
<resource-icon :image="opt.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
</span>
|
||||
<os-logo v-else :osId="opt.ostypeid" :osName="opt.ostypename" size="lg" style="margin-left: -1px" />
|
||||
</span>
|
||||
<span v-if="(field.name.startsWith('zone'))">
|
||||
<span v-if="opt.icon">
|
||||
<resource-icon :image="opt.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
</span>
|
||||
<a-icon v-else type="global" style="margin-right: 5px" />
|
||||
</span>
|
||||
<span v-if="(field.name.startsWith('project'))">
|
||||
<span v-if="opt.icon">
|
||||
<resource-icon :image="opt.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
</span>
|
||||
<a-icon v-else type="project" style="margin-right: 5px" />
|
||||
</span>
|
||||
<span v-if="(field.name.startsWith('account') || field.name.startsWith('user'))">
|
||||
<span v-if="opt.icon">
|
||||
<resource-icon :image="opt.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
</span>
|
||||
<a-icon v-else type="user" style="margin-right: 5px"/>
|
||||
</span>
|
||||
<span v-if="(field.name.startsWith('network'))">
|
||||
<span v-if="opt.icon">
|
||||
<resource-icon :image="opt.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
</span>
|
||||
<a-icon v-else type="apartment" style="margin-right: 5px"/>
|
||||
</span>
|
||||
<span v-if="(field.name.startsWith('domain'))">
|
||||
<span v-if="opt.icon">
|
||||
<resource-icon :image="opt.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
</span>
|
||||
<a-icon v-else type="block" style="margin-right: 5px"/>
|
||||
</span>
|
||||
</span>
|
||||
{{ opt.name || opt.description || opt.traffictype || opt.publicip }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
|
|
@ -411,6 +449,8 @@ import ListView from '@/components/view/ListView'
|
|||
import ResourceView from '@/components/view/ResourceView'
|
||||
import ActionButton from '@/components/view/ActionButton'
|
||||
import SearchView from '@/components/view/SearchView'
|
||||
import OsLogo from '@/components/widgets/OsLogo'
|
||||
import ResourceIcon from '@/components/view/ResourceIcon'
|
||||
import BulkActionProgress from '@/components/view/BulkActionProgress'
|
||||
import TooltipLabel from '@/components/widgets/TooltipLabel'
|
||||
|
||||
|
|
@ -425,7 +465,9 @@ export default {
|
|||
ActionButton,
|
||||
SearchView,
|
||||
BulkActionProgress,
|
||||
TooltipLabel
|
||||
TooltipLabel,
|
||||
OsLogo,
|
||||
ResourceIcon
|
||||
},
|
||||
mixins: [mixinDevice],
|
||||
provide: function () {
|
||||
|
|
@ -493,6 +535,11 @@ export default {
|
|||
this.fetchData()
|
||||
}
|
||||
})
|
||||
eventBus.$on('refresh-icon', () => {
|
||||
if (this.$showIcon()) {
|
||||
this.fetchData()
|
||||
}
|
||||
})
|
||||
eventBus.$on('async-job-complete', (action) => {
|
||||
if (this.$route.path.includes('/vm/')) {
|
||||
if (action && 'api' in action && ['destroyVirtualMachine'].includes(action.api)) {
|
||||
|
|
@ -785,7 +832,11 @@ export default {
|
|||
|
||||
params.page = this.page
|
||||
params.pagesize = this.pageSize
|
||||
this.searchParams = params
|
||||
|
||||
if (this.$showIcon()) {
|
||||
params.showIcon = true
|
||||
}
|
||||
api(this.apiName, params).then(json => {
|
||||
var responseName
|
||||
var objectName
|
||||
|
|
@ -986,6 +1037,10 @@ export default {
|
|||
var extractedParamName = paramName.replace('ids', '').replace('id', '').toLowerCase()
|
||||
var params = { listall: true }
|
||||
const possibleName = 'list' + extractedParamName + 's'
|
||||
var showIcon = false
|
||||
if (this.$showIcon(extractedParamName)) {
|
||||
showIcon = true
|
||||
}
|
||||
var possibleApi
|
||||
if (this.currentAction.mapping && param.name in this.currentAction.mapping && this.currentAction.mapping[param.name].api) {
|
||||
possibleApi = this.currentAction.mapping[param.name].api
|
||||
|
|
@ -1017,6 +1072,9 @@ export default {
|
|||
} else if (possibleApi === 'listHosts') {
|
||||
params.type = 'routing'
|
||||
}
|
||||
if (showIcon) {
|
||||
params.showicon = true
|
||||
}
|
||||
api(possibleApi, params).then(json => {
|
||||
param.loading = false
|
||||
for (const obj in json) {
|
||||
|
|
|
|||
|
|
@ -55,6 +55,8 @@
|
|||
return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||
}" >
|
||||
<a-select-option v-for="domain in domains" :key="domain.name" :value="domain.id">
|
||||
<resource-icon v-if="domain && domain.icon" :image="domain.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
<a-icon v-else type="block" style="margin-right: 5px" />
|
||||
{{ domain.path || domain.name || domain.description }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
|
|
@ -72,6 +74,8 @@
|
|||
return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||
}" >
|
||||
<a-select-option v-for="account in accounts" :key="account.name" :value="account.name">
|
||||
<resource-icon v-if="account && account.icon" :image="account.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
<a-icon v-else type="team" style="margin-right: 5px" />
|
||||
{{ account.name }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
|
|
@ -91,6 +95,8 @@
|
|||
return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||
}" >
|
||||
<a-select-option v-for="project in projects" :key="project.id" :value="project.id">
|
||||
<resource-icon v-if="project && project.icon" :image="project.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
<a-icon v-else type="project" style="margin-right: 5px" />
|
||||
{{ project.name }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
|
|
@ -108,6 +114,8 @@
|
|||
return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||
}" >
|
||||
<a-select-option v-for="network in networks" :key="network.id" :value="network.id">
|
||||
<resource-icon v-if="network && network.icon" :image="network.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
<a-icon v-else type="apartment" style="margin-right: 5px" />
|
||||
{{ network.name ? network.name : '-' }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
|
|
@ -129,6 +137,7 @@
|
|||
|
||||
<script>
|
||||
import { api } from '@/api'
|
||||
import ResourceIcon from '@/components/view/ResourceIcon'
|
||||
|
||||
export default {
|
||||
name: 'AssignInstance',
|
||||
|
|
@ -138,6 +147,9 @@ export default {
|
|||
required: true
|
||||
}
|
||||
},
|
||||
components: {
|
||||
ResourceIcon
|
||||
},
|
||||
inject: ['parentFetchData'],
|
||||
data () {
|
||||
return {
|
||||
|
|
@ -164,6 +176,7 @@ export default {
|
|||
api('listDomains', {
|
||||
response: 'json',
|
||||
listAll: true,
|
||||
showicon: true,
|
||||
details: 'min'
|
||||
}).then(response => {
|
||||
this.domains = response.listdomainsresponse.domain
|
||||
|
|
@ -181,6 +194,7 @@ export default {
|
|||
api('listAccounts', {
|
||||
response: 'json',
|
||||
domainId: this.selectedDomain,
|
||||
showicon: true,
|
||||
state: 'Enabled',
|
||||
isrecursive: false
|
||||
}).then(response => {
|
||||
|
|
@ -197,6 +211,7 @@ export default {
|
|||
response: 'json',
|
||||
domainId: this.selectedDomain,
|
||||
state: 'Active',
|
||||
showicon: true,
|
||||
details: 'min',
|
||||
isrecursive: false
|
||||
}).then(response => {
|
||||
|
|
@ -214,6 +229,7 @@ export default {
|
|||
domainId: this.selectedDomain,
|
||||
listAll: true,
|
||||
isrecursive: false,
|
||||
showicon: true,
|
||||
account: this.selectedAccount,
|
||||
projectid: this.selectedProject
|
||||
}).then(response => {
|
||||
|
|
|
|||
|
|
@ -55,6 +55,8 @@
|
|||
:placeholder="apiParams.zoneid.description"
|
||||
@change="val => { this.handleZoneChange(this.zones[val]) }">
|
||||
<a-select-option v-for="(opt, optIndex) in this.zones" :key="optIndex">
|
||||
<resource-icon v-if="opt.icon" :image="opt.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
<a-icon v-else type="global" style="margin-right: 5px" />
|
||||
{{ opt.name || opt.description }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
|
|
@ -242,12 +244,14 @@
|
|||
|
||||
<script>
|
||||
import { api } from '@/api'
|
||||
import ResourceIcon from '@/components/view/ResourceIcon'
|
||||
import TooltipLabel from '@/components/widgets/TooltipLabel'
|
||||
|
||||
export default {
|
||||
name: 'CreateKubernetesCluster',
|
||||
components: {
|
||||
TooltipLabel
|
||||
TooltipLabel,
|
||||
ResourceIcon
|
||||
},
|
||||
props: {},
|
||||
data () {
|
||||
|
|
@ -306,6 +310,7 @@ export default {
|
|||
fetchZoneData () {
|
||||
const params = {}
|
||||
this.zoneLoading = true
|
||||
params.showicon = true
|
||||
api('listZones', params).then(json => {
|
||||
const listZones = json.listzonesresponse.zone
|
||||
this.zones = this.zones.concat(listZones)
|
||||
|
|
|
|||
|
|
@ -32,18 +32,53 @@
|
|||
<div style="margin-top: 15px">
|
||||
<span>{{ $t('message.select.a.zone') }}</span><br/>
|
||||
<a-form-item :label="this.$t('label.zoneid')">
|
||||
<div v-if="zones.length <= 8">
|
||||
<a-row type="flex" :gutter="5" justify="start">
|
||||
<div v-for="(zoneItem, idx) in zones" :key="idx">
|
||||
<a-radio-group
|
||||
:key="idx"
|
||||
v-decorator="['zoneid', {
|
||||
initialValue: selectedZone,
|
||||
rules: [{ required: true, message: `${$t('message.error.select')}` }]}]"
|
||||
@change="onSelectZoneId(zoneItem.id)">
|
||||
<a-col :span="8">
|
||||
<a-card-grid style="width:200px;" :title="zoneItem.name" :hoverable="false">
|
||||
<a-radio :value="zoneItem.id">
|
||||
<div>
|
||||
<img
|
||||
v-if="zoneItem && zoneItem.icon && zoneItem.icon.base64image"
|
||||
:src="getImg(zoneItem.icon.base64image)"
|
||||
style="marginTop: -30px; marginLeft: 60px"
|
||||
width="36px"
|
||||
height="36px" />
|
||||
<a-icon v-else :style="{fontSize: '36px', marginLeft: '60px', marginTop: '-40px'}" type="global"/>
|
||||
</div>
|
||||
</a-radio>
|
||||
<a-card-meta title="" :description="zoneItem.name" style="text-align:center; paddingTop: 10px;" />
|
||||
</a-card-grid>
|
||||
</a-col>
|
||||
</a-radio-group>
|
||||
</div>
|
||||
</a-row>
|
||||
</div>
|
||||
<a-select
|
||||
v-else
|
||||
v-decorator="['zoneid', {
|
||||
rules: [{ required: true, message: `${this.$t('message.error.select')}` }]
|
||||
rules: [{ required: true, message: `${$t('message.error.select')}` }]
|
||||
}]"
|
||||
showSearch
|
||||
optionFilterProp="children"
|
||||
:filterOption="filterOption"
|
||||
:options="zoneSelectOptions"
|
||||
@change="onSelectZoneId"
|
||||
:loading="loading.zones"
|
||||
autoFocus
|
||||
></a-select>
|
||||
>
|
||||
<a-select-option v-for="zone1 in zones" :key="zone1.id">
|
||||
<resource-icon v-if="zone1.icon && zone1.icon.base64image" :image="zone1.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
<a-icon v-else style="margin-right: 5px" type="global" />
|
||||
{{ zone1.name }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
v-if="!isNormalAndDomainUser"
|
||||
|
|
@ -657,6 +692,7 @@ import store from '@/store'
|
|||
import eventBus from '@/config/eventBus'
|
||||
|
||||
import InfoCard from '@/components/view/InfoCard'
|
||||
import ResourceIcon from '@/components/view/ResourceIcon'
|
||||
import ComputeOfferingSelection from '@views/compute/wizard/ComputeOfferingSelection'
|
||||
import ComputeSelection from '@views/compute/wizard/ComputeSelection'
|
||||
import DiskOfferingSelection from '@views/compute/wizard/DiskOfferingSelection'
|
||||
|
|
@ -685,6 +721,7 @@ export default {
|
|||
ComputeOfferingSelection,
|
||||
ComputeSelection,
|
||||
SecurityGroupSelection,
|
||||
ResourceIcon,
|
||||
TooltipLabel
|
||||
},
|
||||
props: {
|
||||
|
|
@ -813,7 +850,9 @@ export default {
|
|||
diskIOpsMin: 0,
|
||||
diskIOpsMax: 0,
|
||||
minIops: 0,
|
||||
maxIops: 0
|
||||
maxIops: 0,
|
||||
zones: [],
|
||||
selectedZone: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
|
@ -898,7 +937,8 @@ export default {
|
|||
account: store.getters.project && store.getters.project.id ? null : store.getters.userInfo.account,
|
||||
page: 1,
|
||||
pageSize: 10,
|
||||
keyword: undefined
|
||||
keyword: undefined,
|
||||
showIcon: true
|
||||
}
|
||||
},
|
||||
pods: {
|
||||
|
|
@ -1102,6 +1142,7 @@ export default {
|
|||
}
|
||||
|
||||
if (this.iso) {
|
||||
this.vm.isoid = this.iso.id
|
||||
this.vm.templateid = this.iso.id
|
||||
this.vm.templatename = this.iso.displaytext
|
||||
this.vm.ostypeid = this.iso.ostypeid
|
||||
|
|
@ -1226,6 +1267,7 @@ export default {
|
|||
this.form.getFieldDecorator([field], { initialValue: this.dataPreFill[field] })
|
||||
},
|
||||
fetchData () {
|
||||
this.fetchZones()
|
||||
if (this.dataPreFill.zoneid) {
|
||||
this.fetchDataByZone(this.dataPreFill.zoneid)
|
||||
} else {
|
||||
|
|
@ -1247,6 +1289,9 @@ export default {
|
|||
isDynamicallyScalable () {
|
||||
return this.serviceOffering && this.serviceOffering.dynamicscalingenabled && this.template && this.template.isdynamicallyscalable && this.dynamicScalingVmConfigValue
|
||||
},
|
||||
getImg (image) {
|
||||
return 'data:image/png;charset=utf-8;base64, ' + image
|
||||
},
|
||||
async fetchDataByZone (zoneId) {
|
||||
this.fillValue('zoneid')
|
||||
this.options.zones = await this.fetchZones()
|
||||
|
|
@ -1677,9 +1722,9 @@ export default {
|
|||
return new Promise((resolve) => {
|
||||
this.loading.zones = true
|
||||
const param = this.params.zones
|
||||
api(param.list, { listall: true }).then(json => {
|
||||
const zones = json.listzonesresponse.zone || []
|
||||
resolve(zones)
|
||||
api(param.list, { listall: true, showicon: true }).then(json => {
|
||||
this.zones = json.listzonesresponse.zone || []
|
||||
resolve(this.zones)
|
||||
}).catch(function (error) {
|
||||
console.log(error.stack)
|
||||
}).finally(() => {
|
||||
|
|
@ -1759,6 +1804,7 @@ export default {
|
|||
args.zoneid = _.get(this.zone, 'id')
|
||||
args.templatefilter = templateFilter
|
||||
args.details = 'all'
|
||||
args.showicon = 'true'
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
api('listTemplates', args).then((response) => {
|
||||
|
|
@ -1778,6 +1824,7 @@ export default {
|
|||
args.zoneid = _.get(this.zone, 'id')
|
||||
args.isoFilter = isoFilter
|
||||
args.bootable = true
|
||||
args.showicon = 'true'
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
api('listIsos', args).then((response) => {
|
||||
|
|
@ -1842,7 +1889,9 @@ export default {
|
|||
this.clusterId = null
|
||||
this.zone = _.find(this.options.zones, (option) => option.id === value)
|
||||
this.zoneSelected = true
|
||||
this.selectedZone = this.zoneId
|
||||
this.form.setFieldsValue({
|
||||
zoneid: this.zoneId,
|
||||
clusterid: undefined,
|
||||
podid: undefined,
|
||||
hostid: undefined,
|
||||
|
|
|
|||
|
|
@ -171,6 +171,8 @@
|
|||
v-for="network in addNetworkData.allNetworks"
|
||||
:key="network.id"
|
||||
:value="network.id">
|
||||
<resource-icon v-if="network.icon" :image="network.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
<a-icon v-else type="apartment" style="margin-right: 5px" />
|
||||
{{ network.name }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
|
|
@ -302,6 +304,7 @@ import DetailSettings from '@/components/view/DetailSettings'
|
|||
import NicsTable from '@/views/network/NicsTable'
|
||||
import ListResourceTable from '@/components/view/ListResourceTable'
|
||||
import TooltipButton from '@/components/widgets/TooltipButton'
|
||||
import ResourceIcon from '@/components/view/ResourceIcon'
|
||||
import AnnotationsTab from '@/components/view/AnnotationsTab'
|
||||
|
||||
export default {
|
||||
|
|
@ -314,6 +317,7 @@ export default {
|
|||
Status,
|
||||
ListResourceTable,
|
||||
TooltipButton,
|
||||
ResourceIcon,
|
||||
AnnotationsTab
|
||||
},
|
||||
mixins: [mixinDevice],
|
||||
|
|
@ -434,6 +438,7 @@ export default {
|
|||
listNetworks () {
|
||||
api('listNetworks', {
|
||||
listAll: 'true',
|
||||
showicon: true,
|
||||
zoneid: this.vm.zoneid
|
||||
}).then(response => {
|
||||
this.addNetworkData.allNetworks = response.listnetworksresponse.network.filter(network => !this.vm.nic.map(nic => nic.networkid).includes(network.id))
|
||||
|
|
|
|||
|
|
@ -34,6 +34,15 @@
|
|||
:rowSelection="rowSelection"
|
||||
:scroll="{ y: 225 }"
|
||||
>
|
||||
<template slot="name" slot-scope="text, item">
|
||||
<resource-icon
|
||||
v-if="item.icon"
|
||||
:image="item.icon.base64image"
|
||||
size="1x"
|
||||
style="margin-right: 5px"/>
|
||||
<a-icon slot="name" v-else type="apartment" style="margin-right: 5px" />
|
||||
{{ item.name }}
|
||||
</template>
|
||||
<a-list
|
||||
slot="expandedRowRender"
|
||||
slot-scope="record"
|
||||
|
|
@ -91,11 +100,13 @@ import _ from 'lodash'
|
|||
import { api } from '@/api'
|
||||
import store from '@/store'
|
||||
import CreateNetwork from '@/views/network/CreateNetwork'
|
||||
import ResourceIcon from '@/components/view/ResourceIcon'
|
||||
|
||||
export default {
|
||||
name: 'NetworkSelection',
|
||||
components: {
|
||||
CreateNetwork
|
||||
CreateNetwork,
|
||||
ResourceIcon
|
||||
},
|
||||
props: {
|
||||
items: {
|
||||
|
|
@ -158,6 +169,7 @@ export default {
|
|||
{
|
||||
dataIndex: 'name',
|
||||
title: this.$t('label.networks'),
|
||||
scopedSlots: { customRender: 'name' },
|
||||
width: '40%'
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -33,7 +33,13 @@
|
|||
class="radio-group__radio"
|
||||
:value="os.id">
|
||||
{{ os.displaytext }}
|
||||
<resource-icon
|
||||
v-if="os.icon && os.icon.base64image"
|
||||
class="radio-group__os-logo"
|
||||
:image="os.icon.base64image"
|
||||
size="1x" />
|
||||
<os-logo
|
||||
v-else
|
||||
class="radio-group__os-logo"
|
||||
:osId="os.ostypeid"
|
||||
:os-name="os.osName" />
|
||||
|
|
@ -63,10 +69,14 @@
|
|||
|
||||
<script>
|
||||
import OsLogo from '@/components/widgets/OsLogo'
|
||||
import ResourceIcon from '@/components/view/ResourceIcon'
|
||||
|
||||
export default {
|
||||
name: 'TemplateIsoRadioGroup',
|
||||
components: { OsLogo },
|
||||
components: {
|
||||
OsLogo,
|
||||
ResourceIcon
|
||||
},
|
||||
props: {
|
||||
osList: {
|
||||
type: Array,
|
||||
|
|
@ -92,6 +102,7 @@ export default {
|
|||
data () {
|
||||
return {
|
||||
value: '',
|
||||
image: '',
|
||||
options: {
|
||||
page: 1,
|
||||
pageSize: 10
|
||||
|
|
|
|||
|
|
@ -31,6 +31,8 @@
|
|||
return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||
}" >
|
||||
<a-select-option v-for="(zone, index) in zones" :key="index">
|
||||
<resource-icon v-if="zone.icon && zone.icon.base64image" :image="zone.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
<a-icon v-else style="margin-right: 5px" type="global" />
|
||||
{{ zone.name }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
|
|
@ -127,11 +129,13 @@
|
|||
import { api } from '@/api'
|
||||
|
||||
import ChartCard from '@/components/widgets/ChartCard'
|
||||
import ResourceIcon from '@/components/view/ResourceIcon'
|
||||
|
||||
export default {
|
||||
name: 'CapacityDashboard',
|
||||
components: {
|
||||
ChartCard
|
||||
ChartCard,
|
||||
ResourceIcon
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
|
|
@ -245,7 +249,7 @@ export default {
|
|||
return 'blue'
|
||||
},
|
||||
listZones () {
|
||||
api('listZones').then(json => {
|
||||
api('listZones', { showicon: true }).then(json => {
|
||||
if (json && json.listzonesresponse && json.listzonesresponse.zone) {
|
||||
this.zones = json.listzonesresponse.zone
|
||||
if (this.zones.length > 0) {
|
||||
|
|
|
|||
|
|
@ -115,6 +115,8 @@
|
|||
return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||
}" >
|
||||
<a-select-option v-for="domain in domainsList" :key="domain.id">
|
||||
<resource-icon v-if="domain && domain.icon" :image="domain.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
<a-icon v-else type="block" style="margin-right: 5px"/>
|
||||
{{ domain.path || domain.name || domain.description }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
|
|
@ -179,12 +181,14 @@
|
|||
import { api } from '@/api'
|
||||
import { timeZone } from '@/utils/timezone'
|
||||
import debounce from 'lodash/debounce'
|
||||
import ResourceIcon from '@/components/view/ResourceIcon'
|
||||
import TooltipLabel from '@/components/widgets/TooltipLabel'
|
||||
|
||||
export default {
|
||||
name: 'AddAccountForm',
|
||||
components: {
|
||||
TooltipLabel
|
||||
TooltipLabel,
|
||||
ResourceIcon
|
||||
},
|
||||
data () {
|
||||
this.fetchTimeZone = debounce(this.fetchTimeZone, 800)
|
||||
|
|
@ -249,6 +253,7 @@ export default {
|
|||
this.domainLoading = true
|
||||
api('listDomains', {
|
||||
listAll: true,
|
||||
showicon: true,
|
||||
details: 'min'
|
||||
}).then(response => {
|
||||
this.domainsList = response.listdomainsresponse.domain || []
|
||||
|
|
|
|||
|
|
@ -95,6 +95,8 @@
|
|||
return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||
}" >
|
||||
<a-select-option v-for="domain in domainsList" :key="domain.id">
|
||||
<resource-icon v-if="domain && domain.icon" :image="domain.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
<a-icon v-else type="block" style="margin-right: 5px" />
|
||||
{{ domain.path || domain.name || domain.description }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
|
|
@ -113,6 +115,8 @@
|
|||
return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||
}" >
|
||||
<a-select-option v-for="(item, idx) in accountList" :key="idx">
|
||||
<resource-icon v-if="item && item.icon" :image="item.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
<a-icon v-else type="team" style="margin-right: 5px" />
|
||||
{{ item.name }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
|
|
@ -167,12 +171,14 @@
|
|||
import { api } from '@/api'
|
||||
import { timeZone } from '@/utils/timezone'
|
||||
import debounce from 'lodash/debounce'
|
||||
import ResourceIcon from '@/components/view/ResourceIcon'
|
||||
import TooltipLabel from '@/components/widgets/TooltipLabel'
|
||||
|
||||
export default {
|
||||
name: 'AddUser',
|
||||
components: {
|
||||
TooltipLabel
|
||||
TooltipLabel,
|
||||
ResourceIcon
|
||||
},
|
||||
data () {
|
||||
this.fetchTimeZone = debounce(this.fetchTimeZone, 800)
|
||||
|
|
@ -217,6 +223,7 @@ export default {
|
|||
this.domainLoading = true
|
||||
api('listDomains', {
|
||||
listAll: true,
|
||||
showicon: true,
|
||||
details: 'min'
|
||||
}).then(response => {
|
||||
this.domainsList = response.listdomainsresponse.domain || []
|
||||
|
|
@ -233,7 +240,7 @@ export default {
|
|||
fetchAccount () {
|
||||
this.accountList = []
|
||||
this.loadingAccount = true
|
||||
api('listAccounts', { listAll: true }).then(response => {
|
||||
api('listAccounts', { listAll: true, showicon: true }).then(response => {
|
||||
this.accountList = response.listaccountsresponse.account || []
|
||||
}).catch(error => {
|
||||
this.$notification.error({
|
||||
|
|
|
|||
|
|
@ -88,6 +88,7 @@ import ActionButton from '@/components/view/ActionButton'
|
|||
import TreeView from '@/components/view/TreeView'
|
||||
import DomainActionForm from '@/views/iam/DomainActionForm'
|
||||
import ResourceView from '@/components/view/ResourceView'
|
||||
import eventBus from '@/config/eventBus'
|
||||
|
||||
export default {
|
||||
name: 'DomainView',
|
||||
|
|
@ -136,6 +137,11 @@ export default {
|
|||
created () {
|
||||
this.domainStore = store.getters.domainStore
|
||||
this.fetchData()
|
||||
eventBus.$on('refresh-domain-icon', () => {
|
||||
if (this.$showIcon()) {
|
||||
this.fetchData()
|
||||
}
|
||||
})
|
||||
},
|
||||
watch: {
|
||||
'$route' (to, from) {
|
||||
|
|
@ -170,7 +176,7 @@ export default {
|
|||
}
|
||||
|
||||
this.loading = true
|
||||
|
||||
params.showicon = true
|
||||
api('listDomains', params).then(json => {
|
||||
const domains = json.listdomainsresponse.domain || []
|
||||
this.treeData = this.generateTreeData(domains)
|
||||
|
|
@ -296,6 +302,9 @@ export default {
|
|||
|
||||
rootItem[0].title = rootItem[0].title ? rootItem[0].title : rootItem[0].name
|
||||
rootItem[0].key = rootItem[0].id ? rootItem[0].id : 0
|
||||
rootItem[0].slots = {
|
||||
icon: 'leaf'
|
||||
}
|
||||
|
||||
if (!rootItem[0].haschild) {
|
||||
rootItem[0].isLeaf = true
|
||||
|
|
|
|||
|
|
@ -63,6 +63,8 @@
|
|||
:loading="zoneLoading"
|
||||
:placeholder="apiParams.zoneid.description">
|
||||
<a-select-option v-for="(opt, optIndex) in this.zones" :key="optIndex">
|
||||
<resource-icon v-if="opt.icon" :image="opt.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
<a-icon v-else type="global" style="margin-right: 5px"/>
|
||||
{{ opt.name || opt.description }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
|
|
@ -129,11 +131,13 @@
|
|||
|
||||
<script>
|
||||
import { api } from '@/api'
|
||||
import ResourceIcon from '@/components/view/ResourceIcon'
|
||||
import TooltipLabel from '@/components/widgets/TooltipLabel'
|
||||
|
||||
export default {
|
||||
name: 'AddKubernetesSupportedVersion',
|
||||
components: {
|
||||
ResourceIcon,
|
||||
TooltipLabel
|
||||
},
|
||||
data () {
|
||||
|
|
@ -169,6 +173,7 @@ export default {
|
|||
fetchZoneData () {
|
||||
const params = {}
|
||||
params.listAll = true
|
||||
params.showicon = true
|
||||
this.zoneLoading = true
|
||||
api('listZones', params).then(json => {
|
||||
const listZones = json.listzonesresponse.zone
|
||||
|
|
|
|||
|
|
@ -34,6 +34,13 @@
|
|||
:pagination="false"
|
||||
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
|
||||
:rowKey="record => record.zoneid">
|
||||
<div slot="zonename" slot-scope="text, record">
|
||||
<span v-if="fetchZoneIcon(record.zoneid)">
|
||||
<resource-icon :image="zoneIcon" size="1x" style="margin-right: 5px"/>
|
||||
</span>
|
||||
<a-icon v-else type="global" style="margin-right: 5px" />
|
||||
<span> {{ record.zonename }} </span>
|
||||
</div>
|
||||
<div slot="isready" slot-scope="text, record">
|
||||
<span v-if="record.isready">{{ $t('label.yes') }}</span>
|
||||
<span v-else>{{ $t('label.no') }}</span>
|
||||
|
|
@ -119,6 +126,10 @@
|
|||
:loading="zoneLoading"
|
||||
autoFocus>
|
||||
<a-select-option v-for="zone in zones" :key="zone.id">
|
||||
<span v-if="zone.icon && zone.icon.base64image">
|
||||
<resource-icon :image="zone.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
</span>
|
||||
<a-icon v-else type="global" style="margin-right: 5px" />
|
||||
{{ zone.name }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
|
|
@ -152,6 +163,8 @@
|
|||
<script>
|
||||
import { api } from '@/api'
|
||||
import TooltipButton from '@/components/widgets/TooltipButton'
|
||||
import OsLogo from '@/components/widgets/OsLogo'
|
||||
import ResourceIcon from '@/components/view/ResourceIcon'
|
||||
import BulkActionView from '@/components/view/BulkActionView'
|
||||
import eventBus from '@/config/eventBus'
|
||||
|
||||
|
|
@ -159,6 +172,8 @@ export default {
|
|||
name: 'IsoZones',
|
||||
components: {
|
||||
TooltipButton,
|
||||
OsLogo,
|
||||
ResourceIcon,
|
||||
BulkActionView
|
||||
},
|
||||
props: {
|
||||
|
|
@ -206,7 +221,8 @@ export default {
|
|||
this.columns = [
|
||||
{
|
||||
title: this.$t('label.zonename'),
|
||||
dataIndex: 'zonename'
|
||||
dataIndex: 'zonename',
|
||||
scopedSlots: { customRender: 'zonename' }
|
||||
},
|
||||
{
|
||||
title: this.$t('label.status'),
|
||||
|
|
@ -262,6 +278,15 @@ export default {
|
|||
}).finally(() => {
|
||||
this.fetchLoading = false
|
||||
})
|
||||
this.fetchZoneData()
|
||||
},
|
||||
fetchZoneIcon (zoneid) {
|
||||
const zoneItem = this.zones.filter(zone => zone.id === zoneid)
|
||||
if (zoneItem?.[0]?.icon?.base64image) {
|
||||
this.zoneIcon = zoneItem[0].icon.base64image
|
||||
return true
|
||||
}
|
||||
return false
|
||||
},
|
||||
handleChangePage (page, pageSize) {
|
||||
this.page = page
|
||||
|
|
@ -381,7 +406,7 @@ export default {
|
|||
fetchZoneData () {
|
||||
this.zones = []
|
||||
this.zoneLoading = true
|
||||
api('listZones', { listall: true }).then(json => {
|
||||
api('listZones', { listall: true, showicon: true }).then(json => {
|
||||
const zones = json.listzonesresponse.zone || []
|
||||
this.zones = [...zones.filter((zone) => this.currentRecord.zoneid !== zone.id)]
|
||||
}).finally(() => {
|
||||
|
|
|
|||
|
|
@ -93,6 +93,8 @@
|
|||
:loading="zoneLoading"
|
||||
:placeholder="apiParams.zoneid.description">
|
||||
<a-select-option :value="opt.id" v-for="opt in zones" :key="opt.id">
|
||||
<resource-icon v-if="opt.icon" :image="opt.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
<a-icon v-else type="global" style="margin-right: 5px" />
|
||||
{{ opt.name || opt.description }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
|
|
@ -121,6 +123,8 @@
|
|||
:loading="osTypeLoading"
|
||||
:placeholder="apiParams.ostypeid.description">
|
||||
<a-select-option :value="opt.id" v-for="(opt, optIndex) in osTypes" :key="optIndex">
|
||||
<resource-icon v-if="opt.icon" :image="opt.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
<a-icon v-else type="global" style="margin-right: 5px" />
|
||||
{{ opt.name || opt.description }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
|
|
@ -162,6 +166,7 @@
|
|||
import { api } from '@/api'
|
||||
import store from '@/store'
|
||||
import { axios } from '../../utils/request'
|
||||
import ResourceIcon from '@/components/view/ResourceIcon'
|
||||
|
||||
export default {
|
||||
name: 'RegisterIso',
|
||||
|
|
@ -175,6 +180,9 @@ export default {
|
|||
required: true
|
||||
}
|
||||
},
|
||||
components: {
|
||||
ResourceIcon
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
fileList: [],
|
||||
|
|
@ -218,6 +226,7 @@ export default {
|
|||
fetchZoneData () {
|
||||
const params = {}
|
||||
params.listAll = true
|
||||
params.showicon = true
|
||||
|
||||
this.zoneLoading = true
|
||||
if (store.getters.userInfo.roletype === this.rootAdmin) {
|
||||
|
|
|
|||
|
|
@ -104,6 +104,8 @@
|
|||
:placeholder="apiParams.zoneids.description"
|
||||
@change="handlerSelectZone">
|
||||
<a-select-option v-for="opt in zones.opts" :key="opt.id">
|
||||
<resource-icon v-if="opt.icon" :image="opt.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
<a-icon v-else type="global" style="margin-right: 5px" />
|
||||
{{ opt.name || opt.description }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
|
|
@ -137,6 +139,8 @@
|
|||
:placeholder="apiParams.zoneid.description"
|
||||
:loading="zones.loading">
|
||||
<a-select-option :value="zone.id" v-for="zone in zones.opts" :key="zone.id">
|
||||
<resource-icon v-if="zone.icon" :image="zone.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
<a-icon v-else type="global" style="margin-right: 5px" />
|
||||
{{ zone.name || zone.description }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
|
|
@ -394,6 +398,7 @@
|
|||
import { api } from '@/api'
|
||||
import store from '@/store'
|
||||
import { axios } from '../../utils/request'
|
||||
import ResourceIcon from '@/components/view/ResourceIcon'
|
||||
|
||||
export default {
|
||||
name: 'RegisterOrUploadTemplate',
|
||||
|
|
@ -407,6 +412,9 @@ export default {
|
|||
required: true
|
||||
}
|
||||
},
|
||||
components: {
|
||||
ResourceIcon
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
uploadPercentage: 0,
|
||||
|
|
@ -522,7 +530,7 @@ export default {
|
|||
const params = {}
|
||||
let listZones = []
|
||||
params.listAll = true
|
||||
|
||||
params.showicon = true
|
||||
this.allowed = false
|
||||
|
||||
if (store.getters.userInfo.roletype === this.rootAdmin && this.currentForm === 'Create') {
|
||||
|
|
|
|||
|
|
@ -34,6 +34,13 @@
|
|||
:pagination="false"
|
||||
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
|
||||
:rowKey="record => record.zoneid">
|
||||
<div slot="zonename" slot-scope="text, record">
|
||||
<span v-if="fetchZoneIcon(record.zoneid)">
|
||||
<resource-icon :image="zoneIcon" size="1x" style="margin-right: 5px"/>
|
||||
</span>
|
||||
<a-icon v-else type="global" style="margin-right: 5px" />
|
||||
<span> {{ record.zonename }} </span>
|
||||
</div>
|
||||
<div slot="isready" slot-scope="text, record">
|
||||
<span v-if="record.isready">{{ $t('label.yes') }}</span>
|
||||
<span v-else>{{ $t('label.no') }}</span>
|
||||
|
|
@ -120,6 +127,10 @@
|
|||
:loading="zoneLoading"
|
||||
autoFocus>
|
||||
<a-select-option v-for="zone in zones" :key="zone.id">
|
||||
<span v-if="zone.icon && zone.icon.base64image">
|
||||
<resource-icon :image="zone.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
</span>
|
||||
<a-icon v-else type="global" style="margin-right: 5px" />
|
||||
{{ zone.name }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
|
|
@ -186,6 +197,8 @@
|
|||
|
||||
<script>
|
||||
import { api } from '@/api'
|
||||
import OsLogo from '@/components/widgets/OsLogo'
|
||||
import ResourceIcon from '@/components/view/ResourceIcon'
|
||||
import TooltipButton from '@/components/widgets/TooltipButton'
|
||||
import BulkActionProgress from '@/components/view/BulkActionProgress'
|
||||
import Status from '@/components/widgets/Status'
|
||||
|
|
@ -195,6 +208,8 @@ export default {
|
|||
name: 'TemplateZones',
|
||||
components: {
|
||||
TooltipButton,
|
||||
OsLogo,
|
||||
ResourceIcon,
|
||||
BulkActionProgress,
|
||||
Status
|
||||
},
|
||||
|
|
@ -246,7 +261,8 @@ export default {
|
|||
this.columns = [
|
||||
{
|
||||
title: this.$t('label.zonename'),
|
||||
dataIndex: 'zonename'
|
||||
dataIndex: 'zonename',
|
||||
scopedSlots: { customRender: 'zonename' }
|
||||
},
|
||||
{
|
||||
title: this.$t('label.status'),
|
||||
|
|
@ -315,6 +331,15 @@ export default {
|
|||
}).finally(() => {
|
||||
this.fetchLoading = false
|
||||
})
|
||||
this.fetchZoneData()
|
||||
},
|
||||
fetchZoneIcon (zoneid) {
|
||||
const zoneItem = this.zones.filter(zone => zone.id === zoneid)
|
||||
if (zoneItem?.[0]?.icon?.base64image) {
|
||||
this.zoneIcon = zoneItem[0].icon.base64image
|
||||
return true
|
||||
}
|
||||
return false
|
||||
},
|
||||
handleChangePage (page, pageSize) {
|
||||
this.page = page
|
||||
|
|
@ -466,7 +491,7 @@ export default {
|
|||
fetchZoneData () {
|
||||
this.zones = []
|
||||
this.zoneLoading = true
|
||||
api('listZones', { listall: true }).then(json => {
|
||||
api('listZones', { listall: true, showicon: true }).then(json => {
|
||||
const zones = json.listzonesresponse.zone || []
|
||||
this.zones = [...zones.filter((zone) => this.currentRecord.zoneid !== zone.id)]
|
||||
}).finally(() => {
|
||||
|
|
|
|||
|
|
@ -77,6 +77,8 @@
|
|||
return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||
}" >
|
||||
<a-select-option v-for="account in accountsList" :key="account.name">
|
||||
<resource-icon v-if="account.icon" :image="account.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
<a-icon v-else type="team" style="margin-right: 5px" />
|
||||
{{ account.name }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
|
|
@ -104,6 +106,8 @@
|
|||
return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||
}" >
|
||||
<a-select-option v-for="project in projectsList" :key="project.name">
|
||||
<resource-icon v-if="project.icon" :image="project.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
<a-icon v-else type="project" style="margin-right: 5px" />
|
||||
{{ project.name }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
|
|
@ -119,6 +123,7 @@
|
|||
</template>
|
||||
<script>
|
||||
import { api } from '@/api'
|
||||
import ResourceIcon from '@/components/view/ResourceIcon'
|
||||
|
||||
export default {
|
||||
name: 'UpdateTemplateIsoPermissions',
|
||||
|
|
@ -128,6 +133,9 @@ export default {
|
|||
required: true
|
||||
}
|
||||
},
|
||||
components: {
|
||||
ResourceIcon
|
||||
},
|
||||
inject: ['parentFetchData'],
|
||||
data () {
|
||||
return {
|
||||
|
|
@ -188,7 +196,8 @@ export default {
|
|||
fetchAccounts () {
|
||||
this.loading = true
|
||||
api('listAccounts', {
|
||||
domainid: this.resource.domainid
|
||||
domainid: this.resource.domainid,
|
||||
showicon: true
|
||||
}).then(response => {
|
||||
this.accounts = response.listaccountsresponse.account.filter(account => account.name !== this.resource.account)
|
||||
}).finally(e => {
|
||||
|
|
@ -198,6 +207,7 @@ export default {
|
|||
fetchProjects () {
|
||||
api('listProjects', {
|
||||
details: 'min',
|
||||
showicon: true,
|
||||
listall: true
|
||||
}).then(response => {
|
||||
this.projects = response.listprojectsresponse.project
|
||||
|
|
|
|||
|
|
@ -62,6 +62,8 @@
|
|||
return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||
}" >
|
||||
<a-select-option :value="zone.id" v-for="(zone) in zones" :key="zone.id">
|
||||
<resource-icon v-if="zone.icon" :image="zone.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
<a-icon v-else type="global" style="margin-right: 5px" />
|
||||
{{ zone.name }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
|
|
@ -278,12 +280,14 @@
|
|||
<script>
|
||||
import { api } from '@/api'
|
||||
import _ from 'lodash'
|
||||
import ResourceIcon from '@/components/view/ResourceIcon'
|
||||
import TooltipLabel from '@/components/widgets/TooltipLabel'
|
||||
|
||||
export default {
|
||||
name: 'AddPrimaryStorage',
|
||||
components: {
|
||||
TooltipLabel
|
||||
TooltipLabel,
|
||||
ResourceIcon
|
||||
},
|
||||
props: {
|
||||
resource: {
|
||||
|
|
@ -332,7 +336,7 @@ export default {
|
|||
},
|
||||
getInfraData () {
|
||||
this.loading = true
|
||||
api('listZones').then(json => {
|
||||
api('listZones', { showicon: true }).then(json => {
|
||||
this.zones = json.listzonesresponse.zone || []
|
||||
this.changeZone(this.zones[0] ? this.zones[0].id : '')
|
||||
}).finally(() => {
|
||||
|
|
|
|||
|
|
@ -60,8 +60,11 @@
|
|||
<a-select-option
|
||||
:value="zone.id"
|
||||
v-for="(zone) in zones"
|
||||
:key="zone.id"
|
||||
>{{ zone.name }}</a-select-option>
|
||||
:key="zone.id">
|
||||
<resource-icon v-if="zone.icon" :image="zone.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
<a-icon v-else type="global" style="margin-right: 5px" />
|
||||
{{ zone.name }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item :label="$t('label.server')">
|
||||
|
|
@ -167,6 +170,7 @@
|
|||
</template>
|
||||
<script>
|
||||
import { api } from '@/api'
|
||||
import ResourceIcon from '@/components/view/ResourceIcon'
|
||||
|
||||
export default {
|
||||
name: 'AddSecondryStorage',
|
||||
|
|
@ -176,6 +180,9 @@ export default {
|
|||
required: true
|
||||
}
|
||||
},
|
||||
components: {
|
||||
ResourceIcon
|
||||
},
|
||||
inject: ['parentFetchData'],
|
||||
data () {
|
||||
return {
|
||||
|
|
@ -200,7 +207,7 @@ export default {
|
|||
this.$parent.$parent.close()
|
||||
},
|
||||
listZones () {
|
||||
api('listZones').then(json => {
|
||||
api('listZones', { showicon: true }).then(json => {
|
||||
if (json && json.listzonesresponse && json.listzonesresponse.zone) {
|
||||
this.zones = json.listzonesresponse.zone
|
||||
if (this.zones.length > 0) {
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@
|
|||
v-for="zone in zonesList"
|
||||
:value="zone.id"
|
||||
:key="zone.id">
|
||||
<resource-icon v-if="zone.icon" :image="zone.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
<a-icon v-else type="global" style="margin-right: 5px" />
|
||||
{{ zone.name }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
|
|
@ -129,11 +131,13 @@
|
|||
<script>
|
||||
import { api } from '@/api'
|
||||
import DedicateDomain from '../../components/view/DedicateDomain'
|
||||
import ResourceIcon from '@/components/view/ResourceIcon'
|
||||
|
||||
export default {
|
||||
name: 'ClusterAdd',
|
||||
components: {
|
||||
DedicateDomain
|
||||
DedicateDomain,
|
||||
ResourceIcon
|
||||
},
|
||||
props: {
|
||||
resource: {
|
||||
|
|
@ -183,7 +187,7 @@ export default {
|
|||
},
|
||||
fetchZones () {
|
||||
this.loading = true
|
||||
api('listZones').then(response => {
|
||||
api('listZones', { showicon: true }).then(response => {
|
||||
this.zonesList = response.listzonesresponse.zone || []
|
||||
this.zoneId = this.zonesList[0].id || null
|
||||
this.fetchPods()
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@
|
|||
v-for="zone in zonesList"
|
||||
:value="zone.id"
|
||||
:key="zone.id">
|
||||
<resource-icon v-if="zone.icon" :image="zone.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
<a-icon v-else type="global" style="margin-right: 5px" />
|
||||
{{ zone.name }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
|
|
@ -152,11 +154,13 @@
|
|||
<script>
|
||||
import { api } from '@/api'
|
||||
import DedicateDomain from '../../components/view/DedicateDomain'
|
||||
import ResourceIcon from '@/components/view/ResourceIcon'
|
||||
|
||||
export default {
|
||||
name: 'HostAdd',
|
||||
components: {
|
||||
DedicateDomain
|
||||
DedicateDomain,
|
||||
ResourceIcon
|
||||
},
|
||||
props: {
|
||||
resource: {
|
||||
|
|
@ -209,7 +213,7 @@ export default {
|
|||
},
|
||||
fetchZones () {
|
||||
this.loading = true
|
||||
api('listZones').then(response => {
|
||||
api('listZones', { showicon: true }).then(response => {
|
||||
this.zonesList = response.listzonesresponse.zone || []
|
||||
this.zoneId = this.zonesList[0].id || null
|
||||
this.fetchPods()
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@
|
|||
v-for="zone in zonesList"
|
||||
:value="zone.id"
|
||||
:key="zone.id">
|
||||
<resource-icon v-if="zone.icon" :image="zone.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
<a-icon v-else type="global" style="margin-right: 5px" />
|
||||
{{ zone.name }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
|
|
@ -117,11 +119,13 @@
|
|||
<script>
|
||||
import { api } from '@/api'
|
||||
import DedicateDomain from '../../components/view/DedicateDomain'
|
||||
import ResourceIcon from '@/components/view/ResourceIcon'
|
||||
|
||||
export default {
|
||||
name: 'ClusterAdd',
|
||||
components: {
|
||||
DedicateDomain
|
||||
DedicateDomain,
|
||||
ResourceIcon
|
||||
},
|
||||
props: {
|
||||
resource: {
|
||||
|
|
@ -161,7 +165,7 @@ export default {
|
|||
},
|
||||
fetchZones () {
|
||||
this.loading = true
|
||||
api('listZones').then(response => {
|
||||
api('listZones', { showicon: true }).then(response => {
|
||||
this.zonesList = response.listzonesresponse.zone || []
|
||||
this.zoneId = this.zonesList[0].id
|
||||
this.params = this.$store.getters.apis.createPod.params
|
||||
|
|
|
|||
|
|
@ -106,7 +106,11 @@
|
|||
:filterOption="(input, option) => {
|
||||
return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||
}" >
|
||||
<a-select-option v-for="domain in domains" :key="domain.id" :value="domain.id">{{ domain.path || domain.name || domain.description }}</a-select-option>
|
||||
<a-select-option v-for="domain in domains" :key="domain.id" :value="domain.id">
|
||||
<resource-icon v-if="domain && domain.icon" :image="domain.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
<a-icon v-else type="block" style="margin-right: 5px" />
|
||||
{{ domain.path || domain.name || domain.description }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
|
||||
|
|
@ -124,6 +128,8 @@
|
|||
v-for="account in accounts"
|
||||
:key="account.id"
|
||||
:value="account.name">
|
||||
<resource-icon v-if="account && account.icon" :image="account.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
<a-icon v-else type="team" style="margin-right: 5px" />
|
||||
{{ account.name }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
|
|
@ -143,6 +149,8 @@
|
|||
v-for="project in projects"
|
||||
:key="project.id"
|
||||
:value="project.id">
|
||||
<resource-icon v-if="project && project.icon" :image="project.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
<a-icon v-else type="project" style="margin-right: 5px" />
|
||||
{{ project.name }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
|
|
@ -162,11 +170,13 @@
|
|||
<script>
|
||||
import { api } from '@/api'
|
||||
import TooltipButton from '@/components/widgets/TooltipButton'
|
||||
import ResourceIcon from '@/components/view/ResourceIcon'
|
||||
|
||||
export default {
|
||||
name: 'DedicatedVLANTab',
|
||||
components: {
|
||||
TooltipButton
|
||||
TooltipButton,
|
||||
ResourceIcon
|
||||
},
|
||||
props: {
|
||||
resource: {
|
||||
|
|
@ -250,6 +260,7 @@ export default {
|
|||
fetchDomains () {
|
||||
api('listDomains', {
|
||||
details: 'min',
|
||||
showicon: true,
|
||||
listAll: true
|
||||
}).then(response => {
|
||||
this.domains = response.listdomainsresponse.domain || []
|
||||
|
|
@ -274,6 +285,7 @@ export default {
|
|||
api('listAccounts', {
|
||||
domainid: e,
|
||||
details: 'min',
|
||||
showicon: true,
|
||||
listAll: true
|
||||
}).then(response => {
|
||||
this.accounts = response.listaccountsresponse.account
|
||||
|
|
@ -297,6 +309,7 @@ export default {
|
|||
this.formLoading = true
|
||||
api('listProjects', {
|
||||
domainid: e,
|
||||
showicon: true,
|
||||
details: 'min'
|
||||
}).then(response => {
|
||||
this.projects = response.listprojectsresponse.project
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@
|
|||
:pagination="false"
|
||||
>
|
||||
<template slot="name" slot-scope="text, item">
|
||||
<resource-icon v-if="item.icon" :image="item.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
<a-icon v-else type="apartment" style="margin-right: 5px"/>
|
||||
<router-link :to="{ path: '/guestnetwork/' + item.id }">
|
||||
{{ text }}
|
||||
</router-link>
|
||||
|
|
@ -75,11 +77,13 @@
|
|||
<script>
|
||||
import { api } from '@/api'
|
||||
import CreateNetwork from '@/views/network/CreateNetwork'
|
||||
import ResourceIcon from '@/components/view/ResourceIcon'
|
||||
|
||||
export default {
|
||||
name: 'IpRangesTabGuest',
|
||||
components: {
|
||||
CreateNetwork
|
||||
CreateNetwork,
|
||||
ResourceIcon
|
||||
},
|
||||
props: {
|
||||
resource: {
|
||||
|
|
@ -145,6 +149,7 @@ export default {
|
|||
api('listNetworks', {
|
||||
zoneid: this.resource.zoneid,
|
||||
physicalnetworkid: this.resource.id,
|
||||
showicon: true,
|
||||
page: this.page,
|
||||
pagesize: this.pageSize
|
||||
}).then(response => {
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue