diff --git a/api/src/com/cloud/api/ApiConstants.java b/api/src/com/cloud/api/ApiConstants.java index 4577f8ec778..f132b53fb07 100755 --- a/api/src/com/cloud/api/ApiConstants.java +++ b/api/src/com/cloud/api/ApiConstants.java @@ -86,6 +86,7 @@ public class ApiConstants { public static final String IS_PUBLIC = "ispublic"; public static final String IS_READY = "isready"; public static final String IS_RECURSIVE = "isrecursive"; + public static final String IS_SHARED = "isshared"; public static final String ISO_FILTER = "isofilter"; public static final String JOB_ID = "jobid"; public static final String JOB_STATUS = "jobstatus"; @@ -165,4 +166,11 @@ public class ApiConstants { public static final String NETWORK_TYPE = "networktype"; public static final String PAGE = "page"; public static final String PAGE_SIZE = "pagesize"; + public static final String TRAFFIC_TYPE = "traffictype"; + public static final String MAX_CONNECTIONS = "maxconnections"; + public static final String NETWORK_OFFERING_ID = "networkofferingid"; + public static final String NETWORK_IDS = "networkids"; + public static final String SPECIFY_VLAN = "specifyvlan"; + public static final String IS_DEFAULT = "isdefault"; } + diff --git a/api/src/com/cloud/api/ResponseGenerator.java b/api/src/com/cloud/api/ResponseGenerator.java index 7edfa10910c..75dad3250e8 100644 --- a/api/src/com/cloud/api/ResponseGenerator.java +++ b/api/src/com/cloud/api/ResponseGenerator.java @@ -40,6 +40,8 @@ import com.cloud.api.response.IpForwardingRuleResponse; import com.cloud.api.response.ListResponse; import com.cloud.api.response.LoadBalancerResponse; import com.cloud.api.response.NetworkGroupResponse; +import com.cloud.api.response.NetworkOfferingResponse; +import com.cloud.api.response.NetworkResponse; import com.cloud.api.response.PodResponse; import com.cloud.api.response.PreallocatedLunResponse; import com.cloud.api.response.RemoteAccessVpnResponse; @@ -69,6 +71,7 @@ import com.cloud.event.Event; import com.cloud.host.Host; import com.cloud.network.IpAddress; import com.cloud.network.LoadBalancer; +import com.cloud.network.Network; import com.cloud.network.RemoteAccessVpn; import com.cloud.network.VpnUser; import com.cloud.network.router.VirtualRouter; @@ -77,6 +80,7 @@ import com.cloud.network.security.IngressRule; import com.cloud.network.security.NetworkGroup; import com.cloud.network.security.NetworkGroupRules; import com.cloud.offering.DiskOffering; +import com.cloud.offering.NetworkOffering; import com.cloud.offering.ServiceOffering; import com.cloud.org.Cluster; import com.cloud.storage.Snapshot; @@ -201,5 +205,9 @@ public interface ResponseGenerator { TemplatePermissionsResponse createTemplatePermissionsResponse(List accountNames, Long id, boolean isAdmin); AsyncJobResponse queryJobResult(QueryAsyncJobResultCmd cmd); + + NetworkOfferingResponse createNetworkOfferingResponse(NetworkOffering offering); + + NetworkResponse createNetworkResponse(Network network); } diff --git a/api/src/com/cloud/api/commands/CreateNetworkCmd.java b/api/src/com/cloud/api/commands/CreateNetworkCmd.java new file mode 100644 index 00000000000..161605aea57 --- /dev/null +++ b/api/src/com/cloud/api/commands/CreateNetworkCmd.java @@ -0,0 +1,155 @@ +/** + * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. + * + * This software is licensed under the GNU General Public License v3 or later. + * + * It is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.cloud.api.commands; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +import com.cloud.api.BaseCmd; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.NetworkResponse; +import com.cloud.network.Network; + +@Implementation(description="Creates a network", responseObject=NetworkResponse.class) +public class CreateNetworkCmd extends BaseCmd { + public static final Logger s_logger = Logger.getLogger(CreateNetworkCmd.class.getName()); + + private static final String s_name = "createnetworkresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, required=true, description="the name of the network") + private String name; + + @Parameter(name=ApiConstants.DISPLAY_TEXT, type=CommandType.STRING, required=true, description="the display text of the network") + private String displayText; + + @Parameter(name=ApiConstants.NETWORK_OFFERING_ID, type=CommandType.LONG, required=true, description="the network offering id") + private Long networkOfferingId; + + @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.LONG, required=true, description="the Zone ID for the Vlan ip range") + private Long zoneId; + + @Parameter(name=ApiConstants.POD_ID, type=CommandType.LONG, description="the Pod ID for the Vlan ip range") + private Long podId; + + @Parameter(name=ApiConstants.GATEWAY, type=CommandType.STRING, description="the gateway of the VLAN IP range") + private String gateway; + + @Parameter(name=ApiConstants.CIDR, type=CommandType.STRING, description="the cidr of the VLAN IP range") + private String cidr; + + @Parameter(name=ApiConstants.NETMASK, type=CommandType.STRING, description="the netmask of the VLAN IP range") + private String netmask; + + @Parameter(name=ApiConstants.START_IP, type=CommandType.STRING, description="the beginning IP address in the VLAN IP range") + private String startIp; + + @Parameter(name=ApiConstants.END_IP, type=CommandType.STRING, description="the ending IP address in the VLAN IP range") + private String endIp; + + @Parameter(name=ApiConstants.VLAN, type=CommandType.STRING, description="the ID or VID of the VLAN. Default is an \"untagged\" VLAN.") + private String vlan; + + @Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, description="account who will own the VLAN. If VLAN is Zone wide, this parameter should be ommited") + private String accountName; + + @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, description="domain ID of the account owning a VLAN") + private Long domainId; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + public Long getNetworkOfferingId() { + return networkOfferingId; + } + + public Long getZoneId() { + return zoneId; + } + + public Long getPodId() { + return podId; + } + + public String getGateway() { + return gateway; + } + + public String getCidr() { + return cidr; + } + + public String getVlan() { + return vlan; + } + + public String getAccountName() { + return accountName; + } + + public Long getDomainId() { + return domainId; + } + + public String getNetmask() { + return netmask; + } + + public String getStartIp() { + return startIp; + } + + public String getEndIp() { + return endIp; + } + + public String getNetworkName() { + return name; + } + + public String getDisplayText() { + return displayText; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public String getName() { + return s_name; + } + + @Override + public void execute(){ + Network result = _networkService.createNetwork(this); + if (result != null) { + NetworkResponse response = _responseGenerator.createNetworkResponse(result); + response.setResponseName(getName()); + this.setResponseObject(response); + }else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to create network"); + } + } +} diff --git a/api/src/com/cloud/api/commands/CreateNetworkOfferingCmd.java b/api/src/com/cloud/api/commands/CreateNetworkOfferingCmd.java new file mode 100644 index 00000000000..64f9d59276b --- /dev/null +++ b/api/src/com/cloud/api/commands/CreateNetworkOfferingCmd.java @@ -0,0 +1,119 @@ +/** + * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. + * + * This software is licensed under the GNU General Public License v3 or later. + * + * It is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.cloud.api.commands; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +import com.cloud.api.BaseCmd; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.NetworkOfferingResponse; +import com.cloud.offering.NetworkOffering; + +@Implementation(description="Creates a network offering.", responseObject=NetworkOfferingResponse.class) +public class CreateNetworkOfferingCmd extends BaseCmd { + public static final Logger s_logger = Logger.getLogger(CreateNetworkOfferingCmd.class.getName()); + private static final String _name = "createnetworkofferingresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, required=true, description="the name of the network offering") + private String networkOfferingName; + + @Parameter(name=ApiConstants.DISPLAY_TEXT, type=CommandType.STRING, required=true, description="the display text of the network offering") + private String displayText; + + @Parameter(name=ApiConstants.TYPE, type=CommandType.STRING, required=true, description="type of the network. Supported types Virtualized, DirectSingle, DirectDual") + private String type; + + @Parameter(name=ApiConstants.TRAFFIC_TYPE, type=CommandType.STRING, required=true, description="the traffic type for the network offering, supported types are Public, Management, Control, Guest, Vlan or Storage.") + private String traffictype; + + @Parameter(name=ApiConstants.MAX_CONNECTIONS, type=CommandType.INTEGER, description="maximum number of concurrent connections supported by the network offering") + private Integer maxConnections; + + @Parameter(name=ApiConstants.TAGS, type=CommandType.STRING, description="the tags for the network offering.") + private String tags; + + @Parameter(name=ApiConstants.SPECIFY_VLAN, type=CommandType.BOOLEAN, description="true is network offering supports vlans") + private Boolean specifyVlan; + + @Parameter(name=ApiConstants.IS_SHARED, type=CommandType.BOOLEAN, description="true is network offering supports vlans") + private Boolean isShared; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public String getNetworkOfferingName() { + return networkOfferingName; + } + + public String getDisplayText() { + return displayText; + } + + public String getTags() { + return tags; + } + + public String getType() { + return type; + } + + public String getTraffictype() { + return traffictype; + } + + public Integer getMaxconnections() { + return maxConnections; + } + + public Boolean getSpecifyVlan() { + return specifyVlan; + } + + public Boolean getIsShared() { + return isShared; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + @Override + public String getName() { + return _name; + } + + @Override + public void execute(){ + NetworkOffering result = _configService.createNetworkOffering(this); + if (result != null) { + NetworkOfferingResponse response = _responseGenerator.createNetworkOfferingResponse(result); + response.setResponseName(getName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to create network offering"); + } + } +} diff --git a/api/src/com/cloud/api/commands/CreateSnapshotCmd.java b/api/src/com/cloud/api/commands/CreateSnapshotCmd.java index 94fddf93d17..5e54db27421 100644 --- a/api/src/com/cloud/api/commands/CreateSnapshotCmd.java +++ b/api/src/com/cloud/api/commands/CreateSnapshotCmd.java @@ -21,11 +21,12 @@ package com.cloud.api.commands; import org.apache.log4j.Logger; import com.cloud.api.ApiConstants; -import com.cloud.api.BaseAsyncCmd; +import com.cloud.api.BaseAsyncCreateCmd; import com.cloud.api.BaseCmd; import com.cloud.api.Implementation; import com.cloud.api.Parameter; import com.cloud.api.ServerApiException; +import com.cloud.api.BaseCmd.CommandType; import com.cloud.api.response.SnapshotResponse; import com.cloud.async.AsyncJob; import com.cloud.event.EventTypes; @@ -35,7 +36,7 @@ import com.cloud.storage.Volume; import com.cloud.user.Account; @Implementation(description="Creates an instant snapshot of a volume.", responseObject=SnapshotResponse.class) -public class CreateSnapshotCmd extends BaseAsyncCmd { +public class CreateSnapshotCmd extends BaseAsyncCreateCmd { public static final Logger s_logger = Logger.getLogger(CreateSnapshotCmd.class.getName()); private static final String s_name = "createsnapshotresponse"; @@ -52,6 +53,9 @@ public class CreateSnapshotCmd extends BaseAsyncCmd { @Parameter(name=ApiConstants.VOLUME_ID, type=CommandType.LONG, required=true, description="The ID of the disk volume") private Long volumeId; + @Parameter(name=ApiConstants.POLICY_ID, type=CommandType.LONG, description="polocy id of the snapshot, if this is null, then use MANUAL_POLICY.") + private Long policyId; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -67,6 +71,14 @@ public class CreateSnapshotCmd extends BaseAsyncCmd { public Long getVolumeId() { return volumeId; } + + public Long getPolicyId() { + if( policyId != null) { + return policyId; + } else { + return Snapshot.MANUAL_POLICY_ID; + } + } ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// @@ -106,6 +118,12 @@ public class CreateSnapshotCmd extends BaseAsyncCmd { return AsyncJob.Type.Snapshot; } + @Override + public void callCreate(){ + long id = _snapshotMgr.getNextInSequence(this); + this.setId(id); + } + @Override public void execute(){ try { diff --git a/api/src/com/cloud/api/commands/CreateSnapshotInternalCmd.java b/api/src/com/cloud/api/commands/CreateSnapshotInternalCmd.java deleted file mode 100644 index ff43ecd4966..00000000000 --- a/api/src/com/cloud/api/commands/CreateSnapshotInternalCmd.java +++ /dev/null @@ -1,131 +0,0 @@ -/** - * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. - * - * This software is licensed under the GNU General Public License v3 or later. - * - * It is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or any later version. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -package com.cloud.api.commands; - -import org.apache.log4j.Logger; - -import com.cloud.api.ApiConstants; -import com.cloud.api.BaseAsyncCmd; -import com.cloud.api.BaseCmd; -import com.cloud.api.Implementation; -import com.cloud.api.Parameter; -import com.cloud.api.ServerApiException; -import com.cloud.api.response.SnapshotResponse; -import com.cloud.domain.Domain; -import com.cloud.event.EventTypes; -import com.cloud.exception.ResourceAllocationException; -import com.cloud.storage.Snapshot; -import com.cloud.storage.Snapshot.Type; -import com.cloud.storage.Volume; -import com.cloud.user.Account; - -@Implementation(description="Creates an instant snapshot of a volume.", responseObject=SnapshotResponse.class) -public class CreateSnapshotInternalCmd extends BaseAsyncCmd { - public static final Logger s_logger = Logger.getLogger(CreateSnapshotInternalCmd.class.getName()); - private static final String s_name = "createsnapshotresponse"; - - ///////////////////////////////////////////////////// - //////////////// API parameters ///////////////////// - ///////////////////////////////////////////////////// - - @Parameter(name=ApiConstants.POLICY_ID, type=CommandType.LONG) - private Long policyId; - - @Parameter(name=ApiConstants.VOLUME_ID, type=CommandType.LONG, required=true) - private Long volumeId; - - ///////////////////////////////////////////////////// - /////////////////// Accessors /////////////////////// - ///////////////////////////////////////////////////// - - public Long getPolicyId() { - return policyId; - } - - public Long getVolumeId() { - return volumeId; - } - - ///////////////////////////////////////////////////// - /////////////// API Implementation/////////////////// - ///////////////////////////////////////////////////// - - @Override - public String getName() { - return s_name; - } - - public static String getResultObjectName() { - return "snapshot"; - } - - @Override - public long getAccountId() { - Volume volume = _entityMgr.findById(Volume.class, getVolumeId()); - if (volume != null) { - return volume.getAccountId(); - } - - // bad id given, parent this command to SYSTEM so ERROR events are tracked - return Account.ACCOUNT_ID_SYSTEM; - } - - @Override - public String getEventType() { - return EventTypes.EVENT_SNAPSHOT_CREATE; - } - - @Override - public String getEventDescription() { - return "creating snapshot for volume: " + getVolumeId(); - } - - @Override - public void execute(){ - try { - Snapshot snapshot = _snapshotMgr.createSnapshotInternal(this); - if (snapshot != null) { - SnapshotResponse response = new SnapshotResponse(); - response.setId(snapshot.getId()); - - Account account = _entityMgr.findById(Account.class, snapshot.getAccountId()); - if (account != null) { - response.setAccountName(account.getAccountName()); - response.setDomainId(account.getDomainId()); - response.setDomainName(_entityMgr.findById(Domain.class, account.getDomainId()).getName()); - } - - Volume volume = _entityMgr.findById(Volume.class, snapshot.getVolumeId()); - String snapshotTypeStr = Type.values()[snapshot.getSnapshotType()].name(); - response.setSnapshotType(snapshotTypeStr); - response.setVolumeId(snapshot.getVolumeId()); - response.setVolumeName(volume.getName()); - response.setVolumeType(volume.getVolumeType().toString()); - response.setCreated(snapshot.getCreated()); - response.setName(snapshot.getName()); - response.setObjectName("snapshot"); - response.setResponseName(getName()); - this.setResponseObject(response); - } else { - throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to create snapshot"); - } - } catch (ResourceAllocationException ex) { - throw new ServerApiException(BaseCmd.RESOURCE_ALLOCATION_ERROR, ex.getMessage()); - } - } -} diff --git a/api/src/com/cloud/api/commands/CreateVlanIpRangeCmd.java b/api/src/com/cloud/api/commands/CreateVlanIpRangeCmd.java index 420c2b215e3..04dfa5fb806 100644 --- a/api/src/com/cloud/api/commands/CreateVlanIpRangeCmd.java +++ b/api/src/com/cloud/api/commands/CreateVlanIpRangeCmd.java @@ -49,8 +49,8 @@ public class CreateVlanIpRangeCmd extends BaseCmd { @Parameter(name=ApiConstants.END_IP, type=CommandType.STRING, description="the ending IP address in the VLAN IP range") private String endIp; - @Parameter(name=ApiConstants.FOR_VIRTUAL_NETWORK, type=CommandType.BOOLEAN, description="true if VLAN is of Virtual type, false if Direct") - private Boolean forVirtualNetwork; +// @Parameter(name=ApiConstants.FOR_VIRTUAL_NETWORK, type=CommandType.BOOLEAN, description="true if VLAN is of Virtual type, false if Direct") +// private Boolean forVirtualNetwork; @Parameter(name=ApiConstants.GATEWAY, type=CommandType.STRING, required=true, description="the gateway of the VLAN IP range") private String gateway; @@ -86,9 +86,9 @@ public class CreateVlanIpRangeCmd extends BaseCmd { return endIp; } - public Boolean isForVirtualNetwork() { - return forVirtualNetwork; - } +// public Boolean isForVirtualNetwork() { +// return forVirtualNetwork; +// } public String getGateway() { return gateway; diff --git a/api/src/com/cloud/api/commands/DeleteNetworkCmd.java b/api/src/com/cloud/api/commands/DeleteNetworkCmd.java new file mode 100644 index 00000000000..1291fbe71c2 --- /dev/null +++ b/api/src/com/cloud/api/commands/DeleteNetworkCmd.java @@ -0,0 +1,71 @@ +/** + * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. + * + * This software is licensed under the GNU General Public License v3 or later. + * + * It is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.cloud.api.commands; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +import com.cloud.api.BaseCmd; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.SuccessResponse; + +@Implementation(description="Deletes a network", responseObject=SuccessResponse.class) +public class DeleteNetworkCmd extends BaseCmd{ + public static final Logger s_logger = Logger.getLogger(DeleteNetworkOfferingCmd.class.getName()); + private static final String s_name = "deletenetworkresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name=ApiConstants.ID, type=CommandType.LONG, required=true, description="the ID of the network") + private Long id; + + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public Long getId() { + return id; + } + + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public String getName() { + return s_name; + } + + @Override + public void execute(){ + boolean result = _networkService.deleteNetwork(this); + if (result) { + SuccessResponse response = new SuccessResponse(getName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to delete network"); + } + } +} diff --git a/api/src/com/cloud/api/commands/DeleteNetworkOfferingCmd.java b/api/src/com/cloud/api/commands/DeleteNetworkOfferingCmd.java new file mode 100644 index 00000000000..9719f14badc --- /dev/null +++ b/api/src/com/cloud/api/commands/DeleteNetworkOfferingCmd.java @@ -0,0 +1,71 @@ +/** + * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. + * + * This software is licensed under the GNU General Public License v3 or later. + * + * It is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.cloud.api.commands; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +import com.cloud.api.BaseCmd; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.SuccessResponse; + +@Implementation(description="Deletes a network offering.", responseObject=SuccessResponse.class) +public class DeleteNetworkOfferingCmd extends BaseCmd{ + public static final Logger s_logger = Logger.getLogger(DeleteNetworkOfferingCmd.class.getName()); + private static final String s_name = "deletenetworkofferingresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name=ApiConstants.ID, type=CommandType.LONG, required=true, description="the ID of the network offering") + private Long id; + + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public Long getId() { + return id; + } + + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public String getName() { + return s_name; + } + + @Override + public void execute(){ + boolean result = _configService.deleteNetworkOffering(this); + if (result) { + SuccessResponse response = new SuccessResponse(getName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to delete service offering"); + } + } +} diff --git a/api/src/com/cloud/api/commands/DeployVMCmd.java b/api/src/com/cloud/api/commands/DeployVMCmd.java index 489708c674d..c1b4221c664 100644 --- a/api/src/com/cloud/api/commands/DeployVMCmd.java +++ b/api/src/com/cloud/api/commands/DeployVMCmd.java @@ -84,6 +84,9 @@ public class DeployVMCmd extends BaseAsyncCmd { @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.LONG, required=true, description="availability zone for the virtual machine") private Long zoneId; + + @Parameter(name=ApiConstants.NETWORK_IDS, type=CommandType.LIST, collectionType=CommandType.LONG) + private List networkIds; // unexposed parameter needed for serializing/deserializing the command @Parameter(name=ApiConstants.PASSWORD, type=CommandType.STRING, expose=false) @@ -149,11 +152,19 @@ public class DeployVMCmd extends BaseAsyncCmd { public void setPassword(String password) { this.password = password; } + + public List getNetworkIds() { + return networkIds; + } + + public void setNetworkList(List networkIds) { + this.networkIds = networkIds; + } ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// - + @Override public String getName() { return s_name; @@ -216,12 +227,16 @@ public class DeployVMCmd extends BaseAsyncCmd { throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to deploy vm"); } } catch (ResourceAllocationException ex) { + s_logger.warn("Exception: ", ex); throw new ServerApiException(BaseCmd.RESOURCE_ALLOCATION_ERROR, ex.getMessage()); } catch (InsufficientStorageCapacityException ex) { + s_logger.warn("Exception: ", ex); throw new ServerApiException(BaseCmd.INSUFFICIENT_CAPACITY_ERROR, ex.getMessage()); } catch (StorageUnavailableException ex) { + s_logger.warn("Exception: ", ex); throw new ServerApiException(BaseCmd.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage()); } catch (Exception ex) { + s_logger.warn("Exception: ", ex); throw new ServerApiException(BaseCmd.INTERNAL_ERROR, ex.getMessage()); } } diff --git a/api/src/com/cloud/api/commands/ListIpForwardingRulesCmd.java b/api/src/com/cloud/api/commands/ListIpForwardingRulesCmd.java index 22cdf646b7d..a371a48c822 100644 --- a/api/src/com/cloud/api/commands/ListIpForwardingRulesCmd.java +++ b/api/src/com/cloud/api/commands/ListIpForwardingRulesCmd.java @@ -26,6 +26,7 @@ import com.cloud.api.ApiConstants; import com.cloud.api.BaseListCmd; import com.cloud.api.Implementation; import com.cloud.api.Parameter; +import com.cloud.api.BaseCmd.CommandType; import com.cloud.api.response.FirewallRuleResponse; import com.cloud.api.response.IpForwardingRuleResponse; import com.cloud.api.response.ListResponse; @@ -44,6 +45,12 @@ public class ListIpForwardingRulesCmd extends BaseListCmd { @Parameter(name=ApiConstants.IP_ADDRESS, type=CommandType.STRING, description="list the rule belonging to this public ip address") private String publicIpAddress; + @Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, description="the account associated with the ip forwarding rule. Must be used with the domainId parameter.") + private String accountName; + + @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, description="Lists all rules for this id. If used with the account parameter, returns all rules for an account in the specified domain ID.") + private Long domainId; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -65,6 +72,14 @@ public class ListIpForwardingRulesCmd extends BaseListCmd { this.publicIpAddress = publicIpAddress; } + public String getAccountName() { + return accountName; + } + + public Long getDomainId() { + return domainId; + } + @Override public void execute(){ List result = _mgr.searchForIpForwardingRules(this); diff --git a/api/src/com/cloud/api/commands/ListNetworkOfferingsCmd.java b/api/src/com/cloud/api/commands/ListNetworkOfferingsCmd.java new file mode 100644 index 00000000000..563fd6ec1ee --- /dev/null +++ b/api/src/com/cloud/api/commands/ListNetworkOfferingsCmd.java @@ -0,0 +1,125 @@ +/** + * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. + * + * This software is licensed under the GNU General Public License v3 or later. + * + * It is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.cloud.api.commands; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +import com.cloud.api.BaseListCmd; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.response.ListResponse; +import com.cloud.api.response.NetworkOfferingResponse; +import com.cloud.offering.NetworkOffering; + + +@Implementation(description="Lists all available network offerings.", responseObject=NetworkOfferingResponse.class) +public class ListNetworkOfferingsCmd extends BaseListCmd { + public static final Logger s_logger = Logger.getLogger(ListNetworkOfferingsCmd.class.getName()); + private static final String _name = "listnetworkofferingsresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + @Parameter(name=ApiConstants.ID, type=CommandType.LONG, description="list network offerings by id") + private Long id; + + @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, description="list network offerings by name") + private String networkOfferingName; + + @Parameter(name=ApiConstants.DISPLAY_TEXT, type=CommandType.STRING, description="list network offerings by display text") + private String displayText; + + @Parameter(name=ApiConstants.TYPE, type=CommandType.STRING, description="list by type of the network") + private String type; + + @Parameter(name=ApiConstants.TRAFFIC_TYPE, type=CommandType.STRING, description="list by traffic type") + private String trafficType; + + @Parameter(name=ApiConstants.IS_DEFAULT, type=CommandType.BOOLEAN, description="true if need to list only default network offerings. Default value is false") + private Boolean isDefault; + + @Parameter(name=ApiConstants.SPECIFY_VLAN, type=CommandType.BOOLEAN, description="the tags for the network offering.") + private Boolean specifyVlan; + + @Parameter(name=ApiConstants.IS_SHARED, type=CommandType.BOOLEAN, description="true is network offering supports vlans") + private Boolean isShared; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public String getNetworkOfferingName() { + return networkOfferingName; + } + + public String getDisplayText() { + return displayText; + } + + public String getType() { + return type; + } + + public String getTrafficType() { + return trafficType; + } + + public Long getId() { + return id; + } + + public Boolean getIsDefault() { + return isDefault; + } + + public Boolean getSpecifyVlan() { + return specifyVlan; + } + + public Boolean getIsShared() { + return isShared; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + @Override + public String getName() { + return _name; + } + + @Override + public void execute(){ + List offerings = _configService.searchForNetworkOfferings(this); + ListResponse response = new ListResponse(); + List offeringResponses = new ArrayList(); + for (NetworkOffering offering : offerings) { + NetworkOfferingResponse offeringResponse = _responseGenerator.createNetworkOfferingResponse(offering); + offeringResponses.add(offeringResponse); + } + + response.setResponses(offeringResponses); + response.setResponseName(getName()); + this.setResponseObject(response); + } +} diff --git a/api/src/com/cloud/api/commands/ListNetworksCmd.java b/api/src/com/cloud/api/commands/ListNetworksCmd.java new file mode 100644 index 00000000000..4cb95e9516f --- /dev/null +++ b/api/src/com/cloud/api/commands/ListNetworksCmd.java @@ -0,0 +1,89 @@ +/** + * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. + * + * This software is licensed under the GNU General Public License v3 or later. + * + * It is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.cloud.api.commands; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +import com.cloud.api.BaseListCmd; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.response.ListResponse; +import com.cloud.api.response.NetworkResponse; +import com.cloud.network.Network; + + +@Implementation(description="Lists all available networks.", responseObject=NetworkResponse.class) +public class ListNetworksCmd extends BaseListCmd { + public static final Logger s_logger = Logger.getLogger(ListNetworksCmd.class.getName()); + private static final String _name = "listnetworksresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + @Parameter(name=ApiConstants.ID, type=CommandType.LONG, description="list networks by id") + private Long id; + + @Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, description="account who will own the VLAN. If VLAN is Zone wide, this parameter should be ommited") + private String accountName; + + @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, description="domain ID of the account owning a VLAN") + private Long domainId; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public Long getId() { + return id; + } + + public String getAccountName() { + return accountName; + } + + public Long getDomainId() { + return domainId; + } + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + @Override + public String getName() { + return _name; + } + + @Override + public void execute(){ + List networks = _networkService.searchForNetworks(this); + ListResponse response = new ListResponse(); + List networkResponses = new ArrayList(); + for (Network network : networks) { + NetworkResponse networkResponse = _responseGenerator.createNetworkResponse(network); + networkResponses.add(networkResponse); + } + + response.setResponses(networkResponses); + response.setResponseName(getName()); + this.setResponseObject(response); + } +} diff --git a/api/src/com/cloud/api/commands/ListSnapshotsCmd.java b/api/src/com/cloud/api/commands/ListSnapshotsCmd.java index 0469c706094..f7bb87a57fe 100644 --- a/api/src/com/cloud/api/commands/ListSnapshotsCmd.java +++ b/api/src/com/cloud/api/commands/ListSnapshotsCmd.java @@ -109,7 +109,7 @@ public class ListSnapshotsCmd extends BaseListCmd { @Override public void execute(){ - List result = _mgr.listSnapshots(this); + List result = _snapshotMgr.listSnapshots(this); ListResponse response = new ListResponse(); List snapshotResponses = new ArrayList(); for (Snapshot snapshot : result) { diff --git a/api/src/com/cloud/api/commands/StartVMCmd.java b/api/src/com/cloud/api/commands/StartVMCmd.java index cc77fe1fd6b..e1ea9c54649 100644 --- a/api/src/com/cloud/api/commands/StartVMCmd.java +++ b/api/src/com/cloud/api/commands/StartVMCmd.java @@ -110,10 +110,13 @@ public class StartVMCmd extends BaseAsyncCmd { throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to start a vm"); } }catch (ConcurrentOperationException ex) { + s_logger.warn("Exception: ", ex); throw new ServerApiException(BaseCmd.INTERNAL_ERROR, ex.getMessage()); }catch (StorageUnavailableException ex) { + s_logger.warn("Exception: ", ex); throw new ServerApiException(BaseCmd.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage()); }catch (ExecutionException ex) { + s_logger.warn("Exception: ", ex); throw new ServerApiException(BaseCmd.INTERNAL_ERROR, ex.getMessage()); } } diff --git a/api/src/com/cloud/api/response/DomainRouterResponse.java b/api/src/com/cloud/api/response/DomainRouterResponse.java index 54af0bed0ea..122033da668 100644 --- a/api/src/com/cloud/api/response/DomainRouterResponse.java +++ b/api/src/com/cloud/api/response/DomainRouterResponse.java @@ -18,6 +18,7 @@ package com.cloud.api.response; import java.util.Date; +import java.util.List; import com.cloud.api.ApiConstants; import com.cloud.serializer.Param; @@ -107,6 +108,9 @@ public class DomainRouterResponse extends BaseResponse { return getId(); } + @SerializedName("nics") @Param(description="the list of nics associated with domain router") + private List nics; + public Long getId() { return id; } @@ -314,4 +318,12 @@ public class DomainRouterResponse extends BaseResponse { public void setDomainName(String domainName) { this.domainName = domainName; } + + public List getNics() { + return nics; + } + + public void setNics(List nics) { + this.nics = nics; + } } diff --git a/api/src/com/cloud/api/response/IpForwardingRuleResponse.java b/api/src/com/cloud/api/response/IpForwardingRuleResponse.java index 45aaa6e0e4d..feae3d89a99 100644 --- a/api/src/com/cloud/api/response/IpForwardingRuleResponse.java +++ b/api/src/com/cloud/api/response/IpForwardingRuleResponse.java @@ -25,15 +25,9 @@ public class IpForwardingRuleResponse extends BaseResponse { @SerializedName(ApiConstants.ID) @Param(description="the ID of the port forwarding rule") private Long id; - @SerializedName(ApiConstants.PRIVATE_PORT) @Param(description="the private port for the port forwarding rule") - private String privatePort; - @SerializedName(ApiConstants.PROTOCOL) @Param(description="the protocol of the port forwarding rule") private String protocol; - @SerializedName(ApiConstants.PUBLIC_PORT) @Param(description="the public port for the port forwarding rule") - private String publicPort; - @SerializedName(ApiConstants.VIRTUAL_MACHINE_ID) @Param(description="the VM ID for the port forwarding rule") private Long virtualMachineId; @@ -54,14 +48,6 @@ public class IpForwardingRuleResponse extends BaseResponse { this.id = id; } - public String getPrivatePort() { - return privatePort; - } - - public void setPrivatePort(String privatePort) { - this.privatePort = privatePort; - } - public String getProtocol() { return protocol; } @@ -70,14 +56,6 @@ public class IpForwardingRuleResponse extends BaseResponse { this.protocol = protocol; } - public String getPublicPort() { - return publicPort; - } - - public void setPublicPort(String publicPort) { - this.publicPort = publicPort; - } - public Long getVirtualMachineId() { return virtualMachineId; } diff --git a/api/src/com/cloud/api/response/NetworkOfferingResponse.java b/api/src/com/cloud/api/response/NetworkOfferingResponse.java new file mode 100644 index 00000000000..ded3bc6775f --- /dev/null +++ b/api/src/com/cloud/api/response/NetworkOfferingResponse.java @@ -0,0 +1,137 @@ +package com.cloud.api.response; + +import java.util.Date; + +import com.cloud.serializer.Param; +import com.google.gson.annotations.SerializedName; + +public class NetworkOfferingResponse extends BaseResponse{ + @SerializedName("id") @Param(description="the id of the network offering") + private Long id; + + @SerializedName("name") @Param(description="the name of the network offering") + private String name; + + @SerializedName("displaytext") @Param(description="an alternate display text of the network offering.") + private String displayText; + + @SerializedName("tags") @Param(description="the tags for the network offering") + private String tags; + + @SerializedName("created") @Param(description="the date this network offering was created") + private Date created; + + @SerializedName("maxconnections") @Param(description="the max number of concurrent connection the network offering supports") + private Integer maxConnections; + + @SerializedName("type") @Param(description="type of the network. Supported types are Virtualized, DirectSingle, DirectDual") + private String type; + + @SerializedName("traffictype") @Param(description="the traffic type for the network offering, supported types are Public, Management, Control, Guest, Vlan or Storage.") + private String trafficType; + + @SerializedName("isdefault") @Param(description="true if network offering is default, false otherwise") + private Boolean isDefault; + + @SerializedName("isshared") @Param(description="true if network offering is shared, false otherwise") + private Boolean isShared; + + @SerializedName("specifyvlan") @Param(description="true if network offering supports vlans, false otherwise") + private Boolean specifyVlan; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDisplayText() { + return displayText; + } + + public void setDisplayText(String displayText) { + this.displayText = displayText; + } + + public String getTags() { + return tags; + } + + public void setTags(String tags) { + this.tags = tags; + } + + public Date getCreated() { + return created; + } + + public void setCreated(Date created) { + this.created = created; + } + + public Integer getMaxconnections() { + return maxConnections; + } + + public void setMaxconnections(Integer maxConnections) { + this.maxConnections = maxConnections; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getTrafficType() { + return trafficType; + } + + public void setTrafficType(String trafficType) { + this.trafficType = trafficType; + } + + public Boolean getIsDefault() { + return isDefault; + } + + public void setIsDefault(Boolean isDefault) { + this.isDefault = isDefault; + } + + public Integer getMaxConnections() { + return maxConnections; + } + + public void setMaxConnections(Integer maxConnections) { + this.maxConnections = maxConnections; + } + + public Boolean getSpecifyVlan() { + return specifyVlan; + } + + public void setSpecifyVlan(Boolean specifyVlan) { + this.specifyVlan = specifyVlan; + } + + public Boolean getIsShared() { + return isShared; + } + + public void setIsShared(Boolean isShared) { + this.isShared = isShared; + } +} diff --git a/api/src/com/cloud/api/response/NetworkResponse.java b/api/src/com/cloud/api/response/NetworkResponse.java new file mode 100644 index 00000000000..8da95663ac0 --- /dev/null +++ b/api/src/com/cloud/api/response/NetworkResponse.java @@ -0,0 +1,231 @@ +package com.cloud.api.response; + +import com.cloud.api.ApiConstants; +import com.cloud.serializer.Param; +import com.google.gson.annotations.SerializedName; + +public class NetworkResponse extends BaseResponse{ + + @SerializedName("id") @Param(description="the id of the network") + private Long id; + + @SerializedName("name") @Param(description="the name of the network") + private String name; + + @SerializedName("displaytext") @Param(description="the displaytext of the network") + private String displaytext; + + //TODO - add description + @SerializedName("broadcastdomaintype") + private String broadcastDomainType; + + //TODO - add description + @SerializedName("traffictype") + private String trafficType; + + //TODO - add description + @SerializedName("gateway") + private String gateway; + + //TODO - add description + @SerializedName("cidr") + private String cidr; + + //TODO - add description + @SerializedName("zoneid") + private Long zoneId; + + //TODO - add description + @SerializedName("networkofferingid") + private Long networkOfferingId; + + //TODO - add description + @SerializedName("networkofferingname") + private String networkOfferingName; + + //TODO - add description + @SerializedName("networkofferingdisplaytext") + private String networkOfferingDisplayText; + + //TODO - add description + @SerializedName("state") + private String state; + + //TODO - add description + @SerializedName("related") + private Long related; + + //TODO - add description + @SerializedName("broadcasturi") + private String broadcastUri; + + //TODO - add description + @SerializedName("dns1") + private String dns1; + + //TODO - add description + @SerializedName("dns2") + private String dns2; + + //TODO - add description + @SerializedName("type") + private String type; + + @SerializedName(ApiConstants.ACCOUNT) @Param(description="the account associated with the network") + private String accountName; + + @SerializedName(ApiConstants.DOMAIN_ID) @Param(description="the domain id associated with the network") + private Long domainId; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getBroadcastDomainType() { + return broadcastDomainType; + } + + public void setBroadcastDomainType(String broadcastDomainType) { + this.broadcastDomainType = broadcastDomainType; + } + + public String getTrafficType() { + return trafficType; + } + + public void setTrafficType(String trafficType) { + this.trafficType = trafficType; + } + + public String getGateway() { + return gateway; + } + + public void setGateway(String gateway) { + this.gateway = gateway; + } + + public String getCidr() { + return cidr; + } + + public void setCidr(String cidr) { + this.cidr = cidr; + } + + public Long getZoneId() { + return zoneId; + } + + public void setZoneId(Long zoneId) { + this.zoneId = zoneId; + } + + public Long getNetworkOfferingId() { + return networkOfferingId; + } + + public void setNetworkOfferingId(Long networkOfferingId) { + this.networkOfferingId = networkOfferingId; + } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + public Long getRelated() { + return related; + } + + public void setRelated(Long related) { + this.related = related; + } + + public String getBroadcastUri() { + return broadcastUri; + } + + public void setBroadcastUri(String broadcastUri) { + this.broadcastUri = broadcastUri; + } + + public String getDns1() { + return dns1; + } + + public void setDns1(String dns1) { + this.dns1 = dns1; + } + + public String getDns2() { + return dns2; + } + + public void setDns2(String dns2) { + this.dns2 = dns2; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getAccountName() { + return accountName; + } + + public void setAccountName(String accountName) { + this.accountName = accountName; + } + + public Long getDomainId() { + return domainId; + } + + public void setDomainId(Long domainId) { + this.domainId = domainId; + } + + public String getNetworkOfferingName() { + return networkOfferingName; + } + + public void setNetworkOfferingName(String networkOfferingName) { + this.networkOfferingName = networkOfferingName; + } + + public String getNetworkOfferingDisplayText() { + return networkOfferingDisplayText; + } + + public void setNetworkOfferingDisplayText(String networkOfferingDisplayText) { + this.networkOfferingDisplayText = networkOfferingDisplayText; + } + + public String getDisplaytext() { + return displaytext; + } + + public void setDisplaytext(String displaytext) { + this.displaytext = displaytext; + } +} diff --git a/api/src/com/cloud/api/response/NicResponse.java b/api/src/com/cloud/api/response/NicResponse.java new file mode 100644 index 00000000000..97eb5a822f9 --- /dev/null +++ b/api/src/com/cloud/api/response/NicResponse.java @@ -0,0 +1,101 @@ +/** + * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. + * + * This software is licensed under the GNU General Public License v3 or later. + * + * It is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +package com.cloud.api.response; + +import com.cloud.serializer.Param; +import com.google.gson.annotations.SerializedName; + +public class NicResponse extends BaseResponse { + + @SerializedName("id") @Param(description="the ID of the nic") + private Long id; + + @SerializedName("networkid") @Param(description="the ID of the corresponding network") + private Long networkid; + + @SerializedName("netmask") @Param(description="the netmask of the nic") + private String netmask; + + @SerializedName("gateway") @Param(description="the gateway of the nic") + private String gateway; + + @SerializedName("ipaddress") @Param(description="the ip address of the nic") + private String ipaddress; + + @SerializedName("isolationuri") @Param(description="the isolation uri of the nic") + private String isolationUri; + + @SerializedName("broadcasturi") @Param(description="the broadcast uri of the nic") + private String broadcastUri; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Long getNetworkid() { + return networkid; + } + + public void setNetworkid(Long networkid) { + this.networkid = networkid; + } + + public String getNetmask() { + return netmask; + } + + public void setNetmask(String netmask) { + this.netmask = netmask; + } + + public String getGateway() { + return gateway; + } + + public void setGateway(String gateway) { + this.gateway = gateway; + } + + public String getIpaddress() { + return ipaddress; + } + + public void setIpaddress(String ipaddress) { + this.ipaddress = ipaddress; + } + + public String getIsolationUri() { + return isolationUri; + } + + public void setIsolationUri(String isolationUri) { + this.isolationUri = isolationUri; + } + + public String getBroadcastUri() { + return broadcastUri; + } + + public void setBroadcastUri(String broadcastUri) { + this.broadcastUri = broadcastUri; + } +} diff --git a/api/src/com/cloud/api/response/SystemVmResponse.java b/api/src/com/cloud/api/response/SystemVmResponse.java index a24fd0b5bab..3b34066f4fe 100644 --- a/api/src/com/cloud/api/response/SystemVmResponse.java +++ b/api/src/com/cloud/api/response/SystemVmResponse.java @@ -18,6 +18,7 @@ package com.cloud.api.response; import java.util.Date; +import java.util.List; import com.cloud.serializer.Param; import com.google.gson.annotations.SerializedName; @@ -99,6 +100,9 @@ public class SystemVmResponse extends BaseResponse { return getId(); } + @SerializedName("nics") @Param(description="the list of nics associated with system vm") + private List nics; + public Long getId() { return id; } @@ -290,4 +294,12 @@ public class SystemVmResponse extends BaseResponse { public void setActiveViewerSessions(Integer activeViewerSessions) { this.activeViewerSessions = activeViewerSessions; } + + public List getNics() { + return nics; + } + + public void setNics(List nics) { + this.nics = nics; + } } diff --git a/api/src/com/cloud/api/response/UserVmResponse.java b/api/src/com/cloud/api/response/UserVmResponse.java index e06ec3c1a1a..2dbc3272f27 100644 --- a/api/src/com/cloud/api/response/UserVmResponse.java +++ b/api/src/com/cloud/api/response/UserVmResponse.java @@ -18,6 +18,7 @@ package com.cloud.api.response; import java.util.Date; +import java.util.List; import com.cloud.api.ApiConstants; import com.cloud.serializer.Param; @@ -144,6 +145,9 @@ public class UserVmResponse extends BaseResponse { public Long getObjectId() { return getId(); } + + @SerializedName("nics") @Param(description="the list of nics associated with vm") + private List nics; public Long getId() { return id; @@ -456,4 +460,12 @@ public class UserVmResponse extends BaseResponse { public void setForVirtualNetwork(Boolean forVirtualNetwork) { this.forVirtualNetwork = forVirtualNetwork; } + + public List getNics() { + return nics; + } + + public void setNics(List nics) { + this.nics = nics; + } } diff --git a/api/src/com/cloud/api/response/VlanIpRangeResponse.java b/api/src/com/cloud/api/response/VlanIpRangeResponse.java index 6fe2d236119..7fbb9bf3f99 100644 --- a/api/src/com/cloud/api/response/VlanIpRangeResponse.java +++ b/api/src/com/cloud/api/response/VlanIpRangeResponse.java @@ -62,6 +62,9 @@ public class VlanIpRangeResponse extends BaseResponse { @SerializedName("endip") @Param(description="the end ip of the VLAN IP range") private String endIp; + + @SerializedName("networkid") @Param(description="the network id of vlan range") + private Long networkId; public Long getId() { return id; @@ -174,4 +177,12 @@ public class VlanIpRangeResponse extends BaseResponse { public void setEndIp(String endIp) { this.endIp = endIp; } + + public Long getNetworkId() { + return networkId; + } + + public void setNetworkId(Long networkId) { + this.networkId = networkId; + } } diff --git a/api/src/com/cloud/configuration/ConfigurationService.java b/api/src/com/cloud/configuration/ConfigurationService.java index 310cb2f2fd1..f651cdce577 100644 --- a/api/src/com/cloud/configuration/ConfigurationService.java +++ b/api/src/com/cloud/configuration/ConfigurationService.java @@ -1,16 +1,21 @@ package com.cloud.configuration; +import java.util.List; + import com.cloud.api.commands.CreateCfgCmd; import com.cloud.api.commands.CreateDiskOfferingCmd; +import com.cloud.api.commands.CreateNetworkOfferingCmd; import com.cloud.api.commands.CreatePodCmd; import com.cloud.api.commands.CreateServiceOfferingCmd; import com.cloud.api.commands.CreateVlanIpRangeCmd; import com.cloud.api.commands.CreateZoneCmd; import com.cloud.api.commands.DeleteDiskOfferingCmd; +import com.cloud.api.commands.DeleteNetworkOfferingCmd; import com.cloud.api.commands.DeletePodCmd; import com.cloud.api.commands.DeleteServiceOfferingCmd; import com.cloud.api.commands.DeleteVlanIpRangeCmd; import com.cloud.api.commands.DeleteZoneCmd; +import com.cloud.api.commands.ListNetworkOfferingsCmd; import com.cloud.api.commands.UpdateCfgCmd; import com.cloud.api.commands.UpdateDiskOfferingCmd; import com.cloud.api.commands.UpdatePodCmd; @@ -23,6 +28,7 @@ import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.InvalidParameterValueException; import com.cloud.offering.DiskOffering; +import com.cloud.offering.NetworkOffering; import com.cloud.offering.ServiceOffering; public interface ConfigurationService { @@ -166,7 +172,14 @@ public interface ConfigurationService { * @throws * @return The new Vlan object */ - Vlan createVlanAndPublicIpRange(CreateVlanIpRangeCmd cmd) throws InsufficientCapacityException, ConcurrentOperationException; + Vlan createVlanAndPublicIpRange(CreateVlanIpRangeCmd cmd) throws InsufficientCapacityException, ConcurrentOperationException, InvalidParameterValueException; boolean deleteVlanIpRange(DeleteVlanIpRangeCmd cmd); + + NetworkOffering createNetworkOffering(CreateNetworkOfferingCmd cmd); + + List searchForNetworkOfferings(ListNetworkOfferingsCmd cmd); + + boolean deleteNetworkOffering(DeleteNetworkOfferingCmd cmd); + } diff --git a/api/src/com/cloud/dc/Vlan.java b/api/src/com/cloud/dc/Vlan.java index 5182310b250..588092f1dfa 100644 --- a/api/src/com/cloud/dc/Vlan.java +++ b/api/src/com/cloud/dc/Vlan.java @@ -43,5 +43,7 @@ public interface Vlan { public void setVlanType(VlanType ipRange); public VlanType getVlanType(); + + public Long getNetworkId(); } \ No newline at end of file diff --git a/api/src/com/cloud/event/EventTypes.java b/api/src/com/cloud/event/EventTypes.java index 8adf074e265..fd5b5ab16b0 100755 --- a/api/src/com/cloud/event/EventTypes.java +++ b/api/src/com/cloud/event/EventTypes.java @@ -132,6 +132,11 @@ public class EventTypes { public static final String EVENT_DISK_OFFERING_CREATE = "DISK.OFFERING.CREATE"; public static final String EVENT_DISK_OFFERING_EDIT = "DISK.OFFERING.EDIT"; public static final String EVENT_DISK_OFFERING_DELETE = "DISK.OFFERING.DELETE"; + + //Network offerings + public static final String EVENT_NETWORK_OFFERING_CREATE = "NETWORK.OFFERING.CREATE"; + public static final String EVENT_NETWORK_OFFERING_EDIT = "NETWORK.OFFERING.EDIT"; + public static final String EVENT_NETWORK_OFFERING_DELETE = "NETWORK.OFFERING.DELETE"; // Pods public static final String EVENT_POD_CREATE = "POD.CREATE"; diff --git a/api/src/com/cloud/network/Network.java b/api/src/com/cloud/network/Network.java index 2a250609247..d00f4d616d3 100644 --- a/api/src/com/cloud/network/Network.java +++ b/api/src/com/cloud/network/Network.java @@ -80,6 +80,8 @@ public interface Network extends ControlledEntity { * @return id of the network profile. Null means the network profile is not from the database. */ long getId(); + + String getName(); Mode getMode(); @@ -106,4 +108,6 @@ public interface Network extends ControlledEntity { String getDns2(); GuestIpType getGuestType(); + + String getDisplayText(); } diff --git a/api/src/com/cloud/network/NetworkService.java b/api/src/com/cloud/network/NetworkService.java index 0bc9dc0d5f6..04ad345671f 100644 --- a/api/src/com/cloud/network/NetworkService.java +++ b/api/src/com/cloud/network/NetworkService.java @@ -23,11 +23,14 @@ import com.cloud.api.commands.AddVpnUserCmd; import com.cloud.api.commands.AssignToLoadBalancerRuleCmd; import com.cloud.api.commands.AssociateIPAddrCmd; import com.cloud.api.commands.CreateLoadBalancerRuleCmd; +import com.cloud.api.commands.CreateNetworkCmd; import com.cloud.api.commands.CreatePortForwardingRuleCmd; import com.cloud.api.commands.CreateRemoteAccessVpnCmd; import com.cloud.api.commands.DeleteLoadBalancerRuleCmd; +import com.cloud.api.commands.DeleteNetworkCmd; import com.cloud.api.commands.DeleteRemoteAccessVpnCmd; import com.cloud.api.commands.DisassociateIPAddrCmd; +import com.cloud.api.commands.ListNetworksCmd; import com.cloud.api.commands.ListPortForwardingRulesCmd; import com.cloud.api.commands.RemoveFromLoadBalancerRuleCmd; import com.cloud.api.commands.RemoveVpnUserCmd; @@ -122,5 +125,9 @@ public interface NetworkService { boolean deleteIpForwardingRule(Long id); boolean deletePortForwardingRule(Long id, boolean sysContext); + + Network createNetwork(CreateNetworkCmd cmd) throws InvalidParameterValueException, PermissionDeniedException; + List searchForNetworks(ListNetworksCmd cmd) throws InvalidParameterValueException, PermissionDeniedException; + boolean deleteNetwork(DeleteNetworkCmd cmd) throws InvalidParameterValueException, PermissionDeniedException; } diff --git a/api/src/com/cloud/offering/NetworkOffering.java b/api/src/com/cloud/offering/NetworkOffering.java index 0b4f9e84b91..10ce22ad873 100644 --- a/api/src/com/cloud/offering/NetworkOffering.java +++ b/api/src/com/cloud/offering/NetworkOffering.java @@ -70,4 +70,10 @@ public interface NetworkOffering { TrafficType getTrafficType(); boolean getSpecifyVlan(); + + String getTags(); + + boolean isShared(); + + boolean isDefault(); } diff --git a/api/src/com/cloud/server/ManagementService.java b/api/src/com/cloud/server/ManagementService.java index 5199962fdd1..4ebb4769926 100644 --- a/api/src/com/cloud/server/ManagementService.java +++ b/api/src/com/cloud/server/ManagementService.java @@ -344,15 +344,6 @@ public interface ManagementService { */ List listCapacities(ListCapacityCmd cmd); - /** - * List all snapshots of a disk volume. Optionaly lists snapshots created by specified interval - * @param cmd the command containing the search criteria (order by, limit, etc.) - * @return list of snapshots - * @throws InvalidParameterValueException - * @throws PermissionDeniedException - */ - List listSnapshots(ListSnapshotsCmd cmd); - /** * List the permissions on a template. This will return a list of account names that have been granted permission to launch instances from the template. * @param cmd the command wrapping the search criteria (template id) diff --git a/api/src/com/cloud/storage/snapshot/SnapshotService.java b/api/src/com/cloud/storage/snapshot/SnapshotService.java index 52f7b43c089..004da20bff9 100644 --- a/api/src/com/cloud/storage/snapshot/SnapshotService.java +++ b/api/src/com/cloud/storage/snapshot/SnapshotService.java @@ -20,13 +20,14 @@ package com.cloud.storage.snapshot; import java.util.List; import com.cloud.api.commands.CreateSnapshotCmd; -import com.cloud.api.commands.CreateSnapshotInternalCmd; import com.cloud.api.commands.CreateSnapshotPolicyCmd; import com.cloud.api.commands.DeleteSnapshotCmd; import com.cloud.api.commands.DeleteSnapshotPoliciesCmd; import com.cloud.api.commands.ListRecurringSnapshotScheduleCmd; import com.cloud.api.commands.ListSnapshotPoliciesCmd; +import com.cloud.api.commands.ListSnapshotsCmd; import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceAllocationException; import com.cloud.storage.Snapshot; @@ -39,12 +40,13 @@ public interface SnapshotService { Snapshot createSnapshot(CreateSnapshotCmd cmd) throws InvalidParameterValueException, ResourceAllocationException; /** - * An internal method for creating recurring snapshots. The command is not exposed through the API but is used to hook into the async framework. - * @param cmd the command specifying volumeId and policyId - * @return the created snapshot - * @throws ResourceAllocationException + * List all snapshots of a disk volume. Optionally lists snapshots created by specified interval + * @param cmd the command containing the search criteria (order by, limit, etc.) + * @return list of snapshots + * @throws InvalidParameterValueException + * @throws PermissionDeniedException */ - Snapshot createSnapshotInternal(CreateSnapshotInternalCmd cmd) throws ResourceAllocationException; + List listSnapshots(ListSnapshotsCmd cmd); /** * Delete specified snapshot from the specified. @@ -76,5 +78,7 @@ public interface SnapshotService { List listPoliciesforVolume(ListSnapshotPoliciesCmd cmd); boolean deleteSnapshotPolicies(DeleteSnapshotPoliciesCmd cmd); + + long getNextInSequence(CreateSnapshotCmd cmd); } diff --git a/api/src/com/cloud/vm/Nic.java b/api/src/com/cloud/vm/Nic.java index 321a72a06ca..0576b553e6a 100644 --- a/api/src/com/cloud/vm/Nic.java +++ b/api/src/com/cloud/vm/Nic.java @@ -17,6 +17,8 @@ */ package com.cloud.vm; +import java.net.URI; + import com.cloud.network.Networks.Mode; import com.cloud.resource.Resource; @@ -48,4 +50,9 @@ public interface Nic extends Resource { int getDeviceId(); Mode getMode(); + + URI getIsolationUri(); + + URI getBroadcastUri(); + } diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in index 84b1f9af1cb..709d78b795b 100755 --- a/client/tomcatconf/commands.properties.in +++ b/client/tomcatconf/commands.properties.in @@ -230,3 +230,13 @@ listRemoteAccessVpns=com.cloud.api.commands.ListRemoteAccessVpnsCmd;15 addVpnUser=com.cloud.api.commands.AddVpnUserCmd;15 removeVpnUser=com.cloud.api.commands.RemoveVpnUserCmd;15 listVpnUsers=com.cloud.api.commands.ListVpnUsersCmd;15 + +#### network offering commands +createNetworkOffering=com.cloud.api.commands.CreateNetworkOfferingCmd;1 +deleteNetworkOffering=com.cloud.api.commands.DeleteNetworkOfferingCmd;1 +listNetworkOfferings=com.cloud.api.commands.ListNetworkOfferingsCmd;15 + +#### network commands +createNetwork=com.cloud.api.commands.CreateNetworkCmd;1 +deleteNetwork=com.cloud.api.commands.DeleteNetworkCmd;1 +listNetworks=com.cloud.api.commands.ListNetworksCmd;15 \ No newline at end of file diff --git a/core/src/com/cloud/agent/api/DeleteSnapshotsDirCommand.java b/core/src/com/cloud/agent/api/DeleteSnapshotsDirCommand.java index 2073019e61e..c9694d35c43 100644 --- a/core/src/com/cloud/agent/api/DeleteSnapshotsDirCommand.java +++ b/core/src/com/cloud/agent/api/DeleteSnapshotsDirCommand.java @@ -57,10 +57,10 @@ public class DeleteSnapshotsDirCommand extends SnapshotCommand { Long dcId, Long accountId, Long volumeId, - String snapshotUUID, - String snapshotName) + String volumePath) { - super(primaryStoragePoolNameLabel, secondaryStoragePoolURL, snapshotUUID, snapshotName, dcId, accountId, volumeId); + super(primaryStoragePoolNameLabel, secondaryStoragePoolURL, null, null, dcId, accountId, volumeId); + this.setVolumePath(volumePath); } } \ No newline at end of file diff --git a/core/src/com/cloud/agent/api/StartCommand.java b/core/src/com/cloud/agent/api/StartCommand.java index eb5c80e9765..ac99dfd88cf 100755 --- a/core/src/com/cloud/agent/api/StartCommand.java +++ b/core/src/com/cloud/agent/api/StartCommand.java @@ -18,7 +18,6 @@ package com.cloud.agent.api; import java.util.List; -import java.util.Map; import com.cloud.network.router.VirtualRouter; import com.cloud.offering.ServiceOffering; @@ -69,8 +68,6 @@ public class StartCommand extends AbstractStartCommand { guestMacAddress = vm.getGuestMacAddress(); vncPassword = vm.getVncPassword(); hostName = vm.getHostName(); -// networkRateMbps = offering.getRateMbps(); -// networkRateMulticastMbps = offering.getMulticastRateMbps(); networkRateMbps = networkRate; networkRateMulticastMbps = multicastRate; if (bits == 32) { diff --git a/core/src/com/cloud/storage/SnapshotVO.java b/core/src/com/cloud/storage/SnapshotVO.java index 20c68d18957..4b4c3b4dbac 100644 --- a/core/src/com/cloud/storage/SnapshotVO.java +++ b/core/src/com/cloud/storage/SnapshotVO.java @@ -29,6 +29,7 @@ import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; +import javax.persistence.TableGenerator; import com.cloud.utils.db.GenericDao; import com.google.gson.annotations.Expose; @@ -38,8 +39,8 @@ import com.google.gson.annotations.Expose; public class SnapshotVO implements Snapshot { @Id - @GeneratedValue(strategy=GenerationType.IDENTITY) - @Column(name="id") + @TableGenerator(name="snapshots_sq", table="sequence", pkColumnName="name", valueColumnName="value", pkColumnValue="snapshots_seq", allocationSize=1) + @Column(name="id", updatable=false, nullable = false) Long id; @Column(name="account_id") @@ -81,7 +82,8 @@ public class SnapshotVO implements Snapshot { public SnapshotVO() { } - public SnapshotVO(long accountId, long volumeId, String path, String name, short snapshotType, String typeDescription) { + public SnapshotVO(long id, long accountId, long volumeId, String path, String name, short snapshotType, String typeDescription) { + this.id = id; this.accountId = accountId; this.volumeId = volumeId; this.path = path; diff --git a/server/src/com/cloud/api/ApiDBUtils.java b/server/src/com/cloud/api/ApiDBUtils.java index b2a2be27dd9..02a3f4a2a11 100755 --- a/server/src/com/cloud/api/ApiDBUtils.java +++ b/server/src/com/cloud/api/ApiDBUtils.java @@ -37,6 +37,8 @@ import com.cloud.network.security.NetworkGroup; import com.cloud.network.security.NetworkGroupManager; import com.cloud.network.security.dao.NetworkGroupDao; import com.cloud.offering.ServiceOffering; +import com.cloud.offerings.NetworkOfferingVO; +import com.cloud.offerings.dao.NetworkOfferingDao; import com.cloud.server.Criteria; import com.cloud.server.ManagementServer; import com.cloud.server.StatsCollector; @@ -125,6 +127,7 @@ public class ApiDBUtils { private static VlanDao _vlanDao; private static VolumeDao _volumeDao; private static DataCenterDao _zoneDao; + private static NetworkOfferingDao _networkOfferingDao; static { _ms = (ManagementServer)ComponentLocator.getComponent(ManagementServer.Name); @@ -165,6 +168,7 @@ public class ApiDBUtils { _volumeDao = locator.getDao(VolumeDao.class); _zoneDao = locator.getDao(DataCenterDao.class); _networkGroupDao = locator.getDao(NetworkGroupDao.class); + _networkOfferingDao = locator.getDao(NetworkOfferingDao.class); // Note: stats collector should already have been initialized by this time, otherwise a null instance is returned _statsCollector = StatsCollector.getInstance(); @@ -487,4 +491,8 @@ public class ApiDBUtils { _asyncMgr.syncAsyncJobExecution((AsyncJobVO)job, syncObjType, syncObjId); } + public static NetworkOfferingVO findNetworkOfferingById(long networkOfferingId) { + return _networkOfferingDao.findByIdIncludingRemoved(networkOfferingId); + } + } diff --git a/server/src/com/cloud/api/ApiDispatcher.java b/server/src/com/cloud/api/ApiDispatcher.java index c55d5642691..faf15d31f3f 100644 --- a/server/src/com/cloud/api/ApiDispatcher.java +++ b/server/src/com/cloud/api/ApiDispatcher.java @@ -68,22 +68,22 @@ public class ApiDispatcher { cmd.callCreate(); } catch (Throwable t) { if (t instanceof InvalidParameterValueException || t instanceof IllegalArgumentException) { - s_logger.info(t); + s_logger.info("Exception: ", t); throw new ServerApiException(BaseCmd.PARAM_ERROR, t.getMessage()); }else if (t instanceof PermissionDeniedException) { - s_logger.info(t); + s_logger.info("Exception: ", t); throw new ServerApiException(BaseCmd.ACCOUNT_ERROR, t.getMessage()); }else if (t instanceof AccountLimitException) { - s_logger.info(t); + s_logger.info("Exception: ", t); throw new ServerApiException(BaseCmd.ACCOUNT_RESOURCE_LIMIT_ERROR, t.getMessage()); }else if (t instanceof InsufficientCapacityException) { - s_logger.info(t); + s_logger.info("Exception: ", t); throw new ServerApiException(BaseCmd.INSUFFICIENT_CAPACITY_ERROR, t.getMessage()); }else if (t instanceof ResourceAllocationException) { - s_logger.info(t); + s_logger.info("Exception: ", t); throw new ServerApiException(BaseCmd.RESOURCE_ALLOCATION_ERROR, t.getMessage()); }else if (t instanceof ResourceUnavailableException) { - s_logger.warn(t); + s_logger.warn("Exception: ", t); throw new ServerApiException(BaseCmd.RESOURCE_UNAVAILABLE_ERROR, t.getMessage()); }else if (t instanceof ServerApiException) { s_logger.warn(t.getClass() + " : " + ((ServerApiException) t).getDescription()); @@ -91,7 +91,6 @@ public class ApiDispatcher { }else if (t instanceof AsyncCommandQueued) { throw (AsyncCommandQueued)t; }else { - s_logger.warn(t); s_logger.error("Exception while executing " + cmd.getClass().getSimpleName() + ":", t); if (UserContext.current().getAccount() == null || UserContext.current().getAccount().getType() == Account.ACCOUNT_TYPE_ADMIN) throw new ServerApiException(BaseCmd.INTERNAL_ERROR, t.getMessage()); @@ -107,22 +106,22 @@ public class ApiDispatcher { cmd.execute(); } catch (Throwable t) { if (t instanceof InvalidParameterValueException || t instanceof IllegalArgumentException) { - s_logger.info(t); + s_logger.info("Exception: ", t); throw new ServerApiException(BaseCmd.PARAM_ERROR, t.getMessage()); }else if (t instanceof PermissionDeniedException) { - s_logger.info(t); + s_logger.info("Exception: ", t); throw new ServerApiException(BaseCmd.ACCOUNT_ERROR, t.getMessage()); }else if (t instanceof AccountLimitException) { - s_logger.info(t); + s_logger.info("Exception: ", t); throw new ServerApiException(BaseCmd.ACCOUNT_RESOURCE_LIMIT_ERROR, t.getMessage()); }else if (t instanceof InsufficientCapacityException) { - s_logger.info(t); + s_logger.info("Exception: ", t); throw new ServerApiException(BaseCmd.INSUFFICIENT_CAPACITY_ERROR, t.getMessage()); }else if (t instanceof ResourceAllocationException) { - s_logger.warn(t); + s_logger.warn("Exception: ", t); throw new ServerApiException(BaseCmd.RESOURCE_ALLOCATION_ERROR, t.getMessage()); }else if (t instanceof ResourceUnavailableException) { - s_logger.warn(t); + s_logger.warn("Exception: ", t); throw new ServerApiException(BaseCmd.RESOURCE_UNAVAILABLE_ERROR, t.getMessage()); }else if (t instanceof ServerApiException) { s_logger.warn(t.getClass() + " : " + ((ServerApiException) t).getDescription()); @@ -130,7 +129,6 @@ public class ApiDispatcher { } else if (t instanceof AsyncCommandQueued) { throw (AsyncCommandQueued)t; }else { - s_logger.warn(t); s_logger.error("Exception while executing " + cmd.getClass().getSimpleName() + ":", t); if (UserContext.current().getAccount() == null || UserContext.current().getAccount().getType() == Account.ACCOUNT_TYPE_ADMIN) throw new ServerApiException(BaseCmd.INTERNAL_ERROR, t.getMessage()); diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index 8219165c083..0e7e0520f72 100644 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -52,6 +52,9 @@ import com.cloud.api.response.IpForwardingRuleResponse; import com.cloud.api.response.ListResponse; import com.cloud.api.response.LoadBalancerResponse; import com.cloud.api.response.NetworkGroupResponse; +import com.cloud.api.response.NetworkOfferingResponse; +import com.cloud.api.response.NetworkResponse; +import com.cloud.api.response.NicResponse; import com.cloud.api.response.PodResponse; import com.cloud.api.response.PreallocatedLunResponse; import com.cloud.api.response.RemoteAccessVpnResponse; @@ -96,7 +99,6 @@ import com.cloud.host.HostVO; import com.cloud.network.IpAddress; import com.cloud.network.LoadBalancer; import com.cloud.network.Network; -import com.cloud.network.Networks.TrafficType; import com.cloud.network.RemoteAccessVpn; import com.cloud.network.VpnUser; import com.cloud.network.router.VirtualRouter; @@ -105,6 +107,7 @@ import com.cloud.network.security.IngressRule; import com.cloud.network.security.NetworkGroup; import com.cloud.network.security.NetworkGroupRules; import com.cloud.offering.DiskOffering; +import com.cloud.offering.NetworkOffering; import com.cloud.offering.NetworkOffering.GuestIpType; import com.cloud.offering.ServiceOffering; import com.cloud.org.Cluster; @@ -756,6 +759,7 @@ public class ApiResponseHelper implements ResponseGenerator { vlanResponse.setGateway(vlan.getVlanGateway()); vlanResponse.setNetmask(vlan.getVlanNetmask()); vlanResponse.setDescription(vlan.getIpRange()); + vlanResponse.setNetworkId(vlan.getNetworkId()); vlanResponse.setObjectName("vlan"); return vlanResponse; @@ -1068,9 +1072,7 @@ public class ApiResponseHelper implements ResponseGenerator { public IpForwardingRuleResponse createIpForwardingRuleResponse(FirewallRule fwRule) { IpForwardingRuleResponse response = new IpForwardingRuleResponse(); response.setId(fwRule.getId()); - response.setPrivatePort(fwRule.getPrivatePort()); response.setProtocol(fwRule.getProtocol()); - response.setPublicPort(fwRule.getPublicPort()); response.setPublicIpAddress(fwRule.getPublicIpAddress()); if (fwRule.getPublicIpAddress() != null && fwRule.getPrivateIpAddress() != null) { UserVm vm = ApiDBUtils.findUserVmByPublicIpAndGuestIp(fwRule.getPublicIpAddress(), fwRule.getPrivateIpAddress()); @@ -1201,14 +1203,27 @@ public class ApiResponseHelper implements ResponseGenerator { userVmResponse.setNetworkGroupList(ApiDBUtils.getNetworkGroupsNamesForVm(userVm.getId())); List nics = ApiDBUtils.getNics(userVm); + List nicResponses = new ArrayList(); for (Nic singleNic : nics) { - Long configId = singleNic.getNetworkId(); - Network networkConf = ApiDBUtils.getNetwork(configId); - if (networkConf.getTrafficType() == TrafficType.Guest) { - userVmResponse.setIpAddress(singleNic.getIp4Address()); - } + NicResponse nicResponse = new NicResponse(); + nicResponse.setId(singleNic.getId()); + nicResponse.setIpaddress(singleNic.getIp4Address()); + nicResponse.setGateway(singleNic.getGateway()); + nicResponse.setNetmask(singleNic.getNetmask()); + nicResponse.setNetworkid(singleNic.getNetworkId()); + if (acct.getType() == Account.ACCOUNT_TYPE_ADMIN) { + if (singleNic.getBroadcastUri() != null) { + nicResponse.setBroadcastUri(singleNic.getBroadcastUri().toString()); + } + if (singleNic.getIsolationUri() != null) { + nicResponse.setIsolationUri(singleNic.getIsolationUri().toString()); + } + } + nicResponse.setObjectName("nic"); + + nicResponses.add(nicResponse); } - + userVmResponse.setNics(nicResponses); userVmResponse.setObjectName("virtualmachine"); return userVmResponse; } @@ -1238,35 +1253,31 @@ public class ApiResponseHelper implements ResponseGenerator { } List nics = ApiDBUtils.getNics(router); + List nicResponses = new ArrayList(); for (Nic singleNic : nics) { - Long configId = singleNic.getNetworkId(); - Network networkConf = ApiDBUtils.getNetwork(configId); - - if (networkConf.getTrafficType() == TrafficType.Guest) { - routerResponse.setGuestIpAddress(singleNic.getIp4Address()); - routerResponse.setGuestMacAddress(singleNic.getMacAddress()); - routerResponse.setGuestNetmask(singleNic.getNetmask()); + NicResponse nicResponse = new NicResponse(); + nicResponse.setId(singleNic.getId()); + nicResponse.setIpaddress(singleNic.getIp4Address()); + nicResponse.setGateway(singleNic.getGateway()); + nicResponse.setNetmask(singleNic.getNetmask()); + nicResponse.setNetworkid(singleNic.getNetworkId()); + if (singleNic.getBroadcastUri() != null) { + nicResponse.setBroadcastUri(singleNic.getBroadcastUri().toString()); } - - if (networkConf.getTrafficType() == TrafficType.Control) { - routerResponse.setPrivateIp(singleNic.getIp4Address()); - routerResponse.setPrivateMacAddress(singleNic.getMacAddress()); - routerResponse.setPrivateNetmask(singleNic.getNetmask()); - } - - if (networkConf.getTrafficType() == TrafficType.Public) { - routerResponse.setPublicIp(singleNic.getIp4Address()); - routerResponse.setPublicMacAddress(singleNic.getMacAddress()); - routerResponse.setPublicNetmask(singleNic.getNetmask()); - routerResponse.setGateway(singleNic.getGateway()); - } - - DataCenter zone = ApiDBUtils.findZoneById(router.getDataCenterId()); - if (zone != null) { - routerResponse.setZoneName(zone.getName()); - routerResponse.setDns1(zone.getDns1()); - routerResponse.setDns2(zone.getDns2()); + if (singleNic.getIsolationUri() != null) { + nicResponse.setIsolationUri(singleNic.getIsolationUri().toString()); } + + nicResponse.setObjectName("nic"); + nicResponses.add(nicResponse); + } + routerResponse.setNics(nicResponses); + + DataCenter zone = ApiDBUtils.findZoneById(router.getDataCenterId()); + if (zone != null) { + routerResponse.setZoneName(zone.getName()); + routerResponse.setDns1(zone.getDns1()); + routerResponse.setDns2(zone.getDns2()); } routerResponse.setObjectName("domainrouter"); @@ -1323,25 +1334,26 @@ public class ApiResponseHelper implements ResponseGenerator { } List nics = ApiDBUtils.getNics(systemVM); + List nicResponses = new ArrayList(); for (Nic singleNic : nics) { - Long configId = singleNic.getNetworkId(); - Network networkConf = ApiDBUtils.getNetwork(configId); - - if (networkConf.getTrafficType() == TrafficType.Management) { - vmResponse.setPrivateIp(singleNic.getIp4Address()); - vmResponse.setPrivateMacAddress(singleNic.getMacAddress()); - vmResponse.setPrivateNetmask(singleNic.getNetmask()); + NicResponse nicResponse = new NicResponse(); + nicResponse.setId(singleNic.getId()); + nicResponse.setIpaddress(singleNic.getIp4Address()); + nicResponse.setGateway(singleNic.getGateway()); + nicResponse.setNetmask(singleNic.getNetmask()); + nicResponse.setNetworkid(singleNic.getNetworkId()); + if (singleNic.getBroadcastUri() != null) { + nicResponse.setBroadcastUri(singleNic.getBroadcastUri().toString()); } - - if (networkConf.getTrafficType() == TrafficType.Public) { - vmResponse.setPublicIp(singleNic.getIp4Address()); - vmResponse.setPublicMacAddress(singleNic.getMacAddress()); - vmResponse.setPublicNetmask(singleNic.getNetmask()); - vmResponse.setGateway(singleNic.getGateway()); + if (singleNic.getIsolationUri() != null) { + nicResponse.setIsolationUri(singleNic.getIsolationUri().toString()); } + + nicResponse.setObjectName("nic"); + nicResponses.add(nicResponse); } + vmResponse.setNics(nicResponses); } - vmResponse.setObjectName("systemvm"); return vmResponse; } @@ -2160,7 +2172,7 @@ public class ApiResponseHelper implements ResponseGenerator { capacityResponse.setZoneId(summedCapacity.getDataCenterId()); capacityResponse.setZoneName(ApiDBUtils.findZoneById(summedCapacity.getDataCenterId()).getName()); if (summedCapacity.getTotalCapacity() != 0) { - float computed = ((float)summedCapacity.getUsedCapacity() / (float)summedCapacity.getTotalCapacity() * 100f); + //float computed = ((float)summedCapacity.getUsedCapacity() / (float)summedCapacity.getTotalCapacity() * 100f); capacityResponse.setPercentUsed(format.format((float)summedCapacity.getUsedCapacity() / (float)summedCapacity.getTotalCapacity() * 100f)); } else { capacityResponse.setPercentUsed(format.format(0L)); @@ -2265,4 +2277,68 @@ public class ApiResponseHelper implements ResponseGenerator { } return response; } + + @Override + public NetworkOfferingResponse createNetworkOfferingResponse(NetworkOffering offering) { + NetworkOfferingResponse response = new NetworkOfferingResponse(); + response.setId(offering.getId()); + response.setName(offering.getName()); + response.setDisplayText(offering.getDisplayText()); + response.setTags(offering.getTags()); + response.setTrafficType(offering.getTrafficType().toString()); + if (offering.getGuestIpType() != null) { + response.setType(offering.getGuestIpType().toString()); + } + response.setMaxconnections(offering.getConcurrentConnections()); + response.setIsDefault(offering.isDefault()); + response.setSpecifyVlan(offering.getSpecifyVlan()); + response.setIsShared(offering.isShared()); + response.setObjectName("networkoffering"); + return response; + } + + @Override + public NetworkResponse createNetworkResponse(Network network) { + NetworkResponse response = new NetworkResponse(); + response.setId(network.getId()); + response.setName(network.getName()); + response.setDisplaytext(network.getDisplayText()); + if (network.getBroadcastDomainType() != null) { + response.setBroadcastDomainType(network.getBroadcastDomainType().toString()); + } + if (network.getBroadcastUri() != null) { + response.setBroadcastUri(network.getBroadcastUri().toString()); + } + + if (response.getTrafficType() != null) { + response.setTrafficType(network.getTrafficType().toString()); + } + + if (response.getType() != null) { + response.setType(network.getGuestType().toString()); + } + response.setGateway(network.getGateway()); + response.setCidr(network.getCidr()); + response.setZoneId(network.getDataCenterId()); + + //populate network offering information + NetworkOffering networkOffering = ApiDBUtils.findNetworkOfferingById(network.getNetworkOfferingId()); + if (networkOffering != null) { + response.setNetworkOfferingId(networkOffering.getId()); + response.setNetworkOfferingName(networkOffering.getName()); + response.setNetworkOfferingDisplayText(networkOffering.getDisplayText()); + } + response.setState(network.getState().toString()); + response.setRelated(network.getRelated()); + response.setDns1(network.getDns1()); + response.setDns2(network.getDns2()); + + Account account = ApiDBUtils.findAccountById(network.getAccountId()); + if (account != null) { + response.setAccountName(account.getAccountName()); + response.setDomainId(account.getDomainId()); + } + response.setObjectName("network"); + return response; + } } diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java index 0b14e777626..7c635d030a1 100644 --- a/server/src/com/cloud/configuration/Config.java +++ b/server/src/com/cloud/configuration/Config.java @@ -198,7 +198,8 @@ public enum Config { SSOKey("Hidden", ManagementServer.class, String.class, "security.singlesignon.key", null, "A Single Sign-On key used for logging into the cloud", null), SSOAuthTolerance("Advanced", ManagementServer.class, Long.class, "security.singlesignon.tolerance.millis", "300000", "The allowable clock difference in milliseconds between when an SSO login request is made and when it is received.", null), NetworkType("Hidden", ManagementServer.class, String.class, "network.type", "vlan", "The type of network that this deployment will use.", "vlan,direct"), - HashKey("Hidden", ManagementServer.class, String.class, "security.hash.key", null, "for generic key-ed hash", null); + HashKey("Hidden", ManagementServer.class, String.class, "security.hash.key", null, "for generic key-ed hash", null), + UseNewNetwork("Hidden", NetworkManager.class, Boolean.class, "use.new.networking", "false", null, null); private final String _category; private final Class _componentClass; diff --git a/server/src/com/cloud/configuration/ConfigurationManager.java b/server/src/com/cloud/configuration/ConfigurationManager.java index f05e478226a..7af2974a5fc 100644 --- a/server/src/com/cloud/configuration/ConfigurationManager.java +++ b/server/src/com/cloud/configuration/ConfigurationManager.java @@ -19,15 +19,22 @@ package com.cloud.configuration; import java.util.List; +import com.cloud.api.commands.CreateVlanIpRangeCmd; import com.cloud.dc.DataCenter; import com.cloud.dc.DataCenter.DataCenterNetworkType; import com.cloud.dc.DataCenterVO; import com.cloud.dc.HostPodVO; +import com.cloud.dc.Vlan; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientAddressCapacityException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; import com.cloud.offering.DiskOffering; import com.cloud.offering.ServiceOffering; +import com.cloud.network.Networks.TrafficType; +import com.cloud.offering.NetworkOffering.GuestIpType; +import com.cloud.offerings.NetworkOfferingVO; import com.cloud.service.ServiceOfferingVO; import com.cloud.storage.DiskOfferingVO; import com.cloud.user.Account; @@ -63,8 +70,6 @@ public interface ConfigurationManager extends Manager { */ ServiceOfferingVO createServiceOffering(long userId, String name, int cpu, int ramSize, int speed, String displayText, boolean localStorageRequired, boolean offerHA, boolean useVirtualNetwork, String tags, Long domainId); - - /** * Creates a new disk offering * @param domainId @@ -161,4 +166,22 @@ public interface ConfigurationManager extends Manager { void checkDiskOfferingAccess(Account caller, DiskOffering dof) throws PermissionDeniedException; + + + /** + * Creates a new network offering + * @param id + * @param name + * @param displayText + * @param type + * @param trafficType + * @param tags + * @param maxConnections + * @param specifyVlan; + * @return network offering object + */ + NetworkOfferingVO createNetworkOffering(long userId, String name, String displayText, GuestIpType type, TrafficType trafficType, String tags, Integer maxConnections, boolean specifyVlan, boolean isShared); + + Vlan createVlanAndPublicIpRange(Long userId, Long zoneId, Long podId, String startIP, String endIP, String vlanGateway, String vlanNetmask, boolean forVirtualNetwork, String vlanId, Account account, Long networkId) throws InsufficientCapacityException, ConcurrentOperationException, InvalidParameterValueException; + } diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index 20f418602df..22547a2b5a5 100755 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -34,15 +34,18 @@ import com.cloud.api.BaseCmd; import com.cloud.api.ServerApiException; import com.cloud.api.commands.CreateCfgCmd; import com.cloud.api.commands.CreateDiskOfferingCmd; +import com.cloud.api.commands.CreateNetworkOfferingCmd; import com.cloud.api.commands.CreatePodCmd; import com.cloud.api.commands.CreateServiceOfferingCmd; import com.cloud.api.commands.CreateVlanIpRangeCmd; import com.cloud.api.commands.CreateZoneCmd; import com.cloud.api.commands.DeleteDiskOfferingCmd; +import com.cloud.api.commands.DeleteNetworkOfferingCmd; import com.cloud.api.commands.DeletePodCmd; import com.cloud.api.commands.DeleteServiceOfferingCmd; import com.cloud.api.commands.DeleteVlanIpRangeCmd; import com.cloud.api.commands.DeleteZoneCmd; +import com.cloud.api.commands.ListNetworkOfferingsCmd; import com.cloud.api.commands.UpdateCfgCmd; import com.cloud.api.commands.UpdateDiskOfferingCmd; import com.cloud.api.commands.UpdatePodCmd; @@ -81,11 +84,14 @@ import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.network.NetworkManager; +import com.cloud.network.Networks.TrafficType; import com.cloud.network.dao.IPAddressDao; import com.cloud.offering.DiskOffering; import com.cloud.offering.NetworkOffering; import com.cloud.offering.NetworkOffering.GuestIpType; import com.cloud.offering.ServiceOffering; +import com.cloud.offerings.NetworkOfferingVO; +import com.cloud.offerings.dao.NetworkOfferingDao; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.DiskOfferingVO; @@ -103,6 +109,8 @@ import com.cloud.utils.component.Adapters; import com.cloud.utils.component.ComponentLocator; import com.cloud.utils.component.Inject; import com.cloud.utils.db.DB; +import com.cloud.utils.db.Filter; +import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.NetUtils; @@ -131,6 +139,7 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura @Inject DomainDao _domainDao; @Inject ServiceOfferingDao _serviceOfferingDao; @Inject DiskOfferingDao _diskOfferingDao; + @Inject NetworkOfferingDao _networkOfferingDao; @Inject VlanDao _vlanDao; @Inject IPAddressDao _publicIpAddressDao; @Inject DataCenterIpAddressDao _privateIpAddressDao; @@ -1053,7 +1062,6 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura String internalDns2 = cmd.getInternalDns2(); String vnetRange = cmd.getVlan(); String guestCidr = cmd.getGuestCidrAddress(); - String domain = cmd.getDomain();//we are not passing domain right now, always null Long domainId = cmd.getDomainId(); String type = cmd.getNetworkType(); Boolean isBasic = false; @@ -1412,9 +1420,9 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura return genChangeRangeSuccessString(problemIPs, add); } } - + @Override - public Vlan createVlanAndPublicIpRange(CreateVlanIpRangeCmd cmd) throws InsufficientCapacityException, ConcurrentOperationException { + public Vlan createVlanAndPublicIpRange(CreateVlanIpRangeCmd cmd) throws InsufficientCapacityException, ConcurrentOperationException, InvalidParameterValueException { Long zoneId = cmd.getZoneId(); Long podId = cmd.getPodId(); String startIP = cmd.getStartIp(); @@ -1422,12 +1430,25 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura String vlanGateway = cmd.getGateway(); String vlanNetmask = cmd.getNetmask(); Long userId = UserContext.current().getUserId(); - - if (userId == null) { - userId = Long.valueOf(User.UID_SYSTEM); + String vlanId = cmd.getVlan(); + // If an account name and domain ID are specified, look up the account + String accountName = cmd.getAccountName(); + Long domainId = cmd.getDomainId(); + Account account = null; + if ((accountName != null) && (domainId != null)) { + account = _accountDao.findActiveAccount(accountName, domainId); + if (account == null) { + throw new ServerApiException(BaseCmd.PARAM_ERROR, "Please specify a valid account."); + } } + return createVlanAndPublicIpRange(userId, zoneId, podId, startIP, endIP, vlanGateway, vlanNetmask, true, vlanId, account, null); + } + + + @Override + public Vlan createVlanAndPublicIpRange(Long userId, Long zoneId, Long podId, String startIP, String endIP, String vlanGateway, String vlanNetmask, boolean forVirtualNetwork, String vlanId, Account account, Long networkId) throws InsufficientCapacityException, ConcurrentOperationException, InvalidParameterValueException{ - // Check that the pod ID is valid + // Check that the pod ID is valid if (podId != null && ((_podDao.findById(podId)) == null)) { throw new InvalidParameterValueException("Please specify a valid pod."); } @@ -1436,15 +1457,7 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura if (podId != null && _podDao.findById(podId).getDataCenterId() != zoneId) { throw new InvalidParameterValueException("Pod id=" + podId + " doesn't belong to zone id=" + zoneId); } - - // If forVirtualNetworks isn't specified, default it to true - Boolean forVirtualNetwork = cmd.isForVirtualNetwork(); - if (forVirtualNetwork == null) { - forVirtualNetwork = Boolean.TRUE; - } - // If the VLAN id is null, default it to untagged - String vlanId = cmd.getVlan(); if (vlanId == null) { vlanId = Vlan.UNTAGGED; } @@ -1466,17 +1479,6 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura throw new InvalidParameterValueException("Can't add virtual network to the zone id=" + zone.getId() + " as zone doesn't have guest vlan configured"); } - // If an account name and domain ID are specified, look up the account - String accountName = cmd.getAccountName(); - Long domainId = cmd.getDomainId(); - Account account = null; - if ((accountName != null) && (domainId != null)) { - account = _accountDao.findActiveAccount(accountName, domainId); - if (account == null) { - throw new ServerApiException(BaseCmd.PARAM_ERROR, "Please specify a valid account."); - } - } - VlanType vlanType = forVirtualNetwork ? VlanType.VirtualNetwork : VlanType.DirectAttached; @@ -1643,7 +1645,7 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura if (endIP != null) { ipRange += "-" + endIP; } - VlanVO vlan = new VlanVO(vlanType, vlanId, vlanGateway, vlanNetmask, zone.getId(), ipRange); + VlanVO vlan = new VlanVO(vlanType, vlanId, vlanGateway, vlanNetmask, zone.getId(), ipRange, networkId); vlan = _vlanDao.persist(vlan); // Persist the IP range @@ -1685,7 +1687,6 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura // if this is an account VLAN, now associate the IP Addresses to the account associateIpAddressListToAccount(userId, account.getId(), zoneId, vlan.getId()); } - return vlan; } @@ -2378,4 +2379,155 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura assert false : "How can all of the security checkers pass on checking this caller?"; throw new PermissionDeniedException("There's no way to confirm " + caller + " has access to zone:" + zone.getId()); } + + + + @Override + public NetworkOffering createNetworkOffering(CreateNetworkOfferingCmd cmd) throws InvalidParameterValueException { + Long userId = UserContext.current().getUserId(); + String name = cmd.getNetworkOfferingName(); + String displayText = cmd.getDisplayText(); + String tags = cmd.getTags(); + String typeString = cmd.getType(); + String trafficTypeString = cmd.getTraffictype(); + Boolean specifyVlan = cmd.getSpecifyVlan(); + Boolean isShared = cmd.getIsShared(); + TrafficType trafficType = null; + GuestIpType type = null; + + //Verify traffic type + for (TrafficType tType : TrafficType.values()) { + if (tType.name().equalsIgnoreCase(trafficTypeString)) { + trafficType = tType; + } + } + if (trafficType == null) { + throw new InvalidParameterValueException("Invalid value for traffictype. Supported traffic types: Public, Management, Control, Guest, Vlan or Storage"); + } + + //Verify type + for (GuestIpType gType : GuestIpType.values()) { + if (gType.name().equalsIgnoreCase(typeString)) { + type = gType; + } + } + if (type == null) { + throw new InvalidParameterValueException("Invalid value for type. Supported types: Virtualized, DirectSingle, DirectDual"); + } + + if (specifyVlan == null) { + specifyVlan = false; + } + + if (isShared == null) { + isShared = false; + } + + Integer maxConnections = cmd.getMaxconnections(); + return createNetworkOffering(userId, name, displayText, type, trafficType, tags, maxConnections, specifyVlan, isShared); + } + + @Override + public NetworkOfferingVO createNetworkOffering(long userId, String name, String displayText, GuestIpType type, TrafficType trafficType, String tags, Integer maxConnections, boolean specifyVlan, boolean isShared) { + String networkRateStr = _configDao.getValue("network.throttling.rate"); + String multicastRateStr = _configDao.getValue("multicast.throttling.rate"); + int networkRate = ((networkRateStr == null) ? 200 : Integer.parseInt(networkRateStr)); + int multicastRate = ((multicastRateStr == null) ? 10 : Integer.parseInt(multicastRateStr)); + tags = cleanupTags(tags); + NetworkOfferingVO offering = new NetworkOfferingVO(name, displayText, trafficType, type, false, specifyVlan, networkRate, multicastRate, maxConnections, isShared, false); + + if ((offering = _networkOfferingDao.persist(offering)) != null) { + saveConfigurationEvent(userId, null, EventTypes.EVENT_NETWORK_OFFERING_CREATE, "Successfully created new network offering with name: " + name + ".", "noId=" + offering.getId(), "name=" + name, + "displayText=" + displayText, "tags=" + tags); + return offering; + } else { + return null; + } + } + + @Override + public List searchForNetworkOfferings(ListNetworkOfferingsCmd cmd) { + Filter searchFilter = new Filter(NetworkOfferingVO.class, "created", false, cmd.getStartIndex(), cmd.getPageSizeVal()); + SearchCriteria sc = _networkOfferingDao.createSearchCriteria(); + + Object id = cmd.getId(); + Object name = cmd.getNetworkOfferingName(); + Object displayText = cmd.getDisplayText(); + Object type = cmd.getType(); + Object trafficType = cmd.getTrafficType(); + Object isDefault = cmd.getIsDefault(); + Object specifyVlan = cmd.getSpecifyVlan(); + Object isShared = cmd.getIsShared(); + + Object keyword = cmd.getKeyword(); + + if (keyword != null) { + SearchCriteria ssc = _networkOfferingDao.createSearchCriteria(); + ssc.addOr("displayText", SearchCriteria.Op.LIKE, "%" + keyword + "%"); + ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%"); + + sc.addAnd("name", SearchCriteria.Op.SC, ssc); + } + + if (id != null) { + sc.addAnd("id", SearchCriteria.Op.EQ, id); + } + if (name != null) { + sc.addAnd("name", SearchCriteria.Op.LIKE, "%" + name + "%"); + } + if (displayText != null) { + sc.addAnd("displayText", SearchCriteria.Op.LIKE, "%" + displayText + "%"); + } + if (type != null) { + sc.addAnd("guestIpType", SearchCriteria.Op.EQ, type); + } + + if (trafficType != null) { + sc.addAnd("trafficType", SearchCriteria.Op.EQ, trafficType); + } + + if (isDefault != null) { + sc.addAnd("isDefault", SearchCriteria.Op.EQ, isDefault); + } + + if (specifyVlan != null) { + sc.addAnd("specifyVlan", SearchCriteria.Op.EQ, specifyVlan); + } + + if (isShared != null) { + sc.addAnd("isShared", SearchCriteria.Op.EQ, isShared); + } + + //Don't return system network offerings to the user + sc.addAnd("systemOnly", SearchCriteria.Op.EQ, false); + + return _networkOfferingDao.search(sc, searchFilter); + } + + @Override + public boolean deleteNetworkOffering(DeleteNetworkOfferingCmd cmd) throws InvalidParameterValueException{ + Long offeringId = cmd.getId(); + Long userId = UserContext.current().getUserId(); + + //Verify network offering id + NetworkOfferingVO offering = _networkOfferingDao.findById(offeringId); + if (offering == null) { + throw new InvalidParameterValueException("unable to find network offering " + offeringId); + } else if (offering.getRemoved() != null || offering.isSystemOnly()) { + throw new InvalidParameterValueException("unable to find network offering " + offeringId); + } + + //Don't allow to delete default network offerings + if (offering.isDefault() == true) { + throw new InvalidParameterValueException("Default network offering can't be deleted"); + } + + if (_networkOfferingDao.remove(offeringId)) { + saveConfigurationEvent(userId, null, EventTypes.EVENT_NETWORK_OFFERING_DELETE, "Successfully deleted network offering with name: " + offering.getName(), "noId=" + offeringId, "name=" + offering.getName(), + "displayText=" + offering.getDisplayText()); + return true; + } else { + return false; + } + } } diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java index a36fba7a863..6e299080619 100644 --- a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java +++ b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java @@ -1071,9 +1071,9 @@ public class ConsoleProxyManagerImpl implements ConsoleProxyManager, ConsoleProx NicProfile defaultNic = new NicProfile(); defaultNic.setDefaultNic(true); defaultNic.setDeviceId(2); - networks.add(new Pair(_networkMgr.setupNetworkConfiguration(systemAcct, defaultOffering.get(0), plan).get(0), defaultNic)); + networks.add(new Pair(_networkMgr.setupNetworkConfiguration(systemAcct, defaultOffering.get(0), plan, null, null).get(0), defaultNic)); for (NetworkOfferingVO offering : offerings) { - networks.add(new Pair(_networkMgr.setupNetworkConfiguration(systemAcct, offering, plan).get(0), null)); + networks.add(new Pair(_networkMgr.setupNetworkConfiguration(systemAcct, offering, plan, null, null).get(0), null)); } ConsoleProxyVO proxy = new ConsoleProxyVO(id, _serviceOffering.getId(), name, _template.getId(), _template.getGuestOSId(), dataCenterId, systemAcct.getDomainId(), systemAcct.getId(), 0); try { diff --git a/server/src/com/cloud/dc/VlanVO.java b/server/src/com/cloud/dc/VlanVO.java index 1cb991b5f92..29e94e50fad 100644 --- a/server/src/com/cloud/dc/VlanVO.java +++ b/server/src/com/cloud/dc/VlanVO.java @@ -51,17 +51,21 @@ public class VlanVO implements Vlan { @Column(name="description") String ipRange; + @Column(name="network_id") + Long networkId; + @Column(name="vlan_type") @Enumerated(EnumType.STRING) VlanType vlanType; - public VlanVO(VlanType vlanType, String vlanTag, String vlanGateway, String vlanNetmask, long dataCenterId, String ipRange) { + public VlanVO(VlanType vlanType, String vlanTag, String vlanGateway, String vlanNetmask, long dataCenterId, String ipRange, Long networkId) { this.vlanType = vlanType; this.vlanId = vlanTag; this.vlanGateway = vlanGateway; this.vlanNetmask = vlanNetmask; this.dataCenterId = dataCenterId; this.ipRange = ipRange; + this.networkId = networkId; } public VlanVO() { @@ -107,4 +111,8 @@ public class VlanVO implements Vlan { public VlanType getVlanType() { return vlanType; } + + public Long getNetworkId() { + return networkId; + } } diff --git a/server/src/com/cloud/dc/dao/VlanDao.java b/server/src/com/cloud/dc/dao/VlanDao.java index cef49bc268f..047cfc263c7 100644 --- a/server/src/com/cloud/dc/dao/VlanDao.java +++ b/server/src/com/cloud/dc/dao/VlanDao.java @@ -51,4 +51,6 @@ public interface VlanDao extends GenericDao { List listZoneWideVlans(long zoneId, VlanType vlanType, String vlanId); List searchForZoneWideVlans(long dcId, String vlanType,String vlanId); + + List listVlansByNetworkId(long networkId); } diff --git a/server/src/com/cloud/dc/dao/VlanDaoImpl.java b/server/src/com/cloud/dc/dao/VlanDaoImpl.java index f98a4dc644b..d3ff641396a 100644 --- a/server/src/com/cloud/dc/dao/VlanDaoImpl.java +++ b/server/src/com/cloud/dc/dao/VlanDaoImpl.java @@ -55,6 +55,7 @@ public class VlanDaoImpl extends GenericDaoBase implements VlanDao protected SearchBuilder ZoneTypeAllPodsSearch; protected SearchBuilder ZoneTypePodSearch; protected SearchBuilder ZoneVlanSearch; + protected SearchBuilder NetworkVlanSearch; protected PodVlanMapDaoImpl _podVlanMapDao = new PodVlanMapDaoImpl(); protected AccountVlanMapDao _accountVlanMapDao = new AccountVlanMapDaoImpl(); @@ -90,6 +91,9 @@ public class VlanDaoImpl extends GenericDaoBase implements VlanDao ZoneTypeSearch.and("vlanType", ZoneTypeSearch.entity().getVlanType(), SearchCriteria.Op.EQ); ZoneTypeSearch.done(); + NetworkVlanSearch = createSearchBuilder(); + NetworkVlanSearch.and("networkOfferingId", NetworkVlanSearch.entity().getNetworkId(), SearchCriteria.Op.EQ); + NetworkVlanSearch.done(); } @Override @@ -299,7 +303,13 @@ public class VlanDaoImpl extends GenericDaoBase implements VlanDao } catch (SQLException e) { throw new CloudRuntimeException("Unable to execute " + pstmt.toString(), e); } - } + @Override + public List listVlansByNetworkId(long networkOfferingId) { + SearchCriteria sc = NetworkVlanSearch.create(); + sc.setParameters("networkOfferingId", networkOfferingId); + return listBy(sc); + } + } diff --git a/server/src/com/cloud/network/NetworkManager.java b/server/src/com/cloud/network/NetworkManager.java index 34771685b92..06ec7fd910a 100644 --- a/server/src/com/cloud/network/NetworkManager.java +++ b/server/src/com/cloud/network/NetworkManager.java @@ -220,8 +220,8 @@ public interface NetworkManager extends NetworkService { */ List listPublicIpAddressesInVirtualNetwork(long accountId, long dcId, Boolean sourceNat); - List setupNetworkConfiguration(Account owner, NetworkOfferingVO offering, DeploymentPlan plan); - List setupNetworkConfiguration(Account owner, NetworkOfferingVO offering, Network predefined, DeploymentPlan plan); + List setupNetworkConfiguration(Account owner, NetworkOfferingVO offering, DeploymentPlan plan, String name, String displayText); + List setupNetworkConfiguration(Account owner, NetworkOfferingVO offering, Network predefined, DeploymentPlan plan, String name, String displayText); List getSystemAccountNetworkOfferings(String... offeringNames); diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index 74548f93537..a805d08baaa 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -50,11 +50,14 @@ import com.cloud.api.commands.AddVpnUserCmd; import com.cloud.api.commands.AssignToLoadBalancerRuleCmd; import com.cloud.api.commands.AssociateIPAddrCmd; import com.cloud.api.commands.CreateLoadBalancerRuleCmd; +import com.cloud.api.commands.CreateNetworkCmd; import com.cloud.api.commands.CreatePortForwardingRuleCmd; import com.cloud.api.commands.CreateRemoteAccessVpnCmd; import com.cloud.api.commands.DeleteLoadBalancerRuleCmd; +import com.cloud.api.commands.DeleteNetworkCmd; import com.cloud.api.commands.DeleteRemoteAccessVpnCmd; import com.cloud.api.commands.DisassociateIPAddrCmd; +import com.cloud.api.commands.ListNetworksCmd; import com.cloud.api.commands.ListPortForwardingRulesCmd; import com.cloud.api.commands.RemoveFromLoadBalancerRuleCmd; import com.cloud.api.commands.RemoveVpnUserCmd; @@ -69,12 +72,14 @@ import com.cloud.configuration.dao.ResourceLimitDao; import com.cloud.dc.DataCenter; import com.cloud.dc.DataCenterVO; import com.cloud.dc.HostPodVO; +import com.cloud.dc.Vlan; import com.cloud.dc.Vlan.VlanType; import com.cloud.dc.VlanVO; import com.cloud.dc.dao.AccountVlanMapDao; import com.cloud.dc.dao.DataCenterDao; import com.cloud.dc.dao.HostPodDao; import com.cloud.dc.dao.VlanDao; +import com.cloud.deploy.DataCenterDeployment; import com.cloud.deploy.DeployDestination; import com.cloud.deploy.DeploymentPlan; import com.cloud.domain.dao.DomainDao; @@ -97,6 +102,7 @@ import com.cloud.exception.ResourceUnavailableException; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.network.Networks.AddressFormat; import com.cloud.network.Networks.TrafficType; import com.cloud.network.configuration.NetworkGuru; import com.cloud.network.dao.FirewallRulesDao; @@ -143,6 +149,7 @@ import com.cloud.utils.component.Adapters; import com.cloud.utils.component.Inject; import com.cloud.utils.component.Manager; import com.cloud.utils.db.DB; +import com.cloud.utils.db.Filter; import com.cloud.utils.db.JoinBuilder; import com.cloud.utils.db.JoinBuilder.JoinType; import com.cloud.utils.db.SearchBuilder; @@ -206,7 +213,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag @Inject UserStatisticsDao _statsDao = null; @Inject NetworkOfferingDao _networkOfferingDao = null; @Inject NetworkDao _networkConfigDao = null; - @Inject NicDao _nicDao; + @Inject NicDao _nicDao = null; @Inject GuestOSDao _guestOSDao = null; @Inject RemoteAccessVpnDao _remoteAccessVpnDao = null; @Inject VpnUserDao _vpnUsersDao = null; @@ -874,7 +881,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag if (rule.isForwarding()) { fwdRules.add(rule); - final SetFirewallRuleCommand cmd = new SetFirewallRuleCommand(routerName, routerIp,rule, false); + final SetFirewallRuleCommand cmd = new SetFirewallRuleCommand(routerName, routerIp, rule, true); cmds.addCommand(cmd); } else if (rule.getGroupId() != null){ lbRules.add(rule); @@ -1720,9 +1727,9 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag storageNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(storageNetworkOffering); _systemNetworks.put(NetworkOfferingVO.SystemVmStorageNetwork, storageNetworkOffering); - NetworkOfferingVO defaultGuestNetworkOffering = new NetworkOfferingVO(NetworkOffering.DefaultVirtualizedNetworkOffering, "Virtual Vlan", TrafficType.Guest, GuestIpType.Virtualized, false, false, rateMbps, multicastRateMbps, null); + NetworkOfferingVO defaultGuestNetworkOffering = new NetworkOfferingVO(NetworkOffering.DefaultVirtualizedNetworkOffering, "Virtual Vlan", TrafficType.Guest, GuestIpType.Virtualized, false, false, rateMbps, multicastRateMbps, null, false, true); defaultGuestNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultGuestNetworkOffering); - NetworkOfferingVO defaultGuestDirectNetworkOffering = new NetworkOfferingVO(NetworkOffering.DefaultDirectNetworkOffering, "Direct", TrafficType.Guest, GuestIpType.DirectSingle, false, false, rateMbps, multicastRateMbps, null); + NetworkOfferingVO defaultGuestDirectNetworkOffering = new NetworkOfferingVO(NetworkOffering.DefaultDirectNetworkOffering, "Direct", TrafficType.Guest, GuestIpType.DirectSingle, false, false, rateMbps, multicastRateMbps, null, false, true); defaultGuestNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultGuestDirectNetworkOffering); AccountsUsingNetworkConfigurationSearch = _accountDao.createSearchBuilder(); @@ -1802,12 +1809,12 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } @Override - public List setupNetworkConfiguration(Account owner, NetworkOfferingVO offering, DeploymentPlan plan) { - return setupNetworkConfiguration(owner, offering, null, plan); + public List setupNetworkConfiguration(Account owner, NetworkOfferingVO offering, DeploymentPlan plan, String name, String displayText) { + return setupNetworkConfiguration(owner, offering, null, plan, name, displayText); } @Override - public List setupNetworkConfiguration(Account owner, NetworkOfferingVO offering, Network predefined, DeploymentPlan plan) { + public List setupNetworkConfiguration(Account owner, NetworkOfferingVO offering, Network predefined, DeploymentPlan plan, String name, String displayText) { List configs = _networkConfigDao.listBy(owner.getId(), offering.getId(), plan.getDataCenterId()); if (configs.size() > 0) { if (s_logger.isDebugEnabled()) { @@ -1840,7 +1847,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag related = id; } - NetworkVO vo = new NetworkVO(id, config, offering.getId(), plan.getDataCenterId(), guru.getName(), owner.getDomainId(), owner.getId(), related); + NetworkVO vo = new NetworkVO(id, config, offering.getId(), plan.getDataCenterId(), guru.getName(), owner.getDomainId(), owner.getId(), related, name, displayText); configs.add(_networkConfigDao.persist(vo)); } @@ -1881,12 +1888,14 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag NetworkVO config = network.first(); NetworkGuru concierge = _networkGurus.get(config.getGuruName()); NicProfile requested = network.second(); + if (requested != null && requested.getMode() == null) { + requested.setMode(config.getMode()); + } NicProfile profile = concierge.allocate(config, requested, vm); if (profile == null) { continue; } NicVO vo = new NicVO(concierge.getName(), vm.getId(), config.getId()); - vo.setMode(network.first().getMode()); while (deviceIds[deviceId] && deviceId < deviceIds.length) { deviceId++; @@ -1931,12 +1940,15 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } else if (deviceId != null ) { vo.setDeviceId(deviceId++); } + + vo.setReservationStrategy(profile.getReservationStrategy()); vo.setDefaultNic(profile.isDefaultNic()); if (profile.getIp4Address() != null) { vo.setIp4Address(profile.getIp4Address()); vo.setState(NicVO.State.Reserved); + vo.setAddressFormat(AddressFormat.Ip4); } if (profile.getMacAddress() != null) { @@ -2079,6 +2091,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } element.prepare(config, profile, vmProfile, dest, context); } + } else { + profile = new NicProfile(nic, config, nic.getBroadcastUri(), nic.getIsolationUri()); } vmProfile.addNic(profile); @@ -2670,7 +2684,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag @Override public List setupNetworkConfiguration(Account owner, ServiceOfferingVO offering, DeploymentPlan plan) { NetworkOfferingVO networkOffering = _networkOfferingDao.findByServiceOffering(offering); - return setupNetworkConfiguration(owner, networkOffering, plan); + return setupNetworkConfiguration(owner, networkOffering, plan, null, null); } private String [] getGuestIpRange() { @@ -3040,7 +3054,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag ipAddress = _ipAddressDao.acquireInLockTable(ipAddress.getAddress()); if(ipAddress == null){ - s_logger.warn("Unable to acquire lock on ipAddress for creating 1-1 NAT rule"); + s_logger.warn("Unable to acquire lock on ipAddress for creating static NAT rule"); return rule; }else{ locked = true; @@ -3106,7 +3120,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag userVM = _vmDao.acquireInLockTable(userVM.getId()); if(userVM == null){ - s_logger.warn("Unable to acquire lock on user vm for creating 1-1 NAT rule"); + s_logger.warn("Unable to acquire lock on user vm for creating static NAT rule"); return newFwRule; }else{ locked = true; @@ -3134,13 +3148,20 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } } - // check for ip address/port conflicts by checking existing forwarding and load balancing rules - List existingNatRules = _rulesDao.findByPublicIpPrivateIpForNatRule(ipAddr, userVM.getGuestIpAddress()); + // check for ip address/port conflicts by checking existing port/ip forwarding rules + List existingFirewallRules = _rulesDao.findRuleByPublicIp(ipAddr); - if(existingNatRules.size() > 0){ - throw new NetworkRuleConflictException("The specified rule for public ip:"+ipAddr+" vm id:"+virtualMachineId+" already exists"); + if(existingFirewallRules.size() > 0){ + throw new NetworkRuleConflictException("There already exists a firewall rule for public ip:"+ipAddr); } + //check for ip address/port conflicts by checking existing load balancing rules + List existingLoadBalancerRules = _loadBalancerDao.listByIpAddress(ipAddr); + + if(existingLoadBalancerRules.size() > 0){ + throw new NetworkRuleConflictException("There already exists a load balancer rule for public ip:"+ipAddr); + } + //if given ip address is already source nat, return error if(ipAddress.isSourceNat()){ throw new PermissionDeniedException("Cannot create a static nat rule for the ip:"+ipAddress.getAddress()+" ,this is already a source nat ip address"); @@ -3164,9 +3185,9 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag _rulesDao.persist(newFwRule); txn.commit(); } catch (Exception e) { - s_logger.warn("Unable to create new firewall rule for 1:1 NAT"); + s_logger.warn("Unable to create new firewall rule for static NAT"); txn.rollback(); - throw new ServerApiException(BaseCmd.INTERNAL_ERROR,"Unable to create new firewall rule for 1:1 NAT:"+e.getMessage()); + throw new ServerApiException(BaseCmd.INTERNAL_ERROR,"Unable to create new firewall rule for static NAT:"+e.getMessage()); }finally{ if(locked) { _vmDao.releaseFromLockTable(userVM.getId()); @@ -3282,4 +3303,234 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag return true; } } + + @Override @DB + public Network createNetwork(CreateNetworkCmd cmd) throws InvalidParameterValueException, PermissionDeniedException{ + Account ctxAccount = UserContext.current().getAccount(); + Long userId = UserContext.current().getUserId(); + Long networkOfferingId = cmd.getNetworkOfferingId(); + Long zoneId = cmd.getZoneId(); + Long podId = cmd.getPodId(); + String gateway = cmd.getGateway(); + String cidr = cmd.getCidr(); + String startIP = cmd.getStartIp(); + String endIP = cmd.getEndIp(); + String vlanNetmask = cmd.getNetmask(); + String accountName = cmd.getAccountName(); + Long domainId = cmd.getDomainId(); + String vlanId = cmd.getVlan(); + String name = cmd.getNetworkName(); + String displayText = cmd.getDisplayText(); + Account owner = null; + + //Check if network offering exists + NetworkOfferingVO networkOffering = _networkOfferingDao.findById(networkOfferingId); + if (networkOffering == null || networkOffering.isSystemOnly()) { + throw new InvalidParameterValueException("Unable to find network offeirng by id " + networkOfferingId); + } + + //Check if zone exists + if (zoneId == null || ((_dcDao.findById(zoneId)) == null)) { + throw new InvalidParameterValueException("Please specify a valid zone."); + } + + //Check permissions + if (isAdmin(ctxAccount.getType())) { + if (domainId != null) { + if ((ctxAccount != null) && !_domainDao.isChildDomain(ctxAccount.getDomainId(), domainId)) { + throw new PermissionDeniedException("Failed to create a newtwork, invalid domain id (" + domainId + ") given."); + } + if (accountName != null) { + owner = _accountDao.findActiveAccount(accountName, domainId); + if (owner == null) { + throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain " + domainId); + } + } + } else { + owner = ctxAccount; + } + } else { + owner = ctxAccount; + } + + if (owner.getId() == Account.ACCOUNT_ID_SYSTEM && !networkOffering.isShared()) { + throw new InvalidParameterValueException("Non-system account is required when create a network from Dedicated network offering with id=" + networkOfferingId); + } + + //VlanId can be specified only when network offering supports it + if (vlanId != null && !networkOffering.getSpecifyVlan()) { + throw new InvalidParameterValueException("Can't specify vlan because network offering doesn't support it"); + } + + //If gateway, startIp, endIp are speicified, cidr should be present as well + if (gateway != null && startIP != null && endIP != null && cidr == null) { + throw new InvalidParameterValueException("Cidr is missing"); + } + + Transaction txn = Transaction.currentTxn(); + txn.start(); + try { + //Create network + DataCenterDeployment plan = new DataCenterDeployment(zoneId, null, null, null); + NetworkVO userNetwork = new NetworkVO(); + + //cidr should be set only when the user is admin + if (ctxAccount.getType() == Account.ACCOUNT_TYPE_ADMIN && cidr != null && gateway != null) { + userNetwork.setCidr(cidr); + userNetwork.setGateway(gateway); + if (vlanId != null) { + userNetwork.setBroadcastUri(URI.create("vlan://" + vlanId)); + } + } + + List networks = setupNetworkConfiguration(owner, networkOffering, userNetwork, plan, name, displayText); + Long networkId = null; + + if (networks == null || networks.isEmpty()) { + txn.rollback(); + throw new CloudRuntimeException("Fail to create a network"); + } else { + networkId = networks.get(0).getId(); + } + + //If network offering is shared, don't pass owner account and networkOfferingId for vlan + if (networkOffering.isShared()) { + owner = null; + } + + if (ctxAccount.getType() == Account.ACCOUNT_TYPE_ADMIN && networkOffering.getGuestIpType() != GuestIpType.Virtualized && startIP != null && endIP != null && gateway != null) { + //Create vlan ip range + Vlan vlan = _configMgr.createVlanAndPublicIpRange(userId, zoneId, podId, startIP, endIP, gateway, vlanNetmask, false, vlanId, owner, networkId); + if (vlan == null) { + txn.rollback(); + throw new CloudRuntimeException("Fail to create a vlan"); + } + } + txn.commit(); + return networks.get(0); + } catch (Exception ex) { + s_logger.warn("Unexpected exception while creating network ", ex); + txn.rollback(); + }finally { + txn.close(); + } + return null; + } + + @Override + public List searchForNetworks(ListNetworksCmd cmd) { + Object id = cmd.getId(); + Object keyword = cmd.getKeyword(); + Account account = UserContext.current().getAccount(); + Long domainId = cmd.getDomainId(); + String accountName = cmd.getAccountName(); + Long accountId = null; + if (isAdmin(account.getType())) { + if (domainId != null) { + if ((account != null) && !_domainDao.isChildDomain(account.getDomainId(), domainId)) { + throw new PermissionDeniedException("Invalid domain id (" + domainId + ") given, unable to list networks"); + } + + if (accountName != null) { + account = _accountDao.findActiveAccount(accountName, domainId); + if (account == null) { + throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain " + domainId); + } + accountId = account.getId(); + } + } + } else { + accountId = account.getId(); + } + + + Filter searchFilter = new Filter(NetworkVO.class, "id", false, cmd.getStartIndex(), cmd.getPageSizeVal()); + SearchCriteria sc = _networkConfigDao.createSearchCriteria(); + + if (keyword != null) { + SearchCriteria ssc = _networkConfigDao.createSearchCriteria(); + ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%"); + sc.addAnd("name", SearchCriteria.Op.SC, ssc); + } + + if (id != null) { + sc.addAnd("id", SearchCriteria.Op.EQ, id); + } + + if (accountId != null) { + sc.addAnd("accountId", SearchCriteria.Op.EQ, accountId); + } + return _networkConfigDao.search(sc, searchFilter); + } + + @Override @DB + public boolean deleteNetwork(DeleteNetworkCmd cmd) throws InvalidParameterValueException, PermissionDeniedException{ + Long networkId = cmd.getId(); + Long userId = UserContext.current().getUserId(); + Account account = UserContext.current().getAccount(); + + //Verify network id + NetworkVO network = _networkConfigDao.findById(networkId); + if (network == null) { + throw new InvalidParameterValueException("unable to find network " + networkId); + } + + //Perform permission check + if (account != null) { + if (!isAdmin(account.getType())) { + if (network.getAccountId() != account.getId()) { + throw new PermissionDeniedException("Account " + account.getAccountName() + " does not own network id=" + networkId + ", permission denied"); + } + } else if (!(account.getType() == Account.ACCOUNT_TYPE_ADMIN) && !_domainDao.isChildDomain(account.getDomainId(), _accountDao.findById(network.getAccountId()).getId())) { + throw new PermissionDeniedException("Unable to delete network " + networkId + ", permission denied."); + } + } + + //Don't allow to remove network if there are non-destroyed vms using it + List nics = _nicDao.listByNetworkId(networkId); + for (NicVO nic : nics) { + UserVm vm = _vmDao.findById(nic.getId()); + if (vm.getState() != State.Destroyed || vm.getState() != State.Expunging || vm.getState() != State.Error) { + throw new CloudRuntimeException("Can't delete a network; make sure that all vms using the network are destroyed"); + } + } + + //for regular user don't allow to remove network when it's in any other states but allocated + if (account.getType() != Account.ACCOUNT_TYPE_ADMIN) { + if (network.getState() != Network.State.Allocated) { + throw new InvalidParameterValueException("Non-admin user can delete network in " + Network.State.Allocated + " state only."); + } + } else { + if (!(network.getState() == Network.State.Allocated || network.getState() == Network.State.Setup)) { + throw new InvalidParameterValueException("Can delete network in " + Network.State.Allocated + " and " + Network.State.Setup + " states only."); + } + } + + //remove all the vlans associated with the network + Transaction txn = Transaction.currentTxn(); + try { + //remove corresponding vlans + List vlans = _vlanDao.listVlansByNetworkId(networkId); + for (VlanVO vlan : vlans) { + boolean result = _configMgr.deleteVlanAndPublicIpRange(userId, vlan.getId()); + if (result == false) { + txn.rollback(); + throw new CloudRuntimeException("Unable to delete a network: failed to delete corresponding vlan with id " + vlan.getId()); + } + } + + //remove networks + _networkConfigDao.remove(networkId); + + txn.commit(); + return true; + } catch (Exception ex) { + txn.rollback(); + s_logger.warn("Unexpected exception during deleting a network ", ex); + return false; + } finally { + txn.close(); + } + + } } diff --git a/server/src/com/cloud/network/NetworkVO.java b/server/src/com/cloud/network/NetworkVO.java index 8f5f838eee6..d99d06369e4 100644 --- a/server/src/com/cloud/network/NetworkVO.java +++ b/server/src/com/cloud/network/NetworkVO.java @@ -62,6 +62,12 @@ public class NetworkVO implements Network { @Column(name="guest_type") GuestIpType guestType; + @Column(name="name") + String name; + + @Column(name="display_text") + String displayText;; + @Column(name="broadcast_uri") URI broadcastUri; @@ -131,12 +137,13 @@ public class NetworkVO implements Network { this.guestType = guestType; } - public NetworkVO(long id, Network that, long offeringId, long dataCenterId, String guruName, long domainId, long accountId, long related) { - this(id, that.getTrafficType(), that.getGuestType(), that.getMode(), that.getBroadcastDomainType(), offeringId, dataCenterId, domainId, accountId, related); + public NetworkVO(long id, Network that, long offeringId, long dataCenterId, String guruName, long domainId, long accountId, long related, String name, String displayText) { + this(id, that.getTrafficType(), that.getGuestType(), that.getMode(), that.getBroadcastDomainType(), offeringId, dataCenterId, domainId, accountId, related, name, displayText); this.gateway = that.getGateway(); this.dns1 = that.getDns1(); this.dns2 = that.getDns2(); this.cidr = that.getCidr(); + this.broadcastUri = that.getBroadcastUri(); this.guruName = guruName; this.state = that.getState(); if (state == null) { @@ -153,13 +160,17 @@ public class NetworkVO implements Network { * @param dataCenterId * @param domainId * @param accountId + * @param name + * @param displayText */ - public NetworkVO(long id, TrafficType trafficType, GuestIpType guestType, Mode mode, BroadcastDomainType broadcastDomainType, long networkOfferingId, long dataCenterId, long domainId, long accountId, long related) { + public NetworkVO(long id, TrafficType trafficType, GuestIpType guestType, Mode mode, BroadcastDomainType broadcastDomainType, long networkOfferingId, long dataCenterId, long domainId, long accountId, long related, String name, String displayText) { this(trafficType, guestType, mode, broadcastDomainType, networkOfferingId, dataCenterId); this.domainId = domainId; this.accountId = accountId; this.related = related; this.id = id; + this.name = name; + this.displayText = displayText; } @Override @@ -299,8 +310,24 @@ public class NetworkVO implements Network { this.dns2 = dns; } + @Override + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } - + @Override + public String getDisplayText() { + return displayText; + } + + public void setDisplayText(String displayText) { + this.displayText = displayText; + } + @Override public boolean equals(Object obj) { if (!(obj instanceof NetworkVO)) { diff --git a/server/src/com/cloud/network/configuration/GuestNetworkGuru.java b/server/src/com/cloud/network/configuration/GuestNetworkGuru.java index 96311314f45..e134aca6033 100644 --- a/server/src/com/cloud/network/configuration/GuestNetworkGuru.java +++ b/server/src/com/cloud/network/configuration/GuestNetworkGuru.java @@ -101,10 +101,11 @@ public class GuestNetworkGuru extends AdapterBase implements NetworkGuru { String[] cidrTuple = guestNetworkCidr.split("\\/"); config.setGateway(NetUtils.getIpRangeStartIpFromCidr(cidrTuple[0], Long.parseLong(cidrTuple[1]))); config.setCidr(guestNetworkCidr); - config.setDns1(dc.getDns1()); - config.setDns2(dc.getDns2()); } + config.setDns1(dc.getDns1()); + config.setDns2(dc.getDns2()); + if (userSpecified.getBroadcastUri() != null) { config.setBroadcastUri(userSpecified.getBroadcastUri()); config.setState(State.Setup); diff --git a/server/src/com/cloud/network/configuration/PublicNetworkGuru.java b/server/src/com/cloud/network/configuration/PublicNetworkGuru.java index 45cae3ec1f2..6a3c903513a 100644 --- a/server/src/com/cloud/network/configuration/PublicNetworkGuru.java +++ b/server/src/com/cloud/network/configuration/PublicNetworkGuru.java @@ -16,14 +16,14 @@ import com.cloud.deploy.DeployDestination; import com.cloud.deploy.DeploymentPlan; import com.cloud.exception.InsufficientAddressCapacityException; import com.cloud.exception.InsufficientVirtualNetworkCapcityException; +import com.cloud.network.Network; +import com.cloud.network.NetworkManager; +import com.cloud.network.NetworkVO; import com.cloud.network.Networks.AddressFormat; import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.Networks.IsolationType; import com.cloud.network.Networks.Mode; import com.cloud.network.Networks.TrafficType; -import com.cloud.network.Network; -import com.cloud.network.NetworkVO; -import com.cloud.network.NetworkManager; import com.cloud.network.dao.IPAddressDao; import com.cloud.offering.NetworkOffering; import com.cloud.resource.Resource.ReservationStrategy; @@ -87,8 +87,6 @@ public class PublicNetworkGuru extends AdapterBase implements NetworkGuru { if (nic == null) { nic = new NicProfile(ReservationStrategy.Create, null, null, null, null); - } else { - nic.setStrategy(ReservationStrategy.Create); } String mac = _networkMgr.getNextAvailableMacAddressInNetwork(config.getId()); @@ -97,6 +95,12 @@ public class PublicNetworkGuru extends AdapterBase implements NetworkGuru { DataCenter dc = _dcDao.findById(config.getDataCenterId()); getIp(nic, dc, vm); + if (nic.getIp4Address() == null) { + nic.setStrategy(ReservationStrategy.Start); + } else { + nic.setStrategy(ReservationStrategy.Create); + } + return nic; } @@ -104,7 +108,7 @@ public class PublicNetworkGuru extends AdapterBase implements NetworkGuru { public void reserve(NicProfile nic, Network configuration, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException { if (nic.getIp4Address() == null) { getIp(nic, dest.getDataCenter(), vm); - } + } } @Override diff --git a/server/src/com/cloud/network/dao/FirewallRulesDao.java b/server/src/com/cloud/network/dao/FirewallRulesDao.java index d9247c36fdf..62cb4bde12e 100644 --- a/server/src/com/cloud/network/dao/FirewallRulesDao.java +++ b/server/src/com/cloud/network/dao/FirewallRulesDao.java @@ -49,9 +49,9 @@ public interface FirewallRulesDao extends GenericDao { public List listByLoadBalancerId(long loadBalancerId); public List listForwardingByPubAndPrivIp(boolean forwarding, String publicIPAddress, String privateIp); public FirewallRuleVO findByGroupAndPrivateIp(long groupId, String privateIp, boolean forwarding); - public List findByPublicIpPrivateIpForNatRule(String publicIp,String privateIp); public List listByPrivateIp(String privateIp); public boolean isPublicIpOneToOneNATted(String publicIp); void deleteIPForwardingByPublicIpAndPort(String ipAddress, String port); - public List listIPForwardingForLB(long userId, long dcId); + public List listIPForwardingForLB(long userId, long dcId); + public List findRuleByPublicIp(String publicIp); } diff --git a/server/src/com/cloud/network/dao/FirewallRulesDaoImpl.java b/server/src/com/cloud/network/dao/FirewallRulesDaoImpl.java index cd83a38d661..8a2033d7cea 100644 --- a/server/src/com/cloud/network/dao/FirewallRulesDaoImpl.java +++ b/server/src/com/cloud/network/dao/FirewallRulesDaoImpl.java @@ -64,7 +64,7 @@ public class FirewallRulesDaoImpl extends GenericDaoBase i protected SearchBuilder FWByIpForLB; protected SearchBuilder FWByGroupAndPrivateIp; - protected SearchBuilder FWByPrivateIpPrivatePortPublicIpPublicPortSearch; + protected SearchBuilder FWByPublicIpSearch; protected SearchBuilder OneToOneNATSearch; @@ -141,12 +141,9 @@ public class FirewallRulesDaoImpl extends GenericDaoBase i FWByGroupAndPrivateIp.and("forwarding", FWByGroupAndPrivateIp.entity().isForwarding(), SearchCriteria.Op.EQ); FWByGroupAndPrivateIp.done(); - FWByPrivateIpPrivatePortPublicIpPublicPortSearch = createSearchBuilder(); - FWByPrivateIpPrivatePortPublicIpPublicPortSearch.and("publicIpAddress", FWByPrivateIpPrivatePortPublicIpPublicPortSearch.entity().getPublicIpAddress(), SearchCriteria.Op.EQ); - FWByPrivateIpPrivatePortPublicIpPublicPortSearch.and("privateIpAddress", FWByPrivateIpPrivatePortPublicIpPublicPortSearch.entity().getPrivateIpAddress(), SearchCriteria.Op.EQ); - FWByPrivateIpPrivatePortPublicIpPublicPortSearch.and("privatePort", FWByPrivateIpPrivatePortPublicIpPublicPortSearch.entity().getPrivatePort(), SearchCriteria.Op.NULL); - FWByPrivateIpPrivatePortPublicIpPublicPortSearch.and("publicPort", FWByPrivateIpPrivatePortPublicIpPublicPortSearch.entity().getPublicPort(), SearchCriteria.Op.NULL); - FWByPrivateIpPrivatePortPublicIpPublicPortSearch.done(); + FWByPublicIpSearch = createSearchBuilder(); + FWByPublicIpSearch.and("publicIpAddress", FWByPublicIpSearch.entity().getPublicIpAddress(), SearchCriteria.Op.EQ); + FWByPublicIpSearch.done(); OneToOneNATSearch = createSearchBuilder(); OneToOneNATSearch.and("publicIpAddress", OneToOneNATSearch.entity().getPublicIpAddress(), SearchCriteria.Op.EQ); @@ -363,10 +360,9 @@ public class FirewallRulesDaoImpl extends GenericDaoBase i } @Override - public List findByPublicIpPrivateIpForNatRule(String publicIp, String privateIp){ - SearchCriteria sc = FWByPrivateIpPrivatePortPublicIpPublicPortSearch.create(); + public List findRuleByPublicIp(String publicIp){ + SearchCriteria sc = FWByPublicIpSearch.create(); sc.setParameters("publicIpAddress", publicIp); - sc.setParameters("privateIpAddress", privateIp); return listBy(sc); } diff --git a/server/src/com/cloud/network/router/DomainRouterManagerImpl.java b/server/src/com/cloud/network/router/DomainRouterManagerImpl.java index aa6a90c51f1..1206f070a56 100644 --- a/server/src/com/cloud/network/router/DomainRouterManagerImpl.java +++ b/server/src/com/cloud/network/router/DomainRouterManagerImpl.java @@ -2047,7 +2047,7 @@ public class DomainRouterManagerImpl implements DomainRouterManager, DomainRoute if (s_logger.isDebugEnabled()) { s_logger.debug("Starting a router for network configurations: virtual=" + guestConfig + " in " + dest); } - assert guestConfig.getState() == Network.State.Implemented : "Network is not yet fully implemented: " + guestConfig; + assert guestConfig.getState() == Network.State.Implemented || guestConfig.getState() == Network.State.Setup : "Network is not yet fully implemented: " + guestConfig; assert guestConfig.getTrafficType() == TrafficType.Guest; DataCenterDeployment plan = new DataCenterDeployment(dcId); @@ -2068,11 +2068,11 @@ public class DomainRouterManagerImpl implements DomainRouterManager, DomainRoute List offerings = _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemVmControlNetwork); NetworkOfferingVO controlOffering = offerings.get(0); - NetworkVO controlConfig = _networkMgr.setupNetworkConfiguration(_systemAcct, controlOffering, plan).get(0); + NetworkVO controlConfig = _networkMgr.setupNetworkConfiguration(_systemAcct, controlOffering, plan, null, null).get(0); List> networks = new ArrayList>(3); NetworkOfferingVO publicOffering = _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemVmPublicNetwork).get(0); - List publicConfigs = _networkMgr.setupNetworkConfiguration(_systemAcct, publicOffering, plan); + List publicConfigs = _networkMgr.setupNetworkConfiguration(_systemAcct, publicOffering, plan, null, null); NicProfile defaultNic = new NicProfile(); defaultNic.setDefaultNic(true); //defaultNic.setIp4Address(sourceNatIp); diff --git a/server/src/com/cloud/offerings/NetworkOfferingVO.java b/server/src/com/cloud/offerings/NetworkOfferingVO.java index b7fa1c8002a..f758a66d658 100644 --- a/server/src/com/cloud/offerings/NetworkOfferingVO.java +++ b/server/src/com/cloud/offerings/NetworkOfferingVO.java @@ -81,6 +81,12 @@ public class NetworkOfferingVO implements NetworkOffering { @Column(name="tags") String tags; + @Column(name="shared") + boolean isShared; + + @Column(name="default") + boolean isDefault; + @Column(name=GenericDao.REMOVED_COLUMN) Date removed; @@ -134,14 +140,6 @@ public class NetworkOfferingVO implements NetworkOffering { return removed; } - public Long getServiceOfferingId() { - return serviceOfferingId; - } - - public void setServiceOfferingId(long serviceOfferingId) { - this.serviceOfferingId = serviceOfferingId; - } - @Override public Integer getConcurrentConnections() { return concurrentConnections; @@ -190,14 +188,33 @@ public class NetworkOfferingVO implements NetworkOffering { this.systemOnly = systemOnly; } - public void setServiceOfferingId(Long serviceOfferingId) { - this.serviceOfferingId = serviceOfferingId; - } public void setRemoved(Date removed) { this.removed = removed; } + public Long getServiceOfferingId() { + return serviceOfferingId; + } + + public void setServiceOfferingId(long serviceOfferingId) { + this.serviceOfferingId = serviceOfferingId; + } + + @Override + public boolean isShared() { + return isShared; + } + + public void setShared(boolean isShared) { + this.isShared = isShared; + } + + @Override + public boolean isDefault() { + return isDefault; + } + @Override public boolean getSpecifyVlan() { return specifyVlan; @@ -207,7 +224,7 @@ public class NetworkOfferingVO implements NetworkOffering { this.created = created; } - public NetworkOfferingVO(String name, String displayText, TrafficType trafficType, GuestIpType type, boolean systemOnly, boolean specifyVlan, Integer rateMbps, Integer multicastRateMbps, Integer concurrentConnections) { + public NetworkOfferingVO(String name, String displayText, TrafficType trafficType, GuestIpType type, boolean systemOnly, boolean specifyVlan, Integer rateMbps, Integer multicastRateMbps, Integer concurrentConnections, boolean isShared, boolean isDefault) { this.name = name; this.displayText = displayText; this.guestIpType = type; @@ -217,13 +234,16 @@ public class NetworkOfferingVO implements NetworkOffering { this.trafficType = trafficType; this.systemOnly = systemOnly; this.specifyVlan = specifyVlan; + this.isDefault = isDefault; + this.isShared = isShared; } public NetworkOfferingVO(ServiceOfferingVO offering) { - this("Network Offering for " + offering.getName(), "Network Offering for " + offering.getDisplayText(), TrafficType.Guest, offering.getGuestIpType(), false, false, offering.getRateMbps(), offering.getMulticastRateMbps(), null); + this("Network Offering for " + offering.getName(), "Network Offering for " + offering.getDisplayText(), TrafficType.Guest, offering.getGuestIpType(), false, false, offering.getRateMbps(), offering.getMulticastRateMbps(), null, false, false); this.serviceOfferingId = offering.getId(); } + /** * Network Offering for all system vms. * @param name @@ -231,7 +251,7 @@ public class NetworkOfferingVO implements NetworkOffering { * @param type */ public NetworkOfferingVO(String name, TrafficType trafficType, GuestIpType type) { - this(name, "System Offering for " + name, trafficType, type, true, false, null, null, null); + this(name, "System Offering for " + name, trafficType, type, true, false, null, null, null, false, false); } @Override diff --git a/server/src/com/cloud/server/ManagementServer.java b/server/src/com/cloud/server/ManagementServer.java index a7f9b141e46..c5a0034b556 100755 --- a/server/src/com/cloud/server/ManagementServer.java +++ b/server/src/com/cloud/server/ManagementServer.java @@ -503,13 +503,6 @@ public interface ManagementServer extends ManagementService { public long getMemoryUsagebyHost(Long hostId); - /** - * Destroy a snapshot - * @param snapshotId the id of the snapshot to destroy - * @return true if snapshot successfully destroyed, false otherwise - */ - boolean destroyTemplateSnapshot(Long userId, long snapshotId); - /** * Finds a diskOffering by the specified ID. * @param diskOfferingId @@ -547,8 +540,6 @@ public interface ManagementServer extends ManagementService { StoragePoolVO findPoolById(Long id); List searchForStoragePools(Criteria c); - SnapshotPolicyVO findSnapshotPolicyById(Long policyId); - /** * Return whether a domain is a child domain of a given domain. * @param parentId diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index 47e5b75ed7f..573153e2b2f 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -107,7 +107,6 @@ import com.cloud.api.commands.ListPublicIpAddressesCmd; import com.cloud.api.commands.ListRemoteAccessVpnsCmd; import com.cloud.api.commands.ListRoutersCmd; import com.cloud.api.commands.ListServiceOfferingsCmd; -import com.cloud.api.commands.ListSnapshotsCmd; import com.cloud.api.commands.ListStoragePoolsCmd; import com.cloud.api.commands.ListSystemVMsCmd; import com.cloud.api.commands.ListTemplateOrIsoPermissionsCmd; @@ -218,10 +217,6 @@ import com.cloud.storage.DiskOfferingVO; import com.cloud.storage.GuestOSCategoryVO; import com.cloud.storage.GuestOSVO; import com.cloud.storage.LaunchPermissionVO; -import com.cloud.storage.Snapshot; -import com.cloud.storage.Snapshot.Type; -import com.cloud.storage.SnapshotPolicyVO; -import com.cloud.storage.SnapshotVO; import com.cloud.storage.Storage; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.TemplateType; @@ -234,15 +229,12 @@ import com.cloud.storage.Upload.Mode; import com.cloud.storage.UploadVO; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.Volume; -import com.cloud.storage.Volume.VolumeType; import com.cloud.storage.VolumeStats; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.DiskOfferingDao; import com.cloud.storage.dao.GuestOSCategoryDao; import com.cloud.storage.dao.GuestOSDao; import com.cloud.storage.dao.LaunchPermissionDao; -import com.cloud.storage.dao.SnapshotDao; -import com.cloud.storage.dao.SnapshotPolicyDao; import com.cloud.storage.dao.StoragePoolDao; import com.cloud.storage.dao.StoragePoolHostDao; import com.cloud.storage.dao.UploadDao; @@ -346,8 +338,6 @@ public class ManagementServerImpl implements ManagementServer { private final UserAccountDao _userAccountDao; private final AlertDao _alertDao; private final CapacityDao _capacityDao; - private final SnapshotDao _snapshotDao; - private final SnapshotPolicyDao _snapshotPolicyDao; private final GuestOSDao _guestOSDao; private final GuestOSCategoryDao _guestOSCategoryDao; private final StoragePoolDao _poolDao; @@ -443,8 +433,6 @@ public class ManagementServerImpl implements ManagementServer { _userAccountDao = locator.getDao(UserAccountDao.class); _alertDao = locator.getDao(AlertDao.class); _capacityDao = locator.getDao(CapacityDao.class); - _snapshotDao = locator.getDao(SnapshotDao.class); - _snapshotPolicyDao = locator.getDao(SnapshotPolicyDao.class); _guestOSDao = locator.getDao(GuestOSDao.class); _guestOSCategoryDao = locator.getDao(GuestOSCategoryDao.class); _poolDao = locator.getDao(StoragePoolDao.class); @@ -2553,18 +2541,136 @@ public class ManagementServerImpl implements ManagementServer { @Override public List searchForIpForwardingRules(ListIpForwardingRulesCmd cmd){ + //Note:: + //The following was decided after discussing with Will + //ListIpForwardingRules with no params lists the rules for that user ; with a listAll() for admin + //ListIpForwardingRules with accountName and domainId lists the rule for that account (provided the executing user has the right perms) + //ListIpForwardingRules with ipAddress lists the rule for that ip address (provided the executing user has the right perms) + String ipAddress = cmd.getPublicIpAddress(); - Filter searchFilter = new Filter(FirewallRuleVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal()); - SearchCriteria sc = _firewallRulesDao.createSearchCriteria(); - - if (ipAddress != null) { - sc.addAnd("publicIpAddress", SearchCriteria.Op.EQ, ipAddress); + String accountName = cmd.getAccountName(); + Long domainId = cmd.getDomainId(); + Account account = null; + + if((accountName != null && domainId == null) || (accountName == null && domainId != null)){ + throw new ServerApiException(BaseCmd.PARAM_ERROR, "Account name and domain id both have to be passed as a tuple"); } - //search for rules with protocol = nat - sc.addAnd("protocol", SearchCriteria.Op.EQ, NetUtils.NAT_PROTO); + if(accountName != null && domainId != null && ipAddress != null){ + throw new ServerApiException(BaseCmd.PARAM_ERROR, "Either Account name and domain id both have to be passed as a tuple; or the ip address has to be passed whilst searching"); + } + + //account and domainId both provided case + if(accountName != null && domainId != null){ + account = _accountDao.findAccount(accountName, domainId); + if(account == null) + throw new ServerApiException(BaseCmd.ACCOUNT_ERROR, "Specified account for domainId:"+domainId+" account name:"+accountName+" doesn't exist"); + else{ + //get the ctxaccount to see if he has permissions + Account ctxAccount = UserContext.current().getAccount(); + + if(!isChildDomain(ctxAccount.getDomainId(), account.getDomainId())){ + throw new PermissionDeniedException("Unable to list ip forwarding rules for address " + ipAddress + ", permission denied for the executing account: " + ctxAccount.getId()+" to view rules for account: "+account.getId()); + } + + Filter searchFilter = new Filter(FirewallRuleVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal()); + SearchBuilder sb = _firewallRulesDao.createSearchBuilder(); + + SearchBuilder sb1 = _publicIpAddressDao.createSearchBuilder(); + sb1.and("accountId", sb1.entity().getAccountId(), SearchCriteria.Op.EQ); + sb1.and("oneToOneNat", sb1.entity().isOneToOneNat(), SearchCriteria.Op.EQ); + sb.join("sb1", sb1, sb.entity().getPublicIpAddress(),sb1.entity().getAddress(), JoinBuilder.JoinType.INNER); + + SearchCriteria sc = sb.create(); + sc.setJoinParameters("sb1","oneToOneNat", new Long(1)); + sc.setJoinParameters("sb1", "accountId", account.getId()); + + return _firewallRulesDao.search(sc, searchFilter); + } + } - return _firewallRulesDao.search(sc, searchFilter); + if(account == null){ + account = UserContext.current().getAccount();//use user context + } + + if(account == null || account.getType() == Account.ACCOUNT_TYPE_ADMIN){ + return searchIpForwardingRulesInternal(ipAddress, cmd, null, Account.ACCOUNT_TYPE_ADMIN); + } + + if((account.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN)){ + if(ipAddress != null){ + IPAddressVO ipAddressVO = _publicIpAddressDao.findById(ipAddress); + if (ipAddressVO == null) { + throw new InvalidParameterValueException("Unable to find IP address " + ipAddress); + }else{ + //check permissions + Account addrOwner = _accountDao.findById(ipAddressVO.getAccountId()); + if ((addrOwner != null) && !_domainDao.isChildDomain(account.getDomainId(), addrOwner.getDomainId())) { + throw new PermissionDeniedException("Unable to list ip forwarding rule for address " + ipAddress + ", permission denied for account " + account.getId()); + }else{ + return searchIpForwardingRulesInternal(ipAddress, cmd, null, Account.ACCOUNT_TYPE_DOMAIN_ADMIN); + } + } + }else{ + //need to list all rules visible to the domain admin + //join with the ip_address table where account_id = user's account id + return searchIpForwardingRulesInternal(ipAddress, cmd, account.getId(), Account.ACCOUNT_TYPE_DOMAIN_ADMIN); + } + } + + if(account.getType() == Account.ACCOUNT_TYPE_NORMAL){ + if(ipAddress != null){ + IPAddressVO ipAddressVO = _publicIpAddressDao.findById(ipAddress); + if (ipAddressVO == null) { + throw new InvalidParameterValueException("Unable to find IP address " + ipAddress); + }else{ + //check permissions + if ((ipAddressVO.getAccountId() == null) || (account.getId() != ipAddressVO.getAccountId().longValue())) { + throw new PermissionDeniedException("Unable to list ip forwarding rule for address " + ipAddress + ", permission denied for account " + account.getId()); + }else{ + return searchIpForwardingRulesInternal(ipAddress, cmd, null, Account.ACCOUNT_TYPE_NORMAL); + } + } + }else{ + //need to list all rules visible to the user + //join with the ip_address table where account_id = user's account id + return searchIpForwardingRulesInternal(ipAddress, cmd, account.getId(), Account.ACCOUNT_TYPE_NORMAL); + } + } + + return new ArrayList(); + } + + private List searchIpForwardingRulesInternal(String ipAddress, ListIpForwardingRulesCmd cmd, Long accountId, short accountType){ + Filter searchFilter = new Filter(FirewallRuleVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal()); + if(accountId == null){ + SearchCriteria sc = _firewallRulesDao.createSearchCriteria(); + if (ipAddress != null) { + sc.addAnd("publicIpAddress", SearchCriteria.Op.EQ, ipAddress); + } + //search for rules with protocol = nat + sc.addAnd("protocol", SearchCriteria.Op.EQ, NetUtils.NAT_PROTO); + return _firewallRulesDao.search(sc, searchFilter); + + }else{ + //accountId and accountType both given + if((accountType == Account.ACCOUNT_TYPE_NORMAL) || (accountType == Account.ACCOUNT_TYPE_DOMAIN_ADMIN)){ + SearchBuilder sb = _firewallRulesDao.createSearchBuilder(); + + SearchBuilder sb1 = _publicIpAddressDao.createSearchBuilder(); + sb1.and("accountId", sb1.entity().getAccountId(), SearchCriteria.Op.EQ); + sb1.and("oneToOneNat", sb1.entity().isOneToOneNat(), SearchCriteria.Op.EQ); + sb.join("sb1", sb1, sb.entity().getPublicIpAddress(),sb1.entity().getAddress(), JoinBuilder.JoinType.INNER); + + SearchCriteria sc = sb.create(); + sc.setJoinParameters("sb1","oneToOneNat", new Long(1)); + sc.setJoinParameters("sb1", "accountId", accountId); + + return _firewallRulesDao.search(sc, searchFilter); + } + } + + return new ArrayList(); } @Override @@ -4003,117 +4109,6 @@ public class ManagementServerImpl implements ManagementServer { return mem; } - @Override - public boolean destroyTemplateSnapshot(Long userId, long snapshotId) { - return _vmMgr.destroyTemplateSnapshot(userId, snapshotId); - } - - @Override - public List listSnapshots(ListSnapshotsCmd cmd) throws InvalidParameterValueException, PermissionDeniedException { - Long volumeId = cmd.getVolumeId(); - - // Verify parameters - if(volumeId != null){ - VolumeVO volume = _volumeDao.findById(volumeId); - if (volume == null) { - throw new InvalidParameterValueException("unable to find a volume with id " + volumeId); - } - checkAccountPermissions(volume.getAccountId(), volume.getDomainId(), "volume", volumeId); - } - - Account account = UserContext.current().getAccount(); - Long domainId = cmd.getDomainId(); - String accountName = cmd.getAccountName(); - Long accountId = null; - if ((account == null) || isAdmin(account.getType())) { - if (domainId != null) { - if ((account != null) && !_domainDao.isChildDomain(account.getDomainId(), domainId)) { - throw new PermissionDeniedException("Unable to list templates for domain " + domainId + ", permission denied."); - } - } else if ((account != null) && (account.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN)) { - domainId = account.getDomainId(); - } - - if (domainId != null && accountName != null) { - Account userAccount = _accountDao.findActiveAccount(accountName, domainId); - if (userAccount != null) { - accountId = userAccount.getId(); - } - } - } else { - accountId = account.getId(); - } - - Object name = cmd.getSnapshotName(); - Object id = cmd.getId(); - Object keyword = cmd.getKeyword(); - Object snapshotTypeStr = cmd.getSnapshotType(); - - Filter searchFilter = new Filter(SnapshotVO.class, "created", false, cmd.getStartIndex(), cmd.getPageSizeVal()); - SearchBuilder sb = _snapshotDao.createSearchBuilder(); - sb.and("status", sb.entity().getStatus(), SearchCriteria.Op.EQ); - sb.and("volumeId", sb.entity().getVolumeId(), SearchCriteria.Op.EQ); - sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE); - sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); - sb.and("accountId", sb.entity().getAccountId(), SearchCriteria.Op.EQ); - sb.and("snapshotTypeEQ", sb.entity().getSnapshotType(), SearchCriteria.Op.EQ); - sb.and("snapshotTypeNEQ", sb.entity().getSnapshotType(), SearchCriteria.Op.NEQ); - - if ((accountId == null) && (domainId != null)) { - // if accountId isn't specified, we can do a domain match for the admin case - SearchBuilder accountSearch = _accountDao.createSearchBuilder(); - sb.join("accountSearch", accountSearch, sb.entity().getAccountId(), accountSearch.entity().getId(), JoinType.INNER); - - SearchBuilder domainSearch = _domainDao.createSearchBuilder(); - domainSearch.and("path", domainSearch.entity().getPath(), SearchCriteria.Op.LIKE); - accountSearch.join("domainSearch", domainSearch, accountSearch.entity().getDomainId(), domainSearch.entity().getId(), JoinType.INNER); - } - - SearchCriteria sc = sb.create(); - - sc.setParameters("status", Snapshot.Status.BackedUp); - - if (volumeId != null) { - sc.setParameters("volumeId", volumeId); - } - - if (name != null) { - sc.setParameters("name", "%" + name + "%"); - } - - if (id != null) { - sc.setParameters("id", id); - } - - if (keyword != null) { - SearchCriteria ssc = _snapshotDao.createSearchCriteria(); - ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%"); - - sc.addAnd("name", SearchCriteria.Op.SC, ssc); - } - - if (accountId != null) { - sc.setParameters("accountId", accountId); - } else if (domainId != null) { - DomainVO domain = _domainDao.findById(domainId); - SearchCriteria joinSearch = sc.getJoin("accountSearch"); - joinSearch.setJoinParameters("domainSearch", "path", domain.getPath() + "%"); - } - - if (snapshotTypeStr != null) { - Type snapshotType = SnapshotVO.getSnapshotType((String)snapshotTypeStr); - if (snapshotType == null) { - throw new InvalidParameterValueException("Unsupported snapshot type " + snapshotTypeStr); - } - sc.setParameters("snapshotTypeEQ", snapshotType.ordinal()); - } else { - // Show only MANUAL and RECURRING snapshot types - sc.setParameters("snapshotTypeNEQ", Snapshot.Type.TEMPLATE.ordinal()); - } - - return _snapshotDao.search(sc, searchFilter); - } - @Override public DiskOfferingVO findDiskOfferingById(long diskOfferingId) { return _diskOfferingDao.findById(diskOfferingId); @@ -4964,11 +4959,6 @@ public class ManagementServerImpl implements ManagementServer { return _jobDao.search(sc, searchFilter); } - @Override - public SnapshotPolicyVO findSnapshotPolicyById(Long policyId) { - return _snapshotPolicyDao.findById(policyId); - } - @Override public boolean isChildDomain(Long parentId, Long childId) { return _domainDao.isChildDomain(parentId, childId); @@ -5143,25 +5133,6 @@ public class ManagementServerImpl implements ManagementServer { return stopSecondaryStorageVm(vmId, eventId); } } - - private void checkIfStoragePoolAvailable(Long id) throws StorageUnavailableException { - //check if the sp is up before starting - List rootVolList = _volumeDao.findByInstanceAndType(id, VolumeType.ROOT); - if(rootVolList == null || rootVolList.size() == 0){ - throw new StorageUnavailableException("Could not find the root disk for this vm to verify if the pool on which it exists is Up or not"); - }else{ - Long poolId = rootVolList.get(0).getPoolId();//each vm has 1 root vol - StoragePoolVO sp = _poolDao.findById(poolId); - if(sp == null){ - throw new StorageUnavailableException("Could not find the pool for the root disk of vm"+id+", to confirm if it is Up or not"); - }else{ - //found pool - if(!sp.getStatus().equals(com.cloud.host.Status.Up)){ - throw new StorageUnavailableException("Could not start the vm; the associated storage pool is in:"+sp.getStatus().toString()+" state"); - } - } - } - } @Override public VMInstanceVO stopSystemVM(StopSystemVmCmd cmd) { @@ -5845,25 +5816,7 @@ public class ManagementServerImpl implements ManagementServer { return hypers.split(","); } - private Long checkAccountPermissions(long targetAccountId, long targetDomainId, String targetDesc, long targetId) throws ServerApiException { - Long accountId = null; - - Account account = UserContext.current().getAccount(); - if (account != null) { - if (!isAdmin(account.getType())) { - if (account.getId() != targetAccountId) { - throw new ServerApiException(BaseCmd.PARAM_ERROR, "Unable to find a " + targetDesc + " with id " + targetId + " for this account"); - } - } else if (!_domainDao.isChildDomain(account.getDomainId(), targetDomainId)) { - throw new ServerApiException(BaseCmd.PARAM_ERROR, "Unable to perform operation for " + targetDesc + " with id " + targetId + ", permission denied."); - } - accountId = account.getId(); - } - - return accountId; - } - - @Override + @Override public List searchForRemoteAccessVpns(ListRemoteAccessVpnsCmd cmd) throws InvalidParameterValueException, PermissionDeniedException { // do some parameter validation diff --git a/server/src/com/cloud/storage/dao/SnapshotDao.java b/server/src/com/cloud/storage/dao/SnapshotDao.java index 4391add9a82..fcd6d6dd064 100644 --- a/server/src/com/cloud/storage/dao/SnapshotDao.java +++ b/server/src/com/cloud/storage/dao/SnapshotDao.java @@ -31,5 +31,6 @@ public interface SnapshotDao extends GenericDao { SnapshotVO findNextSnapshot(long parentSnapId); long getLastSnapshot(long volumeId, long snapId); List listByVolumeIdType(long volumeId, String type); + List listByVolumeIdIncludingRemoved(long volumeId); } diff --git a/server/src/com/cloud/storage/dao/SnapshotDaoImpl.java b/server/src/com/cloud/storage/dao/SnapshotDaoImpl.java index 19f5b64fde8..fe7f44dc68b 100644 --- a/server/src/com/cloud/storage/dao/SnapshotDaoImpl.java +++ b/server/src/com/cloud/storage/dao/SnapshotDaoImpl.java @@ -18,25 +18,29 @@ package com.cloud.storage.dao; +import java.sql.PreparedStatement; +import java.sql.ResultSet; import java.util.List; import javax.ejb.Local; -import com.cloud.storage.Snapshot; +import org.apache.log4j.Logger; + import com.cloud.storage.SnapshotVO; import com.cloud.utils.db.Filter; import com.cloud.utils.db.GenericDaoBase; -import com.cloud.utils.db.GenericSearchBuilder; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.Transaction; @Local (value={SnapshotDao.class}) public class SnapshotDaoImpl extends GenericDaoBase implements SnapshotDao { + public static final Logger s_logger = Logger.getLogger(SnapshotDaoImpl.class.getName()); + private static final String GET_LAST_SNAPSHOT = "SELECT id FROM snapshots where volume_id = ? AND id != ? ORDER BY created DESC"; private final SearchBuilder VolumeIdSearch; private final SearchBuilder VolumeIdTypeSearch; private final SearchBuilder ParentIdSearch; - private final GenericSearchBuilder lastSnapSearch; @Override public SnapshotVO findNextSnapshot(long snapshotId) { @@ -49,7 +53,6 @@ public class SnapshotDaoImpl extends GenericDaoBase implements public List listByVolumeIdType(long volumeId, String type ) { return listByVolumeIdType(null, volumeId, type); } - @Override public List listByVolumeId(long volumeId) { @@ -63,6 +66,12 @@ public class SnapshotDaoImpl extends GenericDaoBase implements return listBy(sc, filter); } + @Override + public List listByVolumeIdIncludingRemoved(long volumeId) { + SearchCriteria sc = VolumeIdSearch.create(); + sc.setParameters("volumeId", volumeId); + return listIncludingRemovedBy(sc, null); + } public List listByVolumeIdType(Filter filter, long volumeId, String type ) { SearchCriteria sc = VolumeIdTypeSearch.create(); @@ -84,24 +93,28 @@ public class SnapshotDaoImpl extends GenericDaoBase implements ParentIdSearch = createSearchBuilder(); ParentIdSearch.and("prevSnapshotId", ParentIdSearch.entity().getPrevSnapshotId(), SearchCriteria.Op.EQ); ParentIdSearch.done(); - - lastSnapSearch = createSearchBuilder(Long.class); - lastSnapSearch.select(null, SearchCriteria.Func.MAX, lastSnapSearch.entity().getId()); - lastSnapSearch.and("volumeId", lastSnapSearch.entity().getVolumeId(), SearchCriteria.Op.EQ); - lastSnapSearch.and("snapId", lastSnapSearch.entity().getId(), SearchCriteria.Op.NEQ); - lastSnapSearch.done(); + + } + + @Override + public long getLastSnapshot(long volumeId, long snapId) { + Transaction txn = Transaction.currentTxn(); + PreparedStatement pstmt = null; + String sql = GET_LAST_SNAPSHOT; + try { + pstmt = txn.prepareAutoCloseStatement(sql); + pstmt.setLong(1, volumeId); + pstmt.setLong(2, snapId); + ResultSet rs = pstmt.executeQuery(); + if (rs.next()) { + return rs.getLong(1); + } + } catch (Exception ex) { + s_logger.error("error getting last snapshot", ex); + } + return 0; } - @Override - public long getLastSnapshot(long volumeId, long snapId) { - SearchCriteria sc = lastSnapSearch.create(); - sc.setParameters("volumeId", volumeId); - sc.setParameters("snapId", snapId); - List prevSnapshots = searchIncludingRemoved(sc, null); - if(prevSnapshots != null && prevSnapshots.size() > 0 && prevSnapshots.get(0) != null) { - return prevSnapshots.get(0); - } - return 0; - } + } diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java index bd544fc3f05..b93bf3c15dd 100644 --- a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java +++ b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java @@ -741,9 +741,9 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V NicProfile defaultNic = new NicProfile(); defaultNic.setDefaultNic(true); defaultNic.setDeviceId(2); - networks.add(new Pair(_networkMgr.setupNetworkConfiguration(systemAcct, defaultOffering.get(0), plan).get(0), defaultNic)); + networks.add(new Pair(_networkMgr.setupNetworkConfiguration(systemAcct, defaultOffering.get(0), plan, null, null).get(0), defaultNic)); for (NetworkOfferingVO offering : offerings) { - networks.add(new Pair(_networkMgr.setupNetworkConfiguration(systemAcct, offering, plan).get(0), null)); + networks.add(new Pair(_networkMgr.setupNetworkConfiguration(systemAcct, offering, plan, null, null).get(0), null)); } SecondaryStorageVmVO secStorageVm = new SecondaryStorageVmVO(id, _serviceOffering.getId(), name, _template.getId(), _template.getGuestOSId(), dataCenterId, systemAcct.getDomainId(), systemAcct.getId()); diff --git a/server/src/com/cloud/storage/snapshot/SnapshotManager.java b/server/src/com/cloud/storage/snapshot/SnapshotManager.java index e3353074b56..02e5e573e60 100755 --- a/server/src/com/cloud/storage/snapshot/SnapshotManager.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotManager.java @@ -43,7 +43,7 @@ public interface SnapshotManager { * @param cmd the API command wrapping the parameters for creating the snapshot (mainly volumeId) * @return the Snapshot that was created */ - SnapshotVO createSnapshotImpl(Long volumeId, Long policyId, Long startEventId) throws ResourceAllocationException; + SnapshotVO createSnapshotImpl(Long volumeId, Long policyId, Long startEventId, Long snapshotId) throws ResourceAllocationException; /** * After successfully creating a snapshot of a volume, copy the snapshot to the secondary storage for @@ -127,5 +127,5 @@ public interface SnapshotManager { * @param cmd the API command wrapping the parameters for creating the snapshot (mainly volumeId) * @return the Snapshot that was created */ - SnapshotVO createSnapshotOnPrimary(VolumeVO volume, Long polocyId) throws ResourceAllocationException; + SnapshotVO createSnapshotOnPrimary(VolumeVO volume, Long polocyId, Long snapshotId) throws ResourceAllocationException; } diff --git a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java index 63a889a69ae..f53174ec99b 100755 --- a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java @@ -18,6 +18,8 @@ package com.cloud.storage.snapshot; +import java.sql.PreparedStatement; +import java.sql.ResultSet; import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -41,17 +43,18 @@ import com.cloud.agent.api.ManageSnapshotCommand; import com.cloud.api.BaseCmd; import com.cloud.api.ServerApiException; import com.cloud.api.commands.CreateSnapshotCmd; -import com.cloud.api.commands.CreateSnapshotInternalCmd; import com.cloud.api.commands.CreateSnapshotPolicyCmd; import com.cloud.api.commands.DeleteSnapshotCmd; import com.cloud.api.commands.DeleteSnapshotPoliciesCmd; import com.cloud.api.commands.ListRecurringSnapshotScheduleCmd; import com.cloud.api.commands.ListSnapshotPoliciesCmd; +import com.cloud.api.commands.ListSnapshotsCmd; import com.cloud.async.AsyncInstanceCreateStatus; import com.cloud.async.AsyncJobManager; import com.cloud.configuration.ResourceCount.ResourceType; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.dc.dao.DataCenterDao; +import com.cloud.domain.DomainVO; import com.cloud.domain.dao.DomainDao; import com.cloud.event.EventTypes; import com.cloud.event.EventUtils; @@ -60,6 +63,7 @@ import com.cloud.event.dao.EventDao; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceAllocationException; +import com.cloud.exception.UsageServerException; import com.cloud.host.dao.DetailsDao; import com.cloud.host.dao.HostDao; import com.cloud.storage.Snapshot; @@ -84,6 +88,7 @@ import com.cloud.storage.dao.VMTemplatePoolDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.user.Account; import com.cloud.user.AccountManager; +import com.cloud.user.AccountVO; import com.cloud.user.User; import com.cloud.user.UserContext; import com.cloud.user.dao.AccountDao; @@ -95,8 +100,11 @@ import com.cloud.utils.component.ComponentLocator; import com.cloud.utils.component.Inject; import com.cloud.utils.component.Manager; import com.cloud.utils.db.DB; +import com.cloud.utils.db.Filter; import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.JoinBuilder.JoinType; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.VMInstanceVO; import com.cloud.vm.dao.UserVmDao; @@ -104,6 +112,8 @@ import com.cloud.vm.dao.UserVmDao; @Local(value={SnapshotManager.class, SnapshotService.class}) public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Manager { private static final Logger s_logger = Logger.getLogger(SnapshotManagerImpl.class); + private static final String GET_LAST_ID = "SELECT id FROM cloud.snapshots ORDER BY id DESC LIMIT 1"; + private static final String UPDATE_SNAPSHOT_SEQ = "UPDATE cloud.sequence SET value=? WHERE name='snapshots_seq'"; @Inject protected HostDao _hostDao; @Inject protected UserVmDao _vmDao; @@ -143,7 +153,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma if (volume.getInstanceId() == null) { long lastSnapId = _snapshotDao.getLastSnapshot(volumeId, 0); - SnapshotVO lastSnap = _snapshotDao.findById(lastSnapId); + SnapshotVO lastSnap = _snapshotDao.findByIdIncludingRemoved(lastSnapId); if (lastSnap != null) { Date lastSnapTime = lastSnap.getCreated(); if (lastSnapTime.after(volume.getUpdated())){ @@ -154,7 +164,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma } else if (_storageMgr.volumeInactive(volume)) { // Volume is attached to a VM which is in Stopped state. long lastSnapId = _snapshotDao.getLastSnapshot(volumeId, 0); - SnapshotVO lastSnap = _snapshotDao.findById(lastSnapId); + SnapshotVO lastSnap = _snapshotDao.findByIdIncludingRemoved(lastSnapId); if (lastSnap != null) { Date lastSnapTime = lastSnap.getCreated(); VMInstanceVO vmInstance = _vmDao.findById(volume.getInstanceId()); @@ -187,7 +197,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma } @Override - public SnapshotVO createSnapshotOnPrimary(VolumeVO volume, Long policyId) throws ResourceAllocationException { + public SnapshotVO createSnapshotOnPrimary(VolumeVO volume, Long policyId, Long snapshotId) throws ResourceAllocationException { SnapshotVO createdSnapshot = null; Long volumeId = volume.getId(); if (volume.getStatus() != AsyncInstanceCreateStatus.Created) { @@ -221,7 +231,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma // Create the Snapshot object and save it so we can return it to the // user Type snapshotType = SnapshotVO.getSnapshotType(policyId); - SnapshotVO snapshotVO = new SnapshotVO(volume.getAccountId(), volume.getId(), null, snapshotName, + SnapshotVO snapshotVO = new SnapshotVO(snapshotId, volume.getAccountId(), volume.getId(), null, snapshotName, (short) snapshotType.ordinal(), snapshotType.name()); snapshotVO = _snapshotDao.persist(snapshotVO); id = snapshotVO.getId(); @@ -236,7 +246,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma SnapshotVO preSnapshotVO = null; if( preId != 0) { - preSnapshotVO = _snapshotDao.findById(preId); + preSnapshotVO = _snapshotDao.findByIdIncludingRemoved(preId); if (preSnapshotVO != null) { preSnapshotPath = preSnapshotVO.getPath(); } @@ -252,7 +262,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma if( preSnapshotPath != null && preSnapshotPath == answer.getSnapshotPath() ){ //empty snapshot s_logger.debug("CreateSnapshot: this is empty snapshot, remove it "); - createdSnapshot = _snapshotDao.findById(id); + createdSnapshot = _snapshotDao.findByIdIncludingRemoved(id); // delete from the snapshots table _snapshotDao.expunge(id); throw new CloudRuntimeException("There is no change for volume " + volumeId + " since last snapshot, please use last snapshot instead."); @@ -276,7 +286,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma if (preSSId == 0) { break; } - preSnapshotVO = _snapshotDao.findById(preSSId); + preSnapshotVO = _snapshotDao.findByIdIncludingRemoved(preSSId); } if (i >= deltaSnap) { preSnapshotId = 0; @@ -298,7 +308,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma s_logger.error(answer.getDetails()); } // The snapshot was not successfully created - createdSnapshot = _snapshotDao.findById(id); + createdSnapshot = _snapshotDao.findByIdIncludingRemoved(id); // delete from the snapshots table _snapshotDao.expunge(id); throw new CloudRuntimeException("Creating snapshot for volume " + volumeId + " on primary storage failed."); @@ -315,7 +325,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma } @Override @DB - public SnapshotVO createSnapshotImpl(Long volumeId, Long policyId, Long startEventId) throws ResourceAllocationException { + public SnapshotVO createSnapshotImpl(Long volumeId, Long policyId, Long snapshotId, Long startEventId) throws ResourceAllocationException { VolumeVO volume = _volsDao.acquireInLockTable(volumeId, 10); if( volume == null ) { volume = _volsDao.findById(volumeId); @@ -327,9 +337,8 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma } SnapshotVO snapshot = null; boolean backedUp = false; - Long snapshotId = null; try { - snapshot = createSnapshotOnPrimary(volume, policyId); + snapshot = createSnapshotOnPrimary(volume, policyId, snapshotId); if (snapshot != null && snapshot.getStatus() == Snapshot.Status.CreatedOnPrimary ) { snapshotId = snapshot.getId(); backedUp = backupSnapshotToSecondaryStorage(snapshot, startEventId); @@ -351,21 +360,14 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma @Override public SnapshotVO createSnapshot(CreateSnapshotCmd cmd) throws ResourceAllocationException { Long volumeId = cmd.getVolumeId(); - Long policyId = Snapshot.MANUAL_POLICY_ID ; + Long policyId = cmd.getPolicyId(); + Long snapshotId = cmd.getId(); Long startEventId = cmd.getStartEventId(); - return createSnapshotImpl(volumeId, policyId, startEventId); + return createSnapshotImpl(volumeId, policyId, snapshotId, startEventId); } - @Override - public SnapshotVO createSnapshotInternal(CreateSnapshotInternalCmd cmd) throws ResourceAllocationException { - Long volumeId = cmd.getVolumeId(); - Long policyId = cmd.getPolicyId(); - Long startEventId = cmd.getStartEventId(); - return createSnapshotImpl(volumeId, policyId, startEventId); - } - private SnapshotVO updateDBOnCreate(Long id, String snapshotPath, long preSnapshotId) { - SnapshotVO createdSnapshot = _snapshotDao.findById(id); + SnapshotVO createdSnapshot = _snapshotDao.findByIdIncludingRemoved(id); createdSnapshot.setPath(snapshotPath); createdSnapshot.setStatus(Snapshot.Status.CreatedOnPrimary); createdSnapshot.setPrevSnapshotId(preSnapshotId); @@ -433,7 +435,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma long prevSnapshotId = snapshot.getPrevSnapshotId(); if (prevSnapshotId > 0) { - prevSnapshot = _snapshotDao.findById(prevSnapshotId); + prevSnapshot = _snapshotDao.findByIdIncludingRemoved(prevSnapshotId); prevSnapshotUuid = prevSnapshot.getPath(); prevBackupUuid = prevSnapshot.getBackupSnapshotId(); } @@ -539,7 +541,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma // This is a manual create, so increment the count of snapshots for // this account if (policyId == Snapshot.MANUAL_POLICY_ID) { - Snapshot snapshot = _snapshotDao.findById(snapshotId); + Snapshot snapshot = _snapshotDao.findByIdIncludingRemoved(snapshotId); _accountMgr.incrementResourceCount(snapshot.getAccountId(), ResourceType.snapshot); } } @@ -601,7 +603,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma Long snapshotId = cmd.getId(); //Verify parameters - Snapshot snapshotCheck = _snapshotDao.findById(snapshotId.longValue()); + Snapshot snapshotCheck = _snapshotDao.findByIdIncludingRemoved(snapshotId.longValue()); if (snapshotCheck == null) { throw new ServerApiException (BaseCmd.PARAM_ERROR, "unable to find a snapshot with id " + snapshotId); } @@ -641,20 +643,19 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma if (s_logger.isDebugEnabled()) { s_logger.debug("Calling deleteSnapshot for snapshotId: " + snapshotId + " and policyId " + policyId); } - SnapshotVO lastSnapshot = null; _snapshotDao.remove(snapshotId); long lastId = snapshotId; boolean destroy = false; while( true ) { lastSnapshot = _snapshotDao.findNextSnapshot(lastId); - // prevsnapshotId equal 0, means it is a full snapshot if( lastSnapshot == null ) { - break; + // if all snapshots after this snapshot in this chain are removed, remove those snapshots. + destroy = true; + break; } - if( lastSnapshot.getPrevSnapshotId() == 0) { - // have another full snapshot, then we may delete previous delta snapshots - destroy = true; + if( lastSnapshot.getRemoved() == null ) { + // if there is one child not removed, then can not remove back up snapshot. break; } lastId = lastSnapshot.getId(); @@ -676,7 +677,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma if (lastId == 0) { break; } - lastSnapshot = _snapshotDao.findById(lastId); + lastSnapshot = _snapshotDao.findByIdIncludingRemoved(lastId); } } return true; @@ -693,7 +694,10 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma String details = null; SnapshotVO snapshot = _snapshotDao.findByIdIncludingRemoved(snapshotId); - VolumeVO volume = _volsDao.findById(snapshot.getVolumeId()); + VolumeVO volume = _volsDao.findByIdIncludingRemoved(snapshot.getVolumeId()); + if ( volume == null ) { + throw new CloudRuntimeException("Destroying snapshot " + snapshotId + " backup failed due to unable to find volume " + snapshot.getVolumeId()); + } String primaryStoragePoolNameLabel = _storageMgr.getPrimaryStorageNameLabel(volume); String secondaryStoragePoolUrl = _storageMgr.getSecondaryStorageURL(volume.getDataCenterId()); Long dcId = volume.getDataCenterId(); @@ -747,7 +751,6 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma txn.start(); SnapshotVO snapshot = _snapshotDao.findByIdIncludingRemoved(snapshotId); - _snapshotDao.expunge(snapshotId); // If this is a manual delete, decrement the count of snapshots for this account if (policyId == Snapshot.MANUAL_POLICY_ID) { _accountMgr.decrementResourceCount(snapshot.getAccountId(), ResourceType.snapshot); @@ -755,6 +758,114 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma txn.commit(); } + + + @Override + public List listSnapshots(ListSnapshotsCmd cmd) throws InvalidParameterValueException, PermissionDeniedException { + Long volumeId = cmd.getVolumeId(); + + // Verify parameters + if(volumeId != null){ + VolumeVO volume = _volsDao.findById(volumeId); + if (volume == null) { + throw new InvalidParameterValueException("unable to find a volume with id " + volumeId); + } + checkAccountPermissions(volume.getAccountId(), volume.getDomainId(), "volume", volumeId); + } + + Account account = UserContext.current().getAccount(); + Long domainId = cmd.getDomainId(); + String accountName = cmd.getAccountName(); + Long accountId = null; + if ((account == null) || isAdmin(account.getType())) { + if (domainId != null) { + if ((account != null) && !_domainDao.isChildDomain(account.getDomainId(), domainId)) { + throw new PermissionDeniedException("Unable to list templates for domain " + domainId + ", permission denied."); + } + } else if ((account != null) && (account.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN)) { + domainId = account.getDomainId(); + } + + if (domainId != null && accountName != null) { + Account userAccount = _accountDao.findActiveAccount(accountName, domainId); + if (userAccount != null) { + accountId = userAccount.getId(); + } + } + } else { + accountId = account.getId(); + } + + Object name = cmd.getSnapshotName(); + Object id = cmd.getId(); + Object keyword = cmd.getKeyword(); + Object snapshotTypeStr = cmd.getSnapshotType(); + + Filter searchFilter = new Filter(SnapshotVO.class, "created", false, cmd.getStartIndex(), cmd.getPageSizeVal()); + SearchBuilder sb = _snapshotDao.createSearchBuilder(); + sb.and("status", sb.entity().getStatus(), SearchCriteria.Op.EQ); + sb.and("volumeId", sb.entity().getVolumeId(), SearchCriteria.Op.EQ); + sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE); + sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); + sb.and("accountId", sb.entity().getAccountId(), SearchCriteria.Op.EQ); + sb.and("snapshotTypeEQ", sb.entity().getSnapshotType(), SearchCriteria.Op.EQ); + sb.and("snapshotTypeNEQ", sb.entity().getSnapshotType(), SearchCriteria.Op.NEQ); + + if ((accountId == null) && (domainId != null)) { + // if accountId isn't specified, we can do a domain match for the admin case + SearchBuilder accountSearch = _accountDao.createSearchBuilder(); + sb.join("accountSearch", accountSearch, sb.entity().getAccountId(), accountSearch.entity().getId(), JoinType.INNER); + + SearchBuilder domainSearch = _domainDao.createSearchBuilder(); + domainSearch.and("path", domainSearch.entity().getPath(), SearchCriteria.Op.LIKE); + accountSearch.join("domainSearch", domainSearch, accountSearch.entity().getDomainId(), domainSearch.entity().getId(), JoinType.INNER); + } + + SearchCriteria sc = sb.create(); + + sc.setParameters("status", Snapshot.Status.BackedUp); + + if (volumeId != null) { + sc.setParameters("volumeId", volumeId); + } + + if (name != null) { + sc.setParameters("name", "%" + name + "%"); + } + + if (id != null) { + sc.setParameters("id", id); + } + + if (keyword != null) { + SearchCriteria ssc = _snapshotDao.createSearchCriteria(); + ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%"); + + sc.addAnd("name", SearchCriteria.Op.SC, ssc); + } + + if (accountId != null) { + sc.setParameters("accountId", accountId); + } else if (domainId != null) { + DomainVO domain = _domainDao.findById(domainId); + SearchCriteria joinSearch = sc.getJoin("accountSearch"); + joinSearch.setJoinParameters("domainSearch", "path", domain.getPath() + "%"); + } + + if (snapshotTypeStr != null) { + Type snapshotType = SnapshotVO.getSnapshotType((String)snapshotTypeStr); + if (snapshotType == null) { + throw new InvalidParameterValueException("Unsupported snapshot type " + snapshotTypeStr); + } + sc.setParameters("snapshotTypeEQ", snapshotType.ordinal()); + } else { + // Show only MANUAL and RECURRING snapshot types + sc.setParameters("snapshotTypeNEQ", Snapshot.Type.TEMPLATE.ordinal()); + } + + return _snapshotDao.search(sc, searchFilter); + } + @Override public boolean deleteSnapshotDirsForAccount(long accountId) { @@ -772,20 +883,11 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma Long dcId = volume.getDataCenterId(); String secondaryStoragePoolURL = _storageMgr.getSecondaryStorageURL(dcId); String primaryStoragePoolNameLabel = _storageMgr.getPrimaryStorageNameLabel(volume); - long mostRecentSnapshotId = _snapshotDao.getLastSnapshot(volumeId, -1L); - if (mostRecentSnapshotId == 0L) { + if (_snapshotDao.listByVolumeIdIncludingRemoved(volumeId).isEmpty() ) { // This volume doesn't have any snapshots. Nothing do delete. continue; } - SnapshotVO mostRecentSnapshot = _snapshotDao.findById(mostRecentSnapshotId); - if (mostRecentSnapshot == null) { - // Huh. The code should never reach here. - s_logger.error("Volume Id's mostRecentSnapshot with id: " + mostRecentSnapshotId + " turns out to be null"); - } - // even if mostRecentSnapshot.removed() != null, we still have to explicitly remove it from the primary storage. - // Then deleting the volume VDI will GC the base copy and nothing will be left on primary storage. - String mostRecentSnapshotUuid = mostRecentSnapshot.getPath(); - DeleteSnapshotsDirCommand cmd = new DeleteSnapshotsDirCommand(primaryStoragePoolNameLabel, secondaryStoragePoolURL, dcId, accountId, volumeId, mostRecentSnapshotUuid, mostRecentSnapshot.getName()); + DeleteSnapshotsDirCommand cmd = new DeleteSnapshotsDirCommand(primaryStoragePoolNameLabel, secondaryStoragePoolURL, dcId, accountId, volumeId, volume.getPath()); String basicErrMsg = "Failed to destroy snapshotsDir for: " + volume.getId() + " under account: " + accountId; Answer answer = null; Long poolId = volume.getPoolId(); @@ -1046,6 +1148,45 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma return _snapshotPolicyDao.findOneByVolume(volumeId); } + @Override + public long getNextInSequence(CreateSnapshotCmd cmd) { + return _snapshotDao.getNextInSequence(Long.class, "id"); + } + + private Long _getLastId() { + Transaction txn = Transaction.open(Transaction.CLOUD_DB); + PreparedStatement pstmt = null; + String sql = GET_LAST_ID; + try { + pstmt = txn.prepareAutoCloseStatement(sql); + ResultSet rs = pstmt.executeQuery(); + if (rs.next()) { + return Long.valueOf(rs.getLong(1)); + } + } catch (Exception ex) { + s_logger.error("error getting last id", ex); + } + return null; + } + + private void _updateSnapshotSeq(Long seq) { + Transaction txn = Transaction.open(Transaction.CLOUD_DB); + try { + txn.start(); + String sql = UPDATE_SNAPSHOT_SEQ; + PreparedStatement pstmt = null; + pstmt = txn.prepareAutoCloseStatement(sql); + pstmt.setLong(1, seq.longValue()); + pstmt.execute(); + txn.commit(); + } catch (Exception ex) { + txn.rollback(); + String msg = "error seting snapshots_seq to " + seq; + s_logger.error(msg, ex); + throw new CloudRuntimeException(msg, ex); + } + } + @Override public boolean configure(String name, Map params) throws ConfigurationException { _name = name; @@ -1064,7 +1205,15 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma _deltaSnapshotMax = NumbersUtil.parseInt(configDao.getValue("snapshot.delta.max"), DELTAMAX); _totalRetries = NumbersUtil.parseInt(configDao.getValue("total.retries"), 4); _pauseInterval = 2*NumbersUtil.parseInt(configDao.getValue("ping.interval"), 60); - + + Long lastId = _getLastId(); + if ( lastId == null ) { + String msg = "Can not get last id of snapshots"; + s_logger.error(msg); + throw new CloudRuntimeException(msg); + } + s_logger.info("Set shapshot sequence to " + (lastId + 1)); + _updateSnapshotSeq( lastId + 1 ); s_logger.info("Snapshot Manager is configured."); return true; @@ -1134,4 +1283,5 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma return success; } + } diff --git a/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java index be91e3ea66d..d6f7bf7410d 100644 --- a/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java @@ -30,7 +30,7 @@ import javax.persistence.EntityExistsException; import org.apache.log4j.Logger; -import com.cloud.api.commands.CreateSnapshotInternalCmd; +import com.cloud.api.commands.CreateSnapshotCmd; import com.cloud.async.AsyncJobManager; import com.cloud.async.AsyncJobResult; import com.cloud.async.AsyncJobVO; @@ -228,7 +228,7 @@ public class SnapshotSchedulerImpl implements SnapshotScheduler { // Just have SYSTEM own the job for now. Users won't be able to see this job, but // it's an internal job so probably not a huge deal. job.setAccountId(1L); - job.setCmd(CreateSnapshotInternalCmd.class.getName()); + job.setCmd(CreateSnapshotCmd.class.getName()); job.setCmdInfo(GsonHelper.getBuilder().create().toJson(params)); long jobId = _asyncMgr.submitAsyncJob(job); diff --git a/server/src/com/cloud/vm/NicVO.java b/server/src/com/cloud/vm/NicVO.java index 3e0e1481fff..3b45bd4c92c 100644 --- a/server/src/com/cloud/vm/NicVO.java +++ b/server/src/com/cloud/vm/NicVO.java @@ -95,6 +95,10 @@ public class NicVO implements Nic { @Column(name="default_nic") boolean defaultNic; + + @Column(name="strategy") + @Enumerated(value=EnumType.STRING) + ReservationStrategy strategy; public NicVO(String reserver, long instanceId, long configurationId) { this.reserver = reserver; @@ -230,6 +234,11 @@ public class NicVO implements Nic { this.reservationId = id; } + + public void setReservationStrategy(ReservationStrategy strategy) { + this.strategy = strategy; + } + public void setDeviceId(int deviceId) { this.deviceId = deviceId; } @@ -254,7 +263,7 @@ public class NicVO implements Nic { @Override public ReservationStrategy getReservationStrategy() { - return ReservationStrategy.Start; + return strategy; } @Override diff --git a/server/src/com/cloud/vm/UserVmManager.java b/server/src/com/cloud/vm/UserVmManager.java index bea52d38ab6..0d28e60a492 100644 --- a/server/src/com/cloud/vm/UserVmManager.java +++ b/server/src/com/cloud/vm/UserVmManager.java @@ -133,8 +133,6 @@ public interface UserVmManager extends VirtualMachineManager { */ HashMap getVirtualMachineStatistics(long hostId, String hostName, List vmIds); - boolean destroyTemplateSnapshot(Long userId, long snapshotId); - /** * Clean the network rules for the given VM * @param userId diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index c76667263b5..4033f5853ee 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -51,7 +51,6 @@ import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand; import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand; import com.cloud.agent.api.GetVmStatsAnswer; import com.cloud.agent.api.GetVmStatsCommand; -import com.cloud.agent.api.ManageSnapshotCommand; import com.cloud.agent.api.MigrateCommand; import com.cloud.agent.api.PrepareForMigrationCommand; import com.cloud.agent.api.RebootAnswer; @@ -135,15 +134,19 @@ import com.cloud.network.IpAddrAllocator; import com.cloud.network.LoadBalancerVMMapVO; import com.cloud.network.NetworkManager; import com.cloud.network.NetworkVO; +import com.cloud.network.Networks.TrafficType; import com.cloud.network.dao.FirewallRulesDao; import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.LoadBalancerDao; import com.cloud.network.dao.LoadBalancerVMMapDao; +import com.cloud.network.dao.NetworkDao; import com.cloud.network.router.VirtualRouter.Role; import com.cloud.network.security.NetworkGroupManager; import com.cloud.network.security.NetworkGroupVO; import com.cloud.offering.NetworkOffering; import com.cloud.offering.ServiceOffering; +import com.cloud.offerings.NetworkOfferingVO; +import com.cloud.offerings.dao.NetworkOfferingDao; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.DiskOfferingVO; @@ -247,10 +250,12 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, VirtualM @Inject VMTemplateHostDao _vmTemplateHostDao; @Inject NetworkGroupManager _networkGroupMgr; @Inject ServiceOfferingDao _serviceOfferingDao; + @Inject NetworkOfferingDao _networkOfferingDao; @Inject EventDao _eventDao = null; @Inject InstanceGroupDao _vmGroupDao; @Inject InstanceGroupVMMapDao _groupVMMapDao; @Inject VmManager _itMgr; + @Inject NetworkDao _networkDao; private IpAddrAllocator _IpAllocator; ScheduledExecutorService _executor = null; @@ -847,7 +852,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, VirtualM if (s_logger.isDebugEnabled()) { s_logger.debug("Starting VM: " + vmId); } - + State state = vm.getState(); if (state == State.Running) { if (s_logger.isDebugEnabled()) { @@ -1044,6 +1049,9 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, VirtualM } else { bits = template.getBits(); } + +// NetworkVO vmNetwork = _networkDao.findById(Long.valueOf(vm.getVnet())); +// NetworkOfferingVO vmNetworkOffering = _networkOfferingDao.findById(vmNetwork.getNetworkOfferingId()); StartCommand cmdStart = new StartCommand(vm, vm.getInstanceName(), offering, offering.getRateMbps(), offering.getMulticastRateMbps(), router, storageIps, vol.getFolder(), vm.getVnet(), utilization, cpuWeight, vols, mirroredVols, bits, isoPath, bootFromISO, guestOSDescription); if (Storage.ImageFormat.ISO.equals(template.getFormat()) || template.isRequiresHvm()) { @@ -2317,34 +2325,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, VirtualM return false; } } - - @Override - public boolean destroyTemplateSnapshot(Long userId, long snapshotId) { - boolean success = false; - SnapshotVO snapshot = _snapshotDao.findById(Long.valueOf(snapshotId)); - if (snapshot != null) { - VolumeVO volume = _volsDao.findById(snapshot.getVolumeId()); - ManageSnapshotCommand cmd = new ManageSnapshotCommand(snapshotId, snapshot.getPath()); - - Answer answer = null; - String basicErrMsg = "Failed to destroy template snapshot: " + snapshot.getName(); - Long storagePoolId = volume.getPoolId(); - answer = _storageMgr.sendToHostsOnStoragePool(storagePoolId, cmd, basicErrMsg); - - if ((answer != null) && answer.getResult()) { - // delete the snapshot from the database - _snapshotDao.expunge(snapshotId); - success = true; - } - if (answer != null) { - s_logger.error(answer.getDetails()); - } - } - - return success; - } - - + @Override public void cleanNetworkRules(long userId, long instanceId) { UserVmVO vm = _vmDao.findById(instanceId); @@ -3525,6 +3506,34 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, VirtualM @Override @DB public UserVm createVirtualMachine(DeployVMCmd cmd) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException { Account caller = UserContext.current().getAccount(); + String accountName = cmd.getAccountName(); + Long domainId = cmd.getDomainId(); + Account userAccount = null; + Long accountId = null; + List networkList = cmd.getNetworkIds(); + + if ((caller == null) || isAdmin(caller.getType())) { + if (domainId != null) { + if ((caller != null) && !_domainDao.isChildDomain(caller.getDomainId(), domainId)) { + throw new PermissionDeniedException("Failed to deploy VM, invalid domain id (" + domainId + ") given."); + } + if (accountName != null) { + userAccount = _accountDao.findActiveAccount(accountName, domainId); + if (userAccount == null) { + throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain " + domainId); + } + accountId = userAccount.getId(); + } + } else { + accountId = ((caller != null) ? caller.getId() : null); + } + } else { + accountId = caller.getId(); + } + + if (accountId == null) { + throw new InvalidParameterValueException("No valid account specified for deploying a virtual machine."); + } AccountVO owner = _accountDao.findById(cmd.getAccountId()); if (owner == null || owner.getRemoved() != null) { @@ -3633,12 +3642,25 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, VirtualM s_logger.debug("Allocating in the DB for vm"); - List configs = _networkMgr.setupNetworkConfiguration(owner, offering, plan); - List> networks = new ArrayList>(); - for (NetworkVO config : configs) { - networks.add(new Pair(config, null)); + if (networkList == null || networkList.isEmpty()) { + throw new InvalidParameterValueException("NetworkIds have to be specified"); + } + + List> networks = new ArrayList>(); + for (Long networkId : networkList) { + NetworkVO network = _networkDao.findById(networkId); + if (network == null) { + throw new InvalidParameterValueException("Unable to find network by id " + networkId); + } else { + if (network.getAccountId() != Account.ACCOUNT_ID_SYSTEM && network.getAccountId() != accountId) { + throw new PermissionDeniedException("Unable to create a vm using network with id " + networkId + ", permission denied"); + } else if (network.getTrafficType() != TrafficType.Guest) { + throw new InvalidParameterValueException("Unable to create a vm using network which traffic type is " + network.getTrafficType() + ". " + + "Only Guest traffic type is acceptes"); + } + networks.add(new Pair(network, null)); + } } - long id = _vmDao.getNextInSequence(Long.class, "id"); diff --git a/server/src/com/cloud/vm/dao/NicDao.java b/server/src/com/cloud/vm/dao/NicDao.java index 81576b4d041..4d68174be11 100644 --- a/server/src/com/cloud/vm/dao/NicDao.java +++ b/server/src/com/cloud/vm/dao/NicDao.java @@ -12,4 +12,6 @@ public interface NicDao extends GenericDao { List listBy(long instanceId); List listIpAddressInNetworkConfiguration(long networkConfigId); + + List listByNetworkId(long networkId); } diff --git a/server/src/com/cloud/vm/dao/NicDaoImpl.java b/server/src/com/cloud/vm/dao/NicDaoImpl.java index 3e43214e99f..3345e3fc30a 100644 --- a/server/src/com/cloud/vm/dao/NicDaoImpl.java +++ b/server/src/com/cloud/vm/dao/NicDaoImpl.java @@ -18,6 +18,7 @@ import com.cloud.vm.NicVO; public class NicDaoImpl extends GenericDaoBase implements NicDao { private final SearchBuilder InstanceSearch; private final GenericSearchBuilder IpSearch; + private final SearchBuilder NetworkSearch; protected NicDaoImpl() { super(); @@ -31,6 +32,10 @@ public class NicDaoImpl extends GenericDaoBase implements NicDao { IpSearch.and("nc", IpSearch.entity().getNetworkId(), SearchCriteria.Op.EQ); IpSearch.and("address", IpSearch.entity().getIp4Address(), SearchCriteria.Op.NNULL); IpSearch.done(); + + NetworkSearch = createSearchBuilder(); + NetworkSearch.and("networkId", NetworkSearch.entity().getNetworkId(), SearchCriteria.Op.EQ); + NetworkSearch.done(); } @Override @@ -46,4 +51,11 @@ public class NicDaoImpl extends GenericDaoBase implements NicDao { sc.setParameters("nc", networkConfigId); return customSearch(sc, null); } + + @Override + public List listByNetworkId(long networkId) { + SearchCriteria sc = NetworkSearch.create(); + sc.setParameters("networkId", networkId); + return listBy(sc); + } } diff --git a/setup/db/create-index-fk.sql b/setup/db/create-index-fk.sql index 1dd3b1bc61a..efa8c2e9b7c 100755 --- a/setup/db/create-index-fk.sql +++ b/setup/db/create-index-fk.sql @@ -265,3 +265,5 @@ ALTER TABLE `cloud`.`remote_access_vpn` ADD INDEX `i_remote_access_vpn_addr`(`vp ALTER TABLE `cloud`.`vpn_users` ADD CONSTRAINT `fk_vpn_users___account_id` FOREIGN KEY `fk_vpn_users__account_id` (`account_id`) REFERENCES `account` (`id`) ON DELETE CASCADE; ALTER TABLE `cloud`.`vpn_users` ADD INDEX `i_vpn_users_username`(`username`); ALTER TABLE `cloud`.`vpn_users` ADD UNIQUE `i_vpn_users__account_id__username`(`account_id`, `username`); + +ALTER TABLE `cloud`.`vlan` ADD CONSTRAINT `fk_vlan__network_offering_id` FOREIGN KEY `fk_vlan__network_offering_id` (`network_offering_id`) REFERENCES `networks` (`id`) ON DELETE CASCADE; diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql index 551f34d441d..e2350de4893 100755 --- a/setup/db/create-schema.sql +++ b/setup/db/create-schema.sql @@ -112,6 +112,7 @@ CREATE TABLE `cloud`.`op_networks`( CREATE TABLE `cloud`.`networks` ( `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', `name` varchar(255) COMMENT 'name for this network', + `display_text` varchar(255) COMMENT 'display text for this network', `traffic_type` varchar(32) NOT NULL COMMENT 'type of traffic going through this network', `broadcast_domain_type` varchar(32) NOT NULL COMMENT 'type of broadcast domain used', `broadcast_uri` varchar(255) COMMENT 'broadcast domain specifier', @@ -164,6 +165,7 @@ CREATE TABLE `cloud`.`nics` ( `network_id` bigint unsigned NOT NULL COMMENT 'network configuration id', `mode` varchar(32) COMMENT 'mode of getting ip address', `state` varchar(32) NOT NULL COMMENT 'state of the creation', + `strategy` varchar(32) NOT NULL COMMENT 'reservation strategy', `reserver_name` varchar(255) COMMENT 'Name of the component that reserved the ip address', `reservation_id` varchar(64) COMMENT 'id for the reservation', `device_id` int(10) COMMENT 'device id for the network when plugged into the virtual machine', @@ -189,6 +191,8 @@ CREATE TABLE `cloud`.`network_offerings` ( `service_offering_id` bigint unsigned UNIQUE COMMENT 'service offering id that this network offering is tied to', `created` datetime NOT NULL COMMENT 'time the entry was created', `removed` datetime DEFAULT NULL COMMENT 'time the entry was removed', + `shared` int(1) unsigned NOT NULL DEFAULT 0 COMMENT '0 if network is shared, 1 if network dedicated', + `default` int(1) unsigned NOT NULL DEFAULT 0 COMMENT '1 if network is default', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; @@ -277,6 +281,7 @@ INSERT INTO `cloud`.`sequence` (name, value) VALUES ('private_mac_address_seq', INSERT INTO `cloud`.`sequence` (name, value) VALUES ('storage_pool_seq', 200); INSERT INTO `cloud`.`sequence` (name, value) VALUES ('volume_seq', 1); INSERT INTO `cloud`.`sequence` (name, value) VALUES ('networks_seq', 1); +INSERT INTO `cloud`.`sequence` (name, value) VALUES ('snapshots_seq', 1); CREATE TABLE `cloud`.`volumes` ( `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'Primary Key', @@ -315,7 +320,7 @@ CREATE TABLE `cloud`.`volumes` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `cloud`.`snapshots` ( - `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'Primary Key', + `id` bigint unsigned UNIQUE NOT NULL 'Primary Key', `account_id` bigint unsigned NOT NULL COMMENT 'owner. foreign key to account table', `volume_id` bigint unsigned NOT NULL COMMENT 'volume it belongs to. foreign key to volume table', `status` varchar(32) COMMENT 'snapshot creation status', @@ -338,6 +343,7 @@ CREATE TABLE `cloud`.`vlan` ( `description` varchar(255), `vlan_type` varchar(255), `data_center_id` bigint unsigned NOT NULL, + `network_id` bigint unsigned COMMENT 'id of corresponding network offering', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/setup/db/data-21to22.sql b/setup/db/data-21to22.sql index a13fa0a9946..7fcc35e36a8 100644 --- a/setup/db/data-21to22.sql +++ b/setup/db/data-21to22.sql @@ -15,5 +15,7 @@ UPDATE vm_template set unique_name='routing_old' where id=1; INSERT INTO vm_template (id, unique_name, name, public, created, type, hvm, bits, account_id, url, checksum, enable_password, display_text, format, guest_os_id, featured, cross_zones) VALUES (10, 'routing', 'SystemVM Template', 0, now(), 'ext3', 0, 64, 1, 'http://download.cloud.com/releases/2.2/systemvm.vhd.bz2', 'bcc7f290f4c27ab4d0fe95d1012829ea', 0, 'SystemVM Template', 'VHD', 15, 0, 1); Update configuration set name='storage.max.volume.size' where name='max.volume.size.mb'; +INSERT INTO sequence (name, value) + VALUES ('snapshots_seq', '1') COMMIT; diff --git a/setup/db/data-22beta1to22beta2.sql b/setup/db/data-22beta1to22beta2.sql new file mode 100644 index 00000000000..f52a94b3651 --- /dev/null +++ b/setup/db/data-22beta1to22beta2.sql @@ -0,0 +1,2 @@ +INSERT INTO sequence (name, value) + VALUES ('snapshots_seq', '1') diff --git a/setup/db/schema-21to22.sql b/setup/db/schema-21to22.sql index ebfb3a35d3e..3e3d8f0ea5c 100644 --- a/setup/db/schema-21to22.sql +++ b/setup/db/schema-21to22.sql @@ -3,5 +3,6 @@ SET foreign_key_checks = 0; -- -- Schema upgrade from 2.1 to 2.2 -- -ALTER TABLE `cloud`.`template_host_ref` ADD COLUMN `physical_size` bigint unsigned NOT NULL DEFAULT 0; +ALTER TABLE `cloud`.`template_host_ref` ADD COLUMN `physical_size` bigint unsigned NOT NULL DEFAULT 0 +ALTER TABLE `cloud`.`snapshots` MODIFY COLUMN `id` bigint unsigned UNIQUE NOT NULL ALTER TABLE `vm_instance` DROP COLUMN `group` diff --git a/setup/db/schema-22beta1to22beta2.sql b/setup/db/schema-22beta1to22beta2.sql new file mode 100644 index 00000000000..efb631a2deb --- /dev/null +++ b/setup/db/schema-22beta1to22beta2.sql @@ -0,0 +1 @@ +ALTER TABLE `cloud`.`snapshots` MODIFY COLUMN `id` bigint unsigned UNIQUE NOT NULL diff --git a/ui/css/main.css b/ui/css/main.css index 74ae674d9df..13c098330c0 100644 --- a/ui/css/main.css +++ b/ui/css/main.css @@ -1813,11 +1813,11 @@ a:hover { } .adv_searchpopup { - width:156px; + width:207px; height:auto; float:left; position:absolute; - background:#fefae7 repeat top left; + background:#FFF repeat top left; border:1px solid #999; top:5px; left:8px; @@ -1827,7 +1827,7 @@ a:hover { } .adv_searchformbox { - width:140px; + width:190px; height:auto; float:left; margin:0 0 10px 10px; @@ -1894,7 +1894,7 @@ a:hover { } .adv_searchformbox li { - width:140px; + width:190px; float:left; clear:left; font-family:Arial, Helvetica, sans-serif; @@ -1904,7 +1904,7 @@ a:hover { } .adv_searchformbox label { - width:45px; + width:60px; float:left; clear:left; font-family:Arial, Helvetica, sans-serif; @@ -1920,7 +1920,7 @@ a:hover { float:left; border: 1px solid #CCC; height: 13px; - width: 80px; + width: 100px; color:#666; margin:0; padding:1px 0 0 2px; @@ -1933,7 +1933,7 @@ a:hover { float:left; border: 1px solid #CCC; height: 17px; - width: 83px; + width: 103px; margin:0; padding:1px 0 0 2px; color:#666; diff --git a/ui/jsp/account.jsp b/ui/jsp/account.jsp index b642b991eb5..f589764aaab 100644 --- a/ui/jsp/account.jsp +++ b/ui/jsp/account.jsp @@ -200,4 +200,37 @@

<%=t.t("please.confirm.you.want.to.enable.account")%>

- \ No newline at end of file + + + + + \ No newline at end of file diff --git a/ui/jsp/alert.jsp b/ui/jsp/alert.jsp index 4193aff4d20..2ac4c6c7c3a 100644 --- a/ui/jsp/alert.jsp +++ b/ui/jsp/alert.jsp @@ -80,4 +80,28 @@ - \ No newline at end of file + + + + + + \ No newline at end of file diff --git a/ui/jsp/diskoffering.jsp b/ui/jsp/diskoffering.jsp index 55cd5ad173f..05e859da0fa 100644 --- a/ui/jsp/diskoffering.jsp +++ b/ui/jsp/diskoffering.jsp @@ -182,3 +182,31 @@ + + + diff --git a/ui/jsp/instance.jsp b/ui/jsp/instance.jsp index fd38119e372..2b2a0889475 100644 --- a/ui/jsp/instance.jsp +++ b/ui/jsp/instance.jsp @@ -1354,8 +1354,8 @@ - - - \ No newline at end of file + + + + + \ No newline at end of file diff --git a/ui/jsp/ipaddress.jsp b/ui/jsp/ipaddress.jsp index e3ec641812c..2fabc7d6bf7 100644 --- a/ui/jsp/ipaddress.jsp +++ b/ui/jsp/ipaddress.jsp @@ -673,3 +673,44 @@ + + + + + diff --git a/ui/jsp/iso.jsp b/ui/jsp/iso.jsp index 28e9b1bb442..76149c1424a 100644 --- a/ui/jsp/iso.jsp +++ b/ui/jsp/iso.jsp @@ -353,3 +353,42 @@

+ + + \ No newline at end of file diff --git a/ui/jsp/resource.jsp b/ui/jsp/resource.jsp index 02931f6f4a5..d09942c5316 100644 --- a/ui/jsp/resource.jsp +++ b/ui/jsp/resource.jsp @@ -30,7 +30,7 @@
-

N

+

0

@@ -45,7 +45,7 @@
-

N

+

0

@@ -62,7 +62,7 @@
-

N

+

0

@@ -79,7 +79,7 @@
-

N

+

0

@@ -621,7 +621,7 @@
  1. -
  • -
  • + +
  • + + +
  • + - \ No newline at end of file + + + + + + \ No newline at end of file diff --git a/ui/jsp/snapshot.jsp b/ui/jsp/snapshot.jsp index 30a31e76d77..552bc527ef4 100644 --- a/ui/jsp/snapshot.jsp +++ b/ui/jsp/snapshot.jsp @@ -182,3 +182,40 @@ + + + + + + + diff --git a/ui/jsp/systemvm.jsp b/ui/jsp/systemvm.jsp index b7fd09d1790..6c83bd254dd 100644 --- a/ui/jsp/systemvm.jsp +++ b/ui/jsp/systemvm.jsp @@ -203,3 +203,56 @@ <%=t.t("please.confirm.you.want.to.reboot.systemVM")%>

    + + + + + \ No newline at end of file diff --git a/ui/jsp/template.jsp b/ui/jsp/template.jsp index 4e08102531d..19b4bb51f1c 100644 --- a/ui/jsp/template.jsp +++ b/ui/jsp/template.jsp @@ -383,3 +383,44 @@ <%=t.t("please.confirm.you.want.to.delete.the.template")%>

    + + + + + \ No newline at end of file diff --git a/ui/scripts/cloud.core.account.js b/ui/scripts/cloud.core.account.js index 7c46cf50a69..c60db02456d 100644 --- a/ui/scripts/cloud.core.account.js +++ b/ui/scripts/cloud.core.account.js @@ -19,8 +19,27 @@ var systemAccountId = 1; var adminAccountId = 2; -function accountGetSearchParams() { - return ""; +function accountGetSearchParams() { + var moreCriteria = []; + + var $advancedSearchPopup = $("#advanced_search_popup"); + if (lastSearchType == "advanced_search" && $advancedSearchPopup.length > 0) { + var name = $advancedSearchPopup.find("#adv_search_name").val(); + if (name != null && name.length > 0) + moreCriteria.push("&name="+todb(name)); + + var role = $advancedSearchPopup.find("#adv_search_role").val(); + if (role != null && role.length > 0) + moreCriteria.push("&accounttype="+role); + } + else { + var searchInput = $("#basic_search").find("#search_input").val(); + if (lastSearchType == "basic_search" && searchInput != null && searchInput.length > 0) { + moreCriteria.push("&name="+todb(searchInput)); + } + } + + return moreCriteria.join(""); } function afterLoadAccountJSP() { diff --git a/ui/scripts/cloud.core.alert.js b/ui/scripts/cloud.core.alert.js index 4fc02e17f77..7290ef94195 100644 --- a/ui/scripts/cloud.core.alert.js +++ b/ui/scripts/cloud.core.alert.js @@ -16,8 +16,23 @@ * */ -function alertGetSearchParams() { - return ""; +function alertGetSearchParams() { + var moreCriteria = []; + + var $advancedSearchPopup = $("#advanced_search_popup"); + if (lastSearchType == "advanced_search" && $advancedSearchPopup.length > 0) { + var type = $advancedSearchPopup.find("#adv_search_type").val(); + if (type!=null && type.length > 0) + moreCriteria.push("&type="+todb(type)); + } + else { + var searchInput = $("#basic_search").find("#search_input").val(); + if (lastSearchType == "basic_search" && searchInput != null && searchInput.length > 0) { + moreCriteria.push("&type="+todb(searchInput)); + } + } + + return moreCriteria.join(""); } function afterLoadAlertJSP() { diff --git a/ui/scripts/cloud.core.dashboard.js b/ui/scripts/cloud.core.dashboard.js index b4f0cd2e4e3..3448b1a550f 100644 --- a/ui/scripts/cloud.core.dashboard.js +++ b/ui/scripts/cloud.core.dashboard.js @@ -277,16 +277,16 @@ function afterLoadDashboardJSP() { data: createURL("command=listEvents&level=ERROR"), dataType: "json", success: function(json) { - var events = json.listeventsresponse.event; - if (events != null && events.length > 0) { - var errorGrid = $thisSection.find("#error_grid_content").empty(); - var length = (events.length>=3) ? 3 : events.length; + var items = json.listeventsresponse.event; + if (items != null && items.length > 0) { + var $grid = $thisSection.find("#alert_grid_content").empty(); + var length = (items.length>=3) ? 3 : items.length; for (var i = 0; i < length; i++) { - var template = $alertTemplate.clone(true); - template.find("#type").text(alerts[i].type); - template.find("#description").append(fromdb(alerts[i].description)); - setDateField(alerts[i].created, template.find("#date")); - alertGrid.append(template.show()); + var $template = $alertTemplate.clone(true); + $template.find("#type").text(items[i].type); + $template.find("#description").append(fromdb(items[i].description)); + setDateField(items[i].created, $template.find("#date")); + $grid.append($template.show()); } } } diff --git a/ui/scripts/cloud.core.diskoffering.js b/ui/scripts/cloud.core.diskoffering.js index 2e736973b19..19a92287f90 100644 --- a/ui/scripts/cloud.core.diskoffering.js +++ b/ui/scripts/cloud.core.diskoffering.js @@ -17,7 +17,28 @@ */ function diskOfferingGetSearchParams() { - return ""; + var moreCriteria = []; + + var $advancedSearchPopup = $("#advanced_search_popup"); + if (lastSearchType == "advanced_search" && $advancedSearchPopup.length > 0) { + var name = $advancedSearchPopup.find("#adv_search_name").val(); + if (name!=null && trim(name).length > 0) + moreCriteria.push("&name="+todb(name)); + + if ($advancedSearchPopup.find("#adv_search_domain_li").css("display") != "none") { + var domainId = $advancedSearchPopup.find("#adv_search_domain").val(); + if (domainId!=null && domainId.length > 0) + moreCriteria.push("&domainid="+domainId); + } + } + else { + var searchInput = $("#basic_search").find("#search_input").val(); + if (lastSearchType == "basic_search" && searchInput != null && searchInput.length > 0) { + moreCriteria.push("&name="+todb(searchInput)); + } + } + + return moreCriteria.join(""); } function afterLoadDiskOfferingJSP() { diff --git a/ui/scripts/cloud.core.init.js b/ui/scripts/cloud.core.init.js index c77ecaf172e..9c07bd2eecf 100644 --- a/ui/scripts/cloud.core.init.js +++ b/ui/scripts/cloud.core.init.js @@ -255,7 +255,7 @@ $(document).ready(function() { } }); - if(isAdmin()) + if(isAdmin() || isDomainAdmin()) $advancedSearch.find("#adv_search_domain_li, #adv_search_account_li, #adv_search_pod_li").show(); else $advancedSearch.find("#adv_search_domain_li, #adv_search_account_li, #adv_search_pod_li").hide(); @@ -345,7 +345,9 @@ $(document).ready(function() { } }); } - + + $advancedSearch.find("#adv_search_startdate, #adv_search_enddate").datepicker({dateFormat: 'yy-mm-dd'}); + $("#advanced_search_container").empty().append($advancedSearch.show()); return false; diff --git a/ui/scripts/cloud.core.instance.js b/ui/scripts/cloud.core.instance.js index 143fe719ecd..0672beba468 100644 --- a/ui/scripts/cloud.core.instance.js +++ b/ui/scripts/cloud.core.instance.js @@ -25,24 +25,30 @@ function vmGetSearchParams() { if (name!=null && trim(name).length > 0) moreCriteria.push("&name="+todb(name)); - var state = $advancedSearchPopup.find("#adv_search_state").val(); - if (state!=null && state.length > 0) - moreCriteria.push("&state="+todb(state)); - + if($advancedSearchPopup.find("#adv_search_state").length > 0) { + var state = $advancedSearchPopup.find("#adv_search_state").val(); + if (state!=null && state.length > 0) + moreCriteria.push("&state="+todb(state)); + } + var zone = $advancedSearchPopup.find("#adv_search_zone").val(); if (zone!=null && zone.length > 0) moreCriteria.push("&zoneid="+todb(zone)); if ($advancedSearchPopup.find("#adv_search_domain_li").css("display") != "none") { - var domainId = $advancedSearchPopup.find("#adv_search_domain").val(); - if(domainId!=null && domainId.length > 0) - moreCriteria.push("&domainid="+todb(domainId)); + if($advancedSearchPopup.find("#adv_search_domain").length > 0) { + var domainId = $advancedSearchPopup.find("#adv_search_domain").val(); + if(domainId!=null && domainId.length > 0) + moreCriteria.push("&domainid="+todb(domainId)); + } } if ($advancedSearchPopup.find("#adv_search_account_li").css("display") != "none") { - var account = $advancedSearchPopup.find("#adv_search_account").val(); - if(account!=null && account.length > 0) - moreCriteria.push("&account="+todb(account)); + if($advancedSearchPopup.find("#adv_search_account").length > 0) { + var account = $advancedSearchPopup.find("#adv_search_account").val(); + if(account!=null && account.length > 0) + moreCriteria.push("&account="+todb(account)); + } } } else { @@ -131,6 +137,23 @@ function afterLoadInstanceJSP() { initDialog("dialog_confirmation_reboot_router"); vmPopulateDropdown(); + + //customize advanced search + switch(currentLeftMenuId) { + case "leftmenu_instances_my_instances": + $("#advanced_search_template_nodomainaccount").attr("id", "advanced_search_template"); + break; + + case "leftmenu_instances_running_instances": + case "leftmenu_instances_stopped_instances": + case "leftmenu_instances_destroyed_instances": + $("#advanced_search_template_nostate").attr("id", "advanced_search_template"); + break; + + default: + $("#advanced_search_template_general").attr("id", "advanced_search_template"); + break; + } } function initStartVMButton() { @@ -520,26 +543,26 @@ function initVMWizard() { } //vm wizard search and pagination - $vmPopup.find("#search_button").bind("click", function(event) { + $vmPopup.find("#step1").find("#search_button").bind("click", function(event) { currentPageInTemplateGridInVmPopup = 1; listTemplatesInVmPopup(); return false; //event.preventDefault() + event.stopPropagation() }); - $vmPopup.find("#search_input").bind("keypress", function(event) { + $vmPopup.find("#step1").find("#search_input").bind("keypress", function(event) { if(event.keyCode == keycode_Enter) { - $vmPopup.find("#search_button").click(); + $vmPopup.find("#step1").find("#search_button").click(); return false; //event.preventDefault() + event.stopPropagation() } }); - $vmPopup.find("#nextPage").bind("click", function(event){ + $vmPopup.find("#step1").find("#next_page").bind("click", function(event){ currentPageInTemplateGridInVmPopup++; listTemplatesInVmPopup(); return false; //event.preventDefault() + event.stopPropagation() }); - $vmPopup.find("#prevPage").bind("click", function(event){ + $vmPopup.find("#step1").find("#prev_page").bind("click", function(event){ currentPageInTemplateGridInVmPopup--; listTemplatesInVmPopup(); return false; //event.preventDefault() + event.stopPropagation() @@ -554,7 +577,8 @@ function initVMWizard() { var container = $vmPopup.find("#template_container"); var commandString, templateType; - var searchInput = $vmPopup.find("#search_input").val(); + var searchInput = $vmPopup.find("#step1").find("#search_input").val(); + if (selectedTemplateTypeInVmPopup != "blank") { //*** template *** templateType = "template"; if (searchInput != null && searchInput.length > 0) @@ -572,11 +596,11 @@ function initVMWizard() { commandString += "&pagesize="+vmPopupTemplatePageSize+"&page="+currentPageInTemplateGridInVmPopup; - var loading = $vmPopup.find("#wiz_template_loading").show(); + var loading = $vmPopup.find("#wiz_template_loading").show(); if(currentPageInTemplateGridInVmPopup==1) - $vmPopup.find("#prevPage").hide(); + $vmPopup.find("#step1").find("#prev_page").hide(); else - $vmPopup.find("#prevPage").show(); + $vmPopup.find("#step1").find("#prev_page").show(); $.ajax({ data: createURL(commandString), @@ -601,10 +625,16 @@ function initVMWizard() { vmWizardTemplateJsonToTemplate(items[i], $newTemplate, templateType, i); container.append($newTemplate.show()); } + + + $vmPopup.find("#step1").find("#next_page").show(); //delete this line and uncomment the next 4 lines when bug 7410 is fixed ("pagesize is not working correctly on listTemplates API and listISOs API") + /* if(items.length < vmPopupTemplatePageSize) - $vmPopup.find("#nextPage").hide(); + $vmPopup.find("#step1").find("#next_page").hide(); else - $vmPopup.find("#nextPage").show(); + $vmPopup.find("#step1").find("#next_page").show(); + */ + } else { var msg; @@ -617,7 +647,7 @@ function initVMWizard() { +'
    '+msg+'
    ' +''; container.append(html); - $vmPopup.find("#nextPage").hide(); + $vmPopup.find("#step1").find("#next_page").hide(); } } }); diff --git a/ui/scripts/cloud.core.ipaddress.js b/ui/scripts/cloud.core.ipaddress.js index a68008d246c..cba1bd11db5 100644 --- a/ui/scripts/cloud.core.ipaddress.js +++ b/ui/scripts/cloud.core.ipaddress.js @@ -16,8 +16,39 @@ * */ -function ipGetSearchParams() { - return ""; +function ipGetSearchParams() { + var moreCriteria = []; + + var $advancedSearchPopup = $("#advanced_search_popup"); + if (lastSearchType == "advanced_search" && $advancedSearchPopup.length > 0) { + var ipaddress = $advancedSearchPopup.find("#adv_search_ipaddress").val(); + if (ipaddress!=null && trim(ipaddress).length > 0) + moreCriteria.push("&ipaddress="+todb(ipaddress)); + + var zone = $advancedSearchPopup.find("#adv_search_zone").val(); + if (zone!=null && zone.length > 0) + moreCriteria.push("&zoneId="+zone); + + if ($advancedSearchPopup.find("#adv_search_domain_li").css("display") != "none") { + var domainId = $advancedSearchPopup.find("#adv_search_domain").val(); + if (domainId!=null && domainId.length > 0) + moreCriteria.push("&domainid="+domainId); + } + + if ($advancedSearchPopup.find("#adv_search_account_li").css("display") != "none") { + var account = $advancedSearchPopup.find("#adv_search_account").val(); + if (account!=null && account.length > 0) + moreCriteria.push("&account="+account); + } + } + else { + var searchInput = $("#basic_search").find("#search_input").val(); + if (lastSearchType == "basic_search" && searchInput != null && searchInput.length > 0) { + moreCriteria.push("&ipaddress="+todb(searchInput)); + } + } + + return moreCriteria.join(""); } function afterLoadIpJSP() { diff --git a/ui/scripts/cloud.core.iso.js b/ui/scripts/cloud.core.iso.js index de4bdc96b08..70b1a77e59a 100644 --- a/ui/scripts/cloud.core.iso.js +++ b/ui/scripts/cloud.core.iso.js @@ -22,7 +22,38 @@ var g_zoneIds = []; var g_zoneNames = []; function isoGetSearchParams() { - return ""; + var moreCriteria = []; + + var $advancedSearchPopup = $("#advanced_search_popup"); + if (lastSearchType == "advanced_search" && $advancedSearchPopup.length > 0) { + var name = $advancedSearchPopup.find("#adv_search_name").val(); + if (name!=null && trim(name).length > 0) + moreCriteria.push("&name="+todb(name)); + + var zone = $advancedSearchPopup.find("#adv_search_zone").val(); + if (zone!=null && zone.length > 0) + moreCriteria.push("&zoneId="+zone); + + if ($advancedSearchPopup.find("#adv_search_domain_li").css("display") != "none") { + var domainId = $advancedSearchPopup.find("#adv_search_domain").val(); + if (domainId!=null && domainId.length > 0) + moreCriteria.push("&domainid="+domainId); + } + + if ($advancedSearchPopup.find("#adv_search_account_li").css("display") != "none") { + var account = $advancedSearchPopup.find("#adv_search_account").val(); + if (account!=null && account.length > 0) + moreCriteria.push("&account="+account); + } + } + else { + var searchInput = $("#basic_search").find("#search_input").val(); + if (lastSearchType == "basic_search" && searchInput != null && searchInput.length > 0) { + moreCriteria.push("&name="+todb(searchInput)); + } + } + + return moreCriteria.join(""); } function afterLoadIsoJSP() { diff --git a/ui/scripts/cloud.core.js b/ui/scripts/cloud.core.js index a150b1fcc32..b87c09ec0b6 100644 --- a/ui/scripts/cloud.core.js +++ b/ui/scripts/cloud.core.js @@ -655,7 +655,7 @@ function isMiddleMenuShown() { // adding middle menu item *** function beforeAddingMidMenuItem() { - var $midmenuItem1 = $("#midmenu_item").clone(); + var $midmenuItem1 = $("#midmenu_item").clone().attr("id", "midmenu_item_clone"); $midmenuItem1.find("#first_row").text("Adding...."); $midmenuItem1.find("#second_row").html(" "); $midmenuItem1.find("#content").addClass("inaction"); @@ -977,12 +977,14 @@ function listMidMenuItems2(commandString, getSearchParamsFn, jsonResponse1, json return count; } +var currentLeftMenuId; function listMidMenuItems(commandString, getSearchParamsFn, jsonResponse1, jsonResponse2, rightPanelJSP, afterLoadRightPanelJSPFn, toMidmenuFn, toRightPanelFn, getMidmenuIdFn, isMultipleSelectionInMidMenu, leftmenuId) { clearMiddleMenu(); showMiddleMenu(); $("#midmenu_container").hide(); $("#midmenu_spinning_wheel").show(); + currentLeftMenuId = leftmenuId; $("#right_panel").data("onRefreshFn", function() { $("#"+leftmenuId).click(); }); diff --git a/ui/scripts/cloud.core.resource.js b/ui/scripts/cloud.core.resource.js index 367a332ee29..20d3d861eb3 100644 --- a/ui/scripts/cloud.core.resource.js +++ b/ui/scripts/cloud.core.resource.js @@ -124,7 +124,10 @@ function buildZoneTree() { } function refreshClusterUnderPod($podNode, newClusterName, existingClusterId, noClicking) { - var podId = $podNode.data("podId"); + var podId = $podNode.data("podId"); + if(podId == null) //e.g. $podNode is not on the screen (when zone tree is hidden) ($podNode.length==0) + return; + $.ajax({ data: createURL("command=listClusters&podid="+podId), dataType: "json", @@ -635,7 +638,7 @@ function initAddZoneWizard() { var domains = json.listdomainsresponse.domain; if (domains != null && domains.length > 0) { for (var i = 0; i < domains.length; i++) { - domainDropdown.append(""); + domainDropdown.append(""); } } } diff --git a/ui/scripts/cloud.core.router.js b/ui/scripts/cloud.core.router.js index 02024663f64..60f4cfaae94 100644 --- a/ui/scripts/cloud.core.router.js +++ b/ui/scripts/cloud.core.router.js @@ -16,8 +16,49 @@ * */ -function routerGetSearchParams() { - return ""; +function routerGetSearchParams() { + var moreCriteria = []; + + var $advancedSearchPopup = $("#advanced_search_popup"); + if (lastSearchType == "advanced_search" && $advancedSearchPopup.length > 0) { + var name = $advancedSearchPopup.find("#adv_search_name").val(); + if (name!=null && trim(name).length > 0) + moreCriteria.push("&name="+todb(name)); + + var state = $advancedSearchPopup.find("#adv_search_state").val(); + if (state!=null && state.length > 0) + moreCriteria.push("&state="+todb(state)); + + var zone = $advancedSearchPopup.find("#adv_search_zone").val(); + if (zone!=null && zone.length > 0) + moreCriteria.push("&zoneId="+zone); + + if ($advancedSearchPopup.find("#adv_search_pod_li").css("display") != "none") { + var pod = $advancedSearchPopup.find("#adv_search_pod").val(); + if (pod!=null && pod.length > 0) + moreCriteria.push("&podId="+pod); + } + + if ($advancedSearchPopup.find("#adv_search_domain_li").css("display") != "none") { + var domainId = $advancedSearchPopup.find("#adv_search_domain").val(); + if (domainId!=null && domainId.length > 0) + moreCriteria.push("&domainid="+domainId); + } + + if ($advancedSearchPopup.find("#adv_search_account_li").css("display") != "none") { + var account = $advancedSearchPopup.find("#adv_search_account").val(); + if (account!=null && account.length > 0) + moreCriteria.push("&account="+account); + } + } + else { + var searchInput = $("#basic_search").find("#search_input").val(); + if (lastSearchType == "basic_search" && searchInput != null && searchInput.length > 0) { + moreCriteria.push("&name="+todb(searchInput)); + } + } + + return moreCriteria.join(""); } function afterLoadRouterJSP() { diff --git a/ui/scripts/cloud.core.serviceoffering.js b/ui/scripts/cloud.core.serviceoffering.js index 3ff69220fc7..a2c8dccd619 100644 --- a/ui/scripts/cloud.core.serviceoffering.js +++ b/ui/scripts/cloud.core.serviceoffering.js @@ -17,31 +17,78 @@ */ function serviceOfferingGetSearchParams() { - return ""; + var moreCriteria = []; + + var $advancedSearchPopup = $("#advanced_search_popup"); + if (lastSearchType == "advanced_search" && $advancedSearchPopup.length > 0) { + var name = $advancedSearchPopup.find("#adv_search_name").val(); + if (name!=null && trim(name).length > 0) + moreCriteria.push("&name="+todb(name)); + + if ($advancedSearchPopup.find("#adv_search_domain_li").css("display") != "none") { + var domainId = $advancedSearchPopup.find("#adv_search_domain").val(); + if (domainId!=null && domainId.length > 0) + moreCriteria.push("&domainid="+domainId); + } + } + else { + var searchInput = $("#basic_search").find("#search_input").val(); + if (lastSearchType == "basic_search" && searchInput != null && searchInput.length > 0) { + moreCriteria.push("&name="+todb(searchInput)); + } + } + + return moreCriteria.join(""); } -function afterLoadServiceOfferingJSP() { - var $detailsTab = $("#right_panel_content #tab_content_details"); - - //dialogs +function afterLoadServiceOfferingJSP() { + initAddServiceOfferingDialog(); +} + +function initAddServiceOfferingDialog() { initDialog("dialog_add_service"); - + var $dialogAddService = $("#dialog_add_service"); + $dialogAddService.find("#public_dropdown").unbind("change").bind("change", function(event) { + if($(this).val() == "true") { //public zone + $dialogAddService.find("#domain_dropdown_container").hide(); + } + else { //private zone + $dialogAddService.find("#domain_dropdown_container").show(); + } + return false; + }); + + $.ajax({ + data: createURL("command=listDomains"), + dataType: "json", + async: false, + success: function(json) { + var $domainDropdown1 = $("#dialog_add_service").find("#domain_dropdown").empty(); + var $domainDropdown2 = $("#tab_content_details").find("#domain_edit").empty(); + var domains = json.listdomainsresponse.domain; + if (domains != null && domains.length > 0) { + for (var i = 0; i < domains.length; i++) { + $domainDropdown1.append(""); + $domainDropdown2.append(""); + } + } + } + }); + //add button *** $("#midmenu_add_link").find("#label").text("Add Service Offering"); $("#midmenu_add_link").show(); - $("#midmenu_add_link").unbind("click").bind("click", function(event) { - var dialogAddService = $("#dialog_add_service"); - - dialogAddService.find("#add_service_name").val(""); - dialogAddService.find("#add_service_display").val(""); - dialogAddService.find("#add_service_cpucore").val(""); - dialogAddService.find("#add_service_cpu").val(""); - dialogAddService.find("#add_service_memory").val(""); - dialogAddService.find("#add_service_offerha").val("false"); + $("#midmenu_add_link").unbind("click").bind("click", function(event) { + $dialogAddService.find("#add_service_name").val(""); + $dialogAddService.find("#add_service_display").val(""); + $dialogAddService.find("#add_service_cpucore").val(""); + $dialogAddService.find("#add_service_cpu").val(""); + $dialogAddService.find("#add_service_memory").val(""); + $dialogAddService.find("#add_service_offerha").val("false"); - (g_hypervisorType == "kvm")? dialogAddService.find("#add_service_offerha_container").hide():dialogAddService.find("#add_service_offerha_container").show(); + (g_hypervisorType == "kvm")? $dialogAddService.find("#add_service_offerha_container").hide():$dialogAddService.find("#add_service_offerha_container").show(); - dialogAddService + $dialogAddService .dialog('option', 'buttons', { "Add": function() { var thisDialog = $(this); @@ -86,12 +133,17 @@ function afterLoadServiceOfferingJSP() { var useVirtualNetwork = (networkType=="Direct")? false:true; array1.push("&usevirtualnetwork="+useVirtualNetwork); - var tags = trim(thisDialog.find("#add_service_tags").val()); + var tags = thisDialog.find("#add_service_tags").val(); if(tags != null && tags.length > 0) array1.push("&tags="+todb(tags)); + if(thisDialog.find("#domain_dropdown_container").css("display") != "none") { + var domainId = thisDialog.find("#domain_dropdown").val(); + array1.push("&domainid="+domainId); + } + $.ajax({ - data: createURL("command=createServiceOffering"+array1.join("")+"&response=json"), + data: createURL("command=createServiceOffering"+array1.join("")), dataType: "json", success: function(json) { var item = json.createserviceofferingresponse.serviceoffering; @@ -112,14 +164,12 @@ function afterLoadServiceOfferingJSP() { } }).dialog("open"); return false; - }); -} + }); +} function doEditServiceOffering($actionLink, $detailsTab, $midmenuItem1) { - //var $readonlyFields = $detailsTab.find("#name, #displaytext, #offerha, #networktype, #tags"); - var $readonlyFields = $detailsTab.find("#name, #displaytext, #offerha, #tags"); - //var $editFields = $detailsTab.find("#name_edit, #displaytext_edit, #offerha_edit, #networktype_edit, #tags_edit"); - var $editFields = $detailsTab.find("#name_edit, #displaytext_edit, #offerha_edit, #tags_edit"); + var $readonlyFields = $detailsTab.find("#name, #displaytext, #offerha, #tags, #domain"); + var $editFields = $detailsTab.find("#name_edit, #displaytext_edit, #offerha_edit, #tags_edit, #domain_edit"); $readonlyFields.hide(); $editFields.show(); @@ -165,6 +215,9 @@ function doEditServiceOffering2($actionLink, $detailsTab, $midmenuItem1, $readon var tags = $detailsTab.find("#tags_edit").val(); array1.push("&tags="+todb(tags)); + var domainid = $detailsTab.find("#domain_edit").val(); + array1.push("&domainid="+todb(domainid)); + $.ajax({ data: createURL("command=updateServiceOffering&id="+id+array1.join("")), dataType: "json", @@ -217,7 +270,7 @@ function serviceOfferingJsonToDetailsTab() { dataType: "json", async: false, success: function(json) { - var items = json.listserviceofferingsresponse.serviceoffering; + var items = json.listserviceofferingsresponse.serviceoffering; if(items != null && items.length > 0) { jsonObj = items[0]; $midmenuItem1.data("jsonObj", jsonObj); @@ -246,7 +299,10 @@ function serviceOfferingJsonToDetailsTab() { $thisTab.find("#tags").text(fromdb(jsonObj.tags)); $thisTab.find("#tags_edit").val(fromdb(jsonObj.tags)); - + + $thisTab.find("#domain").text(fromdb(jsonObj.domain)); + $thisTab.find("#domain_edit").val(fromdb(jsonObj.domainid)); + setDateField(jsonObj.created, $thisTab.find("#created")); //actions *** diff --git a/ui/scripts/cloud.core.snapshot.js b/ui/scripts/cloud.core.snapshot.js index 1d214c11bdc..05ef4fc3d98 100644 --- a/ui/scripts/cloud.core.snapshot.js +++ b/ui/scripts/cloud.core.snapshot.js @@ -16,8 +16,35 @@ * */ -function snapshotGetSearchParams() { - return ""; +function snapshotGetSearchParams() { + var moreCriteria = []; + + var $advancedSearchPopup = $("#advanced_search_popup"); + if (lastSearchType == "advanced_search" && $advancedSearchPopup.length > 0) { + var name = $advancedSearchPopup.find("#adv_search_name").val(); + if (name!=null && trim(name).length > 0) + moreCriteria.push("&name="+todb(name)); + + if ($advancedSearchPopup.find("#adv_search_domain_li").css("display") != "none") { + var domainId = $advancedSearchPopup.find("#adv_search_domain").val(); + if (domainId!=null && domainId.length > 0) + moreCriteria.push("&domainid="+domainId); + } + + if ($advancedSearchPopup.find("#adv_search_account_li").css("display") != "none") { + var account = $advancedSearchPopup.find("#adv_search_account").val(); + if (account!=null && account.length > 0) + moreCriteria.push("&account="+account); + } + } + else { + var searchInput = $("#basic_search").find("#search_input").val(); + if (lastSearchType == "basic_search" && searchInput != null && searchInput.length > 0) { + moreCriteria.push("&name="+todb(searchInput)); + } + } + + return moreCriteria.join(""); } function afterLoadSnapshotJSP() { diff --git a/ui/scripts/cloud.core.systemvm.js b/ui/scripts/cloud.core.systemvm.js index 298687e9118..ac30d95aea1 100644 --- a/ui/scripts/cloud.core.systemvm.js +++ b/ui/scripts/cloud.core.systemvm.js @@ -17,7 +17,36 @@ */ function systemVmGetSearchParams() { - return ""; + var moreCriteria = []; + + var $advancedSearchPopup = $("#advanced_search_popup"); + if (lastSearchType == "advanced_search" && $advancedSearchPopup.length > 0) { + var name = $advancedSearchPopup.find("#adv_search_name").val(); + if (name!=null && trim(name).length > 0) + moreCriteria.push("&name="+todb(name)); + + var state = $advancedSearchPopup.find("#adv_search_state").val(); + if (state!=null && state.length > 0) + moreCriteria.push("&state="+todb(state)); + + var zone = $advancedSearchPopup.find("#adv_search_zone").val(); + if (zone!=null && zone.length > 0) + moreCriteria.push("&zoneId="+zone); + + if ($advancedSearchPopup.find("#adv_search_pod_li").css("display") != "none") { + var pod = $advancedSearchPopup.find("#adv_search_pod").val(); + if (pod!=null && pod.length > 0) + moreCriteria.push("&podId="+pod); + } + } + else { + var searchInput = $("#basic_search").find("#search_input").val(); + if (lastSearchType == "basic_search" && searchInput != null && searchInput.length > 0) { + moreCriteria.push("&name="+todb(searchInput)); + } + } + + return moreCriteria.join(""); } function afterLoadSystemVmJSP($midmenuItem1) { diff --git a/ui/scripts/cloud.core.template.js b/ui/scripts/cloud.core.template.js index 5de25803486..cb84923628f 100644 --- a/ui/scripts/cloud.core.template.js +++ b/ui/scripts/cloud.core.template.js @@ -21,8 +21,39 @@ var g_zoneIds = []; var g_zoneNames = []; -function templateGetSearchParams() { - return ""; +function templateGetSearchParams() { + var moreCriteria = []; + + var $advancedSearchPopup = $("#advanced_search_popup"); + if (lastSearchType == "advanced_search" && $advancedSearchPopup.length > 0) { + var name = $advancedSearchPopup.find("#adv_search_name").val(); + if (name!=null && trim(name).length > 0) + moreCriteria.push("&name="+todb(name)); + + var zone = $advancedSearchPopup.find("#adv_search_zone").val(); + if (zone!=null && zone.length > 0) + moreCriteria.push("&zoneId="+zone); + + if ($advancedSearchPopup.find("#adv_search_domain_li").css("display") != "none") { + var domainId = $advancedSearchPopup.find("#adv_search_domain").val(); + if (domainId!=null && domainId.length > 0) + moreCriteria.push("&domainid="+domainId); + } + + if ($advancedSearchPopup.find("#adv_search_account_li").css("display") != "none") { + var account = $advancedSearchPopup.find("#adv_search_account").val(); + if (account!=null && account.length > 0) + moreCriteria.push("&account="+account); + } + } + else { + var searchInput = $("#basic_search").find("#search_input").val(); + if (lastSearchType == "basic_search" && searchInput != null && searchInput.length > 0) { + moreCriteria.push("&name="+todb(searchInput)); + } + } + + return moreCriteria.join(""); } function afterLoadTemplateJSP() {