You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by bf...@apache.org on 2013/05/21 21:34:13 UTC
[15/50] [abbrv] CLOUDSTACK-652: meging 'portable public ip' feature
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d6452be8/server/src/com/cloud/network/NetworkServiceImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/NetworkServiceImpl.java b/server/src/com/cloud/network/NetworkServiceImpl.java
index ed9a8c4..1533ca9 100755
--- a/server/src/com/cloud/network/NetworkServiceImpl.java
+++ b/server/src/com/cloud/network/NetworkServiceImpl.java
@@ -39,6 +39,7 @@ import javax.ejb.Local;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
+import com.cloud.network.vpc.dao.VpcDao;
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
import org.apache.cloudstack.acl.SecurityChecker;
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
@@ -184,32 +185,6 @@ import com.cloud.vm.dao.NicSecondaryIpDao;
import com.cloud.vm.dao.NicSecondaryIpVO;
import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.dao.VMInstanceDao;
-import com.cloud.vm.*;
-import com.cloud.vm.dao.*;
-import org.apache.cloudstack.acl.ControlledEntity.ACLType;
-import org.apache.cloudstack.acl.SecurityChecker;
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.api.command.admin.network.DedicateGuestVlanRangeCmd;
-import org.apache.cloudstack.api.command.admin.network.ListDedicatedGuestVlanRangesCmd;
-import org.apache.cloudstack.api.command.admin.usage.ListTrafficTypeImplementorsCmd;
-import org.apache.cloudstack.api.command.user.network.CreateNetworkCmd;
-import org.apache.cloudstack.api.command.user.network.ListNetworksCmd;
-import org.apache.cloudstack.api.command.user.network.RestartNetworkCmd;
-import org.apache.cloudstack.api.command.user.vm.ListNicsCmd;
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import javax.ejb.Local;
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.security.InvalidParameterException;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.*;
/**
@@ -315,6 +290,8 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
@Inject
AccountGuestVlanMapDao _accountGuestVlanMapDao;
@Inject
+ VpcDao _vpcDao;
+ @Inject
NetworkACLDao _networkACLDao;
int _cidrLimit;
@@ -527,22 +504,23 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
public IpAddress allocateIP(Account ipOwner, long zoneId, Long networkId)
throws ResourceAllocationException, InsufficientAddressCapacityException, ConcurrentOperationException {
+ Account caller = UserContext.current().getCaller();
+ long callerUserId = UserContext.current().getCallerUserId();
+ DataCenter zone = _configMgr.getZone(zoneId);
+
if (networkId != null) {
Network network = _networksDao.findById(networkId);
if (network == null) {
throw new InvalidParameterValueException("Invalid network id is given");
}
+
if (network.getGuestType() == Network.GuestType.Shared) {
- DataCenter zone = _configMgr.getZone(zoneId);
if (zone == null) {
throw new InvalidParameterValueException("Invalid zone Id is given");
}
-
// if shared network in the advanced zone, then check the caller against the network for 'AccessType.UseNetwork'
if (zone.getNetworkType() == NetworkType.Advanced) {
if (isSharedNetworkOfferingWithServices(network.getNetworkOfferingId())) {
- Account caller = UserContext.current().getCaller();
- long callerUserId = UserContext.current().getCallerUserId();
_accountMgr.checkAccess(caller, AccessType.UseNetwork, false, network);
if (s_logger.isDebugEnabled()) {
s_logger.debug("Associate IP address called by the user " + callerUserId + " account " + ipOwner.getId());
@@ -554,20 +532,67 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
}
}
}
+ } else {
+ _accountMgr.checkAccess(caller, null, false, ipOwner);
}
- return allocateIP(ipOwner, false, zoneId);
+ return _networkMgr.allocateIp(ipOwner, false, caller, callerUserId, zone);
}
- public IpAddress allocateIP(Account ipOwner, boolean isSystem, long zoneId)
+ @Override
+ @ActionEvent(eventType = EventTypes.EVENT_PORTABLE_IP_ASSIGN, eventDescription = "allocating portable public Ip", create = true)
+ public IpAddress allocatePortableIP(Account ipOwner, int regionId, Long zoneId, Long networkId, Long vpcId)
throws ResourceAllocationException, InsufficientAddressCapacityException, ConcurrentOperationException {
Account caller = UserContext.current().getCaller();
- // check permissions
- _accountMgr.checkAccess(caller, null, false, ipOwner);
long callerUserId = UserContext.current().getCallerUserId();
DataCenter zone = _configMgr.getZone(zoneId);
- return _networkMgr.allocateIp(ipOwner, isSystem, caller, callerUserId, zone);
+ if ((networkId == null && vpcId == null) && (networkId != null && vpcId != null)) {
+ throw new InvalidParameterValueException("One of Network id or VPC is should be passed");
+ }
+
+ if (networkId != null) {
+ Network network = _networksDao.findById(networkId);
+ if (network == null) {
+ throw new InvalidParameterValueException("Invalid network id is given");
+ }
+
+ if (network.getGuestType() == Network.GuestType.Shared) {
+ if (zone == null) {
+ throw new InvalidParameterValueException("Invalid zone Id is given");
+ }
+ // if shared network in the advanced zone, then check the caller against the network for 'AccessType.UseNetwork'
+ if (zone.getNetworkType() == NetworkType.Advanced) {
+ if (isSharedNetworkOfferingWithServices(network.getNetworkOfferingId())) {
+ _accountMgr.checkAccess(caller, AccessType.UseNetwork, false, network);
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Associate IP address called by the user " + callerUserId + " account " + ipOwner.getId());
+ }
+ return _networkMgr.allocatePortableIp(ipOwner, caller, zoneId, networkId, null);
+ } else {
+ throw new InvalidParameterValueException("Associate IP address can only be called on the shared networks in the advanced zone" +
+ " with Firewall/Source Nat/Static Nat/Port Forwarding/Load balancing services enabled");
+ }
+ }
+ }
+ }
+
+ if (vpcId != null) {
+ Vpc vpc = _vpcDao.findById(vpcId);
+ if (vpc != null) {
+ throw new InvalidParameterValueException("Invalid vpc id is given");
+ }
+ }
+
+ _accountMgr.checkAccess(caller, null, false, ipOwner);
+
+ return _networkMgr.allocatePortableIp(ipOwner, caller, zoneId, null, null);
+ }
+
+ @Override
+ @ActionEvent(eventType = EventTypes.EVENT_PORTABLE_IP_RELEASE, eventDescription = "disassociating portable Ip", async = true)
+ public boolean releasePortableIpAddress(long ipAddressId) throws InsufficientAddressCapacityException {
+ return releaseIpAddressInternal(ipAddressId);
}
@Override
@@ -810,9 +835,13 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
}
@Override
- @DB
@ActionEvent(eventType = EventTypes.EVENT_NET_IP_RELEASE, eventDescription = "disassociating Ip", async = true)
public boolean releaseIpAddress(long ipAddressId) throws InsufficientAddressCapacityException {
+ return releaseIpAddressInternal(ipAddressId);
+ }
+
+ @DB
+ private boolean releaseIpAddressInternal(long ipAddressId) throws InsufficientAddressCapacityException {
Long userId = UserContext.current().getCallerUserId();
Account caller = UserContext.current().getCaller();
@@ -851,6 +880,9 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
boolean success = _networkMgr.disassociatePublicIpAddress(ipAddressId, userId, caller);
if (success) {
+ if (!ipVO.isPortable()) {
+ return success;
+ }
Long networkId = ipVO.getAssociatedWithNetworkId();
if (networkId != null) {
Network guestNetwork = getNetwork(networkId);
@@ -867,7 +899,6 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
return success;
}
-
@Override
@DB
public Network getNetwork(long id) {
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d6452be8/server/src/com/cloud/network/addr/PublicIp.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/addr/PublicIp.java b/server/src/com/cloud/network/addr/PublicIp.java
index c753b49..b18c691 100644
--- a/server/src/com/cloud/network/addr/PublicIp.java
+++ b/server/src/com/cloud/network/addr/PublicIp.java
@@ -220,6 +220,15 @@ public class PublicIp implements PublicIpAddress {
return _addr.getVmIp();
}
+ @Override
+ public boolean isPortable() {
+ return _addr.isPortable();
+ }
+
+ public void setPortable(boolean portable) {
+ _addr.setPortable(portable);
+ }
+
public Long getIpMacAddress() {
return _addr.getMacAddress();
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d6452be8/server/src/com/cloud/network/rules/RulesManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/rules/RulesManagerImpl.java b/server/src/com/cloud/network/rules/RulesManagerImpl.java
index c9b47b4..8834553 100755
--- a/server/src/com/cloud/network/rules/RulesManagerImpl.java
+++ b/server/src/com/cloud/network/rules/RulesManagerImpl.java
@@ -491,6 +491,49 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules
return false;
}
performedIpAssoc = true;
+ } else if (ipAddress.isPortable()) {
+ s_logger.info("Portable IP " + ipAddress.getUuid() + " is not associated with the network, so" +
+ "associate IP with the network " + networkId);
+ try {
+ // check if StaticNat service is enabled in the network
+ _networkModel.checkIpForService(ipAddress, Service.StaticNat, networkId);
+
+ // associate portable IP to vpc, if network is part of VPC
+ if (network.getVpcId() != null) {
+ _vpcMgr.associateIPToVpc(ipId, network.getVpcId());
+ }
+
+ // associate portable IP with guest network
+ _networkMgr.associatePortableIPToGuestNetwork(ipId, networkId, false);
+ } catch (Exception e) {
+ s_logger.warn("Failed to associate portable id=" + ipId + " to network id=" + networkId + " as " +
+ "a part of enable static nat");
+ return false;
+ }
+ performedIpAssoc = true;
+ }
+ } else if (ipAddress.getAssociatedWithNetworkId() != networkId) {
+ if (ipAddress.isPortable()) {
+ // check if destination network has StaticNat service enabled
+ _networkModel.checkIpForService(ipAddress, Service.StaticNat, networkId);
+
+ // check if portable IP can be transferred across the networks
+ if (_networkMgr.isPortableIpTransferableFromNetwork(ipId, ipAddress.getAssociatedWithNetworkId() )) {
+ try {
+ _networkMgr.transferPortableIP(ipId, ipAddress.getAssociatedWithNetworkId(), networkId);
+ } catch (Exception e) {
+ s_logger.warn("Failed to associate portable id=" + ipId + " to network id=" + networkId + " as " +
+ "a part of enable static nat");
+ return false;
+ }
+ } else {
+ throw new InvalidParameterValueException("Portable IP: " + ipId + " has associated services" +
+ "in network " + ipAddress.getAssociatedWithNetworkId() + " so can not be transferred to " +
+ " network " + networkId);
+ }
+ } else {
+ throw new InvalidParameterValueException("Invalid network Id=" + networkId + ". IP is associated with"
+ + " a different network than passed network id");
}
} else {
_networkModel.checkIpForService(ipAddress, Service.StaticNat, null);
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d6452be8/server/src/com/cloud/server/ManagementServerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java
index 8b3eea4..8323af8 100755
--- a/server/src/com/cloud/server/ManagementServerImpl.java
+++ b/server/src/com/cloud/server/ManagementServerImpl.java
@@ -47,6 +47,14 @@ import com.cloud.exception.*;
import com.cloud.vm.*;
import org.apache.cloudstack.acl.ControlledEntity;
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.ApiConstants;
+
+import com.cloud.event.ActionEventUtils;
+import org.apache.cloudstack.api.BaseUpdateTemplateOrIsoCmd;
+import org.apache.cloudstack.api.command.admin.region.*;
+import org.apache.cloudstack.api.response.ExtractResponse;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.log4j.Logger;
import org.apache.cloudstack.affinity.AffinityGroupProcessor;
import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
import org.apache.cloudstack.api.ApiConstants;
@@ -124,9 +132,6 @@ import org.apache.cloudstack.api.command.admin.pod.CreatePodCmd;
import org.apache.cloudstack.api.command.admin.pod.DeletePodCmd;
import org.apache.cloudstack.api.command.admin.pod.ListPodsByCmd;
import org.apache.cloudstack.api.command.admin.pod.UpdatePodCmd;
-import org.apache.cloudstack.api.command.admin.region.AddRegionCmd;
-import org.apache.cloudstack.api.command.admin.region.RemoveRegionCmd;
-import org.apache.cloudstack.api.command.admin.region.UpdateRegionCmd;
import org.apache.cloudstack.api.command.admin.resource.ArchiveAlertsCmd;
import org.apache.cloudstack.api.command.admin.resource.DeleteAlertsCmd;
import org.apache.cloudstack.api.command.admin.resource.ListAlertsCmd;
@@ -571,8 +576,78 @@ import com.cloud.vm.dao.VMInstanceDao;
import edu.emory.mathcs.backport.java.util.Arrays;
import edu.emory.mathcs.backport.java.util.Collections;
-import org.apache.cloudstack.api.command.admin.config.ListDeploymentPlannersCmd;
+import org.apache.cloudstack.acl.ControlledEntity;
+import org.apache.cloudstack.api.command.admin.autoscale.CreateCounterCmd;
+import org.apache.cloudstack.api.command.admin.autoscale.DeleteCounterCmd;
+import org.apache.cloudstack.api.command.admin.cluster.AddClusterCmd;
+import org.apache.cloudstack.api.command.admin.cluster.DeleteClusterCmd;
+import org.apache.cloudstack.api.command.admin.cluster.ListClustersCmd;
+import org.apache.cloudstack.api.command.admin.cluster.UpdateClusterCmd;
+import org.apache.cloudstack.api.command.admin.config.ListCfgsByCmd;
+import org.apache.cloudstack.api.command.admin.config.ListHypervisorCapabilitiesCmd;
+import org.apache.cloudstack.api.command.admin.config.UpdateCfgCmd;
+import org.apache.cloudstack.api.command.admin.config.UpdateHypervisorCapabilitiesCmd;
+import org.apache.cloudstack.api.command.admin.ldap.LDAPConfigCmd;
+import org.apache.cloudstack.api.command.admin.ldap.LDAPRemoveCmd;
+import org.apache.cloudstack.api.command.admin.pod.CreatePodCmd;
+import org.apache.cloudstack.api.command.admin.pod.DeletePodCmd;
+import org.apache.cloudstack.api.command.admin.pod.ListPodsByCmd;
+import org.apache.cloudstack.api.command.admin.pod.UpdatePodCmd;
+import org.apache.cloudstack.api.command.admin.swift.AddSwiftCmd;
+import org.apache.cloudstack.api.command.admin.swift.ListSwiftsCmd;
+import org.apache.cloudstack.api.command.admin.template.PrepareTemplateCmd;
+import org.apache.cloudstack.api.command.admin.vlan.CreateVlanIpRangeCmd;
+import org.apache.cloudstack.api.command.admin.vlan.DeleteVlanIpRangeCmd;
+import org.apache.cloudstack.api.command.admin.vlan.ListVlanIpRangesCmd;
+import org.apache.cloudstack.api.command.admin.vm.AssignVMCmd;
+import org.apache.cloudstack.api.command.admin.vm.MigrateVMCmd;
+import org.apache.cloudstack.api.command.admin.vm.MigrateVirtualMachineWithVolumeCmd;
+import org.apache.cloudstack.api.command.admin.vm.RecoverVMCmd;
+import org.apache.cloudstack.api.command.admin.zone.CreateZoneCmd;
+import org.apache.cloudstack.api.command.admin.zone.DeleteZoneCmd;
+import org.apache.cloudstack.api.command.admin.zone.MarkDefaultZoneForAccountCmd;
+import org.apache.cloudstack.api.command.admin.zone.UpdateZoneCmd;
+import org.apache.cloudstack.api.command.user.account.AddAccountToProjectCmd;
+import org.apache.cloudstack.api.command.user.account.DeleteAccountFromProjectCmd;
+import org.apache.cloudstack.api.command.user.account.ListAccountsCmd;
+import org.apache.cloudstack.api.command.user.account.ListProjectAccountsCmd;
+import org.apache.cloudstack.api.command.user.address.AssociateIPAddrCmd;
+import org.apache.cloudstack.api.command.user.address.DisassociateIPAddrCmd;
+import org.apache.cloudstack.api.command.user.address.ListPublicIpAddressesCmd;
+import org.apache.cloudstack.api.command.user.config.ListCapabilitiesCmd;
+import org.apache.cloudstack.api.command.user.event.ArchiveEventsCmd;
+import org.apache.cloudstack.api.command.user.event.DeleteEventsCmd;
+import org.apache.cloudstack.api.command.user.event.ListEventTypesCmd;
+import org.apache.cloudstack.api.command.user.event.ListEventsCmd;
+import org.apache.cloudstack.api.command.user.guest.ListGuestOsCategoriesCmd;
+import org.apache.cloudstack.api.command.user.guest.ListGuestOsCmd;
+import org.apache.cloudstack.api.command.user.job.ListAsyncJobsCmd;
+import org.apache.cloudstack.api.command.user.job.QueryAsyncJobResultCmd;
+import org.apache.cloudstack.api.command.user.offering.ListDiskOfferingsCmd;
+import org.apache.cloudstack.api.command.user.offering.ListServiceOfferingsCmd;
+import org.apache.cloudstack.api.command.user.region.ListRegionsCmd;
+import org.apache.cloudstack.api.command.user.region.ha.gslb.*;
+import org.apache.cloudstack.api.command.user.ssh.CreateSSHKeyPairCmd;
+import org.apache.cloudstack.api.command.user.ssh.DeleteSSHKeyPairCmd;
+import org.apache.cloudstack.api.command.user.ssh.ListSSHKeyPairsCmd;
+import org.apache.cloudstack.api.command.user.ssh.RegisterSSHKeyPairCmd;
+import org.apache.cloudstack.api.command.user.tag.CreateTagsCmd;
+import org.apache.cloudstack.api.command.user.tag.DeleteTagsCmd;
+import org.apache.cloudstack.api.command.user.tag.ListTagsCmd;
+import org.apache.cloudstack.api.command.user.vmgroup.CreateVMGroupCmd;
+import org.apache.cloudstack.api.command.user.vmgroup.DeleteVMGroupCmd;
+import org.apache.cloudstack.api.command.user.vmgroup.ListVMGroupsCmd;
+import org.apache.cloudstack.api.command.user.vmgroup.UpdateVMGroupCmd;
+import org.apache.cloudstack.api.command.user.vmsnapshot.CreateVMSnapshotCmd;
+import org.apache.cloudstack.api.command.user.vmsnapshot.DeleteVMSnapshotCmd;
+import org.apache.cloudstack.api.command.user.vmsnapshot.ListVMSnapshotCmd;
+import org.apache.cloudstack.api.command.user.zone.ListZonesByCmd;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.apache.cloudstack.api.command.admin.config.ListDeploymentPlannersCmd;
public class ManagementServerImpl extends ManagerBase implements ManagementServer {
public static final Logger s_logger = Logger.getLogger(ManagementServerImpl.class.getName());
@@ -2897,6 +2972,9 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
cmdList.add(ListAffinityGroupsCmd.class);
cmdList.add(UpdateVMAffinityGroupCmd.class);
cmdList.add(ListAffinityGroupTypesCmd.class);
+ cmdList.add(CreatePortableIpRangeCmd.class);
+ cmdList.add(DeletePortableIpRangeCmd.class);
+ cmdList.add(ListPortableIpRangesCmd.class);
cmdList.add(ListDeploymentPlannersCmd.class);
cmdList.add(ReleaseHostReservationCmd.class);
cmdList.add(ScaleSystemVMCmd.class);
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d6452be8/server/src/org/apache/cloudstack/region/PortableIpDao.java
----------------------------------------------------------------------
diff --git a/server/src/org/apache/cloudstack/region/PortableIpDao.java b/server/src/org/apache/cloudstack/region/PortableIpDao.java
new file mode 100755
index 0000000..9f5341f
--- /dev/null
+++ b/server/src/org/apache/cloudstack/region/PortableIpDao.java
@@ -0,0 +1,39 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.region;
+
+import java.util.List;
+
+import com.cloud.dc.Vlan;
+import com.cloud.dc.Vlan.VlanType;
+import com.cloud.dc.VlanVO;
+import com.cloud.utils.db.GenericDao;
+
+public interface PortableIpDao extends GenericDao<PortableIpVO, Long> {
+
+ List<PortableIpVO> listByRegionId(int regionId);
+
+ List<PortableIpVO> listByRangeId(long rangeId);
+
+ List<PortableIpVO> listByRangeIdAndState(long rangeId, PortableIp.State state);
+
+ List<PortableIpVO> listByRegionIdAndState(int regionId, PortableIp.State state);
+
+ PortableIpVO findByIpAddress(String ipAddress);
+
+ void unassignIpAddress(long ipAddressId);
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d6452be8/server/src/org/apache/cloudstack/region/PortableIpDaoImpl.java
----------------------------------------------------------------------
diff --git a/server/src/org/apache/cloudstack/region/PortableIpDaoImpl.java b/server/src/org/apache/cloudstack/region/PortableIpDaoImpl.java
new file mode 100755
index 0000000..488761b
--- /dev/null
+++ b/server/src/org/apache/cloudstack/region/PortableIpDaoImpl.java
@@ -0,0 +1,131 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.region;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.ejb.Local;
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.springframework.stereotype.Component;
+
+import com.cloud.dc.AccountVlanMapVO;
+import com.cloud.dc.PodVlanMapVO;
+import com.cloud.dc.Vlan;
+import com.cloud.dc.Vlan.VlanType;
+import com.cloud.dc.VlanVO;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.utils.Pair;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.JoinBuilder;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+@Component
+@Local(value={PortableIpDao.class})
+public class PortableIpDaoImpl extends GenericDaoBase<PortableIpVO, Long> implements PortableIpDao {
+
+ private final SearchBuilder<PortableIpVO> listByRegionIDSearch;
+ private final SearchBuilder<PortableIpVO> listByRangeIDSearch;
+ private final SearchBuilder<PortableIpVO> listByRangeIDAndStateSearch;
+ private final SearchBuilder<PortableIpVO> listByRegionIDAndStateSearch;
+ private final SearchBuilder<PortableIpVO> findByIpAddressSearch;
+
+ public PortableIpDaoImpl() {
+ listByRegionIDSearch = createSearchBuilder();
+ listByRegionIDSearch.and("regionId", listByRegionIDSearch.entity().getRegionId(), SearchCriteria.Op.EQ);
+ listByRegionIDSearch.done();
+
+ listByRangeIDSearch = createSearchBuilder();
+ listByRangeIDSearch.and("rangeId", listByRangeIDSearch.entity().getRangeId(), SearchCriteria.Op.EQ);
+ listByRangeIDSearch.done();
+
+ listByRangeIDAndStateSearch = createSearchBuilder();
+ listByRangeIDAndStateSearch.and("rangeId", listByRangeIDAndStateSearch.entity().getRangeId(), SearchCriteria.Op.EQ);
+ listByRangeIDAndStateSearch.and("state", listByRangeIDAndStateSearch.entity().getState(), SearchCriteria.Op.EQ);
+ listByRangeIDAndStateSearch.done();
+
+ listByRegionIDAndStateSearch = createSearchBuilder();
+ listByRegionIDAndStateSearch.and("regionId", listByRegionIDAndStateSearch.entity().getRangeId(), SearchCriteria.Op.EQ);
+ listByRegionIDAndStateSearch.and("state", listByRegionIDAndStateSearch.entity().getState(), SearchCriteria.Op.EQ);
+ listByRegionIDAndStateSearch.done();
+
+ findByIpAddressSearch = createSearchBuilder();
+ findByIpAddressSearch.and("address", findByIpAddressSearch.entity().getAddress(), SearchCriteria.Op.EQ);
+ findByIpAddressSearch.done();
+ }
+
+ @Override
+ public List<PortableIpVO> listByRegionId(int regionIdId) {
+ SearchCriteria<PortableIpVO> sc = listByRegionIDSearch.create();
+ sc.setParameters("regionId", regionIdId);
+ return listBy(sc);
+ }
+
+ @Override
+ public List<PortableIpVO> listByRangeId(long rangeId) {
+ SearchCriteria<PortableIpVO> sc = listByRangeIDSearch.create();
+ sc.setParameters("rangeId", rangeId);
+ return listBy(sc);
+ }
+
+ @Override
+ public List<PortableIpVO> listByRangeIdAndState(long rangeId, PortableIp.State state) {
+ SearchCriteria<PortableIpVO> sc = listByRangeIDAndStateSearch.create();
+ sc.setParameters("rangeId", rangeId);
+ sc.setParameters("state", state);
+ return listBy(sc);
+ }
+
+ @Override
+ public List<PortableIpVO> listByRegionIdAndState(int regionId, PortableIp.State state) {
+ SearchCriteria<PortableIpVO> sc = listByRegionIDAndStateSearch.create();
+ sc.setParameters("regionId", regionId);
+ sc.setParameters("state", state);
+ return listBy(sc);
+ }
+
+ @Override
+ public PortableIpVO findByIpAddress(String ipAddress) {
+ SearchCriteria<PortableIpVO> sc = findByIpAddressSearch.create();
+ sc.setParameters("address", ipAddress);
+ return findOneBy(sc);
+ }
+
+ @Override
+ public void unassignIpAddress(long ipAddressId) {
+ PortableIpVO address = createForUpdate();
+ address.setAllocatedToAccountId(null);
+ address.setAllocatedInDomainId(null);
+ address.setAllocatedTime(null);
+ address.setState(PortableIp.State.Free);
+ address.setAssociatedWithNetworkId(null);
+ address.setAssociatedDataCenterId(null);
+ address.setAssociatedWithVpcId(null);
+ address.setPhysicalNetworkId(null);
+ update(ipAddressId, address);
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d6452be8/server/src/org/apache/cloudstack/region/PortableIpRangeDao.java
----------------------------------------------------------------------
diff --git a/server/src/org/apache/cloudstack/region/PortableIpRangeDao.java b/server/src/org/apache/cloudstack/region/PortableIpRangeDao.java
new file mode 100755
index 0000000..85da6c0
--- /dev/null
+++ b/server/src/org/apache/cloudstack/region/PortableIpRangeDao.java
@@ -0,0 +1,30 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.region;
+
+import java.util.List;
+
+import com.cloud.dc.Vlan;
+import com.cloud.dc.Vlan.VlanType;
+import com.cloud.dc.VlanVO;
+import com.cloud.utils.db.GenericDao;
+
+public interface PortableIpRangeDao extends GenericDao<PortableIpRangeVO, Long> {
+
+ List<PortableIpRangeVO> listByRegionId(int regionId);
+
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d6452be8/server/src/org/apache/cloudstack/region/PortableIpRangeDaoImpl.java
----------------------------------------------------------------------
diff --git a/server/src/org/apache/cloudstack/region/PortableIpRangeDaoImpl.java b/server/src/org/apache/cloudstack/region/PortableIpRangeDaoImpl.java
new file mode 100755
index 0000000..496c9e6
--- /dev/null
+++ b/server/src/org/apache/cloudstack/region/PortableIpRangeDaoImpl.java
@@ -0,0 +1,65 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.region;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.ejb.Local;
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.springframework.stereotype.Component;
+
+import com.cloud.dc.AccountVlanMapVO;
+import com.cloud.dc.PodVlanMapVO;
+import com.cloud.dc.Vlan;
+import com.cloud.dc.Vlan.VlanType;
+import com.cloud.dc.VlanVO;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.utils.Pair;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.JoinBuilder;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+@Component
+@Local(value={PortableIpRangeDao.class})
+public class PortableIpRangeDaoImpl extends GenericDaoBase<PortableIpRangeVO, Long> implements PortableIpRangeDao {
+
+ private final SearchBuilder<PortableIpRangeVO> listByRegionIDSearch;
+
+ public PortableIpRangeDaoImpl() {
+ listByRegionIDSearch = createSearchBuilder();
+ listByRegionIDSearch.and("regionId", listByRegionIDSearch.entity().getRegionId(), SearchCriteria.Op.EQ);
+ listByRegionIDSearch.done();
+ }
+
+ @Override
+ public List<PortableIpRangeVO> listByRegionId(int regionIdId) {
+ SearchCriteria<PortableIpRangeVO> sc = listByRegionIDSearch.create();
+ sc.setParameters("regionId", regionIdId);
+ return listBy(sc);
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d6452be8/server/src/org/apache/cloudstack/region/PortableIpRangeVO.java
----------------------------------------------------------------------
diff --git a/server/src/org/apache/cloudstack/region/PortableIpRangeVO.java b/server/src/org/apache/cloudstack/region/PortableIpRangeVO.java
new file mode 100644
index 0000000..933fcc3
--- /dev/null
+++ b/server/src/org/apache/cloudstack/region/PortableIpRangeVO.java
@@ -0,0 +1,119 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.region;
+
+import java.util.UUID;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+import org.apache.cloudstack.api.Identity;
+import org.apache.cloudstack.api.InternalIdentity;
+
+@Entity
+@Table(name="portable_ip_range")
+public class PortableIpRangeVO implements PortableIpRange {
+
+ @Id
+ @GeneratedValue(strategy=GenerationType.IDENTITY)
+ @Column(name="id")
+ Long id;
+
+ @Column(name="uuid")
+ String uuid;
+
+ @Column(name="region_id")
+ int regionId;
+
+ @Column(name="vlan_id")
+ String vlan;
+
+ @Column(name="gateway")
+ String gateway;
+
+ @Column(name="netmask")
+ String netmask;
+
+ @Column(name="start_ip")
+ String startIp;
+
+ @Column(name="end_ip")
+ String endIp;
+
+ public PortableIpRangeVO() {
+ this.uuid = UUID.randomUUID().toString();
+ }
+
+ public PortableIpRangeVO(int regionId, String vlan, String gateway, String netmask, String startIp, String endIp) {
+ this.uuid = UUID.randomUUID().toString();
+ this.regionId =regionId;
+ this.vlan = vlan;
+ this.gateway = gateway;
+ this.netmask = netmask;
+ this.startIp = startIp;
+ this.endIp = endIp;
+ }
+
+ @Override
+ public long getId() {
+ return id;
+ }
+
+ @Override
+ public String getUuid() {
+ return this.uuid;
+ }
+
+ public void setUuid(String uuid) {
+ this.uuid = uuid;
+ }
+
+ @Override
+ public String getVlanTag() {
+ return vlan;
+ }
+
+ public void setVlanTag(String vlan) {
+ this.vlan = vlan;
+ }
+
+ @Override
+ public String getGateway() {
+ return gateway;
+ }
+
+ @Override
+ public String getNetmask() {
+ return netmask;
+ }
+
+ @Override
+ public int getRegionId() {
+ return regionId;
+ }
+
+ @Override
+ public String getIpRange() {
+ return startIp + "-" + endIp;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d6452be8/server/src/org/apache/cloudstack/region/PortableIpVO.java
----------------------------------------------------------------------
diff --git a/server/src/org/apache/cloudstack/region/PortableIpVO.java b/server/src/org/apache/cloudstack/region/PortableIpVO.java
new file mode 100644
index 0000000..9a63009
--- /dev/null
+++ b/server/src/org/apache/cloudstack/region/PortableIpVO.java
@@ -0,0 +1,222 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.region;
+
+import java.util.Date;
+import java.util.UUID;
+
+import javax.persistence.*;
+
+import org.apache.cloudstack.api.Identity;
+import org.apache.cloudstack.api.InternalIdentity;
+
+@Entity
+@Table(name="portable_ip_address")
+public class PortableIpVO implements PortableIp {
+
+ @Id
+ @GeneratedValue(strategy=GenerationType.IDENTITY)
+ @Column(name="id")
+ Long id;
+
+ @Column(name="region_id")
+ int regionId;
+
+ @Column(name="allocated")
+ @Temporal(value=TemporalType.TIMESTAMP)
+ private Date allocatedTime;
+
+ @Column(name="account_id")
+ private Long allocatedToAccountId = null;
+
+ @Column(name="domain_id")
+ private Long allocatedInDomainId = null;
+
+ @Column(name="state")
+ private State state;
+
+ @Column(name="vlan")
+ String vlan;
+
+ @Column(name="gateway")
+ String gateway;
+
+ @Column(name="netmask")
+ String netmask;
+
+ @Column(name="portable_ip_address")
+ String address;
+
+ @Column(name="portable_ip_range_id")
+ private long rangeId;
+
+ @Column(name="physical_network_id")
+ private Long physicalNetworkId;
+
+ @Column(name="data_center_id")
+ private Long dataCenterId;
+
+ @Column(name="network_id")
+ private Long networkId;
+
+ @Column(name="vpc_id")
+ private Long vpcId;
+
+ public PortableIpVO() {
+
+ }
+
+ public PortableIpVO(int regionId, Long rangeId, String vlan, String gateway, String netmask, String address) {
+ this.regionId =regionId;
+ this.vlan = vlan;
+ this.gateway = gateway;
+ this.netmask = netmask;
+ this.address = address;
+ state = State.Free;
+ this.rangeId = rangeId;
+ }
+
+ @Override
+ public long getId() {
+ return id;
+ }
+
+ @Override
+ public Long getAllocatedToAccountId() {
+ return allocatedToAccountId;
+ }
+
+ public void setAllocatedToAccountId(Long accountId) {
+ this.allocatedToAccountId = accountId;
+ }
+
+ @Override
+ public Long getAllocatedInDomainId() {
+ return allocatedInDomainId;
+ }
+
+ public void setAllocatedInDomainId(Long domainId) {
+ this.allocatedInDomainId = domainId;
+ }
+
+ @Override
+ public Date getAllocatedTime() {
+ return allocatedTime;
+ }
+
+ public void setAllocatedTime(Date date) {
+ this.allocatedTime = date;
+ }
+
+ @Override
+ public State getState() {
+ return state;
+ }
+
+ public void setState(State state) {
+ this.state = state;
+ }
+
+ @Override
+ public int getRegionId() {
+ return regionId;
+ }
+
+ public void setRegionId(int regionId) {
+ this.regionId = regionId;
+ }
+
+ @Override
+ public Long getAssociatedDataCenterId() {
+ return dataCenterId;
+ }
+
+ public void setAssociatedDataCenterId(Long datacenterId) {
+ this.dataCenterId = datacenterId;
+ }
+
+ @Override
+ public Long getAssociatedWithNetworkId() {
+ return networkId;
+ }
+
+ public void setAssociatedWithNetworkId(Long networkId) {
+ this.networkId = networkId;
+ }
+
+ @Override
+ public Long getAssociatedWithVpcId() {
+ return vpcId;
+ }
+
+ public void setAssociatedWithVpcId(Long vpcId) {
+ this.vpcId = vpcId;
+ }
+
+ @Override
+ public Long getPhysicalNetworkId() {
+ return physicalNetworkId;
+ }
+
+ public void setPhysicalNetworkId(Long physicalNetworkId) {
+ this.physicalNetworkId = physicalNetworkId;
+ }
+
+ @Override
+ public String getAddress() {
+ return address;
+ }
+
+ public void setAddress(String address) {
+ this.address = address;
+ }
+
+ @Override
+ public String getVlan() {
+ return vlan;
+ }
+
+ public void setVlan(String vlan) {
+ this.vlan = vlan;
+ }
+
+ @Override
+ public String getNetmask() {
+ return netmask;
+ }
+
+ public void setNetmask(String netmask) {
+ this.netmask = netmask;
+ }
+
+ @Override
+ public String getGateway() {
+ return gateway;
+ }
+
+ public void setGateay(String gateway) {
+ this.gateway = gateway;
+ }
+
+ Long getRangeId() {
+ return rangeId;
+ }
+
+ public void setRangeId(Long rangeId) {
+ this.rangeId = rangeId;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d6452be8/server/test/com/cloud/network/MockNetworkManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/network/MockNetworkManagerImpl.java b/server/test/com/cloud/network/MockNetworkManagerImpl.java
index 87431ab..1ac014d 100755
--- a/server/test/com/cloud/network/MockNetworkManagerImpl.java
+++ b/server/test/com/cloud/network/MockNetworkManagerImpl.java
@@ -75,7 +75,6 @@ import com.cloud.vm.VirtualMachine;
import com.cloud.vm.*;
import com.cloud.vm.VirtualMachine.Type;
import com.cloud.vm.VirtualMachineProfile;
-import org.apache.cloudstack.acl.ControlledEntity.ACLType;
import org.apache.cloudstack.api.command.admin.network.DedicateGuestVlanRangeCmd;
import org.apache.cloudstack.api.command.admin.network.ListDedicatedGuestVlanRangesCmd;
import org.apache.cloudstack.api.command.admin.usage.ListTrafficTypeImplementorsCmd;
@@ -89,7 +88,6 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
-
@Component
@Local(value = { NetworkManager.class, NetworkService.class })
public class MockNetworkManagerImpl extends ManagerBase implements NetworkManager, NetworkService {
@@ -107,6 +105,27 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkManage
}
@Override
+ public IPAddressVO associatePortableIPToGuestNetwork(long ipAddrId, long networkId, boolean releaseOnFailure) throws ResourceAllocationException, ResourceUnavailableException {
+ return null;// TODO Auto-generated method stub
+ }
+
+ @Override
+ public IPAddressVO disassociatePortableIPToGuestNetwork(long ipAddrId, long networkId) throws ResourceAllocationException, ResourceUnavailableException, InsufficientAddressCapacityException, ConcurrentOperationException {
+ return null; // TODO Auto-generated method stub
+ }
+
+ @Override
+ public boolean isPortableIpTransferableFromNetwork(long ipAddrId, long networkId) {
+ return false;
+ }
+
+ @Override
+ public void transferPortableIP(long ipAddrId, long currentNetworkId, long newNetworkId) throws ResourceAllocationException, ResourceUnavailableException,
+ InsufficientAddressCapacityException, ConcurrentOperationException {
+
+ }
+
+ @Override
public boolean releaseIpAddress(long ipAddressId) {
// TODO Auto-generated method stub
return false;
@@ -862,6 +881,23 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkManage
}
@Override
+ public IpAddress allocatePortableIp(Account ipOwner, Account caller, long dcId, Long networkId, Long vpcID)
+ throws ConcurrentOperationException, ResourceAllocationException, InsufficientAddressCapacityException {
+ return null;// TODO Auto-generated method stub
+ }
+
+ @Override
+ public IpAddress allocatePortableIP(Account ipOwner, int regionId, Long zoneId, Long networkId, Long vpcId) throws ResourceAllocationException,
+ InsufficientAddressCapacityException, ConcurrentOperationException {
+ return null;
+ }
+
+ @Override
+ public boolean releasePortableIpAddress(long ipAddressId) throws InsufficientAddressCapacityException {
+ return false;// TODO Auto-generated method stub
+ }
+
+ @Override
public boolean isSecondaryIpSetForNic(long nicId) {
// TODO Auto-generated method stub
return false;
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d6452be8/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java b/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java
index 4fb182a..21b3590 100755
--- a/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java
+++ b/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java
@@ -16,6 +16,44 @@
// under the License.
package com.cloud.vpc;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.ejb.Local;
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+import javax.naming.NamingException;
+
+import org.apache.cloudstack.api.command.admin.config.UpdateCfgCmd;
+import org.apache.cloudstack.api.command.admin.ldap.LDAPConfigCmd;
+import org.apache.cloudstack.api.command.admin.ldap.LDAPRemoveCmd;
+import org.apache.cloudstack.api.command.admin.network.CreateNetworkOfferingCmd;
+import org.apache.cloudstack.api.command.admin.network.DeleteNetworkOfferingCmd;
+import org.apache.cloudstack.api.command.admin.network.UpdateNetworkOfferingCmd;
+import org.apache.cloudstack.api.command.admin.offering.CreateDiskOfferingCmd;
+import org.apache.cloudstack.api.command.admin.offering.CreateServiceOfferingCmd;
+import org.apache.cloudstack.api.command.admin.offering.DeleteDiskOfferingCmd;
+import org.apache.cloudstack.api.command.admin.offering.DeleteServiceOfferingCmd;
+import org.apache.cloudstack.api.command.admin.offering.UpdateDiskOfferingCmd;
+import org.apache.cloudstack.api.command.admin.offering.UpdateServiceOfferingCmd;
+import org.apache.cloudstack.api.command.admin.pod.DeletePodCmd;
+import org.apache.cloudstack.api.command.admin.pod.UpdatePodCmd;
+import org.apache.cloudstack.api.command.admin.region.CreatePortableIpRangeCmd;
+import org.apache.cloudstack.api.command.admin.region.DeletePortableIpRangeCmd;
+import org.apache.cloudstack.api.command.admin.region.ListPortableIpRangesCmd;
+import org.apache.cloudstack.api.command.admin.vlan.CreateVlanIpRangeCmd;
+import org.apache.cloudstack.api.command.admin.vlan.DedicatePublicIpRangeCmd;
+import org.apache.cloudstack.api.command.admin.vlan.DeleteVlanIpRangeCmd;
+import org.apache.cloudstack.api.command.admin.vlan.ReleasePublicIpRangeCmd;
+import org.apache.cloudstack.api.command.admin.zone.CreateZoneCmd;
+import org.apache.cloudstack.api.command.admin.zone.DeleteZoneCmd;
+import org.apache.cloudstack.api.command.admin.zone.UpdateZoneCmd;
+import org.apache.cloudstack.api.command.user.network.ListNetworkOfferingsCmd;
+import org.apache.cloudstack.region.PortableIp;
+import org.apache.cloudstack.region.PortableIpRange;
+import org.springframework.stereotype.Component;
+
import com.cloud.configuration.Configuration;
import com.cloud.configuration.ConfigurationManager;
import com.cloud.configuration.ConfigurationService;
@@ -381,6 +419,26 @@ public class MockConfigurationManagerImpl extends ManagerBase implements Configu
return false;
}
+ @Override
+ public PortableIpRange createPortableIpRange(CreatePortableIpRangeCmd cmd) throws ConcurrentOperationException {
+ return null;// TODO Auto-generated method stub
+ }
+
+ @Override
+ public boolean deletePortableIpRange(DeletePortableIpRangeCmd cmd) {
+ return false;// TODO Auto-generated method stub
+ }
+
+ @Override
+ public List<? extends PortableIpRange> listPortableIpRanges(ListPortableIpRangesCmd cmd) {
+ return null;// TODO Auto-generated method stub
+ }
+
+ @Override
+ public List<? extends PortableIp> listPortableIps(long id) {
+ return null;// TODO Auto-generated method stub
+ }
+
/* (non-Javadoc)
* @see com.cloud.utils.component.Manager#configure(java.lang.String, java.util.Map)
*/
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d6452be8/server/test/com/cloud/vpc/MockNetworkManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java
index 3e6a08b..62599b8 100644
--- a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java
+++ b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java
@@ -63,7 +63,6 @@ import com.cloud.network.PhysicalNetworkServiceProvider;
import com.cloud.network.PhysicalNetworkTrafficType;
import com.cloud.network.PublicIpAddress;
import com.cloud.network.addr.PublicIp;
-import com.cloud.network.dao.AccountGuestVlanMapVO;
import com.cloud.network.dao.IPAddressVO;
import com.cloud.network.dao.NetworkServiceMapDao;
import com.cloud.network.dao.NetworkVO;
@@ -198,13 +197,36 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkManage
return null;
}
+ @Override
+ public IpAddress allocatePortableIp(Account ipOwner, Account caller, long dcId, Long networkId, Long vpcID)
+ throws ConcurrentOperationException, ResourceAllocationException, InsufficientAddressCapacityException {
+ return null;// TODO Auto-generated method stub
+ }
+ @Override
+ public IpAddress allocatePortableIP(Account ipOwner, int regionId, Long zoneId, Long networkId, Long vpcId) throws ResourceAllocationException,
+ InsufficientAddressCapacityException, ConcurrentOperationException {
+ return null;
+ }
+ @Override
+ public boolean releasePortableIpAddress(long ipAddressId) throws InsufficientAddressCapacityException {
+ return false;// TODO Auto-generated method stub
+ }
+ @Override
+ public boolean isPortableIpTransferableFromNetwork(long ipAddrId, long networkId) {
+ return false;
+ }
+
+ @Override
+ public void transferPortableIP(long ipAddrId, long currentNetworkId, long newNetworkId) throws ResourceAllocationException, ResourceUnavailableException,
+ InsufficientAddressCapacityException, ConcurrentOperationException {
+ }
/* (non-Javadoc)
- * @see com.cloud.network.NetworkService#releaseIpAddress(long)
- */
+ * @see com.cloud.network.NetworkService#releaseIpAddress(long)
+ */
@Override
public boolean releaseIpAddress(long ipAddressId) throws InsufficientAddressCapacityException {
// TODO Auto-generated method stub
@@ -1112,13 +1134,20 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkManage
return null;
}
+ @Override
+ public IPAddressVO associatePortableIPToGuestNetwork(long ipAddrId, long networkId, boolean releaseOnFailure) throws ResourceAllocationException, ResourceUnavailableException {
+ return null;// TODO Auto-generated method stub
+ }
-
+ @Override
+ public IPAddressVO disassociatePortableIPToGuestNetwork(long ipAddrId, long networkId) throws ResourceAllocationException, ResourceUnavailableException, InsufficientAddressCapacityException, ConcurrentOperationException {
+ return null;// TODO Auto-generated method stub
+ }
/* (non-Javadoc)
- * @see com.cloud.network.NetworkManager#setupDns(com.cloud.network.Network, com.cloud.network.Network.Provider)
- */
+ * @see com.cloud.network.NetworkManager#setupDns(com.cloud.network.Network, com.cloud.network.Network.Provider)
+ */
@Override
public boolean setupDns(Network network, Provider provider) {
// TODO Auto-generated method stub
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d6452be8/server/test/org/apache/cloudstack/networkoffering/ChildTestConfiguration.java
----------------------------------------------------------------------
diff --git a/server/test/org/apache/cloudstack/networkoffering/ChildTestConfiguration.java b/server/test/org/apache/cloudstack/networkoffering/ChildTestConfiguration.java
index a825699..f862a2a 100644
--- a/server/test/org/apache/cloudstack/networkoffering/ChildTestConfiguration.java
+++ b/server/test/org/apache/cloudstack/networkoffering/ChildTestConfiguration.java
@@ -20,6 +20,9 @@ package org.apache.cloudstack.networkoffering;
import java.io.IOException;
import org.apache.cloudstack.acl.SecurityChecker;
+import org.apache.cloudstack.region.PortableIpDaoImpl;
+import org.apache.cloudstack.region.dao.RegionDaoImpl;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDaoImpl;
import org.apache.cloudstack.test.utils.SpringUtils;
import org.mockito.Mockito;
@@ -113,6 +116,7 @@ import com.cloud.vm.dao.NicDaoImpl;
import com.cloud.vm.dao.NicSecondaryIpDaoImpl;
import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.dao.VMInstanceDaoImpl;
+import org.apache.cloudstack.region.PortableIpRangeDaoImpl;
@Configuration
@ComponentScan(basePackageClasses={
@@ -162,6 +166,9 @@ import com.cloud.vm.dao.VMInstanceDaoImpl;
NetworkServiceMapDaoImpl.class,
PrimaryDataStoreDaoImpl.class,
StoragePoolDetailsDaoImpl.class,
+ PortableIpRangeDaoImpl.class,
+ RegionDaoImpl.class,
+ PortableIpDaoImpl.class,
AccountGuestVlanMapDaoImpl.class
},
includeFilters={@Filter(value=ChildTestConfiguration.Library.class, type=FilterType.CUSTOM)},
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d6452be8/setup/db/db/schema-410to420.sql
----------------------------------------------------------------------
diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql
index c088ac1..7b5e9cb 100644
--- a/setup/db/db/schema-410to420.sql
+++ b/setup/db/db/schema-410to420.sql
@@ -1267,6 +1267,43 @@ INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'Netwo
alter table `cloud_usage`.`usage_network_offering` add column nic_id bigint(20) unsigned NOT NULL;
+
+CREATE TABLE `cloud`.`portable_ip_range` (
+ `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT,
+ `uuid` varchar(40),
+ `region_id` int unsigned NOT NULL,
+ `vlan_id` varchar(255),
+ `gateway` varchar(255),
+ `netmask` varchar(255),
+ `start_ip` varchar(255),
+ `end_ip` varchar(255),
+ PRIMARY KEY (`id`),
+ CONSTRAINT `fk_portableip__region_id` FOREIGN KEY (`region_id`) REFERENCES `region`(`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+CREATE TABLE `cloud`.`portable_ip_address` (
+ `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT,
+ `account_id` bigint unsigned NULL,
+ `domain_id` bigint unsigned NULL,
+ `allocated` datetime NULL COMMENT 'Date portable ip was allocated',
+ `state` char(32) NOT NULL default 'Free' COMMENT 'state of the portable ip address',
+ `region_id` int unsigned NOT NULL,
+ `vlan` varchar(255),
+ `gateway` varchar(255),
+ `netmask` varchar(255),
+ `portable_ip_address` varchar(255),
+ `portable_ip_range_id` bigint unsigned NOT NULL,
+ `data_center_id` bigint unsigned NULL COMMENT 'zone to which portable IP is associated',
+ `physical_network_id` bigint unsigned NULL COMMENT 'physical network id in the zone to which portable IP is associated',
+ `network_id` bigint unsigned NULL COMMENT 'guest network to which portable ip address is associated with',
+ `vpc_id` bigint unsigned COMMENT 'vpc to which portable ip address is associated with',
+ PRIMARY KEY (`id`),
+ CONSTRAINT `fk_portable_ip_address__portable_ip_range_id` FOREIGN KEY (`portable_ip_range_id`) REFERENCES `portable_ip_range`(`id`) ON DELETE CASCADE,
+ CONSTRAINT `fk_portable_ip_address__region_id` FOREIGN KEY (`region_id`) REFERENCES `region`(`id`) ON DELETE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+ALTER TABLE `cloud`.`user_ip_address` ADD COLUMN is_portable int(1) unsigned NOT NULL default '0';
+
DROP VIEW IF EXISTS `cloud`.`disk_offering_view`;
CREATE VIEW `cloud`.`disk_offering_view` AS
select
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d6452be8/test/integration/smoke/test_portable_publicip.py
----------------------------------------------------------------------
diff --git a/test/integration/smoke/test_portable_publicip.py b/test/integration/smoke/test_portable_publicip.py
new file mode 100644
index 0000000..101747d
--- /dev/null
+++ b/test/integration/smoke/test_portable_publicip.py
@@ -0,0 +1,237 @@
+#!/usr/bin/env python
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+from marvin.cloudstackTestCase import *
+from marvin.cloudstackAPI import *
+from marvin.integration.lib.utils import *
+from marvin.integration.lib.base import *
+from marvin.integration.lib.common import *
+from marvin import remoteSSHClient
+from nose.plugins.attrib import attr
+
+class Services:
+ """Test Data
+ """
+
+ def __init__(self):
+ self.services = {
+ "domain": {
+ "name": "Domain",
+ },
+ "account": {
+ "email": "test@test.com",
+ "firstname": "Test",
+ "lastname": "User",
+ "username": "test",
+ # Random characters are appended for unique
+ # username
+ "password": "password",
+ },
+ "service_offering": {
+ "name": "Tiny Instance",
+ "displaytext": "Tiny Instance",
+ "cpunumber": 1,
+ "cpuspeed": 100,
+ # in MHz
+ "memory": 128,
+ # In MBs
+ },
+ "network_offering": {
+ "name": 'Test Network offering',
+ "displaytext": 'Test Network offering',
+ "guestiptype": 'Isolated',
+ "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding',
+ "traffictype": 'GUEST',
+ "availability": 'Optional',
+ "serviceProviderList" : {
+ "Dhcp": 'VirtualRouter',
+ "Dns": 'VirtualRouter',
+ "SourceNat": 'VirtualRouter',
+ "PortForwarding": 'VirtualRouter',
+ },
+ },
+ "network": {
+ "name": "Test Network",
+ "displaytext": "Test Network",
+ },
+ "ostype": 'CentOS 5.3 (64-bit)',
+ "gateway" : "10.1.1.1",
+ "netmask" : "255.255.255.0",
+ "startip" : "10.1.1.10",
+ "endip" : "10.1.1.20",
+ "regionid" : "1",
+ "vlan" :"10",
+ "isportable" : "true",
+ "virtual_machine" : {
+ "affinity": {
+ "name": "webvms",
+ "type": "host anti-affinity",
+ },
+ "hypervisor" : "XenServer",
+ }
+ }
+
+class TestPortablePublicIPRange(cloudstackTestCase):
+
+ """
+ This test validates functionality where
+ - admin can provision a portable public ip range
+ - list provisioned portable public ip range
+ - delete provisioned portable public ip range
+ """
+ @classmethod
+ def setUpClass(cls):
+ cls.api_client = super(TestPortablePublicIPRange, cls).getClsTestClient().getApiClient()
+ cls.services = Services().services
+ # Get Zone, Domain
+ cls.domain = get_domain(cls.api_client, cls.services)
+ cls.zone = get_zone(cls.api_client, cls.services)
+
+ # Create Account
+ cls.account = Account.create(
+ cls.api_client,
+ cls.services["account"],
+ domainid=cls.domain.id
+ )
+ cls._cleanup = [
+ cls.account,
+ ]
+ return
+
+ @classmethod
+ def tearDownClass(cls):
+ try:
+ # Cleanup resources used
+ cleanup_resources(cls.api_client, cls._cleanup)
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def setUp(self):
+ self.apiclient = self.testClient.getApiClient()
+ self.dbclient = self.testClient.getDbConnection()
+ self.cleanup = []
+ return
+
+ def tearDown(self):
+ try:
+ # Clean up
+ cleanup_resources(self.apiclient, self.cleanup)
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ @attr(tags = ["simulator", "basic", "advanced", "portablepublicip"])
+ def test_createPortablePublicIPRange(self):
+ """
+ """
+ self.debug("attempting to create a portable Public IP range")
+ self.portable_ip_range = PortablePublicIpRange.create(
+ self.api_client,
+ self.services
+ )
+ self.debug("attempting to verify portable Public IP range is created")
+ list_portbale_ip_range_response = PortablePublicIpRange.list(
+ self.apiclient,
+ id=self.portable_ip_range.id
+ )
+ self.portable_ip_range.delete(self.apiclient)
+ return
+
+
+class TestPortablePublicIPAcquire(cloudstackTestCase):
+
+ """
+ This test validates functionality where
+ - admin has provisioned a portable public ip range
+ - user can acquire portable ip from the provisioned ip range
+ """
+ @classmethod
+ def setUpClass(cls):
+ cls.api_client = super(TestPortablePublicIPAcquire, cls).getClsTestClient().getApiClient()
+ cls.services = Services().services
+ # Get Zone, Domain
+ cls.domain = get_domain(cls.api_client, cls.services)
+ cls.zone = get_zone(cls.api_client, cls.services)
+ # Create Account
+ cls.account = Account.create(
+ cls.api_client,
+ cls.services["account"],
+ domainid=cls.domain.id
+ )
+ cls.services["network"]["zoneid"] = cls.zone.id
+
+ cls.network_offering = NetworkOffering.create(
+ cls.api_client,
+ cls.services["network_offering"],
+ )
+ # Enable Network offering
+ cls.network_offering.update(cls.api_client, state='Enabled')
+
+ cls.services["network"]["networkoffering"] = cls.network_offering.id
+ cls.account_network = Network.create(
+ cls.api_client,
+ cls.services["network"],
+ cls.account.name,
+ cls.account.domainid
+ )
+ cls._cleanup = [
+ cls.account_network,
+ cls.network_offering,
+ cls.account
+ ]
+
+ return
+
+ @classmethod
+ def tearDownClass(cls):
+ try:
+ # Cleanup resources used
+ cleanup_resources(cls.api_client, cls._cleanup)
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def setUp(self):
+ self.apiclient = self.testClient.getApiClient()
+ self.dbclient = self.testClient.getDbConnection()
+ self.cleanup = []
+ return
+
+ def tearDown(self):
+ try:
+ # Clean up
+ cleanup_resources(self.apiclient, self.cleanup)
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ @attr(tags = ["simulator", "basic", "advanced", "portablepublicip"])
+ def test_createPortablePublicIPAcquire(self):
+ """
+ """
+ self.debug("attempting to create a portable Public IP range")
+ self.portable_ip_range = PortablePublicIpRange.create(
+ self.api_client,
+ self.services
+ )
+
+ ip_address = PublicIPAddress.create(self.api_client, self.account.name, self.zone.id, self.account.domainid)
+
+ self.portable_ip_range.delete(self.apiclient)
+ return
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d6452be8/tools/marvin/marvin/integration/lib/base.py
----------------------------------------------------------------------
diff --git a/tools/marvin/marvin/integration/lib/base.py b/tools/marvin/marvin/integration/lib/base.py
index f3a96bd..ec1c34e 100755
--- a/tools/marvin/marvin/integration/lib/base.py
+++ b/tools/marvin/marvin/integration/lib/base.py
@@ -2131,6 +2131,42 @@ class PublicIpRange:
cmd.id = self.vlan.id
return apiclient.releasePublicIpRange(cmd)
+
+class PortablePublicIpRange:
+ """Manage portable public Ip Range"""
+
+ def __init__(self, items):
+ self.__dict__.update(items)
+
+ @classmethod
+ def create(cls, apiclient, services):
+ """Create portable public Ip Range"""
+
+ cmd = createPortableIpRange.createPortableIpRangeCmd()
+ cmd.gateway = services["gateway"]
+ cmd.netmask = services["netmask"]
+ cmd.startip = services["startip"]
+ cmd.endip = services["endip"]
+ cmd.regionid = services["regionid"]
+ cmd.vlan = services["vlan"]
+
+ return PortablePublicIpRange(apiclient.createVlanIpRange(cmd).__dict__)
+
+ def delete(self, apiclient):
+ """Delete portable IpRange"""
+
+ cmd = deletePortableIpRange.deletePortableIpRangeCmd()
+ cmd.id = self.id
+ apiclient.deletePortableIpRange(cmd)
+
+ @classmethod
+ def list(cls, apiclient, **kwargs):
+ """Lists all portable public IP ranges."""
+
+ cmd = listPortableIpRanges.listPortableIpRangesCmd()
+ [setattr(cmd, k, v) for k, v in kwargs.items()]
+ return(apiclient.listPortableIpRanges(cmd))
+
class SecondaryStorage:
"""Manage Secondary storage"""
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d6452be8/utils/src/com/cloud/utils/net/NetUtils.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/net/NetUtils.java b/utils/src/com/cloud/utils/net/NetUtils.java
index 9551c26..37dcef3 100755
--- a/utils/src/com/cloud/utils/net/NetUtils.java
+++ b/utils/src/com/cloud/utils/net/NetUtils.java
@@ -1296,6 +1296,18 @@ public class NetUtils {
return resultIp;
}
+ public static boolean isValidVlan(String vlan) {
+ try {
+ int vnet = Integer.parseInt(vlan);
+ if (vnet < 0 || vnet > 4096) {
+ return false;
+ }
+ return true;
+ } catch (NumberFormatException e) {
+ return false;
+ }
+ }
+
public static URI generateUriForPvlan(String primaryVlan, String isolatedPvlan) {
return URI.create("pvlan://" + primaryVlan + "-i" + isolatedPvlan);
}
@@ -1320,4 +1332,5 @@ public class NetUtils {
}
return null;
}
+
}