diff --git a/server/src/com/cloud/network/element/VirtualRouterElement.java b/server/src/com/cloud/network/element/VirtualRouterElement.java index 7a4862484f8..65f06b346cb 100755 --- a/server/src/com/cloud/network/element/VirtualRouterElement.java +++ b/server/src/com/cloud/network/element/VirtualRouterElement.java @@ -982,7 +982,10 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl throw new ResourceUnavailableException("Can't find at least one router!", DataCenter.class, network.getDataCenterId()); } - return _routerMgr.applyUserData(network, nic, uservm, dest, routers); + DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId()); + NetworkTopology networkTopology = networkTopologyContext.retrieveNetworkTopology(dcVO); + + return networkTopology.applyUserData(network, nic, uservm, dest, routers); } return false; } diff --git a/server/src/com/cloud/network/rules/UserdataPwdRules.java b/server/src/com/cloud/network/rules/UserdataPwdRules.java index ab6fc0c1fc6..ecb25092a61 100644 --- a/server/src/com/cloud/network/rules/UserdataPwdRules.java +++ b/server/src/com/cloud/network/rules/UserdataPwdRules.java @@ -19,43 +19,82 @@ package com.cloud.network.rules; import org.apache.cloudstack.network.topology.NetworkTopologyVisitor; +import com.cloud.agent.api.routing.NetworkElementCommand; +import com.cloud.agent.api.routing.SavePasswordCommand; +import com.cloud.agent.manager.Commands; +import com.cloud.dc.DataCenterVO; import com.cloud.deploy.DeployDestination; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.Network; import com.cloud.network.router.VirtualRouter; +import com.cloud.utils.PasswordGenerator; import com.cloud.vm.NicProfile; +import com.cloud.vm.NicVO; +import com.cloud.vm.UserVmVO; import com.cloud.vm.VirtualMachineProfile; public class UserdataPwdRules extends RuleApplier { - private final NicProfile nic; - private final VirtualMachineProfile profile; - private final DeployDestination destination; + private final NicProfile _nic; + private final VirtualMachineProfile _profile; + private final DeployDestination _destination; + + private NicVO _nicVo; + private UserVmVO _userVM; public UserdataPwdRules(final Network network, final NicProfile nic, final VirtualMachineProfile profile, final DeployDestination destination) { super(network); - this.nic = nic; - this.profile = profile; - this.destination = destination; + _nic = nic; + _profile = profile; + _destination = destination; } @Override public boolean accept(final NetworkTopologyVisitor visitor, final VirtualRouter router) throws ResourceUnavailableException { - this._router = router; + _router = router; + + _userVM = _userVmDao.findById(_profile.getId()); + _userVmDao.loadDetails(_userVM); + + //for basic zone, send vm data/password information only to the router in the same pod + _nicVo = _nicDao.findById(_nic.getId()); return visitor.visit(this); } - public NicProfile getNic() { - return nic; - } - public VirtualMachineProfile getProfile() { - return profile; + return _profile; } public DeployDestination getDestination() { - return destination; + return _destination; + } + + public NicVO getNicVo() { + return _nicVo; + } + + public UserVmVO getUserVM() { + return _userVM; + } + + public void createPasswordCommand(final VirtualRouter router, final VirtualMachineProfile profile, final NicVO nic, final Commands cmds) { + final String password = (String)profile.getParameter(VirtualMachineProfile.Param.VmPassword); + final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId()); + + // password should be set only on default network element + if (password != null && nic.isDefaultNic()) { + final String encodedPassword = PasswordGenerator.rot13(password); + final SavePasswordCommand cmd = + new SavePasswordCommand(encodedPassword, nic.getIp4Address(), profile.getVirtualMachine().getHostName(), _networkModel.getExecuteInSeqNtwkElmtCmd()); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, _routerControlHelper.getRouterIpInNetwork(nic.getNetworkId(), router.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); + cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); + + cmds.addCommand("password", cmd); + } + } } \ No newline at end of file diff --git a/server/src/com/cloud/network/rules/VirtualNetworkApplianceFactory.java b/server/src/com/cloud/network/rules/VirtualNetworkApplianceFactory.java index e9126b7852f..c5233c9a72a 100644 --- a/server/src/com/cloud/network/rules/VirtualNetworkApplianceFactory.java +++ b/server/src/com/cloud/network/rules/VirtualNetworkApplianceFactory.java @@ -23,6 +23,7 @@ import javax.inject.Inject; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import com.cloud.dc.dao.DataCenterDao; +import com.cloud.deploy.DeployDestination; import com.cloud.network.Network; import com.cloud.network.NetworkModel; import com.cloud.network.PublicIpAddress; @@ -190,4 +191,16 @@ public class VirtualNetworkApplianceFactory { return userdataRules; } + + public UserdataPwdRules createUserdataPwdRules(final Network network, final NicProfile nic, final VirtualMachineProfile profile, final DeployDestination destination) { + UserdataPwdRules userdataRules = new UserdataPwdRules(network, nic, profile, destination); + + initBeans(userdataRules); + + userdataRules._userVmDao = _userVmDao; + userdataRules._templateDao = _templateDao; + userdataRules._serviceOfferingDao = _serviceOfferingDao; + + return userdataRules; + } } \ No newline at end of file diff --git a/server/src/org/apache/cloudstack/network/topology/AdvancedNetworkTopology.java b/server/src/org/apache/cloudstack/network/topology/AdvancedNetworkTopology.java index 49cc2fbace7..8aad88a6b3a 100644 --- a/server/src/org/apache/cloudstack/network/topology/AdvancedNetworkTopology.java +++ b/server/src/org/apache/cloudstack/network/topology/AdvancedNetworkTopology.java @@ -18,7 +18,6 @@ package org.apache.cloudstack.network.topology; import java.util.List; -import java.util.Map; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; @@ -26,27 +25,19 @@ import org.springframework.beans.factory.annotation.Qualifier; import com.cloud.dc.DataCenter; import com.cloud.deploy.DeployDestination; -import com.cloud.exception.ConcurrentOperationException; -import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.Network; import com.cloud.network.lb.LoadBalancingRule; import com.cloud.network.router.VirtualRouter; import com.cloud.network.rules.RuleApplier; -import com.cloud.user.Account; +import com.cloud.network.rules.RuleApplierWrapper; +import com.cloud.network.rules.UserdataPwdRules; import com.cloud.vm.DomainRouterVO; import com.cloud.vm.NicProfile; import com.cloud.vm.VirtualMachineProfile; -import com.cloud.vm.VirtualMachineProfile.Param; public class AdvancedNetworkTopology implements NetworkTopology { - @Override - public List findOrDeployVirtualRouterInGuestNetwork(final Network guestNetwork, final DeployDestination dest, final Account owner, final boolean isRedundant, - final Map params) throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { - return null; - } - @Override public StringBuilder createGuestBootLoadArgs(final NicProfile guestNic, final String defaultDns1, final String defaultDns2, final DomainRouterVO router) { return null; @@ -74,12 +65,6 @@ public class AdvancedNetworkTopology implements NetworkTopology { return false; } - @Override - public boolean applyUserData(final Network network, final NicProfile nic, final VirtualMachineProfile profile, final DeployDestination dest, final List routers) - throws ResourceUnavailableException { - return false; - } - @Override public boolean applyRules(final Network network, final List routers, final String typeString, final boolean isPodLevelException, final Long podId, final boolean failWhenDisconnect, final RuleApplier applier) throws ResourceUnavailableException { @@ -102,4 +87,19 @@ public class AdvancedNetworkTopology implements NetworkTopology { @Qualifier("advancedNetworkVisitor") protected AdvancedNetworkVisitor _advancedVisitor; + @Override + public boolean applyUserData(final Network network, final NicProfile nic, final VirtualMachineProfile profile, final DeployDestination dest, final List routers) + throws ResourceUnavailableException { + + s_logger.debug("APPLYING USERDATA RULES"); + + final String typeString = "userdata and password entry"; + final boolean isPodLevelException = false; + final boolean failWhenDisconnect = false; + final Long podId = null; + + UserdataPwdRules pwdRules = _virtualNetworkApplianceFactory.createUserdataPwdRules(network, nic, profile, dest); + + return applyRules(network, routers, typeString, isPodLevelException, podId, failWhenDisconnect, new RuleApplierWrapper(pwdRules)); + } } \ No newline at end of file diff --git a/server/src/org/apache/cloudstack/network/topology/AdvancedNetworkVisitor.java b/server/src/org/apache/cloudstack/network/topology/AdvancedNetworkVisitor.java index 9f59ccbbaba..4a06912bf6d 100644 --- a/server/src/org/apache/cloudstack/network/topology/AdvancedNetworkVisitor.java +++ b/server/src/org/apache/cloudstack/network/topology/AdvancedNetworkVisitor.java @@ -17,148 +17,65 @@ package org.apache.cloudstack.network.topology; -import org.apache.log4j.Logger; import org.springframework.stereotype.Component; +import com.cloud.agent.api.Command; import com.cloud.agent.manager.Commands; import com.cloud.exception.ResourceUnavailableException; -import com.cloud.network.Network; -import com.cloud.network.PublicIpAddress; -import com.cloud.network.lb.LoadBalancingRule; import com.cloud.network.router.VirtualRouter; -import com.cloud.network.rules.DhcpRules; -import com.cloud.network.rules.FirewallRule; -import com.cloud.network.rules.FirewallRule.Purpose; -import com.cloud.network.rules.FirewallRules; -import com.cloud.network.rules.IpAssociationRules; -import com.cloud.network.rules.LoadBalancingRules; +import com.cloud.network.rules.DhcpEntryRules; +import com.cloud.network.rules.DhcpSubNetRules; import com.cloud.network.rules.NetworkAclsRules; import com.cloud.network.rules.PasswordToRouterRules; -import com.cloud.network.rules.PortForwardingRule; import com.cloud.network.rules.PrivateGatewayRules; import com.cloud.network.rules.SshKeyToRouterRules; -import com.cloud.network.rules.StaticNat; -import com.cloud.network.rules.StaticNatRule; -import com.cloud.network.rules.StaticNatRules; import com.cloud.network.rules.UserdataPwdRules; import com.cloud.network.rules.UserdataToRouterRules; import com.cloud.network.rules.VpcIpAssociationRules; -import com.cloud.network.rules.VpnRules; +import com.cloud.vm.NicVO; +import com.cloud.vm.UserVmVO; +import com.cloud.vm.VirtualMachineProfile; @Component public class AdvancedNetworkVisitor extends BasicNetworkVisitor { - private static final Logger s_logger = Logger.getLogger(AdvancedNetworkVisitor.class); + @Override + public boolean visit(final UserdataPwdRules userdata) throws ResourceUnavailableException { + final VirtualRouter router = userdata.getRouter(); - protected NEWVirtualNetworkApplianceManager applianceManager; + final Commands commands = new Commands(Command.OnError.Stop); + final VirtualMachineProfile profile = userdata.getProfile(); + final NicVO nicVo = userdata.getNicVo(); + final UserVmVO userVM = userdata.getUserVM(); - public void setApplianceManager(final NEWVirtualNetworkApplianceManager applianceManager) { - this.applianceManager = applianceManager; + userdata.createPasswordCommand(router, profile, nicVo, commands); + userdata.createVmDataCommand(router, userVM, nicVo, userVM.getDetail("SSH.PublicKey"), commands); + + return _applianceManager.sendCommandsToRouter(router, commands); } @Override - public boolean visit(final StaticNatRules nat) throws ResourceUnavailableException { - Network network = nat.getNetwork(); - VirtualRouter router = nat.getRouter(); - List rules = nat.getRules(); - - final Commands cmds = new Commands(Command.OnError.Continue); - nat.createApplyStaticNatCommands(rules, router, cmds, network.getId()); - - return applianceManager.sendCommandsToRouter(router, cmds); - } - - @Override - public boolean visit(final LoadBalancingRules loadbalancing) throws ResourceUnavailableException { - Network network = loadbalancing.getNetwork(); - VirtualRouter router = loadbalancing.getRouter(); - List rules = loadbalancing.getRules(); - - final Commands cmds = new Commands(Command.OnError.Continue); - loadbalancing.createApplyLoadBalancingRulesCommands(rules, router, cmds, network.getId()); - - return networkTopology.sendCommandsToRouter(router, rules, network.getId()); - } - - @SuppressWarnings("unchecked") - @Override - public boolean visit(final FirewallRules firewall) throws ResourceUnavailableException { - Network network = firewall.getNetwork(); - VirtualRouter router = firewall.getRouter(); - List rules = firewall.getRules(); - List loadbalancingRules = firewall.getLoadbalancingRules(); - - Purpose purpose = firewall.getPurpose(); - - final Commands cmds = new Commands(Command.OnError.Continue); - if (purpose == Purpose.LoadBalancing) { - - firewall.createApplyLoadBalancingRulesCommands(loadbalancingRules, router, cmds, network.getId()); - - return applianceManager.sendCommandsToRouter(router, cmds); - - } else if (purpose == Purpose.PortForwarding) { - - firewall.createApplyPortForwardingRulesCommands((List) rules, router, cmds, network.getId()); - - return applianceManager.sendCommandsToRouter(router, cmds); - - } else if (purpose == Purpose.StaticNat) { - - firewall.createApplyStaticNatRulesCommands((List) rules, router, cmds, network.getId()); - - return applianceManager.sendCommandsToRouter(router, cmds); - - } else if (purpose == Purpose.Firewall) { - - firewall.createApplyFirewallRulesCommands(rules, router, cmds, network.getId()); - - return applianceManager.sendCommandsToRouter(router, cmds); - - } - s_logger.warn("Unable to apply rules of purpose: " + rules.get(0).getPurpose()); - + public boolean visit(final DhcpEntryRules dhcp) throws ResourceUnavailableException { return false; } @Override - public boolean visit(final IpAssociationRules ipRules) throws ResourceUnavailableException { - Network network = ipRules.getNetwork(); - VirtualRouter router = ipRules.getRouter(); - Commands commands = ipRules.getCommands(); - List ips = ipRules.getIpAddresses(); - - ipRules.createAssociateIPCommands(router, ips, commands, network.getId()); - return applianceManager.sendCommandsToRouter(router, commands); - } - - @Override - public boolean visit(final UserdataPwdRules nat) throws ResourceUnavailableException { + public boolean visit(final SshKeyToRouterRules sshkey) throws ResourceUnavailableException { return false; } @Override - public boolean visit(final DhcpRules nat) throws ResourceUnavailableException { + public boolean visit(final PasswordToRouterRules pwd) throws ResourceUnavailableException { return false; } @Override - public boolean visit(final SshKeyToRouterRules nat) throws ResourceUnavailableException { + public boolean visit(final NetworkAclsRules acls) throws ResourceUnavailableException { return false; } @Override - public boolean visit(final PasswordToRouterRules nat) throws ResourceUnavailableException { - return false; - } - - @Override - public boolean visit(final NetworkAclsRules nat) throws ResourceUnavailableException { - return false; - } - - @Override - public boolean visit(final VpcIpAssociationRules nat) throws ResourceUnavailableException { + public boolean visit(final VpcIpAssociationRules vpcip) throws ResourceUnavailableException { return false; } @@ -173,12 +90,12 @@ public class AdvancedNetworkVisitor extends BasicNetworkVisitor { } @Override - public boolean visit(final DhcpPvlanRules vpn) throws ResourceUnavailableException { + public boolean visit(final DhcpPvlanRules dhcp) throws ResourceUnavailableException { return false; } @Override - public boolean visit(final VpnRules userdata) throws ResourceUnavailableException { + public boolean visit(final DhcpSubNetRules subnet) throws ResourceUnavailableException { return false; } } \ No newline at end of file diff --git a/server/src/org/apache/cloudstack/network/topology/BasicNetworkTopology.java b/server/src/org/apache/cloudstack/network/topology/BasicNetworkTopology.java index c70fd909011..54e61d03cd2 100644 --- a/server/src/org/apache/cloudstack/network/topology/BasicNetworkTopology.java +++ b/server/src/org/apache/cloudstack/network/topology/BasicNetworkTopology.java @@ -36,6 +36,7 @@ import com.cloud.exception.ResourceUnavailableException; import com.cloud.host.Status; import com.cloud.host.dao.HostDao; import com.cloud.network.Network; +import com.cloud.network.Networks.TrafficType; import com.cloud.network.PublicIpAddress; import com.cloud.network.VpnUser; import com.cloud.network.lb.LoadBalancingRule; @@ -50,12 +51,14 @@ import com.cloud.network.rules.RuleApplierWrapper; import com.cloud.network.rules.SshKeyToRouterRules; import com.cloud.network.rules.StaticNat; import com.cloud.network.rules.StaticNatRules; +import com.cloud.network.rules.UserdataPwdRules; import com.cloud.network.rules.UserdataToRouterRules; import com.cloud.network.rules.VirtualNetworkApplianceFactory; import com.cloud.network.rules.VpnRules; import com.cloud.vm.DomainRouterVO; import com.cloud.vm.NicProfile; import com.cloud.vm.UserVmVO; +import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachine.State; import com.cloud.vm.VirtualMachineProfile; import com.cloud.vm.dao.UserVmDao; @@ -110,7 +113,23 @@ public class BasicNetworkTopology implements NetworkTopology { @Override public boolean applyUserData(final Network network, final NicProfile nic, final VirtualMachineProfile profile, final DeployDestination dest, final List routers) throws ResourceUnavailableException { - return false; + + s_logger.debug("APPLYING USERDATA RULES"); + + final String typeString = "userdata and password entry"; + final Long podId = dest.getPod().getId(); + boolean isPodLevelException = false; + + if (podId != null && profile.getVirtualMachine().getType() == VirtualMachine.Type.User && network.getTrafficType() == TrafficType.Guest + && network.getGuestType() == Network.GuestType.Shared) { + isPodLevelException = true; + } + + final boolean failWhenDisconnect = false; + + UserdataPwdRules pwdRules = _virtualNetworkApplianceFactory.createUserdataPwdRules(network, nic, profile, dest); + + return applyRules(network, routers, typeString, isPodLevelException, podId, failWhenDisconnect, new RuleApplierWrapper(pwdRules)); } @Override diff --git a/server/src/org/apache/cloudstack/network/topology/BasicNetworkVisitor.java b/server/src/org/apache/cloudstack/network/topology/BasicNetworkVisitor.java index 40b8d9424cf..3b1f0715643 100644 --- a/server/src/org/apache/cloudstack/network/topology/BasicNetworkVisitor.java +++ b/server/src/org/apache/cloudstack/network/topology/BasicNetworkVisitor.java @@ -26,6 +26,7 @@ import org.springframework.stereotype.Component; import com.cloud.agent.api.Command; import com.cloud.agent.manager.Commands; +import com.cloud.deploy.DeployDestination; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.Network; import com.cloud.network.PublicIpAddress; @@ -147,7 +148,22 @@ public class BasicNetworkVisitor extends NetworkTopologyVisitor { @Override public boolean visit(final UserdataPwdRules userdata) throws ResourceUnavailableException { - return false; + final VirtualRouter router = userdata.getRouter(); + + final Commands commands = new Commands(Command.OnError.Stop); + final VirtualMachineProfile profile = userdata.getProfile(); + final NicVO nicVo = userdata.getNicVo(); + final UserVmVO userVM = userdata.getUserVM(); + final DeployDestination destination = userdata.getDestination(); + + if (router.getPodIdToDeployIn().longValue() == destination.getPod().getId()) { + userdata.createPasswordCommand(router, profile, nicVo, commands); + userdata.createVmDataCommand(router, userVM, nicVo, userVM.getDetail("SSH.PublicKey"), commands); + + return _applianceManager.sendCommandsToRouter(router, commands); + } + + return true; } @Override diff --git a/server/src/org/apache/cloudstack/network/topology/NetworkTopology.java b/server/src/org/apache/cloudstack/network/topology/NetworkTopology.java index 008196c7fef..42d61979038 100644 --- a/server/src/org/apache/cloudstack/network/topology/NetworkTopology.java +++ b/server/src/org/apache/cloudstack/network/topology/NetworkTopology.java @@ -49,14 +49,14 @@ public interface NetworkTopology { boolean applyDhcpEntry(final Network network, final NicProfile nic, final VirtualMachineProfile profile, final DeployDestination dest, final List routers) throws ResourceUnavailableException; - boolean applyUserData(final Network network, final NicProfile nic, final VirtualMachineProfile profile, final DeployDestination dest, final List routers) - throws ResourceUnavailableException; - boolean applyRules(final Network network, final List routers, final String typeString, final boolean isPodLevelException, final Long podId, final boolean failWhenDisconnect, RuleApplierWrapper ruleApplier) throws ResourceUnavailableException; // ====== USER FOR GUEST NETWORK ====== // + boolean applyUserData(final Network network, final NicProfile nic, final VirtualMachineProfile profile, final DeployDestination dest, final List routers) + throws ResourceUnavailableException; + boolean applyLoadBalancingRules(Network network, List rules, List routers) throws ResourceUnavailableException; boolean applyFirewallRules(final Network network, final List rules, final List routers) throws ResourceUnavailableException;